diff --git a/DEPS b/DEPS index a82af38..4e7d417 100644 --- a/DEPS +++ b/DEPS
@@ -78,7 +78,7 @@ # 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': 'ba9cf60e14c870dae107dc4c071847f6ea800e23', + 'v8_revision': 'ad1474a10f76712669b926fb1e53313c9921b487', # 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.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEngineAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEngineAdapter.java index 03bb959..31c2626 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEngineAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEngineAdapter.java
@@ -424,8 +424,6 @@ String url = TemplateUrlService.getInstance().getSearchEngineUrlFromTemplateUrl( toKeyword(mSelectedSearchEnginePosition)); Bundle fragmentArgs = SingleWebsitePreferences.createFragmentArgsForSite(url); - fragmentArgs.putBoolean(SingleWebsitePreferences.EXTRA_LOCATION, - locationEnabled((TemplateUrl) getItem(mSelectedSearchEnginePosition))); settingsIntent.putExtra(Preferences.EXTRA_SHOW_FRAGMENT_ARGUMENTS, fragmentArgs); mContext.startActivity(settingsIntent); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java index fb99774d..a01eab7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java
@@ -48,12 +48,9 @@ // EXTRA_ORIGIN (a WebsiteAddress) to be present (but not both). If // EXTRA_SITE is present, the fragment will display the permissions in that // Website object. If EXTRA_ORIGIN is present, the fragment will find all - // permissions for that website address and display those. If EXTRA_LOCATION - // is present, the fragment will add a Location toggle, even if the site - // specifies no Location permission. + // permissions for that website address and display those. public static final String EXTRA_SITE = "org.chromium.chrome.preferences.site"; public static final String EXTRA_ORIGIN = "org.chromium.chrome.preferences.origin"; - public static final String EXTRA_LOCATION = "org.chromium.chrome.preferences.location"; public static final String EXTRA_WEB_CONTENTS = "org.chromium.chrome.preferences.web_contents"; public static final String EXTRA_USB_INFO = "org.chromium.chrome.preferences.usb_info"; @@ -620,17 +617,11 @@ private void setUpLocationPreference(Preference preference) { ContentSetting permission = mSite.getGeolocationPermission(); - Object locationAllowed = getArguments().getSerializable(EXTRA_LOCATION); if (shouldUseDSEGeolocationSetting()) { String origin = mSite.getAddress().getOrigin(); mSite.setGeolocationInfo(new GeolocationInfo(origin, origin, false)); setUpListPreference(preference, ContentSetting.ALLOW); updateLocationPreferenceForDSESetting(preference); - } else if (permission == null && locationAllowed != null) { - String origin = mSite.getAddress().getOrigin(); - mSite.setGeolocationInfo(new GeolocationInfo(origin, origin, false)); - setUpListPreference(preference, (boolean) locationAllowed - ? ContentSetting.ALLOW : ContentSetting.BLOCK); } else { setUpListPreference(preference, permission); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index ccacf483..080164c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -332,6 +332,12 @@ } @Override + public void onShown(Tab tab) { + if (TextUtils.isEmpty(tab.getUrl())) return; + mControlContainer.setReadyForBitmapCapture(true); + } + + @Override public void onCrash(Tab tab, boolean sadTabShown) { updateTabLoadingState(false); updateButtonStatus();
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.js b/chrome/browser/resources/gaia_auth_host/authenticator.js index 4d1bc38..a5e1d1a 100644 --- a/chrome/browser/resources/gaia_auth_host/authenticator.js +++ b/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -91,6 +91,7 @@ 'menuGuestMode', // Enables "Guest mode" menu item 'menuKeyboardOptions', // Enables "Keyboard options" menu item 'menuEnterpriseEnrollment', // Enables "Enterprise enrollment" menu item. + 'lsbReleaseBoard', // Chrome OS Release board name // The email fields allow for the following possibilities: // @@ -328,6 +329,9 @@ mi += 'ee,'; if (mi.length) url = appendParam(url, 'mi', mi); + + if (data.lsbReleaseBoard) + url = appendParam(url, 'chromeos_board', data.lsbReleaseBoard); } } else { url = appendParam(url, 'continue', this.continueUrl_);
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc index 740480a..f3eba34 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -12,6 +12,7 @@ #include "base/metrics/histogram_macros.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/sys_info.h" #include "base/task_scheduler/post_task.h" #include "base/values.h" #include "chrome/browser/browser_process.h" @@ -370,6 +371,7 @@ // (see https://crbug.com/709244 ). params.SetString("chromeOSApiVersion", "2"); } + params.SetString("lsbReleaseBoard", base::SysInfo::GetLsbReleaseBoard()); frame_state_ = FRAME_STATE_LOADING; CallJS("loadAuthExtension", params);
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn index 9c5fac9..ce0b826d 100644 --- a/chrome/browser/vr/BUILD.gn +++ b/chrome/browser/vr/BUILD.gn
@@ -22,7 +22,6 @@ "color_scheme.h", "content_input_delegate.cc", "content_input_delegate.h", - "controller_mesh.cc", "controller_mesh.h", "databinding/binding.h", "databinding/binding_base.cc", @@ -156,9 +155,13 @@ "web_contents_event_forwarder.h", ] - public_deps = [ - "//chrome/browser/resources:vr_shell_resources", - ] + if (enable_gvr_services) { + sources += [ "controller_mesh.cc" ] + + public_deps = [ + "//chrome/browser/resources:vr_shell_resources", + ] + } deps = [ "//base", @@ -286,6 +289,12 @@ "test/vr_common_test_suite.h", ] + if (!enable_gvr_services) { + # For testing, we add back controller_mesh.cc on platforms where it isn't + # included by vr_common. + sources += [ "controller_mesh.cc" ] + } + public_deps = [ ":vr_common", ":vr_test_pak",
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni index 4ff9231..10ab601 100644 --- a/chrome/chrome_paks.gni +++ b/chrome/chrome_paks.gni
@@ -172,7 +172,7 @@ sources += [ "$root_gen_dir/chrome/print_preview_resources.pak" ] deps += [ "//chrome/browser/resources:print_preview_resources" ] } - if (enable_vr) { + if (enable_gvr_services) { sources += [ "$root_gen_dir/chrome/vr_shell_resources.pak" ] deps += [ "//chrome/browser/resources:vr_shell_resources" ] }
diff --git a/components/offline_pages/core/model/offline_page_model_taskified.cc b/components/offline_pages/core/model/offline_page_model_taskified.cc index 698d76c9..a4ad6c5 100644 --- a/components/offline_pages/core/model/offline_page_model_taskified.cc +++ b/components/offline_pages/core/model/offline_page_model_taskified.cc
@@ -17,6 +17,7 @@ #include "components/offline_pages/core/model/add_page_task.h" #include "components/offline_pages/core/model/create_archive_task.h" #include "components/offline_pages/core/model/delete_page_task.h" +#include "components/offline_pages/core/model/get_pages_task.h" #include "components/offline_pages/core/model/mark_page_accessed_task.h" #include "components/offline_pages/core/offline_page_metadata_store.h" #include "components/offline_pages/core/offline_page_metadata_store_sql.h" @@ -36,6 +37,14 @@ // one. const base::TimeDelta kClearStorageInterval = base::TimeDelta::FromMinutes(30); +void WrapInMultipleItemsCallback(const MultipleOfflineIdCallback& callback, + const MultipleOfflinePageItemResult& pages) { + std::vector<int64_t> results; + for (const auto& page : pages) + results.push_back(page.offline_id); + callback.Run(results); +} + SavePageResult ArchiverResultToSavePageResult(ArchiverResult archiver_result) { switch (archiver_result) { case ArchiverResult::SUCCESSFULLY_CREATED: @@ -146,38 +155,76 @@ const DeletePageCallback& callback) {} void OfflinePageModelTaskified::GetAllPages( - const MultipleOfflinePageItemCallback& callback) {} + const MultipleOfflinePageItemCallback& callback) { + auto task = GetPagesTask::CreateTaskMatchingAllPages(store_.get(), callback); + task_queue_.AddTask(std::move(task)); +} void OfflinePageModelTaskified::GetPageByOfflineId( int64_t offline_id, - const SingleOfflinePageItemCallback& callback) {} + const SingleOfflinePageItemCallback& callback) { + auto task = GetPagesTask::CreateTaskMatchingOfflineId(store_.get(), callback, + offline_id); + task_queue_.AddTask(std::move(task)); +} void OfflinePageModelTaskified::GetPagesByClientIds( const std::vector<ClientId>& client_ids, - const MultipleOfflinePageItemCallback& callback) {} + const MultipleOfflinePageItemCallback& callback) { + auto task = GetPagesTask::CreateTaskMatchingClientIds(store_.get(), callback, + client_ids); + task_queue_.AddTask(std::move(task)); +} void OfflinePageModelTaskified::GetPagesByURL( const GURL& url, URLSearchMode url_search_mode, - const MultipleOfflinePageItemCallback& callback) {} + const MultipleOfflinePageItemCallback& callback) { + auto task = GetPagesTask::CreateTaskMatchingUrl(store_.get(), callback, url); + task_queue_.AddTask(std::move(task)); +} void OfflinePageModelTaskified::GetPagesByNamespace( const std::string& name_space, - const MultipleOfflinePageItemCallback& callback) {} + const MultipleOfflinePageItemCallback& callback) { + auto task = GetPagesTask::CreateTaskMatchingNamespace(store_.get(), callback, + name_space); + task_queue_.AddTask(std::move(task)); +} void OfflinePageModelTaskified::GetPagesRemovedOnCacheReset( - const MultipleOfflinePageItemCallback& callback) {} + const MultipleOfflinePageItemCallback& callback) { + auto task = GetPagesTask::CreateTaskMatchingPagesRemovedOnCacheReset( + store_.get(), callback, policy_controller_.get()); + task_queue_.AddTask(std::move(task)); +} void OfflinePageModelTaskified::GetPagesSupportedByDownloads( - const MultipleOfflinePageItemCallback& callback) {} + const MultipleOfflinePageItemCallback& callback) { + auto task = GetPagesTask::CreateTaskMatchingPagesSupportedByDownloads( + store_.get(), callback, policy_controller_.get()); + task_queue_.AddTask(std::move(task)); +} void OfflinePageModelTaskified::GetPagesByRequestOrigin( const std::string& request_origin, - const MultipleOfflinePageItemCallback& callback) {} + const MultipleOfflinePageItemCallback& callback) { + auto task = GetPagesTask::CreateTaskMatchingRequestOrigin( + store_.get(), callback, request_origin); + task_queue_.AddTask(std::move(task)); +} void OfflinePageModelTaskified::GetOfflineIdsForClientId( const ClientId& client_id, - const MultipleOfflineIdCallback& callback) {} + const MultipleOfflineIdCallback& callback) { + // We're currently getting offline IDs by querying offline items based on + // client ids, and then extract the offline IDs from the items. This is fine + // since we're not expecting many pages with the same client ID. + auto task = GetPagesTask::CreateTaskMatchingClientIds( + store_.get(), base::Bind(&WrapInMultipleItemsCallback, callback), + {client_id}); + task_queue_.AddTask(std::move(task)); +} const base::FilePath& OfflinePageModelTaskified::GetArchiveDirectory( const std::string& name_space) const {
diff --git a/components/offline_pages/core/model/offline_page_model_taskified.h b/components/offline_pages/core/model/offline_page_model_taskified.h index 42cb3f4..747070b4 100644 --- a/components/offline_pages/core/model/offline_page_model_taskified.h +++ b/components/offline_pages/core/model/offline_page_model_taskified.h
@@ -90,8 +90,10 @@ void GetPagesByNamespace( const std::string& name_space, const MultipleOfflinePageItemCallback& callback) override; + // Get all pages in the namespaces that will be removed on cache reset. void GetPagesRemovedOnCacheReset( const MultipleOfflinePageItemCallback& callback) override; + // Get all pages in the namespaces that are shown in download ui. void GetPagesSupportedByDownloads( const MultipleOfflinePageItemCallback& callback) override; void GetPagesByRequestOrigin(
diff --git a/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc b/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc index 5d4cd4ec..9cc90c8 100644 --- a/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc +++ b/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc
@@ -31,8 +31,12 @@ using testing::_; using testing::A; using testing::An; +using testing::ElementsAre; using testing::Eq; +using testing::IsEmpty; +using testing::Pointee; using testing::SaveArg; +using testing::UnorderedElementsAre; namespace offline_pages { @@ -41,6 +45,9 @@ namespace { const GURL kTestUrl("http://example.com"); const GURL kTestUrl2("http://other.page.com"); +const GURL kTestUrlWithFragment("http://example.com#frag"); +const GURL kTestUrl2WithFragment("http://other.page.com#frag"); +const GURL kRandomUrl("http://foo"); const GURL kFileUrl("file:///foo"); const ClientId kTestClientId1(kDefaultNamespace, "1234"); const ClientId kTestClientId2(kDefaultNamespace, "5678"); @@ -118,8 +125,8 @@ OfflinePageMetadataStoreTestUtil* store_test_util() { return &store_test_util_; } - OfflinePageItemGenerator* generator() { return &generator_; } - TaskQueue* model_task_queue() { return &model_->task_queue_; } + OfflinePageItemGenerator* page_generator() { return &generator_; } + TaskQueue* task_queue() { return &model_->task_queue_; } const base::FilePath& temporary_dir_path() { return temporary_dir_.GetPath(); } @@ -127,7 +134,9 @@ return persistent_dir_.GetPath(); } - const base::FilePath& last_archiver_path() { return last_archiver_path_; } + const base::FilePath& last_path_created_by_archiver() { + return last_path_created_by_archiver_; + } bool observer_add_page_called() { return observer_add_page_called_; } const OfflinePageItem& last_added_page() { return last_added_page_; } bool observer_delete_page_called() { return observer_delete_page_called_; } @@ -141,7 +150,7 @@ base::ScopedTempDir temporary_dir_; base::ScopedTempDir persistent_dir_; - base::FilePath last_archiver_path_; + base::FilePath last_path_created_by_archiver_; bool observer_add_page_called_; OfflinePageItem last_added_page_; bool observer_delete_page_called_; @@ -190,7 +199,7 @@ } void OfflinePageModelTaskifiedTest::ResetResults() { - last_archiver_path_.clear(); + last_path_created_by_archiver_.clear(); observer_add_page_called_ = false; observer_delete_page_called_ = false; } @@ -213,7 +222,7 @@ void OfflinePageModelTaskifiedTest::SetLastPathCreatedByArchiver( const base::FilePath& file_path) { - last_archiver_path_ = file_path; + last_path_created_by_archiver_ = file_path; } void OfflinePageModelTaskifiedTest::SavePageWithCallback( @@ -266,8 +275,8 @@ } void OfflinePageModelTaskifiedTest::CheckTaskQueueIdle() { - EXPECT_FALSE(model_task_queue()->HasPendingTasks()); - EXPECT_FALSE(model_task_queue()->HasRunningTask()); + EXPECT_FALSE(task_queue()->HasPendingTasks()); + EXPECT_FALSE(task_queue()->HasRunningTask()); } TEST_F(OfflinePageModelTaskifiedTest, SavePageSuccessful) { @@ -284,7 +293,7 @@ EXPECT_EQ(kTestUrl, saved_page_ptr->url); EXPECT_EQ(kTestClientId1.id, saved_page_ptr->client_id.id); EXPECT_EQ(kTestClientId1.name_space, saved_page_ptr->client_id.name_space); - EXPECT_EQ(last_archiver_path(), saved_page_ptr->file_path); + EXPECT_EQ(last_path_created_by_archiver(), saved_page_ptr->file_path); EXPECT_EQ(kTestFileSize, saved_page_ptr->file_size); EXPECT_EQ(0, saved_page_ptr->access_count); EXPECT_EQ(0, saved_page_ptr->flags); @@ -325,7 +334,7 @@ EXPECT_EQ(kTestUrl, saved_page_ptr->url); EXPECT_EQ(kTestClientId1.id, saved_page_ptr->client_id.id); EXPECT_EQ(kTestClientId1.name_space, saved_page_ptr->client_id.name_space); - EXPECT_EQ(last_archiver_path(), saved_page_ptr->file_path); + EXPECT_EQ(last_path_created_by_archiver(), saved_page_ptr->file_path); EXPECT_EQ(kTestFileSize, saved_page_ptr->file_size); EXPECT_EQ(0, saved_page_ptr->access_count); EXPECT_EQ(0, saved_page_ptr->flags); @@ -416,7 +425,7 @@ EXPECT_EQ(1LL, GetFileCountInDir(temporary_dir_path())); EXPECT_EQ(1LL, store_test_util()->GetPageCount()); - base::FilePath saved_file_path1 = last_archiver_path(); + base::FilePath saved_file_path1 = last_path_created_by_archiver(); ResetResults(); @@ -427,7 +436,7 @@ // Check that offline_id1 refers to the second save page request. EXPECT_EQ(2LL, GetFileCountInDir(temporary_dir_path())); EXPECT_EQ(2LL, store_test_util()->GetPageCount()); - base::FilePath saved_file_path2 = last_archiver_path(); + base::FilePath saved_file_path2 = last_path_created_by_archiver(); auto saved_page_ptr1 = store_test_util()->GetPageByOfflineId(offline_id1); auto saved_page_ptr2 = store_test_util()->GetPageByOfflineId(offline_id2); @@ -448,14 +457,14 @@ TEST_F(OfflinePageModelTaskifiedTest, AddPage) { // Creates a fresh page. - generator()->SetArchiveDirectory(temporary_dir_path()); - OfflinePageItem page = generator()->CreateItemWithTempFile(); + page_generator()->SetArchiveDirectory(temporary_dir_path()); + OfflinePageItem page = page_generator()->CreateItemWithTempFile(); base::MockCallback<AddPageCallback> callback; EXPECT_CALL(callback, Run(An<AddPageResult>(), Eq(page.offline_id))); model()->AddPage(page, callback.Get()); - EXPECT_TRUE(model_task_queue()->HasRunningTask()); + EXPECT_TRUE(task_queue()->HasRunningTask()); PumpLoop(); EXPECT_TRUE(observer_add_page_called()); @@ -463,11 +472,11 @@ } TEST_F(OfflinePageModelTaskifiedTest, MarkPageAccessed) { - OfflinePageItem page = generator()->CreateItem(); + OfflinePageItem page = page_generator()->CreateItem(); InsertPageIntoStore(page); model()->MarkPageAccessed(page.offline_id); - EXPECT_TRUE(model_task_queue()->HasRunningTask()); + EXPECT_TRUE(task_queue()->HasRunningTask()); PumpLoop(); @@ -477,6 +486,224 @@ EXPECT_EQ(1LL, accessed_page_ptr->access_count); } +TEST_F(OfflinePageModelTaskifiedTest, GetAllPagesWhenStoreEmpty) { + base::MockCallback<MultipleOfflinePageItemCallback> callback; + EXPECT_CALL(callback, Run(IsEmpty())); + + model()->GetAllPages(callback.Get()); + EXPECT_TRUE(task_queue()->HasRunningTask()); + + PumpLoop(); +} + +TEST_F(OfflinePageModelTaskifiedTest, GetPageByOfflineId) { + page_generator()->SetNamespace(kDefaultNamespace); + page_generator()->SetUrl(kTestUrl); + OfflinePageItem page = page_generator()->CreateItem(); + InsertPageIntoStore(page); + + base::MockCallback<SingleOfflinePageItemCallback> callback; + EXPECT_CALL(callback, Run(Pointee(Eq(page)))); + + model()->GetPageByOfflineId(page.offline_id, callback.Get()); + EXPECT_TRUE(task_queue()->HasRunningTask()); + + PumpLoop(); +} + +TEST_F(OfflinePageModelTaskifiedTest, GetPagesByUrl_FinalUrl) { + page_generator()->SetUrl(kTestUrl); + OfflinePageItem page1 = page_generator()->CreateItem(); + InsertPageIntoStore(page1); + page_generator()->SetUrl(kTestUrl2); + OfflinePageItem page2 = page_generator()->CreateItem(); + InsertPageIntoStore(page2); + + // Search by kTestUrl. + base::MockCallback<MultipleOfflinePageItemCallback> callback; + EXPECT_CALL(callback, Run(ElementsAre(page1))); + model()->GetPagesByURL(kTestUrl, URLSearchMode::SEARCH_BY_FINAL_URL_ONLY, + callback.Get()); + EXPECT_TRUE(task_queue()->HasRunningTask()); + PumpLoop(); + + // Search by kTestUrl2. + EXPECT_CALL(callback, Run(ElementsAre(page2))); + model()->GetPagesByURL(kTestUrl2, URLSearchMode::SEARCH_BY_FINAL_URL_ONLY, + callback.Get()); + PumpLoop(); + + // Search by random url, which should return no pages. + EXPECT_CALL(callback, Run(IsEmpty())); + model()->GetPagesByURL(kRandomUrl, URLSearchMode::SEARCH_BY_FINAL_URL_ONLY, + callback.Get()); + EXPECT_TRUE(task_queue()->HasRunningTask()); + PumpLoop(); +} + +TEST_F(OfflinePageModelTaskifiedTest, + GetPagesByUrl_FinalUrlWithFragmentStripped) { + page_generator()->SetUrl(kTestUrl); + OfflinePageItem page1 = page_generator()->CreateItem(); + InsertPageIntoStore(page1); + page_generator()->SetUrl(kTestUrl2WithFragment); + OfflinePageItem page2 = page_generator()->CreateItem(); + InsertPageIntoStore(page2); + + // Search by kTestUrlWithFragment. + base::MockCallback<MultipleOfflinePageItemCallback> callback; + EXPECT_CALL(callback, Run(ElementsAre(page1))); + model()->GetPagesByURL(kTestUrlWithFragment, + URLSearchMode::SEARCH_BY_FINAL_URL_ONLY, + callback.Get()); + EXPECT_TRUE(task_queue()->HasRunningTask()); + PumpLoop(); + + // Search by kTestUrl2. + EXPECT_CALL(callback, Run(ElementsAre(page2))); + model()->GetPagesByURL(kTestUrl2, URLSearchMode::SEARCH_BY_FINAL_URL_ONLY, + callback.Get()); + EXPECT_TRUE(task_queue()->HasRunningTask()); + PumpLoop(); + + // Search by kTestUrl2WithFragment. + EXPECT_CALL(callback, Run(ElementsAre(page2))); + model()->GetPagesByURL(kTestUrl2WithFragment, + URLSearchMode::SEARCH_BY_FINAL_URL_ONLY, + callback.Get()); + EXPECT_TRUE(task_queue()->HasRunningTask()); + PumpLoop(); +} + +TEST_F(OfflinePageModelTaskifiedTest, GetPagesByUrl_AllUrls) { + page_generator()->SetUrl(kTestUrl); + page_generator()->SetOriginalUrl(kTestUrl2); + OfflinePageItem page1 = page_generator()->CreateItem(); + InsertPageIntoStore(page1); + page_generator()->SetUrl(kTestUrl2); + page_generator()->SetOriginalUrl(GURL()); + OfflinePageItem page2 = page_generator()->CreateItem(); + InsertPageIntoStore(page2); + + base::MockCallback<MultipleOfflinePageItemCallback> callback; + EXPECT_CALL(callback, Run(UnorderedElementsAre(page1, page2))); + model()->GetPagesByURL(kTestUrl2, URLSearchMode::SEARCH_BY_ALL_URLS, + callback.Get()); + PumpLoop(); +} + +TEST_F(OfflinePageModelTaskifiedTest, GetOfflineIdsForClientId) { + page_generator()->SetNamespace(kTestClientId1.name_space); + page_generator()->SetId(kTestClientId1.id); + OfflinePageItem page1 = page_generator()->CreateItem(); + OfflinePageItem page2 = page_generator()->CreateItem(); + InsertPageIntoStore(page1); + InsertPageIntoStore(page2); + + base::MockCallback<MultipleOfflineIdCallback> callback; + EXPECT_CALL(callback, + Run(UnorderedElementsAre(page1.offline_id, page2.offline_id))); + + model()->GetOfflineIdsForClientId(kTestClientId1, callback.Get()); + EXPECT_TRUE(task_queue()->HasRunningTask()); + + PumpLoop(); +} + +TEST_F(OfflinePageModelTaskifiedTest, GetPagesByClientIds) { + page_generator()->SetNamespace(kTestClientId1.name_space); + page_generator()->SetId(kTestClientId1.id); + OfflinePageItem page1 = page_generator()->CreateItem(); + OfflinePageItem page2 = page_generator()->CreateItem(); + page_generator()->SetNamespace(kTestUserRequestedClientId.name_space); + OfflinePageItem page3 = page_generator()->CreateItem(); + InsertPageIntoStore(page1); + InsertPageIntoStore(page2); + InsertPageIntoStore(page3); + + base::MockCallback<MultipleOfflinePageItemCallback> callback; + EXPECT_CALL(callback, Run(UnorderedElementsAre(page1, page2))); + + model()->GetPagesByClientIds({kTestClientId1}, callback.Get()); + EXPECT_TRUE(task_queue()->HasRunningTask()); + + PumpLoop(); +} + +TEST_F(OfflinePageModelTaskifiedTest, GetPagesByRequestOrigin) { + page_generator()->SetRequestOrigin(kTestRequestOrigin); + OfflinePageItem page1 = page_generator()->CreateItem(); + page_generator()->SetRequestOrigin(kEmptyRequestOrigin); + OfflinePageItem page2 = page_generator()->CreateItem(); + InsertPageIntoStore(page1); + InsertPageIntoStore(page2); + + base::MockCallback<MultipleOfflinePageItemCallback> callback; + EXPECT_CALL(callback, Run(ElementsAre(page1))); + + model()->GetPagesByRequestOrigin(kTestRequestOrigin, callback.Get()); + EXPECT_TRUE(task_queue()->HasRunningTask()); + + PumpLoop(); +} + +TEST_F(OfflinePageModelTaskifiedTest, GetPagesByNamespace) { + page_generator()->SetNamespace(kDefaultNamespace); + OfflinePageItem page1 = page_generator()->CreateItem(); + OfflinePageItem page2 = page_generator()->CreateItem(); + page_generator()->SetNamespace(kDownloadNamespace); + OfflinePageItem page3 = page_generator()->CreateItem(); + InsertPageIntoStore(page1); + InsertPageIntoStore(page2); + InsertPageIntoStore(page3); + + base::MockCallback<MultipleOfflinePageItemCallback> callback; + EXPECT_CALL(callback, Run(UnorderedElementsAre(page1, page2))); + + model()->GetPagesByNamespace(kDefaultNamespace, callback.Get()); + EXPECT_TRUE(task_queue()->HasRunningTask()); + + PumpLoop(); +} + +TEST_F(OfflinePageModelTaskifiedTest, GetPagesRemovedOnCacheReset) { + page_generator()->SetNamespace(kDefaultNamespace); + OfflinePageItem page1 = page_generator()->CreateItem(); + OfflinePageItem page2 = page_generator()->CreateItem(); + InsertPageIntoStore(page1); + InsertPageIntoStore(page2); + page_generator()->SetNamespace(kDownloadNamespace); + OfflinePageItem page3 = page_generator()->CreateItem(); + InsertPageIntoStore(page3); + + base::MockCallback<MultipleOfflinePageItemCallback> callback; + EXPECT_CALL(callback, Run(UnorderedElementsAre(page1, page2))); + + model()->GetPagesRemovedOnCacheReset(callback.Get()); + EXPECT_TRUE(task_queue()->HasRunningTask()); + + PumpLoop(); +} + +TEST_F(OfflinePageModelTaskifiedTest, GetPagesSupportedByDownloads) { + page_generator()->SetNamespace(kDownloadNamespace); + OfflinePageItem page1 = page_generator()->CreateItem(); + OfflinePageItem page2 = page_generator()->CreateItem(); + InsertPageIntoStore(page1); + InsertPageIntoStore(page2); + page_generator()->SetNamespace(kDefaultNamespace); + OfflinePageItem page3 = page_generator()->CreateItem(); + InsertPageIntoStore(page3); + + base::MockCallback<MultipleOfflinePageItemCallback> callback; + EXPECT_CALL(callback, Run(UnorderedElementsAre(page1, page2))); + + model()->GetPagesSupportedByDownloads(callback.Get()); + EXPECT_TRUE(task_queue()->HasRunningTask()); + + PumpLoop(); +} + // This test is affected by https://crbug.com/725685, which only affects windows // platform. #if defined(OS_WIN) @@ -486,25 +713,17 @@ #define MAYBE_CheckPagesSavedInSeparateDirs CheckPagesSavedInSeparateDirs #endif TEST_F(OfflinePageModelTaskifiedTest, MAYBE_CheckPagesSavedInSeparateDirs) { - auto archiver = BuildArchiver(kTestUrl, ArchiverResult::SUCCESSFULLY_CREATED); - int64_t temporary_id; - int64_t persistent_id; - - base::MockCallback<SavePageCallback> callback; - EXPECT_CALL(callback, Run(Eq(SavePageResult::SUCCESS), A<int64_t>())) - .Times(2) - .WillOnce(SaveArg<1>(&temporary_id)) - .WillOnce(SaveArg<1>(&persistent_id)); - // Save a temporary page. - SavePageWithCallback(kTestUrl, kTestClientId1, GURL(), kEmptyRequestOrigin, - std::move(archiver), callback.Get()); + auto archiver = BuildArchiver(kTestUrl, ArchiverResult::SUCCESSFULLY_CREATED); + int64_t temporary_id = SavePageWithExpectedResult( + kTestUrl, kTestClientId1, GURL(), kEmptyRequestOrigin, + std::move(archiver), SavePageResult::SUCCESS); // Save a persistent page. archiver = BuildArchiver(kTestUrl2, ArchiverResult::SUCCESSFULLY_CREATED); - SavePageWithCallback(kTestUrl2, kTestUserRequestedClientId, GURL(), - kEmptyRequestOrigin, std::move(archiver), - callback.Get()); + int64_t persistent_id = SavePageWithExpectedResult( + kTestUrl2, kTestUserRequestedClientId, GURL(), kEmptyRequestOrigin, + std::move(archiver), SavePageResult::SUCCESS); std::unique_ptr<OfflinePageItem> temporary_page = store_test_util()->GetPageByOfflineId(temporary_id); @@ -528,11 +747,11 @@ TEST_F(OfflinePageModelTaskifiedTest, DISABLED_ClearCachedPagesTriggeredWhenSaveFailed) { // After a save failed, only PostClearCachedPagesTask will be triggered. - generator()->SetArchiveDirectory(temporary_dir_path()); - generator()->SetNamespace(kDefaultNamespace); - generator()->SetUrl(kTestUrl); - OfflinePageItem page1 = generator()->CreateItemWithTempFile(); - OfflinePageItem page2 = generator()->CreateItemWithTempFile(); + page_generator()->SetArchiveDirectory(temporary_dir_path()); + page_generator()->SetNamespace(kDefaultNamespace); + page_generator()->SetUrl(kTestUrl); + OfflinePageItem page1 = page_generator()->CreateItemWithTempFile(); + OfflinePageItem page2 = page_generator()->CreateItemWithTempFile(); InsertPageIntoStore(page1); InsertPageIntoStore(page2); @@ -562,11 +781,11 @@ // Add pages that have the same namespace and url directly into store, in // order to avoid triggering the removal. // The 'default' namespace has a limit of 1 per url. - generator()->SetArchiveDirectory(temporary_dir_path()); - generator()->SetNamespace(kDefaultNamespace); - generator()->SetUrl(kTestUrl); - OfflinePageItem page1 = generator()->CreateItemWithTempFile(); - OfflinePageItem page2 = generator()->CreateItemWithTempFile(); + page_generator()->SetArchiveDirectory(temporary_dir_path()); + page_generator()->SetNamespace(kDefaultNamespace); + page_generator()->SetUrl(kTestUrl); + OfflinePageItem page1 = page_generator()->CreateItemWithTempFile(); + OfflinePageItem page2 = page_generator()->CreateItemWithTempFile(); InsertPageIntoStore(page1); InsertPageIntoStore(page2); @@ -591,4 +810,16 @@ EXPECT_EQ(persistent_dir_path(), persistent_dir); } +TEST_F(OfflinePageModelTaskifiedTest, GetAllPages) { + OfflinePageItem page1 = page_generator()->CreateItem(); + OfflinePageItem page2 = page_generator()->CreateItem(); + InsertPageIntoStore(page1); + InsertPageIntoStore(page2); + + base::MockCallback<MultipleOfflinePageItemCallback> callback; + EXPECT_CALL(callback, Run(UnorderedElementsAre(page1, page2))); + model()->GetAllPages(callback.Get()); + PumpLoop(); +} + } // namespace offline_pages
diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc index c5a0216..7a4cc4c 100644 --- a/components/viz/service/display/direct_renderer.cc +++ b/components/viz/service/display/direct_renderer.cc
@@ -227,15 +227,8 @@ for (auto& pass : render_passes_in_draw_order) { auto& resource = render_pass_textures_[pass->id]; - if (!resource) { + if (!resource) resource = std::make_unique<cc::ScopedResource>(resource_provider_); - - // |has_damage_from_contributing_content| is used to determine if previous - // contents can be reused when caching render pass and as a result needs - // to be true when a new resource is created to ensure that it is updated - // and not assumed to already contain correct contents. - pass->has_damage_from_contributing_content = true; - } } } @@ -377,22 +370,6 @@ current_frame_valid_ = false; } -gfx::Rect DirectRenderer::DrawingFrame::ComputeScissorRectForRenderPass() - const { - if (current_render_pass == root_render_pass) - return root_damage_rect; - - // If the root damage rect has been expanded due to overlays, all the other - // damage rect calculations are incorrect. - if (!root_render_pass->damage_rect.Contains(root_damage_rect)) - return current_render_pass->output_rect; - - DCHECK( - current_render_pass->copy_requests.empty() || - (current_render_pass->damage_rect == current_render_pass->output_rect)); - return current_render_pass->damage_rect; -} - gfx::Rect DirectRenderer::DeviceViewportRectInDrawSpace() const { gfx::Rect device_viewport_rect(current_frame()->device_viewport_size); device_viewport_rect -= current_viewport_rect_.OffsetFromOrigin(); @@ -524,8 +501,9 @@ void DirectRenderer::DrawRenderPass(const RenderPass* render_pass) { TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass"); - if (!UseRenderPass(render_pass)) + if (CanSkipRenderPass(render_pass)) return; + UseRenderPass(render_pass); const gfx::Rect surface_rect_in_draw_space = OutputSurfaceRectInDrawSpace(); gfx::Rect render_pass_scissor_in_draw_space = surface_rect_in_draw_space; @@ -538,7 +516,7 @@ if (use_partial_swap_) { render_pass_scissor_in_draw_space.Intersect( - current_frame()->ComputeScissorRectForRenderPass()); + ComputeScissorRectForRenderPass(current_frame()->current_render_pass)); } bool is_root_render_pass = @@ -624,9 +602,32 @@ GenerateMipmap(); } -bool DirectRenderer::UseRenderPass(const RenderPass* render_pass) { +bool DirectRenderer::CanSkipRenderPass(const RenderPass* render_pass) const { + if (render_pass == current_frame()->root_render_pass) + return false; + + if (ComputeScissorRectForRenderPass(render_pass).IsEmpty()) + return true; + + // If the RenderPass wants to be cached, then we only draw it if we need to. + // When damage is present, then we can't skip the RenderPass. Or if the + // texture does not exist (first frame, or was deleted) then we can't skip + // the RenderPass. + if (render_pass->cache_render_pass) { + if (render_pass->has_damage_from_contributing_content) + return false; + auto it = render_pass_textures_.find(render_pass->id); + DCHECK(it != render_pass_textures_.end()); + cc::ScopedResource* texture = it->second.get(); + DCHECK(texture); + return texture->id() != 0; + } + + return false; +} + +void DirectRenderer::UseRenderPass(const RenderPass* render_pass) { current_frame()->current_render_pass = render_pass; - current_frame()->current_texture = nullptr; if (render_pass == current_frame()->root_render_pass) { BindFramebufferToOutputSurface(); @@ -637,7 +638,7 @@ InitializeViewport(current_frame(), render_pass->output_rect, gfx::Rect(current_frame()->device_viewport_size), current_frame()->device_viewport_size); - return true; + return; } cc::ScopedResource* texture = render_pass_textures_[render_pass->id].get(); @@ -646,26 +647,36 @@ gfx::Size size = RenderPassTextureSize(render_pass); size.Enlarge(enlarge_pass_texture_amount_.width(), enlarge_pass_texture_amount_.height()); + if (!texture->id()) { texture->Allocate(size, RenderPassTextureHint(render_pass), BackbufferFormat(), current_frame()->current_render_pass->color_space); - } else if (render_pass->cache_render_pass && - !render_pass->has_damage_from_contributing_content) { - return false; - } else if (current_frame()->ComputeScissorRectForRenderPass().IsEmpty()) { - return false; } DCHECK(texture->id()); - if (BindFramebufferToTexture(texture)) { - InitializeViewport(current_frame(), render_pass->output_rect, - gfx::Rect(render_pass->output_rect.size()), - texture->size()); - return true; - } + BindFramebufferToTexture(texture); + InitializeViewport(current_frame(), render_pass->output_rect, + gfx::Rect(render_pass->output_rect.size()), + texture->size()); +} - return false; +gfx::Rect DirectRenderer::ComputeScissorRectForRenderPass( + const RenderPass* render_pass) const { + const RenderPass* root_render_pass = current_frame()->root_render_pass; + const gfx::Rect root_damage_rect = current_frame()->root_damage_rect; + + if (render_pass == root_render_pass) + return root_damage_rect; + + // If the root damage rect has been expanded due to overlays, all the other + // damage rect calculations are incorrect. + if (!root_render_pass->damage_rect.Contains(root_damage_rect)) + return render_pass->output_rect; + + DCHECK(render_pass->copy_requests.empty() || + (render_pass->damage_rect == render_pass->output_rect)); + return render_pass->damage_rect; } bool DirectRenderer::HasAllocatedResourcesForTesting(
diff --git a/components/viz/service/display/direct_renderer.h b/components/viz/service/display/direct_renderer.h index df4954fb..b4ae8d3 100644 --- a/components/viz/service/display/direct_renderer.h +++ b/components/viz/service/display/direct_renderer.h
@@ -78,12 +78,10 @@ struct VIZ_SERVICE_EXPORT DrawingFrame { DrawingFrame(); ~DrawingFrame(); - gfx::Rect ComputeScissorRectForRenderPass() const; const RenderPassList* render_passes_in_draw_order = nullptr; const RenderPass* root_render_pass = nullptr; const RenderPass* current_render_pass = nullptr; - const cc::ScopedResource* current_texture = nullptr; gfx::Rect root_damage_rect; std::vector<gfx::Rect> root_content_bounds; @@ -141,7 +139,13 @@ bool use_render_pass_scissor); void DrawRenderPassAndExecuteCopyRequests(RenderPass* render_pass); void DrawRenderPass(const RenderPass* render_pass); - bool UseRenderPass(const RenderPass* render_pass); + // Returns true if it detects that we do not need to draw the render pass. + // This may be because the RenderPass is already cached, or because it is + // entirely clipped out, for instance. + bool CanSkipRenderPass(const RenderPass* render_pass) const; + void UseRenderPass(const RenderPass* render_pass); + gfx::Rect ComputeScissorRectForRenderPass( + const RenderPass* render_pass) const; void DoDrawPolygon(const DrawPolygon& poly, const gfx::Rect& render_pass_scissor, @@ -155,7 +159,7 @@ virtual bool CanPartialSwap() = 0; virtual ResourceFormat BackbufferFormat() const = 0; virtual void BindFramebufferToOutputSurface() = 0; - virtual bool BindFramebufferToTexture(const cc::ScopedResource* resource) = 0; + virtual void BindFramebufferToTexture(const cc::ScopedResource* resource) = 0; virtual void SetScissorTestRect(const gfx::Rect& scissor_rect) = 0; virtual void PrepareSurfaceForPass( SurfaceInitializationMode initialization_mode,
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc index 78800a75..e0a8985 100644 --- a/components/viz/service/display/gl_renderer.cc +++ b/components/viz/service/display/gl_renderer.cc
@@ -1125,11 +1125,20 @@ params->quad->shared_quad_state->quad_to_target_transform; if (!InitializeRPDQParameters(params)) return; + UpdateRPDQShadersForBlending(params); - if (!UpdateRPDQWithSkiaFilters(params)) - return; + bool can_draw = UpdateRPDQWithSkiaFilters(params); + // The above calls use ScopedUseGrContext which can change the bound + // framebuffer, so we need to restore it for the current RenderPass. UseRenderPass(current_frame()->current_render_pass); + // As part of restoring the framebuffer, we call SetViewport directly, rather + // than through PrepareSurfaceForPass. PrepareSurfaceForPass also clears the + // surface, which is not desired when restoring. SetViewport(); + + if (!can_draw) + return; + UpdateRPDQTexturesForSampling(params); UpdateRPDQBlendMode(params); ChooseRPDQProgram(params); @@ -2862,7 +2871,7 @@ } } -bool GLRenderer::BindFramebufferToTexture(const cc::ScopedResource* texture) { +void GLRenderer::BindFramebufferToTexture(const cc::ScopedResource* texture) { DCHECK(texture->id()); // Explicitly release lock, otherwise we can crash when try to lock @@ -2904,7 +2913,6 @@ } else { SetStencilEnabled(false); } - return true; } void GLRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) {
diff --git a/components/viz/service/display/gl_renderer.h b/components/viz/service/display/gl_renderer.h index 6fb1b1a3..2926f3a4 100644 --- a/components/viz/service/display/gl_renderer.h +++ b/components/viz/service/display/gl_renderer.h
@@ -94,7 +94,7 @@ bool CanPartialSwap() override; ResourceFormat BackbufferFormat() const override; void BindFramebufferToOutputSurface() override; - bool BindFramebufferToTexture(const cc::ScopedResource* resource) override; + void BindFramebufferToTexture(const cc::ScopedResource* resource) override; void SetScissorTestRect(const gfx::Rect& scissor_rect) override; void PrepareSurfaceForPass(SurfaceInitializationMode initialization_mode, const gfx::Rect& render_pass_scissor) override;
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index 14b50b7f..409c288 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -215,7 +215,7 @@ } } -bool SkiaRenderer::BindFramebufferToTexture(const cc::ScopedResource* texture) { +void SkiaRenderer::BindFramebufferToTexture(const cc::ScopedResource* texture) { DCHECK(texture->id()); // Explicitly release lock, otherwise we can crash when try to lock @@ -235,7 +235,6 @@ current_framebuffer_lock_->format(), false, true, 0)); current_canvas_ = current_framebuffer_surface_lock_->surface()->getCanvas(); - return true; } void SkiaRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) {
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h index a198a76..1844751 100644 --- a/components/viz/service/display/skia_renderer.h +++ b/components/viz/service/display/skia_renderer.h
@@ -44,7 +44,7 @@ bool CanPartialSwap() override; ResourceFormat BackbufferFormat() const override; void BindFramebufferToOutputSurface() override; - bool BindFramebufferToTexture(const cc::ScopedResource* texture) override; + void BindFramebufferToTexture(const cc::ScopedResource* texture) override; void SetScissorTestRect(const gfx::Rect& scissor_rect) override; void PrepareSurfaceForPass(SurfaceInitializationMode initialization_mode, const gfx::Rect& render_pass_scissor) override;
diff --git a/components/viz/service/display/software_renderer.cc b/components/viz/service/display/software_renderer.cc index cdf5baf..0731801 100644 --- a/components/viz/service/display/software_renderer.cc +++ b/components/viz/service/display/software_renderer.cc
@@ -115,7 +115,7 @@ current_canvas_ = root_canvas_; } -bool SoftwareRenderer::BindFramebufferToTexture( +void SoftwareRenderer::BindFramebufferToTexture( const cc::ScopedResource* texture) { DCHECK(texture->id()); @@ -128,7 +128,6 @@ current_framebuffer_canvas_ = std::make_unique<SkCanvas>(current_framebuffer_lock_->sk_bitmap()); current_canvas_ = current_framebuffer_canvas_.get(); - return true; } void SoftwareRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) {
diff --git a/components/viz/service/display/software_renderer.h b/components/viz/service/display/software_renderer.h index 08b0258..a8784c5 100644 --- a/components/viz/service/display/software_renderer.h +++ b/components/viz/service/display/software_renderer.h
@@ -42,7 +42,7 @@ bool CanPartialSwap() override; ResourceFormat BackbufferFormat() const override; void BindFramebufferToOutputSurface() override; - bool BindFramebufferToTexture(const cc::ScopedResource* texture) override; + void BindFramebufferToTexture(const cc::ScopedResource* texture) override; void SetScissorTestRect(const gfx::Rect& scissor_rect) override; void PrepareSurfaceForPass(SurfaceInitializationMode initialization_mode, const gfx::Rect& render_pass_scissor) override;
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index cc0e307..9d6e2b4 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -688,8 +688,6 @@ "download/download_job_impl.h", "download/download_manager_impl.cc", "download/download_manager_impl.h", - "download/download_net_log_parameters.cc", - "download/download_net_log_parameters.h", "download/download_request_core.cc", "download/download_request_core.h", "download/download_request_handle.cc", @@ -1452,6 +1450,8 @@ "service_worker/service_worker_cache_writer.h", "service_worker/service_worker_client_utils.cc", "service_worker/service_worker_client_utils.h", + "service_worker/service_worker_consts.cc", + "service_worker/service_worker_consts.h", "service_worker/service_worker_content_settings_proxy_impl.cc", "service_worker/service_worker_content_settings_proxy_impl.h", "service_worker/service_worker_context_core.cc",
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 1de0430..f3cffff 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -1493,7 +1493,8 @@ BrowserGpuChannelHostFactory::Initialize(established_gpu_channel); #elif defined(USE_AURA) || defined(OS_MACOSX) established_gpu_channel = true; - if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor() || + if (parsed_command_line_.HasSwitch(switches::kDisableGpu) || + parsed_command_line_.HasSwitch(switches::kDisableGpuCompositing) || parsed_command_line_.HasSwitch(switches::kDisableGpuEarlyInit) || is_mus) { established_gpu_channel = always_uses_gpu = false;
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index b4c871b..5146fdac 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -127,56 +127,6 @@ #endif // defined(OS_WIN) } -scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextCommon( - scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, - gpu::SurfaceHandle surface_handle, - bool need_alpha_channel, - bool need_stencil_bits, - bool support_locking, - ui::ContextProviderCommandBuffer* shared_context_provider, - ui::command_buffer_metrics::ContextType type) { - DCHECK( - content::GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()); - DCHECK(gpu_channel_host); - - // All browser contexts get the same stream id because we don't use sync - // tokens for browser surfaces. - int32_t stream_id = content::kGpuStreamIdDefault; - gpu::SchedulingPriority stream_priority = content::kGpuStreamPriorityUI; - - // This is called from a few places to create different contexts: - // - The shared main thread context (offscreen). - // - The compositor context, which is used by the browser compositor - // (offscreen) for synchronization mostly, and by the display compositor - // (onscreen, except for with mus) for actual GL drawing. - // - The compositor worker context (offscreen) used for GPU raster. - // So ask for capabilities needed by any of these cases (we can optimize by - // branching on |surface_handle| being null if these needs diverge). - // - // The default framebuffer for an offscreen context is not used, so it does - // not need alpha, stencil, depth, antialiasing. The display compositor does - // not use these things either (except for alpha when using mus for - // non-opaque ui that overlaps the system's window borders or stencil bits - // for overdraw feedback), so we can request only that when needed. - gpu::gles2::ContextCreationAttribHelper attributes; - attributes.alpha_size = need_alpha_channel ? 8 : -1; - attributes.depth_size = 0; - attributes.stencil_size = need_stencil_bits ? 8 : 0; - attributes.samples = 0; - attributes.sample_buffers = 0; - attributes.bind_generates_resource = false; - attributes.lose_context_when_out_of_memory = true; - attributes.buffer_preserved = false; - - constexpr bool automatic_flushes = false; - - GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon"); - return base::MakeRefCounted<ui::ContextProviderCommandBuffer>( - std::move(gpu_channel_host), stream_id, stream_priority, surface_handle, - url, automatic_flushes, support_locking, gpu::SharedMemoryLimits(), - attributes, shared_context_provider, type); -} - #if defined(OS_MACOSX) bool IsCALayersDisabledFromCommandLine() { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); @@ -267,8 +217,10 @@ software_backing_ = std::make_unique<viz::OutputDeviceBacking>(); #endif - if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) + if (command_line->HasSwitch(switches::kDisableGpu) || + command_line->HasSwitch(switches::kDisableGpuCompositing)) { DisableGpuCompositing(nullptr); + } } GpuProcessTransportFactory::~GpuProcessTransportFactory() { @@ -373,9 +325,7 @@ const bool use_vulkan = static_cast<bool>(SharedVulkanContextProvider()); const bool use_gpu_compositing = - !compositor->force_software_compositor() && - !is_gpu_compositing_disabled_ && - GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor(); + !compositor->force_software_compositor() && !is_gpu_compositing_disabled_; if (use_gpu_compositing && !use_vulkan) { gpu_channel_factory_->EstablishGpuChannel(base::Bind( &GpuProcessTransportFactory::EstablishedGpuChannel, @@ -392,9 +342,12 @@ if (!compositor) return; - // CanUseGpuBrowserCompositor can change as a result of EstablishGpuChannel(). - if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) + if (gpu_channel_host && + gpu_channel_host->gpu_feature_info() + .status_values[gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING] != + gpu::kGpuFeatureStatusEnabled) { use_gpu_compositing = false; + } // Gpu compositing may have been disabled in the meantime. if (is_gpu_compositing_disabled_) use_gpu_compositing = false; @@ -1003,8 +956,15 @@ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host = gpu_channel_factory_->EstablishGpuChannelSync(nullptr); - if (!gpu_channel_host) + if (!gpu_channel_host || + gpu_channel_host->gpu_feature_info() + .status_values[gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING] != + gpu::kGpuFeatureStatusEnabled) { + DisableGpuCompositing(nullptr); + if (gpu_channel_host) + gpu_channel_host->DestroyChannel(); return nullptr; + } // We need a separate context from the compositor's so that skia and gl_helper // don't step on each other. @@ -1092,4 +1052,54 @@ callback_factory_.GetWeakPtr())); } +scoped_refptr<ui::ContextProviderCommandBuffer> +GpuProcessTransportFactory::CreateContextCommon( + scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, + gpu::SurfaceHandle surface_handle, + bool need_alpha_channel, + bool need_stencil_bits, + bool support_locking, + ui::ContextProviderCommandBuffer* shared_context_provider, + ui::command_buffer_metrics::ContextType type) { + DCHECK(gpu_channel_host); + DCHECK(!is_gpu_compositing_disabled_); + + // All browser contexts get the same stream id because we don't use sync + // tokens for browser surfaces. + int32_t stream_id = content::kGpuStreamIdDefault; + gpu::SchedulingPriority stream_priority = content::kGpuStreamPriorityUI; + + // This is called from a few places to create different contexts: + // - The shared main thread context (offscreen). + // - The compositor context, which is used by the browser compositor + // (offscreen) for synchronization mostly, and by the display compositor + // (onscreen, except for with mus) for actual GL drawing. + // - The compositor worker context (offscreen) used for GPU raster. + // So ask for capabilities needed by any of these cases (we can optimize by + // branching on |surface_handle| being null if these needs diverge). + // + // The default framebuffer for an offscreen context is not used, so it does + // not need alpha, stencil, depth, antialiasing. The display compositor does + // not use these things either (except for alpha when using mus for + // non-opaque ui that overlaps the system's window borders or stencil bits + // for overdraw feedback), so we can request only that when needed. + gpu::gles2::ContextCreationAttribHelper attributes; + attributes.alpha_size = need_alpha_channel ? 8 : -1; + attributes.depth_size = 0; + attributes.stencil_size = need_stencil_bits ? 8 : 0; + attributes.samples = 0; + attributes.sample_buffers = 0; + attributes.bind_generates_resource = false; + attributes.lose_context_when_out_of_memory = true; + attributes.buffer_preserved = false; + + constexpr bool automatic_flushes = false; + + GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon"); + return base::MakeRefCounted<ui::ContextProviderCommandBuffer>( + std::move(gpu_channel_host), stream_id, stream_priority, surface_handle, + url, automatic_flushes, support_locking, gpu::SharedMemoryLimits(), + attributes, shared_context_provider, type); +} + } // namespace content
diff --git a/content/browser/compositor/gpu_process_transport_factory.h b/content/browser/compositor/gpu_process_transport_factory.h index d454929..a2c6a967 100644 --- a/content/browser/compositor/gpu_process_transport_factory.h +++ b/content/browser/compositor/gpu_process_transport_factory.h
@@ -22,6 +22,7 @@ #include "components/viz/host/host_frame_sink_manager.h" #include "content/browser/compositor/image_transport_factory.h" #include "gpu/ipc/client/gpu_channel_host.h" +#include "services/ui/public/cpp/gpu/command_buffer_metrics.h" #include "ui/compositor/compositor.h" namespace base { @@ -129,6 +130,15 @@ // viz::ContextLostObserver implementation. void OnContextLost() override; + scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextCommon( + scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, + gpu::SurfaceHandle surface_handle, + bool need_alpha_channel, + bool need_stencil_bits, + bool support_locking, + ui::ContextProviderCommandBuffer* shared_context_provider, + ui::command_buffer_metrics::ContextType type); + viz::FrameSinkIdAllocator frame_sink_id_allocator_; #if defined(OS_WIN)
diff --git a/content/browser/compositor/image_transport_factory_browsertest.cc b/content/browser/compositor/image_transport_factory_browsertest.cc index 768d897..8a918a7 100644 --- a/content/browser/compositor/image_transport_factory_browsertest.cc +++ b/content/browser/compositor/image_transport_factory_browsertest.cc
@@ -8,10 +8,10 @@ #include "build/build_config.h" #include "components/viz/common/gpu/context_provider.h" #include "content/browser/compositor/owned_mailbox.h" -#include "content/public/browser/gpu_data_manager.h" #include "content/public/test/content_browser_test.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/gles2_interface.h" +#include "gpu/config/gpu_feature_info.h" #include "testing/gmock/include/gmock/gmock.h" #include "ui/compositor/compositor.h" @@ -36,12 +36,17 @@ // resources are reset. IN_PROC_BROWSER_TEST_F(ImageTransportFactoryBrowserTest, MAYBE_TestLostContext) { - // This test doesn't make sense in software compositing mode. - if (!GpuDataManager::GetInstance()->CanUseGpuBrowserCompositor()) - return; - ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); + // This test doesn't make sense in software compositing mode. + scoped_refptr<viz::ContextProvider> context_provider = + factory->GetContextFactory()->SharedMainThreadContextProvider(); + if (context_provider->GetGpuFeatureInfo() + .status_values[gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING] != + gpu::kGpuFeatureStatusEnabled) { + return; + } + scoped_refptr<OwnedMailbox> mailbox = new OwnedMailbox(factory->GetGLHelper()); EXPECT_FALSE(mailbox->mailbox().IsZero()); @@ -53,9 +58,7 @@ EXPECT_CALL(observer, OnLostResources()) .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); - ui::ContextFactory* context_factory = factory->GetContextFactory(); - gpu::gles2::GLES2Interface* gl = - context_factory->SharedMainThreadContextProvider()->ContextGL(); + gpu::gles2::GLES2Interface* gl = context_provider->ContextGL(); gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); @@ -97,10 +100,16 @@ // called and the created resources are reset. IN_PROC_BROWSER_TEST_F(ImageTransportFactoryTearDownBrowserTest, MAYBE_LoseOnTearDown) { - // This test doesn't make sense in software compositing mode. - if (!GpuDataManager::GetInstance()->CanUseGpuBrowserCompositor()) - return; ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); + // This test doesn't make sense in software compositing mode. + scoped_refptr<viz::ContextProvider> context_provider = + factory->GetContextFactory()->SharedMainThreadContextProvider(); + if (context_provider->GetGpuFeatureInfo() + .status_values[gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING] != + gpu::kGpuFeatureStatusEnabled) { + return; + } + viz::GLHelper* helper = factory->GetGLHelper(); ASSERT_TRUE(helper); mailbox_ = new OwnedMailbox(helper);
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc index 91b3a0b..6564be3 100644 --- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc +++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -2217,12 +2217,12 @@ CountingDownloadFile(std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_downloads_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer) : DownloadFileImpl(std::move(save_info), default_downloads_directory, std::move(stream), - net_log, + download_id, observer) {} ~CountingDownloadFile() override { @@ -2274,11 +2274,11 @@ std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_downloads_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer) override { return new CountingDownloadFile(std::move(save_info), default_downloads_directory, - std::move(stream), net_log, observer); + std::move(stream), download_id, observer); } };
diff --git a/content/browser/download/base_file.cc b/content/browser/download/base_file.cc index 0da99a1..230234db 100644 --- a/content/browser/download/base_file.cc +++ b/content/browser/download/base_file.cc
@@ -11,23 +11,60 @@ #include "base/files/file_util.h" #include "base/format_macros.h" #include "base/logging.h" +#include "base/macros.h" #include "base/pickle.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_restrictions.h" +#include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "content/browser/download/download_interrupt_reasons_impl.h" -#include "content/browser/download/download_net_log_parameters.h" #include "content/browser/download/download_stats.h" #include "content/public/browser/content_browser_client.h" +#include "content/public/browser/download_item.h" #include "content/public/common/quarantine.h" #include "crypto/secure_hash.h" #include "net/base/net_errors.h" -#include "net/log/net_log.h" -#include "net/log/net_log_event_type.h" + +#define CONDITIONAL_TRACE(trace) \ + do { \ + if (download_id_ != DownloadItem::kInvalidId) \ + TRACE_EVENT_##trace; \ + } while (0) namespace content { -BaseFile::BaseFile(const net::NetLogWithSource& net_log) : net_log_(net_log) { +namespace { +class FileErrorData : public base::trace_event::ConvertableToTraceFormat { + public: + FileErrorData(const char* operation, + int os_error, + DownloadInterruptReason interrupt_reason) + : operation_(operation), + os_error_(os_error), + interrupt_reason_(interrupt_reason) {} + + ~FileErrorData() override = default; + + void AppendAsTraceFormat(std::string* out) const override { + out->append("{"); + out->append( + base::StringPrintf("\"operation\":\"%s\",", operation_.c_str())); + out->append(base::StringPrintf("\"os_error\":\"%d\",", os_error_)); + out->append(base::StringPrintf( + "\"interrupt_reason\":\"%s\",", + DownloadInterruptReasonToString(interrupt_reason_).c_str())); + out->append("}"); + } + + private: + std::string operation_; + int os_error_; + DownloadInterruptReason interrupt_reason_; + DISALLOW_COPY_AND_ASSIGN(FileErrorData); +}; +} // namespace + +BaseFile::BaseFile(uint32_t download_id) : download_id_(download_id) { DETACH_FROM_SEQUENCE(sequence_checker_); } @@ -103,7 +140,10 @@ if (data_len == 0) return DOWNLOAD_INTERRUPT_REASON_NONE; - net_log_.BeginEvent(net::NetLogEventType::DOWNLOAD_FILE_WRITTEN); + // Use nestable async event instead of sync event so that all the writes + // belong to the same download will be grouped together. + CONDITIONAL_TRACE( + NESTABLE_ASYNC_BEGIN0("download", "DownloadFileWrite", download_id_)); int write_result = file_.Write(offset, data, data_len); DCHECK_NE(0, write_result); @@ -120,8 +160,8 @@ } bytes_so_far_ += data_len; - net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_WRITTEN, - net::NetLog::Int64Callback("bytes", data_len)); + CONDITIONAL_TRACE(NESTABLE_ASYNC_END1("download", "DownloadFileWrite", + download_id_, "bytes", data_len)); if (secure_hash_) secure_hash_->Update(data, data_len); @@ -144,9 +184,9 @@ Close(); - net_log_.BeginEvent( - net::NetLogEventType::DOWNLOAD_FILE_RENAMED, - base::Bind(&FileRenamedNetLogCallback, &full_path_, &new_path)); + CONDITIONAL_TRACE(BEGIN2("download", "DownloadFileRename", "old_filename", + full_path_.AsUTF8Unsafe(), "new_filename", + new_path.AsUTF8Unsafe())); base::CreateDirectory(new_path.DirName()); @@ -154,7 +194,7 @@ // permissions / security descriptors that makes sense in the new directory. rename_result = MoveFileAndAdjustPermissions(new_path); - net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_RENAMED); + CONDITIONAL_TRACE(END0("download", "DownloadFileRename")); if (rename_result == DOWNLOAD_INTERRUPT_REASON_NONE) full_path_ = new_path; @@ -171,19 +211,22 @@ void BaseFile::Detach() { detached_ = true; - net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_FILE_DETACHED); + CONDITIONAL_TRACE( + INSTANT0("download", "DownloadFileDetached", TRACE_EVENT_SCOPE_THREAD)); } void BaseFile::Cancel() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!detached_); - net_log_.AddEvent(net::NetLogEventType::CANCELLED); + CONDITIONAL_TRACE( + INSTANT0("download", "DownloadCancelled", TRACE_EVENT_SCOPE_THREAD)); Close(); if (!full_path_.empty()) { - net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_FILE_DELETED); + CONDITIONAL_TRACE( + INSTANT0("download", "DownloadFileDeleted", TRACE_EVENT_SCOPE_THREAD)); base::DeleteFile(full_path_, false); } @@ -294,9 +337,9 @@ } } - net_log_.BeginEvent( - net::NetLogEventType::DOWNLOAD_FILE_OPENED, - base::Bind(&FileOpenedNetLogCallback, &full_path_, bytes_so_far_)); + CONDITIONAL_TRACE(NESTABLE_ASYNC_BEGIN2( + "download", "DownloadFileOpen", download_id_, "file_name", + full_path_.AsUTF8Unsafe(), "bytes_so_far", bytes_so_far_)); // For sparse file, skip hash validation. if (is_sparse_file_) { @@ -356,14 +399,16 @@ // This should only be called when we have a stream. DCHECK(file_.IsValid()); file_.Close(); - net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_OPENED); + CONDITIONAL_TRACE( + NESTABLE_ASYNC_END0("download", "DownloadFileOpen", download_id_)); } DownloadInterruptReason BaseFile::LogNetError( const char* operation, net::Error error) { - net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_FILE_ERROR, - base::Bind(&FileErrorNetLogCallback, operation, error)); + CONDITIONAL_TRACE(INSTANT2("download", "DownloadFileError", + TRACE_EVENT_SCOPE_THREAD, "operation", operation, + "net_error", error)); return ConvertNetErrorToInterruptReason(error, DOWNLOAD_INTERRUPT_FROM_DISK); } @@ -384,9 +429,11 @@ DVLOG(1) << __func__ << "() operation:" << operation << " os_error:" << os_error << " reason:" << DownloadInterruptReasonToString(reason); - net_log_.AddEvent( - net::NetLogEventType::DOWNLOAD_FILE_ERROR, - base::Bind(&FileInterruptedNetLogCallback, operation, os_error, reason)); + auto error_data = + base::MakeUnique<FileErrorData>(operation, os_error, reason); + CONDITIONAL_TRACE(INSTANT1("download", "DownloadFileError", + TRACE_EVENT_SCOPE_THREAD, "file_error", + std::move(error_data))); return reason; } @@ -433,11 +480,12 @@ DCHECK(!detached_); DCHECK(!full_path_.empty()); - net_log_.BeginEvent(net::NetLogEventType::DOWNLOAD_FILE_ANNOTATED); + CONDITIONAL_TRACE(BEGIN0("download", "DownloadFileAnnotate")); QuarantineFileResult result = QuarantineFile( full_path_, GetEffectiveAuthorityURL(source_url, referrer_url), referrer_url, client_guid); - net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_ANNOTATED); + CONDITIONAL_TRACE(END0("download", "DownloadFileAnnotate")); + switch (result) { case QuarantineFileResult::OK: return DOWNLOAD_INTERRUPT_REASON_NONE;
diff --git a/content/browser/download/base_file.h b/content/browser/download/base_file.h index 8b54877..f7775678 100644 --- a/content/browser/download/base_file.h +++ b/content/browser/download/base_file.h
@@ -22,7 +22,6 @@ #include "content/public/browser/download_interrupt_reasons.h" #include "crypto/secure_hash.h" #include "net/base/net_errors.h" -#include "net/log/net_log_with_source.h" #include "url/gurl.h" namespace content { @@ -36,7 +35,7 @@ public: // May be constructed on any thread. All other routines (including // destruction) must occur on the same sequence. - BaseFile(const net::NetLogWithSource& net_log); + BaseFile(uint32_t download_id); ~BaseFile(); // Returns DOWNLOAD_INTERRUPT_REASON_NONE on success, or a @@ -252,7 +251,8 @@ // verify that writes are not overlapping. bool is_sparse_file_ = false; - net::NetLogWithSource net_log_; + // ID of the download, used for trace events. + uint32_t download_id_; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/content/browser/download/base_file_unittest.cc b/content/browser/download/base_file_unittest.cc index 3dad668..dd03ecad 100644 --- a/content/browser/download/base_file_unittest.cc +++ b/content/browser/download/base_file_unittest.cc
@@ -17,6 +17,7 @@ #include "base/test/test_file_util.h" #include "build/build_config.h" #include "content/public/browser/download_interrupt_reasons.h" +#include "content/public/browser/download_item.h" #include "content/public/test/test_browser_thread_bundle.h" #include "crypto/secure_hash.h" #include "crypto/sha2.h" @@ -60,7 +61,7 @@ void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - base_file_.reset(new BaseFile(net::NetLogWithSource())); + base_file_.reset(new BaseFile(DownloadItem::kInvalidId)); } void TearDown() override { @@ -118,7 +119,7 @@ // Create a file. Returns the complete file path. base::FilePath CreateTestFile() { base::FilePath file_name; - BaseFile file((net::NetLogWithSource())); + BaseFile file(DownloadItem::kInvalidId); EXPECT_EQ( DOWNLOAD_INTERRUPT_REASON_NONE, @@ -140,7 +141,7 @@ // Create a file with the specified file name. void CreateFileWithName(const base::FilePath& file_name) { EXPECT_NE(base::FilePath::StringType(), file_name.value()); - BaseFile duplicate_file((net::NetLogWithSource())); + BaseFile duplicate_file(DownloadItem::kInvalidId); EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, duplicate_file.Initialize(file_name, temp_dir_.GetPath(), base::File(), 0, std::string(), @@ -292,7 +293,7 @@ ASSERT_TRUE(base::CopyFile(base_file_->full_path(), new_file_path)); // Create another file - BaseFile second_file((net::NetLogWithSource())); + BaseFile second_file(DownloadItem::kInvalidId); ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, second_file.Initialize(new_file_path, base::FilePath(), @@ -418,7 +419,7 @@ // Pass a file handle which was opened without the WRITE flag. // This should result in an error when writing. base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ); - base_file_.reset(new BaseFile(net::NetLogWithSource())); + base_file_.reset(new BaseFile(DownloadItem::kInvalidId)); EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Initialize(path, base::FilePath(), std::move(file), 0, std::string(), @@ -460,7 +461,7 @@ set_expected_data(kTestData4); // Use the file we've just created. - base_file_.reset(new BaseFile(net::NetLogWithSource())); + base_file_.reset(new BaseFile(DownloadItem::kInvalidId)); ASSERT_EQ( DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Initialize(existing_file_name, base::FilePath(), base::File(), @@ -491,7 +492,7 @@ EXPECT_TRUE(base::MakeFileUnwritable(readonly_file_name)); // Try to overwrite it. - base_file_.reset(new BaseFile(net::NetLogWithSource())); + base_file_.reset(new BaseFile(DownloadItem::kInvalidId)); EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, base_file_->Initialize(readonly_file_name, base::FilePath(), base::File(), 0, std::string(),
diff --git a/content/browser/download/base_file_win_unittest.cc b/content/browser/download/base_file_win_unittest.cc index f29f79e..1b1c929 100644 --- a/content/browser/download/base_file_win_unittest.cc +++ b/content/browser/download/base_file_win_unittest.cc
@@ -7,6 +7,7 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "content/public/browser/download_interrupt_reasons.h" +#include "content/public/browser/download_item.h" #include "content/public/test/test_browser_thread_bundle.h" #include "net/base/filename_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -68,7 +69,7 @@ SCOPED_TRACE(::testing::Message() << "Source URL: " << url.spec() << " Referrer: " << test_case.referrer); - BaseFile base_file((net::NetLogWithSource())); + BaseFile base_file(DownloadItem::kInvalidId); ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file.Initialize(base::FilePath(), target_directory.GetPath(), base::File(), 0, std::string(),
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc index 8fd1ebf..c8bbf9e 100644 --- a/content/browser/download/download_browsertest.cc +++ b/content/browser/download/download_browsertest.cc
@@ -172,7 +172,7 @@ DownloadFileWithDelay(std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_download_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer, base::WeakPtr<DownloadFileWithDelayFactory> owner); @@ -217,7 +217,7 @@ std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_download_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer) override; void AddRenameCallback(base::Closure callback); @@ -238,13 +238,13 @@ std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_download_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer, base::WeakPtr<DownloadFileWithDelayFactory> owner) : DownloadFileImpl(std::move(save_info), default_download_directory, std::move(stream), - net_log, + download_id, observer), owner_(owner) {} @@ -297,14 +297,11 @@ std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_download_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer) { - return new DownloadFileWithDelay(std::move(save_info), - default_download_directory, - std::move(stream), - net_log, - observer, - weak_ptr_factory_.GetWeakPtr()); + return new DownloadFileWithDelay( + std::move(save_info), default_download_directory, std::move(stream), + download_id, observer, weak_ptr_factory_.GetWeakPtr()); } void DownloadFileWithDelayFactory::AddRenameCallback(base::Closure callback) { @@ -335,12 +332,12 @@ CountingDownloadFile(std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_downloads_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer) : DownloadFileImpl(std::move(save_info), default_downloads_directory, std::move(stream), - net_log, + download_id, observer) {} ~CountingDownloadFile() override { @@ -393,13 +390,11 @@ std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_downloads_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer) override { return new CountingDownloadFile(std::move(save_info), default_downloads_directory, - std::move(stream), - net_log, - observer); + std::move(stream), download_id, observer); } }; @@ -409,14 +404,14 @@ std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_downloads_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer, int64_t error_stream_offset, int64_t error_stream_length) : DownloadFileImpl(std::move(save_info), default_downloads_directory, std::move(stream), - net_log, + download_id, observer), error_stream_offset_(error_stream_offset), error_stream_length_(error_stream_length) {} @@ -456,11 +451,11 @@ std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_download_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer) override { ErrorInjectionDownloadFile* download_file = new ErrorInjectionDownloadFile( std::move(save_info), default_download_directory, std::move(stream), - net_log, observer, injected_error_offset_, injected_error_length_); + download_id, observer, injected_error_offset_, injected_error_length_); // If the InjectError() is not called yet, memorize |download_file| and wait // for error to be injected. if (injected_error_offset_ < 0)
diff --git a/content/browser/download/download_create_info.cc b/content/browser/download/download_create_info.cc index 4f795e10..e7741fb 100644 --- a/content/browser/download/download_create_info.cc +++ b/content/browser/download/download_create_info.cc
@@ -15,7 +15,6 @@ DownloadCreateInfo::DownloadCreateInfo( const base::Time& start_time, - const net::NetLogWithSource& net_log, std::unique_ptr<DownloadSaveInfo> save_info) : download_id(DownloadItem::kInvalidId), start_time(start_time), @@ -25,14 +24,12 @@ transient(false), result(DOWNLOAD_INTERRUPT_REASON_NONE), save_info(std::move(save_info)), - request_net_log(net_log), accept_range(false), connection_info(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN), method("GET") {} DownloadCreateInfo::DownloadCreateInfo() : DownloadCreateInfo(base::Time(), - net::NetLogWithSource(), base::WrapUnique(new DownloadSaveInfo)) {} DownloadCreateInfo::~DownloadCreateInfo() {}
diff --git a/content/browser/download/download_create_info.h b/content/browser/download/download_create_info.h index af6eac17..acc0da42 100644 --- a/content/browser/download/download_create_info.h +++ b/content/browser/download/download_create_info.h
@@ -21,7 +21,6 @@ #include "content/public/browser/download_interrupt_reasons.h" #include "content/public/browser/download_save_info.h" #include "net/http/http_response_info.h" -#include "net/log/net_log_with_source.h" #include "ui/base/page_transition_types.h" #include "url/gurl.h" @@ -35,7 +34,6 @@ // want to pass |DownloadItem|s between threads. struct CONTENT_EXPORT DownloadCreateInfo { DownloadCreateInfo(const base::Time& start_time, - const net::NetLogWithSource& net_log, std::unique_ptr<DownloadSaveInfo> save_info); DownloadCreateInfo(); ~DownloadCreateInfo(); @@ -105,10 +103,6 @@ // The handle to the URLRequest sourcing this download. std::unique_ptr<DownloadRequestHandleInterface> request_handle; - // The request's |NetLogWithSource|, for "source_dependency" linking with the - // download item's. - const net::NetLogWithSource request_net_log; - // --------------------------------------------------------------------------- // The remaining fields are Entity-body properties. These are only set if // |result| is DOWNLOAD_INTERRUPT_REASON_NONE.
diff --git a/content/browser/download/download_file_factory.cc b/content/browser/download/download_file_factory.cc index db80e1f..9030353 100644 --- a/content/browser/download/download_file_factory.cc +++ b/content/browser/download/download_file_factory.cc
@@ -16,10 +16,10 @@ std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_downloads_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer) { return new DownloadFileImpl(std::move(save_info), default_downloads_directory, - std::move(stream), net_log, observer); + std::move(stream), download_id, observer); } } // namespace content
diff --git a/content/browser/download/download_file_factory.h b/content/browser/download/download_file_factory.h index 832c707..bad3ad2 100644 --- a/content/browser/download/download_file_factory.h +++ b/content/browser/download/download_file_factory.h
@@ -16,10 +16,6 @@ #include "content/common/content_export.h" #include "url/gurl.h" -namespace net { -class NetLogWithSource; -} - namespace content { class DownloadDestinationObserver; @@ -34,7 +30,7 @@ std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_downloads_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer); };
diff --git a/content/browser/download/download_file_impl.cc b/content/browser/download/download_file_impl.cc index ea230c3..278594a 100644 --- a/content/browser/download/download_file_impl.cc +++ b/content/browser/download/download_file_impl.cc
@@ -18,7 +18,6 @@ #include "content/browser/download/download_create_info.h" #include "content/browser/download/download_destination_observer.h" #include "content/browser/download/download_interrupt_reasons_impl.h" -#include "content/browser/download/download_net_log_parameters.h" #include "content/browser/download/download_stats.h" #include "content/browser/download/download_utils.h" #include "content/browser/download/parallel_download_utils.h" @@ -28,10 +27,6 @@ #include "crypto/sha2.h" #include "mojo/public/c/system/types.h" #include "net/base/io_buffer.h" -#include "net/log/net_log.h" -#include "net/log/net_log_event_type.h" -#include "net/log/net_log_source.h" -#include "net/log/net_log_source_type.h" namespace content { @@ -201,11 +196,11 @@ std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_download_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& download_item_net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer) : DownloadFileImpl(std::move(save_info), default_download_directory, - download_item_net_log, + download_id, observer) { source_streams_[save_info_->offset] = std::make_unique<SourceStream>( save_info_->offset, save_info_->length, std::move(stream)); @@ -214,12 +209,9 @@ DownloadFileImpl::DownloadFileImpl( std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_download_directory, - const net::NetLogWithSource& download_item_net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer) - : net_log_( - net::NetLogWithSource::Make(download_item_net_log.net_log(), - net::NetLogSourceType::DOWNLOAD_FILE)), - file_(net_log_), + : file_(download_id), save_info_(std::move(save_info)), default_download_directory_(default_download_directory), potential_file_length_(kUnknownContentLength), @@ -229,14 +221,13 @@ bytes_seen_with_parallel_streams_(0), bytes_seen_without_parallel_streams_(0), is_paused_(false), + download_id_(download_id), observer_(observer), weak_factory_(this) { - download_item_net_log.AddEvent( - net::NetLogEventType::DOWNLOAD_FILE_CREATED, - net_log_.source().ToEventParametersCallback()); - net_log_.BeginEvent( - net::NetLogEventType::DOWNLOAD_FILE_ACTIVE, - download_item_net_log.source().ToEventParametersCallback()); + TRACE_EVENT_INSTANT0("download", "DownloadFileCreated", + TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("download", "DownloadFileActive", + download_id); DETACH_FROM_SEQUENCE(sequence_checker_); } @@ -244,7 +235,8 @@ DownloadFileImpl::~DownloadFileImpl() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_ACTIVE); + TRACE_EVENT_NESTABLE_ASYNC_END0("download", "DownloadFileActive", + download_id_); } void DownloadFileImpl::Initialize( @@ -632,11 +624,9 @@ else NotifyObserver(source_stream, reason, state, should_terminate); - if (net_log_.IsCapturing()) { - net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_STREAM_DRAINED, - base::Bind(&FileStreamDrainedNetLogCallback, - total_incoming_data_size, num_buffers)); - } + TRACE_EVENT_INSTANT2("download", "DownloadStreamDrained", + TRACE_EVENT_SCOPE_THREAD, "stream_size", + total_incoming_data_size, "num_buffers", num_buffers); } void DownloadFileImpl::OnStreamCompleted(SourceStream* source_stream) {
diff --git a/content/browser/download/download_file_impl.h b/content/browser/download/download_file_impl.h index e197ee5..3285a64 100644 --- a/content/browser/download/download_file_impl.h +++ b/content/browser/download/download_file_impl.h
@@ -30,7 +30,6 @@ #include "content/public/common/download_stream.mojom.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/system/simple_watcher.h" -#include "net/log/net_log_with_source.h" namespace content { class ByteStreamReader; @@ -49,7 +48,7 @@ DownloadFileImpl(std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_downloads_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer); ~DownloadFileImpl() override; @@ -206,7 +205,7 @@ DownloadFileImpl(std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_downloads_directory, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer); // Options for RenameWithRetryInternal. @@ -306,8 +305,6 @@ // Print the internal states for debugging. void DebugStates() const; - net::NetLogWithSource net_log_; - // The base file instance. BaseFile file_; @@ -356,6 +353,8 @@ // by DownloadRequestCore in that case. bool is_paused_; + uint32_t download_id_; + SEQUENCE_CHECKER(sequence_checker_); base::WeakPtr<DownloadDestinationObserver> observer_;
diff --git a/content/browser/download/download_file_unittest.cc b/content/browser/download/download_file_unittest.cc index 583e1638..9b7b0d0 100644 --- a/content/browser/download/download_file_unittest.cc +++ b/content/browser/download/download_file_unittest.cc
@@ -30,7 +30,6 @@ #include "net/base/file_stream.h" #include "net/base/mock_file_stream.h" #include "net/base/net_errors.h" -#include "net/log/net_log_with_source.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -121,12 +120,12 @@ TestDownloadFileImpl(std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_downloads_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer) : DownloadFileImpl(std::move(save_info), default_downloads_directory, std::move(stream), - net_log, + download_id, observer) {} protected: @@ -230,7 +229,7 @@ std::move(save_info), base::FilePath(), std::make_unique<DownloadManager::InputStream>( std::unique_ptr<ByteStreamReader>(input_stream_)), - net::NetLogWithSource(), observer_factory_.GetWeakPtr())); + DownloadItem::kInvalidId, observer_factory_.GetWeakPtr())); EXPECT_CALL(*input_stream_, Read(_, _)) .WillOnce(Return(ByteStreamReader::STREAM_EMPTY))
diff --git a/content/browser/download/download_item_factory.h b/content/browser/download/download_item_factory.h index c9a083b..a1f64a8 100644 --- a/content/browser/download/download_item_factory.h +++ b/content/browser/download/download_item_factory.h
@@ -23,10 +23,6 @@ class FilePath; } -namespace net { -class NetLogWithSource; -} - namespace content { class DownloadItem; @@ -65,14 +61,12 @@ bool opened, base::Time last_access_time, bool transient, - const std::vector<DownloadItem::ReceivedSlice>& received_slices, - const net::NetLogWithSource& net_log) = 0; + const std::vector<DownloadItem::ReceivedSlice>& received_slices) = 0; virtual DownloadItemImpl* CreateActiveItem( DownloadItemImplDelegate* delegate, uint32_t download_id, - const DownloadCreateInfo& info, - const net::NetLogWithSource& net_log) = 0; + const DownloadCreateInfo& info) = 0; virtual DownloadItemImpl* CreateSavePageItem( DownloadItemImplDelegate* delegate, @@ -80,8 +74,7 @@ const base::FilePath& path, const GURL& url, const std::string& mime_type, - std::unique_ptr<DownloadRequestHandleInterface> request_handle, - const net::NetLogWithSource& net_log) = 0; + std::unique_ptr<DownloadRequestHandleInterface> request_handle) = 0; }; } // namespace content
diff --git a/content/browser/download/download_item_impl.cc b/content/browser/download/download_item_impl.cc index e5a0ca5ad..ae2922c8 100644 --- a/content/browser/download/download_item_impl.cc +++ b/content/browser/download/download_item_impl.cc
@@ -43,7 +43,6 @@ #include "content/browser/download/download_item_impl_delegate.h" #include "content/browser/download/download_job_factory.h" #include "content/browser/download/download_job_impl.h" -#include "content/browser/download/download_net_log_parameters.h" #include "content/browser/download/download_request_handle.h" #include "content/browser/download/download_stats.h" #include "content/browser/download/download_task_runner.h" @@ -61,10 +60,6 @@ #include "content/public/common/referrer.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" -#include "net/log/net_log.h" -#include "net/log/net_log_event_type.h" -#include "net/log/net_log_parameters_callback.h" -#include "net/log/net_log_source.h" #include "net/traffic_annotation/network_traffic_annotation.h" namespace content { @@ -127,6 +122,101 @@ reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED; } +std::string GetDownloadTypeNames(DownloadItem::DownloadType type) { + switch (type) { + case DownloadItem::TYPE_ACTIVE_DOWNLOAD: + return "NEW_DOWNLOAD"; + case DownloadItem::TYPE_HISTORY_IMPORT: + return "HISTORY_IMPORT"; + case DownloadItem::TYPE_SAVE_PAGE_AS: + return "SAVE_PAGE_AS"; + default: + NOTREACHED(); + return "INVALID_TYPE"; + } +} + +std::string GetDownloadDangerNames(DownloadDangerType type) { + switch (type) { + case DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS: + return "NOT_DANGEROUS"; + case DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: + return "DANGEROUS_FILE"; + case DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: + return "DANGEROUS_URL"; + case DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT: + return "DANGEROUS_CONTENT"; + case DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT: + return "MAYBE_DANGEROUS_CONTENT"; + case DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: + return "UNCOMMON_CONTENT"; + case DOWNLOAD_DANGER_TYPE_USER_VALIDATED: + return "USER_VALIDATED"; + case DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: + return "DANGEROUS_HOST"; + case DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED: + return "POTENTIALLY_UNWANTED"; + default: + NOTREACHED(); + return "UNKNOWN_DANGER_TYPE"; + } +} + +class DownloadItemActivatedData + : public base::trace_event::ConvertableToTraceFormat { + public: + DownloadItemActivatedData(DownloadItem::DownloadType download_type, + uint32_t download_id, + std::string original_url, + std::string final_url, + std::string file_name, + DownloadDangerType danger_type, + int64_t start_offset, + bool has_user_gesture) + : download_type_(download_type), + download_id_(download_id), + original_url_(original_url), + final_url_(final_url), + file_name_(file_name), + danger_type_(danger_type), + start_offset_(start_offset), + has_user_gesture_(has_user_gesture) {} + + ~DownloadItemActivatedData() override = default; + + void AppendAsTraceFormat(std::string* out) const override { + out->append("{"); + out->append(base::StringPrintf( + "\"type\":\"%s\",", GetDownloadTypeNames(download_type_).c_str())); + out->append(base::StringPrintf("\"id\":\"%d\",", download_id_)); + out->append( + base::StringPrintf("\"original_url\":\"%s\",", original_url_.c_str())); + out->append( + base::StringPrintf("\"final_url\":\"%s\",", final_url_.c_str())); + out->append( + base::StringPrintf("\"file_name\":\"%s\",", file_name_.c_str())); + out->append( + base::StringPrintf("\"danger_type\":\"%s\",", + GetDownloadDangerNames(danger_type_).c_str())); + out->append( + base::StringPrintf("\"start_offset\":\"%" PRId64 "\",", start_offset_)); + out->append(base::StringPrintf("\"has_user_gesture\":\"%s\"", + has_user_gesture_ ? "true" : "false")); + out->append("}"); + } + + private: + DownloadItem::DownloadType download_type_; + uint32_t download_id_; + std::string original_url_; + std::string final_url_; + std::string file_name_; + DownloadDangerType danger_type_; + int64_t start_offset_; + bool has_user_gesture_; + DISALLOW_COPY_AND_ASSIGN(DownloadItemActivatedData); +}; + } // namespace const uint32_t DownloadItem::kInvalidId = 0; @@ -220,8 +310,7 @@ bool opened, base::Time last_access_time, bool transient, - const std::vector<DownloadItem::ReceivedSlice>& received_slices, - const net::NetLogWithSource& net_log) + const std::vector<DownloadItem::ReceivedSlice>& received_slices) : request_info_(url_chain, referrer_url, site_url, @@ -255,21 +344,19 @@ last_modified_time_(last_modified), etag_(etag), received_slices_(received_slices), - net_log_(net_log), is_updating_observers_(false), weak_ptr_factory_(this) { delegate_->Attach(); DCHECK(state_ == COMPLETE_INTERNAL || state_ == INTERRUPTED_INTERNAL || state_ == CANCELLED_INTERNAL); DCHECK(base::IsValidGUID(guid_)); - Init(false /* not actively downloading */, SRC_HISTORY_IMPORT); + Init(false /* not actively downloading */, TYPE_HISTORY_IMPORT); } // Constructing for a regular download: DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, uint32_t download_id, - const DownloadCreateInfo& info, - const net::NetLogWithSource& net_log) + const DownloadCreateInfo& info) : request_info_(info.url_chain, info.referrer_url, info.site_url, @@ -300,21 +387,13 @@ : TARGET_DISPOSITION_OVERWRITE), last_modified_time_(info.last_modified), etag_(info.etag), - net_log_(net_log), is_updating_observers_(false), fetch_error_body_(info.fetch_error_body), weak_ptr_factory_(this) { delegate_->Attach(); - Init(true /* actively downloading */, SRC_ACTIVE_DOWNLOAD); + Init(true /* actively downloading */, TYPE_ACTIVE_DOWNLOAD); - // Link the event sources. - net_log_.AddEvent( - net::NetLogEventType::DOWNLOAD_URL_REQUEST, - info.request_net_log.source().ToEventParametersCallback()); - - info.request_net_log.AddEvent( - net::NetLogEventType::DOWNLOAD_STARTED, - net_log_.source().ToEventParametersCallback()); + TRACE_EVENT_INSTANT0("download", "DownloadStarted", TRACE_EVENT_SCOPE_THREAD); } // Constructing for the "Save Page As..." feature: @@ -324,8 +403,7 @@ const base::FilePath& path, const GURL& url, const std::string& mime_type, - std::unique_ptr<DownloadRequestHandleInterface> request_handle, - const net::NetLogWithSource& net_log) + std::unique_ptr<DownloadRequestHandleInterface> request_handle) : request_info_(url), guid_(base::GenerateGUID()), download_id_(download_id), @@ -335,13 +413,12 @@ state_(IN_PROGRESS_INTERNAL), delegate_(delegate), destination_info_(path, path, 0, false, std::string(), base::Time()), - net_log_(net_log), is_updating_observers_(false), weak_ptr_factory_(this) { job_ = DownloadJobFactory::CreateJob(this, std::move(request_handle), DownloadCreateInfo(), true); delegate_->Attach(); - Init(true /* actively downloading */, SRC_SAVE_PAGE_AS); + Init(true /* actively downloading */, TYPE_SAVE_PAGE_AS); } DownloadItemImpl::~DownloadItemImpl() { @@ -398,9 +475,9 @@ danger_type_ = DOWNLOAD_DANGER_TYPE_USER_VALIDATED; - net_log_.AddEvent( - net::NetLogEventType::DOWNLOAD_ITEM_SAFETY_STATE_UPDATED, - base::Bind(&ItemCheckedNetLogCallback, GetDangerType())); + TRACE_EVENT_INSTANT1("download", "DownloadItemSaftyStateUpdated", + TRACE_EVENT_SCOPE_THREAD, "danger_type", + GetDownloadDangerNames(danger_type_).c_str()); UpdateObservers(); // TODO(asanka): This is potentially unsafe. The download // may not be in a consistent state or around at all after @@ -1153,10 +1230,6 @@ return weak_ptr_factory_.GetWeakPtr(); } -const net::NetLogWithSource& DownloadItemImpl::GetNetLogWithSource() const { - return net_log_; -} - void DownloadItemImpl::SetTotalBytes(int64_t total_bytes) { total_bytes_ = total_bytes; } @@ -1220,11 +1293,9 @@ UpdateProgress(bytes_so_far, bytes_per_sec); received_slices_ = received_slices; - if (net_log_.IsCapturing()) { - net_log_.AddEvent( - net::NetLogEventType::DOWNLOAD_ITEM_UPDATED, - net::NetLog::Int64Callback("bytes_so_far", GetReceivedBytes())); - } + TRACE_EVENT_INSTANT1("download", "DownloadItemUpdated", + TRACE_EVENT_SCOPE_THREAD, "bytes_so_far", + GetReceivedBytes()); UpdateObservers(); } @@ -1267,11 +1338,11 @@ // **** Download progression cascade void DownloadItemImpl::Init(bool active, - DownloadType download_type) { + DownloadItem::DownloadType download_type) { DCHECK_CURRENTLY_ON(BrowserThread::UI); std::string file_name; - if (download_type == SRC_HISTORY_IMPORT) { + if (download_type == TYPE_HISTORY_IMPORT) { // target_path_ works for History and Save As versions. file_name = GetTargetFilePath().AsUTF8Unsafe(); } else { @@ -1285,14 +1356,17 @@ file_name = GetURL().ExtractFileName(); } - net::NetLogParametersCallback active_data = - base::Bind(&ItemActivatedNetLogCallback, this, download_type, &file_name); + auto active_data = base::MakeUnique<DownloadItemActivatedData>( + download_type, GetId(), GetOriginalUrl().spec(), GetURL().spec(), + file_name, GetDangerType(), GetReceivedBytes(), HasUserGesture()); + if (active) { - net_log_.BeginEvent(net::NetLogEventType::DOWNLOAD_ITEM_ACTIVE, - active_data); + TRACE_EVENT_ASYNC_BEGIN1("download", "DownloadItemActive", download_id_, + "download_item", std::move(active_data)); } else { - net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_ITEM_ACTIVE, - active_data); + TRACE_EVENT_INSTANT1("download", "DownloadItemActive", + TRACE_EVENT_SCOPE_THREAD, "download_item", + std::move(active_data)); } DVLOG(20) << __func__ << "() " << DebugString(true); @@ -2015,37 +2089,39 @@ DCHECK(GetFullPath() == GetTargetFilePath()) << "Current output path must match target path."; - net_log_.AddEvent( - net::NetLogEventType::DOWNLOAD_ITEM_COMPLETING, - base::Bind(&ItemCompletingNetLogCallback, GetReceivedBytes(), - &destination_info_.hash)); + TRACE_EVENT_INSTANT2("download", "DownloadItemCompleting", + TRACE_EVENT_SCOPE_THREAD, "bytes_so_far", + GetReceivedBytes(), "final_hash", + destination_info_.hash); break; case COMPLETE_INTERNAL: - net_log_.AddEvent( - net::NetLogEventType::DOWNLOAD_ITEM_FINISHED, - base::Bind(&ItemFinishedNetLogCallback, auto_opened_)); + TRACE_EVENT_INSTANT1("download", "DownloadItemFinished", + TRACE_EVENT_SCOPE_THREAD, "auto_opened", + auto_opened_ ? "yes" : "no"); break; case INTERRUPTED_INTERNAL: DCHECK(!download_file_) << "Download file must be released prior to interruption."; DCHECK_NE(last_reason_, DOWNLOAD_INTERRUPT_REASON_NONE); - net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_ITEM_INTERRUPTED, - base::Bind(&ItemInterruptedNetLogCallback, last_reason_, - GetReceivedBytes())); + TRACE_EVENT_INSTANT2("download", "DownloadItemInterrupted", + TRACE_EVENT_SCOPE_THREAD, "interrupt_reason", + DownloadInterruptReasonToString(last_reason_), + "bytes_so_far", GetReceivedBytes()); break; case RESUMING_INTERNAL: - net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_ITEM_RESUMED, - base::Bind(&ItemResumingNetLogCallback, false, - last_reason_, GetReceivedBytes())); + TRACE_EVENT_INSTANT2("download", "DownloadItemResumed", + TRACE_EVENT_SCOPE_THREAD, "interrupt_reason", + DownloadInterruptReasonToString(last_reason_), + "bytes_so_far", GetReceivedBytes()); break; case CANCELLED_INTERNAL: - net_log_.AddEvent( - net::NetLogEventType::DOWNLOAD_ITEM_CANCELED, - base::Bind(&ItemCanceledNetLogCallback, GetReceivedBytes())); + TRACE_EVENT_INSTANT1("download", "DownloadItemCancelled", + TRACE_EVENT_SCOPE_THREAD, "bytes_so_far", + GetReceivedBytes()); break; case MAX_DOWNLOAD_INTERNAL_STATE: @@ -2065,22 +2141,25 @@ // Termination if (is_done && !was_done) - net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_ITEM_ACTIVE); + TRACE_EVENT_ASYNC_END0("download", "DownloadItemActive", download_id_); // Resumption if (was_done && !is_done) { std::string file_name(GetTargetFilePath().BaseName().AsUTF8Unsafe()); - net_log_.BeginEvent(net::NetLogEventType::DOWNLOAD_ITEM_ACTIVE, - base::Bind(&ItemActivatedNetLogCallback, this, - SRC_ACTIVE_DOWNLOAD, &file_name)); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( + "download", "DownloadItemActive", download_id_, "download_item", + base::MakeUnique<DownloadItemActivatedData>( + TYPE_ACTIVE_DOWNLOAD, GetId(), GetOriginalUrl().spec(), + GetURL().spec(), file_name, GetDangerType(), GetReceivedBytes(), + HasUserGesture())); } } void DownloadItemImpl::SetDangerType(DownloadDangerType danger_type) { if (danger_type != danger_type_) { - net_log_.AddEvent( - net::NetLogEventType::DOWNLOAD_ITEM_SAFETY_STATE_UPDATED, - base::Bind(&ItemCheckedNetLogCallback, danger_type)); + TRACE_EVENT_INSTANT1("download", "DownloadItemSaftyStateUpdated", + TRACE_EVENT_SCOPE_THREAD, "danger_type", + GetDownloadDangerNames(danger_type).c_str()); } // Only record the Malicious UMA stat if it's going from {not malicious} -> // {malicious}. @@ -2103,9 +2182,10 @@ << DebugString(true); DCHECK(!new_path.empty()); - net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_ITEM_RENAMED, - base::Bind(&ItemRenamedNetLogCallback, - &destination_info_.current_path, &new_path)); + TRACE_EVENT_INSTANT2("download", "DownloadItemRenamed", + TRACE_EVENT_SCOPE_THREAD, "old_filename", + destination_info_.current_path.AsUTF8Unsafe(), + "new_filename", new_path.AsUTF8Unsafe()); destination_info_.current_path = new_path; }
diff --git a/content/browser/download/download_item_impl.h b/content/browser/download/download_item_impl.h index 6a7fc588..ed6795d 100644 --- a/content/browser/download/download_item_impl.h +++ b/content/browser/download/download_item_impl.h
@@ -18,12 +18,10 @@ #include "base/observer_list.h" #include "base/time/time.h" #include "content/browser/download/download_destination_observer.h" -#include "content/browser/download/download_net_log_parameters.h" #include "content/browser/download/download_request_handle.h" #include "content/common/content_export.h" #include "content/public/browser/download_interrupt_reasons.h" #include "content/public/browser/download_item.h" -#include "net/log/net_log_with_source.h" #include "url/gurl.h" namespace content { @@ -178,15 +176,13 @@ bool opened, base::Time last_access_time, bool transient, - const std::vector<DownloadItem::ReceivedSlice>& received_slices, - const net::NetLogWithSource& net_log); + const std::vector<DownloadItem::ReceivedSlice>& received_slices); // Constructing for a regular download. // |net_log| is constructed externally for our use. DownloadItemImpl(DownloadItemImplDelegate* delegate, uint32_t id, - const DownloadCreateInfo& info, - const net::NetLogWithSource& net_log); + const DownloadCreateInfo& info); // Constructing for the "Save Page As..." feature: // |net_log| is constructed externally for our use. @@ -196,8 +192,7 @@ const base::FilePath& path, const GURL& url, const std::string& mime_type, - std::unique_ptr<DownloadRequestHandleInterface> request_handle, - const net::NetLogWithSource& net_log); + std::unique_ptr<DownloadRequestHandleInterface> request_handle); ~DownloadItemImpl() override; @@ -307,9 +302,6 @@ virtual base::WeakPtr<DownloadDestinationObserver> DestinationObserverAsWeakPtr(); - // Get the download's NetLogWithSource. - virtual const net::NetLogWithSource& GetNetLogWithSource() const; - // DownloadItemImpl routines only needed by SavePackage ---------------------- // Called by SavePackage to set the total number of bytes on the item. @@ -497,9 +489,8 @@ // Construction common to all constructors. |active| should be true for new // downloads and false for downloads from the history. - // |download_type| indicates to the net log system what kind of download - // this is. - void Init(bool active, DownloadType download_type); + // |download_type| indicates to the trace event what kind of download this is. + void Init(bool active, DownloadItem::DownloadType download_type); // Callback from file thread when we initialize the DownloadFile. void OnDownloadFileInitialized(DownloadInterruptReason result); @@ -747,9 +738,6 @@ // The data slices that have been received so far. std::vector<DownloadItem::ReceivedSlice> received_slices_; - // Net log to use for this download. - const net::NetLogWithSource net_log_; - std::unique_ptr<DownloadJob> job_; // Value of |received_bytes_| at the time the download was interrupted with
diff --git a/content/browser/download/download_item_impl_unittest.cc b/content/browser/download/download_item_impl_unittest.cc index 0797c3c1..6b0e71b 100644 --- a/content/browser/download/download_item_impl_unittest.cc +++ b/content/browser/download/download_item_impl_unittest.cc
@@ -277,9 +277,8 @@ DownloadItemImpl* CreateDownloadItemWithCreateInfo( std::unique_ptr<DownloadCreateInfo> info) { - DownloadItemImpl* download = - new DownloadItemImpl(mock_delegate(), next_download_id_++, - *(info.get()), net::NetLogWithSource()); + DownloadItemImpl* download = new DownloadItemImpl( + mock_delegate(), next_download_id_++, *(info.get())); allocated_downloads_[download] = base::WrapUnique(download); return download; } @@ -296,9 +295,8 @@ // called. DownloadItemImpl* CreateDownloadItem() { create_info_->download_id = ++next_download_id_; - DownloadItemImpl* download = - new DownloadItemImpl(mock_delegate(), create_info_->download_id, - *create_info_, net::NetLogWithSource()); + DownloadItemImpl* download = new DownloadItemImpl( + mock_delegate(), create_info_->download_id, *create_info_); allocated_downloads_[download] = base::WrapUnique(download); return download; }
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc index 474e2b2..675b085 100644 --- a/content/browser/download/download_manager_impl.cc +++ b/content/browser/download/download_manager_impl.cc
@@ -56,8 +56,6 @@ #include "net/base/load_flags.h" #include "net/base/request_priority.h" #include "net/base/upload_bytes_element_reader.h" -#include "net/log/net_log_source_type.h" -#include "net/log/net_log_with_source.h" #include "net/url_request/url_request_context.h" #include "storage/browser/blob/blob_url_request_job_factory.h" #include "url/origin.h" @@ -103,7 +101,7 @@ base::WeakPtr<DownloadManagerImpl> download_manager) { DCHECK_CURRENTLY_ON(BrowserThread::IO); std::unique_ptr<DownloadCreateInfo> failed_created_info( - new DownloadCreateInfo(base::Time::Now(), net::NetLogWithSource(), + new DownloadCreateInfo(base::Time::Now(), base::WrapUnique(new DownloadSaveInfo))); failed_created_info->url_chain.push_back(params->url()); failed_created_info->result = reason; @@ -244,22 +242,20 @@ bool opened, base::Time last_access_time, bool transient, - const std::vector<DownloadItem::ReceivedSlice>& received_slices, - const net::NetLogWithSource& net_log) override { + const std::vector<DownloadItem::ReceivedSlice>& received_slices) + override { return new DownloadItemImpl( delegate, guid, download_id, current_path, target_path, url_chain, referrer_url, site_url, tab_url, tab_refererr_url, mime_type, original_mime_type, start_time, end_time, etag, last_modified, received_bytes, total_bytes, hash, state, danger_type, interrupt_reason, - opened, last_access_time, transient, received_slices, net_log); + opened, last_access_time, transient, received_slices); } - DownloadItemImpl* CreateActiveItem( - DownloadItemImplDelegate* delegate, - uint32_t download_id, - const DownloadCreateInfo& info, - const net::NetLogWithSource& net_log) override { - return new DownloadItemImpl(delegate, download_id, info, net_log); + DownloadItemImpl* CreateActiveItem(DownloadItemImplDelegate* delegate, + uint32_t download_id, + const DownloadCreateInfo& info) override { + return new DownloadItemImpl(delegate, download_id, info); } DownloadItemImpl* CreateSavePageItem( @@ -268,10 +264,9 @@ const base::FilePath& path, const GURL& url, const std::string& mime_type, - std::unique_ptr<DownloadRequestHandleInterface> request_handle, - const net::NetLogWithSource& net_log) override { + std::unique_ptr<DownloadRequestHandleInterface> request_handle) override { return new DownloadItemImpl(delegate, download_id, path, url, mime_type, - std::move(request_handle), net_log); + std::move(request_handle)); } }; @@ -291,7 +286,6 @@ initialized_(false), browser_context_(browser_context), delegate_(nullptr), - net_log_(nullptr), weak_factory_(this) { DCHECK(browser_context); } @@ -305,10 +299,7 @@ const DownloadCreateInfo& info) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(!base::ContainsKey(downloads_, id)); - net::NetLogWithSource net_log = - net::NetLogWithSource::Make(net_log_, net::NetLogSourceType::DOWNLOAD); - DownloadItemImpl* download = - item_factory_->CreateActiveItem(this, id, info, net_log); + DownloadItemImpl* download = item_factory_->CreateActiveItem(this, id, info); downloads_[id] = base::WrapUnique(download); downloads_by_guid_[download->GetGuid()] = download; return download; @@ -488,8 +479,7 @@ DCHECK(stream.get()); download_file.reset(file_factory_->CreateFile( std::move(info->save_info), default_download_directory, - std::move(stream), download->GetNetLogWithSource(), - download->DestinationObserverAsWeakPtr())); + std::move(stream), id, download->DestinationObserverAsWeakPtr())); } // It is important to leave info->save_info intact in the case of an interrupt // so that the DownloadItem can salvage what it can out of a failed resumption @@ -574,11 +564,8 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_NE(content::DownloadItem::kInvalidId, id); DCHECK(!base::ContainsKey(downloads_, id)); - net::NetLogWithSource net_log = - net::NetLogWithSource::Make(net_log_, net::NetLogSourceType::DOWNLOAD); DownloadItemImpl* download_item = item_factory_->CreateSavePageItem( - this, id, main_file_path, page_url, mime_type, std::move(request_handle), - net_log); + this, id, main_file_path, page_url, mime_type, std::move(request_handle)); downloads_[download_item->GetId()] = base::WrapUnique(download_item); DCHECK(!base::ContainsKey(downloads_by_guid_, download_item->GetGuid())); downloads_by_guid_[download_item->GetGuid()] = download_item; @@ -773,8 +760,7 @@ site_url, tab_url, tab_refererr_url, mime_type, original_mime_type, start_time, end_time, etag, last_modified, received_bytes, total_bytes, hash, state, danger_type, interrupt_reason, opened, last_access_time, - transient, received_slices, - net::NetLogWithSource::Make(net_log_, net::NetLogSourceType::DOWNLOAD)); + transient, received_slices); downloads_[id] = base::WrapUnique(item); downloads_by_guid_[guid] = item; for (auto& observer : observers_)
diff --git a/content/browser/download/download_manager_impl.h b/content/browser/download/download_manager_impl.h index ead13aa..368a104 100644 --- a/content/browser/download/download_manager_impl.h +++ b/content/browser/download/download_manager_impl.h
@@ -30,10 +30,6 @@ #include "content/public/browser/download_url_parameters.h" #include "content/public/browser/ssl_status.h" -namespace net { -class NetLog; -} - namespace content { class DownloadFileFactory; class DownloadItemFactory; @@ -251,8 +247,6 @@ // Allows an embedder to control behavior. Guaranteed to outlive this object. DownloadManagerDelegate* delegate_; - net::NetLog* net_log_; - std::vector<UniqueUrlDownloadHandlerPtr> url_download_handlers_; base::WeakPtrFactory<DownloadManagerImpl> weak_factory_;
diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc index 01b76bd..c59f97f 100644 --- a/content/browser/download/download_manager_impl_unittest.cc +++ b/content/browser/download/download_manager_impl_unittest.cc
@@ -40,7 +40,6 @@ #include "content/public/test/mock_download_item.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" -#include "net/log/net_log_with_source.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" @@ -154,21 +153,17 @@ bool opened, base::Time last_access_time, bool transient, - const std::vector<DownloadItem::ReceivedSlice>& received_slices, - const net::NetLogWithSource& net_log) override; - DownloadItemImpl* CreateActiveItem( - DownloadItemImplDelegate* delegate, - uint32_t download_id, - const DownloadCreateInfo& info, - const net::NetLogWithSource& net_log) override; + const std::vector<DownloadItem::ReceivedSlice>& received_slices) override; + DownloadItemImpl* CreateActiveItem(DownloadItemImplDelegate* delegate, + uint32_t download_id, + const DownloadCreateInfo& info) override; DownloadItemImpl* CreateSavePageItem( DownloadItemImplDelegate* delegate, uint32_t download_id, const base::FilePath& path, const GURL& url, const std::string& mime_type, - std::unique_ptr<DownloadRequestHandleInterface> request_handle, - const net::NetLogWithSource& net_log) override; + std::unique_ptr<DownloadRequestHandleInterface> request_handle) override; private: std::map<uint32_t, MockDownloadItemImpl*> items_; @@ -229,8 +224,7 @@ bool opened, base::Time last_access_time, bool transient, - const std::vector<DownloadItem::ReceivedSlice>& received_slices, - const net::NetLogWithSource& net_log) { + const std::vector<DownloadItem::ReceivedSlice>& received_slices) { DCHECK(items_.find(download_id) == items_.end()); MockDownloadItemImpl* result = new StrictMock<MockDownloadItemImpl>(&item_delegate_); @@ -244,8 +238,7 @@ DownloadItemImpl* MockDownloadItemFactory::CreateActiveItem( DownloadItemImplDelegate* delegate, uint32_t download_id, - const DownloadCreateInfo& info, - const net::NetLogWithSource& net_log) { + const DownloadCreateInfo& info) { DCHECK(items_.find(download_id) == items_.end()); MockDownloadItemImpl* result = @@ -269,8 +262,7 @@ const base::FilePath& path, const GURL& url, const std::string& mime_type, - std::unique_ptr<DownloadRequestHandleInterface> request_handle, - const net::NetLogWithSource& net_log) { + std::unique_ptr<DownloadRequestHandleInterface> request_handle) { DCHECK(items_.find(download_id) == items_.end()); MockDownloadItemImpl* result = @@ -298,7 +290,7 @@ std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_download_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer) override { return MockCreateFile(*save_info, stream.get()); }
diff --git a/content/browser/download/download_net_log_parameters.cc b/content/browser/download/download_net_log_parameters.cc deleted file mode 100644 index d74de475..0000000 --- a/content/browser/download/download_net_log_parameters.cc +++ /dev/null
@@ -1,212 +0,0 @@ -// Copyright (c) 2012 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 "content/browser/download/download_net_log_parameters.h" - -#include <utility> - -#include "base/files/file_path.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/strings/string_number_conversions.h" -#include "base/values.h" -#include "content/public/browser/download_interrupt_reasons.h" -#include "net/base/net_errors.h" -#include "net/log/net_log_capture_mode.h" -#include "url/gurl.h" - -namespace content { - -namespace { - -static const char* const download_type_names[] = { - "NEW_DOWNLOAD", - "HISTORY_IMPORT", - "SAVE_PAGE_AS" -}; -static const char* const download_danger_names[] = { - "NOT_DANGEROUS", - "DANGEROUS_FILE", - "DANGEROUS_URL", - "DANGEROUS_CONTENT", - "MAYBE_DANGEROUS_CONTENT", - "UNCOMMON_CONTENT", - "USER_VALIDATED", - "DANGEROUS_HOST", - "POTENTIALLY_UNWANTED" -}; - -static_assert(arraysize(download_type_names) == SRC_SAVE_PAGE_AS + 1, - "download type enum has changed"); -static_assert(arraysize(download_danger_names) == DOWNLOAD_DANGER_TYPE_MAX, - "download danger enum has changed"); - -} // namespace - -std::unique_ptr<base::Value> ItemActivatedNetLogCallback( - const DownloadItem* download_item, - DownloadType download_type, - const std::string* file_name, - net::NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - - dict->SetString("type", download_type_names[download_type]); - dict->SetString("id", base::UintToString(download_item->GetId())); - dict->SetString("original_url", download_item->GetOriginalUrl().spec()); - dict->SetString("final_url", download_item->GetURL().spec()); - dict->SetString("file_name", *file_name); - dict->SetString("danger_type", - download_danger_names[download_item->GetDangerType()]); - dict->SetString("start_offset", - base::Int64ToString(download_item->GetReceivedBytes())); - dict->SetBoolean("has_user_gesture", download_item->HasUserGesture()); - - return std::move(dict); -} - -std::unique_ptr<base::Value> ItemCheckedNetLogCallback( - DownloadDangerType danger_type, - net::NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - - dict->SetString("danger_type", download_danger_names[danger_type]); - - return std::move(dict); -} - -std::unique_ptr<base::Value> ItemRenamedNetLogCallback( - const base::FilePath* old_filename, - const base::FilePath* new_filename, - net::NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - - dict->SetString("old_filename", old_filename->AsUTF8Unsafe()); - dict->SetString("new_filename", new_filename->AsUTF8Unsafe()); - - return std::move(dict); -} - -std::unique_ptr<base::Value> ItemInterruptedNetLogCallback( - DownloadInterruptReason reason, - int64_t bytes_so_far, - net::NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - - dict->SetString("interrupt_reason", DownloadInterruptReasonToString(reason)); - dict->SetString("bytes_so_far", base::Int64ToString(bytes_so_far)); - - return std::move(dict); -} - -std::unique_ptr<base::Value> ItemResumingNetLogCallback( - bool user_initiated, - DownloadInterruptReason reason, - int64_t bytes_so_far, - net::NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - - dict->SetString("user_initiated", user_initiated ? "true" : "false"); - dict->SetString("interrupt_reason", DownloadInterruptReasonToString(reason)); - dict->SetString("bytes_so_far", base::Int64ToString(bytes_so_far)); - - return std::move(dict); -} - -std::unique_ptr<base::Value> ItemCompletingNetLogCallback( - int64_t bytes_so_far, - const std::string* final_hash, - net::NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - - dict->SetString("bytes_so_far", base::Int64ToString(bytes_so_far)); - dict->SetString("final_hash", - base::HexEncode(final_hash->data(), final_hash->size())); - - return std::move(dict); -} - -std::unique_ptr<base::Value> ItemFinishedNetLogCallback( - bool auto_opened, - net::NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - - dict->SetString("auto_opened", auto_opened ? "yes" : "no"); - - return std::move(dict); -} - -std::unique_ptr<base::Value> ItemCanceledNetLogCallback( - int64_t bytes_so_far, - net::NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - - dict->SetString("bytes_so_far", base::Int64ToString(bytes_so_far)); - - return std::move(dict); -} - -std::unique_ptr<base::Value> FileOpenedNetLogCallback( - const base::FilePath* file_name, - int64_t start_offset, - net::NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - - dict->SetString("file_name", file_name->AsUTF8Unsafe()); - dict->SetString("start_offset", base::Int64ToString(start_offset)); - - return std::move(dict); -} - -std::unique_ptr<base::Value> FileStreamDrainedNetLogCallback( - size_t stream_size, - size_t num_buffers, - net::NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - - dict->SetInteger("stream_size", static_cast<int>(stream_size)); - dict->SetInteger("num_buffers", static_cast<int>(num_buffers)); - - return std::move(dict); -} - -std::unique_ptr<base::Value> FileRenamedNetLogCallback( - const base::FilePath* old_filename, - const base::FilePath* new_filename, - net::NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - - dict->SetString("old_filename", old_filename->AsUTF8Unsafe()); - dict->SetString("new_filename", new_filename->AsUTF8Unsafe()); - - return std::move(dict); -} - -std::unique_ptr<base::Value> FileErrorNetLogCallback( - const char* operation, - net::Error net_error, - net::NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - - dict->SetString("operation", operation); - dict->SetInteger("net_error", net_error); - - return std::move(dict); -} - -std::unique_ptr<base::Value> FileInterruptedNetLogCallback( - const char* operation, - int os_error, - DownloadInterruptReason reason, - net::NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - - dict->SetString("operation", operation); - if (os_error != 0) - dict->SetInteger("os_error", os_error); - dict->SetString("interrupt_reason", DownloadInterruptReasonToString(reason)); - - return std::move(dict); -} - -} // namespace content
diff --git a/content/browser/download/download_net_log_parameters.h b/content/browser/download/download_net_log_parameters.h deleted file mode 100644 index 0e816b3..0000000 --- a/content/browser/download/download_net_log_parameters.h +++ /dev/null
@@ -1,113 +0,0 @@ -// Copyright (c) 2012 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 CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_NET_LOG_PARAMETERS_H_ -#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_NET_LOG_PARAMETERS_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <string> - -#include "content/public/browser/download_item.h" -#include "net/base/net_errors.h" - -namespace base { -class FilePath; -class Value; -} - -namespace net { -class NetLogCaptureMode; -} - -namespace content { - -enum DownloadType { - SRC_ACTIVE_DOWNLOAD, - SRC_HISTORY_IMPORT, - SRC_SAVE_PAGE_AS -}; - -// Returns NetLog parameters when a DownloadItem is activated. -std::unique_ptr<base::Value> ItemActivatedNetLogCallback( - const DownloadItem* download_item, - DownloadType download_type, - const std::string* file_name, - net::NetLogCaptureMode capture_mode); - -// Returns NetLog parameters when a DownloadItem is checked for danger. -std::unique_ptr<base::Value> ItemCheckedNetLogCallback( - DownloadDangerType danger_type, - net::NetLogCaptureMode capture_mode); - -// Returns NetLog parameters when a DownloadItem is renamed. -std::unique_ptr<base::Value> ItemRenamedNetLogCallback( - const base::FilePath* old_filename, - const base::FilePath* new_filename, - net::NetLogCaptureMode capture_mode); - -// Returns NetLog parameters when a DownloadItem is interrupted. -std::unique_ptr<base::Value> ItemInterruptedNetLogCallback( - DownloadInterruptReason reason, - int64_t bytes_so_far, - net::NetLogCaptureMode capture_mode); - -// Returns NetLog parameters when a DownloadItem is resumed. -std::unique_ptr<base::Value> ItemResumingNetLogCallback( - bool user_initiated, - DownloadInterruptReason reason, - int64_t bytes_so_far, - net::NetLogCaptureMode capture_mode); - -// Returns NetLog parameters when a DownloadItem is completing. -std::unique_ptr<base::Value> ItemCompletingNetLogCallback( - int64_t bytes_so_far, - const std::string* final_hash, - net::NetLogCaptureMode capture_mode); - -// Returns NetLog parameters when a DownloadItem is finished. -std::unique_ptr<base::Value> ItemFinishedNetLogCallback( - bool auto_opened, - net::NetLogCaptureMode capture_mode); - -// Returns NetLog parameters when a DownloadItem is canceled. -std::unique_ptr<base::Value> ItemCanceledNetLogCallback( - int64_t bytes_so_far, - net::NetLogCaptureMode capture_mode); - -// Returns NetLog parameters when a DownloadFile is opened. -std::unique_ptr<base::Value> FileOpenedNetLogCallback( - const base::FilePath* file_name, - int64_t start_offset, - net::NetLogCaptureMode capture_mode); - -// Returns NetLog parameters when a DownloadFile is opened. -std::unique_ptr<base::Value> FileStreamDrainedNetLogCallback( - size_t stream_size, - size_t num_buffers, - net::NetLogCaptureMode capture_mode); - -// Returns NetLog parameters when a DownloadFile is renamed. -std::unique_ptr<base::Value> FileRenamedNetLogCallback( - const base::FilePath* old_filename, - const base::FilePath* new_filename, - net::NetLogCaptureMode capture_mode); - -// Returns NetLog parameters when a File has an error. -std::unique_ptr<base::Value> FileErrorNetLogCallback( - const char* operation, - net::Error net_error, - net::NetLogCaptureMode capture_mode); - -// Returns NetLog parameters for a download interruption. -std::unique_ptr<base::Value> FileInterruptedNetLogCallback( - const char* operation, - int os_error, - DownloadInterruptReason reason, - net::NetLogCaptureMode capture_mode); - -} // namespace content - -#endif // CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_NET_LOG_PARAMETERS_H_
diff --git a/content/browser/download/download_request_core.cc b/content/browser/download/download_request_core.cc index f11f2e1d..1f4ff5b0 100644 --- a/content/browser/download/download_request_core.cc +++ b/content/browser/download/download_request_core.cc
@@ -190,8 +190,8 @@ DownloadRequestCore::CreateDownloadCreateInfo(DownloadInterruptReason result) { DCHECK(!started_); started_ = true; - std::unique_ptr<DownloadCreateInfo> create_info(new DownloadCreateInfo( - base::Time::Now(), request()->net_log(), std::move(save_info_))); + std::unique_ptr<DownloadCreateInfo> create_info( + new DownloadCreateInfo(base::Time::Now(), std::move(save_info_))); if (result == DOWNLOAD_INTERRUPT_REASON_NONE) create_info->remote_address = request()->GetSocketAddress().host();
diff --git a/content/browser/download/download_response_handler.cc b/content/browser/download/download_response_handler.cc index 2d982c9..7879b771 100644 --- a/content/browser/download/download_response_handler.cc +++ b/content/browser/download/download_response_handler.cc
@@ -107,8 +107,8 @@ const ResourceResponseHead& head) { // TODO(qinmin): instead of using NetLogWithSource, introduce new logging // class for download. - auto create_info = std::make_unique<DownloadCreateInfo>( - base::Time::Now(), net::NetLogWithSource(), std::move(save_info_)); + auto create_info = base::MakeUnique<DownloadCreateInfo>( + base::Time::Now(), std::move(save_info_)); DownloadInterruptReason result = head.headers
diff --git a/content/browser/download/mock_download_item_impl.cc b/content/browser/download/mock_download_item_impl.cc index 37a92c9..ab1eb1f 100644 --- a/content/browser/download/mock_download_item_impl.cc +++ b/content/browser/download/mock_download_item_impl.cc
@@ -32,8 +32,7 @@ false, base::Time(), true, - DownloadItem::ReceivedSlices(), - net::NetLogWithSource()) {} + DownloadItem::ReceivedSlices()) {} MockDownloadItemImpl::~MockDownloadItemImpl() = default;
diff --git a/content/browser/download/parallel_download_job_unittest.cc b/content/browser/download/parallel_download_job_unittest.cc index 3c5a172..1ce7294b 100644 --- a/content/browser/download/parallel_download_job_unittest.cc +++ b/content/browser/download/parallel_download_job_unittest.cc
@@ -452,7 +452,7 @@ std::move(save_info), base::FilePath(), std::make_unique<DownloadManager::InputStream>( std::unique_ptr<ByteStreamReader>(input_stream)), - net::NetLogWithSource(), observer_factory.GetWeakPtr()); + DownloadItem::kInvalidId, observer_factory.GetWeakPtr()); CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2, 0, 0); job_->Start(download_file.get(), base::Bind(&ParallelDownloadJobTest::OnFileInitialized,
diff --git a/content/browser/download/save_file.cc b/content/browser/download/save_file.cc index a9b0aae..ac029b17 100644 --- a/content/browser/download/save_file.cc +++ b/content/browser/download/save_file.cc
@@ -6,7 +6,7 @@ #include "base/logging.h" #include "content/browser/download/download_task_runner.h" -#include "net/log/net_log_with_source.h" +#include "content/public/browser/download_item.h" namespace content { @@ -15,7 +15,7 @@ // Unfortunately, as it is, constructors of SaveFile don't always // have access to the SavePackage at this point. SaveFile::SaveFile(const SaveFileCreateInfo* info, bool calculate_hash) - : file_(net::NetLogWithSource()), info_(info) { + : file_(DownloadItem::kInvalidId), info_(info) { DCHECK(GetDownloadTaskRunner()->RunsTasksInCurrentSequence()); DCHECK(info);
diff --git a/content/browser/gpu/gpu_data_manager_impl.cc b/content/browser/gpu/gpu_data_manager_impl.cc index 5a3d62c..fc442119 100644 --- a/content/browser/gpu/gpu_data_manager_impl.cc +++ b/content/browser/gpu/gpu_data_manager_impl.cc
@@ -165,11 +165,6 @@ private_->GpuAccessAllowed(nullptr); } -bool GpuDataManagerImpl::CanUseGpuBrowserCompositor() const { - base::AutoLock auto_lock(lock_); - return private_->CanUseGpuBrowserCompositor(); -} - void GpuDataManagerImpl::GetDisabledExtensions( std::string* disabled_extensions) const { base::AutoLock auto_lock(lock_);
diff --git a/content/browser/gpu/gpu_data_manager_impl.h b/content/browser/gpu/gpu_data_manager_impl.h index ebaf2b9..6f81e672 100644 --- a/content/browser/gpu/gpu_data_manager_impl.h +++ b/content/browser/gpu/gpu_data_manager_impl.h
@@ -95,7 +95,6 @@ std::string* gl_version) override; void DisableHardwareAcceleration() override; bool HardwareAccelerationEnabled() const override; - bool CanUseGpuBrowserCompositor() const override; void GetDisabledExtensions(std::string* disabled_extensions) const override; void SetGpuInfo(const gpu::GPUInfo& gpu_info) override;
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc index 571ff80..47d2eeb 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private.cc +++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -803,16 +803,12 @@ void GpuDataManagerImplPrivate::UpdateRendererWebPrefs( WebPreferences* prefs) const { DCHECK(prefs); - -#if defined(USE_AURA) - if (!CanUseGpuBrowserCompositor()) { - prefs->accelerated_2d_canvas_enabled = false; - prefs->pepper_3d_enabled = false; - } -#endif - const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + // TODO(zmo): Remove this when we check on the renderer side for 2d canvas. + if (command_line->HasSwitch(switches::kDisableGpuCompositing)) { + prefs->accelerated_2d_canvas_enabled = false; + } if (!ShouldDisableAcceleratedVideoDecode(command_line) && !command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) { prefs->pepper_accelerated_video_decode_enabled = true; @@ -961,17 +957,6 @@ return true; } -bool GpuDataManagerImplPrivate::CanUseGpuBrowserCompositor() const { - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableGpuCompositing)) - return false; - if (ShouldUseSwiftShader()) - return false; - if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING)) - return false; - return true; -} - bool GpuDataManagerImplPrivate::ShouldDisableAcceleratedVideoDecode( const base::CommandLine* command_line) const { if (command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) {
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.h b/content/browser/gpu/gpu_data_manager_impl_private.h index 8862506d..369d07b0 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private.h +++ b/content/browser/gpu/gpu_data_manager_impl_private.h
@@ -95,7 +95,6 @@ void HandleGpuSwitch(); - bool CanUseGpuBrowserCompositor() const; bool ShouldDisableAcceleratedVideoDecode( const base::CommandLine* command_line) const;
diff --git a/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_browsertest.cc index a74b7bc2..62e8d99a 100644 --- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc +++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -17,7 +17,6 @@ #include "build/build_config.h" #include "cc/paint/skia_paint_canvas.h" #include "content/browser/gpu/compositor_util.h" -#include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/browser/renderer_host/dip_util.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" @@ -677,14 +676,11 @@ run_loop.QuitClosure()); rwhv->CopyFromSurfaceToVideoFrame(copy_rect, video_frame, callback); } else { - if (!content::GpuDataManager::GetInstance() - ->CanUseGpuBrowserCompositor()) { - // Skia rendering can cause color differences, particularly in the - // middle two columns. - SetAllowableError(2); - SetExcludeRect(gfx::Rect(output_size.width() / 2 - 1, 0, 2, - output_size.height())); - } + // Skia rendering can cause color differences, particularly in the + // middle two columns. + SetAllowableError(2); + SetExcludeRect( + gfx::Rect(output_size.width() / 2 - 1, 0, 2, output_size.height())); const ReadbackRequestCallback callback = base::Bind(&CompositingRenderWidgetHostViewBrowserTestTabCapture::
diff --git a/content/browser/service_worker/service_worker_consts.cc b/content/browser/service_worker/service_worker_consts.cc new file mode 100644 index 0000000..0a6663f --- /dev/null +++ b/content/browser/service_worker/service_worker_consts.cc
@@ -0,0 +1,52 @@ +// Copyright 2017 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 "content/browser/service_worker/service_worker_consts.h" + +namespace content { + +const char ServiceWorkerConsts::kBadMessageFromNonWindow[] = + "The request message should not come from a non-window client."; + +const char ServiceWorkerConsts::kBadMessageGetRegistrationForReadyDuplicated[] = + "There's already a completed or ongoing request to get the ready " + "registration."; + +const char ServiceWorkerConsts::kBadMessageImproperOrigins[] = + "Origins are not matching, or some cannot access service worker."; + +const char ServiceWorkerConsts::kBadMessageInvalidURL[] = + "Some URLs are invalid."; + +const char ServiceWorkerConsts::kBadNavigationPreloadHeaderValue[] = + "The navigation preload header value is invalid."; + +const char ServiceWorkerConsts::kDatabaseErrorMessage[] = + "Failed to access storage."; + +const char ServiceWorkerConsts::kEnableNavigationPreloadErrorPrefix[] = + "Failed to enable or disable navigation preload: "; + +const char ServiceWorkerConsts::kGetNavigationPreloadStateErrorPrefix[] = + "Failed to get navigation preload state: "; + +const char ServiceWorkerConsts::kInvalidStateErrorMessage[] = + "The object is in an invalid state."; + +const char ServiceWorkerConsts::kNoActiveWorkerErrorMessage[] = + "The registration does not have an active worker."; + +const char ServiceWorkerConsts::kNoDocumentURLErrorMessage[] = + "No URL is associated with the caller's document."; + +const char ServiceWorkerConsts::kSetNavigationPreloadHeaderErrorPrefix[] = + "Failed to set navigation preload header: "; + +const char ServiceWorkerConsts::kShutdownErrorMessage[] = + "The Service Worker system has shutdown."; + +const char ServiceWorkerConsts::kUserDeniedPermissionMessage[] = + "The user denied permission to use Service Worker."; + +} // namespace content
diff --git a/content/browser/service_worker/service_worker_consts.h b/content/browser/service_worker/service_worker_consts.h new file mode 100644 index 0000000..d119a47 --- /dev/null +++ b/content/browser/service_worker/service_worker_consts.h
@@ -0,0 +1,29 @@ +// Copyright 2017 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 CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONSTS_H_ +#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONSTS_H_ + +namespace content { + +struct ServiceWorkerConsts { + static const char kBadMessageFromNonWindow[]; + static const char kBadMessageGetRegistrationForReadyDuplicated[]; + static const char kBadMessageImproperOrigins[]; + static const char kBadMessageInvalidURL[]; + static const char kBadNavigationPreloadHeaderValue[]; + static const char kDatabaseErrorMessage[]; + static const char kEnableNavigationPreloadErrorPrefix[]; + static const char kGetNavigationPreloadStateErrorPrefix[]; + static const char kInvalidStateErrorMessage[]; + static const char kNoActiveWorkerErrorMessage[]; + static const char kNoDocumentURLErrorMessage[]; + static const char kSetNavigationPreloadHeaderErrorPrefix[]; + static const char kShutdownErrorMessage[]; + static const char kUserDeniedPermissionMessage[]; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONSTS_H_
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index c3f8407..ba845718 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -15,6 +15,7 @@ #include "content/browser/bad_message.h" #include "content/browser/interface_provider_filtering.h" #include "content/browser/service_worker/embedded_worker_status.h" +#include "content/browser/service_worker/service_worker_consts.h" #include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_context_request_handler.h" #include "content/browser/service_worker/service_worker_controllee_request_handler.h" @@ -48,21 +49,6 @@ namespace { -const char kNoDocumentURLErrorMessage[] = - "No URL is associated with the caller's document."; -const char kShutdownErrorMessage[] = "The Service Worker system has shutdown."; -const char kUserDeniedPermissionMessage[] = - "The user denied permission to use Service Worker."; - -const char kBadMessageInvalidURL[] = "Some URLs are invalid."; -const char kBadMessageInproperOrigins[] = - "Origins are not matching, or some cannot access service worker."; -const char kBadMessageFromNonWindow[] = - "The request message should not come from a non-window client."; -const char kBadMessageGetRegistrationForReadyDuplicated[] = - "There's already a completed or ongoing request to get the ready " - "registration."; - // Provider host for navigation with PlzNavigate or when service worker's // context is created on the browser side. This function provides the next // ServiceWorkerProviderHost ID for them, starts at -2 and keeps going down. @@ -928,10 +914,11 @@ trace_id, "Status", status, "Registration ID", registration_id); if (!dispatcher_host_ || !IsContextAlive()) { - std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kAbort, - std::string(kServiceWorkerRegisterErrorPrefix) + - std::string(kShutdownErrorMessage), - nullptr); + std::move(callback).Run( + blink::mojom::ServiceWorkerErrorType::kAbort, + std::string(kServiceWorkerRegisterErrorPrefix) + + std::string(ServiceWorkerConsts::kShutdownErrorMessage), + nullptr); return; } @@ -1027,7 +1014,7 @@ std::move(callback).Run( blink::mojom::ServiceWorkerErrorType::kAbort, std::string(kServiceWorkerGetRegistrationErrorPrefix) + - std::string(kShutdownErrorMessage), + std::string(ServiceWorkerConsts::kShutdownErrorMessage), nullptr); return; } @@ -1065,7 +1052,7 @@ std::move(callback).Run( blink::mojom::ServiceWorkerErrorType::kAbort, std::string(kServiceWorkerGetRegistrationsErrorPrefix) + - std::string(kShutdownErrorMessage), + std::string(ServiceWorkerConsts::kShutdownErrorMessage), base::nullopt); return; } @@ -1142,11 +1129,11 @@ const blink::mojom::ServiceWorkerRegistrationOptions& options, std::string* out_error) const { if (client_type() != blink::kWebServiceWorkerClientTypeWindow) { - *out_error = kBadMessageFromNonWindow; + *out_error = ServiceWorkerConsts::kBadMessageFromNonWindow; return false; } if (!options.scope.is_valid() || !script_url.is_valid()) { - *out_error = kBadMessageInvalidURL; + *out_error = ServiceWorkerConsts::kBadMessageInvalidURL; return false; } if (ServiceWorkerUtils::ContainsDisallowedCharacter(options.scope, script_url, @@ -1155,7 +1142,7 @@ } std::vector<GURL> urls = {document_url(), options.scope, script_url}; if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) { - *out_error = kBadMessageInproperOrigins; + *out_error = ServiceWorkerConsts::kBadMessageImproperOrigins; return false; } @@ -1166,16 +1153,16 @@ const GURL& client_url, std::string* out_error) const { if (client_type() != blink::kWebServiceWorkerClientTypeWindow) { - *out_error = kBadMessageFromNonWindow; + *out_error = ServiceWorkerConsts::kBadMessageFromNonWindow; return false; } if (!client_url.is_valid()) { - *out_error = kBadMessageInvalidURL; + *out_error = ServiceWorkerConsts::kBadMessageInvalidURL; return false; } std::vector<GURL> urls = {document_url(), client_url}; if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) { - *out_error = kBadMessageInproperOrigins; + *out_error = ServiceWorkerConsts::kBadMessageImproperOrigins; return false; } @@ -1185,11 +1172,11 @@ bool ServiceWorkerProviderHost::IsValidGetRegistrationsMessage( std::string* out_error) const { if (client_type() != blink::kWebServiceWorkerClientTypeWindow) { - *out_error = kBadMessageFromNonWindow; + *out_error = ServiceWorkerConsts::kBadMessageFromNonWindow; return false; } if (!OriginCanAccessServiceWorkers(document_url())) { - *out_error = kBadMessageInproperOrigins; + *out_error = ServiceWorkerConsts::kBadMessageImproperOrigins; return false; } @@ -1199,12 +1186,13 @@ bool ServiceWorkerProviderHost::IsValidGetRegistrationForReadyMessage( std::string* out_error) const { if (client_type() != blink::kWebServiceWorkerClientTypeWindow) { - *out_error = kBadMessageFromNonWindow; + *out_error = ServiceWorkerConsts::kBadMessageFromNonWindow; return false; } if (get_ready_callback_) { - *out_error = kBadMessageGetRegistrationForReadyDuplicated; + *out_error = + ServiceWorkerConsts::kBadMessageGetRegistrationForReadyDuplicated; return false; } @@ -1233,7 +1221,8 @@ if (!dispatcher_host_ || !IsContextAlive()) { std::move(*callback).Run( blink::mojom::ServiceWorkerErrorType::kAbort, - std::string(error_prefix) + std::string(kShutdownErrorMessage), + std::string(error_prefix) + + std::string(ServiceWorkerConsts::kShutdownErrorMessage), args...); return false; } @@ -1243,7 +1232,8 @@ if (document_url().is_empty()) { std::move(*callback).Run( blink::mojom::ServiceWorkerErrorType::kSecurity, - std::string(error_prefix) + std::string(kNoDocumentURLErrorMessage), + std::string(error_prefix) + + std::string(ServiceWorkerConsts::kNoDocumentURLErrorMessage), args...); return false; } @@ -1253,7 +1243,8 @@ base::Bind(&GetWebContents, render_process_id_, frame_id()))) { std::move(*callback).Run( blink::mojom::ServiceWorkerErrorType::kDisabled, - std::string(error_prefix) + std::string(kUserDeniedPermissionMessage), + std::string(error_prefix) + + std::string(ServiceWorkerConsts::kUserDeniedPermissionMessage), args...); return false; }
diff --git a/content/browser/service_worker/service_worker_registration_handle.cc b/content/browser/service_worker/service_worker_registration_handle.cc index 0e5abd8c..5da1553 100644 --- a/content/browser/service_worker/service_worker_registration_handle.cc +++ b/content/browser/service_worker/service_worker_registration_handle.cc
@@ -4,6 +4,7 @@ #include "content/browser/service_worker/service_worker_registration_handle.h" +#include "content/browser/service_worker/service_worker_consts.h" #include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_dispatcher_host.h" #include "content/browser/service_worker/service_worker_handle.h" @@ -23,26 +24,6 @@ namespace { -const char kNoDocumentURLErrorMessage[] = - "No URL is associated with the caller's document."; -const char kShutdownErrorMessage[] = "The Service Worker system has shutdown."; -const char kUserDeniedPermissionMessage[] = - "The user denied permission to use Service Worker."; -const char kEnableNavigationPreloadErrorPrefix[] = - "Failed to enable or disable navigation preload: "; -const char kGetNavigationPreloadStateErrorPrefix[] = - "Failed to get navigation preload state: "; -const char kSetNavigationPreloadHeaderErrorPrefix[] = - "Failed to set navigation preload header: "; -const char kInvalidStateErrorMessage[] = "The object is in an invalid state."; -const char kBadMessageImproperOrigins[] = - "Origins are not matching, or some cannot access service worker."; -const char kBadNavigationPreloadHeaderValue[] = - "The navigation preload header value is invalid."; -const char kNoActiveWorkerErrorMessage[] = - "The registration does not have an active worker."; -const char kDatabaseErrorMessage[] = "Failed to access storage."; - WebContents* GetWebContents(int render_process_id, int render_frame_id) { RenderFrameHost* rfh = RenderFrameHost::FromID(render_process_id, render_frame_id); @@ -137,9 +118,10 @@ if (!registration_->GetNewestVersion()) { // This can happen if update() is called during initial script evaluation. // Abort the following steps according to the spec. - std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kState, - std::string(kServiceWorkerUpdateErrorPrefix) + - std::string(kInvalidStateErrorMessage)); + std::move(callback).Run( + blink::mojom::ServiceWorkerErrorType::kState, + std::string(kServiceWorkerUpdateErrorPrefix) + + std::string(ServiceWorkerConsts::kInvalidStateErrorMessage)); return; } @@ -168,14 +150,16 @@ bool enable, EnableNavigationPreloadCallback callback) { if (!CanServeRegistrationObjectHostMethods( - &callback, kEnableNavigationPreloadErrorPrefix)) { + &callback, + ServiceWorkerConsts::kEnableNavigationPreloadErrorPrefix)) { return; } if (!registration_->active_version()) { - std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kState, - std::string(kEnableNavigationPreloadErrorPrefix) + - std::string(kNoActiveWorkerErrorMessage)); + std::move(callback).Run( + blink::mojom::ServiceWorkerErrorType::kState, + std::string(ServiceWorkerConsts::kEnableNavigationPreloadErrorPrefix) + + std::string(ServiceWorkerConsts::kNoActiveWorkerErrorMessage)); return; } @@ -189,7 +173,8 @@ void ServiceWorkerRegistrationHandle::GetNavigationPreloadState( GetNavigationPreloadStateCallback callback) { if (!CanServeRegistrationObjectHostMethods( - &callback, kGetNavigationPreloadStateErrorPrefix, nullptr)) { + &callback, ServiceWorkerConsts::kGetNavigationPreloadStateErrorPrefix, + nullptr)) { return; } @@ -202,22 +187,25 @@ const std::string& value, SetNavigationPreloadHeaderCallback callback) { if (!CanServeRegistrationObjectHostMethods( - &callback, kSetNavigationPreloadHeaderErrorPrefix)) { + &callback, + ServiceWorkerConsts::kSetNavigationPreloadHeaderErrorPrefix)) { return; } if (!registration_->active_version()) { std::move(callback).Run( blink::mojom::ServiceWorkerErrorType::kState, - std::string(kSetNavigationPreloadHeaderErrorPrefix) + - std::string(kNoActiveWorkerErrorMessage)); + std::string( + ServiceWorkerConsts::kSetNavigationPreloadHeaderErrorPrefix) + + std::string(ServiceWorkerConsts::kNoActiveWorkerErrorMessage)); return; } // TODO(falken): Ideally this would match Blink's isValidHTTPHeaderValue. // Chrome's check is less restrictive: it allows non-latin1 characters. if (!net::HttpUtil::IsValidHeaderValue(value)) { - bindings_.ReportBadMessage(kBadNavigationPreloadHeaderValue); + bindings_.ReportBadMessage( + ServiceWorkerConsts::kBadNavigationPreloadHeaderValue); return; } @@ -269,9 +257,10 @@ EnableNavigationPreloadCallback callback, ServiceWorkerStatusCode status) { if (status != SERVICE_WORKER_OK) { - std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kUnknown, - std::string(kEnableNavigationPreloadErrorPrefix) + - std::string(kDatabaseErrorMessage)); + std::move(callback).Run( + blink::mojom::ServiceWorkerErrorType::kUnknown, + std::string(ServiceWorkerConsts::kEnableNavigationPreloadErrorPrefix) + + std::string(ServiceWorkerConsts::kDatabaseErrorMessage)); return; } @@ -288,8 +277,9 @@ if (status != SERVICE_WORKER_OK) { std::move(callback).Run( blink::mojom::ServiceWorkerErrorType::kUnknown, - std::string(kSetNavigationPreloadHeaderErrorPrefix) + - std::string(kDatabaseErrorMessage)); + std::string( + ServiceWorkerConsts::kSetNavigationPreloadHeaderErrorPrefix) + + std::string(ServiceWorkerConsts::kDatabaseErrorMessage)); return; } @@ -342,7 +332,8 @@ if (!provider_host_ || !context_) { std::move(*callback).Run( blink::mojom::ServiceWorkerErrorType::kAbort, - std::string(error_prefix) + std::string(kShutdownErrorMessage), + std::string(error_prefix) + + std::string(ServiceWorkerConsts::kShutdownErrorMessage), args...); return false; } @@ -352,7 +343,8 @@ if (provider_host_->document_url().is_empty()) { std::move(*callback).Run( blink::mojom::ServiceWorkerErrorType::kSecurity, - std::string(error_prefix) + std::string(kNoDocumentURLErrorMessage), + std::string(error_prefix) + + std::string(ServiceWorkerConsts::kNoDocumentURLErrorMessage), args...); return false; } @@ -360,7 +352,7 @@ std::vector<GURL> urls = {provider_host_->document_url(), registration_->pattern()}; if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) { - bindings_.ReportBadMessage(kBadMessageImproperOrigins); + bindings_.ReportBadMessage(ServiceWorkerConsts::kBadMessageImproperOrigins); return false; } @@ -371,7 +363,8 @@ provider_host_->frame_id()))) { std::move(*callback).Run( blink::mojom::ServiceWorkerErrorType::kDisabled, - std::string(error_prefix) + std::string(kUserDeniedPermissionMessage), + std::string(error_prefix) + + std::string(ServiceWorkerConsts::kUserDeniedPermissionMessage), args...); return false; }
diff --git a/content/common/page_state.mojom b/content/common/page_state.mojom index e6afdb43..f30a38c 100644 --- a/content/common/page_state.mojom +++ b/content/common/page_state.mojom
@@ -29,7 +29,7 @@ // compatibility. If re-ordering fields, make sure to retain the original // ordinal value. // Update the below value if your change introduces fields using it. -// Next MinVersion: 1 +// Next MinVersion: 2 // Next Ordinal: 4 struct FileSystemFile { @@ -77,14 +77,17 @@ kManual = 1 }; -// Next Ordinal: 3 +// Next Ordinal: 6 struct ViewState { gfx.mojom.PointF visual_viewport_scroll_offset@0; gfx.mojom.Point scroll_offset@1; double page_scale_factor@2; + // Serialized scroll anchor fields + [MinVersion=1] mojo.common.mojom.String16? scroll_anchor_selector@3; + [MinVersion=1] gfx.mojom.PointF? scroll_anchor_offset@4; + [MinVersion=1] uint64 scroll_anchor_simhash@5 = 0; }; -// Next Ordinal: 12 struct FrameState { mojo.common.mojom.String16? url_string@0; mojo.common.mojom.String16? referrer@1;
diff --git a/content/common/page_state_serialization.cc b/content/common/page_state_serialization.cc index a2ec09f..0e04469 100644 --- a/content/common/page_state_serialization.cc +++ b/content/common/page_state_serialization.cc
@@ -4,8 +4,6 @@ #include "content/common/page_state_serialization.h" -#include <stddef.h> - #include <algorithm> #include <limits> @@ -220,7 +218,7 @@ // 24: Add did save scroll or scale state. // 25: Limit the length of unique names: https://crbug.com/626202 // 26: Switch to mojo-based serialization. -// +// 27: Add serialized scroll anchor to FrameState. // NOTE: If the version is -1, then the pickle contains only a URL string. // See ReadPageState. // @@ -228,7 +226,7 @@ // NOTE: When changing the version, please add a backwards compatibility test. // See PageStateSerializationTest.DumpExpectedPageStateForBackwardsCompat for // instructions on how to generate the new test case. -const int kCurrentVersion = 26; +const int kCurrentVersion = 27; // A bunch of convenience functions to write to/read from SerializeObjects. The // de-serializers assume the input data will be in the correct format and fall @@ -833,6 +831,15 @@ frame->view_state->visual_viewport_scroll_offset = state.visual_viewport_scroll_offset; frame->view_state->page_scale_factor = state.page_scale_factor; + // We discard all scroll anchor data if the selector is over the length + // limit. We don't want to bloat the size of FrameState, and the other + // fields are useless without the selector. + if (state.scroll_anchor_selector && state.scroll_anchor_selector->length() < + kMaxScrollAnchorSelectorLength) { + frame->view_state->scroll_anchor_selector = state.scroll_anchor_selector; + frame->view_state->scroll_anchor_offset = state.scroll_anchor_offset; + frame->view_state->scroll_anchor_simhash = state.scroll_anchor_simhash; + } } frame->item_sequence_number = state.item_sequence_number; @@ -874,6 +881,13 @@ state->page_scale_factor = frame->view_state->page_scale_factor; } + if (frame->view_state) { + state->scroll_anchor_selector = frame->view_state->scroll_anchor_selector; + state->scroll_anchor_offset = + frame->view_state->scroll_anchor_offset.value_or(gfx::PointF()); + state->scroll_anchor_simhash = frame->view_state->scroll_anchor_simhash; + } + state->item_sequence_number = frame->item_sequence_number; state->document_sequence_number = frame->document_sequence_number; @@ -979,7 +993,8 @@ item_sequence_number(0), document_sequence_number(0), page_scale_factor(0.0), - referrer_policy(blink::kWebReferrerPolicyDefault) {} + referrer_policy(blink::kWebReferrerPolicyDefault), + scroll_anchor_simhash(0) {} ExplodedFrameState::ExplodedFrameState(const ExplodedFrameState& other) { assign(other); @@ -1008,6 +1023,9 @@ page_scale_factor = other.page_scale_factor; referrer_policy = other.referrer_policy; http_body = other.http_body; + scroll_anchor_selector = other.scroll_anchor_selector; + scroll_anchor_offset = other.scroll_anchor_offset; + scroll_anchor_simhash = other.scroll_anchor_simhash; children = other.children; }
diff --git a/content/common/page_state_serialization.h b/content/common/page_state_serialization.h index 8f68584..943cc26e 100644 --- a/content/common/page_state_serialization.h +++ b/content/common/page_state_serialization.h
@@ -24,6 +24,8 @@ namespace content { +constexpr int kMaxScrollAnchorSelectorLength = 500; + struct CONTENT_EXPORT ExplodedHttpBody { base::Optional<base::string16> http_content_type; scoped_refptr<ResourceRequestBody> request_body; @@ -48,6 +50,9 @@ double page_scale_factor; blink::WebReferrerPolicy referrer_policy; ExplodedHttpBody http_body; + base::Optional<base::string16> scroll_anchor_selector; + gfx::PointF scroll_anchor_offset; + uint64_t scroll_anchor_simhash; std::vector<ExplodedFrameState> children; ExplodedFrameState();
diff --git a/content/common/page_state_serialization_unittest.cc b/content/common/page_state_serialization_unittest.cc index 2ec8199..ab3dd50 100644 --- a/content/common/page_state_serialization_unittest.cc +++ b/content/common/page_state_serialization_unittest.cc
@@ -86,6 +86,9 @@ EXPECT_EQ(expected.item_sequence_number, actual.item_sequence_number); EXPECT_EQ(expected.document_sequence_number, actual.document_sequence_number); EXPECT_EQ(expected.page_scale_factor, actual.page_scale_factor); + EXPECT_EQ(expected.scroll_anchor_selector, actual.scroll_anchor_selector); + EXPECT_EQ(expected.scroll_anchor_offset, actual.scroll_anchor_offset); + EXPECT_EQ(expected.scroll_anchor_simhash, actual.scroll_anchor_simhash); ExpectEquality(expected.http_body, actual.http_body); ExpectEquality(expected.children, actual.children); } @@ -120,6 +123,9 @@ frame_state->item_sequence_number = 1; frame_state->document_sequence_number = 2; frame_state->page_scale_factor = 2.0; + frame_state->scroll_anchor_selector = base::UTF8ToUTF16("#selector"); + frame_state->scroll_anchor_offset = gfx::PointF(2.5, 3.5); + frame_state->scroll_anchor_simhash = 12345; } void PopulateHttpBody( @@ -408,6 +414,26 @@ ExpectEquality(actual_encoded_state, expected_encoded_state); } +TEST_F(PageStateSerializationTest, ScrollAnchorSelectorLengthLimited) { + ExplodedPageState input; + PopulateFrameState(&input.top); + + std::string excessive_length_string(kMaxScrollAnchorSelectorLength + 1, 'a'); + + input.top.scroll_anchor_selector = base::UTF8ToUTF16(excessive_length_string); + + std::string encoded; + EncodePageState(input, &encoded); + + ExplodedPageState output; + DecodePageState(encoded, &output); + + // We should drop all the scroll anchor data if the length is over the limit. + EXPECT_FALSE(output.top.scroll_anchor_selector); + EXPECT_EQ(output.top.scroll_anchor_offset, gfx::PointF()); + EXPECT_EQ(output.top.scroll_anchor_simhash, 0ul); +} + // Change to #if 1 to enable this code. Run this test to generate data, based on // the current serialization format, for the BackwardsCompat_vXX tests. This // will generate an expected.dat in the temp directory, which should be moved @@ -512,10 +538,20 @@ TestBackwardsCompat(26); } +TEST_F(PageStateSerializationTest, BackwardsCompat_v27) { + TestBackwardsCompat(27); +} + +// Add your new backwards compat test for future versions *above* this +// comment block; field-specific tests go *below* this comment block. +// Any field additions require a new version and backcompat test; only fields +// with external type definitions require their own dedicated test. +// See DumpExpectedPageStateForBackwardsCompat for more details. // If any of the below tests fail, you likely made a backwards incompatible // change to a definition that page_state.mojom relies on. Ideally you should // find a way to avoid making this change; if that's not possible, contact the // page state serialization owners to figure out a resolution. + TEST_F(PageStateSerializationTest, BackwardsCompat_ReferencedFiles) { ExplodedPageState state; state.referenced_files.push_back(base::UTF8ToUTF16("file.txt")); @@ -634,10 +670,8 @@ ExpectEquality(state, saved_state); } -// Add your new backwards compat test for future versions/fields here. -// Any field additions require a new version and backcompat test; only fields -// with external type definitions require their own dedicated test. -// See DumpExpectedPageStateForBackwardsCompat for more details. +// Add new backwards compat field-specific tests here. See comment above for +// where to put backwards compat version tests. } // namespace } // namespace content
diff --git a/content/public/browser/download_item.h b/content/public/browser/download_item.h index 15540f4..fd833f0d 100644 --- a/content/public/browser/download_item.h +++ b/content/public/browser/download_item.h
@@ -84,6 +84,13 @@ // TARGET_DISPOSITION_OVERWRITE. }; + // How download item is created. Used for trace event. + enum DownloadType { + TYPE_ACTIVE_DOWNLOAD, + TYPE_HISTORY_IMPORT, + TYPE_SAVE_PAGE_AS + }; + // Callback used with AcquireFileAndDeleteDownload(). typedef base::Callback<void(const base::FilePath&)> AcquireFileCallback;
diff --git a/content/public/browser/gpu_data_manager.h b/content/public/browser/gpu_data_manager.h index 06758fb..d6db972a 100644 --- a/content/public/browser/gpu_data_manager.h +++ b/content/public/browser/gpu_data_manager.h
@@ -93,9 +93,6 @@ // Whether a GPU is in use (as opposed to a software renderer). virtual bool HardwareAccelerationEnabled() const = 0; - // Whether the browser compositor can be used. - virtual bool CanUseGpuBrowserCompositor() const = 0; - // Extensions that are currently disabled. virtual void GetDisabledExtensions( std::string* disabled_extensions) const = 0;
diff --git a/content/public/test/test_file_error_injector.cc b/content/public/test/test_file_error_injector.cc index f4f3176..ce195bf 100644 --- a/content/public/test/test_file_error_injector.cc +++ b/content/public/test/test_file_error_injector.cc
@@ -34,7 +34,7 @@ DownloadFileWithError(std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_download_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer, const TestFileErrorInjector::FileErrorInfo& error_info, const base::Closure& ctor_callback, @@ -111,7 +111,7 @@ std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_download_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer, const TestFileErrorInjector::FileErrorInfo& error_info, const base::Closure& ctor_callback, @@ -119,7 +119,7 @@ : DownloadFileImpl(std::move(save_info), default_download_directory, std::move(stream), - net_log, + download_id, observer), error_info_(error_info), destruction_callback_(dtor_callback) { @@ -286,7 +286,7 @@ std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_download_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer) override; bool SetError(TestFileErrorInjector::FileErrorInfo error); @@ -312,11 +312,11 @@ std::unique_ptr<DownloadSaveInfo> save_info, const base::FilePath& default_download_directory, std::unique_ptr<DownloadManager::InputStream> stream, - const net::NetLogWithSource& net_log, + uint32_t download_id, base::WeakPtr<DownloadDestinationObserver> observer) { return new DownloadFileWithError( std::move(save_info), default_download_directory, std::move(stream), - net_log, observer, injected_error_, construction_callback_, + download_id, observer, injected_error_, construction_callback_, destruction_callback_); }
diff --git a/content/renderer/history_serialization.cc b/content/renderer/history_serialization.cc index 7f56afd7..0c29a57 100644 --- a/content/renderer/history_serialization.cc +++ b/content/renderer/history_serialization.cc
@@ -65,6 +65,12 @@ state->http_body.request_body = GetRequestBodyForWebHTTPBody(http_body); state->http_body.contains_passwords = http_body.ContainsPasswordData(); } + + blink::ScrollAnchorData anchor = item.GetScrollAnchorData(); + state->scroll_anchor_selector = + WebString::ToOptionalString16(anchor.selector_); + state->scroll_anchor_offset = anchor.offset_; + state->scroll_anchor_simhash = anchor.simhash_; } void RecursivelyGenerateHistoryItem(const ExplodedFrameState& state, @@ -107,6 +113,10 @@ item.SetHTTPBody( GetWebHTTPBodyForRequestBody(state.http_body.request_body)); } + + item.SetScrollAnchorData({WebString::FromUTF16(state.scroll_anchor_selector), + state.scroll_anchor_offset, + state.scroll_anchor_simhash}); node->set_item(item); for (size_t i = 0; i < state.children.size(); ++i)
diff --git a/content/renderer/pepper/ppb_graphics_3d_impl.cc b/content/renderer/pepper/ppb_graphics_3d_impl.cc index eb41e82c..2f52cd26 100644 --- a/content/renderer/pepper/ppb_graphics_3d_impl.cc +++ b/content/renderer/pepper/ppb_graphics_3d_impl.cc
@@ -240,6 +240,8 @@ RenderThreadImpl* render_thread = RenderThreadImpl::current(); if (!render_thread) return false; + if (render_thread->IsGpuCompositingDisabled()) + return false; scoped_refptr<gpu::GpuChannelHost> channel = render_thread->EstablishGpuChannelSync();
diff --git a/content/test/data/page_state/serialized_v27.dat b/content/test/data/page_state/serialized_v27.dat new file mode 100644 index 0000000..f9dd8fc --- /dev/null +++ b/content/test/data/page_state/serialized_v27.dat
@@ -0,0 +1,36 @@ ++AcAABsAAADwBwAAGAAAAAAAAAAQAAAAAAAAAEAAAAAAAAAAEAAAAAEAAAAIAAAAAAAAABAAAAAA +AAAACAAAAAAAAAAYAAAACAAAAGYAaQBsAGUALgB0AHgAdABgAAAAAAAAAFgAAAAAAAAAkAAAAAAA +AADIAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAQAAAJACAAAAAAAAewAAAAAAAADIAQAAAAAA +AOACAAAAAAAACAQAAAAAAAAQAAAAAAAAAAgAAAAAAAAAMAAAABQAAABoAHQAdABwADoALwAvAGMA +aAByAG8AbQBpAHUAbQAuAG8AcgBnAC8AEAAAAAAAAAAIAAAAAAAAACwAAAASAAAAaAB0AHQAcAA6 +AC8ALwBnAG8AbwBnAGwAZQAuAGMAbwBtAC8AAAAAABAAAAAAAAAACAAAAAAAAAAUAAAABgAAAHQA +YQByAGcAZQB0AAAAAABIAAAACAAAAEAAAAAAAAAAsAAAAAAAAADQAAAAAAAAAOgAAAAAAAAAAAEA +AAAAAAAYAQAAAAAAADABAAAAAAAAUAEAAAAAAAAQAAAAAAAAAAgAAAAAAAAAaAAAADAAAAAKAA0A +PwAlACAAVwBlAGIASwBpAHQAIABzAGUAcgBpAGEAbABpAHoAZQBkACAAZgBvAHIAbQAgAHMAdABh +AHQAZQAgAHYAZQByAHMAaQBvAG4AIAA4ACAACgANAD0AJgAQAAAAAAAAAAgAAAAAAAAAGAAAAAgA +AABmAG8AcgBtACAAawBlAHkAEAAAAAAAAAAIAAAAAAAAAAoAAAABAAAAMQAAAAAAAAAQAAAAAAAA +AAgAAAAAAAAADgAAAAMAAABmAG8AbwAAABAAAAAAAAAACAAAAAAAAAAQAAAABAAAAGYAaQBsAGUA +EAAAAAAAAAAIAAAAAAAAAAoAAAABAAAAMgAAAAAAAAAQAAAAAAAAAAgAAAAAAAAAGAAAAAgAAABm +AGkAbABlAC4AdAB4AHQAEAAAAAAAAAAIAAAAAAAAAB4AAAALAAAAZABpAHMAcABsAGEAeQBOAGEA +bQBlAAAAOAAAAAEAAAAwAAAAAAAAADgAAAAAAAAAAAAAAAAAAEAAAAAAAAAAADAAAAAAAAAAAAAA +AAAAAAAQAAAAAAAAAAAAgL8AAIC/EAAAAAAAAAAqAAAA1v///xAAAAAAAAAAAAAAAAAAAAAgAAAA +AAAAABgAAAAAAAAAOAAAAAAAAAAAAAAAAAAAABAAAAAAAAAACAAAAAAAAAAWAAAABwAAAGYAbwBv +AC8AYgBhAHIAAAAgAAAAAAAAABgAAAAAAAAAFQMAAAAAAAAAAAAAAAAAADgAAAADAAAAEAAAAAEA +AAAoAAAAAAAAABAAAAACAAAAMAAAAAAAAAAQAAAAAQAAAIAAAAAAAAAAGAAAABAAAABmaXJzdCBk +YXRhIGJsb2NrKAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAA//////////8wAAAAAAAAABAAAAAAAAAA +CAAAAAAAAAAYAAAACAAAAGYAaQBsAGUALgB0AHgAdAAQAAAAAAAAAAAAAAAAAAAAFwAAAA8AAABk +YXRhIHRoZSBzZWNvbmQAEAAAAAEAAAAIAAAAAAAAAGAAAAAAAAAAWAAAAAAAAACQAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAC4AAAAAAAAAAAAAAABAAAAaAIAAAAAAAB7AAAAAAAAAMgBAAAAAAAAuAIA +AAAAAADQAgAAAAAAABAAAAAAAAAACAAAAAAAAAAwAAAAFAAAAGgAdAB0AHAAOgAvAC8AYwBoAHIA +bwBtAGkAdQBtAC4AbwByAGcALwAQAAAAAAAAAAgAAAAAAAAALAAAABIAAABoAHQAdABwADoALwAv +AGcAbwBvAGcAbABlAC4AYwBvAG0ALwAAAAAASAAAAAgAAABAAAAAAAAAALAAAAAAAAAA0AAAAAAA +AADoAAAAAAAAAAABAAAAAAAAGAEAAAAAAAAwAQAAAAAAAFABAAAAAAAAEAAAAAAAAAAIAAAAAAAA +AGgAAAAwAAAACgANAD8AJQAgAFcAZQBiAEsAaQB0ACAAcwBlAHIAaQBhAGwAaQB6AGUAZAAgAGYA +bwByAG0AIABzAHQAYQB0AGUAIAB2AGUAcgBzAGkAbwBuACAAOAAgAAoADQA9ACYAEAAAAAAAAAAI +AAAAAAAAABgAAAAIAAAAZgBvAHIAbQAgAGsAZQB5ABAAAAAAAAAACAAAAAAAAAAKAAAAAQAAADEA +AAAAAAAAEAAAAAAAAAAIAAAAAAAAAA4AAAADAAAAZgBvAG8AAAAQAAAAAAAAAAgAAAAAAAAAEAAA +AAQAAABmAGkAbABlABAAAAAAAAAACAAAAAAAAAAKAAAAAQAAADIAAAAAAAAAEAAAAAAAAAAIAAAA +AAAAABgAAAAIAAAAZgBpAGwAZQAuAHQAeAB0ABAAAAAAAAAACAAAAAAAAAAeAAAACwAAAGQAaQBz +AHAAbABhAHkATgBhAG0AZQAAADgAAAABAAAAMAAAAAAAAAA4AAAAAAAAAAAAAAAAAABAAAAAAAAA +AAAwAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAIC/AACAvxAAAAAAAAAAKgAAANb///8QAAAAAAAA +AAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAA==
diff --git a/content/test/gpu/gpu_tests/gpu_process_expectations.py b/content/test/gpu/gpu_tests/gpu_process_expectations.py index fa3778e..16b5bac7 100644 --- a/content/test/gpu/gpu_tests/gpu_process_expectations.py +++ b/content/test/gpu/gpu_tests/gpu_process_expectations.py
@@ -17,6 +17,9 @@ self.Skip('GpuProcess_no_gpu_process', ['android'], bug=643282) self.Skip('GpuProcess_skip_gpu_process', ['android'], bug=(610951, 610023)) + # TODO(zmo): Consider deleting this test on Linux/Win due to SwiftShader? + self.Fail('GpuProcess_no_gpu_process', ['win', 'linux']) + # Chrome on Windows and Linux create a GPU process that uses SwiftShader # when using either --disable-gpu or a blacklisted GPU. self.Skip('GpuProcess_skip_gpu_process', ['win', 'linux'], bug=630728)
diff --git a/device/u2f/u2f_apdu_command.cc b/device/u2f/u2f_apdu_command.cc index 7336b116..527c211 100644 --- a/device/u2f/u2f_apdu_command.cc +++ b/device/u2f/u2f_apdu_command.cc
@@ -168,7 +168,8 @@ std::unique_ptr<U2fApduCommand> U2fApduCommand::CreateSign( const std::vector<uint8_t>& appid_digest, const std::vector<uint8_t>& challenge_digest, - const std::vector<uint8_t>& key_handle) { + const std::vector<uint8_t>& key_handle, + bool check_only) { if (appid_digest.size() != kAppIdDigestLen || challenge_digest.size() != kChallengeDigestLen || key_handle.size() > kMaxKeyHandleLength) { @@ -181,7 +182,7 @@ data.push_back(static_cast<uint8_t>(key_handle.size())); data.insert(data.end(), key_handle.begin(), key_handle.end()); command->set_ins(kInsU2fSign); - command->set_p1(kP1TupRequiredConsumed); + command->set_p1(check_only ? kP1CheckOnly : kP1TupRequiredConsumed); command->set_data(data); return command; }
diff --git a/device/u2f/u2f_apdu_command.h b/device/u2f/u2f_apdu_command.h index c44ba564d..cee66e246 100644 --- a/device/u2f/u2f_apdu_command.h +++ b/device/u2f/u2f_apdu_command.h
@@ -53,10 +53,14 @@ static std::unique_ptr<U2fApduCommand> CreateVersion(); // Early U2F drafts defined a non-ISO 7816-4 conforming layout. static std::unique_ptr<U2fApduCommand> CreateLegacyVersion(); + + // Returns an APDU command for sign(). If optional parameter |check_only| is + // set to true, then control byte is set to 0X07. static std::unique_ptr<U2fApduCommand> CreateSign( const std::vector<uint8_t>& appid_digest, const std::vector<uint8_t>& challenge_digest, - const std::vector<uint8_t>& key_handle); + const std::vector<uint8_t>& key_handle, + bool check_only = false); private: FRIEND_TEST_ALL_PREFIXES(U2fApduTest, TestDeserializeBasic); @@ -88,7 +92,10 @@ static constexpr uint8_t kP1TupConsumed = 0x02; static constexpr uint8_t kP1TupRequiredConsumed = kP1TupRequired | kP1TupConsumed; - + // Control byte used for check-only setting. The check-only command is used to + // determine if the provided key handle was originally created by this token + // and whether it was created for the provided application parameter. + static constexpr uint8_t kP1CheckOnly = 0x07; static constexpr size_t kMaxKeyHandleLength = 255; static constexpr size_t kChallengeDigestLen = 32; static constexpr size_t kAppIdDigestLen = 32;
diff --git a/device/u2f/u2f_device.cc b/device/u2f/u2f_device.cc index 2545cc1..f1efa9e 100644 --- a/device/u2f/u2f_device.cc +++ b/device/u2f/u2f_device.cc
@@ -31,9 +31,10 @@ void U2fDevice::Sign(const std::vector<uint8_t>& app_param, const std::vector<uint8_t>& challenge_param, const std::vector<uint8_t>& key_handle, - const MessageCallback& callback) { - std::unique_ptr<U2fApduCommand> sign_cmd = - U2fApduCommand::CreateSign(app_param, challenge_param, key_handle); + const MessageCallback& callback, + bool check_only) { + std::unique_ptr<U2fApduCommand> sign_cmd = U2fApduCommand::CreateSign( + app_param, challenge_param, key_handle, check_only); if (!sign_cmd) { callback.Run(U2fReturnCode::INVALID_PARAMS, std::vector<uint8_t>()); return;
diff --git a/device/u2f/u2f_device.h b/device/u2f/u2f_device.h index 71150c4..ece2b556 100644 --- a/device/u2f/u2f_device.h +++ b/device/u2f/u2f_device.h
@@ -47,7 +47,9 @@ void Sign(const std::vector<uint8_t>& appid_digest, const std::vector<uint8_t>& challenge_digest, const std::vector<uint8_t>& key_handle, - const MessageCallback& callback); + const MessageCallback& callback, + bool check_only = false); + virtual void TryWink(const WinkCallback& callback) = 0; virtual std::string GetId() const = 0;
diff --git a/device/u2f/u2f_register.cc b/device/u2f/u2f_register.cc index 059432d..3c33432 100644 --- a/device/u2f/u2f_register.cc +++ b/device/u2f/u2f_register.cc
@@ -3,60 +3,130 @@ // found in the LICENSE file. #include "device/u2f/u2f_register.h" - #include <utility> - +#include "base/stl_util.h" #include "device/u2f/u2f_discovery.h" #include "services/service_manager/public/cpp/connector.h" namespace device { -U2fRegister::U2fRegister(const std::vector<uint8_t>& challenge_hash, - const std::vector<uint8_t>& app_param, - std::vector<std::unique_ptr<U2fDiscovery>> discoveries, - const ResponseCallback& cb) +U2fRegister::U2fRegister( + const std::vector<std::vector<uint8_t>>& registered_keys, + const std::vector<uint8_t>& challenge_hash, + const std::vector<uint8_t>& app_param, + std::vector<std::unique_ptr<U2fDiscovery>> discoveries, + const ResponseCallback& cb) : U2fRequest(std::move(discoveries), cb), challenge_hash_(challenge_hash), app_param_(app_param), + registered_keys_(registered_keys), weak_factory_(this) {} U2fRegister::~U2fRegister() {} // static std::unique_ptr<U2fRequest> U2fRegister::TryRegistration( + const std::vector<std::vector<uint8_t>>& registered_keys, const std::vector<uint8_t>& challenge_hash, const std::vector<uint8_t>& app_param, std::vector<std::unique_ptr<U2fDiscovery>> discoveries, const ResponseCallback& cb) { std::unique_ptr<U2fRequest> request = std::make_unique<U2fRegister>( - challenge_hash, app_param, std::move(discoveries), cb); + registered_keys, challenge_hash, app_param, std::move(discoveries), cb); request->Start(); return request; } void U2fRegister::TryDevice() { DCHECK(current_device_); - - current_device_->Register( - app_param_, challenge_hash_, - base::Bind(&U2fRegister::OnTryDevice, weak_factory_.GetWeakPtr())); + if (registered_keys_.size() > 0 && !CheckedForDuplicateRegistration()) { + auto it = registered_keys_.cbegin(); + current_device_->Sign(app_param_, challenge_hash_, *it, + base::Bind(&U2fRegister::OnTryCheckRegistration, + weak_factory_.GetWeakPtr(), it), + true); + } else { + current_device_->Register(app_param_, challenge_hash_, + base::Bind(&U2fRegister::OnTryDevice, + weak_factory_.GetWeakPtr(), false)); + } } -void U2fRegister::OnTryDevice(U2fReturnCode return_code, +void U2fRegister::OnTryCheckRegistration( + std::vector<std::vector<uint8_t>>::const_iterator it, + U2fReturnCode return_code, + const std::vector<uint8_t>& response_data) { + switch (return_code) { + case U2fReturnCode::SUCCESS: + case U2fReturnCode::CONDITIONS_NOT_SATISFIED: + // Duplicate registration found. Call bogus registration to check for + // user presence (touch) and terminate the registration process. + current_device_->Register(U2fRequest::GetBogusAppParam(), + U2fRequest::GetBogusChallenge(), + base::Bind(&U2fRegister::OnTryDevice, + weak_factory_.GetWeakPtr(), true)); + break; + + case U2fReturnCode::INVALID_PARAMS: + // Continue to iterate through the provided key handles in the exclude + // list and check for already registered keys. + if (++it != registered_keys_.end()) { + current_device_->Sign(app_param_, challenge_hash_, *it, + base::Bind(&U2fRegister::OnTryCheckRegistration, + weak_factory_.GetWeakPtr(), it), + true); + } else { + checked_device_id_list_.insert(current_device_->GetId()); + if (devices_.empty()) { + // When all devices have been checked, proceed to registration. + CompleteNewDeviceRegistration(); + } else { + state_ = State::IDLE; + Transition(); + } + } + break; + default: + // Some sort of failure occurred. Abandon this device and move on. + state_ = State::IDLE; + current_device_ = nullptr; + Transition(); + break; + } +} + +void U2fRegister::CompleteNewDeviceRegistration() { + if (current_device_) + attempted_devices_.push_back(std::move(current_device_)); + + devices_.splice(devices_.end(), std::move(attempted_devices_)); + state_ = State::IDLE; + Transition(); + return; +} + +bool U2fRegister::CheckedForDuplicateRegistration() { + return base::ContainsKey(checked_device_id_list_, current_device_->GetId()); +} + +void U2fRegister::OnTryDevice(bool is_duplicate_registration, + U2fReturnCode return_code, const std::vector<uint8_t>& response_data) { switch (return_code) { case U2fReturnCode::SUCCESS: state_ = State::COMPLETE; + if (is_duplicate_registration) + return_code = U2fReturnCode::CONDITIONS_NOT_SATISFIED; cb_.Run(return_code, response_data); break; case U2fReturnCode::CONDITIONS_NOT_SATISFIED: - // Waiting for user touch, move on and try this device later + // Waiting for user touch, move on and try this device later. state_ = State::IDLE; Transition(); break; default: state_ = State::IDLE; - // An error has occured, quit trying this device + // An error has occurred, quit trying this device. current_device_ = nullptr; Transition(); break;
diff --git a/device/u2f/u2f_register.h b/device/u2f/u2f_register.h index 9260594..0b11e68 100644 --- a/device/u2f/u2f_register.h +++ b/device/u2f/u2f_register.h
@@ -6,8 +6,8 @@ #define DEVICE_U2F_U2F_REGISTER_H_ #include <memory> +#include <set> #include <vector> - #include "device/u2f/u2f_request.h" namespace device { @@ -16,13 +16,15 @@ class U2fRegister : public U2fRequest { public: - U2fRegister(const std::vector<uint8_t>& challenge_hash, + U2fRegister(const std::vector<std::vector<uint8_t>>& registered_keys, + const std::vector<uint8_t>& challenge_hash, const std::vector<uint8_t>& app_param, std::vector<std::unique_ptr<U2fDiscovery>> discoveries, const ResponseCallback& cb); ~U2fRegister() override; static std::unique_ptr<U2fRequest> TryRegistration( + const std::vector<std::vector<uint8_t>>& registered_keys, const std::vector<uint8_t>& challenge_hash, const std::vector<uint8_t>& app_param, std::vector<std::unique_ptr<U2fDiscovery>> discoveries, @@ -30,11 +32,30 @@ private: void TryDevice() override; - void OnTryDevice(U2fReturnCode return_code, + void OnTryDevice(bool is_duplicate_registration, + U2fReturnCode return_code, const std::vector<uint8_t>& response_data); + // Callback function called when non-empty exclude list was provided. This + // function iterates through all key handles in |registered_keys_| for all + // devices and checks for already registered keys. + void OnTryCheckRegistration( + std::vector<std::vector<uint8_t>>::const_iterator it, + U2fReturnCode return_code, + const std::vector<uint8_t>& response_data); + // Function handling registration flow after all devices were checked for + // already registered keys. + void CompleteNewDeviceRegistration(); + // Returns whether |current_device_| has been checked for duplicate + // registration for all key handles provided in |registered_keys_|. + bool CheckedForDuplicateRegistration(); + std::vector<uint8_t> challenge_hash_; std::vector<uint8_t> app_param_; + const std::vector<std::vector<uint8_t>> registered_keys_; + // List of authenticators that did not create any of the key handles in the + // exclude list. + std::set<std::string> checked_device_id_list_; base::WeakPtrFactory<U2fRegister> weak_factory_; };
diff --git a/device/u2f/u2f_register_unittest.cc b/device/u2f/u2f_register_unittest.cc index 917f7df4..4e0ca38 100644 --- a/device/u2f/u2f_register_unittest.cc +++ b/device/u2f/u2f_register_unittest.cc
@@ -14,6 +14,8 @@ namespace device { +using ::testing::_; + class U2fRegisterTest : public testing::Test { public: U2fRegisterTest() @@ -55,9 +57,12 @@ TEST_F(U2fRegisterTest, TestRegisterSuccess) { std::unique_ptr<MockU2fDevice> device(new MockU2fDevice()); auto discovery = std::make_unique<MockU2fDiscovery>(); - EXPECT_CALL(*device.get(), DeviceTransactPtr(testing::_, testing::_)) + + EXPECT_CALL(*device.get(), GetId()) + .WillRepeatedly(testing::Return("device0")); + EXPECT_CALL(*device.get(), DeviceTransactPtr(_, _)) .WillOnce(testing::Invoke(MockU2fDevice::NoErrorRegister)); - EXPECT_CALL(*device.get(), TryWink(testing::_)) + EXPECT_CALL(*device.get(), TryWink(_)) .WillOnce(testing::Invoke(MockU2fDevice::WinkDoNothing)); EXPECT_CALL(*discovery, Start()) .WillOnce(testing::Invoke(discovery.get(), @@ -67,8 +72,9 @@ std::vector<std::unique_ptr<U2fDiscovery>> discoveries; MockU2fDiscovery* discovery_weak = discovery.get(); discoveries.push_back(std::move(discovery)); + std::vector<std::vector<uint8_t>> registration_keys; std::unique_ptr<U2fRequest> request = U2fRegister::TryRegistration( - std::vector<uint8_t>(32), std::vector<uint8_t>(32), + registration_keys, std::vector<uint8_t>(32), std::vector<uint8_t>(32), std::move(discoveries), cb.callback()); request->Start(); discovery_weak->AddDevice(std::move(device)); @@ -83,11 +89,13 @@ std::unique_ptr<MockU2fDevice> device(new MockU2fDevice()); auto discovery = std::make_unique<MockU2fDiscovery>(); + EXPECT_CALL(*device.get(), GetId()) + .WillRepeatedly(testing::Return("device0")); // Go through the state machine twice before success - EXPECT_CALL(*device.get(), DeviceTransactPtr(testing::_, testing::_)) + EXPECT_CALL(*device.get(), DeviceTransactPtr(_, _)) .WillOnce(testing::Invoke(MockU2fDevice::NotSatisfied)) .WillOnce(testing::Invoke(MockU2fDevice::NoErrorRegister)); - EXPECT_CALL(*device.get(), TryWink(testing::_)) + EXPECT_CALL(*device.get(), TryWink(_)) .Times(2) .WillRepeatedly(testing::Invoke(MockU2fDevice::WinkDoNothing)); EXPECT_CALL(*discovery, Start()) @@ -97,9 +105,10 @@ std::vector<std::unique_ptr<U2fDiscovery>> discoveries; MockU2fDiscovery* discovery_weak = discovery.get(); + std::vector<std::vector<uint8_t>> registration_keys; discoveries.push_back(std::move(discovery)); std::unique_ptr<U2fRequest> request = U2fRegister::TryRegistration( - std::vector<uint8_t>(32), std::vector<uint8_t>(32), + registration_keys, std::vector<uint8_t>(32), std::vector<uint8_t>(32), std::move(discoveries), cb.callback()); request->Start(); discovery_weak->AddDevice(std::move(device)); @@ -116,14 +125,71 @@ std::unique_ptr<MockU2fDevice> device1(new MockU2fDevice()); auto discovery = std::make_unique<MockU2fDiscovery>(); - EXPECT_CALL(*device0.get(), DeviceTransactPtr(testing::_, testing::_)) + EXPECT_CALL(*device0.get(), GetId()) + .WillRepeatedly(testing::Return("device0")); + EXPECT_CALL(*device1.get(), GetId()) + .WillRepeatedly(testing::Return("device1")); + EXPECT_CALL(*device0.get(), DeviceTransactPtr(_, _)) .WillOnce(testing::Invoke(MockU2fDevice::NotSatisfied)); // One wink per device - EXPECT_CALL(*device0.get(), TryWink(testing::_)) + EXPECT_CALL(*device0.get(), TryWink(_)) .WillOnce(testing::Invoke(MockU2fDevice::WinkDoNothing)); - EXPECT_CALL(*device1.get(), DeviceTransactPtr(testing::_, testing::_)) + EXPECT_CALL(*device1.get(), DeviceTransactPtr(_, _)) .WillOnce(testing::Invoke(MockU2fDevice::NoErrorRegister)); - EXPECT_CALL(*device1.get(), TryWink(testing::_)) + EXPECT_CALL(*device1.get(), TryWink(_)) + .WillOnce(testing::Invoke(MockU2fDevice::WinkDoNothing)); + EXPECT_CALL(*discovery, Start()) + .WillOnce(testing::Invoke(discovery.get(), + &MockU2fDiscovery::StartSuccessAsync)); + + TestRegisterCallback cb; + std::vector<std::unique_ptr<U2fDiscovery>> discoveries; + MockU2fDiscovery* discovery_weak = discovery.get(); + discoveries.push_back(std::move(discovery)); + std::vector<std::vector<uint8_t>> registration_keys; + std::unique_ptr<U2fRequest> request = U2fRegister::TryRegistration( + registration_keys, std::vector<uint8_t>(32), std::vector<uint8_t>(32), + std::move(discoveries), cb.callback()); + request->Start(); + discovery_weak->AddDevice(std::move(device0)); + discovery_weak->AddDevice(std::move(device1)); + std::pair<U2fReturnCode, std::vector<uint8_t>>& response = + cb.WaitForCallback(); + EXPECT_EQ(U2fReturnCode::SUCCESS, response.first); + ASSERT_LT(0u, response.second.size()); + EXPECT_EQ(static_cast<uint8_t>(MockU2fDevice::kRegister), response.second[0]); +} + +// Tests a scenario where a single device is connected and registration call +// is received with three unknown key handles. We expect that three check only +// sign-in calls be processed before registration. +TEST_F(U2fRegisterTest, TestSingleDeviceRegistrationWithExclusionList) { + std::vector<uint8_t> unknown_key0(32, 0xB); + std::vector<uint8_t> unknown_key1(32, 0xC); + std::vector<uint8_t> unknown_key2(32, 0xD); + std::vector<std::vector<uint8_t>> handles = {unknown_key0, unknown_key1, + unknown_key2}; + std::unique_ptr<MockU2fDevice> device(new MockU2fDevice()); + auto discovery = std::make_unique<MockU2fDiscovery>(); + + EXPECT_CALL(*device.get(), GetId()) + .WillRepeatedly(testing::Return("device0")); + // DeviceTransact() will be called four times including three check + // only sign-in calls and one registration call. For the first three calls, + // device will invoke MockU2fDevice::WrongData as the authenticator did not + // create the three key handles provided in the exclude list. At the fourth + // call, MockU2fDevice::NoErrorRegister will be invoked after registration. + EXPECT_CALL(*device.get(), DeviceTransactPtr(_, _)) + .Times(4) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::NoErrorRegister)); + // TryWink() will be called twice. First during the check only sign-in. After + // check only sign operation is complete, request state is changed to IDLE, + // and TryWink() is called again before Register() is called. + EXPECT_CALL(*device.get(), TryWink(_)) + .WillOnce(testing::Invoke(MockU2fDevice::WinkDoNothing)) .WillOnce(testing::Invoke(MockU2fDevice::WinkDoNothing)); EXPECT_CALL(*discovery, Start()) .WillOnce(testing::Invoke(discovery.get(), @@ -134,11 +200,9 @@ MockU2fDiscovery* discovery_weak = discovery.get(); discoveries.push_back(std::move(discovery)); std::unique_ptr<U2fRequest> request = U2fRegister::TryRegistration( - std::vector<uint8_t>(32), std::vector<uint8_t>(32), + handles, std::vector<uint8_t>(32), std::vector<uint8_t>(32), std::move(discoveries), cb.callback()); - request->Start(); - discovery_weak->AddDevice(std::move(device0)); - discovery_weak->AddDevice(std::move(device1)); + discovery_weak->AddDevice(std::move(device)); std::pair<U2fReturnCode, std::vector<uint8_t>>& response = cb.WaitForCallback(); EXPECT_EQ(U2fReturnCode::SUCCESS, response.first); @@ -146,4 +210,193 @@ EXPECT_EQ(static_cast<uint8_t>(MockU2fDevice::kRegister), response.second[0]); } +// Tests a scenario where two devices are connected and registration call is +// received with three unknown key handles. We assume that user will proceed the +// registration with second device, "device1". +TEST_F(U2fRegisterTest, TestMultipleDeviceRegistrationWithExclusionList) { + std::vector<uint8_t> unknown_key0(32, 0xB); + std::vector<uint8_t> unknown_key1(32, 0xC); + std::vector<uint8_t> unknown_key2(32, 0xD); + std::vector<std::vector<uint8_t>> handles = {unknown_key0, unknown_key1, + unknown_key2}; + std::unique_ptr<MockU2fDevice> device0(new MockU2fDevice()); + std::unique_ptr<MockU2fDevice> device1(new MockU2fDevice()); + auto discovery = std::make_unique<MockU2fDiscovery>(); + + EXPECT_CALL(*device0.get(), GetId()) + .WillRepeatedly(testing::Return("device0")); + EXPECT_CALL(*device1.get(), GetId()) + .WillRepeatedly(testing::Return("device1")); + + // DeviceTransact() will be called four times: three times to check for + // duplicate key handles and once for registration. Since user + // will register using "device1", the fourth call will invoke + // MockU2fDevice::NotSatisfied. + EXPECT_CALL(*device0.get(), DeviceTransactPtr(_, _)) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::NotSatisfied)); + // We assume that user registers with second device. Therefore, the fourth + // DeviceTransact() will invoke MockU2fDevice::NoErrorRegister after + // successful registration. + EXPECT_CALL(*device1.get(), DeviceTransactPtr(_, _)) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::NoErrorRegister)); + + // TryWink() will be called twice on both devices -- during check only + // sign-in operation and during registration attempt. + EXPECT_CALL(*device0.get(), TryWink(_)) + .WillOnce(testing::Invoke(MockU2fDevice::WinkDoNothing)) + .WillOnce(testing::Invoke(MockU2fDevice::WinkDoNothing)); + EXPECT_CALL(*device1.get(), TryWink(_)) + .WillOnce(testing::Invoke(MockU2fDevice::WinkDoNothing)) + .WillOnce(testing::Invoke(MockU2fDevice::WinkDoNothing)); + + EXPECT_CALL(*discovery, Start()) + .WillOnce(testing::Invoke(discovery.get(), + &MockU2fDiscovery::StartSuccessAsync)); + + TestRegisterCallback cb; + std::vector<std::unique_ptr<U2fDiscovery>> discoveries; + MockU2fDiscovery* discovery_weak = discovery.get(); + discoveries.push_back(std::move(discovery)); + std::unique_ptr<U2fRequest> request = U2fRegister::TryRegistration( + handles, std::vector<uint8_t>(32), std::vector<uint8_t>(32), + std::move(discoveries), cb.callback()); + + discovery_weak->AddDevice(std::move(device0)); + discovery_weak->AddDevice(std::move(device1)); + std::pair<U2fReturnCode, std::vector<uint8_t>>& response = + cb.WaitForCallback(); + + EXPECT_EQ(U2fReturnCode::SUCCESS, response.first); + ASSERT_LT(static_cast<size_t>(0), response.second.size()); + EXPECT_EQ(static_cast<uint8_t>(MockU2fDevice::kRegister), response.second[0]); +} + +// Tests a scenario where single device is connected and registration is called +// with a key in the exclude list that was created by this device. We assume +// that the duplicate key is the last key handle in the exclude list. Therefore, +// after duplicate key handle is found, the process is expected to terminate +// after calling bogus registration which checks for user presence. +TEST_F(U2fRegisterTest, TestSingleDeviceRegistrationWithDuplicateHandle) { + std::vector<uint8_t> unknown_key0(32, 0xB); + std::vector<uint8_t> unknown_key1(32, 0xC); + std::vector<uint8_t> unknown_key2(32, 0xD); + std::vector<uint8_t> duplicate_key(32, 0xA); + + std::vector<std::vector<uint8_t>> handles = {unknown_key0, unknown_key1, + unknown_key2, duplicate_key}; + std::unique_ptr<MockU2fDevice> device(new MockU2fDevice()); + auto discovery = std::make_unique<MockU2fDiscovery>(); + + EXPECT_CALL(*device.get(), GetId()) + .WillRepeatedly(testing::Return("device0")); + + // For four keys in exclude list, the first three keys will invoke + // MockU2fDevice::WrongData and the final duplicate key handle will invoke + // MockU2fDevice::NoErrorSign. Once duplicate key handle is found, bogus + // registration is called to confirm user presence. This invokes + // MockU2fDevice::NoErrorRegister. + EXPECT_CALL(*device.get(), DeviceTransactPtr(_, _)) + .Times(5) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::NoErrorSign)) + .WillOnce(testing::Invoke(MockU2fDevice::NoErrorRegister)); + + // Since duplicate key handle is found, registration process is terminated + // before actual Register() is called on the device. Therefore, TryWink() is + // invoked once. + EXPECT_CALL(*device.get(), TryWink(_)) + .WillOnce(testing::Invoke(MockU2fDevice::WinkDoNothing)); + + EXPECT_CALL(*discovery, Start()) + .WillOnce(testing::Invoke(discovery.get(), + &MockU2fDiscovery::StartSuccessAsync)); + TestRegisterCallback cb; + std::vector<std::unique_ptr<U2fDiscovery>> discoveries; + MockU2fDiscovery* discovery_weak = discovery.get(); + discoveries.push_back(std::move(discovery)); + std::unique_ptr<U2fRequest> request = U2fRegister::TryRegistration( + handles, std::vector<uint8_t>(32), std::vector<uint8_t>(32), + std::move(discoveries), cb.callback()); + discovery_weak->AddDevice(std::move(device)); + std::pair<U2fReturnCode, std::vector<uint8_t>>& response = + cb.WaitForCallback(); + EXPECT_EQ(U2fReturnCode::CONDITIONS_NOT_SATISFIED, response.first); +} + +// Tests a scenario where one(device1) of the two devices connected has created +// a key handle provided in exclude list. We assume that duplicate key is the +// fourth key handle provided in the exclude list. +TEST_F(U2fRegisterTest, TestMultipleDeviceRegistrationWithDuplicateHandle) { + std::vector<uint8_t> unknown_key0(32, 0xB); + std::vector<uint8_t> unknown_key1(32, 0xC); + std::vector<uint8_t> unknown_key2(32, 0xD); + std::vector<uint8_t> duplicate_key(32, 0xA); + std::vector<std::vector<uint8_t>> handles = {unknown_key0, unknown_key1, + unknown_key2, duplicate_key}; + std::unique_ptr<MockU2fDevice> device0(new MockU2fDevice()); + std::unique_ptr<MockU2fDevice> device1(new MockU2fDevice()); + auto discovery = std::make_unique<MockU2fDiscovery>(); + + EXPECT_CALL(*device0.get(), GetId()) + .WillRepeatedly(testing::Return("device0")); + + EXPECT_CALL(*device1.get(), GetId()) + .WillRepeatedly(testing::Return("device1")); + + // Since the first device did not create any of the key handles provided in + // exclude list, we expect that check only sign() should be called + // four times, and all the calls to DeviceTransact() invoke + // MockU2fDevice::WrongData. + EXPECT_CALL(*device0.get(), DeviceTransactPtr(_, _)) + .Times(4) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)); + // Since the last key handle in exclude list is a duplicate key, we expect + // that the first three calls to check only sign() invoke + // MockU2fDevice::WrongData and that fourth sign() call invoke + // MockU2fDevice::NoErrorSign. After duplicate key is found, process is + // terminated after user presence is verified using bogus registration, which + // invokes MockU2fDevice::NoErrorRegister. + EXPECT_CALL(*device1.get(), DeviceTransactPtr(_, _)) + .Times(5) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::WrongData)) + .WillOnce(testing::Invoke(MockU2fDevice::NoErrorSign)) + .WillOnce(testing::Invoke(MockU2fDevice::NoErrorRegister)); + + EXPECT_CALL(*device0.get(), TryWink(_)) + .WillOnce(testing::Invoke(MockU2fDevice::WinkDoNothing)); + + EXPECT_CALL(*device1.get(), TryWink(_)) + .WillOnce(testing::Invoke(MockU2fDevice::WinkDoNothing)); + + EXPECT_CALL(*discovery, Start()) + .WillOnce(testing::Invoke(discovery.get(), + &MockU2fDiscovery::StartSuccessAsync)); + TestRegisterCallback cb; + std::vector<std::unique_ptr<U2fDiscovery>> discoveries; + MockU2fDiscovery* discovery_weak = discovery.get(); + discoveries.push_back(std::move(discovery)); + std::unique_ptr<U2fRequest> request = U2fRegister::TryRegistration( + handles, std::vector<uint8_t>(32), std::vector<uint8_t>(32), + std::move(discoveries), cb.callback()); + discovery_weak->AddDevice(std::move(device0)); + discovery_weak->AddDevice(std::move(device1)); + + std::pair<U2fReturnCode, std::vector<uint8_t>>& response = + cb.WaitForCallback(); + EXPECT_EQ(U2fReturnCode::CONDITIONS_NOT_SATISFIED, response.first); +} + } // namespace device
diff --git a/device/u2f/u2f_request.cc b/device/u2f/u2f_request.cc index 3bb86c4..37a8658 100644 --- a/device/u2f/u2f_request.cc +++ b/device/u2f/u2f_request.cc
@@ -121,4 +121,16 @@ Transition(); } +// static +const std::vector<uint8_t>& U2fRequest::GetBogusAppParam() { + static const std::vector<uint8_t> kBogusAppParam(32, 0x41); + return kBogusAppParam; +} + +// static +const std::vector<uint8_t>& U2fRequest::GetBogusChallenge() { + static const std::vector<uint8_t> kBogusChallenge(32, 0x42); + return kBogusChallenge; +} + } // namespace device
diff --git a/device/u2f/u2f_request.h b/device/u2f/u2f_request.h index 81e31e8..33e1170 100644 --- a/device/u2f/u2f_request.h +++ b/device/u2f/u2f_request.h
@@ -45,10 +45,18 @@ COMPLETE, }; + // Returns bogus application parameter and challenge to be used to verify user + // presence. + static const std::vector<uint8_t>& GetBogusAppParam(); + static const std::vector<uint8_t>& GetBogusChallenge(); + void Transition(); virtual void TryDevice() = 0; std::unique_ptr<U2fDevice> current_device_; + std::list<std::unique_ptr<U2fDevice>> devices_; + std::list<std::unique_ptr<U2fDevice>> attempted_devices_; + State state_; std::vector<std::unique_ptr<U2fDiscovery>> discoveries_; ResponseCallback cb_; @@ -66,8 +74,6 @@ void IterateDevice(); void OnWaitComplete(); - std::list<std::unique_ptr<U2fDevice>> devices_; - std::list<std::unique_ptr<U2fDevice>> attempted_devices_; base::CancelableClosure delay_callback_; size_t started_count_ = 0;
diff --git a/device/u2f/u2f_sign.cc b/device/u2f/u2f_sign.cc index 80071eb..d3c6aad 100644 --- a/device/u2f/u2f_sign.cc +++ b/device/u2f/u2f_sign.cc
@@ -44,7 +44,7 @@ if (registered_keys_.size() == 0) { // Send registration (Fake enroll) if no keys were provided current_device_->Register( - kBogusAppParam, kBogusChallenge, + U2fRequest::GetBogusAppParam(), U2fRequest::GetBogusChallenge(), base::Bind(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(), registered_keys_.cbegin())); return; @@ -81,7 +81,7 @@ // No provided key was accepted by this device. Send registration // (Fake enroll) request to device. current_device_->Register( - kBogusAppParam, kBogusChallenge, + U2fRequest::GetBogusAppParam(), U2fRequest::GetBogusChallenge(), base::Bind(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(), registered_keys_.cbegin())); }
diff --git a/device/u2f/u2f_sign.h b/device/u2f/u2f_sign.h index 5b3f9bfb..0941ddc 100644 --- a/device/u2f/u2f_sign.h +++ b/device/u2f/u2f_sign.h
@@ -39,14 +39,6 @@ const std::vector<std::vector<uint8_t>> registered_keys_; std::vector<uint8_t> challenge_hash_; std::vector<uint8_t> app_param_; - const std::vector<uint8_t> kBogusAppParam = { - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41}; - const std::vector<uint8_t> kBogusChallenge = { - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42}; base::WeakPtrFactory<U2fSign> weak_factory_; };
diff --git a/gpu/config/gpu_util.cc b/gpu/config/gpu_util.cc index 5b0c25a..b1301534 100644 --- a/gpu/config/gpu_util.cc +++ b/gpu/config/gpu_util.cc
@@ -166,6 +166,22 @@ return kGpuFeatureStatusEnabled; } +GpuFeatureStatus GetGpuCompositingFeatureStatus( + const std::set<int>& blacklisted_features, + bool use_swift_shader, + bool use_swift_shader_for_webgl) { + if (use_swift_shader) { + // This is for testing only. Chrome should exercise the GPU accelerated + // path on top of SwiftShader driver. + return kGpuFeatureStatusEnabled; + } + if (use_swift_shader_for_webgl) + return kGpuFeatureStatusDisabled; + if (blacklisted_features.count(GPU_FEATURE_TYPE_GPU_COMPOSITING)) + return kGpuFeatureStatusBlacklisted; + return kGpuFeatureStatusEnabled; +} + void AppendWorkaroundsToCommandLine(const GpuFeatureInfo& gpu_feature_info, base::CommandLine* command_line) { if (gpu_feature_info.IsWorkaroundEnabled(DISABLE_D3D11)) { @@ -327,6 +343,15 @@ gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE] = GetAcceleratedVideoDecodeFeatureStatus( blacklisted_features, use_swift_shader, use_swift_shader_for_webgl); + gpu_feature_info.status_values[GPU_FEATURE_TYPE_GPU_COMPOSITING] = + GetGpuCompositingFeatureStatus(blacklisted_features, use_swift_shader, + use_swift_shader_for_webgl); + + if (gpu_feature_info.status_values[GPU_FEATURE_TYPE_GPU_COMPOSITING] != + kGpuFeatureStatusEnabled) { + gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS] = + kGpuFeatureStatusSoftware; + } gl::ExtensionSet all_disabled_extensions; std::string disabled_gl_extensions_value =
diff --git a/mojo/public/cpp/bindings/tests/connector_unittest.cc b/mojo/public/cpp/bindings/tests/connector_unittest.cc index 8266b910..68f51fc 100644 --- a/mojo/public/cpp/bindings/tests/connector_unittest.cc +++ b/mojo/public/cpp/bindings/tests/connector_unittest.cc
@@ -497,9 +497,7 @@ void AccumulateWithNestedLoop(MessageAccumulator* accumulator, const base::Closure& closure) { - base::RunLoop nested_run_loop; - base::MessageLoop::ScopedNestableTaskAllower allow( - base::MessageLoop::current()); + base::RunLoop nested_run_loop(base::RunLoop::Type::kNestableTasksAllowed); accumulator->set_closure(nested_run_loop.QuitClosure()); nested_run_loop.Run(); closure.Run();
diff --git a/ppapi/proxy/ppb_testing_proxy.cc b/ppapi/proxy/ppb_testing_proxy.cc index 8e85ba2e..44bbd40 100644 --- a/ppapi/proxy/ppb_testing_proxy.cc +++ b/ppapi/proxy/ppb_testing_proxy.cc
@@ -54,11 +54,9 @@ } void RunMessageLoop(PP_Instance instance) { - base::MessageLoop::ScopedNestableTaskAllower allow( - base::MessageLoop::current()); CHECK(PpapiGlobals::Get()->GetMainThreadMessageLoop()-> BelongsToCurrentThread()); - base::RunLoop().Run(); + base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).Run(); } void QuitMessageLoop(PP_Instance instance) { @@ -261,3 +259,4 @@ } // namespace proxy } // namespace ppapi +
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index a1ff8df7..b9125429 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2387,6 +2387,9 @@ crbug.com/678481 http/tests/devtools/appcache/appcache-iframe-manifests.html [ Timeout Failure Pass ] crbug.com/678481 virtual/mojo-loading/http/tests/devtools/appcache/appcache-iframe-manifests.html [ Timeout Failure Pass ] +crbug.com/782858 virtual/display_list_2d_canvas/fast/canvas/canvas-filter-units-off-screen.html [ Skip ] +crbug.com/782858 virtual/display_list_2d_canvas/fast/canvas/canvas-filter-units.html [ Skip ] + crbug.com/701047 [ Mac10.12 ] editing/caret/caret-color.html [ Failure ] crbug.com/701047 [ Mac10.12 ] editing/deleting/delete-at-paragraph-boundaries-011.html [ Failure ] crbug.com/701047 [ Mac10.12 ] editing/deleting/delete-line-001.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/editing/focus/processing-model/preventScroll-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/editing/focus/processing-model/preventScroll-expected.txt deleted file mode 100644 index 3e0d12a..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/html/editing/focus/processing-model/preventScroll-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -This is a testharness.js-based test. -PASS Sanity test -PASS elm.focus() without arguments -PASS elm.focus(undefined) -PASS elm.focus(null) -PASS elm.focus({}) -PASS elm.focus({preventScroll: false}) -FAIL elm.focus({preventScroll: true}) assert_false: expected false got true -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/editing/focus/processing-model/preventScroll.html b/third_party/WebKit/LayoutTests/external/wpt/html/editing/focus/processing-model/preventScroll.html index fda9480..97d341b3 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/editing/focus/processing-model/preventScroll.html +++ b/third_party/WebKit/LayoutTests/external/wpt/html/editing/focus/processing-model/preventScroll.html
@@ -67,7 +67,8 @@ test(() => { resetState(win); elm.focus({preventScroll: true}); - assert_false(isEntirelyInView(elm, win)); + assert_equals(win.scrollX, 0); + assert_equals(win.scrollY, 0); }, 'elm.focus({preventScroll: true})'); done();
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/canvas-composite-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/canvas-composite-expected.png index b0427cd..cf3e85646 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/canvas-composite-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/canvas-composite-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/canvas-incremental-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/canvas-incremental-repaint-expected.png index d2e9d70bb..fc457708 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/canvas-incremental-repaint-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/canvas-incremental-repaint-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/fillrect_gradient-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/fillrect_gradient-expected.png index b7dbc78..e27dc16 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/fillrect_gradient-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/fillrect_gradient-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-composite-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-composite-expected.png index 369581c..0d10a60 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-composite-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-composite-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png index 396bbdb..fe14df1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-incremental-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-incremental-repaint-expected.png index 8a308f1..d1a5b0f1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-incremental-repaint-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-incremental-repaint-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/fillrect_gradient-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/fillrect_gradient-expected.png index 46b4f87..d4b107d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/fillrect_gradient-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/fillrect_gradient-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/canvas-composite-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/canvas-composite-expected.png index 605d21f..ce3c6420c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/canvas-composite-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/canvas-composite-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png index ae68e7d6..836814b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/canvas-imageSmoothingEnabled-patterns-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/canvas-incremental-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/canvas-incremental-repaint-expected.png index 6b357e5..aa94bdad 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/canvas-incremental-repaint-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/canvas-incremental-repaint-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/fillrect_gradient-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/fillrect_gradient-expected.png index 6c923768..5505ce312 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/fillrect_gradient-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/fillrect_gradient-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-arc-circumference-expected.png b/third_party/WebKit/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-arc-circumference-expected.png deleted file mode 100644 index 7ecb23a..0000000 --- a/third_party/WebKit/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-arc-circumference-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-arc-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-arc-circumference-fill-expected.png deleted file mode 100644 index f44424a..0000000 --- a/third_party/WebKit/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-arc-circumference-fill-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-composite-transformclip-expected.png b/third_party/WebKit/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-composite-transformclip-expected.png deleted file mode 100644 index 6ff69f8..0000000 --- a/third_party/WebKit/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-composite-transformclip-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-ellipse-circumference-expected.png b/third_party/WebKit/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-ellipse-circumference-expected.png deleted file mode 100644 index 079d827..0000000 --- a/third_party/WebKit/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-ellipse-circumference-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-ellipse-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-ellipse-circumference-fill-expected.png deleted file mode 100644 index 9679b87..0000000 --- a/third_party/WebKit/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-ellipse-circumference-fill-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/Source/core/core_idl_files.gni b/third_party/WebKit/Source/core/core_idl_files.gni index 30ca70e..3c151af 100644 --- a/third_party/WebKit/Source/core/core_idl_files.gni +++ b/third_party/WebKit/Source/core/core_idl_files.gni
@@ -593,6 +593,7 @@ "geometry/DOMPointInit.idl", "geometry/DOMQuadInit.idl", "geometry/DOMRectInit.idl", + "html/FocusOptions.idl", "html/AssignedNodesOptions.idl", "html/ImageDataColorSettings.idl", "html/canvas/CanvasContextCreationAttributes.idl",
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp index 6a8aad2..a0c751a 100644 --- a/third_party/WebKit/Source/core/dom/Document.cpp +++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -4538,7 +4538,8 @@ goto SetFocusedElementDone; } CancelFocusAppearanceUpdate(); - focused_element_->UpdateFocusAppearance(params.selection_behavior); + focused_element_->UpdateFocusAppearanceWithOptions( + params.selection_behavior, params.options); // Dispatch the focus event and let the node do any other focus related // activities (important for text fields)
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp index e32df9e..4f149e6 100644 --- a/third_party/WebKit/Source/core/dom/Element.cpp +++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -2837,6 +2837,11 @@ return GetElementData()->Attributes().Find(q_name); } +void Element::focus(FocusOptions options) { + focus(FocusParams(SelectionBehaviorOnFocus::kRestore, kWebFocusTypeNone, + nullptr, options)); +} + void Element::focus(const FocusParams& params) { if (!isConnected()) return; @@ -2867,7 +2872,7 @@ .FindFocusableElementInShadowHost(*this); if (found && IsShadowIncludingInclusiveAncestorOf(found)) { found->focus(FocusParams(SelectionBehaviorOnFocus::kReset, - kWebFocusTypeForward, nullptr)); + kWebFocusTypeForward, nullptr, params.options)); return; } } @@ -2891,6 +2896,12 @@ void Element::UpdateFocusAppearance( SelectionBehaviorOnFocus selection_behavior) { + UpdateFocusAppearanceWithOptions(selection_behavior, FocusOptions()); +} + +void Element::UpdateFocusAppearanceWithOptions( + SelectionBehaviorOnFocus selection_behavior, + const FocusOptions& options) { if (selection_behavior == SelectionBehaviorOnFocus::kNone) return; if (IsRootEditableElement(*this)) { @@ -2918,10 +2929,13 @@ .SetShouldClearTypingStyle(true) .SetDoNotSetFocus(true) .Build()); - frame->Selection().RevealSelection(); + if (!options.preventScroll()) + frame->Selection().RevealSelection(); } else if (GetLayoutObject() && !GetLayoutObject()->IsLayoutEmbeddedContent()) { - GetLayoutObject()->ScrollRectToVisible(BoundingBox()); + if (!options.preventScroll()) { + GetLayoutObject()->ScrollRectToVisible(BoundingBox()); + } } }
diff --git a/third_party/WebKit/Source/core/dom/Element.h b/third_party/WebKit/Source/core/dom/Element.h index 61dd005..c30c31c 100644 --- a/third_party/WebKit/Source/core/dom/Element.h +++ b/third_party/WebKit/Source/core/dom/Element.h
@@ -31,6 +31,7 @@ #include "core/dom/ContainerNode.h" #include "core/dom/ElementData.h" #include "core/dom/WhitespaceAttacher.h" +#include "core/html/FocusOptions.h" #include "core/html_names.h" #include "core/resize_observer/ResizeObserver.h" #include "platform/bindings/TraceWrapperMember.h" @@ -55,6 +56,7 @@ class ElementShadow; class ExceptionState; class FloatQuad; +class FocusOptions; class Image; class InputDeviceCapabilities; class Locale; @@ -118,15 +120,18 @@ FocusParams() {} FocusParams(SelectionBehaviorOnFocus selection, WebFocusType focus_type, - InputDeviceCapabilities* capabilities) + InputDeviceCapabilities* capabilities, + FocusOptions focus_options = FocusOptions()) : selection_behavior(selection), type(focus_type), - source_capabilities(capabilities) {} + source_capabilities(capabilities), + options(focus_options) {} SelectionBehaviorOnFocus selection_behavior = SelectionBehaviorOnFocus::kRestore; WebFocusType type = kWebFocusTypeNone; Member<InputDeviceCapabilities> source_capabilities = nullptr; + FocusOptions options = FocusOptions(); }; typedef HeapVector<TraceWrapperMember<Attr>> AttrNodeList; @@ -567,7 +572,11 @@ virtual Image* ImageContents() { return nullptr; } virtual void focus(const FocusParams& = FocusParams()); - virtual void UpdateFocusAppearance(SelectionBehaviorOnFocus); + void focus(FocusOptions); + + void UpdateFocusAppearance(SelectionBehaviorOnFocus); + virtual void UpdateFocusAppearanceWithOptions(SelectionBehaviorOnFocus, + const FocusOptions&); virtual void blur(); void setDistributeScroll(ScrollStateCallback*, String native_scroll_behavior);
diff --git a/third_party/WebKit/Source/core/exported/WebHistoryItem.cpp b/third_party/WebKit/Source/core/exported/WebHistoryItem.cpp index 5b41e0f..dfbaaaa 100644 --- a/third_party/WebKit/Source/core/exported/WebHistoryItem.cpp +++ b/third_party/WebKit/Source/core/exported/WebHistoryItem.cpp
@@ -213,6 +213,20 @@ return private_->GetViewState(); } +ScrollAnchorData WebHistoryItem::GetScrollAnchorData() const { + if (HistoryItem::ViewState* scroll_and_view_state = + private_->GetViewState()) { + return scroll_and_view_state->scroll_anchor_data_; + } + + return ScrollAnchorData(); +} + +void WebHistoryItem::SetScrollAnchorData( + const struct ScrollAnchorData& scroll_anchor_data) { + private_->SetScrollAnchorData(scroll_anchor_data); +} + WebHistoryItem::WebHistoryItem(HistoryItem* item) : private_(item) {} WebHistoryItem& WebHistoryItem::operator=(HistoryItem* item) {
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp index c87ddb5..581f431 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp +++ b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
@@ -1890,6 +1890,13 @@ SetScrollbarsSuppressed(false); } +bool LocalFrameView::RestoreScrollAnchor( + const ScrollAnchor::SerializedAnchor& serialized_anchor) { + if (!RuntimeEnabledFeatures::ScrollAnchorSerializationEnabled()) + return false; + return scroll_anchor_.RestoreAnchor(frame_->GetDocument(), serialized_anchor); +} + void LocalFrameView::ProcessUrlFragment(const KURL& url, UrlFragmentBehavior behavior) { // If our URL has no ref, then we have no place we need to jump to. @@ -2048,6 +2055,8 @@ if (frame_->GetDocument() && !frame_->GetDocument()->GetLayoutViewItem().IsNull()) frame_->GetDocument()->Fetcher()->UpdateAllImageResourcePriorities(); + + GetFrame().Loader().SaveScrollAnchor(); } void LocalFrameView::UpdateLayersAndCompositingAfterScrollIfNeeded() {
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.h b/third_party/WebKit/Source/core/frame/LocalFrameView.h index fd326870..3a290fe 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameView.h +++ b/third_party/WebKit/Source/core/frame/LocalFrameView.h
@@ -283,6 +283,7 @@ void DidAttachDocument(); void RestoreScrollbar(); + bool RestoreScrollAnchor(const ScrollAnchor::SerializedAnchor&); void PostLayoutTimerFired(TimerBase*);
diff --git a/third_party/WebKit/Source/core/html/FocusOptions.idl b/third_party/WebKit/Source/core/html/FocusOptions.idl new file mode 100644 index 0000000..8a9ef0fc --- /dev/null +++ b/third_party/WebKit/Source/core/html/FocusOptions.idl
@@ -0,0 +1,3 @@ +dictionary FocusOptions { + [RuntimeEnabled=FocusOptions]boolean preventScroll = false; +};
diff --git a/third_party/WebKit/Source/core/html/HTMLAreaElement.cpp b/third_party/WebKit/Source/core/html/HTMLAreaElement.cpp index 7b3d10b..e8aadd3a 100644 --- a/third_party/WebKit/Source/core/html/HTMLAreaElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLAreaElement.cpp
@@ -221,14 +221,17 @@ ToLayoutImage(layout_object)->AreaElementFocusChanged(this); } -void HTMLAreaElement::UpdateFocusAppearance( - SelectionBehaviorOnFocus selection_behavior) { +void HTMLAreaElement::UpdateFocusAppearanceWithOptions( + SelectionBehaviorOnFocus selection_behavior, + const FocusOptions& options) { GetDocument().UpdateStyleAndLayoutTreeForNode(this); if (!IsFocusable()) return; - if (HTMLImageElement* image_element = this->ImageElement()) - image_element->UpdateFocusAppearance(selection_behavior); + if (HTMLImageElement* image_element = this->ImageElement()) { + image_element->UpdateFocusAppearanceWithOptions(selection_behavior, + options); + } } } // namespace blink
diff --git a/third_party/WebKit/Source/core/html/HTMLAreaElement.h b/third_party/WebKit/Source/core/html/HTMLAreaElement.h index 18de31b93..9057bb5 100644 --- a/third_party/WebKit/Source/core/html/HTMLAreaElement.h +++ b/third_party/WebKit/Source/core/html/HTMLAreaElement.h
@@ -65,7 +65,8 @@ bool IsKeyboardFocusable() const override; bool IsMouseFocusable() const override; bool LayoutObjectIsFocusable() const override; - void UpdateFocusAppearance(SelectionBehaviorOnFocus) override; + void UpdateFocusAppearanceWithOptions(SelectionBehaviorOnFocus, + const FocusOptions&) override; void SetFocused(bool, WebFocusType) override; enum Shape { kDefault, kPoly, kRect, kCircle };
diff --git a/third_party/WebKit/Source/core/html/HTMLElement.idl b/third_party/WebKit/Source/core/html/HTMLElement.idl index de97f7e..3e2e9989 100644 --- a/third_party/WebKit/Source/core/html/HTMLElement.idl +++ b/third_party/WebKit/Source/core/html/HTMLElement.idl
@@ -33,7 +33,7 @@ [RuntimeCallStatsCounter=HTMLElementClick] void click(); [CEReactions, CustomElementCallbacks] attribute long tabIndex; [CEReactions, RuntimeEnabled=InertAttribute, Reflect] attribute boolean inert; - void focus(); + void focus(optional FocusOptions options); void blur(); [CEReactions, Reflect] attribute DOMString accessKey; [CEReactions, CustomElementCallbacks] attribute boolean draggable;
diff --git a/third_party/WebKit/Source/core/html/forms/HTMLInputElement.cpp b/third_party/WebKit/Source/core/html/forms/HTMLInputElement.cpp index 07692e7a..cf57b07 100644 --- a/third_party/WebKit/Source/core/html/forms/HTMLInputElement.cpp +++ b/third_party/WebKit/Source/core/html/forms/HTMLInputElement.cpp
@@ -295,8 +295,9 @@ return input_type_->ShouldShowFocusRingOnMouseFocus(); } -void HTMLInputElement::UpdateFocusAppearance( - SelectionBehaviorOnFocus selection_behavior) { +void HTMLInputElement::UpdateFocusAppearanceWithOptions( + SelectionBehaviorOnFocus selection_behavior, + const FocusOptions& options) { if (IsTextField()) { switch (selection_behavior) { case SelectionBehaviorOnFocus::kReset: @@ -312,13 +313,15 @@ // FrameSelection::revealSelection(). It doesn't scroll correctly in a // case of RangeSelection. crbug.com/443061. GetDocument().EnsurePaintLocationDataValidForNode(this); - if (GetLayoutObject()) { - GetLayoutObject()->ScrollRectToVisible(BoundingBox()); + if (!options.preventScroll()) { + if (GetLayoutObject()) + GetLayoutObject()->ScrollRectToVisible(BoundingBox()); + if (GetDocument().GetFrame()) + GetDocument().GetFrame()->Selection().RevealSelection(); } - if (GetDocument().GetFrame()) - GetDocument().GetFrame()->Selection().RevealSelection(); } else { - TextControlElement::UpdateFocusAppearance(selection_behavior); + TextControlElement::UpdateFocusAppearanceWithOptions(selection_behavior, + options); } }
diff --git a/third_party/WebKit/Source/core/html/forms/HTMLInputElement.h b/third_party/WebKit/Source/core/html/forms/HTMLInputElement.h index 87fc485..fe8a8e9 100644 --- a/third_party/WebKit/Source/core/html/forms/HTMLInputElement.h +++ b/third_party/WebKit/Source/core/html/forms/HTMLInputElement.h
@@ -180,7 +180,8 @@ bool LayoutObjectIsNeeded(const ComputedStyle&) final; LayoutObject* CreateLayoutObject(const ComputedStyle&) override; void DetachLayoutTree(const AttachContext& = AttachContext()) final; - void UpdateFocusAppearance(SelectionBehaviorOnFocus) final; + void UpdateFocusAppearanceWithOptions(SelectionBehaviorOnFocus, + const FocusOptions&) final; // FIXME: For isActivatedSubmit and setActivatedSubmit, we should use the // NVI-idiom here by making it private virtual in all classes and expose a
diff --git a/third_party/WebKit/Source/core/html/forms/HTMLLabelElement.cpp b/third_party/WebKit/Source/core/html/forms/HTMLLabelElement.cpp index 0d5e0c9..4e5e247 100644 --- a/third_party/WebKit/Source/core/html/forms/HTMLLabelElement.cpp +++ b/third_party/WebKit/Source/core/html/forms/HTMLLabelElement.cpp
@@ -236,7 +236,7 @@ // To match other browsers, always restore previous selection. if (HTMLElement* element = control()) { element->focus(FocusParams(SelectionBehaviorOnFocus::kRestore, params.type, - params.source_capabilities)); + params.source_capabilities, params.options)); } }
diff --git a/third_party/WebKit/Source/core/html/forms/HTMLLegendElement.cpp b/third_party/WebKit/Source/core/html/forms/HTMLLegendElement.cpp index 0becaca..25da8a2 100644 --- a/third_party/WebKit/Source/core/html/forms/HTMLLegendElement.cpp +++ b/third_party/WebKit/Source/core/html/forms/HTMLLegendElement.cpp
@@ -61,7 +61,7 @@ // To match other browsers' behavior, never restore previous selection. if (HTMLFormControlElement* control = AssociatedControl()) { control->focus(FocusParams(SelectionBehaviorOnFocus::kReset, params.type, - params.source_capabilities)); + params.source_capabilities, params.options)); } }
diff --git a/third_party/WebKit/Source/core/html/forms/HTMLTextAreaElement.cpp b/third_party/WebKit/Source/core/html/forms/HTMLTextAreaElement.cpp index 5d660e9..aedb7f0 100644 --- a/third_party/WebKit/Source/core/html/forms/HTMLTextAreaElement.cpp +++ b/third_party/WebKit/Source/core/html/forms/HTMLTextAreaElement.cpp
@@ -246,8 +246,9 @@ return true; } -void HTMLTextAreaElement::UpdateFocusAppearance( - SelectionBehaviorOnFocus selection_behavior) { +void HTMLTextAreaElement::UpdateFocusAppearanceWithOptions( + SelectionBehaviorOnFocus selection_behavior, + const FocusOptions& options) { switch (selection_behavior) { case SelectionBehaviorOnFocus::kReset: // Fallthrough. case SelectionBehaviorOnFocus::kRestore: @@ -256,8 +257,10 @@ case SelectionBehaviorOnFocus::kNone: return; } - if (GetDocument().GetFrame()) - GetDocument().GetFrame()->Selection().RevealSelection(); + if (!options.preventScroll()) { + if (GetDocument().GetFrame()) + GetDocument().GetFrame()->Selection().RevealSelection(); + } } void HTMLTextAreaElement::DefaultEventHandler(Event* event) {
diff --git a/third_party/WebKit/Source/core/html/forms/HTMLTextAreaElement.h b/third_party/WebKit/Source/core/html/forms/HTMLTextAreaElement.h index b23eeda0..03637f4 100644 --- a/third_party/WebKit/Source/core/html/forms/HTMLTextAreaElement.h +++ b/third_party/WebKit/Source/core/html/forms/HTMLTextAreaElement.h
@@ -125,7 +125,8 @@ bool HasCustomFocusLogic() const override; bool ShouldShowFocusRingOnMouseFocus() const override; bool IsKeyboardFocusable() const override; - void UpdateFocusAppearance(SelectionBehaviorOnFocus) override; + void UpdateFocusAppearanceWithOptions(SelectionBehaviorOnFocus, + const FocusOptions&) override; void AccessKeyAction(bool send_mouse_events) override;
diff --git a/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp b/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp index a671d844..7f0abba 100644 --- a/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp +++ b/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp
@@ -17,6 +17,7 @@ namespace blink { using Corner = ScrollAnchor::Corner; +using SerializedAnchor = ScrollAnchor::SerializedAnchor; ScrollAnchor::ScrollAnchor() : anchor_object_(nullptr), @@ -327,6 +328,19 @@ WebFeature::kScrollAnchored); } +bool ScrollAnchor::RestoreAnchor(Document* document, + const SerializedAnchor& serialized_anchor) { + NOTIMPLEMENTED(); + return false; +} + +const SerializedAnchor ScrollAnchor::SerializeAnchor() { + // TODO(pnoland): When implementing, limit the length of the serialized + // anchor's selector to some constant. + NOTIMPLEMENTED(); + return SerializedAnchor("", LayoutPoint()); +} + void ScrollAnchor::ClearSelf() { LayoutObject* anchor_object = anchor_object_; anchor_object_ = nullptr;
diff --git a/third_party/WebKit/Source/core/layout/ScrollAnchor.h b/third_party/WebKit/Source/core/layout/ScrollAnchor.h index b78bb672..9a5a8aa4 100644 --- a/third_party/WebKit/Source/core/layout/ScrollAnchor.h +++ b/third_party/WebKit/Source/core/layout/ScrollAnchor.h
@@ -8,9 +8,11 @@ #include "core/CoreExport.h" #include "platform/geometry/LayoutPoint.h" #include "platform/heap/Handle.h" +#include "platform/wtf/text/WTFString.h" namespace blink { +class Document; class LayoutObject; class ScrollableArea; @@ -58,6 +60,31 @@ // Only meaningful if anchorObject() is non-null. Corner GetCorner() const { return corner_; } + struct SerializedAnchor { + SerializedAnchor() : simhash(0) {} + SerializedAnchor(const String& s, const LayoutPoint& p) + : selector(s), relative_offset(p), simhash(0) {} + SerializedAnchor(const String& s, const LayoutPoint& p, uint64_t hash) + : selector(s), relative_offset(p), simhash(hash) {} + + bool IsValid() { return !selector.IsEmpty(); } + + // Used to locate an element previously used as a scroll anchor. + const String selector; + // Used to restore the previous offset of the element within its scroller. + const LayoutPoint relative_offset; + // Used to compare the similarity of a prospective anchor's contents to the + // contents at the time the previous anchor was saved. + const uint64_t simhash; + }; + + // Attempt to restore |serialized_anchor| by scrolling to the element + // identified by its selector, adjusting by its relative_offset. + bool RestoreAnchor(Document*, const SerializedAnchor&); + + // Create a serialized representation of the current anchor_object_. + const SerializedAnchor SerializeAnchor(); + // Checks if we hold any references to the specified object. bool RefersTo(const LayoutObject*) const;
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp index 8d51c8cf..aa75f34 100644 --- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp +++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -316,6 +316,41 @@ frame_->GetNavigationScheduler().StartTimer(); } +bool FrameLoader::ShouldSerializeScrollAnchor() { + return RuntimeEnabledFeatures::ScrollAnchorSerializationEnabled(); +} + +void FrameLoader::SaveScrollAnchor() { + if (!ShouldSerializeScrollAnchor()) + return; + + if (!document_loader_ || !document_loader_->GetHistoryItem() || + !frame_->View()) + return; + + // Shouldn't clobber anything if we might still restore later. + if (NeedsHistoryItemRestore(document_loader_->LoadType()) && + !document_loader_->GetInitialScrollState().was_scrolled_by_user) + return; + + HistoryItem* history_item = document_loader_->GetHistoryItem(); + if (ScrollableArea* layout_scrollable_area = + frame_->View()->LayoutViewportScrollableArea()) { + ScrollAnchor* scroll_anchor = layout_scrollable_area->GetScrollAnchor(); + DCHECK(scroll_anchor); + + ScrollAnchor::SerializedAnchor serialized_anchor = + scroll_anchor->SerializeAnchor(); + if (serialized_anchor.IsValid()) { + history_item->SetScrollAnchorData( + {serialized_anchor.selector, + WebFloatPoint(serialized_anchor.relative_offset.X(), + serialized_anchor.relative_offset.Y()), + serialized_anchor.simhash}); + } + } +} + void FrameLoader::SaveScrollState() { if (!document_loader_ || !document_loader_->GetHistoryItem() || !frame_->View()) @@ -346,6 +381,9 @@ // protected. It will be detached soon. protect_provisional_loader_ = false; SaveScrollState(); + // TODO(pnoland): move this SaveScrollAnchorCall to where we fire the + // visibilitychange event with value 'hidden.' + SaveScrollAnchor(); if (frame_->GetDocument() && !SVGImage::IsInSVGImage(frame_->GetDocument())) frame_->GetDocument()->DispatchUnloadEvents(); @@ -1141,8 +1179,19 @@ return; if (should_restore_scroll) { - view->LayoutViewportScrollableArea()->SetScrollOffset( - view_state->scroll_offset_, kProgrammaticScroll); + // TODO(pnoland): attempt to restore the anchor in more places than this. + // Anchor-based restore should allow for earlier restoration. + bool did_restore = + ShouldSerializeScrollAnchor() && + view->RestoreScrollAnchor( + {view_state->scroll_anchor_data_.selector_, + LayoutPoint(view_state->scroll_anchor_data_.offset_.x, + view_state->scroll_anchor_data_.offset_.y), + view_state->scroll_anchor_data_.simhash_}); + if (!did_restore) { + view->LayoutViewportScrollableArea()->SetScrollOffset( + view_state->scroll_offset_, kProgrammaticScroll); + } } // For main frame restore scale and visual viewport position
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.h b/third_party/WebKit/Source/core/loader/FrameLoader.h index 6ddc391a..9ee291c9 100644 --- a/third_party/WebKit/Source/core/loader/FrameLoader.h +++ b/third_party/WebKit/Source/core/loader/FrameLoader.h
@@ -176,6 +176,8 @@ FrameLoadType, Document*); + bool ShouldSerializeScrollAnchor(); + void SaveScrollAnchor(); void SaveScrollState(); void RestoreScrollPositionAndViewState();
diff --git a/third_party/WebKit/Source/core/loader/HistoryItem.cpp b/third_party/WebKit/Source/core/loader/HistoryItem.cpp index a20a7fe..90ab5c2c 100644 --- a/third_party/WebKit/Source/core/loader/HistoryItem.cpp +++ b/third_party/WebKit/Source/core/loader/HistoryItem.cpp
@@ -93,6 +93,13 @@ view_state_->page_scale_factor_ = scale_factor; } +void HistoryItem::SetScrollAnchorData( + const ScrollAnchorData& scroll_anchor_data) { + if (!view_state_) + view_state_ = WTF::MakeUnique<ViewState>(); + view_state_->scroll_anchor_data_ = scroll_anchor_data; +} + void HistoryItem::SetDocumentState(const Vector<String>& state) { DCHECK(!document_state_); document_state_vector_ = state;
diff --git a/third_party/WebKit/Source/core/loader/HistoryItem.h b/third_party/WebKit/Source/core/loader/HistoryItem.h index b90548a..83da5ed 100644 --- a/third_party/WebKit/Source/core/loader/HistoryItem.h +++ b/third_party/WebKit/Source/core/loader/HistoryItem.h
@@ -32,10 +32,12 @@ #include "core/loader/FrameLoaderTypes.h" #include "platform/geometry/FloatPoint.h" #include "platform/geometry/IntPoint.h" +#include "platform/geometry/LayoutPoint.h" #include "platform/heap/Handle.h" #include "platform/scroll/ScrollTypes.h" #include "platform/weborigin/Referrer.h" #include "platform/wtf/text/WTFString.h" +#include "public/platform/WebScrollAnchorData.h" #include "public/platform/modules/fetch/fetch_api_request.mojom-shared.h" namespace blink { @@ -67,6 +69,7 @@ ScrollOffset visual_viewport_scroll_offset_; ScrollOffset scroll_offset_; float page_scale_factor_; + ScrollAnchorData scroll_anchor_data_; }; ViewState* GetViewState() const { return view_state_.get(); } @@ -112,6 +115,8 @@ return scroll_restoration_type_; } + void SetScrollAnchorData(const ScrollAnchorData&); + void SetFormInfoFromRequest(const ResourceRequest&); void SetFormData(scoped_refptr<EncodedFormData>); void SetFormContentType(const AtomicString&);
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js index f86fc83..c1748b9 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
@@ -1458,7 +1458,8 @@ if (this._prettyPrintInfobar) return; - if (!TextUtils.isMinified(/** @type {string} */ (this.uiSourceCode().content()))) + var content = this.uiSourceCode().content(); + if (!content || !TextUtils.isMinified(content)) return; this._prettyPrintInfobar = UI.Infobar.create(
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp index 3c960e5..4c05e091 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp +++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
@@ -51,7 +51,6 @@ #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/effects/SkHighContrastFilter.h" #include "third_party/skia/include/effects/SkLumaColorFilter.h" -#include "third_party/skia/include/effects/SkPictureImageFilter.h" #include "third_party/skia/include/effects/SkTableColorFilter.h" #include "third_party/skia/include/pathops/SkPathOps.h" #include "third_party/skia/include/utils/SkNullCanvas.h" @@ -351,17 +350,17 @@ PaintFlags flags; flags.setBlendMode(op); + flags.setFilterQuality( + static_cast<SkFilterQuality>(ImageInterpolationQuality())); canvas_->save(); - SkRect source_bounds = src; - SkRect sk_bounds = dest; - SkMatrix transform; - transform.setRectToRect(source_bounds, sk_bounds, SkMatrix::kFill_ScaleToFit); - canvas_->concat(transform); - flags.setImageFilter(SkPictureImageFilter::MakeForLocalSpace( - ToSkPicture(record, source_bounds), source_bounds, - static_cast<SkFilterQuality>(ImageInterpolationQuality()))); - canvas_->saveLayer(&source_bounds, &flags); - canvas_->restore(); + canvas_->concat( + SkMatrix::MakeRectToRect(src, dest, SkMatrix::kFill_ScaleToFit)); + canvas_->drawImage(PaintImageBuilder::WithDefault() + .set_paint_record(record, RoundedIntRect(src), + PaintImage::GetNextContentId()) + .set_id(PaintImage::GetNextId()) + .TakePaintImage(), + 0, 0, &flags); canvas_->restore(); }
diff --git a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 b/third_party/WebKit/Source/platform/runtime_enabled_features.json5 index 28861401..f83c41e2 100644 --- a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 +++ b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
@@ -413,6 +413,10 @@ status: "stable", }, { + name: "FocusOptions", + status: "stable", + }, + { name: "FontCacheScaling", status: "test", }, @@ -893,6 +897,10 @@ settable_from_internals: true, status: "experimental", }, + // Serialize and restore scroll anchors. + { + name: "ScrollAnchorSerialization", + }, { name: "ScrollCustomization", },
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn index 8f8808b..205fffcb 100644 --- a/third_party/WebKit/public/BUILD.gn +++ b/third_party/WebKit/public/BUILD.gn
@@ -316,6 +316,7 @@ "platform/WebRenderingStats.h", "platform/WebRuntimeFeatures.h", "platform/WebScreenInfo.h", + "platform/WebScrollAnchorData.h", "platform/WebScrollBoundaryBehavior.h", "platform/WebScrollbar.h", "platform/WebScrollbarBehavior.h",
diff --git a/third_party/WebKit/public/platform/WebScrollAnchorData.h b/third_party/WebKit/public/platform/WebScrollAnchorData.h new file mode 100644 index 0000000..feda183f --- /dev/null +++ b/third_party/WebKit/public/platform/WebScrollAnchorData.h
@@ -0,0 +1,54 @@ +/* + * Copyright (C) 2017 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebScrollAnchorData_h +#define WebScrollAnchorData_h + +#include "public/platform/WebFloatPoint.h" +#include "public/platform/WebString.h" + +namespace blink { + +struct ScrollAnchorData { + WebString selector_; + WebFloatPoint offset_; + uint64_t simhash_; + + ScrollAnchorData(const WebString& selector, + const WebFloatPoint& offset, + uint64_t simhash) + : selector_(selector), offset_(offset), simhash_(simhash) {} + + ScrollAnchorData() { ScrollAnchorData(WebString(), WebFloatPoint(0, 0), 0); } +}; + +} // namespace blink + +#endif // WebScrollAnchorData_h
diff --git a/third_party/WebKit/public/web/WebHistoryItem.h b/third_party/WebKit/public/web/WebHistoryItem.h index b4e0ade..547e0582 100644 --- a/third_party/WebKit/public/web/WebHistoryItem.h +++ b/third_party/WebKit/public/web/WebHistoryItem.h
@@ -35,6 +35,7 @@ #include "public/platform/WebHistoryScrollRestorationType.h" #include "public/platform/WebPrivatePtr.h" #include "public/platform/WebReferrerPolicy.h" +#include "public/platform/WebScrollAnchorData.h" #include "public/platform/WebString.h" namespace blink { @@ -119,6 +120,9 @@ BLINK_EXPORT bool DidSaveScrollOrScaleState() const; + BLINK_EXPORT ScrollAnchorData GetScrollAnchorData() const; + BLINK_EXPORT void SetScrollAnchorData(const ScrollAnchorData&); + #if INSIDE_BLINK BLINK_EXPORT WebHistoryItem(HistoryItem*); BLINK_EXPORT WebHistoryItem& operator=(HistoryItem*);
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index b7b1c69..68fe2ad 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc
@@ -544,9 +544,10 @@ void Compositor::RequestNewLayerTreeFrameSink() { DCHECK(!layer_tree_frame_sink_requested_); - layer_tree_frame_sink_requested_ = true; if (widget_valid_) context_factory_->CreateLayerTreeFrameSink(weak_ptr_factory_.GetWeakPtr()); + else + layer_tree_frame_sink_requested_ = true; } void Compositor::DidFailToInitializeLayerTreeFrameSink() {
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index 9c9ddf5..078b9dd0 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -2,7 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//build/config/linux/pangocairo/pangocairo.gni") import("//build/config/ui.gni") import("//device/vr/features/features.gni") import("//testing/test.gni") @@ -219,7 +218,6 @@ "skia_paint_util.cc", "skia_paint_util.h", ] - deps += [ "//build/config/linux/pangocairo:features" ] } configs += [ @@ -387,10 +385,6 @@ sources -= [ "path_x11.cc" ] } - if (use_pangocairo) { - configs += [ "//build/config/linux/pangocairo" ] - } - if (is_fuchsia) { sources += [ "font_fallback_fuchsia.cc",
diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc index c2b610ec..7855804 100644 --- a/ui/gfx/canvas.cc +++ b/ui/gfx/canvas.cc
@@ -9,7 +9,6 @@ #include "base/i18n/rtl.h" #include "base/logging.h" -#include "build/config/linux/pangocairo/features.h" #include "cc/paint/paint_flags.h" #include "cc/paint/paint_shader.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -36,13 +35,6 @@ Size pixel_size = ScaleToCeiledSize(size, image_scale); canvas_ = CreateOwnedCanvas(pixel_size, is_opaque); -#if !BUILDFLAG(USE_PANGOCAIRO) - // skia::PlatformCanvas instances are initialized to 0 by Cairo, but - // uninitialized on other platforms. - if (!is_opaque) - canvas_->clear(SkColorSetARGB(0, 0, 0, 0)); -#endif - SkScalar scale_scalar = SkFloatToScalar(image_scale); canvas_->scale(scale_scalar, scale_scalar); }
diff --git a/ui/gfx/native_widget_types.h b/ui/gfx/native_widget_types.h index 17f9be2..58c5e60 100644 --- a/ui/gfx/native_widget_types.h +++ b/ui/gfx/native_widget_types.h
@@ -91,8 +91,6 @@ class NSWindow; class NSTextField; #endif // __OBJC__ -#elif defined(OS_POSIX) -typedef struct _cairo cairo_t; #endif #if defined(OS_ANDROID)