diff --git a/DEPS b/DEPS index d96feba..0a0b968 100644 --- a/DEPS +++ b/DEPS
@@ -39,11 +39,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '844a0b425741f07cb233332405143931586bbb7d', + 'skia_revision': '6950de6c4166fabb35e6c756fc009e0cf1c47819', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '23533853f416feadfc1b39db7501837d4bf5f7fa', + 'v8_revision': '935b8785b9c5c7e29732c0a4830704e4be4d13f5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -187,7 +187,7 @@ Var('chromium_git') + '/external/selenium/py.git' + '@' + '5fd78261a75fe08d27ca4835fb6c5ce4b42275bd', 'src/third_party/libvpx_new/source/libvpx': - Var('chromium_git') + '/webm/libvpx.git' + '@' + 'c6641709a707ccb98cbdf785428659e44d4f2c8b', + Var('chromium_git') + '/webm/libvpx.git' + '@' + 'eba14ddbe7e7b69803dab770ba25ae2ba75c65e2', 'src/third_party/ffmpeg': Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'd2733b2c43f65f0e779d5d014777fb8ea1e89873', @@ -280,7 +280,7 @@ 'src/third_party/catapult': Var('chromium_git') + '/external/github.com/catapult-project/catapult.git' + '@' + - 'e2c6869c72944a7a7a729c7ccc9fdc1f8f90de8e', + '53ddd9ffa0a29872a62b8288a4adefb7ec3f590d', }
diff --git a/base/trace_event/BUILD.gn b/base/trace_event/BUILD.gn index 862b450..70ebeaa 100644 --- a/base/trace_event/BUILD.gn +++ b/base/trace_event/BUILD.gn
@@ -71,14 +71,17 @@ ] } - if (is_linux || is_android) { + if (is_linux || is_android || is_mac) { sources += [ "malloc_dump_provider.cc", "malloc_dump_provider.h", - "process_memory_maps_dump_provider.cc", ] } + if (is_linux || is_android) { + sources += [ "process_memory_maps_dump_provider.cc" ] + } + configs += [ "//base:base_implementation" ] deps = [
diff --git a/base/trace_event/malloc_dump_provider.cc b/base/trace_event/malloc_dump_provider.cc index 914c684..5279ab0c 100644 --- a/base/trace_event/malloc_dump_provider.cc +++ b/base/trace_event/malloc_dump_provider.cc
@@ -4,7 +4,11 @@ #include "base/trace_event/malloc_dump_provider.h" +#if defined(OS_MACOSX) +#include <malloc/malloc.h> +#else #include <malloc.h> +#endif #include "base/allocator/allocator_extension_thunks.h" #include "base/trace_event/process_memory_dump.h" @@ -21,11 +25,9 @@ LeakySingletonTraits<MallocDumpProvider>>::get(); } -MallocDumpProvider::MallocDumpProvider() { -} +MallocDumpProvider::MallocDumpProvider() {} -MallocDumpProvider::~MallocDumpProvider() { -} +MallocDumpProvider::~MallocDumpProvider() {} // Called at trace dump point time. Creates a snapshot the memory counters for // the current process. @@ -34,7 +36,13 @@ size_t total_virtual_size = 0; size_t resident_size = 0; size_t allocated_objects_size = 0; - +#if defined(OS_MACOSX) || defined(OS_IOS) + malloc_statistics_t stats = {0}; + malloc_zone_statistics(nullptr, &stats); + total_virtual_size = stats.size_allocated; + resident_size = stats.size_in_use; + allocated_objects_size = stats.size_in_use; +#else allocator::thunks::GetNumericPropertyFunction get_property_function = allocator::thunks::GetGetNumericPropertyFunction(); if (get_property_function) { @@ -58,6 +66,7 @@ resident_size = info.uordblks; allocated_objects_size = info.uordblks; } +#endif MemoryAllocatorDump* outer_dump = pmd->CreateAllocatorDump("malloc"); outer_dump->AddScalar("virtual_size", MemoryAllocatorDump::kUnitsBytes,
diff --git a/base/trace_event/malloc_dump_provider.h b/base/trace_event/malloc_dump_provider.h index f351999..f463d0a6 100644 --- a/base/trace_event/malloc_dump_provider.h +++ b/base/trace_event/malloc_dump_provider.h
@@ -7,8 +7,15 @@ #include <istream> +#include "base/macros.h" #include "base/memory/singleton.h" #include "base/trace_event/memory_dump_provider.h" +#include "build/build_config.h" + +#if defined(OS_LINUX) || defined(OS_ANDROID) || \ + (defined(OS_MACOXS) && !defined(OS_IOS)) +#define SUPPORTS_MALLOC_MEMORY_TRACING +#endif namespace base { namespace trace_event {
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc index eec2ff39..43c784b 100644 --- a/base/trace_event/memory_dump_manager.cc +++ b/base/trace_event/memory_dump_manager.cc
@@ -12,6 +12,7 @@ #include "base/compiler_specific.h" #include "base/thread_task_runner_handle.h" #include "base/threading/thread.h" +#include "base/trace_event/malloc_dump_provider.h" #include "base/trace_event/memory_dump_provider.h" #include "base/trace_event/memory_dump_session_state.h" #include "base/trace_event/memory_profiler_allocation_context.h" @@ -24,7 +25,6 @@ #endif #if defined(OS_LINUX) || defined(OS_ANDROID) -#include "base/trace_event/malloc_dump_provider.h" #include "base/trace_event/process_memory_maps_dump_provider.h" #endif @@ -96,7 +96,7 @@ // static const char* const MemoryDumpManager::kSystemAllocatorPoolName = -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(SUPPORTS_MALLOC_MEMORY_TRACING) MallocDumpProvider::kAllocatedObjects; #elif defined(OS_WIN) WinHeapDumpProvider::kAllocatedObjects; @@ -155,10 +155,13 @@ "ProcessMemoryTotals", nullptr); #endif +#if defined(SUPPORTS_MALLOC_MEMORY_TRACING) + RegisterDumpProvider(MallocDumpProvider::GetInstance(), "Malloc", nullptr); +#endif + #if defined(OS_LINUX) || defined(OS_ANDROID) RegisterDumpProvider(ProcessMemoryMapsDumpProvider::GetInstance(), "ProcessMemoryMaps", nullptr); - RegisterDumpProvider(MallocDumpProvider::GetInstance(), "Malloc", nullptr); #endif #if defined(OS_ANDROID)
diff --git a/base/trace_event/process_memory_totals.cc b/base/trace_event/process_memory_totals.cc index 1270924f..de27ab3d 100644 --- a/base/trace_event/process_memory_totals.cc +++ b/base/trace_event/process_memory_totals.cc
@@ -17,6 +17,8 @@ is_peak_rss_resetable_(false) { } +ProcessMemoryTotals::~ProcessMemoryTotals() {} + void ProcessMemoryTotals::AsValueInto(TracedValue* value) const { value->SetString("resident_set_bytes", StringPrintf("%" PRIx64, resident_set_bytes_)); @@ -25,11 +27,21 @@ StringPrintf("%" PRIx64, peak_resident_set_bytes_)); value->SetBoolean("is_peak_rss_resetable", is_peak_rss_resetable_); } + + for (const auto it : extra_fields_) { + value->SetString(it.first, StringPrintf("%" PRIx64, it.second)); + } } void ProcessMemoryTotals::Clear() { resident_set_bytes_ = 0; } +void ProcessMemoryTotals::SetExtraFieldInBytes(const char* name, + uint64_t value) { + DCHECK_EQ(0u, extra_fields_.count(name)); + extra_fields_[name] = value; +} + } // namespace trace_event } // namespace base
diff --git a/base/trace_event/process_memory_totals.h b/base/trace_event/process_memory_totals.h index 1bf8bdc..eb7757c9 100644 --- a/base/trace_event/process_memory_totals.h +++ b/base/trace_event/process_memory_totals.h
@@ -5,6 +5,8 @@ #ifndef BASE_TRACE_EVENT_PROCESS_MEMORY_TOTALS_H_ #define BASE_TRACE_EVENT_PROCESS_MEMORY_TOTALS_H_ +#include <map> + #include "base/base_export.h" #include "base/basictypes.h" @@ -17,6 +19,7 @@ class BASE_EXPORT ProcessMemoryTotals { public: ProcessMemoryTotals(); + ~ProcessMemoryTotals(); // Called at trace generation time to populate the TracedValue. void AsValueInto(TracedValue* value) const; @@ -24,11 +27,11 @@ // Clears up all the data collected. void Clear(); - uint64 resident_set_bytes() const { return resident_set_bytes_; } - void set_resident_set_bytes(uint64 value) { resident_set_bytes_ = value; } + uint64_t resident_set_bytes() const { return resident_set_bytes_; } + void set_resident_set_bytes(uint64_t value) { resident_set_bytes_ = value; } - uint64 peak_resident_set_bytes() const { return peak_resident_set_bytes_; } - void set_peak_resident_set_bytes(uint64 value) { + uint64_t peak_resident_set_bytes() const { return peak_resident_set_bytes_; } + void set_peak_resident_set_bytes(uint64_t value) { peak_resident_set_bytes_ = value; } @@ -39,11 +42,16 @@ bool is_peak_rss_resetable() const { return is_peak_rss_resetable_; } void set_is_peak_rss_resetable(bool value) { is_peak_rss_resetable_ = value; } + void SetExtraFieldInBytes(const char* name, uint64_t value); + private: - uint64 resident_set_bytes_; - uint64 peak_resident_set_bytes_; + uint64_t resident_set_bytes_; + uint64_t peak_resident_set_bytes_; bool is_peak_rss_resetable_; + // Extra metrics for OS-specific statistics. + std::map<const char*, uint64_t> extra_fields_; + DISALLOW_COPY_AND_ASSIGN(ProcessMemoryTotals); };
diff --git a/base/trace_event/process_memory_totals_dump_provider.cc b/base/trace_event/process_memory_totals_dump_provider.cc index a861720..c057deb 100644 --- a/base/trace_event/process_memory_totals_dump_provider.cc +++ b/base/trace_event/process_memory_totals_dump_provider.cc
@@ -77,6 +77,13 @@ } close(clear_refs_fd); } +#elif defined(OS_MACOSX) + size_t private_bytes; + bool res = process_metrics_->GetMemoryBytes(&private_bytes, + nullptr /* shared_bytes */); + if (res) { + pmd->process_totals()->SetExtraFieldInBytes("private_bytes", private_bytes); + } #endif // defined(OS_LINUX) || defined(OS_ANDROID) #endif // !defined(OS_IOS)
diff --git a/base/trace_event/trace_event.gypi b/base/trace_event/trace_event.gypi index db87e4b1c..4713311 100644 --- a/base/trace_event/trace_event.gypi +++ b/base/trace_event/trace_event.gypi
@@ -81,10 +81,14 @@ 'trace_event/winheap_dump_provider_win_unittest.cc', ], 'conditions': [ + ['OS == "linux" or OS=="android" or OS=="mac"', { + 'trace_event_sources': [ + 'trace_event/malloc_dump_provider.cc', + 'trace_event/malloc_dump_provider.h', + ], + }], ['OS == "linux" or OS == "android"', { 'trace_event_sources': [ - 'trace_event/malloc_dump_provider.cc', - 'trace_event/malloc_dump_provider.h', 'trace_event/process_memory_maps_dump_provider.cc', ], 'trace_event_test_sources' : [
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc index 1f9ee3ef..5ed3968 100644 --- a/chrome/browser/password_manager/password_manager_browsertest.cc +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -147,6 +147,24 @@ } #endif +void TestPromptNotShown(const char* failure_message, + content::WebContents* web_contents, + content::RenderViewHost* rvh) { + SCOPED_TRACE(testing::Message(failure_message)); + + NavigationObserver observer(web_contents); + scoped_ptr<PromptObserver> prompt_observer( + PromptObserver::Create(web_contents)); + std::string fill_and_submit = + "document.getElementById('username_failed').value = 'temp';" + "document.getElementById('password_failed').value = 'random';" + "document.getElementById('failed_form').submit()"; + + ASSERT_TRUE(content::ExecuteScript(rvh, fill_and_submit)); + observer.Wait(); + EXPECT_FALSE(prompt_observer->IsShowingPrompt()); +} + } // namespace namespace password_manager { @@ -170,6 +188,25 @@ } IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, + NoPromptIfFormReappeared) { + NavigateToFile("/password/failed.html"); + TestPromptNotShown("normal form", WebContents(), RenderViewHost()); +} + +IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, + NoPromptIfFormReappearedWithPartsHidden) { + NavigateToFile("/password/failed_partly_visible.html"); + TestPromptNotShown("partly visible form", WebContents(), RenderViewHost()); +} + +IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, + NoPromptIfFormReappearedInputOutsideFor) { + NavigateToFile("/password/failed_input_outside.html"); + TestPromptNotShown("form with input outside", WebContents(), + RenderViewHost()); +} + +IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, PromptForSubmitWithInPageNavigation) { NavigateToFile("/password/password_navigate_before_submit.html");
diff --git a/chrome/test/data/password/failed.html b/chrome/test/data/password/failed.html index fd52805..7d12460 100644 --- a/chrome/test/data/password/failed.html +++ b/chrome/test/data/password/failed.html
@@ -1,7 +1,7 @@ <html> <body> Navigation complete. Below is the login form again, a sign of failure. -<form method="POST" action="failed.html" id="to_failed"> +<form method="POST" action="failed.html" id="failed_form"> <input type="text" id="username_failed" name="username_failed"> <input type="password" id="password_failed" name="password_failed"> <input type="submit" id="submit_failed" name="submit_failed">
diff --git a/chrome/test/data/password/failed_input_outside.html b/chrome/test/data/password/failed_input_outside.html new file mode 100644 index 0000000..d23b7b46 --- /dev/null +++ b/chrome/test/data/password/failed_input_outside.html
@@ -0,0 +1,14 @@ +<html> +<body> +Navigation complete. Below is the login form again, a sign of failure. +<form method="POST" action="failed_input_outside.html" id="failed_form"> +</form> + +<input type="text" id="username_failed" name="username_failed" + form="failed_form"> +<input type="password" id="password_failed" name="password_failed" + form="failed_form"> +<input type="submit" id="submit_failed" name="submit_failed" + form="failed_form"> +</body> +</html>
diff --git a/chrome/test/data/password/failed_partly_visible.html b/chrome/test/data/password/failed_partly_visible.html new file mode 100644 index 0000000..c618bff8 --- /dev/null +++ b/chrome/test/data/password/failed_partly_visible.html
@@ -0,0 +1,27 @@ +<html> +<head> + <style> + .absolute { + position: absolute; + } + .hidden { + display: none; + } + </style> +</head> +<body> +This form comes from http://crbug.com/549149#c4. +<form method="POST" action="failed_partly_visible.html" id="failed_form"> + <div class="absolute"> + <div class="hidden"> + <input type="submit" id="hidden_submit"> + </div> + </div> + <div class="absolute"> + <input type="text" id="username_failed"> + <input type="password" id="password_failed"> + </div> +</form> + +</body> +</html>
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc index d003028..f15a5806 100644 --- a/components/autofill/content/renderer/autofill_agent.cc +++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -615,7 +615,7 @@ // Assume form submission only if the form is now gone, either invisible or // removed from the DOM. - if (form_util::IsFormVisible(last_interacted_form_)) + if (form_util::AreFormContentsVisible(last_interacted_form_)) return; // Could not find a visible form equal to our saved form, assume submission.
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc index e6b456d..c044532 100644 --- a/components/autofill/content/renderer/form_autofill_util.cc +++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -1090,17 +1090,6 @@ } // namespace -bool IsNamedElementVisible( - const std::vector<blink::WebFormControlElement>& control_elements, - const base::string16& name) { - for (size_t i = 0; i < control_elements.size(); ++i) { - if (control_elements[i].nameForAutofill() == name) { - return IsWebNodeVisible(control_elements[i]); - } - } - return false; -} - bool ExtractFormData(const WebFormElement& form_element, FormData* data) { return WebFormElementToFormData( form_element, WebFormControlElement(), @@ -1112,10 +1101,9 @@ bool IsFormVisible(blink::WebFrame* frame, const GURL& canonical_action, const GURL& canonical_origin, - const FormData& form_data, - const FormsPredictionsMap& form_predictions) { + const FormData& form_data) { const GURL frame_url = GURL(frame->document().url().string().utf8()); - blink::WebVector<blink::WebFormElement> forms; + blink::WebVector<WebFormElement> forms; frame->document().forms(forms); #if !defined(OS_MACOSX) && !defined(OS_ANDROID) @@ -1128,9 +1116,8 @@ // to the page URL, this method checks ALL fields of the form instead (using // FormData.SameFormAs). This is also true if the action was set to the page // URL on purpose. - for (size_t i = 0; i < forms.size(); ++i) { - const blink::WebFormElement& form = forms[i]; - if (!IsWebNodeVisible(form)) + for (const WebFormElement& form : forms) { + if (!AreFormContentsVisible(form)) continue; GURL iter_canonical_action = GetCanonicalActionForForm(form); @@ -1142,8 +1129,8 @@ if (action_is_empty) { // Both actions are empty, compare all fields. FormData extracted_form_data; - WebFormElementToFormData(form, blink::WebFormControlElement(), - EXTRACT_NONE, &extracted_form_data, nullptr); + WebFormElementToFormData(form, WebFormControlElement(), EXTRACT_NONE, + &extracted_form_data, nullptr); if (form_data.SameFormAs(extracted_form_data)) { return true; // Form still exists. } @@ -1162,12 +1149,19 @@ return false; } -bool IsFormVisible(const WebFormElement& form) { - FormData form_data; - return ExtractFormData(form, &form_data) && - IsFormVisible(form.document().frame(), GetCanonicalActionForForm(form), - GetCanonicalOriginForDocument(form.document()), - form_data, FormsPredictionsMap()); +bool IsSomeControlElementVisible( + const WebVector<WebFormControlElement>& control_elements) { + for (const WebFormControlElement& control_element : control_elements) { + if (IsWebNodeVisible(control_element)) + return true; + } + return false; +} + +bool AreFormContentsVisible(const WebFormElement& form) { + WebVector<WebFormControlElement> control_elements; + form.getFormControlElements(control_elements); + return IsSomeControlElementVisible(control_elements); } GURL GetCanonicalActionForForm(const WebFormElement& form) {
diff --git a/components/autofill/content/renderer/form_autofill_util.h b/components/autofill/content/renderer/form_autofill_util.h index d26ac6d..5632c66 100644 --- a/components/autofill/content/renderer/form_autofill_util.h +++ b/components/autofill/content/renderer/form_autofill_util.h
@@ -56,12 +56,6 @@ // Copied to components/autofill/ios/browser/resources/autofill_controller.js. extern const size_t kMaxParseableFields; -// Returns true if |control_elements| contains an element named |name| and is -// visible. -bool IsNamedElementVisible( - const std::vector<blink::WebFormControlElement>& control_elements, - const base::string16& name); - // Extract FormData from the form element and return whether the operation was // successful. bool ExtractFormData(const blink::WebFormElement& form_element, FormData* data); @@ -76,12 +70,14 @@ bool IsFormVisible(blink::WebFrame* frame, const GURL& action, const GURL& origin, - const FormData& form_data, - const FormsPredictionsMap& form_predictions); + const FormData& form_data); -// Returns whether |form| is still visible in the frame. Ends up calling -// isFormVisible() above, deriving arguments from |form|. -bool IsFormVisible(const blink::WebFormElement& form); +// Returns true if at least one element from |control_elements| is visible. +bool IsSomeControlElementVisible( + const blink::WebVector<blink::WebFormControlElement>& control_elements); + +// Returns true if some control elements of |form| are visible. +bool AreFormContentsVisible(const blink::WebFormElement& form); // Helper functions to assist in getting the canonical form of the action and // origin. The action will proplerly take into account <BASE>, and both will
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index 69b27bc1..3814746 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -126,28 +126,23 @@ scoped_ptr<PasswordForm> unowned_password_form( CreatePasswordFormFromUnownedInputElements(*frame, nullptr, &form_predictions)); + if (!unowned_password_form) + return false; std::vector<blink::WebFormControlElement> control_elements = form_util::GetUnownedAutofillableFormFieldElements( frame->document().all(), nullptr); - if (unowned_password_form && - form_util::IsNamedElementVisible( - control_elements, unowned_password_form->username_element) && - form_util::IsNamedElementVisible( - control_elements, unowned_password_form->password_element)) { -#if !defined(OS_MACOSX) && !defined(OS_ANDROID) - const bool action_is_empty = action == origin; - bool forms_are_same = - action_is_empty ? form_data.SameFormAs(unowned_password_form->form_data) - : action == unowned_password_form->action; - if (forms_are_same) - return true; // Form still exists. -#else // OS_MACOSX or OS_ANDROID - if (action == unowned_password_form->action) - return true; // Form still exists. -#endif - } + if (!form_util::IsSomeControlElementVisible(control_elements)) + return false; - return false; +#if !defined(OS_MACOSX) && !defined(OS_ANDROID) + const bool action_is_empty = action == origin; + bool forms_are_same = + action_is_empty ? form_data.SameFormAs(unowned_password_form->form_data) + : action == unowned_password_form->action; + return forms_are_same; +#else // OS_MACOSX or OS_ANDROID + return action == unowned_password_form->action; +#endif } // Utility function to find the unique entry of |control_elements| for the @@ -946,8 +941,7 @@ blink::WebFrame* frame = render_frame()->GetWebFrame(); if (form_util::IsFormVisible(frame, provisionally_saved_form_->action, provisionally_saved_form_->origin, - provisionally_saved_form_->form_data, - form_predictions_) || + provisionally_saved_form_->form_data) || IsUnownedPasswordFormVisible(frame, provisionally_saved_form_->action, provisionally_saved_form_->origin, provisionally_saved_form_->form_data, @@ -1000,10 +994,9 @@ logger->LogNumber(Logger::STRING_NUMBER_OF_ALL_FORMS, forms.size()); std::vector<PasswordForm> password_forms; - for (size_t i = 0; i < forms.size(); ++i) { - const blink::WebFormElement& form = forms[i]; + for (const blink::WebFormElement& form : forms) { if (only_visible) { - bool is_form_visible = form_util::IsWebNodeVisible(form); + bool is_form_visible = form_util::AreFormContentsVisible(form); if (logger) { LogHTMLForm(logger.get(), Logger::STRING_FORM_FOUND_ON_PAGE, form); logger->LogBoolean(Logger::STRING_FORM_IS_VISIBLE, is_form_visible); @@ -1028,16 +1021,29 @@ // See if there are any unattached input elements that could be used for // password submission. - scoped_ptr<PasswordForm> password_form( - CreatePasswordFormFromUnownedInputElements(*frame, - nullptr, - &form_predictions_)); - if (password_form) { + bool add_unowned_inputs = true; + if (only_visible) { + std::vector<blink::WebFormControlElement> control_elements = + form_util::GetUnownedAutofillableFormFieldElements( + frame->document().all(), nullptr); + add_unowned_inputs = + form_util::IsSomeControlElementVisible(control_elements); if (logger) { - logger->LogPasswordForm(Logger::STRING_FORM_IS_PASSWORD, - *password_form); + logger->LogBoolean(Logger::STRING_UNOWNED_INPUTS_VISIBLE, + add_unowned_inputs); } - password_forms.push_back(*password_form); + } + if (add_unowned_inputs) { + scoped_ptr<PasswordForm> password_form( + CreatePasswordFormFromUnownedInputElements(*frame, nullptr, + &form_predictions_)); + if (password_form) { + if (logger) { + logger->LogPasswordForm(Logger::STRING_FORM_IS_PASSWORD, + *password_form); + } + password_forms.push_back(*password_form); + } } if (password_forms.empty() && !only_visible) {
diff --git a/components/autofill/core/common/save_password_progress_logger.cc b/components/autofill/core/common/save_password_progress_logger.cc index b70d818..33d88753 100644 --- a/components/autofill/core/common/save_password_progress_logger.cc +++ b/components/autofill/core/common/save_password_progress_logger.cc
@@ -354,6 +354,9 @@ return "PasswordFormManager::state_"; case SavePasswordProgressLogger::STRING_ADDING_SIGNATURE: return "Adding manager for form with this signature"; + case SavePasswordProgressLogger::STRING_UNOWNED_INPUTS_VISIBLE: + return "Some control elements not associated to a form element are " + "visible"; case SavePasswordProgressLogger::STRING_INVALID: return "INVALID"; // Intentionally no default: clause here -- all IDs need to get covered.
diff --git a/components/autofill/core/common/save_password_progress_logger.h b/components/autofill/core/common/save_password_progress_logger.h index 15d5e27..c68925b 100644 --- a/components/autofill/core/common/save_password_progress_logger.h +++ b/components/autofill/core/common/save_password_progress_logger.h
@@ -127,6 +127,7 @@ STRING_FORM_SIGNATURE, STRING_ADDING_SIGNATURE, STRING_FORM_MANAGER_STATE, + STRING_UNOWNED_INPUTS_VISIBLE, STRING_INVALID, // Represents a string returned in a case of an error. STRING_MAX = STRING_INVALID };
diff --git a/components/mus/ws/BUILD.gn b/components/mus/ws/BUILD.gn index bc2d0af7..7a186d6 100644 --- a/components/mus/ws/BUILD.gn +++ b/components/mus/ws/BUILD.gn
@@ -27,6 +27,8 @@ "focus_controller.cc", "focus_controller.h", "focus_controller_delegate.h", + "operation.cc", + "operation.h", "server_window.cc", "server_window.h", "server_window_delegate.h",
diff --git a/components/mus/ws/connection_manager.cc b/components/mus/ws/connection_manager.cc index ede74e9..c7cebb1 100644 --- a/components/mus/ws/connection_manager.cc +++ b/components/mus/ws/connection_manager.cc
@@ -8,6 +8,7 @@ #include "base/stl_util.h" #include "components/mus/ws/client_connection.h" #include "components/mus/ws/connection_manager_delegate.h" +#include "components/mus/ws/operation.h" #include "components/mus/ws/server_window.h" #include "components/mus/ws/window_coordinate_conversions.h" #include "components/mus/ws/window_tree_host_connection.h" @@ -22,20 +23,6 @@ namespace ws { -ConnectionManager::ScopedChange::ScopedChange( - WindowTreeImpl* connection, - ConnectionManager* connection_manager, - bool is_delete_window) - : connection_manager_(connection_manager), - connection_id_(connection->id()), - is_delete_window_(is_delete_window) { - connection_manager_->PrepareForChange(this); -} - -ConnectionManager::ScopedChange::~ScopedChange() { - connection_manager_->FinishChange(); -} - ConnectionManager::ConnectionManager( ConnectionManagerDelegate* delegate, const scoped_refptr<mus::SurfacesState>& surfaces_state) @@ -43,7 +30,7 @@ surfaces_state_(surfaces_state), next_connection_id_(1), next_host_id_(0), - current_change_(nullptr), + current_operation_(nullptr), in_destructor_(false) {} ConnectionManager::~ConnectionManager() { @@ -179,13 +166,13 @@ } void ConnectionManager::OnConnectionMessagedClient(ConnectionSpecificId id) { - if (current_change_) - current_change_->MarkConnectionAsMessaged(id); + if (current_operation_) + current_operation_->MarkConnectionAsMessaged(id); } bool ConnectionManager::DidConnectionMessageClient( ConnectionSpecificId id) const { - return current_change_ && current_change_->DidMessageConnection(id); + return current_operation_ && current_operation_->DidMessageConnection(id); } mojom::ViewportMetricsPtr ConnectionManager::GetViewportMetricsForWindow( @@ -249,7 +236,7 @@ const gfx::Rect& new_bounds) { for (auto& pair : connection_map_) { pair.second->service()->ProcessWindowBoundsChanged( - window, old_bounds, new_bounds, IsChangeSource(pair.first)); + window, old_bounds, new_bounds, IsOperationSource(pair.first)); } } @@ -259,7 +246,8 @@ const gfx::Insets& new_client_area) { for (auto& pair : connection_map_) { pair.second->service()->ProcessClientAreaChanged( - window, old_client_area, new_client_area, IsChangeSource(pair.first)); + window, old_client_area, new_client_area, + IsOperationSource(pair.first)); } } @@ -269,7 +257,7 @@ const ServerWindow* old_parent) { for (auto& pair : connection_map_) { pair.second->service()->ProcessWillChangeWindowHierarchy( - window, new_parent, old_parent, IsChangeSource(pair.first)); + window, new_parent, old_parent, IsOperationSource(pair.first)); } } @@ -279,7 +267,7 @@ const ServerWindow* old_parent) { for (auto& pair : connection_map_) { pair.second->service()->ProcessWindowHierarchyChanged( - window, new_parent, old_parent, IsChangeSource(pair.first)); + window, new_parent, old_parent, IsOperationSource(pair.first)); } } @@ -289,14 +277,14 @@ const mojom::OrderDirection direction) { for (auto& pair : connection_map_) { pair.second->service()->ProcessWindowReorder( - window, relative_window, direction, IsChangeSource(pair.first)); + window, relative_window, direction, IsOperationSource(pair.first)); } } void ConnectionManager::ProcessWindowDeleted(const WindowId& window) { for (auto& pair : connection_map_) { pair.second->service()->ProcessWindowDeleted(window, - IsChangeSource(pair.first)); + IsOperationSource(pair.first)); } } @@ -305,20 +293,20 @@ const mojom::ViewportMetrics& new_metrics) { for (auto& pair : connection_map_) { pair.second->service()->ProcessViewportMetricsChanged( - old_metrics, new_metrics, IsChangeSource(pair.first)); + old_metrics, new_metrics, IsOperationSource(pair.first)); } } -void ConnectionManager::PrepareForChange(ScopedChange* change) { +void ConnectionManager::PrepareForOperation(Operation* op) { // Should only ever have one change in flight. - CHECK(!current_change_); - current_change_ = change; + CHECK(!current_operation_); + current_operation_ = op; } -void ConnectionManager::FinishChange() { - // PrepareForChange/FinishChange should be balanced. - CHECK(current_change_); - current_change_ = NULL; +void ConnectionManager::FinishOperation() { + // PrepareForOperation/FinishOperation should be balanced. + CHECK(current_operation_); + current_operation_ = nullptr; } void ConnectionManager::AddConnection(ClientConnection* connection) { @@ -416,7 +404,7 @@ for (auto& pair : connection_map_) { pair.second->service()->ProcessWillChangeWindowVisibility( - window, IsChangeSource(pair.first)); + window, IsOperationSource(pair.first)); } } @@ -426,7 +414,7 @@ const std::vector<uint8_t>* new_data) { for (auto& pair : connection_map_) { pair.second->service()->ProcessWindowPropertyChanged( - window, name, new_data, IsChangeSource(pair.first)); + window, name, new_data, IsOperationSource(pair.first)); } }
diff --git a/components/mus/ws/connection_manager.h b/components/mus/ws/connection_manager.h index 4fca836e..e16b44a 100644 --- a/components/mus/ws/connection_manager.h +++ b/components/mus/ws/connection_manager.h
@@ -16,6 +16,7 @@ #include "components/mus/surfaces/surfaces_state.h" #include "components/mus/ws/focus_controller_delegate.h" #include "components/mus/ws/ids.h" +#include "components/mus/ws/operation.h" #include "components/mus/ws/server_window_delegate.h" #include "components/mus/ws/server_window_observer.h" #include "components/mus/ws/window_tree_host_impl.h" @@ -38,39 +39,6 @@ class ConnectionManager : public ServerWindowDelegate, public ServerWindowObserver { public: - // Create when a WindowTreeImpl is about to make a change. Ensures clients are - // notified correctly. - class ScopedChange { - public: - ScopedChange(WindowTreeImpl* connection, - ConnectionManager* connection_manager, - bool is_delete_window); - ~ScopedChange(); - - ConnectionSpecificId connection_id() const { return connection_id_; } - bool is_delete_window() const { return is_delete_window_; } - - // Marks the connection with the specified id as having seen a message. - void MarkConnectionAsMessaged(ConnectionSpecificId connection_id) { - message_ids_.insert(connection_id); - } - - // Returns true if MarkConnectionAsMessaged(connection_id) was invoked. - bool DidMessageConnection(ConnectionSpecificId connection_id) const { - return message_ids_.count(connection_id) > 0; - } - - private: - ConnectionManager* connection_manager_; - const ConnectionSpecificId connection_id_; - const bool is_delete_window_; - - // See description of MarkConnectionAsMessaged/DidMessageConnection. - std::set<ConnectionSpecificId> message_ids_; - - DISALLOW_COPY_AND_ASSIGN(ScopedChange); - }; - ConnectionManager(ConnectionManagerDelegate* delegate, const scoped_refptr<mus::SurfacesState>& surfaces_state); ~ConnectionManager() override; @@ -115,10 +83,9 @@ // Schedules a paint for the specified region in the coordinates of |window|. void SchedulePaint(const ServerWindow* window, const gfx::Rect& bounds); - bool IsProcessingChange() const { return current_change_ != nullptr; } - - bool is_processing_delete_window() const { - return current_change_ && current_change_->is_delete_window(); + OperationType current_operation_type() const { + return current_operation_ ? current_operation_->type() + : OperationType::NONE; } // Invoked when the WindowTreeHostImpl's display is closed. @@ -176,24 +143,27 @@ void ProcessWindowDeleted(const WindowId& window); private: + friend class Operation; + using ConnectionMap = std::map<ConnectionSpecificId, ClientConnection*>; using HostConnectionMap = std::map<WindowTreeHostImpl*, WindowTreeHostConnection*>; - // Invoked when a connection is about to make a change. Subsequently followed - // by FinishChange() once the change is done. + // Invoked when a connection is about to execute a window server operation. + // Subsequently followed by FinishOperation() once the change is done. // - // Changes should never nest, meaning each PrepareForChange() must be - // balanced with a call to FinishChange() with no PrepareForChange() + // Changes should never nest, meaning each PrepareForOperation() must be + // balanced with a call to FinishOperation() with no PrepareForOperation() // in between. - void PrepareForChange(ScopedChange* change); + void PrepareForOperation(Operation* op); - // Balances a call to PrepareForChange(). - void FinishChange(); + // Balances a call to PrepareForOperation(). + void FinishOperation(); - // Returns true if the specified connection originated the current change. - bool IsChangeSource(ConnectionSpecificId connection_id) const { - return current_change_ && current_change_->connection_id() == connection_id; + // Returns true if the specified connection issued the current operation. + bool IsOperationSource(ConnectionSpecificId connection_id) const { + return current_operation_ && + current_operation_->source_connection_id() == connection_id; } // Adds |connection| to internal maps. @@ -246,9 +216,9 @@ // Set of WindowTreeHostImpls. HostConnectionMap host_connection_map_; - // If non-null we're processing a change. The ScopedChange is not owned by us - // (it's created on the stack by WindowTreeImpl). - ScopedChange* current_change_; + // If non-null then we're processing a client operation. The Operation is + // not owned by us (it's created on the stack by WindowTreeImpl). + Operation* current_operation_; bool in_destructor_;
diff --git a/components/mus/ws/operation.cc b/components/mus/ws/operation.cc new file mode 100644 index 0000000..f302f26 --- /dev/null +++ b/components/mus/ws/operation.cc
@@ -0,0 +1,31 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/mus/ws/operation.h" + +#include "components/mus/ws/connection_manager.h" +#include "components/mus/ws/window_tree_impl.h" + +namespace mus { +namespace ws { + +Operation::Operation(WindowTreeImpl* connection, + ConnectionManager* connection_manager, + OperationType operation_type) + : connection_manager_(connection_manager), + source_connection_id_(connection->id()), + operation_type_(operation_type) { + DCHECK(operation_type != OperationType::NONE); + // Tell the connection manager about the operation currently in flight. + // The connection manager uses this information to suppress certain calls + // out to clients. + connection_manager_->PrepareForOperation(this); +} + +Operation::~Operation() { + connection_manager_->FinishOperation(); +} + +} // namespace ws +} // namespace mus
diff --git a/components/mus/ws/operation.h b/components/mus/ws/operation.h new file mode 100644 index 0000000..615287e --- /dev/null +++ b/components/mus/ws/operation.h
@@ -0,0 +1,73 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_MUS_WS_OPERATION_H_ +#define COMPONENTS_MUS_WS_OPERATION_H_ + +#include <set> + +#include "base/macros.h" +#include "components/mus/public/cpp/types.h" + +namespace mus { +namespace ws { + +class ConnectionManager; +class WindowTreeImpl; + +enum class OperationType { + NONE, + ADD_WINDOW, + DELETE_WINDOW, + EMBED, + REMOVE_WINDOW_FROM_PARENT, + REORDER_WINDOW, + SET_FOCUS, + SET_WINDOW_BOUNDS, + SET_WINDOW_PROPERTY, + SET_WINDOW_VISIBILITY, +}; + +// This class tracks the currently pending client-initiated operation. +// This is typically used to suppress superfluous notifications generated +// by suboperations in the window server. +class Operation { + public: + Operation(WindowTreeImpl* connection, + ConnectionManager* connection_manager, + OperationType operation_type); + ~Operation(); + + ConnectionSpecificId source_connection_id() const { + return source_connection_id_; + } + + const OperationType& type() const { return operation_type_; } + + // Marks the connection with the specified id as having been sent a message + // during the course of |this| operation. + void MarkConnectionAsMessaged(ConnectionSpecificId connection_id) { + message_ids_.insert(connection_id); + } + + // Returns true if MarkConnectionAsMessaged(connection_id) was invoked. + bool DidMessageConnection(ConnectionSpecificId connection_id) const { + return message_ids_.count(connection_id) > 0; + } + + private: + ConnectionManager* const connection_manager_; + const ConnectionSpecificId source_connection_id_; + const OperationType operation_type_; + + // See description of MarkConnectionAsMessaged/DidMessageConnection. + std::set<ConnectionSpecificId> message_ids_; + + DISALLOW_COPY_AND_ASSIGN(Operation); +}; + +} // namespace ws +} // namespace mus + +#endif // COMPONENTS_MUS_WS_OPERATION_H_
diff --git a/components/mus/ws/window_tree_impl.cc b/components/mus/ws/window_tree_impl.cc index 85c6e50..0564c2c 100644 --- a/components/mus/ws/window_tree_impl.cc +++ b/components/mus/ws/window_tree_impl.cc
@@ -9,6 +9,7 @@ #include "components/mus/ws/connection_manager.h" #include "components/mus/ws/default_access_policy.h" #include "components/mus/ws/display_manager.h" +#include "components/mus/ws/operation.h" #include "components/mus/ws/server_window.h" #include "components/mus/ws/window_manager_access_policy.h" #include "components/mus/ws/window_tree_host_impl.h" @@ -133,7 +134,7 @@ ServerWindow* child = GetWindow(child_id); if (parent && child && child->parent() != parent && !child->Contains(parent) && access_policy_->CanAddWindow(parent, child)) { - ConnectionManager::ScopedChange change(this, connection_manager_, false); + Operation op(this, connection_manager_, OperationType::ADD_WINDOW); parent->Add(child); return true; } @@ -156,7 +157,7 @@ !access_policy_->CanChangeWindowVisibility(window)) { return false; } - ConnectionManager::ScopedChange change(this, connection_manager_, false); + Operation op(this, connection_manager_, OperationType::SET_WINDOW_VISIBILITY); window->SetVisible(visible); return true; } @@ -250,7 +251,9 @@ std::vector<const ServerWindow*> unused; GetUnknownWindowsFrom(window, &unused); } - if (originated_change || connection_manager_->is_processing_delete_window() || + if (originated_change || (connection_manager_->current_operation_type() == + OperationType::DELETE_WINDOW) || + (connection_manager_->current_operation_type() == OperationType::EMBED) || connection_manager_->DidConnectionMessageClient(id_)) { return; } @@ -394,7 +397,7 @@ ServerWindow* window) { DCHECK(window); DCHECK_EQ(window->id().connection_id, id_); - ConnectionManager::ScopedChange change(source, connection_manager_, true); + Operation op(source, connection_manager_, OperationType::DELETE_WINDOW); delete window; return true; } @@ -512,7 +515,7 @@ void WindowTreeImpl::DestroyWindows() { if (!window_map_.empty()) { - ConnectionManager::ScopedChange change(this, connection_manager_, true); + Operation op(this, connection_manager_, OperationType::DELETE_WINDOW); // If we get here from the destructor we're not going to get // ProcessWindowDeleted(). Copy the map and delete from the copy so that we // don't have to worry about whether |window_map_| changes or not. @@ -536,7 +539,7 @@ WindowTreeImpl* existing_owner = connection_manager_->GetConnectionWithRoot(window_id); - ConnectionManager::ScopedChange change(this, connection_manager_, true); + Operation op(this, connection_manager_, OperationType::EMBED); RemoveChildrenAsPartOfEmbed(window_id); if (existing_owner) { // Never message the originating connection. @@ -588,7 +591,8 @@ if (window && window->parent() && access_policy_->CanRemoveWindowFromParent(window)) { success = true; - ConnectionManager::ScopedChange change(this, connection_manager_, false); + Operation op(this, connection_manager_, + OperationType::REMOVE_WINDOW_FROM_PARENT); window->parent()->Remove(window); } callback.Run(success); @@ -604,7 +608,7 @@ GetWindow(WindowIdFromTransportId(relative_window_id)); if (CanReorderWindow(window, relative_window, direction)) { success = true; - ConnectionManager::ScopedChange change(this, connection_manager_, false); + Operation op(this, connection_manager_, OperationType::REORDER_WINDOW); window->parent()->Reorder(window, relative_window, direction); connection_manager_->ProcessWindowReorder(window, relative_window, direction); @@ -633,7 +637,7 @@ // Only the owner of the window can change the bounds. bool success = window && access_policy_->CanSetWindowBounds(window); if (success) { - ConnectionManager::ScopedChange change(this, connection_manager_, false); + Operation op(this, connection_manager_, OperationType::SET_WINDOW_BOUNDS); window->SetBounds(bounds.To<gfx::Rect>()); } callback.Run(success); @@ -654,7 +658,7 @@ ServerWindow* window = GetWindow(WindowIdFromTransportId(window_id)); const bool success = window && access_policy_->CanSetWindowProperties(window); if (success) { - ConnectionManager::ScopedChange change(this, connection_manager_, false); + Operation op(this, connection_manager_, OperationType::SET_WINDOW_PROPERTY); if (value.is_null()) { window->SetProperty(name, nullptr); @@ -728,7 +732,7 @@ // TODO(beng): consider shifting non-policy drawn check logic to VTH's // FocusController. if (window && window->IsDrawn() && access_policy_->CanSetFocus(window)) { - ConnectionManager::ScopedChange change(this, connection_manager_, false); + Operation op(this, connection_manager_, OperationType::SET_FOCUS); WindowTreeHostImpl* host = GetHost(); if (host) host->SetFocusedWindow(window);
diff --git a/content/renderer/media/renderer_gpu_video_accelerator_factories.cc b/content/renderer/media/renderer_gpu_video_accelerator_factories.cc index 62e90878..934771c 100644 --- a/content/renderer/media/renderer_gpu_video_accelerator_factories.cc +++ b/content/renderer/media/renderer_gpu_video_accelerator_factories.cc
@@ -60,7 +60,8 @@ gpu_memory_buffer_manager_(ChildThreadImpl::current() ->gpu_memory_buffer_manager()), thread_safe_sender_(ChildThreadImpl::current()->thread_safe_sender()) { - DCHECK(gpu_channel_host_.get()); + DCHECK(main_thread_task_runner_); + DCHECK(gpu_channel_host_); } RendererGpuVideoAcceleratorFactories::~RendererGpuVideoAcceleratorFactories() {}
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index d1ac605..5a9da31 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -455,28 +455,28 @@ return request; } -void UpdateFrameNavigationTiming(WebFrame* frame, - base::TimeTicks browser_navigation_start, - base::TimeTicks renderer_navigation_start) { - // The browser provides the navigation_start time to bootstrap the - // Navigation Timing information for the browser-initiated navigations. In - // case of cross-process navigations, this carries over the time of - // finishing the onbeforeunload handler of the previous page. +// Sanitizes the navigation_start timestamp for browser-initiated navigations, +// where the browser possibly has a better notion of start time than the +// renderer. In the case of cross-process navigations, this carries over the +// time of finishing the onbeforeunload handler of the previous page. +// TimeTicks is sometimes not monotonic across processes, and because +// |browser_navigation_start| is likely before this process existed, +// InterProcessTimeTicksConverter won't help. The timestamp is sanitized by +// clamping it to renderer_navigation_start, initialized earlier in the call +// stack. +base::TimeTicks SanitizeNavigationTiming( + blink::WebFrameLoadType load_type, + const base::TimeTicks& browser_navigation_start, + const base::TimeTicks& renderer_navigation_start) { + if (load_type != blink::WebFrameLoadType::Standard) + return base::TimeTicks(); DCHECK(!browser_navigation_start.is_null()); - if (frame->provisionalDataSource()) { - // |browser_navigation_start| is likely before this process existed, so we - // can't use InterProcessTimeTicksConverter. We need at least to ensure - // that the browser-side navigation start we set is not later than the one - // on the renderer side. - base::TimeTicks navigation_start = std::min( - browser_navigation_start, renderer_navigation_start); - double navigation_start_seconds = - (navigation_start - base::TimeTicks()).InSecondsF(); - frame->provisionalDataSource()->setNavigationStartTime( - navigation_start_seconds); - // TODO(clamy): We need to provide additional timing values for the - // Navigation Timing API to work with browser-side navigations. - } + base::TimeTicks navigation_start = + std::min(browser_navigation_start, renderer_navigation_start); + // TODO(csharrison) Investigate how big a problem the cross process + // monotonicity really is and on what platforms. Log UMA for: + // |renderer_navigation_start - browser_navigation_start| + return navigation_start; } // PlzNavigate @@ -2605,13 +2605,7 @@ // The rest of RenderView assumes that a WebDataSource will always have a // non-null NavigationState. - if (content_initiated) { - document_state->set_navigation_state( - NavigationStateImpl::CreateContentInitiated()); - } else { - document_state->set_navigation_state(CreateNavigationStateFromPending()); - pending_navigation_params_.reset(); - } + UpdateNavigationState(document_state); // DocumentState::referred_by_prefetcher_ is true if we are // navigating from a page that used prefetching using a link on that @@ -2661,6 +2655,17 @@ } } + NavigationStateImpl* navigation_state = static_cast<NavigationStateImpl*>( + document_state->navigation_state()); + + // Set the navigation start time in blink. + base::TimeTicks navigation_start = + navigation_state->common_params().navigation_start; + datasource->setNavigationStartTime( + (navigation_start - base::TimeTicks()).InSecondsF()); + // TODO(clamy) We need to provide additional timing values for the Navigation + // Timing API to work with browser-side navigations. + // Create the serviceworker's per-document network observing object if it // does not exist (When navigation happens within a page, the provider already // exists). @@ -2668,9 +2673,6 @@ DocumentState::FromDataSource(datasource))) return; - NavigationStateImpl* navigation_state = static_cast<NavigationStateImpl*>( - DocumentState::FromDataSource(datasource)->navigation_state()); - ServiceWorkerNetworkProvider::AttachToDocumentState( DocumentState::FromDataSource(datasource), ServiceWorkerNetworkProvider::CreateForNavigation( @@ -3155,11 +3157,10 @@ // ExtraData will get the new NavigationState. Similarly, if we did not // initiate this navigation, then we need to take care to reset any pre- // existing navigation state to a content-initiated navigation state. - // didCreateDataSource conveniently takes care of this for us. - didCreateDataSource(frame, frame->dataSource()); - + // UpdateNavigationState conveniently takes care of this for us. DocumentState* document_state = DocumentState::FromDataSource(frame->dataSource()); + UpdateNavigationState(document_state); static_cast<NavigationStateImpl*>(document_state->navigation_state()) ->set_was_within_same_page(true); @@ -4657,6 +4658,9 @@ bool browser_side_navigation = base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableBrowserSideNavigation); + + // Lower bound for browser initiated navigation start time. + base::TimeTicks renderer_navigation_start = base::TimeTicks::Now(); bool is_reload = IsReload(common_params.navigation_type); bool is_history_navigation = request_params.page_state.IsValid(); WebURLRequest::CachePolicy cache_policy = @@ -4687,6 +4691,14 @@ pending_navigation_params_.reset( new NavigationParams(common_params, start_params, request_params)); + // Unless the load is a WebFrameLoadType::Standard, this should remain + // uninitialized. It will be updated when the load type is determined to be + // Standard, or after the previous document's unload handler has been + // triggered. This occurs in UpdateNavigationState. + // TODO(csharrison) See if we can always use the browser timestamp. + pending_navigation_params_->common_params.navigation_start = + base::TimeTicks(); + // Create parameters for a standard navigation. blink::WebFrameLoadType load_type = blink::WebFrameLoadType::Standard; bool should_load_request = false; @@ -4811,10 +4823,10 @@ } if (should_load_request) { - // Record this before starting the load. We need a lower bound of this - // time to sanitize the navigationStart override set below. - base::TimeTicks renderer_navigation_start = base::TimeTicks::Now(); - + // Sanitize navigation start now that we know the load_type. + pending_navigation_params_->common_params.navigation_start = + SanitizeNavigationTiming(load_type, common_params.navigation_start, + renderer_navigation_start); // Perform a navigation to a data url if needed. if (!common_params.base_url_for_data_url.is_empty() || (browser_side_navigation && @@ -4825,12 +4837,6 @@ frame_->toWebLocalFrame()->load(request, load_type, item_for_history_navigation); } - - if (load_type == blink::WebFrameLoadType::Standard) { - UpdateFrameNavigationTiming(frame_, - common_params.navigation_start, - renderer_navigation_start); - } } // In case LoadRequest failed before didCreateDataSource was called. @@ -5200,6 +5206,22 @@ return NavigationStateImpl::CreateContentInitiated(); } +void RenderFrameImpl::UpdateNavigationState(DocumentState* document_state) { + if (pending_navigation_params_) { + // If this is a browser-initiated load that doesn't override + // navigation_start, set it here. + if (pending_navigation_params_->common_params.navigation_start.is_null()) { + pending_navigation_params_->common_params.navigation_start = + base::TimeTicks::Now(); + } + document_state->set_navigation_state(CreateNavigationStateFromPending()); + pending_navigation_params_.reset(); + } else { + document_state->set_navigation_state( + NavigationStateImpl::CreateContentInitiated()); + } +} + #if defined(OS_ANDROID) WebMediaPlayer* RenderFrameImpl::CreateAndroidWebMediaPlayer( WebMediaPlayerClient* client,
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 7474362..e29cc90 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -870,6 +870,10 @@ // saved in OnNavigate(). NavigationState* CreateNavigationStateFromPending(); + // Sets the NavigationState on the DocumentState based on + // the value of |pending_navigation_params_|. + void UpdateNavigationState(DocumentState* document_state); + #if defined(OS_ANDROID) blink::WebMediaPlayer* CreateAndroidWebMediaPlayer( blink::WebMediaPlayerClient* client,
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index a87d8fe..804e018 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -455,6 +455,8 @@ custom_histograms_.insert("V8.MemoryExternalFragmentationTotal"); custom_histograms_.insert("V8.MemoryHeapSampleTotalCommitted"); custom_histograms_.insert("V8.MemoryHeapSampleTotalUsed"); + custom_histograms_.insert("V8.MemoryHeapUsed"); + custom_histograms_.insert("V8.MemoryHeapCommitted"); } RenderThreadImpl::HistogramCustomizer::~HistogramCustomizer() {} @@ -1422,7 +1424,7 @@ base::StringToUint(image_texture_target_string, &image_texture_target); DCHECK(parsed_image_texture_target); gpu_factories_ = RendererGpuVideoAcceleratorFactories::Create( - gpu_channel_host.get(), main_thread_compositor_task_runner_, + gpu_channel_host.get(), base::ThreadTaskRunnerHandle::Get(), media_task_runner, shared_context_provider, enable_gpu_memory_buffer_video_frames, image_texture_target, enable_video_accelerator);
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index 3f1250f1..3783e905 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -2257,30 +2257,10 @@ // Don't disable here to test that emulation is being shutdown properly. } -// Sanity checks for the Navigation Timing API |navigationStart| override. We +// Sanity check for the Navigation Timing API |navigationStart| override. We // are asserting only most basic constraints, as TimeTicks (passed as the // override) are not comparable with the wall time (returned by the Blink API). TEST_F(RenderViewImplTest, NavigationStartOverride) { - // Verify that a navigation that claims to have started at the earliest - // possible TimeTicks is indeed reported as one that started before - // OnNavigate() is called. - base::Time before_navigation = base::Time::Now(); - CommonNavigationParams early_common_params; - StartNavigationParams early_start_params; - early_common_params.url = GURL("data:text/html,<div>Page</div>"); - early_common_params.navigation_type = FrameMsg_Navigate_Type::NORMAL; - early_common_params.transition = ui::PAGE_TRANSITION_TYPED; - early_common_params.navigation_start = base::TimeTicks::FromInternalValue(1); - early_start_params.is_post = true; - - frame()->Navigate(early_common_params, early_start_params, - RequestNavigationParams()); - ProcessPendingMessages(); - - base::Time early_nav_reported_start = - base::Time::FromDoubleT(GetMainFrame()->performance().navigationStart()); - EXPECT_LT(early_nav_reported_start, before_navigation); - // Verify that a navigation that claims to have started in the future - 42 // days from now is *not* reported as one that starts in the future; as we // sanitize the override allowing a maximum of ::Now().
diff --git a/third_party/WebKit/LayoutTests/http/tests/preload/avoid_delaying_onload_link_preload.html b/third_party/WebKit/LayoutTests/http/tests/preload/avoid_delaying_onload_link_preload.html new file mode 100644 index 0000000..86a7d86 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/preload/avoid_delaying_onload_link_preload.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script> + var t = async_test('Makes sure link preload preloaded resources are not delaying onload'); +</script> +<link rel=preload href="../resources/slow-script.pl?delay=200" as=script> +<script> + window.addEventListener("load", t.step_func(function() { + assert_equals(performance.getEntriesByType("resource").length, 2); + t.done(); + })); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/preload/delaying_onload_link_preload_after_discovery.html b/third_party/WebKit/LayoutTests/http/tests/preload/delaying_onload_link_preload_after_discovery.html new file mode 100644 index 0000000..dcb1d83 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/preload/delaying_onload_link_preload_after_discovery.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script> + var t = async_test('Makes sure link preload preloaded resources are delaying onload after discovery'); +</script> +<link rel=preload href="http://127.0.0.1:8000/resources/slow-script.pl?delay=200" as=script> +<link rel=preload href="http://127.0.0.1:8000/resources/slow-image.php?name=square.png&mimeType=image/png&sleep=400" as=image> +<script> + window.addEventListener("load", t.step_func(function() { + assert_equals(performance.getEntriesByType("resource").length, 4); + t.done(); + })); + document.write('<sc' + 'ript src="../resources/slow-script.pl?delay=200"></sc' + 'ript>'); + document.write("<!--"); + var img = new Image(); + img.src = "http://127.0.0.1:8000/resources/slow-image.php?name=square.png&mimeType=image/png&sleep=400"; +</script> +
diff --git a/third_party/WebKit/LayoutTests/http/tests/preload/delaying_onload_preloader_after_discovery.html b/third_party/WebKit/LayoutTests/http/tests/preload/delaying_onload_preloader_after_discovery.html new file mode 100644 index 0000000..cac245b --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/preload/delaying_onload_preloader_after_discovery.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script> + var t = async_test('Makes sure that preloader preloaded resources are delaying onload after they are discovered'); +</script> +<script src="../resources/slow-script.pl?delay=200"></script> +<script> + window.addEventListener("load", t.step_func(function() { + assert_equals(performance.getEntriesByType("resource").length, 4); + t.done(); + })); +</script> +<script> + document.write("<!--"); + var img = new Image(); + img.src = "http://127.0.0.1:8000/resources/slow-image.php?name=square.png&mimeType=image/png&sleep=400"; +</script> +<img src="http://127.0.0.1:8000/resources/slow-image.php?name=square.png&mimeType=image/png&sleep=400">
diff --git a/third_party/WebKit/Source/core/fetch/FetchRequest.cpp b/third_party/WebKit/Source/core/fetch/FetchRequest.cpp index 417fccd..f620a4d 100644 --- a/third_party/WebKit/Source/core/fetch/FetchRequest.cpp +++ b/third_party/WebKit/Source/core/fetch/FetchRequest.cpp
@@ -37,6 +37,7 @@ , m_options(ResourceFetcher::defaultResourceOptions()) , m_priority(priority) , m_forPreload(false) + , m_avoidBlockingOnLoad(false) , m_defer(NoDefer) , m_originRestriction(UseDefaultOriginRestrictionForType) { @@ -48,6 +49,7 @@ , m_options(options) , m_priority(ResourceLoadPriorityUnresolved) , m_forPreload(false) + , m_avoidBlockingOnLoad(false) , m_defer(NoDefer) , m_originRestriction(UseDefaultOriginRestrictionForType) { @@ -59,6 +61,7 @@ , m_options(ResourceFetcher::defaultResourceOptions()) , m_priority(ResourceLoadPriorityUnresolved) , m_forPreload(false) + , m_avoidBlockingOnLoad(false) , m_defer(NoDefer) , m_originRestriction(UseDefaultOriginRestrictionForType) {
diff --git a/third_party/WebKit/Source/core/fetch/FetchRequest.h b/third_party/WebKit/Source/core/fetch/FetchRequest.h index b476fbf..9e864fad 100644 --- a/third_party/WebKit/Source/core/fetch/FetchRequest.h +++ b/third_party/WebKit/Source/core/fetch/FetchRequest.h
@@ -86,6 +86,9 @@ bool forPreload() const { return m_forPreload; } void setForPreload(bool forPreload) { m_forPreload = forPreload; } + bool avoidBlockingOnLoad() { return m_avoidBlockingOnLoad; } + void setAvoidBlockingOnLoad(bool doNotBlock) { m_avoidBlockingOnLoad = doNotBlock; } + void setContentSecurityCheck(ContentSecurityPolicyDisposition contentSecurityPolicyOption) { m_options.contentSecurityPolicyOption = contentSecurityPolicyOption; } void setCrossOriginAccessControl(SecurityOrigin*, StoredCredentials, CredentialRequest); void setCrossOriginAccessControl(SecurityOrigin*, StoredCredentials); @@ -101,6 +104,7 @@ ResourceLoaderOptions m_options; ResourceLoadPriority m_priority; bool m_forPreload; + bool m_avoidBlockingOnLoad; DeferOption m_defer; OriginRestriction m_originRestriction; ResourceWidth m_resourceWidth;
diff --git a/third_party/WebKit/Source/core/fetch/Resource.cpp b/third_party/WebKit/Source/core/fetch/Resource.cpp index de290b6..15fbaa8d 100644 --- a/third_party/WebKit/Source/core/fetch/Resource.cpp +++ b/third_party/WebKit/Source/core/fetch/Resource.cpp
@@ -163,6 +163,7 @@ , m_status(Pending) , m_wasPurged(false) , m_needsSynchronousCacheHit(false) + , m_avoidBlockingOnLoad(false) #ifdef ENABLE_RESOURCE_IS_DELETED_CHECK , m_deleted(false) #endif @@ -1022,6 +1023,20 @@ return initatorTypeNameToString(initiatorInfo.name); } +bool Resource::shouldBlockLoadEvent() const +{ + return !m_avoidBlockingOnLoad && isNonBlockingResourceType(); +} + +bool Resource::isNonBlockingResourceType() const +{ + return type() != LinkPrefetch + && type() != LinkSubresource + && type() != Media + && type() != Raw + && type() != TextTrack; +} + #if !LOG_DISABLED const char* ResourceTypeName(Resource::Type type) {
diff --git a/third_party/WebKit/Source/core/fetch/Resource.h b/third_party/WebKit/Source/core/fetch/Resource.h index 589bb3a..9af0d10 100644 --- a/third_party/WebKit/Source/core/fetch/Resource.h +++ b/third_party/WebKit/Source/core/fetch/Resource.h
@@ -113,6 +113,9 @@ void setNeedsSynchronousCacheHit(bool needsSynchronousCacheHit) { m_needsSynchronousCacheHit = needsSynchronousCacheHit; } + void setAvoidBlockingOnLoad(bool doNotBlock) { m_avoidBlockingOnLoad = doNotBlock; } + bool avoidBlockingOnLoad() { return m_avoidBlockingOnLoad; } + void setResourceError(const ResourceError& error) { m_error = error; } const ResourceError& resourceError() const { return m_error; } @@ -171,14 +174,8 @@ ResourceLoader* loader() const { return m_loader.get(); } virtual bool isImage() const { return false; } - bool shouldBlockLoadEvent() const - { - return type() != LinkPrefetch - && type() != LinkSubresource - && type() != Media - && type() != Raw - && type() != TextTrack; - } + bool shouldBlockLoadEvent() const; + bool isNonBlockingResourceType() const; // Computes the status of an object after loading. // Updates the expire date on the cache entry file @@ -410,6 +407,7 @@ unsigned m_wasPurged : 1; unsigned m_needsSynchronousCacheHit : 1; + unsigned m_avoidBlockingOnLoad : 1; #ifdef ENABLE_RESOURCE_IS_DELETED_CHECK bool m_deleted;
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp index d52c3ef..9066f81 100644 --- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp +++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
@@ -323,6 +323,18 @@ scheduleDocumentResourcesGC(); } +void ResourceFetcher::moveCachedNonBlockingResourceToBlocking(Resource* resource) +{ + // TODO(yoav): Test that non-blocking resources (video/audio/track) continue to not-block even after being preloaded and discovered. + if (resource && resource->loader() && resource->isNonBlockingResourceType() && resource->avoidBlockingOnLoad()) { + if (m_nonBlockingLoaders) + m_nonBlockingLoaders->remove(resource->loader()); + if (!m_loaders) + m_loaders = ResourceLoaderSet::create(); + m_loaders->add(resource->loader()); + } +} + ResourcePtr<Resource> ResourceFetcher::requestResource(FetchRequest& request, const ResourceFactory& factory, const SubstituteData& substituteData) { ASSERT(request.options().synchronousPolicy == RequestAsynchronously || factory.type() == Resource::Raw || factory.type() == Resource::XSLStyleSheet); @@ -364,8 +376,9 @@ } } - // See if we can use an existing resource from the cache. + // See if we can use an existing resource from the cache. If so, we need to move it to be load blocking. ResourcePtr<Resource> resource = memoryCache()->resourceForURL(url, getCacheIdentifier()); + moveCachedNonBlockingResourceToBlocking(resource.get()); const RevalidationPolicy policy = determineRevalidationPolicy(factory.type(), request, resource.get(), isStaticData); switch (policy) { @@ -519,6 +532,7 @@ initializeResourceRequest(request.mutableResourceRequest(), factory.type()); ResourcePtr<Resource> resource = factory.create(request.resourceRequest(), charset); + resource->setAvoidBlockingOnLoad(request.avoidBlockingOnLoad()); resource->setCacheIdentifier(cacheIdentifier); memoryCache()->add(resource.get());
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h index 893c17f..f74b5eb 100644 --- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h +++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
@@ -167,6 +167,8 @@ enum RevalidationPolicy { Use, Revalidate, Reload, Load }; RevalidationPolicy determineRevalidationPolicy(Resource::Type, const FetchRequest&, Resource* existingResource, bool isStaticData) const; + void moveCachedNonBlockingResourceToBlocking(Resource*); + void initializeResourceRequest(ResourceRequest&, Resource::Type); static bool resourceNeedsLoad(Resource*, const FetchRequest&, RevalidationPolicy);
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoadTiming.cpp b/third_party/WebKit/Source/core/loader/DocumentLoadTiming.cpp index 33f8535..0113356 100644 --- a/third_party/WebKit/Source/core/loader/DocumentLoadTiming.cpp +++ b/third_party/WebKit/Source/core/loader/DocumentLoadTiming.cpp
@@ -87,6 +87,12 @@ void DocumentLoadTiming::markNavigationStart() { + // Allow the embedder to override navigationStart before we record it if + // they have a more accurate timestamp. + if (m_navigationStart) { + ASSERT(m_referenceMonotonicTime && m_referenceWallTime); + return; + } TRACE_EVENT_MARK("blink.user_timing", "navigationStart"); ASSERT(!m_navigationStart && !m_referenceMonotonicTime && !m_referenceWallTime); @@ -98,14 +104,16 @@ void DocumentLoadTiming::setNavigationStart(double navigationStart) { TRACE_EVENT_MARK_WITH_TIMESTAMP("blink.user_timing", "navigationStart", navigationStart); - ASSERT(m_referenceMonotonicTime && m_referenceWallTime); m_navigationStart = navigationStart; // |m_referenceMonotonicTime| and |m_referenceWallTime| represent // navigationStart. When the embedder sets navigationStart (because the // navigation started earlied on the browser side), we need to adjust these // as well. - m_referenceWallTime = monotonicTimeToPseudoWallTime(navigationStart); + if (!m_referenceWallTime) + m_referenceWallTime = currentTime(); + else + m_referenceWallTime = monotonicTimeToPseudoWallTime(navigationStart); m_referenceMonotonicTime = navigationStart; notifyDocumentTimingChanged(); }
diff --git a/third_party/WebKit/Source/core/loader/LinkLoader.cpp b/third_party/WebKit/Source/core/loader/LinkLoader.cpp index a2a2329c..6de4b8e 100644 --- a/third_party/WebKit/Source/core/loader/LinkLoader.cpp +++ b/third_party/WebKit/Source/core/loader/LinkLoader.cpp
@@ -205,6 +205,8 @@ Settings* settings = document.settings(); if (settings && settings->logPreload()) document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, DebugMessageLevel, String("Preload triggered for " + href.host() + href.path()))); + linkRequest.setForPreload(true); + linkRequest.setAvoidBlockingOnLoad(true); document.loader()->startPreload(type, linkRequest); } }
diff --git a/third_party/libvpx_new/README.chromium b/third_party/libvpx_new/README.chromium index a4941116..70b04b59 100644 --- a/third_party/libvpx_new/README.chromium +++ b/third_party/libvpx_new/README.chromium
@@ -5,9 +5,9 @@ License File: source/libvpx/LICENSE Security Critical: yes -Date: Wednesday November 4 2015 +Date: Friday November 6 2015 Branch: master -Commit: c6641709a707ccb98cbdf785428659e44d4f2c8b +Commit: eba14ddbe7e7b69803dab770ba25ae2ba75c65e2 Description: Contains the sources used to compile libvpx binaries used by Google Chrome and
diff --git a/third_party/libvpx_new/source/config/vpx_version.h b/third_party/libvpx_new/source/config/vpx_version.h index b5c4b1f5..7b83a66 100644 --- a/third_party/libvpx_new/source/config/vpx_version.h +++ b/third_party/libvpx_new/source/config/vpx_version.h
@@ -1,7 +1,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 4 #define VERSION_PATCH 0 -#define VERSION_EXTRA "1647-gc664170" +#define VERSION_EXTRA "1655-geba14dd" #define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH)) -#define VERSION_STRING_NOSP "v1.4.0-1647-gc664170" -#define VERSION_STRING " v1.4.0-1647-gc664170" +#define VERSION_STRING_NOSP "v1.4.0-1655-geba14dd" +#define VERSION_STRING " v1.4.0-1655-geba14dd"