diff --git a/BUILD.gn b/BUILD.gn index 48a8693..2c25037 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -586,6 +586,7 @@ if (is_win) { deps += [ "//base:pe_image_test", + "//chrome/browser/browser_switcher/bho:browser_switcher_bho", "//chrome/chrome_cleaner:chrome_cleaner_unittests", "//chrome/elevation_service:elevation_service_unittests", "//chrome/install_static:install_static_unittests",
diff --git a/DEPS b/DEPS index fe85489..9b419f9 100644 --- a/DEPS +++ b/DEPS
@@ -129,7 +129,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'd9b8eed84814a85509f7f7d6c0894199b4183eb5', + 'skia_revision': '80658204f417f90711900b2c761d04f9e835c928', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -141,11 +141,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '0086a8acd8799ef36a84c55781429703584be814', + 'angle_revision': 'fc15ae5571b3b303a26b74dd8085b5c54f964b39', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': 'eba396cc66d3d3d64859b769eb63a359b2d8c065', + 'swiftshader_revision': '3ed8ba0c5a4b71f3a4a20b2a84e65725186e183f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -196,7 +196,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '072a6f14b64c59e8ff678b7ae3ce7596a00483e4', + 'catapult_revision': '3d77140b9d58765cd6fb3aaf541f8a0436375ad0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -268,7 +268,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '865cad89b916a56fefd90d4eb1ab4345819bd4ec', + 'dawn_revision': '2d4c66d2b865a18cd892906e1135eafcd8404a21', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -805,7 +805,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '3674ce2d885b689296361236d6d537ea8e3ba73f', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '69a3f230f57f3495e4e9b643c4e1031bb500b8a0', 'condition': 'checkout_linux', }, @@ -975,7 +975,7 @@ }, 'src/third_party/hunspell_dictionaries': - Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + 'f7ce90e84f5aa9acfbc9b7ca04e567bf471e5bcd', + Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + '83f4659730b4de886afa5ea19f71f332a009d2ee', 'src/third_party/icu': Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '69c72a6dfe1d1ef5677db03920518638f535591f', @@ -1239,7 +1239,7 @@ }, 'src/third_party/re2/src': - Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + '5a982a6dba7c4d98b443471823be0bd9d9677143', + Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + 'a98fad02c421896bc75d97f49ccd245cdce7dd55', 'src/third_party/r8': { 'packages': [ @@ -1384,7 +1384,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@88192dcff2d1e4b3c082850c285bdc0c5cd5dd02', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@cce609cb3785abea3b5ed455cd1b331a00152d7b', 'condition': 'checkout_src_internal', },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 389d66d..fd062ae 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -1761,6 +1761,7 @@ r"^chrome[\\/]browser[\\/]chrome_browser_main\.cc$", r"^chrome[\\/]browser[\\/]ui[\\/]startup[\\/]" r"startup_browser_creator\.cc$", + r"^chrome[\\/]browser[\\/]browser_switcher[\\/]bho[\\/].*", r"^chrome[\\/]installer[\\/]setup[\\/].*", r"^chrome[\\/]chrome_cleaner[\\/].*", r"chrome[\\/]browser[\\/]diagnostics[\\/]" +
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index 1b45d0b..b476c0a 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -895,7 +895,7 @@ std::unique_ptr<content::LoginDelegate> AwContentBrowserClient::CreateLoginDelegate( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, const content::GlobalRequestID& request_id, bool is_main_frame,
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h index b5c8563..a6eae7b3 100644 --- a/android_webview/browser/aw_content_browser_client.h +++ b/android_webview/browser/aw_content_browser_client.h
@@ -194,7 +194,7 @@ bool* ignore_navigation) override; bool ShouldCreateTaskScheduler() override; std::unique_ptr<content::LoginDelegate> CreateLoginDelegate( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, const content::GlobalRequestID& request_id, bool is_main_frame,
diff --git a/android_webview/browser/aw_http_auth_handler.cc b/android_webview/browser/aw_http_auth_handler.cc index 2e9f69aa..4fa2eb3 100644 --- a/android_webview/browser/aw_http_auth_handler.cc +++ b/android_webview/browser/aw_http_auth_handler.cc
@@ -24,13 +24,13 @@ namespace android_webview { -AwHttpAuthHandler::AwHttpAuthHandler(net::AuthChallengeInfo* auth_info, +AwHttpAuthHandler::AwHttpAuthHandler(const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, bool first_auth_attempt, LoginAuthRequiredCallback callback) : WebContentsObserver(web_contents), - host_(auth_info->challenger.host()), - realm_(auth_info->realm), + host_(auth_info.challenger.host()), + realm_(auth_info.realm), callback_(std::move(callback)), weak_factory_(this) { DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/android_webview/browser/aw_http_auth_handler.h b/android_webview/browser/aw_http_auth_handler.h index 3903391e..2ddb4e9 100644 --- a/android_webview/browser/aw_http_auth_handler.h +++ b/android_webview/browser/aw_http_auth_handler.h
@@ -29,7 +29,7 @@ class AwHttpAuthHandler : public content::LoginDelegate, public content::WebContentsObserver { public: - AwHttpAuthHandler(net::AuthChallengeInfo* auth_info, + AwHttpAuthHandler(const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, bool first_auth_attempt, LoginAuthRequiredCallback callback);
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 5bbbec4..3b213e1c 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1336,6 +1336,9 @@ "//chromeos/audio", "//chromeos/components/multidevice/logging", "//chromeos/dbus", + + # TODO(stevenjb): Investigate whether this is OK. https://crbug.com/644336. + "//chromeos/dbus/audio", "//chromeos/dbus/power", "//chromeos/dbus/power:power_manager_proto", "//chromeos/dbus/services:services", @@ -1702,6 +1705,7 @@ "magnifier/magnifier_test_utils.h", "magnifier/magnifier_utils_unittest.cc", "magnifier/partial_magnification_controller_unittest.cc", + "media/media_controller_unittest.cc", "media/media_notification_background_unittest.cc", "media/media_notification_controller_unittest.cc", "media/media_notification_view_unittest.cc", @@ -2208,9 +2212,13 @@ "//cc:test_support", "//chromeos", - # TODO(stevenjb): Investigate whether this is OK. https://crbug.com/644336. + # TODO(https://crbug.com/644336): Move CrasAudioHandler to Chrome or Ash + # only and add a mojo client. "//chromeos/audio", "//chromeos/dbus:test_support", + + # TODO(https://crbug.com/644336): Remove dependencies on CrasAudioClient. + "//chromeos/dbus/audio", "//chromeos/dbus/power", "//chromeos/dbus/system_clock",
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc index 4394d784..905f0be 100644 --- a/ash/app_list/app_list_controller_impl.cc +++ b/ash/app_list/app_list_controller_impl.cc
@@ -254,12 +254,15 @@ } void AppListControllerImpl::SetModelData( + int profile_id, std::vector<AppListItemMetadataPtr> apps, bool is_search_engine_google) { // Clear old model data. model_->DeleteAllItems(); search_model_.DeleteAllResults(); + profile_id_ = profile_id; + // Populate new models. First populate folders and then other items to avoid // automatically creating folder items in |AddItemToFolder|. for (auto& app : apps) { @@ -395,9 +398,9 @@ void AppListControllerImpl::OnAppListItemAdded(app_list::AppListItem* item) { if (item->is_folder()) - client_->OnFolderCreated(item->CloneMetadata()); + client_->OnFolderCreated(profile_id_, item->CloneMetadata()); else if (item->is_page_break()) - client_->OnPageBreakItemAdded(item->id(), item->position()); + client_->OnPageBreakItemAdded(profile_id_, item->id(), item->position()); } void AppListControllerImpl::OnActiveUserPrefServiceChanged( @@ -424,15 +427,15 @@ return; if (item->is_folder()) - client_->OnFolderDeleted(item->CloneMetadata()); + client_->OnFolderDeleted(profile_id_, item->CloneMetadata()); if (item->is_page_break()) - client_->OnPageBreakItemDeleted(item->id()); + client_->OnPageBreakItemDeleted(profile_id_, item->id()); } void AppListControllerImpl::OnAppListItemUpdated(app_list::AppListItem* item) { if (client_) - client_->OnItemUpdated(item->CloneMetadata()); + client_->OnItemUpdated(profile_id_, item->CloneMetadata()); } void AppListControllerImpl::OnAppListStateChanged(ash::AppListState new_state, @@ -920,7 +923,7 @@ void AppListControllerImpl::ActivateItem(const std::string& id, int event_flags) { if (client_) - client_->ActivateItem(id, event_flags); + client_->ActivateItem(profile_id_, id, event_flags); ResetHomeLauncherIfShown(); } @@ -929,14 +932,14 @@ const std::string& id, GetContextMenuModelCallback callback) { if (client_) - client_->GetContextMenuModel(id, std::move(callback)); + client_->GetContextMenuModel(profile_id_, id, std::move(callback)); } void AppListControllerImpl::ContextMenuItemSelected(const std::string& id, int command_id, int event_flags) { if (client_) - client_->ContextMenuItemSelected(id, command_id, event_flags); + client_->ContextMenuItemSelected(profile_id_, id, command_id, event_flags); } void AppListControllerImpl::ShowWallpaperContextMenu(
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h index 74ed8533..2b757a0f 100644 --- a/ash/app_list/app_list_controller_impl.h +++ b/ash/app_list/app_list_controller_impl.h
@@ -102,7 +102,8 @@ void SetItemIsInstalling(const std::string& id, bool is_installing) override; void SetItemPercentDownloaded(const std::string& id, int32_t percent_downloaded) override; - void SetModelData(std::vector<AppListItemMetadataPtr> apps, + void SetModelData(int profile_id, + std::vector<AppListItemMetadataPtr> apps, bool is_search_engine_google) override; void SetSearchResultMetadata(SearchResultMetadataPtr metadata) override; @@ -328,6 +329,11 @@ // True if Shutdown() has been called. bool is_shutdown_ = false; + // Used in mojo callings to specify the profile whose app list data is + // read/written by Ash side through IPC. Notice that in multi-profile mode, + // each profile has its own AppListModelUpdater to manipulate app list items. + int profile_id_ = kAppListInvalidProfileID; + base::ObserverList<AppListControllerObserver> observers_; DISALLOW_COPY_AND_ASSIGN(AppListControllerImpl);
diff --git a/ash/app_list/app_list_metrics.h b/ash/app_list/app_list_metrics.h index ade0ecc..b8fb46c 100644 --- a/ash/app_list/app_list_metrics.h +++ b/ash/app_list/app_list_metrics.h
@@ -192,14 +192,16 @@ // written to logs. New enum values can be added, but existing enums must never // be renumbered or deleted and reused. enum AppListAppMovingType { - kMoveIntoFolder = 0, - kMoveOutOfFolder = 1, + kMoveByDragIntoFolder = 0, + kMoveByDragOutOfFolder = 1, kMoveIntoAnotherFolder = 2, kReorderByDragInFolder = 3, kReorderByDragInTopLevel = 4, kReorderByKeyboardInFolder = 5, kReorderByKeyboardInTopLevel = 6, - kMaxAppListAppMovingType = 7, + kMoveByKeyboardIntoFolder = 7, + kMoveByKeyboardOutOfFolder = 8, + kMaxAppListAppMovingType = 9, }; // Different places a search result can be launched from. These values do not
diff --git a/ash/app_list/test/test_app_list_client.cc b/ash/app_list/test/test_app_list_client.cc index f800f497..b926817 100644 --- a/ash/app_list/test/test_app_list_client.cc +++ b/ash/app_list/test/test_app_list_client.cc
@@ -25,6 +25,7 @@ } void TestAppListClient::GetContextMenuModel( + int profile_id, const std::string& id, GetContextMenuModelCallback callback) { std::move(callback).Run({});
diff --git a/ash/app_list/test/test_app_list_client.h b/ash/app_list/test/test_app_list_client.h index 6826bf465..09f9f252 100644 --- a/ash/app_list/test/test_app_list_client.h +++ b/ash/app_list/test/test_app_list_client.h
@@ -40,20 +40,28 @@ int event_flags) override {} void ViewClosing() override {} void ViewShown(int64_t display_id) override {} - void ActivateItem(const std::string& id, int event_flags) override {} - void GetContextMenuModel(const std::string& id, + void ActivateItem(int profile_id, + const std::string& id, + int event_flags) override {} + void GetContextMenuModel(int profile_id, + const std::string& id, GetContextMenuModelCallback callback) override; - void ContextMenuItemSelected(const std::string& id, + void ContextMenuItemSelected(int profile_id, + const std::string& id, int command_id, int event_flags) override {} void OnAppListTargetVisibilityChanged(bool visible) override {} void OnAppListVisibilityChanged(bool visible) override {} - void OnFolderCreated(mojom::AppListItemMetadataPtr item) override {} - void OnFolderDeleted(mojom::AppListItemMetadataPtr item) override {} - void OnItemUpdated(mojom::AppListItemMetadataPtr item) override {} - void OnPageBreakItemAdded(const std::string& id, + void OnFolderCreated(int profile_id, + mojom::AppListItemMetadataPtr item) override {} + void OnFolderDeleted(int profile_id, + mojom::AppListItemMetadataPtr item) override {} + void OnItemUpdated(int profile_id, + mojom::AppListItemMetadataPtr item) override {} + void OnPageBreakItemAdded(int profile_id, + const std::string& id, const syncer::StringOrdinal& position) override {} - void OnPageBreakItemDeleted(const std::string& id) override {} + void OnPageBreakItemDeleted(int profile_id, const std::string& id) override {} void GetNavigableContentsFactory( mojo::PendingReceiver<content::mojom::NavigableContentsFactory> receiver) override {}
diff --git a/ash/app_list/views/app_list_folder_view.cc b/ash/app_list/views/app_list_folder_view.cc index 76e8c59..74d56657 100644 --- a/ash/app_list/views/app_list_folder_view.cc +++ b/ash/app_list/views/app_list_folder_view.cc
@@ -812,6 +812,13 @@ container_view_->apps_grid_view()->SetDragViewVisible(visible); } +void AppListFolderView::HandleKeyboardReparent(AppListItemView* reparented_view, + ui::KeyboardCode key_code) { + container_view_->ReparentFolderItemTransit(folder_item_); + container_view_->apps_grid_view()->HandleKeyboardReparent(reparented_view, + key_code); +} + void AppListFolderView::GetAccessibleNodeData(ui::AXNodeData* node_data) { node_data->role = ax::mojom::Role::kGenericContainer; }
diff --git a/ash/app_list/views/app_list_folder_view.h b/ash/app_list/views/app_list_folder_view.h index c212504..9318baf5 100644 --- a/ash/app_list/views/app_list_folder_view.h +++ b/ash/app_list/views/app_list_folder_view.h
@@ -150,6 +150,8 @@ bool IsPointOutsideOfFolderBoundary(const gfx::Point& point) override; bool IsOEMFolder() const override; void SetRootLevelDragViewVisible(bool visible) override; + void HandleKeyboardReparent(AppListItemView* reparented_view, + ui::KeyboardCode key_code) override; // Returns the compositor associated to the widget containing this view. // Returns nullptr if there isn't one associated with this widget.
diff --git a/ash/app_list/views/app_list_item_view.h b/ash/app_list/views/app_list_item_view.h index c647b23a..ef9b7df 100644 --- a/ash/app_list/views/app_list_item_view.h +++ b/ash/app_list/views/app_list_item_view.h
@@ -122,6 +122,8 @@ // Enables background blur for folder icon if |enabled| is true. void SetBackgroundBlurEnabled(bool enabled); + bool is_folder() const { return is_folder_; } + private: class IconImageView;
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index 206895b..60ac32b 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc
@@ -672,9 +672,7 @@ if (drop_target_region_ == ON_ITEM && DraggedItemCanEnterFolder() && DropTargetIsValidFolder()) { MaybeCreateFolderDroppingAccessibilityEvent(); - MoveItemToFolder(drag_view_, drop_target_); - folder_item_view = - GetViewDisplayedAtSlotOnCurrentPage(drop_target_.slot); + folder_item_view = MoveItemToFolder(drag_view_, drop_target_); } else if (IsValidReorderTargetIndex(drop_target_)) { // Ensure reorder event has already been announced by the end of drag. MaybeCreateDragReorderAccessibilityEvent(); @@ -954,7 +952,7 @@ return true; if (IsArrowKeyEvent(event) && event.IsControlDown()) { - HandleKeyboardAppMovement(event.key_code()); + HandleKeyboardAppOperations(event.key_code(), event.IsShiftDown()); return true; } @@ -1604,19 +1602,51 @@ return folder_delegate_->IsOEMFolder(); } -void AppsGridView::HandleKeyboardAppMovement(ui::KeyboardCode key_code) { +void AppsGridView::HandleKeyboardAppOperations(ui::KeyboardCode key_code, + bool folder) { DCHECK(selected_view_); - const GridIndex target_index = GetTargetGridIndexForKeyboardMove(key_code); - if (target_index == GetIndexOfView(selected_view_) || - !IsValidReorderTargetIndex(target_index)) { - return; + if (folder) { + if (folder_delegate_) + folder_delegate_->HandleKeyboardReparent(selected_view_, key_code); + else + HandleKeyboardFoldering(key_code); + } else { + HandleKeyboardMove(key_code); } +} - handling_keyboard_move_ = true; +void AppsGridView::HandleKeyboardFoldering(ui::KeyboardCode key_code) { + const GridIndex target_index = GetTargetGridIndexForKeyboardMove(key_code); + if (!CanMoveSelectedToTargetForKeyboardFoldering(target_index)) + return; - MoveAppListItemViewForKeyboardMove(target_index); - AnnounceReorder(target_index); + const base::string16 moving_view_title = selected_view_->title()->text(); + AppListItemView* folder_item = MoveItemToFolder(selected_view_, target_index); + AnnounceFolderDrop(moving_view_title, folder_item->title()->text(), + folder_item->is_folder()); + DCHECK(folder_item->is_folder()); + folder_item->RequestFocus(); + Layout(); + RecordAppMovingTypeMetrics(kMoveByKeyboardIntoFolder); +} + +bool AppsGridView::CanMoveSelectedToTargetForKeyboardFoldering( + const GridIndex& target_index) const { + DCHECK(selected_view_); + + // To folder an item, the item must be moved into the folder, not the folder + // moved over the item. + const AppListItem* selected_item = selected_view_->item(); + if (selected_item->is_folder()) + return false; + + // Do not allow foldering across pages because the destination folder cannot + // be seen. + if (target_index.page != GetIndexOfView(selected_view_).page) + return false; + + return true; } bool AppsGridView::HandleVerticalFocusMovement(bool arrow_up) { @@ -1740,6 +1770,7 @@ } else if (drop_target_region_ != NO_TARGET && IsValidReorderTargetIndex(drop_target_)) { ReparentItemForReorder(drag_view_, drop_target_); + RecordAppMovingTypeMetrics(kMoveByDragOutOfFolder); // Announce accessibility event before the end of drag for reparented // item. MaybeCreateDragReorderAccessibilityEvent(); @@ -1854,6 +1885,37 @@ return true; } +void AppsGridView::HandleKeyboardReparent(AppListItemView* reparented_view, + ui::KeyboardCode key_code) { + DCHECK(key_code == ui::VKEY_LEFT || key_code == ui::VKEY_RIGHT || + key_code == ui::VKEY_UP || key_code == ui::VKEY_DOWN); + DCHECK(!folder_delegate_); + DCHECK(activated_folder_item_view_); + + AppListItemView* reparented_view_in_root_grid = + new AppListItemView(this, reparented_view->item(), + contents_view_->GetAppListMainView()->view_delegate(), + false /* is_in_folder */); + + AddChildView(reparented_view_in_root_grid); + view_model_.Add(reparented_view_in_root_grid, view_model_.view_size()); + view_structure_.Add(reparented_view_in_root_grid, GetLastTargetIndex()); + + // Set |activated_folder_item_view_| selected so |target_index| will be + // computed relative to the open folder. + SetSelectedView(activated_folder_item_view_); + const GridIndex target_index = + GetTargetGridIndexForKeyboardReparent(key_code); + AnnounceReorder(target_index); + ReparentItemForReorder(reparented_view_in_root_grid, target_index); + + contents_view_->GetAppsContainerView()->ResetForShowApps(); + + GetViewAtIndex(target_index)->RequestFocus(); + Layout(); + RecordAppMovingTypeMetrics(kMoveByKeyboardOutOfFolder); +} + AppListItemView* AppsGridView::GetCurrentPageFirstItemViewInFolder() { DCHECK(folder_delegate_); int first_index = pagination_model_.selected_page() * @@ -2025,8 +2087,8 @@ item_list_->AddObserver(this); } -void AppsGridView::MoveItemToFolder(AppListItemView* item_view, - const GridIndex& target) { +AppListItemView* AppsGridView::MoveItemToFolder(AppListItemView* item_view, + const GridIndex& target) { const std::string& source_item_id = item_view->item()->id(); AppListItemView* target_view = GetViewDisplayedAtSlotOnCurrentPage(target.slot); @@ -2045,7 +2107,7 @@ item_list_->AddObserver(this); if (folder_item_id.empty()) { LOG(ERROR) << "Unable to merge into item id: " << target_view_item_id; - return; + return nullptr; } if (folder_item_id != target_view_item_id) { // New folder was created, change the view model to replace the old target @@ -2056,36 +2118,41 @@ GridIndex target_index = GetIndexOfView(target_view); gfx::Rect target_view_bounds = target_view->bounds(); DeleteItemViewAtIndex(target_model_index, false /* sanitize */); - AppListItemView* target_folder_view = - CreateViewForItemAtIndex(folder_item_index); - target_folder_view->SetBoundsRect(target_view_bounds); - view_model_.Add(target_folder_view, target_model_index); + target_view = CreateViewForItemAtIndex(folder_item_index); + target_view->SetBoundsRect(target_view_bounds); + view_model_.Add(target_view, target_model_index); if (!folder_delegate_) - view_structure_.Add(target_folder_view, target_index); + view_structure_.Add(target_view, target_index); // If drag view is in front of the position where it will be moved to, we // should skip it. - int offset = (drag_view_ && - view_model_.GetIndexOfView(drag_view_) < target_model_index) - ? 1 - : 0; - AddChildViewAt(target_folder_view, target_model_index - offset); + const int offset = (drag_view_ && view_model_.GetIndexOfView(drag_view_) < + target_model_index) + ? 1 + : 0; + AddChildViewAt(target_view, target_model_index - offset); } else { LOG(ERROR) << "Folder no longer in item_list: " << folder_item_id; } } - // Fade out the drag_view_ and delete it when animation ends. - int drag_model_index = view_model_.GetIndexOfView(drag_view_); - view_model_.Remove(drag_model_index); - if (!folder_delegate_) - view_structure_.Remove(drag_view_); - bounds_animator_.AnimateViewTo(drag_view_, drag_view_->bounds()); - bounds_animator_.SetAnimationDelegate( - drag_view_, std::unique_ptr<gfx::AnimationDelegate>( - new ItemRemoveAnimationDelegate(drag_view_))); + FadeOutItemViewAndDelete(item_view); + if (drag_view_ == item_view) + RecordAppMovingTypeMetrics(kMoveByDragIntoFolder); - RecordAppMovingTypeMetrics(kMoveIntoFolder); + return target_view; +} + +void AppsGridView::FadeOutItemViewAndDelete(AppListItemView* item_view) { + const int model_index = view_model_.GetIndexOfView(item_view); + + view_model_.Remove(model_index); + if (!folder_delegate_) + view_structure_.Remove(item_view); + bounds_animator_.AnimateViewTo(item_view, item_view->bounds()); + bounds_animator_.SetAnimationDelegate( + item_view, std::unique_ptr<gfx::AnimationDelegate>( + new ItemRemoveAnimationDelegate(item_view))); } void AppsGridView::ReparentItemForReorder(AppListItemView* item_view, @@ -2146,8 +2213,6 @@ item_list_->AddObserver(this); model_->AddObserver(this); UpdatePaging(); - - RecordAppMovingTypeMetrics(kMoveOutOfFolder); } bool AppsGridView::ReparentItemToAnotherFolder(AppListItemView* item_view, @@ -2735,9 +2800,45 @@ return GridIndex(target_page, std::min(last_slot_in_target_page, ideal_slot)); } -void AppsGridView::MoveAppListItemViewForKeyboardMove( - const GridIndex& target_index) { +GridIndex AppsGridView::GetTargetGridIndexForKeyboardReparent( + ui::KeyboardCode key_code) const { + DCHECK(!folder_delegate_) << "Reparenting target calculations occur from the " + "root AppsGridView, not the folder AppsGridView"; + + const GridIndex folder_index = GetIndexOfView(activated_folder_item_view_); + + // A backward move means the item will be placed previous to the folder. To do + // this without displacing other items, place the item in the folders slot. + // The folder will then shift forward. + const ui::KeyboardCode backward = + base::i18n::IsRTL() ? ui::VKEY_RIGHT : ui::VKEY_LEFT; + if (key_code == backward) + return folder_index; + + GridIndex target_index = GetTargetGridIndexForKeyboardMove(key_code); + // Ensure the item is placed on the same page as the folder when possible. + if (target_index.page < folder_index.page) { + target_index.page = folder_index.page; + target_index.slot = 0; + } else if (target_index.page > folder_index.page) { + // Prefer the last slot of the page over the next page. If the page is full + // the item will still end up being pushed off the page. + target_index = folder_index; + ++target_index.slot; + } + return target_index; +} + +void AppsGridView::HandleKeyboardMove(ui::KeyboardCode key_code) { DCHECK(selected_view_); + const GridIndex target_index = GetTargetGridIndexForKeyboardMove(key_code); + const GridIndex starting_index = GetIndexOfView(selected_view_); + if (target_index == starting_index || + !IsValidReorderTargetIndex(target_index)) { + return; + } + + handling_keyboard_move_ = true; if (target_index.page == pagination_model_.total_pages()) view_structure_.AppendPage(); @@ -2781,6 +2882,7 @@ pagination_model_.SelectPage(target_page, false /*animate*/); SetSelectedView(original_selected_view); Layout(); + AnnounceReorder(target_index); if (target_index.page != original_selected_view_index.page) { UMA_HISTOGRAM_ENUMERATION(kAppListPageSwitcherSourceHistogram, @@ -3010,15 +3112,22 @@ GetViewDisplayedAtSlotOnCurrentPage(drop_target_.slot); DCHECK(drop_view); + AnnounceFolderDrop(drag_view_->title()->text(), drop_view->title()->text(), + drop_view->is_folder()); +} + +void AppsGridView::AnnounceFolderDrop(const base::string16& moving_view_title, + const base::string16& target_view_title, + bool target_is_folder) { // Set a11y name to announce possible move to folder or creation of folder. auto* announcement_view = contents_view_->app_list_view()->announcement_view(); announcement_view->GetViewAccessibility().OverrideName( l10n_util::GetStringFUTF16( - IsFolderItem(drop_view->item()) + target_is_folder ? IDS_APP_LIST_APP_DRAG_MOVE_TO_FOLDER_ACCESSIBILE_NAME : IDS_APP_LIST_APP_DRAG_CREATE_FOLDER_ACCESSIBILE_NAME, - drag_view_->title()->text(), drop_view->title()->text())); + moving_view_title, target_view_title)); announcement_view->NotifyAccessibilityEvent(ax::mojom::Event::kAlert, true); }
diff --git a/ash/app_list/views/apps_grid_view.h b/ash/app_list/views/apps_grid_view.h index d3b57da..4d7b368 100644 --- a/ash/app_list/views/apps_grid_view.h +++ b/ash/app_list/views/apps_grid_view.h
@@ -259,6 +259,11 @@ bool HandleScrollFromAppListView(const gfx::Vector2d& offset, ui::EventType type); + // Moves |reparented_item| from its folder to the root AppsGridView in the + // direction of |key_code|. + void HandleKeyboardReparent(AppListItemView* reparented_view, + ui::KeyboardCode key_code); + // Returns the first app list item view in the selected page in the folder. AppListItemView* GetCurrentPageFirstItemViewInFolder(); @@ -402,8 +407,13 @@ // Updates |model_| to move item represented by |item_view| into a folder // containing item located at |target| slot, also update |view_model_| for - // the related view changes. - void MoveItemToFolder(AppListItemView* item_view, const GridIndex& target); + // the related view changes. Returns the preexisting or created folder as a + // result of the move, or nullptr if the move fails. + AppListItemView* MoveItemToFolder(AppListItemView* item_view, + const GridIndex& target); + + // Sets up |item_view| to fade out and delete on animation end. + void FadeOutItemViewAndDelete(AppListItemView* item_view); // Updates both data model and view_model_ for re-parenting a folder item to a // new position in top level item list. @@ -532,9 +542,19 @@ // Returns true if the grid view is under an OEM folder. bool IsUnderOEMFolder(); - // Handles moving the |selected_view_|, triggered by Control+Arrow - // up/down/left/right. - void HandleKeyboardAppMovement(ui::KeyboardCode key_code); + // Handles keyboard app reordering, foldering, and reparenting. Operations + // effect |selected_view_|. |folder| is whether to move the app into or out of + // a folder. + void HandleKeyboardAppOperations(ui::KeyboardCode key_code, bool folder); + + // Handles either creating a folder with |selected_view_| or moving + // |selected_view_| into an existing folder. + void HandleKeyboardFoldering(ui::KeyboardCode key_code); + + // Returns whether |selected_view_| can be foldered to the item at + // |target_index| in the root AppsGridView. + bool CanMoveSelectedToTargetForKeyboardFoldering( + const GridIndex& target_index) const; // Handle vertical focus movement triggered by arrow up and down. bool HandleVerticalFocusMovement(bool arrow_up); @@ -588,8 +608,14 @@ // Returns the target GridIndex for a keyboard move. GridIndex GetTargetGridIndexForKeyboardMove(ui::KeyboardCode key_code) const; - // Swaps |selected_view_| and the item at |target_index|. - void MoveAppListItemViewForKeyboardMove(const GridIndex& target_index); + // Returns the target GridIndex to move an item from a folder to the root + // AppsGridView. + GridIndex GetTargetGridIndexForKeyboardReparent( + ui::KeyboardCode key_code) const; + + // Swaps |selected_view_| with the item in relative position specified by + // |key_code|. + void HandleKeyboardMove(ui::KeyboardCode key_code); // Records the total number of pages, and the number of pages with empty slots // for UMA histograms. @@ -617,6 +643,12 @@ // folder or creating a folder with two apps. void MaybeCreateFolderDroppingAccessibilityEvent(); + // Modifies the announcement view to verbalize |moving_view_title| is creating + // a folder or moving into an existing folder with |target_view_title|. + void AnnounceFolderDrop(const base::string16& moving_view_title, + const base::string16& target_view_title, + bool target_is_folder); + // During an app drag, creates an a11y event to verbalize drop target // location. void MaybeCreateDragReorderAccessibilityEvent();
diff --git a/ash/app_list/views/apps_grid_view_folder_delegate.h b/ash/app_list/views/apps_grid_view_folder_delegate.h index 75c48bb..6ab47be 100644 --- a/ash/app_list/views/apps_grid_view_folder_delegate.h +++ b/ash/app_list/views/apps_grid_view_folder_delegate.h
@@ -52,6 +52,11 @@ // synchronous drag has an icon for reparenting while it loads. virtual void SetRootLevelDragViewVisible(bool visible) = 0; + // Moves |reparented_item| to the root level's grid view, left/right/up/down + // of the folder's grid position. + virtual void HandleKeyboardReparent(AppListItemView* reparented_view, + ui::KeyboardCode key_code) = 0; + protected: virtual ~AppsGridViewFolderDelegate() {} };
diff --git a/ash/app_list/views/apps_grid_view_unittest.cc b/ash/app_list/views/apps_grid_view_unittest.cc index f48b033..be489b5 100644 --- a/ash/app_list/views/apps_grid_view_unittest.cc +++ b/ash/app_list/views/apps_grid_view_unittest.cc
@@ -9,6 +9,7 @@ #include <memory> #include <string> +#include "ash/app_list/app_list_metrics.h" #include "ash/app_list/model/app_list_folder_item.h" #include "ash/app_list/model/app_list_item.h" #include "ash/app_list/model/app_list_model.h" @@ -336,6 +337,9 @@ void SetRootLevelDragViewVisible(bool visible) override {} + void HandleKeyboardReparent(AppListItemView* reparented_item, + ui::KeyboardCode key_code) override {} + private: DISALLOW_COPY_AND_ASSIGN(TestAppsGridViewFolderDelegate); }; @@ -1385,6 +1389,157 @@ EXPECT_EQ(2, test_api_->AppsOnPage(1)); } +// Tests that control + shift + arrow puts |selected_item_| into a folder or +// creates a folder if one does not exist. +TEST_F(AppsGridViewTest, ControlShiftArrowFoldersItemBasic) { + base::HistogramTester histogram_tester; + model_->PopulateApps(GetTilesPerPage(0)); + // Select the first item in the grid, folder it with the item to the right. + AppListItemView* first_item = GetItemViewAt(0); + const std::string first_item_id = first_item->item()->id(); + const std::string second_item_id = GetItemViewAt(1)->item()->id(); + apps_grid_view_->GetFocusManager()->SetFocusedView(first_item); + + SimulateKeyPress(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN); + + // Test that the first item in the grid is now a folder with the first and + // second items, and that the folder is the selected view. + AppListItemView* new_folder = GetItemViewAt(0); + ASSERT_TRUE(apps_grid_view_->IsSelectedView(new_folder)); + AppListFolderItem* folder_item = + static_cast<AppListFolderItem*>(new_folder->item()); + EXPECT_TRUE(folder_item->is_folder()); + EXPECT_EQ(2u, folder_item->ChildItemCount()); + EXPECT_TRUE(folder_item->FindChildItem(first_item_id)); + EXPECT_TRUE(folder_item->FindChildItem(second_item_id)); + histogram_tester.ExpectBucketCount(kAppListAppMovingType, + kMoveByKeyboardIntoFolder, 1); + + // Test that, when a folder is selected, control+shift+arrow does nothing. + SimulateKeyPress(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN); + + EXPECT_TRUE(apps_grid_view_->IsSelectedView(new_folder)); + EXPECT_EQ(2u, folder_item->ChildItemCount()); + histogram_tester.ExpectBucketCount(kAppListAppMovingType, + kMoveByKeyboardIntoFolder, 1); + + // Move selection to the item to the right of the folder and put it in the + // folder. + apps_grid_view_->GetFocusManager()->SetFocusedView(GetItemViewAt(1)); + + SimulateKeyPress(ui::VKEY_LEFT, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN); + + EXPECT_TRUE(apps_grid_view_->IsSelectedView(new_folder)); + EXPECT_EQ(3u, folder_item->ChildItemCount()); + histogram_tester.ExpectBucketCount(kAppListAppMovingType, + kMoveByKeyboardIntoFolder, 2); + + // Move selection to the item below the folder and put it in the folder. + SimulateKeyPress(ui::VKEY_DOWN); + SimulateKeyPress(ui::VKEY_UP, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN); + + EXPECT_TRUE(apps_grid_view_->IsSelectedView(new_folder)); + EXPECT_EQ(4u, folder_item->ChildItemCount()); + histogram_tester.ExpectBucketCount(kAppListAppMovingType, + kMoveByKeyboardIntoFolder, 3); + + // Move the folder to the second row, then put the item above the folder in + // the folder. + SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN); + SimulateKeyPress(ui::VKEY_UP); + SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN); + + EXPECT_TRUE(apps_grid_view_->IsSelectedView(new_folder)); + EXPECT_EQ(5u, folder_item->ChildItemCount()); + histogram_tester.ExpectBucketCount(kAppListAppMovingType, + kMoveByKeyboardIntoFolder, 4); +} + +// Tests that foldering an item that is on a different page fails. +TEST_F(AppsGridViewTest, ControlShiftArrowFailsToFolderAcrossPages) { + model_->PopulateApps(2 * GetTilesPerPage(0)); + + // For every item on the last row of the first page, test that foldering to + // the next page fails. + for (int i = 0; i < apps_grid_view_->cols(); ++i) { + const GridIndex moved_view_index( + 0, + apps_grid_view_->cols() * (apps_grid_view_->rows_per_page() - 1) + i); + AppListItemView* attempted_folder_view = + test_api_->GetViewAtIndex(moved_view_index); + apps_grid_view_->GetFocusManager()->SetFocusedView(attempted_folder_view); + + SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN); + + EXPECT_EQ(attempted_folder_view, + test_api_->GetViewAtIndex(moved_view_index)); + EXPECT_EQ(0, GetPaginationModel()->selected_page()); + } + // The last item on the col is selected, try moving right and test that that + // fails as well. + GridIndex moved_view_index( + 0, apps_grid_view_->cols() * apps_grid_view_->rows_per_page() - 1); + AppListItemView* attempted_folder_view = + test_api_->GetViewAtIndex(moved_view_index); + + SimulateKeyPress(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN); + + EXPECT_EQ(attempted_folder_view, test_api_->GetViewAtIndex(moved_view_index)); + + // Move to the second page and test that foldering up to a new page fails. + SimulateKeyPress(ui::VKEY_DOWN); + + // Select the first item on the second page. + moved_view_index = GridIndex(1, 0); + attempted_folder_view = test_api_->GetViewAtIndex(moved_view_index); + + // Try to folder left to the previous page, it should fail. + SimulateKeyPress(ui::VKEY_LEFT, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN); + + EXPECT_EQ(attempted_folder_view, test_api_->GetViewAtIndex(moved_view_index)); + + // For every item on the first row of the second page, test that foldering to + // the next page fails. + for (int i = 0; i < apps_grid_view_->cols(); ++i) { + const GridIndex moved_view_index(1, i); + AppListItemView* attempted_folder_view = + test_api_->GetViewAtIndex(moved_view_index); + apps_grid_view_->GetFocusManager()->SetFocusedView(attempted_folder_view); + + SimulateKeyPress(ui::VKEY_UP, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN); + + EXPECT_EQ(attempted_folder_view, + test_api_->GetViewAtIndex(moved_view_index)); + EXPECT_EQ(1, GetPaginationModel()->selected_page()); + } +} + +// Tests that foldering the item on the last slot of a page doesn't crash. +TEST_F(AppsGridViewTest, ControlShiftArrowFolderLastItemOnPage) { + const int kNumberOfApps = 4; + model_->PopulateApps(kNumberOfApps); + // Select the second to last item in the grid, folder it with the item to the + // right. + AppListItemView* moving_item = GetItemViewAt(kNumberOfApps - 2); + const std::string first_item_id = moving_item->item()->id(); + const std::string second_item_id = + GetItemViewAt(kNumberOfApps - 1)->item()->id(); + apps_grid_view_->GetFocusManager()->SetFocusedView(moving_item); + + SimulateKeyPress(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN); + + // Test that the first item in the grid is now a folder with the first and + // second items, and that the folder is the selected view. + AppListItemView* new_folder = GetItemViewAt(kNumberOfApps - 2); + ASSERT_TRUE(apps_grid_view_->IsSelectedView(new_folder)); + AppListFolderItem* folder_item = + static_cast<AppListFolderItem*>(new_folder->item()); + EXPECT_TRUE(folder_item->is_folder()); + EXPECT_EQ(2u, folder_item->ChildItemCount()); + EXPECT_TRUE(folder_item->FindChildItem(first_item_id)); + EXPECT_TRUE(folder_item->FindChildItem(second_item_id)); +} + TEST_P(AppsGridViewTest, MouseDragFlipPage) { apps_grid_view_->set_page_flip_delay_in_ms_for_testing(10); GetPaginationModel()->SetTransitionDurations(10, 10);
diff --git a/ash/ime/ime_engine_factory_registry_unittest.cc b/ash/ime/ime_engine_factory_registry_unittest.cc index c2b9279d..0414b45 100644 --- a/ash/ime/ime_engine_factory_registry_unittest.cc +++ b/ash/ime/ime_engine_factory_registry_unittest.cc
@@ -26,15 +26,6 @@ } private: - // ime::mojom::ImeEngineClient: - void CommitText(const std::string& text) override {} - void UpdateCompositionText(const ui::CompositionText& composition, - uint32_t cursor_pos, - bool visible) override {} - void DeleteSurroundingText(int32_t offset, uint32_t length) override {} - void SendKeyEvent(std::unique_ptr<ui::Event> key_event) override {} - void Reconnect() override {} - mojo::Binding<ime::mojom::ImeEngineClient> binding_; DISALLOW_COPY_AND_ASSIGN(TestImeEngineClient);
diff --git a/ash/media/media_controller.cc b/ash/media/media_controller.cc index e3591a7a..eb22e42 100644 --- a/ash/media/media_controller.cc +++ b/ash/media/media_controller.cc
@@ -4,6 +4,8 @@ #include "ash/media/media_controller.h" +#include "ash/session/session_controller.h" +#include "ash/shell.h" #include "base/bind.h" #include "base/feature_list.h" #include "base/metrics/histogram_macros.h" @@ -71,6 +73,9 @@ } void MediaController::HandleMediaPlayPause() { + if (Shell::Get()->session_controller()->IsScreenLocked()) + return; + // If the |client_| is force handling the keys then we should forward them. if (client_ && force_media_client_key_handling_) { ui::RecordMediaHardwareKeyAction(ui::MediaHardwareKeyAction::kPlayPause); @@ -107,6 +112,9 @@ } void MediaController::HandleMediaNextTrack() { + if (Shell::Get()->session_controller()->IsScreenLocked()) + return; + ui::RecordMediaHardwareKeyAction( ui::MediaHardwareKeyAction::kNextTrack); @@ -128,6 +136,9 @@ } void MediaController::HandleMediaPrevTrack() { + if (Shell::Get()->session_controller()->IsScreenLocked()) + return; + ui::RecordMediaHardwareKeyAction( ui::MediaHardwareKeyAction::kPreviousTrack); @@ -182,8 +193,11 @@ } void MediaController::FlushForTesting() { - client_.FlushForTesting(); - media_session_controller_ptr_.FlushForTesting(); + if (client_) + client_.FlushForTesting(); + + if (media_session_controller_ptr_) + media_session_controller_ptr_.FlushForTesting(); } media_session::mojom::MediaController*
diff --git a/ash/media/media_controller.h b/ash/media/media_controller.h index d01984e3..120f656 100644 --- a/ash/media/media_controller.h +++ b/ash/media/media_controller.h
@@ -78,6 +78,7 @@ const base::Optional<base::UnguessableToken>& request_id) override {} private: + friend class MediaControllerTest; friend class MediaSessionAcceleratorTest; friend class MultiProfileMediaTrayItemTest; FRIEND_TEST_ALL_PREFIXES(MediaSessionAcceleratorTest,
diff --git a/ash/media/media_controller_unittest.cc b/ash/media/media_controller_unittest.cc new file mode 100644 index 0000000..1b3ed00 --- /dev/null +++ b/ash/media/media_controller_unittest.cc
@@ -0,0 +1,122 @@ +// Copyright 2018 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 "ash/media/media_controller.h" + +#include <memory> + +#include "ash/session/session_controller.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "base/macros.h" +#include "services/media_session/public/cpp/test/test_media_controller.h" + +namespace ash { + +class MediaControllerTest : public AshTestBase { + public: + MediaControllerTest() = default; + ~MediaControllerTest() override = default; + + // AshTestBase + void SetUp() override { + AshTestBase::SetUp(); + + controller_ = std::make_unique<media_session::test::TestMediaController>(); + + MediaController* media_controller = Shell::Get()->media_controller(); + media_controller->SetMediaSessionControllerForTest( + controller_->CreateMediaControllerPtr()); + media_controller->FlushForTesting(); + + { + std::vector<media_session::mojom::MediaSessionAction> actions; + actions.push_back(media_session::mojom::MediaSessionAction::kPlay); + controller_->SimulateMediaSessionActionsChanged(actions); + } + + { + media_session::mojom::MediaSessionInfoPtr session_info( + media_session::mojom::MediaSessionInfo::New()); + + session_info->state = + media_session::mojom::MediaSessionInfo::SessionState::kActive; + session_info->playback_state = + media_session::mojom::MediaPlaybackState::kPlaying; + controller_->SimulateMediaSessionInfoChanged(std::move(session_info)); + } + + Flush(); + } + + media_session::test::TestMediaController* controller() const { + return controller_.get(); + } + + void SimulateSessionLock() { + mojom::SessionInfoPtr info_ptr = mojom::SessionInfo::New(); + info_ptr->state = session_manager::SessionState::LOCKED; + Shell::Get()->session_controller()->SetSessionInfo(std::move(info_ptr)); + } + + void Flush() { + controller_->Flush(); + Shell::Get()->media_controller()->FlushForTesting(); + } + + private: + std::unique_ptr<media_session::test::TestMediaController> controller_; + + DISALLOW_COPY_AND_ASSIGN(MediaControllerTest); +}; + +TEST_F(MediaControllerTest, DisablePlayPauseWhenLocked) { + EXPECT_EQ(0, controller()->suspend_count()); + + Shell::Get()->media_controller()->HandleMediaPlayPause(); + Flush(); + + EXPECT_EQ(1, controller()->suspend_count()); + + SimulateSessionLock(); + + Shell::Get()->media_controller()->HandleMediaPlayPause(); + Flush(); + + EXPECT_EQ(1, controller()->suspend_count()); +} + +TEST_F(MediaControllerTest, DisablePreviousTrackWhenLocked) { + EXPECT_EQ(0, controller()->previous_track_count()); + + Shell::Get()->media_controller()->HandleMediaPrevTrack(); + Flush(); + + EXPECT_EQ(1, controller()->previous_track_count()); + + SimulateSessionLock(); + + Shell::Get()->media_controller()->HandleMediaPrevTrack(); + Flush(); + + EXPECT_EQ(1, controller()->previous_track_count()); +} + +TEST_F(MediaControllerTest, DisableNextTrackWhenLocked) { + EXPECT_EQ(0, controller()->next_track_count()); + + Shell::Get()->media_controller()->HandleMediaNextTrack(); + Flush(); + + EXPECT_EQ(1, controller()->next_track_count()); + + SimulateSessionLock(); + + Shell::Get()->media_controller()->HandleMediaNextTrack(); + Flush(); + + EXPECT_EQ(1, controller()->next_track_count()); +} + +} // namespace ash
diff --git a/ash/public/cpp/app_list/app_list_types.h b/ash/public/cpp/app_list/app_list_types.h index f6976c6..de305a51 100644 --- a/ash/public/cpp/app_list/app_list_types.h +++ b/ash/public/cpp/app_list/app_list_types.h
@@ -13,6 +13,13 @@ namespace ash { +// The initial value of |profile_id_| in AppListControllerImpl. +constexpr int kAppListInvalidProfileID = -1; + +// The value from which the unique profile id starts. Notice that this profile +// id is only used for mojo callings between AppListController and AppListClient +constexpr int kAppListProfileIdStartFrom = 0; + // Id of OEM folder in app list. ASH_PUBLIC_EXPORT extern const char kOemFolderId[];
diff --git a/ash/public/interfaces/app_list.mojom b/ash/public/interfaces/app_list.mojom index 0e8e0e1..fbd8f7a 100644 --- a/ash/public/interfaces/app_list.mojom +++ b/ash/public/interfaces/app_list.mojom
@@ -254,7 +254,8 @@ // Publishes search results to Ash to render them. PublishSearchResults(array<SearchResultMetadata> results); // Update the whole model, usually when profile changes happen in Chrome. - SetModelData(array<AppListItemMetadata> apps, + SetModelData(int32 profile_id, + array<AppListItemMetadata> apps, bool is_search_engine_google); ////////////////////////////////////////////////////////////////////////////// @@ -372,27 +373,34 @@ OnAppListVisibilityChanged(bool visible); ////////////////////////////////////////////////////////////////////////////// - // Interfaces on app list items: + // Interfaces on app list items. |profile_id| indicates the profile to which + // app list items belong. In multi-profile mode, each profile has its own + // app list model updater: // Activates (opens) the item with |id|. - ActivateItem(string id, int32 event_flags); + ActivateItem(int32 profile_id, string id, int32 event_flags); // Returns the context menu model for the item with |id|, or an empty array if // there is currently no menu for the item (e.g. during install). - GetContextMenuModel(string id) => (array<MenuItem> items); + GetContextMenuModel(int32 profile_id, string id) => (array<MenuItem> items); // Invoked when a context menu item of an app list item is clicked. // |id|: the clicked AppListItem's id. // |command_id|: the clicked menu item's command id. // |event_flags|: flags from the event which triggered this command. - ContextMenuItemSelected(string id, int32 command_id, int32 event_flags); + ContextMenuItemSelected(int32 profile_id, + string id, + int32 command_id, + int32 event_flags); // Invoked when a folder is created in Ash (e.g. merge items into a folder). - OnFolderCreated(AppListItemMetadata folder); + OnFolderCreated(int32 profile_id, AppListItemMetadata folder); // Invoked when a folder has only one item left and so gets removed. - OnFolderDeleted(AppListItemMetadata folder); + OnFolderDeleted(int32 profile_id, AppListItemMetadata folder); // Invoked when user changes a folder's name or an item's position. - OnItemUpdated(AppListItemMetadata folder); + OnItemUpdated(int32 profile_id, AppListItemMetadata folder); // Invoked when a "page break" item is added with |id| and |position|. - OnPageBreakItemAdded(string id, syncer.mojom.StringOrdinal position); + OnPageBreakItemAdded(int32 profile_id, + string id, + syncer.mojom.StringOrdinal position); // Invoked when a "page break" item with |id| is deleted. - OnPageBreakItemDeleted(string id); + OnPageBreakItemDeleted(int32 profile_id, string id); // Updated when item with |id| is set to |visible|. Only sent if // |notify_visibility_change| was set on the SearchResultMetadata.
diff --git a/ash/shell/example_app_list_client.cc b/ash/shell/example_app_list_client.cc index b798f46..771021b 100644 --- a/ash/shell/example_app_list_client.cc +++ b/ash/shell/example_app_list_client.cc
@@ -245,7 +245,8 @@ WindowTypeShelfItem::ActivateItem((*it)->type(), event_flags); } -void ExampleAppListClient::ActivateItem(const std::string& id, +void ExampleAppListClient::ActivateItem(int profile_id, + const std::string& id, int event_flags) { auto it = std::find_if(apps_.begin(), apps_.end(),
diff --git a/ash/shell/example_app_list_client.h b/ash/shell/example_app_list_client.h index e008068..3952128 100644 --- a/ash/shell/example_app_list_client.h +++ b/ash/shell/example_app_list_client.h
@@ -37,7 +37,9 @@ ash::mojom::AppListLaunchedFrom launched_from, ash::mojom::AppListLaunchType launch_type, int suggestion_index) override; - void ActivateItem(const std::string& id, int event_flags) override; + void ActivateItem(int profile_id, + const std::string& id, + int event_flags) override; AppListControllerImpl* controller_;
diff --git a/ash/wm/default_state.cc b/ash/wm/default_state.cc index 0e20c55..ea0533c 100644 --- a/ash/wm/default_state.cc +++ b/ash/wm/default_state.cc
@@ -297,7 +297,7 @@ gfx::Rect new_bounds(work_area.x(), window->bounds().y(), work_area.width(), window->bounds().height()); - gfx::Rect restore_bounds = window->bounds(); + gfx::Rect restore_bounds = window->GetTargetBounds(); if (window_state->IsSnapped()) { window_state->SetRestoreBoundsInParent(new_bounds); window_state->Restore();
diff --git a/ash/wm/window_util.cc b/ash/wm/window_util.cc index cf5f3ba..a2d18106 100644 --- a/ash/wm/window_util.cc +++ b/ash/wm/window_util.cc
@@ -101,6 +101,14 @@ } bool ShouldUseExtendedBounds(const aura::Window* target) const override { + // Fullscreen/maximized windows can't be drag-resized. + const WindowState* window_state = GetWindowState(window()); + const WindowState* target_window_state = GetWindowState(target); + if ((window_state && window_state->IsMaximizedOrFullscreenOrPinned()) || + (target_window_state && !target_window_state->CanResize())) { + return false; + } + // The shrunken hit region only applies to children of |window()|. return target->parent() == window(); }
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc index 9b42c4b..84a9346 100644 --- a/ash/wm/workspace/workspace_window_resizer.cc +++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -689,6 +689,8 @@ } instance = this; + // Use |bounds()| instead of |GetTargetBounds()| because that's the position a + // user captured the window. pre_drag_window_bounds_ = window_state->window()->bounds(); window_state->OnDragStarted(details().window_component);
diff --git a/base/sampling_heap_profiler/poisson_allocation_sampler.cc b/base/sampling_heap_profiler/poisson_allocation_sampler.cc index 58be9c65..1168ee82b 100644 --- a/base/sampling_heap_profiler/poisson_allocation_sampler.cc +++ b/base/sampling_heap_profiler/poisson_allocation_sampler.cc
@@ -535,6 +535,8 @@ void PoissonAllocationSampler::AddSamplesObserver(SamplesObserver* observer) { ScopedMuteThreadSamples no_reentrancy_scope; AutoLock lock(mutex_); + DCHECK(std::find(observers_.begin(), observers_.end(), observer) == + observers_.end()); observers_.push_back(observer); InstallAllocatorHooksOnce(); g_running = !observers_.empty(); @@ -545,7 +547,7 @@ ScopedMuteThreadSamples no_reentrancy_scope; AutoLock lock(mutex_); auto it = std::find(observers_.begin(), observers_.end(), observer); - CHECK(it != observers_.end()); + DCHECK(it != observers_.end()); observers_.erase(it); g_running = !observers_.empty(); }
diff --git a/build/android/gyp/util/build_utils.py b/build/android/gyp/util/build_utils.py index a0ef2ee..e4d7cc61 100644 --- a/build/android/gyp/util/build_utils.py +++ b/build/android/gyp/util/build_utils.py
@@ -22,8 +22,7 @@ # Any new non-system import must be added to: # //build/config/android/internal_rules.gni -# Some clients do not add //build/android/gyp to PYTHONPATH. -import md5_check # pylint: disable=relative-import +from util import md5_check sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir)) @@ -36,7 +35,7 @@ os.pardir, os.pardir, os.pardir, os.pardir))) HERMETIC_TIMESTAMP = (2001, 1, 1, 0, 0, 0) -_HERMETIC_FILE_ATTR = (0644 << 16L) +_HERMETIC_FILE_ATTR = (0o644 << 16) @contextlib.contextmanager @@ -263,7 +262,7 @@ # The two high-order bytes of ZipInfo.external_attr represent # UNIX permissions and file type bits. - return stat.S_ISLNK(zi.external_attr >> 16L) + return stat.S_ISLNK(zi.external_attr >> 16) def ExtractAll(zip_path, path=None, no_clobber=True, pattern=None, @@ -326,19 +325,19 @@ if src_path and os.path.islink(src_path): zipinfo.filename = zip_path - zipinfo.external_attr |= stat.S_IFLNK << 16L # mark as a symlink + zipinfo.external_attr |= stat.S_IFLNK << 16 # mark as a symlink zip_file.writestr(zipinfo, os.readlink(src_path)) return # zipfile.write() does - # external_attr = (os.stat(src_path)[0] & 0xFFFF) << 16L + # external_attr = (os.stat(src_path)[0] & 0xFFFF) << 16 # but we want to use _HERMETIC_FILE_ATTR, so manually set # the few attr bits we care about. if src_path: st = os.stat(src_path) for mode in (stat.S_IXUSR, stat.S_IXGRP, stat.S_IXOTH): if st.st_mode & mode: - zipinfo.external_attr |= mode << 16L + zipinfo.external_attr |= mode << 16 if src_path: with open(src_path, 'rb') as f: @@ -482,7 +481,7 @@ deps_map[node] = deps discover(top) - return deps_map.keys() + return list(deps_map) def _ComputePythonDependencies():
diff --git a/build/android/gyp/util/build_utils_test.py b/build/android/gyp/util/build_utils_test.py index bcc892f..d462f0c 100755 --- a/build/android/gyp/util/build_utils_test.py +++ b/build/android/gyp/util/build_utils_test.py
@@ -4,9 +4,13 @@ # found in the LICENSE file. import collections +import os +import sys import unittest -import build_utils # pylint: disable=W0403 +sys.path.insert( + 0, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))) +from util import build_utils _DEPS = collections.OrderedDict() _DEPS['a'] = []
diff --git a/build/android/gyp/util/md5_check.py b/build/android/gyp/util/md5_check.py index bac22a01..9a15ee6 100644 --- a/build/android/gyp/util/md5_check.py +++ b/build/android/gyp/util/md5_check.py
@@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +from __future__ import print_function + import difflib import hashlib import itertools @@ -78,10 +80,10 @@ return if PRINT_EXPLANATIONS: - print '=' * 80 - print 'Target is stale: %s' % record_path - print changes.DescribeDifference() - print '=' * 80 + print('=' * 80) + print('Target is stale: %s' % record_path) + print(changes.DescribeDifference()) + print('=' * 80) args = (changes,) if pass_changes else () function(*args)
diff --git a/build/android/gyp/util/md5_check_test.py b/build/android/gyp/util/md5_check_test.py index 75ddf3e..41e9d3c 100755 --- a/build/android/gyp/util/md5_check_test.py +++ b/build/android/gyp/util/md5_check_test.py
@@ -4,11 +4,15 @@ # found in the LICENSE file. import fnmatch +import os +import sys import tempfile import unittest import zipfile -import md5_check # pylint: disable=W0403 +sys.path.insert( + 0, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))) +from util import md5_check def _WriteZipFile(path, entries): @@ -26,7 +30,7 @@ input_strings = ['string1', 'string2'] input_file1 = tempfile.NamedTemporaryFile(suffix='.txt') input_file2 = tempfile.NamedTemporaryFile(suffix='.zip') - file1_contents = 'input file 1' + file1_contents = b'input file 1' input_file1.write(file1_contents) input_file1.flush() # Test out empty zip file to start.
diff --git a/build/android/gyp/util/resource_utils_test.py b/build/android/gyp/util/resource_utils_test.py index 8aa29d4..dc1094ac 100755 --- a/build/android/gyp/util/resource_utils_test.py +++ b/build/android/gyp/util/resource_utils_test.py
@@ -6,15 +6,17 @@ import collections import os -import unittest import sys +import unittest -import build_utils # pylint: disable=relative-import +sys.path.insert( + 0, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))) +from util import build_utils # Required because the following import needs build/android/gyp in the # Python path to import util.build_utils. _BUILD_ANDROID_GYP_ROOT = os.path.abspath( - os.path.join(os.path.dirname(__file__), '..')) + os.path.join(os.path.dirname(__file__), os.pardir)) sys.path.insert(1, _BUILD_ANDROID_GYP_ROOT) import resource_utils # pylint: disable=relative-import
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 912ef5e..b771c246 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -273,6 +273,7 @@ "java/src/org/chromium/chrome/browser/compositor/layouts/ToolbarSwipeLayout.java", "java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java", "java/src/org/chromium/chrome/browser/compositor/layouts/components/LayoutTab.java", + "java/src/org/chromium/chrome/browser/compositor/layouts/components/TintedCompositorButton.java", "java/src/org/chromium/chrome/browser/compositor/layouts/components/VirtualView.java", "java/src/org/chromium/chrome/browser/compositor/layouts/content/ContentOffsetProvider.java", "java/src/org/chromium/chrome/browser/compositor/layouts/content/InvalidationAwareThumbnailProvider.java",
diff --git a/chrome/android/features/autofill_assistant/BUILD.gn b/chrome/android/features/autofill_assistant/BUILD.gn index 059e3f0..6977726 100644 --- a/chrome/android/features/autofill_assistant/BUILD.gn +++ b/chrome/android/features/autofill_assistant/BUILD.gn
@@ -69,6 +69,7 @@ "java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsCoordinator.java", "java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsModel.java", "java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java", + "java/src/org/chromium/chrome/browser/autofill_assistant/details/ImageClickthroughData.java", "java/src/org/chromium/chrome/browser/autofill_assistant/header/AnimatedProgressBar.java", "java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderCoordinator.java", "java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderDelegate.java",
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetails.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetails.java index 216a73c..eec2423 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetails.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetails.java
@@ -24,7 +24,7 @@ private final String mTitle; private final String mImageUrl; - private final boolean mAllowImageClickthrough; + private final ImageClickthroughData mImageClickthroughData; private final boolean mShowImagePlaceholder; @Nullable private final Date mDate; @@ -48,15 +48,15 @@ /** An optional price label, such as 'Estimated Total incl. VAT'. */ private final String mTotalPriceLabel; - public AssistantDetails(String title, String imageUrl, boolean allowImageClickthrough, - boolean showImagePlaceholder, String totalPriceLabel, String totalPrice, - @Nullable Date date, String descriptionLine1, String descriptionLine2, - boolean userApprovalRequired, boolean highlightTitle, boolean highlightLine1, - boolean highlightLine2, boolean animatePlaceholders) { + public AssistantDetails(String title, String imageUrl, + ImageClickthroughData imageClickthroughData, boolean showImagePlaceholder, + String totalPriceLabel, String totalPrice, @Nullable Date date, String descriptionLine1, + String descriptionLine2, boolean userApprovalRequired, boolean highlightTitle, + boolean highlightLine1, boolean highlightLine2, boolean animatePlaceholders) { this.mTotalPriceLabel = totalPriceLabel; this.mTitle = title; this.mImageUrl = imageUrl; - this.mAllowImageClickthrough = allowImageClickthrough; + this.mImageClickthroughData = imageClickthroughData; this.mShowImagePlaceholder = showImagePlaceholder; this.mTotalPrice = totalPrice; this.mDate = date; @@ -78,8 +78,12 @@ return mImageUrl; } - boolean getAllowImageClickthrough() { - return mAllowImageClickthrough; + boolean hasImageClickthroughData() { + return mImageClickthroughData != null; + } + + ImageClickthroughData getImageClickthroughData() { + return mImageClickthroughData; } boolean getShowImagePlaceholder() { @@ -132,11 +136,13 @@ */ @CalledByNative private static AssistantDetails create(String title, String imageUrl, - boolean allowImageClickthrough, boolean showImagePlaceholder, String totalPriceLabel, - String totalPrice, String datetime, long year, int month, int day, int hour, int minute, - int second, String descriptionLine1, String descriptionLine2, - boolean userApprovalRequired, boolean highlightTitle, boolean highlightLine1, - boolean highlightLine2, boolean animatePlaceholders) { + boolean allowImageClickthrough, String imageClickthroughDesc, + String imageClickthroughPostiveText, String imageClickthroughNegativeText, + boolean showImagePlaceholder, String totalPriceLabel, String totalPrice, + String datetime, long year, int month, int day, int hour, int minute, int second, + String descriptionLine1, String descriptionLine2, boolean userApprovalRequired, + boolean highlightTitle, boolean highlightLine1, boolean highlightLine2, + boolean animatePlaceholders) { Date date = null; if (year > 0 && month > 0 && day > 0 && hour >= 0 && minute >= 0 && second >= 0) { Calendar calendar = Calendar.getInstance(); @@ -155,9 +161,11 @@ } } - return new AssistantDetails(title, imageUrl, allowImageClickthrough, showImagePlaceholder, - totalPriceLabel, totalPrice, date, descriptionLine1, descriptionLine2, - userApprovalRequired, highlightTitle, highlightLine1, highlightLine2, - animatePlaceholders); + return new AssistantDetails(title, imageUrl, + new ImageClickthroughData(allowImageClickthrough, imageClickthroughDesc, + imageClickthroughPostiveText, imageClickthroughNegativeText), + showImagePlaceholder, totalPriceLabel, totalPrice, date, descriptionLine1, + descriptionLine2, userApprovalRequired, highlightTitle, highlightLine1, + highlightLine2, animatePlaceholders); } -} +} \ No newline at end of file
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java index a2d0c92..d8684dd 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java
@@ -173,9 +173,11 @@ ImageFetcher.ASSISTANT_DETAILS_UMA_CLIENT_NAME, image -> { if (image != null) { viewHolder.mImageView.setImageDrawable(getRoundedImage(image)); - if (details.getAllowImageClickthrough()) { + if (details.hasImageClickthroughData() + && details.getImageClickthroughData().getAllowClickthrough()) { viewHolder.mImageView.setOnClickListener(unusedView - -> onImageClicked(mContext, details.getImageUrl())); + -> onImageClicked(mContext, details.getImageUrl(), + details.getImageClickthroughData())); } else { viewHolder.mImageView.setOnClickListener(null); } @@ -328,7 +330,8 @@ * see the original image, if they choose to see it, a new custom tab pointing to the * url of the orinial image will present on top of current one. */ - private void onImageClicked(Context context, String imageUrl) { + private void onImageClicked( + Context context, String imageUrl, ImageClickthroughData clickthroughData) { ModalDialogManager manager = new ModalDialogManager( new AppModalPresenter((android.app.Activity) context), ModalDialogType.APP); @@ -350,19 +353,31 @@ }; Resources resources = context.getResources(); - // TODO(wuandy): Make these strings server side and pass along with potential - // 'showAttribution' flag. PropertyModel.Builder builder = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) - .with(ModalDialogProperties.CONTROLLER, dialogController) - .with(ModalDialogProperties.TITLE, resources, - R.string.autofill_assistant_view_original_image_title) - .with(ModalDialogProperties.MESSAGE, resources, - R.string.autofill_assistant_view_original_image_desc) - .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, - R.string.autofill_assistant_view_original_image_view) - .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, - R.string.autofill_assistant_view_original_image_cancel); + .with(ModalDialogProperties.CONTROLLER, dialogController); + if (clickthroughData.getDescription() != null) { + builder.with(ModalDialogProperties.MESSAGE, clickthroughData.getDescription()); + } else { + builder.with(ModalDialogProperties.MESSAGE, resources, + R.string.autofill_assistant_view_original_image_desc); + } + + if (clickthroughData.getPositiveText() != null) { + builder.with( + ModalDialogProperties.POSITIVE_BUTTON_TEXT, clickthroughData.getPositiveText()); + } else { + builder.with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, + R.string.autofill_assistant_view_original_image_view); + } + + if (clickthroughData.getNegativeText() != null) { + builder.with( + ModalDialogProperties.NEGATIVE_BUTTON_TEXT, clickthroughData.getNegativeText()); + } else { + builder.with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, + R.string.autofill_assistant_view_original_image_cancel); + } PropertyModel dialogModel = builder.build(); manager.showDialog(dialogModel, ModalDialogType.APP);
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/ImageClickthroughData.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/ImageClickthroughData.java new file mode 100644 index 0000000..75ac73e --- /dev/null +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/ImageClickthroughData.java
@@ -0,0 +1,49 @@ +// Copyright 2019 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. + +package org.chromium.chrome.browser.autofill_assistant.details; + +/** + * Holds information controlling whether to show image clickthrough dialog and + * how to customize the dialog. + */ +/*package*/ class ImageClickthroughData { + private final boolean mAllowClickthrough; + private final String mDescription; + private final String mPositiveText; + private final String mNegativeText; + + ImageClickthroughData(boolean allowClickthrough, String description, String positiveText, + String negativeText) { + mAllowClickthrough = allowClickthrough; + mDescription = description; + mPositiveText = positiveText; + mNegativeText = negativeText; + } + + boolean getAllowClickthrough() { + return mAllowClickthrough; + } + + /** + * The description text in the clickthrough dialog. + */ + String getDescription() { + return mDescription; + } + + /** + * The text appear on positive button of clickthrough dialog. + */ + String getPositiveText() { + return mPositiveText; + } + + /** + * The text appear on negative button of clickthrough dialog. + */ + String getNegativeText() { + return mNegativeText; + } +}
diff --git a/chrome/android/features/autofill_assistant/java/strings/android_chrome_autofill_assistant_strings.grd b/chrome/android/features/autofill_assistant/java/strings/android_chrome_autofill_assistant_strings.grd index dd59c43e..7373067 100644 --- a/chrome/android/features/autofill_assistant/java/strings/android_chrome_autofill_assistant_strings.grd +++ b/chrome/android/features/autofill_assistant/java/strings/android_chrome_autofill_assistant_strings.grd
@@ -147,11 +147,8 @@ internal_comment="TODO(wnwen): Remove duplication in components/autofill_assistant_strings.grdp"> Sorry I'm not able to help, please continue on your own. </message> - <message name="IDS_AUTOFILL_ASSISTANT_VIEW_ORIGINAL_IMAGE_TITLE" desc="Title of view image dialog."> - Open Image - </message> <message name="IDS_AUTOFILL_ASSISTANT_VIEW_ORIGINAL_IMAGE_DESC" desc="Description of view image dialog."> - Would you like to navigate to the image URL? + Open external link? </message> <message name="IDS_AUTOFILL_ASSISTANT_VIEW_ORIGINAL_IMAGE_VIEW" desc="Text on the button to view original image."> View
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java index df39ad4..2662b69 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java
@@ -168,7 +168,7 @@ -> assistantCoordinator.getModel().getDetailsModel().set( AssistantDetailsModel.DETAILS, new AssistantDetails(movieTitle, /* imageUrl = */ "", - /* allowImageClickThrough = */ false, + /* imageClickthroughData = */ null, /* showImage = */ false, /* totalPriceLabel = */ "", /* totalPrice = */ "", Calendar.getInstance().getTime(),
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java index 328d9ed..25173ab 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java
@@ -42,8 +42,8 @@ CompositorViewHolder compositorViewHolder, ChromeFullscreenManager fullscreenManager) { PropertyModel containerViewModel = new PropertyModel(TabListContainerProperties.ALL_KEYS); - mMediator = new GridTabSwitcherMediator( - this, containerViewModel, tabModelSelector, fullscreenManager); + mMediator = new GridTabSwitcherMediator(this, containerViewModel, tabModelSelector, + fullscreenManager, compositorViewHolder); mMultiThumbnailCardProvider = new MultiThumbnailCardProvider(context, tabContentManager, tabModelSelector);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediator.java index db4ea22..560a1ca8 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediator.java
@@ -17,6 +17,7 @@ import org.chromium.base.ObserverList; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.browser.UrlConstants; +import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.compositor.layouts.OverviewModeController; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; import org.chromium.chrome.browser.fullscreen.FullscreenManager; @@ -70,6 +71,8 @@ } }; + private final CompositorViewHolder mCompositorViewHolder; + /** * In cases where a didSelectTab was due to switching models with a toggle, * we don't change tab grid visibility. @@ -90,9 +93,11 @@ * grid. * @param tabModelSelector {@link TabModelSelector} to observer for model and selection changes. * @param fullscreenManager {@link FullscreenManager} to use. + * @param compositorViewHolder {@link CompositorViewHolder} to use. */ GridTabSwitcherMediator(ResetHandler resetHandler, PropertyModel containerViewModel, - TabModelSelector tabModelSelector, ChromeFullscreenManager fullscreenManager) { + TabModelSelector tabModelSelector, ChromeFullscreenManager fullscreenManager, + CompositorViewHolder compositorViewHolder) { mResetHandler = resetHandler; mContainerViewModel = containerViewModel; mTabModelSelector = tabModelSelector; @@ -134,6 +139,8 @@ mContainerViewModel.set(TOP_CONTROLS_HEIGHT, fullscreenManager.getTopControlsHeight()); mContainerViewModel.set( BOTTOM_CONTROLS_HEIGHT, fullscreenManager.getBottomControlsHeight()); + + mCompositorViewHolder = compositorViewHolder; } private void setVisibility(boolean isVisible) { @@ -151,6 +158,12 @@ mContainerViewModel.set(IS_VISIBLE, isVisible); } + private void setContentOverlayVisibility(boolean isVisible) { + Tab currentTab = mTabModelSelector.getCurrentTab(); + if (currentTab == null) return; + mCompositorViewHolder.setContentOverlayVisibility(isVisible, true); + } + @Override public boolean overviewVisible() { return mContainerViewModel.get(IS_VISIBLE); @@ -182,6 +195,7 @@ @Override public void startedShowing(boolean isAnimating) { + setContentOverlayVisibility(false); for (OverviewModeObserver observer : mObservers) { observer.onOverviewModeStartedShowing(true); } @@ -196,6 +210,7 @@ @Override public void startedHiding(boolean isAnimating) { + setContentOverlayVisibility(true); for (OverviewModeObserver observer : mObservers) { observer.onOverviewModeStartedHiding(true, false); }
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediatorUnitTest.java index 248202a..97fb1ae7 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediatorUnitTest.java
@@ -37,6 +37,7 @@ import org.chromium.base.UserDataHost; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; @@ -95,6 +96,8 @@ PropertyObservable.PropertyObserver<PropertyKey> mPropertyObserver; @Mock OverviewModeBehavior.OverviewModeObserver mOverviewModeObserver; + @Mock + CompositorViewHolder mCompositorViewHolder; @Captor ArgumentCaptor<TabModelObserver> mTabModelObserverCaptor; @@ -152,8 +155,8 @@ mModel = new PropertyModel(TabListContainerProperties.ALL_KEYS); mModel.addObserver(mPropertyObserver); - mMediator = new GridTabSwitcherMediator( - mResetHandler, mModel, mTabModelSelector, mFullscreenManager); + mMediator = new GridTabSwitcherMediator(mResetHandler, mModel, mTabModelSelector, + mFullscreenManager, mCompositorViewHolder); mMediator.addOverviewModeObserver(mOverviewModeObserver); }
diff --git a/chrome/android/java/res/drawable-hdpi/bg_tabstrip_background_tab.9.png b/chrome/android/java/res/drawable-hdpi/bg_tabstrip_background_tab.9.png deleted file mode 100644 index 5b2583e..0000000 --- a/chrome/android/java/res/drawable-hdpi/bg_tabstrip_background_tab.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/bg_tabstrip_background_tab_outline.9.png b/chrome/android/java/res/drawable-hdpi/bg_tabstrip_background_tab_outline.9.png new file mode 100644 index 0000000..5ec3a9eb --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/bg_tabstrip_background_tab_outline.9.png Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/bg_tabstrip_incognito_background_tab.9.png b/chrome/android/java/res/drawable-hdpi/bg_tabstrip_incognito_background_tab.9.png deleted file mode 100644 index afcee82a..0000000 --- a/chrome/android/java/res/drawable-hdpi/bg_tabstrip_incognito_background_tab.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/bg_tabstrip_incognito_tab.9.png b/chrome/android/java/res/drawable-hdpi/bg_tabstrip_incognito_tab.9.png deleted file mode 100644 index 30b08c4f..0000000 --- a/chrome/android/java/res/drawable-hdpi/bg_tabstrip_incognito_tab.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/btn_tab_close_pressed.png b/chrome/android/java/res/drawable-hdpi/btn_tab_close_pressed.png deleted file mode 100644 index 8f35ee2b..0000000 --- a/chrome/android/java/res/drawable-hdpi/btn_tab_close_pressed.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/btn_tab_close_white_normal.png b/chrome/android/java/res/drawable-hdpi/btn_tab_close_white_normal.png deleted file mode 100644 index 81bdd38..0000000 --- a/chrome/android/java/res/drawable-hdpi/btn_tab_close_white_normal.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/btn_tab_close_white_pressed.png b/chrome/android/java/res/drawable-hdpi/btn_tab_close_white_pressed.png deleted file mode 100644 index 3a32f2d..0000000 --- a/chrome/android/java/res/drawable-hdpi/btn_tab_close_white_pressed.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/bg_tabstrip_background_tab.9.png b/chrome/android/java/res/drawable-mdpi/bg_tabstrip_background_tab.9.png deleted file mode 100644 index 5226350..0000000 --- a/chrome/android/java/res/drawable-mdpi/bg_tabstrip_background_tab.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/bg_tabstrip_background_tab_outline.9.png b/chrome/android/java/res/drawable-mdpi/bg_tabstrip_background_tab_outline.9.png new file mode 100644 index 0000000..e808cca --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/bg_tabstrip_background_tab_outline.9.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/bg_tabstrip_incognito_background_tab.9.png b/chrome/android/java/res/drawable-mdpi/bg_tabstrip_incognito_background_tab.9.png deleted file mode 100644 index aef8c53..0000000 --- a/chrome/android/java/res/drawable-mdpi/bg_tabstrip_incognito_background_tab.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/bg_tabstrip_incognito_tab.9.png b/chrome/android/java/res/drawable-mdpi/bg_tabstrip_incognito_tab.9.png deleted file mode 100644 index 2d187752..0000000 --- a/chrome/android/java/res/drawable-mdpi/bg_tabstrip_incognito_tab.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/btn_tab_close_pressed.png b/chrome/android/java/res/drawable-mdpi/btn_tab_close_pressed.png deleted file mode 100644 index 814e7c0..0000000 --- a/chrome/android/java/res/drawable-mdpi/btn_tab_close_pressed.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/btn_tab_close_white_normal.png b/chrome/android/java/res/drawable-mdpi/btn_tab_close_white_normal.png deleted file mode 100644 index 114b207..0000000 --- a/chrome/android/java/res/drawable-mdpi/btn_tab_close_white_normal.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/btn_tab_close_white_pressed.png b/chrome/android/java/res/drawable-mdpi/btn_tab_close_white_pressed.png deleted file mode 100644 index fd63f27..0000000 --- a/chrome/android/java/res/drawable-mdpi/btn_tab_close_white_pressed.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_background_tab.9.png b/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_background_tab.9.png deleted file mode 100644 index d973615..0000000 --- a/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_background_tab.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_background_tab_outline.9.png b/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_background_tab_outline.9.png new file mode 100644 index 0000000..38a4111 --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_background_tab_outline.9.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_incognito_background_tab.9.png b/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_incognito_background_tab.9.png deleted file mode 100644 index 7a494bf6..0000000 --- a/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_incognito_background_tab.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_incognito_tab.9.png b/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_incognito_tab.9.png deleted file mode 100644 index 68069b9..0000000 --- a/chrome/android/java/res/drawable-xhdpi/bg_tabstrip_incognito_tab.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/btn_tab_close_pressed.png b/chrome/android/java/res/drawable-xhdpi/btn_tab_close_pressed.png deleted file mode 100644 index a7fc020..0000000 --- a/chrome/android/java/res/drawable-xhdpi/btn_tab_close_pressed.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/btn_tab_close_white_normal.png b/chrome/android/java/res/drawable-xhdpi/btn_tab_close_white_normal.png deleted file mode 100644 index 5a08cc3..0000000 --- a/chrome/android/java/res/drawable-xhdpi/btn_tab_close_white_normal.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/btn_tab_close_white_pressed.png b/chrome/android/java/res/drawable-xhdpi/btn_tab_close_white_pressed.png deleted file mode 100644 index 4c96eaf2..0000000 --- a/chrome/android/java/res/drawable-xhdpi/btn_tab_close_white_pressed.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_background_tab.9.png b/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_background_tab.9.png deleted file mode 100644 index 6c65194f..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_background_tab.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_background_tab_outline.9.png b/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_background_tab_outline.9.png new file mode 100644 index 0000000..6ca01df --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_background_tab_outline.9.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_incognito_background_tab.9.png b/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_incognito_background_tab.9.png deleted file mode 100644 index 66b5ac9..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_incognito_background_tab.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_incognito_tab.9.png b/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_incognito_tab.9.png deleted file mode 100644 index 1b8eeaa..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/bg_tabstrip_incognito_tab.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/btn_tab_close_pressed.png b/chrome/android/java/res/drawable-xxhdpi/btn_tab_close_pressed.png deleted file mode 100644 index ac4c79b..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/btn_tab_close_pressed.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/btn_tab_close_white_normal.png b/chrome/android/java/res/drawable-xxhdpi/btn_tab_close_white_normal.png deleted file mode 100644 index 89eded1..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/btn_tab_close_white_normal.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/btn_tab_close_white_pressed.png b/chrome/android/java/res/drawable-xxhdpi/btn_tab_close_white_pressed.png deleted file mode 100644 index 6f24fdd5..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/btn_tab_close_white_pressed.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_background_tab.9.png b/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_background_tab.9.png deleted file mode 100644 index 6d09a93..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_background_tab.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_background_tab_outline.9.png b/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_background_tab_outline.9.png new file mode 100644 index 0000000..ed35bd3c --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_background_tab_outline.9.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_incognito_background_tab.9.png b/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_incognito_background_tab.9.png deleted file mode 100644 index bbadf3f..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_incognito_background_tab.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_incognito_tab.9.png b/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_incognito_tab.9.png deleted file mode 100644 index 228d388f..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/bg_tabstrip_incognito_tab.9.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/btn_tab_close_pressed.png b/chrome/android/java/res/drawable-xxxhdpi/btn_tab_close_pressed.png deleted file mode 100644 index 30ce70db..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/btn_tab_close_pressed.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/btn_tab_close_white_normal.png b/chrome/android/java/res/drawable-xxxhdpi/btn_tab_close_white_normal.png deleted file mode 100644 index c9aaa8b..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/btn_tab_close_white_normal.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/btn_tab_close_white_pressed.png b/chrome/android/java/res/drawable-xxxhdpi/btn_tab_close_white_pressed.png deleted file mode 100644 index e43f417..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/btn_tab_close_white_pressed.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/layout/find_in_page.xml b/chrome/android/java/res/layout/find_in_page.xml index fef4e1f9..1b7aef2 100644 --- a/chrome/android/java/res/layout/find_in_page.xml +++ b/chrome/android/java/res/layout/find_in_page.xml
@@ -39,8 +39,7 @@ android:layout_height="match_parent" android:layout_marginTop="8dp" android:layout_marginBottom="8dp" - android:background="#000000" - android:alpha="0.1" /> + android:background="@color/divider_bg_color" /> <org.chromium.ui.widget.ChromeImageButton android:id="@+id/find_prev_button" style="@style/ToolbarButton"
diff --git a/chrome/android/java/res/layout/radio_button_with_description.xml b/chrome/android/java/res/layout/radio_button_with_description.xml index 06458fd..ce3cb5e2 100644 --- a/chrome/android/java/res/layout/radio_button_with_description.xml +++ b/chrome/android/java/res/layout/radio_button_with_description.xml
@@ -31,6 +31,5 @@ android:layout_alignStart="@id/title" android:layout_below="@id/title" android:textAppearance="@style/TextAppearance.BlackHint2" - android:paddingTop="4dp" android:visibility="gone" /> </merge>
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml index 697f568..cc79e2d8 100644 --- a/chrome/android/java/res/values/colors.xml +++ b/chrome/android/java/res/values/colors.xml
@@ -92,6 +92,12 @@ <color name="data_reduction_original_color">@color/pref_accent_color</color> <color name="data_reduction_chart_background_color">@color/modern_secondary_color</color> + <!-- Compositor Tab Colors --> + <color name="compositor_background_tab_bg">@color/modern_grey_300</color> + <color name="compositor_background_tab_bg_incognito">#2A2D2F</color> + <color name="compositor_background_tab_outline">#ACB1B6</color> + <color name="compositor_background_tab_outline_incognito">#0E0F10</color> + <!-- Compositor Tab Title Colors --> <color name="compositor_tab_title_bar_text">@color/default_text_color</color> <color name="compositor_tab_title_bar_text_incognito">@android:color/white</color> @@ -157,7 +163,7 @@ <color name="find_result_bar_active_border_color">#C37E3B</color> <color name="find_in_page_query_white_color">@android:color/white</color> <color name="find_in_page_query_incognito_hint_color">@color/white_alpha_70</color> - <color name="find_in_page_failed_results_status_color">#DB4437</color> + <color name="find_in_page_failed_results_status_color">@color/default_red</color> <color name="find_in_page_query_default_hint_color">@color/search_box_hint</color> <!-- App Background Colors -->
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index fac9f9d4..a1ba5c0 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -605,6 +605,7 @@ <dimen name="swipe_to_dismiss_threshold">72dp</dimen> <!-- RadioButtonWithDescription dimensions --> - <dimen name="radio_button_with_description_padding">12dp</dimen> + <dimen name="radio_button_with_description_lateral_padding">16dp</dimen> + <dimen name="radio_button_with_description_vertical_padding">10dp</dimen> </resources>
diff --git a/chrome/android/java/res_night/values-night/colors.xml b/chrome/android/java/res_night/values-night/colors.xml index 0b0d3833..551605b6 100644 --- a/chrome/android/java/res_night/values-night/colors.xml +++ b/chrome/android/java/res_night/values-night/colors.xml
@@ -5,7 +5,7 @@ <resources> <color name="light_active_color">@color/modern_blue_300</color> - <color name="control_normal_color">@color/modern_grey_200</color> + <color name="control_normal_color">@color/modern_grey_500</color> <color name="toolbar_text_box_background">@color/modern_grey_800</color> @@ -19,4 +19,8 @@ <color name="signin_header_animation_line_light">@color/modern_grey_700</color> <color name="signin_header_animation_line_dark">@color/modern_grey_700</color> <color name="signin_header_animation_laptop_screen">@color/modern_grey_900</color> + + <!-- Tab Strip Colors --> + <color name="compositor_background_tab_bg">@color/modern_grey_900</color> + <color name="compositor_background_tab_outline">@android:color/black</color> </resources>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index 39b6d9e..0d6a74e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -1436,10 +1436,11 @@ */ @Override public SnackbarManager getSnackbarManager() { - return mBottomSheetController != null - && mBottomSheetController.getBottomSheet().isSheetOpen() - ? mBottomSheetController.getSnackbarManager() - : mSnackbarManager; + boolean useBottomSheetContainer = mBottomSheetController != null + && mBottomSheetController.getBottomSheet().isSheetOpen() + && !mBottomSheetController.getBottomSheet().isClosing(); + return useBottomSheetContainer ? mBottomSheetController.getSnackbarManager() + : mSnackbarManager; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/SwipeRefreshHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/SwipeRefreshHandler.java index ce7dda0d..104c051 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/SwipeRefreshHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/SwipeRefreshHandler.java
@@ -17,6 +17,7 @@ import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.gesturenav.NavigationHandler; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabWebContentsUserData; import org.chromium.components.feature_engagement.EventConstants; @@ -55,6 +56,8 @@ // The Tab where the swipe occurs. private Tab mTab; + private EmptyTabObserver mTabObserver; + // The container view the SwipeRefreshHandler instance is currently // associated with. private ViewGroup mContainerView; @@ -95,15 +98,29 @@ private SwipeRefreshHandler(Tab tab) { super(tab); mTab = tab; + mTabObserver = new EmptyTabObserver() { + @Override + public void onActivityAttachmentChanged(Tab tab, boolean isAttached) { + if (!isAttached && mSwipeRefreshLayout != null) { + cancelStopRefreshingRunnable(); + detachSwipeRefreshLayoutIfNecessary(); + mSwipeRefreshLayout.setOnRefreshListener(null); + mSwipeRefreshLayout.setOnResetListener(null); + mSwipeRefreshLayout = null; + } + } + }; + mTab.addObserver(mTabObserver); mNavigationEnabled = ChromeFeatureList.isEnabled(ChromeFeatureList.OVERSCROLL_HISTORY_NAVIGATION); } - private void initSwipeRefreshLayout() { - final Context context = mTab.getThemedApplicationContext(); + private void initSwipeRefreshLayout(final Context context) { mSwipeRefreshLayout = new SwipeRefreshLayout(context); mSwipeRefreshLayout.setLayoutParams( new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); + mSwipeRefreshLayout.setProgressBackgroundColorSchemeResource( + R.color.default_bg_color_elev_2); mSwipeRefreshLayout.setColorSchemeResources(R.color.light_active_color); if (mContainerView != null) mSwipeRefreshLayout.setEnabled(true); @@ -174,7 +191,7 @@ mSwipeType = type; if (type == OverscrollAction.PULL_TO_REFRESH) { - if (mSwipeRefreshLayout == null) initSwipeRefreshLayout(); + if (mSwipeRefreshLayout == null) initSwipeRefreshLayout(mTab.getContext()); attachSwipeRefreshLayoutIfNecessary(); return mSwipeRefreshLayout.start(); } else if (type == OverscrollAction.HISTORY_NAVIGATION && mNavigationEnabled) { @@ -244,7 +261,11 @@ private Runnable getStopRefreshingRunnable() { if (mStopRefreshingRunnable == null) { - mStopRefreshingRunnable = () -> mSwipeRefreshLayout.setRefreshing(false); + mStopRefreshingRunnable = () -> { + if (mSwipeRefreshLayout != null) { + mSwipeRefreshLayout.setRefreshing(false); + } + }; } return mStopRefreshingRunnable; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java index 2fceca8..0fed566f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java
@@ -48,7 +48,8 @@ private final CompositorOnClickHandler mClickHandler; - private int mResource; + protected int mResource; + private int mPressedResource; private int mIncognitoResource; private int mIncognitoPressedResource; @@ -122,7 +123,7 @@ } /** - * @return The the x offset of the button. + * @return The x offset of the button. */ public float getX() { return mBounds.left;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/TintedCompositorButton.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/TintedCompositorButton.java new file mode 100644 index 0000000..db151aa --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/TintedCompositorButton.java
@@ -0,0 +1,89 @@ +// Copyright 2019 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. + +package org.chromium.chrome.browser.compositor.layouts.components; + +import android.content.Context; +import android.support.annotation.ColorInt; +import android.support.annotation.DrawableRes; +import android.support.annotation.IdRes; + +/** + * Class for a CompositorButton that uses tint instead of multiple drawable resources. + */ +public class TintedCompositorButton extends CompositorButton { + private Context mContext; + + private @IdRes int mDefaultTintResource; + private @IdRes int mPressedTintResource; + private @IdRes int mIncognitoTintResource; + private @IdRes int mIncognitoPressedTintResource; + + public TintedCompositorButton( + Context context, float width, float height, CompositorOnClickHandler clickHandler) { + super(context, width, height, clickHandler); + + mContext = context; + } + + public TintedCompositorButton(Context context, float width, float height, + CompositorOnClickHandler clickHandler, @DrawableRes int resource) { + super(context, width, height, clickHandler); + + mContext = context; + mResource = resource; + } + + /* + * This method should not be called. Use setResource and setTintResources instead. + */ + @Override + public void setResources(int resource, int pressedResource, int incognitoResource, + int incognitoPressedResource) { + throw new UnsupportedOperationException(); + } + + /** + * @param resource The default Android resource. + */ + public void setResource(@DrawableRes int resource) { + mResource = resource; + } + + /** + * @return The default Android resource. + */ + @Override + public int getResourceId() { + return mResource; + } + + /** + * A set of Android resources to supply to the compositor. + * @param defaultTint The default tint resource. + * @param pressedTint The pressed tint resource. + * @param incognitoTint The incognito tint resource. + * @param incognitoPressedTint The incognito pressed tint resource. + */ + public void setTintResources(@IdRes int defaultTint, @IdRes int pressedTint, + @IdRes int incognitoTint, @IdRes int incognitoPressedTint) { + mDefaultTintResource = defaultTint; + mPressedTintResource = pressedTint; + mIncognitoTintResource = incognitoTint; + mIncognitoPressedTintResource = incognitoPressedTint; + } + + /** + * @return The tint (color value, NOT the resource Id) depending on the state of the button and + * the tab (incognito or not). + */ + public @ColorInt int getTint() { + int tint = isIncognito() ? mIncognitoTintResource : mDefaultTintResource; + if (isPressed()) { + tint = isIncognito() ? mIncognitoPressedTintResource : mPressedTintResource; + } + + return mContext.getResources().getColor(tint); + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java index 4b1d0b6a..8681b2b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
@@ -19,6 +19,7 @@ import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost; import org.chromium.chrome.browser.compositor.layouts.components.CompositorButton; import org.chromium.chrome.browser.compositor.layouts.components.CompositorButton.CompositorOnClickHandler; +import org.chromium.chrome.browser.compositor.layouts.components.TintedCompositorButton; import org.chromium.chrome.browser.compositor.layouts.components.VirtualView; import org.chromium.chrome.browser.compositor.overlays.strip.TabLoadTracker.TabLoadTrackerCallback; import org.chromium.chrome.browser.tab.Tab; @@ -112,10 +113,12 @@ private int mId = Tab.INVALID_TAB_ID; + private final Context mContext; private final StripLayoutTabDelegate mDelegate; private final TabLoadTracker mLoadTracker; private final LayoutRenderHost mRenderHost; private final LayoutUpdateHost mUpdateHost; + private final TintedCompositorButton mCloseButton; private boolean mVisible = true; private boolean mIsDying; @@ -139,8 +142,6 @@ private boolean mShowingCloseButton = true; - private final CompositorButton mCloseButton; - // Content Animations private CompositorAnimator mButtonOpacityAnimation; @@ -167,6 +168,7 @@ TabLoadTrackerCallback loadTrackerCallback, LayoutRenderHost renderHost, LayoutUpdateHost updateHost, boolean incognito) { mId = id; + mContext = context; mDelegate = delegate; mLoadTracker = new TabLoadTracker(id, loadTrackerCallback); mRenderHost = renderHost; @@ -178,9 +180,10 @@ mDelegate.handleCloseButtonClick(StripLayoutTab.this, time); } }; - mCloseButton = new CompositorButton(context, 0, 0, closeClickAction); - mCloseButton.setResources(R.drawable.btn_tab_close_normal, R.drawable.btn_tab_close_pressed, - R.drawable.btn_tab_close_white_normal, R.drawable.btn_tab_close_white_pressed); + mCloseButton = new TintedCompositorButton( + context, 0, 0, closeClickAction, R.drawable.btn_tab_close_normal); + mCloseButton.setTintResources(R.color.default_icon_color, R.color.default_icon_color_blue, + R.color.default_icon_color_white, R.color.modern_blue_300); mCloseButton.setIncognito(mIncognito); mCloseButton.setBounds(getCloseRect()); mCloseButton.setClickSlop(0.f); @@ -250,15 +253,45 @@ } /** - * @param foreground Whether or not this tab is a foreground tab. * @return The Android resource that represents the tab background. */ - public int getResourceId(boolean foreground) { + public int getResourceId() { + return R.drawable.bg_tabstrip_tab; + } + + /** + * @return The Android resource that represents the tab outline. + */ + public int getOutlineResourceId() { + return R.drawable.bg_tabstrip_background_tab_outline; + } + + /** + * @param foreground Whether or not this tab is a foreground tab. + * @return The tint color resource that represents the tab background. + */ + public int getTint(boolean foreground) { + int tint = mIncognito ? R.color.compositor_background_tab_bg_incognito + : R.color.compositor_background_tab_bg; if (foreground) { - return mIncognito ? R.drawable.bg_tabstrip_incognito_tab : R.drawable.bg_tabstrip_tab; + tint = mIncognito ? R.color.modern_grey_800 : R.color.default_bg_color_elev_3; } - return mIncognito ? R.drawable.bg_tabstrip_incognito_background_tab - : R.drawable.bg_tabstrip_background_tab; + + return mContext.getResources().getColor(tint); + } + + /** + * @param foreground Whether or not this tab is a foreground tab. + * @return The tint color resource that represents the tab outline. + */ + public int getOutlineTint(boolean foreground) { + int tint = mIncognito ? R.color.compositor_background_tab_outline_incognito + : R.color.compositor_background_tab_outline; + if (foreground) { + tint = mIncognito ? R.color.modern_grey_800 : R.color.default_bg_color_elev_3; + } + + return mContext.getResources().getColor(tint); } /** @@ -468,7 +501,7 @@ /** * @return The close button for this tab. */ - public CompositorButton getCloseButton() { + public TintedCompositorButton getCloseButton() { return mCloseButton; } @@ -571,7 +604,7 @@ ResourceManager manager = mRenderHost.getResourceManager(); if (manager != null) { LayoutResource resource = - manager.getResource(AndroidResourceType.STATIC, getResourceId(false)); + manager.getResource(AndroidResourceType.STATIC, getResourceId()); if (resource != null) { xOffset = LocalizationUtils.isLayoutRtl() ? resource.getPadding().left
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/resources/StaticResourcePreloads.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/resources/StaticResourcePreloads.java index 7cad1dc5..14db2da 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/resources/StaticResourcePreloads.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/resources/StaticResourcePreloads.java
@@ -16,11 +16,13 @@ public class StaticResourcePreloads { /** A list of resources to load synchronously once the compositor is initialized. */ private static int[] sSynchronousResources = new int[] { - R.drawable.bg_tabstrip_tab, R.drawable.bg_tabstrip_background_tab, - R.drawable.btn_tab_close_normal, R.drawable.btn_tab_close_white_normal, - R.drawable.btn_tab_close_pressed, R.drawable.btn_tabstrip_new_tab_normal, + R.drawable.bg_tabstrip_tab, + R.drawable.btn_tab_close_normal, + R.drawable.btn_tabstrip_new_tab_normal, R.drawable.btn_tabstrip_new_incognito_tab_normal, - R.drawable.btn_tabstrip_new_tab_pressed, R.drawable.spinner, R.drawable.spinner_white, + R.drawable.btn_tabstrip_new_tab_pressed, + R.drawable.spinner, + R.drawable.spinner_white, }; /** A list of resources to load asynchronously once the compositor is initialized. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java index 4223a1a..635007c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
@@ -133,12 +133,13 @@ final StripLayoutTab st = stripTabs[i]; boolean isSelected = st.getId() == selectedTabId; nativePutStripTabLayer(mNativePtr, st.getId(), st.getCloseButton().getResourceId(), - st.getResourceId(isSelected), isSelected, st.getClosePressed(), - layoutHelper.getWidth() * mDpToPx, st.getDrawX() * mDpToPx, - st.getDrawY() * mDpToPx, st.getWidth() * mDpToPx, st.getHeight() * mDpToPx, - st.getContentOffsetX() * mDpToPx, st.getCloseButton().getOpacity(), - st.isLoading(), st.getLoadingSpinnerRotation(), layerTitleCache, - resourceManager); + st.getResourceId(), st.getOutlineResourceId(), st.getCloseButton().getTint(), + st.getTint(isSelected), st.getOutlineTint(isSelected), isSelected, + st.getClosePressed(), layoutHelper.getWidth() * mDpToPx, + st.getDrawX() * mDpToPx, st.getDrawY() * mDpToPx, st.getWidth() * mDpToPx, + st.getHeight() * mDpToPx, st.getContentOffsetX() * mDpToPx, + st.getCloseButton().getOpacity(), st.isLoading(), + st.getLoadingSpinnerRotation(), layerTitleCache, resourceManager); } } @@ -165,7 +166,8 @@ private native void nativeUpdateTabStripRightFade(long nativeTabStripSceneLayer, int resourceId, float opacity, ResourceManager resourceManager); private native void nativePutStripTabLayer(long nativeTabStripSceneLayer, int id, - int closeResourceId, int handleResourceId, boolean foreground, boolean closePressed, + int closeResourceId, int handleResourceId, int handleOutlineResourceId, int closeTint, + int handleTint, int handleOutlineTint, boolean foreground, boolean closePressed, float toolbarWidth, float x, float y, float width, float height, float contentOffsetX, float closeButtonAlpha, boolean isLoading, float spinnerRotation, LayerTitleCache layerTitleCache, ResourceManager resourceManager);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java index e718efc..b0014009 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java
@@ -113,6 +113,7 @@ @Override public void destroy() { if (mTabModelObserver != null) mTabModelObserver.destroy(); + if (mPresenter != null) mPresenter.destroy(); } /** Update whether the {@link ModalDialogManager} should suspend tab modal dialogs. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalPresenter.java b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalPresenter.java index 467f2b7..878cffca 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalPresenter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalPresenter.java
@@ -21,13 +21,11 @@ import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel; import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager; +import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabAttributeKeys; import org.chromium.chrome.browser.tab.TabAttributes; import org.chromium.chrome.browser.tab.TabBrowserControlsOffsetHelper; -import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet; -import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetObserver; -import org.chromium.chrome.browser.widget.bottomsheet.EmptyBottomSheetObserver; import org.chromium.content_public.browser.SelectionPopupController; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.common.BrowserControlsState; @@ -44,24 +42,16 @@ * The presenter that displays a single tab modal dialog. */ public class TabModalPresenter - extends ModalDialogManager.Presenter implements TabBrowserControlsOffsetHelper.Observer { + extends ModalDialogManager.Presenter implements TabBrowserControlsOffsetHelper.Observer, + ChromeFullscreenManager.FullscreenListener { private static final int ENTER_EXIT_ANIMATION_DURATION_MS = 200; /** The activity displaying the dialogs. */ private final ChromeActivity mChromeActivity; - /** Whether browser controls are at the bottom */ - private final boolean mHasBottomControls; - /** The active tab of which the dialog will be shown on top. */ private Tab mActiveTab; - /** - * The observer to change view hierarchy for the dialog container when the sheet is opened or - * closed. - */ - private BottomSheetObserver mBottomSheetObserver; - /** The parent view that contains the dialog container. */ private ViewGroup mContainerParent; @@ -96,6 +86,10 @@ /** Enter and exit animation duration that can be overwritten in tests. */ private int mEnterExitAnimationDurationMs; + private final ChromeFullscreenManager mChromeFullscreenManager; + private int mBottomControlsHeight; + private boolean mShouldUpdateContainerLayoutParams; + private class ViewBinder extends ModalDialogViewBinder { @Override public void bind(PropertyModel model, ModalDialogView view, PropertyKey propertyKey) { @@ -120,22 +114,14 @@ */ public TabModalPresenter(ChromeActivity chromeActivity) { mChromeActivity = chromeActivity; - mHasBottomControls = mChromeActivity.getBottomSheet() != null; mEnterExitAnimationDurationMs = ENTER_EXIT_ANIMATION_DURATION_MS; + mChromeFullscreenManager = mChromeActivity.getFullscreenManager(); + mChromeFullscreenManager.addListener(this); + } - if (mHasBottomControls) { - mBottomSheetObserver = new EmptyBottomSheetObserver() { - @Override - public void onSheetOpened(@BottomSheet.StateChangeReason int reason) { - updateContainerHierarchy(false); - } + public void destroy() { + if (mChromeFullscreenManager != null) mChromeFullscreenManager.removeListener(this); - @Override - public void onSheetClosed(@BottomSheet.StateChangeReason int reason) { - updateContainerHierarchy(true); - } - }; - } } // ModalDialogManager.Presenter implementation. @@ -143,6 +129,7 @@ @Override protected void addDialogView(PropertyModel model) { if (mDialogContainer == null) initDialogContainer(); + updateContainerLayoutParams(); mDialogView = (ModalDialogView) LayoutInflater .from(new ContextThemeWrapper( mChromeActivity, R.style.Theme_Chromium_ModalDialog)) @@ -192,6 +179,23 @@ } } + // ChromeFullscreenManager.FullscreenListener implementation. + + @Override + public void onContentOffsetChanged(int offset) {} + + @Override + public void onControlsOffsetChanged(int topOffset, int bottomOffset, boolean needsAnimate) {} + + @Override + public void onToggleOverlayVideoMode(boolean enabled) {} + + @Override + public void onBottomControlsHeightChanged(int bottomControlsHeight) { + mBottomControlsHeight = bottomControlsHeight; + mShouldUpdateContainerLayoutParams = true; + } + private TabBrowserControlsOffsetHelper getControlsOffsetHelper() { return TabBrowserControlsOffsetHelper.from(mActiveTab); } @@ -254,26 +258,32 @@ MarginLayoutParams params = (MarginLayoutParams) mDialogContainer.getLayoutParams(); params.width = ViewGroup.MarginLayoutParams.MATCH_PARENT; params.height = ViewGroup.MarginLayoutParams.MATCH_PARENT; - params.topMargin = !mHasBottomControls ? containerVerticalMargin : 0; - params.bottomMargin = mHasBottomControls ? containerVerticalMargin : 0; + params.topMargin = containerVerticalMargin; + params.bottomMargin = mChromeActivity.getFullscreenManager().getBottomControlsHeight(); mDialogContainer.setLayoutParams(params); View scrimView = mDialogContainer.findViewById(R.id.scrim); params = (MarginLayoutParams) scrimView.getLayoutParams(); params.width = MarginLayoutParams.MATCH_PARENT; params.height = MarginLayoutParams.MATCH_PARENT; - params.topMargin = !mHasBottomControls ? scrimVerticalMargin : 0; - params.bottomMargin = mHasBottomControls ? scrimVerticalMargin : 0; + params.topMargin = scrimVerticalMargin; scrimView.setLayoutParams(params); } + private void updateContainerLayoutParams() { + if (!mShouldUpdateContainerLayoutParams) return; + MarginLayoutParams params = (MarginLayoutParams) mDialogContainer.getLayoutParams(); + params.bottomMargin = mBottomControlsHeight; + mDialogContainer.setLayoutParams(params); + mShouldUpdateContainerLayoutParams = false; + } + /** * Set whether the browser controls access should be restricted. If true, dialogs are expected * to be showing and overflow menu would be disabled. * @param restricted Whether the browser controls access should be restricted. */ private void setBrowserControlsAccess(boolean restricted) { - BottomSheet bottomSheet = mChromeActivity.getBottomSheet(); View menuButton = mChromeActivity.getToolbarManager().getMenuButton(); if (restricted) { @@ -308,12 +318,8 @@ // Force toolbar to show and disable overflow menu. onTabModalDialogStateChanged(true); - if (mHasBottomControls) { - bottomSheet.setSheetState(BottomSheet.SheetState.PEEK, true); - bottomSheet.addObserver(mBottomSheetObserver); - } else { - mChromeActivity.getToolbarManager().setUrlBarFocus(false); - } + mChromeActivity.getToolbarManager().setUrlBarFocus(false); + menuButton.setEnabled(false); } else { getControlsOffsetHelper().removeObserver(this); @@ -329,7 +335,6 @@ onTabModalDialogStateChanged(false); menuButton.setEnabled(true); - if (mHasBottomControls) bottomSheet.removeObserver(mBottomSheetObserver); mActiveTab = null; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/RadioButtonWithDescription.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/RadioButtonWithDescription.java index 3180c7a8..f578d51 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/RadioButtonWithDescription.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/RadioButtonWithDescription.java
@@ -54,9 +54,13 @@ if (attrs != null) applyAttributes(attrs); - final int padding = - getResources().getDimensionPixelSize(R.dimen.radio_button_with_description_padding); - setPaddingRelative(padding, padding, padding, padding); + setMinimumHeight(getResources().getDimensionPixelSize(R.dimen.min_touch_target_size)); + + final int lateralPadding = getResources().getDimensionPixelSize( + R.dimen.radio_button_with_description_lateral_padding); + final int verticalPadding = getResources().getDimensionPixelSize( + R.dimen.radio_button_with_description_vertical_padding); + setPaddingRelative(lateralPadding, verticalPadding, lateralPadding, verticalPadding); // We want RadioButtonWithDescription to handle the clicks itself. setOnClickListener(this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java index 31f86ae..7d17bac0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -472,6 +472,13 @@ return mActionBarDelegate; } + /** + * @return Whether the sheet is in the process of closing. + */ + public boolean isClosing() { + return mSettleAnimator != null && mTargetState == SheetState.HIDDEN; + } + @Override public boolean onInterceptTouchEvent(MotionEvent e) { // If touch is disabled, act like a black hole and consume touch events without doing
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbar.java index 8cb2279..b0175851 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbar.java
@@ -76,6 +76,7 @@ protected ImageButton mCloseFindButton; protected ImageButton mFindPrevButton; protected ImageButton mFindNextButton; + protected View mDivider; private FindResultBar mResultBar; @@ -335,6 +336,8 @@ deactivate(); } }); + + mDivider = findViewById(R.id.find_separator); } // Overriden by subclasses. @@ -762,8 +765,8 @@ * @return The color of the status text. */ protected int getStatusColor(boolean failed, boolean incognito) { - int colorResourceId = - failed ? R.color.find_in_page_failed_results_status_color : R.color.black_alpha_38; + int colorResourceId = failed ? R.color.find_in_page_failed_results_status_color + : R.color.disabled_text_color; return ApiCompatibilityUtils.getColor(getContext().getResources(), colorResourceId); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarPhone.java index f5bf47b3..7602a33 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarPhone.java
@@ -43,6 +43,7 @@ protected void updateVisualsForTabModel(boolean isIncognito) { int queryTextColorId; int queryHintTextColorId; + int dividerColorId; if (isIncognito) { setBackgroundColor(ColorUtils.getDefaultThemeColor(getResources(), true)); ColorStateList white = ColorUtils.getIconTint(getContext(), true); @@ -51,7 +52,7 @@ ApiCompatibilityUtils.setImageTintList(mCloseFindButton, white); queryTextColorId = R.color.find_in_page_query_white_color; queryHintTextColorId = R.color.find_in_page_query_incognito_hint_color; - + dividerColorId = R.color.white_alpha_12; } else { setBackgroundColor(ColorUtils.getDefaultThemeColor(getResources(), false)); ColorStateList dark = ColorUtils.getIconTint(getContext(), false); @@ -60,20 +61,21 @@ ApiCompatibilityUtils.setImageTintList(mCloseFindButton, dark); queryTextColorId = R.color.default_text_color; queryHintTextColorId = R.color.find_in_page_query_default_hint_color; + dividerColorId = R.color.divider_bg_color; } mFindQuery.setTextColor( ApiCompatibilityUtils.getColor(getContext().getResources(), queryTextColorId)); mFindQuery.setHintTextColor( ApiCompatibilityUtils.getColor(getContext().getResources(), queryHintTextColorId)); + mDivider.setBackgroundResource(dividerColorId); } @Override protected int getStatusColor(boolean failed, boolean incognito) { - if (!failed && incognito) { - return ApiCompatibilityUtils.getColor( - getContext().getResources(), R.color.white_alpha_50); + if (incognito) { + final int colorResourceId = failed ? R.color.default_red_light : R.color.white_alpha_50; + return ApiCompatibilityUtils.getColor(getContext().getResources(), colorResourceId); } - return super.getStatusColor(failed, incognito); } }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 9ba340d..eddda5d 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -705,7 +705,7 @@ System default </message> <message name="IDS_THEMES_SYSTEM_DEFAULT_SUMMARY" desc="Summary for the System Default option."> - Turn on dark theme when your device's Power Saver is on + Turn on dark theme when your device's Battery Saver is on </message> <!-- Privacy preferences -->
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_PREFS_THEMES.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_PREFS_THEMES.png.sha1 index 79c36c2..e7eea2d 100644 --- a/chrome/android/java/strings/android_chrome_strings_grd/IDS_PREFS_THEMES.png.sha1 +++ b/chrome/android/java/strings/android_chrome_strings_grd/IDS_PREFS_THEMES.png.sha1
@@ -1 +1 @@ -83e6b33441fb9fb040453b65e62b1ec2806b5dc0 \ No newline at end of file +4b29c5541aa913738c53a46c8bff615c56b35548 \ No newline at end of file
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_THEMES_SYSTEM_DEFAULT_SUMMARY.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_THEMES_SYSTEM_DEFAULT_SUMMARY.png.sha1 index 6a948f2..d9f335720 100644 --- a/chrome/android/java/strings/android_chrome_strings_grd/IDS_THEMES_SYSTEM_DEFAULT_SUMMARY.png.sha1 +++ b/chrome/android/java/strings/android_chrome_strings_grd/IDS_THEMES_SYSTEM_DEFAULT_SUMMARY.png.sha1
@@ -1 +1 @@ -f480a380262e59945a8f6e231402e7811992452c \ No newline at end of file +ae1cfcb91300aac48797b74eead8b426a124aa14 \ No newline at end of file
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_THEMES_SYSTEM_DEFAULT_TITLE.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_THEMES_SYSTEM_DEFAULT_TITLE.png.sha1 index cb22137..a5a3723 100644 --- a/chrome/android/java/strings/android_chrome_strings_grd/IDS_THEMES_SYSTEM_DEFAULT_TITLE.png.sha1 +++ b/chrome/android/java/strings/android_chrome_strings_grd/IDS_THEMES_SYSTEM_DEFAULT_TITLE.png.sha1
@@ -1 +1 @@ -9050bd8f51737af32a7b110df31e7528028253b2 \ No newline at end of file +97131ff8855cb8e38dc9de883eecd40903526c9a \ No newline at end of file
diff --git a/chrome/android/webapk/shell_apk/manifest/manifest_mustache_pass.py b/chrome/android/webapk/shell_apk/manifest/manifest_mustache_pass.py index 39852ba..e1be178 100755 --- a/chrome/android/webapk/shell_apk/manifest/manifest_mustache_pass.py +++ b/chrome/android/webapk/shell_apk/manifest/manifest_mustache_pass.py
@@ -15,10 +15,10 @@ #Import pystache from //third_party/pystache src_dir = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, os.pardir, os.pardir) -sys.path.append(os.path.join(src_dir, 'third_party')) +sys.path.insert(0, os.path.join(src_dir, 'third_party')) import pystache -sys.path.append(os.path.join(src_dir, 'build', 'android', 'gyp', 'util')) -import build_utils +sys.path.insert(0, os.path.join(src_dir, 'build/android/gyp')) +from util import build_utils # pylint: disable=import-error def _AppendParsedVariables(initial_variable_list, variables_arg, error_func):
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 940e2e48..4ef8f9f 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -8764,6 +8764,9 @@ <message name="IDS_TOOLTIP_TAB_ALERT_STATE_USB_CONNECTED" desc="Extra tool tip text, when tab is connected to a USB device."> This tab is connected to a USB device. </message> + <message name="IDS_TOOLTIP_TAB_ALERT_STATE_SERIAL_CONNECTED" desc="Extra tool tip text, when tab is connected to a serial port."> + This tab is connected to a serial port. + </message> <message name="IDS_TOOLTIP_TAB_ALERT_STATE_PIP_PLAYING" desc="Extra tool tip text, when tab is playing a video in Picture-in-Picture."> This tab is playing a video in picture-in-picture mode. </message> @@ -8796,6 +8799,9 @@ <message name="IDS_TAB_AX_LABEL_USB_CONNECTED_FORMAT" desc="Accessibility label text, when a tab is connected to a USB device. Example: 'Google Photos - USB device connected'"> <ph name="WINDOW_TITLE">$1<ex>Google Photos</ex></ph> - USB device connected </message> + <message name="IDS_TAB_AX_LABEL_SERIAL_CONNECTED_FORMAT" desc="Accessibility label text, when a tab is connected to a serial port. Example: 'Google Photos - Serial port connected'"> + <ph name="WINDOW_TITLE">$1<ex>Google Photos</ex></ph> - Serial port connected + </message> <message name="IDS_TAB_AX_LABEL_NETWORK_ERROR_FORMAT" desc="Accessibility label text, when tab has encountered a network error such as being disconnected from the internet. Example: 'www.google.com - Network error'"> <ph name="WINDOW_TITLE">$1<ex>www.google.com</ex></ph> - Network error </message>
diff --git a/chrome/app/generated_resources_grd/IDS_TOOLTIP_TAB_ALERT_STATE_SERIAL_CONNECTED.png.sha1 b/chrome/app/generated_resources_grd/IDS_TOOLTIP_TAB_ALERT_STATE_SERIAL_CONNECTED.png.sha1 new file mode 100644 index 0000000..af8326e --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TOOLTIP_TAB_ALERT_STATE_SERIAL_CONNECTED.png.sha1
@@ -0,0 +1 @@ +d067f692af0231441e02b61aa8d578119d81ec87 \ No newline at end of file
diff --git a/chrome/app/theme/default_100_percent/common/calculator_round_24.png b/chrome/app/theme/default_100_percent/common/calculator_round_24.png deleted file mode 100644 index db7ad7d..0000000 --- a/chrome/app/theme/default_100_percent/common/calculator_round_24.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/calculator_round_24.png b/chrome/app/theme/default_200_percent/common/calculator_round_24.png deleted file mode 100644 index f1f302d..0000000 --- a/chrome/app/theme/default_200_percent/common/calculator_round_24.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index bdcfd22..a8150ed 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd
@@ -156,7 +156,6 @@ <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_EASYUNLOCK_ENABLED" file="cros/notification_easyunlock_enabled.png" /> </if> <if expr="not is_android"> - <structure type="chrome_scaled_image" name="IDR_OMNIBOX_CALCULATOR_ROUND" file="common/calculator_round_24.png" /> <structure type="chrome_scaled_image" name="IDR_OMNIBOX_TRANSLATION_ROUND" file="common/translate_round_32.png" /> </if> <structure type="chrome_scaled_image" name="IDR_PLUGINS_FAVICON" file="common/favicon_extensions.png" />
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index da54c19f..d201a5383 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1535,8 +1535,8 @@ "signin/investigator_dependency_provider.h", "signin/local_auth.cc", "signin/local_auth.h", - "signin/profile_oauth2_token_service_builder.cc", - "signin/profile_oauth2_token_service_builder.h", + "signin/profile_oauth2_token_service_factory.cc", + "signin/profile_oauth2_token_service_factory.h", "signin/signin_error_controller_factory.cc", "signin/signin_error_controller_factory.h", "signin/signin_profile_attributes_updater.cc", @@ -1970,7 +1970,8 @@ "//components/undo", "//components/unified_consent", "//components/update_client", - "//components/update_client:common_impl", + "//components/update_client:patch_impl", + "//components/update_client:unzip_impl", "//components/upload_list", "//components/url_formatter", "//components/url_formatter/top_domains:top500_domains",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 0f500e9..75e297a 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS
@@ -26,6 +26,7 @@ # Use identity_manager.h instead of the below files; # see https://groups.google.com/a/chromium.org/d/msg/chromium-dev/dgFLuxqZt1o/iEqkyoQQBwAJ for help and info. "!components/signin/core/browser/fake_profile_oauth2_token_service.h", + "!components/signin/core/browser/profile_oauth2_token_service.h", "!components/signin/core/browser/signin_manager.h", "!components/signin/core/browser/signin_manager_base.h", "+content/public/browser",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index b44d5f6..a09a044 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -106,7 +106,6 @@ #include "content/public/common/buildflags.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" -#include "content/public/common/feature_h264_with_openh264_ffmpeg.h" #include "device/base/features.h" #include "device/fido/features.h" #include "device/vr/buildflags/buildflags.h" @@ -1351,14 +1350,6 @@ flag_descriptions::kEnableAppListSearchAutocompleteName, flag_descriptions::kEnableAppListSearchAutocompleteDescription, kOsCrOS, FEATURE_VALUE_TYPE(app_list_features::kEnableAppListSearchAutocomplete)}, - { - "enable-pinch", - flag_descriptions::kPinchScaleName, - flag_descriptions::kPinchScaleDescription, - kOsLinux | kOsWin | kOsCrOS, - ENABLE_DISABLE_VALUE_TYPE(switches::kEnablePinch, - switches::kDisablePinch), - }, {"enable-video-player-chromecast-support", flag_descriptions::kVideoPlayerChromecastSupportName, flag_descriptions::kVideoPlayerChromecastSupportDescription, kOsCrOS,
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index 2836e40..033992fcb 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -622,7 +622,14 @@ auto jdetails = Java_AssistantDetails_create( env, base::android::ConvertUTF8ToJavaString(env, proto.title()), base::android::ConvertUTF8ToJavaString(env, proto.image_url()), - proto.allow_image_clickthrough(), proto.show_image_placeholder(), + proto.image_clickthrough_data().allow_clickthrough(), + base::android::ConvertUTF8ToJavaString( + env, proto.image_clickthrough_data().description()), + base::android::ConvertUTF8ToJavaString( + env, proto.image_clickthrough_data().positive_text()), + base::android::ConvertUTF8ToJavaString( + env, proto.image_clickthrough_data().negative_text()), + proto.show_image_placeholder(), base::android::ConvertUTF8ToJavaString(env, proto.total_price_label()), base::android::ConvertUTF8ToJavaString(env, proto.total_price()), base::android::ConvertUTF8ToJavaString(env, details->GetDatetime()),
diff --git a/chrome/browser/android/compositor/layer/tab_handle_layer.cc b/chrome/browser/android/compositor/layer/tab_handle_layer.cc index d4dcff1..35f95ee 100644 --- a/chrome/browser/android/compositor/layer/tab_handle_layer.cc +++ b/chrome/browser/android/compositor/layer/tab_handle_layer.cc
@@ -23,21 +23,23 @@ return base::WrapRefCounted(new TabHandleLayer(layer_title_cache)); } -void TabHandleLayer::SetProperties(int id, - ui::Resource* close_button_resource, - ui::NinePatchResource* tab_handle_resource, - bool foreground, - bool close_pressed, - float toolbar_width, - float x, - float y, - float width, - float height, - float content_offset_x, - float close_button_alpha, - bool is_loading, - float spinner_rotation, - float brightness) { +void TabHandleLayer::SetProperties( + int id, + ui::Resource* close_button_resource, + ui::NinePatchResource* tab_handle_resource, + ui::NinePatchResource* tab_handle_outline_resource, + bool foreground, + bool close_pressed, + float toolbar_width, + float x, + float y, + float width, + float height, + float content_offset_x, + float close_button_alpha, + bool is_loading, + float spinner_rotation, + float brightness) { if (brightness != brightness_ || foreground != foreground_) { brightness_ = brightness; foreground_ = foreground; @@ -84,7 +86,7 @@ if (title_layer) { title_layer->setOpacity(1.0f); - unsigned expected_children = 3; + unsigned expected_children = 4; title_layer_ = title_layer->layer(); if (layer_->children().size() < expected_children) { layer_->AddChild(title_layer_); @@ -106,10 +108,21 @@ decoration_tab_->SetBorder( tab_handle_resource->Border(decoration_tab_->bounds())); - if (foreground_) + tab_outline_->SetUIResourceId( + tab_handle_outline_resource->ui_resource()->id()); + tab_outline_->SetAperture(tab_handle_outline_resource->aperture()); + tab_outline_->SetFillCenter(true); + tab_outline_->SetBounds(tab_bounds); + tab_outline_->SetBorder( + tab_handle_outline_resource->Border(tab_outline_->bounds())); + + if (foreground_) { decoration_tab_->SetPosition(gfx::PointF(original_x, original_y)); - else + tab_outline_->SetPosition(gfx::PointF(original_x, original_y)); + } else { decoration_tab_->SetPosition(gfx::PointF(0, 0)); + tab_outline_->SetPosition(gfx::PointF(0, 0)); + } close_button_->SetUIResourceId(close_button_resource->ui_resource()->id()); close_button_->SetBounds(close_button_resource->size()); @@ -166,10 +179,13 @@ layer_(cc::Layer::Create()), close_button_(cc::UIResourceLayer::Create()), decoration_tab_(cc::NinePatchLayer::Create()), + tab_outline_(cc::NinePatchLayer::Create()), brightness_(1.0f), foreground_(false) { decoration_tab_->SetIsDrawable(true); + tab_outline_->SetIsDrawable(true); layer_->AddChild(decoration_tab_); + layer_->AddChild(tab_outline_); layer_->AddChild(close_button_); }
diff --git a/chrome/browser/android/compositor/layer/tab_handle_layer.h b/chrome/browser/android/compositor/layer/tab_handle_layer.h index b2fd819f..e606bed1 100644 --- a/chrome/browser/android/compositor/layer/tab_handle_layer.h +++ b/chrome/browser/android/compositor/layer/tab_handle_layer.h
@@ -35,6 +35,7 @@ void SetProperties(int id, ui::Resource* close_button_resource, ui::NinePatchResource* tab_handle_resource, + ui::NinePatchResource* tab_handle_outline_resource, bool foreground, bool close_pressed, float toolbar_width, @@ -59,6 +60,7 @@ scoped_refptr<cc::Layer> layer_; scoped_refptr<cc::UIResourceLayer> close_button_; scoped_refptr<cc::NinePatchLayer> decoration_tab_; + scoped_refptr<cc::NinePatchLayer> tab_outline_; scoped_refptr<cc::Layer> title_layer_; float brightness_;
diff --git a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc index 1fc0d6a..422c578 100644 --- a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc +++ b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
@@ -271,6 +271,10 @@ jint id, jint close_resource_id, jint handle_resource_id, + jint handle_outline_resource_id, + jint close_tint, + jint handle_tint, + jint handle_outline_tint, jboolean foreground, jboolean close_pressed, jfloat toolbar_width, @@ -290,14 +294,19 @@ ui::ResourceManagerImpl::FromJavaObject(jresource_manager); scoped_refptr<TabHandleLayer> layer = GetNextLayer(layer_title_cache); ui::NinePatchResource* tab_handle_resource = - ui::NinePatchResource::From(resource_manager->GetResource( - ui::ANDROID_RESOURCE_TYPE_STATIC, handle_resource_id)); - ui::Resource* close_button_resource = resource_manager->GetResource( - ui::ANDROID_RESOURCE_TYPE_STATIC, close_resource_id); + ui::NinePatchResource::From(resource_manager->GetStaticResourceWithTint( + handle_resource_id, handle_tint)); + ui::NinePatchResource* tab_handle_outline_resource = + ui::NinePatchResource::From(resource_manager->GetStaticResourceWithTint( + handle_outline_resource_id, handle_outline_tint)); + ui::Resource* close_button_resource = + resource_manager->GetStaticResourceWithTint(close_resource_id, + close_tint); layer->SetProperties(id, close_button_resource, tab_handle_resource, - foreground, close_pressed, toolbar_width, x, y, width, - height, content_offset_x, close_button_alpha, is_loading, - spinner_rotation, background_tab_brightness_); + tab_handle_outline_resource, foreground, close_pressed, + toolbar_width, x, y, width, height, content_offset_x, + close_button_alpha, is_loading, spinner_rotation, + background_tab_brightness_); } scoped_refptr<TabHandleLayer> TabStripSceneLayer::GetNextLayer(
diff --git a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h index 6562baa..76beab96 100644 --- a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h +++ b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h
@@ -96,6 +96,10 @@ jint id, jint close_resource_id, jint handle_resource_id, + jint handle_outline_resource_id, + jint close_tint, + jint handle_tint, + jint handle_outline_tint, jboolean foreground, jboolean close_pressed, jfloat toolbar_width,
diff --git a/chrome/browser/android/vr/gvr_keyboard_delegate.cc b/chrome/browser/android/vr/gvr_keyboard_delegate.cc index fa28bcb..26212e2 100644 --- a/chrome/browser/android/vr/gvr_keyboard_delegate.cc +++ b/chrome/browser/android/vr/gvr_keyboard_delegate.cc
@@ -158,11 +158,22 @@ void GvrKeyboardDelegate::UpdateInput(const TextInputInfo& info) { cached_text_input_info_ = info; - gvr_keyboard_set_text(gvr_keyboard_, base::UTF16ToUTF8(info.text).c_str()); - gvr_keyboard_set_selection_indices(gvr_keyboard_, info.selection_start, - info.selection_end); - gvr_keyboard_set_composing_indices(gvr_keyboard_, info.composition_start, - info.composition_end); + + // Gvr doesn't like inverted selections, so un-invert them for Gvr. + if (cached_text_input_info_.selection_start > + cached_text_input_info_.selection_end) { + std::swap(cached_text_input_info_.selection_start, + cached_text_input_info_.selection_end); + } + + gvr_keyboard_set_text( + gvr_keyboard_, base::UTF16ToUTF8(cached_text_input_info_.text).c_str()); + gvr_keyboard_set_selection_indices(gvr_keyboard_, + cached_text_input_info_.selection_start, + cached_text_input_info_.selection_end); + gvr_keyboard_set_composing_indices(gvr_keyboard_, + cached_text_input_info_.composition_start, + cached_text_input_info_.composition_end); pause_keyboard_update_ = false; }
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 87b10e7..50d0d4e 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -455,7 +455,6 @@ <include name="IDR_POLICY_JS" file="resources\policy\policy.js" type="BINDATA" compress="gzip" /> <if expr="not is_android"> <include name="IDR_MANAGEMENT_HTML" file="resources\management\management.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" /> - <include name="IDR_MANAGEMENT_JS" file="resources\management\management.js" type="BINDATA" compress="gzip" /> <include name="IDR_MANAGEMENT_UI_HTML" file="resources\management\management_ui.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" /> <include name="IDR_MANAGEMENT_UI_JS" file="resources\management\management_ui.js" type="BINDATA" compress="gzip" preprocess="true" /> <include name="IDR_MANAGEMENT_BROWSER_PROXY_HTML" file="resources\management\management_browser_proxy.html" allowexternalscript="true" type="BINDATA" compress="gzip" />
diff --git a/chrome/browser/browser_switcher/bho/BUILD.gn b/chrome/browser/browser_switcher/bho/BUILD.gn new file mode 100644 index 0000000..beeeaec --- /dev/null +++ b/chrome/browser/browser_switcher/bho/BUILD.gn
@@ -0,0 +1,35 @@ +# Copyright 2019 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. + +import("//build/toolchain/win/midl.gni") + +assert(is_win) + +shared_library("browser_switcher_bho") { + # TODO(nicolaso): Reduce binary size as much as possible. + # + # TODO(nicolaso): Use ie_bho.def and ie_bho.rc. + # + # TODO(nicolaso): avoid code duplication, by using BrowserSwitcherSitelist and + # AlternativeBrowserDriver classes from chrome/browser_switcher/. + sources = [ + "//base/win/atl.h", + "bho.cc", + "bho.h", + "browser_switcher_core.cc", + "browser_switcher_core.h", + "logging.cc", + "logging.h", + "resource.h", + ] + deps = [ + ":ie_bho_idl", + ] +} + +midl("ie_bho_idl") { + sources = [ + "ie_bho_idl.idl", + ] +}
diff --git a/chrome/browser/browser_switcher/bho/bho.cc b/chrome/browser/browser_switcher/bho/bho.cc new file mode 100644 index 0000000..d3ecb49 --- /dev/null +++ b/chrome/browser/browser_switcher/bho/bho.cc
@@ -0,0 +1,105 @@ +// Copyright 2019 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 "chrome/browser/browser_switcher/bho/bho.h" + +#include <atlstr.h> +#include <initguid.h> +#include <time.h> +#include <wininet.h> + +#include "chrome/browser/browser_switcher/bho/logging.h" + +// Declare this GUID for Windows 8 Enhanced Protected Mode Compatibility. +// This is defined in newer SDK versions but since we need XP support we can't +// use them. +DEFINE_GUID(CATID_AppContainerCompatible, + 0x59fb2056, + 0xd625, + 0x48d0, + 0xa9, + 0x44, + 0x1a, + 0x85, + 0xb5, + 0xab, + 0x26, + 0x40); + +namespace { +const wchar_t kHttpPrefix[] = L"http://"; +const wchar_t kHttpsPrefix[] = L"https://"; +const wchar_t kFilePrefix[] = L"file://"; +} // namespace + +CBrowserSwitcherBHO::CBrowserSwitcherBHO() = default; + +CBrowserSwitcherBHO::~CBrowserSwitcherBHO() = default; + +// Implementation of IObjectWithSiteImpl::SetSite. +STDMETHODIMP CBrowserSwitcherBHO::SetSite(IUnknown* site) { + if (site != NULL) { + HRESULT hr = site->QueryInterface(IID_IWebBrowser2, + reinterpret_cast<void**>(&web_browser_)); + if (SUCCEEDED(hr)) { + hr = DispEventAdvise(web_browser_); + advised_ = true; + } + } else { // site == NULL + if (advised_) { + DispEventUnadvise(web_browser_); + advised_ = false; + } + web_browser_.Release(); + } + return IObjectWithSiteImpl<CBrowserSwitcherBHO>::SetSite(site); +} + +// If enabled, monitors navigations and redirects them to Chrome if they are +// not intended to happen in IE according to the Legacy Browser Support policy. +// This only applies to top-level documents (not to frames). +void STDMETHODCALLTYPE +CBrowserSwitcherBHO::BeforeNavigate(IDispatch* disp, + VARIANT* url, + VARIANT* flags, + VARIANT* target_frame_name, + VARIANT* post_data, + VARIANT* headers, + VARIANT_BOOL* cancel) { + if (web_browser_ != NULL && disp != NULL) { + ATL::CComPtr<IUnknown> unknown1; + ATL::CComPtr<IUnknown> unknown2; + if (SUCCEEDED(web_browser_->QueryInterface( + IID_IUnknown, reinterpret_cast<void**>(&unknown1))) && + SUCCEEDED(disp->QueryInterface(IID_IUnknown, + reinterpret_cast<void**>(&unknown2)))) { + // check if this is the outter frame. + if (unknown1 == unknown2) { + bool result = + CheckUrl((LPOLESTR)url->bstrVal, *cancel != VARIANT_FALSE); + if (result) + web_browser_->Quit(); + *cancel = result ? VARIANT_TRUE : VARIANT_FALSE; + } + } + } +} + +// Checks if an url should be loaded in IE or forwarded to the default browser. +bool CBrowserSwitcherBHO::CheckUrl(LPOLESTR url, bool cancel) { + // Only verify the url if it is http[s] link. + if ((!_wcsnicmp(url, kHttpPrefix, wcslen(kHttpPrefix)) || + !_wcsnicmp(url, kHttpsPrefix, wcslen(kHttpsPrefix)) || + !_wcsnicmp(url, kFilePrefix, wcslen(kFilePrefix))) && + !browser_switcher_.ShouldOpenInAlternativeBrowser(url)) { + LOG(INFO) << "\tTriggering redirect" << std::endl; + if (!browser_switcher_.InvokeChrome(url)) { + LOG(ERR) << "Could not invoke alternative browser! " + << "Will resume loading in IE!" << std::endl; + } else { + cancel = true; + } + } + return cancel; +}
diff --git a/chrome/browser/browser_switcher/bho/bho.h b/chrome/browser/browser_switcher/bho/bho.h new file mode 100644 index 0000000..bb792fe --- /dev/null +++ b/chrome/browser/browser_switcher/bho/bho.h
@@ -0,0 +1,103 @@ +// Copyright 2019 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 CHROME_BROWSER_BROWSER_SWITCHER_BHO_BHO_H_ +#define CHROME_BROWSER_BROWSER_SWITCHER_BHO_BHO_H_ + +#include "base/win/atl.h" + +#include <exdispid.h> // NOLINT(build/include_order) +#include <shlguid.h> // NOLINT(build/include_order) +#include <shlobj.h> // NOLINT(build/include_order) + +#include "chrome/browser/browser_switcher/bho/browser_switcher_core.h" +#include "chrome/browser/browser_switcher/bho/ie_bho_idl.h" +#include "chrome/browser/browser_switcher/bho/resource.h" + +DEFINE_GUID(CATID_AppContainerCompatible, + 0x59fb2056, + 0xd625, + 0x48d0, + 0xa9, + 0x44, + 0x1a, + 0x85, + 0xb5, + 0xab, + 0x26, + 0x40); + +// Once loaded, this BHO ensures that any url that is not meant for IE is opened +// in the default browser. +class ATL_NO_VTABLE CBrowserSwitcherBHO + : public ATL::CComObjectRootEx<ATL::CComSingleThreadModel>, + public ATL::CComCoClass<CBrowserSwitcherBHO, &CLSID_BrowserSwitcherBHO>, + public ATL::IObjectWithSiteImpl<CBrowserSwitcherBHO>, + public ATL::IDispatchImpl<IBrowserSwitcherBHO, + &IID_IBrowserSwitcherBHO, + &LIBID_BrowserSwitcherLib, + 1, + 0>, + public ATL::IDispEventImpl<1, + CBrowserSwitcherBHO, + &DIID_DWebBrowserEvents2, + &LIBID_SHDocVw, + 1, + 1> { + public: + CBrowserSwitcherBHO(); + ~CBrowserSwitcherBHO() override; + + STDMETHOD(SetSite)(IUnknown* site); + + DECLARE_REGISTRY_RESOURCEID(IDR_BROWSERSWITCHERBHO) + + BEGIN_CATEGORY_MAP(CBrowserSwitcherBHO) + IMPLEMENTED_CATEGORY(CATID_AppContainerCompatible) + END_CATEGORY_MAP() + + BEGIN_COM_MAP(CBrowserSwitcherBHO) + COM_INTERFACE_ENTRY(IBrowserSwitcherBHO) + COM_INTERFACE_ENTRY(IDispatch) + COM_INTERFACE_ENTRY(IObjectWithSite) + END_COM_MAP() + + BEGIN_SINK_MAP(CBrowserSwitcherBHO) + SINK_ENTRY_EX(1, + DIID_DWebBrowserEvents2, + DISPID_BEFORENAVIGATE2, + &CBrowserSwitcherBHO::BeforeNavigate) + END_SINK_MAP() + + void STDMETHODCALLTYPE BeforeNavigate(IDispatch* disp, + VARIANT* url, + VARIANT* flags, + VARIANT* target_frame_name, + VARIANT* post_data, + VARIANT* headers, + VARIANT_BOOL* cancel); + + private: + bool CheckUrl(LPOLESTR url, bool cancel); + + ATL::CComPtr<IWebBrowser2> web_browser_; + bool advised_; + + BrowserSwitcherCore browser_switcher_; +}; + +// OBJECT_ENTRY_AUTO() contains an extra semicolon that causes compilation to +// fail. +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wextra-semi" +#endif + +OBJECT_ENTRY_AUTO(__uuidof(BrowserSwitcherBHO), CBrowserSwitcherBHO) + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + +#endif // CHROME_BROWSER_BROWSER_SWITCHER_BHO_BHO_H_
diff --git a/chrome/browser/browser_switcher/bho/bho.rgs b/chrome/browser/browser_switcher/bho/bho.rgs new file mode 100644 index 0000000..829994c4 --- /dev/null +++ b/chrome/browser/browser_switcher/bho/bho.rgs
@@ -0,0 +1,42 @@ +HKCR { + browser_switcher_bho.BrowserSwitcherBHO.1 = s 'BrowserSwitcherBHO Class' { + CLSID = s '{08B5789A-BD8E-4DAE-85DF-EF792C658B86}' + } + browser_switcher_bho.BrowserSwitcherBHO = s 'BrowserSwitcherBHO Class' { + CLSID = s '{08B5789A-BD8E-4DAE-85DF-EF792C658B86}' + CurVer = s 'browser_switcher_bho.BrowserSwitcherBHO.1' + } + NoRemove CLSID { + ForceRemove {08B5789A-BD8E-4DAE-85DF-EF792C658B86} = s 'Browser Switcher BHO' { + ProgID = s 'browser_switcher_bho.BrowserSwitcherBHO.1' + VersionIndependentProgID = s 'browser_switcher_bho.BrowserSwitcherBHO' + ForceRemove 'Programmable' + InprocServer32 = s '%MODULE%' { + val ThreadingModel = s 'Apartment' + } + 'TypeLib' = s '{E042FD04-3D7E-4A3A-9B9E-D4D9C70B4484}' + 'Implemented Categories' = s '' { + {59fb2056-d625-48d0-a944-1a85b5ab2640} = s '' { + } + } + } + } +} + +HKLM { + NoRemove SOFTWARE { + NoRemove Microsoft { + NoRemove Windows { + NoRemove CurrentVersion { + NoRemove Explorer { + NoRemove 'Browser Helper Objects' { + ForceRemove '{08B5789A-BD8E-4DAE-85DF-EF792C658B86}' = s 'Browser Switcher BHO' { + val 'NoExplorer' = d '1' + } + } + } + } + } + } + } +}
diff --git a/chrome/browser/browser_switcher/bho/browser_switcher.rgs b/chrome/browser/browser_switcher/bho/browser_switcher.rgs new file mode 100644 index 0000000..a257d12 --- /dev/null +++ b/chrome/browser/browser_switcher/bho/browser_switcher.rgs
@@ -0,0 +1,8 @@ +HKCR { + NoRemove AppID { + '%APPID%' = s 'browser_switcher_bho' + 'browser_switcher_bho.dll' { + val AppID = s '%APPID%' + } + } +}
diff --git a/chrome/browser/browser_switcher/bho/browser_switcher_core.cc b/chrome/browser/browser_switcher/bho/browser_switcher_core.cc new file mode 100644 index 0000000..ece81d4 --- /dev/null +++ b/chrome/browser/browser_switcher/bho/browser_switcher_core.cc
@@ -0,0 +1,645 @@ +// Copyright 2019 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 "chrome/browser/browser_switcher/bho/browser_switcher_core.h" + +#include <Shellapi.h> +#include <ShlObj.h> +#include <WinInet.h> + +#include <algorithm> +#include <codecvt> +#include <fstream> +#include <memory> +#include <string> +#include <vector> + +#include "chrome/browser/browser_switcher/bho/logging.h" + +namespace { + +const wchar_t kChromeKey[] = + L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe"; + +const wchar_t kChromeVarName[] = L"${chrome}"; +const wchar_t kUrlVarName[] = L"${url}"; + +const wchar_t kWildcardUrl[] = L"*"; + +const int kMinSupportedFileVersion = 1; +const int kCurrentFileVersion = 1; + +const size_t kMaxUrlFilterSize = 10000; + +// Reads a line from a file and returns true on success and false otherwise. +bool ReadLineFromFile(std::wifstream* stream, std::wstring* line) { + if (stream->eof()) + return false; + std::getline(*stream, *line); + if (stream->fail()) + return false; + return true; +} + +// Checks if the omitted prefix for a non-fully specified prefix rule is one of +// the expected parts that are allowed to be omitted. +bool IsValidPrefix(const std::wstring& prefix) { + return (prefix == L"https://") || (prefix == L"https:") || + (prefix == L"http://") || (prefix == L"http:") || + (prefix == L"file://") || (prefix == L"file:"); +} + +} // namespace + +BrowserSwitcherCore::BrowserSwitcherCore() { + Initialize(); +} + +BrowserSwitcherCore::~BrowserSwitcherCore() { + ::CloseHandle(site_list_mutex_); +} + +bool BrowserSwitcherCore::InvokeChrome(const std::wstring& url) const { + std::wstring command_line = CompileCommandLine(GetChromeParameters(), url); + HINSTANCE browser_instance = + ::ShellExecute(NULL, NULL, chrome_path_.c_str(), command_line.c_str(), + NULL, SW_SHOWNORMAL); + if (reinterpret_cast<int>(browser_instance) <= 32) { + LOG(ERR) << "Could not start Chrome! Handle: " << browser_instance << " " + << ::GetLastError() << std::endl; + return false; + } + return true; +} + +void BrowserSwitcherCore::SetChromePath(const std::wstring& path) { + chrome_path_ = path; + if (chrome_path_.empty() || chrome_path_.compare(kChromeVarName) == 0) + chrome_path_ = GetBrowserLocation(kChromeKey); + chrome_path_ = ExpandEnvironmentVariables(chrome_path_); +} + +const std::wstring& BrowserSwitcherCore::GetChromePath() const { + return chrome_path_; +} + +void BrowserSwitcherCore::SetChromeParameters(const std::wstring& parameters) { + chrome_parameters_ = parameters; + chrome_parameters_ = ExpandEnvironmentVariables(chrome_parameters_); +} + +const std::wstring& BrowserSwitcherCore::GetChromeParameters() const { + return chrome_parameters_; +} + +const BrowserSwitcherCore::UrlList& BrowserSwitcherCore::GetUrlsToRedirect() + const { + return urls_to_redirect_; +} + +void BrowserSwitcherCore::SetUrlsToRedirect(const UrlList& urls) { + urls_to_redirect_ = urls; + ProcessUrlList(&urls_to_redirect_, &urls_to_redirect_type_); +} + +const BrowserSwitcherCore::UrlList& BrowserSwitcherCore::GetUrlGreylist() + const { + return url_greylist_; +} + +void BrowserSwitcherCore::SetUrlGreylist(const UrlList& urls) { + url_greylist_ = urls; + ProcessUrlList(&url_greylist_, &url_greylist_type_); +} + +bool BrowserSwitcherCore::GetIESiteList( + BrowserSwitcherCore::UrlList* list) const { + // Wait for max 1s to avoid blocking the caller indefinetely. + if (site_list_mutex_ && + ::WaitForSingleObject(site_list_mutex_, 1000) == WAIT_OBJECT_0) { + *list = urls_from_site_list_; + ::ReleaseMutex(site_list_mutex_); + return true; + } + return false; +} + +void BrowserSwitcherCore::SetIESiteList(const UrlList& urls) { + urls_from_site_list_ = urls; + ProcessUrlList(&urls_from_site_list_, &urls_from_site_list_type_); +} + +void BrowserSwitcherCore::ProcessUrlList(UrlList* list, + UrlListTypes* types) const { + // Sort will push negative entries first because those should have higher + // priority. + std::sort(list->begin(), list->end()); + types->resize(list->size()); + for (size_t i = 0; i < list->size(); ++i) { + if ((*list)[i].compare(kWildcardUrl) == 0) { + (*types)[i] = WILDCARD; + continue; + } + + if ((*list)[i].find('/') != (*list)[i].npos) + (*types)[i] = PREFIX; + else + (*types)[i] = HOST; + + if ((*list)[i].find('!') == 0) + (*types)[i] = ((*types)[i] == HOST ? NEGATED_HOST : NEGATED_PREFIX); + } +} + +// static +void BrowserSwitcherCore::IsRuleMatching(const std::wstring& url, + const std::wstring& hostname, + const UrlListEntryType& rule_type, + const std::wstring& rule_entry, + TransitionDecision* decision, + bool* all_in_alternative_browser) { + // Employ a simple, yet powerful heuristic on the entries in the list: + // If the entry has no slashes it is assumed to be a host name or substring of + // one. In that case we match only the host part of the url to the entry. If + // on the other hand we have at least one slash in the string it is assumed to + // be a proper url prefix like "http://example.com/somepath". In this case we + // compare the beginning whole url with the list entry (up to a few allowed + // prefixes that can be omitted (see |IsValidPrefix|). Lastly if the entry + // starts with a '!' we negate the check. An entry consisting of only '*' + // means all should be opened in the alternative browser except the negated + // ones. + switch (rule_type) { + case HOST: + if (hostname.find(rule_entry) != hostname.npos) + *decision = ALT_BROWSER; + break; + case PREFIX: { + size_t pos = url.find(rule_entry); + if (pos == 0) { + *decision = ALT_BROWSER; + } else if (pos != url.npos) { + const std::wstring prefix = url.substr(0, pos); + if (IsValidPrefix(prefix)) { + *decision = ALT_BROWSER; + } + } + break; + } + case NEGATED_HOST: + if (hostname.find(rule_entry.substr(1)) != hostname.npos) + *decision = CHROME; + break; + case NEGATED_PREFIX: { + size_t pos = url.find(rule_entry.substr(1)); + if (pos == 0) { + *decision = CHROME; + } else if (pos != url.npos) { + const std::wstring prefix = url.substr(0, pos); + if (IsValidPrefix(prefix)) { + *decision = CHROME; + } + } + break; + } + case WILDCARD: + *all_in_alternative_browser = true; + break; + } +} + +bool BrowserSwitcherCore::ShouldOpenInAlternativeBrowser( + const std::wstring& url) { + TransitionDecision decision = NONE; + + // Since we can not decide in this case we should assume it is ok to use the + // alternative browser. + if (!HasValidConfiguration()) + return true; + // In case the url cracking fails at least compare the whole url. + std::wstring hostname = url; + + URL_COMPONENTS parsed_url; + memset(&parsed_url, 0, sizeof(parsed_url)); + parsed_url.dwStructSize = sizeof(parsed_url); + parsed_url.dwHostNameLength = static_cast<DWORD>(-1); + parsed_url.dwSchemeLength = static_cast<DWORD>(-1); + parsed_url.dwUrlPathLength = static_cast<DWORD>(-1); + parsed_url.dwExtraInfoLength = static_cast<DWORD>(-1); + if (InternetCrackUrl(url.c_str(), 0, 0, &parsed_url)) + hostname.assign(parsed_url.lpszHostName, parsed_url.dwHostNameLength); + else + LOG(ERR) << "URL Parsing failed!" << std::endl; + + bool all_in_alternative_browser = false; + std::wstring decision_rule; + for (size_t i = 0; i < urls_to_redirect_.size(); ++i) { + TransitionDecision single_decision = NONE; + bool single_all_in_alt_browser = false; + IsRuleMatching(url, hostname, urls_to_redirect_type_[i], + urls_to_redirect_[i], &single_decision, + &single_all_in_alt_browser); + if (single_decision != NONE || single_all_in_alt_browser) { + if (decision_rule.length() < urls_to_redirect_[i].length()) { + decision_rule = urls_to_redirect_[i]; + decision = single_decision; + all_in_alternative_browser = single_all_in_alt_browser; + } + } + } + + // Since the gray list can only contribute to staying in the alt and the + // internal list is higher prio than site list, if there is a decision exit. + if (decision == ALT_BROWSER || all_in_alternative_browser) + return true; + + if (decision == NONE && site_list_mutex_) { + if (::WaitForSingleObject(site_list_mutex_, 500) == WAIT_OBJECT_0) { + for (size_t i = 0; i < urls_from_site_list_.size(); ++i) { + TransitionDecision single_decision = NONE; + bool single_all_in_alt_browser = false; + IsRuleMatching(url, hostname, urls_from_site_list_type_[i], + urls_from_site_list_[i], &single_decision, + &single_all_in_alt_browser); + if (single_decision != NONE || single_all_in_alt_browser) { + if (decision_rule.length() < urls_from_site_list_[i].length()) { + decision_rule = urls_from_site_list_[i]; + decision = single_decision; + all_in_alternative_browser = single_all_in_alt_browser; + } + } + } + ::ReleaseMutex(site_list_mutex_); + + if (decision == ALT_BROWSER) + return true; + } + } + + for (size_t i = 0; i < url_greylist_.size(); ++i) { + // See comments on the matching behavior above. + switch (url_greylist_type_[i]) { + case HOST: + // Pick the greylist decision over the other one if it is more precise. + if (hostname.find(url_greylist_[i]) != hostname.npos) { + if (decision == NONE || + url_greylist_[i].length() > decision_rule.length()) { + return true; + } + } + break; + case PREFIX: { + // Pick the greylist decision over the other one if it is more precise. + const size_t pos = url.find(url_greylist_[i]); + if (pos == 0 || + (pos != url.npos && IsValidPrefix(url.substr(0, pos)))) { + if (decision == NONE || + url_greylist_[i].length() > decision_rule.length()) { + return true; + } + } + break; + } + // Negative entries have no meaning in the greylist. + case NEGATED_HOST: + case NEGATED_PREFIX: + break; + case WILDCARD: + all_in_alternative_browser = true; + break; + } + } + + if (decision != NONE) + return decision == ALT_BROWSER; + return all_in_alternative_browser; +} + +void BrowserSwitcherCore::Initialize() { + chrome_path_ = GetBrowserLocation(kChromeKey); + configuration_valid_ = false; + if (!LoadConfigFile()) + LOG(ERR) << "Confing file could not be loaded!" << std::endl; + if (!LoadIESiteListCache()) + LOG(INFO) << "No IE Site List found or file can't be read." << std::endl; + + site_list_mutex_ = ::CreateMutex(NULL, FALSE, NULL); + if (!site_list_mutex_) { + LOG(ERR) << "Could not create mutex object for IE Site List thread. " + << "Site list will not get updated at this run." << std::endl; + } +} + +bool BrowserSwitcherCore::LoadConfigFile() { + std::wstring path_string = GetConfigFileLocation(); + // Protect against failed config file location retrieval. + if (path_string.empty()) + return false; + + LOG(INFO) << "Loading cache from : " << path_string.c_str() << std::endl; + + const std::locale wloc(std::locale::classic(), + new std::codecvt_utf8_utf16<wchar_t>); + std::wifstream config_file(path_string.c_str()); + config_file.imbue(wloc); + if (config_file.bad()) { + LOG(ERR) << "Can't open config file : " << ::GetLastError() << std::endl; + return false; + } + + int file_version = 0; + config_file >> file_version; + if (config_file.fail()) + return false; + LOG(INFO) << "file_version : '" << file_version << "'" << std::endl; + if (file_version < kMinSupportedFileVersion || + file_version > kCurrentFileVersion) { + return false; + } + std::wstring skip_to_eol; + std::getline(config_file, skip_to_eol); + + std::wstring alternative_browser_path; + if (!ReadLineFromFile(&config_file, &alternative_browser_path)) + return false; + LOG(INFO) << "alternative_browser_path : '" << alternative_browser_path + << "'" << std::endl; + std::wstring alternative_browser_parameters; + if (!ReadLineFromFile(&config_file, &alternative_browser_parameters)) + return false; + LOG(INFO) << "alternative_browser_parameters : '" + << alternative_browser_parameters << "'" << std::endl; + std::wstring chrome_path; + if (!ReadLineFromFile(&config_file, &chrome_path)) + return false; + LOG(INFO) << "chrome_path : '" << chrome_path << "'" << std::endl; + std::wstring chrome_parameters; + if (!ReadLineFromFile(&config_file, &chrome_parameters)) + return false; + LOG(INFO) << "chrome_parameters : '" << chrome_parameters << "'" << std::endl; + + size_t urls_to_load = 0; + config_file >> urls_to_load; + if (config_file.fail()) + return false; + LOG(INFO) << "url list size : '" << urls_to_load << "'" << std::endl; + if (urls_to_load > kMaxUrlFilterSize) { + return false; + } + std::getline(config_file, skip_to_eol); + + UrlList urls_to_redirect; + std::wstring url; + for (size_t i = 0; i < urls_to_load; ++i) { + if (!ReadLineFromFile(&config_file, &url)) + return false; + LOG(INFO) << "url : '" << url << "'" << std::endl; + urls_to_redirect.push_back(url); + } + + config_file >> urls_to_load; + if (config_file.fail()) + return false; + LOG(INFO) << "url grey list size : '" << urls_to_load << "'" << std::endl; + if (urls_to_load > kMaxUrlFilterSize) { + return false; + } + std::getline(config_file, skip_to_eol); + + UrlList url_greylist; + for (size_t i = 0; i < urls_to_load; ++i) { + if (!ReadLineFromFile(&config_file, &url)) + return false; + LOG(INFO) << "url : '" << url << "'" << std::endl; + url_greylist.push_back(url); + } + + SetChromePath(chrome_path); + SetChromeParameters(chrome_parameters); + SetUrlsToRedirect(urls_to_redirect); + SetUrlGreylist(url_greylist); + configuration_valid_ = true; + return true; +} + +bool BrowserSwitcherCore::LoadIESiteListCache() { + std::wstring path_string = GetIESiteListCacheLocation(); + // Protect against failed config file location retrieval. + if (path_string.empty()) + return false; + + LOG(INFO) << "Loading IE Site List cache from : " << path_string.c_str() + << std::endl; + + const std::locale wloc(std::locale::classic(), + new std::codecvt_utf8_utf16<wchar_t>); + std::wifstream config_file(path_string.c_str()); + config_file.imbue(wloc); + if (config_file.bad()) { + LOG(ERR) << "Can't open config file : " << ::GetLastError() << std::endl; + return false; + } + + int file_version = 0; + config_file >> file_version; + if (config_file.fail()) + return false; + LOG(INFO) << "file_version : '" << file_version << "'" << std::endl; + if (file_version < kMinSupportedFileVersion || + file_version > kCurrentFileVersion) { + return false; + } + std::wstring skip_to_eol; + std::getline(config_file, skip_to_eol); + + size_t urls_to_load = 0; + config_file >> urls_to_load; + if (config_file.fail()) + return false; + LOG(INFO) << "url list size : '" << urls_to_load << "'" << std::endl; + if (urls_to_load > kMaxUrlFilterSize) { + return false; + } + std::getline(config_file, skip_to_eol); + + UrlList urls_to_redirect; + std::wstring url; + for (size_t i = 0; i < urls_to_load; ++i) { + if (!ReadLineFromFile(&config_file, &url)) + return false; + LOG(INFO) << "url : '" << url << "'" << std::endl; + urls_to_redirect.push_back(url); + } + + SetIESiteList(urls_to_redirect); + return true; +} + +bool BrowserSwitcherCore::HasValidConfiguration() const { + return configuration_valid_; +} + +void BrowserSwitcherCore::SetConfigFileLocationForTest( + const std::wstring& path) { + config_file_path_ = path; + configuration_valid_ = false; +} + +void BrowserSwitcherCore::SetIESiteListCacheLocationForTest( + const std::wstring& path) { + site_list_cache_file_path_ = path; +} + +void BrowserSwitcherCore::SetIESiteListLocationForTest( + const std::wstring& path) { + site_list_location_for_test_ = path; +} + +std::wstring BrowserSwitcherCore::CompileCommandLine( + const std::wstring& raw_command_line, + const std::wstring& url) const { + std::wstring sanitized_url; + // In almost every case should this be enough for the sanitization because + // any ASCII char will expand to at most 3 chars - %[0-9A-F][0-9A-F]. + DWORD length = static_cast<DWORD>(url.length() * 3 + 1); + std::auto_ptr<wchar_t> buffer(new wchar_t[length]); + if (!::InternetCanonicalizeUrl(url.c_str(), buffer.get(), &length, 0)) { + DWORD error = ::GetLastError(); + if (error == ERROR_INSUFFICIENT_BUFFER) { + // If we get this error it means that the buffer is too small to hold the + // canoncial url. In that case resize the buffer to what the requested + // size is (returned in |length| and try again. + buffer.reset(new wchar_t[length]); + if (::InternetCanonicalizeUrl(url.c_str(), buffer.get(), &length, 0)) { + sanitized_url = buffer.get(); + } + } + } else { + sanitized_url = buffer.get(); + } + // If the API failed, do some poor man's sanitizing at least. + if (sanitized_url.empty()) { + LOG(WARNING) << "::InternetCanonicalizeUrl failed : " << ::GetLastError() + << std::endl; + sanitized_url = SanitizeUrl(url); + } + + std::wstring command_line = raw_command_line; + size_t pos = command_line.find(kUrlVarName); + if (pos != command_line.npos) { + command_line = + command_line.replace(pos, wcslen(kUrlVarName), sanitized_url); + } else { + if (command_line.empty()) + command_line = sanitized_url; + else + command_line.append(L" ").append(sanitized_url); + } + return command_line; +} + +std::wstring BrowserSwitcherCore::SanitizeUrl(const std::wstring url) const { + // In almost every case should this be enough for the sanitization because + // any ASCII char will expand to at most 3 chars - %[0-9A-F][0-9A-F]. + std::wstring::const_iterator it = url.begin(); + std::wstring untranslated_chars(L".:/\\_-@~();"); + std::auto_ptr<wchar_t> sanitized_url(new wchar_t[url.length() * 3 + 1]); + wchar_t* output = sanitized_url.get(); + + while (it != url.end()) { + if (isalnum(*it) || untranslated_chars.find(*it) != std::wstring::npos) { + *output++ = *it; + } else { + // Will only work for ASCII chars but hey it's at least something. + // Any unicode char will be truncated to its first 8 bits and encoded. + *output++ = '%'; + int nibble = (*it & 0xf0) >> 4; + *output++ = nibble > 9 ? nibble - 10 + 'A' : nibble + '0'; + nibble = *it & 0xf; + *output++ = nibble > 9 ? nibble - 10 + 'A' : nibble + '0'; + } + it++; + } + *output = '\0'; + + return std::wstring(sanitized_url.get()); +} + +std::wstring BrowserSwitcherCore::GetConfigPath() const { + std::wstring config_path; + wchar_t path[MAX_PATH]; + if (!::SHGetSpecialFolderPath(0, path, CSIDL_LOCAL_APPDATA, false)) { + LOG(ERR) << "Error locating %LOCAL_APPDATA%!" << std::endl; + NOTREACHED(); + return config_path; + } + config_path.assign(path); + ::CreateDirectory(config_path.append(L"\\Google").c_str(), NULL); + ::CreateDirectory(config_path.append(L"\\BrowserSwitcher").c_str(), NULL); + return config_path; +} + +std::wstring BrowserSwitcherCore::GetConfigFileLocation() { + if (config_file_path_.empty()) { + config_file_path_ = GetConfigPath(); + config_file_path_.append(L"\\cache.dat"); + } + return config_file_path_; +} + +std::wstring BrowserSwitcherCore::GetIESiteListCacheLocation() { + if (site_list_cache_file_path_.empty()) { + site_list_cache_file_path_ = GetConfigPath(); + site_list_cache_file_path_.append(L"\\sitelistcache.dat"); + } + return site_list_cache_file_path_; +} + +std::wstring BrowserSwitcherCore::GetBrowserLocation( + const wchar_t* key_name) const { + HKEY key; + if (ERROR_SUCCESS != ::RegOpenKey(HKEY_LOCAL_MACHINE, key_name, &key) && + ERROR_SUCCESS != ::RegOpenKey(HKEY_CURRENT_USER, key_name, &key)) { + LOG(ERR) << "Could not open registry key " << key_name + << "! Error Code:" << ::GetLastError() << std::endl; + return std::wstring(); + } + return ReadRegValue(key, NULL); +} + +std::wstring BrowserSwitcherCore::ReadRegValue(HKEY key, + const wchar_t* name) const { + DWORD length = 0; + if (ERROR_SUCCESS != + ::RegQueryValueEx(key, name, NULL, NULL, NULL, &length)) { + LOG(ERR) << "Could not get size of the value!" << ::GetLastError() + << std::endl; + return std::wstring(); + } + std::auto_ptr<wchar_t> browser_path(new wchar_t[length]); + if (ERROR_SUCCESS != + ::RegQueryValueEx(key, name, NULL, NULL, + reinterpret_cast<LPBYTE>(browser_path.get()), + &length)) { + LOG(ERR) << "Could not get the value!" << ::GetLastError() << std::endl; + return std::wstring(); + } + + return std::wstring(browser_path.get()); +} + +std::wstring BrowserSwitcherCore::ExpandEnvironmentVariables( + const std::wstring& str) const { + std::wstring output = str; + DWORD expanded_size = 0; + expanded_size = ::ExpandEnvironmentStrings(str.c_str(), NULL, expanded_size); + if (expanded_size != 0) { + // The expected buffer length as defined in MSDN is chars + null + 1. + std::auto_ptr<wchar_t> expanded_path(new wchar_t[expanded_size + 2]); + expanded_size = ::ExpandEnvironmentStrings(str.c_str(), expanded_path.get(), + expanded_size); + if (expanded_size != 0) + output = expanded_path.get(); + } + return output; +}
diff --git a/chrome/browser/browser_switcher/bho/browser_switcher_core.h b/chrome/browser/browser_switcher/bho/browser_switcher_core.h new file mode 100644 index 0000000..37ae5be3 --- /dev/null +++ b/chrome/browser/browser_switcher/bho/browser_switcher_core.h
@@ -0,0 +1,169 @@ +// Copyright 2019 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 CHROME_BROWSER_BROWSER_SWITCHER_BHO_BROWSER_SWITCHER_CORE_H_ +#define CHROME_BROWSER_BROWSER_SWITCHER_BHO_BROWSER_SWITCHER_CORE_H_ + +#include <Windows.h> + +#include <string> +#include <vector> + +// Implements the browser switching logic for both Chrome and the alternative +// browser. +class BrowserSwitcherCore { + public: + // Defines the type of the list of domains to open in the alternative browser. + typedef std::vector<std::wstring> UrlList; + + BrowserSwitcherCore(); + virtual ~BrowserSwitcherCore(); + + // Invokes Chrome and loads |url| in it. + bool InvokeChrome(const std::wstring& url) const; + + // Setter and getter for Chrome's executable. |path| can be either a fully + // qualified path to an executable or the following variable. If this variable + // is used then it should be the only content of the parameter as it will + // resolve to the fully qualified path of the browser. + // ${chrome} - The default location of Chrome as defined in the registry. + void SetChromePath(const std::wstring& path); + const std::wstring& GetChromePath() const; + + // Setter and getter for the Chrome command line parameters. + // |parameters| can contain the following variable in which case this will be + // the position of the url to be opened, otherwise it will be appended at the + // end: + // ${url} - The location of the url parameter in the command line. + void SetChromeParameters(const std::wstring& parameters); + const std::wstring& GetChromeParameters() const; + + // Setter and getter for the list of urls to be opened in the alternative + // browser. + const UrlList& GetUrlsToRedirect() const; + void SetUrlsToRedirect(const UrlList& urls); + + // Setter and getter for the list of urls to be opened in both browsers. This + // is the set of urls that should not trigger transition. Such set might be + // required if for example there are third party authentication pages that + // need to be accessible by both legacy and normal applications. + const UrlList& GetUrlGreylist() const; + void SetUrlGreylist(const UrlList& urls); + + // Setter and getter for the list of urls to be opened in both browsers. This + // is the set of urls that should not trigger transition. Such set might be + // required if for example there are third party authentication pages that + // need to be accessible by both legacy and normal applications. + bool GetIESiteList(UrlList* list) const; + void SetIESiteList(const UrlList& urls); + + // Checks if an url should be opened in the alternative browser. Returns true + // if the hostname (or part of it) of the url is contained in the url lists. + // This function should be used by external browsers to verify if they should + // bounce back to Chrome. Chrome itself uses different logic to decide if the + // url should be opened in the external browser. + bool ShouldOpenInAlternativeBrowser(const std::wstring& url); + + // Loader for the configuration file. + bool LoadConfigFile(); + + // Loader for the site list cache file. The cache is used to speed up the + // start time of LBS since retrieving the original list might require network + // access. + bool LoadIESiteListCache(); + + // Returns true if the configuration has been loaded or saved successfully. + // Used mainly to verify the course of action in the alternative browser + // which has no direct access to policy and relies on properly loaded confi- + // guration. + bool HasValidConfiguration() const; + + private: + friend class BrowserSwitcherCoreTest; + + enum TransitionDecision { NONE, CHROME, ALT_BROWSER }; + + enum UrlListEntryType { + HOST, + PREFIX, + NEGATED_HOST, + NEGATED_PREFIX, + WILDCARD + }; + typedef std::vector<UrlListEntryType> UrlListTypes; + + // Performs initialization of the class and loads the config file. + void Initialize(); + + // Retrieves the configuration files path based on %LOCALAPPDATA%. + std::wstring GetConfigPath() const; + std::wstring GetConfigFileLocation(); + std::wstring GetIESiteListCacheLocation(); + // Used for tests only to mock the config file. + void SetConfigFileLocationForTest(const std::wstring& path); + void SetIESiteListCacheLocationForTest(const std::wstring& path); + void SetIESiteListLocationForTest(const std::wstring& path); + + // Compiles the final command line to start a browser. It will replace the + // ${url} variable with the supplied url if it is present or append the url to + // the end if the variable is not present in the command line. + // The function will also attempt to canonicalize the url to make sure it is + // not passing potentially dangerous argument to the browser. + std::wstring CompileCommandLine(const std::wstring& raw_command_line, + const std::wstring& url) const; + + // Poor man's implementation of URL sanitization, used if the call to the + // WinInet API InternetCanonicalizeUrl fails for some reason. + std::wstring SanitizeUrl(const std::wstring url) const; + + // Processes a list of url patterns creating a parallel list with the pattern + // types for each entry. This is done to speed up searching for matches when + // deciding for redirecting. + void ProcessUrlList(UrlList* list, UrlListTypes* types) const; + + // Retrieves the location of various browsers. Using the values in the + // registry under HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\. + // Returns either the executable location or an empty string if not found. + std::wstring GetBrowserLocation(const wchar_t* key_name) const; + + // Retrieves a string value from the registry stored at |key| or an empty + // string if missing. + std::wstring ReadRegValue(HKEY key, const wchar_t* name) const; + + // Expands any environment variables the input string |str| might contain. + std::wstring ExpandEnvironmentVariables(const std::wstring& str) const; + + static void IsRuleMatching(const std::wstring& url, + const std::wstring& hostname, + const UrlListEntryType& rule_type, + const std::wstring& rule_entry, + TransitionDecision* decision, + bool* all_in_alternative_browser); + + std::wstring chrome_path_; + + std::wstring chrome_parameters_; + + UrlList urls_to_redirect_; + UrlListTypes urls_to_redirect_type_; + UrlList url_greylist_; + UrlListTypes url_greylist_type_; + UrlList urls_from_site_list_; + UrlListTypes urls_from_site_list_type_; + + HANDLE site_list_mutex_; + + std::wstring config_file_path_; + std::wstring site_list_cache_file_path_; + // Tracks the validity of the cached configuration. If a load has succeeded + // once this status is flipped to true. As long as no load has been successful + // and no configuration has been set and successfully saved this status stays + // false. + bool configuration_valid_; + + // Used to override default sitelist file location for tests. + std::wstring site_list_location_for_test_; +}; + +#endif // CHROME_BROWSER_BROWSER_SWITCHER_BHO_BROWSER_SWITCHER_CORE_H_
diff --git a/chrome/browser/browser_switcher/bho/ie_bho.cc b/chrome/browser/browser_switcher/bho/ie_bho.cc new file mode 100644 index 0000000..88031b2 --- /dev/null +++ b/chrome/browser/browser_switcher/bho/ie_bho.cc
@@ -0,0 +1,110 @@ +// Copyright 2019 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. + +// Implementation of DLL Exports. + +#include <ShlObj.h> +#include <atlbase.h> + +#include "chrome/browser/browser_switcher/bho/ie_bho.h" +#include "chrome/browser/browser_switcher/bho/logging.h" +#include "chrome/browser/browser_switcher/bho/resource.h" + +class CBrowserSwitcherModule + : public ATL::CAtlDllModuleT<CBrowserSwitcherModule> { + public: + DECLARE_LIBID(LIBID_BrowserSwitcherLib) + DECLARE_REGISTRY_APPID_RESOURCEID(IDR_BROWSERSWITCHER, + "{7D7BEC19-57EE-41C9-9FEE-63A873363614}") +}; + +CBrowserSwitcherModule _AtlModule; + +// DLL Entry Point. +extern "C" BOOL WINAPI DllMain(HINSTANCE instance, + DWORD reason, + LPVOID reserved) { + switch (reason) { + case DLL_PROCESS_ATTACH: { + std::wstring log_file_path; + + OSVERSIONINFO info; + memset(&info, 0, sizeof(info)); + info.dwOSVersionInfoSize = sizeof(info); + ::GetVersionEx(&info); + if (info.dwMajorVersion >= 6) { + wchar_t* path = NULL; + // On modern Windows versions there is a special AppData folder for + // processes with lowered execution rights, however older versions lack + // this folder so be prepared to back off to the usual AppData folder. + if (S_OK != + ::SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0, NULL, &path)) { + if (S_OK != + ::SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &path)) { + break; + } + } + log_file_path = path; + ::CoTaskMemFree(path); + } else { + // Old windows version only support SHGetSpecialFolderPath. + wchar_t path[MAX_PATH]; + if (!::SHGetSpecialFolderPath(0, path, CSIDL_LOCAL_APPDATA, false)) + break; + log_file_path = path; + } + ::CreateDirectory(log_file_path.append(L"\\Google").c_str(), NULL); + ::CreateDirectory(log_file_path.append(L"\\BrowserSwitcher").c_str(), + NULL); + log_file_path.append(L"\\ie_bho_log2.txt"); + InitLog(log_file_path); + break; + } + case DLL_PROCESS_DETACH: + CloseLog(); + break; + } + + return _AtlModule.DllMain(reason, reserved); +} + +// Used to determine whether the DLL can be unloaded by OLE. +STDAPI DllCanUnloadNow(void) { + return _AtlModule.DllCanUnloadNow(); +} + +// Returns a class factory to create an object of the requested type. +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { + return _AtlModule.DllGetClassObject(rclsid, riid, ppv); +} + +// Adds entries to the system registry. +STDAPI DllRegisterServer(void) { + return _AtlModule.DllRegisterServer(); +} + +// Removes entries from the system registry. +STDAPI DllUnregisterServer(void) { + return _AtlModule.DllUnregisterServer(); +} + +// Adds/Removes entries to the system registry per user per machine. +STDAPI DllInstall(BOOL install, LPCWSTR cmdLine) { + HRESULT result = E_FAIL; + static const wchar_t user_switch[] = L"user"; + + if (cmdLine != NULL && + _wcsnicmp(cmdLine, user_switch, _countof(user_switch)) == 0) { + ATL::AtlSetPerUserRegistration(true); + } + + if (install) { + result = DllRegisterServer(); + if (FAILED(result)) + DllUnregisterServer(); + } else { + result = DllUnregisterServer(); + } + return result; +}
diff --git a/chrome/browser/browser_switcher/bho/ie_bho.def b/chrome/browser/browser_switcher/bho/ie_bho.def new file mode 100644 index 0000000..4afff8f2 --- /dev/null +++ b/chrome/browser/browser_switcher/bho/ie_bho.def
@@ -0,0 +1,14 @@ +; Copyright 2019 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. + +; Declares the module parameters. + +LIBRARY BROWSER_SWITCHER_BHO.DLL + +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + DllInstall PRIVATE \ No newline at end of file
diff --git a/chrome/browser/browser_switcher/bho/ie_bho_idl.idl b/chrome/browser/browser_switcher/bho/ie_bho_idl.idl new file mode 100644 index 0000000..f05ac069 --- /dev/null +++ b/chrome/browser/browser_switcher/bho/ie_bho_idl.idl
@@ -0,0 +1,36 @@ +// Copyright 2019 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. + +// This file will be processed by the MIDL tool to produce the type library +// and marshalling code. + +import "oaidl.idl"; +import "ocidl.idl"; + +[ + object, + uuid(68CB9FDF-5E2E-41D7-A906-EF6C58AF0429), // B0608AA2-3C43-424B-9814-5A9DFF06AABE + dual, + nonextensible, + helpstring("IBrowserSwitcherBHO Interface"), + pointer_default(unique) +] +interface IBrowserSwitcherBHO : IDispatch{ }; + +[ + uuid(E042FD04-3D7E-4A3A-9B9E-D4D9C70B4484), // F240BFEF-88DD-4F6D-9816-D32E509B929B + version(1.0), + helpstring("BrowserSwitcher 1.0 Type Library") +] +library BrowserSwitcherLib +{ + importlib("stdole2.tlb"); + [ + uuid(08B5789A-BD8E-4DAE-85DF-EF792C658B86), // 8E425EB4-ADBD-4816-B1E8-49BB9DECF034 + helpstring("BrowserSwitcherBHO Class") + ] + coclass BrowserSwitcherBHO { + [default] interface IBrowserSwitcherBHO; + }; +};
diff --git a/chrome/browser/browser_switcher/bho/logging.cc b/chrome/browser/browser_switcher/bho/logging.cc new file mode 100644 index 0000000..3728c61 --- /dev/null +++ b/chrome/browser/browser_switcher/bho/logging.cc
@@ -0,0 +1,31 @@ +// Copyright 2019 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 "chrome/browser/browser_switcher/bho/logging.h" + +#include <codecvt> +#include <iostream> + +std::wostream* gLogStream = &std::wcout; +std::wofstream gLogFileStream; +const std::locale gLocale(std::locale::classic(), + new std::codecvt_utf8_utf16<wchar_t>); + +LogLevels gLogLevel = INFO; + +// Must be called before the first logging call is made. +void InitLog(const std::wstring& file) { + gLogFileStream.open(file.c_str(), std::ios_base::out | std::ios_base::trunc); + gLogFileStream.imbue(gLocale); + gLogStream = &gLogFileStream; +} + +// Closes the log file. No more logging is possible after this call. +void CloseLog() { + gLogFileStream.close(); +} + +void SetLogLevel(LogLevels level) { + gLogLevel = level; +}
diff --git a/chrome/browser/browser_switcher/bho/logging.h b/chrome/browser/browser_switcher/bho/logging.h new file mode 100644 index 0000000..2d7a7e7 --- /dev/null +++ b/chrome/browser/browser_switcher/bho/logging.h
@@ -0,0 +1,31 @@ +// Copyright 2019 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 CHROME_BROWSER_BROWSER_SWITCHER_BHO_LOGGING_H_ +#define CHROME_BROWSER_BROWSER_SWITCHER_BHO_LOGGING_H_ + +#include <cassert> +#include <fstream> + +enum LogLevels { OFF = 0, ERR = 1, WARNING = 2, INFO = 3 }; + +extern std::wostream* gLogStream; +extern LogLevels gLogLevel; + +void InitLog(const std::wstring& file); +void CloseLog(); +void SetLogLevel(LogLevels level); + +#define INFO_MSG "[info] : " +#define WARNING_MSG "[WARN] : " +#define ERR_MSG "[*ERROR!*] : " + +#define LOG(a) \ + if (gLogLevel >= a) \ + *gLogStream << (a##_MSG) << __FILE__ << ":" << __LINE__ << " : " + +#define DCHECK(a) assert(a) +#define NOTREACHED() assert(false) + +#endif // CHROME_BROWSER_BROWSER_SWITCHER_BHO_LOGGING_H_
diff --git a/chrome/browser/browser_switcher/bho/resource.h b/chrome/browser/browser_switcher/bho/resource.h new file mode 100644 index 0000000..0d2e636 --- /dev/null +++ b/chrome/browser/browser_switcher/bho/resource.h
@@ -0,0 +1,29 @@ +// Copyright 2019 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 CHROME_BROWSER_BROWSER_SWITCHER_BHO_RESOURCE_H_ +#define CHROME_BROWSER_BROWSER_SWITCHER_BHO_RESOURCE_H_ + +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by ie_bho.rc +// +#define VS_VERSION_INFO 1 +#define IDS_PROJNAME 100 +#define IDR_BROWSERSWITCHER 101 +#define IDR_BROWSERSWITCHERBHO 102 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif + +#endif // CHROME_BROWSER_BROWSER_SWITCHER_BHO_RESOURCE_H_
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index bf46e4470..28fe0840 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -5122,7 +5122,7 @@ std::unique_ptr<content::LoginDelegate> ChromeContentBrowserClient::CreateLoginDelegate( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, const content::GlobalRequestID& request_id, bool is_request_for_main_frame,
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 5bd4858..319bd17 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -523,7 +523,7 @@ std::unique_ptr<net::ClientCertStore> CreateClientCertStore( content::ResourceContext* resource_context) override; std::unique_ptr<content::LoginDelegate> CreateLoginDelegate( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, const content::GlobalRequestID& request_id, bool is_request_for_main_frame,
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index ce9768d..5575527 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -91,6 +91,7 @@ "//chromeos/dbus:metrics_event_proto", "//chromeos/dbus:oobe_config_proto", "//chromeos/dbus:plugin_vm_service_proto", + "//chromeos/dbus/audio", "//chromeos/dbus/auth_policy", "//chromeos/dbus/auth_policy:authpolicy_proto", "//chromeos/dbus/biod",
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_app_list_browsertest.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_app_list_browsertest.cc index 9034c1af..74e73dc 100644 --- a/chrome/browser/chromeos/accessibility/spoken_feedback_app_list_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/spoken_feedback_app_list_browsertest.cc
@@ -27,7 +27,7 @@ class TestSuggestionChipResult : public app_list::TestSearchResult { public: - TestSuggestionChipResult(const base::string16& title) { + explicit TestSuggestionChipResult(const base::string16& title) { set_display_type(ash::SearchResultDisplayType::kRecommendation); set_title(title); }
diff --git a/chrome/browser/chromeos/arc/policy/OWNERS b/chrome/browser/chromeos/arc/policy/OWNERS index 9f1793d7..fdc935c 100644 --- a/chrome/browser/chromeos/arc/policy/OWNERS +++ b/chrome/browser/chromeos/arc/policy/OWNERS
@@ -1 +1,3 @@ bartfab@chromium.org + +# COMPONENT: Enterprise
diff --git a/chrome/browser/chromeos/diagnosticsd/OWNERS b/chrome/browser/chromeos/diagnosticsd/OWNERS index 8c3eff5..f301e83 100644 --- a/chrome/browser/chromeos/diagnosticsd/OWNERS +++ b/chrome/browser/chromeos/diagnosticsd/OWNERS
@@ -1,2 +1,4 @@ emaxx@chromium.org pmarko@chromium.org + +# COMPONENT: Enterprise
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.cc b/chrome/browser/chromeos/input_method/input_method_engine.cc index f084489..38b3fdc 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine.cc
@@ -133,10 +133,11 @@ private: void OnConnectionLost() { - // After the connection to |ImeEngineFactoryRegistry| is broken, notifies - // the client to reconnect through Window Service. - if (engine_client_) - engine_client_->Reconnect(); + // After the connection to |ImeEngineFactoryRegistry| is broken, break the + // connection to the client, so that the client can reconnect through Window + // Service. + engine_binding_.Close(); + engine_client_.reset(); } InputMethodEngine* engine_; @@ -369,8 +370,7 @@ uint32_t cursor_pos, bool is_visible) { if (mojo_helper_->IsConnected()) { - mojo_helper_->engine_client()->UpdateCompositionText( - composition_text, cursor_pos, is_visible); + NOTIMPLEMENTED_LOG_ONCE(); } else { ui::IMEInputContextHandlerInterface* input_context = ui::IMEBridge::Get()->GetInputContextHandler(); @@ -384,7 +384,7 @@ const std::string& text) { bool committed = false; if (mojo_helper_->IsConnected()) { - mojo_helper_->engine_client()->CommitText(text); + NOTIMPLEMENTED_LOG_ONCE(); } else { ui::IMEInputContextHandlerInterface* input_context = ui::IMEBridge::Get()->GetInputContextHandler(); @@ -407,8 +407,7 @@ int offset, size_t number_of_chars) { if (mojo_helper_->IsConnected()) { - mojo_helper_->engine_client()->DeleteSurroundingText(offset, - number_of_chars); + NOTIMPLEMENTED_LOG_ONCE(); } else { ui::IMEInputContextHandlerInterface* input_context = ui::IMEBridge::Get()->GetInputContextHandler(); @@ -430,7 +429,7 @@ bool sent = false; if (mojo_helper_->IsConnected()) { - mojo_helper_->engine_client()->SendKeyEvent(ui::Event::Clone(*event)); + NOTIMPLEMENTED_LOG_ONCE(); } else { ui::IMEInputContextHandlerInterface* input_context = ui::IMEBridge::Get()->GetInputContextHandler();
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc index 93088e8..f055275 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
@@ -187,22 +187,8 @@ return ptr; } - bool commit_text_called() const { return commit_text_called_; } - private: - // ime::mojom::ImeEngineClient: - void CommitText(const std::string& text) override { - commit_text_called_ = true; - } - void UpdateCompositionText(const ui::CompositionText& composition_text, - uint32_t cursor_pos, - bool visible) override {} - void DeleteSurroundingText(int32_t offset, uint32_t length) override {} - void SendKeyEvent(std::unique_ptr<ui::Event> key_event) override {} - void Reconnect() override {} - mojo::Binding<ime::mojom::ImeEngineClient> binding_; - bool commit_text_called_ = false; DISALLOW_COPY_AND_ASSIGN(TestImeEngineClient); }; @@ -418,12 +404,6 @@ false)); engine_ptr.FlushForTesting(); EXPECT_EQ(ACTIVATE | ONFOCUS, observer_->GetCallsBitmapAndReset()); - - int context = engine_->GetContextIdForTesting(); - std::string error; - engine_->CommitText(context, "input", &error); - engine_->FlushForTesting(); - EXPECT_TRUE(client.commit_text_called()); } } // namespace input_method
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc index 9d58db3..0dfa436 100644 --- a/chrome/browser/chromeos/login/chrome_restart_request.cc +++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -114,7 +114,6 @@ ::switches::kEnableNativeGpuMemoryBuffers, ::switches::kEnableOopRasterization, ::switches::kEnablePartialRaster, - ::switches::kEnablePinch, ::switches::kEnablePreferCompositingToLCDText, ::switches::kEnableRGBA4444Textures, ::switches::kEnableTouchDragDrop,
diff --git a/chrome/browser/chromeos/login/configuration_based_enrollment_browsertest.cc b/chrome/browser/chromeos/login/configuration_based_oobe_browsertest.cc similarity index 76% rename from chrome/browser/chromeos/login/configuration_based_enrollment_browsertest.cc rename to chrome/browser/chromeos/login/configuration_based_oobe_browsertest.cc index c2591f79..9813e94 100644 --- a/chrome/browser/chromeos/login/configuration_based_enrollment_browsertest.cc +++ b/chrome/browser/chromeos/login/configuration_based_oobe_browsertest.cc
@@ -7,8 +7,11 @@ #include "chrome/browser/chromeos/login/demo_mode/demo_setup_controller.h" #include "chrome/browser/chromeos/login/demo_mode/demo_setup_test_utils.h" #include "chrome/browser/chromeos/login/test/enrollment_helper_mixin.h" +#include "chrome/browser/chromeos/login/test/enrollment_ui_mixin.h" +#include "chrome/browser/chromeos/login/test/fake_gaia_mixin.h" #include "chrome/browser/chromeos/login/test/hid_controller_mixin.h" #include "chrome/browser/chromeos/login/test/js_checker.h" +#include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h" #include "chrome/browser/chromeos/login/test/oobe_base_test.h" #include "chrome/browser/chromeos/login/test/oobe_configuration_waiter.h" #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" @@ -31,9 +34,9 @@ // OOBE configuration for each of the tests and verify that relevant parts // of OOBE automation took place. OOBE WebUI will not be started until // LoadConfiguration() is called to allow configure relevant stubs. -class EnterpriseEnrollmentConfigurationTest : public OobeBaseTest { +class OobeConfigurationTest : public OobeBaseTest { public: - EnterpriseEnrollmentConfigurationTest() = default; + OobeConfigurationTest() = default; bool ShouldWaitForOobeUI() override { return false; } @@ -121,51 +124,52 @@ NetworkHandler::Get()->network_state_handler()->SetCheckPortalList(""); } - // Waits until specific enrollment step is displayed. - void WaitForStep(const std::string& step) { - const std::string js = - "document.getElementsByClassName('oauth-enroll-state-" + step + - "').length > 0"; - test::OobeJS().CreateWaiter(js)->Wait(); - } - protected: - test::EnrollmentHelperMixin enrollment_helper_{&mixin_host_}; - // Owned by DBusThreadManagerSetter chromeos::FakeUpdateEngineClient* fake_update_engine_client_; base::ScopedTempDir fake_policy_dir_; private: - DISALLOW_COPY_AND_ASSIGN(EnterpriseEnrollmentConfigurationTest); + DISALLOW_COPY_AND_ASSIGN(OobeConfigurationTest); }; // EnterpriseEnrollmentConfigurationTest with no input devices. -class EnterpriseEnrollmentConfigurationTestNoHID - : public EnterpriseEnrollmentConfigurationTest { +class OobeConfigurationTestNoHID : public OobeConfigurationTest { public: - EnterpriseEnrollmentConfigurationTestNoHID() = default; - - ~EnterpriseEnrollmentConfigurationTestNoHID() override = default; + OobeConfigurationTestNoHID() = default; + ~OobeConfigurationTestNoHID() override = default; protected: test::HIDControllerMixin hid_controller_{&mixin_host_}; private: - DISALLOW_COPY_AND_ASSIGN(EnterpriseEnrollmentConfigurationTestNoHID); + DISALLOW_COPY_AND_ASSIGN(OobeConfigurationTestNoHID); +}; + +class OobeConfigurationEnrollmentTest : public OobeConfigurationTest { + public: + OobeConfigurationEnrollmentTest() = default; + ~OobeConfigurationEnrollmentTest() override = default; + + protected: + LocalPolicyTestServerMixin policy_server_{&mixin_host_}; + // We need fake gaia to fetch device local account tokens. + FakeGaiaMixin fake_gaia_{&mixin_host_, embedded_test_server()}; + test::EnrollmentUIMixin enrollment_ui_{&mixin_host_}; + + private: + DISALLOW_COPY_AND_ASSIGN(OobeConfigurationEnrollmentTest); }; // Check that configuration lets correctly pass Welcome screen. -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, - TestLeaveWelcomeScreen) { +IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestLeaveWelcomeScreen) { LoadConfiguration(); OobeScreenWaiter(OobeScreen::SCREEN_OOBE_NETWORK).Wait(); } // Check that language and input methods are set correctly. -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, - TestSwitchLanguageIME) { +IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestSwitchLanguageIME) { LoadConfiguration(); OobeScreenWaiter(OobeScreen::SCREEN_OOBE_NETWORK).Wait(); @@ -187,23 +191,20 @@ } // Check that configuration lets correctly start Demo mode setup. -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, - TestEnableDemoMode) { +IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestEnableDemoMode) { LoadConfiguration(); OobeScreenWaiter(OobeScreen::SCREEN_OOBE_DEMO_PREFERENCES).Wait(); } // Check that configuration lets correctly pass through demo preferences. -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, - TestDemoModePreferences) { +IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestDemoModePreferences) { LoadConfiguration(); OobeScreenWaiter(OobeScreen::SCREEN_OOBE_NETWORK).Wait(); } // Check that configuration lets correctly use offline demo mode on network // screen. -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, - TestDemoModeOfflineNetwork) { +IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestDemoModeOfflineNetwork) { LoadConfiguration(); OobeScreenWaiter(OobeScreen::SCREEN_OOBE_DEMO_PREFERENCES).Wait(); SimulateOfflineEnvironment(); @@ -212,8 +213,7 @@ // Check that configuration lets correctly use offline demo mode on EULA // screen. -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, - TestDemoModeAcceptEula) { +IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestDemoModeAcceptEula) { LoadConfiguration(); OobeScreenWaiter(OobeScreen::SCREEN_OOBE_DEMO_PREFERENCES).Wait(); SimulateOfflineEnvironment(); @@ -222,8 +222,7 @@ // Check that configuration lets correctly use offline demo mode on ARC++ ToS // screen. -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, - TestDemoModeAcceptArcTos) { +IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestDemoModeAcceptArcTos) { LoadConfiguration(); OobeScreenWaiter(OobeScreen::SCREEN_OOBE_DEMO_PREFERENCES).Wait(); SimulateOfflineEnvironment(); @@ -239,29 +238,26 @@ } // Check that configuration lets correctly select a network by GUID. -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, - TestSelectNetwork) { +IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestSelectNetwork) { LoadConfiguration(); OobeScreenWaiter(OobeScreen::SCREEN_OOBE_EULA).Wait(); } // Check that configuration would proceed if there is a connected network. -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, - TestSelectConnectedNetwork) { +IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestSelectConnectedNetwork) { LoadConfiguration(); OobeScreenWaiter(OobeScreen::SCREEN_OOBE_EULA).Wait(); } // Check that configuration would not proceed with connected network if // welcome screen is not automated. -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, - TestConnectedNetworkNoWelcome) { +IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestConnectedNetworkNoWelcome) { LoadConfiguration(); OobeScreenWaiter(OobeScreen::SCREEN_OOBE_WELCOME).Wait(); } // Check that when configuration has ONC and EULA, we get to update screen. -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, TestAcceptEula) { +IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestAcceptEula) { UpdateEngineClient::Status status; status.status = UpdateEngineClient::UPDATE_STATUS_DOWNLOADING; status.download_progress = 0.1; @@ -271,18 +267,9 @@ OobeScreenWaiter(OobeScreen::SCREEN_OOBE_UPDATE).Wait(); } -// Check that configuration allows to skip Update screen and get to Enrollment -// screen. -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, TestSkipUpdate) { - LoadConfiguration(); - OobeScreenWaiter(OobeScreen::SCREEN_OOBE_ENROLLMENT).Wait(); - WaitForStep("signin"); -} - // Check that when configuration has requisition, it gets applied at the // beginning. -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, - TestDeviceRequisition) { +IN_PROC_BROWSER_TEST_F(OobeConfigurationTest, TestDeviceRequisition) { LoadConfiguration(); OobeScreenWaiter(OobeScreen::SCREEN_OOBE_EULA).Wait(); auto* policy_manager = g_browser_process->platform_part() @@ -293,30 +280,34 @@ // Check that configuration allows to skip Update screen and get to Enrollment // screen. -// https://crbug.com/945834 -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, - DISABLED_TestEnrollUsingToken) { - enrollment_helper_.DisableAttributePromptUpdate(); - // Token from configuration file: - enrollment_helper_.ExpectTokenEnrollmentSuccess( - "00000000-1111-2222-3333-444444444444"); +IN_PROC_BROWSER_TEST_F(OobeConfigurationEnrollmentTest, TestSkipUpdate) { LoadConfiguration(); OobeScreenWaiter(OobeScreen::SCREEN_OOBE_ENROLLMENT).Wait(); - WaitForStep("success"); + enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepSignin); +} + +IN_PROC_BROWSER_TEST_F(OobeConfigurationEnrollmentTest, TestEnrollUsingToken) { + policy_server_.SetUpdateDeviceAttributesPermission(false); + policy_server_.SetFakeAttestationFlow(); + + // Token from configuration file: + policy_server_.ExpectTokenEnrollment("00000000-1111-2222-3333-444444444444", + FakeGaiaMixin::kEnterpriseUser1); + LoadConfiguration(); + OobeScreenWaiter(OobeScreen::SCREEN_OOBE_ENROLLMENT).Wait(); + enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepSuccess); } // Check that HID detection screen is shown if it is not specified by // configuration. -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTestNoHID, - TestLeaveWelcomeScreen) { +IN_PROC_BROWSER_TEST_F(OobeConfigurationTestNoHID, TestLeaveWelcomeScreen) { LoadConfiguration(); OobeScreenWaiter(OobeScreen::SCREEN_OOBE_HID_DETECTION).Wait(); } // Check that HID detection screen is really skipped and rest of configuration // is applied. -IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTestNoHID, - TestSkipHIDDetection) { +IN_PROC_BROWSER_TEST_F(OobeConfigurationTestNoHID, TestSkipHIDDetection) { LoadConfiguration(); OobeScreenWaiter(OobeScreen::SCREEN_OOBE_NETWORK).Wait(); }
diff --git a/chrome/browser/chromeos/login/enrollment/OWNERS b/chrome/browser/chromeos/login/enrollment/OWNERS index b63c3ee..1aeb4f3 100644 --- a/chrome/browser/chromeos/login/enrollment/OWNERS +++ b/chrome/browser/chromeos/login/enrollment/OWNERS
@@ -3,6 +3,7 @@ atwilson@chromium.org bartfab@chromium.org emaxx@chromium.org +pmarko@chromium.org poromov@chromium.org rsorokin@chromium.org tnagel@chromium.org
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc b/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc index c1c6a1aa..377553a 100644 --- a/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc +++ b/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc
@@ -118,17 +118,6 @@ "5"); } - void SetFakeAttestationFlow() { - g_browser_process->platform_part() - ->browser_policy_connector_chromeos() - ->GetDeviceCloudPolicyInitializer() - ->SetAttestationFlowForTesting( - std::make_unique<chromeos::attestation::AttestationFlow>( - cryptohome::AsyncMethodCaller::GetInstance(), - chromeos::FakeCryptohomeClient::Get(), - std::make_unique<chromeos::attestation::FakeServerProxy>())); - } - policy::ServerBackedStateKeysBroker* state_keys_broker() { return g_browser_process->platform_part() ->browser_policy_connector_chromeos() @@ -444,7 +433,7 @@ // Attestation enrollment. IN_PROC_BROWSER_TEST_F(AutoEnrollmentLocalPolicyServer, Attestation) { - SetFakeAttestationFlow(); + policy_server_.SetFakeAttestationFlow(); EXPECT_TRUE(policy_server_.SetDeviceStateRetrievalResponse( state_keys_broker(), enterprise_management::DeviceStateRetrievalResponse::
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc b/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc index 3fc1429..d10ffd7 100644 --- a/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc +++ b/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc
@@ -253,8 +253,7 @@ view_->ShowEnrollmentSpinnerScreen(); CreateEnrollmentHelper(); - enrollment_helper_->EnrollUsingAuthCode(auth_code, - false /* fetch_additional_token */); + enrollment_helper_->EnrollUsingAuthCode(auth_code); } void EnrollmentScreen::OnLicenseTypeSelected(const std::string& license_type) {
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_screen_unittest.cc b/chrome/browser/chromeos/login/enrollment/enrollment_screen_unittest.cc index 1cb749d6..a326a2e 100644 --- a/chrome/browser/chromeos/login/enrollment/enrollment_screen_unittest.cc +++ b/chrome/browser/chromeos/login/enrollment/enrollment_screen_unittest.cc
@@ -332,9 +332,9 @@ std::unique_ptr<EnterpriseEnrollmentHelperMock> mock = std::make_unique<EnterpriseEnrollmentHelperMock>(); auto* mock_ref = mock.get(); - EXPECT_CALL(*mock, EnrollUsingAuthCode(_, _)) + EXPECT_CALL(*mock, EnrollUsingAuthCode(_)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([mock_ref](const std::string&, bool) { + .WillRepeatedly(Invoke([mock_ref](const std::string&) { EnrollmentLicenseMap licenses; static_cast<EnrollmentScreen*>(mock_ref->status_consumer()) ->OnMultipleLicensesAvailable(licenses);
diff --git a/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper.h b/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper.h index 5916fe10..69a5394 100644 --- a/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper.h +++ b/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper.h
@@ -98,13 +98,9 @@ // Starts enterprise enrollment using |auth_code|. First tries to exchange the // auth code to authentication token, then tries to enroll the device with the // received token. - // If |fetch_additional_token| is true, the helper fetches an additional token - // and passes it to the |status_consumer| on successful enrollment. // EnrollUsingAuthCode can be called only once during this object's lifetime, // and only if none of the EnrollUsing* methods was called before. - // TODO (alemate): Remove unused |fetch_additional_token| parameter. - virtual void EnrollUsingAuthCode(const std::string& auth_code, - bool fetch_additional_token) = 0; + virtual void EnrollUsingAuthCode(const std::string& auth_code) = 0; // Starts enterprise enrollment using |token|. // This flow is used when enrollment is controlled by the paired device.
diff --git a/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.cc b/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.cc index 5387ae9..63f224c66a 100644 --- a/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.cc +++ b/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.cc
@@ -96,8 +96,7 @@ } void EnterpriseEnrollmentHelperImpl::EnrollUsingAuthCode( - const std::string& auth_code, - bool fetch_additional_token) { + const std::string& auth_code) { DCHECK(oauth_status_ == OAUTH_NOT_STARTED); oauth_status_ = OAUTH_STARTED_WITH_AUTH_CODE; oauth_fetcher_ = policy::PolicyOAuth2TokenFetcher::CreateInstance(); @@ -106,8 +105,7 @@ g_browser_process->system_network_context_manager() ->GetSharedURLLoaderFactory(), base::Bind(&EnterpriseEnrollmentHelperImpl::OnTokenFetched, - weak_ptr_factory_.GetWeakPtr(), - fetch_additional_token /* is_additional_token */)); + weak_ptr_factory_.GetWeakPtr())); } void EnterpriseEnrollmentHelperImpl::EnrollUsingToken( @@ -208,11 +206,6 @@ void EnterpriseEnrollmentHelperImpl::ClearAuth(base::OnceClosure callback) { if (oauth_status_ != OAUTH_NOT_STARTED) { - // Do not revoke the additional token if enrollment has finished - // successfully. - if (!success_ && additional_token_.length()) - (new TokenRevoker())->Start(additional_token_); - if (oauth_fetcher_) { if (!oauth_fetcher_->OAuth2AccessToken().empty()) (new TokenRevoker())->Start(oauth_fetcher_->OAuth2AccessToken()); @@ -336,7 +329,6 @@ } void EnterpriseEnrollmentHelperImpl::OnTokenFetched( - bool is_additional_token, const std::string& token, const GoogleServiceAuthError& error) { if (error.state() != GoogleServiceAuthError::NONE) { @@ -346,21 +338,7 @@ return; } - if (!is_additional_token) { - EnrollUsingToken(token); - return; - } - - additional_token_ = token; - std::string refresh_token = oauth_fetcher_->OAuth2RefreshToken(); - oauth_fetcher_ = policy::PolicyOAuth2TokenFetcher::CreateInstance(); - oauth_fetcher_->StartWithRefreshToken( - refresh_token, - g_browser_process->system_network_context_manager() - ->GetSharedURLLoaderFactory(), - base::Bind(&EnterpriseEnrollmentHelperImpl::OnTokenFetched, - weak_ptr_factory_.GetWeakPtr(), - false /* is_additional_token */)); + EnrollUsingToken(token); } void EnterpriseEnrollmentHelperImpl::OnEnrollmentFinished(
diff --git a/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.h b/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.h index 7b9b046..6b1e48f8 100644 --- a/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.h +++ b/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.h
@@ -35,8 +35,7 @@ ~EnterpriseEnrollmentHelperImpl() override; // EnterpriseEnrollmentHelper: - void EnrollUsingAuthCode(const std::string& auth_code, - bool fetch_additional_token) override; + void EnrollUsingAuthCode(const std::string& auth_code) override; void EnrollUsingToken(const std::string& token) override; void EnrollUsingEnrollmentToken(const std::string& token) override; void EnrollUsingAttestation() override; @@ -75,8 +74,7 @@ void DoEnroll(std::unique_ptr<policy::DMAuth> auth_data); // Handles completion of the OAuth2 token fetch attempt. - void OnTokenFetched(bool is_additional_token, - const std::string& token, + void OnTokenFetched(const std::string& token, const GoogleServiceAuthError& error); // Handles multiple license types case. @@ -107,9 +105,7 @@ policy::EnrollmentConfig enrollment_config_; std::string enrolling_user_domain_; - bool fetch_additional_token_; - std::string additional_token_; enum { OAUTH_NOT_STARTED, OAUTH_STARTED_WITH_AUTH_CODE,
diff --git a/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_mock.h b/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_mock.h index 5ca5fdc4..cd64ad5f 100644 --- a/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_mock.h +++ b/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_mock.h
@@ -25,8 +25,7 @@ void(ActiveDirectoryJoinDelegate* ad_join_delegate, const policy::EnrollmentConfig& enrollment_config, const std::string& enrolling_user_domain)); - MOCK_METHOD2(EnrollUsingAuthCode, - void(const std::string& auth_code, bool fetch_additional_token)); + MOCK_METHOD1(EnrollUsingAuthCode, void(const std::string& auth_code)); MOCK_METHOD1(EnrollUsingToken, void(const std::string& token)); MOCK_METHOD1(EnrollUsingEnrollmentToken, void(const std::string& token)); MOCK_METHOD0(EnrollUsingAttestation, void());
diff --git a/chrome/browser/chromeos/login/test/enrollment_helper_mixin.cc b/chrome/browser/chromeos/login/test/enrollment_helper_mixin.cc index a6edb4f..dcf3cd7 100644 --- a/chrome/browser/chromeos/login/test/enrollment_helper_mixin.cc +++ b/chrome/browser/chromeos/login/test/enrollment_helper_mixin.cc
@@ -75,7 +75,7 @@ } void EnrollmentHelperMixin::ExpectSuccessfulOAuthEnrollment() { - EXPECT_CALL(*mock_, EnrollUsingAuthCode(kTestAuthCode, _)) + EXPECT_CALL(*mock_, EnrollUsingAuthCode(kTestAuthCode)) .WillOnce(InvokeWithoutArgs( [this]() { mock_->status_consumer()->OnDeviceEnrolled(); })); } @@ -91,7 +91,7 @@ if (kiosk >= 0) license_map[policy::LicenseType::KIOSK] = kiosk; CHECK(license_map.size() > 1); - EXPECT_CALL(*mock_, EnrollUsingAuthCode(kTestAuthCode, _)) + EXPECT_CALL(*mock_, EnrollUsingAuthCode(kTestAuthCode)) .WillOnce(InvokeWithoutArgs([this, license_map]() { mock_->status_consumer()->OnMultipleLicensesAvailable(license_map); })); @@ -151,7 +151,7 @@ } void EnrollmentHelperMixin::ExpectEnrollmentCredentials() { - EXPECT_CALL(*mock_, EnrollUsingAuthCode(kTestAuthCode, _)); + EXPECT_CALL(*mock_, EnrollUsingAuthCode(kTestAuthCode)); } void EnrollmentHelperMixin::DisableAttributePromptUpdate() { @@ -182,7 +182,7 @@ const std::string& expected_domain, const std::string& domain_join_config, const std::string& dm_token) { - EXPECT_CALL(*mock_, EnrollUsingAuthCode(kTestAuthCode, _)) + EXPECT_CALL(*mock_, EnrollUsingAuthCode(kTestAuthCode)) .WillOnce(InvokeWithoutArgs( [delegate, expected_domain, domain_join_config, dm_token]() { delegate->JoinDomain(dm_token, domain_join_config,
diff --git a/chrome/browser/chromeos/login/test/enrollment_ui_mixin.h b/chrome/browser/chromeos/login/test/enrollment_ui_mixin.h index 26c180e..7eb6ada3c 100644 --- a/chrome/browser/chromeos/login/test/enrollment_ui_mixin.h +++ b/chrome/browser/chromeos/login/test/enrollment_ui_mixin.h
@@ -17,6 +17,7 @@ // WaitForStep(...) constants. +extern const char kEnrollmentStepSignin[]; extern const char kEnrollmentStepLicenses[]; extern const char kEnrollmentStepDeviceAttributes[]; extern const char kEnrollmentStepSuccess[];
diff --git a/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.cc b/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.cc index 5909887..2d3513d 100644 --- a/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.cc +++ b/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.cc
@@ -7,7 +7,13 @@ #include <utility> #include "base/guid.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/login/test/fake_gaia_mixin.h" +#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" +#include "chrome/browser/chromeos/policy/device_cloud_policy_initializer.h" +#include "chromeos/attestation/mock_attestation_flow.h" +#include "chromeos/cryptohome/async_method_caller.h" +#include "chromeos/dbus/cryptohome/fake_cryptohome_client.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "components/policy/core/common/cloud/policy_builder.h" #include "components/policy/core/common/policy_switches.h" @@ -77,6 +83,16 @@ policy_test_server_->SetConfig(server_config_); } +void LocalPolicyTestServerMixin::ExpectTokenEnrollment( + const std::string& enrollment_token, + const std::string& token_creator) { + base::Value token_enrollment(base::Value::Type::DICTIONARY); + token_enrollment.SetKey("token", base::Value(enrollment_token)); + token_enrollment.SetKey("username", base::Value(token_creator)); + server_config_.SetKey("token_enrollment", std::move(token_enrollment)); + policy_test_server_->SetConfig(server_config_); +} + void LocalPolicyTestServerMixin::SetUpdateDeviceAttributesPermission( bool allowed) { server_config_.SetKey("allow_set_device_attributes", base::Value(allowed)); @@ -112,6 +128,17 @@ std::string() /* entity_id */, policy.SerializeAsString()); } +void LocalPolicyTestServerMixin::SetFakeAttestationFlow() { + g_browser_process->platform_part() + ->browser_policy_connector_chromeos() + ->GetDeviceCloudPolicyInitializer() + ->SetAttestationFlowForTesting( + std::make_unique<chromeos::attestation::AttestationFlow>( + cryptohome::AsyncMethodCaller::GetInstance(), + chromeos::FakeCryptohomeClient::Get(), + std::make_unique<chromeos::attestation::FakeServerProxy>())); +} + bool LocalPolicyTestServerMixin::SetDeviceStateRetrievalResponse( policy::ServerBackedStateKeysBroker* keys_broker, enterprise_management::DeviceStateRetrievalResponse::RestoreMode
diff --git a/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h b/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h index 8181140..f21ca4a 100644 --- a/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h +++ b/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h
@@ -39,8 +39,15 @@ // There should be at least one license type. void ExpectAvailableLicenseCount(int perpetual, int annual, int kiosk); + void ExpectTokenEnrollment(const std::string& enrollment_token, + const std::string& token_creator); + void SetUpdateDeviceAttributesPermission(bool allowed); + // Configures fake attestation flow so that we can test attestation-based + // enrollment flows. + void SetFakeAttestationFlow(); + // Configures server to respond with particular error code during requests. // |net_error_code| - error code from device_management_service.cc. void SetExpectedDeviceEnrollmentError(int net_error_code);
diff --git a/chrome/browser/chromeos/login/ui/login_feedback.cc b/chrome/browser/chromeos/login/ui/login_feedback.cc index 45781aa..ee05ac8 100644 --- a/chrome/browser/chromeos/login/ui/login_feedback.cc +++ b/chrome/browser/chromeos/login/ui/login_feedback.cc
@@ -81,7 +81,8 @@ FeedbackExtensionLoader::~FeedbackExtensionLoader() { extension_registry_->RemoveObserver(this); - GetComponentLoader(profile_)->Remove(extension_misc::kFeedbackExtensionId); + // The extension will be removed via a JS FeedbackPrivate API call to + // indicate when it is done, } void FeedbackExtensionLoader::Load(base::OnceClosure on_ready_callback) {
diff --git a/chrome/browser/chromeos/login/wizard_controller.h b/chrome/browser/chromeos/login/wizard_controller.h index 1e43b3b0..75996697 100644 --- a/chrome/browser/chromeos/login/wizard_controller.h +++ b/chrome/browser/chromeos/login/wizard_controller.h
@@ -391,7 +391,7 @@ ControlFlowNoForcedReEnrollmentOnFirstBoot); friend class DemoSetupTest; - friend class EnterpriseEnrollmentConfigurationTest; + friend class OobeConfigurationTest; friend class HandsOffEnrollmentTest; friend class WizardControllerBrokenLocalStateTest; friend class WizardControllerDemoSetupTest;
diff --git a/chrome/browser/chromeos/policy/off_hours/OWNERS b/chrome/browser/chromeos/policy/off_hours/OWNERS index 6090b08..e0cc5f1 100644 --- a/chrome/browser/chromeos/policy/off_hours/OWNERS +++ b/chrome/browser/chromeos/policy/off_hours/OWNERS
@@ -1 +1,3 @@ poromov@chromium.org + +# COMPONENT: Enterprise
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index c01f2f5..a086a5d 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -854,7 +854,8 @@ "//components/undo", "//components/unified_consent", "//components/update_client", - "//components/update_client:common_impl", + "//components/update_client:patch_impl", + "//components/update_client:unzip_impl", "//components/url_matcher", "//components/user_prefs", "//components/vector_icons",
diff --git a/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc b/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc index eef6c514..4d2d5b0 100644 --- a/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc +++ b/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc
@@ -29,8 +29,12 @@ #include "chrome/browser/chromeos/system_logs/iwlwifi_dump_log_source.h" #include "chrome/browser/chromeos/system_logs/single_debug_daemon_log_source.h" #include "chrome/browser/chromeos/system_logs/single_log_file_log_source.h" +#include "chrome/browser/extensions/component_loader.h" +#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" #include "components/feedback/system_logs/system_logs_source.h" +#include "extensions/browser/extension_system.h" +#include "extensions/common/constants.h" #endif // defined(OS_CHROMEOS) namespace extensions { @@ -192,6 +196,14 @@ std::move(original_sys_logs), std::move(callback))); } + +void ChromeFeedbackPrivateDelegate::UnloadFeedbackExtension( + content::BrowserContext* context) const { + extensions::ExtensionSystem::Get(context) + ->extension_service() + ->component_loader() + ->Remove(extension_misc::kFeedbackExtensionId); +} #endif // defined(OS_CHROMEOS) std::string ChromeFeedbackPrivateDelegate::GetSignedInUserEmail(
diff --git a/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h b/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h index b900965..3b6a5291 100644 --- a/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h +++ b/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h
@@ -30,6 +30,7 @@ std::unique_ptr<FeedbackCommon::SystemLogsMap> original_sys_logs, content::BrowserContext* context, system_logs::SysLogsFetcherCallback callback) const override; + void UnloadFeedbackExtension(content::BrowserContext* context) const override; #endif // defined(OS_CHROMEOS) std::string GetSignedInUserEmail( content::BrowserContext* context) const override;
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 93975ea8..99881e34 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -198,11 +198,6 @@ "expiry_milestone": 76 }, { - "name": "autofill-dynamic-forms", - "owners": [ "sebsg" ], - "expiry_milestone": 72 - }, - { "name": "autofill-enable-company-name", "owners": [ "sebsg" ], "expiry_milestone": 73 @@ -252,11 +247,6 @@ "expiry_milestone": 79 }, { - "name": "autofill-prefilled-fields", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "autofill-profile-client-validation", "owners": [ "parastoog" ], "expiry_milestone": 77 @@ -292,11 +282,6 @@ "expiry_milestone": 76 }, { - "name": "automatic-tab-discarding", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "autoplay-policy", // "owners": [ "your-team" ], "expiry_milestone": 76 @@ -307,11 +292,6 @@ "expiry_milestone": 76 }, { - "name": "bookmark-apps", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "bypass-app-banner-engagement-checks", // "owners": [ "your-team" ], "expiry_milestone": 76 @@ -442,11 +422,6 @@ "expiry_milestone": 74 }, { - "name": "create-app-windows-in-app", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "cros-regions-mode", // "owners": [ "your-team" ], "expiry_milestone": 76 @@ -570,11 +545,6 @@ "expiry_milestone": 76 }, { - "name": "disable-hosted-apps-in-windows", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { // See https://crbug.com/882238. "name": "disable-ipc-flooding-protection", "owners": [ "arthursonzogni@chromium.org", "palmer@chromium.org" ], @@ -943,11 +913,6 @@ "expiry_milestone": 76 }, { - "name": "enable-blink-heap-unified-garbage-collection", - "owners": [ "mlippautz" ], - "expiry_milestone": 76 - }, - { "name": "enable-bloated-renderer-detection", "owners": [ "ulan" ], "expiry_milestone": 75 @@ -1171,11 +1136,6 @@ "expiry_milestone": 76 }, { - "name": "enable-fullscreen-handwriting-virtual-keyboard", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "enable-future-v8-vm-features", "owners": [ "hablich" ], // This flag enables the rolling set of upcoming V8 features, for early @@ -1407,11 +1367,6 @@ "expiry_milestone": -1 }, { - "name": "enable-new-contacts-picker", - "owners": [ "finnur", "peter" ], - "expiry_milestone": 74 - }, - { "name": "download-auto-resumption-native", "owners": [ "shaktisahu", "qinmin" ], "expiry_milestone": 76 @@ -1513,8 +1468,10 @@ }, { "name": "enable-parallel-downloading", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "qinmin", "xingliu", "dtrainor" ], + // This flag is used by dev teams on Android to disable this feature, since + // it can badly break pages under test. + "expiry_milestone": -1 }, { "name": "enable-physical-keyboard-autocorrect", @@ -1522,11 +1479,6 @@ "expiry_milestone": 76 }, { - "name": "enable-pinch", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "enable-pixel-canvas-recording", // "owners": [ "your-team" ], "expiry_milestone": 76 @@ -1702,11 +1654,6 @@ "expiry_milestone": 76 }, { - "name": "enable-stylus-virtual-keyboard", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "enable-suggestions-with-substring-match", // "owners": [ "your-team" ], "expiry_milestone": 76 @@ -1872,11 +1819,6 @@ "expiry_milestone": -1 }, { - "name": "enable-virtual-keyboard-ukm", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "enable-viz-display-compositor", "owners": [ "fsamuel", "kylechar" ], "expiry_milestone": 76 @@ -1945,11 +1887,6 @@ "expiry_milestone": 79 }, { - "name": "enable-webrtc-h264-with-openh264-ffmpeg", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "enable-webrtc-hide-local-ips-with-mdns", // "owners": [ "your-team" ], "expiry_milestone": 76 @@ -3071,11 +3008,6 @@ "expiry_milestone": 76 }, { - "name": "upcoming-ui-features", - "owners": [ "robliao" ], - "expiry_milestone": 76 - }, - { "name": "update-menu-item-custom-summary", "owners": [ "//chrome/android/java/src/org/chromium/chrome/browser/omaha/OWNERS" ], // This is required by test teams to verify functionality on devices which @@ -3177,11 +3109,6 @@ "expiry_milestone": 79 }, { - "name": "webxr-gamepad-support", - "owners": [ "//third_party/blink/renderer/modules/xr/OWNERS", "xr-dev@chromium.org" ], - "expiry_milestone": 76 - }, - { "name": "webxr-hit-test", "owners": [ "//third_party/blink/renderer/modules/xr/OWNERS", "xr-dev@chromium.org" ], "expiry_milestone": 76
diff --git a/chrome/browser/flag-never-expire-list.json b/chrome/browser/flag-never-expire-list.json index 3475ebb..880605b 100644 --- a/chrome/browser/flag-never-expire-list.json +++ b/chrome/browser/flag-never-expire-list.json
@@ -31,6 +31,7 @@ "enable-gpu-service-logging", "enable-logging-js-console-messages", "enable-network-logging-to-file", + "enable-parallel-downloading", "enable-show-autofill-signatures", "enable-site-per-process", "enable-touchscreen-calibration",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index cc7a8d4..e9e3319 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1639,10 +1639,6 @@ "Allow calling canMakePayment() for different payment methods, as long as " "method-specific parameters remain unchanged."; -const char kPinchScaleName[] = "Pinch scale"; -const char kPinchScaleDescription[] = - "Enables experimental support for scale using pinch."; - const char kPreviewsAllowedName[] = "Previews Allowed"; const char kPreviewsAllowedDescription[] = "Allows previews to be shown subject to specific preview types being "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index c1a26f8b..3b454c5f 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -985,9 +985,6 @@ extern const char kPerMethodCanMakePaymentQuotaName[]; extern const char kPerMethodCanMakePaymentQuotaDescription[]; -extern const char kPinchScaleName[]; -extern const char kPinchScaleDescription[]; - extern const char kPreviewsAllowedName[]; extern const char kPreviewsAllowedDescription[];
diff --git a/chrome/browser/media/webrtc/tab_desktop_media_list.cc b/chrome/browser/media/webrtc/tab_desktop_media_list.cc index 806a766f..86a3655 100644 --- a/chrome/browser/media/webrtc/tab_desktop_media_list.cc +++ b/chrome/browser/media/webrtc/tab_desktop_media_list.cc
@@ -19,6 +19,7 @@ #include "media/base/video_util.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkImage.h" +#include "ui/gfx/favicon_size.h" #include "ui/gfx/image/image.h" using content::BrowserThread; @@ -28,8 +29,8 @@ gfx::ImageSkia CreateEnclosedFaviconImage(gfx::Size size, const gfx::ImageSkia& favicon) { - DCHECK_GE(size.width(), 20); - DCHECK_GE(size.height(), 20); + DCHECK_GE(size.width(), gfx::kFaviconSize); + DCHECK_GE(size.height(), gfx::kFaviconSize); // Create a bitmap. SkBitmap result;
diff --git a/chrome/browser/offline_pages/android/downloads/offline_page_share_helper.cc b/chrome/browser/offline_pages/android/downloads/offline_page_share_helper.cc index 840221a..9cfb952 100644 --- a/chrome/browser/offline_pages/android/downloads/offline_page_share_helper.cc +++ b/chrome/browser/offline_pages/android/downloads/offline_page_share_helper.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/offline_pages/android/downloads/offline_page_share_helper.h" +#include <utility> +#include <vector> + #include "base/android/jni_string.h" #include "base/bind.h" #include "base/callback.h" @@ -13,6 +16,7 @@ #include "chrome/browser/offline_pages/offline_page_mhtml_archiver.h" #include "components/offline_pages/core/offline_page_feature.h" #include "components/offline_pages/core/offline_page_model.h" +#include "components/offline_pages/core/page_criteria.h" using OfflineItemShareInfo = offline_items_collection::OfflineItemShareInfo; @@ -46,21 +50,25 @@ content_id_ = id; result_cb_ = std::move(result_cb); - model_->GetPageByGuid( - content_id_.id, base::BindOnce(&OfflinePageShareHelper::OnPageGetForShare, - weak_ptr_factory_.GetWeakPtr())); + PageCriteria criteria; + criteria.guid = content_id_.id; + criteria.maximum_matches = 1; + model_->GetPagesWithCriteria( + criteria, base::BindOnce(&OfflinePageShareHelper::OnPageGetForShare, + weak_ptr_factory_.GetWeakPtr())); } -void OfflinePageShareHelper::OnPageGetForShare(const OfflinePageItem* page) { - if (!page) { +void OfflinePageShareHelper::OnPageGetForShare( + const std::vector<OfflinePageItem>& pages) { + if (pages.empty()) { // Continue to share without share info. NotifyCompletion(ShareResult::kSuccess, nullptr); return; } - + const OfflinePageItem& page = pages[0]; bool is_suggested = - model_->GetPolicyController()->IsSuggested(page->client_id.name_space); - bool in_private_dir = model_->IsArchiveInInternalDir(page->file_path); + model_->GetPolicyController()->IsSuggested(page.client_id.name_space); + bool in_private_dir = model_->IsArchiveInInternalDir(page.file_path); // Need to publish internal page to public directory to share the file with // content URI instead of the web page URL. @@ -70,7 +78,7 @@ } // Try to share the mhtml file if the page is in public directory. - NotifyCompletion(ShareResult::kSuccess, CreateShareInfo(page->file_path)); + NotifyCompletion(ShareResult::kSuccess, CreateShareInfo(page.file_path)); } void OfflinePageShareHelper::AcquireFileAccessPermission() { @@ -87,16 +95,21 @@ } // Retrieve the offline page again in case it's deleted. - model_->GetPageByGuid( - content_id_.id, - base::BindOnce(&OfflinePageShareHelper::OnPageGetForPublish, - weak_ptr_factory_.GetWeakPtr())); + PageCriteria criteria; + criteria.guid = content_id_.id; + criteria.maximum_matches = 1; + model_->GetPagesWithCriteria( + criteria, base::BindOnce(&OfflinePageShareHelper::OnPageGetForPublish, + weak_ptr_factory_.GetWeakPtr())); } -void OfflinePageShareHelper::OnPageGetForPublish(const OfflinePageItem* page) { +void OfflinePageShareHelper::OnPageGetForPublish( + const std::vector<OfflinePageItem>& pages) { + if (pages.empty()) + return; // Publish the page. model_->PublishInternalArchive( - *page, std::make_unique<OfflinePageMHTMLArchiver>(), + pages[0], std::make_unique<OfflinePageMHTMLArchiver>(), base::BindOnce(&OfflinePageShareHelper::OnPagePublished, weak_ptr_factory_.GetWeakPtr())); }
diff --git a/chrome/browser/offline_pages/android/downloads/offline_page_share_helper.h b/chrome/browser/offline_pages/android/downloads/offline_page_share_helper.h index 56a1279..c7561eb 100644 --- a/chrome/browser/offline_pages/android/downloads/offline_page_share_helper.h +++ b/chrome/browser/offline_pages/android/downloads/offline_page_share_helper.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_OFFLINE_PAGES_ANDROID_DOWNLOADS_OFFLINE_PAGE_SHARE_HELPER_H_ #include <memory> +#include <vector> #include "base/callback_forward.h" #include "base/macros.h" @@ -35,12 +36,12 @@ void GetShareInfo(const ContentId& id, ResultCallback result_cb); private: - void OnPageGetForShare(const OfflinePageItem* page); + void OnPageGetForShare(const std::vector<OfflinePageItem>& pages); void AcquireFileAccessPermission(); void OnFileAccessPermissionDone(bool granted); - void OnPageGetForPublish(const OfflinePageItem* page); + void OnPageGetForPublish(const std::vector<OfflinePageItem>& pages); void OnPagePublished(const base::FilePath& file_path, SavePageResult result); void NotifyCompletion(ShareResult result,
diff --git a/chrome/browser/offline_pages/android/offline_page_bridge.cc b/chrome/browser/offline_pages/android/offline_page_bridge.cc index 9cdd2c8..b045684 100644 --- a/chrome/browser/offline_pages/android/offline_page_bridge.cc +++ b/chrome/browser/offline_pages/android/offline_page_bridge.cc
@@ -43,6 +43,7 @@ #include "components/offline_pages/core/offline_page_item.h" #include "components/offline_pages/core/offline_page_model.h" #include "components/offline_pages/core/offline_page_types.h" +#include "components/offline_pages/core/page_criteria.h" #include "components/offline_pages/core/request_header/offline_page_header.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/web_contents.h" @@ -551,9 +552,11 @@ j_callback_ref.Reset(env, j_callback_obj); std::vector<ClientId> client_ids = getClientIdsFromObjectArrays(env, j_namespaces_array, j_ids_array); - offline_page_model_->GetPagesByClientIds( - client_ids, base::BindOnce(&MultipleOfflinePageItemCallback, j_result_ref, - j_callback_ref)); + PageCriteria criteria; + criteria.client_ids = client_ids; + offline_page_model_->GetPagesWithCriteria( + criteria, base::BindOnce(&MultipleOfflinePageItemCallback, j_result_ref, + j_callback_ref)); } void OfflinePageBridge::GetPagesByRequestOrigin( @@ -568,11 +571,11 @@ ScopedJavaGlobalRef<jobject> j_callback_ref; j_callback_ref.Reset(env, j_callback_obj); - std::string request_origin = ConvertJavaStringToUTF8(env, j_request_origin); - - offline_page_model_->GetPagesByRequestOrigin( - request_origin, base::BindOnce(&MultipleOfflinePageItemCallback, - j_result_ref, j_callback_ref)); + PageCriteria criteria; + criteria.request_origin = ConvertJavaStringToUTF8(env, j_request_origin); + offline_page_model_->GetPagesWithCriteria( + criteria, base::BindOnce(&MultipleOfflinePageItemCallback, j_result_ref, + j_callback_ref)); } void OfflinePageBridge::GetPagesByNamespace( @@ -586,11 +589,12 @@ ScopedJavaGlobalRef<jobject> j_callback_ref; j_callback_ref.Reset(env, j_callback_obj); - std::string name_space = ConvertJavaStringToUTF8(env, j_namespace); - - offline_page_model_->GetPagesByNamespace( - name_space, base::BindOnce(&MultipleOfflinePageItemCallback, j_result_ref, - j_callback_ref)); + PageCriteria criteria; + criteria.client_namespaces.push_back( + ConvertJavaStringToUTF8(env, j_namespace)); + offline_page_model_->GetPagesWithCriteria( + criteria, base::BindOnce(&MultipleOfflinePageItemCallback, j_result_ref, + j_callback_ref)); } void OfflinePageBridge::SelectPageForOnlineUrl( @@ -706,14 +710,29 @@ OfflinePageModel* offline_page_model = OfflinePageModelFactory::GetForBrowserContext(browser_context_); DCHECK(offline_page_model); - - offline_page_model->GetPageByGuid( - ConvertJavaStringToUTF8(env, j_guid), - base::BindOnce(&OfflinePageBridge::PublishInternalArchive, + PageCriteria criteria; + criteria.guid = ConvertJavaStringToUTF8(env, j_guid); + criteria.maximum_matches = 1; + offline_page_model->GetPagesWithCriteria( + criteria, + base::BindOnce(&OfflinePageBridge::PublishInternalArchiveOfFirstItem, weak_ptr_factory_.GetWeakPtr(), j_published_callback_ref, PublishSource::kPublishByGuid)); } +void OfflinePageBridge::PublishInternalArchiveOfFirstItem( + const ScopedJavaGlobalRef<jobject>& j_callback_obj, + const PublishSource publish_source, + const std::vector<OfflinePageItem>& offline_pages) { + // Should only ever be called with 0 or 1 page. + DCHECK_GE(1UL, offline_pages.size()); + if (offline_pages.empty()) { + PublishInternalArchive(j_callback_obj, publish_source, nullptr); + return; + } + PublishInternalArchive(j_callback_obj, publish_source, &offline_pages[0]); +} + void OfflinePageBridge::PublishInternalArchive( const ScopedJavaGlobalRef<jobject>& j_callback_obj, const PublishSource publish_source, @@ -725,7 +744,6 @@ publish_source); return; } - OfflinePageModel* offline_page_model = OfflinePageModelFactory::GetForBrowserContext(browser_context_); DCHECK(offline_page_model); @@ -921,9 +939,11 @@ const JavaParamRef<jobject>& j_callback_obj) { base::Time pages_created_after = base::Time::FromJavaTime(j_timestamp_millis); ScopedJavaGlobalRef<jobject> j_callback_ref(j_callback_obj); - - offline_page_model_->GetPagesSupportedByDownloads(base::Bind( - &CheckForNewOfflineContentCallback, pages_created_after, j_callback_ref)); + PageCriteria criteria; + criteria.supported_by_downloads = true; + offline_page_model_->GetPagesWithCriteria( + criteria, base::BindOnce(&CheckForNewOfflineContentCallback, + pages_created_after, j_callback_ref)); } void OfflinePageBridge::GetLoadUrlParamsByOfflineId( @@ -1014,28 +1034,31 @@ offline_pages::OfflinePageHeader()); return; } - - offline_page_model_->GetPageBySizeAndDigest( - size_and_digest.first, size_and_digest.second, - base::BindOnce(&OfflinePageBridge::GetPageBySizeAndDigestDone, - weak_ptr_factory_.GetWeakPtr(), j_callback_obj, - intent_url)); + PageCriteria criteria; + criteria.file_size = size_and_digest.first; + criteria.digest = size_and_digest.second; + criteria.maximum_matches = 1; + offline_page_model_->GetPagesWithCriteria( + criteria, base::BindOnce(&OfflinePageBridge::GetPageBySizeAndDigestDone, + weak_ptr_factory_.GetWeakPtr(), j_callback_obj, + intent_url)); } void OfflinePageBridge::GetPageBySizeAndDigestDone( const ScopedJavaGlobalRef<jobject>& j_callback_obj, const GURL& intent_url, - const OfflinePageItem* offline_page) { + const std::vector<OfflinePageItem>& offline_pages) { GURL launch_url; offline_pages::OfflinePageHeader offline_header; - if (offline_page) { - launch_url = offline_page->url; + if (!offline_pages.empty()) { + const OfflinePageItem& offline_page = offline_pages[0]; + launch_url = offline_page.url; offline_header.reason = intent_url.SchemeIsFile() ? offline_pages::OfflinePageHeader::Reason::FILE_URL_INTENT : offline_pages::OfflinePageHeader::Reason::CONTENT_URL_INTENT; offline_header.need_to_persist = true; - offline_header.id = base::NumberToString(offline_page->offline_id); + offline_header.id = base::NumberToString(offline_page.offline_id); offline_header.intent_url = intent_url; } else { // If the offline page can't be found, launch the intent URL.
diff --git a/chrome/browser/offline_pages/android/offline_page_bridge.h b/chrome/browser/offline_pages/android/offline_page_bridge.h index 248decd..747bdfa 100644 --- a/chrome/browser/offline_pages/android/offline_page_bridge.h +++ b/chrome/browser/offline_pages/android/offline_page_bridge.h
@@ -5,7 +5,11 @@ #ifndef CHROME_BROWSER_OFFLINE_PAGES_ANDROID_OFFLINE_PAGE_BRIDGE_H_ #define CHROME_BROWSER_OFFLINE_PAGES_ANDROID_OFFLINE_PAGE_BRIDGE_H_ -#include <stdint.h> +#include <cstdint> +#include <memory> +#include <string> +#include <utility> +#include <vector> #include "base/android/jni_android.h" #include "base/android/jni_weak_ref.h" @@ -259,7 +263,7 @@ void GetPageBySizeAndDigestDone( const base::android::ScopedJavaGlobalRef<jobject>& j_callback_obj, const GURL& intent_url, - const OfflinePageItem* offline_page); + const std::vector<OfflinePageItem>& offline_pages); void NotifyIfDoneLoading() const; @@ -270,7 +274,12 @@ void PublishInternalArchive( const base::android::ScopedJavaGlobalRef<jobject>& j_callback_obj, const PublishSource publish_source, - const OfflinePageItem* offline_page); + const OfflinePageItem* offline_pages); + + void PublishInternalArchiveOfFirstItem( + const base::android::ScopedJavaGlobalRef<jobject>& j_callback_obj, + const PublishSource publish_source, + const std::vector<OfflinePageItem>& offline_pages); base::android::ScopedJavaGlobalRef<jobject> java_ref_; // Not owned.
diff --git a/chrome/browser/offline_pages/offline_page_tab_helper.cc b/chrome/browser/offline_pages/offline_page_tab_helper.cc index fbd9b76..ff7de267 100644 --- a/chrome/browser/offline_pages/offline_page_tab_helper.cc +++ b/chrome/browser/offline_pages/offline_page_tab_helper.cc
@@ -24,6 +24,7 @@ #include "components/offline_pages/core/offline_page_item_utils.h" #include "components/offline_pages/core/offline_page_model.h" #include "components/offline_pages/core/offline_store_utils.h" +#include "components/offline_pages/core/page_criteria.h" #include "components/offline_pages/core/prefetch/offline_metrics_collector.h" #include "components/offline_pages/core/prefetch/prefetch_service.h" #include "components/offline_pages/core/request_header/offline_page_header.h" @@ -318,8 +319,12 @@ return; } - OfflinePageUtils::SelectPagesForURL( - web_contents()->GetBrowserContext(), navigation_handle->GetURL(), tab_id, + PageCriteria criteria; + criteria.url = navigation_handle->GetURL(); + criteria.pages_for_tab_id = tab_id; + criteria.maximum_matches = 1; + OfflinePageUtils::SelectPagesWithCriteria( + web_contents()->GetBrowserContext(), criteria, base::BindOnce(&OfflinePageTabHelper::SelectPagesForURLDone, weak_ptr_factory_.GetWeakPtr())); }
diff --git a/chrome/browser/offline_pages/offline_page_utils.cc b/chrome/browser/offline_pages/offline_page_utils.cc index 8f229a7..1b1072f 100644 --- a/chrome/browser/offline_pages/offline_page_utils.cc +++ b/chrome/browser/offline_pages/offline_page_utils.cc
@@ -58,34 +58,6 @@ } }; -void OnGetPagesByURLDone( - const GURL& url, - int tab_id, - const std::vector<std::string>& namespaces_restricted_to_tab_from_client_id, - base::OnceCallback<void(const std::vector<OfflinePageItem>&)> callback, - const MultipleOfflinePageItemResult& pages) { - std::vector<OfflinePageItem> selected_pages; - std::string tab_id_str = base::NumberToString(tab_id); - - // Exclude pages whose tab id does not match. - // Note: For this restriction to work offline pages saved to tab-bound - // namespaces must have the assigned tab id set to their ClientId::id field. - for (const auto& page : pages) { - if (base::ContainsValue(namespaces_restricted_to_tab_from_client_id, - page.client_id.name_space) && - page.client_id.id != tab_id_str) { - continue; - } - selected_pages.push_back(page); - } - - // Sort based on creation date. - std::sort(selected_pages.begin(), selected_pages.end(), - OfflinePageComparer()); - - std::move(callback).Run(selected_pages); -} - bool IsSupportedByDownload(content::BrowserContext* browser_context, const std::string& name_space) { OfflinePageModel* offline_page_model = @@ -207,6 +179,17 @@ const GURL& url, int tab_id, base::OnceCallback<void(const std::vector<OfflinePageItem>&)> callback) { + PageCriteria criteria; + criteria.url = url; + criteria.pages_for_tab_id = tab_id; + SelectPagesWithCriteria(browser_context, criteria, std::move(callback)); +} + +// static +void OfflinePageUtils::SelectPagesWithCriteria( + content::BrowserContext* browser_context, + const PageCriteria& criteria, + base::OnceCallback<void(const std::vector<OfflinePageItem>&)> callback) { OfflinePageModel* offline_page_model = OfflinePageModelFactory::GetForBrowserContext(browser_context); if (!offline_page_model) { @@ -216,11 +199,7 @@ return; } - offline_page_model->GetPagesByURL( - url, base::BindOnce(&OnGetPagesByURLDone, url, tab_id, - offline_page_model->GetPolicyController() - ->GetNamespacesRestrictedToTabFromClientId(), - std::move(callback))); + offline_page_model->GetPagesWithCriteria(criteria, std::move(callback)); } const OfflinePageItem* OfflinePageUtils::GetOfflinePageFromWebContents( @@ -317,9 +296,10 @@ callback.Run(DuplicateCheckResult::DUPLICATE_PAGE_FOUND); } }; - - offline_page_model->GetPagesByURL( - url, base::BindOnce(continuation, browser_context, url, callback)); + PageCriteria criteria; + criteria.url = url; + offline_page_model->GetPagesWithCriteria( + criteria, base::BindOnce(continuation, browser_context, url, callback)); } // static @@ -368,8 +348,11 @@ OfflinePageModelFactory::GetForBrowserContext(browser_context); if (!offline_page_model || begin_time > end_time) return false; - offline_page_model->GetPagesRemovedOnCacheReset(base::BindOnce( - &DoCalculateSizeBetween, std::move(callback), begin_time, end_time)); + PageCriteria criteria; + criteria.removed_on_cache_reset = true; + offline_page_model->GetPagesWithCriteria( + criteria, base::BindOnce(&DoCalculateSizeBetween, std::move(callback), + begin_time, end_time)); return true; }
diff --git a/chrome/browser/offline_pages/offline_page_utils.h b/chrome/browser/offline_pages/offline_page_utils.h index 2917a92..5b340e0 100644 --- a/chrome/browser/offline_pages/offline_page_utils.h +++ b/chrome/browser/offline_pages/offline_page_utils.h
@@ -28,6 +28,7 @@ namespace offline_pages { struct OfflinePageHeader; struct OfflinePageItem; +struct PageCriteria; class OfflinePageUtils { public: @@ -72,6 +73,11 @@ int tab_id, base::OnceCallback<void(const std::vector<OfflinePageItem>&)> callback); + static void SelectPagesWithCriteria( + content::BrowserContext* browser_context, + const PageCriteria& criteria, + base::OnceCallback<void(const std::vector<OfflinePageItem>&)> callback); + // Gets the offline page corresponding to the given web contents. The // returned pointer is owned by the web_contents and may be deleted by user // navigation, so it is unsafe to store a copy of the returned pointer.
diff --git a/chrome/browser/policy/policy_network_browsertest.cc b/chrome/browser/policy/policy_network_browsertest.cc index 1a869a64..47809e2 100644 --- a/chrome/browser/policy/policy_network_browsertest.cc +++ b/chrome/browser/policy/policy_network_browsertest.cc
@@ -452,7 +452,8 @@ // QUIC is allowed, then disallowed by policy after the profile has been // initialized. -IN_PROC_BROWSER_TEST_F(QuicAllowedPolicyDynamicTest, QuicAllowedTrueThenFalse) { +IN_PROC_BROWSER_TEST_F(QuicAllowedPolicyDynamicTest, + DISABLED_QuicAllowedTrueThenFalse) { // After browser start, QuicAllowed=true comes in dynamically SetQuicAllowedPolicy(policy_for_profile_1(), true); EXPECT_TRUE(IsQuicEnabledForSystem());
diff --git a/chrome/browser/policy/test/policy_testserver.py b/chrome/browser/policy/test/policy_testserver.py index 3de8b36d5..a2ee88e 100644 --- a/chrome/browser/policy/test/policy_testserver.py +++ b/chrome/browser/policy/test/policy_testserver.py
@@ -411,7 +411,7 @@ is GoogleEnrollmentToken token from an Authorization header. Returns None if no token is present. """ - match = re.match('GoogleEnrollmentToken auth=(\\w+)', + match = re.match('GoogleEnrollmentToken token=(\\S+)', self.headers.getheader('Authorization', '')) if match: return match.group(1)
diff --git a/chrome/browser/resources/feedback/js/event_handler.js b/chrome/browser/resources/feedback/js/event_handler.js index e0fff4c..653cc0ae 100644 --- a/chrome/browser/resources/feedback/js/event_handler.js +++ b/chrome/browser/resources/feedback/js/event_handler.js
@@ -166,7 +166,6 @@ this.onSystemInfoReadyCallback_ = this.sendReportNow; return; } - this.sendReportNow(); } @@ -198,6 +197,9 @@ 'Feedback: Report for request with ID ' + ID + ' will be sent later.'); } + if (FLOW == chrome.feedbackPrivate.FeedbackFlow.LOGIN) { + chrome.feedbackPrivate.loginFeedbackComplete(); + } }); } @@ -208,6 +210,10 @@ onWindowClosed() { if (!this.reportIsBeingSent_) { this.isRequestCanceled_ = true; + if (this.feedbackInfo_.flow == + chrome.feedbackPrivate.FeedbackFlow.LOGIN) { + chrome.feedbackPrivate.loginFeedbackComplete(); + } } } }
diff --git a/chrome/browser/resources/feedback/js/feedback.js b/chrome/browser/resources/feedback/js/feedback.js index 609469a..6ed999e 100644 --- a/chrome/browser/resources/feedback/js/feedback.js +++ b/chrome/browser/resources/feedback/js/feedback.js
@@ -262,6 +262,9 @@ function cancel(e) { e.preventDefault(); scheduleWindowClose(); + if (feedbackInfo.flow == chrome.feedbackPrivate.FeedbackFlow.LOGIN) { + chrome.feedbackPrivate.loginFeedbackComplete(); + } } // <if expr="chromeos"> @@ -371,7 +374,7 @@ takeScreenshot(function(screenshotCanvas) { // We've taken our screenshot, show the feedback page without any // further delay. - window.webkitRequestAnimationFrame(function() { + window.requestAnimationFrame(function() { resizeAppWindow(); }); chrome.app.window.current().show();
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.js b/chrome/browser/resources/gaia_auth_host/authenticator.js index 07aa7c4..48d0de3d 100644 --- a/chrome/browser/resources/gaia_auth_host/authenticator.js +++ b/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -634,6 +634,8 @@ if (this.email_ && this.gaiaId_ && this.sessionIndex_) { this.maybeCompleteAuth_(); } + } else if (msg.method == 'showIncognito') { + this.dispatchEvent(new Event('showIncognito')); } else { console.warn('Unrecognized message from GAIA: ' + msg.method); }
diff --git a/chrome/browser/resources/inline_login/inline_login.js b/chrome/browser/resources/inline_login/inline_login.js index a4be6f05..a77f3313 100644 --- a/chrome/browser/resources/inline_login/inline_login.js +++ b/chrome/browser/resources/inline_login/inline_login.js
@@ -56,6 +56,10 @@ $('contents').classList.toggle('loading', true); } + function onShowIncognito() { + chrome.send('showIncognito'); + } + /** * Initialize the UI. */ @@ -67,6 +71,7 @@ authExtHost.addEventListener('newWindow', onNewWindow); authExtHost.addEventListener('resize', onResize); authExtHost.addEventListener('authCompleted', onAuthCompleted); + authExtHost.addEventListener('showIncognito', onShowIncognito); chrome.send('initialize'); }
diff --git a/chrome/browser/resources/management/management.html b/chrome/browser/resources/management/management.html index b682e7d..e238673 100644 --- a/chrome/browser/resources/management/management.html +++ b/chrome/browser/resources/management/management.html
@@ -4,6 +4,7 @@ <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no"> + <title>$i18n{title}</title> <link rel="stylesheet" href="chrome://resources/css/md_colors.css"> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> @@ -36,6 +37,4 @@ <body> <management-ui></management-ui> </body> - -<script src="management.js"></script> </html>
diff --git a/chrome/browser/resources/management/management.js b/chrome/browser/resources/management/management.js deleted file mode 100644 index d3b3ea01..0000000 --- a/chrome/browser/resources/management/management.js +++ /dev/null
@@ -1,10 +0,0 @@ -// Copyright 2019 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. - -cr.define('management', function() { - document.title = loadTimeData.getString('title'); - cr.addWebUIListener( - 'browser-reporting-info-updated', - () => document.title = loadTimeData.getString('title')); -});
diff --git a/chrome/browser/resources/management/management_browser_proxy.js b/chrome/browser/resources/management/management_browser_proxy.js index 29fa20c..ebe34d7c 100644 --- a/chrome/browser/resources/management/management_browser_proxy.js +++ b/chrome/browser/resources/management/management_browser_proxy.js
@@ -5,8 +5,8 @@ cr.exportPath('management'); /** * @typedef {{ - * name: string, - * permissions: !Array<string> + * name: string, + * permissions: !Array<string> * }} */ management.Extension; @@ -22,8 +22,8 @@ /** * @typedef {{ - * messageId: string, - * reportingType: !management.ReportingType, + * messageId: string, + * reportingType: !management.ReportingType, * }} */ management.BrowserReportingResponse; @@ -45,22 +45,40 @@ /** * @typedef {{ - * messageId: string, - * reportingType: !management.DeviceReportingType, + * messageId: string, + * reportingType: !management.DeviceReportingType, * }} */ management.DeviceReportingResponse; // </if> +/** + * @typedef {{ + * overview: string, + * setup: string, + * data: string, + * }} + */ +management.ManagedInfo; + +/** + * @typedef {{ + * overview: string, + * deviceManagedInfo: ?management.ManagedInfo, + * accountManagedInfo: ?management.ManagedInfo, + * }} + */ +management.ManagementStatus; + cr.define('management', function() { /** @interface */ class ManagementBrowserProxy { - /** @return {string} */ - getExtensionReportingTitle() {} - /** @return {!Promise<!Array<!management.Extension>>} */ getExtensions() {} + /** @return {!Promise<!management.ManagementStatus>} */ + getManagementStatus() {} + // <if expr="chromeos"> /** * @return {!Promise<boolean>} Boolean describing trust root configured @@ -80,9 +98,6 @@ getManagementNotice() {} // </if> - /** @return {string} */ - getPageTitle() {} - /** * @return {!Promise<!Array<!management.BrowserReportingResponse>>} The list * of browser reporting info messages. @@ -93,13 +108,13 @@ /** @implements {management.ManagementBrowserProxy} */ class ManagementBrowserProxyImpl { /** @override */ - getExtensionReportingTitle() { - return loadTimeData.getString('extensionsInstalled'); + getExtensions() { + return cr.sendWithPromise('getExtensions'); } /** @override */ - getExtensions() { - return cr.sendWithPromise('getExtensions'); + getManagementStatus() { + return cr.sendWithPromise('getManagementStatus'); } // <if expr="chromeos"> @@ -122,11 +137,6 @@ // </if> /** @override */ - getPageTitle() { - return loadTimeData.getString('title'); - } - - /** @override */ initBrowserReportingInfo() { return cr.sendWithPromise('initBrowserReportingInfo'); }
diff --git a/chrome/browser/resources/management/management_ui.html b/chrome/browser/resources/management/management_ui.html index 7024466..361ae91 100644 --- a/chrome/browser/resources/management/management_ui.html +++ b/chrome/browser/resources/management/management_ui.html
@@ -25,6 +25,14 @@ text-decoration: none; } + .page-subtitle a { + margin-inline-end: 32px; + } + + a iron-icon { + color: var(--cr-primary-text-color); + } + cr-toolbar { flex-shrink: 0; } @@ -80,8 +88,16 @@ justify-content: center; } - .three-line { - min-height: var(--cr-section-three-line-min-height); + .content-indented { + margin-inline-start: 20px; + } + + .overview-section div + div { + margin-top: 1em; + } + + .overview-messages div + div { + margin-top: 0; } <if expr="chromeos"> @@ -143,24 +159,56 @@ } </style> - <cr-toolbar page-name="[[title_]]" show-search="[[showSearchInToolbar_]]"> + <cr-toolbar page-name="$i18n{toolbarTitle}" + show-search="[[showSearchInToolbar_]]"> </cr-toolbar> <main id="mainContent"> <div class="sections-container"> <div class="card"> -<if expr="not chromeos"> - <section class="three-line single-column"> - <p inner-h-t-m-l="[[managementNoticeHtml_]]"></p> + <section class="page-subtitle"> + <a href="chrome://settings/help"> + <iron-icon icon="cr:arrow-back"></iron-icon> + </a> + [[subtitle_]] </section> + <section class="single-column overview-section"> +<if expr="not chromeos"> + <p inner-h-t-m-l="[[managementNoticeHtml_]]"></p> </if> <if expr="chromeos"> + <div>[[managementOverview_]]</div> + <div class="overview-messages" + hidden="[[!deviceManagedInfo_]]"> + [[deviceManagedInfo_.overview]] + <div class="content-indented"> + [[deviceManagedInfo_.setup]] + <a href="$i18nRaw{managementDeviceLearnMoreUrl}" + target="_blank">$i18n{learnMore}</a> + </div> + <div class="content-indented">[[deviceManagedInfo_.data]]</div> + </div> +</if> + <div class="overview-messages" hidden="[[!accountManagedInfo_]]"> + [[accountManagedInfo_.overview]] + <div class="content-indented"> +<if expr="chromeos"> + [[accountManagedInfo_.setup]] + <a href="$i18nRaw{managementAccountLearnMoreUrl}" + target="_blank">$i18n{learnMore}</a> +</if> +<if expr="not chromeos"> + [[accountManagedInfo_.setup]] +</if> + </div> + <div class="content-indented">[[accountManagedInfo_.data]]</div> + </div> + </section> +<if expr="chromeos"> <template is="dom-if" if="[[showDeviceReportingInfo_(deviceReportingInfo_)]]"> - <section class="three-line single-column"> + <section class="single-column"> <h2>$i18n{deviceReporting}</h2> - <div class="subtitle"> - $i18n{deviceConfiguration} - </div> + <div class="subtitle">$i18n{deviceConfiguration}</div> <template is="dom-repeat" items="[[deviceReportingInfo_]]"> <div class="device-reporting"> <span> @@ -173,9 +221,10 @@ </section> </template> </if> + <template is="dom-if" if="[[showBrowserReportingInfo_(browserReportingInfo_)]]"> - <section class="three-line single-column"> + <section class="single-column"> <h2>$i18n{browserReporting}</h2> <div class="subtitle"> $i18n{browserReportingExplanation} @@ -195,7 +244,7 @@ </template> <template is="dom-if" if="[[showExtensionReportingInfo_(extensions_)]]"> - <section class="three-line single-column"> + <section class="single-column"> <h2>$i18n{extensionReporting}</h2> <div class="subtitle">[[extensionReportingSubtitle_]]</div> <div class="extensions-list"> @@ -226,7 +275,7 @@ </template> <if expr="chromeos"> <template is="dom-if" if="[[localTrustRoots_]]"> - <section class="three-line single-column"> + <section class="single-column"> <h2>$i18n{localTrustRoots}</h2> <div id="trust-roots-configuration">[[localTrustRoots_]]</div> </section>
diff --git a/chrome/browser/resources/management/management_ui.js b/chrome/browser/resources/management/management_ui.js index 1d429da..7ed9dcf 100644 --- a/chrome/browser/resources/management/management_ui.js +++ b/chrome/browser/resources/management/management_ui.js
@@ -5,8 +5,8 @@ cr.exportPath('management'); /** * @typedef {{ - * messageIds: !Array<string>, - * icon: string, + * messageIds: !Array<string>, + * icon: string, * }} */ management.BrowserReportingData; @@ -44,8 +44,17 @@ * @private */ localTrustRoots_: String, + + /** @private */ + managementOverview_: String, + + /** @private {?management.ManagedInfo} */ + deviceManagedInfo_: Object, // </if> + /** @private {?management.ManagedInfo} */ + accountManagedInfo_: Object, + /** * Indicates if the search field in visible in the toolbar. * @private @@ -56,7 +65,7 @@ }, /** @private */ - title_: String, + subtitle_: String, // <if expr="not chromeos"> /** @private */ @@ -91,6 +100,7 @@ this.getDeviceReportingInfo_(); this.getLocalTrustRootsInfo_(); // </if> + this.getManagementStatus_(); }, /** @private */ @@ -128,6 +138,17 @@ }, /** @private */ + getManagementStatus_() { + this.browserProxy_.getManagementStatus().then(status => { + // <if expr="chromeos"> + this.managementOverview_ = status.overview; + this.deviceManagedInfo_ = status.deviceManagedInfo; + // </if> + this.accountManagedInfo_ = status.accountManagedInfo; + }); + }, + + /** @private */ getExtensions_() { this.browserProxy_.getExtensions().then(extensions => { this.extensions_ = extensions; @@ -225,11 +246,11 @@ /** @private */ updateManagedFields_() { - this.title_ = this.browserProxy_.getPageTitle(); + this.subtitle_ = loadTimeData.getString('subtitle'); // <if expr="not chromeos"> this.managementNoticeHtml_ = this.browserProxy_.getManagementNotice(); // </if> this.extensionReportingSubtitle_ = - this.browserProxy_.getExtensionReportingTitle(); + loadTimeData.getString('extensionReportingTitle'); }, });
diff --git a/chrome/browser/resources/md_extensions/options_dialog.html b/chrome/browser/resources/md_extensions/options_dialog.html index 419fab0..59ced39 100644 --- a/chrome/browser/resources/md_extensions/options_dialog.html +++ b/chrome/browser/resources/md_extensions/options_dialog.html
@@ -27,29 +27,19 @@ } cr-dialog { - --scroll-border: 0; --cr-dialog-body: { height: 100%; padding-bottom: 0; padding-inline-end: 0; padding-inline-start: 0; padding-top: 0; - }; - - --cr-dialog-wrapper: { - height: 100%; - max-height: initial; - overflow: hidden; - }; - + } + --cr-dialog-body-border-bottom: none; + --cr-dialog-body-border-top: none; --cr-dialog-body-container: { height: 100%; min-height: initial; - }; - - --cr-dialog-body-border-bottom: none; - --cr-dialog-body-border-top: none; - + } --cr-dialog-native: { opacity: 0; /* When loading, it's possible for an size update to follow after the @@ -57,7 +47,13 @@ A 100ms delay for the opacity transition will allow two updates to occur without showing the dialog resizing to the user. */ transition: opacity 100ms ease 100ms; - }; + } + --cr-dialog-wrapper: { + height: 100%; + max-height: initial; + overflow: hidden; + } + --scroll-border: none; } </style>
diff --git a/chrome/browser/resources/plugin_metadata/plugins_linux.json b/chrome/browser/resources/plugin_metadata/plugins_linux.json index b427556..78d32ee 100644 --- a/chrome/browser/resources/plugin_metadata/plugins_linux.json +++ b/chrome/browser/resources/plugin_metadata/plugins_linux.json
@@ -1,5 +1,5 @@ { - "x-version": 38, + "x-version": 39, "adobe-flash-player": { "mime_types": [ "application/futuresplash", @@ -10,9 +10,9 @@ ], "versions": [ { - "version": "32.0.0.142", + "version": "32.0.0.171", "status": "up_to_date", - "reference": "https://helpx.adobe.com/security/products/flash-player/apsb19-06.html" + "reference": "https://helpx.adobe.com/security/products/flash-player/apsb19-19.html" } ], "lang": "en-US",
diff --git a/chrome/browser/resources/plugin_metadata/plugins_mac.json b/chrome/browser/resources/plugin_metadata/plugins_mac.json index 06ce510..ed22d33 100644 --- a/chrome/browser/resources/plugin_metadata/plugins_mac.json +++ b/chrome/browser/resources/plugin_metadata/plugins_mac.json
@@ -1,5 +1,5 @@ { - "x-version": 44, + "x-version": 45, "adobe-flash-player": { "mime_types": [ "application/futuresplash", @@ -7,9 +7,9 @@ ], "versions": [ { - "version": "32.0.0.142", + "version": "32.0.0.171", "status": "requires_authorization", - "reference": "https://helpx.adobe.com/security/products/flash-player/apsb19-06.html" + "reference": "https://helpx.adobe.com/security/products/flash-player/apsb19-19.html" } ], "lang": "en-US",
diff --git a/chrome/browser/resources/plugin_metadata/plugins_win.json b/chrome/browser/resources/plugin_metadata/plugins_win.json index 2dedd10..0d449d1 100644 --- a/chrome/browser/resources/plugin_metadata/plugins_win.json +++ b/chrome/browser/resources/plugin_metadata/plugins_win.json
@@ -1,5 +1,5 @@ { - "x-version": 53, + "x-version": 54, "adobe-flash-player": { "mime_types": [ "application/futuresplash", @@ -7,9 +7,9 @@ ], "versions": [ { - "version": "32.0.0.142", + "version": "32.0.0.171", "status": "requires_authorization", - "reference": "https://helpx.adobe.com/security/products/flash-player/apsb19-06.html" + "reference": "https://helpx.adobe.com/security/products/flash-player/apsb19-19.html" } ], "lang": "en-US",
diff --git a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html index 6467115..e1e85f9 100644 --- a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html +++ b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html
@@ -18,7 +18,7 @@ <div class="settings-box first two-line"> <cr-input class="printer-name-input" autofocus id="printerName" - value="{{activePrinter.printerName}}" + value="{{pendingPrinter_.printerName}}" on-input="onPrinterInfoChange_" label="$i18n{printerName}" maxlength=64> @@ -27,8 +27,8 @@ <div class="settings-box two-line"> <cr-input label="$i18n{printerAddress}" id="printerAddress" - value="{{activePrinter.printerAddress}}" on-input="onPrinterInfoChange_" + value="{{pendingPrinter_.printerAddress}}" disabled="[[!networkProtocolActive_]]" maxlength=128> </cr-input> @@ -38,7 +38,7 @@ <div id="printerProtocol" class="label">$i18n{printerProtocol}</div> <div class="secondary"> <select class="md-select" aria-labelledby="printerProtocol" - value="[[activePrinter.printerProtocol]]" + value="[[pendingPrinter_.printerProtocol]]" on-change="onProtocolChange_" disabled="[[!networkProtocolActive_]]"> <option value="ipp" disabled="[[!networkProtocolActive_]]"> @@ -71,7 +71,7 @@ </div> <div class="settings-box two-line"> <cr-input id="printerQueue" label="$i18n{printerQueue}" - value="{{activePrinter.printerQueue}}" + value="{{pendingPrinter_.printerQueue}}" on-input="onPrinterInfoChange_" disabled="[[!networkProtocolActive_]]" maxlength=64> @@ -79,21 +79,21 @@ </div> <div class="settings-box two-line"> <cr-input label="$i18n{printerURI}" readonly - value="[[getPrinterURI_(activePrinter)]]"> + value="[[getPrinterURI_(pendingPrinter_)]]"> </cr-input> </div> <div class="settings-box two-line"> <cr-searchable-drop-down items="[[manufacturerList]]" id="printerPPDManufacturer" label="$i18n{printerManufacturer}" - value="{{activePrinter.ppdManufacturer}}"> + value="{{pendingPrinter_.ppdManufacturer}}"> </cr-searchable-drop-down> </div> <div class="settings-box two-line"> <cr-searchable-drop-down items="[[modelList]]" id="printerPPDModel" label="$i18n{printerModel}" - value="{{activePrinter.ppdModel}}"> + value="{{pendingPrinter_.ppdModel}}"> </cr-searchable-drop-down> </div> <div class="settings-box two-line"> @@ -113,8 +113,8 @@ $i18n{cancel} </paper-button> <paper-button class="action-button" on-click="onSaveTap_" - disabled="[[!canSavePrinter_(activePrinter.*, - printerInfoChanged_)]]"> + disabled="[[!canSavePrinter_(pendingPrinter_.*, + printerInfoChanged_)]]"> $i18n{editPrinterButtonText} </paper-button> </div>
diff --git a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js index 2180914..cb0d4a22 100644 --- a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js +++ b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js
@@ -15,11 +15,18 @@ ], properties: { - /** @type {!CupsPrinterInfo} */ - activePrinter: { - type: Object, - notify: true, - }, + /** + * The currently saved printer. + * @type {CupsPrinterInfo} + */ + activePrinter: Object, + + /** + * Printer that holds the modified changes to activePrinter and only + * applies these changes when the save button is clicked. + * @type {CupsPrinterInfo} + */ + pendingPrinter_: Object, /** * If the printer needs to be re-configured. @@ -62,7 +69,7 @@ networkProtocolActive_: { type: Boolean, - computed: 'isNetworkProtocol_(activePrinter.printerProtocol)', + computed: 'isNetworkProtocol_(pendingPrinter_.printerProtocol)', }, /** @type {?Array<string>} */ @@ -88,15 +95,18 @@ }, observers: [ - 'printerPathChanged_(activePrinter.*)', - 'selectedEditManufacturerChanged_(activePrinter.ppdManufacturer)', - 'onModelChanged_(activePrinter.ppdModel)', + 'printerPathChanged_(pendingPrinter_.*)', + 'selectedEditManufacturerChanged_(pendingPrinter_.ppdManufacturer)', + 'onModelChanged_(pendingPrinter_.ppdModel)', ], /** @override */ attached: function() { + // Create a copy of activePrinter so that we can modify its fields. + this.pendingPrinter_ = /** @type{CupsPrinterInfo} */ + (Object.assign({}, this.activePrinter)); settings.CupsPrintersBrowserProxyImpl.getInstance() - .getPrinterPpdManufacturerAndModel(this.activePrinter.printerId) + .getPrinterPpdManufacturerAndModel(this.pendingPrinter_.printerId) .then( this.onGetPrinterPpdManufacturerAndModel_.bind(this), this.onGetPrinterPpdManufacturerAndModelFailed_.bind(this)); @@ -104,7 +114,7 @@ .getCupsPrinterManufacturersList() .then(this.manufacturerListChanged_.bind(this)); this.userPPD_ = - settings.printing.getBaseName(this.activePrinter.printerPPDPath); + settings.printing.getBaseName(this.pendingPrinter_.printerPPDPath); }, /** @@ -112,7 +122,7 @@ * @private */ printerPathChanged_: function(change) { - if (change.path != 'activePrinter.printerName') { + if (change.path != 'pendingPrinter_.printerName') { this.needsReconfigured_ = true; } }, @@ -122,7 +132,7 @@ * @private */ onProtocolChange_: function(event) { - this.set('activePrinter.printerProtocol', event.target.value); + this.set('pendingPrinter_.printerProtocol', event.target.value); this.onPrinterInfoChange_(); }, @@ -138,6 +148,7 @@ /** @private */ onSaveTap_: function() { + this.updateActivePrinter_(); if (this.needsReconfigured_) { settings.CupsPrintersBrowserProxyImpl.getInstance() .reconfigureCupsPrinter(this.activePrinter); @@ -174,8 +185,8 @@ * @private */ onGetPrinterPpdManufacturerAndModel_: function(info) { - this.set('activePrinter.ppdManufacturer', info.ppdManufacturer); - this.set('activePrinter.ppdModel', info.ppdModel); + this.set('pendingPrinter_.ppdManufacturer', info.ppdManufacturer); + this.set('pendingPrinter_.ppdModel', info.ppdModel); // |needsReconfigured_| needs to reset to false after |ppdManufacturer| and // |ppdModel| are initialized to their correct values. @@ -214,7 +225,7 @@ */ selectedEditManufacturerChanged_: function(manufacturer) { // Reset model if manufacturer is changed. - this.set('activePrinter.ppdModel', ''); + this.set('pendingPrinter_.ppdModel', ''); this.modelList = []; if (!!manufacturer && manufacturer.length != 0) { settings.CupsPrintersBrowserProxyImpl.getInstance() @@ -249,9 +260,9 @@ return; } this.manufacturerList = manufacturersInfo.manufacturers; - if (this.activePrinter.ppdManufacturer.length != 0) { + if (this.pendingPrinter_.ppdManufacturer.length != 0) { settings.CupsPrintersBrowserProxyImpl.getInstance() - .getCupsPrinterModelsList(this.activePrinter.ppdManufacturer) + .getCupsPrinterModelsList(this.pendingPrinter_.ppdManufacturer) .then(this.modelListChanged_.bind(this)); } }, @@ -263,7 +274,7 @@ modelListChanged_: function(modelsInfo) { if (modelsInfo.success) { this.modelList = modelsInfo.models; - // ModelListChanged_ is the final step of initializing activePrinter. + // ModelListChanged_ is the final step of initializing pendingPrinter. this.arePrinterFieldsInitialized_ = true; } }, @@ -273,7 +284,7 @@ * @private */ printerPPDPathChanged_: function(path) { - this.set('activePrinter.printerPPDPath', path); + this.set('pendingPrinter_.printerPPDPath', path); this.invalidPPD_ = !path; if (!this.invalidPPD_) { // A new valid PPD file should be treated as a saveable change. @@ -287,9 +298,21 @@ * @return {boolean} */ isPrinterValid: function() { - return settings.printing.isNameAndAddressValid(this.activePrinter) && + return settings.printing.isNameAndAddressValid(this.pendingPrinter_) && settings.printing.isPPDInfoValid( - this.activePrinter.ppdManufacturer, this.activePrinter.ppdModel, - this.activePrinter.printerPPDPath); + this.pendingPrinter_.ppdManufacturer, this.pendingPrinter_.ppdModel, + this.pendingPrinter_.printerPPDPath); + }, + + /* + * Helper function to copy over modified fields to activePrinter. + * @private + */ + updateActivePrinter_: function() { + this.activePrinter = + /** @type{CupsPrinterInfo} */ (Object.assign({}, this.pendingPrinter_)); + // Set ppdModel since there is an observer that clears ppdmodel's value when + // ppdManufacturer changes. + this.activePrinter.ppdModel = this.pendingPrinter_.ppdModel; }, });
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.html b/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.html index ad45e1e..96abaa0 100644 --- a/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.html +++ b/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.html
@@ -16,7 +16,7 @@ cr-input { display: inline-block; padding-inline-end: 2em; - width: 8em; + --cr-input-width: 8em; } #newPINRow {
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service_browsertest.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service_browsertest.cc index e21f10e..733eafa 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_service_browsertest.cc +++ b/chrome/browser/safe_browsing/download_protection/download_protection_service_browsertest.cc
@@ -5,11 +5,13 @@ #include "base/files/file_path.h" #include "base/path_service.h" #include "base/run_loop.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_paths.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/safe_browsing/features.h" #include "components/safe_browsing/proto/csd.pb.h" #include "components/safe_browsing/web_ui/safe_browsing_ui.h" #include "content/public/browser/browser_context.h" @@ -25,6 +27,11 @@ class DownloadProtectionServiceBrowserTest : public InProcessBrowserTest { protected: + void SetUp() override { + scoped_feature_list_.InitAndEnableFeature(kInspectRarContentFeature); + InProcessBrowserTest::SetUp(); + } + base::FilePath GetTestDataDirectory() { base::FilePath test_file_directory; base::PathService::Get(chrome::DIR_TEST_DATA, &test_file_directory); @@ -56,6 +63,9 @@ // echo "BBBBBBBBB" > a.zip // sha256sum a.zip static const uint8_t kBZipDigest[]; + + private: + base::test::ScopedFeatureList scoped_feature_list_; }; const uint8_t DownloadProtectionServiceBrowserTest::kAZipDigest[] = {
diff --git a/chrome/browser/signin/chrome_signin_helper.cc b/chrome/browser/signin/chrome_signin_helper.cc index 2e70a22..70359b1 100644 --- a/chrome/browser/signin/chrome_signin_helper.cc +++ b/chrome/browser/signin/chrome_signin_helper.cc
@@ -64,6 +64,9 @@ namespace signin { +const void* const kManageAccountsHeaderReceivedUserDataKey = + &kManageAccountsHeaderReceivedUserDataKey; + namespace { const char kChromeManageAccountsHeader[] = "X-Chrome-Manage-Accounts"; @@ -161,6 +164,12 @@ DISALLOW_COPY_AND_ASSIGN(RequestDestructionObserverUserData); }; +// This user data is used as a marker that a Mirror header was found on the +// redirect chain. It does not contain any data, its presence is enough to +// indicate that a header has already be found on the request. +class ManageAccountsHeaderReceivedUserData + : public base::SupportsUserData::Data {}; + // Processes the mirror response header on the UI thread. Currently depending // on the value of |header_value|, it either shows the profile avatar menu, or // opens an incognito window/tab. @@ -327,13 +336,11 @@ void ProcessMirrorResponseHeaderIfExists(ResponseAdapter* response, bool is_off_the_record) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + DCHECK(gaia::IsGaiaSignonRealm(response->GetOrigin())); if (!response->IsMainFrame()) return; - if (!gaia::IsGaiaSignonRealm(response->GetOrigin())) - return; - const net::HttpResponseHeaders* response_headers = response->GetHeaders(); if (!response_headers) return; @@ -356,6 +363,18 @@ if (params.service_type == GAIA_SERVICE_TYPE_NONE) return; + // Only process one mirror header per request (multiple headers on the same + // redirect chain are ignored). + if (response->GetUserData(kManageAccountsHeaderReceivedUserDataKey)) { + LOG(ERROR) << "Multiple X-Chrome-Manage-Accounts headers on a redirect " + << "chain, ignoring"; + return; + } + + response->SetUserData( + kManageAccountsHeaderReceivedUserDataKey, + std::make_unique<ManageAccountsHeaderReceivedUserData>()); + base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, base::BindOnce(ProcessMirrorHeaderUIThread, params, response->GetWebContentsGetter())); @@ -365,13 +384,11 @@ void ProcessDiceResponseHeaderIfExists(ResponseAdapter* response, bool is_off_the_record) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + DCHECK(gaia::IsGaiaSignonRealm(response->GetOrigin())); if (is_off_the_record) return; - if (!gaia::IsGaiaSignonRealm(response->GetOrigin())) - return; - const net::HttpResponseHeaders* response_headers = response->GetHeaders(); if (!response_headers) return; @@ -436,7 +453,7 @@ std::make_unique<RequestDestructionObserverUserData>(std::move(closure))); } -ResponseAdapter::ResponseAdapter(const net::URLRequest* request) +ResponseAdapter::ResponseAdapter(net::URLRequest* request) : request_(request) {} ResponseAdapter::~ResponseAdapter() = default; @@ -464,6 +481,17 @@ request_->response_headers()->RemoveHeader(name); } +base::SupportsUserData::Data* ResponseAdapter::GetUserData( + const void* key) const { + return request_->GetUserData(key); +} + +void ResponseAdapter::SetUserData( + const void* key, + std::unique_ptr<base::SupportsUserData::Data> data) { + request_->SetUserData(key, std::move(data)); +} + void SetDiceAccountReconcilorBlockDelayForTesting(int delay_ms) { g_dice_account_reconcilor_blocked_delay_ms = delay_ms; } @@ -538,14 +566,13 @@ void ProcessAccountConsistencyResponseHeaders(ResponseAdapter* response, const GURL& redirect_url, bool is_off_the_record) { - if (redirect_url.is_empty()) { - // This is not a redirect. + if (!gaia::IsGaiaSignonRealm(response->GetOrigin())) + return; - // See if the response contains the X-Chrome-Manage-Accounts header. If so - // show the profile avatar bubble so that user can complete signin/out - // action the native UI. - ProcessMirrorResponseHeaderIfExists(response, is_off_the_record); - } + // See if the response contains the X-Chrome-Manage-Accounts header. If so + // show the profile avatar bubble so that user can complete signin/out + // action the native UI. + ProcessMirrorResponseHeaderIfExists(response, is_off_the_record); #if BUILDFLAG(ENABLE_DICE_SUPPORT) // Process the Dice header: on sign-in, exchange the authorization code for a
diff --git a/chrome/browser/signin/chrome_signin_helper.h b/chrome/browser/signin/chrome_signin_helper.h index 71eccf48..940e7c0 100644 --- a/chrome/browser/signin/chrome_signin_helper.h +++ b/chrome/browser/signin/chrome_signin_helper.h
@@ -5,9 +5,11 @@ #ifndef CHROME_BROWSER_SIGNIN_CHROME_SIGNIN_HELPER_H_ #define CHROME_BROWSER_SIGNIN_CHROME_SIGNIN_HELPER_H_ +#include <memory> #include <string> #include "base/macros.h" +#include "base/supports_user_data.h" #include "components/signin/core/browser/signin_header_helper.h" #include "content/public/browser/resource_request_info.h" @@ -26,6 +28,9 @@ // handle signin accordingly. namespace signin { +// Key for ManageAccountsHeaderReceivedUserData. Exposed for testing. +extern const void* const kManageAccountsHeaderReceivedUserDataKey; + class ChromeRequestAdapter : public RequestAdapter { public: explicit ChromeRequestAdapter(net::URLRequest* request); @@ -48,7 +53,7 @@ class ResponseAdapter { public: - explicit ResponseAdapter(const net::URLRequest* request); + explicit ResponseAdapter(net::URLRequest* request); virtual ~ResponseAdapter(); virtual content::ResourceRequestInfo::WebContentsGetter GetWebContentsGetter() @@ -58,8 +63,12 @@ virtual const net::HttpResponseHeaders* GetHeaders() const; virtual void RemoveHeader(const std::string& name); + virtual base::SupportsUserData::Data* GetUserData(const void* key) const; + virtual void SetUserData(const void* key, + std::unique_ptr<base::SupportsUserData::Data> data); + private: - const net::URLRequest* const request_; + net::URLRequest* const request_; DISALLOW_COPY_AND_ASSIGN(ResponseAdapter); };
diff --git a/chrome/browser/signin/chrome_signin_helper_unittest.cc b/chrome/browser/signin/chrome_signin_helper_unittest.cc index f3a27ece..432b18b 100644 --- a/chrome/browser/signin/chrome_signin_helper_unittest.cc +++ b/chrome/browser/signin/chrome_signin_helper_unittest.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/signin/scoped_account_consistency.h" #include "components/signin/core/browser/account_consistency_method.h" #include "components/signin/core/browser/signin_buildflags.h" +#include "components/signin/core/browser/signin_header_helper.h" #include "content/public/browser/resource_request_info.h" #include "content/public/test/test_browser_thread_bundle.h" #include "net/http/http_response_headers.h" @@ -27,28 +28,34 @@ namespace { -#if BUILDFLAG(ENABLE_DICE_SUPPORT) - +const char kChromeManageAccountsHeader[] = "X-Chrome-Manage-Accounts"; +const char kMirrorAction[] = "action=ADDSESSION"; const GURL kGaiaUrl("https://accounts.google.com"); -const char kDiceResponseHeader[] = "X-Chrome-ID-Consistency-Response"; -// URLRequestInterceptor adding a Dice response header to Gaia responses. +// URLRequestInterceptor adding a account consistency response header to Gaia +// responses. class TestRequestInterceptor : public net::URLRequestInterceptor { public: - ~TestRequestInterceptor() override {} + explicit TestRequestInterceptor(const std::string& header_name, + const std::string& header_value) + : header_name_(header_name), header_value_(header_value) {} + ~TestRequestInterceptor() override = default; private: net::URLRequestJob* MaybeInterceptRequest( net::URLRequest* request, net::NetworkDelegate* network_delegate) const override { std::string response_headers = - base::StringPrintf("HTTP/1.1 200 OK\n\n%s: Foo\n", kDiceResponseHeader); + base::StringPrintf("HTTP/1.1 200 OK\n\n%s: %s\n", header_name_.c_str(), + header_value_.c_str()); return new net::URLRequestTestJob(request, network_delegate, response_headers, "", true); } + + const std::string header_name_; + const std::string header_value_; }; -#endif // BUILDFLAG(ENABLE_DICE_SUPPORT) } // namespace @@ -59,6 +66,32 @@ ~ChromeSigninHelperTest() override {} + void SetupRequest(const std::string& header_name, + const std::string& header_value, + bool is_main_frame) { + test_request_delegate_ = std::make_unique<net::TestDelegate>(); + request_ = url_request_context_.CreateRequest( + kGaiaUrl, net::DEFAULT_PRIORITY, test_request_delegate_.get(), + TRAFFIC_ANNOTATION_FOR_TESTS); + content::ResourceRequestInfo::AllocateForTesting( + request_.get(), + is_main_frame ? content::RESOURCE_TYPE_MAIN_FRAME + : content::RESOURCE_TYPE_SUB_FRAME, + nullptr, -1, -1, -1, true, content::ResourceInterceptPolicy::kAllowNone, + true, content::PREVIEWS_OFF, nullptr); + net::URLRequestFilter::GetInstance()->AddUrlInterceptor( + kGaiaUrl, + std::make_unique<TestRequestInterceptor>(header_name, header_value)); + request_->Start(); + base::RunLoop().RunUntilIdle(); + net::URLRequestFilter::GetInstance()->RemoveUrlHandler(kGaiaUrl); + + // Check that the response header is correctly set. + net::HttpResponseHeaders* response_headers = request_->response_headers(); + ASSERT_TRUE(response_headers); + ASSERT_TRUE(request_->response_headers()->HasHeader(header_name)); + } + content::TestBrowserThreadBundle thread_bundle_; net::TestURLRequestContext url_request_context_; std::unique_ptr<net::TestDelegate> test_request_delegate_; @@ -71,24 +104,7 @@ ScopedAccountConsistencyDiceMigration scoped_dice_migration; // Create a response with the Dice header. - test_request_delegate_ = std::make_unique<net::TestDelegate>(); - request_ = url_request_context_.CreateRequest(kGaiaUrl, net::DEFAULT_PRIORITY, - test_request_delegate_.get(), - TRAFFIC_ANNOTATION_FOR_TESTS); - content::ResourceRequestInfo::AllocateForTesting( - request_.get(), content::RESOURCE_TYPE_MAIN_FRAME, nullptr, -1, -1, -1, - true, content::ResourceInterceptPolicy::kAllowNone, true, - content::PREVIEWS_OFF, nullptr); - net::URLRequestFilter::GetInstance()->AddUrlInterceptor( - kGaiaUrl, std::make_unique<TestRequestInterceptor>()); - request_->Start(); - base::RunLoop().RunUntilIdle(); - net::URLRequestFilter::GetInstance()->RemoveUrlHandler(kGaiaUrl); - - // Check that the Dice response header is correctly set. - net::HttpResponseHeaders* response_headers = request_->response_headers(); - ASSERT_TRUE(response_headers); - ASSERT_TRUE(request_->response_headers()->HasHeader(kDiceResponseHeader)); + SetupRequest(signin::kDiceResponseHeader, "Foo", /*is_main_frame=*/false); // Process the header. signin::ResponseAdapter response_adapter(request_.get()); @@ -96,6 +112,44 @@ false /* is_incognito */); // Check that the header has been removed. - EXPECT_FALSE(request_->response_headers()->HasHeader(kDiceResponseHeader)); + EXPECT_FALSE( + request_->response_headers()->HasHeader(signin::kDiceResponseHeader)); } #endif // BUILDFLAG(ENABLE_DICE_SUPPORT) + +// Tests that user data is set on Mirror requests. +TEST_F(ChromeSigninHelperTest, MirrorMainFrame) { + ScopedAccountConsistencyMirror scoped_mirror; + + // Create a response with the Mirror header. + SetupRequest(kChromeManageAccountsHeader, kMirrorAction, + /*is_main_frame=*/true); + + // Process the header. + signin::ResponseAdapter response_adapter(request_.get()); + signin::ProcessAccountConsistencyResponseHeaders(&response_adapter, GURL(), + false /* is_incognito */); + // Check that the header has not been removed. + EXPECT_TRUE( + request_->response_headers()->HasHeader(kChromeManageAccountsHeader)); + // Request was flagged with the user data. + EXPECT_TRUE( + request_->GetUserData(signin::kManageAccountsHeaderReceivedUserDataKey)); +} + +// Tests that user data is not set on Mirror requests for sub frames. +TEST_F(ChromeSigninHelperTest, MirrorSubFrame) { + ScopedAccountConsistencyMirror scoped_mirror; + + // Create a response with the Mirror header. + SetupRequest(kChromeManageAccountsHeader, kMirrorAction, + /*is_main_frame=*/false); + + // Process the header. + signin::ResponseAdapter response_adapter(request_.get()); + signin::ProcessAccountConsistencyResponseHeaders(&response_adapter, GURL(), + false /* is_incognito */); + // Request was not flagged with the user data. + EXPECT_FALSE( + request_->GetUserData(signin::kManageAccountsHeaderReceivedUserDataKey)); +}
diff --git a/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc b/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc index 7468ceb32..381250b96 100644 --- a/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc +++ b/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc
@@ -6,6 +6,7 @@ #include "base/barrier_closure.h" #include "base/bind.h" +#include "base/supports_user_data.h" #include "base/task/post_task.h" #include "build/buildflag.h" #include "chrome/browser/profiles/profile.h" @@ -84,7 +85,8 @@ class ProxyingURLLoaderFactory::InProgressRequest : public network::mojom::URLLoader, - public network::mojom::URLLoaderClient { + public network::mojom::URLLoaderClient, + public base::SupportsUserData { public: InProgressRequest( ProxyingURLLoaderFactory* factory, @@ -263,7 +265,7 @@ class ProxyingURLLoaderFactory::InProgressRequest::ProxyResponseAdapter : public ResponseAdapter { public: - ProxyResponseAdapter(const InProgressRequest* in_progress_request, + ProxyResponseAdapter(InProgressRequest* in_progress_request, net::HttpResponseHeaders* headers) : ResponseAdapter(nullptr), in_progress_request_(in_progress_request), @@ -296,8 +298,18 @@ headers_->RemoveHeader(name); } + base::SupportsUserData::Data* GetUserData(const void* key) const override { + return in_progress_request_->GetUserData(key); + } + + void SetUserData( + const void* key, + std::unique_ptr<base::SupportsUserData::Data> data) override { + in_progress_request_->SetUserData(key, std::move(data)); + } + private: - const InProgressRequest* const in_progress_request_; + InProgressRequest* const in_progress_request_; net::HttpResponseHeaders* const headers_; DISALLOW_COPY_AND_ASSIGN(ProxyResponseAdapter);
diff --git a/chrome/browser/signin/chrome_signin_proxying_url_loader_factory_unittest.cc b/chrome/browser/signin/chrome_signin_proxying_url_loader_factory_unittest.cc index 1e9cfd84..b71dc610 100644 --- a/chrome/browser/signin/chrome_signin_proxying_url_loader_factory_unittest.cc +++ b/chrome/browser/signin/chrome_signin_proxying_url_loader_factory_unittest.cc
@@ -202,6 +202,12 @@ adapter->SetDestructionCallback(ignored_destruction_callback.Get()); })); + const void* const kResponseUserDataKey = &kResponseUserDataKey; + std::unique_ptr<base::SupportsUserData::Data> response_user_data = + std::make_unique<base::SupportsUserData::Data>(); + base::SupportsUserData::Data* response_user_data_ptr = + response_user_data.get(); + // The delegate will also be called twice to process a response, first when // the redirect is received and again for the redirect response. EXPECT_CALL(*delegate, ProcessResponse(_, _)) @@ -209,6 +215,11 @@ EXPECT_EQ(GURL("https://google.com"), adapter->GetOrigin()); EXPECT_TRUE(adapter->IsMainFrame()); + adapter->SetUserData(kResponseUserDataKey, + std::move(response_user_data)); + EXPECT_EQ(response_user_data_ptr, + adapter->GetUserData(kResponseUserDataKey)); + const net::HttpResponseHeaders* headers = adapter->GetHeaders(); EXPECT_TRUE(headers->HasHeader("X-Response-1")); EXPECT_TRUE(headers->HasHeader("X-Response-2")); @@ -220,6 +231,9 @@ EXPECT_EQ(GURL("https://youtube.com"), adapter->GetOrigin()); EXPECT_TRUE(adapter->IsMainFrame()); + EXPECT_EQ(response_user_data_ptr, + adapter->GetUserData(kResponseUserDataKey)); + const net::HttpResponseHeaders* headers = adapter->GetHeaders(); // This is a new response and so previous headers should not carry over. EXPECT_FALSE(headers->HasHeader("X-Response-1"));
diff --git a/chrome/browser/signin/chrome_signin_url_loader_throttle.cc b/chrome/browser/signin/chrome_signin_url_loader_throttle.cc index 87d23936..9adf2a2 100644 --- a/chrome/browser/signin/chrome_signin_url_loader_throttle.cc +++ b/chrome/browser/signin/chrome_signin_url_loader_throttle.cc
@@ -113,6 +113,16 @@ headers_->RemoveHeader(name); } + base::SupportsUserData::Data* GetUserData(const void* key) const override { + return throttle_->GetUserData(key); + } + + void SetUserData( + const void* key, + std::unique_ptr<base::SupportsUserData::Data> data) override { + throttle_->SetUserData(key, std::move(data)); + } + private: URLLoaderThrottle* const throttle_; net::HttpResponseHeaders* headers_;
diff --git a/chrome/browser/signin/chrome_signin_url_loader_throttle.h b/chrome/browser/signin/chrome_signin_url_loader_throttle.h index fd958e5..d54daf0 100644 --- a/chrome/browser/signin/chrome_signin_url_loader_throttle.h +++ b/chrome/browser/signin/chrome_signin_url_loader_throttle.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_SIGNIN_CHROME_SIGNIN_URL_LOADER_THROTTLE_H_ #include "base/macros.h" +#include "base/supports_user_data.h" #include "content/public/browser/resource_request_info.h" #include "content/public/common/url_loader_throttle.h" @@ -19,7 +20,8 @@ // This class is used to modify the main frame request made when loading the // GAIA signin realm. -class URLLoaderThrottle : public content::URLLoaderThrottle { +class URLLoaderThrottle : public content::URLLoaderThrottle, + public base::SupportsUserData { public: // Creates a new throttle if |delegate| says that this request should be // intercepted.
diff --git a/chrome/browser/signin/chrome_signin_url_loader_throttle_unittest.cc b/chrome/browser/signin/chrome_signin_url_loader_throttle_unittest.cc index b82310c1..1691cc1 100644 --- a/chrome/browser/signin/chrome_signin_url_loader_throttle_unittest.cc +++ b/chrome/browser/signin/chrome_signin_url_loader_throttle_unittest.cc
@@ -107,11 +107,22 @@ // Phase 2: Redirect the request. const GURL kTestRedirectURL("https://youtube.com/index.html"); + const void* const kResponseUserDataKey = &kResponseUserDataKey; + std::unique_ptr<base::SupportsUserData::Data> response_user_data = + std::make_unique<base::SupportsUserData::Data>(); + base::SupportsUserData::Data* response_user_data_ptr = + response_user_data.get(); + EXPECT_CALL(*delegate, ProcessResponse(_, _)) .WillOnce(Invoke([&](ResponseAdapter* adapter, const GURL& redirect_url) { EXPECT_EQ(GURL("https://google.com"), adapter->GetOrigin()); EXPECT_TRUE(adapter->IsMainFrame()); + adapter->SetUserData(kResponseUserDataKey, + std::move(response_user_data)); + EXPECT_EQ(response_user_data_ptr, + adapter->GetUserData(kResponseUserDataKey)); + const net::HttpResponseHeaders* headers = adapter->GetHeaders(); EXPECT_TRUE(headers->HasHeader("X-Response-1")); EXPECT_TRUE(headers->HasHeader("X-Response-2")); @@ -184,6 +195,9 @@ EXPECT_EQ(GURL("https://youtube.com"), adapter->GetOrigin()); EXPECT_TRUE(adapter->IsMainFrame()); + EXPECT_EQ(response_user_data_ptr, + adapter->GetUserData(kResponseUserDataKey)); + const net::HttpResponseHeaders* headers = adapter->GetHeaders(); // This is a new response and so previous headers should not carry over. EXPECT_FALSE(headers->HasHeader("X-Response-1"));
diff --git a/chrome/browser/signin/identity_manager_factory.cc b/chrome/browser/signin/identity_manager_factory.cc index 7d3fed22..69ee9ef 100644 --- a/chrome/browser/signin/identity_manager_factory.cc +++ b/chrome/browser/signin/identity_manager_factory.cc
@@ -13,7 +13,7 @@ #include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/chrome_signin_client_factory.h" -#include "chrome/browser/signin/profile_oauth2_token_service_builder.h" +#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/keyed_service/core/keyed_service.h" #include "components/pref_registry/pref_registry_syncable.h" @@ -30,8 +30,6 @@ #endif #if !defined(OS_ANDROID) -#include "chrome/browser/web_data_service_factory.h" -#include "components/signin/core/browser/mutable_profile_oauth2_token_service_delegate.h" #include "services/identity/public/cpp/accounts_mutator_impl.h" #endif @@ -63,12 +61,12 @@ // current platform. std::unique_ptr<identity::AccountsMutator> BuildAccountsMutator( Profile* profile, - ProfileOAuth2TokenService* token_service, SigninManagerBase* signin_manager) { #if !defined(OS_ANDROID) return std::make_unique<identity::AccountsMutatorImpl>( - token_service, AccountTrackerServiceFactory::GetForProfile(profile), - signin_manager, profile->GetPrefs()); + ProfileOAuth2TokenServiceFactory::GetForProfile(profile), + AccountTrackerServiceFactory::GetForProfile(profile), signin_manager, + profile->GetPrefs()); #else return nullptr; #endif @@ -76,18 +74,17 @@ std::unique_ptr<ConcreteSigninManager> BuildSigninManager( Profile* profile, - ProfileOAuth2TokenService* token_service, GaiaCookieManagerService* gaia_cookie_manager_service) { std::unique_ptr<ConcreteSigninManager> signin_manager; SigninClient* client = ChromeSigninClientFactory::GetInstance()->GetForProfile(profile); #if defined(OS_CHROMEOS) signin_manager = std::make_unique<ConcreteSigninManager>( - client, token_service, + client, ProfileOAuth2TokenServiceFactory::GetForProfile(profile), AccountTrackerServiceFactory::GetForProfile(profile)); #else signin_manager = std::make_unique<ConcreteSigninManager>( - client, token_service, + client, ProfileOAuth2TokenServiceFactory::GetForProfile(profile), AccountTrackerServiceFactory::GetForProfile(profile), gaia_cookie_manager_service, AccountConsistencyModeManager::GetMethodForProfile(profile)); @@ -120,7 +117,6 @@ public: explicit IdentityManagerWrapper( Profile* profile, - std::unique_ptr<ProfileOAuth2TokenService> token_service, std::unique_ptr<GaiaCookieManagerService> gaia_cookie_manager_service, std::unique_ptr<SigninManagerBase> signin_manager, std::unique_ptr<AccountFetcherService> account_fetcher_service, @@ -130,10 +126,10 @@ accounts_cookie_mutator, std::unique_ptr<identity::DiagnosticsProviderImpl> diagnostics_provider) : identity::IdentityManager( - std::move(token_service), std::move(gaia_cookie_manager_service), std::move(signin_manager), std::move(account_fetcher_service), + ProfileOAuth2TokenServiceFactory::GetForProfile(profile), AccountTrackerServiceFactory::GetForProfile(profile), std::move(primary_account_mutator), std::move(accounts_mutator), @@ -147,20 +143,15 @@ void IdentityManagerFactory::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { identity::IdentityManager::RegisterProfilePrefs(registry); -#if !defined(OS_ANDROID) - MutableProfileOAuth2TokenServiceDelegate::RegisterProfilePrefs(registry); -#endif } IdentityManagerFactory::IdentityManagerFactory() : BrowserContextKeyedServiceFactory( "IdentityManager", BrowserContextDependencyManager::GetInstance()) { -#if !defined(OS_ANDROID) - DependsOn(WebDataServiceFactory::GetInstance()); -#endif DependsOn(AccountTrackerServiceFactory::GetInstance()); DependsOn(ChromeSigninClientFactory::GetInstance()); + DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); } IdentityManagerFactory::~IdentityManagerFactory() {} @@ -190,6 +181,7 @@ IdentityManagerFactory::GetInstance(); AccountTrackerServiceFactory::GetInstance(); ChromeSigninClientFactory::GetInstance(); + ProfileOAuth2TokenServiceFactory::GetInstance(); } void IdentityManagerFactory::AddObserver(Observer* observer) { @@ -205,44 +197,35 @@ Profile* profile = Profile::FromBrowserContext(context); // Construct the dependencies that IdentityManager will own. - auto token_service = - ProfileOAuth2TokenServiceBuilder::BuildInstanceFor(context); - auto gaia_cookie_manager_service = std::make_unique<GaiaCookieManagerService>( - token_service.get(), ChromeSigninClientFactory::GetForProfile(profile)); - - std::unique_ptr<ConcreteSigninManager> signin_manager = BuildSigninManager( - profile, token_service.get(), gaia_cookie_manager_service.get()); - + ProfileOAuth2TokenServiceFactory::GetForProfile(profile), + ChromeSigninClientFactory::GetForProfile(profile)); + std::unique_ptr<ConcreteSigninManager> signin_manager = + BuildSigninManager(profile, gaia_cookie_manager_service.get()); std::unique_ptr<identity::PrimaryAccountMutator> primary_account_mutator = BuildPrimaryAccountMutator(profile, signin_manager.get()); - std::unique_ptr<identity::AccountsMutator> accounts_mutator = - BuildAccountsMutator(profile, token_service.get(), signin_manager.get()); - + BuildAccountsMutator(profile, signin_manager.get()); auto accounts_cookie_mutator = std::make_unique<identity::AccountsCookieMutatorImpl>( gaia_cookie_manager_service.get()); - auto diagnostics_provider = std::make_unique<identity::DiagnosticsProviderImpl>( - token_service.get(), gaia_cookie_manager_service.get()); - + ProfileOAuth2TokenServiceFactory::GetForProfile(profile), + gaia_cookie_manager_service.get()); std::unique_ptr<AccountFetcherService> account_fetcher_service = BuildAccountFetcherService( ChromeSigninClientFactory::GetForProfile(profile), - token_service.get(), + ProfileOAuth2TokenServiceFactory::GetForProfile(profile), AccountTrackerServiceFactory::GetForProfile(profile)); auto identity_manager = std::make_unique<IdentityManagerWrapper>( - profile, std::move(token_service), std::move(gaia_cookie_manager_service), + profile, std::move(gaia_cookie_manager_service), std::move(signin_manager), std::move(account_fetcher_service), std::move(primary_account_mutator), std::move(accounts_mutator), std::move(accounts_cookie_mutator), std::move(diagnostics_provider)); - for (Observer& observer : observer_list_) observer.IdentityManagerCreated(identity_manager.get()); - return identity_manager.release(); }
diff --git a/chrome/browser/signin/identity_test_environment_profile_adaptor.cc b/chrome/browser/signin/identity_test_environment_profile_adaptor.cc index c6dbe16..53a521ec 100644 --- a/chrome/browser/signin/identity_test_environment_profile_adaptor.cc +++ b/chrome/browser/signin/identity_test_environment_profile_adaptor.cc
@@ -8,8 +8,21 @@ #include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/chrome_signin_client_factory.h" #include "chrome/browser/signin/identity_manager_factory.h" +#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" +namespace { + +// Testing factory that creates a FakeProfileOAuth2TokenService. +std::unique_ptr<KeyedService> BuildFakeProfileOAuth2TokenService( + content::BrowserContext* context) { + Profile* profile = Profile::FromBrowserContext(context); + std::unique_ptr<FakeProfileOAuth2TokenService> service( + new FakeProfileOAuth2TokenService(profile->GetPrefs())); + return std::move(service); +} +} // namespace + // static std::unique_ptr<TestingProfile> IdentityTestEnvironmentProfileAdaptor:: CreateProfileForIdentityTestEnvironment() { @@ -64,24 +77,11 @@ // static TestingProfile::TestingFactories IdentityTestEnvironmentProfileAdaptor::GetIdentityTestEnvironmentFactories() { - return {{IdentityManagerFactory::GetInstance(), - base::BindRepeating(&BuildIdentityManagerForTests)}}; -} - -// static -std::unique_ptr<KeyedService> -IdentityTestEnvironmentProfileAdaptor::BuildIdentityManagerForTests( - content::BrowserContext* context) { - Profile* profile = Profile::FromBrowserContext(context); - auto fake_token_service = - std::make_unique<FakeProfileOAuth2TokenService>(profile->GetPrefs()); - - return identity::IdentityTestEnvironment::BuildIdentityManagerForTests( - ChromeSigninClientFactory::GetForProfile(profile), profile->GetPrefs(), - std::move(fake_token_service), - AccountTrackerServiceFactory::GetForProfile(profile)); + return {{ProfileOAuth2TokenServiceFactory::GetInstance(), + base::BindRepeating(&BuildFakeProfileOAuth2TokenService)}}; } IdentityTestEnvironmentProfileAdaptor::IdentityTestEnvironmentProfileAdaptor( Profile* profile) - : identity_test_env_(IdentityManagerFactory::GetForProfile(profile)) {} + : identity_test_env_( + IdentityManagerFactory::GetForProfile(profile)) {}
diff --git a/chrome/browser/signin/identity_test_environment_profile_adaptor.h b/chrome/browser/signin/identity_test_environment_profile_adaptor.h index 1e71f4c..0e84d341 100644 --- a/chrome/browser/signin/identity_test_environment_profile_adaptor.h +++ b/chrome/browser/signin/identity_test_environment_profile_adaptor.h
@@ -80,11 +80,6 @@ } private: - // Testing factory that creates an IdentityManager - // with a FakeProfileOAuth2TokenService. - static std::unique_ptr<KeyedService> BuildIdentityManagerForTests( - content::BrowserContext* context); - identity::IdentityTestEnvironment identity_test_env_; DISALLOW_COPY_AND_ASSIGN(IdentityTestEnvironmentProfileAdaptor);
diff --git a/chrome/browser/signin/profile_oauth2_token_service_builder.h b/chrome/browser/signin/profile_oauth2_token_service_builder.h deleted file mode 100644 index d528fdc..0000000 --- a/chrome/browser/signin/profile_oauth2_token_service_builder.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2019 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 CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_BUILDER_H_ -#define CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_BUILDER_H_ - -#include <memory> - -namespace content { -class BrowserContext; -} - -class ProfileOAuth2TokenService; -class IdentityManagerFactory; - -class ProfileOAuth2TokenServiceBuilder { - private: - // Builds a ProfileOAuth2TokenService instance for use by IdentityManager. - static std::unique_ptr<ProfileOAuth2TokenService> BuildInstanceFor( - content::BrowserContext* context); - - friend IdentityManagerFactory; -}; -#endif // CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_BUILDER_H_
diff --git a/chrome/browser/signin/profile_oauth2_token_service_builder.cc b/chrome/browser/signin/profile_oauth2_token_service_factory.cc similarity index 78% rename from chrome/browser/signin/profile_oauth2_token_service_builder.cc rename to chrome/browser/signin/profile_oauth2_token_service_factory.cc index c86fc0ed..405fc4be 100644 --- a/chrome/browser/signin/profile_oauth2_token_service_builder.cc +++ b/chrome/browser/signin/profile_oauth2_token_service_factory.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/signin/profile_oauth2_token_service_builder.h" +#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include <memory> #include <string> @@ -10,10 +10,13 @@ #include "base/bind.h" #include "base/callback.h" +#include "base/logging.h" #include "build/build_config.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/signin/account_tracker_service_factory.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/pref_registry/pref_registry_syncable.h" #include "components/signin/core/browser/device_id_helper.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "content/public/browser/network_service_instance.h" @@ -132,10 +135,42 @@ } // namespace +ProfileOAuth2TokenServiceFactory::ProfileOAuth2TokenServiceFactory() + : BrowserContextKeyedServiceFactory( + "ProfileOAuth2TokenService", + BrowserContextDependencyManager::GetInstance()) { +#if !defined(OS_ANDROID) + DependsOn(ChromeSigninClientFactory::GetInstance()); + DependsOn(WebDataServiceFactory::GetInstance()); +#endif + DependsOn(AccountTrackerServiceFactory::GetInstance()); +} + +ProfileOAuth2TokenServiceFactory::~ProfileOAuth2TokenServiceFactory() { +} + +ProfileOAuth2TokenService* +ProfileOAuth2TokenServiceFactory::GetForProfile(Profile* profile) { + return static_cast<ProfileOAuth2TokenService*>( + GetInstance()->GetServiceForBrowserContext(profile, true)); +} + // static -std::unique_ptr<ProfileOAuth2TokenService> -ProfileOAuth2TokenServiceBuilder::BuildInstanceFor( - content::BrowserContext* context) { +ProfileOAuth2TokenServiceFactory* + ProfileOAuth2TokenServiceFactory::GetInstance() { + return base::Singleton<ProfileOAuth2TokenServiceFactory>::get(); +} + +void ProfileOAuth2TokenServiceFactory::RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* registry) { + ProfileOAuth2TokenService::RegisterProfilePrefs(registry); +#if !defined(OS_ANDROID) + MutableProfileOAuth2TokenServiceDelegate::RegisterProfilePrefs(registry); +#endif +} + +KeyedService* ProfileOAuth2TokenServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { Profile* profile = static_cast<Profile*>(context); // On ChromeOS the device ID is not managed by the token service. @@ -147,6 +182,6 @@ DCHECK(!device_id.empty()); #endif - return std::make_unique<ProfileOAuth2TokenService>( + return new ProfileOAuth2TokenService( profile->GetPrefs(), CreateOAuth2TokenServiceDelegate(profile)); }
diff --git a/chrome/browser/signin/profile_oauth2_token_service_factory.h b/chrome/browser/signin/profile_oauth2_token_service_factory.h new file mode 100644 index 0000000..0c0bb0d --- /dev/null +++ b/chrome/browser/signin/profile_oauth2_token_service_factory.h
@@ -0,0 +1,45 @@ +// Copyright 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 CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_FACTORY_H_ + +#include "base/macros.h" +#include "base/memory/singleton.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +class ProfileOAuth2TokenService; +class Profile; + +// Singleton that owns all ProfileOAuth2TokenServices and associates them with +// Profiles. Listens for the Profile's destruction notification and cleans up +// the associated ProfileOAuth2TokenService. +class ProfileOAuth2TokenServiceFactory + : public BrowserContextKeyedServiceFactory { + public: + // Returns the instance of ProfileOAuth2TokenService associated with this + // profile (creating one if none exists). Returns NULL if this profile + // cannot have a ProfileOAuth2TokenService (for example, if |profile| is + // incognito). + static ProfileOAuth2TokenService* GetForProfile(Profile* profile); + + // Returns an instance of the ProfileOAuth2TokenServiceFactory singleton. + static ProfileOAuth2TokenServiceFactory* GetInstance(); + + private: + friend struct base::DefaultSingletonTraits<ProfileOAuth2TokenServiceFactory>; + + ProfileOAuth2TokenServiceFactory(); + ~ProfileOAuth2TokenServiceFactory() override; + + // BrowserContextKeyedServiceFactory implementation. + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + void RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* registry) override; + + DISALLOW_COPY_AND_ASSIGN(ProfileOAuth2TokenServiceFactory); +}; + +#endif // CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_FACTORY_H_
diff --git a/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc b/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc index 4b1be45..a47fe82 100644 --- a/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc
@@ -7,12 +7,15 @@ #include "base/bind.h" #include "base/macros.h" #include "base/test/scoped_feature_list.h" +#include "base/time/time.h" +#include "chrome/browser/sync/test/integration/encryption_helper.h" #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sessions_helper.h" #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h" #include "chrome/browser/sync/test/integration/status_change_checker.h" #include "chrome/browser/sync/test/integration/sync_integration_test_util.h" #include "chrome/browser/sync/test/integration/sync_test.h" +#include "chrome/browser/sync/test/integration/user_events_helper.h" #include "chrome/browser/sync/user_event_service_factory.h" #include "components/sync/driver/sync_driver_switches.h" #include "components/sync/model/model_type_sync_bridge.h" @@ -21,20 +24,13 @@ #include "components/variations/variations_associated_data.h" using fake_server::FakeServer; -using sync_pb::UserEventSpecifics; -using sync_pb::SyncEntity; using sync_pb::CommitResponse; +using sync_pb::SyncEntity; +using sync_pb::UserEventSpecifics; +using user_events_helper::CreateTestEvent; namespace { -UserEventSpecifics CreateTestEvent(int microseconds) { - UserEventSpecifics specifics; - specifics.set_event_time_usec(microseconds); - specifics.set_navigation_id(microseconds); - specifics.mutable_test_event(); - return specifics; -} - CommitResponse::ResponseType BounceType( CommitResponse::ResponseType type, const syncer::LoopbackServerEntity& entity) { @@ -56,65 +52,6 @@ } } -class UserEventEqualityChecker : public SingleClientStatusChangeChecker { - public: - UserEventEqualityChecker(syncer::ProfileSyncService* service, - FakeServer* fake_server, - std::vector<UserEventSpecifics> expected_specifics) - : SingleClientStatusChangeChecker(service), fake_server_(fake_server) { - for (const UserEventSpecifics& specifics : expected_specifics) { - expected_specifics_.insert(std::pair<int64_t, UserEventSpecifics>( - specifics.event_time_usec(), specifics)); - } - } - - bool IsExitConditionSatisfied() override { - std::vector<SyncEntity> entities = - fake_server_->GetSyncEntitiesByModelType(syncer::USER_EVENTS); - - // |entities.size()| is only going to grow, if |entities.size()| ever - // becomes bigger then all hope is lost of passing, stop now. - EXPECT_GE(expected_specifics_.size(), entities.size()); - - if (expected_specifics_.size() > entities.size()) { - return false; - } - - // Number of events on server matches expected, exit condition is satisfied. - // Let's verify that content matches as well. It is safe to modify - // |expected_specifics_|. - for (const SyncEntity& entity : entities) { - UserEventSpecifics server_specifics = entity.specifics().user_event(); - auto iter = expected_specifics_.find(server_specifics.event_time_usec()); - // We don't expect to encounter id matching events with different values, - // this isn't going to recover so fail the test case now. - EXPECT_TRUE(expected_specifics_.end() != iter); - if (expected_specifics_.end() == iter) { - return false; - } - // TODO(skym): This may need to change if we start updating navigation_id - // based on what sessions data is committed, and end up committing the - // same event multiple times. - EXPECT_EQ(iter->second.navigation_id(), server_specifics.navigation_id()); - EXPECT_EQ(iter->second.event_case(), server_specifics.event_case()); - - expected_specifics_.erase(iter); - } - - return true; - } - - std::string GetDebugMessage() const override { - return "Waiting server side USER_EVENTS to match expected."; - } - - private: - FakeServer* fake_server_; - std::multimap<int64_t, UserEventSpecifics> expected_specifics_; - - DISALLOW_COPY_AND_ASSIGN(UserEventEqualityChecker); -}; - // A more simplistic version of UserEventEqualityChecker that only checks the // case of the events. This is helpful if you do not know (or control) some of // the fields of the events that are created. @@ -191,15 +128,17 @@ GetFakeServer()->GetSyncEntitiesByModelType(syncer::USER_EVENTS).size()); syncer::UserEventService* event_service = browser_sync::UserEventServiceFactory::GetForProfile(GetProfile(0)); - const UserEventSpecifics specifics = CreateTestEvent(0); + const UserEventSpecifics specifics = CreateTestEvent(base::Time()); event_service->RecordUserEvent(specifics); EXPECT_TRUE(ExpectUserEvents({specifics})); } IN_PROC_BROWSER_TEST_F(SingleClientUserEventsSyncTest, RetrySequential) { ASSERT_TRUE(SetupSync()); - const UserEventSpecifics specifics1 = CreateTestEvent(1); - const UserEventSpecifics specifics2 = CreateTestEvent(2); + const UserEventSpecifics specifics1 = + CreateTestEvent(base::Time() + base::TimeDelta::FromMicroseconds(1)); + const UserEventSpecifics specifics2 = + CreateTestEvent(base::Time() + base::TimeDelta::FromMicroseconds(2)); syncer::UserEventService* event_service = browser_sync::UserEventServiceFactory::GetForProfile(GetProfile(0)); @@ -225,8 +164,10 @@ IN_PROC_BROWSER_TEST_F(SingleClientUserEventsSyncTest, RetryParallel) { ASSERT_TRUE(SetupSync()); bool first = true; - const UserEventSpecifics specifics1 = CreateTestEvent(1); - const UserEventSpecifics specifics2 = CreateTestEvent(2); + const UserEventSpecifics specifics1 = + CreateTestEvent(base::Time() + base::TimeDelta::FromMicroseconds(1)); + const UserEventSpecifics specifics2 = + CreateTestEvent(base::Time() + base::TimeDelta::FromMicroseconds(2)); UserEventSpecifics retry_specifics; syncer::UserEventService* event_service = @@ -245,9 +186,12 @@ } IN_PROC_BROWSER_TEST_F(SingleClientUserEventsSyncTest, NoHistory) { - const UserEventSpecifics test_event1 = CreateTestEvent(1); - const UserEventSpecifics test_event2 = CreateTestEvent(2); - const UserEventSpecifics test_event3 = CreateTestEvent(3); + const UserEventSpecifics test_event1 = + CreateTestEvent(base::Time() + base::TimeDelta::FromMicroseconds(1)); + const UserEventSpecifics test_event2 = + CreateTestEvent(base::Time() + base::TimeDelta::FromMicroseconds(2)); + const UserEventSpecifics test_event3 = + CreateTestEvent(base::Time() + base::TimeDelta::FromMicroseconds(3)); ASSERT_TRUE(SetupSync()); syncer::UserEventService* event_service = @@ -270,7 +214,8 @@ } IN_PROC_BROWSER_TEST_F(SingleClientUserEventsSyncTest, NoSessions) { - const UserEventSpecifics specifics = CreateTestEvent(1); + const UserEventSpecifics specifics = + CreateTestEvent(base::Time() + base::TimeDelta::FromMicroseconds(1)); ASSERT_TRUE(SetupSync()); ASSERT_TRUE(GetClient(0)->DisableSyncForDatatype(syncer::PROXY_TABS)); syncer::UserEventService* event_service = @@ -283,15 +228,17 @@ } IN_PROC_BROWSER_TEST_F(SingleClientUserEventsSyncTest, Encryption) { - const UserEventSpecifics test_event1 = CreateTestEvent(1); - const UserEventSpecifics test_event2 = CreateTestEvent(2); + const UserEventSpecifics test_event1 = + CreateTestEvent(base::Time() + base::TimeDelta::FromMicroseconds(1)); + const UserEventSpecifics test_event2 = + CreateTestEvent(base::Time() + base::TimeDelta::FromMicroseconds(2)); ASSERT_TRUE(SetupSync()); syncer::UserEventService* event_service = browser_sync::UserEventServiceFactory::GetForProfile(GetProfile(0)); event_service->RecordUserEvent(test_event1); - ASSERT_TRUE(EnableEncryption(0)); EXPECT_TRUE(ExpectUserEvents({test_event1})); + ASSERT_TRUE(EnableEncryption(0)); event_service->RecordUserEvent(test_event2); // Just checking that we don't see test_event2 isn't very convincing yet,
diff --git a/chrome/browser/sync/test/integration/two_client_user_events_sync_test.cc b/chrome/browser/sync/test/integration/two_client_user_events_sync_test.cc new file mode 100644 index 0000000..d5f35d3 --- /dev/null +++ b/chrome/browser/sync/test/integration/two_client_user_events_sync_test.cc
@@ -0,0 +1,102 @@ +// Copyright 2019 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 "base/time/time.h" +#include "chrome/browser/sync/test/integration/bookmarks_helper.h" +#include "chrome/browser/sync/test/integration/encryption_helper.h" +#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" +#include "chrome/browser/sync/test/integration/sync_integration_test_util.h" +#include "chrome/browser/sync/test/integration/sync_test.h" +#include "chrome/browser/sync/test/integration/user_events_helper.h" +#include "chrome/browser/sync/user_event_service_factory.h" +#include "components/sync/protocol/user_event_specifics.pb.h" +#include "components/sync/user_events/user_event_service.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +using sync_pb::UserEventSpecifics; + +const int kEncryptingClientId = 0; +const int kDecryptingClientId = 1; + +class TwoClientUserEventsSyncTest : public SyncTest { + public: + TwoClientUserEventsSyncTest() : SyncTest(TWO_CLIENT) {} + ~TwoClientUserEventsSyncTest() override {} + + bool ExpectNoUserEvent(int index) { + return UserEventEqualityChecker(GetSyncService(index), GetFakeServer(), + /*expected_specifics=*/{}) + .Wait(); + } + + bool WaitForPassphraseRequiredState(int index, bool desired_state) { + return PassphraseRequiredStateChecker(GetSyncService(index), desired_state) + .Wait(); + } + + bool WaitForBookmarksToMatchVerifier() { + return BookmarksMatchVerifierChecker().Wait(); + } + + void AddTestBookmarksToClient(int index) { + ASSERT_TRUE( + bookmarks_helper::AddURL(index, 0, "What are you syncing about?", + GURL("https://google.com/synced-bookmark-1"))); + } + + private: + DISALLOW_COPY_AND_ASSIGN(TwoClientUserEventsSyncTest); +}; + +IN_PROC_BROWSER_TEST_F(TwoClientUserEventsSyncTest, + SetPassphraseAndRecordEventAndThenSetupSync) { + ASSERT_TRUE(SetupClients()); + ASSERT_TRUE(GetClient(kEncryptingClientId)->SetupSync()); + + // Set up a sync client with custom passphrase to get the data encrypted on + // the server. + GetSyncService(kEncryptingClientId) + ->GetUserSettings() + ->SetEncryptionPassphrase("hunter2"); + ASSERT_TRUE( + PassphraseAcceptedChecker(GetSyncService(kEncryptingClientId)).Wait()); + + // Record a user event on the second client before setting up sync (before + // knowing it will be encrypted). This event should not get recorded while + // starting up sync because the user has custom passphrase setup. + syncer::UserEventService* event_service = + browser_sync::UserEventServiceFactory::GetForProfile(GetProfile(0)); + event_service->RecordUserEvent(user_events_helper::CreateTestEvent( + base::Time() + base::TimeDelta::FromMicroseconds(1))); + + // Set up sync on the second client. + ASSERT_TRUE( + GetClient(kDecryptingClientId) + ->SetupSyncNoWaitForCompletion(syncer::UserSelectableTypes())); + // The second client asks the user to provide a password for decryption. + ASSERT_TRUE( + PassphraseRequiredChecker(GetSyncService(kDecryptingClientId)).Wait()); + // Provide the password. + ASSERT_TRUE(GetSyncService(kDecryptingClientId) + ->GetUserSettings() + ->SetDecryptionPassphrase("hunter2")); + // Check it is accepted and finish the setup. + ASSERT_TRUE( + PassphraseAcceptedChecker(GetSyncService(kDecryptingClientId)).Wait()); + GetClient(kDecryptingClientId)->FinishSyncSetup(); + + // Just checking that we don't see the recorded test event isn't very + // convincing yet, because it may simply not have reached the server yet. So + // let's send something else on the second client through the system that we + // can wait on before checking. Bookmark data was picked fairly arbitrarily. + AddTestBookmarksToClient(kDecryptingClientId); + ASSERT_TRUE(WaitForBookmarksToMatchVerifier()); + + // Finally, make sure no user event got sent to the server. + EXPECT_TRUE(ExpectNoUserEvent(kDecryptingClientId)); +} + +} // namespace
diff --git a/chrome/browser/sync/test/integration/user_events_helper.cc b/chrome/browser/sync/test/integration/user_events_helper.cc new file mode 100644 index 0000000..cd2e6f66 --- /dev/null +++ b/chrome/browser/sync/test/integration/user_events_helper.cc
@@ -0,0 +1,81 @@ +// Copyright 2019 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 "chrome/browser/sync/test/integration/user_events_helper.h" + +#include <string> +#include <vector> + +#include "chrome/browser/sync/test/integration/single_client_status_change_checker.h" +#include "components/sync/test/fake_server/fake_server.h" +#include "testing/gtest/include/gtest/gtest.h" + +using fake_server::FakeServer; +using sync_pb::SyncEntity; +using sync_pb::UserEventSpecifics; + +namespace user_events_helper { + +UserEventSpecifics CreateTestEvent(base::Time time) { + UserEventSpecifics specifics; + specifics.set_event_time_usec( + time.ToDeltaSinceWindowsEpoch().InMicroseconds()); + specifics.set_navigation_id(time.ToDeltaSinceWindowsEpoch().InMicroseconds()); + specifics.mutable_test_event(); + return specifics; +} + +} // namespace user_events_helper + +UserEventEqualityChecker::UserEventEqualityChecker( + syncer::ProfileSyncService* service, + FakeServer* fake_server, + std::vector<UserEventSpecifics> expected_specifics) + : SingleClientStatusChangeChecker(service), fake_server_(fake_server) { + for (const UserEventSpecifics& specifics : expected_specifics) { + expected_specifics_.emplace(specifics.event_time_usec(), specifics); + } +} + +UserEventEqualityChecker::~UserEventEqualityChecker() = default; + +bool UserEventEqualityChecker::IsExitConditionSatisfied() { + std::vector<SyncEntity> entities = + fake_server_->GetSyncEntitiesByModelType(syncer::USER_EVENTS); + + // |entities.size()| is only going to grow, if |entities.size()| ever + // becomes bigger then all hope is lost of passing, stop now. + EXPECT_GE(expected_specifics_.size(), entities.size()); + + if (expected_specifics_.size() > entities.size()) { + return false; + } + + // Number of events on server matches expected, exit condition is satisfied. + // Let's verify that content matches as well. It is safe to modify + // |expected_specifics_|. + for (const SyncEntity& entity : entities) { + UserEventSpecifics server_specifics = entity.specifics().user_event(); + auto iter = expected_specifics_.find(server_specifics.event_time_usec()); + // We don't expect to encounter id matching events with different values, + // this isn't going to recover so fail the test case now. + EXPECT_TRUE(expected_specifics_.end() != iter); + if (expected_specifics_.end() == iter) { + return false; + } + // TODO(skym): This may need to change if we start updating navigation_id + // based on what sessions data is committed, and end up committing the + // same event multiple times. + EXPECT_EQ(iter->second.navigation_id(), server_specifics.navigation_id()); + EXPECT_EQ(iter->second.event_case(), server_specifics.event_case()); + + expected_specifics_.erase(iter); + } + + return true; +} + +std::string UserEventEqualityChecker::GetDebugMessage() const { + return "Waiting server side USER_EVENTS to match expected."; +}
diff --git a/chrome/browser/sync/test/integration/user_events_helper.h b/chrome/browser/sync/test/integration/user_events_helper.h new file mode 100644 index 0000000..7d87b49 --- /dev/null +++ b/chrome/browser/sync/test/integration/user_events_helper.h
@@ -0,0 +1,44 @@ +// Copyright 2019 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 CHROME_BROWSER_SYNC_TEST_INTEGRATION_USER_EVENTS_HELPER_H_ +#define CHROME_BROWSER_SYNC_TEST_INTEGRATION_USER_EVENTS_HELPER_H_ + +#include <string> + +#include "base/time/time.h" +#include "chrome/browser/sync/test/integration/single_client_status_change_checker.h" +#include "components/sync/protocol/user_event_specifics.pb.h" + +namespace fake_server { +class FakeServer; +} + +namespace user_events_helper { + +// Creates a test user event with specified event time. +sync_pb::UserEventSpecifics CreateTestEvent(base::Time time); + +} // namespace user_events_helper + +class UserEventEqualityChecker : public SingleClientStatusChangeChecker { + public: + UserEventEqualityChecker( + syncer::ProfileSyncService* service, + fake_server::FakeServer* fake_server, + std::vector<sync_pb::UserEventSpecifics> expected_specifics); + ~UserEventEqualityChecker() override; + + bool IsExitConditionSatisfied() override; + + std::string GetDebugMessage() const override; + + private: + fake_server::FakeServer* fake_server_; + std::multimap<int64_t, sync_pb::UserEventSpecifics> expected_specifics_; + + DISALLOW_COPY_AND_ASSIGN(UserEventEqualityChecker); +}; + +#endif // CHROME_BROWSER_SYNC_TEST_INTEGRATION_USER_EVENTS_HELPER_H_
diff --git a/chrome/browser/sync/user_event_service_factory.cc b/chrome/browser/sync/user_event_service_factory.cc index b0cf20a..88a5430 100644 --- a/chrome/browser/sync/user_event_service_factory.cc +++ b/chrome/browser/sync/user_event_service_factory.cc
@@ -11,7 +11,6 @@ #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/model_type_store_service_factory.h" -#include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/sync/session_sync_service_factory.h" #include "chrome/common/channel_info.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" @@ -45,25 +44,17 @@ BrowserContextDependencyManager::GetInstance()) { DependsOn(ModelTypeStoreServiceFactory::GetInstance()); DependsOn(SessionSyncServiceFactory::GetInstance()); - // TODO(vitaliii): This is missing - // DependsOn(ProfileSyncServiceFactory::GetInstance()), which we can't - // simply add because ProfileSyncServiceFactory itself depends on this - // factory. This won't be relevant anymore once the separate consents datatype - // is fully launched. } UserEventServiceFactory::~UserEventServiceFactory() {} KeyedService* UserEventServiceFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { - Profile* profile = Profile::FromBrowserContext(context); - syncer::SyncService* sync_service = - ProfileSyncServiceFactory::GetForProfile(profile); - if (!syncer::UserEventServiceImpl::MightRecordEvents( - context->IsOffTheRecord(), sync_service)) { + if (context->IsOffTheRecord()) { return new syncer::NoOpUserEventService(); } + Profile* profile = Profile::FromBrowserContext(context); syncer::OnceModelTypeStoreFactory store_factory = ModelTypeStoreServiceFactory::GetForProfile(profile)->GetStoreFactory(); @@ -75,7 +66,7 @@ auto bridge = std::make_unique<syncer::UserEventSyncBridge>( std::move(store_factory), std::move(change_processor), SessionSyncServiceFactory::GetForProfile(profile)->GetGlobalIdMapper()); - return new syncer::UserEventServiceImpl(sync_service, std::move(bridge)); + return new syncer::UserEventServiceImpl(std::move(bridge)); } content::BrowserContext* UserEventServiceFactory::GetBrowserContextToUse(
diff --git a/chrome/browser/task_manager/task_manager_browsertest.cc b/chrome/browser/task_manager/task_manager_browsertest.cc index 0698cb5..02d0d90 100644 --- a/chrome/browser/task_manager/task_manager_browsertest.cc +++ b/chrome/browser/task_manager/task_manager_browsertest.cc
@@ -903,10 +903,20 @@ WaitForTaskManagerRows(1, MatchSubframe("http://c.com/"))); ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnySubframe())); + content::WebContents* tab = + browser()->tab_strip_model()->GetActiveWebContents(); + + // Simulate a user gesture on the frame about to be navigated so that the + // corresponding navigation entry is not marked as skippable. + content::RenderFrameHost* child_frame = ChildFrameAt(tab->GetMainFrame(), 0); + content::RenderFrameHost* grandchild_frame = ChildFrameAt(child_frame, 0); + grandchild_frame->ExecuteJavaScriptWithUserGestureForTests( + base::UTF8ToUTF16("a=5")); + GURL d_url = embedded_test_server()->GetURL( "d.com", "/cross_site_iframe_factory.html?d(e)"); ASSERT_TRUE(content::ExecuteScript( - browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), + tab->GetMainFrame(), "frames[0][0].location.href = '" + d_url.spec() + "';")); ASSERT_NO_FATAL_FAILURE( @@ -919,6 +929,7 @@ WaitForTaskManagerRows(1, MatchSubframe("http://b.com/"))); ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(3, MatchAnySubframe())); + ASSERT_TRUE(chrome::CanGoBack(browser())); chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB); ASSERT_NO_FATAL_FAILURE( @@ -931,6 +942,7 @@ WaitForTaskManagerRows(1, MatchSubframe("http://b.com/"))); ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnySubframe())); + ASSERT_TRUE(chrome::CanGoForward(browser())); chrome::GoForward(browser(), WindowOpenDisposition::CURRENT_TAB); // When the subframe appears in the cloned process, it must have a valid
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 1d4793b..7640896 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1800,6 +1800,7 @@ "//chromeos/components/tether", "//chromeos/cryptohome", "//chromeos/dbus", + "//chromeos/dbus/audio", "//chromeos/dbus/cryptohome", "//chromeos/dbus/cryptohome:cryptohome_proto", "//chromeos/dbus/power", @@ -2503,6 +2504,8 @@ "views/desktop_capture/desktop_media_picker_views.h", "views/desktop_capture/desktop_media_source_view.cc", "views/desktop_capture/desktop_media_source_view.h", + "views/desktop_capture/desktop_media_tab_list.cc", + "views/desktop_capture/desktop_media_tab_list.h", "views/device_chooser_content_view.cc", "views/device_chooser_content_view.h", "views/download/download_danger_prompt_views.cc",
diff --git a/chrome/browser/ui/android/login_handler_android.cc b/chrome/browser/ui/android/login_handler_android.cc index 5383bfa5..98d32b06 100644 --- a/chrome/browser/ui/android/login_handler_android.cc +++ b/chrome/browser/ui/android/login_handler_android.cc
@@ -27,7 +27,7 @@ class LoginHandlerAndroid : public LoginHandler { public: - LoginHandlerAndroid(net::AuthChallengeInfo* auth_info, + LoginHandlerAndroid(const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, LoginAuthRequiredCallback auth_required_callback) : LoginHandler(auth_info, @@ -89,7 +89,7 @@ // static std::unique_ptr<LoginHandler> LoginHandler::Create( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, LoginAuthRequiredCallback auth_required_callback) { return std::make_unique<LoginHandlerAndroid>(
diff --git a/chrome/browser/ui/app_list/app_list_client_impl.cc b/chrome/browser/ui/app_list/app_list_client_impl.cc index 6cc25cac..6cee5ce 100644 --- a/chrome/browser/ui/app_list/app_list_client_impl.cc +++ b/chrome/browser/ui/app_list/app_list_client_impl.cc
@@ -56,6 +56,15 @@ } // namespace +AppListClientImpl::MojoRecorderForTest::MojoRecorderForTest() = default; +AppListClientImpl::MojoRecorderForTest::~MojoRecorderForTest() = default; + +int AppListClientImpl::MojoRecorderForTest::Query(int profile_id) const { + auto iter = recorder_.find(profile_id); + return iter == recorder_.end() ? 0 : iter->second; +} +/////////////////////////////////////////////////////////////////////////////// + AppListClientImpl::AppListClientImpl() : template_url_service_observer_(this), binding_(this), @@ -177,21 +186,32 @@ } void AppListClientImpl::ViewShown(int64_t display_id) { - if (model_updater_) { + if (current_model_updater_) { base::RecordAction(base::UserMetricsAction("Launcher_Show")); base::UmaHistogramSparse("Apps.AppListBadgedAppsCount", - model_updater_->BadgedItemCount()); + current_model_updater_->BadgedItemCount()); } display_id_ = display_id; } -void AppListClientImpl::ActivateItem(const std::string& id, int event_flags) { - if (!model_updater_) +void AppListClientImpl::ActivateItem(int profile_id, + const std::string& id, + int event_flags) { + auto* requested_model_updater = profile_model_mappings_[profile_id]; + + // Pointless to notify the AppListModelUpdater of the activated item if the + // |requested_model_updater| is not the current one, which means that the + // active profile is changed. The same rule applies to the GetContextMenuModel + // and ContextMenuItemSelected. + if (requested_model_updater != current_model_updater_ || + !requested_model_updater) { return; - model_updater_->ActivateChromeItem(id, event_flags); + } + + requested_model_updater->ActivateChromeItem(id, event_flags); // Send a training signal to the search controller. - const auto* item = model_updater_->FindItem(id); + const auto* item = current_model_updater_->FindItem(id); if (item) { search_controller_->Train( id, app_list::RankingItemTypeFromChromeAppListItem(*item)); @@ -201,13 +221,16 @@ } void AppListClientImpl::GetContextMenuModel( + int profile_id, const std::string& id, GetContextMenuModelCallback callback) { - if (!model_updater_) { + auto* requested_model_updater = profile_model_mappings_[profile_id]; + if (requested_model_updater != current_model_updater_ || + !requested_model_updater) { std::move(callback).Run(std::vector<ash::mojom::MenuItemPtr>()); return; } - model_updater_->GetContextMenuModel( + requested_model_updater->GetContextMenuModel( id, base::BindOnce( [](GetContextMenuModelCallback callback, @@ -218,12 +241,17 @@ std::move(callback))); } -void AppListClientImpl::ContextMenuItemSelected(const std::string& id, +void AppListClientImpl::ContextMenuItemSelected(int profile_id, + const std::string& id, int command_id, int event_flags) { - if (!model_updater_) + auto* requested_model_updater = profile_model_mappings_[profile_id]; + if (requested_model_updater != current_model_updater_ || + !requested_model_updater) { return; - model_updater_->ContextMenuItemSelected(id, command_id, event_flags); + } + + requested_model_updater->ContextMenuItemSelected(id, command_id, event_flags); } void AppListClientImpl::OnAppListTargetVisibilityChanged(bool visible) { @@ -235,39 +263,52 @@ } void AppListClientImpl::OnFolderCreated( + int profile_id, ash::mojom::AppListItemMetadataPtr item) { - if (!model_updater_) + if (mojo_recorder_for_test_.get()) + mojo_recorder_for_test_->Record(profile_id); + + auto* requested_model_updater = profile_model_mappings_[profile_id]; + if (!requested_model_updater) return; DCHECK(item->is_folder); - model_updater_->OnFolderCreated(std::move(item)); + requested_model_updater->OnFolderCreated(std::move(item)); } void AppListClientImpl::OnFolderDeleted( + int profile_id, ash::mojom::AppListItemMetadataPtr item) { - if (!model_updater_) + auto* requested_model_updater = profile_model_mappings_[profile_id]; + if (!requested_model_updater) return; DCHECK(item->is_folder); - model_updater_->OnFolderDeleted(std::move(item)); + requested_model_updater->OnFolderDeleted(std::move(item)); } -void AppListClientImpl::OnItemUpdated(ash::mojom::AppListItemMetadataPtr item) { - if (!model_updater_) +void AppListClientImpl::OnItemUpdated(int profile_id, + ash::mojom::AppListItemMetadataPtr item) { + auto* requested_model_updater = profile_model_mappings_[profile_id]; + if (!requested_model_updater) return; - model_updater_->OnItemUpdated(std::move(item)); + requested_model_updater->OnItemUpdated(std::move(item)); } void AppListClientImpl::OnPageBreakItemAdded( + int profile_id, const std::string& id, const syncer::StringOrdinal& position) { - if (!model_updater_) + auto* requested_model_updater = profile_model_mappings_[profile_id]; + if (!requested_model_updater) return; - model_updater_->OnPageBreakItemAdded(id, position); + requested_model_updater->OnPageBreakItemAdded(id, position); } -void AppListClientImpl::OnPageBreakItemDeleted(const std::string& id) { - if (!model_updater_) +void AppListClientImpl::OnPageBreakItemDeleted(int profile_id, + const std::string& id) { + auto* requested_model_updater = profile_model_mappings_[profile_id]; + if (!requested_model_updater) return; - model_updater_->OnPageBreakItemDeleted(id); + requested_model_updater->OnPageBreakItemDeleted(id); } void AppListClientImpl::GetNavigableContentsFactory( @@ -310,13 +351,13 @@ return; if (profile_) { - DCHECK(model_updater_); - model_updater_->SetActive(false); + DCHECK(current_model_updater_); + current_model_updater_->SetActive(false); search_resource_manager_.reset(); search_controller_.reset(); app_sync_ui_state_watcher_.reset(); - model_updater_ = nullptr; + current_model_updater_ = nullptr; } template_url_service_observer_.RemoveAll(); @@ -338,26 +379,33 @@ app_list::AppListSyncableService* syncable_service = app_list::AppListSyncableServiceFactory::GetForProfile(profile_); - model_updater_ = syncable_service->GetModelUpdater(); - model_updater_->SetActive(true); + current_model_updater_ = syncable_service->GetModelUpdater(); + current_model_updater_->SetActive(true); + + // On ChromeOS, there is no way to sign-off just one user. When signing off + // all users, AppListClientImpl instance is destructed before profiles are + // unloaded. So we don't need to remove elements from + // |profile_model_mappings_| explicitly. + profile_model_mappings_[current_model_updater_->model_id()] = + current_model_updater_; app_sync_ui_state_watcher_ = - std::make_unique<AppSyncUIStateWatcher>(profile_, model_updater_); + std::make_unique<AppSyncUIStateWatcher>(profile_, current_model_updater_); SetUpSearchUI(); OnTemplateURLServiceChanged(); // Clear search query. - model_updater_->UpdateSearchBox(base::string16(), - false /* initiated_by_user */); + current_model_updater_->UpdateSearchBox(base::string16(), + false /* initiated_by_user */); } void AppListClientImpl::SetUpSearchUI() { search_resource_manager_ = std::make_unique<app_list::SearchResourceManager>( - profile_, model_updater_); + profile_, current_model_updater_); search_controller_ = - app_list::CreateSearchController(profile_, model_updater_, this); + app_list::CreateSearchController(profile_, current_model_updater_, this); } app_list::SearchController* AppListClientImpl::search_controller() { @@ -365,11 +413,20 @@ } AppListModelUpdater* AppListClientImpl::GetModelUpdaterForTest() { - return model_updater_; + return current_model_updater_; +} + +void AppListClientImpl::SetUpMojoRecorderForTest() { + mojo_recorder_for_test_ = std::make_unique<MojoRecorderForTest>(); +} + +int AppListClientImpl::QueryMojoRecorderForTest(int profile_id) { + DCHECK(mojo_recorder_for_test_.get()); + return mojo_recorder_for_test_->Query(profile_id); } void AppListClientImpl::OnTemplateURLServiceChanged() { - DCHECK(model_updater_); + DCHECK(current_model_updater_); TemplateURLService* template_url_service = TemplateURLServiceFactory::GetForProfile(profile_); @@ -380,7 +437,7 @@ default_provider->GetEngineType( template_url_service->search_terms_data()) == SEARCH_ENGINE_GOOGLE; - model_updater_->SetSearchEngineIsGoogle(is_google); + current_model_updater_->SetSearchEngineIsGoogle(is_google); } void AppListClientImpl::ShowAndSwitchToState(ash::AppListState state) {
diff --git a/chrome/browser/ui/app_list/app_list_client_impl.h b/chrome/browser/ui/app_list/app_list_client_impl.h index 402a98da..aa9571f8 100644 --- a/chrome/browser/ui/app_list/app_list_client_impl.h +++ b/chrome/browser/ui/app_list/app_list_client_impl.h
@@ -31,6 +31,7 @@ class SearchResourceManager; } // namespace app_list +class AppListClientWithProfileTest; class AppListModelUpdater; class AppSyncUIStateWatcher; class Profile; @@ -41,6 +42,23 @@ public user_manager::UserManager::UserSessionStateObserver, public TemplateURLServiceObserver { public: + class MojoRecorderForTest { + public: + MojoRecorderForTest(); + ~MojoRecorderForTest(); + + void Record(int profile_id) { recorder_[profile_id]++; } + + int Query(int profile_id) const; + + private: + // For each pair in the map, the key is a profile id while the value is the + // mojo calling times associated with the particular profile. + std::map<int, int> recorder_; + + DISALLOW_COPY_AND_ASSIGN(MojoRecorderForTest); + }; + AppListClientImpl(); ~AppListClientImpl() override; @@ -64,20 +82,28 @@ int event_flags) override; void ViewClosing() override; void ViewShown(int64_t display_id) override; - void ActivateItem(const std::string& id, int event_flags) override; - void GetContextMenuModel(const std::string& id, + void ActivateItem(int profile_id, + const std::string& id, + int event_flags) override; + void GetContextMenuModel(int profile_id, + const std::string& id, GetContextMenuModelCallback callback) override; - void ContextMenuItemSelected(const std::string& id, + void ContextMenuItemSelected(int profile_id, + const std::string& id, int command_id, int event_flags) override; void OnAppListTargetVisibilityChanged(bool visible) override; void OnAppListVisibilityChanged(bool visible) override; - void OnFolderCreated(ash::mojom::AppListItemMetadataPtr item) override; - void OnFolderDeleted(ash::mojom::AppListItemMetadataPtr item) override; - void OnItemUpdated(ash::mojom::AppListItemMetadataPtr item) override; - void OnPageBreakItemAdded(const std::string& id, + void OnFolderCreated(int profile_id, + ash::mojom::AppListItemMetadataPtr item) override; + void OnFolderDeleted(int profile_id, + ash::mojom::AppListItemMetadataPtr item) override; + void OnItemUpdated(int profile_id, + ash::mojom::AppListItemMetadataPtr item) override; + void OnPageBreakItemAdded(int profile_id, + const std::string& id, const syncer::StringOrdinal& position) override; - void OnPageBreakItemDeleted(const std::string& id) override; + void OnPageBreakItemDeleted(int profile_id, const std::string& id) override; void GetNavigableContentsFactory( mojo::PendingReceiver<content::mojom::NavigableContentsFactory> receiver) override; @@ -136,10 +162,16 @@ AppListModelUpdater* GetModelUpdaterForTest(); + void SetUpMojoRecorderForTest(); + + int QueryMojoRecorderForTest(int profile_id); + // Flushes all pending mojo call to Ash for testing. void FlushMojoForTesting(); private: + FRIEND_TEST_ALL_PREFIXES(AppListClientWithProfileTest, CheckDataRace); + // Overridden from TemplateURLServiceObserver: void OnTemplateURLServiceChanged() override; @@ -158,14 +190,25 @@ // called. Profile* profile_ = nullptr; - // Unowned pointer to the model updater owned by AppListSyncableService. - // Will change if |profile_| changes. - AppListModelUpdater* model_updater_ = nullptr; + // Unowned pointer to the model updater owned by AppListSyncableService. Will + // change if |profile_| changes. + AppListModelUpdater* current_model_updater_ = nullptr; + + // Store the mappings between profiles and AppListModelUpdater instances. + // In multi-profile mode, mojo callings from the Ash process to access the app + // list items should be dealt with the correct AppListModelUpdater instance. + // Otherwise data race may happen, like the issue 939755 + // (https://crbug.com/939755). + // TODO: Replace the mojo interface functions provided by AppListClient with + // callbacks. + std::map<int, AppListModelUpdater*> profile_model_mappings_; std::unique_ptr<app_list::SearchResourceManager> search_resource_manager_; std::unique_ptr<app_list::SearchController> search_controller_; std::unique_ptr<AppSyncUIStateWatcher> app_sync_ui_state_watcher_; + std::unique_ptr<MojoRecorderForTest> mojo_recorder_for_test_; + ScopedObserver<TemplateURLService, AppListClientImpl> template_url_service_observer_;
diff --git a/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc b/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc index cc7eaca..9279307 100644 --- a/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc +++ b/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc
@@ -20,12 +20,16 @@ #include "chrome/browser/apps/platform_apps/app_browsertest_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/login/demo_mode/demo_session.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" #include "chrome/browser/ui/app_list/app_list_model_updater.h" +#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" #include "chrome/browser/ui/app_list/chrome_app_list_item.h" #include "chrome/browser/ui/app_list/search/search_controller.h" #include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h" @@ -39,7 +43,9 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/testing_profile.h" #include "chromeos/constants/chromeos_switches.h" +#include "components/browser_sync/browser_sync_switches.h" #include "components/prefs/pref_service.h" +#include "components/user_manager/scoped_user_manager.h" #include "components/user_manager/user_names.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" @@ -357,3 +363,124 @@ "DemoMode.AppLaunchSource", chromeos::DemoSession::AppLaunchSource::kAppList, 1); } + +class AppListClientWithProfileTest : public InProcessBrowserTest { + protected: + AppListClientWithProfileTest() + : account_id1_( + AccountId::FromUserEmailGaiaId("test1@example.com", "ID1")), + account_id2_( + AccountId::FromUserEmailGaiaId("test2@example.com", "ID2")) {} + ~AppListClientWithProfileTest() override {} + + static std::unique_ptr<KeyedService> BuildTestSyncService( + content::BrowserContext* context) { + Profile* profile = Profile::FromBrowserContext(context); + return std::make_unique<app_list::AppListSyncableService>( + profile, extensions::ExtensionSystem::Get(profile)); + } + + static std::unique_ptr<KeyedService> BuildTestURLService( + content::BrowserContext* context) { + return std::make_unique<TemplateURLService>(nullptr, 0); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + // Disable the password sync service. Otherwise the test will crash. + command_line->AppendSwitchASCII( + switches::kDisableSyncTypes, + syncer::ModelTypeSetToString(syncer::PASSWORDS)); + } + + void SetUpOnMainThread() override { + user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>( + std::make_unique<chromeos::FakeChromeUserManager>()); + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + + profile1_ = BuildProfile(account_id1_); + profile2_ = BuildProfile(account_id2_); + + AppListClientImpl::GetInstance()->SetUpMojoRecorderForTest(); + } + + void TearDownOnMainThread() override { + GetFakeUserManager()->RemoveUserFromList(account_id1_); + profile1_.reset(); + profile2_.reset(); + base::RunLoop().RunUntilIdle(); + user_manager_enabler_.reset(); + } + + chromeos::FakeChromeUserManager* GetFakeUserManager() const { + return static_cast<chromeos::FakeChromeUserManager*>( + user_manager::UserManager::Get()); + } + + TestingProfile* GetProfile1() { return profile1_.get(); } + TestingProfile* GetProfile2() { return profile2_.get(); } + + private: + std::unique_ptr<TestingProfile> BuildProfile(AccountId account_id) { + GetFakeUserManager()->AddUser(account_id); + GetFakeUserManager()->LoginUser(account_id); + + TestingProfile::Builder profile_builder; + profile_builder.SetPath( + temp_dir_.GetPath().AppendASCII(account_id.GetUserEmail())); + profile_builder.SetProfileName(account_id.GetUserEmail()); + + // Add service factories needed by AppListClientImpl::SetProfile. + profile_builder.AddTestingFactory( + app_list::AppListSyncableServiceFactory::GetInstance(), + base::BindRepeating(&BuildTestSyncService)); + profile_builder.AddTestingFactory( + TemplateURLServiceFactory::GetInstance(), + base::BindRepeating(&BuildTestURLService)); + + return IdentityTestEnvironmentProfileAdaptor:: + CreateProfileForIdentityTestEnvironment(profile_builder); + } + + AccountId account_id1_; + AccountId account_id2_; + std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_; + std::unique_ptr<TestingProfile> profile1_; + std::unique_ptr<TestingProfile> profile2_; + base::ScopedTempDir temp_dir_; +}; + +// Verifies that in multi-profile mode, mojo callings from Ash side to access +// the app list are handled by the correct AppListModelUpdater. (see +// https://crbug.com/939755) +IN_PROC_BROWSER_TEST_F(AppListClientWithProfileTest, CheckDataRace) { + AppListClientImpl* client = AppListClientImpl::GetInstance(); + + // Emulate that the default profile is the profile 1. + client->SetProfile(GetProfile1()); + int profile_id1 = client->GetModelUpdaterForTest()->model_id(); + + // Emulate that the AppListSyncableService adds an item within the folder. + // So the AppListClientImpl should receive OnFolderCreated event later. + auto* model_updater = client->GetModelUpdaterForTest(); + std::unique_ptr<ChromeAppListItem> item = std::make_unique<ChromeAppListItem>( + GetProfile1(), "item 1", model_updater); + item->SetFolderId("folder"); + model_updater->AddItem(std::move(item)); + + // Emulate that the current profile is switched to the profile 2. Wait until + // the AppListClientImpl receives the mojo callings from Ash side. + client->SetProfile(GetProfile2()); + client->FlushMojoForTesting(); + + int profile_id2 = client->GetModelUpdaterForTest()->model_id(); + + // Check the following things: + // (1) The model updater associated with the profile 2 should not process the + // OnFolderCreated event. + // (2) The model updater associated with the profile 1 should process the On- + // FolderCreated event. + EXPECT_EQ(0, client->QueryMojoRecorderForTest(profile_id2)); + EXPECT_EQ(1, client->QueryMojoRecorderForTest(profile_id1)); + + client->SetProfile(nullptr); +}
diff --git a/chrome/browser/ui/app_list/app_list_model_updater.cc b/chrome/browser/ui/app_list/app_list_model_updater.cc index 9ff3210..e398f96 100644 --- a/chrome/browser/ui/app_list/app_list_model_updater.cc +++ b/chrome/browser/ui/app_list/app_list_model_updater.cc
@@ -6,8 +6,18 @@ #include <algorithm> #include "ash/public/cpp/app_list/app_list_config.h" +#include "ash/public/cpp/app_list/app_list_types.h" #include "chrome/browser/ui/app_list/chrome_app_list_item.h" +namespace { + +int g_next_unique_model_id = ash::kAppListProfileIdStartFrom; + +} // namespace + +AppListModelUpdater::AppListModelUpdater() + : model_id_(g_next_unique_model_id++) {} + // static syncer::StringOrdinal AppListModelUpdater::GetFirstAvailablePositionInternal( const std::vector<ChromeAppListItem*>& top_level_items) {
diff --git a/chrome/browser/ui/app_list/app_list_model_updater.h b/chrome/browser/ui/app_list/app_list_model_updater.h index a62fb91..cc45a96 100644 --- a/chrome/browser/ui/app_list/app_list_model_updater.h +++ b/chrome/browser/ui/app_list/app_list_model_updater.h
@@ -39,6 +39,8 @@ virtual ~AppListModelUpdater() {} + int model_id() const { return model_id_; } + // Set whether this model updater is active. // When we have multiple user profiles, only the active one has access to the // model. All others profile can only cache model changes in Chrome. @@ -146,11 +148,16 @@ virtual void RemoveObserver(AppListModelUpdaterObserver* observer) = 0; protected: + AppListModelUpdater(); + // Returns the first available position in app list. |top_level_items| are // items without parents. Note that all items in |top_level_items| should have // valid position. static syncer::StringOrdinal GetFirstAvailablePositionInternal( const std::vector<ChromeAppListItem*>& top_level_items); + + private: + const int model_id_; }; #endif // CHROME_BROWSER_UI_APP_LIST_APP_LIST_MODEL_UPDATER_H_
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc index 2b831591..29aa515 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc +++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
@@ -37,7 +37,9 @@ std::vector<ash::mojom::AppListItemMetadataPtr> items_to_sync; for (auto const& item : items_) items_to_sync.push_back(item.second->CloneMetadata()); - app_list_controller_->SetModelData(std::move(items_to_sync), + + DCHECK(profile_); + app_list_controller_->SetModelData(model_id(), std::move(items_to_sync), search_engine_is_google_); }
diff --git a/chrome/browser/ui/browser_dialogs.h b/chrome/browser/ui/browser_dialogs.h index 44dca67..117255d 100644 --- a/chrome/browser/ui/browser_dialogs.h +++ b/chrome/browser/ui/browser_dialogs.h
@@ -138,7 +138,7 @@ // Creates a toolkit-views based LoginHandler (e.g. HTTP-Auth dialog). std::unique_ptr<LoginHandler> CreateLoginHandlerViews( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, LoginAuthRequiredCallback auth_required_callback);
diff --git a/chrome/browser/ui/login/login_handler.cc b/chrome/browser/ui/login/login_handler.cc index ec3102b..1c13aa99 100644 --- a/chrome/browser/ui/login/login_handler.cc +++ b/chrome/browser/ui/login/login_handler.cc
@@ -89,7 +89,7 @@ DCHECK(model); } -LoginHandler::LoginHandler(net::AuthChallengeInfo* auth_info, +LoginHandler::LoginHandler(const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, LoginAuthRequiredCallback auth_required_callback) : WebContentsObserver(web_contents), @@ -98,7 +98,6 @@ prompt_started_(false), weak_factory_(this) { DCHECK(web_contents); - DCHECK(auth_info_) << "LoginHandler constructed with NULL auth info"; } LoginHandler::~LoginHandler() { @@ -139,7 +138,7 @@ base::BindOnce(&LoginHandler::MaybeSetUpLoginPrompt, weak_factory_.GetWeakPtr(), request_url, is_main_frame); if (api->MaybeProxyAuthRequest(web_contents()->GetBrowserContext(), - auth_info_.get(), std::move(response_headers), + auth_info_, std::move(response_headers), request_id, is_main_frame, std::move(continuation))) { return; @@ -236,7 +235,7 @@ DCHECK(login_details->handler() != this); // Only handle notification for the identical auth info. - if (!login_details->handler()->auth_info()->Equals(*auth_info())) + if (login_details->handler()->auth_info() != auth_info()) return; // Ignore login notification events from other profiles. @@ -472,7 +471,7 @@ request_url.GetOrigin(); if (is_request_for_main_frame && (is_cross_origin_request || web_contents()->ShowingInterstitialPage() || - auth_info()->is_proxy) && + auth_info().is_proxy) && web_contents()->GetDelegate()->GetDisplayMode(web_contents()) != blink::kWebDisplayModeStandalone) { RecordHttpAuthPromptType(AUTH_PROMPT_TYPE_WITH_INTERSTITIAL); @@ -486,7 +485,7 @@ // This cancels any existing interstitial. interstitial_delegate_ = (new LoginInterstitialDelegate( - web_contents(), auth_info()->is_proxy ? GURL() : request_url, + web_contents(), auth_info().is_proxy ? GURL() : request_url, std::move(callback))) ->GetWeakPtr(); @@ -518,7 +517,7 @@ base::string16 authority; base::string16 explanation; - GetDialogStrings(request_url, *auth_info(), &authority, &explanation); + GetDialogStrings(request_url, auth_info(), &authority, &explanation); password_manager::PasswordManager* password_manager = GetPasswordManagerForLogin(); @@ -548,7 +547,7 @@ } PasswordForm observed_form( - MakeInputForPasswordManager(request_url, *auth_info())); + MakeInputForPasswordManager(request_url, auth_info())); LoginModelData model_data(password_manager, observed_form); BuildViewAndNotify(authority, explanation, &model_data); } @@ -570,7 +569,7 @@ // ---------------------------------------------------------------------------- // Public API std::unique_ptr<content::LoginDelegate> CreateLoginPrompt( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, const content::GlobalRequestID& request_id, bool is_request_for_main_frame,
diff --git a/chrome/browser/ui/login/login_handler.h b/chrome/browser/ui/login/login_handler.h index 08d4aef..a14fd1c 100644 --- a/chrome/browser/ui/login/login_handler.h +++ b/chrome/browser/ui/login/login_handler.h
@@ -23,6 +23,7 @@ #include "content/public/browser/notification_registrar.h" #include "content/public/browser/resource_request_info.h" #include "content/public/browser/web_contents_observer.h" +#include "net/base/auth.h" class GURL; class LoginInterstitialDelegate; @@ -31,10 +32,6 @@ class WebContents; } // namespace content -namespace net { -class AuthChallengeInfo; -} // namespace net - // This is the base implementation for the OS-specific classes that prompt for // authentication information. class LoginHandler : public content::LoginDelegate, @@ -56,7 +53,7 @@ const autofill::PasswordForm& form; }; - LoginHandler(net::AuthChallengeInfo* auth_info, + LoginHandler(const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, LoginAuthRequiredCallback auth_required_callback); ~LoginHandler() override; @@ -67,7 +64,7 @@ // them, the login request is aborted and the callback will not be called. The // callback must remain valid until one of those two events occurs. static std::unique_ptr<LoginHandler> Create( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, LoginAuthRequiredCallback auth_required_callback); @@ -93,7 +90,7 @@ const content::NotificationDetails& details) override; // Who/where/what asked for the authentication. - const net::AuthChallengeInfo* auth_info() const { return auth_info_.get(); } + const net::AuthChallengeInfo& auth_info() const { return auth_info_; } protected: // Implement this to initialize the underlying platform specific view. If @@ -169,7 +166,7 @@ LoginModelData* login_model_data); // Who/where/what asked for the authentication. - scoped_refptr<net::AuthChallengeInfo> auth_info_; + net::AuthChallengeInfo auth_info_; // The PasswordForm sent to the PasswordManager. This is so we can refer to it // when later notifying the password manager if the credentials were accepted @@ -232,7 +229,7 @@ // request by destroying the returned LoginDelegate. It must do this before // invalidating the callback. std::unique_ptr<content::LoginDelegate> CreateLoginPrompt( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, const content::GlobalRequestID& request_id, bool is_main_frame,
diff --git a/chrome/browser/ui/login/login_handler_browsertest.cc b/chrome/browser/ui/login/login_handler_browsertest.cc index a1d3cb3..9930929 100644 --- a/chrome/browser/ui/login/login_handler_browsertest.cc +++ b/chrome/browser/ui/login/login_handler_browsertest.cc
@@ -163,10 +163,9 @@ }; void LoginPromptBrowserTest::SetAuthFor(LoginHandler* handler) { - const net::AuthChallengeInfo* challenge = handler->auth_info(); + const net::AuthChallengeInfo& challenge = handler->auth_info(); - ASSERT_TRUE(challenge); - auto i = auth_map_.find(challenge->realm); + auto i = auth_map_.find(challenge.realm); EXPECT_TRUE(auth_map_.end() != i); if (i != auth_map_.end()) { const AuthInfo& info = i->second; @@ -604,10 +603,10 @@ login_prompt_observer_.handlers().begin(), login_prompt_observer_.handlers().end(), [&seen_realms](LoginHandler* handler) { - return seen_realms.count(handler->auth_info()->realm) == 0; + return seen_realms.count(handler->auth_info().realm) == 0; }); ASSERT_TRUE(it != login_prompt_observer_.handlers().end()); - seen_realms.insert((*it)->auth_info()->realm); + seen_realms.insert((*it)->auth_info().realm); for_each_realm_func(*it); }
diff --git a/chrome/browser/ui/login/login_handler_unittest.cc b/chrome/browser/ui/login/login_handler_unittest.cc index 2a9c978ff9..fb2fa41 100644 --- a/chrome/browser/ui/login/login_handler_unittest.cc +++ b/chrome/browser/ui/login/login_handler_unittest.cc
@@ -114,26 +114,26 @@ } // namespace TEST(LoginHandlerTest, DialogStringsAndRealm) { - scoped_refptr<net::AuthChallengeInfo> auth_info = new net::AuthChallengeInfo; for (const auto& test_case : kTestCases) { + net::AuthChallengeInfo auth_info; GURL request_url(test_case.request_url); - auth_info->is_proxy = test_case.auth_info.target_type == PROXY; - auth_info->scheme = test_case.auth_info.scheme; - auth_info->realm = test_case.auth_info.realm; - auth_info->challenger = url::Origin::Create( + auth_info.is_proxy = test_case.auth_info.target_type == PROXY; + auth_info.scheme = test_case.auth_info.scheme; + auth_info.realm = test_case.auth_info.realm; + auth_info.challenger = url::Origin::Create( test_case.auth_info.challenger ? GURL(test_case.auth_info.challenger) : request_url); SCOPED_TRACE(::testing::Message() << "request_url:" << test_case.request_url - << " auth_info: { is_proxy:" << auth_info->is_proxy - << " scheme:'" << auth_info->scheme << "' realm:'" - << auth_info->realm << "' challenger:'" - << auth_info->challenger.Serialize() << "' }"); + << " auth_info: { is_proxy:" << auth_info.is_proxy + << " scheme:'" << auth_info.scheme << "' realm:'" + << auth_info.realm << "' challenger:'" + << auth_info.challenger.Serialize() << "' }"); base::string16 authority; base::string16 explanation; - LoginHandler::GetDialogStrings(request_url, *auth_info, &authority, + LoginHandler::GetDialogStrings(request_url, auth_info, &authority, &explanation); EXPECT_EQ(ExpectedAuthority(test_case.auth_info.target_type == PROXY, test_case.expected.authority), @@ -142,6 +142,6 @@ base::UTF16ToASCII(explanation).c_str()); EXPECT_STREQ(test_case.expected.signon_realm, - LoginHandler::GetSignonRealm(request_url, *auth_info).c_str()); + LoginHandler::GetSignonRealm(request_url, auth_info).c_str()); } }
diff --git a/chrome/browser/ui/tabs/tab_utils.cc b/chrome/browser/ui/tabs/tab_utils.cc index 9deb09a..da380e4 100644 --- a/chrome/browser/ui/tabs/tab_utils.cc +++ b/chrome/browser/ui/tabs/tab_utils.cc
@@ -48,6 +48,9 @@ if (usb_tab_helper && usb_tab_helper->IsDeviceConnected()) return TabAlertState::USB_CONNECTED; + if (contents->IsConnectedToSerialPort()) + return TabAlertState::SERIAL_CONNECTED; + // Check if VR content is being presented in a headset. // NOTE: This icon must take priority over the audio alert ones // because most VR content has audio and its usage is implied by the VR icon. @@ -85,6 +88,7 @@ case TabAlertState::TAB_CAPTURING: case TabAlertState::BLUETOOTH_CONNECTED: case TabAlertState::USB_CONNECTED: + case TabAlertState::SERIAL_CONNECTED: case TabAlertState::DESKTOP_CAPTURING: // The new Audio Service implements muting separately from the tab audio // capture infrastructure; so the mute state can be toggled independently
diff --git a/chrome/browser/ui/tabs/tab_utils.h b/chrome/browser/ui/tabs/tab_utils.h index 8e4ca381..e9ff577 100644 --- a/chrome/browser/ui/tabs/tab_utils.h +++ b/chrome/browser/ui/tabs/tab_utils.h
@@ -28,6 +28,7 @@ AUDIO_MUTING, // Tab audio is being muted. BLUETOOTH_CONNECTED, // Tab is connected to a BT Device. USB_CONNECTED, // Tab is connected to a USB device. + SERIAL_CONNECTED, // Tab is connected to a serial device. PIP_PLAYING, // Tab contains a video in Picture-in-Picture mode. DESKTOP_CAPTURING, // Desktop contents being recorded, consumed by tab. VR_PRESENTING_IN_HEADSET, // VR content is being presented in a headset.
diff --git a/chrome/browser/ui/views/browser_dialogs_views.cc b/chrome/browser/ui/views/browser_dialogs_views.cc index 1844555..8f0c610 100644 --- a/chrome/browser/ui/views/browser_dialogs_views.cc +++ b/chrome/browser/ui/views/browser_dialogs_views.cc
@@ -18,7 +18,7 @@ // all toolkit-views platforms. // static std::unique_ptr<LoginHandler> LoginHandler::Create( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, LoginAuthRequiredCallback auth_required_callback) { return chrome::CreateLoginHandlerViews(auth_info, web_contents,
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.cc index 9a53555..75b9c3f1 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.cc
@@ -5,10 +5,12 @@ #include "chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.h" #include "base/command_line.h" +#include "base/numerics/safe_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" #include "chrome/browser/ui/views/desktop_capture/desktop_media_list_view.h" #include "chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.h" +#include "chrome/browser/ui/views/desktop_capture/desktop_media_tab_list.h" #include "chrome/common/chrome_switches.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -33,6 +35,16 @@ return view; } +std::unique_ptr<views::View> DesktopMediaListController::CreateTabListView( + const base::string16& accessible_name) { + DCHECK(!view_); + + auto view = std::make_unique<DesktopMediaTabList>(this, accessible_name); + view_ = view.get(); + view_observer_.Add(view_); + return view; +} + void DesktopMediaListController::StartUpdating( content::DesktopMediaID dialog_window_id) { media_list_->SetViewDialogWindowId(dialog_window_id); @@ -46,10 +58,7 @@ base::Optional<content::DesktopMediaID> DesktopMediaListController::GetSelection() const { - if (!view_ || !view_->GetSelection()) - return base::nullopt; - return base::Optional<content::DesktopMediaID>( - view_->GetSelection()->source_id()); + return view_ ? view_->GetSelection() : base::nullopt; } void DesktopMediaListController::OnSourceListLayoutChanged() { @@ -69,8 +78,12 @@ dialog_->AcceptSpecificSource(source); } +size_t DesktopMediaListController::GetSourceCount() const { + return base::checked_cast<size_t>(media_list_->GetSourceCount()); +} + const DesktopMediaList::Source& DesktopMediaListController::GetSource( - int index) const { + size_t index) const { return media_list_->GetSource(index); } @@ -84,8 +97,10 @@ void DesktopMediaListController::OnSourceAdded(DesktopMediaList* list, int index) { - if (view_) - view_->OnSourceAdded(index); + if (view_) { + view_->GetSourceListListener()->OnSourceAdded( + base::checked_cast<size_t>(index)); + } std::string autoselect_source = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( @@ -103,26 +118,35 @@ void DesktopMediaListController::OnSourceRemoved(DesktopMediaList* list, int index) { - if (view_) - view_->OnSourceRemoved(index); + if (view_) { + view_->GetSourceListListener()->OnSourceRemoved( + base::checked_cast<size_t>(index)); + } } void DesktopMediaListController::OnSourceMoved(DesktopMediaList* list, int old_index, int new_index) { - if (view_) - view_->OnSourceMoved(old_index, new_index); + if (view_) { + view_->GetSourceListListener()->OnSourceMoved( + base::checked_cast<size_t>(old_index), + base::checked_cast<size_t>(new_index)); + } } void DesktopMediaListController::OnSourceNameChanged(DesktopMediaList* list, int index) { - if (view_) - view_->OnSourceNameChanged(index); + if (view_) { + view_->GetSourceListListener()->OnSourceNameChanged( + base::checked_cast<size_t>(index)); + } } void DesktopMediaListController::OnSourceThumbnailChanged( DesktopMediaList* list, int index) { - if (view_) - view_->OnSourceThumbnailChanged(index); + if (view_) { + view_->GetSourceListListener()->OnSourceThumbnailChanged( + base::checked_cast<size_t>(index)); + } } void DesktopMediaListController::OnViewIsDeleting(views::View* view) {
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.h b/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.h index f9925292..9057f9b 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.h +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.h
@@ -15,19 +15,46 @@ #include "ui/views/view.h" #include "ui/views/view_observer.h" -class DesktopMediaListView; class DesktopMediaPickerDialogView; -// This class is the controller for a DesktopMediaListView. It is responsible -// for: +// This class is the controller for a View that displays a DesktopMediaList. It +// is responsible for: // * Observing a DesktopMediaList -// * Updating its internal view (currently a DesktopMediaListView) when that -// DesktopMediaList changes -// * Providing access to the state of its internal view to the dialog -// * Proxying between its internal view's callbacks and the dialog's callbacks +// * Updating its controlled view when that DesktopMediaList changes +// * Providing access to the state of its controlled view to the dialog +// * Proxying between its controlled view's callbacks and the dialog's +// callbacks class DesktopMediaListController : public DesktopMediaListObserver, public views::ViewObserver { public: + // The interface implemented by a controlled view or one of its helper classes + // to listen for updates to the source list. + class SourceListListener { + public: + virtual void OnSourceAdded(size_t index) = 0; + virtual void OnSourceRemoved(size_t index) = 0; + virtual void OnSourceMoved(size_t old_index, size_t new_index) = 0; + virtual void OnSourceNameChanged(size_t index) = 0; + virtual void OnSourceThumbnailChanged(size_t index) = 0; + }; + + // The abstract interface implemented by any view controlled by this + // controller. + class ListView : public views::View { + public: + // Returns the DesktopMediaID of the selected element of this list, or + // nullopt if no element is selected. + virtual base::Optional<content::DesktopMediaID> GetSelection() = 0; + + // Returns the SourceListListener to use to notify this ListView of changes + // to the backing DesktopMediaList. + virtual SourceListListener* GetSourceListListener() = 0; + + protected: + ListView() = default; + ~ListView() override = default; + }; + DesktopMediaListController(DesktopMediaPickerDialogView* dialog, std::unique_ptr<DesktopMediaList> media_list); ~DesktopMediaListController() override; @@ -40,6 +67,9 @@ DesktopMediaSourceViewStyle single_style, const base::string16& accessible_name); + std::unique_ptr<views::View> CreateTabListView( + const base::string16& accessible_name); + // Starts observing the DesktopMediaList given earlier, ignoring any entries // whose id matches dialog_window_id. void StartUpdating(content::DesktopMediaID dialog_window_id); @@ -63,9 +93,10 @@ // controller's source list is the one being shown. views::View* GetViewForInitialFocus(); - // These two methods are used by the view (or its subviews) to query and + // These methods are used by the view (or its subviews) to query and // update the underlying DesktopMediaList. - const DesktopMediaList::Source& GetSource(int index) const; + size_t GetSourceCount() const; + const DesktopMediaList::Source& GetSource(size_t index) const; void SetThumbnailSize(const gfx::Size& size); private: @@ -91,7 +122,7 @@ DesktopMediaPickerDialogView* dialog_; std::unique_ptr<DesktopMediaList> media_list_; - DesktopMediaListView* view_{nullptr}; + ListView* view_ = nullptr; ScopedObserver<views::View, views::ViewObserver> view_observer_{this}; base::WeakPtrFactory<DesktopMediaListController> weak_factory_{this};
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_list_view.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_list_view.cc index 2800c9a..cd481e1 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_list_view.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_list_view.cc
@@ -46,6 +46,12 @@ } #endif +DesktopMediaSourceView* AsDesktopMediaSourceView(views::View* view) { + DCHECK_EQ(DesktopMediaSourceView::kDesktopMediaSourceViewClassName, + view->GetClassName()); + return static_cast<DesktopMediaSourceView*>(view); +} + } // namespace DesktopMediaListView::DesktopMediaListView( @@ -73,15 +79,6 @@ controller_->AcceptSource(); } -DesktopMediaSourceView* DesktopMediaListView::GetSelection() { - for (int i = 0; i < child_count(); ++i) { - DesktopMediaSourceView* source_view = GetChild(i); - if (source_view->is_selected()) - return source_view; - } - return nullptr; -} - gfx::Size DesktopMediaListView::CalculatePreferredSize() const { int total_rows = (child_count() + active_style_->columns - 1) / active_style_->columns; @@ -128,7 +125,7 @@ if (position_increment == 0) return false; - views::View* selected = GetSelection(); + views::View* selected = GetSelectedView(); views::View* new_selected = nullptr; if (selected) { @@ -147,7 +144,18 @@ return true; } -void DesktopMediaListView::OnSourceAdded(int index) { +base::Optional<content::DesktopMediaID> DesktopMediaListView::GetSelection() { + DesktopMediaSourceView* view = GetSelectedView(); + return view ? base::Optional<content::DesktopMediaID>(view->source_id()) + : base::nullopt; +} + +DesktopMediaListController::SourceListListener* +DesktopMediaListView::GetSourceListListener() { + return this; +} + +void DesktopMediaListView::OnSourceAdded(size_t index) { const DesktopMediaList::Source& source = controller_->GetSource(index); // We are going to have a second item, apply the generic style. @@ -180,8 +188,8 @@ PreferredSizeChanged(); } -void DesktopMediaListView::OnSourceRemoved(int index) { - DesktopMediaSourceView* view = GetChild(index); +void DesktopMediaListView::OnSourceRemoved(size_t index) { + DesktopMediaSourceView* view = AsDesktopMediaSourceView(children()[index]); DCHECK(view); bool was_selected = view->is_selected(); @@ -201,20 +209,22 @@ PreferredSizeChanged(); } -void DesktopMediaListView::OnSourceMoved(int old_index, int new_index) { +void DesktopMediaListView::OnSourceMoved(size_t old_index, size_t new_index) { ReorderChildView(child_at(old_index), new_index); PreferredSizeChanged(); } -void DesktopMediaListView::OnSourceNameChanged(int index) { +void DesktopMediaListView::OnSourceNameChanged(size_t index) { const DesktopMediaList::Source& source = controller_->GetSource(index); - DesktopMediaSourceView* source_view = GetChild(index); + DesktopMediaSourceView* source_view = + AsDesktopMediaSourceView(children()[index]); source_view->SetName(source.name); } -void DesktopMediaListView::OnSourceThumbnailChanged(int index) { +void DesktopMediaListView::OnSourceThumbnailChanged(size_t index) { const DesktopMediaList::Source& source = controller_->GetSource(index); - DesktopMediaSourceView* source_view = GetChild(index); + DesktopMediaSourceView* source_view = + AsDesktopMediaSourceView(children()[index]); source_view->SetThumbnail(source.thumbnail); } @@ -224,16 +234,15 @@ style->image_rect.width() - 2 * style->selection_border_thickness, style->image_rect.height() - 2 * style->selection_border_thickness)); - for (int i = 0; i < child_count(); i++) { - GetChild(i)->SetStyle(*active_style_); - } + for (auto* child : children()) + AsDesktopMediaSourceView(child)->SetStyle(*active_style_); } -DesktopMediaSourceView* DesktopMediaListView::GetChild(int index) { - views::View* child = child_at(index); - DCHECK_EQ(DesktopMediaSourceView::kDesktopMediaSourceViewClassName, - child->GetClassName()); - return static_cast<DesktopMediaSourceView*>(child); +DesktopMediaSourceView* DesktopMediaListView::GetSelectedView() { + const auto i = std::find_if( + children().cbegin(), children().cend(), + [](View* v) { return AsDesktopMediaSourceView(v)->is_selected(); }); + return (i == children().cend()) ? nullptr : AsDesktopMediaSourceView(*i); } void DesktopMediaListView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_list_view.h b/chrome/browser/ui/views/desktop_capture/desktop_media_list_view.h index 62d19e40..fe61dc2e 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_list_view.h +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_list_view.h
@@ -8,6 +8,7 @@ #include <memory> #include "chrome/browser/media/webrtc/desktop_media_list.h" +#include "chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.h" #include "chrome/browser/ui/views/desktop_capture/desktop_media_source_view.h" #include "content/public/browser/desktop_media_id.h" #include "ui/views/view.h" @@ -16,7 +17,9 @@ // View that shows a list of desktop media sources available from // DesktopMediaList. -class DesktopMediaListView : public views::View { +class DesktopMediaListView + : public DesktopMediaListController::ListView, + public DesktopMediaListController::SourceListListener { public: DesktopMediaListView(DesktopMediaListController* controller, DesktopMediaSourceViewStyle generic_style, @@ -31,27 +34,29 @@ // Called by DesktopMediaSourceView when a source has been double-clicked. void OnDoubleClick(); - // Returns currently selected source. - DesktopMediaSourceView* GetSelection(); - - // views::View overrides. + // views::View: gfx::Size CalculatePreferredSize() const override; void Layout() override; bool OnKeyPressed(const ui::KeyEvent& event) override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; - void OnSourceAdded(int index); - void OnSourceRemoved(int index); - void OnSourceMoved(int old_index, int new_index); - void OnSourceNameChanged(int index); - void OnSourceThumbnailChanged(int index); + // DesktopMediaListController::ListView: + base::Optional<content::DesktopMediaID> GetSelection() override; + DesktopMediaListController::SourceListListener* GetSourceListListener() + override; + + // DesktopMediaListController::SourceListListener: + void OnSourceAdded(size_t index) override; + void OnSourceRemoved(size_t index) override; + void OnSourceMoved(size_t old_index, size_t new_index) override; + void OnSourceNameChanged(size_t index) override; + void OnSourceThumbnailChanged(size_t index) override; private: // Change the source style of this list on the fly. void SetStyle(DesktopMediaSourceViewStyle* style); - // Helper for child_at(). - DesktopMediaSourceView* GetChild(int index); + DesktopMediaSourceView* GetSelectedView(); DesktopMediaListController* controller_;
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc index 5e31d8e..943fe50d 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
@@ -155,31 +155,14 @@ case DesktopMediaID::TYPE_WEB_CONTENTS: { source_types_.push_back(DesktopMediaID::TYPE_WEB_CONTENTS); - const DesktopMediaSourceViewStyle kTabStyle( - 1, // columns - gfx::Size(600, 30), // item_size - gfx::Rect(), // icon_rect - gfx::Rect(46, 0, 490, 30), // label_rect - gfx::HorizontalAlignment::ALIGN_LEFT, // text_alignment - gfx::Rect(10, 2, 26, 26), // image_rect - 1, // selection_border_thickness - 0); // focus_rectangle_inset - - views::ScrollView* tab_scroll_view = - views::ScrollView::CreateScrollViewWithBorder(); - base::string16 tab_title_text = + base::string16 title = l10n_util::GetStringUTF16(IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_TAB); auto list_controller = std::make_unique<DesktopMediaListController>( this, std::move(source_list)); - tab_scroll_view->SetContents( - list_controller->CreateView(kTabStyle, kTabStyle, tab_title_text)); + pane_->AddTab(title, + list_controller->CreateTabListView(title).release()); list_controllers_.push_back(std::move(list_controller)); - tab_scroll_view->ClipHeightTo(kTabStyle.item_size.height() * 10, - kTabStyle.item_size.height() * 10); - tab_scroll_view->set_hide_horizontal_scrollbar(true); - - pane_->AddTab(tab_title_text, tab_scroll_view); pane_->set_listener(this); break; }
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.h b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.h index ae3843d..6b7b403 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.h +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.h
@@ -39,13 +39,13 @@ void OnSourceListLayoutChanged(); void SelectTab(content::DesktopMediaID::Type source_type); - // views::TabbedPaneListener overrides. + // views::TabbedPaneListener: void TabSelectedAt(int index) override; - // views::View overrides. + // views::View: gfx::Size CalculatePreferredSize() const override; - // views::DialogDelegateView overrides. + // views::DialogDelegateView: ui::ModalType GetModalType() const override; base::string16 GetWindowTitle() const override; bool IsDialogButtonEnabled(ui::DialogButton button) const override; @@ -89,7 +89,7 @@ void NotifyDialogResult(content::DesktopMediaID source); - // DesktopMediaPicker overrides. + // DesktopMediaPicker: void Show(const DesktopMediaPicker::Params& params, std::vector<std::unique_ptr<DesktopMediaList>> source_lists, const DoneCallback& done_callback) override;
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_test_api.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_test_api.cc index ec63391..a025ae36 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_test_api.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_test_api.cc
@@ -7,16 +7,30 @@ #include "chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.h" #include "chrome/browser/ui/views/desktop_capture/desktop_media_list_view.h" #include "chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.h" +#include "chrome/browser/ui/views/desktop_capture/desktop_media_tab_list.h" #include "ui/events/base_event_utils.h" #include "ui/views/controls/button/checkbox.h" #include "ui/views/controls/tabbed_pane/tabbed_pane.h" +#include "ui/views/controls/table/table_view.h" + +namespace { + +bool IsDesktopMediaTabList(views::View* view) { + return !strcmp(view->GetClassName(), "DesktopMediaTabList"); +} + +} // namespace DesktopMediaPickerViewsTestApi::DesktopMediaPickerViewsTestApi() = default; DesktopMediaPickerViewsTestApi::~DesktopMediaPickerViewsTestApi() = default; -void DesktopMediaPickerViewsTestApi::FocusSourceAtIndex(int index) { - GetSourceAtIndex(index)->RequestFocus(); +void DesktopMediaPickerViewsTestApi::FocusSourceAtIndex(size_t index) { + views::View* source_view = GetSourceAtIndex(index); + if (source_view) + source_view->RequestFocus(); + else + GetTableView()->Select(index); } void DesktopMediaPickerViewsTestApi::FocusAudioCheckbox() { @@ -24,21 +38,33 @@ } void DesktopMediaPickerViewsTestApi::PressMouseOnSourceAtIndex( - int index, + size_t index, bool double_click) { int flags = ui::EF_LEFT_MOUSE_BUTTON; if (double_click) flags |= ui::EF_IS_DOUBLE_CLICK; - GetSourceAtIndex(index)->OnMousePressed( - ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), - ui::EventTimeForNow(), flags, ui::EF_LEFT_MOUSE_BUTTON)); + views::View* source_view = GetSourceAtIndex(index); + if (source_view) { + source_view->OnMousePressed( + ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), + ui::EventTimeForNow(), flags, ui::EF_LEFT_MOUSE_BUTTON)); + } else { + // There's no source view to target, and trying to target a specific source + // within a larger view would be breakage-prone; just ask the TableView to + // to select. + GetTableView()->Select(index); + if (double_click) + picker_->dialog_->GetSelectedController()->AcceptSource(); + } } -void DesktopMediaPickerViewsTestApi::DoubleTapSourceAtIndex(int index) { +void DesktopMediaPickerViewsTestApi::DoubleTapSourceAtIndex(size_t index) { ui::GestureEventDetails details(ui::ET_GESTURE_TAP); details.set_tap_count(2); ui::GestureEvent double_tap(10, 10, 0, base::TimeTicks(), details); - GetSourceAtIndex(index)->OnGestureEvent(&double_tap); + views::View* source_view = GetSourceAtIndex(index); + DCHECK(source_view); + source_view->OnGestureEvent(&double_tap); } void DesktopMediaPickerViewsTestApi::SelectTabForSourceType( @@ -50,14 +76,19 @@ picker_->dialog_->pane_->SelectTabAt(std::distance(source_types.cbegin(), i)); } -int DesktopMediaPickerViewsTestApi::GetSelectedSourceId() const { +base::Optional<int> DesktopMediaPickerViewsTestApi::GetSelectedSourceId() + const { DesktopMediaListController* controller = picker_->dialog_->GetSelectedController(); base::Optional<content::DesktopMediaID> source = controller->GetSelection(); - return source.has_value() ? source.value().id : -1; + return source.has_value() ? base::Optional<int>(source.value().id) + : base::nullopt; } -bool DesktopMediaPickerViewsTestApi::HasSourceAtIndex(int index) const { +bool DesktopMediaPickerViewsTestApi::HasSourceAtIndex(size_t index) const { + const views::TableView* table = GetTableView(); + if (table) + return base::checked_cast<size_t>(table->RowCount()) > index; return bool{GetSourceAtIndex(index)}; } @@ -70,12 +101,30 @@ } const views::View* DesktopMediaPickerViewsTestApi::GetSourceAtIndex( - int index) const { + size_t index) const { views::View* list = picker_->dialog_->GetSelectedController()->view_; - return (index < list->child_count()) ? list->child_at(index) : nullptr; + if (IsDesktopMediaTabList(list) || index >= list->children().size()) + return nullptr; + return list->children()[index]; } -views::View* DesktopMediaPickerViewsTestApi::GetSourceAtIndex(int index) { +views::View* DesktopMediaPickerViewsTestApi::GetSourceAtIndex(size_t index) { views::View* list = picker_->dialog_->GetSelectedController()->view_; - return (index < list->child_count()) ? list->child_at(index) : nullptr; + if (IsDesktopMediaTabList(list) || index >= list->children().size()) + return nullptr; + return list->children()[index]; +} + +const views::TableView* DesktopMediaPickerViewsTestApi::GetTableView() const { + views::View* list = picker_->dialog_->GetSelectedController()->view_; + return IsDesktopMediaTabList(list) + ? static_cast<DesktopMediaTabList*>(list)->child_ + : nullptr; +} + +views::TableView* DesktopMediaPickerViewsTestApi::GetTableView() { + views::View* list = picker_->dialog_->GetSelectedController()->view_; + return IsDesktopMediaTabList(list) + ? static_cast<DesktopMediaTabList*>(list)->child_ + : nullptr; }
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_test_api.h b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_test_api.h index 14bc7d2..f7cb043 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_test_api.h +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_test_api.h
@@ -11,6 +11,7 @@ namespace views { class Checkbox; +class TableView; class View; } // namespace views @@ -26,19 +27,21 @@ void set_picker(DesktopMediaPickerViews* picker) { picker_ = picker; } void FocusAudioCheckbox(); - void PressMouseOnSourceAtIndex(int index, bool double_click = false); + void PressMouseOnSourceAtIndex(size_t index, bool double_click = false); void SelectTabForSourceType(content::DesktopMediaID::Type source_type); views::Checkbox* GetAudioShareCheckbox(); - bool HasSourceAtIndex(int index) const; - void FocusSourceAtIndex(int index); - void DoubleTapSourceAtIndex(int index); - int GetSelectedSourceId() const; + bool HasSourceAtIndex(size_t index) const; + void FocusSourceAtIndex(size_t index); + void DoubleTapSourceAtIndex(size_t index); + base::Optional<int> GetSelectedSourceId() const; views::View* GetSelectedListView(); private: - const views::View* GetSourceAtIndex(int index) const; - views::View* GetSourceAtIndex(int index); + const views::View* GetSourceAtIndex(size_t index) const; + views::View* GetSourceAtIndex(size_t index); + const views::TableView* GetTableView() const; + views::TableView* GetTableView(); DesktopMediaPickerViews* picker_; };
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc index 7eeb883..254b52e84 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc
@@ -136,13 +136,15 @@ DesktopMediaID(source_type, 20)); // By default, nothing should be selected. - EXPECT_EQ(-1, test_api_.GetSelectedSourceId()); + EXPECT_FALSE(test_api_.GetSelectedSourceId().has_value()); test_api_.PressMouseOnSourceAtIndex(0); - EXPECT_EQ(10, test_api_.GetSelectedSourceId()); + ASSERT_TRUE(test_api_.GetSelectedSourceId().has_value()); + EXPECT_EQ(10, test_api_.GetSelectedSourceId().value()); test_api_.PressMouseOnSourceAtIndex(1); - EXPECT_EQ(20, test_api_.GetSelectedSourceId()); + ASSERT_TRUE(test_api_.GetSelectedSourceId().has_value()); + EXPECT_EQ(20, test_api_.GetSelectedSourceId().value()); } } @@ -208,13 +210,16 @@ DesktopMediaID(source_type, 20)); test_api_.FocusSourceAtIndex(0); - EXPECT_EQ(10, test_api_.GetSelectedSourceId()); + ASSERT_TRUE(test_api_.GetSelectedSourceId().has_value()); + EXPECT_EQ(10, test_api_.GetSelectedSourceId().value()); test_api_.FocusAudioCheckbox(); - EXPECT_EQ(10, test_api_.GetSelectedSourceId()); + ASSERT_TRUE(test_api_.GetSelectedSourceId().has_value()); + EXPECT_EQ(10, test_api_.GetSelectedSourceId().value()); test_api_.FocusSourceAtIndex(1); - EXPECT_EQ(20, test_api_.GetSelectedSourceId()); + ASSERT_TRUE(test_api_.GetSelectedSourceId().has_value()); + EXPECT_EQ(20, test_api_.GetSelectedSourceId().value()); } }
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_tab_list.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_tab_list.cc new file mode 100644 index 0000000..d920eec --- /dev/null +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_tab_list.cc
@@ -0,0 +1,168 @@ +// Copyright 2019 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 "chrome/browser/ui/views/desktop_capture/desktop_media_tab_list.h" + +#include "base/numerics/safe_conversions.h" +#include "ui/gfx/favicon_size.h" +#include "ui/views/accessibility/view_accessibility.h" +#include "ui/views/border.h" +#include "ui/views/controls/scroll_view.h" +#include "ui/views/controls/table/table_view.h" +#include "ui/views/controls/table/table_view_observer.h" +#include "ui/views/layout/fill_layout.h" +#include "ui/views/view.h" + +namespace { + +// ui::TableModel that wraps a DesktopMediaListController and listens for +// updates from it. +class TabListModel : public ui::TableModel, + public DesktopMediaListController::SourceListListener { + public: + explicit TabListModel(DesktopMediaListController* controller); + + // ui::TableModel: + int RowCount() override; + base::string16 GetText(int row, int column) override; + gfx::ImageSkia GetIcon(int row) override; + void SetObserver(ui::TableModelObserver* observer) override; + + // DesktopMediaListController::SourceListListener: + void OnSourceAdded(size_t index) override; + void OnSourceRemoved(size_t index) override; + void OnSourceMoved(size_t old_index, size_t new_index) override; + void OnSourceNameChanged(size_t index) override; + void OnSourceThumbnailChanged(size_t index) override; + + private: + TabListModel(const TabListModel&) = delete; + TabListModel operator=(const TabListModel&) = delete; + + DesktopMediaListController* controller_; + ui::TableModelObserver* observer_ = nullptr; +}; + +TabListModel::TabListModel(DesktopMediaListController* controller) + : controller_(controller) {} + +int TabListModel::RowCount() { + return base::checked_cast<int>(controller_->GetSourceCount()); +} + +base::string16 TabListModel::GetText(int row, int column) { + return controller_->GetSource(row).name; +} + +gfx::ImageSkia TabListModel::GetIcon(int row) { + return controller_->GetSource(row).thumbnail; +} + +void TabListModel::SetObserver(ui::TableModelObserver* observer) { + observer_ = observer; +} + +void TabListModel::OnSourceAdded(size_t index) { + observer_->OnItemsAdded(index, 1); +} + +void TabListModel::OnSourceRemoved(size_t index) { + observer_->OnItemsRemoved(index, 1); +} + +void TabListModel::OnSourceMoved(size_t old_index, size_t new_index) { + observer_->OnItemsMoved(old_index, 1, new_index); +} + +void TabListModel::OnSourceNameChanged(size_t index) { + observer_->OnItemsChanged(index, 1); +} + +void TabListModel::OnSourceThumbnailChanged(size_t index) { + observer_->OnItemsChanged(index, 1); +} + +// TableViewObserver implementation that bridges between the actual TableView +// listing tabs and the DesktopMediaTabList. +class TabListViewObserver : public views::TableViewObserver { + public: + explicit TabListViewObserver(DesktopMediaListController* controller); + + void OnSelectionChanged() override; + void OnDoubleClick() override; + void OnKeyDown(ui::KeyboardCode virtual_keycode) override; + + private: + TabListViewObserver(const TabListViewObserver&) = delete; + TabListViewObserver operator=(const TabListViewObserver&) = delete; + + DesktopMediaListController* controller_; +}; + +TabListViewObserver::TabListViewObserver(DesktopMediaListController* controller) + : controller_(controller) {} + +void TabListViewObserver::OnSelectionChanged() { + controller_->OnSourceSelectionChanged(); +} + +void TabListViewObserver::OnDoubleClick() { + controller_->AcceptSource(); +} + +void TabListViewObserver::OnKeyDown(ui::KeyboardCode virtual_keycode) { + if (virtual_keycode == ui::VKEY_RETURN) + controller_->AcceptSource(); +} + +} // namespace + +DesktopMediaTabList::DesktopMediaTabList(DesktopMediaListController* controller, + const base::string16& accessible_name) + : controller_(controller) { + // The thumbnail size isn't allowed to be smaller than gfx::kFaviconSize by + // the underlying media list. TableView requires that the icon size be exactly + // ui::TableModel::kIconSize; if it's not, rendering of the TableView breaks. + // This DCHECK enforces that kIconSize is an acceptable size for the source + // list. + DCHECK_GE(ui::TableModel::kIconSize, gfx::kFaviconSize); + + controller_->SetThumbnailSize( + gfx::Size(ui::TableModel::kIconSize, ui::TableModel::kIconSize)); + + SetLayoutManager(std::make_unique<views::FillLayout>()); + + model_ = std::make_unique<TabListModel>(controller_); + view_observer_ = std::make_unique<TabListViewObserver>(controller_); + + auto child = std::make_unique<views::TableView>( + model_.get(), std::vector<ui::TableColumn>(1), views::ICON_AND_TEXT, + true); + child->set_observer(view_observer_.get()); + child->GetViewAccessibility().OverrideName(accessible_name); + child->SetBorder(views::CreateSolidBorder(1, SK_ColorBLACK)); + child_ = child.get(); + + AddChildView(views::TableView::CreateScrollViewWithTable(std::move(child))); +} + +DesktopMediaTabList::~DesktopMediaTabList() { + child_->SetModel(nullptr); +} + +const char* DesktopMediaTabList::GetClassName() const { + return "DesktopMediaTabList"; +} + +base::Optional<content::DesktopMediaID> DesktopMediaTabList::GetSelection() { + int row = child_->FirstSelectedRow(); + if (row == -1) + return base::nullopt; + return controller_->GetSource(row).id; +} + +DesktopMediaListController::SourceListListener* +DesktopMediaTabList::GetSourceListListener() { + return model_.get(); +}
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_tab_list.h b/chrome/browser/ui/views/desktop_capture/desktop_media_tab_list.h new file mode 100644 index 0000000..3ea2ce4 --- /dev/null +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_tab_list.h
@@ -0,0 +1,64 @@ +// Copyright 2019 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 CHROME_BROWSER_UI_VIEWS_DESKTOP_CAPTURE_DESKTOP_MEDIA_TAB_LIST_H_ +#define CHROME_BROWSER_UI_VIEWS_DESKTOP_CAPTURE_DESKTOP_MEDIA_TAB_LIST_H_ + +#include "chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.h" + +namespace views { +class TableView; +class View; +} // namespace views + +namespace { +class TabListModel; +class TabListViewObserver; +} // namespace + +// This class is one of the possible ListViews a DesktopMediaListController can +// control. It displays a table of sources, one per line, with their "thumbnail" +// scaled down and displayed as an icon on that line of the table. It is used to +// display a list of tabs which are possible cast sources. +// +// Internally, this class has two helper classes: +// * TabListModel, which is a ui::TableModel that proxies for DesktopMediaList - +// it fetches data from the DesktopMediaList to populate the model, and +// observes the DesktopMediaList to update the TableModel. +// * TabListViewObserver, which is a TableViewObserver that notifies the +// controller when the user takes an action on the TableView. +// +// Since TableView really wants to be the child of a ScrollView, this class's +// internal view hierarchy actually looks like: +// DesktopMediaTabList +// ScrollView +// [ScrollView internal helper Views] +// TableView +class DesktopMediaTabList : public DesktopMediaListController::ListView { + public: + DesktopMediaTabList(DesktopMediaListController* controller, + const base::string16& accessible_name); + ~DesktopMediaTabList() override; + + // views::View: + const char* GetClassName() const override; + + // DesktopMediaListController::ListView: + base::Optional<content::DesktopMediaID> GetSelection() override; + DesktopMediaListController::SourceListListener* GetSourceListListener() + override; + + private: + friend class DesktopMediaPickerViewsTestApi; + + DesktopMediaTabList(const DesktopMediaTabList&) = delete; + DesktopMediaTabList operator=(const DesktopMediaTabList&) = delete; + + DesktopMediaListController* controller_; + std::unique_ptr<TabListModel> model_; + std::unique_ptr<TabListViewObserver> view_observer_; + views::TableView* child_ = nullptr; +}; + +#endif // CHROME_BROWSER_UI_VIEWS_DESKTOP_CAPTURE_DESKTOP_MEDIA_TAB_LIST_H_
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc index 955edaf..e78bf3d 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
@@ -735,7 +735,9 @@ } int BrowserNonClientFrameViewAsh::GetTabStripRightInset() const { - return caption_button_container_->GetPreferredSize().width(); + return ShouldShowCaptionButtons() + ? caption_button_container_->GetPreferredSize().width() + : 0; } bool BrowserNonClientFrameViewAsh::ShouldPaint() const {
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index a723a48e..5d070edf11 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1911,6 +1911,9 @@ case TabAlertState::BLUETOOTH_CONNECTED: return l10n_util::GetStringFUTF16( IDS_TAB_AX_LABEL_BLUETOOTH_CONNECTED_FORMAT, title); + case TabAlertState::SERIAL_CONNECTED: + return l10n_util::GetStringFUTF16( + IDS_TAB_AX_LABEL_SERIAL_CONNECTED_FORMAT, title); case TabAlertState::MEDIA_RECORDING: return l10n_util::GetStringFUTF16(IDS_TAB_AX_LABEL_MEDIA_RECORDING_FORMAT, title); @@ -1923,7 +1926,6 @@ case TabAlertState::PIP_PLAYING: return l10n_util::GetStringFUTF16(IDS_TAB_AX_LABEL_PIP_PLAYING_FORMAT, title); - case TabAlertState::DESKTOP_CAPTURING: return l10n_util::GetStringFUTF16( IDS_TAB_AX_LABEL_DESKTOP_CAPTURING_FORMAT, title);
diff --git a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc index 11f70b0..761ac3e 100644 --- a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc +++ b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
@@ -663,6 +663,16 @@ const int new_height = widget_layer->bounds().height() + top_container_height; root_bounds.set_height(new_height); root_view->SetBoundsRect(root_bounds); + // Changing the bounds will have triggered an InvalidateLayout() on + // NativeViewHost. InvalidateLayout() results in Layout() being called later, + // after transforms are set. NativeViewHostAura calculates the bounds of the + // window using transforms. By calling LayoutRootViewIfNecessary() we force + // the layout now, before any transforms are installed. To do otherwise + // results in NativeViewHost positioning the WebContents at the wrong + // location. + // TODO(https://crbug.com/950981): this is rather fragile, and the code should + // deal with Layout() being called during the slide. + root_view->GetWidget()->LayoutRootViewIfNecessary(); // We don't want anything to show outside the browser window's bounds. widget_layer->SetMasksToBounds(true);
diff --git a/chrome/browser/ui/views/location_bar/keyword_hint_view.cc b/chrome/browser/ui/views/location_bar/keyword_hint_view.cc index 6e547114..d1029f4d 100644 --- a/chrome/browser/ui/views/location_bar/keyword_hint_view.cc +++ b/chrome/browser/ui/views/location_bar/keyword_hint_view.cc
@@ -15,7 +15,6 @@ #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/omnibox/omnibox_theme.h" #include "chrome/browser/ui/views/chrome_typography.h" -#include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "chrome/grit/generated_resources.h" #include "components/omnibox/browser/omnibox_field_trial.h" #include "components/search_engines/template_url_service.h" @@ -28,16 +27,14 @@ #include "ui/views/controls/label.h" #include "ui/views/layout/fill_layout.h" -KeywordHintView::KeywordHintView(views::ButtonListener* listener, - Profile* profile, - OmniboxTint tint) - : Button(listener), +KeywordHintView::KeywordHintView(LocationBarView* parent, Profile* profile) + : Button(parent), + location_bar_view_(parent), profile_(profile), - leading_label_(nullptr), chip_container_(new views::View()), chip_label_( - new views::Label(base::string16(), CONTEXT_OMNIBOX_DECORATION)), - trailing_label_(nullptr) { + new views::Label(base::string16(), CONTEXT_OMNIBOX_DECORATION)) { + OmniboxTint tint = parent->GetTint(); const SkColor leading_label_text_color = GetOmniboxColor(OmniboxPart::LOCATION_BAR_TEXT_DEFAULT, tint); const SkColor background_color = @@ -207,6 +204,35 @@ views::Button::OnBoundsChanged(previous_bounds); } +void KeywordHintView::OnThemeChanged() { + OmniboxTint tint = location_bar_view_->GetTint(); + const SkColor leading_label_text_color = + GetOmniboxColor(OmniboxPart::LOCATION_BAR_TEXT_DEFAULT, tint); + const SkColor background_color = + GetOmniboxColor(OmniboxPart::LOCATION_BAR_BACKGROUND, tint); + leading_label_->SetEnabledColor(leading_label_text_color); + leading_label_->SetBackgroundColor(background_color); + + const SkColor tab_border_color = + GetOmniboxColor(OmniboxPart::LOCATION_BAR_BUBBLE_OUTLINE, tint); + SkColor text_color = leading_label_text_color; + SkColor tab_bg_color = GetOmniboxColor(OmniboxPart::RESULTS_BACKGROUND, tint); + if (OmniboxFieldTrial::IsExperimentalKeywordModeEnabled()) { + text_color = SK_ColorWHITE; + tab_bg_color = tab_border_color; + } + chip_label_->SetEnabledColor(text_color); + chip_label_->SetBackgroundColor(tab_bg_color); + + chip_container_->SetBackground(CreateBackgroundFromPainter( + views::Painter::CreateRoundRectWith1PxBorderPainter( + tab_bg_color, tab_border_color, + GetLayoutConstant(LOCATION_BAR_BUBBLE_CORNER_RADIUS)))); + + trailing_label_->SetEnabledColor(text_color); + trailing_label_->SetBackgroundColor(background_color); +} + views::Label* KeywordHintView::CreateLabel(SkColor text_color, SkColor background_color) { views::Label* label =
diff --git a/chrome/browser/ui/views/location_bar/keyword_hint_view.h b/chrome/browser/ui/views/location_bar/keyword_hint_view.h index 78d46ad..78e36d3 100644 --- a/chrome/browser/ui/views/location_bar/keyword_hint_view.h +++ b/chrome/browser/ui/views/location_bar/keyword_hint_view.h
@@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" +#include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "ui/gfx/geometry/size.h" #include "ui/views/controls/button/button.h" @@ -30,9 +31,7 @@ // couldn't bring myself to use such a long name. class KeywordHintView : public views::Button { public: - KeywordHintView(views::ButtonListener* listener, - Profile* profile, - OmniboxTint tint); + KeywordHintView(LocationBarView* parent, Profile* profile); ~KeywordHintView() override; void SetKeyword(const base::string16& keyword); @@ -46,18 +45,21 @@ gfx::Size CalculatePreferredSize() const override; void OnBoundsChanged(const gfx::Rect& previous_bounds) override; + void OnThemeChanged() override; + private: // Creates a label for non-chip text. views::Label* CreateLabel(SkColor text_color, SkColor background_color); int GetCornerRadius() const; - Profile* profile_; + LocationBarView* location_bar_view_ = nullptr; + Profile* profile_ = nullptr; - views::Label* leading_label_; - views::View* chip_container_; - views::Label* chip_label_; - views::Label* trailing_label_; + views::Label* leading_label_ = nullptr; + views::View* chip_container_ = nullptr; + views::Label* chip_label_ = nullptr; + views::Label* trailing_label_ = nullptr; base::string16 keyword_;
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index 7e3cb62..cda05a2 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -201,7 +201,7 @@ selected_keyword_view_ = new SelectedKeywordView(this, font_list, profile()); AddChildView(selected_keyword_view_); - keyword_hint_view_ = new KeywordHintView(this, profile(), tint()); + keyword_hint_view_ = new KeywordHintView(this, profile()); AddChildView(keyword_hint_view_); SkColor icon_color = GetColor(OmniboxPart::RESULTS_ICON); @@ -938,24 +938,6 @@ return omnibox_view_->model()->popup_model()->view(); } -OmniboxTint LocationBarView::GetTint() { - ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile()); - bool is_dark_mode = GetNativeTheme()->SystemDarkModeEnabled(); - if (theme_service->UsingDefaultTheme()) { - return profile()->GetProfileType() == Profile::INCOGNITO_PROFILE || - is_dark_mode - ? OmniboxTint::DARK - : OmniboxTint::LIGHT; - } - - // Check for GTK on Desktop Linux. - if (theme_service->IsSystemThemeDistinctFromDefaultTheme() && - theme_service->UsingSystemTheme()) - return OmniboxTint::NATIVE; - - return is_dark_mode ? OmniboxTint::DARK : OmniboxTint::LIGHT; -} - //////////////////////////////////////////////////////////////////////////////// // LocationBarView, private LocationBar implementation: @@ -1205,6 +1187,24 @@ } } +OmniboxTint LocationBarView::GetTint() { + ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile()); + bool is_dark_mode = GetNativeTheme()->SystemDarkModeEnabled(); + if (theme_service->UsingDefaultTheme()) { + return profile()->GetProfileType() == Profile::INCOGNITO_PROFILE || + is_dark_mode + ? OmniboxTint::DARK + : OmniboxTint::LIGHT; + } + + // Check for GTK on Desktop Linux. + if (theme_service->IsSystemThemeDistinctFromDefaultTheme() && + theme_service->UsingSystemTheme()) + return OmniboxTint::NATIVE; + + return is_dark_mode ? OmniboxTint::DARK : OmniboxTint::LIGHT; +} + //////////////////////////////////////////////////////////////////////////////// // LocationBarView, private DropdownBarHostDelegate implementation:
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h index cb3cd0e..de5490c 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.h +++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -255,6 +255,9 @@ on_icon_fetched) const override; SkColor GetLocationIconInkDropColor() const override; + // Gets the theme color tint for the location bar and results. + OmniboxTint GetTint(); + private: FRIEND_TEST_ALL_PREFIXES(SecurityIndicatorTest, CheckIndicatorText); FRIEND_TEST_ALL_PREFIXES(TouchLocationBarViewBrowserTest, @@ -301,9 +304,6 @@ // Gets the OmniboxPopupView associated with the model in |omnibox_view_|. OmniboxPopupView* GetOmniboxPopupView(); - // Gets the theme color tint for the location bar and results. - OmniboxTint GetTint(); - // LocationBar: GURL GetDestinationURL() const override; WindowOpenDisposition GetWindowOpenDisposition() const override;
diff --git a/chrome/browser/ui/views/login_handler_views.cc b/chrome/browser/ui/views/login_handler_views.cc index a61539b5..3b3eeb12 100644 --- a/chrome/browser/ui/views/login_handler_views.cc +++ b/chrome/browser/ui/views/login_handler_views.cc
@@ -29,7 +29,7 @@ // have been called. class LoginHandlerViews : public LoginHandler { public: - LoginHandlerViews(net::AuthChallengeInfo* auth_info, + LoginHandlerViews(const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, LoginAuthRequiredCallback auth_required_callback) : LoginHandler(auth_info, @@ -178,7 +178,7 @@ } // namespace std::unique_ptr<LoginHandler> CreateLoginHandlerViews( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, LoginAuthRequiredCallback auth_required_callback) { return std::make_unique<LoginHandlerViews>(auth_info, web_contents,
diff --git a/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc b/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc index 536cbd33..c7207ac 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc
@@ -279,12 +279,14 @@ icon_view_->SetSize(icon_view_->CalculatePreferredSize()); } - if (match.type == AutocompleteMatchType::CALCULATOR) { + const auto apply_vector_icon = [=](const gfx::VectorIcon& vector_icon) { + const auto& icon = gfx::CreateVectorIcon(vector_icon, SK_ColorWHITE); answer_image_view_->SetImage( - ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - IDR_OMNIBOX_CALCULATOR_ROUND)); - answer_image_view_->SetImageSize( - gfx::Size(kNewAnswerImageSize, kNewAnswerImageSize)); + gfx::CanvasImageSource::MakeImageSkia<EncircledImageSource>( + kNewAnswerImageSize / 2, gfx::kGoogleBlue600, icon)); + }; + if (match.type == AutocompleteMatchType::CALCULATOR) { + apply_vector_icon(omnibox::kAnswerCalculatorIcon); } else if (!is_rich_suggestion_) { // An old style answer entry may use the answer_image_view_. But // it's set when the image arrives (later). @@ -322,10 +324,7 @@ break; } if (vector_icon) { - const auto& icon = gfx::CreateVectorIcon(*vector_icon, SK_ColorWHITE); - answer_image_view_->SetImage( - gfx::CanvasImageSource::MakeImageSkia<EncircledImageSource>( - kNewAnswerImageSize / 2, gfx::kGoogleBlue600, icon)); + apply_vector_icon(*vector_icon); } else if (idr_image) { answer_image_view_->SetImage( ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
diff --git a/chrome/browser/ui/views/tabs/alert_indicator.cc b/chrome/browser/ui/views/tabs/alert_indicator.cc index b81e682..a60dc693 100644 --- a/chrome/browser/ui/views/tabs/alert_indicator.cc +++ b/chrome/browser/ui/views/tabs/alert_indicator.cc
@@ -7,6 +7,7 @@ #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/views/tabs/tab.h" +#include "components/vector_icons/vector_icons.h" #include "ui/base/material_design/material_design_controller.h" #include "ui/gfx/animation/animation_delegate.h" #include "ui/gfx/animation/multi_animation.h" @@ -103,6 +104,11 @@ case TabAlertState::USB_CONNECTED: icon = &kTabUsbConnectedIcon; break; + case TabAlertState::SERIAL_CONNECTED: + // TODO(https://crbug.com/917204): This icon is too large to fit properly + // as a tab indicator and should be replaced. + icon = &vector_icons::kSerialPortIcon; + break; case TabAlertState::PIP_PLAYING: icon = &kPictureInPictureAltIcon; break;
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index 3a550d0..ccda17a 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -631,6 +631,7 @@ return theme_provider->GetColor(ThemeProperties::COLOR_TAB_PIP_PLAYING); case TabAlertState::BLUETOOTH_CONNECTED: case TabAlertState::USB_CONNECTED: + case TabAlertState::SERIAL_CONNECTED: case TabAlertState::NONE: case TabAlertState::VR_PRESENTING_IN_HEADSET: return button_color_; @@ -755,6 +756,10 @@ result.append( l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_ALERT_STATE_USB_CONNECTED)); break; + case TabAlertState::SERIAL_CONNECTED: + result.append(l10n_util::GetStringUTF16( + IDS_TOOLTIP_TAB_ALERT_STATE_SERIAL_CONNECTED)); + break; case TabAlertState::PIP_PLAYING: result.append( l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_ALERT_STATE_PIP_PLAYING));
diff --git a/chrome/browser/ui/webui/chromeos/login/l10n_util_test_util.cc b/chrome/browser/ui/webui/chromeos/login/l10n_util_test_util.cc index 7189ed29..63a7250 100644 --- a/chrome/browser/ui/webui/chromeos/login/l10n_util_test_util.cc +++ b/chrome/browser/ui/webui/chromeos/login/l10n_util_test_util.cc
@@ -18,12 +18,6 @@ ~MockInputMethodManagerWithInputMethods() { } -std::unique_ptr<input_method::InputMethodDescriptors> -MockInputMethodManagerWithInputMethods::GetSupportedInputMethods() const { - return std::unique_ptr<input_method::InputMethodDescriptors>( - new input_method::InputMethodDescriptors(descriptors_)); -} - void MockInputMethodManagerWithInputMethods::AddInputMethod( const std::string& id, const std::string& raw_layout,
diff --git a/chrome/browser/ui/webui/chromeos/login/l10n_util_test_util.h b/chrome/browser/ui/webui/chromeos/login/l10n_util_test_util.h index 8136458..1b460c9f07 100644 --- a/chrome/browser/ui/webui/chromeos/login/l10n_util_test_util.h +++ b/chrome/browser/ui/webui/chromeos/login/l10n_util_test_util.h
@@ -22,10 +22,6 @@ MockInputMethodManagerWithInputMethods(); ~MockInputMethodManagerWithInputMethods() override; - // input_method::MockInputMethodManagerImpl: - std::unique_ptr<input_method::InputMethodDescriptors> - GetSupportedInputMethods() const override; - void AddInputMethod(const std::string& id, const std::string& raw_layout, const std::string& language_code);
diff --git a/chrome/browser/ui/webui/management_ui.cc b/chrome/browser/ui/webui/management_ui.cc index a35921d..fcf8957 100644 --- a/chrome/browser/ui/webui/management_ui.cc +++ b/chrome/browser/ui/webui/management_ui.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/ui/webui/localized_string.h" #include "chrome/browser/ui/webui/management_ui_handler.h" #include "chrome/common/url_constants.h" +#include "chrome/common/webui_url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/theme_resources.h" #include "components/safe_browsing/common/safebrowsing_constants.h" @@ -33,12 +34,12 @@ #if defined(OS_CHROMEOS) -base::string16 GetChromeOSManagementPageTitle() { +base::string16 GetChromeOSManagementPageSubtitle() { policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); const auto device_type = ui::GetChromeOSDeviceTypeResourceId(); if (!connector->IsEnterpriseManaged()) { - return l10n_util::GetStringFUTF16(IDS_MANAGEMENT_NOT_MANAGED_TITLE, + return l10n_util::GetStringFUTF16(IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE, l10n_util::GetStringUTF16(device_type)); } @@ -46,13 +47,13 @@ if (display_domain.empty()) { if (!connector->IsActiveDirectoryManaged()) { - return l10n_util::GetStringFUTF16(IDS_MANAGEMENT_TITLE_MANAGED, + return l10n_util::GetStringFUTF16(IDS_MANAGEMENT_SUBTITLE_MANAGED, l10n_util::GetStringUTF16(device_type)); } display_domain = connector->GetRealm(); } - return l10n_util::GetStringFUTF16(IDS_MANAGEMENT_TITLE_BY, + return l10n_util::GetStringFUTF16(IDS_MANAGEMENT_SUBTITLE_MANAGED_BY, l10n_util::GetStringUTF16(device_type), base::UTF8ToUTF16(display_domain)); } @@ -63,11 +64,12 @@ content::WebUIDataSource::Create(chrome::kChromeUIManagementHost); #if defined(OS_CHROMEOS) - source->AddString("title", GetChromeOSManagementPageTitle()); + source->AddString("subtitle", GetChromeOSManagementPageSubtitle()); #endif // defined(OS_CHROMEOS) static constexpr LocalizedString kLocalizedStrings[] = { #if defined(OS_CHROMEOS) + {"learnMore", IDS_LEARN_MORE}, {"deviceConfiguration", IDS_MANAGEMENT_DEVICE_CONFIGURATION}, {"deviceReporting", IDS_MANAGEMENT_DEVICE_REPORTING}, {kManagementLogUploadEnabled, IDS_MANAGEMENT_LOG_UPLOAD_ENABLED}, @@ -84,12 +86,13 @@ {"browserReportingExplanation", IDS_MANAGEMENT_BROWSER_REPORTING_EXPLANATION}, {"extensionReporting", IDS_MANAGEMENT_EXTENSION_REPORTING}, - {"extensionsInstalled", IDS_MANAGEMENT_EXTENSIONS_INSTALLED}, {"extensionName", IDS_MANAGEMENT_EXTENSIONS_NAME}, {"extensionPermissions", IDS_MANAGEMENT_EXTENSIONS_PERMISSIONS}, {"localTrustRoots", IDS_MANAGEMENT_LOCAL_TRUST_ROOTS}, {"managementTrustRootsNotConfigured", IDS_MANAGEMENT_TRUST_ROOTS_NOT_CONFIGURED}, + {"title", IDS_MANAGEMENT_TITLE}, + {"toolbarTitle", IDS_MANAGEMENT_TOOLBAR_TITLE}, #if BUILDFLAG(ENABLE_EXTENSIONS) {kManagementExtensionReportMachineName, IDS_MANAGEMENT_EXTENSION_REPORT_MACHINE_NAME}, @@ -115,6 +118,12 @@ l10n_util::GetStringFUTF16( IDS_MANAGEMENT_EXTENSION_REPORT_SAFE_BROWSING_WARNINGS, base::UTF8ToUTF16(safe_browsing::kSafeBrowsingUrl))); +#if defined(OS_CHROMEOS) + source->AddString("managementDeviceLearnMoreUrl", + chrome::kLearnMoreEnterpriseURL); +#endif // defined(OS_CHROMEOS) + source->AddString("managementAccountLearnMoreUrl", + chrome::kManagedUiLearnMoreUrl); #if BUILDFLAG(ENABLE_EXTENSIONS) @@ -126,7 +135,6 @@ #endif // defined(OS_CHROMEOS) source->SetJsonPath("strings.js"); // Add required resources. - source->AddResourcePath("management.js", IDR_MANAGEMENT_JS); source->AddResourcePath("management_browser_proxy.html", IDR_MANAGEMENT_BROWSER_PROXY_HTML); source->AddResourcePath("management_browser_proxy.js",
diff --git a/chrome/browser/ui/webui/management_ui_browsertest.cc b/chrome/browser/ui/webui/management_ui_browsertest.cc index e3e1174..798ef00 100644 --- a/chrome/browser/ui/webui/management_ui_browsertest.cc +++ b/chrome/browser/ui/webui/management_ui_browsertest.cc
@@ -76,13 +76,11 @@ "});" "unmanaged_result.push({" " name: 'extensionReportingTitle'," - " value: management.ManagementBrowserProxyImpl" - " .getInstance().getExtensionReportingTitle()" + " value: loadTimeData.getString('extensionReportingTitle')" "});" "unmanaged_result.push({" - " name: 'pageTitle'," - " value: management.ManagementBrowserProxyImpl" - " .getInstance().getPageTitle()" + " name: 'pageSubtitle'," + " value: loadTimeData.getString('subtitle')" "});" "domAutomationController.send(JSON.stringify(unmanaged_result));"; @@ -101,8 +99,8 @@ base::UTF8ToUTF16(chrome::kManagedUiLearnMoreUrl))}, {"extensionReportingTitle", l10n_util::GetStringUTF16(IDS_MANAGEMENT_EXTENSIONS_INSTALLED)}, - {"pageTitle", - l10n_util::GetStringUTF16(IDS_MANAGEMENT_NOT_MANAGED_TITLE)}, + {"pageSubtitle", + l10n_util::GetStringUTF16(IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE)}, }; VerifyTexts(unmanaged_value_ptr.get(), expected_unmanaged_values); @@ -128,13 +126,11 @@ "});" "managed_result.push({" " name: 'extensionReportingTitle'," - " value: management.ManagementBrowserProxyImpl" - " .getInstance().getExtensionReportingTitle()" + " value: loadTimeData.getString('extensionReportingTitle')" "});" "managed_result.push({" - " name: 'pageTitle'," - " value: management.ManagementBrowserProxyImpl" - " .getInstance().getPageTitle()" + " name: 'pageSubtitle'," + " value: loadTimeData.getString('subtitle')" "});" "domAutomationController.send(JSON.stringify(managed_result));"; @@ -150,7 +146,7 @@ base::UTF8ToUTF16(chrome::kManagedUiLearnMoreUrl))}, {"extensionReportingTitle", l10n_util::GetStringUTF16(IDS_MANAGEMENT_EXTENSIONS_INSTALLED)}, - {"pageTitle", l10n_util::GetStringUTF16(IDS_MANAGEMENT_TITLE)}, + {"pageSubtitle", l10n_util::GetStringUTF16(IDS_MANAGEMENT_SUBTITLE)}, }; VerifyTexts(managed_value_ptr.get(), expected_managed_values);
diff --git a/chrome/browser/ui/webui/management_ui_handler.cc b/chrome/browser/ui/webui/management_ui_handler.cc index d289c26..2f8359bb 100644 --- a/chrome/browser/ui/webui/management_ui_handler.cc +++ b/chrome/browser/ui/webui/management_ui_handler.cc
@@ -118,6 +118,12 @@ const char kManagementPrinting[] = "managementPrinting"; #endif // defined(OS_CHROMEOS) +const char kOverview[] = "overview"; +const char kDeviceManagedInfo[] = "deviceManagedInfo"; +const char kAccountManagedInfo[] = "accountManagedInfo"; +const char kSetup[] = "setup"; +const char kData[] = "data"; + namespace { bool IsProfileManaged(Profile* profile) { @@ -158,7 +164,7 @@ if (management_domain.empty()) { update->SetString( - "extensionsInstalled", + "extensionReportingTitle", l10n_util::GetStringUTF16(IDS_MANAGEMENT_EXTENSIONS_INSTALLED)); update->SetString("managementNotice", @@ -166,13 +172,14 @@ managed ? IDS_MANAGEMENT_BROWSER_NOTICE : IDS_MANAGEMENT_NOT_MANAGED_NOTICE, base::UTF8ToUTF16(chrome::kManagedUiLearnMoreUrl))); - update->SetString("title", l10n_util::GetStringUTF16( - managed ? IDS_MANAGEMENT_TITLE - : IDS_MANAGEMENT_NOT_MANAGED_TITLE)); + update->SetString("subtitle", + l10n_util::GetStringUTF16( + managed ? IDS_MANAGEMENT_SUBTITLE + : IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE)); } else { update->SetString( - "extensionsInstalled", + "extensionReportingTitle", l10n_util::GetStringFUTF16(IDS_MANAGEMENT_EXTENSIONS_INSTALLED_BY, base::UTF8ToUTF16(management_domain))); @@ -186,11 +193,11 @@ IDS_MANAGEMENT_NOT_MANAGED_NOTICE, base::UTF8ToUTF16(chrome::kManagedUiLearnMoreUrl))); update->SetString( - "title", + "subtitle", managed - ? l10n_util::GetStringFUTF16(IDS_MANAGEMENT_TITLE_BY, + ? l10n_util::GetStringFUTF16(IDS_MANAGEMENT_SUBTITLE_MANAGED_BY, base::UTF8ToUTF16(management_domain)) - : l10n_util::GetStringUTF16(IDS_MANAGEMENT_NOT_MANAGED_TITLE)); + : l10n_util::GetStringUTF16(IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE)); } } #endif // !defined(OS_CHROMEOS) @@ -387,8 +394,8 @@ void ManagementUIHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( - "getDeviceManagementStatus", - base::BindRepeating(&ManagementUIHandler::HandleGetDeviceManagementStatus, + "getManagementStatus", + base::BindRepeating(&ManagementUIHandler::HandleGetManagementStatus, base::Unretained(this))); web_ui()->RegisterMessageCallback( "getExtensions", @@ -542,31 +549,123 @@ return update; } -base::string16 ManagementUIHandler::GetEnterpriseManagementStatusString() { - auto* profile = Profile::FromWebUI(web_ui()); - const bool account_managed = IsProfileManaged(profile); - const std::string account_domain = GetAccountDomain(profile); - bool profile_associated_with_gaia_account = true; #if defined(OS_CHROMEOS) - profile_associated_with_gaia_account = - chromeos::IsProfileAssociatedWithGaiaAccount(profile); +void AddStatusDeviceManagedInfo(base::Value* status, + const std::string& device_domain) { + base::Value info(base::Value::Type::DICTIONARY); + info.SetKey(kOverview, base::Value(l10n_util::GetStringFUTF16( + IDS_MANAGEMENT_DEVICE_MANAGED_CLARIFICATION, + base::UTF8ToUTF16(device_domain)))); + info.SetKey(kSetup, base::Value(l10n_util::GetStringUTF16( + IDS_MANAGEMENT_DEVICE_MANAGED_SETUP))); + info.SetKey(kData, base::Value(l10n_util::GetStringUTF16( + IDS_MANAGEMENT_DEVICE_MANAGED_DATA))); + status->SetKey(kDeviceManagedInfo, std::move(info)); +} + +void AddStatusDeviceAndAccountManagedInfo( + base::Value* status, + const std::string& device_and_account_domain) { + base::Value info(base::Value::Type::DICTIONARY); + info.SetKey(kOverview, + base::Value(l10n_util::GetStringFUTF16( + IDS_MANAGEMENT_DEVICE_AND_ACCOUNT_MANAGED_CLARIFICATION, + base::UTF8ToUTF16(device_and_account_domain)))); + info.SetKey(kSetup, base::Value(l10n_util::GetStringUTF16( + IDS_MANAGEMENT_DEVICE_AND_ACCOUNT_MANAGED_SETUP))); + info.SetKey(kData, base::Value(l10n_util::GetStringUTF16( + IDS_MANAGEMENT_DEVICE_AND_ACCOUNT_MANAGED_DATA))); + status->SetKey(kDeviceManagedInfo, std::move(info)); +} #endif // defined(OS_CHROMEOS) - bool device_managed = false; - std::string device_domain; +void AddStatusAccountManagedInfo(base::Value* status, + const std::string& account_domain) { + base::Value info(base::Value::Type::DICTIONARY); + info.SetKey(kOverview, base::Value(l10n_util::GetStringFUTF16( + IDS_MANAGEMENT_ACCOUNT_MANAGED_CLARIFICATION, + base::UTF8ToUTF16(account_domain)))); + info.SetKey(kSetup, base::Value(l10n_util::GetStringUTF16( + IDS_MANAGEMENT_ACCOUNT_MANAGED_SETUP))); + info.SetKey(kData, base::Value(l10n_util::GetStringUTF16( + IDS_MANAGEMENT_ACCOUNT_MANAGED_DATA))); + status->SetKey(kAccountManagedInfo, std::move(info)); +} + #if defined(OS_CHROMEOS) +void AddStatusOverviewManagedDeviceAndAccount( + base::Value* status, + const std::string& device_domain, + const std::string& account_domain) { + status->SetKey(kOverview, + base::Value(l10n_util::GetStringFUTF16( + IDS_MANAGEMENT_DEVICE_MANAGED_BY_ACCOUNT_MANAGED_BY, + base::UTF8ToUTF16(device_domain), + base::UTF8ToUTF16(account_domain)))); + AddStatusDeviceManagedInfo(status, device_domain); + status->SetKey(kAccountManagedInfo, base::Value()); +} + +void AddStatusOverviewManagedDeviceAndAccount( + base::Value* status, + const std::string& device_and_account_domain) { + status->SetKey(kOverview, base::Value(l10n_util::GetStringFUTF16( + IDS_MANAGEMENT_DEVICE_AND_ACCOUNT_MANAGED_BY, + base::UTF8ToUTF16(device_and_account_domain)))); + AddStatusDeviceAndAccountManagedInfo(status, device_and_account_domain); + status->SetKey(kAccountManagedInfo, base::Value()); +} + +void AddStatusOverviewManagedDevice(base::Value* status, + const std::string& device_domain) { + status->SetKey(kOverview, base::Value(l10n_util::GetStringFUTF16( + IDS_MANAGEMENT_DEVICE_MANAGED_BY, + base::UTF8ToUTF16(device_domain)))); + AddStatusDeviceManagedInfo(status, device_domain); + status->SetKey(kAccountManagedInfo, base::Value()); +} + +#endif // defined(OS_CHROMEOS) + +void AddStatusOverviewManagedAccount(base::Value* status, + const std::string& account_domain) { +#if defined(OS_CHROMEOS) + status->SetKey(kOverview, base::Value(l10n_util::GetStringFUTF16( + IDS_MANAGEMENT_ACCOUNT_MANAGED_BY, + base::UTF8ToUTF16(account_domain)))); +#endif // defined(OS_CHROMEOS) + status->SetKey(kDeviceManagedInfo, base::Value()); + AddStatusAccountManagedInfo(status, account_domain); +} + +#if defined(OS_CHROMEOS) +void AddStatusOverviewNotManaged(base::Value* status) { + status->SetKey(kOverview, base::Value(l10n_util::GetStringUTF16( + IDS_MANAGEMENT_DEVICE_NOT_MANAGED))); + status->SetKey(kAccountManagedInfo, base::Value()); + status->SetKey(kDeviceManagedInfo, base::Value()); +} +#endif // defined(OS_CHROMEOS) + +void ManagementUIHandler::GetManagementStatus(base::Value* status) { + auto* profile = Profile::FromWebUI(web_ui()); + const std::string account_domain = GetAccountDomain(profile); +#if defined(OS_CHROMEOS) + const bool account_managed = IsProfileManaged(profile); + const bool profile_associated_with_gaia_account = + chromeos::IsProfileAssociatedWithGaiaAccount(profile); + + std::string device_domain; policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); - device_managed = connector->IsEnterpriseManaged(); + const bool device_managed = connector->IsEnterpriseManaged(); if (device_managed) device_domain = connector->GetEnterpriseDisplayDomain(); if (device_domain.empty() && connector->IsActiveDirectoryManaged()) device_domain = connector->GetRealm(); -#endif // defined(OS_CHROMEOS) bool primary_user_managed = false; std::string primary_user_account_domain; -#if defined(OS_CHROMEOS) auto* primary_user = user_manager::UserManager::Get()->GetPrimaryUser(); if (primary_user) { auto* primary_profile = @@ -576,47 +675,47 @@ primary_user_account_domain = GetAccountDomain(primary_profile); } } -#endif // defined(OS_CHROMEOS) if (device_managed) { DCHECK(!device_domain.empty()); if (account_managed) { if (device_domain == account_domain || !profile_associated_with_gaia_account) { - return l10n_util::GetStringFUTF16( - IDS_MANAGEMENT_DEVICE_AND_ACCOUNT_MANAGED_BY, - base::UTF8ToUTF16(device_domain)); + AddStatusOverviewManagedDeviceAndAccount(status, device_domain); + return; } DCHECK(!account_domain.empty()); - return l10n_util::GetStringFUTF16( - IDS_MANAGEMENT_DEVICE_MANAGED_BY_ACCOUNT_MANAGED_BY, - base::UTF8ToUTF16(device_domain), base::UTF8ToUTF16(account_domain)); + AddStatusOverviewManagedDeviceAndAccount(status, device_domain, + account_domain); + return; } - return l10n_util::GetStringFUTF16(IDS_MANAGEMENT_DEVICE_MANAGED_BY, - base::UTF8ToUTF16(device_domain)); - } - - if (account_managed) { - return l10n_util::GetStringFUTF16(IDS_MANAGEMENT_ACCOUNT_MANAGED_BY, - base::UTF8ToUTF16(account_domain)); + AddStatusOverviewManagedDevice(status, device_domain); + return; } if (primary_user_managed) { - return l10n_util::GetStringFUTF16( - IDS_MANAGEMENT_ACCOUNT_MANAGED_BY, - base::UTF8ToUTF16(primary_user_account_domain)); + AddStatusOverviewManagedAccount(status, primary_user_account_domain); + return; + } +#endif // defined(OS_CHROMEOS) + + if (managed_) { + AddStatusOverviewManagedAccount(status, account_domain); + return; } - return l10n_util::GetStringUTF16(IDS_MANAGEMENT_DEVICE_NOT_MANAGED); +#if defined(OS_CHROMEOS) + AddStatusOverviewNotManaged(status); +#endif // defined(OS_CHROMEOS) } -void ManagementUIHandler::HandleGetDeviceManagementStatus( +void ManagementUIHandler::HandleGetManagementStatus( const base::ListValue* args) { base::RecordAction(base::UserMetricsAction("ManagementPageViewed")); AllowJavascript(); - base::Value managed_string(GetEnterpriseManagementStatusString()); - ResolveJavascriptCallback(args->GetList()[0] /* callback_id */, - managed_string); + base::Value status(base::Value::Type::DICTIONARY); + GetManagementStatus(&status); + ResolveJavascriptCallback(args->GetList()[0] /* callback_id */, status); } void ManagementUIHandler::HandleGetExtensions(const base::ListValue* args) {
diff --git a/chrome/browser/ui/webui/management_ui_handler.h b/chrome/browser/ui/webui/management_ui_handler.h index 83f23025..a32f8952 100644 --- a/chrome/browser/ui/webui/management_ui_handler.h +++ b/chrome/browser/ui/webui/management_ui_handler.h
@@ -119,9 +119,9 @@ #endif // BUILDFLAG(ENABLE_EXTENSIONS) private: - base::string16 GetEnterpriseManagementStatusString(); + void GetManagementStatus(base::Value* status); - void HandleGetDeviceManagementStatus(const base::ListValue* args); + void HandleGetManagementStatus(const base::ListValue* args); #if defined(OS_CHROMEOS) void HandleGetDeviceReportingInfo(const base::ListValue* args);
diff --git a/chrome/browser/ui/webui/management_ui_handler_unittest.cc b/chrome/browser/ui/webui/management_ui_handler_unittest.cc index 212d62f..e501b03 100644 --- a/chrome/browser/ui/webui/management_ui_handler_unittest.cc +++ b/chrome/browser/ui/webui/management_ui_handler_unittest.cc
@@ -29,9 +29,9 @@ using testing::ReturnRef; struct ContextualManagementSourceUpdate { - base::string16* extensions_installed; + base::string16* extension_reporting_title; base::string16* browser_management_notice; - base::string16* title; + base::string16* subtitle; }; class TestManagementUIHandler : public ManagementUIHandler { @@ -88,9 +88,10 @@ void ExtractContextualSourceUpdate( base::DictionaryValue* data, const ContextualManagementSourceUpdate& extracted) { - data->GetString("extensionsInstalled", extracted.extensions_installed); + data->GetString("extensionReportingTitle", + extracted.extension_reporting_title); data->GetString("managementNotice", extracted.browser_management_notice); - data->GetString("title", extracted.title); + data->GetString("subtitle", extracted.subtitle); } protected: @@ -105,48 +106,49 @@ ManagementContextualSourceUpdateUnmanagedNoDomain) { auto profile = TestingProfile::Builder().Build(); - base::string16 extensions_installed; + base::string16 extension_reporting_title; base::string16 browser_management_notice; - base::string16 title; + base::string16 subtitle; ContextualManagementSourceUpdate extracted{ - &extensions_installed, &browser_management_notice, &title}; + &extension_reporting_title, &browser_management_notice, &subtitle}; handler_.SetManagedForTesting(false); auto data = handler_.GetDataSourceUpdate(profile.get()); ExtractContextualSourceUpdate(data.get(), extracted); EXPECT_EQ(data->DictSize(), 3u); - EXPECT_EQ(extensions_installed, + EXPECT_EQ(extension_reporting_title, l10n_util::GetStringUTF16(IDS_MANAGEMENT_EXTENSIONS_INSTALLED)); EXPECT_EQ(browser_management_notice, l10n_util::GetStringFUTF16( IDS_MANAGEMENT_NOT_MANAGED_NOTICE, base::UTF8ToUTF16(chrome::kManagedUiLearnMoreUrl))); - EXPECT_EQ(title, l10n_util::GetStringUTF16(IDS_MANAGEMENT_NOT_MANAGED_TITLE)); + EXPECT_EQ(subtitle, + l10n_util::GetStringUTF16(IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE)); } TEST_F(ManagementUIHandlerTests, ManagementContextualSourceUpdateManageNoDomain) { auto profile = TestingProfile::Builder().Build(); - base::string16 extensions_installed; + base::string16 extension_reporting_title; base::string16 browser_management_notice; - base::string16 title; + base::string16 subtitle; ContextualManagementSourceUpdate extracted{ - &extensions_installed, &browser_management_notice, &title}; + &extension_reporting_title, &browser_management_notice, &subtitle}; handler_.SetManagedForTesting(true); auto data = handler_.GetDataSourceUpdate(profile.get()); ExtractContextualSourceUpdate(data.get(), extracted); EXPECT_EQ(data->DictSize(), 3u); - EXPECT_EQ(extensions_installed, + EXPECT_EQ(extension_reporting_title, l10n_util::GetStringUTF16(IDS_MANAGEMENT_EXTENSIONS_INSTALLED)); EXPECT_EQ(browser_management_notice, l10n_util::GetStringFUTF16( IDS_MANAGEMENT_BROWSER_NOTICE, base::UTF8ToUTF16(chrome::kManagedUiLearnMoreUrl))); - EXPECT_EQ(title, l10n_util::GetStringUTF16(IDS_MANAGEMENT_TITLE)); + EXPECT_EQ(subtitle, l10n_util::GetStringUTF16(IDS_MANAGEMENT_SUBTITLE)); } TEST_F(ManagementUIHandlerTests, @@ -157,9 +159,9 @@ base::string16 extensions_installed; base::string16 browser_management_notice; - base::string16 title; + base::string16 subtitle; ContextualManagementSourceUpdate extracted{ - &extensions_installed, &browser_management_notice, &title}; + &extensions_installed, &browser_management_notice, &subtitle}; handler_.SetManagedForTesting(true); auto data = handler_.GetDataSourceUpdate(profile.get()); @@ -172,7 +174,7 @@ l10n_util::GetStringFUTF16( IDS_MANAGEMENT_BROWSER_NOTICE, base::UTF8ToUTF16(chrome::kManagedUiLearnMoreUrl))); - EXPECT_EQ(title, l10n_util::GetStringUTF16(IDS_MANAGEMENT_TITLE)); + EXPECT_EQ(subtitle, l10n_util::GetStringUTF16(IDS_MANAGEMENT_SUBTITLE)); } TEST_F(ManagementUIHandlerTests, @@ -181,11 +183,11 @@ builder.SetProfileName("managed@manager.com"); auto profile = builder.Build(); - base::string16 extensions_installed; + base::string16 extension_reporting_title; base::string16 browser_management_notice; - base::string16 title; + base::string16 subtitle; ContextualManagementSourceUpdate extracted{ - &extensions_installed, &browser_management_notice, &title}; + &extension_reporting_title, &browser_management_notice, &subtitle}; handler_.SetManagedForTesting(false); @@ -193,14 +195,15 @@ ExtractContextualSourceUpdate(data.get(), extracted); EXPECT_EQ(data->DictSize(), 3u); - EXPECT_EQ(extensions_installed, + EXPECT_EQ(extension_reporting_title, l10n_util::GetStringFUTF16(IDS_MANAGEMENT_EXTENSIONS_INSTALLED_BY, base::UTF8ToUTF16("manager.com"))); EXPECT_EQ(browser_management_notice, l10n_util::GetStringFUTF16( IDS_MANAGEMENT_NOT_MANAGED_NOTICE, base::UTF8ToUTF16(chrome::kManagedUiLearnMoreUrl))); - EXPECT_EQ(title, l10n_util::GetStringUTF16(IDS_MANAGEMENT_NOT_MANAGED_TITLE)); + EXPECT_EQ(subtitle, + l10n_util::GetStringUTF16(IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE)); } TEST_F(ManagementUIHandlerTests, @@ -227,7 +230,8 @@ l10n_util::GetStringFUTF16( IDS_MANAGEMENT_NOT_MANAGED_NOTICE, base::UTF8ToUTF16(chrome::kManagedUiLearnMoreUrl))); - EXPECT_EQ(title, l10n_util::GetStringUTF16(IDS_MANAGEMENT_NOT_MANAGED_TITLE)); + EXPECT_EQ(title, + l10n_util::GetStringUTF16(IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE)); } TEST_F(ManagementUIHandlerTests, @@ -236,18 +240,18 @@ builder.SetProfileName("managed@manager.com"); auto profile = builder.Build(); - base::string16 extensions_installed; + base::string16 extension_reporting_title; base::string16 browser_management_notice; - base::string16 title; + base::string16 subtitle; ContextualManagementSourceUpdate extracted{ - &extensions_installed, &browser_management_notice, &title}; + &extension_reporting_title, &browser_management_notice, &subtitle}; handler_.SetManagedForTesting(true); auto data = handler_.GetDataSourceUpdate(profile.get()); ExtractContextualSourceUpdate(data.get(), extracted); EXPECT_EQ(data->DictSize(), 3u); - EXPECT_EQ(extensions_installed, + EXPECT_EQ(extension_reporting_title, l10n_util::GetStringFUTF16(IDS_MANAGEMENT_EXTENSIONS_INSTALLED_BY, base::UTF8ToUTF16("manager.com"))); EXPECT_EQ( @@ -255,8 +259,8 @@ l10n_util::GetStringFUTF16( IDS_MANAGEMENT_MANAGEMENT_BY_NOTICE, base::UTF8ToUTF16("manager.com"), base::UTF8ToUTF16(chrome::kManagedUiLearnMoreUrl))); - EXPECT_EQ(title, - l10n_util::GetStringFUTF16(IDS_MANAGEMENT_TITLE_BY, + EXPECT_EQ(subtitle, + l10n_util::GetStringFUTF16(IDS_MANAGEMENT_SUBTITLE_MANAGED_BY, base::UTF8ToUTF16("manager.com"))); }
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc index 3e2fdac..f5f0fe7 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc
@@ -12,6 +12,7 @@ #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/webui/signin/inline_login_handler.h" #include "chromeos/components/account_manager/account_manager.h" #include "chromeos/components/account_manager/account_manager_factory.h" @@ -102,6 +103,16 @@ InlineLoginHandlerChromeOS::~InlineLoginHandlerChromeOS() = default; +void InlineLoginHandlerChromeOS::RegisterMessages() { + InlineLoginHandler::RegisterMessages(); + + web_ui()->RegisterMessageCallback( + "showIncognito", + base::BindRepeating( + &InlineLoginHandlerChromeOS::ShowIncognitoAndCloseDialog, + base::Unretained(this))); +} + void InlineLoginHandlerChromeOS::SetExtraInitParams( base::DictionaryValue& params) { const GaiaUrls* const gaia_urls = GaiaUrls::GetInstance(); @@ -144,4 +155,10 @@ auth_code); } +void InlineLoginHandlerChromeOS::ShowIncognitoAndCloseDialog( + const base::ListValue* args) { + chrome::NewIncognitoWindow(Profile::FromWebUI(web_ui())); + close_dialog_closure_.Run(); +} + } // namespace chromeos
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.h b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.h index f876ae8..415bf57 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.h +++ b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.h
@@ -21,6 +21,7 @@ ~InlineLoginHandlerChromeOS() override; // InlineLoginHandler overrides. + void RegisterMessages() override; void SetExtraInitParams(base::DictionaryValue& params) override; void CompleteLogin(const std::string& email, const std::string& password, @@ -32,6 +33,8 @@ bool choose_what_to_sync) override; private: + void ShowIncognitoAndCloseDialog(const base::ListValue* args); + base::RepeatingClosure close_dialog_closure_; DISALLOW_COPY_AND_ASSIGN(InlineLoginHandlerChromeOS); };
diff --git a/chrome/browser/vr/elements/omnibox_text_field.cc b/chrome/browser/vr/elements/omnibox_text_field.cc index c55360e6..d8502c8 100644 --- a/chrome/browser/vr/elements/omnibox_text_field.cc +++ b/chrome/browser/vr/elements/omnibox_text_field.cc
@@ -28,14 +28,18 @@ return; TextInputInfo current = edited_text().current; - base::string16 current_base = current.text.substr(0, current.selection_start); + base::string16 current_base = current.text.substr(0, current.selection_end); if (current_base != autocompletion.input) return; TextInputInfo info; info.text = current_base + autocompletion.suffix; - info.selection_start = current_base.size(); - info.selection_end = info.text.size(); + + // Select the autocompletion suffix, with the selection end at the previous + // cursor position (inverted selection) so that + // what the user typed remains in view. + info.selection_end = current_base.size(); + info.selection_start = info.text.size(); EditedText new_state(edited_text()); new_state.Update(info);
diff --git a/chrome/browser/vr/elements/omnibox_text_field_unittest.cc b/chrome/browser/vr/elements/omnibox_text_field_unittest.cc index 0254da5..be03466 100644 --- a/chrome/browser/vr/elements/omnibox_text_field_unittest.cc +++ b/chrome/browser/vr/elements/omnibox_text_field_unittest.cc
@@ -125,7 +125,7 @@ { // Type at the beginning, ensuring that in-line match is disabled. SCOPED_TRACE(__LINE__); - ExpectKeyboardUpdate(".wi", 1, 1); + ExpectKeyboardUpdate(".wi", 1); ExpectAutocompleteRequest(".wi", 1, kPreventInline); SetInput(".wi", 1, 1, "wi", 0, 0); VerifyMocks(); @@ -168,14 +168,14 @@ { // Supply a match, and ensure no new autocomplete request is sent. SCOPED_TRACE(__LINE__); - ExpectKeyboardUpdate("wiki", 1, 4); + ExpectKeyboardUpdate("wiki", 4, 1); SetAutocompletion("w", "iki"); VerifyMocks(); } { // Supply a new match that replaces the previous. SCOPED_TRACE(__LINE__); - ExpectKeyboardUpdate("wikipedia", 1, 9); + ExpectKeyboardUpdate("wikipedia", 9, 1); SetAutocompletion("w", "ikipedia"); VerifyMocks(); } @@ -198,7 +198,7 @@ { // Restore a match. SCOPED_TRACE(__LINE__); - ExpectKeyboardUpdate("wikipedia", 1, 9); + ExpectKeyboardUpdate("wikipedia", 9, 1); SetAutocompletion("w", "ikipedia"); VerifyMocks(); } @@ -206,7 +206,7 @@ // Move the cursor into the match, ensuring that the match is incorporated // into the next autocomplete request, but that in-line is disabled. SCOPED_TRACE(__LINE__); - ExpectKeyboardUpdate("wikipedia", 4, 4); + ExpectKeyboardUpdate("wikipedia", 4); ExpectAutocompleteRequest("wikipedia", 4, kPreventInline); SetInput("wikipedia", 4, 4, "wikipedia", 1, 9); VerifyMocks(); @@ -215,7 +215,7 @@ // Type into the middle of what used to be the match, ensuring that in-line // stays disabled. SCOPED_TRACE(__LINE__); - ExpectKeyboardUpdate("wikippedia", 5, 5); + ExpectKeyboardUpdate("wikippedia", 5); ExpectAutocompleteRequest("wikippedia", 5, kPreventInline); SetInput("wikippedia", 5, 5, "wikipedia", 4, 4); VerifyMocks();
diff --git a/chrome/browser/vr/elements/text_input.cc b/chrome/browser/vr/elements/text_input.cc index 41ae233..a4d2d63 100644 --- a/chrome/browser/vr/elements/text_input.cc +++ b/chrome/browser/vr/elements/text_input.cc
@@ -98,14 +98,6 @@ void TextInput::OnButtonUp(const gfx::PointF& position, base::TimeTicks timestamp) { - if (edited_text_.current.selection_start > - edited_text_.current.selection_end) { - TextInputInfo new_info(edited_text_.current); - std::swap(new_info.selection_start, new_info.selection_end); - EditedText new_edited_text(edited_text_); - new_edited_text.Update(new_info); - UpdateInput(new_edited_text); - } ResetCursorBlinkCycle(); RequestFocus(); }
diff --git a/chrome/common/extensions/api/webstore.json b/chrome/common/extensions/api/webstore.json deleted file mode 100644 index 1194ab6..0000000 --- a/chrome/common/extensions/api/webstore.json +++ /dev/null
@@ -1,167 +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. - -[ - { - "namespace": "webstore", - "description": "Use the <code>chrome.webstore</code> API to initiate app and extension installations \"inline\" from your site.", - "types": [ - { - "id": "InstallStage", - "type": "string", - "enum": ["installing", "downloading"], - "description": "Enum used to indicate the stage of the installation process. 'downloading' indicates that the necessary files are being downloaded, and 'installing' indicates that the files are downloaded and are being actively installed.", - "deprecated": "Inline installation is deprecated." - }, - { - "id": "ErrorCode", - "type": "string", - "description": "Enum of the possible install results, including error codes sent back in the event that an inline installation has failed.", - "enum": [ - // Keep this list of enums in sync with - // chrome/common/extensions/webstore_install_result.h and - // chrome/common/extensions/api/webstore/webstore_api_constants.cc! - { - "description": "An uncommon, unrecognized, or unexpected error. In some cases, the readable error string can provide more information.", - "name": "otherError" - }, - { - "description": "The operation was aborted as the requestor is no longer alive.", - "name": "aborted" - }, - { - "description": "An installation of the same extension is in progress.", - "name": "installInProgress" - }, - { - "description": "The installation is not permitted.", - "name": "notPermitted" - }, - { - "description": "Invalid Chrome Web Store item ID.", - "name": "invalidId" - }, - { - "description": "Failed to retrieve extension metadata from the Web Store.", - "name": "webstoreRequestError" - }, - { - "description": "The extension metadata retrieved from the Web Store was invalid.", - "name": "invalidWebstoreResponse" - }, - { - "description": "An error occurred while parsing the extension manifest retrieved from the Web Store.", - "name": "invalidManifest" - }, - { - "description": "Failed to retrieve the extension's icon from the Web Store, or the icon was invalid.", - "name": "iconError" - }, - { - "description": "The user canceled the operation.", - "name": "userCanceled" - }, - { - "description": "The extension is blacklisted.", - "name": "blacklisted" - }, - { - "description": "Unsatisfied dependencies, such as shared modules.", - "name": "missingDependencies" - }, - { - "description": "Unsatisfied requirements, such as webgl.", - "name": "requirementViolations" - }, - { - "description": "The extension is blocked by management policies.", - "name": "blockedByPolicy" - }, - { - "description": "The launch feature is not available.", - "name": "launchFeatureDisabled" - }, - { - "description": "The launch feature is not supported for the extension type.", - "name": "launchUnsupportedExtensionType" - }, - { - "description": "A launch of the same extension is in progress.", - "name": "launchInProgress" - } - ], - "deprecated": "Inline installation is deprecated." - } - ], // types - "events": [ - { - "name": "onInstallStageChanged", - "description": "Fired when an inline installation enters a new InstallStage. In order to receive notifications about this event, listeners must be registered before the inline installation begins.", - "type": "function", - "parameters": [ - { - "name": "stage", - "$ref": "InstallStage", - "description": "The InstallStage that just began." - } - ], - "deprecated": "Inline installation is deprecated." - }, // onInstallStageChanged - { - "name": "onDownloadProgress", - "description": "Fired periodically with the download progress of an inline install. In order to receive notifications about this event, listeners must be registered before the inline installation begins.", - "type": "function", - "parameters": [ - { - "name": "percentDownloaded", - "type": "number", - "description": "The progress of the download, between 0 and 1. 0 indicates no progress; 1.0 indicates complete." - } - ], - "deprecated": "Inline installation is deprecated." - } // onDownloadProgress - ], // events - "functions": [ - { - "name": "install", - "allowAmbiguousOptionalArguments": true, - "parameters": [ - { - "name": "url", - "type": "string", - "optional": true, - "description": "If you have more than one <code><link></code> tag on your page with the <code>chrome-webstore-item</code> relation, you can choose which item you'd like to install by passing in its URL here. If it is omitted, then the first (or only) link will be used. An exception will be thrown if the passed in URL does not exist on the page." - }, - { - "name": "successCallback", - "type": "function", - "optional": true, - "parameters": [], - "description": "This function is invoked when inline installation successfully completes (after the dialog is shown and the user agrees to add the item to Chrome). You may wish to use this to hide the user interface element that prompted the user to install the app or extension." - }, - { - "name": "failureCallback", - "type": "function", - "optional": true, - "parameters": [ - { - "name": "error", - "type": "string", - "description": "The failure detail. You may wish to inspect or log this for debugging purposes, but you should not rely on specific strings being passed back." - }, - { - "name": "errorCode", - "$ref": "ErrorCode", - "optional": "true", - "description": "The error code from the stable set of possible errors." - } - ], - "description": "This function is invoked when inline installation does not successfully complete. Possible reasons for this include the user canceling the dialog, the linked item not being found in the store, or the install being initiated from a non-verified site." - } - ], - "deprecated": "Inline installation is deprecated." - } // install - ] // functions - } // webstore -]
diff --git a/chrome/renderer/chrome_render_frame_observer.cc b/chrome/renderer/chrome_render_frame_observer.cc index 73fcbc4..bc5fa16 100644 --- a/chrome/renderer/chrome_render_frame_observer.cc +++ b/chrome/renderer/chrome_render_frame_observer.cc
@@ -289,8 +289,7 @@ blink::mojom::ConsoleMessageLevel::kWarning, "<meta name=\"apple-mobile-web-app-capable\" content=\"yes\"> is " "deprecated. Please include <meta name=\"mobile-web-app-capable\" " - "content=\"yes\"> - " - "http://developers.google.com/chrome/mobile/docs/installtohomescreen"); + "content=\"yes\">"); frame->AddMessageToConsole(message); }
diff --git a/chrome/services/diagnosticsd/OWNERS b/chrome/services/diagnosticsd/OWNERS index 8c3eff5..f301e83 100644 --- a/chrome/services/diagnosticsd/OWNERS +++ b/chrome/services/diagnosticsd/OWNERS
@@ -1,2 +1,4 @@ emaxx@chromium.org pmarko@chromium.org + +# COMPONENT: Enterprise
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 3cc491da..799ce791 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1821,7 +1821,7 @@ "../browser/chromeos/login/active_directory_test_helper.cc", "../browser/chromeos/login/active_directory_test_helper.h", "../browser/chromeos/login/auto_launched_kiosk_browsertest.cc", - "../browser/chromeos/login/configuration_based_enrollment_browsertest.cc", + "../browser/chromeos/login/configuration_based_oobe_browsertest.cc", "../browser/chromeos/login/crash_restore_browsertest.cc", "../browser/chromeos/login/demo_mode/demo_app_launcher_browsertest.cc", "../browser/chromeos/login/demo_mode/demo_session_browsertest.cc", @@ -5470,6 +5470,8 @@ "../browser/sync/test/integration/typed_urls_helper.h", "../browser/sync/test/integration/updated_progress_marker_checker.cc", "../browser/sync/test/integration/updated_progress_marker_checker.h", + "../browser/sync/test/integration/user_events_helper.cc", + "../browser/sync/test/integration/user_events_helper.h", "../browser/sync/test/integration/wallet_helper.cc", "../browser/sync/test/integration/wallet_helper.h", ] @@ -5573,6 +5575,7 @@ "../browser/sync/test/integration/two_client_sessions_sync_test.cc", "../browser/sync/test/integration/two_client_themes_sync_test.cc", "../browser/sync/test/integration/two_client_typed_urls_sync_test.cc", + "../browser/sync/test/integration/two_client_user_events_sync_test.cc", "../browser/sync/test/integration/two_client_uss_sync_test.cc", "../browser/sync/test/integration/two_client_wallet_sync_test.cc", ]
diff --git a/chrome/test/chromedriver/session.h b/chrome/test/chromedriver/session.h index bfd9c53d..9ee248e 100644 --- a/chrome/test/chromedriver/session.h +++ b/chrome/test/chromedriver/session.h
@@ -28,7 +28,7 @@ // Controls whether ChromeDriver operates in W3C mode (when true) or legacy // mode (when false) by default. -static const bool kW3CDefault = false; +static const bool kW3CDefault = true; namespace base { class DictionaryValue;
diff --git a/chrome/test/chromedriver/session_commands.cc b/chrome/test/chromedriver/session_commands.cc index 055ad1a..f92c782 100644 --- a/chrome/test/chromedriver/session_commands.cc +++ b/chrome/test/chromedriver/session_commands.cc
@@ -239,6 +239,10 @@ } } + if (!params.GetDictionary("capabilities", &dict)) { + return false; + } + return kW3CDefault; }
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index f7b56da..5c295c4d 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -2959,8 +2959,8 @@ def testDefaultComplianceMode(self): driver = self.CreateDriver(send_w3c_capability=None, - send_w3c_request=False) - self.assertFalse(driver.w3c_compliant) + send_w3c_request=True) + self.assertTrue(driver.w3c_compliant) def testW3cCompliantResponses(self): # It's an error to send Legacy format request
diff --git a/chrome/test/data/webui/settings/cups_printer_page_tests.js b/chrome/test/data/webui/settings/cups_printer_page_tests.js index 02fabdd..f937df8 100644 --- a/chrome/test/data/webui/settings/cups_printer_page_tests.js +++ b/chrome/test/data/webui/settings/cups_printer_page_tests.js
@@ -487,8 +487,22 @@ // Sets ppdManufacturer and ppdModel since ppdManufacturer has an observer // that erases ppdModel when ppdManufacturer changes. function setPpdManufacturerAndPpdModel(manufacturer, model) { - dialog.activePrinter.ppdManufacturer = manufacturer; - dialog.activePrinter.ppdModel = model; + dialog.pendingPrinter_.ppdManufacturer = manufacturer; + dialog.pendingPrinter_.ppdModel = model; + } + + function clickSaveButton(dialog) { + assertTrue(!!dialog, 'Dialog is null for save'); + const saveButton = dialog.$$('.action-button'); + assertTrue(!!saveButton, 'Button is null'); + saveButton.click(); + } + + function clickCancelButton(dialog) { + assertTrue(!!dialog, 'Dialog is null for cancel'); + const cancelButton = dialog.$$('.cancel-button'); + assertTrue(!!cancelButton, 'Button is null'); + cancelButton.click(); } /** @type {?settings.TestCupsPrintersBrowserProxy} */ @@ -503,7 +517,7 @@ dialog = document.createElement('settings-cups-edit-printer-dialog'); - dialog.activePrinter = { + dialog.pendingPrinter_ = { ppdManufacturer: '', ppdModel: '', printerAddress: '', @@ -537,7 +551,7 @@ * Test that USB printers can be editted. */ test('USBPrinterCanBeEdited', function() { - dialog.activePrinter = { + dialog.pendingPrinter_ = { ppdManufacturer: '', ppdModel: '', printerAddress: '03f0/e414?serial=CD4234', @@ -559,8 +573,8 @@ printerStatus: '', }; - // Set activePrinter.ppdManufactuer and activePrinter.ppdModel to simulate - // a printer for which we have a PPD. + // Set pendingPrinter_.ppdManufactuer and pendingPrinter_.ppdModel to + // simulate a printer for which we have a PPD. setPpdManufacturerAndPpdModel('manufacturer', 'model'); // Edit the printer name. @@ -580,7 +594,7 @@ * invalid. */ test('EditPrinter', function() { - dialog.activePrinter = { + dialog.pendingPrinter_ = { ppdManufacturer: '', ppdModel: '', printerAddress: '192.168.1.13', @@ -628,8 +642,8 @@ assertTrue(saveButton.disabled); }); - test('TestEditNameAndSave', function() { - dialog.activePrinter = { + test('CloseEditDialogDoesNotModifyActivePrinter', function() { + const expectedPrinter = { ppdManufacturer: '', ppdModel: '', printerAddress: 'test123', @@ -650,6 +664,59 @@ printerQueue: 'moreinfohere', printerStatus: '', }; + + dialog.activePrinter = Object.assign({}, expectedPrinter); + + const nameField = dialog.$$('.printer-name-input'); + assertTrue(!!nameField); + nameField.value = 'edited printer name'; + + const addressField = dialog.$$('#printerAddress'); + assertTrue(!!addressField); + addressField.value = '9.9.9.9'; + + const queueField = dialog.$$('#printerQueue'); + assertTrue(!!queueField); + queueField.value = 'edited/print'; + + const protocolField = dialog.$$('.md-select'); + assertTrue(!!protocolField); + protocolField.value = 'http'; + + clickCancelButton(dialog); + + // Assert that activePrinter properties were not changed. + assertEquals(expectedPrinter.printerName, dialog.activePrinter.printerName); + assertEquals( + expectedPrinter.printerAddress, dialog.activePrinter.printerAddress); + assertEquals( + expectedPrinter.printerQueue, dialog.activePrinter.printerQueue); + assertEquals( + expectedPrinter.printerProtocol, dialog.activePrinter.printerProtocol); + }); + + test('TestEditNameAndSave', function() { + dialog.pendingPrinter_ = { + printerAutoconf: false, + printerDescription: '', + printerId: 'id_123', + printerManufacturer: '', + printerModel: '', + printerMakeAndModel: '', + printerName: 'Test Printer', + printerPPDPath: '', + printerPpdReference: { + userSuppliedPpdUrl: '', + effectiveMakeAndModel: '', + autoconf: false, + }, + ppdManufacturer: '', + ppdModel: '', + printerAddress: '03f0/e414?serial=CD4234', + printerProtocol: 'usb', + printerQueue: 'moreinfohere', + printerStatus: '', + }; setPpdManufacturerAndPpdModel('manufacture', 'model'); // Initializing activePrinter will set |needsReconfigured_| to true. Reset @@ -663,7 +730,6 @@ Polymer.dom.flush(); - // Editing only the printer name results in a updateCupsPrinter. const saveButton = dialog.$$('.action-button'); saveButton.click(); @@ -674,10 +740,10 @@ }); test('TestEditFieldsAndSave', function() { - dialog.activePrinter = { + dialog.pendingPrinter_ = { ppdManufacturer: '', ppdModel: '', - printerAddress: 'test123', + printerAddress: '03f0/e414?serial=CD4234', printerAutoconf: false, printerDescription: '', printerId: 'id_123', @@ -719,8 +785,7 @@ queueField.value = expectedQueue; assertTrue(dialog.needsReconfigured_); - const saveButton = dialog.$$('.action-button'); - saveButton.click(); + clickSaveButton(dialog); return cupsPrintersBrowserProxy.whenCalled('reconfigureCupsPrinter') .then(function() { @@ -730,7 +795,7 @@ }); test('TestChangingNameEnablesSaveButton', function() { - dialog.activePrinter_ = { + dialog.pendingPrinter_ = { ppdManufacturer: '', ppdModel: '', printerAddress: 'test:123', @@ -766,7 +831,7 @@ }); test('TestChangingAddressEnablesSaveButton', function() { - dialog.activePrinter = { + dialog.pendingPrinter_ = { ppdManufacturer: '', ppdModel: '', printerAddress: 'test:123', @@ -802,7 +867,7 @@ }); test('TestChangingQueueEnablesSaveButton', function() { - dialog.activePrinter = { + dialog.pendingPrinter_ = { ppdManufacturer: '', ppdModel: '', printerAddress: 'test:123', @@ -838,7 +903,7 @@ }); test('TestChangingProtocolEnablesSaveButton', function() { - dialog.activePrinter = { + dialog.pendingPrinter_ = { ppdManufacturer: '', ppdModel: '', printerAddress: 'test:123', @@ -874,7 +939,7 @@ }); test('TestChangingModelEnablesSaveButton', function() { - dialog.activePrinter = { + dialog.pendingPrinter_ = { ppdManufacturer: '', ppdModel: '', printerAddress: 'test:123',
diff --git a/chromecast/browser/extension_request_protocol_handler.cc b/chromecast/browser/extension_request_protocol_handler.cc index b673ed88..276760d 100644 --- a/chromecast/browser/extension_request_protocol_handler.cc +++ b/chromecast/browser/extension_request_protocol_handler.cc
@@ -123,8 +123,7 @@ bool CopyFragmentOnRedirect(const GURL& location) const override; bool IsSafeRedirect(const GURL& location) override; bool NeedsAuth() override; - void GetAuthChallengeInfo( - scoped_refptr<net::AuthChallengeInfo>* auth_info) override; + std::unique_ptr<net::AuthChallengeInfo> GetAuthChallengeInfo() override; void SetAuth(const net::AuthCredentials& credentials) override; void CancelAuth() override; void ContinueWithCertificate( @@ -137,7 +136,7 @@ const net::RedirectInfo& redirect_info, bool* defer_redirect) override; void OnAuthRequired(net::URLRequest* request, - net::AuthChallengeInfo* auth_info) override; + const net::AuthChallengeInfo& auth_info) override; void OnCertificateRequested( net::URLRequest* request, net::SSLCertRequestInfo* cert_request_info) override; @@ -281,8 +280,10 @@ return false; } -void CastExtensionURLRequestJob::GetAuthChallengeInfo( - scoped_refptr<net::AuthChallengeInfo>* auth_info) {} +std::unique_ptr<net::AuthChallengeInfo> +CastExtensionURLRequestJob::GetAuthChallengeInfo() { + return nullptr; +} void CastExtensionURLRequestJob::SetAuth( const net::AuthCredentials& credentials) { @@ -313,7 +314,7 @@ void CastExtensionURLRequestJob::OnAuthRequired( net::URLRequest* request, - net::AuthChallengeInfo* auth_info) { + const net::AuthChallengeInfo& auth_info) { net::URLRequest::Delegate::OnAuthRequired(request, auth_info); }
diff --git a/chromeos/audio/BUILD.gn b/chromeos/audio/BUILD.gn index fb3d38a..d57dfbd9 100644 --- a/chromeos/audio/BUILD.gn +++ b/chromeos/audio/BUILD.gn
@@ -11,7 +11,7 @@ deps = [ "//base", "//chromeos/constants", - "//chromeos/dbus", + "//chromeos/dbus/audio", "//components/prefs", "//media/base:video_facing", ] @@ -36,7 +36,7 @@ ":audio", "//base/test:test_support", "//chromeos/constants", - "//chromeos/dbus:test_support", + "//chromeos/dbus/audio", "//components/prefs:test_support", "//media/base:video_facing", "//testing/gtest",
diff --git a/chromeos/dbus/BUILD.gn b/chromeos/dbus/BUILD.gn index 28145cb..af9d255 100644 --- a/chromeos/dbus/BUILD.gn +++ b/chromeos/dbus/BUILD.gn
@@ -42,14 +42,6 @@ "arc_obb_mounter_client.h", "arc_oemcrypto_client.cc", "arc_oemcrypto_client.h", - "audio/audio_node.cc", - "audio/audio_node.h", - "audio/cras_audio_client.cc", - "audio/cras_audio_client.h", - "audio/fake_cras_audio_client.cc", - "audio/fake_cras_audio_client.h", - "audio/volume_state.cc", - "audio/volume_state.h", "cec_service_client.cc", "cec_service_client.h", "cicerone_client.cc", @@ -186,6 +178,7 @@ ":test_support", "//base", "//base/test:test_support", + "//chromeos/dbus/audio", "//chromeos/dbus/auth_policy", "//chromeos/dbus/biod:test_support", "//chromeos/dbus/cryptohome",
diff --git a/chromeos/dbus/audio/BUILD.gn b/chromeos/dbus/audio/BUILD.gn new file mode 100644 index 0000000..8ad7946 --- /dev/null +++ b/chromeos/dbus/audio/BUILD.gn
@@ -0,0 +1,28 @@ +# Copyright 2019 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. + +assert(is_chromeos, "Non-Chrome-OS builds cannot depend on //chromeos") + +component("audio") { + output_name = "chromeos_dbus_audio" + + defines = [ "IS_DBUS_AUDIO_IMPL" ] + + deps = [ + "//base", + "//chromeos/dbus:common", + "//dbus", + ] + + sources = [ + "audio_node.cc", + "audio_node.h", + "cras_audio_client.cc", + "cras_audio_client.h", + "fake_cras_audio_client.cc", + "fake_cras_audio_client.h", + "volume_state.cc", + "volume_state.h", + ] +}
diff --git a/chromeos/dbus/audio/audio_node.h b/chromeos/dbus/audio/audio_node.h index 30af6ae3..ac0244e 100644 --- a/chromeos/dbus/audio/audio_node.h +++ b/chromeos/dbus/audio/audio_node.h
@@ -15,7 +15,7 @@ namespace chromeos { // Structure to hold AudioNode data received from cras. -struct COMPONENT_EXPORT(CHROMEOS_DBUS) AudioNode { +struct COMPONENT_EXPORT(DBUS_AUDIO) AudioNode { bool is_input = false; uint64_t id = 0; bool has_v2_stable_device_id = false;
diff --git a/chromeos/dbus/audio/cras_audio_client.h b/chromeos/dbus/audio/cras_audio_client.h index 037dc7b..f2ae386 100644 --- a/chromeos/dbus/audio/cras_audio_client.h +++ b/chromeos/dbus/audio/cras_audio_client.h
@@ -25,7 +25,7 @@ namespace chromeos { // CrasAudioClient is used to communicate with the cras audio dbus interface. -class COMPONENT_EXPORT(CHROMEOS_DBUS) CrasAudioClient { +class COMPONENT_EXPORT(DBUS_AUDIO) CrasAudioClient { public: // Interface for observing changes from the cras audio changes. class Observer {
diff --git a/chromeos/dbus/audio/fake_cras_audio_client.h b/chromeos/dbus/audio/fake_cras_audio_client.h index 0915ae2..6210447f 100644 --- a/chromeos/dbus/audio/fake_cras_audio_client.h +++ b/chromeos/dbus/audio/fake_cras_audio_client.h
@@ -16,7 +16,7 @@ namespace chromeos { // The CrasAudioClient implementation used on Linux desktop. -class COMPONENT_EXPORT(CHROMEOS_DBUS) FakeCrasAudioClient +class COMPONENT_EXPORT(DBUS_AUDIO) FakeCrasAudioClient : public CrasAudioClient { public: FakeCrasAudioClient();
diff --git a/chromeos/dbus/audio/volume_state.h b/chromeos/dbus/audio/volume_state.h index 41dde91..7b7ca4e 100644 --- a/chromeos/dbus/audio/volume_state.h +++ b/chromeos/dbus/audio/volume_state.h
@@ -13,7 +13,7 @@ namespace chromeos { -struct COMPONENT_EXPORT(CHROMEOS_DBUS) VolumeState { +struct COMPONENT_EXPORT(DBUS_AUDIO) VolumeState { int32_t output_volume; bool output_system_mute; int32_t input_gain;
diff --git a/chromeos/dbus/permission_broker/fake_permission_broker_client.cc b/chromeos/dbus/permission_broker/fake_permission_broker_client.cc index c2bf031..9b86e06 100644 --- a/chromeos/dbus/permission_broker/fake_permission_broker_client.cc +++ b/chromeos/dbus/permission_broker/fake_permission_broker_client.cc
@@ -29,8 +29,8 @@ // permission broker by opening the path specified and returning the resulting // file descriptor. void OpenPath(const std::string& path, - const PermissionBrokerClient::OpenPathCallback& callback, - const PermissionBrokerClient::ErrorCallback& error_callback, + PermissionBrokerClient::OpenPathCallback callback, + PermissionBrokerClient::ErrorCallback error_callback, scoped_refptr<base::TaskRunner> task_runner) { base::ScopedFD fd(HANDLE_EINTR(open(path.c_str(), O_RDWR))); if (!fd.is_valid()) { @@ -38,14 +38,15 @@ task_runner->PostTask( FROM_HERE, base::BindOnce( - error_callback, kOpenFailedError, + std::move(error_callback), kOpenFailedError, base::StringPrintf( "Failed to open '%s': %s", path.c_str(), logging::SystemErrorCodeToString(error_code).c_str()))); return; } - task_runner->PostTask(FROM_HERE, base::BindOnce(callback, std::move(fd))); + task_runner->PostTask(FROM_HERE, + base::BindOnce(std::move(callback), std::move(fd))); } } // namespace @@ -66,19 +67,19 @@ return g_instance; } -void FakePermissionBrokerClient::CheckPathAccess( - const std::string& path, - const ResultCallback& callback) { - callback.Run(true); +void FakePermissionBrokerClient::CheckPathAccess(const std::string& path, + ResultCallback callback) { + std::move(callback).Run(true); } void FakePermissionBrokerClient::OpenPath(const std::string& path, - const OpenPathCallback& callback, - const ErrorCallback& error_callback) { + OpenPathCallback callback, + ErrorCallback error_callback) { base::PostTaskWithTraits( FROM_HERE, {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::BindOnce(&chromeos::OpenPath, path, callback, error_callback, + base::BindOnce(&chromeos::OpenPath, path, std::move(callback), + std::move(error_callback), base::ThreadTaskRunnerHandle::Get())); } @@ -86,8 +87,8 @@ uint16_t port, const std::string& interface, int lifeline_fd, - const ResultCallback& callback) { - callback.Run( + ResultCallback callback) { + std::move(callback).Run( RequestPortImpl(port, interface, tcp_deny_rule_set_, &tcp_hole_set_)); } @@ -95,23 +96,21 @@ uint16_t port, const std::string& interface, int lifeline_fd, - const ResultCallback& callback) { - callback.Run( + ResultCallback callback) { + std::move(callback).Run( RequestPortImpl(port, interface, udp_deny_rule_set_, &udp_hole_set_)); } -void FakePermissionBrokerClient::ReleaseTcpPort( - uint16_t port, - const std::string& interface, - const ResultCallback& callback) { - callback.Run(tcp_hole_set_.erase(std::make_pair(port, interface))); +void FakePermissionBrokerClient::ReleaseTcpPort(uint16_t port, + const std::string& interface, + ResultCallback callback) { + std::move(callback).Run(tcp_hole_set_.erase(std::make_pair(port, interface))); } -void FakePermissionBrokerClient::ReleaseUdpPort( - uint16_t port, - const std::string& interface, - const ResultCallback& callback) { - callback.Run(udp_hole_set_.erase(std::make_pair(port, interface))); +void FakePermissionBrokerClient::ReleaseUdpPort(uint16_t port, + const std::string& interface, + ResultCallback callback) { + std::move(callback).Run(udp_hole_set_.erase(std::make_pair(port, interface))); } void FakePermissionBrokerClient::AddTcpDenyRule(uint16_t port,
diff --git a/chromeos/dbus/permission_broker/fake_permission_broker_client.h b/chromeos/dbus/permission_broker/fake_permission_broker_client.h index eae60c7..cee8404 100644 --- a/chromeos/dbus/permission_broker/fake_permission_broker_client.h +++ b/chromeos/dbus/permission_broker/fake_permission_broker_client.h
@@ -27,24 +27,24 @@ static FakePermissionBrokerClient* Get(); void CheckPathAccess(const std::string& path, - const ResultCallback& callback) override; + ResultCallback callback) override; void OpenPath(const std::string& path, - const OpenPathCallback& callback, - const ErrorCallback& error_callback) override; + OpenPathCallback callback, + ErrorCallback error_callback) override; void RequestTcpPortAccess(uint16_t port, const std::string& interface, int lifeline_fd, - const ResultCallback& callback) override; + ResultCallback callback) override; void RequestUdpPortAccess(uint16_t port, const std::string& interface, int lifeline_fd, - const ResultCallback& callback) override; + ResultCallback callback) override; void ReleaseTcpPort(uint16_t port, const std::string& interface, - const ResultCallback& callback) override; + ResultCallback callback) override; void ReleaseUdpPort(uint16_t port, const std::string& interface, - const ResultCallback& callback) override; + ResultCallback callback) override; // Add a rule to have RequestTcpPortAccess fail. void AddTcpDenyRule(uint16_t port, const std::string& interface);
diff --git a/chromeos/dbus/permission_broker/permission_broker_client.cc b/chromeos/dbus/permission_broker/permission_broker_client.cc index bf2bdd4b..546f4911 100644 --- a/chromeos/dbus/permission_broker/permission_broker_client.cc +++ b/chromeos/dbus/permission_broker/permission_broker_client.cc
@@ -42,34 +42,35 @@ ~PermissionBrokerClientImpl() override = default; void CheckPathAccess(const std::string& path, - const ResultCallback& callback) override { + ResultCallback callback) override { dbus::MethodCall method_call(kPermissionBrokerInterface, kCheckPathAccess); dbus::MessageWriter writer(&method_call); writer.AppendString(path); proxy_->CallMethod( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::BindOnce(&PermissionBrokerClientImpl::OnResponse, - weak_ptr_factory_.GetWeakPtr(), callback)); + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void OpenPath(const std::string& path, - const OpenPathCallback& callback, - const ErrorCallback& error_callback) override { + OpenPathCallback callback, + ErrorCallback error_callback) override { dbus::MethodCall method_call(kPermissionBrokerInterface, kOpenPath); dbus::MessageWriter writer(&method_call); writer.AppendString(path); proxy_->CallMethodWithErrorCallback( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::BindOnce(&PermissionBrokerClientImpl::OnOpenPathResponse, - weak_ptr_factory_.GetWeakPtr(), callback), + weak_ptr_factory_.GetWeakPtr(), std::move(callback)), base::BindOnce(&PermissionBrokerClientImpl::OnError, - weak_ptr_factory_.GetWeakPtr(), error_callback)); + weak_ptr_factory_.GetWeakPtr(), + std::move(error_callback))); } void RequestTcpPortAccess(uint16_t port, const std::string& interface, int lifeline_fd, - const ResultCallback& callback) override { + ResultCallback callback) override { dbus::MethodCall method_call(kPermissionBrokerInterface, kRequestTcpPortAccess); dbus::MessageWriter writer(&method_call); @@ -79,13 +80,13 @@ proxy_->CallMethod( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::BindOnce(&PermissionBrokerClientImpl::OnResponse, - weak_ptr_factory_.GetWeakPtr(), callback)); + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void RequestUdpPortAccess(uint16_t port, const std::string& interface, int lifeline_fd, - const ResultCallback& callback) override { + ResultCallback callback) override { dbus::MethodCall method_call(kPermissionBrokerInterface, kRequestUdpPortAccess); dbus::MessageWriter writer(&method_call); @@ -95,12 +96,12 @@ proxy_->CallMethod( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::BindOnce(&PermissionBrokerClientImpl::OnResponse, - weak_ptr_factory_.GetWeakPtr(), callback)); + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void ReleaseTcpPort(uint16_t port, const std::string& interface, - const ResultCallback& callback) override { + ResultCallback callback) override { dbus::MethodCall method_call(kPermissionBrokerInterface, kReleaseTcpPort); dbus::MessageWriter writer(&method_call); writer.AppendUint16(port); @@ -108,12 +109,12 @@ proxy_->CallMethod( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::BindOnce(&PermissionBrokerClientImpl::OnResponse, - weak_ptr_factory_.GetWeakPtr(), callback)); + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void ReleaseUdpPort(uint16_t port, const std::string& interface, - const ResultCallback& callback) override { + ResultCallback callback) override { dbus::MethodCall method_call(kPermissionBrokerInterface, kReleaseUdpPort); dbus::MessageWriter writer(&method_call); writer.AppendUint16(port); @@ -121,7 +122,7 @@ proxy_->CallMethod( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::BindOnce(&PermissionBrokerClientImpl::OnResponse, - weak_ptr_factory_.GetWeakPtr(), callback)); + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void Init(dbus::Bus* bus) { @@ -133,10 +134,10 @@ private: // Handle a DBus response from the permission broker, invoking the callback // that the method was originally called with with the success response. - void OnResponse(const ResultCallback& callback, dbus::Response* response) { + void OnResponse(ResultCallback callback, dbus::Response* response) { if (!response) { LOG(WARNING) << "Access request method call failed."; - callback.Run(false); + std::move(callback).Run(false); return; } @@ -144,19 +145,18 @@ dbus::MessageReader reader(response); if (!reader.PopBool(&result)) LOG(WARNING) << "Could not parse response: " << response->ToString(); - callback.Run(result); + std::move(callback).Run(result); } - void OnOpenPathResponse(const OpenPathCallback& callback, - dbus::Response* response) { + void OnOpenPathResponse(OpenPathCallback callback, dbus::Response* response) { base::ScopedFD fd; dbus::MessageReader reader(response); if (!reader.PopFileDescriptor(&fd)) LOG(WARNING) << "Could not parse response: " << response->ToString(); - callback.Run(std::move(fd)); + std::move(callback).Run(std::move(fd)); } - void OnError(const ErrorCallback& callback, dbus::ErrorResponse* response) { + void OnError(ErrorCallback callback, dbus::ErrorResponse* response) { std::string error_name; std::string error_message; if (response) { @@ -166,7 +166,7 @@ } else { error_name = kNoResponseError; } - callback.Run(error_name, error_message); + std::move(callback).Run(error_name, error_message); } dbus::ObjectProxy* proxy_ = nullptr;
diff --git a/chromeos/dbus/permission_broker/permission_broker_client.h b/chromeos/dbus/permission_broker/permission_broker_client.h index c665b476..480d23e 100644 --- a/chromeos/dbus/permission_broker/permission_broker_client.h +++ b/chromeos/dbus/permission_broker/permission_broker_client.h
@@ -32,16 +32,15 @@ // The ResultCallback is used for both the RequestPathAccess and // RequestUsbAccess methods. Its boolean parameter represents the result of // the operation that it was submitted alongside. - typedef base::Callback<void(bool)> ResultCallback; + using ResultCallback = base::OnceCallback<void(bool)>; // An OpenPathCallback callback is run when an OpenPath request is completed. - typedef base::Callback<void(base::ScopedFD)> OpenPathCallback; + using OpenPathCallback = base::OnceCallback<void(base::ScopedFD)>; // An ErrorCallback callback is run when an error is returned by the // permission broker. - typedef base::Callback<void(const std::string& error_name, - const std::string& message)> - ErrorCallback; + using ErrorCallback = base::OnceCallback<void(const std::string& error_name, + const std::string& message)>; // Creates and initializes the global instance. |bus| must not be null. static void Initialize(dbus::Bus* bus); @@ -60,14 +59,14 @@ // the |interface_id| value passed to RequestPathAccess will be // UsbDevicePermissionsData::ANY_INTERFACE). virtual void CheckPathAccess(const std::string& path, - const ResultCallback& callback) = 0; + ResultCallback callback) = 0; // OpenPath requests that the permission broker open the device node // identified by |path| and return the resulting file descriptor. One of // |callback| or |error_callback| is called. virtual void OpenPath(const std::string& path, - const OpenPathCallback& callback, - const ErrorCallback& error_callback) = 0; + OpenPathCallback callback, + ErrorCallback error_callback) = 0; // Requests the |port| be opened on the firewall for incoming TCP/IP // connections received on |interface| (an empty string indicates all @@ -78,7 +77,7 @@ virtual void RequestTcpPortAccess(uint16_t port, const std::string& interface, int lifeline_fd, - const ResultCallback& callback) = 0; + ResultCallback callback) = 0; // Requests the |port| be opened on the firewall for incoming UDP packets // received on |interface| (an empty string indicates all interfaces). One end @@ -89,21 +88,21 @@ virtual void RequestUdpPortAccess(uint16_t port, const std::string& interface, int lifeline_fd, - const ResultCallback& callback) = 0; + ResultCallback callback) = 0; // Releases a request for an open firewall port for TCP/IP connections. The // |port| and |interface| parameters must be the same as a previous call to // RequestTcpPortAccess. virtual void ReleaseTcpPort(uint16_t port, const std::string& interface, - const ResultCallback& callback) = 0; + ResultCallback callback) = 0; // Releases a request for an open firewall port for UDP packets. The |port| // and |interface| parameters must be the same as a previous call to // RequestUdpPortAccess. virtual void ReleaseUdpPort(uint16_t port, const std::string& interface, - const ResultCallback& callback) = 0; + ResultCallback callback) = 0; protected: // Initialize/Shutdown should be used instead.
diff --git a/chromeos/network/firewall_hole.cc b/chromeos/network/firewall_hole.cc index c99ca1d..c86d140 100644 --- a/chromeos/network/firewall_hole.cc +++ b/chromeos/network/firewall_hole.cc
@@ -60,9 +60,9 @@ base::ScopedFD lifeline_local(lifeline[0]); base::ScopedFD lifeline_remote(lifeline[1]); - base::Callback<void(bool)> access_granted_closure = - base::Bind(&FirewallHole::PortAccessGranted, type, port, interface, - base::Passed(&lifeline_local), callback); + base::OnceCallback<void(bool)> access_granted_closure = + base::BindOnce(&FirewallHole::PortAccessGranted, type, port, interface, + std::move(lifeline_local), callback); PermissionBrokerClient* client = PermissionBrokerClient::Get(); DCHECK(client) << "Could not get permission broker client."; @@ -70,27 +70,29 @@ switch (type) { case PortType::TCP: client->RequestTcpPortAccess(port, interface, lifeline_remote.get(), - access_granted_closure); + std::move(access_granted_closure)); return; case PortType::UDP: client->RequestUdpPortAccess(port, interface, lifeline_remote.get(), - access_granted_closure); + std::move(access_granted_closure)); return; } } FirewallHole::~FirewallHole() { - base::Callback<void(bool)> port_released_closure = base::Bind( - &PortReleased, type_, port_, interface_, base::Passed(&lifeline_fd_)); + base::OnceCallback<void(bool)> port_released_closure = base::BindOnce( + &PortReleased, type_, port_, interface_, std::move(lifeline_fd_)); PermissionBrokerClient* client = PermissionBrokerClient::Get(); DCHECK(client) << "Could not get permission broker client."; switch (type_) { case PortType::TCP: - client->ReleaseTcpPort(port_, interface_, port_released_closure); + client->ReleaseTcpPort(port_, interface_, + std::move(port_released_closure)); return; case PortType::UDP: - client->ReleaseUdpPort(port_, interface_, port_released_closure); + client->ReleaseUdpPort(port_, interface_, + std::move(port_released_closure)); return; } }
diff --git a/components/arc/usb/usb_host_bridge.cc b/components/arc/usb/usb_host_bridge.cc index 60c963ad..1dcb4e3 100644 --- a/components/arc/usb/usb_host_bridge.cc +++ b/components/arc/usb/usb_host_bridge.cc
@@ -159,8 +159,9 @@ auto repeating_callback = base::AdaptCallbackForRepeating(std::move(callback)); chromeos::PermissionBrokerClient::Get()->OpenPath( - device->device_path(), base::Bind(&OnDeviceOpened, repeating_callback), - base::Bind(&OnDeviceOpenError, repeating_callback)); + device->device_path(), + base::BindOnce(&OnDeviceOpened, repeating_callback), + base::BindOnce(&OnDeviceOpenError, repeating_callback)); } void ArcUsbHostBridge::OpenDeviceDeprecated(
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index 267e145c..83d04a97 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -830,9 +830,21 @@ bool show_image_placeholder = 10; } - // Whether to show the original URL where image is extracted from. Only useful - // when 'image_url' is set. - optional bool allow_image_clickthrough = 12; + // Specifies what happens when user tap on the image in the details section. + message ImageClickthroughData { + // Whether to show the original URL where image is extracted from. Only + // useful when 'image_url' is set. + optional bool allow_clickthrough = 1; + + // When image clickthrough is allowed, below texts are used to customize the + // modal dialog shown to user *if* they are set, otherwise default texts + // will be used. + optional string description = 2; + optional string positive_text = 3; + optional string negative_text = 4; + } + + optional ImageClickthroughData image_clickthrough_data = 12; // Optional label to provide additional price information. optional string total_price_label = 9;
diff --git a/components/browser_sync/profile_sync_components_factory_impl.cc b/components/browser_sync/profile_sync_components_factory_impl.cc index 5de561a..b30f371d 100644 --- a/components/browser_sync/profile_sync_components_factory_impl.cc +++ b/components/browser_sync/profile_sync_components_factory_impl.cc
@@ -41,6 +41,7 @@ #include "components/sync/model/model_type_store_service.h" #include "components/sync/model_impl/forwarding_model_type_controller_delegate.h" #include "components/sync/model_impl/proxy_model_type_controller_delegate.h" +#include "components/sync/user_events/user_event_model_type_controller.h" #include "components/sync_bookmarks/bookmark_change_processor.h" #include "components/sync_bookmarks/bookmark_data_type_controller.h" #include "components/sync_bookmarks/bookmark_model_associator.h" @@ -397,8 +398,16 @@ } if (!disabled_types.Has(syncer::USER_EVENTS)) { - controllers.push_back(CreateModelTypeControllerForModelRunningOnUIThread( - syncer::USER_EVENTS)); + // TODO(crbug.com/867801): Switch to forwarding delegate. + controllers.push_back( + std::make_unique<syncer::UserEventModelTypeController>( + sync_service, + std::make_unique<syncer::ProxyModelTypeControllerDelegate>( + ui_thread_, + base::BindRepeating(&browser_sync::BrowserSyncClient:: + GetControllerDelegateForModelType, + base::Unretained(sync_client_), + syncer::USER_EVENTS)))); } if (!disabled_types.Has(syncer::SEND_TAB_TO_SELF) &&
diff --git a/components/cronet/tools/api_static_checks.py b/components/cronet/tools/api_static_checks.py index a52f927..84ea8a90 100755 --- a/components/cronet/tools/api_static_checks.py +++ b/components/cronet/tools/api_static_checks.py
@@ -12,13 +12,13 @@ import sys import tempfile -REPOSITORY_ROOT = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..', '..', '..')) +REPOSITORY_ROOT = os.path.abspath( + os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir)) -sys.path.append(os.path.join(REPOSITORY_ROOT, 'build/android/gyp/util')) -import build_utils +sys.path.insert(0, os.path.join(REPOSITORY_ROOT, 'build/android/gyp')) +from util import build_utils # pylint: disable=import-error -sys.path.append(os.path.join(REPOSITORY_ROOT, 'components')) +sys.path.insert(0, os.path.join(REPOSITORY_ROOT, 'components')) from cronet.tools import update_api
diff --git a/components/cronet/tools/check_no_neon.py b/components/cronet/tools/check_no_neon.py index 344ba691..cd13987 100755 --- a/components/cronet/tools/check_no_neon.py +++ b/components/cronet/tools/check_no_neon.py
@@ -9,11 +9,11 @@ import os import sys -REPOSITORY_ROOT = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..', '..', '..')) +REPOSITORY_ROOT = os.path.abspath( + os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir)) -sys.path.append(os.path.join(REPOSITORY_ROOT, 'build/android/gyp/util')) -import build_utils +sys.path.insert(0, os.path.join(REPOSITORY_ROOT, 'build/android/gyp')) +from util import build_utils # pylint: disable=import-error def main(args):
diff --git a/components/cronet/tools/generate_javadoc.py b/components/cronet/tools/generate_javadoc.py index ba6133a..406500ac 100755 --- a/components/cronet/tools/generate_javadoc.py +++ b/components/cronet/tools/generate_javadoc.py
@@ -10,14 +10,14 @@ import sys import tempfile -REPOSITORY_ROOT = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..', '..', '..')) +REPOSITORY_ROOT = os.path.abspath( + os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir)) DOCLAVA_DIR = os.path.join(REPOSITORY_ROOT, 'buildtools', 'android', 'doclava') SDK_DIR = os.path.join(REPOSITORY_ROOT, 'third_party', 'android_sdk', 'public') -sys.path.append(os.path.join(REPOSITORY_ROOT, 'build/android/gyp/util')) -sys.path.append(os.path.join(REPOSITORY_ROOT, 'net/tools/net_docs')) -import build_utils +sys.path.insert(0, os.path.join(REPOSITORY_ROOT, 'build/android/gyp')) +sys.path.insert(0, os.path.join(REPOSITORY_ROOT, 'net/tools/net_docs')) +from util import build_utils # pylint: disable=import-error import net_docs from markdown.postprocessors import Postprocessor from markdown.extensions import Extension
diff --git a/components/cronet/tools/jar_src.py b/components/cronet/tools/jar_src.py index 9bef15734..df60b424 100755 --- a/components/cronet/tools/jar_src.py +++ b/components/cronet/tools/jar_src.py
@@ -9,11 +9,11 @@ import sys import zipfile -REPOSITORY_ROOT = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..', '..', '..')) +REPOSITORY_ROOT = os.path.abspath( + os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir)) -sys.path.append(os.path.join(REPOSITORY_ROOT, 'build/android/gyp/util')) -import build_utils +sys.path.insert(0, os.path.join(REPOSITORY_ROOT, 'build/android/gyp')) +from util import build_utils # pylint: disable=import-error JAVA_PACKAGE_PREFIX = 'org/chromium/'
diff --git a/components/dom_distiller/content/browser/test/dom_distiller_js_browsertest.cc b/components/dom_distiller/content/browser/test/dom_distiller_js_browsertest.cc index 98f5c02..9baf04e7 100644 --- a/components/dom_distiller/content/browser/test/dom_distiller_js_browsertest.cc +++ b/components/dom_distiller/content/browser/test/dom_distiller_js_browsertest.cc
@@ -111,10 +111,10 @@ } }; -// Disabled on MSan and Android CFI bots. +// Disabled on MSan as well as Android and Linux CFI bots. // https://crbug.com/845180 #if defined(MEMORY_SANITIZER) || defined(OS_WIN) || \ - (defined(OS_ANDROID) && \ + ((defined(OS_ANDROID) || defined(OS_LINUX)) && \ (BUILDFLAG(CFI_CAST_CHECK) || BUILDFLAG(CFI_ICALL_CHECK) || \ BUILDFLAG(CFI_ENFORCEMENT_DIAGNOSTIC) || \ BUILDFLAG(CFI_ENFORCEMENT_TRAP)))
diff --git a/components/feed/content/feed_offline_host.cc b/components/feed/content/feed_offline_host.cc index 98b39cc..b49d4ab7 100644 --- a/components/feed/content/feed_offline_host.cc +++ b/components/feed/content/feed_offline_host.cc
@@ -12,6 +12,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "components/feed/core/feed_scheduler_host.h" #include "components/offline_pages/core/client_namespace_constants.h" +#include "components/offline_pages/core/page_criteria.h" #include "components/offline_pages/core/prefetch/prefetch_service.h" #include "url/gurl.h" @@ -35,7 +36,8 @@ using CacheIdCallback = base::RepeatingCallback<void(const std::string&, int64_t)>; - CallbackAggregator(ReportStatusCallback on_completion, + CallbackAggregator(OfflinePageModel* model, + ReportStatusCallback on_completion, CacheIdCallback on_each_result) : on_completion_(std::move(on_completion)), on_each_result_(std::move(on_each_result)), @@ -81,6 +83,8 @@ std::move(on_completion_).Run(std::move(urls_)); } + OfflinePageModel* offline_page_model_; + // To be called once all callbacks are run or destroyed. ReportStatusCallback on_completion_; @@ -182,15 +186,17 @@ scoped_refptr<CallbackAggregator> aggregator = base::MakeRefCounted<CallbackAggregator>( - std::move(callback), + offline_page_model_, std::move(callback), base::BindRepeating(&FeedOfflineHost::CacheOfflinePageUrlAndId, weak_factory_.GetWeakPtr())); for (std::string url : urls) { - GURL gurl(url); - offline_page_model_->GetPagesByURL( - gurl, base::BindOnce(&CallbackAggregator::OnGetPages, aggregator, - std::move(url))); + offline_pages::PageCriteria criteria; + criteria.url = GURL(url); + criteria.exclude_tab_bound_pages = true; + offline_page_model_->GetPagesWithCriteria( + criteria, base::BindOnce(&CallbackAggregator::OnGetPages, aggregator, + std::move(url))); } }
diff --git a/components/feed/content/feed_offline_host_unittest.cc b/components/feed/content/feed_offline_host_unittest.cc index d2e052f..fb1a9c129 100644 --- a/components/feed/content/feed_offline_host_unittest.cc +++ b/components/feed/content/feed_offline_host_unittest.cc
@@ -18,6 +18,7 @@ #include "components/offline_pages/core/client_namespace_constants.h" #include "components/offline_pages/core/offline_page_item.h" #include "components/offline_pages/core/offline_page_types.h" +#include "components/offline_pages/core/page_criteria.h" #include "components/offline_pages/core/prefetch/stub_prefetch_service.h" #include "components/offline_pages/core/stub_offline_page_model.h" #include "testing/gmock/include/gmock/gmock.h" @@ -28,11 +29,12 @@ namespace { +using offline_pages::MultipleOfflinePageItemCallback; using offline_pages::OfflinePageItem; using offline_pages::OfflinePageModel; -using offline_pages::StubOfflinePageModel; -using offline_pages::MultipleOfflinePageItemCallback; +using offline_pages::PageCriteria; using offline_pages::PrefetchSuggestion; +using offline_pages::StubOfflinePageModel; using offline_pages::StubPrefetchService; using offline_pages::SuggestionsProvider; @@ -75,9 +77,12 @@ MOCK_METHOD1(RemoveObserver, void(Observer*)); private: - void GetPagesByURL(const GURL& url, - MultipleOfflinePageItemCallback callback) override { - auto iter = url_to_offline_page_item_.equal_range(url.spec()); + void GetPagesWithCriteria(const PageCriteria& criteria, + MultipleOfflinePageItemCallback callback) override { + // Feed should ignore tab-bound pages. + EXPECT_TRUE(criteria.exclude_tab_bound_pages); + + auto iter = url_to_offline_page_item_.equal_range(criteria.url.spec()); std::vector<OfflinePageItem> ret; ret.resize(std::distance(iter.first, iter.second)); std::transform(iter.first, iter.second, ret.begin(),
diff --git a/components/history/core/browser/sync/typed_url_sync_bridge.cc b/components/history/core/browser/sync/typed_url_sync_bridge.cc index 3b5286ea..0482f2a 100644 --- a/components/history/core/browser/sync/typed_url_sync_bridge.cc +++ b/components/history/core/browser/sync/typed_url_sync_bridge.cc
@@ -352,6 +352,7 @@ base::Time visit_time) { DCHECK(sequence_checker_.CalledOnValidSequence()); DCHECK(sync_metadata_database_); + DCHECK_GE(row.typed_count(), 0); if (processing_syncer_changes_) return; // These are changes originating from us, ignore. @@ -384,14 +385,10 @@ CreateMetadataChangeList(); for (const auto& row : changed_urls) { - // Only care if the modified URL is typed. - // TODO(crbug.com/907476): Get rid of this trivial check. Typed_count() - // cannot ever be negative. - if (row.typed_count() >= 0) { - // If there were any errors updating the sync node, just ignore them and - // continue on to process the next URL. - UpdateSyncFromLocal(row, is_from_expiration, metadata_change_list.get()); - } + DCHECK_GE(row.typed_count(), 0); + // If there were any errors updating the sync node, just ignore them and + // continue on to process the next URL. + UpdateSyncFromLocal(row, is_from_expiration, metadata_change_list.get()); } } @@ -930,8 +927,6 @@ URLRow row, bool is_from_expiration, MetadataChangeList* metadata_change_list) { - DCHECK_GE(row.typed_count(), 0); - if (ShouldIgnoreUrl(row.url())) return; @@ -1099,10 +1094,7 @@ // suggestions. But there are relatively few URLs with > 10 visits, and those // tend to be more broadly distributed such that there's no need to sync up // every visit to preserve their relative ordering. - // TODO(crbug.com/907476): Get rid of the trivial 'typed_count >= 0' check; - // typed_count cannot ever be negative. return (ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED) && - typed_count >= 0 && (typed_count < kTypedUrlVisitThrottleThreshold || (typed_count % kTypedUrlVisitThrottleMultiple) == 0)); }
diff --git a/components/management_strings.grdp b/components/management_strings.grdp index 970a4ac..6bc6afe 100644 --- a/components/management_strings.grdp +++ b/components/management_strings.grdp
@@ -12,27 +12,39 @@ <grit-part> <!-- Title of the page --> - <if expr="chromeos"> - <message name="IDS_MANAGEMENT_TITLE_MANAGED" desc="Title of chrome://management page, shows when device is managed by unknown organization"> + <message name="IDS_MANAGEMENT_TITLE" desc="Title of management page."> + Settings - Management + </message> + <message name="IDS_MANAGEMENT_TOOLBAR_TITLE" desc="Title of the toolbar in the management page."> + Settings + </message> + + <!-- Subtitle of the page --> + <if expr="chromeos"> + <message name="IDS_MANAGEMENT_SUBTITLE_MANAGED" desc="Title of chrome://management page, shows when device is managed by unknown organization"> Your <ph name="DEVICE_NAME">$1<ex>Chromebook</ex></ph> is managed </message> - <message name="IDS_MANAGEMENT_TITLE_BY" desc="Title of chrome://management page, shows when device managed by known organization"> + <message name="IDS_MANAGEMENT_SUBTITLE_MANAGED_BY" desc="Title of chrome://management page, shows when device managed by known organization"> <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> managed by <ph name="ENROLLMENT_DOMAIN">$2<ex>example.com</ex></ph> </message> - <message name="IDS_MANAGEMENT_NOT_MANAGED_TITLE" desc="Message indicating that the device is not managed"> + <message name="IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE" desc="Message indicating that the device is not managed"> Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> is not managed </message> </if> <if expr="not chromeos"> - <message name="IDS_MANAGEMENT_TITLE" desc="Title of chrome://management page, which shows the administrator's capabilities in a managed environment"> + <message name="IDS_MANAGEMENT_SUBTITLE" desc="Title of chrome://management page, which shows the administrator's capabilities in a managed environment"> Your browser is managed </message> - <message name="IDS_MANAGEMENT_TITLE_BY" desc="Title of chrome://management page, which shows the administrator's capabilities in a managed environment"> + <message name="IDS_MANAGEMENT_SUBTITLE_MANAGED_BY" desc="Title of chrome://management page, which shows the administrator's capabilities in a managed environment"> Your browser is managed by <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph> </message> - <message name="IDS_MANAGEMENT_NOT_MANAGED_TITLE" desc="Title of chrome://management page for a browser that is not managed"> + <message name="IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE" desc="Title of chrome://management page for a browser that is not managed"> Your browser is not managed </message> + </if> + + <!-- Browser managed status section --> + <if expr="not chromeos"> <message name="IDS_MANAGEMENT_BROWSER_NOTICE" desc="Message indicating that the browser is managed by an unknown organization"> This browser is managed by a company, school or other organization. Your administrator can change your browser setup remotely. Activity on this device may also be managed outside of Chrome. <ph name="BEGIN_LINK"><a target="_blank" href="$1"></ph>Learn More<ph name="END_LINK"></a></ph> </message> @@ -44,20 +56,53 @@ </message> </if> - <message name="IDS_MANAGEMENT_DEVICE_NOT_MANAGED" desc="Message indicating that the device is not managed"> - Your device is not managed by an administrator. + <!-- Chrome OS managed status section --> + <if expr="chromeos"> + <message name="IDS_MANAGEMENT_DEVICE_NOT_MANAGED" desc="Message indicating that the device and account are not managed"> + This device and account are not managed by a company or other organization. + </message> + <message name="IDS_MANAGEMENT_DEVICE_MANAGED_BY" desc="Message indicating that the device is enterprise enrolled to be managed by an administrator, from a specific domain"> + Your device is managed by <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph>. + </message> + <message name="IDS_MANAGEMENT_DEVICE_MANAGED_BY_ACCOUNT_MANAGED_BY" desc="Message indicating that the device is enterprise enrolled to be managed by an administrator, from a specific domain. And account is managed by an administrator, from another specific domain."> + Your device is managed by <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph> and your account is managed by <ph name="ACCOUNT_DOMAIN">$2<ex>example.com</ex></ph>. + </message> + <message name="IDS_MANAGEMENT_DEVICE_AND_ACCOUNT_MANAGED_BY" desc="Message indicating that the device and account are enterprise enrolled to be managed by an administrator, from a specific domain"> + Your device and account are managed by <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph>. + </message> + <message name="IDS_MANAGEMENT_ACCOUNT_MANAGED_BY" desc="Message indicating that the account is enterprise enrolled to be managed by an administrator"> + Your account is managed by <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph>. + </message> + <!-- Device managed clarification --> + <message name="IDS_MANAGEMENT_DEVICE_MANAGED_CLARIFICATION" desc="First part of the sentence of the managed device clarification."> + As the manager of this device, <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph>: + </message> + <message name="IDS_MANAGEMENT_DEVICE_MANAGED_SETUP" desc="Continuation of the managed device clarification sentence explaining device setup management."> + Can remotely change your device setup. + </message> + <message name="IDS_MANAGEMENT_DEVICE_MANAGED_DATA" desc="Continuation of the managed device clarification sentence explaining device user data management."> + Controls how your device data is handled. Google processes your device data exclusively under the direction of your device manager and solely for the purposes specified by your device manager. + </message> + <!-- Device and account managed clarification --> + <message name="IDS_MANAGEMENT_DEVICE_AND_ACCOUNT_MANAGED_CLARIFICATION" desc="First part of the sentence of the managed device and account clarification, when enrollment domain equals account domain."> + As the manager of your device and account, <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph>: + </message> + <message name="IDS_MANAGEMENT_DEVICE_AND_ACCOUNT_MANAGED_SETUP" desc="Continuation of the managed device and account clarification sentence explaining device and account setup management."> + Can remotely change your device and account setup. + </message> + <message name="IDS_MANAGEMENT_DEVICE_AND_ACCOUNT_MANAGED_DATA" desc="Continuation of the managed device and account clarification sentence explaining device and account user data management."> + Controls how your device and account data is handled. Google processes your device and account data exclusively under the direction of your device and account manager and solely for the purposes specified by your device and account manager. + </message> + </if> + <!-- Account managed clarification --> + <message name="IDS_MANAGEMENT_ACCOUNT_MANAGED_CLARIFICATION" desc="First part of the sentence of the managed account clarification."> + As the manager of your account, <ph name="ACCOUNT_DOMAIN">$1<ex>example.com</ex></ph>: </message> - <message name="IDS_MANAGEMENT_DEVICE_MANAGED_BY" desc="Message indicating that the device is enterprise enrolled to be managed by an administrator, from a specific domain"> - Your device is managed by <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph>. This means your administrator may remotely configure your device. + <message name="IDS_MANAGEMENT_ACCOUNT_MANAGED_SETUP" desc="Continuation of the managed account clarification sentence explaining account setup management."> + Can remotely change your account setup. </message> - <message name="IDS_MANAGEMENT_DEVICE_MANAGED_BY_ACCOUNT_MANAGED_BY" desc="Message indicating that the device is enterprise enrolled to be managed by an administrator, from a specific domain. And account is managed by an administrator, from another specific domain."> - Your device is managed by <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph > and your account is managed by <ph name="ACCOUNT_DOMAIN">$2<ex>example.com</ex></ph>. This means your administrators may remotely configure your device and account. - </message> - <message name="IDS_MANAGEMENT_DEVICE_AND_ACCOUNT_MANAGED_BY" desc="Message indicating that the device and account is enterprise enrolled to be managed by an administrator, from a specific domain"> - Your device and account is managed by <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph>. This means your administrator may remotely configure your device and account. - </message> - <message name="IDS_MANAGEMENT_ACCOUNT_MANAGED_BY" desc="Message indicating that the account is enterprise enrolled to be managed by an administrator"> - Your account is managed by <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph>. This means your administrator may remotely configure your account. + <message name="IDS_MANAGEMENT_ACCOUNT_MANAGED_DATA" desc="Continuation of the managed account clarification sentence explaining account user data management."> + Controls how your account data is handled. Google processes your account data exclusively under the direction of your account manager and solely for the purposes specified by your account manager. </message> <if expr="chromeos">
diff --git a/components/ntp_snippets/offline_pages/offline_pages_test_utils.cc b/components/ntp_snippets/offline_pages/offline_pages_test_utils.cc index 6bd01ec..a892490 100644 --- a/components/ntp_snippets/offline_pages/offline_pages_test_utils.cc +++ b/components/ntp_snippets/offline_pages/offline_pages_test_utils.cc
@@ -5,6 +5,8 @@ #include "components/ntp_snippets/offline_pages/offline_pages_test_utils.h" #include <iterator> +#include <string> +#include <utility> #include <vector> #include "base/guid.h" @@ -16,6 +18,7 @@ using offline_pages::ClientPolicyController; using offline_pages::MultipleOfflinePageItemCallback; using offline_pages::OfflinePageItem; +using offline_pages::PageCriteria; using offline_pages::StubOfflinePageModel; namespace ntp_snippets { @@ -25,35 +28,23 @@ FakeOfflinePageModel::~FakeOfflinePageModel() = default; -void FakeOfflinePageModel::GetPagesByNamespace( - const std::string& name_space, +void FakeOfflinePageModel::GetAllPages( MultipleOfflinePageItemCallback callback) { - MultipleOfflinePageItemResult filtered_result; - for (auto& item : items_) { - if (item.client_id.name_space == name_space) { - filtered_result.emplace_back(item); - } - } - std::move(callback).Run(filtered_result); + std::move(callback).Run(items_); } -void FakeOfflinePageModel::GetPagesSupportedByDownloads( +void FakeOfflinePageModel::GetPagesWithCriteria( + const PageCriteria& criteria, MultipleOfflinePageItemCallback callback) { ClientPolicyController controller; MultipleOfflinePageItemResult filtered_result; for (auto& item : items_) { - if (controller.IsSupportedByDownload(item.client_id.name_space)) { + if (offline_pages::MeetsCriteria(controller, criteria, item)) filtered_result.emplace_back(item); - } } std::move(callback).Run(filtered_result); } -void FakeOfflinePageModel::GetAllPages( - MultipleOfflinePageItemCallback callback) { - std::move(callback).Run(items_); -} - const std::vector<OfflinePageItem>& FakeOfflinePageModel::items() { return items_; }
diff --git a/components/ntp_snippets/offline_pages/offline_pages_test_utils.h b/components/ntp_snippets/offline_pages/offline_pages_test_utils.h index 5360096..530653f0 100644 --- a/components/ntp_snippets/offline_pages/offline_pages_test_utils.h +++ b/components/ntp_snippets/offline_pages/offline_pages_test_utils.h
@@ -5,8 +5,12 @@ #ifndef COMPONENTS_NTP_SNIPPETS_OFFLINE_PAGES_OFFLINE_PAGES_TEST_UTILS_H_ #define COMPONENTS_NTP_SNIPPETS_OFFLINE_PAGES_OFFLINE_PAGES_TEST_UTILS_H_ +#include <string> +#include <vector> + #include "components/ntp_snippets/content_suggestion.h" #include "components/offline_pages/core/offline_page_item.h" +#include "components/offline_pages/core/page_criteria.h" #include "components/offline_pages/core/stub_offline_page_model.h" namespace ntp_snippets { @@ -17,16 +21,13 @@ FakeOfflinePageModel(); ~FakeOfflinePageModel() override; - void GetPagesByNamespace( - const std::string& name_space, - offline_pages::MultipleOfflinePageItemCallback callback) override; - - void GetPagesSupportedByDownloads( - offline_pages::MultipleOfflinePageItemCallback callback) override; - void GetAllPages( offline_pages::MultipleOfflinePageItemCallback callback) override; + void GetPagesWithCriteria( + const offline_pages::PageCriteria& criteria, + offline_pages::MultipleOfflinePageItemCallback callback) override; + const std::vector<offline_pages::OfflinePageItem>& items(); std::vector<offline_pages::OfflinePageItem>* mutable_items();
diff --git a/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc b/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc index f9b5807..8ca23916 100644 --- a/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc +++ b/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc
@@ -4,11 +4,15 @@ #include "components/ntp_snippets/remote/prefetched_pages_tracker_impl.h" +#include <utility> + #include "base/bind.h" #include "components/offline_pages/core/client_namespace_constants.h" +#include "components/offline_pages/core/page_criteria.h" using offline_pages::OfflinePageItem; using offline_pages::OfflinePageModel; +using offline_pages::PageCriteria; namespace ntp_snippets { @@ -47,8 +51,11 @@ // calls to this method. In this case, there is at least one callback // already waiting. if (initialization_completed_callbacks_.size() == 1) { - offline_page_model_->GetPagesByNamespace( - offline_pages::kSuggestedArticlesNamespace, + PageCriteria criteria; + criteria.client_namespaces.push_back( + offline_pages::kSuggestedArticlesNamespace); + offline_page_model_->GetPagesWithCriteria( + criteria, base::BindOnce(&PrefetchedPagesTrackerImpl::OfflinePagesLoaded, weak_ptr_factory_.GetWeakPtr())); }
diff --git a/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc b/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc index f58eaea..2a8458a6 100644 --- a/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc +++ b/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc
@@ -4,6 +4,8 @@ #include "components/ntp_snippets/remote/prefetched_pages_tracker_impl.h" +#include <utility> + #include "base/bind.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" @@ -17,6 +19,8 @@ using ntp_snippets::test::FakeOfflinePageModel; using offline_pages::MultipleOfflinePageItemCallback; using offline_pages::OfflinePageItem; +using offline_pages::OfflinePageModel; +using offline_pages::PageCriteria; using testing::_; using testing::Eq; using testing::SaveArg; @@ -32,8 +36,8 @@ public: ~MockOfflinePageModel() override = default; - MOCK_METHOD2(GetPagesByNamespace, - void(const std::string& name_space, + MOCK_METHOD2(GetPagesWithCriteria, + void(const PageCriteria& criteria, MultipleOfflinePageItemCallback callback)); }; @@ -171,9 +175,7 @@ TEST_F(PrefetchedPagesTrackerImplTest, ShouldReportAsNotInitializedBeforeReceivedArticles) { - EXPECT_CALL( - *mock_offline_page_model(), - GetPagesByNamespace(offline_pages::kSuggestedArticlesNamespace, _)); + EXPECT_CALL(*mock_offline_page_model(), GetPagesWithCriteria(_, _)); PrefetchedPagesTrackerImpl tracker(mock_offline_page_model()); tracker.Initialize(base::BindOnce([] {})); EXPECT_FALSE(tracker.IsInitialized()); @@ -182,13 +184,11 @@ TEST_F(PrefetchedPagesTrackerImplTest, ShouldReportAsInitializedAfterInitialization) { MultipleOfflinePageItemCallback offline_pages_callback; - EXPECT_CALL( - *mock_offline_page_model(), - GetPagesByNamespace(offline_pages::kSuggestedArticlesNamespace, _)) - .WillOnce([&](const std::string& name_space, - MultipleOfflinePageItemCallback callback) { - offline_pages_callback = std::move(callback); - }); + EXPECT_CALL(*mock_offline_page_model(), GetPagesWithCriteria(_, _)) + .WillOnce( + [&](const PageCriteria&, MultipleOfflinePageItemCallback callback) { + offline_pages_callback = std::move(callback); + }); PrefetchedPagesTrackerImpl tracker(mock_offline_page_model()); tracker.Initialize(base::BindOnce([] {})); @@ -199,13 +199,11 @@ TEST_F(PrefetchedPagesTrackerImplTest, ShouldCallCallbackAfterInitialization) { MultipleOfflinePageItemCallback offline_pages_callback; - EXPECT_CALL( - *mock_offline_page_model(), - GetPagesByNamespace(offline_pages::kSuggestedArticlesNamespace, _)) - .WillOnce([&](const std::string& name_space, - MultipleOfflinePageItemCallback callback) { - offline_pages_callback = std::move(callback); - }); + EXPECT_CALL(*mock_offline_page_model(), GetPagesWithCriteria(_, _)) + .WillOnce( + [&](const PageCriteria&, MultipleOfflinePageItemCallback callback) { + offline_pages_callback = std::move(callback); + }); PrefetchedPagesTrackerImpl tracker(mock_offline_page_model()); base::MockCallback<base::OnceCallback<void()>> @@ -218,13 +216,11 @@ TEST_F(PrefetchedPagesTrackerImplTest, ShouldCallMultipleCallbacksAfterInitialization) { MultipleOfflinePageItemCallback offline_pages_callback; - EXPECT_CALL( - *mock_offline_page_model(), - GetPagesByNamespace(offline_pages::kSuggestedArticlesNamespace, _)) - .WillOnce([&](const std::string& name_space, - MultipleOfflinePageItemCallback callback) { - offline_pages_callback = std::move(callback); - }); + EXPECT_CALL(*mock_offline_page_model(), GetPagesWithCriteria(_, _)) + .WillOnce( + [&](const PageCriteria&, MultipleOfflinePageItemCallback callback) { + offline_pages_callback = std::move(callback); + }); PrefetchedPagesTrackerImpl tracker(mock_offline_page_model()); base::MockCallback<base::OnceCallback<void()>> @@ -240,13 +236,11 @@ TEST_F(PrefetchedPagesTrackerImplTest, ShouldCallCallbackImmediatelyIfAlreadyInitialiazed) { MultipleOfflinePageItemCallback offline_pages_callback; - EXPECT_CALL( - *mock_offline_page_model(), - GetPagesByNamespace(offline_pages::kSuggestedArticlesNamespace, _)) - .WillOnce([&](const std::string& name_space, - MultipleOfflinePageItemCallback callback) { - offline_pages_callback = std::move(callback); - }); + EXPECT_CALL(*mock_offline_page_model(), GetPagesWithCriteria(_, _)) + .WillOnce( + [&](const PageCriteria&, MultipleOfflinePageItemCallback callback) { + offline_pages_callback = std::move(callback); + }); PrefetchedPagesTrackerImpl tracker(mock_offline_page_model()); tracker.Initialize(base::BindOnce([] {}));
diff --git a/components/offline_pages/core/BUILD.gn b/components/offline_pages/core/BUILD.gn index 1dfd358f..07cdd91 100644 --- a/components/offline_pages/core/BUILD.gn +++ b/components/offline_pages/core/BUILD.gn
@@ -79,6 +79,8 @@ "offline_store_types.h", "offline_store_utils.cc", "offline_store_utils.h", + "page_criteria.cc", + "page_criteria.h", "snapshot_controller.cc", "snapshot_controller.h", "system_download_manager.h", @@ -176,6 +178,7 @@ "offline_page_metadata_store_unittest.cc", "offline_page_model_event_logger_unittest.cc", "offline_page_thumbnail_unittest.cc", + "page_criteria_unittest.cc", "snapshot_controller_unittest.cc", ]
diff --git a/components/offline_pages/core/downloads/download_ui_adapter.cc b/components/offline_pages/core/downloads/download_ui_adapter.cc index 5f2a764..fcc9ca4 100644 --- a/components/offline_pages/core/downloads/download_ui_adapter.cc +++ b/components/offline_pages/core/downloads/download_ui_adapter.cc
@@ -4,6 +4,8 @@ #include "components/offline_pages/core/downloads/download_ui_adapter.h" +#include <utility> + #include "base/bind.h" #include "base/bind_helpers.h" #include "base/guid.h" @@ -19,6 +21,7 @@ #include "components/offline_pages/core/client_policy_controller.h" #include "components/offline_pages/core/downloads/offline_item_conversions.h" #include "components/offline_pages/core/offline_page_model.h" +#include "components/offline_pages/core/page_criteria.h" #include "components/offline_pages/core/thumbnail_decoder.h" #include "ui/gfx/image/image.h" @@ -242,10 +245,13 @@ void DownloadUIAdapter::GetVisualsForItem(const ContentId& id, VisualsCallback visuals_callback) { - model_->GetPageByGuid(id.id, - base::BindOnce(&DownloadUIAdapter::OnPageGetForVisuals, - weak_ptr_factory_.GetWeakPtr(), id, - std::move(visuals_callback))); + PageCriteria criteria; + criteria.guid = id.id; + criteria.maximum_matches = 1; + model_->GetPagesWithCriteria( + criteria, base::BindOnce(&DownloadUIAdapter::OnPageGetForVisuals, + weak_ptr_factory_.GetWeakPtr(), id, + std::move(visuals_callback))); } void DownloadUIAdapter::GetShareInfoForItem(const ContentId& id, @@ -259,15 +265,16 @@ NOTREACHED(); } -void DownloadUIAdapter::OnPageGetForVisuals(const ContentId& id, - VisualsCallback visuals_callback, - const OfflinePageItem* page) { - if (!page) { +void DownloadUIAdapter::OnPageGetForVisuals( + const ContentId& id, + VisualsCallback visuals_callback, + const std::vector<OfflinePageItem>& pages) { + if (pages.empty()) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(visuals_callback), id, nullptr)); return; } - + const OfflinePageItem* page = &pages[0]; VisualResultCallback callback = base::BindOnce(std::move(visuals_callback), id); if (page->client_id.name_space == kSuggestedArticlesNamespace) { @@ -335,8 +342,11 @@ void DownloadUIAdapter::GetItemById( const ContentId& id, OfflineContentProvider::SingleItemCallback callback) { - model_->GetPageByGuid( - id.id, + PageCriteria criteria; + criteria.guid = id.id; + criteria.maximum_matches = 1; + model_->GetPagesWithCriteria( + criteria, base::BindOnce(&DownloadUIAdapter::OnPageGetForGetItem, weak_ptr_factory_.GetWeakPtr(), id, std::move(callback))); } @@ -344,8 +354,9 @@ void DownloadUIAdapter::OnPageGetForGetItem( const ContentId& id, OfflineContentProvider::SingleItemCallback callback, - const OfflinePageItem* page) { - if (page) { + const std::vector<OfflinePageItem>& pages) { + if (!pages.empty()) { + const OfflinePageItem* page = &pages[0]; bool is_suggested = model_->GetPolicyController()->IsSuggested(page->client_id.name_space); base::ThreadTaskRunnerHandle::Get()->PostTask( @@ -373,16 +384,20 @@ } void DownloadUIAdapter::OpenItem(LaunchLocation location, const ContentId& id) { - model_->GetPageByGuid( - id.id, base::BindOnce(&DownloadUIAdapter::OnPageGetForOpenItem, - weak_ptr_factory_.GetWeakPtr(), location)); + PageCriteria criteria; + criteria.guid = id.id; + criteria.maximum_matches = 1; + model_->GetPagesWithCriteria( + criteria, base::BindOnce(&DownloadUIAdapter::OnPageGetForOpenItem, + weak_ptr_factory_.GetWeakPtr(), location)); } -void DownloadUIAdapter::OnPageGetForOpenItem(LaunchLocation location, - const OfflinePageItem* page) { - if (!page) +void DownloadUIAdapter::OnPageGetForOpenItem( + LaunchLocation location, + const std::vector<OfflinePageItem>& pages) { + if (pages.empty()) return; - + const OfflinePageItem* page = &pages[0]; bool is_suggested = model_->GetPolicyController()->IsSuggested(page->client_id.name_space); OfflineItem item =
diff --git a/components/offline_pages/core/downloads/download_ui_adapter.h b/components/offline_pages/core/downloads/download_ui_adapter.h index 3393662f..a284ddb4 100644 --- a/components/offline_pages/core/downloads/download_ui_adapter.h +++ b/components/offline_pages/core/downloads/download_ui_adapter.h
@@ -150,17 +150,17 @@ std::vector<std::unique_ptr<SavePageRequest>> requests); void OnPageGetForVisuals(const ContentId& id, VisualsCallback visuals_callback, - const OfflinePageItem* page); + const std::vector<OfflinePageItem>& pages); void OnPageGetForGetItem(const ContentId& id, OfflineContentProvider::SingleItemCallback callback, - const OfflinePageItem* page); + const std::vector<OfflinePageItem>& pages); void OnAllRequestsGetForGetItem( const ContentId& id, OfflineContentProvider::SingleItemCallback callback, std::vector<std::unique_ptr<SavePageRequest>> requests); void OnPageGetForOpenItem(LaunchLocation location, - const OfflinePageItem* page); + const std::vector<OfflinePageItem>& pages); void OnPageGetForThumbnailAdded(const OfflinePageItem* page); void OnDeletePagesDone(DeletePageResult result); @@ -192,4 +192,4 @@ } // namespace offline_pages -#endif // COMPONENTS_OFFLINE_PAGE_DOWNLOADS_DOWNLOAD_UI_ADAPTER_H_ +#endif // COMPONENTS_OFFLINE_PAGES_CORE_DOWNLOADS_DOWNLOAD_UI_ADAPTER_H_
diff --git a/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc b/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc index 4de15b8..d4279a1b 100644 --- a/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc +++ b/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc
@@ -9,6 +9,7 @@ #include <map> #include <memory> #include <string> +#include <utility> #include <vector> #include "base/bind.h" @@ -113,7 +114,7 @@ // Mock OfflinePageModel for testing the SavePage calls. class MockOfflinePageModel : public StubOfflinePageModel { public: - MockOfflinePageModel(base::TestMockTimeTaskRunner* task_runner) + explicit MockOfflinePageModel(base::TestMockTimeTaskRunner* task_runner) : observer_(nullptr), task_runner_(task_runner), policy_controller_(new ClientPolicyController()) {} @@ -192,15 +193,16 @@ std::move(callback).Run(nullptr); } - void GetPageByGuid(const std::string& guid, - SingleOfflinePageItemCallback callback) override { + void GetPagesWithCriteria(const PageCriteria& criteria, + MultipleOfflinePageItemCallback callback) override { + ClientPolicyController policy_controller; + std::vector<OfflinePageItem> matches; for (const auto& page : pages) { - if (page.second.client_id.id == guid) { - std::move(callback).Run(&(page.second)); - return; + if (MeetsCriteria(policy_controller, criteria, page.second)) { + matches.push_back(page.second); } } - std::move(callback).Run(nullptr); + std::move(callback).Run(matches); } void AddPageAndNotifyAdapter(const OfflinePageItem& page) {
diff --git a/components/offline_pages/core/model/get_pages_task.cc b/components/offline_pages/core/model/get_pages_task.cc index 000af333..4ac177e 100644 --- a/components/offline_pages/core/model/get_pages_task.cc +++ b/components/offline_pages/core/model/get_pages_task.cc
@@ -5,11 +5,16 @@ #include "components/offline_pages/core/model/get_pages_task.h" #include <algorithm> +#include <string> +#include <utility> #include "base/bind.h" #include "base/files/file_path.h" #include "base/memory/ptr_util.h" +#include "base/strings/string_number_conversions.h" #include "components/offline_pages/core/client_policy_controller.h" +#include "components/offline_pages/core/offline_page_client_policy.h" +#include "components/offline_pages/core/offline_page_item_utils.h" #include "components/offline_pages/core/offline_store_utils.h" #include "sql/database.h" #include "sql/statement.h" @@ -27,350 +32,178 @@ "client_namespace,client_id,online_url," \ "file_path,title,original_url,request_origin,digest" +ClientId OfflinePageClientId(const sql::Statement& statement) { + return ClientId(statement.ColumnString(7), statement.ColumnString(8)); +} + // Create an offline page item from a SQL result. // Expects the order of columns as defined by OFFLINE_PAGE_PROJECTION macro. -OfflinePageItem MakeOfflinePageItem(sql::Statement* statement) { - int64_t id = statement->ColumnInt64(0); - base::Time creation_time = - store_utils::FromDatabaseTime(statement->ColumnInt64(1)); - int64_t file_size = statement->ColumnInt64(2); - base::Time last_access_time = - store_utils::FromDatabaseTime(statement->ColumnInt64(3)); - int access_count = statement->ColumnInt(4); - int64_t system_download_id = statement->ColumnInt64(5); - base::Time file_missing_time = - store_utils::FromDatabaseTime(statement->ColumnInt64(6)); - ClientId client_id(statement->ColumnString(7), statement->ColumnString(8)); - GURL url(statement->ColumnString(9)); - base::FilePath path( - store_utils::FromDatabaseFilePath(statement->ColumnString(10))); - base::string16 title = statement->ColumnString16(11); - GURL original_url(statement->ColumnString(12)); - std::string request_origin = statement->ColumnString(13); - std::string digest = statement->ColumnString(14); - - OfflinePageItem item(url, id, client_id, path, file_size, creation_time); - item.last_access_time = last_access_time; - item.access_count = access_count; - item.title = title; - item.original_url_if_different = original_url; - item.request_origin = request_origin; - item.system_download_id = system_download_id; - item.file_missing_time = file_missing_time; - item.digest = digest; +OfflinePageItem MakeOfflinePageItem(const sql::Statement& statement) { + OfflinePageItem item; + item.offline_id = statement.ColumnInt64(0); + item.creation_time = store_utils::FromDatabaseTime(statement.ColumnInt64(1)); + item.file_size = statement.ColumnInt64(2); + item.last_access_time = + store_utils::FromDatabaseTime(statement.ColumnInt64(3)); + item.access_count = statement.ColumnInt(4); + item.system_download_id = statement.ColumnInt64(5); + item.file_missing_time = + store_utils::FromDatabaseTime(statement.ColumnInt64(6)); + item.client_id = OfflinePageClientId(statement); + item.url = GURL(statement.ColumnString(9)); + item.file_path = base::FilePath( + store_utils::FromDatabaseFilePath(statement.ColumnString(10))); + item.title = statement.ColumnString16(11); + item.original_url_if_different = GURL(statement.ColumnString(12)); + item.request_origin = statement.ColumnString(13); + item.digest = statement.ColumnString(14); return item; } -ReadResult ReadAllPagesSync(sql::Database* db) { - ReadResult result; - - static const char kSql[] = - "SELECT " OFFLINE_PAGE_PROJECTION " FROM offlinepages_v1"; - sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); - while (statement.Step()) - result.pages.emplace_back(MakeOfflinePageItem(&statement)); - - result.success = true; - return result; +// Returns a pattern to be used in an SQLite LIKE expression to match a +// a URL ignoring the fragment. Warning: this match produces false positives, +// so the URL match must be verified by doing +// UrlWithoutFragment(a)==UrlWithoutFragment(b). +std::string RelaxedLikePattern(const GURL& url) { + // In a LIKE expression, % matches any number of characters, and _ matches any + // single character. + // Replace % with _ in the URL to because _ is more restrictive. + // Append a % to match any URL with our URL as a prefix, just in case the URL + // being matched has a fragment. + std::string string_to_match = UrlWithoutFragment(url).spec(); + std::replace(string_to_match.begin(), string_to_match.end(), '%', '_'); + string_to_match.push_back('%'); + return string_to_match; } -ReadResult ReadPagesByClientIdsSync(const std::vector<ClientId>& client_ids, - sql::Database* db) { - ReadResult result; - - sql::Transaction transaction(db); - if (!transaction.Begin()) - return result; - - static const char kSql[] = "SELECT " OFFLINE_PAGE_PROJECTION - " FROM offlinepages_v1" - " WHERE client_namespace = ? AND client_id = ?"; - for (auto client_id : client_ids) { - sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); - statement.BindString(0, client_id.name_space); - statement.BindString(1, client_id.id); - while (statement.Step()) - result.pages.emplace_back(MakeOfflinePageItem(&statement)); - } - - if (!transaction.Commit()) { - result.pages.clear(); - return result; - } - - result.success = true; - return result; -} - -void ReadPagesByNamespaceSync(sql::Database* db, - const std::string& name_space, - ReadResult* result) { - DCHECK(db); - DCHECK(result); - - static const char kSql[] = "SELECT " OFFLINE_PAGE_PROJECTION - " FROM offlinepages_v1" - " WHERE client_namespace = ?"; - sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); - statement.BindString(0, name_space); - while (statement.Step()) - result->pages.emplace_back(MakeOfflinePageItem(&statement)); -} - -ReadResult ReadPagesByMultipleNamespacesSync( - const std::vector<std::string>& namespaces, +// Some comments on query performance as of March 2019: +// - SQLite stores data in row-oriented fashion, so there's little cost to +// querying additional columns. +// - SQLite supports REGEXP, but it's slow, seems hardly worth using. LIKE is +// fast. +// - Adding more simple conditions to the WHERE clause seems to hardly increase +// runtime, so it's advantageous to add new conditions if they are likely to +// eliminate output. +// - When a single item is returned from a query, using a WHERE clause is about +// 10x faster compared to just querying all rows and filtering the output in +// C++. +// - The below query can process 10K rows in ~1ms (in-memory db). +// - If offline_id is in criteria, SQLite will use the index to evaluate the +// query quickly. Otherwise, we need to read the whole table anyway. Unless +// the db is loaded to memory, and disk access will likely dwarf any +// other query optimizations. +ReadResult ReadPagesByCriteriaSync( + const PageCriteria& criteria, + const ClientPolicyController* policy_controller, sql::Database* db) { ReadResult result; - sql::Transaction transaction(db); - if (!transaction.Begin()) - return result; - for (auto name_space : namespaces) - ReadPagesByNamespaceSync(db, name_space, &result); + // Note: the WHERE clause here is a relaxed form of |criteria|, so returned + // items must be re-checked with |MeetsCriteria|. + static const char kSql[] = + "SELECT " OFFLINE_PAGE_PROJECTION + " FROM offlinepages_v1" + " WHERE" + " offline_id BETWEEN ? AND ?" + " AND (? OR file_size=?)" + " AND (? OR digest=?)" + " AND (? OR instr(?,client_namespace)>0)" + " AND (? OR request_origin=?)" + " AND (? OR instr(?,client_id)>0)" + " AND (? OR online_url LIKE ? OR original_url LIKE ?)" + " ORDER BY creation_time DESC"; - if (!transaction.Commit()) { - result.pages.clear(); - return result; + sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); + + int param = 0; + + if (criteria.offline_id) { + int64_t id = criteria.offline_id.value(); + statement.BindInt64(param++, id); + statement.BindInt64(param++, id); + } else { + statement.BindInt64(param++, INT64_MIN); + statement.BindInt64(param++, INT64_MAX); } - result.success = true; - return result; -} + statement.BindBool(param++, !criteria.file_size); + statement.BindInt64(param++, criteria.file_size.value_or(0)); -ReadResult ReadPagesByRequestOriginSync(const std::string& request_origin, - sql::Database* db) { - ReadResult result; + statement.BindBool(param++, criteria.digest.empty()); + statement.BindString(param++, criteria.digest); - static const char kSql[] = "SELECT " OFFLINE_PAGE_PROJECTION - " FROM offlinepages_v1" - " WHERE request_origin = ?"; - sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); - statement.BindString(0, request_origin); - while (statement.Step()) - result.pages.emplace_back(MakeOfflinePageItem(&statement)); + // For namespace and client_id, we use SQL's substring match function, + // instr(), to provided an inexact match within the query. In both cases, we + // pass SQLite a string equal to the concatenation of all possible values we + // want to find, and then search that string for the row's namespace and + // client_id respectively. + std::vector<std::string> potential_namespaces = + PotentiallyMatchingNamespaces(*policy_controller, criteria); + if (!potential_namespaces.empty()) { + statement.BindBool(param++, false); + statement.BindString(param++, base::JoinString(potential_namespaces, "")); + } else { + statement.BindBool(param++, true); + statement.BindString(param++, ""); + } - result.success = true; - return result; -} + statement.BindBool(param++, criteria.request_origin.empty()); + statement.BindString(param++, criteria.request_origin); -// Notes on implementation: -// The problem we are solving here is matching URLs, but disregarding the -// fragments. We apply the following strategy: -// * Dropping the fragments from the input url, on which we match -// * Replacing '%' characters with '_', to prevent SQL side explosion of -// pattern matching. '%' - matches unbounded length of characters, while -// '_' matches a single character. This choice was made as opposed to -// escaping the '%' character, as it would still include updating the whole -// pattern string and would make the SQL query a little less readable. -// * Appending '%' to the end of pattern, to match both URLs with or without -// fragments. -// Above approach produces false positives, because '_' replacing '%' in -// original URL, but we deal with that by doing exact URL match inside of the -// while loop. -ReadResult ReadPagesByUrlSync(const GURL& url, sql::Database* db) { - ReadResult result; - - GURL::Replacements remove_fragment; - remove_fragment.ClearRef(); - GURL url_to_match = url.ReplaceComponents(remove_fragment); - std::string string_to_match = url_to_match.spec(); - std::replace(string_to_match.begin(), string_to_match.end(), '%', '_'); - string_to_match = string_to_match.append(1UL, '%'); - static const char kSql[] = "SELECT " OFFLINE_PAGE_PROJECTION - " FROM offlinepages_v1" - " WHERE online_url LIKE ? OR original_url like ?"; - sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); - statement.BindString(0, string_to_match); - statement.BindString(1, string_to_match); - while (statement.Step()) { - OfflinePageItem temp_item = MakeOfflinePageItem(&statement); - if (temp_item.url.ReplaceComponents(remove_fragment) == url_to_match || - temp_item.original_url_if_different.ReplaceComponents( - remove_fragment) == url_to_match) { - result.pages.push_back(temp_item); + if (!criteria.client_ids.empty()) { + // Collect all client ids into a single string for matching in the query + // with substring match (instr()). + std::string concatenated_ids; + for (const ClientId& id : criteria.client_ids) { + concatenated_ids += id.id; } + statement.BindBool(param++, false); + statement.BindString(param++, concatenated_ids); + } else { + statement.BindBool(param++, true); + statement.BindString(param++, std::string()); } + const std::string url_pattern = !criteria.url.is_empty() + ? RelaxedLikePattern(criteria.url) + : std::string(); + + statement.BindBool(param++, criteria.url.is_empty()); + statement.BindString(param++, url_pattern); + statement.BindString(param++, url_pattern); + + while (statement.Step()) { + // Initially, read just the client ID to avoid creating the offline item + // if it's filtered out. + if (!MeetsCriteria(*policy_controller, criteria, + OfflinePageClientId(statement))) { + continue; + } + OfflinePageItem item = MakeOfflinePageItem(statement); + if (!MeetsCriteria(*policy_controller, criteria, item)) + continue; + + result.pages.push_back(std::move(item)); + if (criteria.maximum_matches == result.pages.size()) + break; + } result.success = true; return result; } -ReadResult ReadPagesByOfflineId(int64_t offline_id, sql::Database* db) { - ReadResult result; - - static const char kSql[] = "SELECT " OFFLINE_PAGE_PROJECTION - " FROM offlinepages_v1" - " WHERE offline_id = ?"; - sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); - statement.BindInt64(0, offline_id); - while (statement.Step()) - result.pages.emplace_back(MakeOfflinePageItem(&statement)); - - result.success = true; - return result; -} - -ReadResult ReadPagesByGuid(const std::string& guid, sql::Database* db) { - ReadResult result; - - static const char kSql[] = "SELECT " OFFLINE_PAGE_PROJECTION - " FROM offlinepages_v1" - " WHERE client_id = ?"; - sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); - statement.BindString(0, guid); - while (statement.Step()) - result.pages.emplace_back(MakeOfflinePageItem(&statement)); - - result.success = true; - return result; -} - -ReadResult ReadPagesBySizeAndDigest(int64_t file_size, - const std::string& digest, - sql::Database* db) { - ReadResult result; - - static const char kSql[] = "SELECT " OFFLINE_PAGE_PROJECTION - " FROM offlinepages_v1" - " WHERE file_size = ? AND digest = ?"; - sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); - statement.BindInt64(0, file_size); - statement.BindString(1, digest); - while (statement.Step()) - result.pages.emplace_back(MakeOfflinePageItem(&statement)); - - result.success = true; - return result; -} - -void WrapInMultipleItemsCallback(SingleOfflinePageItemCallback callback, - const std::vector<OfflinePageItem>& pages) { - if (pages.size() == 0) - std::move(callback).Run(nullptr); - else - std::move(callback).Run(&pages[0]); -} - } // namespace -GetPagesTask::ReadResult::ReadResult() {} - +GetPagesTask::ReadResult::ReadResult() = default; GetPagesTask::ReadResult::ReadResult(const ReadResult& other) = default; - -GetPagesTask::ReadResult::~ReadResult() {} - -// static -std::unique_ptr<GetPagesTask> GetPagesTask::CreateTaskMatchingAllPages( - OfflinePageMetadataStore* store, - MultipleOfflinePageItemCallback callback) { - return base::WrapUnique(new GetPagesTask( - store, base::BindOnce(&ReadAllPagesSync), std::move(callback))); -} - -// static -std::unique_ptr<GetPagesTask> GetPagesTask::CreateTaskMatchingClientIds( - OfflinePageMetadataStore* store, - MultipleOfflinePageItemCallback callback, - const std::vector<ClientId>& client_ids) { - // Creates an instance of GetPagesTask, which wraps the client_ids argument in - // a OnceClosure. It will then be used to execute. - return base::WrapUnique(new GetPagesTask( - store, base::BindOnce(&ReadPagesByClientIdsSync, client_ids), - std::move(callback))); -} - -// static -std::unique_ptr<GetPagesTask> GetPagesTask::CreateTaskMatchingNamespace( - OfflinePageMetadataStore* store, - MultipleOfflinePageItemCallback callback, - const std::string& name_space) { - std::vector<std::string> namespaces = {name_space}; - return base::WrapUnique(new GetPagesTask( - store, base::BindOnce(&ReadPagesByMultipleNamespacesSync, namespaces), - std::move(callback))); -} - -// static -std::unique_ptr<GetPagesTask> -GetPagesTask::CreateTaskMatchingPagesRemovedOnCacheReset( - OfflinePageMetadataStore* store, - MultipleOfflinePageItemCallback callback, - ClientPolicyController* policy_controller) { - return base::WrapUnique(new GetPagesTask( - store, - base::BindOnce(&ReadPagesByMultipleNamespacesSync, - policy_controller->GetNamespacesRemovedOnCacheReset()), - std::move(callback))); -} - -// static -std::unique_ptr<GetPagesTask> -GetPagesTask::CreateTaskMatchingPagesSupportedByDownloads( - OfflinePageMetadataStore* store, - MultipleOfflinePageItemCallback callback, - ClientPolicyController* policy_controller) { - return base::WrapUnique(new GetPagesTask( - store, - base::BindOnce(&ReadPagesByMultipleNamespacesSync, - policy_controller->GetNamespacesSupportedByDownload()), - std::move(callback))); -} - -// static -std::unique_ptr<GetPagesTask> GetPagesTask::CreateTaskMatchingRequestOrigin( - OfflinePageMetadataStore* store, - MultipleOfflinePageItemCallback callback, - const std::string& request_origin) { - return base::WrapUnique(new GetPagesTask( - store, base::BindOnce(&ReadPagesByRequestOriginSync, request_origin), - std::move(callback))); -} - -// static -std::unique_ptr<GetPagesTask> GetPagesTask::CreateTaskMatchingUrl( - OfflinePageMetadataStore* store, - MultipleOfflinePageItemCallback callback, - const GURL& url) { - return base::WrapUnique(new GetPagesTask( - store, base::BindOnce(&ReadPagesByUrlSync, url), std::move(callback))); -} - -// static -std::unique_ptr<GetPagesTask> GetPagesTask::CreateTaskMatchingOfflineId( - OfflinePageMetadataStore* store, - SingleOfflinePageItemCallback callback, - int64_t offline_id) { - return base::WrapUnique(new GetPagesTask( - store, base::BindOnce(&ReadPagesByOfflineId, offline_id), - base::BindOnce(&WrapInMultipleItemsCallback, std::move(callback)))); -} - -// static -std::unique_ptr<GetPagesTask> GetPagesTask::CreateTaskMatchingGuid( - OfflinePageMetadataStore* store, - SingleOfflinePageItemCallback callback, - const std::string& guid) { - return base::WrapUnique(new GetPagesTask( - store, base::BindOnce(&ReadPagesByGuid, guid), - base::BindOnce(&WrapInMultipleItemsCallback, std::move(callback)))); -} - -// static -std::unique_ptr<GetPagesTask> GetPagesTask::CreateTaskMatchingSizeAndDigest( - OfflinePageMetadataStore* store, - SingleOfflinePageItemCallback callback, - int64_t file_size, - const std::string& digest) { - return base::WrapUnique(new GetPagesTask( - store, base::BindOnce(&ReadPagesBySizeAndDigest, file_size, digest), - base::BindOnce(&WrapInMultipleItemsCallback, std::move(callback)))); -} +GetPagesTask::ReadResult::~ReadResult() = default; GetPagesTask::GetPagesTask(OfflinePageMetadataStore* store, - DbWorkCallback db_work_callback, + const ClientPolicyController* policy_controller, + const PageCriteria& criteria, MultipleOfflinePageItemCallback callback) : store_(store), - db_work_callback_(std::move(db_work_callback)), + policy_controller_(policy_controller), + criteria_(criteria), callback_(std::move(callback)), weak_ptr_factory_(this) { DCHECK(store_); @@ -380,11 +213,8 @@ GetPagesTask::~GetPagesTask() {} void GetPagesTask::Run() { - ReadRequests(); -} - -void GetPagesTask::ReadRequests() { - store_->Execute(std::move(db_work_callback_), + store_->Execute(base::BindOnce(&ReadPagesByCriteriaSync, std::move(criteria_), + policy_controller_), base::BindOnce(&GetPagesTask::CompleteWithResult, weak_ptr_factory_.GetWeakPtr()), ReadResult());
diff --git a/components/offline_pages/core/model/get_pages_task.h b/components/offline_pages/core/model/get_pages_task.h index d89c7ea..22c3cb6 100644 --- a/components/offline_pages/core/model/get_pages_task.h +++ b/components/offline_pages/core/model/get_pages_task.h
@@ -13,14 +13,13 @@ #include "components/offline_pages/core/offline_page_item.h" #include "components/offline_pages/core/offline_page_metadata_store.h" #include "components/offline_pages/core/offline_page_types.h" +#include "components/offline_pages/core/page_criteria.h" #include "components/offline_pages/task/task.h" -class GURL; - namespace offline_pages { class ClientPolicyController; -// Gets offline pages that match the list of client IDs. +// Gets offline pages that match the criteria. class GetPagesTask : public Task { public: // Structure defining and intermediate read result. @@ -33,79 +32,10 @@ std::vector<OfflinePageItem> pages; }; - using DbWorkCallback = OfflinePageMetadataStore::RunCallback<ReadResult>; - - // Creates |GetPagesTask| reading all pages from DB. - static std::unique_ptr<GetPagesTask> CreateTaskMatchingAllPages( - OfflinePageMetadataStore* store, - MultipleOfflinePageItemCallback callback); - - // Creates |GetPagesTask| reading pages matching provided |client_ids| from - // DB. - static std::unique_ptr<GetPagesTask> CreateTaskMatchingClientIds( - OfflinePageMetadataStore* store, - MultipleOfflinePageItemCallback callback, - const std::vector<ClientId>& client_ids); - - // Creates |GetPagesTask| reading pages belonging to provided |name_space| - // from DB. - static std::unique_ptr<GetPagesTask> CreateTaskMatchingNamespace( - OfflinePageMetadataStore* store, - MultipleOfflinePageItemCallback callback, - const std::string& name_space); - - // Creates |GetPagesTask| reading pages removed on cache reset from DB. - static std::unique_ptr<GetPagesTask> - CreateTaskMatchingPagesRemovedOnCacheReset( - OfflinePageMetadataStore* store, - MultipleOfflinePageItemCallback callback, - ClientPolicyController* policy_controller); - - // Creates |GetPagesTask| reading pages in namespaces supported by downloads - // from DB. - static std::unique_ptr<GetPagesTask> - CreateTaskMatchingPagesSupportedByDownloads( - OfflinePageMetadataStore* store, - MultipleOfflinePageItemCallback callback, - ClientPolicyController* policy_controller); - - // Creates |GetPagesTask| reading pages matching provided |request_origin| - // from DB. - static std::unique_ptr<GetPagesTask> CreateTaskMatchingRequestOrigin( - OfflinePageMetadataStore* store, - MultipleOfflinePageItemCallback callback, - const std::string& request_origin); - - // Creates |GetPagesTask| reading pages matching provided |url| from DB. - // The url will be matched against original URL and final URL. Fragments will - // be removed from all URLs prior to matching. Only a match on a single field - // is necessary. - static std::unique_ptr<GetPagesTask> CreateTaskMatchingUrl( - OfflinePageMetadataStore* store, - MultipleOfflinePageItemCallback callback, - const GURL& url); - - // Creates |GetPagesTask| reading a single page matching provided |offline_id| - // from DB. - static std::unique_ptr<GetPagesTask> CreateTaskMatchingOfflineId( - OfflinePageMetadataStore* store, - SingleOfflinePageItemCallback callback, - int64_t offline_id); - - // Creates |GetPagesTask| reading a single page matching provided |guid| from - // DB. - static std::unique_ptr<GetPagesTask> CreateTaskMatchingGuid( - OfflinePageMetadataStore* store, - SingleOfflinePageItemCallback callback, - const std::string& guid); - - // Creates |GetPagesTask| reading a single page matching provided |file_size| - // and |digest| from DB. - static std::unique_ptr<GetPagesTask> CreateTaskMatchingSizeAndDigest( - OfflinePageMetadataStore* store, - SingleOfflinePageItemCallback callback, - int64_t file_size, - const std::string& digest); + GetPagesTask(OfflinePageMetadataStore* store, + const ClientPolicyController* policy_controller, + const PageCriteria& criteria, + MultipleOfflinePageItemCallback callback); ~GetPagesTask() override; @@ -113,15 +43,11 @@ void Run() override; private: - GetPagesTask(OfflinePageMetadataStore* store, - DbWorkCallback db_work_callback, - MultipleOfflinePageItemCallback callback); - - void ReadRequests(); void CompleteWithResult(ReadResult result); OfflinePageMetadataStore* store_; - DbWorkCallback db_work_callback_; + const ClientPolicyController* policy_controller_; + PageCriteria criteria_; MultipleOfflinePageItemCallback callback_; base::WeakPtrFactory<GetPagesTask> weak_ptr_factory_;
diff --git a/components/offline_pages/core/model/get_pages_task_unittest.cc b/components/offline_pages/core/model/get_pages_task_unittest.cc index 915f4e56e..6fe12a8 100644 --- a/components/offline_pages/core/model/get_pages_task_unittest.cc +++ b/components/offline_pages/core/model/get_pages_task_unittest.cc
@@ -5,6 +5,9 @@ #include "components/offline_pages/core/model/get_pages_task.h" #include <stdint.h> +#include <memory> +#include <set> +#include <string> #include <utility> #include "base/bind.h" @@ -12,6 +15,7 @@ #include "components/offline_pages/core/client_namespace_constants.h" #include "components/offline_pages/core/model/model_task_test_base.h" #include "components/offline_pages/core/offline_page_types.h" +#include "components/offline_pages/core/offline_store_utils.h" #include "testing/gtest/include/gtest/gtest.h" namespace offline_pages { @@ -24,246 +28,227 @@ class GetPagesTaskTest : public ModelTaskTestBase { public: - void OnGetPagesDone(const std::vector<OfflinePageItem>& pages); - void OnGetPageDone(const OfflinePageItem* page); + const std::set<OfflinePageItem>& task_result() const { return task_result_; } - MultipleOfflinePageItemCallback get_pages_callback(); - SingleOfflinePageItemCallback get_single_page_callback(); - - const std::vector<OfflinePageItem>& read_result() const { - return read_result_; + void InsertItems(std::vector<OfflinePageItem> items) { + for (auto& item : items) { + store_test_util()->InsertItem(item); + } } - const OfflinePageItem& single_page_result() const { - return single_page_result_; + std::unique_ptr<GetPagesTask> CreateTask(const PageCriteria& criteria) { + return std::make_unique<GetPagesTask>( + store(), &policy_controller_, criteria, + base::BindOnce(&GetPagesTaskTest::OnGetPagesDone, + base::Unretained(this))); } private: - std::vector<OfflinePageItem> read_result_; - OfflinePageItem single_page_result_; + void OnGetPagesDone(const std::vector<OfflinePageItem>& result) { + task_result_.clear(); + task_result_.insert(result.begin(), result.end()); + // Verify there were no identical items, to ensure the set contains the + // same data. + EXPECT_EQ(result.size(), task_result_.size()); + } + + protected: + ClientPolicyController policy_controller_; + std::set<OfflinePageItem> task_result_; }; -void GetPagesTaskTest::OnGetPagesDone( - const std::vector<OfflinePageItem>& result) { - read_result_.clear(); - for (auto page : result) - read_result_.push_back(page); -} - -void GetPagesTaskTest::OnGetPageDone(const OfflinePageItem* page) { - if (!page) - return; - single_page_result_ = *page; -} - -MultipleOfflinePageItemCallback GetPagesTaskTest::get_pages_callback() { - return base::BindOnce(&GetPagesTaskTest::OnGetPagesDone, - base::Unretained(this)); -} - -SingleOfflinePageItemCallback GetPagesTaskTest::get_single_page_callback() { - return base::BindOnce(&GetPagesTaskTest::OnGetPageDone, - base::Unretained(this)); -} - TEST_F(GetPagesTaskTest, GetAllPages) { generator()->SetNamespace(kTestNamespace); OfflinePageItem item_1 = generator()->CreateItem(); - store_test_util()->InsertItem(item_1); OfflinePageItem item_2 = generator()->CreateItem(); - store_test_util()->InsertItem(item_2); OfflinePageItem item_3 = generator()->CreateItem(); - store_test_util()->InsertItem(item_3); + InsertItems({item_1, item_2, item_3}); - RunTask( - GetPagesTask::CreateTaskMatchingAllPages(store(), get_pages_callback())); + RunTask(CreateTask(PageCriteria())); - std::set<OfflinePageItem> result_set; - result_set.insert(read_result().begin(), read_result().end()); - EXPECT_EQ(3UL, result_set.size()); - EXPECT_EQ(1UL, result_set.count(item_1)); - EXPECT_EQ(1UL, result_set.count(item_2)); - EXPECT_EQ(1UL, result_set.count(item_3)); + EXPECT_EQ(std::set<OfflinePageItem>({item_1, item_2, item_3}), task_result()); } -TEST_F(GetPagesTaskTest, GetPagesForSingleClientId) { +TEST_F(GetPagesTaskTest, MultipleClientIds) { generator()->SetNamespace(kTestNamespace); OfflinePageItem item_1 = generator()->CreateItem(); - store_test_util()->InsertItem(item_1); - - std::vector<ClientId> client_ids = {item_1.client_id}; - - RunTask(GetPagesTask::CreateTaskMatchingClientIds( - store(), get_pages_callback(), client_ids)); - - EXPECT_EQ(1UL, read_result().size()); - EXPECT_EQ(item_1, *(read_result().begin())); -} - -TEST_F(GetPagesTaskTest, GetPagesForMultipleClientIds) { - generator()->SetNamespace(kTestNamespace); - OfflinePageItem item_1 = generator()->CreateItem(); - store_test_util()->InsertItem(item_1); OfflinePageItem item_2 = generator()->CreateItem(); - store_test_util()->InsertItem(item_2); OfflinePageItem item_3 = generator()->CreateItem(); - store_test_util()->InsertItem(item_3); + InsertItems({item_1, item_2, item_3}); - std::vector<ClientId> client_ids{item_1.client_id, item_2.client_id}; + PageCriteria criteria; + criteria.client_ids = {item_1.client_id, item_2.client_id}; + RunTask(CreateTask(criteria)); - RunTask(GetPagesTask::CreateTaskMatchingClientIds( - store(), get_pages_callback(), client_ids)); - - std::set<OfflinePageItem> result_set; - result_set.insert(read_result().begin(), read_result().end()); - EXPECT_EQ(2UL, result_set.size()); - EXPECT_EQ(1UL, result_set.count(item_1)); - EXPECT_EQ(1UL, result_set.count(item_2)); + EXPECT_EQ(std::set<OfflinePageItem>({item_1, item_2}), task_result()); } -TEST_F(GetPagesTaskTest, GetPagesByNamespace) { +TEST_F(GetPagesTaskTest, Namespace) { static const char kOtherNamespace[] = "other_namespace"; generator()->SetNamespace(kTestNamespace); OfflinePageItem item_1 = generator()->CreateItem(); - store_test_util()->InsertItem(item_1); OfflinePageItem item_2 = generator()->CreateItem(); - store_test_util()->InsertItem(item_2); generator()->SetNamespace(kOtherNamespace); OfflinePageItem item_3 = generator()->CreateItem(); - store_test_util()->InsertItem(item_3); + InsertItems({item_1, item_2, item_3}); - RunTask(GetPagesTask::CreateTaskMatchingNamespace( - store(), get_pages_callback(), kTestNamespace)); + PageCriteria criteria; + criteria.client_namespaces.push_back(kTestNamespace); + RunTask(CreateTask(criteria)); - std::set<OfflinePageItem> result_set; - result_set.insert(read_result().begin(), read_result().end()); - EXPECT_EQ(2UL, result_set.size()); - EXPECT_EQ(1UL, result_set.count(item_1)); - EXPECT_EQ(1UL, result_set.count(item_2)); + EXPECT_EQ(std::set<OfflinePageItem>({item_1, item_2}), task_result()); } -TEST_F(GetPagesTaskTest, GetPagesByRequestOrigin) { +TEST_F(GetPagesTaskTest, RequestOrigin) { static const char kRequestOrigin1[] = "bar"; static const char kRequestOrigin2[] = "baz"; generator()->SetNamespace(kTestNamespace); generator()->SetRequestOrigin(kRequestOrigin1); OfflinePageItem item_1 = generator()->CreateItem(); - store_test_util()->InsertItem(item_1); OfflinePageItem item_2 = generator()->CreateItem(); - store_test_util()->InsertItem(item_2); generator()->SetRequestOrigin(kRequestOrigin2); OfflinePageItem item_3 = generator()->CreateItem(); - store_test_util()->InsertItem(item_3); + InsertItems({item_1, item_2, item_3}); - RunTask(GetPagesTask::CreateTaskMatchingRequestOrigin( - store(), get_pages_callback(), kRequestOrigin1)); + PageCriteria criteria; + criteria.request_origin = kRequestOrigin1; + RunTask(CreateTask(criteria)); - std::set<OfflinePageItem> result_set; - result_set.insert(read_result().begin(), read_result().end()); - EXPECT_EQ(2UL, result_set.size()); - EXPECT_EQ(1UL, result_set.count(item_1)); - EXPECT_EQ(1UL, result_set.count(item_2)); + EXPECT_EQ(std::set<OfflinePageItem>({item_1, item_2}), task_result()); } -TEST_F(GetPagesTaskTest, GetPagesByUrl) { - static const GURL kUrl1("http://cs.chromium.org"); - static const GURL kUrl1Frag("http://cs.chromium.org#frag1"); - static const GURL kUrl2("http://chrome.google.com"); +TEST_F(GetPagesTaskTest, Url) { + const GURL kUrl1("http://cs.chromium.org"); + const GURL kUrl1WithSuffix("http://cs.chromium.org/suffix"); + const GURL kUrl1Frag("http://cs.chromium.org#frag1"); + const GURL kUrl2("http://chrome.google.com"); generator()->SetNamespace(kTestNamespace); generator()->SetUrl(kUrl1); OfflinePageItem item_1 = generator()->CreateItem(); - store_test_util()->InsertItem(item_1); generator()->SetUrl(kUrl1Frag); OfflinePageItem item_2 = generator()->CreateItem(); - store_test_util()->InsertItem(item_2); generator()->SetUrl(kUrl2); generator()->SetOriginalUrl(kUrl1); OfflinePageItem item_3 = generator()->CreateItem(); - store_test_util()->InsertItem(item_3); generator()->SetUrl(kUrl2); generator()->SetOriginalUrl(kUrl1Frag); OfflinePageItem item_4 = generator()->CreateItem(); - store_test_util()->InsertItem(item_4); generator()->SetUrl(kUrl2); generator()->SetOriginalUrl(kUrl2); OfflinePageItem item_5 = generator()->CreateItem(); - store_test_util()->InsertItem(item_5); - RunTask(GetPagesTask::CreateTaskMatchingUrl(store(), get_pages_callback(), - kUrl1)); + generator()->SetUrl(kUrl1WithSuffix); + generator()->SetOriginalUrl(kUrl1WithSuffix); + OfflinePageItem item_6 = generator()->CreateItem(); - std::set<OfflinePageItem> result_set; - result_set.insert(read_result().begin(), read_result().end()); - EXPECT_EQ(4UL, result_set.size()); - EXPECT_EQ(1UL, result_set.count(item_1)); - EXPECT_EQ(1UL, result_set.count(item_2)); - EXPECT_EQ(1UL, result_set.count(item_3)); - EXPECT_EQ(1UL, result_set.count(item_4)); + InsertItems({item_1, item_2, item_3, item_4, item_5, item_6}); + + PageCriteria criteria; + criteria.url = kUrl1; + RunTask(CreateTask(criteria)); + + EXPECT_EQ(std::set<OfflinePageItem>({item_1, item_2, item_3, item_4}), + task_result()); } -TEST_F(GetPagesTaskTest, GetPageByOfflineId) { +TEST_F(GetPagesTaskTest, OfflineId) { generator()->SetNamespace(kTestNamespace); - OfflinePageItem item_1 = generator()->CreateItem(); - store_test_util()->InsertItem(item_1); - OfflinePageItem item_2 = generator()->CreateItem(); - store_test_util()->InsertItem(item_2); - OfflinePageItem item_3 = generator()->CreateItem(); - store_test_util()->InsertItem(item_3); + const OfflinePageItem item_1 = generator()->CreateItem(); + const OfflinePageItem item_2 = generator()->CreateItem(); + const OfflinePageItem item_3 = generator()->CreateItem(); + InsertItems({item_1, item_2, item_3}); - RunTask(GetPagesTask::CreateTaskMatchingOfflineId( - store(), get_single_page_callback(), item_1.offline_id)); + PageCriteria criteria; + criteria.offline_id = item_1.offline_id; + RunTask(CreateTask(criteria)); - EXPECT_EQ(item_1, single_page_result()); + EXPECT_EQ(std::set<OfflinePageItem>({item_1}), task_result()); } -TEST_F(GetPagesTaskTest, GetPageByGuid) { - OfflinePageItem item_1 = generator()->CreateItem(); - store_test_util()->InsertItem(item_1); - OfflinePageItem item_2 = generator()->CreateItem(); - store_test_util()->InsertItem(item_2); - OfflinePageItem item_3 = generator()->CreateItem(); - store_test_util()->InsertItem(item_3); +TEST_F(GetPagesTaskTest, Guid) { + const OfflinePageItem item_1 = generator()->CreateItem(); + const OfflinePageItem item_2 = generator()->CreateItem(); + const OfflinePageItem item_3 = generator()->CreateItem(); + InsertItems({item_1, item_2, item_3}); - RunTask(GetPagesTask::CreateTaskMatchingGuid( - store(), get_single_page_callback(), item_1.client_id.id)); + PageCriteria criteria; + criteria.guid = item_1.client_id.id; + RunTask(CreateTask(criteria)); - EXPECT_EQ(item_1, single_page_result()); + EXPECT_EQ(std::set<OfflinePageItem>({item_1}), task_result()); } -TEST_F(GetPagesTaskTest, GetPageBySizeAndDigest) { - static const int64_t kFileSize1 = 123LL; - static const int64_t kFileSize2 = 999999LL; - static const char kDigest1[] = "digest 1"; - static const char kDigest2[] = "digest 2"; - generator()->SetFileSize(kFileSize1); - generator()->SetDigest(kDigest1); +TEST_F(GetPagesTaskTest, FileSize) { OfflinePageItem item_1 = generator()->CreateItem(); - store_test_util()->InsertItem(item_1); - generator()->SetDigest(kDigest2); + item_1.file_size = 123; OfflinePageItem item_2 = generator()->CreateItem(); - store_test_util()->InsertItem(item_2); - generator()->SetFileSize(kFileSize2); - OfflinePageItem item_3 = generator()->CreateItem(); - store_test_util()->InsertItem(item_3); + InsertItems({item_1, item_2}); - RunTask(GetPagesTask::CreateTaskMatchingSizeAndDigest( - store(), get_single_page_callback(), kFileSize1, "mismatched digest")); - EXPECT_EQ(OfflinePageItem(), single_page_result()); + PageCriteria criteria; + criteria.file_size = 123; + RunTask(CreateTask(criteria)); - RunTask(GetPagesTask::CreateTaskMatchingSizeAndDigest( - store(), get_single_page_callback(), 0LL, kDigest1)); - EXPECT_EQ(OfflinePageItem(), single_page_result()); - - RunTask(GetPagesTask::CreateTaskMatchingSizeAndDigest( - store(), get_single_page_callback(), kFileSize2, kDigest2)); - EXPECT_EQ(item_3, single_page_result()); + EXPECT_EQ(std::set<OfflinePageItem>({item_1}), task_result()); } -TEST_F(GetPagesTaskTest, GetPagesSupportedByDownloads) { +TEST_F(GetPagesTaskTest, Digest) { + OfflinePageItem item_1 = generator()->CreateItem(); + item_1.digest = "abc"; + OfflinePageItem item_2 = generator()->CreateItem(); + item_2.digest = "123"; + InsertItems({item_1, item_2}); + + PageCriteria criteria; + criteria.digest = "abc"; + RunTask(CreateTask(criteria)); + + EXPECT_EQ(std::set<OfflinePageItem>({item_1}), task_result()); +} + +TEST_F(GetPagesTaskTest, MultipleConditions) { + const GURL kUrl1("http://cs.chromium.org"); + const std::string digest = "abc"; + + // |item_1| matches, and all other items differ by one criteria. + OfflinePageItem item_1 = generator()->CreateItem(); + item_1.digest = digest; + item_1.file_size = 123; + item_1.url = kUrl1; + item_1.client_id.name_space = kDownloadNamespace; + + OfflinePageItem item_2 = item_1; + item_2.offline_id = store_utils::GenerateOfflineId(); + item_2.digest = "other"; + + OfflinePageItem item_3 = item_1; + item_3.offline_id = store_utils::GenerateOfflineId(); + item_3.client_id.name_space = kLastNNamespace; + + OfflinePageItem item_4 = item_1; + item_4.offline_id = store_utils::GenerateOfflineId(); + item_4.file_size = 0; + + OfflinePageItem item_5 = item_1; + item_5.offline_id = store_utils::GenerateOfflineId(); + item_5.url = GURL("http://cs.chromium.org/1"); + + InsertItems({item_1, item_2, item_3, item_4, item_5}); + + PageCriteria criteria; + criteria.digest = digest; + criteria.file_size = 123; + criteria.url = kUrl1; + criteria.exclude_tab_bound_pages = true; + RunTask(CreateTask(criteria)); + + EXPECT_EQ(std::set<OfflinePageItem>({item_1}), task_result()); +} + +TEST_F(GetPagesTaskTest, SupportedByDownloads) { generator()->SetNamespace(kCCTNamespace); store_test_util()->InsertItem(generator()->CreateItem()); generator()->SetNamespace(kDownloadNamespace); @@ -273,17 +258,28 @@ OfflinePageItem ntp_suggestion_item = generator()->CreateItem(); store_test_util()->InsertItem(ntp_suggestion_item); - RunTask(GetPagesTask::CreateTaskMatchingPagesSupportedByDownloads( - store(), get_pages_callback(), policy_controller())); + // All pages with supported_by_downloads. + { + PageCriteria criteria; + criteria.supported_by_downloads = true; + RunTask(CreateTask(criteria)); - std::set<OfflinePageItem> result_set; - result_set.insert(read_result().begin(), read_result().end()); - EXPECT_EQ(2UL, result_set.size()); - EXPECT_EQ(1UL, result_set.count(download_item)); - EXPECT_EQ(1UL, result_set.count(ntp_suggestion_item)); + EXPECT_EQ(std::set<OfflinePageItem>({download_item, ntp_suggestion_item}), + task_result()); + } + + // Only CCT, NTP with supported_by_downloads. + { + PageCriteria criteria; + criteria.supported_by_downloads = true; + criteria.client_namespaces = {kCCTNamespace, kNTPSuggestionsNamespace}; + RunTask(CreateTask(criteria)); + + EXPECT_EQ(std::set<OfflinePageItem>({ntp_suggestion_item}), task_result()); + } } -TEST_F(GetPagesTaskTest, GetPagesRemovedOnCacheReset) { +TEST_F(GetPagesTaskTest, RemovedOnCacheReset) { generator()->SetNamespace(kCCTNamespace); OfflinePageItem cct_item = generator()->CreateItem(); store_test_util()->InsertItem(cct_item); @@ -292,13 +288,11 @@ generator()->SetNamespace(kNTPSuggestionsNamespace); store_test_util()->InsertItem(generator()->CreateItem()); - RunTask(GetPagesTask::CreateTaskMatchingPagesRemovedOnCacheReset( - store(), get_pages_callback(), policy_controller())); + PageCriteria criteria; + criteria.removed_on_cache_reset = true; + RunTask(CreateTask(criteria)); - std::set<OfflinePageItem> result_set; - result_set.insert(read_result().begin(), read_result().end()); - EXPECT_EQ(1UL, result_set.size()); - EXPECT_EQ(1UL, result_set.count(cct_item)); + EXPECT_EQ(std::set<OfflinePageItem>({cct_item}), task_result()); } } // namespace offline_pages
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 f7a421cf..09108161 100644 --- a/components/offline_pages/core/model/offline_page_model_taskified.cc +++ b/components/offline_pages/core/model/offline_page_model_taskified.cc
@@ -313,84 +313,31 @@ void OfflinePageModelTaskified::GetAllPages( MultipleOfflinePageItemCallback callback) { - auto task = GetPagesTask::CreateTaskMatchingAllPages( - store_.get(), - base::BindOnce(&ReportSavedPagesCount, std::move(callback))); - task_queue_.AddTask(std::move(task)); + GetPagesWithCriteria(PageCriteria(), base::BindOnce(&ReportSavedPagesCount, + std::move(callback))); ScheduleMaintenanceTasks(); } void OfflinePageModelTaskified::GetPageByOfflineId( int64_t offline_id, SingleOfflinePageItemCallback callback) { - auto task = GetPagesTask::CreateTaskMatchingOfflineId( - store_.get(), std::move(callback), offline_id); - task_queue_.AddTask(std::move(task)); + PageCriteria criteria; + criteria.offline_id = offline_id; + // Adapt multiple result to single result callback. + auto wrapped_callback = base::BindOnce( + [](SingleOfflinePageItemCallback callback, + const std::vector<OfflinePageItem>& pages) { + std::move(callback).Run(pages.empty() ? nullptr : &pages[0]); + }, + std::move(callback)); + GetPagesWithCriteria(criteria, std::move(wrapped_callback)); } -void OfflinePageModelTaskified::GetPageByGuid( - const std::string& guid, - SingleOfflinePageItemCallback callback) { - auto task = GetPagesTask::CreateTaskMatchingGuid(store_.get(), - std::move(callback), guid); - task_queue_.AddTask(std::move(task)); -} - -void OfflinePageModelTaskified::GetPagesByClientIds( - const std::vector<ClientId>& client_ids, +void OfflinePageModelTaskified::GetPagesWithCriteria( + const PageCriteria& criteria, MultipleOfflinePageItemCallback callback) { - auto task = GetPagesTask::CreateTaskMatchingClientIds( - store_.get(), std::move(callback), client_ids); - task_queue_.AddTask(std::move(task)); -} - -void OfflinePageModelTaskified::GetPagesByURL( - const GURL& url, - MultipleOfflinePageItemCallback callback) { - auto task = GetPagesTask::CreateTaskMatchingUrl(store_.get(), - std::move(callback), url); - task_queue_.AddTask(std::move(task)); -} - -void OfflinePageModelTaskified::GetPagesByNamespace( - const std::string& name_space, - MultipleOfflinePageItemCallback callback) { - auto task = GetPagesTask::CreateTaskMatchingNamespace( - store_.get(), std::move(callback), name_space); - task_queue_.AddTask(std::move(task)); -} - -void OfflinePageModelTaskified::GetPagesRemovedOnCacheReset( - MultipleOfflinePageItemCallback callback) { - auto task = GetPagesTask::CreateTaskMatchingPagesRemovedOnCacheReset( - store_.get(), std::move(callback), policy_controller_.get()); - task_queue_.AddTask(std::move(task)); -} - -void OfflinePageModelTaskified::GetPagesSupportedByDownloads( - MultipleOfflinePageItemCallback callback) { - auto task = GetPagesTask::CreateTaskMatchingPagesSupportedByDownloads( - store_.get(), std::move(callback), policy_controller_.get()); - task_queue_.AddTask(std::move(task)); -} - -void OfflinePageModelTaskified::GetPagesByRequestOrigin( - const std::string& request_origin, - MultipleOfflinePageItemCallback callback) { - auto task = GetPagesTask::CreateTaskMatchingRequestOrigin( - store_.get(), std::move(callback), request_origin); - task_queue_.AddTask(std::move(task)); -} - -void OfflinePageModelTaskified::GetPageBySizeAndDigest( - int64_t file_size, - const std::string& digest, - SingleOfflinePageItemCallback callback) { - DCHECK_GT(file_size, 0); - DCHECK(!digest.empty()); - auto task = GetPagesTask::CreateTaskMatchingSizeAndDigest( - store_.get(), std::move(callback), file_size, digest); - task_queue_.AddTask(std::move(task)); + task_queue_.AddTask(std::make_unique<GetPagesTask>( + store_.get(), policy_controller_.get(), criteria, std::move(callback))); } void OfflinePageModelTaskified::GetOfflineIdsForClientId( @@ -399,11 +346,10 @@ // 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::BindOnce(&WrapInMultipleItemsCallback, std::move(callback)), - {client_id}); - task_queue_.AddTask(std::move(task)); + PageCriteria criteria; + criteria.client_ids = {client_id}; + GetPagesWithCriteria(criteria, base::BindOnce(&WrapInMultipleItemsCallback, + std::move(callback))); } void OfflinePageModelTaskified::StoreThumbnail(
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 090812d..7abb07f 100644 --- a/components/offline_pages/core/model/offline_page_model_taskified.h +++ b/components/offline_pages/core/model/offline_page_model_taskified.h
@@ -95,24 +95,8 @@ void GetAllPages(MultipleOfflinePageItemCallback callback) override; void GetPageByOfflineId(int64_t offline_id, SingleOfflinePageItemCallback callback) override; - void GetPageByGuid(const std::string& guid, - SingleOfflinePageItemCallback callback) override; - void GetPagesByClientIds(const std::vector<ClientId>& client_ids, - MultipleOfflinePageItemCallback callback) override; - void GetPagesByURL(const GURL& url, - MultipleOfflinePageItemCallback callback) override; - void GetPagesByNamespace(const std::string& name_space, - MultipleOfflinePageItemCallback callback) override; - void GetPagesRemovedOnCacheReset( - MultipleOfflinePageItemCallback callback) override; - void GetPagesSupportedByDownloads( - MultipleOfflinePageItemCallback callback) override; - void GetPagesByRequestOrigin( - const std::string& request_origin, - MultipleOfflinePageItemCallback callback) override; - void GetPageBySizeAndDigest(int64_t file_size, - const std::string& digest, - SingleOfflinePageItemCallback callback) override; + void GetPagesWithCriteria(const PageCriteria& criteria, + MultipleOfflinePageItemCallback callback) override; void GetOfflineIdsForClientId(const ClientId& client_id, MultipleOfflineIdCallback callback) override; void StoreThumbnail(const OfflinePageThumbnail& thumb) override;
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 a927485..dfba7cc 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
@@ -949,7 +949,7 @@ PumpLoop(); } -TEST_F(OfflinePageModelTaskifiedTest, GetPagesByUrl_FinalUrl) { +TEST_F(OfflinePageModelTaskifiedTest, GetPagesWithCriteria_FinalUrl) { page_generator()->SetUrl(kTestUrl); OfflinePageItem page1 = page_generator()->CreateItem(); InsertPageIntoStore(page1); @@ -960,18 +960,22 @@ // Search by kTestUrl. base::MockCallback<MultipleOfflinePageItemCallback> callback; EXPECT_CALL(callback, Run(ElementsAre(page1))); - model()->GetPagesByURL(kTestUrl, callback.Get()); + PageCriteria criteria; + criteria.url = kTestUrl; + model()->GetPagesWithCriteria(criteria, callback.Get()); EXPECT_TRUE(task_queue()->HasRunningTask()); PumpLoop(); // Search by kTestUrl2. EXPECT_CALL(callback, Run(ElementsAre(page2))); - model()->GetPagesByURL(kTestUrl2, callback.Get()); + criteria.url = kTestUrl2; + model()->GetPagesWithCriteria(criteria, callback.Get()); PumpLoop(); // Search by random url, which should return no pages. EXPECT_CALL(callback, Run(IsEmpty())); - model()->GetPagesByURL(kOtherUrl, callback.Get()); + criteria.url = kOtherUrl; + model()->GetPagesWithCriteria(criteria, callback.Get()); EXPECT_TRUE(task_queue()->HasRunningTask()); PumpLoop(); } @@ -988,26 +992,28 @@ // Search by kTestUrlWithFragment. base::MockCallback<MultipleOfflinePageItemCallback> callback; EXPECT_CALL(callback, Run(ElementsAre(page1))); - model()->GetPagesByURL(kTestUrlWithFragment, - callback.Get()); + PageCriteria criteria; + criteria.url = kTestUrlWithFragment; + model()->GetPagesWithCriteria(criteria, callback.Get()); EXPECT_TRUE(task_queue()->HasRunningTask()); PumpLoop(); // Search by kTestUrl2. EXPECT_CALL(callback, Run(ElementsAre(page2))); - model()->GetPagesByURL(kTestUrl2, callback.Get()); + criteria.url = kTestUrl2; + model()->GetPagesWithCriteria(criteria, callback.Get()); EXPECT_TRUE(task_queue()->HasRunningTask()); PumpLoop(); // Search by kTestUrl2WithFragment. EXPECT_CALL(callback, Run(ElementsAre(page2))); - model()->GetPagesByURL(kTestUrl2WithFragment, - callback.Get()); + criteria.url = kTestUrl2WithFragment; + model()->GetPagesWithCriteria(criteria, callback.Get()); EXPECT_TRUE(task_queue()->HasRunningTask()); PumpLoop(); } -TEST_F(OfflinePageModelTaskifiedTest, GetPagesByUrl_AllUrls) { +TEST_F(OfflinePageModelTaskifiedTest, GetPagesWithCriteria_AllUrls) { page_generator()->SetUrl(kTestUrl); page_generator()->SetOriginalUrl(kTestUrl2); OfflinePageItem page1 = page_generator()->CreateItem(); @@ -1019,7 +1025,9 @@ base::MockCallback<MultipleOfflinePageItemCallback> callback; EXPECT_CALL(callback, Run(UnorderedElementsAre(page1, page2))); - model()->GetPagesByURL(kTestUrl2, callback.Get()); + PageCriteria criteria; + criteria.url = kTestUrl2; + model()->GetPagesWithCriteria(criteria, callback.Get()); PumpLoop(); } @@ -1051,65 +1059,6 @@ 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, GetPageBySizeAndDigest) { - static const int64_t kFileSize1 = 123LL; - static const int64_t kFileSize2 = 999999LL; - static const char kDigest1[] = "digest 1"; - page_generator()->SetFileSize(kFileSize1); - page_generator()->SetDigest(kDigest1); - OfflinePageItem page1 = page_generator()->CreateItem(); - page_generator()->SetFileSize(kFileSize2); - page_generator()->SetDigest(kDigest1); - OfflinePageItem page2 = page_generator()->CreateItem(); - InsertPageIntoStore(page1); - InsertPageIntoStore(page2); - - base::MockCallback<SingleOfflinePageItemCallback> callback; - EXPECT_CALL(callback, Run(Pointee(Eq(page2)))); - - model()->GetPageBySizeAndDigest(kFileSize2, kDigest1, callback.Get()); - EXPECT_TRUE(task_queue()->HasRunningTask()); - - PumpLoop(); -} - TEST_F(OfflinePageModelTaskifiedTest, DeletePagesByClientIds) { page_generator()->SetArchiveDirectory(temporary_dir_path()); page_generator()->SetNamespace(kTestClientId1.name_space); @@ -1152,63 +1101,6 @@ 1); } -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)
diff --git a/components/offline_pages/core/offline_page_item_utils.cc b/components/offline_pages/core/offline_page_item_utils.cc index 081a43b..34fd50fb 100644 --- a/components/offline_pages/core/offline_page_item_utils.cc +++ b/components/offline_pages/core/offline_page_item_utils.cc
@@ -8,13 +8,13 @@ namespace offline_pages { bool EqualsIgnoringFragment(const GURL& lhs, const GURL& rhs) { - GURL::Replacements remove_params; - remove_params.ClearRef(); + return UrlWithoutFragment(lhs) == UrlWithoutFragment(rhs); +} - GURL lhs_stripped = lhs.ReplaceComponents(remove_params); - GURL rhs_stripped = rhs.ReplaceComponents(remove_params); - - return lhs_stripped == rhs_stripped; +GURL UrlWithoutFragment(const GURL& url) { + GURL::Replacements remove_fragment; + remove_fragment.ClearRef(); + return url.ReplaceComponents(remove_fragment); } } // namespace offline_pages
diff --git a/components/offline_pages/core/offline_page_item_utils.h b/components/offline_pages/core/offline_page_item_utils.h index 51c3c952..b009e87 100644 --- a/components/offline_pages/core/offline_page_item_utils.h +++ b/components/offline_pages/core/offline_page_item_utils.h
@@ -14,5 +14,8 @@ // for checking if an offline item's URL matches another URL. bool EqualsIgnoringFragment(const GURL& lhs, const GURL& rhs); +// Strips any fragment from |url| and returns the result. +GURL UrlWithoutFragment(const GURL& url); + } // namespace offline_pages #endif // COMPONENTS_OFFLINE_PAGES_CORE_OFFLINE_PAGE_ITEM_UTILS_H_
diff --git a/components/offline_pages/core/offline_page_metadata_store_test_util.cc b/components/offline_pages/core/offline_page_metadata_store_test_util.cc index 60649d1..f171e40 100644 --- a/components/offline_pages/core/offline_page_metadata_store_test_util.cc +++ b/components/offline_pages/core/offline_page_metadata_store_test_util.cc
@@ -4,6 +4,8 @@ #include "components/offline_pages/core/offline_page_metadata_store_test_util.h" +#include <utility> + #include "base/bind.h" #include "base/callback_forward.h" #include "base/memory/ptr_util.h" @@ -88,16 +90,18 @@ std::unique_ptr<OfflinePageItem> OfflinePageMetadataStoreTestUtil::GetPageByOfflineId(int64_t offline_id) { + PageCriteria criteria; + criteria.offline_id = offline_id; OfflinePageItem* page = nullptr; - auto task = GetPagesTask::CreateTaskMatchingOfflineId( - store(), + auto task = std::make_unique<GetPagesTask>( + store(), nullptr, criteria, base::BindOnce( - [](OfflinePageItem** out_page, const OfflinePageItem* cb_page) { - if (cb_page) - *out_page = new OfflinePageItem(*cb_page); + [](OfflinePageItem** out_page, + const std::vector<OfflinePageItem>& cb_pages) { + if (!cb_pages.empty()) + *out_page = new OfflinePageItem(cb_pages[0]); }, - &page), - offline_id); + &page)); task->Run(); task_runner_->RunUntilIdle(); return base::WrapUnique<OfflinePageItem>(page);
diff --git a/components/offline_pages/core/offline_page_metadata_store_unittest.cc b/components/offline_pages/core/offline_page_metadata_store_unittest.cc index 3c89827..55ba3dc 100644 --- a/components/offline_pages/core/offline_page_metadata_store_unittest.cc +++ b/components/offline_pages/core/offline_page_metadata_store_unittest.cc
@@ -5,8 +5,10 @@ #include "components/offline_pages/core/offline_page_metadata_store.h" #include <stdint.h> - #include <memory> +#include <set> +#include <string> +#include <utility> #include "base/bind.h" #include "base/files/file_path.h" @@ -21,7 +23,6 @@ #include "components/offline_pages/core/model/offline_page_item_generator.h" #include "components/offline_pages/core/offline_clock.h" #include "components/offline_pages/core/offline_page_item.h" -#include "components/offline_pages/core/offline_page_metadata_store.h" #include "components/offline_pages/core/offline_page_model.h" #include "components/offline_pages/core/offline_page_thumbnail.h" #include "components/offline_pages/core/offline_store_utils.h" @@ -35,6 +36,7 @@ namespace { using InitializationStatus = SqlStoreBase::InitializationStatus; +using OfflinePageSet = std::set<OfflinePageItem>; #define OFFLINE_PAGES_TABLE_V1 "offlinepages_v1" @@ -662,7 +664,7 @@ auto store = std::make_unique<OfflinePageMetadataStore>( base::ThreadTaskRunnerHandle::Get(), TempPath()); OfflinePageItem item = CheckThatStoreHasOneItem(store.get()); - CheckThatPageThumbnailCanBeSaved((OfflinePageMetadataStore*)store.get()); + CheckThatPageThumbnailCanBeSaved(store.get()); CheckThatOfflinePageCanBeSaved(std::move(store)); VerifyMetaVersions(); } @@ -690,7 +692,7 @@ EXPECT_EQ(1U, thumbnails.size()); EXPECT_EQ(TestThumbnailVersion3(), thumbnails.back()); - CheckThatPageThumbnailCanBeSaved((OfflinePageMetadataStore*)store.get()); + CheckThatPageThumbnailCanBeSaved(store.get()); CheckThatOfflinePageCanBeSaved(std::move(store)); VerifyMetaVersions(); } @@ -725,6 +727,13 @@ store, base::BindOnce(&GetOfflinePagesSync), {}); } + OfflinePageSet GetOfflinePageSet(OfflinePageMetadataStore* store) { + std::vector<OfflinePageItem> items = GetOfflinePages(store); + auto page_set = OfflinePageSet(items.begin(), items.end()); + CHECK_EQ(page_set.size(), items.size()); + return page_set; + } + ItemActionStatus AddOfflinePage(OfflinePageMetadataStore* store, const OfflinePageItem& item) { auto result_callback = base::BindLambdaForTesting([&](sql::Database* db) { @@ -833,27 +842,27 @@ // positive results now. store->SetInitializationStatusForTesting( InitializationStatus::kNotInitialized, false); - EXPECT_EQ(0UL, GetOfflinePages(store.get()).size()); + EXPECT_EQ(OfflinePageSet(), GetOfflinePageSet(store.get())); EXPECT_EQ(InitializationStatus::kSuccess, store->initialization_status_for_testing()); store->SetInitializationStatusForTesting(InitializationStatus::kFailure, false); - EXPECT_EQ(0UL, GetOfflinePages(store.get()).size()); + EXPECT_EQ(OfflinePageSet(), GetOfflinePageSet(store.get())); EXPECT_EQ(InitializationStatus::kFailure, store->initialization_status_for_testing()); store->SetInitializationStatusForTesting(InitializationStatus::kSuccess, true); - EXPECT_EQ(0UL, GetOfflinePages(store.get()).size()); + EXPECT_EQ(OfflinePageSet(), GetOfflinePageSet(store.get())); store->SetInitializationStatusForTesting( InitializationStatus::kNotInitialized, true); - EXPECT_EQ(0UL, GetOfflinePages(store.get()).size()); + EXPECT_EQ(OfflinePageSet(), GetOfflinePageSet(store.get())); store->SetInitializationStatusForTesting(InitializationStatus::kFailure, false); - EXPECT_EQ(0UL, GetOfflinePages(store.get()).size()); + EXPECT_EQ(OfflinePageSet(), GetOfflinePageSet(store.get())); } // Loads a store which has an outdated schema. @@ -951,17 +960,15 @@ EXPECT_EQ(ItemActionStatus::SUCCESS, AddOfflinePage(store.get(), offline_page_2)); - // Get all pages from the store. - std::vector<OfflinePageItem> pages = GetOfflinePages(store.get()); - EXPECT_EQ(2U, pages.size()); + // Check all pages are in the store. + EXPECT_EQ(OfflinePageSet({offline_page_1, offline_page_2}), + GetOfflinePageSet(store.get())); // Close and reload the store. store.reset(); store = BuildStore(); - pages = GetOfflinePages(store.get()); - ASSERT_EQ(2U, pages.size()); - EXPECT_EQ(offline_page_2, pages[0]); - EXPECT_EQ(offline_page_2.offline_id, pages[0].offline_id); + EXPECT_EQ(OfflinePageSet({offline_page_1, offline_page_2}), + GetOfflinePageSet(store.get())); } TEST_F(OfflinePageMetadataStoreTest, StoreCloses) {
diff --git a/components/offline_pages/core/offline_page_model.h b/components/offline_pages/core/offline_page_model.h index 8f8b5f5..e9cbc687 100644 --- a/components/offline_pages/core/offline_page_model.h +++ b/components/offline_pages/core/offline_page_model.h
@@ -19,6 +19,7 @@ #include "components/offline_pages/core/offline_page_archiver.h" #include "components/offline_pages/core/offline_page_thumbnail.h" #include "components/offline_pages/core/offline_page_types.h" +#include "components/offline_pages/core/page_criteria.h" #include "url/gurl.h" namespace offline_pages { @@ -188,49 +189,13 @@ virtual void GetPageByOfflineId(int64_t offline_id, SingleOfflinePageItemCallback callback) = 0; - // Returns zero or one offline page associated with a specified |guid|. - // Note: this should only be used for the case that |guid| can uniquely - // identify the page regardless its namespace. - virtual void GetPageByGuid(const std::string& guid, - SingleOfflinePageItemCallback callback) = 0; - - // Retrieves all pages associated with any of |client_ids|. - virtual void GetPagesByClientIds( - const std::vector<ClientId>& client_ids, - MultipleOfflinePageItemCallback callback) = 0; - - // Returns via callback all offline pages related to |url|. The provided URL - // is matched both against the original and the actual URL fields (they - // sometimes differ because of possible redirects). The returned list is + // Returns all offline pages that match |criteria|. The returned list is // sorted by descending creation date so that the most recent offline page // will be the first element of the list. - virtual void GetPagesByURL(const GURL& url, - MultipleOfflinePageItemCallback callback) = 0; - - // Returns the offline pages that belong in |name_space|. - virtual void GetPagesByNamespace( - const std::string& name_space, + virtual void GetPagesWithCriteria( + const PageCriteria& criteria, MultipleOfflinePageItemCallback callback) = 0; - // Returns the offline pages that are removed when cache is reset. - virtual void GetPagesRemovedOnCacheReset( - MultipleOfflinePageItemCallback callback) = 0; - - // Returns the offline pages that are visible in download manager UI. - virtual void GetPagesSupportedByDownloads( - MultipleOfflinePageItemCallback callback) = 0; - - // Retrieves all pages associated with the |request_origin|. - virtual void GetPagesByRequestOrigin( - const std::string& request_origin, - MultipleOfflinePageItemCallback callback) = 0; - - // Returns zero or one offline pages associated with a specified |digest|. - virtual void GetPageBySizeAndDigest( - int64_t file_size, - const std::string& digest, - SingleOfflinePageItemCallback callback) = 0; - // Gets all offline ids where the offline page has the matching client id. virtual void GetOfflineIdsForClientId(const ClientId& client_id, MultipleOfflineIdCallback callback) = 0;
diff --git a/components/offline_pages/core/page_criteria.cc b/components/offline_pages/core/page_criteria.cc new file mode 100644 index 0000000..3e23981 --- /dev/null +++ b/components/offline_pages/core/page_criteria.cc
@@ -0,0 +1,122 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/offline_pages/core/page_criteria.h" + +#include "base/strings/string_number_conversions.h" +#include "components/offline_pages/core/client_policy_controller.h" +#include "components/offline_pages/core/offline_page_client_policy.h" +#include "components/offline_pages/core/offline_page_item.h" +#include "components/offline_pages/core/offline_page_item_utils.h" + +namespace offline_pages { + +PageCriteria::PageCriteria() = default; +PageCriteria::~PageCriteria() = default; +PageCriteria::PageCriteria(const PageCriteria&) = default; +PageCriteria::PageCriteria(PageCriteria&&) = default; + +bool MeetsCriteria(const ClientPolicyController& policy_controller, + const PageCriteria& criteria, + const ClientId& client_id) { + if (criteria.exclude_tab_bound_pages) { + const OfflinePageClientPolicy& policy = + policy_controller.GetPolicy(client_id.name_space); + if (policy.feature_policy.is_restricted_to_tab_from_client_id) + return false; + } + if (criteria.pages_for_tab_id && + policy_controller.IsRestrictedToTabFromClientId(client_id.name_space)) { + std::string tab_id_str = + base::NumberToString(criteria.pages_for_tab_id.value()); + if (client_id.id != tab_id_str) + return false; + } + if (!criteria.client_ids.empty()) { + if (std::find(criteria.client_ids.begin(), criteria.client_ids.end(), + client_id) == criteria.client_ids.end()) { + return false; + } + } + if (!criteria.client_namespaces.empty()) { + if (std::find(criteria.client_namespaces.begin(), + criteria.client_namespaces.end(), + client_id.name_space) == criteria.client_namespaces.end()) { + return false; + } + } + if (criteria.supported_by_downloads && + !policy_controller.IsSupportedByDownload(client_id.name_space)) { + return false; + } + if (criteria.removed_on_cache_reset && + !policy_controller.IsRemovedOnCacheReset(client_id.name_space)) { + return false; + } + if (!criteria.guid.empty() && client_id.id != criteria.guid) + return false; + + return true; +} + +bool MeetsCriteria(const ClientPolicyController& policy_controller, + const PageCriteria& criteria, + const OfflinePageItem& item) { + if (!MeetsCriteria(policy_controller, criteria, item.client_id)) + return false; + + if (criteria.file_size && item.file_size != criteria.file_size.value()) + return false; + if (!criteria.digest.empty() && item.digest != criteria.digest) + return false; + + if (!criteria.request_origin.empty() && + item.request_origin != criteria.request_origin) + return false; + + if (!criteria.url.is_empty() && + !EqualsIgnoringFragment(criteria.url, item.url) && + (item.original_url_if_different.is_empty() || + !EqualsIgnoringFragment(criteria.url, item.original_url_if_different))) { + return false; + } + + if (criteria.offline_id && criteria.offline_id.value() != item.offline_id) + return false; + + return true; +} + +std::vector<std::string> PotentiallyMatchingNamespaces( + const ClientPolicyController& policy_controller, + const PageCriteria& criteria) { + std::vector<std::string> matching_namespaces; + if (criteria.supported_by_downloads || criteria.removed_on_cache_reset) { + std::vector<std::string> allowed_namespaces; + if (criteria.client_namespaces.empty()) { + allowed_namespaces = policy_controller.GetAllNamespaces(); + } else { + allowed_namespaces = criteria.client_namespaces; + } + std::vector<std::string> filtered; + for (const std::string& name_space : allowed_namespaces) { + if (criteria.supported_by_downloads && + !policy_controller.IsSupportedByDownload(name_space)) { + continue; + } + if (criteria.removed_on_cache_reset && + !policy_controller.IsRemovedOnCacheReset(name_space)) { + continue; + } + matching_namespaces.push_back(name_space); + } + } else if (!criteria.client_namespaces.empty()) { + matching_namespaces = criteria.client_namespaces; + } + // no filter otherwise. + + return matching_namespaces; +} + +} // namespace offline_pages
diff --git a/components/offline_pages/core/page_criteria.h b/components/offline_pages/core/page_criteria.h new file mode 100644 index 0000000..66910f8 --- /dev/null +++ b/components/offline_pages/core/page_criteria.h
@@ -0,0 +1,81 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_OFFLINE_PAGES_CORE_PAGE_CRITERIA_H_ +#define COMPONENTS_OFFLINE_PAGES_CORE_PAGE_CRITERIA_H_ + +#include <cstdint> + +#include <string> +#include <vector> + +#include "base/optional.h" +#include "components/offline_pages/core/client_id.h" +#include "url/gurl.h" + +namespace offline_pages { +class ClientPolicyController; +struct OfflinePageItem; + +// Criteria for matching an offline page. The default |PageCriteria| matches +// all pages. +struct PageCriteria { + PageCriteria(); + ~PageCriteria(); + PageCriteria(const PageCriteria&); + PageCriteria(PageCriteria&&); + + // If non-empty, the page must match this URL. The provided URL + // is matched both against the original and the actual URL fields (they + // sometimes differ because of possible redirects). + GURL url; + // Whether to exclude pages that may only be opened in a specific tab. + bool exclude_tab_bound_pages = false; + // If specified, accepts pages that can be displayed in the specified tab. + // That is, tab-bound pages are filtered out unless the tab ID matches this + // field and non-tab-bound pages are always included. + base::Optional<int> pages_for_tab_id; + // Whether to restrict pages to those in namespaces supported by the + // downloads UI. + bool supported_by_downloads = false; + // Whether to restrict pages to those removed on cache reset. + bool removed_on_cache_reset = false; + // If set, the page's file_size must match. + base::Optional<int64_t> file_size; + // If non-empty, the page's digest must match. + std::string digest; + // If non-empty, the page's namespace must match. + std::vector<std::string> client_namespaces; + // If non-empty, the page's client_id must match one of these. + std::vector<ClientId> client_ids; + // If non-empty, the page's client_id.id must match this. + std::string guid; + // If > 0, returns at most this many pages. + size_t maximum_matches = 0; + // If non-empty, the page's request_origin must match. + std::string request_origin; + // If set, the page's offline_id must match. + base::Optional<int64_t> offline_id; +}; + +// Returns true if an offline page with |client_id| could potentially match +// |criteria|. +bool MeetsCriteria(const ClientPolicyController& policy_controller, + const PageCriteria& criteria, + const ClientId& client_id); + +// Returns whether |item| matches |criteria|. +bool MeetsCriteria(const ClientPolicyController& policy_controller, + const PageCriteria& criteria, + const OfflinePageItem& item); + +// Returns the list of offline page namespaces that could potentially match +// Criteria. Returns an empty list if any namespace could match. +std::vector<std::string> PotentiallyMatchingNamespaces( + const ClientPolicyController& policy_controller, + const PageCriteria& criteria); + +} // namespace offline_pages + +#endif // COMPONENTS_OFFLINE_PAGES_CORE_PAGE_CRITERIA_H_
diff --git a/components/offline_pages/core/page_criteria_unittest.cc b/components/offline_pages/core/page_criteria_unittest.cc new file mode 100644 index 0000000..05dd7db --- /dev/null +++ b/components/offline_pages/core/page_criteria_unittest.cc
@@ -0,0 +1,289 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/offline_pages/core/page_criteria.h" + +#include "base/bind.h" +#include "components/offline_pages/core/client_namespace_constants.h" +#include "components/offline_pages/core/client_policy_controller.h" +#include "components/offline_pages/core/offline_page_item.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace offline_pages { + +namespace { + +GURL TestURL() { + return GURL("http://someurl.com"); +} +GURL OtherURL() { + return GURL("http://other.com"); +} +GURL TestURLWithFragment() { + return GURL("http://someurl.com#fragment"); +} + +class PageCriteriaTest : public testing::Test { + protected: + ClientPolicyController policy_controller_; +}; + +TEST_F(PageCriteriaTest, MeetsCriteria_Url) { + PageCriteria criteria; + criteria.url = TestURL(); + + OfflinePageItem item; + + item.url = TestURLWithFragment(); + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.url = TestURL(); + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.url = OtherURL(); + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); +} + +TEST_F(PageCriteriaTest, MeetsCriteria_UrlWithFragment) { + PageCriteria criteria; + criteria.url = TestURLWithFragment(); + + OfflinePageItem item; + + item.url = TestURLWithFragment(); + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.url = TestURL(); + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.url = OtherURL(); + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); +} + +TEST_F(PageCriteriaTest, MeetsCriteria_ExcludeTabBoundPages) { + PageCriteria criteria; + criteria.exclude_tab_bound_pages = true; + + OfflinePageItem item; + item.client_id.name_space = kLastNNamespace; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id.name_space = ""; + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id.name_space = kDownloadNamespace; + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); +} + +TEST_F(PageCriteriaTest, MeetsCriteria_PagesForTabId) { + PageCriteria criteria; + criteria.pages_for_tab_id = 0; + + OfflinePageItem item; + item.client_id.id = "0"; + item.client_id.name_space = kLastNNamespace; + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + // Namespace not restricted to tab. + item.client_id.id = "1"; + item.client_id.name_space = kDownloadNamespace; + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + // Different tab id. + item.client_id.id = "1"; + item.client_id.name_space = kLastNNamespace; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); +} + +TEST_F(PageCriteriaTest, MeetsCriteria_SupportedByDownloads) { + PageCriteria criteria; + criteria.supported_by_downloads = true; + + OfflinePageItem item; + item.client_id.name_space = kDownloadNamespace; + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item.client_id)); + + item.client_id.name_space = kLastNNamespace; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item.client_id)); +} + +TEST_F(PageCriteriaTest, MeetsCriteria_RemovedOnCacheReset) { + PageCriteria criteria; + criteria.removed_on_cache_reset = true; + + OfflinePageItem item; + item.client_id.name_space = kLastNNamespace; + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item.client_id)); + + item.client_id.name_space = kDownloadNamespace; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item.client_id)); +} + +TEST_F(PageCriteriaTest, MeetsCriteria_FileSize) { + PageCriteria criteria; + criteria.file_size = 123; + + OfflinePageItem item; + item.file_size = 123; + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.file_size = 124; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + + item.file_size = 0; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); +} + +TEST_F(PageCriteriaTest, MeetsCriteria_Digest) { + PageCriteria criteria; + criteria.digest = "abc"; + + OfflinePageItem item; + item.digest = "abc"; + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.digest = ""; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + + item.digest = "def"; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); +} + +TEST_F(PageCriteriaTest, MeetsCriteria_Namespaces) { + PageCriteria criteria; + criteria.client_namespaces = {"namespace1"}; + + OfflinePageItem item; + item.client_id.name_space = "namespace1"; + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item.client_id)); + + item.client_id.name_space = "namespace2"; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item.client_id)); + + item.client_id.name_space = ""; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item.client_id)); +} + +TEST_F(PageCriteriaTest, MeetsCriteria_MultipleNamespaces) { + PageCriteria criteria; + criteria.client_namespaces = {"namespace1", "foobar1"}; + + OfflinePageItem item; + item.client_id.name_space = "namespace1"; + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id.name_space = "foobar1"; + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id.name_space = "namespace"; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id.name_space = "foobar"; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id.name_space = ""; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); +} + +TEST_F(PageCriteriaTest, MeetsCriteria_ClientId) { + PageCriteria criteria; + criteria.client_ids = {ClientId("namespace1", "id")}; + + OfflinePageItem item; + item.client_id = ClientId("namespace1", "id"); + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id = ClientId("namespace2", "id"); + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id = ClientId("namespace1", "id2"); + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id = ClientId(); + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); +} + +TEST_F(PageCriteriaTest, MeetsCriteria_MultipleClientId) { + PageCriteria criteria; + criteria.client_ids = {ClientId("namespace1", "id"), + ClientId("namespace2", "id"), + ClientId("namespace3", "id3")}; + + OfflinePageItem item; + item.client_id = ClientId("namespace1", "id"); + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id = ClientId("namespace2", "id"); + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id = ClientId("namespace3", "id3"); + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id = ClientId("namespace", "i"); + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id = ClientId("namespace", ""); + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id = ClientId("name", "id"); + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id = ClientId("namespace", "foo"); + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); +} + +TEST_F(PageCriteriaTest, MeetsCriteria_Guid) { + PageCriteria criteria; + criteria.guid = "abc"; + + OfflinePageItem item; + item.client_id = ClientId("namespace", "abc"); + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id = ClientId("namespace2", "abc"); + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id = ClientId("namespace", "abcd"); + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + + item.client_id = ClientId(); + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); +} + +TEST_F(PageCriteriaTest, MeetsCriteria_RequestOrigin) { + PageCriteria criteria; + criteria.request_origin = "abc"; + + OfflinePageItem item; + item.request_origin = "abc"; + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.request_origin = "abcd"; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); + + item.request_origin = ""; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); +} + +TEST_F(PageCriteriaTest, MeetsCriteria_OfflineId) { + PageCriteria criteria; + criteria.offline_id = 5; + + OfflinePageItem item; + item.offline_id = 5; + EXPECT_TRUE(MeetsCriteria(policy_controller_, criteria, item)); + + item.offline_id = 4; + EXPECT_FALSE(MeetsCriteria(policy_controller_, criteria, item)); +} + +} // namespace +} // namespace offline_pages
diff --git a/components/offline_pages/core/stub_offline_page_model.cc b/components/offline_pages/core/stub_offline_page_model.cc index 74b8650..4ad9bc7 100644 --- a/components/offline_pages/core/stub_offline_page_model.cc +++ b/components/offline_pages/core/stub_offline_page_model.cc
@@ -36,9 +36,6 @@ const std::vector<ClientId>& client_ids, const std::string& origin, DeletePageCallback callback) {} -void StubOfflinePageModel::GetPagesByClientIds( - const std::vector<ClientId>& client_ids, - MultipleOfflinePageItemCallback callback) {} void StubOfflinePageModel::DeleteCachedPagesByURLPredicate( const UrlPredicate& predicate, DeletePageCallback callback) {} @@ -50,25 +47,8 @@ void StubOfflinePageModel::GetPageByOfflineId( int64_t offline_id, SingleOfflinePageItemCallback callback) {} -void StubOfflinePageModel::GetPageByGuid( - const std::string& guid, - SingleOfflinePageItemCallback callback) {} -void StubOfflinePageModel::GetPagesByURL( - const GURL& url, - MultipleOfflinePageItemCallback callback) {} -void StubOfflinePageModel::GetPagesByRequestOrigin( - const std::string& origin, - MultipleOfflinePageItemCallback callback) {} -void StubOfflinePageModel::GetPageBySizeAndDigest( - int64_t file_size, - const std::string& digest, - SingleOfflinePageItemCallback callback) {} -void StubOfflinePageModel::GetPagesRemovedOnCacheReset( - MultipleOfflinePageItemCallback callback) {} -void StubOfflinePageModel::GetPagesByNamespace( - const std::string& name_space, - MultipleOfflinePageItemCallback callback) {} -void StubOfflinePageModel::GetPagesSupportedByDownloads( +void StubOfflinePageModel::GetPagesWithCriteria( + const PageCriteria& criteria, MultipleOfflinePageItemCallback callback) {} void StubOfflinePageModel::StoreThumbnail(const OfflinePageThumbnail& thumb) {} void StubOfflinePageModel::GetThumbnailByOfflineId(
diff --git a/components/offline_pages/core/stub_offline_page_model.h b/components/offline_pages/core/stub_offline_page_model.h index 90d5636..8547421 100644 --- a/components/offline_pages/core/stub_offline_page_model.h +++ b/components/offline_pages/core/stub_offline_page_model.h
@@ -40,8 +40,6 @@ void DeletePagesByClientIdsAndOrigin(const std::vector<ClientId>& client_ids, const std::string& origin, DeletePageCallback callback) override; - void GetPagesByClientIds(const std::vector<ClientId>& client_ids, - MultipleOfflinePageItemCallback callback) override; void DeleteCachedPagesByURLPredicate(const UrlPredicate& predicate, DeletePageCallback callback) override; void GetAllPages(MultipleOfflinePageItemCallback callback) override; @@ -49,22 +47,8 @@ MultipleOfflineIdCallback callback) override; void GetPageByOfflineId(int64_t offline_id, SingleOfflinePageItemCallback callback) override; - void GetPageByGuid(const std::string& guid, - SingleOfflinePageItemCallback callback) override; - void GetPagesByURL(const GURL& url, - MultipleOfflinePageItemCallback callback) override; - void GetPagesByRequestOrigin( - const std::string& origin, - MultipleOfflinePageItemCallback callback) override; - void GetPageBySizeAndDigest(int64_t file_size, - const std::string& digest, - SingleOfflinePageItemCallback callback) override; - void GetPagesRemovedOnCacheReset( - MultipleOfflinePageItemCallback callback) override; - void GetPagesByNamespace(const std::string& name_space, - MultipleOfflinePageItemCallback callback) override; - void GetPagesSupportedByDownloads( - MultipleOfflinePageItemCallback callback) override; + void GetPagesWithCriteria(const PageCriteria& criteria, + MultipleOfflinePageItemCallback callback) override; void StoreThumbnail(const OfflinePageThumbnail& thumb) override; void GetThumbnailByOfflineId(int64_t offline_id, GetThumbnailCallback callback) override;
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn index 00682b2..d44043fb 100644 --- a/components/omnibox/browser/BUILD.gn +++ b/components/omnibox/browser/BUILD.gn
@@ -22,6 +22,7 @@ icon_directory = "vector_icons" icons = [ + "answer_calculator.icon", "answer_currency.icon", "answer_default.icon", "answer_dictionary.icon",
diff --git a/components/omnibox/browser/search_suggestion_parser.cc b/components/omnibox/browser/search_suggestion_parser.cc index 4703493c..9c2831cd 100644 --- a/components/omnibox/browser/search_suggestion_parser.cc +++ b/components/omnibox/browser/search_suggestion_parser.cc
@@ -492,13 +492,15 @@ base::string16 annotation; base::string16 match_contents = suggestion; if (match_type == AutocompleteMatchType::CALCULATOR) { - if (!suggestion.compare(0, 2, base::UTF8ToUTF16("= "))) { + const bool has_equals_prefix = + !suggestion.compare(0, 2, base::UTF8ToUTF16("= ")); + if (has_equals_prefix) { // Calculator results include a "= " prefix but we don't want to // include this in the search terms. suggestion.erase(0, 2); } if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_DESKTOP) { - annotation = match_contents; + annotation = has_equals_prefix ? suggestion : match_contents; match_contents = query; } }
diff --git a/components/omnibox/browser/vector_icons/answer_calculator.icon b/components/omnibox/browser/vector_icons/answer_calculator.icon new file mode 100644 index 0000000..81d404f --- /dev/null +++ b/components/omnibox/browser/vector_icons/answer_calculator.icon
@@ -0,0 +1,24 @@ +// Copyright 2019 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. + +// Source: calculator_16px.svg -> SVGOMG -> Skiafy +// Appearance Description: A large equals sign (=). + +// This answer_calculator.icon is not to be confused with calculator.icon. +// answer_calculator.icon is considered by UX like other AiS icons and is +// intended to be encircled like other answer_*.icon vectors. + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 3, 5, +R_H_LINE_TO, 10, +R_V_LINE_TO, 2, +H_LINE_TO, 3, +V_LINE_TO, 5, +CLOSE, +R_MOVE_TO, 0, 4, +R_H_LINE_TO, 10, +R_V_LINE_TO, 2, +H_LINE_TO, 3, +V_LINE_TO, 9, +CLOSE
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc index 973448f..201aec82 100644 --- a/components/password_manager/core/browser/password_form_manager_unittest.cc +++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -1029,10 +1029,12 @@ class PasswordFormManagerFillOnAccountSelectTest : public PasswordFormManagerTest { public: - PasswordFormManagerFillOnAccountSelectTest() { + void SetUp() override { + PasswordFormManagerTest::SetUp(); scoped_feature_list_.InitAndEnableFeature(features::kFillOnAccountSelect); } + private: base::test::ScopedFeatureList scoped_feature_list_; };
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto index 3c4855e..c9d29c2d 100644 --- a/components/policy/proto/device_management_backend.proto +++ b/components/policy/proto/device_management_backend.proto
@@ -563,6 +563,12 @@ // belongs to. This is domain metadata included in a device policy response, // but it is not an explicit device policy. optional CustomerLogo customer_logo = 31; + + // b/129771193 + // This setting is from SingleSignOnSettingsProto#change_password_uri + // http://google3/ccc/hosted/policies/services/common/sso_settings.proto?l=48&rcl=241246111 + // This field is currently only set for User Policy response. + optional string change_password_uri = 32; } message PolicyFetchResponse {
diff --git a/components/signin/core/browser/profile_oauth2_token_service.h b/components/signin/core/browser/profile_oauth2_token_service.h index c985a24..55bd353 100644 --- a/components/signin/core/browser/profile_oauth2_token_service.h +++ b/components/signin/core/browser/profile_oauth2_token_service.h
@@ -40,7 +40,8 @@ // Note: requests should be started from the UI thread. To start a // request from other thread, please use OAuth2TokenServiceRequest. class ProfileOAuth2TokenService : public OAuth2TokenService, - public OAuth2TokenService::Observer { + public OAuth2TokenService::Observer, + public KeyedService { public: ProfileOAuth2TokenService( PrefService* user_prefs, @@ -50,7 +51,8 @@ // Registers per-profile prefs. static void RegisterProfilePrefs(PrefRegistrySimple* registry); - void Shutdown(); + // KeyedService implementation. + void Shutdown() override; // Loads credentials from a backing persistent store to make them available // after service is used between profile restarts.
diff --git a/components/spellcheck/common/spellcheck_common.cc b/components/spellcheck/common/spellcheck_common.cc index cf8eb4f..94d206ca 100644 --- a/components/spellcheck/common/spellcheck_common.cc +++ b/components/spellcheck/common/spellcheck_common.cc
@@ -55,6 +55,7 @@ {"hi", "hi-IN"}, {"hr", "hr-HR"}, {"hu", "hu-HU"}, + {"hy", "hy"}, {"id", "id-ID"}, {"it", "it-IT"}, {"ko", "ko"}, @@ -126,6 +127,9 @@ // Feb 2019: Initial check-in of Welsh. {"cy-GB", "-1-0"}, + + // April 2019: Initial check-in of Armenian. + {"hy", "-1-0"}, }; // Generate the bdict file name using default version string or special
diff --git a/components/spellcheck/renderer/spellcheck_unittest.cc b/components/spellcheck/renderer/spellcheck_unittest.cc index 0d84e85..010a6f7 100644 --- a/components/spellcheck/renderer/spellcheck_unittest.cc +++ b/components/spellcheck/renderer/spellcheck_unittest.cc
@@ -510,6 +510,11 @@ L"tak, aby byly v\x0161\x0065obecn\x011B p\x0159\x00EDstupn\x00E9 " L"a u\x017Eite\x010Dn\x00E9." }, { + // Welsh + "cy-GB", + L"Y genhadaeth yw trefnu gwybodaeth y byd a'i gwneud yn hygyrch ac yn " + L"ddefnyddiol i bawb." + }, { // Danish "da-DK", L"Googles " @@ -625,6 +630,18 @@ // L"univerzalno " - to be added. L"pristupa\x010Dnima i korisnima." }, { + // Armenian + "hy", + L"Google- \x056B \x0561\x057C\x0561\x0584\x0565\x056C\x0578\x0582\x0569" + L"\x0575\x0578\x0582\x0576\x0576 \x0567 \x0570\x0561\x0574\x0561\x0577" + L"\x056D\x0561\x0580\x0570\x0561\x0575\x056B\x0576 \x057F\x0565\x0572" + L"\x0565\x056F\x0561\x057F\x057E\x0578\x0582\x0569\x0575\x0578\x0582" + L"\x0576\x0568 \x056F\x0561\x0566\x0574\x0561\x056F\x0565\x0580\x057A" + L"\x0565\x056C \x0565\x0582 \x0564\x0561\x0580\x0571\x0576\x0565\x056C " + L"\x0561\x0575\x0576 \x0570\x0561\x0574\x0568\x0576\x0564\x0570\x0561" + L"\x0576\x0578\x0582\x0580 \x0570\x0561\x057D\x0561\x0576\x0565\x056C" + L"\x056B \x0565\x0582 \x0585\x0563\x057F\x0561\x056F\x0561\x0580:" + }, { // Indonesian "id-ID", L"Misi Google adalah untuk mengelola informasi dunia dan membuatnya "
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index 3f08b02..78a0158 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -563,6 +563,8 @@ "user_events/fake_user_event_service.h", "user_events/no_op_user_event_service.cc", "user_events/no_op_user_event_service.h", + "user_events/user_event_model_type_controller.cc", + "user_events/user_event_model_type_controller.h", "user_events/user_event_service.h", "user_events/user_event_service_impl.cc", "user_events/user_event_service_impl.h",
diff --git a/components/sync/engine/non_blocking_sync_common.cc b/components/sync/engine/non_blocking_sync_common.cc index 95cd9dd0..35dda50 100644 --- a/components/sync/engine/non_blocking_sync_common.cc +++ b/components/sync/engine/non_blocking_sync_common.cc
@@ -10,8 +10,6 @@ CommitRequestData::CommitRequestData() {} -CommitRequestData::CommitRequestData(const CommitRequestData& other) = default; - CommitRequestData::~CommitRequestData() {} CommitResponseData::CommitResponseData() {}
diff --git a/components/sync/engine/non_blocking_sync_common.h b/components/sync/engine/non_blocking_sync_common.h index 26b7c42..60b96a5 100644 --- a/components/sync/engine/non_blocking_sync_common.h +++ b/components/sync/engine/non_blocking_sync_common.h
@@ -7,9 +7,11 @@ #include <stdint.h> +#include <memory> #include <string> #include <vector> +#include "base/macros.h" #include "base/time/time.h" #include "components/sync/model/entity_data.h" #include "components/sync/protocol/sync.pb.h" @@ -20,7 +22,6 @@ struct CommitRequestData { CommitRequestData(); - CommitRequestData(const CommitRequestData& other); ~CommitRequestData(); // Fields sent to the sync server. @@ -36,6 +37,9 @@ int64_t sequence_number = 0; std::string specifics_hash; base::Time unsynced_time; + + private: + DISALLOW_COPY_AND_ASSIGN(CommitRequestData); }; struct CommitResponseData { @@ -66,7 +70,7 @@ std::string encryption_key_name; }; -using CommitRequestDataList = std::vector<CommitRequestData>; +using CommitRequestDataList = std::vector<std::unique_ptr<CommitRequestData>>; using CommitResponseDataList = std::vector<CommitResponseData>; using UpdateResponseDataList = std::vector<UpdateResponseData>;
diff --git a/components/sync/engine_impl/model_type_worker.cc b/components/sync/engine_impl/model_type_worker.cc index 0419b780..ee668b8 100644 --- a/components/sync/engine_impl/model_type_worker.cc +++ b/components/sync/engine_impl/model_type_worker.cc
@@ -490,8 +490,8 @@ DCHECK(response.size() <= max_entries); return std::make_unique<NonBlockingTypeCommitContribution>( - GetModelType(), model_type_state_.type_context(), response, this, - cryptographer_.get(), passphrase_type_, debug_info_emitter_, + GetModelType(), model_type_state_.type_context(), std::move(response), + this, cryptographer_.get(), passphrase_type_, debug_info_emitter_, CommitOnlyTypes().Has(GetModelType())); } @@ -714,7 +714,7 @@ void GetLocalChangesRequest::SetResponse( CommitRequestDataList&& local_changes) { - response_ = local_changes; + response_ = std::move(local_changes); response_accepted_.Signal(); }
diff --git a/components/sync/engine_impl/model_type_worker_unittest.cc b/components/sync/engine_impl/model_type_worker_unittest.cc index b74578e0..7774c10 100644 --- a/components/sync/engine_impl/model_type_worker_unittest.cc +++ b/components/sync/engine_impl/model_type_worker_unittest.cc
@@ -1650,15 +1650,15 @@ start_event_.Wait(); { CommitRequestDataList response; - response.emplace_back(); - response.back().specifics_hash = kHash1; + response.push_back(std::make_unique<CommitRequestData>()); + response.back()->specifics_hash = kHash1; request->SetResponse(std::move(response)); } done_event_.Wait(); EXPECT_FALSE(request->WasCancelled()); CommitRequestDataList response = request->ExtractResponse(); EXPECT_EQ(1U, response.size()); - EXPECT_EQ(kHash1, response[0].specifics_hash); + EXPECT_EQ(kHash1, response[0]->specifics_hash); } // Analogous test fixture but uses PASSWORDS instead of PREFERENCES, in order
diff --git a/components/sync/engine_impl/net/server_connection_manager.cc b/components/sync/engine_impl/net/server_connection_manager.cc index c056d25..25a0ff88 100644 --- a/components/sync/engine_impl/net/server_connection_manager.cc +++ b/components/sync/engine_impl/net/server_connection_manager.cc
@@ -7,7 +7,6 @@ #include <errno.h> #include <ostream> -#include <vector> #include "base/metrics/histogram.h" #include "build/build_config.h" @@ -22,25 +21,19 @@ namespace syncer { -using std::ostream; using std::string; -using std::vector; -static const char kSyncServerSyncPath[] = "/command/"; +namespace { -HttpResponse::HttpResponse() - : http_status_code(kUnsetResponseCode), - content_length(kUnsetContentLength), - payload_length(kUnsetPayloadLength), - server_status(NONE) {} +const char kSyncServerSyncPath[] = "/command/"; -#define ENUM_CASE(x) \ - case x: \ - return #x; \ +#define ENUM_CASE(x) \ + case HttpResponse::x: \ + return #x; \ break -const char* HttpResponse::GetServerConnectionCodeString( - ServerConnectionCode code) { +const char* GetServerConnectionCodeString( + HttpResponse::ServerConnectionCode code) { switch (code) { ENUM_CASE(NONE); ENUM_CASE(CONNECTION_UNAVAILABLE); @@ -55,6 +48,15 @@ #undef ENUM_CASE +} // namespace + +HttpResponse::HttpResponse() + : net_error_code(-1), + http_status_code(-1), + content_length(-1), + payload_length(-1), + server_status(NONE) {} + ServerConnectionManager::Connection::Connection(ServerConnectionManager* scm) : scm_(scm) {} @@ -264,8 +266,7 @@ std::ostream& operator<<(std::ostream& s, const struct HttpResponse& hr) { s << " Response Code (bogus on error): " << hr.http_status_code; s << " Content-Length (bogus on error): " << hr.content_length; - s << " Server Status: " - << HttpResponse::GetServerConnectionCodeString(hr.server_status); + s << " Server Status: " << GetServerConnectionCodeString(hr.server_status); return s; }
diff --git a/components/sync/engine_impl/net/server_connection_manager.h b/components/sync/engine_impl/net/server_connection_manager.h index b56a72c..380941c 100644 --- a/components/sync/engine_impl/net/server_connection_manager.h +++ b/components/sync/engine_impl/net/server_connection_manager.h
@@ -11,23 +11,15 @@ #include <memory> #include <string> -#include "base/atomicops.h" #include "base/macros.h" #include "base/observer_list.h" #include "base/sequence_checker.h" -#include "base/strings/string_util.h" -#include "base/synchronization/lock.h" -#include "components/sync/base/cancelation_observer.h" #include "components/sync/syncable/syncable_id.h" namespace syncer { class CancelationSignal; -static const int32_t kUnsetResponseCode = -1; -static const int32_t kUnsetContentLength = -1; -static const int32_t kUnsetPayloadLength = -1; - // HttpResponse gathers the relevant output properties of an HTTP request. // Depending on the value of the server_status code, response_code, and // content_length may not be valid. @@ -70,8 +62,6 @@ ServerConnectionCode server_status; HttpResponse(); - - static const char* GetServerConnectionCodeString(ServerConnectionCode code); }; struct ServerConnectionEvent {
diff --git a/components/sync/engine_impl/net/sync_server_connection_manager.h b/components/sync/engine_impl/net/sync_server_connection_manager.h index 07cbdce..9354ff8 100644 --- a/components/sync/engine_impl/net/sync_server_connection_manager.h +++ b/components/sync/engine_impl/net/sync_server_connection_manager.h
@@ -11,6 +11,7 @@ #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" #include "base/macros.h" +#include "components/sync/base/cancelation_observer.h" #include "components/sync/engine_impl/net/server_connection_manager.h" namespace syncer {
diff --git a/components/sync/engine_impl/non_blocking_type_commit_contribution.cc b/components/sync/engine_impl/non_blocking_type_commit_contribution.cc index 731bb186..b7838704 100644 --- a/components/sync/engine_impl/non_blocking_type_commit_contribution.cc +++ b/components/sync/engine_impl/non_blocking_type_commit_contribution.cc
@@ -20,7 +20,7 @@ NonBlockingTypeCommitContribution::NonBlockingTypeCommitContribution( ModelType type, const sync_pb::DataTypeContext& context, - const CommitRequestDataList& commit_requests, + CommitRequestDataList commit_requests, ModelTypeWorker* worker, Cryptographer* cryptographer, PassphraseType passphrase_type, @@ -31,7 +31,7 @@ cryptographer_(cryptographer), passphrase_type_(passphrase_type), context_(context), - commit_requests_(commit_requests), + commit_requests_(std::move(commit_requests)), cleaned_up_(false), debug_info_emitter_(debug_info_emitter), only_commit_specifics_(only_commit_specifics) {} @@ -52,13 +52,13 @@ for (const auto& commit_request : commit_requests_) { sync_pb::SyncEntity* sync_entity = commit_message->add_entries(); if (only_commit_specifics_) { - DCHECK(!commit_request.entity->is_deleted()); + DCHECK(!commit_request->entity->is_deleted()); DCHECK(!cryptographer_); // Only send specifics to server for commit-only types. sync_entity->mutable_specifics()->CopyFrom( - commit_request.entity->specifics); + commit_request->entity->specifics); } else { - PopulateCommitProto(commit_request, sync_entity); + PopulateCommitProto(*commit_request, sync_entity); AdjustCommitProto(sync_entity); } @@ -68,9 +68,9 @@ !sync_entity->specifics().password().has_client_only_encrypted_data()); // Update the relevant counter based on the type of the commit request. - if (commit_request.entity->is_deleted()) { + if (commit_request->entity->is_deleted()) { counters->num_deletion_commits_attempted++; - } else if (commit_request.base_version <= 0) { + } else if (commit_request->base_version <= 0) { counters->num_creation_commits_attempted++; } else { counters->num_update_commits_attempted++; @@ -110,7 +110,7 @@ case sync_pb::CommitResponse::SUCCESS: { ++successes; CommitResponseData response_data; - const CommitRequestData& commit_request = commit_requests_[i]; + const CommitRequestData& commit_request = *commit_requests_[i]; response_data.id = entry_response.id_string(); if (response_data.id != commit_request.entity->id) { // Server has changed the sync id in the request. Write back the
diff --git a/components/sync/engine_impl/non_blocking_type_commit_contribution.h b/components/sync/engine_impl/non_blocking_type_commit_contribution.h index 74ea40c..7e9ec461 100644 --- a/components/sync/engine_impl/non_blocking_type_commit_contribution.h +++ b/components/sync/engine_impl/non_blocking_type_commit_contribution.h
@@ -31,7 +31,7 @@ NonBlockingTypeCommitContribution( ModelType type, const sync_pb::DataTypeContext& context, - const CommitRequestDataList& commit_requests, + CommitRequestDataList commit_requests, ModelTypeWorker* worker, Cryptographer* cryptographer, PassphraseType passphrase_type,
diff --git a/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc b/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc index a65a1a6d..01ddc51 100644 --- a/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc +++ b/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc
@@ -4,7 +4,9 @@ #include "components/sync/engine_impl/non_blocking_type_commit_contribution.h" +#include <memory> #include <string> +#include <utility> #include "base/base64.h" #include "base/hash/sha1.h" @@ -152,12 +154,12 @@ data.specifics.mutable_password()->mutable_unencrypted_metadata()->set_url( kMetadataUrl); - CommitRequestData request_data; - request_data.entity = data.PassToPtr(); - request_data.sequence_number = 2; - request_data.base_version = kBaseVersion; + auto request_data = std::make_unique<CommitRequestData>(); + request_data->entity = data.PassToPtr(); + request_data->sequence_number = 2; + request_data->base_version = kBaseVersion; base::Base64Encode(base::SHA1HashString(data.specifics.SerializeAsString()), - &request_data.specifics_hash); + &request_data->specifics_hash); base::ObserverList<TypeDebugInfoObserver>::Unchecked observers; DataTypeDebugInfoEmitter debug_info_emitter(PASSWORDS, &observers); @@ -166,8 +168,10 @@ Cryptographer cryptographer(&fake_encryptor); cryptographer.AddKey({KeyDerivationParams::CreateForPbkdf2(), "dummy"}); + CommitRequestDataList requests_data; + requests_data.push_back(std::move(request_data)); NonBlockingTypeCommitContribution contribution( - PASSWORDS, sync_pb::DataTypeContext(), {request_data}, + PASSWORDS, sync_pb::DataTypeContext(), std::move(requests_data), /*worker=*/nullptr, &cryptographer, PassphraseType::IMPLICIT_PASSPHRASE, &debug_info_emitter, /*only_commit_specifics=*/false); @@ -212,12 +216,12 @@ data.specifics.mutable_password()->mutable_unencrypted_metadata()->set_url( kMetadataUrl); - CommitRequestData request_data; - request_data.entity = data.PassToPtr(); - request_data.sequence_number = 2; - request_data.base_version = kBaseVersion; + auto request_data = std::make_unique<CommitRequestData>(); + request_data->entity = data.PassToPtr(); + request_data->sequence_number = 2; + request_data->base_version = kBaseVersion; base::Base64Encode(base::SHA1HashString(data.specifics.SerializeAsString()), - &request_data.specifics_hash); + &request_data->specifics_hash); base::ObserverList<TypeDebugInfoObserver>::Unchecked observers; DataTypeDebugInfoEmitter debug_info_emitter(PASSWORDS, &observers); @@ -226,8 +230,10 @@ Cryptographer cryptographer(&fake_encryptor); cryptographer.AddKey({KeyDerivationParams::CreateForPbkdf2(), "dummy"}); + CommitRequestDataList requests_data; + requests_data.push_back(std::move(request_data)); NonBlockingTypeCommitContribution contribution( - PASSWORDS, sync_pb::DataTypeContext(), {request_data}, + PASSWORDS, sync_pb::DataTypeContext(), std::move(requests_data), /*worker=*/nullptr, &cryptographer, PassphraseType::CUSTOM_PASSPHRASE, &debug_info_emitter, /*only_commit_specifics=*/false);
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor.cc b/components/sync/model_impl/client_tag_based_model_type_processor.cc index f7940d9..1133fb8 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor.cc +++ b/components/sync/model_impl/client_tag_based_model_type_processor.cc
@@ -1167,9 +1167,9 @@ for (const auto& kv : entities_) { ProcessorEntity* entity = kv.second.get(); if (entity->RequiresCommitRequest() && !entity->RequiresCommitData()) { - CommitRequestData request; - entity->InitializeCommitRequestData(&request); - commit_requests.push_back(request); + auto request = std::make_unique<CommitRequestData>(); + entity->InitializeCommitRequestData(request.get()); + commit_requests.push_back(std::move(request)); if (commit_requests.size() >= max_entries) { break; }
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc b/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc index 21b976c..195bf0d 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc +++ b/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc
@@ -712,11 +712,12 @@ // Verify the commit request this operation has triggered. worker()->VerifyPendingCommits({{kHash1}}); - const CommitRequestData& tag1_request_data = + const CommitRequestData* tag1_request_data = worker()->GetLatestPendingCommitForHash(kHash1); - const EntityData& tag1_data = tag1_request_data.entity.value(); + ASSERT_TRUE(tag1_request_data); + const EntityData& tag1_data = tag1_request_data->entity.value(); - EXPECT_EQ(kUncommittedVersion, tag1_request_data.base_version); + EXPECT_EQ(kUncommittedVersion, tag1_request_data->base_version); EXPECT_TRUE(tag1_data.id.empty()); EXPECT_FALSE(tag1_data.creation_time.is_null()); EXPECT_FALSE(tag1_data.modification_time.is_null()); @@ -780,8 +781,9 @@ ASSERT_FALSE(worker()->HasPendingCommitForHash(kHash3)); ASSERT_TRUE(worker()->HasPendingCommitForHash(kHash1)); EXPECT_EQ(1U, db()->metadata_count()); + ASSERT_TRUE(worker()->GetLatestPendingCommitForHash(kHash1)); const EntityData& out_entity1 = - worker()->GetLatestPendingCommitForHash(kHash1).entity.value(); + worker()->GetLatestPendingCommitForHash(kHash1)->entity.value(); const EntityMetadata metadata_v1 = db()->GetMetadata(kKey1); EXPECT_EQ(kId1, out_entity1.id); @@ -805,8 +807,9 @@ ASSERT_FALSE(worker()->HasPendingCommitForHash(kHash3)); ASSERT_TRUE(worker()->HasPendingCommitForHash(kHash1)); EXPECT_EQ(1U, db()->metadata_count()); + ASSERT_TRUE(worker()->GetLatestPendingCommitForHash(kHash1)); const EntityData& out_entity2 = - worker()->GetLatestPendingCommitForHash(kHash1).entity.value(); + worker()->GetLatestPendingCommitForHash(kHash1)->entity.value(); const EntityMetadata metadata_v2 = db()->GetMetadata(kKey1); EXPECT_EQ(kValue2, out_entity2.specifics.preference().value()); @@ -828,10 +831,17 @@ ASSERT_EQ(1U, db()->metadata_count()); worker()->VerifyPendingCommits({{kHash1}}); - const CommitRequestData& request_data_v1 = - worker()->GetLatestPendingCommitForHash(kHash1); - const EntityData& data_v1 = request_data_v1.entity.value(); const EntityMetadata metadata_v1 = db()->GetMetadata(kKey1); + int64_t request_data_v1_sequence_number; + { + // request_data_v1 is valid only while the commit is still pending. + const CommitRequestData* request_data_v1 = + worker()->GetLatestPendingCommitForHash(kHash1); + ASSERT_TRUE(request_data_v1); + const EntityData& data_v1 = request_data_v1->entity.value(); + EXPECT_EQ(data_v1.specifics.preference().value(), kValue1); + request_data_v1_sequence_number = request_data_v1->sequence_number; + } worker()->AckOnePendingCommit(); ASSERT_FALSE(type_processor()->IsEntityUnsynced(kKey1)); @@ -852,17 +862,18 @@ const base::Time mtime = type_processor()->GetEntityModificationTime(kKey1); EXPECT_NE(ctime, mtime); - const CommitRequestData& request_data_v2 = + const CommitRequestData* request_data_v2 = worker()->GetLatestPendingCommitForHash(kHash1); - const EntityData& data_v2 = request_data_v2.entity.value(); + ASSERT_TRUE(request_data_v2); + const EntityData& data_v2 = request_data_v2->entity.value(); const EntityMetadata metadata_v2 = db()->GetMetadata(kKey1); // Test some of the relations between old and new commit requests. - EXPECT_GT(request_data_v2.sequence_number, request_data_v1.sequence_number); - EXPECT_EQ(data_v1.specifics.preference().value(), kValue1); + EXPECT_GT(request_data_v2->sequence_number, request_data_v1_sequence_number); + EXPECT_EQ(data_v2.specifics.preference().value(), kValue2); // Perform a thorough examination of the update-generated request. - EXPECT_NE(kUncommittedVersion, request_data_v2.base_version); + EXPECT_NE(kUncommittedVersion, request_data_v2->base_version); EXPECT_FALSE(data_v2.id.empty()); EXPECT_EQ(ctime, data_v2.creation_time); EXPECT_EQ(mtime, data_v2.modification_time); @@ -898,9 +909,10 @@ ASSERT_EQ(1U, db()->metadata_count()); worker()->VerifyPendingCommits({{kHash1}}); - const CommitRequestData& request_data_v1 = + const CommitRequestData* request_data_v1 = worker()->GetLatestPendingCommitForHash(kHash1); - const EntityData& data_v1 = request_data_v1.entity.value(); + ASSERT_TRUE(request_data_v1); + const EntityData& data_v1 = request_data_v1->entity.value(); const EntityMetadata metadata_v1 = db()->GetMetadata(kKey1); ASSERT_TRUE(type_processor()->IsEntityUnsynced(kKey1)); @@ -921,17 +933,18 @@ const base::Time mtime = type_processor()->GetEntityModificationTime(kKey1); EXPECT_NE(mtime, ctime); - const CommitRequestData& request_data_v2 = + const CommitRequestData* request_data_v2 = worker()->GetLatestPendingCommitForHash(kHash1); - const EntityData& data_v2 = request_data_v2.entity.value(); + ASSERT_TRUE(request_data_v2); + const EntityData& data_v2 = request_data_v2->entity.value(); const EntityMetadata metadata_v2 = db()->GetMetadata(kKey1); // Test some of the relations between old and new commit requests. - EXPECT_GT(request_data_v2.sequence_number, request_data_v1.sequence_number); + EXPECT_GT(request_data_v2->sequence_number, request_data_v1->sequence_number); EXPECT_EQ(data_v1.specifics.preference().value(), kValue1); // Perform a thorough examination of the update-generated request. - EXPECT_EQ(kUncommittedVersion, request_data_v2.base_version); + EXPECT_EQ(kUncommittedVersion, request_data_v2->base_version); EXPECT_TRUE(data_v2.id.empty()); EXPECT_EQ(ctime, data_v2.creation_time); EXPECT_EQ(mtime, data_v2.modification_time); @@ -1114,8 +1127,9 @@ InitializeToReadyState(); bridge()->WriteItem(kKey1, kValue1); worker()->VerifyPendingCommits({{kHash1}}); - const CommitRequestData& data_v1 = + const CommitRequestData* data_v1 = worker()->GetLatestPendingCommitForHash(kHash1); + ASSERT_TRUE(data_v1); const EntityMetadata metadata_v1 = db()->GetMetadata(kKey1); EXPECT_FALSE(metadata_v1.is_deleted()); @@ -1129,12 +1143,13 @@ EXPECT_EQ(1U, ProcessorEntityCount()); worker()->VerifyPendingCommits({{kHash1}, {kHash1}}); - const CommitRequestData& data_v2 = + const CommitRequestData* data_v2 = worker()->GetLatestPendingCommitForHash(kHash1); - EXPECT_GT(data_v2.sequence_number, data_v1.sequence_number); - EXPECT_TRUE(data_v2.entity->id.empty()); - EXPECT_EQ(kUncommittedVersion, data_v2.base_version); - EXPECT_TRUE(data_v2.entity->is_deleted()); + ASSERT_TRUE(data_v2); + EXPECT_GT(data_v2->sequence_number, data_v1->sequence_number); + EXPECT_TRUE(data_v2->entity->id.empty()); + EXPECT_EQ(kUncommittedVersion, data_v2->base_version); + EXPECT_TRUE(data_v2->entity->is_deleted()); const EntityMetadata metadata_v2 = db()->GetMetadata(kKey1); EXPECT_TRUE(metadata_v2.is_deleted()); @@ -1228,7 +1243,7 @@ type_processor()->GetLocalChanges( INT_MAX, base::BindOnce(&CaptureCommitRequest, &commit_request)); EXPECT_EQ(1U, commit_request.size()); - EXPECT_EQ(kHash1, commit_request[0].entity->client_tag_hash); + EXPECT_EQ(kHash1, commit_request[0]->entity->client_tag_hash); } // Tests that GetLocalChanges honors max_entries parameter. @@ -1325,8 +1340,9 @@ bridge()->WriteItem(kKey1, kValue1); ASSERT_EQ(1U, worker()->GetNumPendingCommits()); + ASSERT_TRUE(worker()->GetLatestPendingCommitForHash(kHash1)); ASSERT_TRUE( - worker()->GetLatestPendingCommitForHash(kHash1).entity->id.empty()); + worker()->GetLatestPendingCommitForHash(kHash1)->entity->id.empty()); // The update from the server should be mostly ignored because local wins, but // the server ID should be updated. @@ -1338,11 +1354,12 @@ EXPECT_EQ(2U, worker()->GetNumPendingCommits()); // Verify the commit request this operation has triggered. - const CommitRequestData& tag1_request_data = + const CommitRequestData* tag1_request_data = worker()->GetLatestPendingCommitForHash(kHash1); - const EntityData& tag1_data = tag1_request_data.entity.value(); + ASSERT_TRUE(tag1_request_data); + const EntityData& tag1_data = tag1_request_data->entity.value(); - EXPECT_EQ(1, tag1_request_data.base_version); + EXPECT_EQ(1, tag1_request_data->base_version); EXPECT_FALSE(tag1_data.id.empty()); EXPECT_FALSE(tag1_data.creation_time.is_null()); EXPECT_FALSE(tag1_data.modification_time.is_null());
diff --git a/components/sync/test/engine/mock_model_type_processor.cc b/components/sync/test/engine/mock_model_type_processor.cc index 4c244ce..5f1755c 100644 --- a/components/sync/test/engine/mock_model_type_processor.cc +++ b/components/sync/test/engine/mock_model_type_processor.cc
@@ -69,7 +69,7 @@ pending_tasks_.clear(); } -CommitRequestData MockModelTypeProcessor::CommitRequest( +std::unique_ptr<CommitRequestData> MockModelTypeProcessor::CommitRequest( const std::string& tag_hash, const sync_pb::EntitySpecifics& specifics) { const int64_t base_version = GetBaseVersion(tag_hash); @@ -90,17 +90,17 @@ data.creation_time + base::TimeDelta::FromSeconds(base_version); data.non_unique_name = "Name: " + tag_hash; - CommitRequestData request_data; - request_data.entity = data.PassToPtr(); - request_data.sequence_number = GetNextSequenceNumber(tag_hash); - request_data.base_version = base_version; + auto request_data = std::make_unique<CommitRequestData>(); + request_data->entity = data.PassToPtr(); + request_data->sequence_number = GetNextSequenceNumber(tag_hash); + request_data->base_version = base_version; base::Base64Encode(base::SHA1HashString(specifics.SerializeAsString()), - &request_data.specifics_hash); + &request_data->specifics_hash); return request_data; } -CommitRequestData MockModelTypeProcessor::DeleteRequest( +std::unique_ptr<CommitRequestData> MockModelTypeProcessor::DeleteRequest( const std::string& tag_hash) { const int64_t base_version = GetBaseVersion(tag_hash); @@ -120,10 +120,10 @@ data.modification_time = data.creation_time + base::TimeDelta::FromSeconds(base_version); - CommitRequestData request_data; - request_data.entity = data.PassToPtr(); - request_data.sequence_number = GetNextSequenceNumber(tag_hash); - request_data.base_version = base_version; + auto request_data = std::make_unique<CommitRequestData>(); + request_data->entity = data.PassToPtr(); + request_data->sequence_number = GetNextSequenceNumber(tag_hash); + request_data->base_version = base_version; pending_deleted_hashes_.insert(tag_hash); @@ -194,8 +194,8 @@ } void MockModelTypeProcessor::SetCommitRequest( - const CommitRequestDataList& commit_request) { - commit_request_ = commit_request; + CommitRequestDataList commit_request) { + commit_request_ = std::move(commit_request); } int MockModelTypeProcessor::GetLocalChangesCallCount() const {
diff --git a/components/sync/test/engine/mock_model_type_processor.h b/components/sync/test/engine/mock_model_type_processor.h index 866c767..691a224 100644 --- a/components/sync/test/engine/mock_model_type_processor.h +++ b/components/sync/test/engine/mock_model_type_processor.h
@@ -68,9 +68,10 @@ // directly to its attached CommitQueue. These methods // return the value to the caller so the test framework can handle them as it // sees fit. - CommitRequestData CommitRequest(const std::string& tag_hash, - const sync_pb::EntitySpecifics& specifics); - CommitRequestData DeleteRequest(const std::string& tag_hash); + std::unique_ptr<CommitRequestData> CommitRequest( + const std::string& tag_hash, + const sync_pb::EntitySpecifics& specifics); + std::unique_ptr<CommitRequestData> DeleteRequest(const std::string& tag_hash); // Getters to access the log of received update responses. // @@ -97,7 +98,7 @@ void SetDisconnectCallback(const DisconnectCallback& callback); // Sets commit request that will be returned by GetLocalChanges(). - void SetCommitRequest(const CommitRequestDataList& commit_request); + void SetCommitRequest(CommitRequestDataList commit_request); int GetLocalChangesCallCount() const;
diff --git a/components/sync/test/engine/mock_model_type_worker.cc b/components/sync/test/engine/mock_model_type_worker.cc index 5e3e923..27ae551a 100644 --- a/components/sync/test/engine/mock_model_type_worker.cc +++ b/components/sync/test/engine/mock_model_type_worker.cc
@@ -34,27 +34,34 @@ void MockModelTypeWorker::LocalChangesReceived( CommitRequestDataList&& commit_request) { // Verify that all request entities have valid id, version combinations. - for (const CommitRequestData& commit_request_data : commit_request) { - EXPECT_TRUE(commit_request_data.base_version == -1 || - !commit_request_data.entity->id.empty()); + for (const std::unique_ptr<CommitRequestData>& commit_request_data : + commit_request) { + EXPECT_TRUE(commit_request_data->base_version == -1 || + !commit_request_data->entity->id.empty()); } - pending_commits_.push_back(commit_request); + pending_commits_.push_back(std::move(commit_request)); } size_t MockModelTypeWorker::GetNumPendingCommits() const { return pending_commits_.size(); } -CommitRequestDataList MockModelTypeWorker::GetNthPendingCommit(size_t n) const { +std::vector<const CommitRequestData*> MockModelTypeWorker::GetNthPendingCommit( + size_t n) const { DCHECK_LT(n, GetNumPendingCommits()); - return pending_commits_[n]; + std::vector<const CommitRequestData*> nth_pending_commits; + for (const std::unique_ptr<CommitRequestData>& request_data : + pending_commits_[n]) { + nth_pending_commits.push_back(request_data.get()); + } + return nth_pending_commits; } bool MockModelTypeWorker::HasPendingCommitForHash( const std::string& tag_hash) const { for (const CommitRequestDataList& commit : pending_commits_) { - for (const CommitRequestData& data : commit) { - if (data.entity->client_tag_hash == tag_hash) { + for (const std::unique_ptr<CommitRequestData>& data : commit) { + if (data && data->entity->client_tag_hash == tag_hash) { return true; } } @@ -62,20 +69,20 @@ return false; } -CommitRequestData MockModelTypeWorker::GetLatestPendingCommitForHash( +const CommitRequestData* MockModelTypeWorker::GetLatestPendingCommitForHash( const std::string& tag_hash) const { // Iterate backward through the sets of commit requests to find the most // recent one that applies to the specified tag_hash. for (auto rev_it = pending_commits_.rbegin(); rev_it != pending_commits_.rend(); ++rev_it) { - for (const CommitRequestData& data : *rev_it) { - if (data.entity->client_tag_hash == tag_hash) { - return data; + for (const std::unique_ptr<CommitRequestData>& data : *rev_it) { + if (data && data->entity->client_tag_hash == tag_hash) { + return data.get(); } } } NOTREACHED() << "Could not find commit for tag hash " << tag_hash << "."; - return CommitRequestData(); + return nullptr; } void MockModelTypeWorker::VerifyNthPendingCommit( @@ -83,10 +90,11 @@ const std::vector<std::string>& tag_hashes, const std::vector<sync_pb::EntitySpecifics>& specifics_list) { ASSERT_EQ(tag_hashes.size(), specifics_list.size()); - const CommitRequestDataList& list = GetNthPendingCommit(n); + std::vector<const CommitRequestData*> list = GetNthPendingCommit(n); ASSERT_EQ(tag_hashes.size(), list.size()); for (size_t i = 0; i < tag_hashes.size(); i++) { - const EntityData& data = list[i].entity.value(); + ASSERT_TRUE(list[i]); + const EntityData& data = list[i]->entity.value(); EXPECT_EQ(tag_hashes[i], data.client_tag_hash); EXPECT_EQ(specifics_list[i].SerializeAsString(), data.specifics.SerializeAsString()); @@ -95,12 +103,13 @@ void MockModelTypeWorker::VerifyPendingCommits( const std::vector<std::vector<std::string>>& tag_hashes) { - EXPECT_EQ(tag_hashes.size(), GetNumPendingCommits()); + ASSERT_EQ(tag_hashes.size(), GetNumPendingCommits()); for (size_t i = 0; i < tag_hashes.size(); i++) { - const CommitRequestDataList& commits = GetNthPendingCommit(i); - EXPECT_EQ(tag_hashes[i].size(), commits.size()); + std::vector<const CommitRequestData*> commits = GetNthPendingCommit(i); + ASSERT_EQ(tag_hashes[i].size(), commits.size()); for (size_t j = 0; j < tag_hashes[i].size(); j++) { - EXPECT_EQ(tag_hashes[i][j], commits[j].entity->client_tag_hash) + ASSERT_TRUE(commits[j]); + EXPECT_EQ(tag_hashes[i][j], commits[j]->entity->client_tag_hash) << "Hash for tag " << tag_hashes[i][j] << " doesn't match."; } } @@ -236,8 +245,9 @@ void MockModelTypeWorker::AckOnePendingCommit(int64_t version_offset) { CommitResponseDataList list; ASSERT_FALSE(pending_commits_.empty()); - for (const CommitRequestData& data : pending_commits_.front()) { - list.push_back(SuccessfulCommitResponse(data, version_offset)); + for (const std::unique_ptr<CommitRequestData>& data : + pending_commits_.front()) { + list.push_back(SuccessfulCommitResponse(*data, version_offset)); } pending_commits_.pop_front(); processor_->OnCommitCompleted(model_type_state_, list);
diff --git a/components/sync/test/engine/mock_model_type_worker.h b/components/sync/test/engine/mock_model_type_worker.h index 5b1830a..1269f7ef 100644 --- a/components/sync/test/engine/mock_model_type_worker.h +++ b/components/sync/test/engine/mock_model_type_worker.h
@@ -9,6 +9,7 @@ #include <stdint.h> #include <map> +#include <memory> #include <string> #include <vector> @@ -43,9 +44,9 @@ // Getters to inspect the requests sent to this object. size_t GetNumPendingCommits() const; - CommitRequestDataList GetNthPendingCommit(size_t n) const; + std::vector<const CommitRequestData*> GetNthPendingCommit(size_t n) const; bool HasPendingCommitForHash(const std::string& tag_hash) const; - CommitRequestData GetLatestPendingCommitForHash( + const CommitRequestData* GetLatestPendingCommitForHash( const std::string& tag_hash) const; // Verify that the |n|th commit request list has the corresponding commit
diff --git a/components/sync/user_events/user_event_model_type_controller.cc b/components/sync/user_events/user_event_model_type_controller.cc new file mode 100644 index 0000000..53734b9 --- /dev/null +++ b/components/sync/user_events/user_event_model_type_controller.cc
@@ -0,0 +1,44 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/sync/user_events/user_event_model_type_controller.h" + +#include <utility> + +#include "base/bind.h" +#include "components/sync/driver/sync_service.h" +#include "components/sync/driver/sync_user_settings.h" + +namespace syncer { + +UserEventModelTypeController::UserEventModelTypeController( + SyncService* sync_service, + std::unique_ptr<ModelTypeControllerDelegate> delegate_on_disk) + : ModelTypeController(syncer::USER_EVENTS, std::move(delegate_on_disk)), + sync_service_(sync_service) { + DCHECK(sync_service_); + sync_service_->AddObserver(this); +} + +UserEventModelTypeController::~UserEventModelTypeController() { + sync_service_->RemoveObserver(this); +} + +bool UserEventModelTypeController::ReadyForStart() const { + return !sync_service_->GetUserSettings()->IsUsingSecondaryPassphrase(); +} + +void UserEventModelTypeController::OnStateChanged(syncer::SyncService* sync) { + // Just disable if we start encrypting; we do not care about re-enabling it + // during run-time. + if (ReadyForStart()) { + return; + } + + // This results in stopping the data type (and is a no-op if the data type is + // already stopped because of being unready). + sync->ReadyForStartChanged(type()); +} + +} // namespace syncer
diff --git a/components/sync/user_events/user_event_model_type_controller.h b/components/sync/user_events/user_event_model_type_controller.h new file mode 100644 index 0000000..b162b6b --- /dev/null +++ b/components/sync/user_events/user_event_model_type_controller.h
@@ -0,0 +1,41 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SYNC_USER_EVENTS_USER_EVENT_MODEL_TYPE_CONTROLLER_H_ +#define COMPONENTS_SYNC_USER_EVENTS_USER_EVENT_MODEL_TYPE_CONTROLLER_H_ + +#include <memory> + +#include "components/sync/driver/model_type_controller.h" +#include "components/sync/driver/sync_service_observer.h" + +namespace syncer { + +class ModelTypeControllerDelegate; +class SyncService; + +class UserEventModelTypeController : public syncer::ModelTypeController, + public syncer::SyncServiceObserver { + public: + // |sync_service| must not be null and must outlive this object. + UserEventModelTypeController( + SyncService* sync_service, + std::unique_ptr<ModelTypeControllerDelegate> delegate_on_disk); + ~UserEventModelTypeController() override; + + // syncer::DataTypeController implementation. + bool ReadyForStart() const override; + + // syncer::SyncServiceObserver implementation. + void OnStateChanged(syncer::SyncService* sync) override; + + private: + SyncService* sync_service_; + + DISALLOW_COPY_AND_ASSIGN(UserEventModelTypeController); +}; + +} // namespace syncer + +#endif // COMPONENTS_SYNC_USER_EVENTS_USER_EVENT_MODEL_TYPE_CONTROLLER_H_
diff --git a/components/sync/user_events/user_event_service_impl.cc b/components/sync/user_events/user_event_service_impl.cc index db28eeb..c098acd 100644 --- a/components/sync/user_events/user_event_service_impl.cc +++ b/components/sync/user_events/user_event_service_impl.cc
@@ -10,7 +10,6 @@ #include "base/stl_util.h" #include "base/time/time.h" #include "components/sync/driver/sync_driver_switches.h" -#include "components/sync/driver/sync_service.h" #include "components/sync/driver/sync_user_settings.h" #include "components/sync/user_events/user_event_sync_bridge.h" @@ -61,13 +60,9 @@ } // namespace UserEventServiceImpl::UserEventServiceImpl( - SyncService* sync_service, std::unique_ptr<UserEventSyncBridge> bridge) - : sync_service_(sync_service), - bridge_(std::move(bridge)), - session_id_(base::RandUint64()) { + : bridge_(std::move(bridge)), session_id_(base::RandUint64()) { DCHECK(bridge_); - DCHECK(sync_service_); } UserEventServiceImpl::~UserEventServiceImpl() {} @@ -92,32 +87,6 @@ return bridge_.get(); } -// static -bool UserEventServiceImpl::MightRecordEvents(bool off_the_record, - SyncService* sync_service) { - return !off_the_record && sync_service; -} - -bool UserEventServiceImpl::CanRecordHistory() { - // Before the engine is initialized, Sync doesn't know if there is a - // secondary passphrase. Similarly, unless the Sync feature is enabled, - // GetPreferredDataTypes() isn't meaningful. - return sync_service_->IsEngineInitialized() && - !sync_service_->GetUserSettings()->IsUsingSecondaryPassphrase() && - sync_service_->IsSyncFeatureEnabled() && - sync_service_->GetPreferredDataTypes().Has(HISTORY_DELETE_DIRECTIVES); -} - -bool UserEventServiceImpl::IsUserEventsDatatypeEnabled() { - // Before the engine is initialized, Sync doesn't know if there is a - // secondary passphrase. Similarly, unless the Sync feature is enabled, - // GetPreferredDataTypes() isn't meaningful. - return sync_service_->IsEngineInitialized() && - !sync_service_->GetUserSettings()->IsUsingSecondaryPassphrase() && - sync_service_->IsSyncFeatureEnabled() && - sync_service_->GetPreferredDataTypes().Has(USER_EVENTS); -} - bool UserEventServiceImpl::ShouldRecordEvent( const UserEventSpecifics& specifics) { if (specifics.event_case() == UserEventSpecifics::EVENT_NOT_SET) { @@ -129,21 +98,6 @@ return false; } - // TODO(vitaliii): Checking HISTORY_DELETE_DIRECTIVES directly should not be - // needed once USER_CONSENTS are fully launched. Then USER_EVENTS datatype - // should depend on History in Sync layers instead of here. - if (specifics.has_navigation_id() && !CanRecordHistory()) { - return false; - } - - // TODO(vitaliii): Checking USER_EVENTS directly should not be needed once - // https://crbug.com/830535 is fixed. Then disabling USER_EVENTS should be - // honored by the processor and it should drop all events. - if (!IsUserEventsDatatypeEnabled()) { - DCHECK(!specifics.has_user_consent()); - return false; - } - return true; }
diff --git a/components/sync/user_events/user_event_service_impl.h b/components/sync/user_events/user_event_service_impl.h index 8c421c846..35154c4 100644 --- a/components/sync/user_events/user_event_service_impl.h +++ b/components/sync/user_events/user_event_service_impl.h
@@ -17,13 +17,11 @@ namespace syncer { class ModelTypeSyncBridge; -class SyncService; class UserEventSyncBridge; class UserEventServiceImpl : public UserEventService { public: - UserEventServiceImpl(SyncService* sync_service, - std::unique_ptr<UserEventSyncBridge> bridge); + explicit UserEventServiceImpl(std::unique_ptr<UserEventSyncBridge> bridge); ~UserEventServiceImpl() override; // KeyedService implementation. @@ -35,20 +33,10 @@ void RecordUserEvent(const sync_pb::UserEventSpecifics& specifics) override; ModelTypeSyncBridge* GetSyncBridge() override; - // Checks known (and immutable) conditions that should not change at runtime. - static bool MightRecordEvents(bool off_the_record, SyncService* sync_service); - private: - // Whether allowed to record events that link to navigation data. - bool CanRecordHistory(); - - bool IsUserEventsDatatypeEnabled(); - // Checks dynamic or event specific conditions. bool ShouldRecordEvent(const sync_pb::UserEventSpecifics& specifics); - SyncService* sync_service_; - std::unique_ptr<UserEventSyncBridge> bridge_; // Holds onto a random number for the duration of this execution of chrome. On
diff --git a/components/sync/user_events/user_event_service_impl_unittest.cc b/components/sync/user_events/user_event_service_impl_unittest.cc index 7b86abd..17a5aed 100644 --- a/components/sync/user_events/user_event_service_impl_unittest.cc +++ b/components/sync/user_events/user_event_service_impl_unittest.cc
@@ -86,47 +86,16 @@ TestGlobalIdMapper mapper_; }; -TEST_F(UserEventServiceImplTest, MightRecordEvents) { - // All conditions are met, might record. - EXPECT_TRUE(UserEventServiceImpl::MightRecordEvents(false, sync_service())); - // No sync service, will not record. - EXPECT_FALSE(UserEventServiceImpl::MightRecordEvents(false, nullptr)); - // Off the record, will not record. - EXPECT_FALSE(UserEventServiceImpl::MightRecordEvents(true, sync_service())); -} - TEST_F(UserEventServiceImplTest, ShouldRecord) { - UserEventServiceImpl service(sync_service(), MakeBridge()); + UserEventServiceImpl service(MakeBridge()); EXPECT_CALL(*mock_processor(), Put(_, _, _)); service.RecordUserEvent(AsTest(Event())); } -TEST_F(UserEventServiceImplTest, - ShouldOnlyRecordEventsWithoutNavIdWhenHistorySyncIsDisabled) { - sync_service()->SetPreferredDataTypes({USER_EVENTS}); - UserEventServiceImpl service(sync_service(), MakeBridge()); - - // Only record events without navigation ids when history sync is off. - EXPECT_CALL(*mock_processor(), Put(_, _, _)).Times(0); - service.RecordUserEvent(WithNav(AsTest(Event()))); - EXPECT_CALL(*mock_processor(), Put(_, _, _)); - service.RecordUserEvent(AsTest(Event())); -} - -TEST_F(UserEventServiceImplTest, ShouldNotRecordWhenPassphraseIsUsed) { - sync_service()->SetIsUsingSecondaryPassphrase(true); - UserEventServiceImpl service(sync_service(), MakeBridge()); - - // Do not record events when a passphrase is used. - EXPECT_CALL(*mock_processor(), Put(_, _, _)).Times(0); - service.RecordUserEvent(WithNav(AsTest(Event()))); - service.RecordUserEvent(AsTest(Event())); -} - -TEST_F(UserEventServiceImplTest, ShouldNotRecordWhenEngineIsNotInitialized) { - sync_service()->SetTransportState( - syncer::SyncService::TransportState::INITIALIZING); - UserEventServiceImpl service(sync_service(), MakeBridge()); +TEST_F(UserEventServiceImplTest, ShouldNotRecordWhenSyncIsNotStarted) { + ON_CALL(*mock_processor(), IsTrackingMetadata()) + .WillByDefault(testing::Return(false)); + UserEventServiceImpl service(MakeBridge()); // Do not record events when the engine is off. EXPECT_CALL(*mock_processor(), Put(_, _, _)).Times(0); @@ -135,7 +104,7 @@ } TEST_F(UserEventServiceImplTest, ShouldNotRecordEmptyEvents) { - UserEventServiceImpl service(sync_service(), MakeBridge()); + UserEventServiceImpl service(MakeBridge()); // All untyped events should always be ignored. EXPECT_CALL(*mock_processor(), Put(_, _, _)).Times(0); @@ -144,7 +113,7 @@ } TEST_F(UserEventServiceImplTest, ShouldRecordHasNavigationId) { - UserEventServiceImpl service(sync_service(), MakeBridge()); + UserEventServiceImpl service(MakeBridge()); // Verify logic for types that might or might not have a navigation id. EXPECT_CALL(*mock_processor(), Put(_, _, _)); @@ -175,24 +144,16 @@ entity_data->specifics.user_event().session_id()); }); - UserEventServiceImpl service1(sync_service(), MakeBridge()); + UserEventServiceImpl service1(MakeBridge()); service1.RecordUserEvent(AsTest(Event())); - UserEventServiceImpl service2(sync_service(), MakeBridge()); + UserEventServiceImpl service2(MakeBridge()); service2.RecordUserEvent(AsTest(Event())); ASSERT_EQ(2U, put_session_ids.size()); EXPECT_NE(put_session_ids[0], put_session_ids[1]); } -TEST_F(UserEventServiceImplTest, ShouldNotRecordWhenEventsDatatypeIsDisabled) { - sync_service()->SetPreferredDataTypes({HISTORY_DELETE_DIRECTIVES}); - UserEventServiceImpl service(sync_service(), MakeBridge()); - // USER_EVENTS type is disabled, thus, they should not be recorded. - EXPECT_CALL(*mock_processor(), Put(_, _, _)).Times(0); - service.RecordUserEvent(AsTest(Event())); -} - } // namespace } // namespace syncer
diff --git a/components/sync_bookmarks/bookmark_local_changes_builder.cc b/components/sync_bookmarks/bookmark_local_changes_builder.cc index 9d4210fe..1f3bc55 100644 --- a/components/sync_bookmarks/bookmark_local_changes_builder.cc +++ b/components/sync_bookmarks/bookmark_local_changes_builder.cc
@@ -4,6 +4,7 @@ #include "components/sync_bookmarks/bookmark_local_changes_builder.h" +#include <memory> #include <string> #include <utility> @@ -24,22 +25,21 @@ DCHECK(bookmark_model); } -std::vector<syncer::CommitRequestData> -BookmarkLocalChangesBuilder::BuildCommitRequests(size_t max_entries) const { +syncer::CommitRequestDataList BookmarkLocalChangesBuilder::BuildCommitRequests( + size_t max_entries) const { DCHECK(bookmark_tracker_); const std::vector<const SyncedBookmarkTracker::Entity*> entities_with_local_changes = bookmark_tracker_->GetEntitiesWithLocalChanges(max_entries); DCHECK_LE(entities_with_local_changes.size(), max_entries); - std::vector<syncer::CommitRequestData> commit_requests; + syncer::CommitRequestDataList commit_requests; for (const SyncedBookmarkTracker::Entity* entity : entities_with_local_changes) { DCHECK(entity); DCHECK(entity->IsUnsynced()); const sync_pb::EntityMetadata* metadata = entity->metadata(); - syncer::CommitRequestData request; syncer::EntityData data; data.id = metadata->server_id(); data.creation_time = syncer::ProtoTimeToTime(metadata->creation_time()); @@ -67,12 +67,13 @@ node, bookmark_model_, /*force_favicon_load=*/true); data.non_unique_name = data.specifics.bookmark().title(); } - request.entity = data.PassToPtr(); - request.sequence_number = metadata->sequence_number(); - request.base_version = metadata->server_version(); + auto request = std::make_unique<syncer::CommitRequestData>(); + request->entity = data.PassToPtr(); + request->sequence_number = metadata->sequence_number(); + request->base_version = metadata->server_version(); // Specifics hash has been computed in the tracker when this entity has been // added/updated. - request.specifics_hash = metadata->specifics_hash(); + request->specifics_hash = metadata->specifics_hash(); commit_requests.push_back(std::move(request)); }
diff --git a/components/sync_bookmarks/bookmark_local_changes_builder.h b/components/sync_bookmarks/bookmark_local_changes_builder.h index e8938159..181c08ed 100644 --- a/components/sync_bookmarks/bookmark_local_changes_builder.h +++ b/components/sync_bookmarks/bookmark_local_changes_builder.h
@@ -24,8 +24,7 @@ BookmarkLocalChangesBuilder(const SyncedBookmarkTracker* bookmark_tracker, bookmarks::BookmarkModel* bookmark_model); // Builds the commit requests list. - std::vector<syncer::CommitRequestData> BuildCommitRequests( - size_t max_entries) const; + syncer::CommitRequestDataList BuildCommitRequests(size_t max_entries) const; private: const SyncedBookmarkTracker* const bookmark_tracker_;
diff --git a/components/sync_bookmarks/bookmark_model_type_processor.cc b/components/sync_bookmarks/bookmark_model_type_processor.cc index eb091cf..4cb7d49 100644 --- a/components/sync_bookmarks/bookmark_model_type_processor.cc +++ b/components/sync_bookmarks/bookmark_model_type_processor.cc
@@ -11,6 +11,7 @@ #include "base/feature_list.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "base/trace_event/trace_event.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_node.h" #include "components/bookmarks/browser/bookmark_utils.h" @@ -140,7 +141,7 @@ GetLocalChangesCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); BookmarkLocalChangesBuilder builder(bookmark_tracker_.get(), bookmark_model_); - std::vector<syncer::CommitRequestData> local_changes = + syncer::CommitRequestDataList local_changes = builder.BuildCommitRequests(max_entries); std::move(callback).Run(std::move(local_changes)); } @@ -258,6 +259,9 @@ DCHECK(!bookmark_tracker_); DCHECK(!bookmark_model_observer_); + // TODO(crbug.com/950869): Remove after investigations are completed. + TRACE_EVENT0("browser", "BookmarkModelTypeProcessor::ModelReadyToSync"); + bookmark_model_ = model; schedule_save_closure_ = schedule_save_closure;
diff --git a/components/update_client/BUILD.gn b/components/update_client/BUILD.gn index 5f87e658..fc11b0c 100644 --- a/components/update_client/BUILD.gn +++ b/components/update_client/BUILD.gn
@@ -4,15 +4,26 @@ import("//net/features.gni") -source_set("network_impl") { +source_set("network_public") { sources = [ "net/network_chromium.h", + ] + + deps = [ + "//base", + ] +} + +source_set("network") { + sources = [ "net/network_impl.cc", "net/network_impl.h", ] + visibility = [ ":*" ] + deps = [ - ":update_client", + ":network_public", "//base", "//net", "//services/network/public/cpp:cpp", @@ -42,14 +53,6 @@ ] } -group("common_impl") { - public_deps = [ - ":network_impl", - ":patch_impl", - ":unzip_impl", - ] -} - static_library("update_client") { sources = [ "action_runner.cc", @@ -122,16 +125,29 @@ "utils.h", ] + # Allows callers to include the network factory through "update_client" deps. + public_deps = [ + ":network_public", + ] + deps = [ + ":network", + ":network_public", "//base", "//components/client_update_protocol", "//components/crx_file", + "//components/data_use_measurement/core", "//components/prefs", "//components/version_info:version_info", "//courgette:courgette_lib", "//crypto", "//url", ] + + allow_circular_includes_from = [ + ":network", + ":network_public", + ] } static_library("test_support") { @@ -150,7 +166,6 @@ ] deps = [ - ":network_impl", ":patch_impl", ":unzip_impl", "//base", @@ -218,7 +233,7 @@ } deps = [ - ":network_impl", + ":network", ":patch_impl", ":test_support", ":unit_tests_bundle_data",
diff --git a/components/update_client/DEPS b/components/update_client/DEPS index b89a744..0a397d61 100644 --- a/components/update_client/DEPS +++ b/components/update_client/DEPS
@@ -1,6 +1,7 @@ include_rules = [ "+components/client_update_protocol", "+components/crx_file", + "+components/data_use_measurement/core", "+components/services/patch", "+components/prefs", "+components/services/unzip",
diff --git a/components/update_client/url_fetcher_downloader.cc b/components/update_client/url_fetcher_downloader.cc index 7a550feb..03eb432 100644 --- a/components/update_client/url_fetcher_downloader.cc +++ b/components/update_client/url_fetcher_downloader.cc
@@ -14,6 +14,7 @@ #include "base/sequenced_task_runner.h" #include "base/task/post_task.h" #include "base/task/task_traits.h" +#include "components/data_use_measurement/core/data_use_user_data.h" #include "components/update_client/network.h" #include "components/update_client/utils.h" #include "url/gurl.h"
diff --git a/components/update_client/utils.cc b/components/update_client/utils.cc index ded9add..06fa82a 100644 --- a/components/update_client/utils.cc +++ b/components/update_client/utils.cc
@@ -21,6 +21,7 @@ #include "base/strings/string_util.h" #include "base/values.h" #include "components/crx_file/id_util.h" +#include "components/data_use_measurement/core/data_use_user_data.h" #include "components/update_client/component.h" #include "components/update_client/configurator.h" #include "components/update_client/network.h"
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc index c81c4fa0..6084025 100644 --- a/components/viz/service/display/renderer_pixeltest.cc +++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -4489,14 +4489,6 @@ &pass_list, base::FilePath(FILE_PATH_LITERAL("rounded_corner_render_pass.png")), cc::ExactPixelComparator(true))); - } else if (std::is_same<TypeParam, SkiaRenderer>()) { - // This is a bug where the render pass is being clipped incorrectly in the - // skia renderer. Change the expectation to true when the following bug is - // fixed: https://crbug.com/947243 - EXPECT_FALSE(this->RunPixelTest( - &pass_list, - base::FilePath(FILE_PATH_LITERAL("rounded_corner_render_pass.png")), - cc::FuzzyPixelComparator(true, 0.6f, 0.f, 255.f, 255, 0))); } else { // Software/skia renderer uses skia rrect to create rounded corner clip. // This results in a different corner path due to a different anti aliasing
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index 78c544b..3ce59f4 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -288,7 +288,6 @@ // Other quad types do not expose filter quality, so default to bilinear // TODO(penghuang): figure out how to set correct filter quality for YUV // and video stream quads. - // TODO(michaelludwig): use kMedium for RPDQs that ask for mipmaps nearest_neighbor = false; break; } @@ -313,34 +312,42 @@ } // namespace -// Parameters needed to draw a RenderPassDrawQuad. -struct SkiaRenderer::DrawRenderPassDrawQuadParams { - // The "in" parameters that will be used when apply filters. - const cc::FilterOperations* filters = nullptr; +// chrome style prevents this from going in skia_renderer.h, but since it +// uses base::Optional, the style also requires it to have a declared ctor +SkiaRenderer::BatchedQuadState::BatchedQuadState() = default; - // The "out" parameters returned by CalculateRPDQParams. +// Parameters needed to draw a RenderPassDrawQuad. +struct SkiaRenderer::DrawRPDQParams { + explicit DrawRPDQParams(const gfx::RectF& visible_rect); + // Root of the calculated image filter DAG to be applied to the render pass. - sk_sp<SkImageFilter> image_filter; - // Non-null |color_filter| should be applied when render pass is drawn. It is - // a portion of the image filter DAG that was separated out because direct - // color filter drawing is much faster than a colorFilterImageFilter drawing. - // TODO(skbug.com/8700): Delete this after Skia side implementation is done. - sk_sp<SkColorFilter> color_filter; + sk_sp<SkImageFilter> image_filter = nullptr; + // Root of the calculated backdrop filter DAG to be applied to the render pass + sk_sp<SkImageFilter> backdrop_filter = nullptr; + // Resolved mask image and calculated transform matrix + sk_sp<SkImage> mask_image = nullptr; + SkMatrix mask_to_quad_matrix; + // Backdrop border box for the render pass, to clip backdrop-filtered content + base::Optional<gfx::RRectF> backdrop_filter_bounds; + // The content space bounds that includes any filtered extents. If empty, + // the draw can be skipped. + gfx::Rect filter_bounds; }; +SkiaRenderer::DrawRPDQParams::DrawRPDQParams(const gfx::RectF& visible_rect) + : filter_bounds(gfx::ToEnclosingRect(visible_rect)) {} + // State calculated from a DrawQuad and current renderer state, that is common // to all DrawQuad rendering. struct SkiaRenderer::DrawQuadParams { DrawQuadParams() = default; DrawQuadParams(const gfx::Transform& cdt, - const gfx::RectF visible_rect, + const gfx::RectF& visible_rect, unsigned aa_flags, SkBlendMode blend_mode, float opacity, SkFilterQuality filter_quality, - const gfx::QuadF* draw_region, - bool enable_scissor_rect, - const gfx::RRectF* rounded_corner_bounds); + const gfx::QuadF* draw_region); // window_matrix * projection_matrix * quad_to_target_transform gfx::Transform content_device_transform; @@ -358,12 +365,12 @@ // Optional restricted draw geometry, will point to a length 4 SkPoint array // with its points in CW order matching Skia's vertex/edge expectations. base::Optional<SkDrawRegion> draw_region; - // True if renderer's scissor_rect_ should be used as a clipRect on the - // canvas. Is false if is_scissor_enabled_ is false or the scissor was - // explicitly applied to the visible geometry already. - bool has_scissor_rect; - // The rounded corner clip to be applied. This is in target space. - const gfx::RRectF* rounded_corner_bounds; + // Optional rounded corner clip to apply. If present, it will have been + // transformed to device space and ShouldApplyRoundedCorner returns true. + base::Optional<gfx::RRectF> rounded_corner_bounds; + // Optional device space clip to apply. If present, it is equal to the current + // |scissor_rect_| of the renderer. + base::Optional<gfx::Rect> scissor_rect; SkPaint paint() const { SkPaint p; @@ -375,24 +382,19 @@ } }; -SkiaRenderer::DrawQuadParams::DrawQuadParams( - const gfx::Transform& cdt, - const gfx::RectF visible_rect, - unsigned aa_flags, - SkBlendMode blend_mode, - float opacity, - SkFilterQuality filter_quality, - const gfx::QuadF* draw_region, - bool has_scissor_rect, - const gfx::RRectF* rounded_corner_bounds) +SkiaRenderer::DrawQuadParams::DrawQuadParams(const gfx::Transform& cdt, + const gfx::RectF& visible_rect, + unsigned aa_flags, + SkBlendMode blend_mode, + float opacity, + SkFilterQuality filter_quality, + const gfx::QuadF* draw_region) : content_device_transform(cdt), visible_rect(visible_rect), aa_flags(aa_flags), blend_mode(blend_mode), opacity(opacity), - filter_quality(filter_quality), - has_scissor_rect(has_scissor_rect), - rounded_corner_bounds(rounded_corner_bounds) { + filter_quality(filter_quality) { if (draw_region) { this->draw_region.emplace(*draw_region); } @@ -778,8 +780,6 @@ FlushBatchedQuads(); } - // TODO(michaelludwig): By the end of the Skia API update, this switch will - // hold all quad draw types and resemble the old DoDrawSingleQuad. switch (quad->material) { case DrawQuad::DEBUG_BORDER: DrawDebugBorderQuad(DebugBorderDrawQuad::MaterialCast(quad), params); @@ -787,6 +787,9 @@ case DrawQuad::PICTURE_CONTENT: DrawPictureQuad(PictureDrawQuad::MaterialCast(quad), params); break; + case DrawQuad::RENDER_PASS: + DrawRenderPassQuad(RenderPassDrawQuad::MaterialCast(quad), params); + break; case DrawQuad::SOLID_COLOR: DrawSolidColorQuad(SolidColorDrawQuad::MaterialCast(quad), params); break; @@ -816,26 +819,28 @@ DrawUnsupportedQuad(quad, params); break; default: - // If we've reached here, the quad's type hasn't been updated to be - // batch aware yet. - DoSingleDrawQuad(quad, draw_region, params); + // If we've reached here, it's a new quad type that needs a + // dedicated implementation + DrawUnsupportedQuad(quad, params); + NOTREACHED(); break; } } -void SkiaRenderer::PrepareCanvas(const gfx::Rect* scissor_rect, - const gfx::RRectF* rounded_corner_bounds, - const gfx::Transform* cdt) { +void SkiaRenderer::PrepareCanvas( + const base::Optional<gfx::Rect>& scissor_rect, + const base::Optional<gfx::RRectF>& rounded_corner_bounds, + const gfx::Transform* cdt) { // Scissor is applied in the device space (CTM == I) and since no changes // to the canvas persist, CTM should already be the identity DCHECK(current_canvas_->getTotalMatrix() == SkMatrix::I()); - if (scissor_rect) { + if (scissor_rect.has_value()) { current_canvas_->clipRect(gfx::RectToSkRect(*scissor_rect)); } - if (rounded_corner_bounds && !rounded_corner_bounds->IsEmpty()) - current_canvas_->clipRRect(SkRRect(*rounded_corner_bounds), true); + if (rounded_corner_bounds.has_value()) + current_canvas_->clipRRect(SkRRect(*rounded_corner_bounds), true /* AA */); if (cdt) { SkMatrix m; @@ -847,13 +852,13 @@ SkiaRenderer::DrawQuadParams SkiaRenderer::CalculateDrawQuadParams( const DrawQuad* quad, const gfx::QuadF* draw_region) { + gfx::Transform target_to_device = + current_frame()->window_matrix * current_frame()->projection_matrix; DrawQuadParams params( - current_frame()->window_matrix * current_frame()->projection_matrix * - quad->shared_quad_state->quad_to_target_transform, + target_to_device * quad->shared_quad_state->quad_to_target_transform, gfx::RectF(quad->visible_rect), SkCanvas::kNone_QuadAAFlags, quad->shared_quad_state->blend_mode, quad->shared_quad_state->opacity, - GetFilterQuality(quad), draw_region, is_scissor_enabled_, - &quad->shared_quad_state->rounded_corner_bounds); + GetFilterQuality(quad), draw_region); params.content_device_transform.FlattenTo2d(); @@ -889,12 +894,34 @@ // Applying the scissor explicitly means avoiding a clipRect() call and // allows more quads to be batched together in a DrawEdgeAAImageSet call - if (is_scissor_enabled_ && - CanExplicitlyScissor(quad, draw_region, - params.content_device_transform)) { - ApplyExplicitScissor(quad, scissor_rect_, params.content_device_transform, - ¶ms.aa_flags, ¶ms.visible_rect); - params.has_scissor_rect = false; + if (is_scissor_enabled_) { + if (CanExplicitlyScissor(quad, draw_region, + params.content_device_transform)) { + ApplyExplicitScissor(quad, scissor_rect_, params.content_device_transform, + ¶ms.aa_flags, ¶ms.visible_rect); + } else { + params.scissor_rect = scissor_rect_; + } + } + + // Determine final rounded rect clip geometry. We transform it from target + // space to window space to make batching and canvas preparation easier + // (otherwise we'd have to separate those two matrices in the CDT). + if (ShouldApplyRoundedCorner(quad)) { + // Transform by the window and projection matrix to go from target to + // device space, which should always be a scale+translate. + SkRRect corner_bounds = + SkRRect(quad->shared_quad_state->rounded_corner_bounds); + SkMatrix to_device; + gfx::TransformToFlattenedSkMatrix(target_to_device, &to_device); + + SkRRect device_bounds; + bool success = corner_bounds.transform(to_device, &device_bounds); + // Since to_device should just be scale+translate, transform always succeeds + DCHECK(success); + if (!device_bounds.isEmpty()) { + params.rounded_corner_bounds.emplace(device_bounds); + } } return params; @@ -917,9 +944,8 @@ if (batched_quads_.empty()) return false; - // TODO(michaelludwig) - Once other quad types are migrated from - // DoDrawQuadLegacy, this check will be widened - if (new_quad->material != DrawQuad::STREAM_VIDEO_CONTENT && + if (new_quad->material != DrawQuad::RENDER_PASS && + new_quad->material != DrawQuad::STREAM_VIDEO_CONTENT && new_quad->material != DrawQuad::TEXTURE_CONTENT && new_quad->material != DrawQuad::TILED_CONTENT) return true; @@ -928,19 +954,12 @@ batched_quad_state_.filter_quality != params.filter_quality) return true; - bool no_scissor = - !batched_quad_state_.has_scissor_rect && !params.has_scissor_rect; - bool same_scissor = batched_quad_state_.has_scissor_rect && - params.has_scissor_rect && - batched_quad_state_.scissor_rect == scissor_rect_; - - if (!no_scissor && !same_scissor) + if (batched_quad_state_.scissor_rect != params.scissor_rect) { return true; + } - if (batched_quad_state_.rounded_corner_bounds && - params.rounded_corner_bounds && - *batched_quad_state_.rounded_corner_bounds != - *params.rounded_corner_bounds) { + if (batched_quad_state_.rounded_corner_bounds != + params.rounded_corner_bounds) { return true; } @@ -952,16 +971,10 @@ const gfx::RectF& tex_coords) { // Configure batch state if it's the first if (batched_quads_.empty()) { - if (params.has_scissor_rect) { - batched_quad_state_.scissor_rect = scissor_rect_; - batched_quad_state_.has_scissor_rect = true; - } else { - batched_quad_state_.has_scissor_rect = false; - } - + batched_quad_state_.scissor_rect = params.scissor_rect; + batched_quad_state_.rounded_corner_bounds = params.rounded_corner_bounds; batched_quad_state_.blend_mode = params.blend_mode; batched_quad_state_.filter_quality = params.filter_quality; - batched_quad_state_.rounded_corner_bounds = params.rounded_corner_bounds; } // Add entry, with optional clip quad and shared transform @@ -986,9 +999,7 @@ TRACE_EVENT0("viz", "SkiaRenderer::FlushBatchedQuads"); SkAutoCanvasRestore acr(current_canvas_, true /* do_save */); - PrepareCanvas(batched_quad_state_.has_scissor_rect - ? &batched_quad_state_.scissor_rect - : nullptr, + PrepareCanvas(batched_quad_state_.scissor_rect, batched_quad_state_.rounded_corner_bounds, nullptr); SkPaint paint; @@ -1009,8 +1020,8 @@ TRACE_EVENT0("viz", "SkiaRenderer::DrawColoredQuad"); SkAutoCanvasRestore acr(current_canvas_, true /* do_save */); - PrepareCanvas(params.has_scissor_rect ? &scissor_rect_ : nullptr, - params.rounded_corner_bounds, ¶ms.content_device_transform); + PrepareCanvas(params.scissor_rect, params.rounded_corner_bounds, + ¶ms.content_device_transform); color = SkColorSetA(color, params.opacity * SkColorGetA(color)); const SkPoint* draw_region = @@ -1029,8 +1040,8 @@ TRACE_EVENT0("viz", "SkiaRenderer::DrawSingleImage"); SkAutoCanvasRestore acr(current_canvas_, true /* do_save */); - PrepareCanvas(params.has_scissor_rect ? &scissor_rect_ : nullptr, - params.rounded_corner_bounds, ¶ms.content_device_transform); + PrepareCanvas(params.scissor_rect, params.rounded_corner_bounds, + ¶ms.content_device_transform); // Use -1 for matrix index since the cdt is set on the canvas. // Assume params.opacity has been somehow handled in the SkPaint // (setAlphaf, color filter, image filter node, etc.). @@ -1048,8 +1059,7 @@ SkAutoCanvasRestore acr(current_canvas_, true /* do_save */); // We need to apply the matrix manually to have pixel-sized stroke width. - PrepareCanvas(params.has_scissor_rect ? &scissor_rect_ : nullptr, nullptr, - nullptr); + PrepareCanvas(params.scissor_rect, params.rounded_corner_bounds, nullptr); SkMatrix cdt; gfx::TransformToFlattenedSkMatrix(params.content_device_transform, &cdt); @@ -1085,8 +1095,8 @@ params.filter_quality == kNone_SkFilterQuality; SkAutoCanvasRestore acr(current_canvas_, true /* do_save */); - PrepareCanvas(params.has_scissor_rect ? &scissor_rect_ : nullptr, - params.rounded_corner_bounds, ¶ms.content_device_transform); + PrepareCanvas(params.scissor_rect, params.rounded_corner_bounds, + ¶ms.content_device_transform); // Unlike other quads which draw visible_rect or draw_region as their geometry // these represent the valid windows of content to show for the display list, @@ -1324,99 +1334,6 @@ #endif } -void SkiaRenderer::DoSingleDrawQuad(const DrawQuad* quad, - const gfx::QuadF* draw_region, - const DrawQuadParams& params) { - base::Optional<SkAutoCanvasRestore> auto_canvas_restore; - const gfx::Rect* scissor_rect = - is_scissor_enabled_ ? &scissor_rect_ : nullptr; - const gfx::RRectF* rounded_corner_bounds = - ShouldApplyRoundedCorner(quad) - ? &quad->shared_quad_state->rounded_corner_bounds - : nullptr; - PrepareCanvasForDrawQuads(quad->shared_quad_state->quad_to_target_transform, - draw_region, scissor_rect, rounded_corner_bounds, - &auto_canvas_restore); - - SkPaint paint = params.paint(); - - switch (quad->material) { - case DrawQuad::DEBUG_BORDER: - NOTREACHED(); - break; - case DrawQuad::PICTURE_CONTENT: - NOTREACHED(); - break; - case DrawQuad::RENDER_PASS: - DrawRenderPassQuad(RenderPassDrawQuad::MaterialCast(quad), &paint); - break; - case DrawQuad::SOLID_COLOR: - NOTREACHED(); - break; - case DrawQuad::TEXTURE_CONTENT: - NOTREACHED(); - break; - case DrawQuad::TILED_CONTENT: - NOTREACHED(); - break; - case DrawQuad::SURFACE_CONTENT: - // Surface content should be fully resolved to other quad types before - // reaching a direct renderer. - NOTREACHED(); - break; - case DrawQuad::YUV_VIDEO_CONTENT: - NOTREACHED(); - break; - case DrawQuad::STREAM_VIDEO_CONTENT: - NOTREACHED(); - break; - case DrawQuad::INVALID: - case DrawQuad::VIDEO_HOLE: - NOTREACHED(); - break; - } - - current_canvas_->resetMatrix(); -} - -void SkiaRenderer::PrepareCanvasForDrawQuads( - gfx::Transform quad_to_target_transform, - const gfx::QuadF* draw_region, - const gfx::Rect* scissor_rect, - const gfx::RRectF* rounded_corner_bounds, - base::Optional<SkAutoCanvasRestore>* auto_canvas_restore) { - gfx::Transform screen_transform = - current_frame()->window_matrix * current_frame()->projection_matrix; - screen_transform.FlattenTo2d(); - if (draw_region || scissor_rect || rounded_corner_bounds) { - auto_canvas_restore->emplace(current_canvas_, true /* do_save */); - if (scissor_rect) - current_canvas_->clipRect(gfx::RectToSkRect(*scissor_rect)); - if (rounded_corner_bounds) { - SkRRect result; - if (SkRRect(*rounded_corner_bounds) - .transform(screen_transform.matrix(), &result)) { - current_canvas_->clipRRect(result, true); - } - } - } - gfx::Transform contents_device_transform = - screen_transform * quad_to_target_transform; - contents_device_transform.FlattenTo2d(); - SkMatrix sk_device_matrix; - gfx::TransformToFlattenedSkMatrix(contents_device_transform, - &sk_device_matrix); - current_canvas_->setMatrix(sk_device_matrix); - - if (draw_region) { - SkPath draw_region_clip_path; - SkPoint clip_points[4]; - QuadFToSkPoints(*draw_region, clip_points); - draw_region_clip_path.addPoly(clip_points, 4, true); - current_canvas_->clipPath(draw_region_clip_path); - } -} - sk_sp<SkColorFilter> SkiaRenderer::GetColorFilter(const gfx::ColorSpace& src, const gfx::ColorSpace& dst, float resource_offset, @@ -1463,71 +1380,132 @@ return color_filter; } -bool SkiaRenderer::CalculateRPDQParams(sk_sp<SkImage> content, - const RenderPassDrawQuad* quad, - DrawRenderPassDrawQuadParams* params) { - if (!params->filters) - return true; +SkiaRenderer::DrawRPDQParams SkiaRenderer::CalculateRPDQParams( + const SkImage* content, + const RenderPassDrawQuad* quad, + const DrawQuadParams& params) { + DrawRPDQParams rpdq_params(params.visible_rect); - DCHECK(!params->filters->IsEmpty()); - auto paint_filter = cc::RenderSurfaceFilters::BuildImageFilter( - *params->filters, gfx::SizeF(content->width(), content->height())); - auto filter = paint_filter ? paint_filter->cached_sk_filter_ : nullptr; + // Prepare mask. + ScopedSkImageBuilder mask_image_builder(this, quad->mask_resource_id()); + const SkImage* mask_image = mask_image_builder.sk_image(); + DCHECK_EQ(!!quad->mask_resource_id(), !!mask_image); + if (mask_image) { + rpdq_params.mask_image = sk_ref_sp(mask_image); - // If the first imageFilter is a colorFilterImageFilter, pull it off and store - // it to be used later. Fall through to allow the remainder of the DAG (if - // any) to be applied. Applying the colorFilter as part of the final draw is - // much more efficient than applying it as a colorFilterImageFilter. This - // optimization would be covered by skbug.com/8700. Delete color_filter - // related code after Skia side implementation is done. - if (filter) { - SkColorFilter* colorfilter_rawptr = nullptr; - filter->asColorFilter(&colorfilter_rawptr); - sk_sp<SkColorFilter> color_filter(colorfilter_rawptr); + // Scale normalized uv rect into absolute texel coordinates. + SkRect mask_rect = gfx::RectFToSkRect( + gfx::ScaleRect(quad->mask_uv_rect, quad->mask_texture_size.width(), + quad->mask_texture_size.height())); + // Map to full quad rect so that mask coordinates don't change with clipping + rpdq_params.mask_to_quad_matrix = SkMatrix::MakeRectToRect( + mask_rect, gfx::RectToSkRect(quad->rect), SkMatrix::kFill_ScaleToFit); + } - if (color_filter) { - params->color_filter = color_filter; - filter = sk_ref_sp(filter->getInput(0)); + const cc::FilterOperations* filters = FiltersForPass(quad->render_pass_id); + const cc::FilterOperations* backdrop_filters = + BackdropFiltersForPass(quad->render_pass_id); + // Early out if there are no filters to convert to SkImageFilters + if (!filters && !backdrop_filters) { + return rpdq_params; + } + + // Calculate local matrix that's shared by filters and backdrop_filters + SkMatrix local_matrix; + local_matrix.setTranslate(quad->filters_origin.x(), quad->filters_origin.y()); + local_matrix.postScale(quad->filters_scale.x(), quad->filters_scale.y()); + + gfx::SizeF filter_size(content->width(), content->height()); + + // Convert CC image filters into a SkImageFilter root node + if (filters) { + DCHECK(!filters->IsEmpty()); + auto paint_filter = + cc::RenderSurfaceFilters::BuildImageFilter(*filters, filter_size); + auto sk_filter = paint_filter ? paint_filter->cached_sk_filter_ : nullptr; + + if (sk_filter) { + if (params.opacity != 1.f) { + // Apply opacity as the last step of image filter so it is uniform + // across any overlapping content produced by the image filters. + sk_sp<SkColorFilter> cf = MakeOpacityFilter(params.opacity, nullptr); + sk_filter = SkColorFilterImageFilter::Make(std::move(cf), sk_filter); + } + + // Update the filter bounds based to account for how the image filters + // grow or expand the area touched by drawing. + rpdq_params.filter_bounds = + filters->MapRect(rpdq_params.filter_bounds, local_matrix); + + // If after applying the filter we would be clipped out, skip the draw. + gfx::Rect clip_rect = quad->shared_quad_state->clip_rect; + if (clip_rect.IsEmpty()) { + clip_rect = current_draw_rect_; + } + const gfx::Transform& transform = + quad->shared_quad_state->quad_to_target_transform; + gfx::QuadF clip_quad = gfx::QuadF(gfx::RectF(clip_rect)); + gfx::QuadF local_clip = + cc::MathUtil::InverseMapQuadToLocalSpace(transform, clip_quad); + + rpdq_params.filter_bounds.Intersect( + gfx::ToEnclosingRect(local_clip.BoundingBox())); + // If we've been fully clipped out (by crop rect or clipping), there's + // nothing to draw. + if (rpdq_params.filter_bounds.IsEmpty()) { + return rpdq_params; + } + + rpdq_params.image_filter = sk_filter->makeWithLocalMatrix(local_matrix); } } - // If we need to apply filter, apply opacity as the last step of image filter - // so it is uniform across. - if (filter && quad->shared_quad_state->opacity != 1.f) { - sk_sp<SkColorFilter> cf = - MakeOpacityFilter(quad->shared_quad_state->opacity, nullptr); - filter = SkColorFilterImageFilter::Make(cf, filter); - } + // Convert CC image filters for the backdrop into a SkImageFilter root node + if (backdrop_filters) { + DCHECK(!backdrop_filters->IsEmpty()); + auto paint_filter = cc::RenderSurfaceFilters::BuildImageFilter( + *backdrop_filters, filter_size); + auto sk_backdrop_filter = + paint_filter ? paint_filter->cached_sk_filter_ : nullptr; - // If after applying the filter we would be clipped out, skip the draw. - if (filter) { - gfx::Rect clip_rect = quad->shared_quad_state->clip_rect; - if (clip_rect.IsEmpty()) { - clip_rect = current_draw_rect_; + if (sk_backdrop_filter) { + SkMatrix content_to_dest = SkMatrix::MakeRectToRect( + gfx::RectFToSkRect(quad->tex_coord_rect), + gfx::RectToSkRect(quad->rect), SkMatrix::kFill_ScaleToFit); + content_to_dest.preConcat(local_matrix); + rpdq_params.backdrop_filter = + sk_backdrop_filter->makeWithLocalMatrix(content_to_dest); } - gfx::Transform transform = - quad->shared_quad_state->quad_to_target_transform; - gfx::QuadF clip_quad = gfx::QuadF(gfx::RectF(clip_rect)); - gfx::QuadF local_clip = - cc::MathUtil::InverseMapQuadToLocalSpace(transform, clip_quad); - - SkMatrix local_matrix; - local_matrix.setTranslate(quad->filters_origin.x(), - quad->filters_origin.y()); - local_matrix.postScale(quad->filters_scale.x(), quad->filters_scale.y()); - gfx::RectF dst_rect(params->filters - ? params->filters->MapRect(quad->rect, local_matrix) - : quad->rect); - - dst_rect.Intersect(local_clip.BoundingBox()); - // If we've been fully clipped out (by crop rect or clipping), there's - // nothing to draw. - if (dst_rect.IsEmpty()) - return false; - - params->image_filter = filter->makeWithLocalMatrix(local_matrix); } - return true; + + // Determine if the backdrop filter has its own clip (which only needs to be + // checked when we have a backdrop filter to apply) + if (rpdq_params.backdrop_filter) { + const gfx::RRectF* backdrop_filter_bounds = + BackdropFilterBoundsForPass(quad->render_pass_id); + if (backdrop_filter_bounds) { + // Map this into the same coordinate system as the quad. It is almost + // there, barring the offset, which is equal to the difference in origins + // between the quad->rect and the render pass' output rect. + // (See gl_renderer::GetBackdropBoundingBoxForRenderPassQuad) + rpdq_params.backdrop_filter_bounds = *backdrop_filter_bounds; + rpdq_params.backdrop_filter_bounds->Offset( + quad->rect.origin() - + current_frame()->current_render_pass->output_rect.origin()); + + // If there are also regular image filters, they apply to the area of + // the backdrop_filter_bounds too, so expand the backdrop bounds and join + // it with the main filter bounds. + if (rpdq_params.image_filter) { + gfx::Rect backdrop_rect = + gfx::ToEnclosingRect(rpdq_params.backdrop_filter_bounds->rect()); + rpdq_params.filter_bounds.Union( + filters->MapRect(backdrop_rect, local_matrix)); + } + } + } + + return rpdq_params; } const TileDrawQuad* SkiaRenderer::CanPassBeDrawnDirectly( @@ -1536,8 +1514,7 @@ } void SkiaRenderer::DrawRenderPassQuad(const RenderPassDrawQuad* quad, - SkPaint* paint) { - DCHECK(paint); + const DrawQuadParams& params) { auto bypass = render_pass_bypass_quads_.find(quad->render_pass_id); // When Render Pass has a single quad inside we would draw that directly. if (bypass != render_pass_bypass_quads_.end()) { @@ -1546,8 +1523,8 @@ tile_quad->is_premultiplied ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); - sk_sp<SkImage> content_image = sk_ref_sp(builder.sk_image()); - DrawRenderPassQuadInternal(quad, content_image, paint); + DrawRenderPassQuadInternal(quad, params, builder.sk_image(), + false /* mipmap */); } else { auto iter = render_pass_backings_.find(quad->render_pass_id); DCHECK(render_pass_backings_.end() != iter); @@ -1573,122 +1550,128 @@ } } - // Currently the only trigger for generate_mipmap for render pass is - // trilinear filtering. It only affects GPU backed implementations and thus - // requires medium filter quality level. - if (backing.generate_mipmap) - paint->setFilterQuality(kMedium_SkFilterQuality); - DrawRenderPassQuadInternal(quad, content_image, paint); + DrawRenderPassQuadInternal(quad, params, content_image.get(), + backing.generate_mipmap); } } void SkiaRenderer::DrawRenderPassQuadInternal(const RenderPassDrawQuad* quad, - sk_sp<SkImage> content_image, - SkPaint* paint) { - DCHECK(paint); - DrawRenderPassDrawQuadParams params; - params.filters = FiltersForPass(quad->render_pass_id); - bool can_draw = CalculateRPDQParams(content_image, quad, ¶ms); - - if (!can_draw) + const DrawQuadParams& params, + const SkImage* content_image, + bool needs_mipmap) { + DrawRPDQParams rpdq_params = CalculateRPDQParams(content_image, quad, params); + if (rpdq_params.filter_bounds.IsEmpty()) return; - // Add color filter. - if (params.color_filter) - paint->setColorFilter(params.color_filter); - // Add image filter. - if (params.image_filter) - paint->setImageFilter(params.image_filter); - - // If this render pass has filter, reset paint to opaque. Render Pass should - // apply their opacity as last step, this is done by using a color filter. - // This is required for reflector filter. - if (params.image_filter) - paint->setAlpha(255); - - SkRect content_rect = RectFToSkRect(quad->tex_coord_rect); - SkRect dest_visible_rect = gfx::RectToSkRect(quad->visible_rect); - - // Prepare mask. - ScopedSkImageBuilder mask_image_builder(this, quad->mask_resource_id()); - const SkImage* mask_image = mask_image_builder.sk_image(); - DCHECK_EQ(!!quad->mask_resource_id(), !!mask_image); - SkMatrix mask_to_dest_matrix; - sk_sp<SkMaskFilter> mask_filter; - if (mask_image) { - // Scale normalized uv rect into absolute texel coordinates. - SkRect mask_rect = gfx::RectFToSkRect( - gfx::ScaleRect(quad->mask_uv_rect, quad->mask_texture_size.width(), - quad->mask_texture_size.height())); - mask_to_dest_matrix.setRectToRect(mask_rect, gfx::RectToSkRect(quad->rect), - SkMatrix::kFill_ScaleToFit); - mask_filter = - SkShaderMaskFilter::Make(mask_image->makeShader(&mask_to_dest_matrix)); - DCHECK(mask_filter); - } - - const cc::FilterOperations* backdrop_filters = - BackdropFiltersForPass(quad->render_pass_id); - // Without backdrop effect. - if (!ShouldApplyBackdropFilters(backdrop_filters)) { - if (mask_filter) - paint->setMaskFilter(mask_filter); - - // Draw now that all the filters are set up correctly. - current_canvas_->drawImageRect(content_image, content_rect, - dest_visible_rect, paint); + gfx::RectF vis_tex_coords = cc::MathUtil::ScaleRectProportional( + quad->tex_coord_rect, gfx::RectF(quad->rect), params.visible_rect); + if (!needs_mipmap && !rpdq_params.image_filter && + !rpdq_params.backdrop_filter && !rpdq_params.mask_image) { + // We've checked enough to know that this is a plain textured draw that + // is compatible with any batched images, so preserve that + DCHECK(!MustFlushBatchedQuads(quad, params)); + AddQuadToBatch(params, content_image, vis_tex_coords); return; } - // Draw render pass with backdrop effects. - // Update the backdrop filter to include "regular" filters and opacity. - cc::FilterOperations backdrop_filters_plus_effects = *backdrop_filters; - if (params.filters) { - for (const auto& filter_op : params.filters->operations()) - backdrop_filters_plus_effects.Append(filter_op); - } - if (quad->shared_quad_state->opacity < 1.0) { - backdrop_filters_plus_effects.Append( - cc::FilterOperation::CreateOpacityFilter( - quad->shared_quad_state->opacity)); + // Whether or not there are background filters, the paint itself is complex + // enough that it has to be drawn on its own + if (!batched_quads_.empty()) + FlushBatchedQuads(); + + SkPaint paint = params.paint(); + + // Currently the only trigger for generate_mipmap for render pass is + // trilinear filtering. It only affects GPU backed implementations and thus + // requires medium filter quality level. + if (needs_mipmap) + paint.setFilterQuality(kMedium_SkFilterQuality); + + if (!rpdq_params.image_filter && !rpdq_params.backdrop_filter) { + // When there are no filters, there is no need to save a layer, but we do + // have to incorporate the mask directly into the paint then. + if (rpdq_params.mask_image) { + paint.setMaskFilter( + SkShaderMaskFilter::Make(rpdq_params.mask_image->makeShader( + &rpdq_params.mask_to_quad_matrix))); + DCHECK(paint.getMaskFilter()); + } + DrawSingleImage(params, content_image, vis_tex_coords, &paint); + return; } - auto background_paint_filter = cc::RenderSurfaceFilters::BuildImageFilter( - backdrop_filters_plus_effects, - gfx::SizeF(content_image->width(), content_image->height())); - auto background_image_filter = - background_paint_filter ? background_paint_filter->cached_sk_filter_ - : nullptr; - DCHECK(background_image_filter); - SkMatrix content_to_dest_matrix; - content_to_dest_matrix.setRectToRect( - content_rect, gfx::RectToSkRect(quad->rect), SkMatrix::kFill_ScaleToFit); - SkMatrix local_matrix; - local_matrix.setTranslate(quad->filters_origin.x(), quad->filters_origin.y()); - local_matrix.postScale(quad->filters_scale.x(), quad->filters_scale.y()); - local_matrix.postConcat(content_to_dest_matrix); - background_image_filter = - background_image_filter->makeWithLocalMatrix(local_matrix); + // Use Skia's SaveLayerRec feature to automatically handle backdrop and + // regular image filters, mask clipping, and final layer blending. This will: + // 1. Automatically copy the backbuffer contents (InitWithPrevious flag) + // 2. Automatically apply provided backdrop filter to the image from #1 + // 3. Draw an inverted clip round-rect to zero the filtered backdrop outside + // of the allowed border. + // 4. Draw the main render pass content, but using SrcOver and no opacity + // modification, since we apply the layer's blending at the very end. + // 5. Automatically restore the saved layer, applying the restore paint's + // image filters and opacity to the results of #3. + // - This will also use the given mask's alpha to clip the final blending. - SkAutoCanvasRestore auto_canvas_restore(current_canvas_, true /* do_save */); - current_canvas_->clipRect(gfx::RectToSkRect(quad->rect)); + // Make sure everything is provided in the quad space coordinate system. + SkAutoCanvasRestore acr(current_canvas_, true /* do_save */); + PrepareCanvas(params.scissor_rect, params.rounded_corner_bounds, + ¶ms.content_device_transform); - SkPaint tmp_paint; - tmp_paint.setMaskFilter(mask_filter); - SkCanvas::SaveLayerRec rec(&dest_visible_rect, &tmp_paint, - background_image_filter.get(), - SkCanvas::kInitWithPrevious_SaveLayerFlag); - // Lift content in the current_canvas_ into a new layer with - // background_image_filter, and then paint content_image in the layer, - // and then the current_canvas_->restore() will drop the layer into the - // canvas. - SkAutoCanvasRestore auto_canvas_restore_for_save_layer(current_canvas_, - false /* do_save */); - current_canvas_->saveLayer(rec); - // TODO(916317): need to draw the backdrop once first here. Also need to - // pull the backdrop-filter bounds rect in and clip the backdrop image. - current_canvas_->drawImageRect(content_image, content_rect, dest_visible_rect, - paint); + // saveLayer automatically respects the clip when it is restored, and + // automatically reads beyond the clip for its backdrop filtered content. + // However, since Chromium does not want image-filtered content (ex. blurs) to + // be clipped to the visible_rect of the RPDQ, configure the clip to be the + // expanded bounds that encloses the entire filtered content. + SkRect bounds = gfx::RectToSkRect(rpdq_params.filter_bounds); + current_canvas_->clipRect(bounds, paint.isAntiAlias()); + + // Add the image filter to the restoration paint. + if (rpdq_params.image_filter) { + paint.setImageFilter(rpdq_params.image_filter); + // Reset paint to opaque. Render Pass should apply their opacity as last + // step, so the opacity is built into the image filter. + paint.setAlphaf(1.f); + } + + // Save the layer with the restoration paint (which holds the final image + // filters and blending parameters), the backdrop filters, and mask image. + SkCanvas::SaveLayerFlags layer_flags = 0; + if (rpdq_params.backdrop_filter) { + layer_flags |= SkCanvas::kInitWithPrevious_SaveLayerFlag; + } + current_canvas_->saveLayer( + SkCanvas::SaveLayerRec(&bounds, &paint, rpdq_params.backdrop_filter.get(), + rpdq_params.mask_image.get(), + &rpdq_params.mask_to_quad_matrix, layer_flags)); + + if (rpdq_params.backdrop_filter_bounds.has_value()) { + // The initial contents of saved layer is all of the background within + // |bounds| filtered by the backdrop filters. Must set all pixels outside + // of the border rrect to transparent black. This cannot simply be a clip + // when the layer is restored since this rrect should not clip the rest + // of the render pass content. + current_canvas_->save(); + current_canvas_->clipRRect(SkRRect(*rpdq_params.backdrop_filter_bounds), + SkClipOp::kDifference, paint.isAntiAlias()); + current_canvas_->clear(SK_ColorTRANSPARENT); + current_canvas_->restore(); + } + + // Now draw the main content using the same per-edge AA API to be consistent + // with DrawSingleImage. Use a new paint that defaults to opaque+src-over, + // and just preserve the filter quality from the original paint. + SkPaint content_paint; + content_paint.setFilterQuality(paint.getFilterQuality()); + + SkCanvas::ImageSetEntry entry = + MakeEntry(params, content_image, vis_tex_coords, -1, + false /* use params.opacity */); + const SkPoint* draw_region = + params.draw_region.has_value() ? params.draw_region->points : nullptr; + current_canvas_->experimental_DrawEdgeAAImageSet(&entry, 1, draw_region, + nullptr, &content_paint); + + // And the saved layer will be auto-restored when |acr| is destructed } void SkiaRenderer::CopyDrawnRenderPass( @@ -1756,14 +1739,6 @@ // RenderPassDrawQuad is what actually generates generate_mipmap. } -bool SkiaRenderer::ShouldApplyBackdropFilters( - const cc::FilterOperations* backdrop_filters) const { - if (!backdrop_filters) - return false; - DCHECK(!backdrop_filters->IsEmpty()); - return true; -} - GrContext* SkiaRenderer::GetGrContext() { switch (draw_mode_) { case DrawMode::DDL:
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h index 465e515..f189d38 100644 --- a/components/viz/service/display/skia_renderer.h +++ b/components/viz/service/display/skia_renderer.h
@@ -90,36 +90,26 @@ private: struct DrawQuadParams; - struct DrawRenderPassDrawQuadParams; + struct DrawRPDQParams; class ScopedSkImageBuilder; class ScopedYUVSkImageBuilder; void ClearCanvas(SkColor color); void ClearFramebuffer(); - // TODO(michaelludwig): - // The majority of quad types need to be updated to call the new experimental - // SkCanvas APIs, which changes what is needed for canvas prep. This is the - // old implementation of DoDrawQuad and types will be migrated individually - // to the new system and handled directly in the new DoDrawQuad definition, - // after which this function can be removed. - void DoSingleDrawQuad(const DrawQuad* quad, - const gfx::QuadF* draw_region, - const DrawQuadParams& params); - - void PrepareCanvasForDrawQuads( - gfx::Transform quad_to_target_transform, - const gfx::QuadF* draw_region, - const gfx::Rect* scissor_rect, - const gfx::RRectF* rounded_corner_bounds, - base::Optional<SkAutoCanvasRestore>* auto_canvas_restore); // Callers should init an SkAutoCanvasRestore before calling this function. - void PrepareCanvas(const gfx::Rect* scissor_rect, - const gfx::RRectF* rounded_corner_bounds, + // |scissor_rect| and |rounded_corner_bounds| should be in device space, + // i.e. same space that |cdt| will transform subsequent draws into. + void PrepareCanvas(const base::Optional<gfx::Rect>& scissor_rect, + const base::Optional<gfx::RRectF>& rounded_corner_bounds, const gfx::Transform* cdt); DrawQuadParams CalculateDrawQuadParams(const DrawQuad* quad, const gfx::QuadF* draw_region); + DrawRPDQParams CalculateRPDQParams(const SkImage* src_image, + const RenderPassDrawQuad* quad, + const DrawQuadParams& params); + SkCanvas::ImageSetEntry MakeEntry(const DrawQuadParams& params, const SkImage* image, const gfx::RectF& src, @@ -149,11 +139,12 @@ const DrawQuadParams& params); void DrawPictureQuad(const PictureDrawQuad* quad, const DrawQuadParams& params); - void DrawRenderPassQuad(const RenderPassDrawQuad* quad, SkPaint* paint); + void DrawRenderPassQuad(const RenderPassDrawQuad* quad, + const DrawQuadParams& params); void DrawRenderPassQuadInternal(const RenderPassDrawQuad* quad, - sk_sp<SkImage> content_image, - SkPaint* paint); - + const DrawQuadParams& params, + const SkImage* content_image, + bool needs_mipmap); void DrawSolidColorQuad(const SolidColorDrawQuad* quad, const DrawQuadParams& state); @@ -166,11 +157,6 @@ const DrawQuadParams& params); void DrawUnsupportedQuad(const DrawQuad* quad, const DrawQuadParams& params); - bool CalculateRPDQParams(sk_sp<SkImage> src_image, - const RenderPassDrawQuad* quad, - DrawRenderPassDrawQuadParams* params); - bool ShouldApplyBackdropFilters( - const cc::FilterOperations* backdrop_filters) const; const TileDrawQuad* CanPassBeDrawnDirectly(const RenderPass* pass) override; // Get corresponding GrContext. Returns nullptr when there is no GrContext. @@ -235,11 +221,12 @@ // State common to all quads in a batch. Draws that require an SkPaint not // captured by this state cannot be batched. struct BatchedQuadState { - gfx::Rect scissor_rect; + base::Optional<gfx::Rect> scissor_rect; + base::Optional<gfx::RRectF> rounded_corner_bounds; SkBlendMode blend_mode; SkFilterQuality filter_quality; - bool has_scissor_rect; - const gfx::RRectF* rounded_corner_bounds; + + BatchedQuadState(); }; BatchedQuadState batched_quad_state_; std::vector<SkCanvas::ImageSetEntry> batched_quads_;
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index baf9f95..c27711c6 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -1492,6 +1492,19 @@ } } +base::string16 BrowserAccessibility::GetStyleNameAttributeAsLocalizedString() + const { + const BrowserAccessibility* current_node = this; + while (current_node) { + if (current_node->GetData().role == ax::mojom::Role::kMark) { + const ContentClient* content_client = content::GetContentClient(); + return content_client->GetLocalizedString(IDS_AX_ROLE_MARK); + } + current_node = current_node->PlatformGetParent(); + } + return {}; +} + bool BrowserAccessibility::ShouldIgnoreHoveredStateForTesting() { BrowserAccessibilityStateImpl* accessibility_state = BrowserAccessibilityStateImpl::GetInstance();
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h index b4b9189e..4f884f7 100644 --- a/content/browser/accessibility/browser_accessibility.h +++ b/content/browser/accessibility/browser_accessibility.h
@@ -427,6 +427,7 @@ ax::mojom::ImageAnnotationStatus status) const override; base::string16 GetLocalizedRoleDescriptionForUnlabeledImage() const override; base::string16 GetLocalizedStringForLandmarkType() const override; + base::string16 GetStyleNameAttributeAsLocalizedString() const override; bool ShouldIgnoreHoveredStateForTesting() override; bool IsOffscreen() const override; bool IsWebContent() const override;
diff --git a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc index cebad7e..a34d8ab9 100644 --- a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc +++ b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
@@ -564,6 +564,59 @@ } IN_PROC_BROWSER_TEST_F(CrossPlatformAccessibilityBrowserTest, + GetStyleNameAttributeAsLocalizedString) { + AccessibilityNotificationWaiter waiter(shell()->web_contents(), + ui::kAXModeComplete, + ax::mojom::Event::kLoadComplete); + GURL url( + "data:text/html," + "<!doctype html>" + "<p>text <mark>mark text</mark></p>"); + + NavigateToURL(shell(), url); + waiter.WaitForNotification(); + + BrowserAccessibility* root = GetManager()->GetRoot(); + ASSERT_NE(nullptr, root); + ASSERT_EQ(1u, root->PlatformChildCount()); + + auto TestGetStyleNameAttributeAsLocalizedString = + [](BrowserAccessibility* node, ax::mojom::Role expected_role, + const base::string16& expected_localized_style_name_attribute = {}) { + ASSERT_NE(nullptr, node); + + EXPECT_EQ(expected_role, node->GetRole()); + EXPECT_EQ(expected_localized_style_name_attribute, + node->GetStyleNameAttributeAsLocalizedString()); + }; + + // For testing purposes, assume we get en-US localized strings. + BrowserAccessibility* para_node = root->PlatformGetChild(0); + ASSERT_EQ(2u, para_node->PlatformChildCount()); + TestGetStyleNameAttributeAsLocalizedString(para_node, + ax::mojom::Role::kParagraph); + + BrowserAccessibility* text_node = para_node->PlatformGetChild(0); + ASSERT_EQ(0u, text_node->PlatformChildCount()); + TestGetStyleNameAttributeAsLocalizedString(text_node, + ax::mojom::Role::kStaticText); + + BrowserAccessibility* mark_node = para_node->PlatformGetChild(1); + TestGetStyleNameAttributeAsLocalizedString( + mark_node, ax::mojom::Role::kMark, + base::ASCIIToUTF16("highlighted content")); + + // Android doesn't always have a child in this case. + if (mark_node->PlatformChildCount() > 0) { + BrowserAccessibility* mark_text_node = mark_node->PlatformGetChild(0); + ASSERT_EQ(0u, mark_text_node->PlatformChildCount()); + TestGetStyleNameAttributeAsLocalizedString( + mark_text_node, ax::mojom::Role::kStaticText, + base::ASCIIToUTF16("highlighted content")); + } +} + +IN_PROC_BROWSER_TEST_F(CrossPlatformAccessibilityBrowserTest, TooltipStringAttributeMutuallyExclusiveOfNameFromTitle) { const char url_str[] = "data:text/html,"
diff --git a/content/browser/android/content_startup_flags.cc b/content/browser/android/content_startup_flags.cc index 6d1a3a5..680ae76 100644 --- a/content/browser/android/content_startup_flags.cc +++ b/content/browser/android/content_startup_flags.cc
@@ -34,7 +34,6 @@ parsed_command_line->AppendSwitch(switches::kSingleProcess); } - parsed_command_line->AppendSwitch(switches::kEnablePinch); parsed_command_line->AppendSwitch(switches::kEnableViewport); parsed_command_line->AppendSwitch(switches::kValidateInputEventStream);
diff --git a/content/browser/devtools/devtools_network_interceptor.h b/content/browser/devtools/devtools_network_interceptor.h index d92b1f2..ca735f4 100644 --- a/content/browser/devtools/devtools_network_interceptor.h +++ b/content/browser/devtools/devtools_network_interceptor.h
@@ -32,7 +32,7 @@ bool is_navigation; int response_error_code; std::unique_ptr<protocol::Network::Request> network_request; - scoped_refptr<net::AuthChallengeInfo> auth_challenge; + std::unique_ptr<net::AuthChallengeInfo> auth_challenge; scoped_refptr<net::HttpResponseHeaders> response_headers; protocol::Maybe<bool> is_download; protocol::Maybe<protocol::String> redirect_url;
diff --git a/content/browser/devtools/devtools_url_interceptor_request_job.cc b/content/browser/devtools/devtools_url_interceptor_request_job.cc index 6ce7f431..32cff2f 100644 --- a/content/browser/devtools/devtools_url_interceptor_request_job.cc +++ b/content/browser/devtools/devtools_url_interceptor_request_job.cc
@@ -53,7 +53,7 @@ // net::URLRequest::Delegate methods: void OnAuthRequired(net::URLRequest* request, - net::AuthChallengeInfo* auth_info) override; + const net::AuthChallengeInfo& auth_info) override; void OnCertificateRequested( net::URLRequest* request, net::SSLCertRequestInfo* cert_request_info) override; @@ -188,7 +188,7 @@ void DevToolsURLInterceptorRequestJob::SubRequest::OnAuthRequired( net::URLRequest* request, - net::AuthChallengeInfo* auth_info) { + const net::AuthChallengeInfo& auth_info) { devtools_interceptor_request_job_->OnSubRequestAuthRequired(auth_info); } @@ -706,9 +706,10 @@ return !!auth_info_; } -void DevToolsURLInterceptorRequestJob::GetAuthChallengeInfo( - scoped_refptr<net::AuthChallengeInfo>* auth_info) { - *auth_info = auth_info_.get(); +std::unique_ptr<net::AuthChallengeInfo> +DevToolsURLInterceptorRequestJob::GetAuthChallengeInfo() { + DCHECK(auth_info_); + return std::make_unique<net::AuthChallengeInfo>(*auth_info_); } void DevToolsURLInterceptorRequestJob::SetAuth( @@ -723,8 +724,8 @@ } void DevToolsURLInterceptorRequestJob::OnSubRequestAuthRequired( - net::AuthChallengeInfo* auth_info) { - auth_info_ = auth_info; + const net::AuthChallengeInfo& auth_info) { + auth_info_ = std::make_unique<net::AuthChallengeInfo>(auth_info); if (stage_to_intercept_ == InterceptionStage::DONT_INTERCEPT) { // This should trigger default auth behavior. @@ -741,7 +742,8 @@ waiting_for_user_response_ = WaitingForUserResponse::WAITING_FOR_AUTH_ACK; std::unique_ptr<InterceptedRequestInfo> request_info = BuildRequestInfo(); - request_info->auth_challenge = auth_info; + request_info->auth_challenge = + std::make_unique<net::AuthChallengeInfo>(auth_info); base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, base::BindOnce(callback_, std::move(request_info))); }
diff --git a/content/browser/devtools/devtools_url_interceptor_request_job.h b/content/browser/devtools/devtools_url_interceptor_request_job.h index f8ed00c..7a22e70e1 100644 --- a/content/browser/devtools/devtools_url_interceptor_request_job.h +++ b/content/browser/devtools/devtools_url_interceptor_request_job.h
@@ -53,8 +53,7 @@ bool GetCharset(std::string* charset) override; void GetLoadTimingInfo(net::LoadTimingInfo* load_timing_info) const override; bool NeedsAuth() override; - void GetAuthChallengeInfo( - scoped_refptr<net::AuthChallengeInfo>* auth_info) override; + std::unique_ptr<net::AuthChallengeInfo> GetAuthChallengeInfo() override; void SetAuth(const net::AuthCredentials& credentials) override; void CancelAuth() override; @@ -117,7 +116,7 @@ const net::CookieStatusList& excluded_cookies); // Callbacks from SubRequest. - void OnSubRequestAuthRequired(net::AuthChallengeInfo* auth_info); + void OnSubRequestAuthRequired(const net::AuthChallengeInfo& auth_info); void OnSubRequestRedirectReceived(const net::URLRequest& request, const net::RedirectInfo& redirectinfo, bool* defer_redirect); @@ -152,7 +151,7 @@ std::unique_ptr<MockResponseDetails> mock_response_details_; std::unique_ptr<net::RedirectInfo> redirect_; WaitingForUserResponse waiting_for_user_response_; - scoped_refptr<net::AuthChallengeInfo> auth_info_; + std::unique_ptr<net::AuthChallengeInfo> auth_info_; const std::string interception_id_; const intptr_t owning_entry_id_;
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.cc b/content/browser/devtools/devtools_url_loader_interceptor.cc index 65af691..716d0de 100644 --- a/content/browser/devtools/devtools_url_loader_interceptor.cc +++ b/content/browser/devtools/devtools_url_loader_interceptor.cc
@@ -203,7 +203,7 @@ void Detach(); void OnAuthRequest( - const scoped_refptr<net::AuthChallengeInfo>& auth_info, + const net::AuthChallengeInfo& auth_info, DevToolsURLLoaderInterceptor::HandleAuthRequestCallback callback); private: @@ -583,7 +583,7 @@ int32_t process_id, int32_t routing_id, int32_t request_id, - const scoped_refptr<net::AuthChallengeInfo>& auth_info, + const net::AuthChallengeInfo& auth_info, HandleAuthRequestCallback callback) { GlobalRequestId req_id = std::make_tuple(process_id, routing_id, request_id); if (auto* job = InterceptionJob::FindByRequestId(req_id)) @@ -1411,7 +1411,7 @@ } void InterceptionJob::OnAuthRequest( - const scoped_refptr<net::AuthChallengeInfo>& auth_info, + const net::AuthChallengeInfo& auth_info, DevToolsURLLoaderInterceptor::HandleAuthRequestCallback callback) { DCHECK_EQ(kRequestSent, state_); DCHECK(pending_auth_callback_.is_null()); @@ -1424,7 +1424,8 @@ } state_ = State::kAuthRequired; auto request_info = BuildRequestInfo(nullptr); - request_info->auth_challenge = auth_info; + request_info->auth_challenge = + std::make_unique<net::AuthChallengeInfo>(auth_info); pending_auth_callback_ = std::move(callback); NotifyClient(std::move(request_info)); }
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.h b/content/browser/devtools/devtools_url_loader_interceptor.h index d4a9ab6c..24813a9 100644 --- a/content/browser/devtools/devtools_url_loader_interceptor.h +++ b/content/browser/devtools/devtools_url_loader_interceptor.h
@@ -21,12 +21,11 @@ base::OnceCallback<void(bool use_fallback, const base::Optional<net::AuthCredentials>&)>; // Can only be called on the IO thread. - static void HandleAuthRequest( - int32_t process_id, - int32_t routing_id, - int32_t request_id, - const scoped_refptr<net::AuthChallengeInfo>& auth_info, - HandleAuthRequestCallback callback); + static void HandleAuthRequest(int32_t process_id, + int32_t routing_id, + int32_t request_id, + const net::AuthChallengeInfo& auth_info, + HandleAuthRequestCallback callback); explicit DevToolsURLLoaderInterceptor( DevToolsNetworkInterceptor::RequestInterceptedCallback callback);
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index d2f4e37..35a4ebf 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -1001,7 +1001,7 @@ const FrameHostMsg_DidCommitProvisionalLoad_Params& params, LoadCommittedDetails* details, bool is_same_document_navigation, - bool previous_page_was_activated, + bool previous_document_was_activated, NavigationRequest* navigation_request) { DCHECK(navigation_request); is_initial_navigation_ = false; @@ -1105,7 +1105,7 @@ case NAVIGATION_TYPE_NEW_PAGE: RendererDidNavigateToNewPage( rfh, params, details->is_same_document, details->did_replace_entry, - previous_page_was_activated, navigation_handle); + previous_document_was_activated, navigation_handle); break; case NAVIGATION_TYPE_EXISTING_PAGE: RendererDidNavigateToExistingPage(rfh, params, details->is_same_document, @@ -1117,8 +1117,9 @@ navigation_handle); break; case NAVIGATION_TYPE_NEW_SUBFRAME: - RendererDidNavigateNewSubframe(rfh, params, details->is_same_document, - details->did_replace_entry); + RendererDidNavigateNewSubframe( + rfh, params, details->is_same_document, details->did_replace_entry, + previous_document_was_activated, navigation_handle); break; case NAVIGATION_TYPE_AUTO_SUBFRAME: if (!RendererDidNavigateAutoSubframe(rfh, params)) { @@ -1364,7 +1365,7 @@ const FrameHostMsg_DidCommitProvisionalLoad_Params& params, bool is_same_document, bool replace_entry, - bool previous_page_was_activated, + bool previous_document_was_activated, NavigationHandleImpl* handle) { std::unique_ptr<NavigationEntryImpl> new_entry; bool update_virtual_url = false; @@ -1521,30 +1522,9 @@ last_committed_entry_index_ = pending_entry_index_; } - // The previous page that started this navigation needs to be skipped in - // subsequent back/forward UI navigations if it never received any user - // gesture. This is to intervene against pages that manipulate the history - // such that the user is not able to go back to the last site they interacted - // with (crbug.com/907167). - if (!replace_entry && !previous_page_was_activated && - last_committed_entry_index_ != -1 && handle->IsRendererInitiated()) { - GetLastCommittedEntry()->set_should_skip_on_back_forward_ui(true); - UMA_HISTOGRAM_BOOLEAN("Navigation.BackForward.SetShouldSkipOnBackForwardUI", - true); - - // Log UKM with the URL of the page we are navigating away from. Note that - // GetUkmSourceIdForLastCommittedSource looks into the WebContents to get - // the last committed source. Since WebContents has not yet been updated - // with the current URL being committed, this should give the correct source - // even though |rfh| here belongs to the current navigation. - ukm::SourceId source_id = rfh->delegate() - ->GetUkmSourceIdForLastCommittedSource(); - ukm::builders::HistoryManipulationIntervention(source_id).Record( - ukm::UkmRecorder::Get()); - } else if (last_committed_entry_index_ != -1) { - UMA_HISTOGRAM_BOOLEAN("Navigation.BackForward.SetShouldSkipOnBackForwardUI", - false); - } + SetShouldSkipOnBackForwardUIIfNeeded(rfh, replace_entry, + previous_document_was_activated, + handle->IsRendererInitiated()); InsertOrReplaceEntry(std::move(new_entry), replace_entry); } @@ -1785,7 +1765,9 @@ RenderFrameHostImpl* rfh, const FrameHostMsg_DidCommitProvisionalLoad_Params& params, bool is_same_document, - bool replace_entry) { + bool replace_entry, + bool previous_document_was_activated, + NavigationHandleImpl* handle) { DCHECK(ui::PageTransitionCoreTypeIs(params.transition, ui::PAGE_TRANSITION_MANUAL_SUBFRAME)); @@ -1815,6 +1797,10 @@ frame_entry.get(), is_same_document, rfh->frame_tree_node(), delegate_->GetFrameTree()->root()); + SetShouldSkipOnBackForwardUIIfNeeded(rfh, replace_entry, + previous_document_was_activated, + handle->IsRendererInitiated()); + // TODO(creis): Update this to add the frame_entry if we can't find the one // to replace, which can happen due to a unique name change. See // https://crbug.com/607205. For now, frame_entry will be deleted when it @@ -2153,6 +2139,8 @@ // When a user activation occurs, ensure that all adjacent entries for the // same document clear their skippable bit, so that the history manipulation // intervention does not apply to them. + // TODO(crbug.com/949279) in case it becomes necessary for resetting based on + // which frame created an entry and which frame has the user gesture. auto* last_committed_entry = GetLastCommittedEntry(); if (!last_committed_entry) return; @@ -3453,4 +3441,39 @@ delegate_->NotifyNavigationEntryCommitted(details); } +// History manipulation intervention: +void NavigationControllerImpl::SetShouldSkipOnBackForwardUIIfNeeded( + RenderFrameHostImpl* rfh, + bool replace_entry, + bool previous_document_was_activated, + bool is_renderer_initiated) { + // Note that for a subframe navigation, previous_document_was_activated is + // false if there has been any user gesture on an ancestor frame but not on + // the subframe doing the navigation. + if (replace_entry || previous_document_was_activated || + !is_renderer_initiated) { + if (last_committed_entry_index_ != -1) { + UMA_HISTOGRAM_BOOLEAN( + "Navigation.BackForward.SetShouldSkipOnBackForwardUI", false); + } + return; + } + if (last_committed_entry_index_ == -1) + return; + + GetLastCommittedEntry()->set_should_skip_on_back_forward_ui(true); + UMA_HISTOGRAM_BOOLEAN("Navigation.BackForward.SetShouldSkipOnBackForwardUI", + true); + + // Log UKM with the URL we are navigating away from. Note that + // GetUkmSourceIdForLastCommittedSource looks into the WebContents to get + // the last committed source. Since WebContents has not yet been updated + // with the current URL being committed, this should give the correct source + // even though |rfh| here belongs to the current navigation. + ukm::SourceId source_id = + rfh->delegate()->GetUkmSourceIdForLastCommittedSource(); + ukm::builders::HistoryManipulationIntervention(source_id).Record( + ukm::UkmRecorder::Get()); +} + } // namespace content
diff --git a/content/browser/frame_host/navigation_controller_impl.h b/content/browser/frame_host/navigation_controller_impl.h index f9ecb1c..bab46163 100644 --- a/content/browser/frame_host/navigation_controller_impl.h +++ b/content/browser/frame_host/navigation_controller_impl.h
@@ -164,7 +164,7 @@ // In the case that nothing has changed, the details structure is undefined // and it will return false. // - // |previous_page_was_activated| is true if the previous page had user + // |previous_document_was_activated| is true if the previous document had user // interaction. This is used for a new renderer-initiated navigation to decide // if the page that initiated the navigation should be skipped on // back/forward button. @@ -173,7 +173,7 @@ const FrameHostMsg_DidCommitProvisionalLoad_Params& params, LoadCommittedDetails* details, bool is_same_document_navigation, - bool previous_page_was_activated, + bool previous_document_was_activated, NavigationRequest* navigation_request); // Notifies us that we just became active. This is used by the WebContentsImpl @@ -383,7 +383,7 @@ const FrameHostMsg_DidCommitProvisionalLoad_Params& params, bool is_same_document, bool replace_entry, - bool previous_page_was_activated, + bool previous_document_was_activated, NavigationHandleImpl* handle); void RendererDidNavigateToExistingPage( RenderFrameHostImpl* rfh, @@ -401,7 +401,9 @@ RenderFrameHostImpl* rfh, const FrameHostMsg_DidCommitProvisionalLoad_Params& params, bool is_same_document, - bool replace_entry); + bool replace_entry, + bool previous_document_was_activated, + NavigationHandleImpl* handle); bool RendererDidNavigateAutoSubframe( RenderFrameHostImpl* rfh, const FrameHostMsg_DidCommitProvisionalLoad_Params& params); @@ -461,6 +463,21 @@ // This updates the URL bar and the history buttons. void CommitRestoreFromBackForwardCache(); + // History Manipulation intervention: + // The previous document that started this navigation needs to be skipped in + // subsequent back/forward UI navigations if it never received any user + // gesture. This is to intervene against pages that manipulate the history + // such that the user is not able to go back to the last site they interacted + // with (crbug.com/907167). + // Note that this function must be called before the new navigation entry is + // inserted in |entries_| to make sure UKM reports the URL of the document + // adding the entry. + void SetShouldSkipOnBackForwardUIIfNeeded( + RenderFrameHostImpl* rfh, + bool replace_entry, + bool previous_document_was_activated, + bool is_renderer_initiated); + // --------------------------------------------------------------------------- // The user browser context associated with this controller.
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc index c53bf6ad..387584c1 100644 --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -9276,6 +9276,81 @@ "Navigation.BackForward.SetShouldSkipOnBackForwardUI", true, 1); } +// Tests that the navigation entry is marked as skippable on back/forward +// button if a subframe does a push state without ever getting a user +// activation. +IN_PROC_BROWSER_TEST_F(NavigationControllerHistoryInterventionBrowserTest, + NoUserActivationSetSkipOnBackForwardSubframe) { + base::HistogramTester histograms; + + GURL non_skippable_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), non_skippable_url)); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetFrameTree() + ->root(); + + GURL skippable_url( + embedded_test_server()->GetURL("/frame_tree/page_with_one_frame.html")); + EXPECT_TRUE(NavigateToURL(shell(), skippable_url)); + + EXPECT_FALSE(root->HasBeenActivated()); + EXPECT_FALSE(root->HasTransientUserActivation()); + + // Simulate user gesture in the main frame. Cross origin subframes creating + // entries without user gesture will still lead to the last committed entry + // being marked as skippable. + root->UpdateUserActivationState( + blink::UserActivationUpdateType::kNotifyActivation); + EXPECT_TRUE(root->HasBeenActivated()); + EXPECT_TRUE(root->HasTransientUserActivation()); + + // Invoke pushstate from a subframe. + std::string script = "history.pushState({}, 'page 1', 'simple_page_1.html')"; + EXPECT_TRUE(ExecuteScriptWithoutUserGesture(root->child_at(0), script)); + + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(2, controller.GetCurrentEntryIndex()); + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); + + EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_TRUE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); + histograms.ExpectBucketCount( + "Navigation.BackForward.SetShouldSkipOnBackForwardUI", true, 1); + + EXPECT_TRUE(controller.CanGoBack()); + + // Attempt to go back or forward to the skippable entry should log the + // corresponding histogram and skip the corresponding entry. + TestNavigationObserver back_load_observer(shell()->web_contents()); + controller.GoBack(); + back_load_observer.Wait(); + histograms.ExpectBucketCount("Navigation.BackForward.BackTargetSkipped", 1, + 1); + EXPECT_EQ(non_skippable_url, controller.GetLastCommittedEntry()->GetURL()); + EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); + + // Go forward to the 3rd entry. + TestNavigationObserver load_observer(shell()->web_contents()); + controller.GoToIndex(2); + load_observer.Wait(); + + // A user gesture even in the main frame now will lead to all same document + // entries to be marked as non-skippable. This is an inconsistency but the + // other option of tracking which entries to reset based on which frame was + // activated seems unnecessarily complex. + root->UpdateUserActivationState( + blink::UserActivationUpdateType::kNotifyActivation); + EXPECT_TRUE(root->HasBeenActivated()); + EXPECT_TRUE(root->HasTransientUserActivation()); + EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(1)->should_skip_on_back_forward_ui()); + EXPECT_FALSE(controller.GetEntryAtIndex(2)->should_skip_on_back_forward_ui()); +} + // Tests that a same document navigation followed by a client redirect // do not add any more session history entries and going to previous entry // works.
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc index 5eb56c0..8ef7d20 100644 --- a/content/browser/frame_host/navigation_controller_impl_unittest.cc +++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -1273,19 +1273,19 @@ const GURL url1("http://foo1"); - controller.LoadURL( - url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); - int entry_id = controller.GetPendingEntry()->GetUniqueID(); + auto navigation = + NavigationSimulator::CreateBrowserInitiated(url1, contents()); + navigation->Start(); EXPECT_EQ(0U, navigation_entry_changed_counter_); EXPECT_EQ(0U, navigation_list_pruned_counter_); - main_test_rfh()->PrepareForCommit(); - main_test_rfh()->SendNavigate(entry_id, true, url1); + navigation->Commit(); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; ASSERT_TRUE(controller.GetVisibleEntry()); - entry_id = controller.GetLastCommittedEntry()->GetUniqueID(); controller.Reload(ReloadType::NORMAL, true); + navigation = NavigationSimulator::CreateFromPending( + RenderViewHostTestHarness::web_contents()); EXPECT_EQ(0U, navigation_entry_changed_counter_); EXPECT_EQ(0U, navigation_list_pruned_counter_); @@ -1301,8 +1301,7 @@ EXPECT_FALSE(controller.CanGoBack()); EXPECT_FALSE(controller.CanGoForward()); - main_test_rfh()->PrepareForCommit(); - main_test_rfh()->SendNavigate(entry_id, false, url1); + navigation->Commit(); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1379,32 +1378,22 @@ EXPECT_EQ(entry1, entry2); } -namespace { -void SetOriginalURL(const GURL& url, - FrameHostMsg_DidCommitProvisionalLoad_Params* params) { - params->original_request_url = url; -} -} - TEST_F(NavigationControllerTest, ReloadOriginalRequestURL) { NavigationControllerImpl& controller = controller_impl(); const GURL original_url("http://foo1"); const GURL final_url("http://foo2"); - auto set_original_url_callback = base::Bind(SetOriginalURL, original_url); // Load up the original URL, but get redirected. - controller.LoadURL( - original_url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); - int entry_id = controller.GetPendingEntry()->GetUniqueID(); + auto navigation = + NavigationSimulator::CreateBrowserInitiated(original_url, contents()); + navigation->Start(); EXPECT_EQ(0U, navigation_entry_changed_counter_); EXPECT_EQ(0U, navigation_list_pruned_counter_); - main_test_rfh()->PrepareForCommitWithServerRedirect(final_url); - main_test_rfh()->SendNavigateWithModificationCallback( - entry_id, true, final_url, std::move(set_original_url_callback)); + navigation->Redirect(final_url); + navigation->Commit(); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; - entry_id = controller.GetLastCommittedEntry()->GetUniqueID(); // The NavigationEntry should save both the original URL and the final // redirected URL. @@ -1428,8 +1417,10 @@ EXPECT_FALSE(controller.CanGoForward()); // Send that the navigation has proceeded; say it got redirected again. - main_test_rfh()->PrepareForCommitWithServerRedirect(final_url); - main_test_rfh()->SendNavigate(entry_id, false, final_url); + navigation = NavigationSimulator::CreateFromPending( + RenderViewHostTestHarness::web_contents()); + navigation->Redirect(final_url); + navigation->Commit(); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -2301,7 +2292,7 @@ EXPECT_EQ(url3, entry3->root_node()->children[0]->frame_entry->url()); // Go back one. - controller.GoBack(); + controller.GoToOffset(-1); params.nav_entry_id = entry2->GetUniqueID(); params.did_create_new_entry = false; params.url = url2; @@ -2326,7 +2317,7 @@ EXPECT_FALSE(controller.GetPendingEntry()); // Go back one more. - controller.GoBack(); + controller.GoToOffset(-1); params.nav_entry_id = entry1->GetUniqueID(); params.did_create_new_entry = false; params.url = subframe_url;
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index 7802415..af289a0 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -221,7 +221,7 @@ // Save the activation status of the previous page here before it gets reset // in FrameTreeNode::ResetForNavigation. - bool previous_page_was_activated = frame_tree_node->HasBeenActivated(); + bool previous_document_was_activated = frame_tree_node->HasBeenActivated(); // Navigating to a new location means a new, fresh set of http headers and/or // <meta> elements - we need to reset CSP and Feature Policy. @@ -258,7 +258,7 @@ LoadCommittedDetails details; bool did_navigate = controller_->RendererDidNavigate( render_frame_host, params, &details, is_same_document_navigation, - previous_page_was_activated, navigation_request.get()); + previous_document_was_activated, navigation_request.get()); // If the history length and/or offset changed, update other renderers in the // FrameTree.
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 1d9c1f5..89c2fbd6 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1016,14 +1016,6 @@ return *overlay_routing_token_; } -void RenderFrameHostImpl::DidCommitNavigationForTesting( - NavigationRequest* navigation_request, - std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params, - mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params) { - DidCommitNavigation(navigation_request, std::move(params), - std::move(interface_params)); -} - void RenderFrameHostImpl::AudioContextPlaybackStarted(int audio_context_id) { delegate_->AudioContextPlaybackStarted(this, audio_context_id); } @@ -2163,7 +2155,7 @@ mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params) { if (MaybeInterceptCommitCallback(nullptr, validated_params.get(), &interface_params)) { - DidCommitNavigation(nullptr /* committing_navigation_request */, + DidCommitNavigation(std::move(navigation_request_), std::move(validated_params), std::move(interface_params)); } @@ -2176,12 +2168,22 @@ mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params) { DCHECK(committing_navigation_request); committing_navigation_request->IgnoreCommitInterfaceDisconnection(); - if (MaybeInterceptCommitCallback(committing_navigation_request, - validated_params.get(), &interface_params)) { - DidCommitNavigation(committing_navigation_request, - std::move(validated_params), - std::move(interface_params)); + if (!MaybeInterceptCommitCallback(committing_navigation_request, + validated_params.get(), + &interface_params)) { + return; } + + auto request = navigation_requests_.find(committing_navigation_request); + + // The committing request should be in the map of NavigationRequests for + // this RenderFrameHost. + CHECK(request != navigation_requests_.end()); + + std::unique_ptr<NavigationRequest> owned_request = std::move(request->second); + navigation_requests_.erase(committing_navigation_request); + DidCommitNavigation(std::move(owned_request), std::move(validated_params), + std::move(interface_params)); } void RenderFrameHostImpl::DidCommitSameDocumentNavigation( @@ -2208,12 +2210,16 @@ "frame_tree_node", frame_tree_node_->frame_tree_node_id(), "url", validated_params->url.possibly_invalid_spec()); - // TODO(ahemery): We also create a NavigationRequest for browser initiated - // same document navigations, so implement the passing of this request to - // DidCommitNavigationInternal. - if (!DidCommitNavigationInternal(nullptr /* navigation_request */, - validated_params.get(), - true /* is_same_document_navigation*/)) { + // Check if the navigation matches a stored same-document NavigationRequest. + // In that case it is browser-initiated. + bool is_browser_initiated = + same_document_navigation_request_ && + (same_document_navigation_request_->commit_params().navigation_token == + validated_params->navigation_token); + if (!DidCommitNavigationInternal( + is_browser_initiated ? std::move(same_document_navigation_request_) + : nullptr, + validated_params.get(), true /* is_same_document_navigation*/)) { return; } @@ -5824,115 +5830,38 @@ } std::unique_ptr<NavigationRequest> -RenderFrameHostImpl::TakeNavigationRequestForSameDocumentCommit( - const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { - bool is_browser_initiated = (params.nav_entry_id != 0); - - // A NavigationRequest is created for browser-initiated same-document - // navigation. Try to take it if it's still available and matches the - // current navigation. - if (is_browser_initiated && same_document_navigation_request_ && - same_document_navigation_request_->common_params().url == params.url) { - return std::move(same_document_navigation_request_); - } - - // No existing NavigationRequest has been found. Create a new one, but don't - // reset any NavigationRequest tracking an ongoing navigation, since this may - // lead to the cancellation of the navigation. - // First, determine if the navigation corresponds to the pending navigation - // entry. This is the case if the NavigationRequest for a browser-initiated - // same-document navigation was erased due to a race condition. - // TODO(ahemery): Remove when the full mojo interface is in place. - // (https://bugs.chromium.org/p/chromium/issues/detail?id=784904) - bool is_renderer_initiated = true; - NavigationEntryImpl* pending_entry = NavigationEntryImpl::FromNavigationEntry( - frame_tree_node()->navigator()->GetController()->GetPendingEntry()); - if (pending_entry && pending_entry->GetUniqueID() == params.nav_entry_id) { - is_renderer_initiated = pending_entry->is_renderer_initiated(); - } else { - // Don't reuse the pending entry if it doesn't match. - pending_entry = nullptr; - } - +RenderFrameHostImpl::CreateNavigationRequestForCommit( + const FrameHostMsg_DidCommitProvisionalLoad_Params& params, + bool is_same_document, + NavigationEntryImpl* entry_for_request) { + bool is_renderer_initiated = + entry_for_request ? entry_for_request->is_renderer_initiated() : true; return NavigationRequest::CreateForCommit( - frame_tree_node_, this, pending_entry, params, is_renderer_initiated, - true /* was_within_same_document */); + frame_tree_node_, this, entry_for_request, params, is_renderer_initiated, + is_same_document); } -std::unique_ptr<NavigationRequest> -RenderFrameHostImpl::TakeNavigationRequestForCommit( - const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { - // TODO(ahemery): Once we have IsPerNavigationMojoInterfaceEnabled() always - // true, it becomes obsolete to match the NavigationRequest since we are - // sure it is the correct one. However using the same request even though - // url might have changed ("" becomes "about:blank", etc.) requires some - // updating. - - // Determine if the current NavigationRequest can be used. - NavigationHandleImpl* navigation_handle = - navigation_request_ ? navigation_request_->navigation_handle() : nullptr; - - // TODO(lukasza, clamy): https://crbug.com/784904: Match commit IPC to proper - // NavigationHandle without requiring URLs to match. - if (navigation_handle && navigation_handle->GetURL() == params.url) { - return std::move(navigation_request_); - } - - // At this point we know that the right/matching |navigation_request_| has - // already been found based on navigation id look-up performed by - // RFHI::OnCrossDocumentCommitProcessed. OTOH, we cannot use its - // NavigationHandle, because it has a mismatched URL (which would cause - // DCHECKs - for example in NavigationHandleImpl::DidCommitNavigation). - // - // Because of the above, if the URL does not match what the NavigationHandle - // expects, we want to treat the commit as a new navigation. - // This mostly works, but there are some remaining issues here tracked - // by https://crbug.com/872803. - // - // The URL mismatch can happen when loading a Data navigation with - // LoadDataWithBaseURL. - // TODO(csharrison): Data navigations loaded with LoadDataWithBaseURL get - // reset here, because the NavigationHandle tracks the URL but the params.url - // tracks the data. The trick of saving the old entry ids for these - // navigations should go away when this is properly handled. - // See https://crbug.com/588317. - // - // Other cases are where URL mismatch can happen is when committing an error - // page - for example this can happen during CSP/frame-ancestors checks (see - // https://crbug.com/759184). - - NavigationEntryImpl* entry_for_request = nullptr; - bool is_renderer_initiated = true; - - // Make sure that the pending entry was really loaded via LoadDataWithBaseURL - // and that it matches this handle. TODO(csharrison): The pending entry's - // base url should equal |params.base_url|. This is not the case for loads - // with invalid base urls. - if (navigation_handle) { - NavigationEntryImpl* pending_entry = - NavigationEntryImpl::FromNavigationEntry( - frame_tree_node()->navigator()->GetController()->GetPendingEntry()); - bool pending_entry_matches_handle = - pending_entry && pending_entry->GetUniqueID() == - navigation_handle->pending_nav_entry_id(); +bool RenderFrameHostImpl::NavigationRequestWasIntendedForPendingEntry( + NavigationRequest* request, + const FrameHostMsg_DidCommitProvisionalLoad_Params& params, + bool same_document) { + NavigationEntryImpl* pending_entry = NavigationEntryImpl::FromNavigationEntry( + frame_tree_node()->navigator()->GetController()->GetPendingEntry()); + if (!pending_entry) + return false; + if (request->nav_entry_id() != pending_entry->GetUniqueID()) + return false; + if (!same_document) { + // Make sure that the pending entry was really loaded via + // LoadDataWithBaseURL and that it matches this handle. // TODO(csharrison): The pending entry's base url should equal - // |validated_params.base_url|. This is not the case for loads with invalid - // base urls. - if (navigation_handle->GetURL() == params.base_url && - pending_entry_matches_handle && - !pending_entry->GetBaseURLForDataURL().is_empty()) { - entry_for_request = pending_entry; - is_renderer_initiated = pending_entry->is_renderer_initiated(); + // |params.base_url|. This is not the case for loads with invalid base urls. + if (request->common_params().url != params.base_url || + pending_entry->GetBaseURLForDataURL().is_empty()) { + return false; } } - - // There is no pending NavigationEntry in these cases, so pass 0 as the - // pending_nav_entry_id. If the previous handle was a prematurely aborted - // navigation loaded via LoadDataWithBaseURL, propagate the entry id. - return NavigationRequest::CreateForCommit( - frame_tree_node_, this, entry_for_request, params, - is_renderer_initiated /* is_renderer_initiated */, - false /* is_same_document */); + return true; } void RenderFrameHostImpl::BeforeUnloadTimeout() { @@ -6065,6 +5994,7 @@ } bool RenderFrameHostImpl::ValidateDidCommitParams( + NavigationRequest* navigation_request, FrameHostMsg_DidCommitProvisionalLoad_Params* validated_params, bool is_same_document_navigation) { RenderProcessHost* process = GetProcess(); @@ -6102,8 +6032,9 @@ // Without error page isolation, a blocked navigation is expected to // commit in the old renderer process. This may be true for subframe // navigations even when error page isolation is enabled for main frames. - if (GetNavigationHandle() && GetNavigationHandle()->GetNetErrorCode() == - net::ERR_BLOCKED_BY_CLIENT) { + if (navigation_request && + navigation_request->navigation_handle()->GetNetErrorCode() == + net::ERR_BLOCKED_BY_CLIENT) { // Since this is known to be an error page commit, verify it happened in // a unique origin, terminating the renderer process otherwise. if (!validated_params->origin.opaque()) { @@ -6174,8 +6105,8 @@ base::debug::CrashKeySize::Size32), bool_to_crash_key(IsCrossProcessSubframe())); - if (navigation_request_ && navigation_request_->navigation_handle()) { - NavigationHandleImpl* handle = navigation_request_->navigation_handle(); + if (navigation_request && navigation_request->navigation_handle()) { + NavigationHandleImpl* handle = navigation_request->navigation_handle(); base::debug::SetCrashKeyString( base::debug::AllocateCrashKeyString( "is_renderer_initiated", base::debug::CrashKeySize::Size32), @@ -6256,20 +6187,59 @@ } bool RenderFrameHostImpl::DidCommitNavigationInternal( - NavigationRequest* navigation_request, + std::unique_ptr<NavigationRequest> navigation_request, FrameHostMsg_DidCommitProvisionalLoad_Params* validated_params, bool is_same_document_navigation) { // Sanity-check the page transition for frame type. DCHECK_EQ(ui::PageTransitionIsMainFrame(validated_params->transition), !GetParent()); - if (navigation_request) { - OnCrossDocumentCommitProcessed(navigation_request, - blink::mojom::CommitResult::Ok); + // Check that the committing navigation token matches the navigation request. + std::unique_ptr<NavigationRequest> invalid_request = nullptr; + if (navigation_request && + navigation_request->commit_params().navigation_token != + validated_params->navigation_token) { + navigation_request.reset(); + // TODO(clamy): We should kill the renderer in all cases where we expect to + // have a NavigationRequest matching the commit URL. } - if (!ValidateDidCommitParams(validated_params, is_same_document_navigation)) + if (!ValidateDidCommitParams(navigation_request.get(), validated_params, + is_same_document_navigation)) { return false; + } + + if (navigation_request && + navigation_request->common_params().url != validated_params->url) { + // At this point we know that the right/matching |navigation_request| has + // already been found based on token matching performed or the commit + // originated from a NavigationClient owned by the NavigationRequest. OTOH, + // we cannot use its NavigationHandle, because it has a mismatched URL + // (which would cause DCHECKs - for example in + // NavigationHandleImpl::DidCommitNavigation). + // + // Because of the above, if the URL does not match what the NavigationHandle + // expects, we want to treat the commit as a new navigation. + // + // The URL mismatch can happen when loading a Data navigation with + // LoadDataWithBaseURL. + // TODO(csharrison): Data navigations loaded with LoadDataWithBaseURL get + // reset here, because the NavigationHandle tracks the URL but the + // params.url tracks the data. The trick of saving the old entry ids for + // these navigations should go away when this is properly handled. See + // https://crbug.com/588317. + // + // Other cases are where URL mismatch can happen is when committing an error + // page - for example this can happen during CSP/frame-ancestors checks (see + // https://crbug.com/759184). + // + // TODO(clamy): We should support the URL filtering without deleting the + // request. + + // Note: the NavigationRequest is not reset here, as this could potentially + // lead to the deletion of the pending NavigationEntry. + invalid_request = std::move(navigation_request); + } // Set is loading to true now if it has not been set yet. This happens for // renderer-initiated same-document navigations. It can also happen when a @@ -6282,47 +6252,64 @@ was_loading); } - if (navigation_request_) - was_discarded_ = navigation_request_->commit_params().was_discarded; + if (navigation_request) + was_discarded_ = navigation_request->commit_params().was_discarded; - std::unique_ptr<NavigationRequest> committed_request; - if (is_same_document_navigation) { - committed_request = - TakeNavigationRequestForSameDocumentCommit(*validated_params); - } else { - committed_request = TakeNavigationRequestForCommit(*validated_params); + // If there is no valid NavigationRequest corresponding to this commit, create + // one in order to properly issue DidFinishNavigation calls to + // WebContentsObservers. + if (!navigation_request) { + // First check if there was a request for this navigation that cannot be + // used due to URL mismatch. If that's the case and it corresponds to a + // navigation to the pending NavigationEntry, the new request should be + // associated with the pending NavigationEntry as well so that the pending + // NavigationEntry is properly committed. + NavigationEntryImpl* entry_for_navigation = nullptr; + if (invalid_request && NavigationRequestWasIntendedForPendingEntry( + invalid_request.get(), *validated_params, + is_same_document_navigation)) { + entry_for_navigation = NavigationEntryImpl::FromNavigationEntry( + frame_tree_node()->navigator()->GetController()->GetPendingEntry()); + } + + navigation_request = CreateNavigationRequestForCommit( + *validated_params, is_same_document_navigation, entry_for_navigation); } - DCHECK(committed_request); - DCHECK(committed_request->navigation_handle()); + DCHECK(navigation_request); + DCHECK(navigation_request->navigation_handle()); // Update the page transition. For subframe navigations, the renderer process // only gives the correct page transition at commit time. // TODO(clamy): We should get the correct page transition when starting the // request. - committed_request->set_transition(validated_params->transition); + navigation_request->set_transition(validated_params->transition); - committed_request->set_has_user_gesture(validated_params->gesture == - NavigationGestureUser); + navigation_request->set_has_user_gesture(validated_params->gesture == + NavigationGestureUser); UpdateSiteURL(validated_params->url, validated_params->url_is_unreachable); // Set the state whether this navigation is to an MHTML document, since there // are certain security checks that we cannot apply to subframes in MHTML // documents. Do not trust renderer data when determining that, rather use - // the |committed_request|, which was generated and stays browser side. + // the |navigation_request|, which was generated and stays browser side. is_mhtml_document_ = - (committed_request->GetMimeType() == "multipart/related" || - committed_request->GetMimeType() == "message/rfc822"); + (navigation_request->GetMimeType() == "multipart/related" || + navigation_request->GetMimeType() == "message/rfc822"); accessibility_reset_count_ = 0; appcache_handle_ = - committed_request->navigation_handle()->TakeAppCacheHandle(); + navigation_request->navigation_handle()->TakeAppCacheHandle(); frame_tree_node()->navigator()->DidNavigate(this, *validated_params, - std::move(committed_request), + std::move(navigation_request), is_same_document_navigation); - if (!is_same_document_navigation) - navigation_request_.reset(); + + // TODO(clamy): We should stop having a special case for same-document + // navigation and just put them in the general map of NavigationRequests. + if (is_same_document_navigation && invalid_request) + same_document_navigation_request_ = std::move(invalid_request); + return true; } @@ -6508,7 +6495,7 @@ // Called when the renderer navigates. For every frame loaded, we'll get this // notification containing parameters identifying the navigation. void RenderFrameHostImpl::DidCommitNavigation( - NavigationRequest* committing_navigation_request, + std::unique_ptr<NavigationRequest> committing_navigation_request, std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> validated_params, mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params) { @@ -6614,7 +6601,7 @@ // therefore the global object is not replaced. } - if (!DidCommitNavigationInternal(committing_navigation_request, + if (!DidCommitNavigationInternal(std::move(committing_navigation_request), validated_params.get(), false /* is_same_document_navigation */)) { return;
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 949cbfec..15d0da85 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -136,6 +136,7 @@ class GeolocationServiceImpl; class KeepAliveHandleFactory; class MediaInterfaceProxy; +class NavigationEntryImpl; class NavigationHandleImpl; class NavigationRequest; class PermissionServiceContext; @@ -832,11 +833,6 @@ // waiting to commit in this RenderFrameHost. std::set<int> GetNavigationEntryIdsPendingCommit(); - void DidCommitNavigationForTesting( - NavigationRequest* navigation_request, - std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params, - mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params); - service_manager::BinderRegistry& BinderRegistryForTesting() { return *registry_; } @@ -1361,12 +1357,24 @@ bool success, const base::string16& user_input); - // Returns ownership of the NavigationRequest associated with a navigation - // that just committed. - std::unique_ptr<NavigationRequest> TakeNavigationRequestForSameDocumentCommit( - const FrameHostMsg_DidCommitProvisionalLoad_Params& params); - std::unique_ptr<NavigationRequest> TakeNavigationRequestForCommit( - const FrameHostMsg_DidCommitProvisionalLoad_Params& params); + // Creates a NavigationRequest to use for commit. This should only be used + // when no appropriate NavigationRequest has been found. + std::unique_ptr<NavigationRequest> CreateNavigationRequestForCommit( + const FrameHostMsg_DidCommitProvisionalLoad_Params& params, + bool is_same_document, + NavigationEntryImpl* entry_for_request); + + // Whether the |request| corresponds to a navigation to the pending + // NavigationEntry. This is used at commit time, when the NavigationRequest + // does not match the data sent by the renderer to re-create a + // NavigationRequest and associate it with the pending NavigationEntry if + // needed. + // TODO(clamy): We should handle the mismatches gracefully without deleting + // the NavigationRequest and having to re-create one. + bool NavigationRequestWasIntendedForPendingEntry( + NavigationRequest* request, + const FrameHostMsg_DidCommitProvisionalLoad_Params& params, + bool same_document); // Helper to process the beforeunload ACK. |proceed| indicates whether the // navigation or tab close should be allowed to proceed. If @@ -1468,6 +1476,7 @@ // the renderer during the commit notification. // A return value of true means that the commit should proceed. bool ValidateDidCommitParams( + NavigationRequest* navigation_request, FrameHostMsg_DidCommitProvisionalLoad_Params* validated_params, bool is_same_document_navigation); @@ -1478,7 +1487,7 @@ // The actual implementation of DidCommitProvisionalLoad and // DidCommitPerNavigationMojoInterfaceNavigation. void DidCommitNavigation( - NavigationRequest* committing_navigation_request, + std::unique_ptr<NavigationRequest> committing_navigation_request, std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> validated_params, mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params); @@ -1489,7 +1498,7 @@ // Returns true if the navigation did commit properly, false if the commit // state should be restored to its pre-commit value. bool DidCommitNavigationInternal( - NavigationRequest* navigation_request, + std::unique_ptr<NavigationRequest> navigation_request, FrameHostMsg_DidCommitProvisionalLoad_Params* validated_params, bool is_same_document_navigation);
diff --git a/content/browser/image_capture/OWNERS b/content/browser/image_capture/OWNERS index c261502..83bc2c2 100644 --- a/content/browser/image_capture/OWNERS +++ b/content/browser/image_capture/OWNERS
@@ -1,5 +1,7 @@ -mcasas@chromium.org miu@chromium.org +# Original (legacy) owner. +mcasas@chromium.org + # COMPONENT: Blink>ImageCapture # TEAM: media-dev@chromium.org
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index e06d2a5..31fed5c 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -237,7 +237,7 @@ delegate_ui_.reset(new DelegateOwnerUI(weak_factory_.GetWeakPtr())); } - void Start(net::AuthChallengeInfo* auth_info, + void Start(const net::AuthChallengeInfo& auth_info, ResourceRequestInfo::WebContentsGetter web_contents_getter, const GlobalRequestID& request_id, bool is_request_for_main_frame, @@ -247,11 +247,11 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); base::PostTaskWithTraits( FROM_HERE, {BrowserThread::UI}, - base::BindOnce( - &DelegateOwnerUI::Start, base::Unretained(delegate_ui_.get()), - base::RetainedRef(auth_info), std::move(web_contents_getter), - request_id, is_request_for_main_frame, url, - std::move(response_headers), first_auth_attempt)); + base::BindOnce(&DelegateOwnerUI::Start, + base::Unretained(delegate_ui_.get()), auth_info, + std::move(web_contents_getter), request_id, + is_request_for_main_frame, url, + std::move(response_headers), first_auth_attempt)); } private: @@ -264,7 +264,7 @@ : proxy_(std::move(proxy)) {} ~DelegateOwnerUI() { DCHECK_CURRENTLY_ON(BrowserThread::UI); } - void Start(net::AuthChallengeInfo* auth_info, + void Start(const net::AuthChallengeInfo& auth_info, ResourceRequestInfo::WebContentsGetter web_contents_getter, const GlobalRequestID& request_id, bool is_request_for_main_frame, @@ -585,7 +585,7 @@ std::unique_ptr<LoginDelegate> ResourceDispatcherHostImpl::CreateLoginDelegate( ResourceLoader* loader, - net::AuthChallengeInfo* auth_info) { + const net::AuthChallengeInfo& auth_info) { if (!delegate_) return nullptr;
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h index dfeee02..68ac30b5 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.h +++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -393,7 +393,7 @@ // ResourceLoaderDelegate implementation: std::unique_ptr<LoginDelegate> CreateLoginDelegate( ResourceLoader* loader, - net::AuthChallengeInfo* auth_info) override; + const net::AuthChallengeInfo& auth_info) override; bool HandleExternalProtocol(ResourceLoader* loader, const GURL& url) override; void DidStartRequest(ResourceLoader* loader) override; void DidReceiveRedirect(ResourceLoader* loader,
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc index 03291049..bd0f57f6 100644 --- a/content/browser/loader/resource_loader.cc +++ b/content/browser/loader/resource_loader.cc
@@ -403,7 +403,7 @@ } void ResourceLoader::OnAuthRequired(net::URLRequest* unused, - net::AuthChallengeInfo* auth_info) { + const net::AuthChallengeInfo& auth_info) { DCHECK_EQ(request_.get(), unused); ResourceRequestInfoImpl* info = GetRequestInfo();
diff --git a/content/browser/loader/resource_loader.h b/content/browser/loader/resource_loader.h index 4bd8138..dbb477b 100644 --- a/content/browser/loader/resource_loader.h +++ b/content/browser/loader/resource_loader.h
@@ -73,7 +73,7 @@ const net::RedirectInfo& redirect_info, bool* defer) override; void OnAuthRequired(net::URLRequest* request, - net::AuthChallengeInfo* info) override; + const net::AuthChallengeInfo& info) override; void OnCertificateRequested(net::URLRequest* request, net::SSLCertRequestInfo* info) override; void OnSSLCertificateError(net::URLRequest* request,
diff --git a/content/browser/loader/resource_loader_delegate.h b/content/browser/loader/resource_loader_delegate.h index 73cfdda..7926ac4e 100644 --- a/content/browser/loader/resource_loader_delegate.h +++ b/content/browser/loader/resource_loader_delegate.h
@@ -27,7 +27,7 @@ public: virtual std::unique_ptr<LoginDelegate> CreateLoginDelegate( ResourceLoader* loader, - net::AuthChallengeInfo* auth_info) = 0; + const net::AuthChallengeInfo& auth_info) = 0; virtual bool HandleExternalProtocol(ResourceLoader* loader, const GURL& url) = 0;
diff --git a/content/browser/loader/resource_loader_unittest.cc b/content/browser/loader/resource_loader_unittest.cc index 0f774df..074dd87 100644 --- a/content/browser/loader/resource_loader_unittest.cc +++ b/content/browser/loader/resource_loader_unittest.cc
@@ -489,7 +489,7 @@ // ResourceLoaderDelegate: std::unique_ptr<LoginDelegate> CreateLoginDelegate( ResourceLoader* loader, - net::AuthChallengeInfo* auth_info) override { + const net::AuthChallengeInfo& auth_info) override { return nullptr; } bool HandleExternalProtocol(ResourceLoader* loader,
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc index 60eb029..93ce013e7 100644 --- a/content/browser/navigation_browsertest.cc +++ b/content/browser/navigation_browsertest.cc
@@ -1167,97 +1167,6 @@ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); } -// This test reproduces the following race condition: -// 1) A first navigation starts, the headers are received, the navigation -// reaches ready-to-commit. It is sent to the renderer to be committed. -// 2) In the meantime, a second navigation reaches ready-to-commit in the -// browser. -// 3) Before the renderer gets notified of the new navigation, the -// first navigation is committed. -// 4) The browser gets notified of the commit of the first navigation. This -// should not destroy the NavigationRequest corresponding to the second -// navigation. -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, - RaceNewNavigationCommitWhileOldOneFinishesLoading) { - // Start the test with an initial document. - GURL main_url(embedded_test_server()->GetURL("/simple_page.html")); - EXPECT_TRUE(NavigateToURL(shell(), main_url)); - RenderFrameHostImpl* render_frame_host = static_cast<RenderFrameHostImpl*>( - shell()->web_contents()->GetMainFrame()); - - NavigationRecorder recorder(shell()->web_contents()); - // Note: These two pages contain an image that will never load. The goal is to - // prevent RenderFrameHostImpl::DidStopLoading() to be called since it will - // cancel any pending navigation. - GURL page_1(embedded_test_server()->GetURL("/infinite_load_1.html")); - GURL page_2(embedded_test_server()->GetURL("/infinite_load_2.html")); - // Intercept and cancel any FrameMsgHost_DidCommitProvisionalLoad events. - InterceptAndCancelDidCommitProvisionalLoad interceptor( - shell()->web_contents()); - - // 1) Navigate to page_1. - shell()->LoadURL(page_1); - - // 2) The browser receives the response's headers. The navigation commits in - // the browser. - recorder.WaitForEvents(2); - EXPECT_EQ(2u, recorder.records().size()); - EXPECT_STREQ("start /infinite_load_1.html", recorder.records()[0].c_str()); - EXPECT_STREQ("ready-to-commit /infinite_load_1.html", - recorder.records()[1].c_str()); - - // 3) Wait for the renderer to receive the response's body, but do not notify - // the browser of it right now. It is delayed in 6). - interceptor.Wait(1); - EXPECT_EQ(1u, interceptor.intercepted_messages().size()); - - // 4) In the meantime, the browser starts a navigation to page_2. - shell()->LoadURL(page_2); - - // 5) The response's headers are received, the navigation reaches - // ready-to-commit in the browser. This should not delete the ongoing - // NavigationRequest. - recorder.WaitForEvents(4); - EXPECT_EQ(4u, recorder.records().size()); - EXPECT_STREQ("start /infinite_load_2.html", recorder.records()[2].c_str()); - EXPECT_STREQ("ready-to-commit /infinite_load_2.html", - recorder.records()[3].c_str()); - - // 6) The browser receives the first DidCommitProvisionalLoad message. This - // should not delete the second navigation. This is the end of the first - // navigation. - ASSERT_GE(interceptor.intercepted_navigations().size(), 1u); - render_frame_host->DidCommitNavigationForTesting( - interceptor.intercepted_navigations()[0], - std::make_unique<::FrameHostMsg_DidCommitProvisionalLoad_Params>( - interceptor.intercepted_messages()[0]), - mojom::DidCommitProvisionalLoadInterfaceParams::New( - std::move(interceptor.intercepted_requests()[0]), - std::move(interceptor.intercepted_broker_content_requests()[0]), - std::move(interceptor.intercepted_broker_blink_requests()[0]))); - recorder.WaitForEvents(5); - EXPECT_EQ(5u, recorder.records().size()); - EXPECT_STREQ("did-commit /infinite_load_1.html", - recorder.records()[4].c_str()); - - // 7) Wait for the renderer to receive the second response's body. This is the - // end of the second navigation. - interceptor.Wait(2); - EXPECT_EQ(2u, interceptor.intercepted_messages().size()); - render_frame_host->DidCommitNavigationForTesting( - interceptor.intercepted_navigations()[1], - std::make_unique<::FrameHostMsg_DidCommitProvisionalLoad_Params>( - interceptor.intercepted_messages()[1]), - mojom::DidCommitProvisionalLoadInterfaceParams::New( - std::move(interceptor.intercepted_requests()[1]), - std::move(interceptor.intercepted_broker_content_requests()[1]), - std::move(interceptor.intercepted_broker_blink_requests()[1]))); - recorder.WaitForEvents(6); - EXPECT_EQ(6u, recorder.records().size()); - EXPECT_STREQ("did-commit /infinite_load_2.html", - recorder.records()[5].c_str()); -} - // Renderer initiated back/forward navigation in beforeunload should not prevent // the user to navigate away from a website. IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, HistoryBackInBeforeUnload) {
diff --git a/content/browser/network_service_client.cc b/content/browser/network_service_client.cc index 92f5e9be..e728d987 100644 --- a/content/browser/network_service_client.cc +++ b/content/browser/network_service_client.cc
@@ -175,7 +175,7 @@ LoginHandlerDelegate( network::mojom::AuthChallengeResponderPtr auth_challenge_responder, ResourceRequestInfo::WebContentsGetter web_contents_getter, - scoped_refptr<net::AuthChallengeInfo> auth_info, + const net::AuthChallengeInfo& auth_info, bool is_request_for_main_frame, uint32_t process_id, uint32_t routing_id, @@ -247,8 +247,8 @@ // WeakPtr is not strictly necessary here due to OnRequestCancelled. creating_login_delegate_ = true; login_delegate_ = GetContentClient()->browser()->CreateLoginDelegate( - auth_info_.get(), web_contents, request_id_, is_request_for_main_frame_, - url_, response_headers_, first_auth_attempt_, + auth_info_, web_contents, request_id_, is_request_for_main_frame_, url_, + response_headers_, first_auth_attempt_, base::BindOnce(&LoginHandlerDelegate::OnAuthCredentials, weak_factory_.GetWeakPtr())); creating_login_delegate_ = false; @@ -269,7 +269,7 @@ } network::mojom::AuthChallengeResponderPtr auth_challenge_responder_; - scoped_refptr<net::AuthChallengeInfo> auth_info_; + net::AuthChallengeInfo auth_info_; const content::GlobalRequestID request_id_; const uint32_t routing_id_; bool is_request_for_main_frame_; @@ -432,7 +432,7 @@ const GURL& url, const GURL& site_for_cookies, bool first_auth_attempt, - const scoped_refptr<net::AuthChallengeInfo>& auth_info, + const net::AuthChallengeInfo& auth_info, int32_t resource_type, const base::Optional<network::ResourceResponseHead>& head, network::mojom::AuthChallengeResponderPtr auth_challenge_responder) {
diff --git a/content/browser/network_service_client.h b/content/browser/network_service_client.h index 6714aef..58d907f 100644 --- a/content/browser/network_service_client.h +++ b/content/browser/network_service_client.h
@@ -41,7 +41,7 @@ const GURL& url, const GURL& site_for_cookies, bool first_auth_attempt, - const scoped_refptr<net::AuthChallengeInfo>& auth_info, + const net::AuthChallengeInfo& auth_info, int32_t resource_type, const base::Optional<network::ResourceResponseHead>& head, network::mojom::AuthChallengeResponderPtr
diff --git a/content/browser/renderer_host/media/OWNERS b/content/browser/renderer_host/media/OWNERS index 68a9bdc..5a4b6f04 100644 --- a/content/browser/renderer_host/media/OWNERS +++ b/content/browser/renderer_host/media/OWNERS
@@ -7,8 +7,10 @@ olka@chromium.org maxmorin@chromium.org -per-file *video*=mcasas@chromium.org per-file *video*=chfremer@chromium.org +# Original (legacy) owner. +per-file *video*=mcasas@chromium.org + # TEAM: media-capture-and-streams@grotations.appspotmail.com # COMPONENT: Blink>GetUserMedia
diff --git a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc index 38c4daf..f4e39230 100644 --- a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc +++ b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc
@@ -134,6 +134,34 @@ return std::make_unique<ppapi::host::MessageFilterHost>( host_->GetPpapiHost(), instance, resource, udp_socket); } + + // The following interfaces are "private" because permission will be + // checked against a whitelist of apps at the time of the corresponding + // instance's method calls (because permission check can be performed + // only on the UI thread). + case PpapiHostMsg_TCPServerSocket_CreatePrivate::ID: { + if (!CanCreateSocket()) + return nullptr; + scoped_refptr<ppapi::host::ResourceMessageFilter> tcp_server_socket( + new PepperTCPServerSocketMessageFilter(this, host_, instance, + true)); + return std::make_unique<ppapi::host::MessageFilterHost>( + host_->GetPpapiHost(), instance, resource, tcp_server_socket); + } + case PpapiHostMsg_TCPSocket_CreatePrivate::ID: { + if (!CanCreateSocket()) + return nullptr; + return CreateNewTCPSocket(instance, resource, + ppapi::TCP_SOCKET_VERSION_PRIVATE); + } + case PpapiHostMsg_UDPSocket_CreatePrivate::ID: { + if (!CanCreateSocket()) + return nullptr; + scoped_refptr<ppapi::host::ResourceMessageFilter> udp_socket( + new PepperUDPSocketMessageFilter(host_, instance, true)); + return std::make_unique<ppapi::host::MessageFilterHost>( + host_->GetPpapiHost(), instance, resource, udp_socket); + } } } @@ -199,32 +227,6 @@ new ppapi::host::MessageFilterHost(host_->GetPpapiHost(), instance, resource, host_resolver)); } - if (message.type() == PpapiHostMsg_TCPServerSocket_CreatePrivate::ID) { - if (CanCreateSocket()) { - scoped_refptr<ppapi::host::ResourceMessageFilter> tcp_server_socket( - new PepperTCPServerSocketMessageFilter(this, host_, instance, true)); - return std::unique_ptr<ppapi::host::ResourceHost>( - new ppapi::host::MessageFilterHost(host_->GetPpapiHost(), instance, - resource, tcp_server_socket)); - } else { - return std::unique_ptr<ppapi::host::ResourceHost>(); - } - } - if (message.type() == PpapiHostMsg_TCPSocket_CreatePrivate::ID) { - return CreateNewTCPSocket(instance, resource, - ppapi::TCP_SOCKET_VERSION_PRIVATE); - } - if (message.type() == PpapiHostMsg_UDPSocket_CreatePrivate::ID) { - if (CanCreateSocket()) { - scoped_refptr<ppapi::host::ResourceMessageFilter> udp_socket( - new PepperUDPSocketMessageFilter(host_, instance, true)); - return std::unique_ptr<ppapi::host::ResourceHost>( - new ppapi::host::MessageFilterHost(host_->GetPpapiHost(), instance, - resource, udp_socket)); - } else { - return std::unique_ptr<ppapi::host::ResourceHost>(); - } - } if (message.type() == PpapiHostMsg_NetworkMonitor_Create::ID) { return std::unique_ptr<ppapi::host::ResourceHost>( new PepperNetworkMonitorHost(host_, instance, resource)); @@ -272,9 +274,6 @@ PP_Instance instance, PP_Resource resource, ppapi::TCPSocketVersion version) { - if (!CanCreateSocket()) - return std::unique_ptr<ppapi::host::ResourceHost>(); - scoped_refptr<ppapi::host::ResourceMessageFilter> tcp_socket( new PepperTCPSocketMessageFilter(this, host_, instance, version)); if (!tcp_socket.get())
diff --git a/content/browser/serial/serial_browsertest.cc b/content/browser/serial/serial_browsertest.cc index 361bd9d7..9c6c3368 100644 --- a/content/browser/serial/serial_browsertest.cc +++ b/content/browser/serial/serial_browsertest.cc
@@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/unguessable_token.h" +#include "content/browser/serial/serial_test_utils.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/serial_chooser.h" #include "content/public/browser/serial_delegate.h" @@ -14,6 +15,7 @@ #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/shell/browser/shell.h" +#include "services/device/public/cpp/test/fake_serial_port_manager.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,73 +27,6 @@ namespace { -class FakeSerialPortManager : public device::mojom::SerialPortManager { - public: - FakeSerialPortManager() = default; - ~FakeSerialPortManager() override = default; - - void AddPort(device::mojom::SerialPortInfoPtr port) { - base::UnguessableToken token = port->token; - ports_[token] = std::move(port); - } - - // device::mojom::SerialPortManager - void GetDevices(GetDevicesCallback callback) override { - std::vector<device::mojom::SerialPortInfoPtr> ports; - for (const auto& map_entry : ports_) - ports.push_back(map_entry.second.Clone()); - std::move(callback).Run(std::move(ports)); - } - - void GetPort(const base::UnguessableToken& token, - device::mojom::SerialPortRequest request) override {} - - private: - std::map<base::UnguessableToken, device::mojom::SerialPortInfoPtr> ports_; - - DISALLOW_COPY_AND_ASSIGN(FakeSerialPortManager); -}; - -class MockSerialDelegate : public SerialDelegate { - public: - MockSerialDelegate() = default; - ~MockSerialDelegate() override = default; - - std::unique_ptr<SerialChooser> RunChooser( - RenderFrameHost* frame, - std::vector<blink::mojom::SerialPortFilterPtr> filters, - SerialChooser::Callback callback) override { - std::move(callback).Run(RunChooserInternal()); - return nullptr; - } - - MOCK_METHOD0(RunChooserInternal, device::mojom::SerialPortInfoPtr()); - MOCK_METHOD2(HasPortPermission, - bool(content::RenderFrameHost* frame, - const device::mojom::SerialPortInfo& port)); - MOCK_METHOD1( - GetPortManager, - device::mojom::SerialPortManager*(content::RenderFrameHost* frame)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockSerialDelegate); -}; - -class TestContentBrowserClient : public ContentBrowserClient { - public: - TestContentBrowserClient() = default; - ~TestContentBrowserClient() override = default; - - MockSerialDelegate& delegate() { return delegate_; } - - SerialDelegate* GetSerialDelegate() override { return &delegate_; } - - private: - MockSerialDelegate delegate_; - - DISALLOW_COPY_AND_ASSIGN(TestContentBrowserClient); -}; - class SerialTest : public ContentBrowserTest { public: SerialTest() { @@ -115,12 +50,12 @@ } MockSerialDelegate& delegate() { return test_client_.delegate(); } - FakeSerialPortManager* port_manager() { return &port_manager_; } + device::FakeSerialPortManager* port_manager() { return &port_manager_; } private: - TestContentBrowserClient test_client_; + SerialTestContentBrowserClient test_client_; ContentBrowserClient* original_client_ = nullptr; - FakeSerialPortManager port_manager_; + device::FakeSerialPortManager port_manager_; }; } // namespace @@ -140,15 +75,9 @@ .WillOnce(Return(false)) .WillOnce(Return(true)); - int result; - EXPECT_TRUE(ExecuteScriptAndExtractInt( - shell(), - "navigator.serial.getPorts()" - " .then(ports => {" - " domAutomationController.send(ports.length);" - " });", - &result)); - EXPECT_EQ(2, result); + EXPECT_EQ( + 2, EvalJs(shell(), + R"(navigator.serial.getPorts().then(ports => ports.length))")); } IN_PROC_BROWSER_TEST_F(SerialTest, RequestPort) { @@ -159,17 +88,11 @@ EXPECT_CALL(delegate(), RunChooserInternal) .WillOnce(Return(ByMove(std::move(port)))); - bool result; - EXPECT_TRUE( - ExecuteScriptAndExtractBool(shell(), - "navigator.serial.requestPort({})" - " .then(port => {" - " domAutomationController.send(true);" - " }, error => {" - " domAutomationController.send(false);" - " });", - &result)); - EXPECT_TRUE(result); + EXPECT_EQ(true, EvalJs(shell(), + R"((async () => { + let port = await navigator.serial.requestPort({}); + return port instanceof SerialPort; + })())")); } } // namespace content
diff --git a/content/browser/serial/serial_service.cc b/content/browser/serial/serial_service.cc index d62e9ece..e4b7c9d0 100644 --- a/content/browser/serial/serial_service.cc +++ b/content/browser/serial/serial_service.cc
@@ -6,11 +6,15 @@ #include <utility> +#include "base/bind.h" #include "base/callback.h" +#include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/serial_chooser.h" #include "content/public/browser/serial_delegate.h" +#include "content/public/browser/web_contents.h" +#include "mojo/public/cpp/bindings/interface_request.h" #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom.h" namespace content { @@ -36,9 +40,15 @@ : render_frame_host_(render_frame_host) { DCHECK(render_frame_host_->IsFeatureEnabled( blink::mojom::FeaturePolicyFeature::kSerial)); + watchers_.set_connection_error_handler(base::BindRepeating( + &SerialService::OnWatcherConnectionError, base::Unretained(this))); } -SerialService::~SerialService() = default; +SerialService::~SerialService() { + // The remaining watchers will be closed from this end. + if (!watchers_.empty()) + DecrementActiveFrameCount(); +} void SerialService::Bind(blink::mojom::SerialServiceRequest request) { bindings_.AddBinding(this, std::move(request)); @@ -72,6 +82,24 @@ weak_factory_.GetWeakPtr(), std::move(callback))); } +void SerialService::GetPort(const base::UnguessableToken& token, + device::mojom::SerialPortRequest request) { + SerialDelegate* delegate = GetContentClient()->browser()->GetSerialDelegate(); + if (!delegate) + return; + + if (watchers_.empty()) { + auto* web_contents_impl = static_cast<WebContentsImpl*>( + WebContents::FromRenderFrameHost(render_frame_host_)); + web_contents_impl->IncrementSerialActiveFrameCount(); + } + + device::mojom::SerialPortConnectionWatcherPtr watcher; + watchers_.AddBinding(this, mojo::MakeRequest(&watcher)); + delegate->GetPortManager(render_frame_host_) + ->GetPort(token, std::move(request), std::move(watcher)); +} + void SerialService::FinishGetPorts( GetPortsCallback callback, std::vector<device::mojom::SerialPortInfoPtr> ports) { @@ -101,4 +129,15 @@ std::move(callback).Run(ToBlinkType(*port)); } +void SerialService::OnWatcherConnectionError() { + if (watchers_.empty()) + DecrementActiveFrameCount(); +} + +void SerialService::DecrementActiveFrameCount() { + auto* web_contents_impl = static_cast<WebContentsImpl*>( + WebContents::FromRenderFrameHost(render_frame_host_)); + web_contents_impl->DecrementSerialActiveFrameCount(); +} + } // namespace content
diff --git a/content/browser/serial/serial_service.h b/content/browser/serial/serial_service.h index 81c8048..12378db 100644 --- a/content/browser/serial/serial_service.h +++ b/content/browser/serial/serial_service.h
@@ -19,7 +19,8 @@ class RenderFrameHost; class SerialChooser; -class SerialService : public blink::mojom::SerialService { +class SerialService : public blink::mojom::SerialService, + public device::mojom::SerialPortConnectionWatcher { public: explicit SerialService(RenderFrameHost* render_frame_host); ~SerialService() override; @@ -30,12 +31,16 @@ void GetPorts(GetPortsCallback callback) override; void RequestPort(std::vector<blink::mojom::SerialPortFilterPtr> filters, RequestPortCallback callback) override; + void GetPort(const base::UnguessableToken& token, + device::mojom::SerialPortRequest request) override; private: void FinishGetPorts(GetPortsCallback callback, std::vector<device::mojom::SerialPortInfoPtr> ports); void FinishRequestPort(RequestPortCallback callback, device::mojom::SerialPortInfoPtr port); + void OnWatcherConnectionError(); + void DecrementActiveFrameCount(); RenderFrameHost* const render_frame_host_; mojo::BindingSet<blink::mojom::SerialService> bindings_; @@ -43,6 +48,10 @@ // The last shown serial port chooser UI. std::unique_ptr<SerialChooser> chooser_; + // Each pipe here watches a connection created by GetPort() in order to notify + // the WebContentsImpl when an active connection indicator should be shown. + mojo::BindingSet<device::mojom::SerialPortConnectionWatcher> watchers_; + base::WeakPtrFactory<SerialService> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(SerialService);
diff --git a/content/browser/serial/serial_test_utils.cc b/content/browser/serial/serial_test_utils.cc new file mode 100644 index 0000000..4b7f103 --- /dev/null +++ b/content/browser/serial/serial_test_utils.cc
@@ -0,0 +1,33 @@ +// Copyright 2019 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/serial/serial_test_utils.h" + +#include <utility> + +#include "base/callback.h" + +namespace content { + +MockSerialDelegate::MockSerialDelegate() = default; + +MockSerialDelegate::~MockSerialDelegate() = default; + +std::unique_ptr<SerialChooser> MockSerialDelegate::RunChooser( + RenderFrameHost* frame, + std::vector<blink::mojom::SerialPortFilterPtr> filters, + SerialChooser::Callback callback) { + std::move(callback).Run(RunChooserInternal()); + return nullptr; +} + +SerialTestContentBrowserClient::SerialTestContentBrowserClient() = default; + +SerialTestContentBrowserClient::~SerialTestContentBrowserClient() = default; + +SerialDelegate* SerialTestContentBrowserClient::GetSerialDelegate() { + return &delegate_; +} + +} // namespace content
diff --git a/content/browser/serial/serial_test_utils.h b/content/browser/serial/serial_test_utils.h new file mode 100644 index 0000000..cdc08c6 --- /dev/null +++ b/content/browser/serial/serial_test_utils.h
@@ -0,0 +1,54 @@ +// Copyright 2019 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_SERIAL_SERIAL_TEST_UTILS_H_ +#define CONTENT_BROWSER_SERIAL_SERIAL_TEST_UTILS_H_ + +#include "content/public/browser/content_browser_client.h" +#include "content/public/browser/serial_delegate.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace content { + +class MockSerialDelegate : public SerialDelegate { + public: + MockSerialDelegate(); + ~MockSerialDelegate() override; + + std::unique_ptr<SerialChooser> RunChooser( + RenderFrameHost* frame, + std::vector<blink::mojom::SerialPortFilterPtr> filters, + SerialChooser::Callback callback) override; + + MOCK_METHOD0(RunChooserInternal, device::mojom::SerialPortInfoPtr()); + MOCK_METHOD2(HasPortPermission, + bool(content::RenderFrameHost* frame, + const device::mojom::SerialPortInfo& port)); + MOCK_METHOD1( + GetPortManager, + device::mojom::SerialPortManager*(content::RenderFrameHost* frame)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockSerialDelegate); +}; + +class SerialTestContentBrowserClient : public ContentBrowserClient { + public: + SerialTestContentBrowserClient(); + ~SerialTestContentBrowserClient() override; + + MockSerialDelegate& delegate() { return delegate_; } + + // ContentBrowserClient: + SerialDelegate* GetSerialDelegate() override; + + private: + MockSerialDelegate delegate_; + + DISALLOW_COPY_AND_ASSIGN(SerialTestContentBrowserClient); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SERIAL_SERIAL_TEST_UTILS_H_
diff --git a/content/browser/serial/serial_unittest.cc b/content/browser/serial/serial_unittest.cc new file mode 100644 index 0000000..c29428dd --- /dev/null +++ b/content/browser/serial/serial_unittest.cc
@@ -0,0 +1,104 @@ +// Copyright 2019 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/serial/serial_test_utils.h" +#include "content/public/common/content_client.h" +#include "content/test/test_render_view_host.h" +#include "content/test/test_web_contents.h" +#include "services/device/public/cpp/test/fake_serial_port_manager.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { + +namespace { + +const char kTestUrl[] = "https://www.google.com"; +const char kCrossOriginTestUrl[] = "https://www.chromium.org"; + +class SerialTest : public RenderViewHostImplTestHarness { + public: + SerialTest() { + ON_CALL(test_client_.delegate(), GetPortManager) + .WillByDefault(testing::Return(&port_manager_)); + } + + ~SerialTest() override = default; + + void SetUp() override { + original_client_ = SetBrowserClientForTesting(&test_client_); + RenderViewHostTestHarness::SetUp(); + } + + void TearDown() override { + RenderViewHostTestHarness::TearDown(); + if (original_client_) + SetBrowserClientForTesting(original_client_); + } + + device::FakeSerialPortManager* port_manager() { return &port_manager_; } + + private: + SerialTestContentBrowserClient test_client_; + ContentBrowserClient* original_client_ = nullptr; + device::FakeSerialPortManager port_manager_; + + DISALLOW_COPY_AND_ASSIGN(SerialTest); +}; + +} // namespace + +TEST_F(SerialTest, OpenAndClosePort) { + NavigateAndCommit(GURL(kTestUrl)); + + blink::mojom::SerialServicePtr service; + contents()->GetMainFrame()->BinderRegistryForTesting().BindInterface( + blink::mojom::SerialService::Name_, + mojo::MakeRequest(&service).PassMessagePipe()); + + auto token = base::UnguessableToken::Create(); + auto port_info = device::mojom::SerialPortInfo::New(); + port_info->token = token; + port_manager()->AddPort(std::move(port_info)); + + EXPECT_FALSE(contents()->IsConnectedToSerialPort()); + + device::mojom::SerialPortPtr port; + service->GetPort(token, mojo::MakeRequest(&port)); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(contents()->IsConnectedToSerialPort()); + + port.reset(); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(contents()->IsConnectedToSerialPort()); +} + +TEST_F(SerialTest, OpenAndNavigateCrossOrigin) { + NavigateAndCommit(GURL(kTestUrl)); + + blink::mojom::SerialServicePtr service; + contents()->GetMainFrame()->BinderRegistryForTesting().BindInterface( + blink::mojom::SerialService::Name_, + mojo::MakeRequest(&service).PassMessagePipe()); + + auto token = base::UnguessableToken::Create(); + auto port_info = device::mojom::SerialPortInfo::New(); + port_info->token = token; + port_manager()->AddPort(std::move(port_info)); + + EXPECT_FALSE(contents()->IsConnectedToSerialPort()); + + device::mojom::SerialPortPtr port; + service->GetPort(token, mojo::MakeRequest(&port)); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(contents()->IsConnectedToSerialPort()); + + NavigateAndCommit(GURL(kCrossOriginTestUrl)); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(contents()->IsConnectedToSerialPort()); + port.FlushForTesting(); + EXPECT_TRUE(port.encountered_error()); +} + +} // namespace content
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index a012751..c319c1a 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -583,7 +583,6 @@ GetContentClient()->browser()->GetAXModeForBrowserContext( browser_context)), audio_stream_monitor_(this), - bluetooth_connected_device_count_(0), media_web_contents_observer_( std::make_unique<MediaWebContentsObserver>(this)), media_device_group_id_salt_base_( @@ -1542,6 +1541,10 @@ return bluetooth_connected_device_count_ > 0; } +bool WebContentsImpl::IsConnectedToSerialPort() const { + return serial_active_frame_count_ > 0; +} + bool WebContentsImpl::HasPictureInPictureVideo() { return has_picture_in_picture_video_; } @@ -6713,6 +6716,31 @@ } } +void WebContentsImpl::IncrementSerialActiveFrameCount() { + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) + return; + + // Notify for UI updates if the state changes. + serial_active_frame_count_++; + if (serial_active_frame_count_ == 1) + NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); +} + +void WebContentsImpl::DecrementSerialActiveFrameCount() { + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) + return; + + // Notify for UI updates if the state changes. + DCHECK_NE(0u, serial_active_frame_count_); + serial_active_frame_count_--; + if (serial_active_frame_count_ == 0) + NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); +} + void WebContentsImpl::SetHasPersistentVideo(bool has_persistent_video) { if (has_persistent_video_ == has_persistent_video) return;
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index f2eeeea..d2c789a 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -344,6 +344,7 @@ void SetAudioMuted(bool mute) override; bool IsCurrentlyAudible() override; bool IsConnectedToBluetoothDevice() override; + bool IsConnectedToSerialPort() const override; bool HasPictureInPictureVideo() override; bool IsCrashed() override; void SetIsCrashed(base::TerminationStatus status, int error_code) override; @@ -935,6 +936,11 @@ void IncrementBluetoothConnectedDeviceCount(); void DecrementBluetoothConnectedDeviceCount(); + // Modify the counter of frames in this WebContents actively using serial + // ports. + void IncrementSerialActiveFrameCount(); + void DecrementSerialActiveFrameCount(); + // Called when the WebContents gains or loses a persistent video. void SetHasPersistentVideo(bool has_persistent_video); @@ -1754,7 +1760,8 @@ // Created on-demand to mute all audio output from this WebContents. std::unique_ptr<WebContentsAudioMuter> audio_muter_; - size_t bluetooth_connected_device_count_; + size_t bluetooth_connected_device_count_ = 0; + size_t serial_active_frame_count_ = 0; bool has_picture_in_picture_video_ = false;
diff --git a/content/browser/webrtc/OWNERS b/content/browser/webrtc/OWNERS index 4002051..11f9e9d 100644 --- a/content/browser/webrtc/OWNERS +++ b/content/browser/webrtc/OWNERS
@@ -1,9 +1,11 @@ chfremer@chromium.org emircan@chromium.org guidou@chromium.org -mcasas@chromium.org tommi@chromium.org per-file *test*=phoglund@chromium.org +# Original (legacy) owner. +mcasas@chromium.org + # COMPONENT: Blink>WebRTC
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 9d6cfeeb..614e3f7 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -481,6 +481,9 @@ WebRuntimeFeatures::EnableSignedExchangeSubresourcePrefetch( base::FeatureList::IsEnabled( features::kSignedExchangeSubresourcePrefetch)); + + if (!base::FeatureList::IsEnabled(features::kIdleDetection)) + WebRuntimeFeatures::EnableIdleDetection(false); } } // namespace
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 48b2fe1..4221f73 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -440,6 +440,10 @@ // Request ID generated by the renderer. IPC_STRUCT_MEMBER(int, request_id) + + // A token that has been passed by the browser process when it asked the + // renderer process to commit the navigation. + IPC_STRUCT_MEMBER(base::UnguessableToken, navigation_token) IPC_STRUCT_END() IPC_STRUCT_BEGIN(FrameMsg_PostMessage_Params) @@ -525,6 +529,7 @@ IPC_STRUCT_TRAITS_MEMBER(navigation_timing) IPC_STRUCT_TRAITS_MEMBER(appcache_host_id) IPC_STRUCT_TRAITS_MEMBER(was_activated) + IPC_STRUCT_TRAITS_MEMBER(navigation_token) #if defined(OS_ANDROID) IPC_STRUCT_TRAITS_MEMBER(data_url_as_string) #endif
diff --git a/content/common/navigation_params.cc b/content/common/navigation_params.cc index 3a802800..ef3ec05 100644 --- a/content/common/navigation_params.cc +++ b/content/common/navigation_params.cc
@@ -164,7 +164,8 @@ CommonNavigationParams::~CommonNavigationParams() = default; -CommitNavigationParams::CommitNavigationParams() = default; +CommitNavigationParams::CommitNavigationParams() + : navigation_token(base::UnguessableToken::Create()) {} CommitNavigationParams::CommitNavigationParams( const base::Optional<url::Origin>& origin_to_commit, @@ -198,7 +199,8 @@ current_history_list_offset(current_history_list_offset), current_history_list_length(current_history_list_length), is_view_source(is_view_source), - should_clear_history_list(should_clear_history_list) {} + should_clear_history_list(should_clear_history_list), + navigation_token(base::UnguessableToken::Create()) {} CommitNavigationParams::CommitNavigationParams( const CommitNavigationParams& other) = default;
diff --git a/content/common/navigation_params.h b/content/common/navigation_params.h index eff2dc20..727f5cc 100644 --- a/content/common/navigation_params.h +++ b/content/common/navigation_params.h
@@ -14,6 +14,7 @@ #include "base/memory/ref_counted.h" #include "base/optional.h" #include "base/time/time.h" +#include "base/unguessable_token.h" #include "build/build_config.h" #include "content/common/content_export.h" #include "content/common/content_security_policy/content_security_policy.h" @@ -396,6 +397,12 @@ // `user_gesture` will answer the latter. WasActivatedOption was_activated = WasActivatedOption::kUnknown; + // A token that should be passed to the browser process in + // DidCommitProvisionalLoadParams. + // TODO(clamy): Remove this once NavigationClient has shipped and + // same-document browser-initiated navigations are properly handled as well. + base::UnguessableToken navigation_token; + #if defined(OS_ANDROID) // The real content of the data: URL. Only used in Android WebView for // implementing LoadDataWithBaseUrl API method to circumvent the restriction
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 8f9aa70..d4cc92d3 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -878,7 +878,7 @@ } std::unique_ptr<LoginDelegate> ContentBrowserClient::CreateLoginDelegate( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, const GlobalRequestID& request_id, bool is_request_for_main_frame,
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 25e62c13..b7eb0de 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -1428,7 +1428,7 @@ // WebContentsDelegate, where the lifetime ordering is more // obvious. https://crbug.com/456255 virtual std::unique_ptr<LoginDelegate> CreateLoginDelegate( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, WebContents* web_contents, const GlobalRequestID& request_id, bool is_request_for_main_frame,
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h index b33d118..6cf2ca2 100644 --- a/content/public/browser/web_contents.h +++ b/content/public/browser/web_contents.h
@@ -474,6 +474,10 @@ // Device. virtual bool IsConnectedToBluetoothDevice() = 0; + // Indicates whether any frame in the WebContents is connected to a serial + // port. + virtual bool IsConnectedToSerialPort() const = 0; + // Indicates whether a video is in Picture-in-Picture for |this|. virtual bool HasPictureInPictureVideo() = 0;
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 705bae0..36b815680 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -188,6 +188,12 @@ const base::Feature kHistoryManipulationIntervention{ "HistoryManipulationIntervention", base::FEATURE_ENABLED_BY_DEFAULT}; +// This is intended as a kill switch for the Idle Detection feature. To enable +// this feature,the experimental web platform features flag should be set, +// or the site should obtain an Origin Trial token. +const base::Feature kIdleDetection{"IdleDetection", + base::FEATURE_ENABLED_BY_DEFAULT}; + // This flag is used to set field parameters to choose predictor we use when // kResamplingInputEvents is disabled. It's used for gatherig accuracy metrics // on finch and also for choosing predictor type for predictedEvents API without
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 584f1e4..1d2f9b9e 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -51,6 +51,7 @@ CONTENT_EXPORT extern const base::Feature kGuestViewCrossProcessFrames; CONTENT_EXPORT extern const base::Feature kHeapCompaction; CONTENT_EXPORT extern const base::Feature kHistoryManipulationIntervention; +CONTENT_EXPORT extern const base::Feature kIdleDetection; CONTENT_EXPORT extern const base::Feature kInputPredictorTypeChoice; CONTENT_EXPORT extern const base::Feature kIsolateOrigins; CONTENT_EXPORT extern const char kIsolateOriginsFieldTrialParamName[];
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index b341ba6b..e1dd1a94 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -382,9 +382,6 @@ // Disables the video decoder from drawing to an NV12 textures instead of ARGB. const char kDisableNv12DxgiVideo[] = "disable-nv12-dxgi-video"; -// Enables compositor-accelerated touch-screen pinch gestures. -const char kEnablePinch[] = "enable-pinch"; - // Enables testing features of the Plugin Placeholder. For internal use only. const char kEnablePluginPlaceholderTesting[] = "enable-plugin-placeholder-testing";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index e36c9e6..3ad2be1 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -122,7 +122,6 @@ CONTENT_EXPORT extern const char kEnableLogging[]; CONTENT_EXPORT extern const char kEnableNetworkInformationDownlinkMax[]; CONTENT_EXPORT extern const char kDisableNv12DxgiVideo[]; -CONTENT_EXPORT extern const char kEnablePinch[]; CONTENT_EXPORT extern const char kEnablePluginPlaceholderTesting[]; CONTENT_EXPORT extern const char kEnablePreciseMemoryInfo[]; CONTENT_EXPORT extern const char kEnablePrintBrowser[];
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 9512126..d74bbd0 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -100,8 +100,6 @@ "effective_connection_type_helper.h", "fetchers/associated_resource_fetcher_impl.cc", "fetchers/associated_resource_fetcher_impl.h", - "fetchers/manifest_fetcher.cc", - "fetchers/manifest_fetcher.h", "fetchers/multi_resolution_image_resource_fetcher.cc", "fetchers/multi_resolution_image_resource_fetcher.h", "fetchers/resource_fetcher_impl.cc",
diff --git a/content/renderer/fetchers/manifest_fetcher.cc b/content/renderer/fetchers/manifest_fetcher.cc deleted file mode 100644 index 8c45f2e..0000000 --- a/content/renderer/fetchers/manifest_fetcher.cc +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2014 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/renderer/fetchers/manifest_fetcher.h" - -#include "base/bind.h" -#include "base/logging.h" -#include "content/public/renderer/associated_resource_fetcher.h" -#include "services/network/public/mojom/request_context_frame_type.mojom.h" -#include "third_party/blink/public/platform/web_url_request.h" -#include "third_party/blink/public/web/web_associated_url_loader_options.h" -#include "third_party/blink/public/web/web_local_frame.h" - -namespace content { - -ManifestFetcher::ManifestFetcher(const GURL& url) - : completed_(false) { - fetcher_.reset(AssociatedResourceFetcher::Create(url)); -} - -ManifestFetcher::~ManifestFetcher() { - if (!completed_) - Cancel(); -} - -void ManifestFetcher::Start(blink::WebLocalFrame* frame, - bool use_credentials, - const Callback& callback) { - callback_ = callback; - - blink::WebAssociatedURLLoaderOptions options; - fetcher_->SetLoaderOptions(options); - - // See https://w3c.github.io/manifest/. Use "include" when use_credentials is - // true, and "omit" otherwise. - fetcher_->Start( - frame, blink::mojom::RequestContextType::MANIFEST, - network::mojom::FetchRequestMode::kCors, - use_credentials ? network::mojom::FetchCredentialsMode::kInclude - : network::mojom::FetchCredentialsMode::kOmit, - base::Bind(&ManifestFetcher::OnLoadComplete, base::Unretained(this))); -} - -void ManifestFetcher::Cancel() { - DCHECK(!completed_); - fetcher_->Cancel(); -} - -void ManifestFetcher::OnLoadComplete(const blink::WebURLResponse& response, - const std::string& data) { - DCHECK(!completed_); - completed_ = true; - - Callback callback = callback_; - std::move(callback).Run(response, data); -} - -} // namespace content
diff --git a/content/renderer/fetchers/manifest_fetcher.h b/content/renderer/fetchers/manifest_fetcher.h deleted file mode 100644 index ef48c184..0000000 --- a/content/renderer/fetchers/manifest_fetcher.h +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2014 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_RENDERER_FETCHERS_MANIFEST_FETCHER_H_ -#define CONTENT_RENDERER_FETCHERS_MANIFEST_FETCHER_H_ - -#include <memory> -#include <string> - -#include "base/callback.h" -#include "base/macros.h" -#include "content/common/content_export.h" -#include "third_party/blink/public/platform/web_url_response.h" - -class GURL; - -namespace blink { -class WebLocalFrame; -} - -namespace content { - -class AssociatedResourceFetcher; - -// Helper class to download a Web Manifest. When an instance is created, the -// caller need to call Start() and wait for the passed callback to be executed. -// If the fetch fails, the callback will be called with two empty objects. -class CONTENT_EXPORT ManifestFetcher { - public: - // This will be called asynchronously after the URL has been fetched, - // successfully or not. If there is a failure, response and data will both be - // empty. |response| and |data| are both valid until the URLFetcher instance - // is destroyed. - typedef base::Callback<void(const blink::WebURLResponse& response, - const std::string& data)> Callback; - - explicit ManifestFetcher(const GURL& url); - virtual ~ManifestFetcher(); - - void Start(blink::WebLocalFrame* frame, - bool use_credentials, - const Callback& callback); - void Cancel(); - - private: - void OnLoadComplete(const blink::WebURLResponse& response, - const std::string& data); - - bool completed_; - Callback callback_; - std::unique_ptr<AssociatedResourceFetcher> fetcher_; - - DISALLOW_COPY_AND_ASSIGN(ManifestFetcher); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_FETCHERS_MANIFEST_FETCHER_H_
diff --git a/content/renderer/image_capture/OWNERS b/content/renderer/image_capture/OWNERS index 57aa41f..cfb0c16 100644 --- a/content/renderer/image_capture/OWNERS +++ b/content/renderer/image_capture/OWNERS
@@ -1,5 +1,7 @@ -mcasas@chromium.org reillyg@chromium.org +# Original (legacy) owner. +mcasas@chromium.org + # COMPONENT: Blink>ImageCapture # TEAM: media-dev@chromium.org
diff --git a/content/renderer/manifest/manifest_manager.cc b/content/renderer/manifest/manifest_manager.cc index 77b5333b..4cefec39 100644 --- a/content/renderer/manifest/manifest_manager.cc +++ b/content/renderer/manifest/manifest_manager.cc
@@ -10,7 +10,6 @@ #include "base/no_destructor.h" #include "base/strings/nullable_string16.h" #include "content/public/renderer/render_frame.h" -#include "content/renderer/fetchers/manifest_fetcher.h" #include "content/renderer/manifest/manifest_uma_util.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/mojom/manifest/manifest.mojom.h" @@ -18,6 +17,7 @@ #include "third_party/blink/public/web/web_console_message.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_manifest_fetcher.h" #include "third_party/blink/public/web/web_manifest_parser.h" namespace content { @@ -114,7 +114,8 @@ return; } - manifest_url_ = render_frame()->GetWebFrame()->GetDocument().ManifestURL(); + blink::WebDocument document = render_frame()->GetWebFrame()->GetDocument(); + manifest_url_ = document.ManifestURL(); if (manifest_url_.is_empty()) { ManifestUmaUtil::FetchFailed(ManifestUmaUtil::FETCH_EMPTY_URL); @@ -122,13 +123,11 @@ return; } - fetcher_.reset(new ManifestFetcher(manifest_url_)); - fetcher_->Start( - render_frame()->GetWebFrame(), - render_frame()->GetWebFrame()->GetDocument().ManifestUseCredentials(), - base::Bind(&ManifestManager::OnManifestFetchComplete, - base::Unretained(this), - render_frame()->GetWebFrame()->GetDocument().Url())); + fetcher_.reset(new blink::WebManifestFetcher(manifest_url_)); + + fetcher_->Start(&document, document.ManifestUseCredentials(), + base::BindOnce(&ManifestManager::OnManifestFetchComplete, + base::Unretained(this), document.Url())); } static const std::string& GetMessagePrefix() { @@ -139,9 +138,9 @@ void ManifestManager::OnManifestFetchComplete( const GURL& document_url, const blink::WebURLResponse& response, - const std::string& data) { + const blink::WebString& data) { fetcher_.reset(); - if (response.IsNull() && data.empty()) { + if (response.IsNull() && data.IsEmpty()) { manifest_debug_info_ = nullptr; ManifestUmaUtil::FetchFailed(ManifestUmaUtil::FETCH_UNSPECIFIED_REASON); ResolveCallbacks(ResolveStateFailure); @@ -150,14 +149,15 @@ ManifestUmaUtil::FetchSucceeded(); GURL response_url = response.CurrentRequestUrl(); - base::StringPiece data_piece(data); + std::string data_string = data.Utf8(); + base::StringPiece data_piece(data_string); blink::WebVector<blink::ManifestError> errors; bool result = blink::WebManifestParser::ParseManifest( data_piece, response_url, document_url, &manifest_, &errors); manifest_debug_info_ = blink::mojom::ManifestDebugInfo::New(); - manifest_debug_info_->raw_manifest = data; + manifest_debug_info_->raw_manifest = data_string; for (const auto& error : errors) { blink::WebConsoleMessage message;
diff --git a/content/renderer/manifest/manifest_manager.h b/content/renderer/manifest/manifest_manager.h index 5836e41..a1920c9 100644 --- a/content/renderer/manifest/manifest_manager.h +++ b/content/renderer/manifest/manifest_manager.h
@@ -20,6 +20,7 @@ class GURL; namespace blink { +class WebManifestFetcher; class WebURLResponse; } @@ -71,10 +72,10 @@ void FetchManifest(); void OnManifestFetchComplete(const GURL& document_url, const blink::WebURLResponse& response, - const std::string& data); + const blink::WebString& data); void ResolveCallbacks(ResolveState state); - std::unique_ptr<ManifestFetcher> fetcher_; + std::unique_ptr<blink::WebManifestFetcher> fetcher_; // Whether the RenderFrame may have an associated Manifest. If true, the frame // may have a manifest, if false, it can't have one. This boolean is true when
diff --git a/content/renderer/media_capture_from_element/OWNERS b/content/renderer/media_capture_from_element/OWNERS index 446f8fb0..92fb9b5b 100644 --- a/content/renderer/media_capture_from_element/OWNERS +++ b/content/renderer/media_capture_from_element/OWNERS
@@ -1,4 +1,6 @@ emircan@chromium.org + +# Original (legacy) owner. mcasas@chromium.org # COMPONENT: Blink>MediaStream>CaptureFromElement
diff --git a/content/renderer/media_recorder/OWNERS b/content/renderer/media_recorder/OWNERS index 6675929..75beff3 100644 --- a/content/renderer/media_recorder/OWNERS +++ b/content/renderer/media_recorder/OWNERS
@@ -1,5 +1,6 @@ emircan@chromium.org + +# Original (legacy) owner. mcasas@chromium.org # COMPONENT: Blink>MediaRecording -# TEAM: media-dev@chromium.org
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index c6418073..a08682d9 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -5828,6 +5828,15 @@ params->post_id = -1; params->nav_entry_id = navigation_state->commit_params().nav_entry_id; + // Pass the navigation token back to the browser process, or generate a new + // one if this navigation is committing without the browser process asking for + // it. + // TODO(clamy): We should add checks on navigations that commit without having + // been asked to commit by the browser process. + params->navigation_token = navigation_state->commit_params().navigation_token; + if (params->navigation_token.is_empty()) + params->navigation_token = base::UnguessableToken::Create(); + // "Standard" commits from Blink create new NavigationEntries. We also treat // main frame "inert" commits as creating new NavigationEntries if they // replace the current entry on a cross-document navigation (e.g., client
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index 20a1d31..7307994c 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -481,7 +481,7 @@ } std::unique_ptr<LoginDelegate> ShellContentBrowserClient::CreateLoginDelegate( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, const content::GlobalRequestID& request_id, bool is_main_frame,
diff --git a/content/shell/browser/shell_content_browser_client.h b/content/shell/browser/shell_content_browser_client.h index 052bed3..3828b35 100644 --- a/content/shell/browser/shell_content_browser_client.h +++ b/content/shell/browser/shell_content_browser_client.h
@@ -79,7 +79,7 @@ const OpenURLParams& params, const base::Callback<void(WebContents*)>& callback) override; std::unique_ptr<LoginDelegate> CreateLoginDelegate( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, const content::GlobalRequestID& request_id, bool is_main_frame,
diff --git a/content/shell/browser/shell_login_dialog.cc b/content/shell/browser/shell_login_dialog.cc index bdb0ff6..fcbe687 100644 --- a/content/shell/browser/shell_login_dialog.cc +++ b/content/shell/browser/shell_login_dialog.cc
@@ -19,7 +19,7 @@ // static std::unique_ptr<ShellLoginDialog> ShellLoginDialog::Create( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, LoginAuthRequiredCallback auth_required_callback) { auto ret = std::make_unique<ShellLoginDialog>(std::move(auth_required_callback)); @@ -39,15 +39,15 @@ PlatformCleanUp(); } -void ShellLoginDialog::Init(net::AuthChallengeInfo* auth_info) { +void ShellLoginDialog::Init(const net::AuthChallengeInfo& auth_info) { // Run this in a new event loop iteration, to ensure the callback isn't called // reentrantly. base::PostTaskWithTraits( FROM_HERE, {BrowserThread::UI}, base::BindOnce( &ShellLoginDialog::PrepDialog, weak_factory_.GetWeakPtr(), - url_formatter::FormatOriginForSecurityDisplay(auth_info->challenger), - base::UTF8ToUTF16(auth_info->realm))); + url_formatter::FormatOriginForSecurityDisplay(auth_info.challenger), + base::UTF8ToUTF16(auth_info.realm))); } void ShellLoginDialog::UserAcceptedAuth(const base::string16& username,
diff --git a/content/shell/browser/shell_login_dialog.h b/content/shell/browser/shell_login_dialog.h index 68c0216..00e9efb 100644 --- a/content/shell/browser/shell_login_dialog.h +++ b/content/shell/browser/shell_login_dialog.h
@@ -35,7 +35,7 @@ class ShellLoginDialog : public LoginDelegate { public: static std::unique_ptr<ShellLoginDialog> Create( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, LoginAuthRequiredCallback auth_required_callback); explicit ShellLoginDialog(LoginAuthRequiredCallback auth_required_callback); @@ -49,7 +49,7 @@ void UserCancelledAuth(); private: - void Init(net::AuthChallengeInfo* auth_info); + void Init(const net::AuthChallengeInfo& auth_info); // All the methods that begin with Platform need to be implemented by the // platform specific LoginDialog implementation.
diff --git a/content/shell/browser/web_test/web_test_content_browser_client.cc b/content/shell/browser/web_test/web_test_content_browser_client.cc index a538828..a303b16 100644 --- a/content/shell/browser/web_test/web_test_content_browser_client.cc +++ b/content/shell/browser/web_test/web_test_content_browser_client.cc
@@ -317,7 +317,7 @@ } std::unique_ptr<LoginDelegate> WebTestContentBrowserClient::CreateLoginDelegate( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, const content::GlobalRequestID& request_id, bool is_main_frame,
diff --git a/content/shell/browser/web_test/web_test_content_browser_client.h b/content/shell/browser/web_test/web_test_content_browser_client.h index 10440a2..6413e5f 100644 --- a/content/shell/browser/web_test/web_test_content_browser_client.h +++ b/content/shell/browser/web_test/web_test_content_browser_client.h
@@ -78,7 +78,7 @@ service_manager::BinderRegistryWithArgs<content::RenderFrameHost*>* registry) override; std::unique_ptr<LoginDelegate> CreateLoginDelegate( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, const content::GlobalRequestID& request_id, bool is_main_frame,
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 18455585..7e712184 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -433,6 +433,11 @@ "//content/shell:android_shell_descriptors", "//mojo/public/java/system:native_support", ] + } else { + sources += [ + "../browser/serial/serial_test_utils.cc", + "../browser/serial/serial_test_utils.h", + ] } if (enable_plugins) { @@ -1249,10 +1254,7 @@ if (is_chromeos) { deps += [ "//chromeos/audio", - - # TODO(stevenjb): Replace with //chromeos/dbus/audio once extracted. - # https://crbug.com/940810. - "//chromeos/dbus", + "//chromeos/dbus/audio", ] } @@ -2157,10 +2159,7 @@ if (is_chromeos) { deps += [ "//chromeos/audio", - - # TODO(stevenjb): Replace with //chromeos/dbus/audio once extracted. - # https://crbug.com/940810. - "//chromeos/dbus", + "//chromeos/dbus/audio", ] } if (is_android) { @@ -2205,6 +2204,7 @@ # Non-Android. sources += [ "../browser/host_zoom_map_impl_unittest.cc", + "../browser/serial/serial_unittest.cc", "../browser/speech/chunked_byte_buffer_unittest.cc", "../browser/speech/endpointer/endpointer_unittest.cc", "../browser/speech/speech_recognition_engine_unittest.cc",
diff --git a/content/test/navigation_simulator_impl.cc b/content/test/navigation_simulator_impl.cc index f37f0f75..21a65ebf 100644 --- a/content/test/navigation_simulator_impl.cc +++ b/content/test/navigation_simulator_impl.cc
@@ -310,6 +310,7 @@ ? render_frame_host->frame_tree_node() : web_contents->GetMainFrame()->frame_tree_node()), request_(nullptr), + original_url_(original_url), navigation_url_(original_url), initial_method_("GET"), browser_initiated_(browser_initiated), @@ -359,6 +360,7 @@ CHECK(render_frame_host_); CHECK_EQ(frame_tree_node_, request_->frame_tree_node()); state_ = STARTED; + original_url_ = request->commit_params().original_url; navigation_url_ = handle->GetURL(); // |remote_endpoint_| cannot be inferred from the request. // |initial_method_| cannot be set after the request has started. @@ -1218,7 +1220,7 @@ std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params = std::make_unique<FrameHostMsg_DidCommitProvisionalLoad_Params>(); params->url = navigation_url_; - params->original_request_url = navigation_url_; + params->original_request_url = original_url_; params->referrer = referrer_; params->contents_mime_type = contents_mime_type_; params->transition = transition_; @@ -1227,6 +1229,9 @@ params->history_list_was_cleared = history_list_was_cleared_; params->did_create_new_entry = DidCreateNewEntry(); params->should_replace_current_entry = should_replace_current_entry_; + params->navigation_token = request_ + ? request_->commit_params().navigation_token + : base::UnguessableToken::Create(); if (intended_as_new_entry_.has_value()) params->intended_as_new_entry = intended_as_new_entry_.value();
diff --git a/content/test/navigation_simulator_impl.h b/content/test/navigation_simulator_impl.h index 6c4cfff9..517dbdc 100644 --- a/content/test/navigation_simulator_impl.h +++ b/content/test/navigation_simulator_impl.h
@@ -246,6 +246,7 @@ // Note: additional parameters to modify the navigation should be properly // initialized (if needed) in InitializeFromStartedRequest. + GURL original_url_; GURL navigation_url_; net::IPEndPoint remote_endpoint_; bool is_signed_exchange_inner_response_ = false;
diff --git a/device/usb/mojo/device_manager_impl.cc b/device/usb/mojo/device_manager_impl.cc index aa8cac0..5e4a00d 100644 --- a/device/usb/mojo/device_manager_impl.cc +++ b/device/usb/mojo/device_manager_impl.cc
@@ -97,10 +97,10 @@ static_cast<device::UsbDeviceLinux*>(device.get())->device_path(); chromeos::PermissionBrokerClient::Get()->OpenPath( devpath, - base::BindRepeating(&DeviceManagerImpl::OnOpenFileDescriptor, - weak_factory_.GetWeakPtr(), copyable_callback), - base::BindRepeating(&DeviceManagerImpl::OnOpenFileDescriptorError, - weak_factory_.GetWeakPtr(), copyable_callback)); + base::BindOnce(&DeviceManagerImpl::OnOpenFileDescriptor, + weak_factory_.GetWeakPtr(), copyable_callback), + base::BindOnce(&DeviceManagerImpl::OnOpenFileDescriptorError, + weak_factory_.GetWeakPtr(), copyable_callback)); } }
diff --git a/device/usb/usb_device_linux.cc b/device/usb/usb_device_linux.cc index dc2be5a..6085eedb 100644 --- a/device/usb/usb_device_linux.cc +++ b/device/usb/usb_device_linux.cc
@@ -48,8 +48,8 @@ void UsbDeviceLinux::CheckUsbAccess(ResultCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - chromeos::PermissionBrokerClient::Get()->CheckPathAccess( - device_path_, base::AdaptCallbackForRepeating(std::move(callback))); + chromeos::PermissionBrokerClient::Get()->CheckPathAccess(device_path_, + std::move(callback)); } #endif // defined(OS_CHROMEOS) @@ -61,9 +61,10 @@ auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback)); chromeos::PermissionBrokerClient::Get()->OpenPath( device_path_, - base::Bind(&UsbDeviceLinux::OnOpenRequestComplete, this, - copyable_callback), - base::Bind(&UsbDeviceLinux::OnOpenRequestError, this, copyable_callback)); + base::BindOnce(&UsbDeviceLinux::OnOpenRequestComplete, this, + copyable_callback), + base::BindOnce(&UsbDeviceLinux::OnOpenRequestError, this, + copyable_callback)); #else scoped_refptr<base::SequencedTaskRunner> blocking_task_runner = UsbService::CreateBlockingTaskRunner();
diff --git a/docs/vscode.md b/docs/vscode.md index ef87c75..d598b97d5 100644 --- a/docs/vscode.md +++ b/docs/vscode.md
@@ -262,6 +262,10 @@ $ cp tools/vscode/keybindings.json5 .vscode/keybindings.json ``` +### Snippets +There are some useful snippets provided in +[//tools/vscode/cpp.json5](/tools/vscode/cpp.json5). + ### Tips #### The `out` folder
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index 61239e12..6a4df71 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn
@@ -514,6 +514,7 @@ "//chromeos", "//chromeos/audio", "//chromeos/dbus:test_support", + "//chromeos/dbus/audio", "//chromeos/dbus/media_analytics", "//chromeos/dbus/media_analytics:media_perception_proto", "//chromeos/dbus/permission_broker", @@ -724,6 +725,7 @@ deps += [ "//chromeos:test_support", "//chromeos/dbus:test_support", + "//chromeos/dbus/audio", "//chromeos/dbus/media_analytics", "//chromeos/dbus/media_analytics:media_perception_proto", "//chromeos/dbus/power",
diff --git a/extensions/browser/api/device_permissions_prompt.cc b/extensions/browser/api/device_permissions_prompt.cc index 167a75c..ec62bbb 100644 --- a/extensions/browser/api/device_permissions_prompt.cc +++ b/extensions/browser/api/device_permissions_prompt.cc
@@ -262,8 +262,8 @@ #if defined(OS_CHROMEOS) chromeos::PermissionBrokerClient::Get()->CheckPathAccess( device_info.get()->device()->device_node, - base::Bind(&HidDevicePermissionsPrompt::AddCheckedDevice, this, - base::Passed(&device_info))); + base::BindOnce(&HidDevicePermissionsPrompt::AddCheckedDevice, this, + std::move(device_info))); #else AddCheckedDevice(std::move(device_info), true); #endif // defined(OS_CHROMEOS)
diff --git a/extensions/browser/api/feedback_private/feedback_private_api.cc b/extensions/browser/api/feedback_private/feedback_private_api.cc index b0f7700..7a989fc 100644 --- a/extensions/browser/api/feedback_private/feedback_private_api.cc +++ b/extensions/browser/api/feedback_private/feedback_private_api.cc
@@ -397,4 +397,14 @@ } } +ExtensionFunction::ResponseAction +FeedbackPrivateLoginFeedbackCompleteFunction::Run() { +#if defined(OS_CHROMEOS) + FeedbackPrivateDelegate* feedback_private_delegate = + ExtensionsAPIClient::Get()->GetFeedbackPrivateDelegate(); + feedback_private_delegate->UnloadFeedbackExtension(browser_context()); +#endif + return RespondNow(NoArguments()); +} + } // namespace extensions
diff --git a/extensions/browser/api/feedback_private/feedback_private_api.h b/extensions/browser/api/feedback_private/feedback_private_api.h index 794fa510..55e3c07b 100644 --- a/extensions/browser/api/feedback_private/feedback_private_api.h +++ b/extensions/browser/api/feedback_private/feedback_private_api.h
@@ -148,6 +148,17 @@ void OnCompleted(api::feedback_private::LandingPageType type, bool success); }; +class FeedbackPrivateLoginFeedbackCompleteFunction + : public UIThreadExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("feedbackPrivate.loginFeedbackComplete", + FEEDBACKPRIVATE_LOGINFEEDBACKCOMPLETE) + + protected: + ~FeedbackPrivateLoginFeedbackCompleteFunction() override {} + ResponseAction Run() override; +}; + } // namespace extensions #endif // EXTENSIONS_BROWSER_API_FEEDBACK_PRIVATE_FEEDBACK_PRIVATE_API_H_
diff --git a/extensions/browser/api/feedback_private/feedback_private_delegate.h b/extensions/browser/api/feedback_private/feedback_private_delegate.h index a4204fced..6a05b106 100644 --- a/extensions/browser/api/feedback_private/feedback_private_delegate.h +++ b/extensions/browser/api/feedback_private/feedback_private_delegate.h
@@ -59,6 +59,11 @@ std::unique_ptr<FeedbackCommon::SystemLogsMap> original_sys_logs, content::BrowserContext* context, system_logs::SysLogsFetcherCallback callback) const = 0; + + // Unloads the feedback extension from the current profile, should only be + // called when feedback is complete for the login profile. + virtual void UnloadFeedbackExtension( + content::BrowserContext* context) const = 0; #endif // Returns the normalized email address of the signed-in user associated with
diff --git a/extensions/browser/api/serial/serial_apitest.cc b/extensions/browser/api/serial/serial_apitest.cc index 79240759..ddd3289 100644 --- a/extensions/browser/api/serial/serial_apitest.cc +++ b/extensions/browser/api/serial/serial_apitest.cc
@@ -285,7 +285,9 @@ } void GetPort(const base::UnguessableToken& token, - device::mojom::SerialPortRequest request) override { + device::mojom::SerialPortRequest request, + device::mojom::SerialPortConnectionWatcherPtr watcher) override { + DCHECK(!watcher); auto it = token_path_map_.find(token); DCHECK(it != token_path_map_.end()); mojo::MakeStrongBinding(std::make_unique<FakeSerialPort>(it->second),
diff --git a/extensions/browser/api/serial/serial_port_manager.cc b/extensions/browser/api/serial/serial_port_manager.cc index 44ea9b1..f47311b 100644 --- a/extensions/browser/api/serial/serial_port_manager.cc +++ b/extensions/browser/api/serial/serial_port_manager.cc
@@ -194,7 +194,8 @@ for (auto& device : devices) { if (device->path.AsUTF8Unsafe() == path) { - port_manager_->GetPort(device->token, std::move(request)); + port_manager_->GetPort(device->token, std::move(request), + /*watcher=*/nullptr); return; } }
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc index 6722eb9..13598c2 100644 --- a/extensions/browser/api/web_request/web_request_api.cc +++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -405,7 +405,7 @@ void MaybeProxyAuthRequestOnIO( content::ResourceContext* resource_context, - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, scoped_refptr<net::HttpResponseHeaders> response_headers, const content::GlobalRequestID& request_id, WebRequestAPI::AuthRequestCallback callback) { @@ -477,7 +477,7 @@ } // namespace void WebRequestAPI::Proxy::HandleAuthRequest( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, scoped_refptr<net::HttpResponseHeaders> response_headers, int32_t request_id, AuthRequestCallback callback) { @@ -558,7 +558,7 @@ } void WebRequestAPI::ProxySet::MaybeProxyAuthRequest( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, scoped_refptr<net::HttpResponseHeaders> response_headers, const content::GlobalRequestID& request_id, AuthRequestCallback callback) { @@ -714,7 +714,7 @@ bool WebRequestAPI::MaybeProxyAuthRequest( content::BrowserContext* browser_context, - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, scoped_refptr<net::HttpResponseHeaders> response_headers, const content::GlobalRequestID& request_id, bool is_main_frame, @@ -736,9 +736,9 @@ base::PostTaskWithTraits( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&MaybeProxyAuthRequestOnIO, - browser_context->GetResourceContext(), - base::RetainedRef(auth_info), std::move(response_headers), - proxied_request_id, std::move(callback))); + browser_context->GetResourceContext(), auth_info, + std::move(response_headers), proxied_request_id, + std::move(callback))); return true; }
diff --git a/extensions/browser/api/web_request/web_request_api.h b/extensions/browser/api/web_request/web_request_api.h index d13caea5..e0322509 100644 --- a/extensions/browser/api/web_request/web_request_api.h +++ b/extensions/browser/api/web_request/web_request_api.h
@@ -95,7 +95,7 @@ // in-progress network requests. If the request will *not* be handled by // the proxy, |callback| should be invoked with |base::nullopt|. virtual void HandleAuthRequest( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, scoped_refptr<net::HttpResponseHeaders> response_headers, int32_t request_id, AuthRequestCallback callback); @@ -134,7 +134,7 @@ Proxy* GetProxyFromRequestId(const content::GlobalRequestID& id); void MaybeProxyAuthRequest( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, scoped_refptr<net::HttpResponseHeaders> response_headers, const content::GlobalRequestID& request_id, AuthRequestCallback callback); @@ -209,7 +209,7 @@ // thread. bool MaybeProxyAuthRequest( content::BrowserContext* browser_context, - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, scoped_refptr<net::HttpResponseHeaders> response_headers, const content::GlobalRequestID& request_id, bool is_main_frame,
diff --git a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc index cb617f9a..7df76569 100644 --- a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc +++ b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
@@ -276,7 +276,7 @@ } void WebRequestProxyingURLLoaderFactory::InProgressRequest::HandleAuthRequest( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, scoped_refptr<net::HttpResponseHeaders> response_headers, WebRequestAPI::AuthRequestCallback callback) { DCHECK(!auth_credentials_); @@ -294,7 +294,7 @@ // which indicated a need to authenticate. HandleResponseOrRedirectHeaders(base::BindOnce( &InProgressRequest::ContinueAuthRequest, weak_factory_.GetWeakPtr(), - base::RetainedRef(auth_info), std::move(callback))); + auth_info, std::move(callback))); } void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnLoaderCreated( @@ -519,7 +519,7 @@ } void WebRequestProxyingURLLoaderFactory::InProgressRequest::ContinueAuthRequest( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, WebRequestAPI::AuthRequestCallback callback, int error_code) { if (error_code != net::OK) { @@ -538,7 +538,7 @@ net::NetworkDelegate::AuthRequiredResponse response = ExtensionWebRequestEventRouter::GetInstance()->OnAuthRequired( factory_->browser_context_, factory_->info_map_, &info_.value(), - *auth_info, continuation, &auth_credentials_.value()); + auth_info, continuation, &auth_credentials_.value()); // At least one extension has a blocking handler for this request, so we'll // just wait for them to finish. |OnAuthRequestHandled()| will be invoked @@ -866,7 +866,7 @@ } void WebRequestProxyingURLLoaderFactory::HandleAuthRequest( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, scoped_refptr<net::HttpResponseHeaders> response_headers, int32_t request_id, WebRequestAPI::AuthRequestCallback callback) {
diff --git a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h index 278921bc..2226b1ea 100644 --- a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h +++ b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h
@@ -90,7 +90,7 @@ void OnComplete(const network::URLLoaderCompletionStatus& status) override; void HandleAuthRequest( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, scoped_refptr<net::HttpResponseHeaders> response_headers, WebRequestAPI::AuthRequestCallback callback); @@ -108,7 +108,7 @@ void ContinueToStartRequest(int error_code); void ContinueToHandleOverrideHeaders(int error_code); void ContinueToResponseStarted(int error_code); - void ContinueAuthRequest(net::AuthChallengeInfo* auth_info, + void ContinueAuthRequest(const net::AuthChallengeInfo& auth_info, WebRequestAPI::AuthRequestCallback callback, int error_code); void OnAuthRequestHandled( @@ -219,7 +219,7 @@ // WebRequestAPI::Proxy: void HandleAuthRequest( - net::AuthChallengeInfo* auth_info, + const net::AuthChallengeInfo& auth_info, scoped_refptr<net::HttpResponseHeaders> response_headers, int32_t request_id, WebRequestAPI::AuthRequestCallback callback) override;
diff --git a/extensions/browser/api/web_request/web_request_proxying_websocket.cc b/extensions/browser/api/web_request/web_request_proxying_websocket.cc index d630a42..41baffb 100644 --- a/extensions/browser/api/web_request/web_request_proxying_websocket.cc +++ b/extensions/browser/api/web_request/web_request_proxying_websocket.cc
@@ -266,11 +266,11 @@ } void WebRequestProxyingWebSocket::OnAuthRequired( - const scoped_refptr<net::AuthChallengeInfo>& auth_info, + const net::AuthChallengeInfo& auth_info, const scoped_refptr<net::HttpResponseHeaders>& headers, const net::IPEndPoint& remote_endpoint, OnAuthRequiredCallback callback) { - if (!auth_info || !callback) { + if (!callback) { OnError(net::ERR_FAILED); return; } @@ -464,7 +464,7 @@ } void WebRequestProxyingWebSocket::OnHeadersReceivedCompleteForAuth( - scoped_refptr<net::AuthChallengeInfo> auth_info, + const net::AuthChallengeInfo& auth_info, int rv) { if (rv != net::OK) { OnError(rv); @@ -477,7 +477,7 @@ base::BindRepeating(&WebRequestProxyingWebSocket::OnAuthRequiredComplete, weak_factory_.GetWeakPtr()); auto auth_rv = ExtensionWebRequestEventRouter::GetInstance()->OnAuthRequired( - browser_context_, info_map_, &info_.value(), *auth_info, + browser_context_, info_map_, &info_.value(), auth_info, std::move(continuation), &auth_credentials_); PauseIncomingMethodCallProcessing(); if (auth_rv == net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_IO_PENDING)
diff --git a/extensions/browser/api/web_request/web_request_proxying_websocket.h b/extensions/browser/api/web_request/web_request_proxying_websocket.h index cac917d..1e5d162 100644 --- a/extensions/browser/api/web_request/web_request_proxying_websocket.h +++ b/extensions/browser/api/web_request/web_request_proxying_websocket.h
@@ -86,7 +86,7 @@ void OnClosingHandshake() override; // mojom::AuthenticationHandler method: - void OnAuthRequired(const scoped_refptr<net::AuthChallengeInfo>& auth_info, + void OnAuthRequired(const net::AuthChallengeInfo& auth_info, const scoped_refptr<net::HttpResponseHeaders>& headers, const net::IPEndPoint& remote_endpoint, OnAuthRequiredCallback callback) override; @@ -117,9 +117,8 @@ void OnHeadersReceivedComplete(int error_code); void ContinueToHeadersReceived(); void OnAuthRequiredComplete(net::NetworkDelegate::AuthRequiredResponse rv); - void OnHeadersReceivedCompleteForAuth( - scoped_refptr<net::AuthChallengeInfo> auth_info, - int rv); + void OnHeadersReceivedCompleteForAuth(const net::AuthChallengeInfo& auth_info, + int rv); void PauseIncomingMethodCallProcessing(); void ResumeIncomingMethodCallProcessing();
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index f51c381a..ad5f98e 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1390,6 +1390,7 @@ AUTOTESTPRIVATE_IMPORTCROSTINI = 1327, ACCESSIBILITY_PRIVATE_SETVIRTUALKEYBOARDVISIBLE = 1328, AUTOTESTPRIVATE_SHOWVIRTUALKEYBOARDIFENABLED = 1329, + FEEDBACKPRIVATE_LOGINFEEDBACKCOMPLETE = 1330, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/browser/suggest_permission_util.cc b/extensions/browser/suggest_permission_util.cc index e9e30ab..be259e6b 100644 --- a/extensions/browser/suggest_permission_util.cc +++ b/extensions/browser/suggest_permission_util.cc
@@ -17,9 +17,9 @@ namespace { const char kPermissionsHelpURLForExtensions[] = - "http://developer.chrome.com/extensions/manifest.html#permissions"; + "https://developer.chrome.com/extensions/manifest.html#permissions"; const char kPermissionsHelpURLForApps[] = - "http://developer.chrome.com/apps/declare_permissions.html"; + "https://developer.chrome.com/apps/declare_permissions.html"; void SuggestAPIPermissionInDevToolsConsole( APIPermission::ID permission,
diff --git a/extensions/common/api/feedback_private.idl b/extensions/common/api/feedback_private.idl index 08a908b..4585ed73 100644 --- a/extensions/common/api/feedback_private.idl +++ b/extensions/common/api/feedback_private.idl
@@ -229,6 +229,11 @@ // </ul> static void readLogSource(ReadLogSourceParams params, ReadLogSourceCallback callback); + + // Invoked when the extension is complete during sending feedback from the + // login page. This is then used to know we can unload the feedback + // extension from the login profile. + static void loginFeedbackComplete(); }; interface Events {
diff --git a/extensions/shell/BUILD.gn b/extensions/shell/BUILD.gn index bd5667fc..52e89cd 100644 --- a/extensions/shell/BUILD.gn +++ b/extensions/shell/BUILD.gn
@@ -230,6 +230,7 @@ "//chromeos/audio", "//chromeos/constants", "//chromeos/dbus", + "//chromeos/dbus/audio", "//chromeos/dbus/power", "//chromeos/disks", "//chromeos/login/login_state", @@ -361,6 +362,7 @@ "//chromeos/audio", "//chromeos/constants", "//chromeos/dbus:test_support", + "//chromeos/dbus/audio", "//chromeos/dbus/power", ] }
diff --git a/extensions/shell/browser/api/feedback_private/shell_feedback_private_delegate.cc b/extensions/shell/browser/api/feedback_private/shell_feedback_private_delegate.cc index a4b1671..fa890377 100644 --- a/extensions/shell/browser/api/feedback_private/shell_feedback_private_delegate.cc +++ b/extensions/shell/browser/api/feedback_private/shell_feedback_private_delegate.cc
@@ -48,6 +48,11 @@ NOTIMPLEMENTED(); std::move(callback).Run(std::move(original_sys_logs)); } + +void ShellFeedbackPrivateDelegate::UnloadFeedbackExtension( + content::BrowserContext* context) const { + NOTIMPLEMENTED(); +} #endif std::string ShellFeedbackPrivateDelegate::GetSignedInUserEmail(
diff --git a/extensions/shell/browser/api/feedback_private/shell_feedback_private_delegate.h b/extensions/shell/browser/api/feedback_private/shell_feedback_private_delegate.h index 3315e6f..0e2d2c9 100644 --- a/extensions/shell/browser/api/feedback_private/shell_feedback_private_delegate.h +++ b/extensions/shell/browser/api/feedback_private/shell_feedback_private_delegate.h
@@ -30,6 +30,7 @@ std::unique_ptr<FeedbackCommon::SystemLogsMap> original_sys_logs, content::BrowserContext* context, system_logs::SysLogsFetcherCallback callback) const override; + void UnloadFeedbackExtension(content::BrowserContext* context) const override; #endif // defined(OS_CHROMEOS) std::string GetSignedInUserEmail( content::BrowserContext* context) const override;
diff --git a/fuchsia/http/url_loader_impl.cc b/fuchsia/http/url_loader_impl.cc index e09aac9..ee793d96 100644 --- a/fuchsia/http/url_loader_impl.cc +++ b/fuchsia/http/url_loader_impl.cc
@@ -232,7 +232,7 @@ } void URLLoaderImpl::OnAuthRequired(net::URLRequest* request, - net::AuthChallengeInfo* auth_info) { + const net::AuthChallengeInfo& auth_info) { NOTIMPLEMENTED(); DCHECK_EQ(net_request_.get(), request); request->CancelAuth();
diff --git a/fuchsia/http/url_loader_impl.h b/fuchsia/http/url_loader_impl.h index 874a8ff..9e154337e 100644 --- a/fuchsia/http/url_loader_impl.h +++ b/fuchsia/http/url_loader_impl.h
@@ -47,7 +47,7 @@ const net::RedirectInfo& redirect_info, bool* defer_redirect) override; void OnAuthRequired(net::URLRequest* request, - net::AuthChallengeInfo* auth_info) override; + const net::AuthChallengeInfo& auth_info) override; void OnCertificateRequested( net::URLRequest* request, net::SSLCertRequestInfo* cert_request_info) override; @@ -118,4 +118,4 @@ DISALLOW_COPY_AND_ASSIGN(URLLoaderImpl); }; -#endif // FUCHSIA_HTTP_URL_LOADER_IMPL_H_ \ No newline at end of file +#endif // FUCHSIA_HTTP_URL_LOADER_IMPL_H_
diff --git a/google_apis/gaia/fake_oauth2_token_service_delegate.cc b/google_apis/gaia/fake_oauth2_token_service_delegate.cc index 5da5fcb..efc528f 100644 --- a/google_apis/gaia/fake_oauth2_token_service_delegate.cc +++ b/google_apis/gaia/fake_oauth2_token_service_delegate.cc
@@ -3,8 +3,6 @@ // found in the LICENSE file. #include "google_apis/gaia/fake_oauth2_token_service_delegate.h" - -#include "build/build_config.h" #include "google_apis/gaia/oauth2_access_token_fetcher_impl.h" namespace { @@ -165,11 +163,3 @@ it->second->error = error; FireAuthErrorChanged(account_id, error); } - -#if defined(OS_IOS) -void FakeOAuth2TokenServiceDelegate::ReloadAccountsFromSystem( - const std::string& primary_account_id) { - UpdateCredentials(primary_account_id, - "refresh_token_for_" + primary_account_id); -} -#endif
diff --git a/google_apis/gaia/fake_oauth2_token_service_delegate.h b/google_apis/gaia/fake_oauth2_token_service_delegate.h index 497092a..8fff5cc3 100644 --- a/google_apis/gaia/fake_oauth2_token_service_delegate.h +++ b/google_apis/gaia/fake_oauth2_token_service_delegate.h
@@ -9,7 +9,6 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "build/build_config.h" #include "google_apis/gaia/google_service_auth_error.h" #include "google_apis/gaia/oauth2_token_service_delegate.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" @@ -45,10 +44,6 @@ void ExtractCredentials(OAuth2TokenService* to_service, const std::string& account_id) override; -#if defined(OS_IOS) - void ReloadAccountsFromSystem(const std::string& primary_account_id) override; -#endif - scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() const override;
diff --git a/google_apis/google_api_keys.cc b/google_apis/google_api_keys.cc index f6a7f4e..6d187b5 100644 --- a/google_apis/google_api_keys.cc +++ b/google_apis/google_api_keys.cc
@@ -97,7 +97,7 @@ namespace google_apis { const char kAPIKeysDevelopersHowToURL[] = - "http://www.chromium.org/developers/how-tos/api-keys"; + "https://www.chromium.org/developers/how-tos/api-keys"; // This is used as a lazy instance to determine keys once and cache them. class APIKeyCache {
diff --git a/gpu/command_buffer/service/shared_image_factory.cc b/gpu/command_buffer/service/shared_image_factory.cc index fbf1c84..86d40301 100644 --- a/gpu/command_buffer/service/shared_image_factory.cc +++ b/gpu/command_buffer/service/shared_image_factory.cc
@@ -209,8 +209,9 @@ uint32_t usage, bool* allow_legacy_mailbox) { // wrapped_sk_image_factory_ is only used for OOPR. - constexpr auto kUsageOOPR = - SHARED_IMAGE_USAGE_OOP_RASTERIZATION | SHARED_IMAGE_USAGE_DISPLAY; + constexpr auto kUsageOOPR = SHARED_IMAGE_USAGE_RASTER | + SHARED_IMAGE_USAGE_OOP_RASTERIZATION | + SHARED_IMAGE_USAGE_DISPLAY; bool oopr_only_usage = !(usage & ~kUsageOOPR); bool using_wrapped_sk_image = wrapped_sk_image_factory_ && oopr_only_usage;
diff --git a/infra/config/cr-buildbucket.cfg b/infra/config/cr-buildbucket.cfg index a9d1609a..c64a286ce 100644 --- a/infra/config/cr-buildbucket.cfg +++ b/infra/config/cr-buildbucket.cfg
@@ -3672,7 +3672,7 @@ dimensions:"os:Mac-10.13" } builders { mixins: "mac-try" name: "mac_chromium_compile_rel_ng" } - builders { mixins: "mac-try" name: "mac_chromium_dbg_ng" dimensions:"os:Mac-10.12"} + builders { mixins: "mac-try" name: "mac_chromium_dbg_ng" } builders { mixins: "mac-try" mixins: "goma-j150"
diff --git a/ios/chrome/browser/DEPS b/ios/chrome/browser/DEPS index 7da5adfa..f834bffb 100644 --- a/ios/chrome/browser/DEPS +++ b/ios/chrome/browser/DEPS
@@ -76,6 +76,7 @@ # Use identity_manager.h instead of the below files; # see https://groups.google.com/a/chromium.org/d/msg/chromium-dev/dgFLuxqZt1o/iEqkyoQQBwAJ for help and info. "!components/signin/core/browser/fake_profile_oauth2_token_service.h", + "!components/signin/core/browser/profile_oauth2_token_service.h", "!components/signin/core/browser/fake_signin_manager.h", "!components/signin/core/browser/signin_manager.h", "!components/signin/core/browser/signin_manager_base.h",
diff --git a/ios/chrome/browser/autofill/BUILD.gn b/ios/chrome/browser/autofill/BUILD.gn index 480b838..3bb6bbc 100644 --- a/ios/chrome/browser/autofill/BUILD.gn +++ b/ios/chrome/browser/autofill/BUILD.gn
@@ -510,6 +510,7 @@ "//ios/testing/earl_grey:earl_grey_support", "//ios/third_party/earl_grey:earl_grey+link", "//ios/web:earl_grey_test_support", + "//ios/web/public/test:element_selector", "//ios/web/public/test/http_server", ] }
diff --git a/ios/chrome/browser/autofill/automation/BUILD.gn b/ios/chrome/browser/autofill/automation/BUILD.gn index 47b24ff..4dd97d7 100644 --- a/ios/chrome/browser/autofill/automation/BUILD.gn +++ b/ios/chrome/browser/autofill/automation/BUILD.gn
@@ -31,6 +31,7 @@ "//ios/chrome/test/earl_grey:test_support", "//ios/testing/earl_grey:earl_grey_support", "//ios/web:earl_grey_test_support", + "//ios/web/public/test:element_selector", "//ios/web/public/test/http_server:http_server", "//ui/base", ]
diff --git a/ios/chrome/browser/component_updater/BUILD.gn b/ios/chrome/browser/component_updater/BUILD.gn index 273566f6..09b3fb8 100644 --- a/ios/chrome/browser/component_updater/BUILD.gn +++ b/ios/chrome/browser/component_updater/BUILD.gn
@@ -11,7 +11,8 @@ "//base", "//components/component_updater", "//components/update_client", - "//components/update_client:common_impl", + "//components/update_client:patch_impl", + "//components/update_client:unzip_impl", "//ios/chrome/browser", "//ios/chrome/browser/google", "//ios/chrome/common",
diff --git a/ios/chrome/browser/context_menu/BUILD.gn b/ios/chrome/browser/context_menu/BUILD.gn index 63b60e5..9be41b12 100644 --- a/ios/chrome/browser/context_menu/BUILD.gn +++ b/ios/chrome/browser/context_menu/BUILD.gn
@@ -22,6 +22,7 @@ "//ios/third_party/earl_grey:earl_grey+link", "//ios/web:earl_grey_test_support", "//ios/web/public", + "//ios/web/public/test:element_selector", "//ios/web/public/test/http_server", "//url", ]
diff --git a/ios/chrome/browser/metrics/BUILD.gn b/ios/chrome/browser/metrics/BUILD.gn index d87b37a..00d1656e 100644 --- a/ios/chrome/browser/metrics/BUILD.gn +++ b/ios/chrome/browser/metrics/BUILD.gn
@@ -205,6 +205,7 @@ "//ios/public/provider/chrome/browser/signin:test_support", "//ios/web:earl_grey_test_support", "//ios/web/public/test", + "//ios/web/public/test:element_selector", "//ios/web/public/test/http_server", "//ui/base", "//url",
diff --git a/ios/chrome/browser/signin/BUILD.gn b/ios/chrome/browser/signin/BUILD.gn index 0305843..fc5b250 100644 --- a/ios/chrome/browser/signin/BUILD.gn +++ b/ios/chrome/browser/signin/BUILD.gn
@@ -39,6 +39,8 @@ "ios_chrome_signin_client.mm", "ios_chrome_signin_status_metrics_provider_delegate.cc", "ios_chrome_signin_status_metrics_provider_delegate.h", + "profile_oauth2_token_service_factory.h", + "profile_oauth2_token_service_factory.mm", "profile_oauth2_token_service_ios_provider_impl.h", "profile_oauth2_token_service_ios_provider_impl.mm", "signin_browser_state_info_updater.h",
diff --git a/ios/chrome/browser/signin/identity_manager_factory.cc b/ios/chrome/browser/signin/identity_manager_factory.cc index 5f42e434c..bc3efca 100644 --- a/ios/chrome/browser/signin/identity_manager_factory.cc +++ b/ios/chrome/browser/signin/identity_manager_factory.cc
@@ -12,14 +12,12 @@ #include "components/keyed_service/ios/browser_state_dependency_manager.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/signin/core/browser/account_consistency_method.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" -#include "components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h" #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/signin/account_tracker_service_factory.h" #include "ios/chrome/browser/signin/identity_manager_factory_observer.h" -#include "ios/chrome/browser/signin/profile_oauth2_token_service_ios_provider_impl.h" +#include "ios/chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "ios/chrome/browser/signin/signin_client_factory.h" #include "services/identity/public/cpp/accounts_cookie_mutator_impl.h" #include "services/identity/public/cpp/accounts_mutator.h" @@ -29,17 +27,6 @@ namespace { -std::unique_ptr<ProfileOAuth2TokenService> BuildTokenService( - ios::ChromeBrowserState* chrome_browser_state) { - auto delegate = std::make_unique<ProfileOAuth2TokenServiceIOSDelegate>( - SigninClientFactory::GetForBrowserState(chrome_browser_state), - std::make_unique<ProfileOAuth2TokenServiceIOSProviderImpl>(), - ios::AccountTrackerServiceFactory::GetForBrowserState( - chrome_browser_state)); - return std::make_unique<ProfileOAuth2TokenService>( - chrome_browser_state->GetPrefs(), std::move(delegate)); -} - std::unique_ptr<AccountFetcherService> BuildAccountFetcherService( SigninClient* signin_client, ProfileOAuth2TokenService* token_service, @@ -53,11 +40,11 @@ std::unique_ptr<SigninManager> BuildSigninManager( ios::ChromeBrowserState* chrome_browser_state, - ProfileOAuth2TokenService* token_service, GaiaCookieManagerService* gaia_cookie_manager_service) { std::unique_ptr<SigninManager> service = std::make_unique<SigninManager>( SigninClientFactory::GetForBrowserState(chrome_browser_state), - token_service, + ProfileOAuth2TokenServiceFactory::GetForBrowserState( + chrome_browser_state), ios::AccountTrackerServiceFactory::GetForBrowserState( chrome_browser_state), gaia_cookie_manager_service, signin::AccountConsistencyMethod::kMirror); @@ -77,7 +64,6 @@ public identity::IdentityManager { public: IdentityManagerWrapper( - std::unique_ptr<ProfileOAuth2TokenService> token_service, std::unique_ptr<GaiaCookieManagerService> gaia_cookie_manager_service, std::unique_ptr<SigninManagerBase> signin_manager, std::unique_ptr<AccountFetcherService> account_fetcher_service, @@ -87,10 +73,10 @@ std::unique_ptr<identity::DiagnosticsProviderImpl> diagnostics_provider, ios::ChromeBrowserState* browser_state) : identity::IdentityManager( - std::move(token_service), std::move(gaia_cookie_manager_service), std::move(signin_manager), std::move(account_fetcher_service), + ProfileOAuth2TokenServiceFactory::GetForBrowserState(browser_state), ios::AccountTrackerServiceFactory::GetForBrowserState( browser_state), std::move(primary_account_mutator), @@ -112,6 +98,7 @@ "IdentityManager", BrowserStateDependencyManager::GetInstance()) { DependsOn(ios::AccountTrackerServiceFactory::GetInstance()); + DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); DependsOn(SigninClientFactory::GetInstance()); } @@ -141,6 +128,7 @@ void IdentityManagerFactory::EnsureFactoryAndDependeeFactoriesBuilt() { IdentityManagerFactory::GetInstance(); ios::AccountTrackerServiceFactory::GetInstance(); + ProfileOAuth2TokenServiceFactory::GetInstance(); SigninClientFactory::GetInstance(); } @@ -160,40 +148,32 @@ ios::ChromeBrowserState::FromBrowserState(context); // Construct the dependencies that IdentityManager will own. - std::unique_ptr<ProfileOAuth2TokenService> token_service = - BuildTokenService(browser_state); - auto gaia_cookie_manager_service = std::make_unique<GaiaCookieManagerService>( - token_service.get(), + ProfileOAuth2TokenServiceFactory::GetForBrowserState(browser_state), SigninClientFactory::GetForBrowserState(browser_state)); - - std::unique_ptr<SigninManager> signin_manager = BuildSigninManager( - browser_state, token_service.get(), gaia_cookie_manager_service.get()); - + std::unique_ptr<SigninManager> signin_manager = + BuildSigninManager(browser_state, gaia_cookie_manager_service.get()); auto primary_account_mutator = std::make_unique<identity::PrimaryAccountMutatorImpl>( ios::AccountTrackerServiceFactory::GetForBrowserState(browser_state), signin_manager.get()); - auto accounts_cookie_mutator = std::make_unique<identity::AccountsCookieMutatorImpl>( gaia_cookie_manager_service.get()); - auto diagnostics_provider = std::make_unique<identity::DiagnosticsProviderImpl>( - token_service.get(), gaia_cookie_manager_service.get()); - + ProfileOAuth2TokenServiceFactory::GetForBrowserState(browser_state), + gaia_cookie_manager_service.get()); std::unique_ptr<AccountFetcherService> account_fetcher_service = BuildAccountFetcherService( SigninClientFactory::GetForBrowserState(browser_state), - token_service.get(), + ProfileOAuth2TokenServiceFactory::GetForBrowserState(browser_state), ios::AccountTrackerServiceFactory::GetForBrowserState(browser_state)); - auto identity_manager = std::make_unique<IdentityManagerWrapper>( - std::move(token_service), std::move(gaia_cookie_manager_service), - std::move(signin_manager), std::move(account_fetcher_service), - std::move(primary_account_mutator), std::move(accounts_cookie_mutator), - std::move(diagnostics_provider), browser_state); + std::move(gaia_cookie_manager_service), std::move(signin_manager), + std::move(account_fetcher_service), std::move(primary_account_mutator), + std::move(accounts_cookie_mutator), std::move(diagnostics_provider), + browser_state); for (auto& observer : observer_list_) observer.IdentityManagerCreated(identity_manager.get());
diff --git a/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc b/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc index e4e9f944..9f87a1a 100644 --- a/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc +++ b/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc
@@ -7,23 +7,54 @@ #include <utility> #include "base/bind.h" -#include "components/signin/core/browser/account_consistency_method.h" #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" #include "components/signin/core/browser/test_signin_client.h" #include "components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/signin/account_tracker_service_factory.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" +#include "ios/chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "ios/chrome/browser/signin/profile_oauth2_token_service_ios_provider_impl.h" #include "ios/chrome/browser/signin/signin_client_factory.h" namespace { +std::unique_ptr<KeyedService> BuildFakeOAuth2TokenService( + web::BrowserState* context) { + ios::ChromeBrowserState* browser_state = + ios::ChromeBrowserState::FromBrowserState(context); + return std::make_unique<FakeProfileOAuth2TokenService>( + browser_state->GetPrefs()); +} + +std::unique_ptr<KeyedService> BuildFakeOAuth2TokenServiceWithIOSDelegate( + web::BrowserState* context) { + ios::ChromeBrowserState* browser_state = + ios::ChromeBrowserState::FromBrowserState(context); + std::unique_ptr<OAuth2TokenServiceDelegate> delegate = + std::make_unique<ProfileOAuth2TokenServiceIOSDelegate>( + SigninClientFactory::GetForBrowserState(browser_state), + std::make_unique<ProfileOAuth2TokenServiceIOSProviderImpl>(), + ios::AccountTrackerServiceFactory::GetForBrowserState(browser_state)); + return std::make_unique<FakeProfileOAuth2TokenService>( + browser_state->GetPrefs(), std::move(delegate)); +} + std::unique_ptr<KeyedService> BuildTestSigninClient(web::BrowserState* state) { return std::make_unique<TestSigninClient>( ios::ChromeBrowserState::FromBrowserState(state)->GetPrefs()); } +TestChromeBrowserState::TestingFactories GetIdentityTestEnvironmentFactories( + bool use_ios_token_service_delegate) { + return {{SigninClientFactory::GetInstance(), + base::BindRepeating(&BuildTestSigninClient)}, + {ProfileOAuth2TokenServiceFactory::GetInstance(), + base::BindRepeating(use_ios_token_service_delegate + ? &BuildFakeOAuth2TokenServiceWithIOSDelegate + : &BuildFakeOAuth2TokenService)}}; +} + } // namespace // static @@ -65,11 +96,10 @@ // static void IdentityTestEnvironmentChromeBrowserStateAdaptor:: SetIdentityTestEnvironmentFactoriesOnBrowserContext( - TestChromeBrowserState* chrome_browser_state) { + TestChromeBrowserState* browser_state) { for (const auto& factory_pair : GetIdentityTestEnvironmentFactories( /*use_ios_token_service_delegate=*/false)) { - factory_pair.first->SetTestingFactory(chrome_browser_state, - factory_pair.second); + factory_pair.first->SetTestingFactory(browser_state, factory_pair.second); } } @@ -85,63 +115,8 @@ identity_factories.end()); } -// static -std::unique_ptr<KeyedService> -IdentityTestEnvironmentChromeBrowserStateAdaptor::BuildIdentityManagerForTests( - web::BrowserState* browser_state) { - ios::ChromeBrowserState* chrome_browser_state = - ios::ChromeBrowserState::FromBrowserState(browser_state); - - auto fake_token_service = std::make_unique<FakeProfileOAuth2TokenService>( - chrome_browser_state->GetPrefs()); - - return identity::IdentityTestEnvironment::BuildIdentityManagerForTests( - SigninClientFactory::GetForBrowserState(chrome_browser_state), - chrome_browser_state->GetPrefs(), std::move(fake_token_service), - ios::AccountTrackerServiceFactory::GetForBrowserState( - chrome_browser_state), - signin::AccountConsistencyMethod::kMirror); -} - -// static -std::unique_ptr<KeyedService> IdentityTestEnvironmentChromeBrowserStateAdaptor:: - BuildIdentityManagerForTestWithIOSDelegate( - web::BrowserState* browser_state) { - ios::ChromeBrowserState* chrome_browser_state = - ios::ChromeBrowserState::FromBrowserState(browser_state); - - std::unique_ptr<OAuth2TokenServiceDelegate> delegate = - std::make_unique<ProfileOAuth2TokenServiceIOSDelegate>( - SigninClientFactory::GetForBrowserState(chrome_browser_state), - std::make_unique<ProfileOAuth2TokenServiceIOSProviderImpl>(), - ios::AccountTrackerServiceFactory::GetForBrowserState( - chrome_browser_state)); - - auto fake_token_service = std::make_unique<FakeProfileOAuth2TokenService>( - chrome_browser_state->GetPrefs(), std::move(delegate)); - - return identity::IdentityTestEnvironment::BuildIdentityManagerForTests( - SigninClientFactory::GetForBrowserState(chrome_browser_state), - chrome_browser_state->GetPrefs(), std::move(fake_token_service), - ios::AccountTrackerServiceFactory::GetForBrowserState( - chrome_browser_state), - signin::AccountConsistencyMethod::kMirror); -} - -// static -TestChromeBrowserState::TestingFactories -IdentityTestEnvironmentChromeBrowserStateAdaptor:: - GetIdentityTestEnvironmentFactories(bool use_ios_token_service_delegate) { - return {{SigninClientFactory::GetInstance(), - base::BindRepeating(&BuildTestSigninClient)}, - {IdentityManagerFactory::GetInstance(), - base::BindRepeating(use_ios_token_service_delegate - ? &BuildIdentityManagerForTestWithIOSDelegate - : &BuildIdentityManagerForTests)}}; -} - IdentityTestEnvironmentChromeBrowserStateAdaptor:: IdentityTestEnvironmentChromeBrowserStateAdaptor( - ios::ChromeBrowserState* chrome_browser_state) + ios::ChromeBrowserState* browser_state) : identity_test_env_( - IdentityManagerFactory::GetForBrowserState(chrome_browser_state)) {} + IdentityManagerFactory::GetForBrowserState(browser_state)) {}
diff --git a/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.h b/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.h index 303ece0..e8446457 100644 --- a/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.h +++ b/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.h
@@ -83,15 +83,6 @@ } private: - // Testing factory that creates an IdentityManager with a - // FakeProfileOAuth2TokenService. - static std::unique_ptr<KeyedService> BuildIdentityManagerForTests( - web::BrowserState* browser_state); - static std::unique_ptr<KeyedService> - BuildIdentityManagerForTestWithIOSDelegate(web::BrowserState* browser_state); - static TestChromeBrowserState::TestingFactories - GetIdentityTestEnvironmentFactories(bool use_ios_token_service_delegate); - identity::IdentityTestEnvironment identity_test_env_; DISALLOW_COPY_AND_ASSIGN(IdentityTestEnvironmentChromeBrowserStateAdaptor);
diff --git a/ios/chrome/browser/signin/profile_oauth2_token_service_factory.h b/ios/chrome/browser/signin/profile_oauth2_token_service_factory.h new file mode 100644 index 0000000..2733fcdf --- /dev/null +++ b/ios/chrome/browser/signin/profile_oauth2_token_service_factory.h
@@ -0,0 +1,50 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_FACTORY_H_ +#define IOS_CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_FACTORY_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/no_destructor.h" +#include "components/keyed_service/ios/browser_state_keyed_service_factory.h" + +namespace ios { +class ChromeBrowserState; +} + +class ProfileOAuth2TokenService; + +// Singleton that owns all ProfileOAuth2TokenServices and associates them with +// ios::ChromeBrowserState. +class ProfileOAuth2TokenServiceFactory + : public BrowserStateKeyedServiceFactory { + public: + // Returns the instance of ProfileOAuth2TokenService associated with this + // browser state (creating one if none exists). Returns nulltpr if this + // browser state cannot have a ProfileOAuth2TokenService (for example, if + // |browser_state| is incognito). + static ProfileOAuth2TokenService* GetForBrowserState( + ios::ChromeBrowserState* browser_state); + + // Returns an instance of the ProfileOAuth2TokenServiceFactory singleton. + static ProfileOAuth2TokenServiceFactory* GetInstance(); + + private: + friend class base::NoDestructor<ProfileOAuth2TokenServiceFactory>; + + ProfileOAuth2TokenServiceFactory(); + ~ProfileOAuth2TokenServiceFactory() override; + + // BrowserStateKeyedServiceFactory implementation. + std::unique_ptr<KeyedService> BuildServiceInstanceFor( + web::BrowserState* context) const override; + void RegisterBrowserStatePrefs( + user_prefs::PrefRegistrySyncable* registry) override; + + DISALLOW_COPY_AND_ASSIGN(ProfileOAuth2TokenServiceFactory); +}; + +#endif // IOS_CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_FACTORY_H_
diff --git a/ios/chrome/browser/signin/profile_oauth2_token_service_factory.mm b/ios/chrome/browser/signin/profile_oauth2_token_service_factory.mm new file mode 100644 index 0000000..899ded2 --- /dev/null +++ b/ios/chrome/browser/signin/profile_oauth2_token_service_factory.mm
@@ -0,0 +1,61 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/chrome/browser/signin/profile_oauth2_token_service_factory.h" + +#include "base/no_destructor.h" +#include "components/keyed_service/ios/browser_state_dependency_manager.h" +#include "components/pref_registry/pref_registry_syncable.h" +#include "components/signin/core/browser/profile_oauth2_token_service.h" +#include "components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/signin/account_tracker_service_factory.h" +#include "ios/chrome/browser/signin/profile_oauth2_token_service_ios_provider_impl.h" +#include "ios/chrome/browser/signin/signin_client_factory.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +ProfileOAuth2TokenServiceFactory::ProfileOAuth2TokenServiceFactory() + : BrowserStateKeyedServiceFactory( + "ProfileOAuth2TokenService", + BrowserStateDependencyManager::GetInstance()) { + DependsOn(ios::AccountTrackerServiceFactory::GetInstance()); + DependsOn(SigninClientFactory::GetInstance()); +} + +ProfileOAuth2TokenServiceFactory::~ProfileOAuth2TokenServiceFactory() {} + +ProfileOAuth2TokenService* ProfileOAuth2TokenServiceFactory::GetForBrowserState( + ios::ChromeBrowserState* browser_state) { + return static_cast<ProfileOAuth2TokenService*>( + GetInstance()->GetServiceForBrowserState(browser_state, true)); +} + +// static +ProfileOAuth2TokenServiceFactory* +ProfileOAuth2TokenServiceFactory::GetInstance() { + static base::NoDestructor<ProfileOAuth2TokenServiceFactory> instance; + return instance.get(); +} + +void ProfileOAuth2TokenServiceFactory::RegisterBrowserStatePrefs( + user_prefs::PrefRegistrySyncable* registry) { + ProfileOAuth2TokenService::RegisterProfilePrefs(registry); +} + +std::unique_ptr<KeyedService> +ProfileOAuth2TokenServiceFactory::BuildServiceInstanceFor( + web::BrowserState* context) const { + ios::ChromeBrowserState* chrome_browser_state = + ios::ChromeBrowserState::FromBrowserState(context); + auto delegate = std::make_unique<ProfileOAuth2TokenServiceIOSDelegate>( + SigninClientFactory::GetForBrowserState(chrome_browser_state), + std::make_unique<ProfileOAuth2TokenServiceIOSProviderImpl>(), + ios::AccountTrackerServiceFactory::GetForBrowserState( + chrome_browser_state)); + return std::make_unique<ProfileOAuth2TokenService>( + chrome_browser_state->GetPrefs(), std::move(delegate)); +}
diff --git a/ios/chrome/browser/sync/ios_user_event_service_factory.cc b/ios/chrome/browser/sync/ios_user_event_service_factory.cc index 27361c3..1300ac3 100644 --- a/ios/chrome/browser/sync/ios_user_event_service_factory.cc +++ b/ios/chrome/browser/sync/ios_user_event_service_factory.cc
@@ -21,7 +21,6 @@ #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/sync/model_type_store_service_factory.h" -#include "ios/chrome/browser/sync/profile_sync_service_factory.h" #include "ios/chrome/browser/sync/session_sync_service_factory.h" #include "ios/chrome/common/channel_info.h" #include "ios/web/public/browser_state.h" @@ -52,16 +51,12 @@ std::unique_ptr<KeyedService> IOSUserEventServiceFactory::BuildServiceInstanceFor( web::BrowserState* context) const { - ios::ChromeBrowserState* browser_state = - ios::ChromeBrowserState::FromBrowserState(context); - - syncer::SyncService* sync_service = - ProfileSyncServiceFactory::GetForBrowserState(browser_state); - if (!syncer::UserEventServiceImpl::MightRecordEvents( - browser_state->IsOffTheRecord(), sync_service)) { + if (context->IsOffTheRecord()) { return std::make_unique<syncer::NoOpUserEventService>(); } + ios::ChromeBrowserState* browser_state = + ios::ChromeBrowserState::FromBrowserState(context); syncer::OnceModelTypeStoreFactory store_factory = ModelTypeStoreServiceFactory::GetForBrowserState(browser_state) ->GetStoreFactory(); @@ -72,8 +67,7 @@ &syncer::ReportUnrecoverableError, ::GetChannel())), SessionSyncServiceFactory::GetForBrowserState(browser_state) ->GetGlobalIdMapper()); - return std::make_unique<syncer::UserEventServiceImpl>(sync_service, - std::move(bridge)); + return std::make_unique<syncer::UserEventServiceImpl>(std::move(bridge)); } web::BrowserState* IOSUserEventServiceFactory::GetBrowserStateToUse(
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn index f5012b5..841716a 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn +++ b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
@@ -219,6 +219,7 @@ "//ios/testing/earl_grey:earl_grey_support", "//ios/third_party/earl_grey:earl_grey+link", "//ios/web:earl_grey_test_support", + "//ios/web/public/test:element_selector", "//ios/web/public/test/http_server", "//third_party/ocmock", ]
diff --git a/ios/chrome/browser/ui/dialogs/BUILD.gn b/ios/chrome/browser/ui/dialogs/BUILD.gn index 4f054c6..3e7e7f6e 100644 --- a/ios/chrome/browser/ui/dialogs/BUILD.gn +++ b/ios/chrome/browser/ui/dialogs/BUILD.gn
@@ -120,6 +120,7 @@ "//ios/web", "//ios/web:earl_grey_test_support", "//ios/web/public/test", + "//ios/web/public/test:element_selector", "//ios/web/public/test/http_server", "//ui/base", "//url",
diff --git a/ios/chrome/browser/ui/download/BUILD.gn b/ios/chrome/browser/ui/download/BUILD.gn index 58d249e..2440ba3e4 100644 --- a/ios/chrome/browser/ui/download/BUILD.gn +++ b/ios/chrome/browser/ui/download/BUILD.gn
@@ -131,6 +131,7 @@ "//ios/third_party/earl_grey:earl_grey+link", "//ios/web:earl_grey_test_support", "//ios/web/public", + "//ios/web/public/test:element_selector", "//ui/base", ] libs = [ "XCTest.framework" ]
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_container_view.h b/ios/chrome/browser/ui/omnibox/omnibox_container_view.h index 98724cb..ba2b87b5 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_container_view.h +++ b/ios/chrome/browser/ui/omnibox/omnibox_container_view.h
@@ -40,6 +40,9 @@ // Sets the alpha level of the leading image view. - (void)setLeadingImageAlpha:(CGFloat)alpha; +// Asks the container view to attch any layout guides to its views. +- (void)attachLayoutGuides; + @end #endif // IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_CONTAINER_VIEW_H_
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_container_view.mm b/ios/chrome/browser/ui/omnibox/omnibox_container_view.mm index bab2a32aa..d894b25 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_container_view.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_container_view.mm
@@ -95,11 +95,16 @@ return self; } -- (void)didMoveToWindow { - [super didMoveToWindow]; - +- (void)attachLayoutGuides { [NamedGuide guideWithName:kOmniboxTextFieldGuide view:self].constrainedView = self.textField; + + // The leading image view can be not present, in which case the guide + // shouldn't be attached. + if (self.leadingImageView.superview) { + [NamedGuide guideWithName:kOmniboxLeadingImageGuide view:self] + .constrainedView = self.leadingImageView; + } } - (void)setLeadingImageHidden:(BOOL)hidden { @@ -124,9 +129,6 @@ self.leadingImageViewLeadingConstraint, leadingImageViewToTextField, ]]; - - [NamedGuide guideWithName:kOmniboxLeadingImageGuide view:self] - .constrainedView = self.leadingImageView; } }
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm b/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm index 07ea3787..0e781c4 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm
@@ -119,6 +119,12 @@ object:self.textField]; } +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + + [self.view attachLayoutGuides]; +} + - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; self.textField.selectedTextRange =
diff --git a/ios/chrome/browser/ui/settings/password/BUILD.gn b/ios/chrome/browser/ui/settings/password/BUILD.gn index 2af89f3f..be9017f 100644 --- a/ios/chrome/browser/ui/settings/password/BUILD.gn +++ b/ios/chrome/browser/ui/settings/password/BUILD.gn
@@ -124,6 +124,7 @@ "//ios/chrome/test/earl_grey:test_support", "//ios/third_party/material_components_ios", "//ios/web:earl_grey_test_support", + "//ios/web/public/test:element_selector", "//ios/web/public/test:util", "//ios/web/public/test/http_server", "//ui/base",
diff --git a/ios/chrome/browser/ui/toolbar/BUILD.gn b/ios/chrome/browser/ui/toolbar/BUILD.gn index c7071ad..775ae4b 100644 --- a/ios/chrome/browser/ui/toolbar/BUILD.gn +++ b/ios/chrome/browser/ui/toolbar/BUILD.gn
@@ -180,6 +180,7 @@ "//ios/testing/earl_grey:earl_grey_support", "//ios/third_party/earl_grey:earl_grey+link", "//ios/web:earl_grey_test_support", + "//ios/web/public/test:element_selector", "//ios/web/public/test/http_server", "//ui/base", ]
diff --git a/ios/chrome/browser/ui/util/ui_util.mm b/ios/chrome/browser/ui/util/ui_util.mm index 13a788a87..c4c7804 100644 --- a/ios/chrome/browser/ui/util/ui_util.mm +++ b/ios/chrome/browser/ui/util/ui_util.mm
@@ -14,7 +14,6 @@ #import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" -#include "ios/web/public/features.h" #include "ui/base/device_form_factor.h" #include "ui/gfx/ios/uikit_util.h"
diff --git a/ios/chrome/browser/ui/webui/BUILD.gn b/ios/chrome/browser/ui/webui/BUILD.gn index 188f0f4..9191715 100644 --- a/ios/chrome/browser/ui/webui/BUILD.gn +++ b/ios/chrome/browser/ui/webui/BUILD.gn
@@ -124,6 +124,7 @@ "//ios/chrome/test/app:test_support", "//ios/chrome/test/earl_grey:test_support", "//ios/web", + "//ios/web/public/test:element_selector", "//ui/base", "//url", ]
diff --git a/ios/chrome/browser/ui/webui/web_ui_egtest.mm b/ios/chrome/browser/ui/webui/web_ui_egtest.mm index ca3f7d2..37bab22 100644 --- a/ios/chrome/browser/ui/webui/web_ui_egtest.mm +++ b/ios/chrome/browser/ui/webui/web_ui_egtest.mm
@@ -19,7 +19,6 @@ #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" -#include "ios/web/public/features.h" #import "ios/web/public/web_client.h" #include "ui/base/device_form_factor.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn index 47c7bad..a541a7f 100644 --- a/ios/chrome/browser/web/BUILD.gn +++ b/ios/chrome/browser/web/BUILD.gn
@@ -357,6 +357,7 @@ "//ios/web", "//ios/web:earl_grey_test_support", "//ios/web/public/test", + "//ios/web/public/test:element_selector", "//ios/web/public/test/http_server", "//net", "//net:test_support",
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index 3ddd43f..a6666ca 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -268,6 +268,7 @@ "//ios/third_party/material_components_ios", "//ios/web", "//ios/web:earl_grey_test_support", + "//ios/web/public/test:element_selector", "//ios/web/public/test/http_server", "//ui/base", "//ui/base:test_support",
diff --git a/ios/net/clients/crn_network_client_protocol.h b/ios/net/clients/crn_network_client_protocol.h index aa44076..4caa7ba 100644 --- a/ios/net/clients/crn_network_client_protocol.h +++ b/ios/net/clients/crn_network_client_protocol.h
@@ -67,7 +67,7 @@ // was successful. // If authentication was successful, |callback|'s second and third parameters // are username and password; if unsuccessful they are empty strings. -- (void)didRecieveAuthChallenge:(net::AuthChallengeInfo*)authInfo +- (void)didRecieveAuthChallenge:(const net::AuthChallengeInfo&)authInfo nativeRequest:(const net::URLRequest&)nativeRequest callback:(const network_client::AuthCallback&)callback;
diff --git a/ios/net/crn_http_protocol_handler.mm b/ios/net/crn_http_protocol_handler.mm index b5fac7e..e541e10a 100644 --- a/ios/net/crn_http_protocol_handler.mm +++ b/ios/net/crn_http_protocol_handler.mm
@@ -162,7 +162,7 @@ const RedirectInfo& new_url, bool* defer_redirect) override; void OnAuthRequired(URLRequest* request, - AuthChallengeInfo* auth_info) override; + const AuthChallengeInfo& auth_info) override; void OnCertificateRequested(URLRequest* request, SSLCertRequestInfo* cert_request_info) override; void OnSSLCertificateError(URLRequest* request, @@ -401,8 +401,9 @@ StopNetRequest(); } -void HttpProtocolHandlerCore::OnAuthRequired(URLRequest* request, - AuthChallengeInfo* auth_info) { +void HttpProtocolHandlerCore::OnAuthRequired( + URLRequest* request, + const AuthChallengeInfo& auth_info) { DCHECK(thread_checker_.CalledOnValidThread()); // A request with no tab ID should not hit HTTP authentication. if (tracker_) {
diff --git a/ios/net/crn_http_protocol_handler_proxy_with_client_thread.mm b/ios/net/crn_http_protocol_handler_proxy_with_client_thread.mm index 586e887..07ca5f25 100644 --- a/ios/net/crn_http_protocol_handler_proxy_with_client_thread.mm +++ b/ios/net/crn_http_protocol_handler_proxy_with_client_thread.mm
@@ -194,7 +194,7 @@ // no-op. } -- (void)didRecieveAuthChallenge:(net::AuthChallengeInfo*)authInfo +- (void)didRecieveAuthChallenge:(const net::AuthChallengeInfo&)authInfo nativeRequest:(const net::URLRequest&)nativeRequest callback:(const network_client::AuthCallback&)callback { // If we get this far, authentication has failed.
diff --git a/ios/third_party/material_components_ios/BUILD.gn b/ios/third_party/material_components_ios/BUILD.gn index dd571fc..54760ae 100644 --- a/ios/third_party/material_components_ios/BUILD.gn +++ b/ios/third_party/material_components_ios/BUILD.gn
@@ -184,6 +184,8 @@ "src/components/Cards/src/ColorThemer/MDCCardsColorThemer.m", "src/components/Cards/src/MDCCard.h", "src/components/Cards/src/MDCCard.m", + "src/components/Cards/src/MDCCardCollectionCell.h", + "src/components/Cards/src/MDCCardCollectionCell.m", "src/components/CollectionCells/src/MDCCollectionViewCell.h", "src/components/CollectionCells/src/MDCCollectionViewCell.m", "src/components/CollectionCells/src/MDCCollectionViewTextCell.h",
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index d19dcea3..77ece4f 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -115,6 +115,7 @@ "//ios/third_party/earl_grey:earl_grey+link", "//ios/web/interstitials", "//ios/web/public/test", + "//ios/web/public/test:element_selector", "//net", ] @@ -574,6 +575,7 @@ "//ios/web/navigation:wk_navigation_util", "//ios/web/public/find_in_page", "//ios/web/public/test", + "//ios/web/public/test:element_selector", "//ios/web/public/test/fakes", "//ios/web/public/test/http_server", "//ios/web/test:mojo_bindings",
diff --git a/ios/web/common/crw_web_view_content_view.mm b/ios/web/common/crw_web_view_content_view.mm index 5f0ad01..49ccbad 100644 --- a/ios/web/common/crw_web_view_content_view.mm +++ b/ios/web/common/crw_web_view_content_view.mm
@@ -9,7 +9,6 @@ #include <limits> #include "base/logging.h" -#import "ios/web/public/features.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/web/public/test/BUILD.gn b/ios/web/public/test/BUILD.gn index 8a0ff442..e5d54f0 100644 --- a/ios/web/public/test/BUILD.gn +++ b/ios/web/public/test/BUILD.gn
@@ -41,11 +41,26 @@ ] } +source_set("element_selector") { + configs += [ "//build/config/compiler:enable_arc" ] + testonly = true + + sources = [ + "element_selector.h", + "element_selector.mm", + ] + + deps = [ + "//base", + ] +} + source_set("util") { configs += [ "//build/config/compiler:enable_arc" ] testonly = true deps = [ + ":element_selector", "//base", "//base/test:test_support", "//ios/web/public:public", @@ -56,9 +71,13 @@ "//testing/gtest", ] + # TODO(crbug.com/922813): Remove this once internal targets depend directly + # on ":element_selector". + public_deps = [ + "//ios/web/public/test:element_selector", + ] + sources = [ - "element_selector.h", - "element_selector.mm", "error_test_util.h", "error_test_util.mm", "js_test_util.h",
diff --git a/ios/web/shell/test/BUILD.gn b/ios/web/shell/test/BUILD.gn index 6cb8818..d1c1f03 100644 --- a/ios/web/shell/test/BUILD.gn +++ b/ios/web/shell/test/BUILD.gn
@@ -32,6 +32,7 @@ "//ios/web", "//ios/web:earl_grey_test_support", "//ios/web/public/test", + "//ios/web/public/test:element_selector", "//ios/web/public/test/fakes", "//ios/web/shell", "//ios/web/shell:shell_interfaces", @@ -59,6 +60,7 @@ "//ios/web", "//ios/web:earl_grey_test_support", "//ios/web/public/test", + "//ios/web/public/test:element_selector", "//ios/web/shell", "//testing/gtest:gtest", "//url",
diff --git a/ios/web/web_state/ui/crw_web_view_content_view_unittest.mm b/ios/web/web_state/ui/crw_web_view_content_view_unittest.mm index 78a1cd8..def046b 100644 --- a/ios/web/web_state/ui/crw_web_view_content_view_unittest.mm +++ b/ios/web/web_state/ui/crw_web_view_content_view_unittest.mm
@@ -6,7 +6,6 @@ #import <UIKit/UIKit.h> -#import "ios/web/public/features.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" #import "third_party/ocmock/OCMock/OCMock.h"
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn index 54f848d..0d6b08e4 100644 --- a/ios/web_view/BUILD.gn +++ b/ios/web_view/BUILD.gn
@@ -166,6 +166,8 @@ "internal/signin/web_view_account_tracker_service_factory.mm", "internal/signin/web_view_identity_manager_factory.h", "internal/signin/web_view_identity_manager_factory.mm", + "internal/signin/web_view_oauth2_token_service_factory.h", + "internal/signin/web_view_oauth2_token_service_factory.mm", "internal/signin/web_view_profile_oauth2_token_service_ios_provider_impl.h", "internal/signin/web_view_profile_oauth2_token_service_ios_provider_impl.mm", "internal/signin/web_view_signin_client_factory.h",
diff --git a/ios/web_view/internal/DEPS b/ios/web_view/internal/DEPS index bb77ed6c..4955a21 100644 --- a/ios/web_view/internal/DEPS +++ b/ios/web_view/internal/DEPS
@@ -23,6 +23,7 @@ # Use identity_manager.h instead of the below files; # see https://groups.google.com/a/chromium.org/d/msg/chromium-dev/dgFLuxqZt1o/iEqkyoQQBwAJ for help and info. "!components/signin/core/browser/fake_profile_oauth2_token_service.h", + "!components/signin/core/browser/profile_oauth2_token_service.h", "!components/signin/core/browser/fake_signin_manager.h", "!components/signin/core/browser/signin_manager_base.h", "+components/signin/ios",
diff --git a/ios/web_view/internal/signin/web_view_identity_manager_factory.mm b/ios/web_view/internal/signin/web_view_identity_manager_factory.mm index a3fc002..b6bf4c2 100644 --- a/ios/web_view/internal/signin/web_view_identity_manager_factory.mm +++ b/ios/web_view/internal/signin/web_view_identity_manager_factory.mm
@@ -12,14 +12,12 @@ #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" #include "components/signin/core/browser/account_consistency_method.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/browser/signin_pref_names.h" -#include "components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h" #include "ios/web_view/internal/app/application_context.h" #include "ios/web_view/internal/signin/ios_web_view_signin_client.h" #include "ios/web_view/internal/signin/web_view_account_tracker_service_factory.h" -#include "ios/web_view/internal/signin/web_view_profile_oauth2_token_service_ios_provider_impl.h" +#include "ios/web_view/internal/signin/web_view_oauth2_token_service_factory.h" #include "ios/web_view/internal/signin/web_view_signin_client_factory.h" #include "ios/web_view/internal/web_view_browser_state.h" #include "services/identity/public/cpp/accounts_cookie_mutator_impl.h" @@ -36,20 +34,6 @@ namespace { -std::unique_ptr<ProfileOAuth2TokenService> BuildTokenService( - WebViewBrowserState* browser_state) { - IOSWebViewSigninClient* signin_client = - WebViewSigninClientFactory::GetForBrowserState(browser_state); - auto token_service_provider = - std::make_unique<WebViewProfileOAuth2TokenServiceIOSProviderImpl>( - signin_client); - auto delegate = std::make_unique<ProfileOAuth2TokenServiceIOSDelegate>( - signin_client, std::move(token_service_provider), - WebViewAccountTrackerServiceFactory::GetForBrowserState(browser_state)); - return std::make_unique<ProfileOAuth2TokenService>(browser_state->GetPrefs(), - std::move(delegate)); -} - std::unique_ptr<AccountFetcherService> BuildAccountFetcherService( SigninClient* signin_client, ProfileOAuth2TokenService* token_service, @@ -63,7 +47,6 @@ std::unique_ptr<SigninManager> BuildSigninManager( WebViewBrowserState* browser_state, - ProfileOAuth2TokenService* token_service, GaiaCookieManagerService* gaia_cookie_manager_service) { // Clearing the sign in state on start up greatly simplifies the management of // ChromeWebView's signin state. @@ -74,7 +57,7 @@ std::unique_ptr<SigninManager> service = std::make_unique<SigninManager>( WebViewSigninClientFactory::GetForBrowserState(browser_state), - token_service, + WebViewOAuth2TokenServiceFactory::GetForBrowserState(browser_state), WebViewAccountTrackerServiceFactory::GetForBrowserState(browser_state), gaia_cookie_manager_service, signin::AccountConsistencyMethod::kDisabled); service->Initialize(ApplicationContext::GetInstance()->GetLocalState()); @@ -93,7 +76,6 @@ public identity::IdentityManager { public: explicit IdentityManagerWrapper( - std::unique_ptr<ProfileOAuth2TokenService> token_service, std::unique_ptr<GaiaCookieManagerService> gaia_cookie_manager_service, std::unique_ptr<SigninManagerBase> signin_manager, std::unique_ptr<AccountFetcherService> account_fetcher_service, @@ -103,10 +85,10 @@ std::unique_ptr<identity::DiagnosticsProviderImpl> diagnostics_provider, WebViewBrowserState* browser_state) : identity::IdentityManager( - std::move(token_service), std::move(gaia_cookie_manager_service), std::move(signin_manager), std::move(account_fetcher_service), + WebViewOAuth2TokenServiceFactory::GetForBrowserState(browser_state), WebViewAccountTrackerServiceFactory::GetForBrowserState( browser_state), std::move(primary_account_mutator), @@ -128,6 +110,7 @@ "IdentityManager", BrowserStateDependencyManager::GetInstance()) { DependsOn(WebViewAccountTrackerServiceFactory::GetInstance()); + DependsOn(WebViewOAuth2TokenServiceFactory::GetInstance()); DependsOn(WebViewSigninClientFactory::GetInstance()); } @@ -150,6 +133,7 @@ void WebViewIdentityManagerFactory::EnsureFactoryAndDependeeFactoriesBuilt() { WebViewIdentityManagerFactory::GetInstance(); WebViewAccountTrackerServiceFactory::GetInstance(); + WebViewOAuth2TokenServiceFactory::GetInstance(); WebViewSigninClientFactory::GetInstance(); } @@ -160,42 +144,35 @@ WebViewBrowserState::FromBrowserState(context); // Construct the dependencies that IdentityManager will own. - std::unique_ptr<ProfileOAuth2TokenService> token_service = - BuildTokenService(browser_state); - auto gaia_cookie_manager_service = std::make_unique<GaiaCookieManagerService>( - token_service.get(), + WebViewOAuth2TokenServiceFactory::GetForBrowserState(browser_state), WebViewSigninClientFactory::GetForBrowserState(browser_state)); - - std::unique_ptr<SigninManager> signin_manager = BuildSigninManager( - browser_state, token_service.get(), gaia_cookie_manager_service.get()); - + std::unique_ptr<SigninManager> signin_manager = + BuildSigninManager(browser_state, gaia_cookie_manager_service.get()); auto primary_account_mutator = std::make_unique<identity::PrimaryAccountMutatorImpl>( WebViewAccountTrackerServiceFactory::GetForBrowserState( browser_state), signin_manager.get()); - auto accounts_cookie_mutator = std::make_unique<identity::AccountsCookieMutatorImpl>( gaia_cookie_manager_service.get()); - auto diagnostics_provider = std::make_unique<identity::DiagnosticsProviderImpl>( - token_service.get(), gaia_cookie_manager_service.get()); - + WebViewOAuth2TokenServiceFactory::GetForBrowserState(browser_state), + gaia_cookie_manager_service.get()); std::unique_ptr<AccountFetcherService> account_fetcher_service = BuildAccountFetcherService( WebViewSigninClientFactory::GetForBrowserState(browser_state), - token_service.get(), + WebViewOAuth2TokenServiceFactory::GetForBrowserState(browser_state), WebViewAccountTrackerServiceFactory::GetForBrowserState( browser_state)); - - return std::make_unique<IdentityManagerWrapper>( - std::move(token_service), std::move(gaia_cookie_manager_service), - std::move(signin_manager), std::move(account_fetcher_service), - std::move(primary_account_mutator), std::move(accounts_cookie_mutator), - std::move(diagnostics_provider), browser_state); + auto identity_manager = std::make_unique<IdentityManagerWrapper>( + std::move(gaia_cookie_manager_service), std::move(signin_manager), + std::move(account_fetcher_service), std::move(primary_account_mutator), + std::move(accounts_cookie_mutator), std::move(diagnostics_provider), + browser_state); + return identity_manager; } } // namespace ios_web_view
diff --git a/ios/web_view/internal/signin/web_view_oauth2_token_service_factory.h b/ios/web_view/internal/signin/web_view_oauth2_token_service_factory.h new file mode 100644 index 0000000..060b6ac --- /dev/null +++ b/ios/web_view/internal/signin/web_view_oauth2_token_service_factory.h
@@ -0,0 +1,51 @@ +// 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 IOS_WEB_VIEW_INTERNAL_SIGNIN_WEB_VIEW_OAUTH2_TOKEN_SERVICE_FACTORY_H_ +#define IOS_WEB_VIEW_INTERNAL_SIGNIN_WEB_VIEW_OAUTH2_TOKEN_SERVICE_FACTORY_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/no_destructor.h" +#include "components/keyed_service/ios/browser_state_keyed_service_factory.h" + +class ProfileOAuth2TokenService; + +namespace ios_web_view { +class WebViewBrowserState; + +// Singleton that owns all ProfileOAuth2TokenServices and associates them with +// a browser state. +class WebViewOAuth2TokenServiceFactory + : public BrowserStateKeyedServiceFactory { + public: + // Returns the instance of ProfileOAuth2TokenService associated with this + // browser state (creating one if none exists). Returns nulltpr if this + // browser state cannot have a ProfileOAuth2TokenService (for example, if + // |browser_state| is incognito). + static ProfileOAuth2TokenService* GetForBrowserState( + ios_web_view::WebViewBrowserState* browser_state); + + // Returns an instance of the OAuth2TokenServiceFactory singleton. + static WebViewOAuth2TokenServiceFactory* GetInstance(); + + private: + friend class base::NoDestructor<WebViewOAuth2TokenServiceFactory>; + + WebViewOAuth2TokenServiceFactory(); + ~WebViewOAuth2TokenServiceFactory() override = default; + + // BrowserStateKeyedServiceFactory implementation. + std::unique_ptr<KeyedService> BuildServiceInstanceFor( + web::BrowserState* context) const override; + void RegisterBrowserStatePrefs( + user_prefs::PrefRegistrySyncable* registry) override; + + DISALLOW_COPY_AND_ASSIGN(WebViewOAuth2TokenServiceFactory); +}; + +} // namespace ios_web_view + +#endif // IOS_WEB_VIEW_INTERNAL_SIGNIN_WEB_VIEW_OAUTH2_TOKEN_SERVICE_FACTORY_H_
diff --git a/ios/web_view/internal/signin/web_view_oauth2_token_service_factory.mm b/ios/web_view/internal/signin/web_view_oauth2_token_service_factory.mm new file mode 100644 index 0000000..c2ca9262 --- /dev/null +++ b/ios/web_view/internal/signin/web_view_oauth2_token_service_factory.mm
@@ -0,0 +1,67 @@ +// 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 "ios/web_view/internal/signin/web_view_oauth2_token_service_factory.h" + +#include "base/no_destructor.h" +#include "components/keyed_service/ios/browser_state_dependency_manager.h" +#include "components/pref_registry/pref_registry_syncable.h" +#include "components/signin/core/browser/profile_oauth2_token_service.h" +#include "components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h" +#include "ios/web_view/internal/signin/ios_web_view_signin_client.h" +#include "ios/web_view/internal/signin/web_view_account_tracker_service_factory.h" +#include "ios/web_view/internal/signin/web_view_profile_oauth2_token_service_ios_provider_impl.h" +#include "ios/web_view/internal/signin/web_view_signin_client_factory.h" +#include "ios/web_view/internal/web_view_browser_state.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace ios_web_view { + +WebViewOAuth2TokenServiceFactory::WebViewOAuth2TokenServiceFactory() + : BrowserStateKeyedServiceFactory( + "ProfileOAuth2TokenService", + BrowserStateDependencyManager::GetInstance()) { + DependsOn(WebViewAccountTrackerServiceFactory::GetInstance()); + DependsOn(WebViewSigninClientFactory::GetInstance()); +} + +ProfileOAuth2TokenService* WebViewOAuth2TokenServiceFactory::GetForBrowserState( + ios_web_view::WebViewBrowserState* browser_state) { + return static_cast<ProfileOAuth2TokenService*>( + GetInstance()->GetServiceForBrowserState(browser_state, true)); +} + +// static +WebViewOAuth2TokenServiceFactory* +WebViewOAuth2TokenServiceFactory::GetInstance() { + static base::NoDestructor<WebViewOAuth2TokenServiceFactory> instance; + return instance.get(); +} + +void WebViewOAuth2TokenServiceFactory::RegisterBrowserStatePrefs( + user_prefs::PrefRegistrySyncable* registry) { + ProfileOAuth2TokenService::RegisterProfilePrefs(registry); +} + +std::unique_ptr<KeyedService> +WebViewOAuth2TokenServiceFactory::BuildServiceInstanceFor( + web::BrowserState* context) const { + WebViewBrowserState* browser_state = + WebViewBrowserState::FromBrowserState(context); + IOSWebViewSigninClient* signin_client = + WebViewSigninClientFactory::GetForBrowserState(browser_state); + auto token_service_provider = + std::make_unique<WebViewProfileOAuth2TokenServiceIOSProviderImpl>( + signin_client); + auto delegate = std::make_unique<ProfileOAuth2TokenServiceIOSDelegate>( + signin_client, std::move(token_service_provider), + WebViewAccountTrackerServiceFactory::GetForBrowserState(browser_state)); + return std::make_unique<ProfileOAuth2TokenService>(browser_state->GetPrefs(), + std::move(delegate)); +} + +} // namespace ios_web_view
diff --git a/ios/web_view/internal/sync/cwv_sync_controller.mm b/ios/web_view/internal/sync/cwv_sync_controller.mm index 24cefc7..b9318ac 100644 --- a/ios/web_view/internal/sync/cwv_sync_controller.mm +++ b/ios/web_view/internal/sync/cwv_sync_controller.mm
@@ -149,14 +149,13 @@ #pragma mark - Public Methods - (CWVIdentity*)currentIdentity { - base::Optional<AccountInfo> accountInfo = - _identityManager->FindExtendedAccountInfoForAccount( - _identityManager->GetPrimaryAccountInfo()); - if (!accountInfo) + if (!_identityManager->HasPrimaryAccount()) { return nil; - NSString* email = base::SysUTF8ToNSString(accountInfo->email); - NSString* fullName = base::SysUTF8ToNSString(accountInfo->full_name); - NSString* gaiaID = base::SysUTF8ToNSString(accountInfo->gaia); + } + AccountInfo accountInfo = _identityManager->GetPrimaryAccountInfoDeprecated(); + NSString* email = base::SysUTF8ToNSString(accountInfo.email); + NSString* fullName = base::SysUTF8ToNSString(accountInfo.full_name); + NSString* gaiaID = base::SysUTF8ToNSString(accountInfo.gaia); return [[CWVIdentity alloc] initWithEmail:email fullName:fullName gaiaID:gaiaID]; }
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn index dbc89ab..cb7a5305 100644 --- a/media/audio/BUILD.gn +++ b/media/audio/BUILD.gn
@@ -424,7 +424,7 @@ if (!is_chromecast) { deps += [ "//chromeos/audio", - "//chromeos/dbus:test_support", + "//chromeos/dbus/audio", ] }
diff --git a/media/capture/video/OWNERS b/media/capture/video/OWNERS index ea5ac3b3..bbd4afd7 100644 --- a/media/capture/video/OWNERS +++ b/media/capture/video/OWNERS
@@ -1,7 +1,9 @@ emircan@chromium.org chfremer@chromium.org -mcasas@chromium.org tommi@chromium.org +# Original (legacy) owner. +mcasas@chromium.org + # TEAM: media-capture-and-streams@grotations.appspotmail.com # COMPONENT: Blink>GetUserMedia>WebCam
diff --git a/media/capture/video/android/java/src/org/chromium/media/OWNERS b/media/capture/video/android/java/src/org/chromium/media/OWNERS index e34b150738..aa9f61f 100644 --- a/media/capture/video/android/java/src/org/chromium/media/OWNERS +++ b/media/capture/video/android/java/src/org/chromium/media/OWNERS
@@ -1,5 +1,7 @@ -mcasas@chromium.org qinmin@chromium.org +# Original (legacy) owner. +mcasas@chromium.org + # media-capture-and-streams@grotations.appspotmail.com # COMPONENT: Blink>GetUserMedia>WebCam
diff --git a/media/muxers/OWNERS b/media/muxers/OWNERS index 2198557..9198d8a 100644 --- a/media/muxers/OWNERS +++ b/media/muxers/OWNERS
@@ -1,4 +1,6 @@ -mcasas@chromium.org miu@chromium.org +# Original (legacy) owner. +mcasas@chromium.org + # COMPONENT: Blink>MediaRecording
diff --git a/net/base/auth.cc b/net/base/auth.cc index 343d0b5..99c02bf 100644 --- a/net/base/auth.cc +++ b/net/base/auth.cc
@@ -9,10 +9,15 @@ AuthChallengeInfo::AuthChallengeInfo() : is_proxy(false) { } -bool AuthChallengeInfo::Equals(const AuthChallengeInfo& that) const { - return (this->is_proxy == that.is_proxy && - this->challenger == that.challenger && this->scheme == that.scheme && - this->realm == that.realm); +AuthChallengeInfo::AuthChallengeInfo(const AuthChallengeInfo& other) = default; + +bool AuthChallengeInfo::operator==(const AuthChallengeInfo& that) const { + return (is_proxy == that.is_proxy && challenger == that.challenger && + scheme == that.scheme && realm == that.realm); +} + +bool AuthChallengeInfo::operator!=(const AuthChallengeInfo& that) const { + return !(*this == that); } AuthChallengeInfo::~AuthChallengeInfo() = default;
diff --git a/net/base/auth.h b/net/base/auth.h index 9db8447..f206dc26 100644 --- a/net/base/auth.h +++ b/net/base/auth.h
@@ -7,7 +7,6 @@ #include <string> -#include "base/memory/ref_counted.h" #include "base/strings/string16.h" #include "net/base/net_export.h" #include "url/origin.h" @@ -16,13 +15,14 @@ // Holds info about an authentication challenge that we may want to display // to the user. -class NET_EXPORT AuthChallengeInfo : - public base::RefCountedThreadSafe<AuthChallengeInfo> { +class NET_EXPORT AuthChallengeInfo { public: AuthChallengeInfo(); + AuthChallengeInfo(const AuthChallengeInfo& other); + ~AuthChallengeInfo(); - // Determines whether two AuthChallengeInfo's are equivalent. - bool Equals(const AuthChallengeInfo& other) const; + bool operator==(const AuthChallengeInfo& other) const; + bool operator!=(const AuthChallengeInfo& other) const; // Whether this came from a server or a proxy. bool is_proxy; @@ -36,10 +36,6 @@ // The realm of the challenge. May be empty. The encoding is UTF-8. std::string realm; - - private: - friend class base::RefCountedThreadSafe<AuthChallengeInfo>; - ~AuthChallengeInfo(); }; // Authentication Credentials for an authentication credentials.
diff --git a/net/base/layered_network_delegate_unittest.cc b/net/base/layered_network_delegate_unittest.cc index 9ae629c7..b6b867e 100644 --- a/net/base/layered_network_delegate_unittest.cc +++ b/net/base/layered_network_delegate_unittest.cc
@@ -178,7 +178,7 @@ ~TestLayeredNetworkDelegate() override = default; void CallAndVerify() { - scoped_refptr<AuthChallengeInfo> auth_challenge(new AuthChallengeInfo()); + AuthChallengeInfo auth_challenge; std::unique_ptr<URLRequest> request = context_.CreateRequest( GURL(), IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS); std::unique_ptr<HttpRequestHeaders> request_headers( @@ -204,9 +204,9 @@ OnCompleted(request.get(), false, net::OK); OnURLRequestDestroyed(request.get()); OnPACScriptError(0, base::string16()); - EXPECT_EQ(NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION, - OnAuthRequired(request.get(), *auth_challenge, AuthCallback(), - nullptr)); + EXPECT_EQ( + NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION, + OnAuthRequired(request.get(), auth_challenge, AuthCallback(), nullptr)); EXPECT_FALSE(OnCanGetCookies(*request, CookieList(), true)); EXPECT_FALSE( OnCanSetCookie(*request, net::CanonicalCookie(), nullptr, true));
diff --git a/net/http/http_auth_controller.cc b/net/http/http_auth_controller.cc index 6bb51b9c..cafe348c 100644 --- a/net/http/http_auth_controller.cc +++ b/net/http/http_auth_controller.cc
@@ -353,7 +353,7 @@ identity_.credentials = credentials; // auth_info_ is no longer necessary. - auth_info_ = nullptr; + auth_info_ = base::nullopt; } DCHECK(identity_.source != HttpAuth::IDENT_SRC_PATH_LOOKUP); @@ -508,7 +508,7 @@ // Populates response_.auth_challenge with the authentication challenge info. // This info is consumed by URLRequestHttpJob::GetAuthChallengeInfo(). - auth_info_ = new AuthChallengeInfo; + auth_info_ = AuthChallengeInfo(); auth_info_->is_proxy = (target_ == HttpAuth::AUTH_PROXY); auth_info_->challenger = url::Origin::Create(auth_origin_); auth_info_->scheme = HttpAuth::SchemeToString(handler_->auth_scheme()); @@ -572,9 +572,10 @@ } } -scoped_refptr<AuthChallengeInfo> HttpAuthController::auth_info() { +void HttpAuthController::TakeAuthInfo( + base::Optional<AuthChallengeInfo>* other) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - return auth_info_; + auth_info_.swap(*other); } bool HttpAuthController::IsAuthSchemeDisabled(HttpAuth::Scheme scheme) const {
diff --git a/net/http/http_auth_controller.h b/net/http/http_auth_controller.h index e71c3f93..94e3221 100644 --- a/net/http/http_auth_controller.h +++ b/net/http/http_auth_controller.h
@@ -10,6 +10,7 @@ #include <string> #include "base/memory/ref_counted.h" +#include "base/optional.h" #include "base/threading/thread_checker.h" #include "net/base/completion_once_callback.h" #include "net/base/net_export.h" @@ -82,7 +83,8 @@ // and thus the server would presumably reject a request on HTTP/2 anyway. bool NeedsHTTP11() const; - scoped_refptr<AuthChallengeInfo> auth_info(); + // Swaps the authentication challenge info into |other|. + void TakeAuthInfo(base::Optional<AuthChallengeInfo>* other); bool IsAuthSchemeDisabled(HttpAuth::Scheme scheme) const; void DisableAuthScheme(HttpAuth::Scheme scheme); @@ -170,7 +172,7 @@ std::string auth_token_; // Contains information about the auth challenge. - scoped_refptr<AuthChallengeInfo> auth_info_; + base::Optional<AuthChallengeInfo> auth_info_; // True if we've used the username:password embedded in the URL. This // makes sure we use the embedded identity only once for the transaction,
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc index 6ab67f99..7f37dc2 100644 --- a/net/http/http_cache_transaction.cc +++ b/net/http/http_cache_transaction.cc
@@ -1779,7 +1779,6 @@ // able to authenticate this request because we should have authenticated // this URL moments ago. if (IsReadyToRestartForAuth()) { - DCHECK(!response_.auth_challenge.get()); TransitionToState(STATE_SEND_REQUEST_COMPLETE); // In theory we should check to see if there are new cookies, but there // is no way to do that from here.
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index eba13448..118a1ff 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc
@@ -1846,10 +1846,7 @@ if (auth_controllers_[target]->HaveAuthHandler()) pending_auth_target_ = target; - scoped_refptr<AuthChallengeInfo> auth_info = - auth_controllers_[target]->auth_info(); - if (auth_info.get()) - response_.auth_challenge = auth_info; + auth_controllers_[target]->TakeAuthInfo(&response_.auth_challenge); return rv; }
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 0ee8d86..bf83c0a 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -716,7 +716,8 @@ // Helper functions for validating that AuthChallengeInfo's are correctly // configured for common cases. -bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) { +bool CheckBasicServerAuth( + const base::Optional<AuthChallengeInfo>& auth_challenge) { if (!auth_challenge) return false; EXPECT_FALSE(auth_challenge->is_proxy); @@ -726,7 +727,8 @@ return true; } -bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) { +bool CheckBasicProxyAuth( + const base::Optional<AuthChallengeInfo>& auth_challenge) { if (!auth_challenge) return false; EXPECT_TRUE(auth_challenge->is_proxy); @@ -736,7 +738,8 @@ return true; } -bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) { +bool CheckBasicSecureProxyAuth( + const base::Optional<AuthChallengeInfo>& auth_challenge) { if (!auth_challenge) return false; EXPECT_TRUE(auth_challenge->is_proxy); @@ -746,7 +749,8 @@ return true; } -bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) { +bool CheckDigestServerAuth( + const base::Optional<AuthChallengeInfo>& auth_challenge) { if (!auth_challenge) return false; EXPECT_FALSE(auth_challenge->is_proxy); @@ -757,7 +761,8 @@ } #if defined(NTLM_PORTABLE) -bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) { +bool CheckNTLMServerAuth( + const base::Optional<AuthChallengeInfo>& auth_challenge) { if (!auth_challenge) return false; EXPECT_FALSE(auth_challenge->is_proxy); @@ -767,7 +772,8 @@ return true; } -bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) { +bool CheckNTLMProxyAuth( + const base::Optional<AuthChallengeInfo>& auth_challenge) { if (!auth_challenge) return false; EXPECT_TRUE(auth_challenge->is_proxy); @@ -2664,7 +2670,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge)); TestCompletionCallback callback2; @@ -2690,7 +2696,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(100, response->headers->GetContentLength()); } @@ -2769,7 +2775,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge)); IPEndPoint endpoint; EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint)); @@ -2800,7 +2806,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(100, response->headers->GetContentLength()); EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint)); @@ -2863,7 +2869,7 @@ EXPECT_THAT(rv, IsOk()); const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge)); data_restarts.push_back(std::make_unique<StaticSocketDataProvider>( data_reads, data_writes_restart)); @@ -2921,7 +2927,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); } // Test the request-challenge-retry sequence for basic auth, over a keep-alive @@ -2986,7 +2992,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge)); TestCompletionCallback callback2; @@ -3005,7 +3011,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(5, response->headers->GetContentLength()); std::string response_data; @@ -3075,7 +3081,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge)); TestCompletionCallback callback2; @@ -3087,7 +3093,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(5, response->headers->GetContentLength()); } @@ -3156,7 +3162,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge)); TestCompletionCallback callback2; @@ -3168,7 +3174,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(5, response->headers->GetContentLength()); } @@ -3242,7 +3248,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge)); TestCompletionCallback callback2; @@ -3254,7 +3260,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(5, response->headers->GetContentLength()); } @@ -3349,7 +3355,7 @@ ASSERT_TRUE(response->headers); EXPECT_EQ(407, response->headers->response_code()); EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion()); - EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge)); LoadTimingInfo load_timing_info; // CONNECT requests and responses are handled at the connect job level, so @@ -3374,7 +3380,7 @@ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); // The password prompt info should not be set. - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReusedWithPac(load_timing_info, @@ -3474,7 +3480,7 @@ ASSERT_TRUE(response->headers); EXPECT_EQ(407, response->headers->response_code()); EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); - EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge)); LoadTimingInfo load_timing_info; // CONNECT requests and responses are handled at the connect job level, so @@ -3499,7 +3505,7 @@ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); // The password prompt info should not be set. - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReusedWithPac(load_timing_info, @@ -3598,7 +3604,7 @@ EXPECT_EQ(407, response->headers->response_code()); EXPECT_EQ(10, response->headers->GetContentLength()); EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion()); - EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge)); TestCompletionCallback callback2; @@ -3614,7 +3620,7 @@ EXPECT_EQ(407, response->headers->response_code()); EXPECT_EQ(10, response->headers->GetContentLength()); EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion()); - EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge)); // Flush the idle socket before the NetLog and HttpNetworkTransaction go // out of scope. @@ -3709,7 +3715,7 @@ EXPECT_EQ(407, response->headers->response_code()); EXPECT_EQ(10, response->headers->GetContentLength()); EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); - EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge)); EXPECT_FALSE(response->did_use_http_auth); TestCompletionCallback callback2; @@ -3726,7 +3732,7 @@ EXPECT_EQ(407, response->headers->response_code()); EXPECT_EQ(10, response->headers->GetContentLength()); EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); - EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge)); EXPECT_TRUE(response->did_use_http_auth); // Flush the idle socket before the NetLog and HttpNetworkTransaction go @@ -3834,7 +3840,7 @@ EXPECT_TRUE(response->headers->IsKeepAlive()); EXPECT_EQ(407, response->headers->response_code()); EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); - EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge)); LoadTimingInfo load_timing_info; // CONNECT requests and responses are handled at the connect job level, so @@ -3853,7 +3859,7 @@ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); // The password prompt info should not be set. - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReusedWithPac(load_timing_info, @@ -3939,7 +3945,7 @@ ASSERT_TRUE(response->headers); EXPECT_TRUE(response->headers->IsKeepAlive()); EXPECT_EQ(407, response->headers->response_code()); - EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge)); rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback()); EXPECT_THAT(callback.GetResult(rv), IsOk()); @@ -4269,7 +4275,7 @@ EXPECT_EQ(407, response->headers->response_code()); EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); EXPECT_TRUE(trans->IsReadyToRestartForAuth()); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); LoadTimingInfo load_timing_info; // CONNECT requests and responses are handled at the connect job level, so @@ -4287,7 +4293,7 @@ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); // The password prompt info should not be set. - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReusedWithPac(load_timing_info, @@ -4389,7 +4395,7 @@ EXPECT_EQ(407, response->headers->response_code()); EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); EXPECT_TRUE(trans->IsReadyToRestartForAuth()); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); LoadTimingInfo load_timing_info; // CONNECT requests and responses are handled at the connect job level, so @@ -4408,7 +4414,7 @@ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); // The password prompt info should not be set. - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReusedWithPac(load_timing_info, @@ -4504,7 +4510,7 @@ EXPECT_EQ(407, response->headers->response_code()); EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); EXPECT_TRUE(trans->IsReadyToRestartForAuth()); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); LoadTimingInfo load_timing_info; EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info)); @@ -4733,7 +4739,7 @@ EXPECT_EQ(407, response->headers->response_code()); EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); EXPECT_TRUE(trans->IsReadyToRestartForAuth()); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); LoadTimingInfo load_timing_info; EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info)); @@ -4745,7 +4751,7 @@ ASSERT_TRUE(response->headers); EXPECT_EQ(407, response->headers->response_code()); EXPECT_FALSE(trans->IsReadyToRestartForAuth()); - EXPECT_TRUE(response->auth_challenge); + EXPECT_TRUE(response->auth_challenge.has_value()); trans.reset(); session->CloseAllConnections(); @@ -4855,7 +4861,7 @@ // ambient credentials. EXPECT_EQ(401, response->headers->response_code()); EXPECT_TRUE(trans->IsReadyToRestartForAuth()); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); rv = trans->RestartWithAuth(AuthCredentials(), callback.callback()); EXPECT_THAT(callback.GetResult(rv), IsOk()); @@ -4868,7 +4874,7 @@ // to respond to the challenge. EXPECT_EQ(401, response->headers->response_code()); EXPECT_FALSE(trans->IsReadyToRestartForAuth()); - EXPECT_TRUE(response->auth_challenge); + EXPECT_TRUE(response->auth_challenge.has_value()); rv = trans->RestartWithAuth(AuthCredentials(), callback.callback()); EXPECT_THAT(callback.GetResult(rv), IsOk()); @@ -5424,7 +5430,7 @@ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); // The password prompt info should not be set. - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); } // Test a SPDY get through an HTTPS Proxy. @@ -5637,7 +5643,7 @@ ASSERT_TRUE(response->headers); EXPECT_EQ(407, response->headers->response_code()); EXPECT_TRUE(response->was_fetched_via_spdy); - EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge)); TestCompletionCallback callback2; @@ -5653,7 +5659,7 @@ ASSERT_TRUE(response_restart->headers); EXPECT_EQ(200, response_restart->headers->response_code()); // The password prompt info should not be set. - EXPECT_FALSE(response_restart->auth_challenge); + EXPECT_FALSE(response_restart->auth_challenge.has_value()); } // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server. @@ -5991,7 +5997,7 @@ ASSERT_TRUE(response->headers); EXPECT_EQ(407, response->headers->response_code()); EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); - EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge)); // Run second request until an auth challenge is observed. HttpRequestInfo request2; @@ -6007,7 +6013,7 @@ ASSERT_TRUE(response->headers); EXPECT_EQ(407, response->headers->response_code()); EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); - EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge)); // Now provide credentials for the first request, and wait for it to complete. rv = trans1.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback()); @@ -6741,7 +6747,7 @@ ASSERT_TRUE(response->headers); EXPECT_EQ(407, response->headers->response_code()); EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); - EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge)); EXPECT_FALSE(response->did_use_http_auth); TestCompletionCallback callback2; @@ -6767,7 +6773,7 @@ EXPECT_TRUE(response->did_use_http_auth); // The password prompt info should not be set. - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); } void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus( @@ -7080,7 +7086,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge)); TestCompletionCallback callback2; @@ -7092,7 +7098,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge)); TestCompletionCallback callback3; @@ -7104,7 +7110,7 @@ EXPECT_THAT(rv, IsOk()); response = trans.GetResponseInfo(); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(100, response->headers->GetContentLength()); } @@ -7233,7 +7239,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge)); TestCompletionCallback callback2; @@ -7249,7 +7255,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); TestCompletionCallback callback3; @@ -7261,7 +7267,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(14, response->headers->GetContentLength()); std::string response_data; @@ -7440,7 +7446,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge)); TestCompletionCallback callback2; @@ -7463,7 +7469,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge)); TestCompletionCallback callback4; @@ -7488,7 +7494,7 @@ EXPECT_THAT(rv, IsOk()); response = trans.GetResponseInfo(); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(14, response->headers->GetContentLength()); std::string response_data; @@ -7627,7 +7633,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge)); TestCompletionCallback callback2; @@ -7643,7 +7649,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); TestCompletionCallback callback3; @@ -7655,7 +7661,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(14, response->headers->GetContentLength()); std::string response_data; @@ -7783,7 +7789,7 @@ EXPECT_FALSE(trans.IsReadyToRestartForAuth()); const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge)); // Configure credentials. The proxy responds with the challenge message. rv = callback.GetResult(trans.RestartWithAuth( @@ -7793,7 +7799,7 @@ EXPECT_TRUE(trans.IsReadyToRestartForAuth()); response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); // Restart once more. The tunnel will be established and the the SSL handshake // will reset. The TLS 1.3 version interference probe will then kick in and @@ -7805,7 +7811,7 @@ EXPECT_TRUE(trans.IsReadyToRestartForAuth()); response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); // The proxy responds with the NTLM challenge message. rv = callback.GetResult( @@ -7814,7 +7820,7 @@ EXPECT_TRUE(trans.IsReadyToRestartForAuth()); response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); // Send the NTLM authenticate message. The tunnel is established and the // handshake resets again. We should not retry again. @@ -8563,7 +8569,7 @@ ASSERT_TRUE(response); // There is no challenge info, since the identity in URL worked. - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(100, response->headers->GetContentLength()); @@ -8660,7 +8666,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge)); TestCompletionCallback callback3; rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback()); @@ -8673,7 +8679,7 @@ ASSERT_TRUE(response); // There is no challenge info, since the identity worked. - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(100, response->headers->GetContentLength()); @@ -8741,7 +8747,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge)); TestCompletionCallback callback3; rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback()); @@ -8754,7 +8760,7 @@ ASSERT_TRUE(response); // There is no challenge info, since the identity worked. - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(100, response->headers->GetContentLength()); // Empty the current queue. @@ -8820,7 +8826,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge)); TestCompletionCallback callback2; @@ -8833,7 +8839,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(100, response->headers->GetContentLength()); } @@ -8918,7 +8924,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(100, response->headers->GetContentLength()); } @@ -8966,7 +8972,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(100, response->headers->GetContentLength()); } @@ -9036,7 +9042,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(100, response->headers->GetContentLength()); } @@ -9126,7 +9132,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge)); TestCompletionCallback callback3; @@ -9139,7 +9145,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(100, response->headers->GetContentLength()); } } @@ -9212,7 +9218,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge)); TestCompletionCallback callback2; @@ -9225,7 +9231,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); } // ------------------------------------------------------------------------ @@ -9275,7 +9281,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); } } @@ -9292,7 +9298,7 @@ // Setup state in response_ HttpResponseInfo* response = &trans.response_; - response->auth_challenge = new AuthChallengeInfo(); + response->auth_challenge = base::nullopt; response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical. response->response_time = base::Time::Now(); response->was_cached = true; // (Wouldn't ever actually be true...) @@ -9314,7 +9320,7 @@ EXPECT_FALSE(trans.read_buf_); EXPECT_EQ(0, trans.read_buf_len_); EXPECT_TRUE(trans.request_headers_.IsEmpty()); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_FALSE(response->headers); EXPECT_FALSE(response->was_cached); EXPECT_EQ(0U, response->ssl_info.cert_status); @@ -10050,8 +10056,8 @@ ASSERT_TRUE(response->headers); EXPECT_EQ(407, response->headers->response_code()); EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); - EXPECT_TRUE(response->auth_challenge); - EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get())); + EXPECT_TRUE(response->auth_challenge.has_value()); + EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge)); TestCompletionCallback callback2; @@ -10071,7 +10077,7 @@ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); // The password prompt info should not be set. - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); LoadTimingInfo load_timing_info; EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); @@ -11618,7 +11624,7 @@ const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); + EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge)); TestCompletionCallback callback2; @@ -11630,7 +11636,7 @@ response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(100, response->headers->GetContentLength()); } @@ -11947,7 +11953,7 @@ EXPECT_THAT(rv, IsOk()); const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); - const AuthChallengeInfo* challenge = response->auth_challenge.get(); + base::Optional<AuthChallengeInfo> challenge = response->auth_challenge; ASSERT_TRUE(challenge); EXPECT_FALSE(challenge->is_proxy); EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize()); @@ -11965,7 +11971,7 @@ EXPECT_THAT(rv, IsOk()); response = trans.GetResponseInfo(); ASSERT_TRUE(response); - challenge = response->auth_challenge.get(); + challenge = response->auth_challenge; ASSERT_TRUE(challenge); EXPECT_FALSE(challenge->is_proxy); EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize()); @@ -11984,7 +11990,7 @@ EXPECT_THAT(rv, IsOk()); response = trans.GetResponseInfo(); ASSERT_TRUE(response); - challenge = response->auth_challenge.get(); + challenge = response->auth_challenge; ASSERT_TRUE(challenge); EXPECT_FALSE(challenge->is_proxy); EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize()); @@ -12000,7 +12006,7 @@ EXPECT_THAT(rv, IsOk()); response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); } // Regression test for https://crbug.com/754395. @@ -14375,9 +14381,9 @@ continue; } if (round + 1 < test_config.num_auth_rounds) { - EXPECT_TRUE(response->auth_challenge); + EXPECT_TRUE(response->auth_challenge.has_value()); } else { - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_FALSE(trans.IsReadyToRestartForAuth()); } } @@ -14494,7 +14500,7 @@ EXPECT_THAT(rv, IsOk()); response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_TRUE(response->auth_challenge); + EXPECT_TRUE(response->auth_challenge.has_value()); EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN, auth_handler->state()); @@ -14519,7 +14525,7 @@ EXPECT_THAT(rv, IsOk()); response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN, auth_handler->state()); @@ -14532,7 +14538,7 @@ EXPECT_THAT(rv, IsOk()); response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN, auth_handler->state()); @@ -14545,7 +14551,7 @@ EXPECT_THAT(rv, IsOk()); response = trans.GetResponseInfo(); ASSERT_TRUE(response); - EXPECT_FALSE(response->auth_challenge); + EXPECT_FALSE(response->auth_challenge.has_value()); EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
diff --git a/net/http/http_response_info.cc b/net/http/http_response_info.cc index 0dfb809..64e0e38 100644 --- a/net/http/http_response_info.cc +++ b/net/http/http_response_info.cc
@@ -8,7 +8,6 @@ #include "base/numerics/safe_conversions.h" #include "base/pickle.h" #include "base/time/time.h" -#include "net/base/auth.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/cert/sct_status_flags.h"
diff --git a/net/http/http_response_info.h b/net/http/http_response_info.h index 48fea75..4638527 100644 --- a/net/http/http_response_info.h +++ b/net/http/http_response_info.h
@@ -7,7 +7,9 @@ #include <string> +#include "base/optional.h" #include "base/time/time.h" +#include "net/base/auth.h" #include "net/base/ip_endpoint.h" #include "net/base/net_export.h" #include "net/base/proxy_server.h" @@ -20,7 +22,6 @@ namespace net { -class AuthChallengeInfo; class HttpResponseHeaders; class IOBufferWithSize; class SSLCertRequestInfo; @@ -189,7 +190,7 @@ // If the response headers indicate a 401 or 407 failure, then this structure // will contain additional information about the authentication challenge. - scoped_refptr<AuthChallengeInfo> auth_challenge; + base::Optional<AuthChallengeInfo> auth_challenge; // The SSL client certificate request info. // TODO(wtc): does this really belong in HttpResponseInfo? I put it here
diff --git a/net/http/proxy_client_socket.cc b/net/http/proxy_client_socket.cc index 6dde1d5..c80ccee 100644 --- a/net/http/proxy_client_socket.cc +++ b/net/http/proxy_client_socket.cc
@@ -52,7 +52,7 @@ DCHECK(response->headers.get()); int rv = auth->HandleAuthChallenge(response->headers, response->ssl_info, false, true, net_log); - response->auth_challenge = auth->auth_info(); + auth->TakeAuthInfo(&response->auth_challenge); if (rv == OK) return ERR_PROXY_AUTH_REQUESTED; return rv;
diff --git a/net/proxy_resolution/pac_file_fetcher_impl.cc b/net/proxy_resolution/pac_file_fetcher_impl.cc index 4e7b612..126c58c1 100644 --- a/net/proxy_resolution/pac_file_fetcher_impl.cc +++ b/net/proxy_resolution/pac_file_fetcher_impl.cc
@@ -256,7 +256,7 @@ } void PacFileFetcherImpl::OnAuthRequired(URLRequest* request, - AuthChallengeInfo* auth_info) { + const AuthChallengeInfo& auth_info) { DCHECK_EQ(request, cur_request_.get()); // TODO(eroman): http://crbug.com/77366 LOG(WARNING) << "Auth required to fetch PAC script, aborting.";
diff --git a/net/proxy_resolution/pac_file_fetcher_impl.h b/net/proxy_resolution/pac_file_fetcher_impl.h index a9e13db5..e51e258c 100644 --- a/net/proxy_resolution/pac_file_fetcher_impl.h +++ b/net/proxy_resolution/pac_file_fetcher_impl.h
@@ -79,7 +79,7 @@ const RedirectInfo& redirect_info, bool* defer_redirect) override; void OnAuthRequired(URLRequest* request, - AuthChallengeInfo* auth_info) override; + const AuthChallengeInfo& auth_info) override; void OnSSLCertificateError(URLRequest* request, const SSLInfo& ssl_info, bool is_hsts_ok) override;
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc index 43ea8acb..17f9ac87 100644 --- a/net/quic/quic_network_transaction_unittest.cc +++ b/net/quic/quic_network_transaction_unittest.cc
@@ -8435,8 +8435,9 @@ EXPECT_EQ(407, response->headers->response_code()); EXPECT_EQ(10, response->headers->GetContentLength()); EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion()); - const AuthChallengeInfo* auth_challenge = response->auth_challenge.get(); - ASSERT_TRUE(auth_challenge != nullptr); + base::Optional<AuthChallengeInfo> auth_challenge = + response->auth_challenge; + ASSERT_TRUE(auth_challenge.has_value()); EXPECT_TRUE(auth_challenge->is_proxy); EXPECT_EQ("https://proxy.example.org:70", auth_challenge->challenger.Serialize()); @@ -8458,8 +8459,8 @@ EXPECT_EQ(407, response->headers->response_code()); EXPECT_EQ(10, response->headers->GetContentLength()); EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion()); - auth_challenge = response->auth_challenge.get(); - ASSERT_TRUE(auth_challenge != nullptr); + auth_challenge = response->auth_challenge; + ASSERT_TRUE(auth_challenge.has_value()); EXPECT_TRUE(auth_challenge->is_proxy); EXPECT_EQ("https://proxy.example.org:70", auth_challenge->challenger.Serialize());
diff --git a/net/reporting/reporting_uploader.cc b/net/reporting/reporting_uploader.cc index 5e5848b7..1f7bfa7e 100644 --- a/net/reporting/reporting_uploader.cc +++ b/net/reporting/reporting_uploader.cc
@@ -234,7 +234,7 @@ } void OnAuthRequired(URLRequest* request, - AuthChallengeInfo* auth_info) override { + const AuthChallengeInfo& auth_info) override { request->Cancel(); }
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index a17437d95..feaf25b 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -5426,7 +5426,8 @@ ASSERT_TRUE(response_start->headers); EXPECT_EQ(401, response_start->headers->response_code()); EXPECT_TRUE(response_start->was_fetched_via_spdy); - AuthChallengeInfo* auth_challenge = response_start->auth_challenge.get(); + const base::Optional<AuthChallengeInfo>& auth_challenge = + response_start->auth_challenge; ASSERT_TRUE(auth_challenge); EXPECT_FALSE(auth_challenge->is_proxy); EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme); @@ -5447,7 +5448,7 @@ ASSERT_TRUE(response_restart); ASSERT_TRUE(response_restart->headers); EXPECT_EQ(200, response_restart->headers->response_code()); - EXPECT_TRUE(response_restart->auth_challenge.get() == nullptr); + EXPECT_FALSE(response_restart->auth_challenge); } struct PushHeaderTestParams {
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index 9507dc7..f7ee1c6 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc
@@ -146,7 +146,7 @@ bool* defer_redirect) {} void URLRequest::Delegate::OnAuthRequired(URLRequest* request, - AuthChallengeInfo* auth_info) { + const AuthChallengeInfo& auth_info) { request->CancelAuth(); } @@ -1018,14 +1018,16 @@ job_->SetPriority(priority_); } -void URLRequest::NotifyAuthRequired(AuthChallengeInfo* auth_info) { +void URLRequest::NotifyAuthRequired( + std::unique_ptr<AuthChallengeInfo> auth_info) { NetworkDelegate::AuthRequiredResponse rv = NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; - auth_info_ = auth_info; + auth_info_ = std::move(auth_info); + DCHECK(auth_info_); if (network_delegate_) { OnCallToDelegate(NetLogEventType::NETWORK_DELEGATE_AUTH_REQUIRED); rv = network_delegate_->NotifyAuthRequired( - this, *auth_info, + this, *auth_info_.get(), base::BindOnce(&URLRequest::NotifyAuthRequiredComplete, base::Unretained(this)), &auth_credentials_); @@ -1048,14 +1050,14 @@ // so it can be reset on another round. AuthCredentials credentials = auth_credentials_; auth_credentials_ = AuthCredentials(); - scoped_refptr<AuthChallengeInfo> auth_info; + std::unique_ptr<AuthChallengeInfo> auth_info; auth_info.swap(auth_info_); switch (result) { case NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION: // Defer to the URLRequest::Delegate, since the NetworkDelegate // didn't take an action. - delegate_->OnAuthRequired(this, auth_info.get()); + delegate_->OnAuthRequired(this, *auth_info.get()); break; case NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH:
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h index 2b80fba..b264ca0 100644 --- a/net/url_request/url_request.h +++ b/net/url_request/url_request.h
@@ -187,7 +187,7 @@ // When it does so, the request will be reissued, restarting the sequence // of On* callbacks. virtual void OnAuthRequired(URLRequest* request, - AuthChallengeInfo* auth_info); + const AuthChallengeInfo& auth_info); // Called when we receive an SSL CertificateRequest message for client // authentication. The delegate should call @@ -824,7 +824,7 @@ // These functions delegate to |delegate_|. See URLRequest::Delegate for the // meaning of these functions. - void NotifyAuthRequired(AuthChallengeInfo* auth_info); + void NotifyAuthRequired(std::unique_ptr<AuthChallengeInfo> auth_info); void NotifyAuthRequiredComplete(NetworkDelegate::AuthRequiredResponse result); void NotifyCertificateRequested(SSLCertRequestInfo* cert_request_info); void NotifySSLCertificateError(const SSLInfo& ssl_info, bool fatal); @@ -948,7 +948,7 @@ // |NotifyAuthRequired| on the NetworkDelegate. |auth_info_| holds // the authentication challenge being handled by |NotifyAuthRequired|. AuthCredentials auth_credentials_; - scoped_refptr<AuthChallengeInfo> auth_info_; + std::unique_ptr<AuthChallengeInfo> auth_info_; int64_t received_response_content_length_;
diff --git a/net/url_request/url_request_data_job_fuzzer.cc b/net/url_request/url_request_data_job_fuzzer.cc index 29d0ddb..17635ef9 100644 --- a/net/url_request/url_request_data_job_fuzzer.cc +++ b/net/url_request/url_request_data_job_fuzzer.cc
@@ -125,7 +125,7 @@ const net::RedirectInfo& redirect_info, bool* defer_redirect) override {} void OnAuthRequired(net::URLRequest* request, - net::AuthChallengeInfo* auth_info) override {} + const net::AuthChallengeInfo& auth_info) override {} void OnCertificateRequested( net::URLRequest* request, net::SSLCertRequestInfo* cert_request_info) override {}
diff --git a/net/url_request/url_request_ftp_job.cc b/net/url_request/url_request_ftp_job.cc index 3f5633142..9e888e904 100644 --- a/net/url_request/url_request_ftp_job.cc +++ b/net/url_request/url_request_ftp_job.cc
@@ -301,22 +301,24 @@ return auth_data_.get() && auth_data_->state == AUTH_STATE_NEED_AUTH; } -void URLRequestFtpJob::GetAuthChallengeInfo( - scoped_refptr<AuthChallengeInfo>* result) { +std::unique_ptr<AuthChallengeInfo> URLRequestFtpJob::GetAuthChallengeInfo() { DCHECK(NeedsAuth()); if (http_response_info_) { - *result = http_response_info_->auth_challenge; - return; + if (!http_response_info_->auth_challenge.has_value()) + return nullptr; + return std::make_unique<AuthChallengeInfo>( + http_response_info_->auth_challenge.value()); } - scoped_refptr<AuthChallengeInfo> auth_info(new AuthChallengeInfo); - auth_info->is_proxy = false; - auth_info->challenger = url::Origin::Create(request_->url()); + std::unique_ptr<AuthChallengeInfo> result = + std::make_unique<AuthChallengeInfo>(); + result->is_proxy = false; + result->challenger = url::Origin::Create(request_->url()); // scheme and realm are kept empty. - DCHECK(auth_info->scheme.empty()); - DCHECK(auth_info->realm.empty()); - result->swap(auth_info); + DCHECK(result->scheme.empty()); + DCHECK(result->realm.empty()); + return result; } void URLRequestFtpJob::SetAuth(const AuthCredentials& credentials) {
diff --git a/net/url_request/url_request_ftp_job.h b/net/url_request/url_request_ftp_job.h index cfc27ff..c01f7ed 100644 --- a/net/url_request/url_request_ftp_job.h +++ b/net/url_request/url_request_ftp_job.h
@@ -69,8 +69,7 @@ // Overridden from URLRequestJob: LoadState GetLoadState() const override; bool NeedsAuth() override; - void GetAuthChallengeInfo( - scoped_refptr<AuthChallengeInfo>* auth_info) override; + std::unique_ptr<AuthChallengeInfo> GetAuthChallengeInfo() override; void SetAuth(const AuthCredentials& credentials) override; void CancelAuth() override;
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index 3b187a9..4f1fa6e0 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc
@@ -411,7 +411,6 @@ // of sending authorization information. Each time it restarts, we get // notified of the headers completion so that we can update the cookie store. if (transaction_->IsReadyToRestartForAuth()) { - DCHECK(!response_info_->auth_challenge.get()); // TODO(battre): This breaks the webrequest API for // URLRequestTestHTTP.BasicAuthWithCookies // where OnBeforeStartTransaction -> OnStartTransaction -> @@ -1126,8 +1125,7 @@ return false; } -void URLRequestHttpJob::GetAuthChallengeInfo( - scoped_refptr<AuthChallengeInfo>* result) { +std::unique_ptr<AuthChallengeInfo> URLRequestHttpJob::GetAuthChallengeInfo() { DCHECK(transaction_.get()); DCHECK(response_info_); @@ -1138,7 +1136,10 @@ (GetResponseHeaders()->response_code() == HTTP_PROXY_AUTHENTICATION_REQUIRED)); - *result = response_info_->auth_challenge; + if (!response_info_->auth_challenge.has_value()) + return nullptr; + return std::make_unique<AuthChallengeInfo>( + response_info_->auth_challenge.value()); } void URLRequestHttpJob::SetAuth(const AuthCredentials& credentials) {
diff --git a/net/url_request/url_request_http_job.h b/net/url_request/url_request_http_job.h index dbfe3b9..5da15f7 100644 --- a/net/url_request/url_request_http_job.h +++ b/net/url_request/url_request_http_job.h
@@ -114,7 +114,7 @@ bool CopyFragmentOnRedirect(const GURL& location) const override; bool IsSafeRedirect(const GURL& location) override; bool NeedsAuth() override; - void GetAuthChallengeInfo(scoped_refptr<AuthChallengeInfo>*) override; + std::unique_ptr<AuthChallengeInfo> GetAuthChallengeInfo() override; void SetAuth(const AuthCredentials& credentials) override; void CancelAuth() override; void ContinueWithCertificate(
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc index 85a1889..06df9bd3 100644 --- a/net/url_request/url_request_job.cc +++ b/net/url_request/url_request_job.cc
@@ -222,11 +222,11 @@ return false; } -void URLRequestJob::GetAuthChallengeInfo( - scoped_refptr<AuthChallengeInfo>* auth_info) { +std::unique_ptr<AuthChallengeInfo> URLRequestJob::GetAuthChallengeInfo() { // This will only be called if NeedsAuth() returns true, in which // case the derived class should implement this! NOTREACHED(); + return nullptr; } void URLRequestJob::SetAuth(const AuthCredentials& credentials) { @@ -449,13 +449,11 @@ } if (NeedsAuth()) { - scoped_refptr<AuthChallengeInfo> auth_info; - GetAuthChallengeInfo(&auth_info); - + std::unique_ptr<AuthChallengeInfo> auth_info = GetAuthChallengeInfo(); // Need to check for a NULL auth_info because the server may have failed // to send a challenge with the 401 response. - if (auth_info.get()) { - request_->NotifyAuthRequired(auth_info.get()); + if (auth_info) { + request_->NotifyAuthRequired(std::move(auth_info)); // Wait for SetAuth or CancelAuth to be called. return; }
diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h index 2b2cd17..019e8102 100644 --- a/net/url_request/url_request_job.h +++ b/net/url_request/url_request_job.h
@@ -180,9 +180,9 @@ // obtaining the credentials passing them to SetAuth. virtual bool NeedsAuth(); - // Fills the authentication info with the server's response. - virtual void GetAuthChallengeInfo( - scoped_refptr<AuthChallengeInfo>* auth_info); + // Returns a copy of the authentication challenge that came with the server's + // response. + virtual std::unique_ptr<AuthChallengeInfo> GetAuthChallengeInfo(); // Resend the request with authentication credentials. virtual void SetAuth(const AuthCredentials& credentials);
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc index 0c11ad2..a217e18 100644 --- a/net/url_request/url_request_test_util.cc +++ b/net/url_request/url_request_test_util.cc
@@ -248,7 +248,7 @@ } void TestDelegate::OnAuthRequired(URLRequest* request, - AuthChallengeInfo* auth_info) { + const AuthChallengeInfo& auth_info) { auth_required_ = true; if (on_auth_required_) { std::move(on_auth_required_).Run();
diff --git a/net/url_request/url_request_test_util.h b/net/url_request/url_request_test_util.h index 59b7525..a6324bf 100644 --- a/net/url_request/url_request_test_util.h +++ b/net/url_request/url_request_test_util.h
@@ -204,7 +204,7 @@ const RedirectInfo& redirect_info, bool* defer_redirect) override; void OnAuthRequired(URLRequest* request, - AuthChallengeInfo* auth_info) override; + const AuthChallengeInfo& auth_info) override; // NOTE: |fatal| causes |certificate_errors_are_fatal_| to be set to true. // (Unit tests use this as a post-condition.) But for policy, this method // consults |allow_certificate_errors_|.
diff --git a/net/websockets/websocket_channel.cc b/net/websockets/websocket_channel.cc index 69bcd78..504453d0 100644 --- a/net/websockets/websocket_channel.cc +++ b/net/websockets/websocket_channel.cc
@@ -205,12 +205,12 @@ fatal); } - int OnAuthRequired(scoped_refptr<AuthChallengeInfo> auth_info, + int OnAuthRequired(const AuthChallengeInfo& auth_info, scoped_refptr<HttpResponseHeaders> headers, const IPEndPoint& remote_endpoint, base::OnceCallback<void(const AuthCredentials*)> callback, base::Optional<AuthCredentials>* credentials) override { - return creator_->OnAuthRequired(std::move(auth_info), std::move(headers), + return creator_->OnAuthRequired(auth_info, std::move(headers), remote_endpoint, std::move(callback), credentials); } @@ -602,13 +602,13 @@ } int WebSocketChannel::OnAuthRequired( - scoped_refptr<AuthChallengeInfo> auth_info, + const AuthChallengeInfo& auth_info, scoped_refptr<HttpResponseHeaders> response_headers, const IPEndPoint& remote_endpoint, base::OnceCallback<void(const AuthCredentials*)> callback, base::Optional<AuthCredentials>* credentials) { return event_interface_->OnAuthRequired( - std::move(auth_info), std::move(response_headers), remote_endpoint, + auth_info, std::move(response_headers), remote_endpoint, std::move(callback), credentials); }
diff --git a/net/websockets/websocket_channel.h b/net/websockets/websocket_channel.h index 44f475d..977fdc4 100644 --- a/net/websockets/websocket_channel.h +++ b/net/websockets/websocket_channel.h
@@ -213,7 +213,7 @@ // Authentication request from WebSocketStream::CreateAndConnectStream(). // Forwards the request to the event interface. - int OnAuthRequired(scoped_refptr<AuthChallengeInfo> auth_info, + int OnAuthRequired(const AuthChallengeInfo& auth_info, scoped_refptr<HttpResponseHeaders> response_headers, const IPEndPoint& remote_endpoint, base::OnceCallback<void(const AuthCredentials*)> callback,
diff --git a/net/websockets/websocket_channel_test.cc b/net/websockets/websocket_channel_test.cc index 7209658..655ff91 100644 --- a/net/websockets/websocket_channel_test.cc +++ b/net/websockets/websocket_channel_test.cc
@@ -202,7 +202,7 @@ OnSSLCertificateErrorCalled( ssl_error_callbacks.get(), url, ssl_info, fatal); } - int OnAuthRequired(scoped_refptr<AuthChallengeInfo> auth_info, + int OnAuthRequired(const AuthChallengeInfo& auth_info, scoped_refptr<HttpResponseHeaders> response_headers, const IPEndPoint& remote_endpoint, base::OnceCallback<void(const AuthCredentials*)> callback, @@ -218,7 +218,7 @@ OnSSLCertificateErrorCalled, void(SSLErrorCallbacks*, const GURL&, const SSLInfo&, bool)); // NOLINT MOCK_METHOD4(OnAuthRequiredCalled, - int(scoped_refptr<AuthChallengeInfo>, + int(const AuthChallengeInfo&, scoped_refptr<HttpResponseHeaders>, const IPEndPoint&, base::Optional<AuthCredentials>*)); @@ -249,7 +249,7 @@ const GURL& url, const SSLInfo& ssl_info, bool fatal) override {} - int OnAuthRequired(scoped_refptr<AuthChallengeInfo> auth_info, + int OnAuthRequired(const AuthChallengeInfo& auth_info, scoped_refptr<HttpResponseHeaders> response_headers, const IPEndPoint& remote_endpoint, base::OnceCallback<void(const AuthCredentials*)> callback, @@ -2965,8 +2965,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, OnAuthRequiredCalled) { const GURL wss_url("wss://example.com/on_auth_required"); connect_data_.socket_url = wss_url; - scoped_refptr<AuthChallengeInfo> auth_info = - base::MakeRefCounted<AuthChallengeInfo>(); + AuthChallengeInfo auth_info; base::Optional<AuthCredentials> credentials; scoped_refptr<HttpResponseHeaders> response_headers = base::MakeRefCounted<HttpResponseHeaders>("HTTP/1.1 200 OK");
diff --git a/net/websockets/websocket_end_to_end_test.cc b/net/websockets/websocket_end_to_end_test.cc index 9622efb..4ce998a 100644 --- a/net/websockets/websocket_end_to_end_test.cc +++ b/net/websockets/websocket_end_to_end_test.cc
@@ -126,7 +126,7 @@ const SSLInfo& ssl_info, bool fatal) override; - int OnAuthRequired(scoped_refptr<AuthChallengeInfo> auth_info, + int OnAuthRequired(const AuthChallengeInfo& auth_info, scoped_refptr<HttpResponseHeaders> response_headers, const IPEndPoint& remote_endpoint, base::OnceCallback<void(const AuthCredentials*)> callback, @@ -209,7 +209,7 @@ } int ConnectTestingEventInterface::OnAuthRequired( - scoped_refptr<AuthChallengeInfo> auth_info, + const AuthChallengeInfo& auth_info, scoped_refptr<HttpResponseHeaders> response_headers, const IPEndPoint& remote_endpoint, base::OnceCallback<void(const AuthCredentials*)> callback,
diff --git a/net/websockets/websocket_event_interface.h b/net/websockets/websocket_event_interface.h index 4c3d6e3c..b7a4343 100644 --- a/net/websockets/websocket_event_interface.h +++ b/net/websockets/websocket_event_interface.h
@@ -136,7 +136,7 @@ // async case) cancels authentication. Otherwise the new credentials are set // and the opening handshake will be retried with the credentials. virtual int OnAuthRequired( - scoped_refptr<AuthChallengeInfo> auth_info, + const AuthChallengeInfo& auth_info, scoped_refptr<HttpResponseHeaders> response_headers, const IPEndPoint& socket_address, base::OnceCallback<void(const AuthCredentials*)> callback,
diff --git a/net/websockets/websocket_handshake_stream_create_helper_test.cc b/net/websockets/websocket_handshake_stream_create_helper_test.cc index 3fb6248..4aa13d6 100644 --- a/net/websockets/websocket_handshake_stream_create_helper_test.cc +++ b/net/websockets/websocket_handshake_stream_create_helper_test.cc
@@ -121,8 +121,7 @@ ssl_error_callbacks, const SSLInfo& ssl_info, bool fatal) override {} - int OnAuthRequired(scoped_refptr<AuthChallengeInfo> auth_info, - + int OnAuthRequired(const AuthChallengeInfo& auth_info, scoped_refptr<HttpResponseHeaders> response_headers, const IPEndPoint& host_port_pair, base::OnceCallback<void(const AuthCredentials*)> callback,
diff --git a/net/websockets/websocket_stream.cc b/net/websockets/websocket_stream.cc index 5e716880..9020000 100644 --- a/net/websockets/websocket_stream.cc +++ b/net/websockets/websocket_stream.cc
@@ -87,7 +87,7 @@ void OnResponseStarted(URLRequest* request, int net_error) override; void OnAuthRequired(URLRequest* request, - AuthChallengeInfo* auth_info) override; + const AuthChallengeInfo& auth_info) override; void OnCertificateRequested(URLRequest* request, SSLCertRequestInfo* cert_request_info) override; @@ -410,12 +410,12 @@ } void Delegate::OnAuthRequired(URLRequest* request, - AuthChallengeInfo* auth_info) { + const AuthChallengeInfo& auth_info) { base::Optional<AuthCredentials> credentials; // This base::Unretained(this) relies on an assumption that |callback| can // be called called during the opening handshake. int rv = owner_->connect_delegate()->OnAuthRequired( - scoped_refptr<AuthChallengeInfo>(auth_info), request->response_headers(), + auth_info, request->response_headers(), request->GetResponseRemoteEndpoint(), base::BindOnce(&Delegate::OnAuthRequiredComplete, base::Unretained(this), request),
diff --git a/net/websockets/websocket_stream.h b/net/websockets/websocket_stream.h index 867b5a9..70c05cef 100644 --- a/net/websockets/websocket_stream.h +++ b/net/websockets/websocket_stream.h
@@ -129,7 +129,7 @@ // async case) cancels authentication. Otherwise the new credentials are set // and the opening handshake will be retried with the credentials. virtual int OnAuthRequired( - scoped_refptr<AuthChallengeInfo> auth_info, + const AuthChallengeInfo& auth_info, scoped_refptr<HttpResponseHeaders> response_headers, const IPEndPoint& remote_endpoint, base::OnceCallback<void(const AuthCredentials*)> callback,
diff --git a/net/websockets/websocket_stream_create_test_base.cc b/net/websockets/websocket_stream_create_test_base.cc index 9db4381..6e8284e 100644 --- a/net/websockets/websocket_stream_create_test_base.cc +++ b/net/websockets/websocket_stream_create_test_base.cc
@@ -69,13 +69,13 @@ owner_->ssl_fatal_ = fatal; } - int OnAuthRequired(scoped_refptr<AuthChallengeInfo> auth_info, + int OnAuthRequired(const AuthChallengeInfo& auth_info, scoped_refptr<HttpResponseHeaders> response_headers, const IPEndPoint& remote_endpoint, base::OnceCallback<void(const AuthCredentials*)> callback, base::Optional<AuthCredentials>* credentials) override { owner_->run_loop_waiting_for_on_auth_required_.Quit(); - owner_->auth_challenge_info_ = std::move(auth_info); + owner_->auth_challenge_info_ = auth_info; *credentials = owner_->auth_credentials_; owner_->on_auth_required_callback_ = std::move(callback); return owner_->on_auth_required_rv_;
diff --git a/net/websockets/websocket_stream_create_test_base.h b/net/websockets/websocket_stream_create_test_base.h index 228789c..3df0f4d6 100644 --- a/net/websockets/websocket_stream_create_test_base.h +++ b/net/websockets/websocket_stream_create_test_base.h
@@ -81,7 +81,7 @@ SSLInfo ssl_info_; bool ssl_fatal_; URLRequest* url_request_; - scoped_refptr<AuthChallengeInfo> auth_challenge_info_; + AuthChallengeInfo auth_challenge_info_; base::OnceCallback<void(const AuthCredentials*)> on_auth_required_callback_; // This value will be copied to |*credentials| on OnAuthRequired.
diff --git a/net/websockets/websocket_test_util.cc b/net/websockets/websocket_test_util.cc index 5335404..ecacab3 100644 --- a/net/websockets/websocket_test_util.cc +++ b/net/websockets/websocket_test_util.cc
@@ -259,7 +259,7 @@ } int DummyConnectDelegate::OnAuthRequired( - scoped_refptr<AuthChallengeInfo> auth_info, + const AuthChallengeInfo& auth_info, scoped_refptr<HttpResponseHeaders> response_headers, const IPEndPoint& host_port_pair, base::OnceCallback<void(const AuthCredentials*)> callback,
diff --git a/net/websockets/websocket_test_util.h b/net/websockets/websocket_test_util.h index 7346a657..db4bc1a7 100644 --- a/net/websockets/websocket_test_util.h +++ b/net/websockets/websocket_test_util.h
@@ -195,7 +195,7 @@ ssl_error_callbacks, const SSLInfo& ssl_info, bool fatal) override {} - int OnAuthRequired(scoped_refptr<AuthChallengeInfo> auth_info, + int OnAuthRequired(const AuthChallengeInfo& auth_info, scoped_refptr<HttpResponseHeaders> response_headers, const IPEndPoint& remote_endpoint, base::OnceCallback<void(const AuthCredentials*)> callback,
diff --git a/ppapi/thunk/interfaces_ppb_private_no_permissions.h b/ppapi/thunk/interfaces_ppb_private_no_permissions.h index 5029225..166540f 100644 --- a/ppapi/thunk/interfaces_ppb_private_no_permissions.h +++ b/ppapi/thunk/interfaces_ppb_private_no_permissions.h
@@ -5,6 +5,9 @@ // Please see inteface_ppb_public_stable for the documentation on the format of // this file. +// no-include-guard-because-multiply-included +// NOLINT(build/header_guard) + #include "ppapi/thunk/interfaces_preamble.h" // These interfaces don't require private permissions. However, they only work @@ -17,22 +20,6 @@ PROXIED_IFACE(PPB_HOSTRESOLVER_PRIVATE_INTERFACE_0_1, PPB_HostResolver_Private_0_1) -PROXIED_IFACE(PPB_TCPSERVERSOCKET_PRIVATE_INTERFACE_0_1, - PPB_TCPServerSocket_Private_0_1) -PROXIED_IFACE(PPB_TCPSERVERSOCKET_PRIVATE_INTERFACE_0_2, - PPB_TCPServerSocket_Private_0_2) -PROXIED_IFACE(PPB_TCPSOCKET_PRIVATE_INTERFACE_0_3, - PPB_TCPSocket_Private_0_3) -PROXIED_IFACE(PPB_TCPSOCKET_PRIVATE_INTERFACE_0_4, - PPB_TCPSocket_Private_0_4) -PROXIED_IFACE(PPB_TCPSOCKET_PRIVATE_INTERFACE_0_5, - PPB_TCPSocket_Private_0_5) -PROXIED_IFACE(PPB_UDPSOCKET_PRIVATE_INTERFACE_0_2, - PPB_UDPSocket_Private_0_2) -PROXIED_IFACE(PPB_UDPSOCKET_PRIVATE_INTERFACE_0_3, - PPB_UDPSocket_Private_0_3) -PROXIED_IFACE(PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4, - PPB_UDPSocket_Private_0_4) PROXIED_IFACE(PPB_NETADDRESS_PRIVATE_INTERFACE_0_1, PPB_NetAddress_Private_0_1)
diff --git a/ppapi/thunk/interfaces_ppb_public_socket.h b/ppapi/thunk/interfaces_ppb_public_socket.h index f79f7e7..2558f97 100644 --- a/ppapi/thunk/interfaces_ppb_public_socket.h +++ b/ppapi/thunk/interfaces_ppb_public_socket.h
@@ -15,4 +15,16 @@ PROXIED_IFACE(PPB_UDPSOCKET_INTERFACE_1_1, PPB_UDPSocket_1_1) PROXIED_IFACE(PPB_UDPSOCKET_INTERFACE_1_2, PPB_UDPSocket_1_2) +// These interfaces only work for whitelisted origins. +PROXIED_IFACE(PPB_TCPSERVERSOCKET_PRIVATE_INTERFACE_0_1, + PPB_TCPServerSocket_Private_0_1) +PROXIED_IFACE(PPB_TCPSERVERSOCKET_PRIVATE_INTERFACE_0_2, + PPB_TCPServerSocket_Private_0_2) +PROXIED_IFACE(PPB_TCPSOCKET_PRIVATE_INTERFACE_0_3, PPB_TCPSocket_Private_0_3) +PROXIED_IFACE(PPB_TCPSOCKET_PRIVATE_INTERFACE_0_4, PPB_TCPSocket_Private_0_4) +PROXIED_IFACE(PPB_TCPSOCKET_PRIVATE_INTERFACE_0_5, PPB_TCPSocket_Private_0_5) +PROXIED_IFACE(PPB_UDPSOCKET_PRIVATE_INTERFACE_0_2, PPB_UDPSocket_Private_0_2) +PROXIED_IFACE(PPB_UDPSOCKET_PRIVATE_INTERFACE_0_3, PPB_UDPSocket_Private_0_3) +PROXIED_IFACE(PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4, PPB_UDPSocket_Private_0_4) + #include "ppapi/thunk/interfaces_postamble.h"
diff --git a/remoting/ios/facade/ios_oauth_token_getter.mm b/remoting/ios/facade/ios_oauth_token_getter.mm index d9d542f..a07c0cc7 100644 --- a/remoting/ios/facade/ios_oauth_token_getter.mm +++ b/remoting/ios/facade/ios_oauth_token_getter.mm
@@ -46,9 +46,7 @@ } void IosOauthTokenGetter::InvalidateCache() { - // TODO(crbug.com/782071): Implement this once we make the caller invalidate - // the cache. - NOTIMPLEMENTED(); + [RemotingService.instance.authentication invalidateCache]; } base::WeakPtr<IosOauthTokenGetter> IosOauthTokenGetter::GetWeakPtr() {
diff --git a/remoting/ios/facade/remoting_authentication.h b/remoting/ios/facade/remoting_authentication.h index 92e0fc7..6ecd436 100644 --- a/remoting/ios/facade/remoting_authentication.h +++ b/remoting/ios/facade/remoting_authentication.h
@@ -32,6 +32,7 @@ // management and currently active user. It will make sure the user object is // saved to the keychain correctly and loaded on startup. It also is the entry // point for gaining access to an auth token for authrized calls. +// TODO(yuweih): Refactor and rewrite this class in C++. @protocol RemotingAuthentication<NSObject> // Fetches an Access Token and passes it back to the callback if the user is @@ -43,6 +44,9 @@ // Forget the current user. - (void)logout; +// Invalidates the cached access token. +- (void)invalidateCache; + // Returns the currently logged in user or nil. @property(strong, nonatomic, readonly) UserInfo* user;
diff --git a/remoting/ios/facade/remoting_oauth_authentication.mm b/remoting/ios/facade/remoting_oauth_authentication.mm index a33a7c02..f799c15 100644 --- a/remoting/ios/facade/remoting_oauth_authentication.mm +++ b/remoting/ios/facade/remoting_oauth_authentication.mm
@@ -185,6 +185,10 @@ [self setUser:nil]; } +- (void)invalidateCache { + _tokenGetter->InvalidateCache(); +} + #pragma mark - Persistence - (void)storeUserInfo:(UserInfo*)user {
diff --git a/sandbox/linux/services/libc_interceptor.cc b/sandbox/linux/services/libc_interceptor.cc index 55ab6954..50c8f96c 100644 --- a/sandbox/linux/services/libc_interceptor.cc +++ b/sandbox/linux/services/libc_interceptor.cc
@@ -200,7 +200,7 @@ reinterpret_cast<LocaltimeRFunction>(dlsym(RTLD_NEXT, "localtime64_r")); if (!g_libc_funcs->localtime || !g_libc_funcs->localtime_r) { - // http://code.google.com/p/chromium/issues/detail?id=16800 + // https://bugs.chromium.org/p/chromium/issues/detail?id=16800 // // Nvidia's libGL.so overrides dlsym for an unknown reason and replaces // it with a version which doesn't work. In this case we'll get a NULL @@ -208,7 +208,7 @@ LOG(ERROR) << "Your system is broken: dlsym doesn't work! This has been " "reported to be caused by Nvidia's libGL. You should expect" " time related functions to misbehave. " - "http://code.google.com/p/chromium/issues/detail?id=16800"; + "https://bugs.chromium.org/p/chromium/issues/detail?id=16800"; } if (!g_libc_funcs->localtime)
diff --git a/services/device/geolocation/OWNERS b/services/device/geolocation/OWNERS index 2ce1e4a..2596b2d 100644 --- a/services/device/geolocation/OWNERS +++ b/services/device/geolocation/OWNERS
@@ -1,6 +1,8 @@ mattreynolds@chromium.org + +# Original (legacy) owners. mcasas@chromium.org timvolodine@chromium.org +# COMPONENT: Blink>Geolocation # TEAM: device-dev@chromium.org -# COMPONENT: Blink>Location
diff --git a/services/device/hid/hid_service_linux.cc b/services/device/hid/hid_service_linux.cc index 7272f9e..25f48d7 100644 --- a/services/device/hid/hid_service_linux.cc +++ b/services/device/hid/hid_service_linux.cc
@@ -225,12 +225,12 @@ #if defined(OS_CHROMEOS) chromeos::PermissionBrokerClient::ErrorCallback error_callback = - base::Bind(&HidServiceLinux::OnPathOpenError, - params->device_info->device_node(), params->callback); + base::BindOnce(&HidServiceLinux::OnPathOpenError, + params->device_info->device_node(), params->callback); chromeos::PermissionBrokerClient::Get()->OpenPath( device_info->device_node(), - base::Bind(&HidServiceLinux::OnPathOpenComplete, base::Passed(¶ms)), - error_callback); + base::BindOnce(&HidServiceLinux::OnPathOpenComplete, std::move(params)), + std::move(error_callback)); #else scoped_refptr<base::SequencedTaskRunner> blocking_task_runner = params->blocking_task_runner;
diff --git a/services/device/public/cpp/test/BUILD.gn b/services/device/public/cpp/test/BUILD.gn index 9473041..adb8901 100644 --- a/services/device/public/cpp/test/BUILD.gn +++ b/services/device/public/cpp/test/BUILD.gn
@@ -8,6 +8,8 @@ sources = [ "fake_sensor_and_provider.cc", "fake_sensor_and_provider.h", + "fake_serial_port_manager.cc", + "fake_serial_port_manager.h", "scoped_geolocation_overrider.cc", "scoped_geolocation_overrider.h", "test_wake_lock_provider.cc",
diff --git a/services/device/public/cpp/test/fake_serial_port_manager.cc b/services/device/public/cpp/test/fake_serial_port_manager.cc new file mode 100644 index 0000000..519f482 --- /dev/null +++ b/services/device/public/cpp/test/fake_serial_port_manager.cc
@@ -0,0 +1,112 @@ +// Copyright 2019 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 "services/device/public/cpp/test/fake_serial_port_manager.h" + +#include <utility> +#include <vector> + +#include "base/callback.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/system/data_pipe.h" + +namespace device { + +namespace { + +class FakeSerialPort : public mojom::SerialPort { + public: + FakeSerialPort(mojom::SerialPortRequest request, + mojom::SerialPortConnectionWatcherPtr watcher) + : binding_(this, std::move(request)), watcher_(std::move(watcher)) { + binding_.set_connection_error_handler(base::BindOnce( + [](FakeSerialPort* self) { delete self; }, base::Unretained(this))); + watcher_.set_connection_error_handler(base::BindOnce( + [](FakeSerialPort* self) { delete self; }, base::Unretained(this))); + } + + ~FakeSerialPort() override = default; + + // mojom::SerialPort + void Open(mojom::SerialConnectionOptionsPtr options, + mojo::ScopedDataPipeConsumerHandle in_stream, + mojo::ScopedDataPipeProducerHandle out_stream, + mojom::SerialPortClientAssociatedPtrInfo client, + OpenCallback callback) override { + in_stream_ = std::move(in_stream); + out_stream_ = std::move(out_stream); + client_ = std::move(client); + std::move(callback).Run(true); + } + + void ClearSendError(mojo::ScopedDataPipeConsumerHandle consumer) override { + NOTREACHED(); + } + + void ClearReadError(mojo::ScopedDataPipeProducerHandle producer) override { + NOTREACHED(); + } + + void Flush(FlushCallback callback) override { NOTREACHED(); } + + void GetControlSignals(GetControlSignalsCallback callback) override { + NOTREACHED(); + } + + void SetControlSignals(mojom::SerialHostControlSignalsPtr signals, + SetControlSignalsCallback callback) override { + NOTREACHED(); + } + + void ConfigurePort(mojom::SerialConnectionOptionsPtr options, + ConfigurePortCallback callback) override { + NOTREACHED(); + } + + void GetPortInfo(GetPortInfoCallback callback) override { NOTREACHED(); } + + void SetBreak(SetBreakCallback callback) override { NOTREACHED(); } + + void ClearBreak(ClearBreakCallback callback) override { NOTREACHED(); } + + private: + mojo::Binding<mojom::SerialPort> binding_; + mojom::SerialPortConnectionWatcherPtr watcher_; + + // Mojo handles to keep open in order to simulate an active connection. + mojo::ScopedDataPipeConsumerHandle in_stream_; + mojo::ScopedDataPipeProducerHandle out_stream_; + mojom::SerialPortClientAssociatedPtrInfo client_; + + DISALLOW_COPY_AND_ASSIGN(FakeSerialPort); +}; + +} // namespace + +FakeSerialPortManager::FakeSerialPortManager() = default; + +FakeSerialPortManager::~FakeSerialPortManager() = default; + +void FakeSerialPortManager::AddPort(mojom::SerialPortInfoPtr port) { + base::UnguessableToken token = port->token; + ports_[token] = std::move(port); +} + +void FakeSerialPortManager::GetDevices(GetDevicesCallback callback) { + std::vector<mojom::SerialPortInfoPtr> ports; + for (const auto& map_entry : ports_) + ports.push_back(map_entry.second.Clone()); + std::move(callback).Run(std::move(ports)); +} + +void FakeSerialPortManager::GetPort( + const base::UnguessableToken& token, + mojom::SerialPortRequest request, + mojom::SerialPortConnectionWatcherPtr watcher) { + // The new FakeSerialPort instance is owned by the |request| and |watcher| + // pipes. + new FakeSerialPort(std::move(request), std::move(watcher)); +} + +} // namespace device
diff --git a/services/device/public/cpp/test/fake_serial_port_manager.h b/services/device/public/cpp/test/fake_serial_port_manager.h new file mode 100644 index 0000000..e34afd3 --- /dev/null +++ b/services/device/public/cpp/test/fake_serial_port_manager.h
@@ -0,0 +1,37 @@ +// Copyright 2019 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 SERVICES_DEVICE_PUBLIC_CPP_TEST_FAKE_SERIAL_PORT_MANAGER_H_ +#define SERVICES_DEVICE_PUBLIC_CPP_TEST_FAKE_SERIAL_PORT_MANAGER_H_ + +#include <map> + +#include "base/macros.h" +#include "base/unguessable_token.h" +#include "services/device/public/mojom/serial.mojom.h" + +namespace device { + +class FakeSerialPortManager : public mojom::SerialPortManager { + public: + FakeSerialPortManager(); + ~FakeSerialPortManager() override; + + void AddPort(mojom::SerialPortInfoPtr port); + + // mojom::SerialPortManager + void GetDevices(GetDevicesCallback callback) override; + void GetPort(const base::UnguessableToken& token, + mojom::SerialPortRequest request, + mojom::SerialPortConnectionWatcherPtr watcher) override; + + private: + std::map<base::UnguessableToken, mojom::SerialPortInfoPtr> ports_; + + DISALLOW_COPY_AND_ASSIGN(FakeSerialPortManager); +}; + +} // namespace device + +#endif // SERVICES_DEVICE_PUBLIC_CPP_TEST_FAKE_SERIAL_PORT_MANAGER_H_
diff --git a/services/device/public/mojom/serial.mojom b/services/device/public/mojom/serial.mojom index 4fde005..231e171 100644 --- a/services/device/public/mojom/serial.mojom +++ b/services/device/public/mojom/serial.mojom
@@ -91,7 +91,13 @@ // Discovers and enumerates serial devices available to the host. interface SerialPortManager { GetDevices() => (array<SerialPortInfo> devices); - GetPort(mojo_base.mojom.UnguessableToken token, SerialPort& port_request); + + // Creates a SerialPort instance attached to the port represented by |token|. + // When the pipe passed in |port_request| is closed the optional pipe passed + // in |watcher| will also be closed. + GetPort(mojo_base.mojom.UnguessableToken token, + SerialPort& port_request, + SerialPortConnectionWatcher? watcher); }; // Performs asynchronous I/O on serial devices. @@ -140,3 +146,6 @@ OnReadError(SerialReceiveError error); OnSendError(SerialSendError error); }; + +interface SerialPortConnectionWatcher { +};
diff --git a/services/device/serial/serial_port_impl.cc b/services/device/serial/serial_port_impl.cc index 5cec6719..19b5992 100644 --- a/services/device/serial/serial_port_impl.cc +++ b/services/device/serial/serial_port_impl.cc
@@ -20,19 +20,31 @@ void SerialPortImpl::Create( const base::FilePath& path, mojom::SerialPortRequest request, + mojom::SerialPortConnectionWatcherPtrInfo watcher, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { - mojo::MakeStrongBinding( - std::make_unique<SerialPortImpl>(path, ui_task_runner), - std::move(request)); + // This SerialPortImpl is owned by |request| and |watcher|. + new SerialPortImpl(path, std::move(request), std::move(watcher), + std::move(ui_task_runner)); } SerialPortImpl::SerialPortImpl( const base::FilePath& path, + mojom::SerialPortRequest request, + mojom::SerialPortConnectionWatcherPtrInfo watcher, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) - : io_handler_(device::SerialIoHandler::Create(path, ui_task_runner)), + : binding_(this, std::move(request)), + io_handler_(device::SerialIoHandler::Create(path, ui_task_runner)), + watcher_(std::move(watcher)), in_stream_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL), out_stream_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL), - weak_factory_(this) {} + weak_factory_(this) { + binding_.set_connection_error_handler(base::BindOnce( + [](SerialPortImpl* self) { delete self; }, base::Unretained(this))); + if (watcher_.is_bound()) { + watcher_.set_connection_error_handler(base::BindOnce( + [](SerialPortImpl* self) { delete self; }, base::Unretained(this))); + } +} SerialPortImpl::~SerialPortImpl() = default;
diff --git a/services/device/serial/serial_port_impl.h b/services/device/serial/serial_port_impl.h index c75decd2..7c0d729 100644 --- a/services/device/serial/serial_port_impl.h +++ b/services/device/serial/serial_port_impl.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/system/data_pipe.h" #include "mojo/public/cpp/system/simple_watcher.h" #include "services/device/public/mojom/serial.mojom.h" @@ -32,13 +33,16 @@ static void Create( const base::FilePath& path, mojom::SerialPortRequest request, + mojom::SerialPortConnectionWatcherPtrInfo watcher, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); + private: SerialPortImpl(const base::FilePath& path, + mojom::SerialPortRequest request, + mojom::SerialPortConnectionWatcherPtrInfo watcher, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); ~SerialPortImpl() override; - private: // mojom::SerialPort methods: void Open(mojom::SerialConnectionOptionsPtr options, mojo::ScopedDataPipeConsumerHandle in_stream, @@ -66,8 +70,16 @@ const mojo::HandleSignalsState& state); void WriteToOutStream(uint32_t bytes_read, mojom::SerialReceiveError error); + mojo::Binding<mojom::SerialPort> binding_; + + // Underlying connection to the serial port. scoped_refptr<SerialIoHandler> io_handler_; + + // Client interfaces. mojom::SerialPortClientAssociatedPtr client_; + mojom::SerialPortConnectionWatcherPtr watcher_; + + // Data pipes for input and output. mojo::ScopedDataPipeConsumerHandle in_stream_; mojo::SimpleWatcher in_stream_watcher_; mojo::ScopedDataPipeProducerHandle out_stream_;
diff --git a/services/device/serial/serial_port_impl_unittest.cc b/services/device/serial/serial_port_impl_unittest.cc index 2e4405c7..51e62ae 100644 --- a/services/device/serial/serial_port_impl_unittest.cc +++ b/services/device/serial/serial_port_impl_unittest.cc
@@ -5,9 +5,9 @@ #include "services/device/serial/serial_port_impl.h" #include "base/macros.h" -#include "mojo/public/cpp/bindings/interface_ptr.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "mojo/public/cpp/bindings/strong_binding.h" #include "services/device/device_service_test_base.h" -#include "services/device/public/mojom/constants.mojom.h" #include "services/device/public/mojom/serial.mojom.h" namespace device { @@ -20,25 +20,55 @@ ~SerialPortImplTest() override = default; protected: - void SetUp() override { - DeviceServiceTestBase::SetUp(); - connector()->BindInterface(mojom::kServiceName, &port_manager_); - } - - void TearDown() override { port_manager_.reset(); } - - mojom::SerialPortManagerPtr port_manager_; DISALLOW_COPY_AND_ASSIGN(SerialPortImplTest); }; -// This is to simply test that on Linux/Mac/Windows a client can connect to -// Device Service and bind the serial SerialPort interface correctly. -// TODO(leonhsl): figure out how to add more robust tests. -TEST_F(SerialPortImplTest, SimpleConnectTest) { +TEST_F(SerialPortImplTest, WatcherClosedWhenPortClosed) { mojom::SerialPortPtr serial_port; - port_manager_->GetPort(base::UnguessableToken::Create(), - mojo::MakeRequest(&serial_port)); + mojom::SerialPortConnectionWatcherPtrInfo watcher_ptr; + auto watcher_binding = mojo::MakeStrongBinding( + std::make_unique<mojom::SerialPortConnectionWatcher>(), + mojo::MakeRequest(&watcher_ptr)); + SerialPortImpl::Create(base::FilePath(), mojo::MakeRequest(&serial_port), + std::move(watcher_ptr), + base::ThreadTaskRunnerHandle::Get()); + + // To start with both the serial port connection and the connection watcher + // connection should remain open. serial_port.FlushForTesting(); + EXPECT_FALSE(serial_port.encountered_error()); + watcher_binding->FlushForTesting(); + EXPECT_TRUE(watcher_binding); + + // When the serial port connection is closed the watcher connection should be + // closed. + serial_port.reset(); + watcher_binding->FlushForTesting(); + EXPECT_FALSE(watcher_binding); +} + +TEST_F(SerialPortImplTest, PortClosedWhenWatcherClosed) { + mojom::SerialPortPtr serial_port; + mojom::SerialPortConnectionWatcherPtrInfo watcher_ptr; + auto watcher_binding = mojo::MakeStrongBinding( + std::make_unique<mojom::SerialPortConnectionWatcher>(), + mojo::MakeRequest(&watcher_ptr)); + SerialPortImpl::Create(base::FilePath(), mojo::MakeRequest(&serial_port), + std::move(watcher_ptr), + base::ThreadTaskRunnerHandle::Get()); + + // To start with both the serial port connection and the connection watcher + // connection should remain open. + serial_port.FlushForTesting(); + EXPECT_FALSE(serial_port.encountered_error()); + watcher_binding->FlushForTesting(); + EXPECT_TRUE(watcher_binding); + + // When the watcher connection is closed, for safety, the serial port + // connection should also be closed. + watcher_binding->Close(); + serial_port.FlushForTesting(); + EXPECT_TRUE(serial_port.encountered_error()); } } // namespace
diff --git a/services/device/serial/serial_port_manager_impl.cc b/services/device/serial/serial_port_manager_impl.cc index 6a0030d..b63d273 100644 --- a/services/device/serial/serial_port_manager_impl.cc +++ b/services/device/serial/serial_port_manager_impl.cc
@@ -39,15 +39,18 @@ std::move(callback).Run(enumerator_->GetDevices()); } -void SerialPortManagerImpl::GetPort(const base::UnguessableToken& token, - mojom::SerialPortRequest request) { +void SerialPortManagerImpl::GetPort( + const base::UnguessableToken& token, + mojom::SerialPortRequest request, + mojom::SerialPortConnectionWatcherPtr watcher) { if (!enumerator_) enumerator_ = SerialDeviceEnumerator::Create(); base::Optional<base::FilePath> path = enumerator_->GetPathFromToken(token); if (path) { io_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&SerialPortImpl::Create, *path, - std::move(request), ui_task_runner_)); + FROM_HERE, + base::BindOnce(&SerialPortImpl::Create, *path, std::move(request), + watcher.PassInterface(), ui_task_runner_)); } }
diff --git a/services/device/serial/serial_port_manager_impl.h b/services/device/serial/serial_port_manager_impl.h index 7013395..a4ddaf6 100644 --- a/services/device/serial/serial_port_manager_impl.h +++ b/services/device/serial/serial_port_manager_impl.h
@@ -39,7 +39,8 @@ // mojom::SerialPortManager methods: void GetDevices(GetDevicesCallback callback) override; void GetPort(const base::UnguessableToken& token, - mojom::SerialPortRequest request) override; + mojom::SerialPortRequest request, + mojom::SerialPortConnectionWatcherPtr watcher) override; std::unique_ptr<SerialDeviceEnumerator> enumerator_;
diff --git a/services/device/serial/serial_port_manager_impl_unittest.cc b/services/device/serial/serial_port_manager_impl_unittest.cc index c41ebc9..3714950f 100644 --- a/services/device/serial/serial_port_manager_impl_unittest.cc +++ b/services/device/serial/serial_port_manager_impl_unittest.cc
@@ -13,9 +13,11 @@ #include "base/macros.h" #include "base/message_loop/message_loop.h" #include "base/task/post_task.h" +#include "base/test/bind_test_util.h" #include "base/test/scoped_task_environment.h" #include "base/threading/thread.h" #include "mojo/public/cpp/bindings/interface_ptr.h" +#include "mojo/public/cpp/bindings/interface_request.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "services/device/device_service_test_base.h" #include "services/device/public/mojom/constants.mojom.h" @@ -43,46 +45,6 @@ mojo::MakeStrongBinding(std::move(manager), std::move(request)); } -void ExpectDevicesAndThen(const std::set<base::FilePath>& expected_paths, - base::OnceClosure continuation, - std::vector<mojom::SerialPortInfoPtr> results) { - EXPECT_EQ(expected_paths.size(), results.size()); - std::set<base::FilePath> actual_paths; - for (size_t i = 0; i < results.size(); ++i) - actual_paths.insert(results[i]->path); - EXPECT_EQ(expected_paths, actual_paths); - std::move(continuation).Run(); -} - -void OnGotDevicesAndGetPort(mojom::SerialPortManagerPtr port_manager, - base::OnceClosure continuation, - std::vector<mojom::SerialPortInfoPtr> results) { - EXPECT_GT(results.size(), 0u); - - mojom::SerialPortPtr serial_port; - port_manager->GetPort(results[0]->token, mojo::MakeRequest(&serial_port)); - // Send a message on the pipe and wait for the response to make sure that the - // interface request was bound successfully. - serial_port.FlushForTesting(); - EXPECT_FALSE(serial_port.encountered_error()); - std::move(continuation).Run(); -} - -void OnGotDevicesForSimpleConnect( - mojom::SerialPortManagerPtr port_manager, - base::OnceClosure continuation, - std::vector<mojom::SerialPortInfoPtr> results) { - for (auto& device : results) { - mojom::SerialPortPtr serial_port; - port_manager->GetPort(device->token, mojo::MakeRequest(&serial_port)); - // Send a message on the pipe and wait for the response to make sure that - // the interface request was bound successfully. - serial_port.FlushForTesting(); - EXPECT_FALSE(serial_port.encountered_error()); - } - std::move(continuation).Run(); -} - } // namespace class SerialPortManagerImplTest : public DeviceServiceTestBase { @@ -110,22 +72,38 @@ connector()->BindInterface(mojom::kServiceName, &port_manager); base::RunLoop loop; - auto* manager = port_manager.get(); - manager->GetDevices(base::BindOnce(&OnGotDevicesForSimpleConnect, - std::move(port_manager), - loop.QuitClosure())); + port_manager->GetDevices(base::BindLambdaForTesting( + [&](std::vector<mojom::SerialPortInfoPtr> results) { + for (auto& device : results) { + mojom::SerialPortPtr serial_port; + port_manager->GetPort(device->token, mojo::MakeRequest(&serial_port), + /*watcher=*/nullptr); + // Send a message on the pipe and wait for the response to make sure + // that the interface request was bound successfully. + serial_port.FlushForTesting(); + EXPECT_FALSE(serial_port.encountered_error()); + } + loop.Quit(); + })); loop.Run(); } TEST_F(SerialPortManagerImplTest, GetDevices) { mojom::SerialPortManagerPtr port_manager; BindSerialPortManager(mojo::MakeRequest(&port_manager)); - std::set<base::FilePath> expected_paths = {kFakeDevicePath1, - kFakeDevicePath2}; + const std::set<base::FilePath> expected_paths = {kFakeDevicePath1, + kFakeDevicePath2}; base::RunLoop loop; - port_manager->GetDevices(base::BindOnce(&ExpectDevicesAndThen, expected_paths, - loop.QuitClosure())); + port_manager->GetDevices(base::BindLambdaForTesting( + [&](std::vector<mojom::SerialPortInfoPtr> results) { + EXPECT_EQ(expected_paths.size(), results.size()); + std::set<base::FilePath> actual_paths; + for (size_t i = 0; i < results.size(); ++i) + actual_paths.insert(results[i]->path); + EXPECT_EQ(expected_paths, actual_paths); + loop.Quit(); + })); loop.Run(); } @@ -134,9 +112,20 @@ BindSerialPortManager(mojo::MakeRequest(&port_manager)); base::RunLoop loop; - auto* manager = port_manager.get(); - manager->GetDevices(base::BindOnce( - &OnGotDevicesAndGetPort, std::move(port_manager), loop.QuitClosure())); + port_manager->GetDevices(base::BindLambdaForTesting( + [&](std::vector<mojom::SerialPortInfoPtr> results) { + EXPECT_GT(results.size(), 0u); + + mojom::SerialPortPtr serial_port; + port_manager->GetPort(results[0]->token, + mojo::MakeRequest(&serial_port), + /*watcher=*/nullptr); + // Send a message on the pipe and wait for the response to make sure + // that the interface request was bound successfully. + serial_port.FlushForTesting(); + EXPECT_FALSE(serial_port.encountered_error()); + loop.Quit(); + })); loop.Run(); }
diff --git a/services/identity/public/cpp/identity_manager.cc b/services/identity/public/cpp/identity_manager.cc index 7286ab4..ad20c7df3 100644 --- a/services/identity/public/cpp/identity_manager.cc +++ b/services/identity/public/cpp/identity_manager.cc
@@ -40,19 +40,19 @@ } // namespace IdentityManager::IdentityManager( - std::unique_ptr<ProfileOAuth2TokenService> token_service, std::unique_ptr<GaiaCookieManagerService> gaia_cookie_manager_service, std::unique_ptr<SigninManagerBase> signin_manager, std::unique_ptr<AccountFetcherService> account_fetcher_service, + ProfileOAuth2TokenService* token_service, AccountTrackerService* account_tracker_service, std::unique_ptr<PrimaryAccountMutator> primary_account_mutator, std::unique_ptr<AccountsMutator> accounts_mutator, std::unique_ptr<AccountsCookieMutator> accounts_cookie_mutator, std::unique_ptr<DiagnosticsProvider> diagnostics_provider) - : token_service_(std::move(token_service)), - gaia_cookie_manager_service_(std::move(gaia_cookie_manager_service)), + : gaia_cookie_manager_service_(std::move(gaia_cookie_manager_service)), signin_manager_(std::move(signin_manager)), account_fetcher_service_(std::move(account_fetcher_service)), + token_service_(token_service), account_tracker_service_(account_tracker_service), primary_account_mutator_(std::move(primary_account_mutator)), accounts_mutator_(std::move(accounts_mutator)), @@ -209,7 +209,7 @@ AccessTokenFetcher::TokenCallback callback, AccessTokenFetcher::Mode mode) { return std::make_unique<AccessTokenFetcher>(account_id, oauth_consumer_name, - token_service_.get(), scopes, + token_service_, scopes, std::move(callback), mode); } @@ -222,7 +222,7 @@ AccessTokenFetcher::TokenCallback callback, AccessTokenFetcher::Mode mode) { return std::make_unique<AccessTokenFetcher>( - account_id, oauth_consumer_name, token_service_.get(), url_loader_factory, + account_id, oauth_consumer_name, token_service_, url_loader_factory, scopes, std::move(callback), mode); } @@ -236,8 +236,8 @@ AccessTokenFetcher::TokenCallback callback, AccessTokenFetcher::Mode mode) { return std::make_unique<AccessTokenFetcher>( - account_id, client_id, client_secret, oauth_consumer_name, - token_service_.get(), scopes, std::move(callback), mode); + account_id, client_id, client_secret, oauth_consumer_name, token_service_, + scopes, std::move(callback), mode); } void IdentityManager::RemoveAccessTokenFromCache( @@ -261,7 +261,7 @@ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, bool bount_to_channel_id) { return std::make_unique<signin::UbertokenFetcherImpl>( - account_id, token_service_.get(), std::move(callback), source, + account_id, token_service_, std::move(callback), source, url_loader_factory, bount_to_channel_id); } @@ -277,7 +277,6 @@ // static void IdentityManager::RegisterProfilePrefs(PrefRegistrySimple* registry) { - ProfileOAuth2TokenService::RegisterProfilePrefs(registry); SigninManagerBase::RegisterProfilePrefs(registry); AccountFetcherService::RegisterPrefs(registry); } @@ -396,7 +395,6 @@ void IdentityManager::Shutdown() { account_fetcher_service_->Shutdown(); gaia_cookie_manager_service_->Shutdown(); - token_service_->Shutdown(); } SigninManagerBase* IdentityManager::GetSigninManager() { @@ -404,7 +402,7 @@ } ProfileOAuth2TokenService* IdentityManager::GetTokenService() { - return token_service_.get(); + return token_service_; } AccountTrackerService* IdentityManager::GetAccountTrackerService() {
diff --git a/services/identity/public/cpp/identity_manager.h b/services/identity/public/cpp/identity_manager.h index 1d13fe0..5b54669 100644 --- a/services/identity/public/cpp/identity_manager.h +++ b/services/identity/public/cpp/identity_manager.h
@@ -44,7 +44,6 @@ class AccountsMutator; class AccountsCookieMutator; -class IdentityManagerTest; class IdentityTestEnvironment; class DiagnosticsProvider; class PrimaryAccountMutator; @@ -194,10 +193,10 @@ }; IdentityManager( - std::unique_ptr<ProfileOAuth2TokenService> token_service, std::unique_ptr<GaiaCookieManagerService> gaia_cookie_manager_service, std::unique_ptr<SigninManagerBase> signin_manager, std::unique_ptr<AccountFetcherService> account_fetcher_service, + ProfileOAuth2TokenService* token_service, AccountTrackerService* account_tracker_service, std::unique_ptr<PrimaryAccountMutator> primary_account_mutator, std::unique_ptr<AccountsMutator> accounts_mutator, @@ -541,7 +540,6 @@ // IdentityManagerTest reaches into IdentityManager internals in // order to drive its behavior. // TODO(https://crbug.com/943135): Find a better way to accomplish this. - friend IdentityManagerTest; FRIEND_TEST_ALL_PREFIXES(IdentityManagerTest, RemoveAccessTokenFromCache); FRIEND_TEST_ALL_PREFIXES(IdentityManagerTest, CreateAccessTokenFetcherWithCustomURLLoaderFactory); @@ -646,12 +644,11 @@ // these classes in the IdentityManager implementation, as all such // synchronous access will become impossible when IdentityManager is // backed by the Identity Service. - std::unique_ptr<ProfileOAuth2TokenService> token_service_; std::unique_ptr<GaiaCookieManagerService> gaia_cookie_manager_service_; std::unique_ptr<SigninManagerBase> signin_manager_; std::unique_ptr<AccountFetcherService> account_fetcher_service_; + ProfileOAuth2TokenService* token_service_; AccountTrackerService* account_tracker_service_; - // PrimaryAccountMutator instance. May be null if mutation of the primary // account state is not supported on the current platform. std::unique_ptr<PrimaryAccountMutator> primary_account_mutator_;
diff --git a/services/identity/public/cpp/identity_manager_unittest.cc b/services/identity/public/cpp/identity_manager_unittest.cc index 4c65af61..43ebf0c 100644 --- a/services/identity/public/cpp/identity_manager_unittest.cc +++ b/services/identity/public/cpp/identity_manager_unittest.cc
@@ -110,6 +110,50 @@ base::OnceClosure on_access_token_invalidated_callback_; }; +// Class that observes updates from ProfileOAuth2TokenService and and verifies +// thereby that IdentityManager receives updates before direct observers of +// ProfileOAuth2TokenService. +class TestTokenServiceObserver : public OAuth2TokenService::Observer, + public identity::IdentityManager::Observer { + public: + explicit TestTokenServiceObserver(OAuth2TokenService* token_service) + : token_service_(token_service) { + token_service_->AddObserver(this); + } + ~TestTokenServiceObserver() override { token_service_->RemoveObserver(this); } + + void set_identity_manager(IdentityManager* identity_manager) { + identity_manager_ = identity_manager; + } + + void set_on_refresh_token_available_callback(base::OnceClosure callback) { + on_refresh_token_available_callback_ = std::move(callback); + } + void set_on_refresh_token_revoked_callback(base::OnceClosure callback) { + on_refresh_token_revoked_callback_ = std::move(callback); + } + + private: + // OAuth2TokenService::Observer: + void OnRefreshTokenAvailable(const std::string& account_id) override { + // IdentityManager should have already updated its state. + EXPECT_TRUE(identity_manager_->HasAccountWithRefreshToken(account_id)); + if (on_refresh_token_available_callback_) + std::move(on_refresh_token_available_callback_).Run(); + } + void OnRefreshTokenRevoked(const std::string& account_id) override { + // IdentityManager should have already updated its state. + EXPECT_FALSE(identity_manager_->HasAccountWithRefreshToken(account_id)); + if (on_refresh_token_revoked_callback_) + std::move(on_refresh_token_revoked_callback_).Run(); + } + + OAuth2TokenService* token_service_; + IdentityManager* identity_manager_; + base::OnceClosure on_refresh_token_available_callback_; + base::OnceClosure on_refresh_token_revoked_callback_; +}; + class TestIdentityManagerDiagnosticsObserver : IdentityManager::DiagnosticsObserver { public: @@ -210,8 +254,10 @@ class IdentityManagerTest : public testing::Test { protected: - IdentityManagerTest() : signin_client_(&pref_service_) { + IdentityManagerTest() + : signin_client_(&pref_service_), token_service_(&pref_service_) { AccountTrackerService::RegisterPrefs(pref_service_.registry()); + ProfileOAuth2TokenService::RegisterProfilePrefs(pref_service_.registry()); IdentityManager::RegisterProfilePrefs(pref_service_.registry()); IdentityManager::RegisterLocalStatePrefs(pref_service_.registry()); @@ -223,6 +269,7 @@ ~IdentityManagerTest() override { identity_manager_->Shutdown(); signin_client_.Shutdown(); + token_service_.Shutdown(); account_tracker_.Shutdown(); } @@ -245,8 +292,7 @@ AccountTrackerService* account_tracker() { return &account_tracker_; } CustomFakeProfileOAuth2TokenService* token_service() { - return static_cast<CustomFakeProfileOAuth2TokenService*>( - identity_manager()->GetTokenService()); + return &token_service_; } // See RecreateIdentityManager. @@ -279,12 +325,9 @@ } identity_manager_.reset(); - auto token_service = - std::make_unique<CustomFakeProfileOAuth2TokenService>(&pref_service_); - auto gaia_cookie_manager_service = std::make_unique<GaiaCookieManagerService>( - token_service.get(), &signin_client_, + &token_service_, &signin_client_, base::BindRepeating( [](network::TestURLLoaderFactory* test_url_loader_factory) -> scoped_refptr<network::SharedURLLoaderFactory> { @@ -294,17 +337,17 @@ auto account_fetcher_service = std::make_unique<AccountFetcherService>(); account_fetcher_service->Initialize( - &signin_client_, token_service.get(), &account_tracker_, + &signin_client_, &token_service_, &account_tracker_, std::make_unique<image_fetcher::FakeImageDecoder>()); #if defined(OS_CHROMEOS) DCHECK_EQ(account_consistency, signin::AccountConsistencyMethod::kDisabled) << "AccountConsistency is not used by SigninManagerBase"; auto signin_manager = std::make_unique<SigninManagerBase>( - &signin_client_, token_service.get(), &account_tracker_); + &signin_client_, &token_service_, &account_tracker_); #else auto signin_manager = std::make_unique<SigninManager>( - &signin_client_, token_service.get(), &account_tracker_, + &signin_client_, &token_service_, &account_tracker_, gaia_cookie_manager_service.get(), account_consistency); #endif @@ -324,12 +367,12 @@ gaia_cookie_manager_service.get()); auto diagnostics_provider = std::make_unique<DiagnosticsProviderImpl>( - token_service.get(), gaia_cookie_manager_service.get()); + &token_service_, gaia_cookie_manager_service.get()); identity_manager_.reset(new IdentityManager( - std::move(token_service), std::move(gaia_cookie_manager_service), - std::move(signin_manager), std::move(account_fetcher_service), - &account_tracker_, nullptr, nullptr, std::move(accounts_cookie_mutator), + std::move(gaia_cookie_manager_service), std::move(signin_manager), + std::move(account_fetcher_service), &token_service_, &account_tracker_, + nullptr, nullptr, std::move(accounts_cookie_mutator), std::move(diagnostics_provider))); identity_manager_observer_.reset( new TestIdentityManagerObserver(identity_manager_.get())); @@ -373,6 +416,7 @@ sync_preferences::TestingPrefServiceSyncable pref_service_; AccountTrackerService account_tracker_; TestSigninClient signin_client_; + CustomFakeProfileOAuth2TokenService token_service_; network::TestURLLoaderFactory test_url_loader_factory_; std::unique_ptr<IdentityManager> identity_manager_; std::unique_ptr<TestIdentityManagerObserver> identity_manager_observer_; @@ -551,7 +595,35 @@ EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken()); } -TEST_F(IdentityManagerTest, QueryingOfRefreshTokensReflectsEmptyInitialState) { +TEST_F(IdentityManagerTest, GetAccountsReflectsNonemptyInitialState) { + EXPECT_TRUE(identity_manager()->GetAccountsWithRefreshTokens().empty()); + + // Add a refresh token for the primary account and sanity-check that it shows + // up in GetAccountsWithRefreshTokens(). + SetRefreshTokenForPrimaryAccount(identity_manager()); + + std::vector<AccountInfo> accounts_after_update = + identity_manager()->GetAccountsWithRefreshTokens(); + + EXPECT_EQ(1u, accounts_after_update.size()); + EXPECT_EQ(accounts_after_update[0].account_id, primary_account_id()); + EXPECT_EQ(accounts_after_update[0].gaia, kTestGaiaId); + EXPECT_EQ(accounts_after_update[0].email, kTestEmail); + + // Recreate the IdentityManager and check that the newly-created instance + // reflects the current state. + RecreateIdentityManager(); + + std::vector<AccountInfo> accounts_after_recreation = + identity_manager()->GetAccountsWithRefreshTokens(); + EXPECT_EQ(1u, accounts_after_recreation.size()); + EXPECT_EQ(accounts_after_recreation[0].account_id, primary_account_id()); + EXPECT_EQ(accounts_after_recreation[0].gaia, kTestGaiaId); + EXPECT_EQ(accounts_after_recreation[0].email, kTestEmail); +} + +TEST_F(IdentityManagerTest, + QueryingOfRefreshTokensReflectsNonemptyInitialState) { CoreAccountInfo account_info = identity_manager()->GetPrimaryAccountInfo(); std::string account_id = account_info.account_id; @@ -564,6 +636,15 @@ EXPECT_TRUE( identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken()); + + // Recreate the IdentityManager and check that the newly-created instance + // reflects the current state. + RecreateIdentityManager(signin::AccountConsistencyMethod::kDisabled, + SigninManagerSetup::kWithAuthenticatedAccout); + + EXPECT_TRUE( + identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); + EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken()); } TEST_F(IdentityManagerTest, GetAccountsInteractionWithSecondaryAccounts) { @@ -1462,6 +1543,63 @@ identity_manager_observer()->AccountIdFromRefreshTokenRemovedCallback()); } +TEST_F( + IdentityManagerTest, + IdentityManagerGivesConsistentValuesFromTokenServiceObserverNotificationOfTokenUpdate) { + base::RunLoop run_loop; + TestTokenServiceObserver token_service_observer(token_service()); + token_service_observer.set_on_refresh_token_available_callback( + run_loop.QuitClosure()); + + // NOTE: For this test to be meaningful, TestTokenServiceObserver + // needs to be created before the IdentityManager instance that it's + // interacting with. Otherwise, even an implementation where they're + // both TokenService::Observers would work as IdentityManager would + // get notified first during the observer callbacks. + RecreateIdentityManager(signin::AccountConsistencyMethod::kDisabled, + SigninManagerSetup::kWithAuthenticatedAccout); + EXPECT_TRUE(identity_manager()->GetAccountsWithRefreshTokens().empty()); + token_service_observer.set_identity_manager(identity_manager()); + + // When the observer receives the callback directly from the token service, + // IdentityManager should have already received the event and forwarded it on + // to its own observers. This is checked internally by + // TestTokenServiceObserver. + token_service()->UpdateCredentials(primary_account_id(), "refresh_token"); + run_loop.Run(); +} + +TEST_F( + IdentityManagerTest, + IdentityManagerGivesConsistentValuesFromTokenServiceObserverNotificationOfTokenRemoval) { + base::RunLoop run_loop; + TestTokenServiceObserver token_service_observer(token_service()); + token_service_observer.set_on_refresh_token_available_callback( + run_loop.QuitClosure()); + + // NOTE: For this test to be meaningful, TestTokenServiceObserver + // needs to be created before the IdentityManager instance that it's + // interacting with. Otherwise, even an implementation where they're + // both TokenService::Observers would work as IdentityManager would + // get notified first during the observer callbacks. + RecreateIdentityManager(signin::AccountConsistencyMethod::kDisabled, + SigninManagerSetup::kWithAuthenticatedAccout); + token_service_observer.set_identity_manager(identity_manager()); + + token_service()->UpdateCredentials(primary_account_id(), "refresh_token"); + run_loop.Run(); + + // When the observer receives the callback directly from the token service, + // IdentityManager should have already received the event and forwarded it on + // to its own observers. This is checked internally by + // TestTokenServiceObserver. + base::RunLoop run_loop2; + token_service_observer.set_on_refresh_token_revoked_callback( + run_loop2.QuitClosure()); + token_service()->RevokeCredentials(primary_account_id()); + run_loop2.Run(); +} + TEST_F(IdentityManagerTest, IdentityManagerGetsTokensLoadedEvent) { base::RunLoop run_loop; identity_manager_observer()->SetOnRefreshTokensLoadedCallback(
diff --git a/services/identity/public/cpp/identity_test_environment.cc b/services/identity/public/cpp/identity_test_environment.cc index 1431fe3..ed0a235 100644 --- a/services/identity/public/cpp/identity_test_environment.cc +++ b/services/identity/public/cpp/identity_test_environment.cc
@@ -96,30 +96,6 @@ return raw_signin_client_ ? raw_signin_client_ : owned_signin_client_.get(); } -TestIdentityManagerWrapper::TestIdentityManagerWrapper( - AccountTrackerService* account_tracker_service, - std::unique_ptr<ProfileOAuth2TokenService> token_service, - std::unique_ptr<GaiaCookieManagerService> gaia_cookie_manager_service, - std::unique_ptr<SigninManagerBase> signin_manager, - std::unique_ptr<AccountFetcherService> account_fetcher_service, - std::unique_ptr<identity::PrimaryAccountMutator> primary_account_mutator, - std::unique_ptr<identity::AccountsMutator> accounts_mutator, - std::unique_ptr<identity::AccountsCookieMutator> accounts_cookie_mutator, - std::unique_ptr<identity::DiagnosticsProvider> diagnostics_provider) - : identity::IdentityManager(std::move(token_service), - std::move(gaia_cookie_manager_service), - std::move(signin_manager), - std::move(account_fetcher_service), - account_tracker_service, - std::move(primary_account_mutator), - std::move(accounts_mutator), - std::move(accounts_cookie_mutator), - std::move(diagnostics_provider)) {} - -void TestIdentityManagerWrapper::Shutdown() { - IdentityManager::Shutdown(); -} - IdentityTestEnvironment::IdentityTestEnvironment( network::TestURLLoaderFactory* test_url_loader_factory, sync_preferences::TestingPrefServiceSyncable* pref_service, @@ -164,18 +140,18 @@ dependencies_owner_->pref_service(); AccountTrackerService::RegisterPrefs(test_pref_service->registry()); + ProfileOAuth2TokenService::RegisterProfilePrefs( + test_pref_service->registry()); - auto token_service = + owned_token_service_ = std::make_unique<FakeProfileOAuth2TokenService>(test_pref_service); owned_account_tracker_service_ = std::make_unique<AccountTrackerService>(); owned_account_tracker_service_->Initialize(test_pref_service, base::FilePath()); - IdentityManager::RegisterProfilePrefs(test_pref_service->registry()); - IdentityManager::RegisterLocalStatePrefs(test_pref_service->registry()); owned_identity_manager_ = BuildIdentityManagerForTests( - test_signin_client, test_pref_service, std::move(token_service), + test_signin_client, test_pref_service, owned_token_service_.get(), owned_account_tracker_service_.get(), account_consistency, test_url_loader_factory); @@ -183,35 +159,38 @@ } // static -std::unique_ptr<TestIdentityManagerWrapper> +std::unique_ptr<IdentityManager> IdentityTestEnvironment::BuildIdentityManagerForTests( SigninClient* signin_client, - PrefService* pref_service, - std::unique_ptr<FakeProfileOAuth2TokenService> token_service, + sync_preferences::TestingPrefServiceSyncable* test_pref_service, + FakeProfileOAuth2TokenService* token_service, AccountTrackerService* account_tracker_service, signin::AccountConsistencyMethod account_consistency, network::TestURLLoaderFactory* test_url_loader_factory) { + IdentityManager::RegisterProfilePrefs(test_pref_service->registry()); + IdentityManager::RegisterLocalStatePrefs(test_pref_service->registry()); + auto account_fetcher_service = std::make_unique<AccountFetcherService>(); account_fetcher_service->Initialize( - signin_client, token_service.get(), account_tracker_service, + signin_client, token_service, account_tracker_service, std::make_unique<image_fetcher::FakeImageDecoder>()); #if defined(OS_CHROMEOS) std::unique_ptr<SigninManagerBase> signin_manager = - std::make_unique<SigninManagerBase>(signin_client, token_service.get(), + std::make_unique<SigninManagerBase>(signin_client, token_service, account_tracker_service); #else std::unique_ptr<SigninManagerBase> signin_manager = - std::make_unique<SigninManager>(signin_client, token_service.get(), + std::make_unique<SigninManager>(signin_client, token_service, account_tracker_service, nullptr, account_consistency); #endif - signin_manager->Initialize(pref_service); + signin_manager->Initialize(test_pref_service); std::unique_ptr<GaiaCookieManagerService> gaia_cookie_manager_service; if (test_url_loader_factory != nullptr) { gaia_cookie_manager_service = std::make_unique<GaiaCookieManagerService>( - token_service.get(), signin_client, + token_service, signin_client, base::BindRepeating( [](network::TestURLLoaderFactory* test_url_loader_factory) -> scoped_refptr<network::SharedURLLoaderFactory> { @@ -220,7 +199,7 @@ test_url_loader_factory)); } else { gaia_cookie_manager_service = std::make_unique<GaiaCookieManagerService>( - token_service.get(), signin_client); + token_service, signin_client); } std::unique_ptr<PrimaryAccountMutator> primary_account_mutator; @@ -234,20 +213,22 @@ #if !defined(OS_ANDROID) && !defined(OS_IOS) accounts_mutator = std::make_unique<AccountsMutatorImpl>( - token_service.get(), account_tracker_service, signin_manager.get(), - pref_service); + token_service, account_tracker_service, signin_manager.get(), + test_pref_service); #endif - auto diagnostics_provider = std::make_unique<DiagnosticsProviderImpl>( - token_service.get(), gaia_cookie_manager_service.get()); + std::unique_ptr<DiagnosticsProvider> diagnostics_provider = + std::make_unique<DiagnosticsProviderImpl>( + token_service, gaia_cookie_manager_service.get()); - auto accounts_cookie_mutator = std::make_unique<AccountsCookieMutatorImpl>( - gaia_cookie_manager_service.get()); + std::unique_ptr<AccountsCookieMutator> accounts_cookie_mutator = + std::make_unique<AccountsCookieMutatorImpl>( + gaia_cookie_manager_service.get()); - return std::make_unique<TestIdentityManagerWrapper>( - account_tracker_service, std::move(token_service), + return std::make_unique<IdentityManager>( std::move(gaia_cookie_manager_service), std::move(signin_manager), - std::move(account_fetcher_service), std::move(primary_account_mutator), + std::move(account_fetcher_service), token_service, + account_tracker_service, std::move(primary_account_mutator), std::move(accounts_mutator), std::move(accounts_cookie_mutator), std::move(diagnostics_provider)); }
diff --git a/services/identity/public/cpp/identity_test_environment.h b/services/identity/public/cpp/identity_test_environment.h index e487d94..504fe9b 100644 --- a/services/identity/public/cpp/identity_test_environment.h +++ b/services/identity/public/cpp/identity_test_environment.h
@@ -7,15 +7,11 @@ #include "base/optional.h" #include "components/signin/core/browser/account_consistency_method.h" -#include "services/identity/public/cpp/accounts_cookie_mutator_impl.h" -#include "services/identity/public/cpp/diagnostics_provider_impl.h" #include "services/identity/public/cpp/identity_manager.h" #include "services/identity/public/cpp/identity_test_utils.h" class AccountTrackerService; class FakeProfileOAuth2TokenService; -class KeyedService; -class Profile; class IdentityTestEnvironmentChromeBrowserStateAdaptor; class IdentityTestEnvironmentProfileAdaptor; class PrefService; @@ -34,28 +30,6 @@ class IdentityManagerDependenciesOwner; class TestIdentityManagerObserver; -// A KeyedService wrapper around IdentityManager. Necessary to allow -// embedder-level tests to inject |BuildIdentityManagerForTests()| as the -// factory function for their IdentityManagerFactory instances, as that -// injection requires that the injected function return a KeyedService -class TestIdentityManagerWrapper : public KeyedService, - public identity::IdentityManager { - public: - TestIdentityManagerWrapper( - AccountTrackerService* account_tracker_service, - std::unique_ptr<ProfileOAuth2TokenService> token_service, - std::unique_ptr<GaiaCookieManagerService> gaia_cookie_manager_service, - std::unique_ptr<SigninManagerBase> signin_manager, - std::unique_ptr<AccountFetcherService> account_fetcher_service, - std::unique_ptr<identity::PrimaryAccountMutator> primary_account_mutator, - std::unique_ptr<identity::AccountsMutator> accounts_mutator, - std::unique_ptr<identity::AccountsCookieMutator> accounts_cookie_mutator, - std::unique_ptr<identity::DiagnosticsProvider> diagnostics_provider); - - // KeyedService overrides. - void Shutdown() override; -}; - // Class that creates an IdentityManager for use in testing contexts and // provides facilities for driving that IdentityManager. The IdentityManager // instance is brought up in an environment where the primary account is @@ -363,6 +337,10 @@ // IdentityTestEnvironment's constructor. std::unique_ptr<AccountTrackerService> owned_account_tracker_service_; + // This will be null if a FakeProfileOAuth2TokenService was provided to + // IdentityTestEnvironment's constructor. + std::unique_ptr<FakeProfileOAuth2TokenService> owned_token_service_; + // Depending on which constructor is used, exactly one of these will be // non-null. See the documentation on the constructor wherein IdentityManager // is passed in for required lifetime invariants in that case. @@ -375,11 +353,10 @@ std::vector<AccessTokenRequestState> requesters_; // Create an IdentityManager instance for tests. - static std::unique_ptr<TestIdentityManagerWrapper> - BuildIdentityManagerForTests( + static std::unique_ptr<IdentityManager> BuildIdentityManagerForTests( SigninClient* signin_client, - PrefService* pref_service, - std::unique_ptr<FakeProfileOAuth2TokenService> token_service, + sync_preferences::TestingPrefServiceSyncable* test_pref_service, + FakeProfileOAuth2TokenService* token_service, AccountTrackerService* account_tracker_service, signin::AccountConsistencyMethod account_consistency = signin::AccountConsistencyMethod::kDisabled,
diff --git a/services/network/public/cpp/net_ipc_param_traits.cc b/services/network/public/cpp/net_ipc_param_traits.cc index dc975f4..dec6b7ca 100644 --- a/services/network/public/cpp/net_ipc_param_traits.cc +++ b/services/network/public/cpp/net_ipc_param_traits.cc
@@ -11,38 +11,24 @@ namespace IPC { -void ParamTraits<scoped_refptr<net::AuthChallengeInfo>>::Write( - base::Pickle* m, - const param_type& p) { - WriteParam(m, p != nullptr); - if (p) { - WriteParam(m, p->is_proxy); - WriteParam(m, p->challenger); - WriteParam(m, p->scheme); - WriteParam(m, p->realm); - } +void ParamTraits<net::AuthChallengeInfo>::Write(base::Pickle* m, + const param_type& p) { + WriteParam(m, p.is_proxy); + WriteParam(m, p.challenger); + WriteParam(m, p.scheme); + WriteParam(m, p.realm); } -bool ParamTraits<scoped_refptr<net::AuthChallengeInfo>>::Read( - const base::Pickle* m, - base::PickleIterator* iter, - param_type* r) { - bool has_object; - if (!ReadParam(m, iter, &has_object)) - return false; - if (!has_object) { - *r = nullptr; - return true; - } - *r = new net::AuthChallengeInfo(); - return ReadParam(m, iter, &(*r)->is_proxy) && - ReadParam(m, iter, &(*r)->challenger) && - ReadParam(m, iter, &(*r)->scheme) && ReadParam(m, iter, &(*r)->realm); +bool ParamTraits<net::AuthChallengeInfo>::Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* r) { + return ReadParam(m, iter, &r->is_proxy) && + ReadParam(m, iter, &r->challenger) && ReadParam(m, iter, &r->scheme) && + ReadParam(m, iter, &r->realm); } -void ParamTraits<scoped_refptr<net::AuthChallengeInfo>>::Log( - const param_type& p, - std::string* l) { +void ParamTraits<net::AuthChallengeInfo>::Log(const param_type& p, + std::string* l) { l->append("<AuthChallengeInfo>"); }
diff --git a/services/network/public/cpp/net_ipc_param_traits.h b/services/network/public/cpp/net_ipc_param_traits.h index 3cff701..04121b94 100644 --- a/services/network/public/cpp/net_ipc_param_traits.h +++ b/services/network/public/cpp/net_ipc_param_traits.h
@@ -45,9 +45,8 @@ namespace IPC { template <> -struct COMPONENT_EXPORT(NETWORK_CPP_BASE) - ParamTraits<scoped_refptr<net::AuthChallengeInfo>> { - typedef scoped_refptr<net::AuthChallengeInfo> param_type; +struct COMPONENT_EXPORT(NETWORK_CPP_BASE) ParamTraits<net::AuthChallengeInfo> { + typedef net::AuthChallengeInfo param_type; static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter,
diff --git a/services/network/public/cpp/network_param.typemap b/services/network/public/cpp/network_param.typemap index 69e0c62..2ef9f78 100644 --- a/services/network/public/cpp/network_param.typemap +++ b/services/network/public/cpp/network_param.typemap
@@ -33,7 +33,7 @@ "//services/network/public/cpp:cpp_base", ] type_mappings = [ - "network.mojom.AuthChallengeInfo=scoped_refptr<net::AuthChallengeInfo>[nullable_is_same_type]", + "network.mojom.AuthChallengeInfo=net::AuthChallengeInfo", "network.mojom.AuthCredentials=net::AuthCredentials", "network.mojom.CertVerifyResult=net::CertVerifyResult", "network.mojom.CTVerifyResult=net::ct::CTVerifyResult",
diff --git a/services/network/test/test_network_service_client.cc b/services/network/test/test_network_service_client.cc index e406716..079d523 100644 --- a/services/network/test/test_network_service_client.cc +++ b/services/network/test/test_network_service_client.cc
@@ -25,7 +25,7 @@ const GURL& url, const GURL& site_for_cookies, bool first_auth_attempt, - const scoped_refptr<net::AuthChallengeInfo>& auth_info, + const net::AuthChallengeInfo& auth_info, int32_t resource_type, const base::Optional<ResourceResponseHead>& head, mojom::AuthChallengeResponderPtr auth_challenge_responder) {
diff --git a/services/network/test/test_network_service_client.h b/services/network/test/test_network_service_client.h index cc70741..fa011107 100644 --- a/services/network/test/test_network_service_client.h +++ b/services/network/test/test_network_service_client.h
@@ -35,7 +35,7 @@ const GURL& url, const GURL& site_for_cookies, bool first_auth_attempt, - const scoped_refptr<net::AuthChallengeInfo>& auth_info, + const net::AuthChallengeInfo& auth_info, int32_t resource_type, const base::Optional<ResourceResponseHead>& head, mojom::AuthChallengeResponderPtr auth_challenge_responder) override;
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index fcb025f..7243b22 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -754,7 +754,7 @@ } void URLLoader::OnAuthRequired(net::URLRequest* url_request, - net::AuthChallengeInfo* auth_info) { + const net::AuthChallengeInfo& auth_info) { if (!network_service_client_) { OnAuthCredentials(base::nullopt); return;
diff --git a/services/network/url_loader.h b/services/network/url_loader.h index 20d6dc6..2bf69e8 100644 --- a/services/network/url_loader.h +++ b/services/network/url_loader.h
@@ -89,7 +89,7 @@ const net::RedirectInfo& redirect_info, bool* defer_redirect) override; void OnAuthRequired(net::URLRequest* request, - net::AuthChallengeInfo* info) override; + const net::AuthChallengeInfo& info) override; void OnCertificateRequested(net::URLRequest* request, net::SSLCertRequestInfo* info) override; void OnSSLCertificateError(net::URLRequest* request,
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc index 21f70aa..e42fc3c 100644 --- a/services/network/url_loader_unittest.cc +++ b/services/network/url_loader_unittest.cc
@@ -2276,7 +2276,7 @@ const GURL& url, const GURL& site_for_cookies, bool first_auth_attempt, - const scoped_refptr<net::AuthChallengeInfo>& auth_info, + const net::AuthChallengeInfo& auth_info, int32_t resource_type, const base::Optional<network::ResourceResponseHead>& head, mojom::AuthChallengeResponderPtr auth_challenge_responder) override {
diff --git a/services/network/websocket.cc b/services/network/websocket.cc index efc98f5..69760c4 100644 --- a/services/network/websocket.cc +++ b/services/network/websocket.cc
@@ -104,7 +104,7 @@ const net::SSLInfo& ssl_info, bool fatal) override; int OnAuthRequired( - scoped_refptr<net::AuthChallengeInfo> auth_info, + const net::AuthChallengeInfo& auth_info, scoped_refptr<net::HttpResponseHeaders> response_headers, const net::IPEndPoint& remote_endpoint, base::OnceCallback<void(const net::AuthCredentials*)> callback, @@ -288,7 +288,7 @@ } int WebSocket::WebSocketEventHandler::OnAuthRequired( - scoped_refptr<net::AuthChallengeInfo> auth_info, + const net::AuthChallengeInfo& auth_info, scoped_refptr<net::HttpResponseHeaders> response_headers, const net::IPEndPoint& remote_endpoint, base::OnceCallback<void(const net::AuthCredentials*)> callback, @@ -301,7 +301,7 @@ } impl_->auth_handler_->OnAuthRequired( - std::move(auth_info), std::move(response_headers), remote_endpoint, + auth_info, std::move(response_headers), remote_endpoint, base::BindOnce(&WebSocket::OnAuthRequiredComplete, impl_->weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
diff --git a/services/shape_detection/OWNERS b/services/shape_detection/OWNERS index 0e57d5f..4009628 100644 --- a/services/shape_detection/OWNERS +++ b/services/shape_detection/OWNERS
@@ -1,5 +1,7 @@ -# COMPONENT: Blink>ImageCapture -# TEAM: media-dev@chromium.org - -mcasas@chromium.org reillyg@chromium.org + +# Original (legacy) owner. +mcasas@chromium.org + +# COMPONENT: Blink>ShapeDetection +# TEAM: device-dev@chromium.org
diff --git a/services/video_capture/OWNERS b/services/video_capture/OWNERS index c3dbbd03..4116bac 100644 --- a/services/video_capture/OWNERS +++ b/services/video_capture/OWNERS
@@ -1,6 +1,8 @@ -# TEAM: media-capture-and-streams@grotations.appspotmail.com -# COMPONENT: Blink>GetUserMedia - chfremer@chromium.org emircan@chromium.org -mcasas@chromium.org + +# Original (legacy) owner. +per-file *video*=mcasas@chromium.org + +# COMPONENT: Blink>GetUserMedia +# TEAM: media-capture-and-streams@grotations.appspotmail.com
diff --git a/services/ws/window_service_unittest.cc b/services/ws/window_service_unittest.cc index b20c9f7..1928508b 100644 --- a/services/ws/window_service_unittest.cc +++ b/services/ws/window_service_unittest.cc
@@ -120,15 +120,6 @@ } private: - // ime::mojom::ImeEngineClient: - void CommitText(const std::string& text) override {} - void UpdateCompositionText(const ui::CompositionText& composition, - uint32_t cursor_pos, - bool visible) override {} - void DeleteSurroundingText(int32_t offset, uint32_t length) override {} - void SendKeyEvent(std::unique_ptr<ui::Event> key_event) override {} - void Reconnect() override {} - mojo::Binding<ime::mojom::ImeEngineClient> binding_; DISALLOW_COPY_AND_ASSIGN(TestImeEngineClient);
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 3007830..03005c4 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2021,7 +2021,9 @@ "windows", "mac", "chromeos", - "ios" + "ios", + "linux", + "android_webview" ], "experiments": [ {
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 9b623ee..0a8edd5 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -461,6 +461,7 @@ "web/web_language_detection_details.h", "web/web_local_frame.h", "web/web_local_frame_client.h", + "web/web_manifest_fetcher.h", "web/web_manifest_parser.h", "web/web_meaningful_layout.h", "web/web_media_player_action.h",
diff --git a/third_party/blink/public/mojom/serial/serial.mojom b/third_party/blink/public/mojom/serial/serial.mojom index ee8d9cea..34533152 100644 --- a/third_party/blink/public/mojom/serial/serial.mojom +++ b/third_party/blink/public/mojom/serial/serial.mojom
@@ -5,6 +5,7 @@ module blink.mojom; import "mojo/public/mojom/base/unguessable_token.mojom"; +import "services/device/public/mojom/serial.mojom"; struct SerialPortInfo { // Opaque identifier for this port. @@ -31,4 +32,9 @@ // Requests permission to access a port. RequestPort(array<SerialPortFilter> filters) => (SerialPortInfo? port); + + // Connects an instance of the SerialPort interface attached to the serial + // port identified by |token|. + GetPort(mojo_base.mojom.UnguessableToken token, + device.mojom.SerialPort& port_request); };
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index 5fbe024..2c0bc8cc 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -234,6 +234,7 @@ BLINK_PLATFORM_EXPORT static void EnableHTMLImports(bool); BLINK_PLATFORM_EXPORT static void EnableSignedExchangeSubresourcePrefetch( bool); + BLINK_PLATFORM_EXPORT static void EnableIdleDetection(bool); private: WebRuntimeFeatures();
diff --git a/third_party/blink/public/web/web_manifest_fetcher.h b/third_party/blink/public/web/web_manifest_fetcher.h new file mode 100644 index 0000000..58bf778 --- /dev/null +++ b/third_party/blink/public/web/web_manifest_fetcher.h
@@ -0,0 +1,48 @@ +// Copyright 2019 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 THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_MANIFEST_FETCHER_H_ +#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_MANIFEST_FETCHER_H_ + +#include <memory> +#include "base/callback.h" +#include "third_party/blink/public/platform/web_common.h" +#include "third_party/blink/public/platform/web_private_ptr.h" + +namespace blink { + +class ManifestFetcher; +class WebDocument; +class WebURL; +class WebURLResponse; +class WebString; + +class WebManifestFetcher { + public: + // This will be called asynchronously after the URL has been fetched, + // successfully or not. If there is a failure, response and data will both be + // empty. |response| and |data| are both valid until the ManifestFetcher + // instance is destroyed. + using Callback = + base::OnceCallback<void(const WebURLResponse&, const WebString&)>; + + BLINK_EXPORT explicit WebManifestFetcher(const WebURL& url); + BLINK_EXPORT ~WebManifestFetcher() { Reset(); } + + BLINK_EXPORT void Reset(); + + BLINK_EXPORT void Start(WebDocument* web_document, + bool use_credentials, + Callback callback); + BLINK_EXPORT void Cancel(); + + private: + bool IsNull() const { return private_.IsNull(); } + + WebPrivatePtr<ManifestFetcher> private_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_MANIFEST_FETCHER_H_
diff --git a/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc b/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc index 83b5579..6d0c8f6 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc +++ b/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc
@@ -293,8 +293,12 @@ EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(0); platform_->RunForPeriodSeconds(1); - // Seek to some time in the past. A completed seek should trigger a *single* - // timeupdate. + EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(1); + Video()->pause(); + platform_->RunUntilIdle(); + + // Seek to some time in the past. A completed seek while paused should trigger + // a *single* timeupdate. EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(1); ASSERT_GE(WebMediaPlayer()->CurrentTime(), 1); Video()->setCurrentTime(WebMediaPlayer()->CurrentTime() - 1); @@ -347,10 +351,14 @@ ASSERT_GE(WebMediaPlayer()->CurrentTime(), 1); Video()->setCurrentTime(WebMediaPlayer()->CurrentTime() - 1); WebMediaPlayer()->FinishSeek(); + + // Expect another timeupdate after FinishSeek due to + // seeking -> begin scrubbing -> pause -> timeupdate. + EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(1); platform_->RunUntilIdle(); // Advancing the remainder of the last periodic timeupdate interval should be - // insufficient to triggger a new timeupdate event because the seek's + // insufficient to trigger a new timeupdate event because the seek's // timeupdate occurred only 125ms ago. We desire to fire periodic timeupdates // exactly every 250ms from the last timeupdate, and the seek's timeupdate // should reset that 250ms ms countdown.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc index fd032f2..8d66c3c 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc
@@ -15,11 +15,22 @@ namespace blink { void NGLineBoxFragmentBuilder::Reset() { - children_.resize(0); - offsets_.resize(0); - line_box_type_ = NGPhysicalLineBoxFragment::kNormalLineBox; - metrics_ = NGLineHeightMetrics(); + children_.Shrink(0); + offsets_.Shrink(0); + child_break_tokens_.Shrink(0); + inline_break_tokens_.Shrink(0); + oof_positioned_candidates_.Shrink(0); + size_.inline_size = LayoutUnit(); + metrics_ = NGLineHeightMetrics(); + line_box_type_ = NGPhysicalLineBoxFragment::kNormalLineBox; + + has_last_resort_break_ = false; + has_floating_descendants_ = false; + has_orthogonal_flow_roots_ = false; + has_child_that_depends_on_percentage_block_size_ = false; + has_block_fragmentation_ = false; + may_have_descendant_above_block_start_ = false; } void NGLineBoxFragmentBuilder::SetIsEmptyLineBox() {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h index 6e9b284..5db3e92 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h
@@ -239,11 +239,10 @@ NGFloatTypes adjoining_floats_ = kFloatTypeNone; - bool has_last_resort_break_ = false; - bool is_pushed_by_floats_ = false; bool is_old_layout_root_ = false; + bool has_last_resort_break_ = false; bool has_floating_descendants_ = false; bool has_orthogonal_flow_roots_ = false; bool has_child_that_depends_on_percentage_block_size_ = false;
diff --git a/third_party/blink/renderer/modules/exported/BUILD.gn b/third_party/blink/renderer/modules/exported/BUILD.gn index 74f7348..b62c939 100644 --- a/third_party/blink/renderer/modules/exported/BUILD.gn +++ b/third_party/blink/renderer/modules/exported/BUILD.gn
@@ -13,6 +13,7 @@ "web_dom_media_stream_track.cc", "web_embedded_worker_impl.cc", "web_embedded_worker_impl.h", + "web_manifest_fetcher.cc", "web_manifest_parser.cc", "web_storage_event_dispatcher_impl.cc", "web_user_media_request.cc",
diff --git a/third_party/blink/renderer/modules/exported/web_manifest_fetcher.cc b/third_party/blink/renderer/modules/exported/web_manifest_fetcher.cc new file mode 100644 index 0000000..f2bffec69 --- /dev/null +++ b/third_party/blink/renderer/modules/exported/web_manifest_fetcher.cc
@@ -0,0 +1,36 @@ +// Copyright 2019 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 "third_party/blink/public/web/web_manifest_fetcher.h" + +#include "third_party/blink/public/platform/web_url.h" +#include "third_party/blink/public/web/web_document.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/modules/manifest/manifest_fetcher.h" +#include "third_party/blink/renderer/platform/weborigin/kurl.h" + +namespace blink { + +WebManifestFetcher::WebManifestFetcher(const WebURL& url) + : private_(MakeGarbageCollected<ManifestFetcher>(url)) {} + +void WebManifestFetcher::Start(WebDocument* web_document, + bool use_credentials, + Callback callback) { + DCHECK(!IsNull()); + + Document* document = web_document->Unwrap<Document>(); + private_->Start(*document, use_credentials, std::move(callback)); +} + +void WebManifestFetcher::Cancel() { + DCHECK(!IsNull()); + private_->Cancel(); +} + +void WebManifestFetcher::Reset() { + private_.Reset(); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/geolocation/OWNERS b/third_party/blink/renderer/modules/geolocation/OWNERS index 51b1f3e2..2dbeb1a 100644 --- a/third_party/blink/renderer/modules/geolocation/OWNERS +++ b/third_party/blink/renderer/modules/geolocation/OWNERS
@@ -1,5 +1,7 @@ mattreynolds@chromium.org + +# Original (legacy) owner. mcasas@chromium.org # TEAM: device-dev@chromium.org -# COMPONENT: Blink>Location +# COMPONENT: Blink>Geolocation
diff --git a/third_party/blink/renderer/modules/manifest/BUILD.gn b/third_party/blink/renderer/modules/manifest/BUILD.gn index 31862cc..dc27426 100644 --- a/third_party/blink/renderer/modules/manifest/BUILD.gn +++ b/third_party/blink/renderer/modules/manifest/BUILD.gn
@@ -8,6 +8,8 @@ sources = [ "image_resource_type_converters.cc", "image_resource_type_converters.h", + "manifest_fetcher.cc", + "manifest_fetcher.h", "manifest_parser.cc", "manifest_parser.h", "manifest_uma_util.cc",
diff --git a/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc b/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc new file mode 100644 index 0000000..f6c0cf1 --- /dev/null +++ b/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc
@@ -0,0 +1,88 @@ +// Copyright 2019 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 "third_party/blink/renderer/modules/manifest/manifest_fetcher.h" + +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/loader/threadable_loader.h" +#include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h" + +namespace blink { + +ManifestFetcher::ManifestFetcher(const KURL& url) + : url_(url), completed_(false) {} + +ManifestFetcher::~ManifestFetcher() { + if (!completed_) + Cancel(); +} + +void ManifestFetcher::Start(Document& document, + bool use_credentials, + WebManifestFetcher::Callback callback) { + callback_ = std::move(callback); + + ResourceRequest request(url_); + request.SetRequestContext(mojom::RequestContextType::MANIFEST); + request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors); + // See https://w3c.github.io/manifest/. Use "include" when use_credentials is + // true, and "omit" otherwise. + request.SetFetchCredentialsMode( + use_credentials ? network::mojom::FetchCredentialsMode::kInclude + : network::mojom::FetchCredentialsMode::kOmit); + + ResourceLoaderOptions resource_loader_options; + resource_loader_options.data_buffering_policy = kDoNotBufferData; + + loader_ = MakeGarbageCollected<ThreadableLoader>(document, this, + resource_loader_options); + loader_->Start(request); +} + +void ManifestFetcher::Cancel() { + if (!loader_) + return; + + DCHECK(!completed_); + + ThreadableLoader* loader = loader_.Release(); + loader->Cancel(); +} + +void ManifestFetcher::DidReceiveResponse(uint64_t, + const ResourceResponse& response) { + response_ = response; +} + +void ManifestFetcher::DidReceiveData(const char* data, unsigned length) { + if (!length) + return; + + data_.Append(data, length); +} + +void ManifestFetcher::DidFinishLoading(uint64_t) { + DCHECK(!completed_); + completed_ = true; + + WrappedResourceResponse wrapped_response(response_); + std::move(callback_).Run(wrapped_response, data_.ToString()); + data_.Clear(); +} + +void ManifestFetcher::DidFail(const ResourceError& error) { + if (!callback_) + return; + + data_.Clear(); + + WrappedResourceResponse wrapped_response(response_); + std::move(callback_).Run(wrapped_response, String()); +} + +void ManifestFetcher::DidFailRedirectCheck() { + DidFail(ResourceError::Failure(NullURL())); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/manifest/manifest_fetcher.h b/third_party/blink/renderer/modules/manifest/manifest_fetcher.h new file mode 100644 index 0000000..9a73ed4 --- /dev/null +++ b/third_party/blink/renderer/modules/manifest/manifest_fetcher.h
@@ -0,0 +1,62 @@ +// Copyright 2019 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 THIRD_PARTY_BLINK_RENDERER_MODULES_MANIFEST_MANIFEST_FETCHER_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_MANIFEST_MANIFEST_FETCHER_H_ + +#include <memory> + +#include "base/callback.h" +#include "third_party/blink/public/web/web_manifest_fetcher.h" +#include "third_party/blink/renderer/core/loader/threadable_loader.h" +#include "third_party/blink/renderer/core/loader/threadable_loader_client.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" +#include "third_party/blink/renderer/platform/heap/member.h" +#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h" +#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" + +namespace blink { + +class Document; +class KURL; + +// Helper class to download a Web Manifest. When an instance is created, the +// caller need to call Start() and wait for the passed callback to be executed. +// If the fetch fails, the callback will be called with two empty objects. +class ManifestFetcher final : public GarbageCollectedFinalized<ManifestFetcher>, + public ThreadableLoaderClient { + USING_GARBAGE_COLLECTED_MIXIN(ManifestFetcher); + + public: + explicit ManifestFetcher(const KURL& url); + ~ManifestFetcher() override; + + void Start(Document& document, + bool use_credentials, + WebManifestFetcher::Callback callback); + void Cancel(); + + // ThreadableLoaderClient + void DidReceiveResponse(uint64_t, const ResourceResponse&) override; + void DidReceiveData(const char*, unsigned) override; + void DidFinishLoading(uint64_t) override; + void DidFail(const ResourceError&) override; + void DidFailRedirectCheck() override; + + void Trace(Visitor* visitor) override { visitor->Trace(loader_); } + + private: + KURL url_; + bool completed_; + WebManifestFetcher::Callback callback_; + ResourceResponse response_; + StringBuilder data_; + Member<ThreadableLoader> loader_; + + DISALLOW_COPY_AND_ASSIGN(ManifestFetcher); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MANIFEST_MANIFEST_FETCHER_H_
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc index c9560ec..e6400ca 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
@@ -942,9 +942,7 @@ UpdatePlayState(); - UpdateCurrentTimeDisplay(); - - timeline_->SetPosition(MediaElement().currentTime()); + UpdateTimeIndicators(); OnVolumeChange(); OnTextTracksAddedOrRemoved(); @@ -959,6 +957,11 @@ OnControlsListUpdated(); } +void MediaControlsImpl::UpdateTimeIndicators() { + timeline_->SetPosition(MediaElement().currentTime()); + UpdateCurrentTimeDisplay(); +} + void MediaControlsImpl::OnControlsListUpdated() { BatchedControlUpdate batch(this); @@ -1129,6 +1132,9 @@ if (panel_->KeepDisplayedForAccessibility()) return false; + if (MediaElement().seeking()) + return false; + return true; } @@ -1590,8 +1596,7 @@ is_mouse_over_controls_ = true; if (!MediaElement().paused()) { MakeOpaqueFromPointerEvent(); - if (ShouldHideMediaControls()) - StartHideMediaControlsTimer(); + StartHideMediaControlsIfNecessary(); } } } else if (event->type() == event_type_names::kPointerout) { @@ -1777,6 +1782,11 @@ overlay_cast_button_->SetIsWanted(false); } +void MediaControlsImpl::StartHideMediaControlsIfNecessary() { + if (ShouldHideMediaControls()) + StartHideMediaControlsTimer(); +} + void MediaControlsImpl::StartHideMediaControlsTimer() { hide_media_controls_timer_.StartOneShot( GetTimeWithoutMouseMovementBeforeHidingMediaControls(), FROM_HERE); @@ -1850,8 +1860,7 @@ } void MediaControlsImpl::OnTimeUpdate() { - timeline_->SetPosition(MediaElement().currentTime()); - UpdateCurrentTimeDisplay(); + UpdateTimeIndicators(); // 'timeupdate' might be called in a paused state. The controls should not // become transparent in that case. @@ -1893,8 +1902,7 @@ void MediaControlsImpl::OnPlay() { UpdatePlayState(); - timeline_->SetPosition(MediaElement().currentTime()); - UpdateCurrentTimeDisplay(); + UpdateTimeIndicators(); UpdateCSSClassFromState(); } @@ -1907,8 +1915,7 @@ void MediaControlsImpl::OnPause() { UpdatePlayState(); - timeline_->SetPosition(MediaElement().currentTime()); - UpdateCurrentTimeDisplay(); + UpdateTimeIndicators(); MakeOpaque(); StopHideMediaControlsTimer(); @@ -1916,6 +1923,32 @@ UpdateCSSClassFromState(); } +void MediaControlsImpl::OnSeeking() { + UpdateTimeIndicators(); + if (!is_scrubbing_) { + is_scrubbing_ = true; + UpdateCSSClassFromState(); + } + + // Don't try to show the controls if the seek was caused by the video being + // looped. + if (MediaElement().Loop() && MediaElement().currentTime() == 0) + return; + + if (!MediaElement().ShouldShowControls()) + return; + + MaybeShow(); + StopHideMediaControlsTimer(); +} + +void MediaControlsImpl::OnSeeked() { + StartHideMediaControlsIfNecessary(); + + is_scrubbing_ = false; + UpdateCSSClassFromState(); +} + void MediaControlsImpl::OnTextTracksAddedOrRemoved() { toggle_closed_captions_button_->UpdateDisplayType(); toggle_closed_captions_button_->SetIsWanted(
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl.h b/third_party/blink/renderer/modules/media_controls/media_controls_impl.h index 672552d..96e07b3e 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_impl.h +++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
@@ -278,6 +278,9 @@ void ElementSizeChangedTimerFired(TimerBase*); + // Update any visible indicators of the current time. + void UpdateTimeIndicators(); + // Hide elements that don't fit, and show those things that we want which // do fit. This requires that m_effectiveWidth and m_effectiveHeight are // current. @@ -334,6 +337,8 @@ void OnPlay(); void OnPlaying(); void OnPause(); + void OnSeeking(); + void OnSeeked(); void OnTextTracksAddedOrRemoved(); void OnTextTracksChanged(); void OnError();
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc index bc3d2a5..50c29985 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
@@ -207,6 +207,9 @@ void SimulateLoadedMetadata() { media_controls_->OnLoadedMetadata(); } + void SimulateOnSeeking() { media_controls_->OnSeeking(); } + void SimulateOnSeeked() { media_controls_->OnSeeked(); } + MediaControlsImpl& MediaControls() { return *media_controls_; } MediaControlVolumeSliderElement* VolumeSliderElement() const { return media_controls_->volume_slider_; @@ -628,6 +631,32 @@ EXPECT_EQ(duration / 2, current_time_display->CurrentValue()); } +TEST_F(MediaControlsImplTest, TimeIndicatorsUpdatedOnSeeking) { + EnsureSizing(); + + MediaControlCurrentTimeDisplayElement* current_time_display = + GetCurrentTimeDisplayElement(); + MediaControlTimelineElement* timeline = TimelineElement(); + double duration = 1000; + LoadMediaWithDuration(duration); + + EXPECT_EQ(0, current_time_display->CurrentValue()); + EXPECT_EQ(0, timeline->valueAsNumber()); + + MediaControls().MediaElement().setCurrentTime(duration / 4); + + // Time indicators are not yet updated. + EXPECT_EQ(0, current_time_display->CurrentValue()); + EXPECT_EQ(0, timeline->valueAsNumber()); + + SimulateOnSeeking(); + + // The time indicators should be updated immediately when the 'seeking' event + // is fired. + EXPECT_EQ(duration / 4, current_time_display->CurrentValue()); + EXPECT_EQ(duration / 4, timeline->valueAsNumber()); +} + TEST_F(MediaControlsImplTest, TimelineMetricsWidth) { MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4"); test::RunPendingTasks(); @@ -877,6 +906,45 @@ } // namespace +TEST_F(MediaControlsImplTestWithMockScheduler, SeekingShowsControls) { + Element* panel = GetElementByShadowPseudoId(MediaControls(), + "-webkit-media-controls-panel"); + ASSERT_NE(nullptr, panel); + + MediaControls().MediaElement().SetSrc("http://example.com"); + MediaControls().MediaElement().Play(); + + // Hide the controls to start. + MediaControls().Hide(); + EXPECT_FALSE(IsElementVisible(*panel)); + + // Seeking should cause the controls to become visible. + SimulateOnSeeking(); + EXPECT_TRUE(IsElementVisible(*panel)); +} + +TEST_F(MediaControlsImplTestWithMockScheduler, + SeekingDoesNotShowControlsWhenNoControlsAttr) { + Element* panel = GetElementByShadowPseudoId(MediaControls(), + "-webkit-media-controls-panel"); + ASSERT_NE(nullptr, panel); + + MediaControls().MediaElement().SetBooleanAttribute(html_names::kControlsAttr, + false); + + MediaControls().MediaElement().SetSrc("http://example.com"); + MediaControls().MediaElement().Play(); + + // Hide the controls to start. + MediaControls().Hide(); + EXPECT_FALSE(IsElementVisible(*panel)); + + // Seeking should not cause the controls to become visible because the + // controls attribute is not set. + SimulateOnSeeking(); + EXPECT_FALSE(IsElementVisible(*panel)); +} + TEST_F(MediaControlsImplTestWithMockScheduler, ControlsRemainVisibleDuringKeyboardInteraction) { EnsureSizing();
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc b/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc index 3581220..0fe65f1f 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc
@@ -36,6 +36,8 @@ GetMediaElement().addEventListener(event_type_names::kPause, this, false); GetMediaElement().addEventListener(event_type_names::kDurationchange, this, false); + GetMediaElement().addEventListener(event_type_names::kSeeking, this, false); + GetMediaElement().addEventListener(event_type_names::kSeeked, this, false); GetMediaElement().addEventListener(event_type_names::kError, this, false); GetMediaElement().addEventListener(event_type_names::kLoadedmetadata, this, false); @@ -177,6 +179,14 @@ media_controls_->OnPause(); return; } + if (event->type() == event_type_names::kSeeking) { + media_controls_->OnSeeking(); + return; + } + if (event->type() == event_type_names::kSeeked) { + media_controls_->OnSeeked(); + return; + } if (event->type() == event_type_names::kError) { media_controls_->OnError(); return;
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/OWNERS b/third_party/blink/renderer/modules/mediacapturefromelement/OWNERS index 14affd71..2bc54e9 100644 --- a/third_party/blink/renderer/modules/mediacapturefromelement/OWNERS +++ b/third_party/blink/renderer/modules/mediacapturefromelement/OWNERS
@@ -1,4 +1,6 @@ emircan@chromium.org + +# Original (legacy) owner. mcasas@chromium.org # TEAM: media-capture-and-streams@grotations.appspotmail.com
diff --git a/third_party/blink/renderer/modules/mediarecorder/OWNERS b/third_party/blink/renderer/modules/mediarecorder/OWNERS index c824512..f3deb0e 100644 --- a/third_party/blink/renderer/modules/mediarecorder/OWNERS +++ b/third_party/blink/renderer/modules/mediarecorder/OWNERS
@@ -1,5 +1,7 @@ -mcasas@chromium.org peter@chromium.org +# Original (legacy) owner. +mcasas@chromium.org + # COMPONENT: Blink>MediaRecording # TEAM: media-dev@chromium.org
diff --git a/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc b/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc index e6fbe128..c2f6c00 100644 --- a/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc +++ b/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc
@@ -4,7 +4,7 @@ #include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h" -#include <memory> +#include <utility> #include "third_party/blink/renderer/modules/peerconnection/adapters/quic_packet_transport_adapter.h" #include "third_party/webrtc/api/ice_transport_factory.h" @@ -34,27 +34,37 @@ port_allocator_->Initialize(); ice_transport_channel_ = webrtc::CreateIceTransport(port_allocator_.get()); - p2p_transport_channel()->SignalGatheringState.connect( - this, &IceTransportAdapterImpl::OnGatheringStateChanged); - p2p_transport_channel()->SignalCandidateGathered.connect( - this, &IceTransportAdapterImpl::OnCandidateGathered); - p2p_transport_channel()->SignalIceTransportStateChanged.connect( - this, &IceTransportAdapterImpl::OnStateChanged); - p2p_transport_channel()->SignalNetworkRouteChanged.connect( - this, &IceTransportAdapterImpl::OnNetworkRouteChanged); - p2p_transport_channel()->SignalRoleConflict.connect( - this, &IceTransportAdapterImpl::OnRoleConflict); + SetupIceTransportChannel(); // We need to set the ICE role even before Start is called since the Port // assumes that the role has been set before receiving incoming connectivity // checks. These checks can race with the information signaled for Start. - p2p_transport_channel()->SetIceRole(cricket::ICEROLE_CONTROLLING); + ice_transport_channel()->SetIceRole(cricket::ICEROLE_CONTROLLING); // The ICE tiebreaker is used to determine which side is controlling/ // controlled when both sides start in the same role. The number is randomly // generated so that each peer can calculate a.tiebreaker <= b.tiebreaker // consistently. - p2p_transport_channel()->SetIceTiebreaker(rtc::CreateRandomId64()); + ice_transport_channel()->SetIceTiebreaker(rtc::CreateRandomId64()); + quic_packet_transport_adapter_ = - std::make_unique<QuicPacketTransportAdapter>(p2p_transport_channel()); + std::make_unique<QuicPacketTransportAdapter>(ice_transport_channel()); +} + +IceTransportAdapterImpl::IceTransportAdapterImpl( + Delegate* delegate, + rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport, + rtc::Thread* thread) + : delegate_(delegate), ice_transport_channel_(ice_transport) { + // TODO(bugs.webrtc.org/9419): Remove once WebRTC can be built as a component. + if (!rtc::ThreadManager::Instance()->CurrentThread()) { + rtc::ThreadManager::Instance()->SetCurrentThread(thread); + } + + // The native webrtc peer connection might have been closed in the meantime, + // clearing the ice transport channel; don't do anything in that case. |this| + // will eventually be destroyed when the blink layer gets notified by the + // webrtc layer that the transport has been cleared. + if (ice_transport_channel()) + SetupIceTransportChannel(); } IceTransportAdapterImpl::~IceTransportAdapterImpl() = default; @@ -75,14 +85,16 @@ const cricket::ServerAddresses& stun_servers, const std::vector<cricket::RelayServerConfig>& turn_servers, IceTransportPolicy policy) { - port_allocator_->set_candidate_filter(GetCandidateFilterForPolicy(policy)); - port_allocator_->SetConfiguration(stun_servers, turn_servers, - port_allocator_->candidate_pool_size(), - port_allocator_->prune_turn_ports()); + if (port_allocator_) { + port_allocator_->set_candidate_filter(GetCandidateFilterForPolicy(policy)); + port_allocator_->SetConfiguration(stun_servers, turn_servers, + port_allocator_->candidate_pool_size(), + port_allocator_->prune_turn_ports()); + } - p2p_transport_channel()->SetIceParameters(local_parameters); - p2p_transport_channel()->MaybeStartGathering(); - DCHECK_EQ(p2p_transport_channel()->gathering_state(), + ice_transport_channel()->SetIceParameters(local_parameters); + ice_transport_channel()->MaybeStartGathering(); + DCHECK_EQ(ice_transport_channel()->gathering_state(), cricket::kIceGatheringGathering); } @@ -90,52 +102,65 @@ const cricket::IceParameters& remote_parameters, cricket::IceRole role, const std::vector<cricket::Candidate>& initial_remote_candidates) { - p2p_transport_channel()->SetRemoteIceParameters(remote_parameters); - p2p_transport_channel()->SetIceRole(role); + ice_transport_channel()->SetRemoteIceParameters(remote_parameters); + ice_transport_channel()->SetIceRole(role); for (const auto& candidate : initial_remote_candidates) { - p2p_transport_channel()->AddRemoteCandidate(candidate); + ice_transport_channel()->AddRemoteCandidate(candidate); } } void IceTransportAdapterImpl::HandleRemoteRestart( const cricket::IceParameters& new_remote_parameters) { - p2p_transport_channel()->RemoveAllRemoteCandidates(); - p2p_transport_channel()->SetRemoteIceParameters(new_remote_parameters); + ice_transport_channel()->RemoveAllRemoteCandidates(); + ice_transport_channel()->SetRemoteIceParameters(new_remote_parameters); } void IceTransportAdapterImpl::AddRemoteCandidate( const cricket::Candidate& candidate) { - p2p_transport_channel()->AddRemoteCandidate(candidate); + ice_transport_channel()->AddRemoteCandidate(candidate); } P2PQuicPacketTransport* IceTransportAdapterImpl::packet_transport() const { return quic_packet_transport_adapter_.get(); } +void IceTransportAdapterImpl::SetupIceTransportChannel() { + ice_transport_channel()->SignalGatheringState.connect( + this, &IceTransportAdapterImpl::OnGatheringStateChanged); + ice_transport_channel()->SignalCandidateGathered.connect( + this, &IceTransportAdapterImpl::OnCandidateGathered); + ice_transport_channel()->SignalIceTransportStateChanged.connect( + this, &IceTransportAdapterImpl::OnStateChanged); + ice_transport_channel()->SignalNetworkRouteChanged.connect( + this, &IceTransportAdapterImpl::OnNetworkRouteChanged); + ice_transport_channel()->SignalRoleConflict.connect( + this, &IceTransportAdapterImpl::OnRoleConflict); +} + void IceTransportAdapterImpl::OnGatheringStateChanged( cricket::IceTransportInternal* transport) { - DCHECK_EQ(transport, p2p_transport_channel()); + DCHECK_EQ(transport, ice_transport_channel()); delegate_->OnGatheringStateChanged( - p2p_transport_channel()->gathering_state()); + ice_transport_channel()->gathering_state()); } void IceTransportAdapterImpl::OnCandidateGathered( cricket::IceTransportInternal* transport, const cricket::Candidate& candidate) { - DCHECK_EQ(transport, p2p_transport_channel()); + DCHECK_EQ(transport, ice_transport_channel()); delegate_->OnCandidateGathered(candidate); } void IceTransportAdapterImpl::OnStateChanged( cricket::IceTransportInternal* transport) { - DCHECK_EQ(transport, p2p_transport_channel()); - delegate_->OnStateChanged(p2p_transport_channel()->GetIceTransportState()); + DCHECK_EQ(transport, ice_transport_channel()); + delegate_->OnStateChanged(ice_transport_channel()->GetIceTransportState()); } void IceTransportAdapterImpl::OnNetworkRouteChanged( absl::optional<rtc::NetworkRoute> new_network_route) { const cricket::CandidatePairInterface* selected_connection = - p2p_transport_channel()->selected_connection(); + ice_transport_channel()->selected_connection(); if (!selected_connection) { // The selected connection will only be null if the ICE connection has // totally failed, at which point we'll get a StateChanged signal. The @@ -173,13 +198,13 @@ void IceTransportAdapterImpl::OnRoleConflict( cricket::IceTransportInternal* transport) { - DCHECK_EQ(transport, p2p_transport_channel()); + DCHECK_EQ(transport, ice_transport_channel()); // This logic is copied from JsepTransportController. cricket::IceRole reversed_role = - IceRoleReversed(p2p_transport_channel()->GetIceRole()); + IceRoleReversed(ice_transport_channel()->GetIceRole()); LOG(INFO) << "Got role conflict; switching to " << IceRoleToString(reversed_role) << " role."; - p2p_transport_channel()->SetIceRole(reversed_role); + ice_transport_channel()->SetIceRole(reversed_role); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h b/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h index 8727cb8..e039f2f7 100644 --- a/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h +++ b/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h
@@ -5,6 +5,9 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_ADAPTER_IMPL_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_ADAPTER_IMPL_H_ +#include <memory> +#include <vector> + #include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter.h" #include "third_party/webrtc/api/ice_transport_interface.h" @@ -24,6 +27,15 @@ std::unique_ptr<cricket::PortAllocator> port_allocator, std::unique_ptr<webrtc::AsyncResolverFactory> async_resolver_factory, rtc::Thread* thread); + + // Create an IceTransportAdapter for an existing |ice_transport_channel| + // object. In this case, |port_allocator_|, |async_resolver_factory_| and + // |quic_packet_transport_adapter_| are not used (and null). + IceTransportAdapterImpl( + Delegate* delegate, + rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport_channel, + rtc::Thread* thread); + ~IceTransportAdapterImpl() override; // IceTransportAdapter overrides. @@ -42,9 +54,10 @@ P2PQuicPacketTransport* packet_transport() const override; private: - cricket::IceTransportInternal* p2p_transport_channel() { + cricket::IceTransportInternal* ice_transport_channel() { return ice_transport_channel_->internal(); } + void SetupIceTransportChannel(); // Callbacks from P2PTransportChannel. void OnGatheringStateChanged(cricket::IceTransportInternal* transport); void OnCandidateGathered(cricket::IceTransportInternal* transport,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc b/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc index 70fada94..eaaa6f3 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc
@@ -115,9 +115,11 @@ if (!closed_from_owner_) { DispatchEvent(*Event::Create(event_type_names::kStatechange)); } - // Make sure the ICE transport is also closed. This must happen prior - // to garbage collection. - ice_transport_->stop(); + if (current_state_.state() == webrtc::DtlsTransportState::kClosed) { + // Make sure the ICE transport is also closed. This must happen prior + // to garbage collection. + ice_transport_->stop(); + } } const AtomicString& RTCDtlsTransport::InterfaceName() const {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc index 32333d9..cb729e1 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h" +#include <vector> + #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -22,6 +24,8 @@ #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event_init.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" +#include "third_party/webrtc/api/ice_transport_factory.h" +#include "third_party/webrtc/api/ice_transport_interface.h" #include "third_party/webrtc/api/jsep_ice_candidate.h" #include "third_party/webrtc/api/peer_connection_interface.h" #include "third_party/webrtc/p2p/base/port_allocator.h" @@ -52,6 +56,31 @@ WebString::FromUTF8(webrtc::SdpSerializeCandidate(candidate)), "", 0)); } +class DtlsIceTransportAdapterCrossThreadFactory + : public IceTransportAdapterCrossThreadFactory { + public: + explicit DtlsIceTransportAdapterCrossThreadFactory( + rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport) + : ice_transport_(ice_transport) {} + void InitializeOnMainThread(LocalFrame& frame) override { + DCHECK(!worker_thread_rtc_thread_); + worker_thread_rtc_thread_ = + Platform::Current()->GetWebRtcWorkerThreadRtcThread(); + } + + std::unique_ptr<IceTransportAdapter> ConstructOnWorkerThread( + IceTransportAdapter::Delegate* delegate) override { + DCHECK(ice_transport_); + DCHECK(worker_thread_rtc_thread_); + return std::make_unique<IceTransportAdapterImpl>( + delegate, std::move(ice_transport_), worker_thread_rtc_thread_); + } + + private: + rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport_; + rtc::Thread* worker_thread_rtc_thread_ = nullptr; +}; + class DefaultIceTransportAdapterCrossThreadFactory : public IceTransportAdapterCrossThreadFactory { public: @@ -98,6 +127,20 @@ RTCIceTransport* RTCIceTransport::Create( ExecutionContext* context, + rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport) { + LocalFrame* frame = To<Document>(context)->GetFrame(); + scoped_refptr<base::SingleThreadTaskRunner> proxy_thread = + frame->GetTaskRunner(TaskType::kNetworking); + scoped_refptr<base::SingleThreadTaskRunner> host_thread = + Platform::Current()->GetWebRtcWorkerThread(); + return MakeGarbageCollected<RTCIceTransport>( + context, std::move(proxy_thread), std::move(host_thread), + std::make_unique<DtlsIceTransportAdapterCrossThreadFactory>( + std::move(ice_transport))); +} + +RTCIceTransport* RTCIceTransport::Create( + ExecutionContext* context, scoped_refptr<base::SingleThreadTaskRunner> proxy_thread, scoped_refptr<base::SingleThreadTaskRunner> host_thread, std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory) {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h index 2c65b3c..4b3fd86 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h +++ b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
@@ -5,6 +5,9 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ICE_TRANSPORT_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ICE_TRANSPORT_H_ +#include <memory> +#include <utility> + #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_candidate_pair.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" @@ -15,6 +18,10 @@ #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" #include "third_party/webrtc/api/transport/enums.h" +namespace webrtc { +class IceTransportInterface; +} + namespace blink { class ExceptionState; @@ -51,6 +58,9 @@ static RTCIceTransport* Create(ExecutionContext* context); static RTCIceTransport* Create( ExecutionContext* context, + rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport_channel); + static RTCIceTransport* Create( + ExecutionContext* context, scoped_refptr<base::SingleThreadTaskRunner> proxy_thread, scoped_refptr<base::SingleThreadTaskRunner> host_thread, std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc index b3d4356..215e82e 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -2482,9 +2482,8 @@ if (transport_locator != ice_transports_by_native_transport_.end()) { return transport_locator->value; } - // TODO(crbug.com/907849): Create a functional ICE transport object. - // This is a dummy. - RTCIceTransport* transport = RTCIceTransport::Create(GetExecutionContext()); + RTCIceTransport* transport = + RTCIceTransport::Create(GetExecutionContext(), ice_transport); ice_transports_by_native_transport_.insert(ice_transport.get(), transport); return transport; }
diff --git a/third_party/blink/renderer/modules/serial/DEPS b/third_party/blink/renderer/modules/serial/DEPS index 755fee5..ee7d4d0 100644 --- a/third_party/blink/renderer/modules/serial/DEPS +++ b/third_party/blink/renderer/modules/serial/DEPS
@@ -1,3 +1,4 @@ include_rules = [ - "+base/unguessable_token.h" + "+base/unguessable_token.h", + "+services/device/public/mojom", ]
diff --git a/third_party/blink/renderer/modules/serial/serial.cc b/third_party/blink/renderer/modules/serial/serial.cc index abeb880..b0bb3bf 100644 --- a/third_party/blink/renderer/modules/serial/serial.cc +++ b/third_party/blink/renderer/modules/serial/serial.cc
@@ -45,6 +45,11 @@ return event_target_names::kSerial; } +void Serial::ContextDestroyed(ExecutionContext*) { + for (auto& entry : port_cache_) + entry.value->ContextDestroyed(); +} + ScriptPromise Serial::getPorts(ScriptState* script_state) { auto* context = GetExecutionContext(); if (!context) { @@ -107,6 +112,12 @@ return resolver->Promise(); } +void Serial::GetPort(const base::UnguessableToken& token, + device::mojom::blink::SerialPortRequest request) { + EnsureServiceConnection(); + service_->GetPort(token, std::move(request)); +} + void Serial::Trace(Visitor* visitor) { visitor->Trace(get_ports_promises_); visitor->Trace(request_port_promises_); @@ -150,8 +161,8 @@ SerialPort* Serial::GetOrCreatePort(mojom::blink::SerialPortInfoPtr info) { SerialPort* port = port_cache_.at(TokenToString(info->token)); if (!port) { - port = MakeGarbageCollected<SerialPort>(std::move(info)); - port_cache_.insert(TokenToString(port->Token()), port); + port = MakeGarbageCollected<SerialPort>(this, std::move(info)); + port_cache_.insert(TokenToString(port->token()), port); } return port; }
diff --git a/third_party/blink/renderer/modules/serial/serial.h b/third_party/blink/renderer/modules/serial/serial.h index c44191a..b13b237 100644 --- a/third_party/blink/renderer/modules/serial/serial.h +++ b/third_party/blink/renderer/modules/serial/serial.h
@@ -34,11 +34,17 @@ ExecutionContext* GetExecutionContext() const override; const AtomicString& InterfaceName() const override; + // ContextLifecycleObserver + void ContextDestroyed(ExecutionContext*) override; + + // Web-exposed interfaces DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect) DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect, kDisconnect) ScriptPromise getPorts(ScriptState*); ScriptPromise requestPort(ScriptState*, const SerialPortRequestOptions*); + void GetPort(const base::UnguessableToken& token, + device::mojom::blink::SerialPortRequest request); void Trace(Visitor*) override; private:
diff --git a/third_party/blink/renderer/modules/serial/serial_port.cc b/third_party/blink/renderer/modules/serial/serial_port.cc index e46dccb..bf98e94 100644 --- a/third_party/blink/renderer/modules/serial/serial_port.cc +++ b/third_party/blink/renderer/modules/serial/serial_port.cc
@@ -3,36 +3,43 @@ // found in the LICENSE file. #include "third_party/blink/renderer/modules/serial/serial_port.h" + #include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/streams/readable_stream.h" +#include "third_party/blink/renderer/core/streams/writable_stream.h" +#include "third_party/blink/renderer/modules/serial/serial.h" namespace blink { -SerialPort::SerialPort(mojom::blink::SerialPortInfoPtr info) - : info_(std::move(info)) {} +SerialPort::SerialPort(Serial* parent, mojom::blink::SerialPortInfoPtr info) + : info_(std::move(info)), parent_(parent) {} SerialPort::~SerialPort() = default; -ReadableStream* SerialPort::in() { - return nullptr; -} - -WritableStream* SerialPort::out() { - return nullptr; -} - ScriptPromise SerialPort::open(ScriptState* script_state, const SerialOptions* options) { - return ScriptPromise::RejectWithDOMException( - script_state, DOMException::Create(DOMExceptionCode::kNotSupportedError)); + if (port_) + return ScriptPromise::CastUndefined(script_state); + + parent_->GetPort(info_->token, mojo::MakeRequest(&port_)); + // TODO(https://crbug.com/884928): Call port_->Open() and initialize the + // ReadableStream and WritableStream. + return ScriptPromise::CastUndefined(script_state); } ScriptPromise SerialPort::close(ScriptState* script_state) { - return ScriptPromise::RejectWithDOMException( - script_state, DOMException::Create(DOMExceptionCode::kNotSupportedError)); + ContextDestroyed(); + return ScriptPromise::CastUndefined(script_state); } -const base::UnguessableToken& SerialPort::Token() const { - return info_->token; +void SerialPort::ContextDestroyed() { + // Release connection-related resources as quickly as possible. + port_.reset(); +} + +void SerialPort::Trace(Visitor* visitor) { + visitor->Trace(parent_); + ScriptWrappable::Trace(visitor); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/serial/serial_port.h b/third_party/blink/renderer/modules/serial/serial_port.h index 631f1d159..3073b99 100644 --- a/third_party/blink/renderer/modules/serial/serial_port.h +++ b/third_party/blink/renderer/modules/serial/serial_port.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_SERIAL_PORT_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_SERIAL_PORT_H_ +#include "services/device/public/mojom/serial.mojom-blink.h" #include "third_party/blink/public/mojom/serial/serial.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -18,6 +19,7 @@ class ReadableStream; class ScriptState; +class Serial; class SerialOptions; class WritableStream; @@ -25,19 +27,26 @@ DEFINE_WRAPPERTYPEINFO(); public: - explicit SerialPort(mojom::blink::SerialPortInfoPtr info); + explicit SerialPort(Serial* parent, mojom::blink::SerialPortInfoPtr info); ~SerialPort() override; - ReadableStream* in(); - WritableStream* out(); + // Web-exposed functions + ReadableStream* in() const { return nullptr; } + WritableStream* out() const { return nullptr; } ScriptPromise open(ScriptState*, const SerialOptions* options); ScriptPromise close(ScriptState*); - const base::UnguessableToken& Token() const; + const base::UnguessableToken& token() const { return info_->token; } + + void ContextDestroyed(); + void Trace(Visitor*) override; private: mojom::blink::SerialPortInfoPtr info_; + device::mojom::blink::SerialPortPtr port_; + + Member<Serial> parent_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/shapedetection/OWNERS b/third_party/blink/renderer/modules/shapedetection/OWNERS index 2a126b8..f479be2 100644 --- a/third_party/blink/renderer/modules/shapedetection/OWNERS +++ b/third_party/blink/renderer/modules/shapedetection/OWNERS
@@ -1,8 +1,10 @@ -mcasas@chromium.org reillyg@chromium.org +# Original (legacy) owner. +mcasas@chromium.org + per-file *_type_converter*.*=set noparent per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS -# COMPONENT: Blink>ImageCapture -# TEAM: media-dev@chromium.org +# COMPONENT: Blink>ShapeDetection +# TEAM: device-dev@chromium.org
diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer.cc b/third_party/blink/renderer/modules/webaudio/audio_buffer.cc index dedd3a0..fd85f8425 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_buffer.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_buffer.cc
@@ -128,21 +128,6 @@ return buffer; } -AudioBuffer* AudioBuffer::CreateFromAudioFileData(const void* data, - size_t data_size, - bool mix_to_mono, - float sample_rate) { - scoped_refptr<AudioBus> bus = - CreateBusFromInMemoryAudioFile(data, data_size, mix_to_mono, sample_rate); - if (bus) { - AudioBuffer* buffer = MakeGarbageCollected<AudioBuffer>(bus.get()); - if (buffer->CreatedSuccessfully(bus->NumberOfChannels())) - return buffer; - } - - return nullptr; -} - AudioBuffer* AudioBuffer::CreateFromAudioBus(AudioBus* bus) { if (!bus) return nullptr;
diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer.h b/third_party/blink/renderer/modules/webaudio/audio_buffer.h index 8934714e..1bf9cff 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_buffer.h +++ b/third_party/blink/renderer/modules/webaudio/audio_buffer.h
@@ -66,12 +66,6 @@ uint32_t number_of_frames, float sample_rate); - // Returns 0 if data is not a valid audio file. - static AudioBuffer* CreateFromAudioFileData(const void* data, - size_t data_size, - bool mix_to_mono, - float sample_rate); - static AudioBuffer* CreateFromAudioBus(AudioBus*); explicit AudioBuffer(AudioBus*);
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc b/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc index f7f30c3..d2db7c7 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc
@@ -4,15 +4,65 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_bind_group.h" +#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group_descriptor.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_sampler.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_texture_view.h" namespace blink { +DawnBindGroupBinding AsDawnType(const GPUBindGroupBinding* webgpu_binding) { + DawnBindGroupBinding dawn_binding = {}; + + dawn_binding.binding = webgpu_binding->binding(); + + if (webgpu_binding->resource().IsGPUBufferBinding()) { + GPUBufferBinding* buffer = + webgpu_binding->resource().GetAsGPUBufferBinding(); + dawn_binding.offset = buffer->offset(); + dawn_binding.size = buffer->size(); + dawn_binding.buffer = AsDawnType(buffer->buffer()); + + } else if (webgpu_binding->resource().IsGPUSampler()) { + GPUSampler* sampler = webgpu_binding->resource().GetAsGPUSampler(); + dawn_binding.sampler = AsDawnType(sampler); + + } else if (webgpu_binding->resource().IsGPUTextureView()) { + GPUTextureView* texture_view = + webgpu_binding->resource().GetAsGPUTextureView(); + dawn_binding.textureView = AsDawnType(texture_view); + + } else { + NOTREACHED(); + } + + return dawn_binding; +} + // static GPUBindGroup* GPUBindGroup::Create(GPUDevice* device, const GPUBindGroupDescriptor* webgpu_desc) { - NOTIMPLEMENTED(); - return nullptr; + DCHECK(device); + DCHECK(webgpu_desc); + + uint32_t binding_count = + static_cast<uint32_t>(webgpu_desc->bindings().size()); + + std::unique_ptr<DawnBindGroupBinding[]> bindings = + binding_count != 0 ? AsDawnType(webgpu_desc->bindings()) : nullptr; + + DawnBindGroupDescriptor dawn_desc; + dawn_desc.nextInChain = nullptr; + dawn_desc.layout = AsDawnType(webgpu_desc->layout()); + dawn_desc.bindingCount = binding_count; + dawn_desc.bindings = bindings.get(); + + return MakeGarbageCollected<GPUBindGroup>( + device, device->GetProcs().deviceCreateBindGroup(device->GetHandle(), + &dawn_desc)); } GPUBindGroup::GPUBindGroup(GPUDevice* device, DawnBindGroup bind_group)
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc index d35d830..ebb2e552 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" namespace blink { @@ -28,4 +30,25 @@ GetProcs().computePassEncoderRelease(GetHandle()); } +void GPUComputePassEncoder::setBindGroup( + uint32_t index, + GPUBindGroup* bindGroup, + const Vector<uint64_t>& dynamicOffsets) { + GetProcs().computePassEncoderSetBindGroup( + GetHandle(), index, bindGroup->GetHandle(), dynamicOffsets.size(), + dynamicOffsets.data()); +} + +void GPUComputePassEncoder::setPipeline(GPUComputePipeline* pipeline) { + GetProcs().computePassEncoderSetPipeline(GetHandle(), pipeline->GetHandle()); +} + +void GPUComputePassEncoder::dispatch(uint32_t x, uint32_t y, uint32_t z) { + GetProcs().computePassEncoderDispatch(GetHandle(), x, y, z); +} + +void GPUComputePassEncoder::endPass() { + GetProcs().computePassEncoderEndPass(GetHandle()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h b/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h index a5eb355b..89efd4c 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h
@@ -9,6 +9,9 @@ namespace blink { +class GPUBindGroup; +class GPUComputePipeline; + class GPUComputePassEncoder : public DawnObject<DawnComputePassEncoder> { DEFINE_WRAPPERTYPEINFO(); @@ -21,7 +24,12 @@ ~GPUComputePassEncoder() override; // gpu_compute_pass_encoder.idl - // TODO(crbug.com/877147): implement GPUComputePassEncoder. + void setBindGroup(uint32_t index, + GPUBindGroup* bindGroup, + const Vector<uint64_t>& dynamicOffsets); + void setPipeline(GPUComputePipeline* pipeline); + void dispatch(uint32_t x, uint32_t y, uint32_t z); + void endPass(); private: DISALLOW_COPY_AND_ASSIGN(GPUComputePassEncoder);
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.idl b/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.idl index 15490c0e..8b05aaa 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.idl
@@ -7,4 +7,14 @@ [ RuntimeEnabled=WebGPU ] interface GPUComputePassEncoder { + void setBindGroup(unsigned long index, + GPUBindGroup bindGroup, + optional sequence<unsigned long long> dynamicOffsets = []); + void setPipeline(GPUComputePipeline pipeline); + + void dispatch(unsigned long x, + optional unsigned long y = 1, + optional unsigned long z = 1); + + void endPass(); };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc index 75f0eae..07f6100f 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc
@@ -4,7 +4,12 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h" +#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_color.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.h" namespace blink { @@ -28,4 +33,88 @@ GetProcs().renderPassEncoderRelease(GetHandle()); } +void GPURenderPassEncoder::setBindGroup( + uint32_t index, + GPUBindGroup* bindGroup, + const Vector<uint64_t>& dynamicOffsets) { + GetProcs().renderPassEncoderSetBindGroup( + GetHandle(), index, bindGroup->GetHandle(), dynamicOffsets.size(), + dynamicOffsets.data()); +} + +void GPURenderPassEncoder::setPipeline(GPURenderPipeline* pipeline) { + GetProcs().renderPassEncoderSetPipeline(GetHandle(), pipeline->GetHandle()); +} + +void GPURenderPassEncoder::setBlendColor(GPUColor* color) { + DawnColor dawn_color = AsDawnType(color); + GetProcs().renderPassEncoderSetBlendColor(GetHandle(), &dawn_color); +} + +void GPURenderPassEncoder::setStencilReference(uint32_t reference) { + GetProcs().renderPassEncoderSetStencilReference(GetHandle(), reference); +} + +void GPURenderPassEncoder::setViewport(float x, + float y, + float width, + float height, + float minDepth, + float maxDepth) { + // TODO(crbug.com/dawn/53): Implement setViewport in Dawn. + NOTIMPLEMENTED(); +} + +void GPURenderPassEncoder::setScissorRect(uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height) { + GetProcs().renderPassEncoderSetScissorRect(GetHandle(), x, y, width, height); +} + +void GPURenderPassEncoder::setIndexBuffer(GPUBuffer* buffer, uint64_t offset) { + GetProcs().renderPassEncoderSetIndexBuffer(GetHandle(), buffer->GetHandle(), + offset); +} + +void GPURenderPassEncoder::setVertexBuffers( + uint32_t startSlot, + const HeapVector<Member<GPUBuffer>>& buffers, + const Vector<uint64_t>& offsets, + ExceptionState& exception_state) { + if (buffers.size() != offsets.size()) { + exception_state.ThrowRangeError( + "buffers array and offsets array must be the same length"); + return; + } + + std::unique_ptr<DawnBuffer[]> dawn_buffers = AsDawnType(buffers); + + GetProcs().renderPassEncoderSetVertexBuffers( + GetHandle(), startSlot, buffers.size(), dawn_buffers.get(), + offsets.data()); +} + +void GPURenderPassEncoder::draw(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) { + GetProcs().renderPassEncoderDraw(GetHandle(), vertexCount, instanceCount, + firstVertex, firstInstance); +} + +void GPURenderPassEncoder::drawIndexed(uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t baseVertex, + uint32_t firstInstance) { + GetProcs().renderPassEncoderDrawIndexed(GetHandle(), indexCount, + instanceCount, firstIndex, baseVertex, + firstInstance); +} + +void GPURenderPassEncoder::endPass() { + GetProcs().renderPassEncoderEndPass(GetHandle()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h index fb41c63..f4de0d3 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h
@@ -6,9 +6,15 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_RENDER_PASS_ENCODER_H_ #include "third_party/blink/renderer/modules/webgpu/dawn_object.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" namespace blink { +class GPUBindGroup; +class GPUBuffer; +class GPUColor; +class GPURenderPipeline; + class GPURenderPassEncoder : public DawnObject<DawnRenderPassEncoder> { DEFINE_WRAPPERTYPEINFO(); @@ -21,7 +27,36 @@ ~GPURenderPassEncoder() override; // gpu_render_pass_encoder.idl - // TODO(crbug.com/877147): implement GPURenderPassEncoder. + void setBindGroup(uint32_t index, + GPUBindGroup* bindGroup, + const Vector<uint64_t>& dynamicOffsets); + void setPipeline(GPURenderPipeline* pipeline); + + void setBlendColor(GPUColor* color); + void setStencilReference(uint32_t reference); + void setViewport(float x, + float y, + float width, + float height, + float minDepth, + float maxDepth); + void setScissorRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height); + void setIndexBuffer(GPUBuffer* buffer, uint64_t offset); + void setVertexBuffers(uint32_t startSlot, + const HeapVector<Member<GPUBuffer>>& buffers, + const Vector<uint64_t>& offsets, + ExceptionState& exception_state); + void draw(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance); + void drawIndexed(uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t baseVertex, + uint32_t firstInstance); + + void endPass(); private: DISALLOW_COPY_AND_ASSIGN(GPURenderPassEncoder);
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.idl b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.idl index a607322..5e7a7a3 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.idl
@@ -7,4 +7,29 @@ [ RuntimeEnabled=WebGPU ] interface GPURenderPassEncoder { + void setBindGroup(unsigned long index, + GPUBindGroup bindGroup, + optional sequence<unsigned long long> dynamicOffsets = []); + void setPipeline(GPURenderPipeline pipeline); + + void setBlendColor(GPUColor color); + void setStencilReference(unsigned long reference); + void setViewport(float x, float y, + float width, float height, + float minDepth, float maxDepth); + void setScissorRect(unsigned long x, unsigned long y, + unsigned long width, unsigned long height); + void setIndexBuffer(GPUBuffer buffer, unsigned long long offset); + [RaisesException] void setVertexBuffers(unsigned long startSlot, + sequence<GPUBuffer> buffers, + sequence<unsigned long long> offsets); + void draw(unsigned long vertexCount, unsigned long instanceCount, + unsigned long firstVertex, + unsigned long firstInstance); + void drawIndexed(unsigned long indexCount, unsigned long instanceCount, + unsigned long firstIndex, + long baseVertex, + unsigned long firstInstance); + + void endPass(); };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc b/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc index ebeff2f..80cc70f 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc
@@ -4,15 +4,48 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_sampler.h" +#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_sampler_descriptor.h" namespace blink { +namespace { + +DawnSamplerDescriptor AsDawnType(const GPUSamplerDescriptor* webgpu_desc) { + DCHECK(webgpu_desc); + + DawnSamplerDescriptor dawn_desc; + dawn_desc.nextInChain = nullptr; + dawn_desc.addressModeU = + AsDawnEnum<DawnAddressMode>(webgpu_desc->addressModeU()); + dawn_desc.addressModeV = + AsDawnEnum<DawnAddressMode>(webgpu_desc->addressModeV()); + dawn_desc.addressModeW = + AsDawnEnum<DawnAddressMode>(webgpu_desc->addressModeW()); + dawn_desc.magFilter = AsDawnEnum<DawnFilterMode>(webgpu_desc->magFilter()); + dawn_desc.minFilter = AsDawnEnum<DawnFilterMode>(webgpu_desc->minFilter()); + dawn_desc.mipmapFilter = + AsDawnEnum<DawnFilterMode>(webgpu_desc->mipmapFilter()); + dawn_desc.lodMinClamp = webgpu_desc->lodMinClamp(); + dawn_desc.lodMaxClamp = webgpu_desc->lodMaxClamp(); + dawn_desc.compareFunction = + AsDawnEnum<DawnCompareFunction>(webgpu_desc->compareFunction()); + + return dawn_desc; +} + +} // anonymous namespace + // static GPUSampler* GPUSampler::Create(GPUDevice* device, const GPUSamplerDescriptor* webgpu_desc) { - NOTIMPLEMENTED(); - return nullptr; + DCHECK(device); + DCHECK(webgpu_desc); + DawnSamplerDescriptor dawn_desc = AsDawnType(webgpu_desc); + return MakeGarbageCollected<GPUSampler>( + device, + device->GetProcs().deviceCreateSampler(device->GetHandle(), &dawn_desc)); } GPUSampler::GPUSampler(GPUDevice* device, DawnSampler sampler)
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index 071f81d..ff0881a 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -648,4 +648,8 @@ RuntimeEnabledFeatures::SetSignedExchangeSubresourcePrefetchEnabled(enable); } +void WebRuntimeFeatures::EnableIdleDetection(bool enable) { + RuntimeEnabledFeatures::SetIdleDetectionEnabled(enable); +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/gradient_generated_image.h b/third_party/blink/renderer/platform/graphics/gradient_generated_image.h index eeadaf62..d0df7078 100644 --- a/third_party/blink/renderer/platform/graphics/gradient_generated_image.h +++ b/third_party/blink/renderer/platform/graphics/gradient_generated_image.h
@@ -44,6 +44,10 @@ ~GradientGeneratedImage() override = default; bool ApplyShader(PaintFlags&, const SkMatrix&) override; + DarkModeClassification ClassifyImageForDarkMode( + const FloatRect& src_rect) override { + return DarkModeClassification::kApplyDarkModeFilter; + } protected: void Draw(cc::PaintCanvas*,
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.cc b/third_party/blink/renderer/platform/graphics/graphics_context.cc index 2adf55d..73b15d19 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_context.cc +++ b/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -951,6 +951,8 @@ image_flags.setColor(SK_ColorBLACK); image_flags.setFilterQuality( ComputeFilterQuality(image, dest.Rect(), src_rect)); + if (ShouldApplyDarkModeFilterToImage(*image, src_rect)) + image_flags.setColorFilter(dark_mode_filter_); bool use_shader = (visible_src == src_rect) && (respect_orientation == kDoNotRespectImageOrientation);
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc b/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc index 75670d7..4602b76 100644 --- a/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc +++ b/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
@@ -172,10 +172,18 @@ void VideoFrameSubmitter::OnBeginFrame( const viz::BeginFrameArgs& args, - WTF::HashMap<uint32_t, ::gfx::mojom::blink::PresentationFeedbackPtr>) { + WTF::HashMap<uint32_t, ::gfx::mojom::blink::PresentationFeedbackPtr> + feedbacks) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); TRACE_EVENT0("media", "VideoFrameSubmitter::OnBeginFrame"); + for (const auto& pair : feedbacks) { + if (viz::FrameTokenGT(pair.key, *next_frame_token_)) + continue; + TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0("media", "VideoFrameSubmitter", + pair.key, pair.value->timestamp); + } + // Don't call UpdateCurrentFrame() for MISSED BeginFrames. Also don't call it // after StopRendering() has been called (forbidden by API contract). viz::BeginFrameAck current_begin_frame_ack(args, false); @@ -483,6 +491,10 @@ compositor_frame.metadata.begin_frame_ack = begin_frame_ack; compositor_frame.metadata.frame_token = ++next_frame_token_; + TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0("media", "VideoFrameSubmitter", + *next_frame_token_, + base::TimeTicks::Now()); + // We don't assume that the ack is marked as having damage. However, we're // definitely emitting a CompositorFrame that damages the entire surface. compositor_frame.metadata.begin_frame_ack.has_damage = true;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_error.cc b/third_party/blink/renderer/platform/loader/fetch/resource_error.cc index ca115e69..bee7c5e 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_error.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_error.cc
@@ -38,7 +38,7 @@ namespace { constexpr char kThrottledErrorDescription[] = - "Request throttled. Visit http://dev.chromium.org/throttling for more " + "Request throttled. Visit https://dev.chromium.org/throttling for more " "information."; } // namespace
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 02b44ad9..76f29c4 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -6187,11 +6187,6 @@ crbug.com/946323 [ Mac ] editing/caret/caret-painting-low-dpi.html [ Failure Pass ] crbug.com/946624 virtual/user-activation-v2/http/tests/media/autoplay/document-user-activation-cross-origin-feature-policy-header.html [ Failure Pass ] -#Imperceptible changes to Skia GPU blur -skbug.com/8942 virtual/disable-blink-gen-property-trees/compositing/masks/mask-with-added-filters.html [ Failure Pass ] -skbug.com/8942 virtual/gpu/fast/canvas/canvas-shadow-source-in.html [ Failure Pass ] -skbug.com/8942 compositing/masks/mask-with-added-filters.html [ Failure Pass ] - # Sheriff 2019-03-28 crbug.com/946890 external/wpt/html/semantics/embedded-content/media-elements/location-of-the-media-resource/currentSrc.html [ Failure Pass Crash ] crbug.com/946990 http/tests/devtools/application-panel/storage-view-reports-quota.js [ Pass Timeout ] @@ -6256,3 +6251,6 @@ crbug.com/946701 [ Win7 ] virtual/streams-native/http/tests/fetch/serviceworker-proxied/thorough/auth-base-https-other-https.html [ Pass Timeout ] crbug.com/950222 [ Win7 ] virtual/streams-native/http/tests/fetch/serviceworker-proxied/thorough/auth.html [ Pass Timeout ] crbug.com/947670 [ Win7 ] virtual/streams-native/http/tests/fetch/serviceworker-proxied/thorough/cors-preflight2-base-https-other-https.html [ Pass Timeout ] + +# Sheriff 2019-04-09 +crbug.com/946335 [ Linux Mac ] fast/filesystem/file-writer-abort-depth.html [ Pass Crash ]
diff --git a/third_party/blink/web_tests/external/wpt/geolocation-API/OWNERS b/third_party/blink/web_tests/external/wpt/geolocation-API/OWNERS index 6d678d86..61e5876 100644 --- a/third_party/blink/web_tests/external/wpt/geolocation-API/OWNERS +++ b/third_party/blink/web_tests/external/wpt/geolocation-API/OWNERS
@@ -1,3 +1,5 @@ # TEAM: device-dev@chromium.org -# COMPONENT: Blink>Location +# COMPONENT: Blink>Geolocation + +# Original (legacy) owner. mcasas@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/html-media-capture/OWNERS b/third_party/blink/web_tests/external/wpt/html-media-capture/OWNERS index 5db6e74..d96b9bf 100644 --- a/third_party/blink/web_tests/external/wpt/html-media-capture/OWNERS +++ b/third_party/blink/web_tests/external/wpt/html-media-capture/OWNERS
@@ -1,4 +1,4 @@ # TEAM: media-dev@chromium.org # COMPONENT: Blink>ImageCapture + rijubrata.bhaumik@intel.com -mcasas@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-record/OWNERS b/third_party/blink/web_tests/external/wpt/mediacapture-record/OWNERS index 681555b..1b523fa 100644 --- a/third_party/blink/web_tests/external/wpt/mediacapture-record/OWNERS +++ b/third_party/blink/web_tests/external/wpt/mediacapture-record/OWNERS
@@ -1,3 +1,5 @@ # TEAM: media-dev@chromium.org # COMPONENT: Blink>MediaRecording + +# Original (legacy) owner. mcasas@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-connectionState.https-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-connectionState.https-expected.txt deleted file mode 100644 index 5613cd8b..0000000 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-connectionState.https-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -This is a testharness.js-based test. -PASS Initial connectionState should be new -PASS Closing the connection should set connectionState to closed -PASS connection with one data channel should eventually have connected connection state -FAIL connection with one data channel should eventually have transports in connected state assert_true: Expect ICE transport to be in connected or completed state expected true got false -PASS connectionState remains new when not adding remote ice candidates -PASS connectionState transitions to connected via connecting -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt index 8958c51..7ea53f6 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt
@@ -2,7 +2,7 @@ PASS Initial iceConnectionState should be new PASS Closing the connection should set iceConnectionState to closed PASS connection with one data channel should eventually have connected or completed connection state -FAIL connection with one data channel should eventually have connected connection state assert_equals: Expect ICE transport to be in checking state when iceConnectionState is checking expected "checking" but got "closed" +FAIL connection with one data channel should eventually have connected connection state assert_equals: Expect ICE transport to be in checking state when iceConnectionState is checking expected "checking" but got "connected" PASS ICE can connect in a recvonly usecase Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/media/controls-drag-timebar-rendering-expected-mismatch.html b/third_party/blink/web_tests/media/controls-drag-timebar-rendering-expected-mismatch.html deleted file mode 100644 index e942443..0000000 --- a/third_party/blink/web_tests/media/controls-drag-timebar-rendering-expected-mismatch.html +++ /dev/null
@@ -1,29 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>drag timebar reftest</title> - <script src=media-controls.js></script> - <script src=media-file.js></script> - </head> - <body> - <video controls></video> - <script> - if (window.testRunner) - testRunner.waitUntilDone(); - - var video = document.querySelector("video"); - video.src = "content/test.ogv"; - video.addEventListener("loadeddata", function() - { - if (window.eventSender) { - var coords = mediaControlsButtonCoordinates(video, "timeline"); - eventSender.mouseMoveTo(coords[0], coords[1]); - eventSender.mouseDown(); - } - - if (window.testRunner) - testRunner.notifyDone(); - }); - </script> - </body> -</html>
diff --git a/third_party/blink/web_tests/media/controls-drag-timebar-rendering.html b/third_party/blink/web_tests/media/controls-drag-timebar-rendering.html deleted file mode 100644 index 9c53639..0000000 --- a/third_party/blink/web_tests/media/controls-drag-timebar-rendering.html +++ /dev/null
@@ -1,31 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>drag timebar reftest</title> - <script src=media-controls.js></script> - <script src=media-file.js></script> - </head> - <body> - <video controls></video> - <script> - if (window.testRunner) - testRunner.waitUntilDone(); - - var video = document.querySelector("video"); - video.src = "content/test.ogv"; - video.addEventListener("loadeddata", function() - { - video.play(); - - if (window.eventSender) { - var coords = mediaControlsButtonCoordinates(video, "timeline"); - eventSender.mouseMoveTo(coords[0], coords[1]); - eventSender.mouseDown(); - } - - if (window.testRunner) - testRunner.notifyDone(); - }); - </script> - </body> -</html>
diff --git a/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt b/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt index 9f880cef..4ab9a280 100644 --- a/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt
@@ -24,7 +24,7 @@ "drawsContent": false }, { - "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small test-mode phase-ready state-stopped'", + "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small test-mode phase-ready state-scrubbing'", "position": [8, 8], "bounds": [320, 240] },
diff --git a/third_party/blink/web_tests/platform/linux/compositing/masks/mask-with-added-filters-expected.png b/third_party/blink/web_tests/platform/linux/compositing/masks/mask-with-added-filters-expected.png index 5bb69db..b5f6655 100644 --- a/third_party/blink/web_tests/platform/linux/compositing/masks/mask-with-added-filters-expected.png +++ b/third_party/blink/web_tests/platform/linux/compositing/masks/mask-with-added-filters-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/filters/effect-contrast-hw-expected.png b/third_party/blink/web_tests/platform/linux/css3/filters/effect-contrast-hw-expected.png deleted file mode 100644 index bece2a8..0000000 --- a/third_party/blink/web_tests/platform/linux/css3/filters/effect-contrast-hw-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/disable-blink-gen-property-trees/compositing/masks/mask-with-added-filters-expected.png b/third_party/blink/web_tests/platform/linux/virtual/disable-blink-gen-property-trees/compositing/masks/mask-with-added-filters-expected.png index 23f446e..1ae39c5 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/disable-blink-gen-property-trees/compositing/masks/mask-with-added-filters-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/disable-blink-gen-property-trees/compositing/masks/mask-with-added-filters-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/gpu/fast/canvas/canvas-shadow-source-in-expected.png b/third_party/blink/web_tests/platform/linux/virtual/gpu/fast/canvas/canvas-shadow-source-in-expected.png index 623926f..018238ce 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/gpu/fast/canvas/canvas-shadow-source-in-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/gpu/fast/canvas/canvas-shadow-source-in-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/compositing/masks/mask-with-added-filters-expected.png b/third_party/blink/web_tests/platform/mac/compositing/masks/mask-with-added-filters-expected.png index 2a3efbb..eb9f5b8 100644 --- a/third_party/blink/web_tests/platform/mac/compositing/masks/mask-with-added-filters-expected.png +++ b/third_party/blink/web_tests/platform/mac/compositing/masks/mask-with-added-filters-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt index e90e866..a2be4ec 100644 --- a/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt +++ b/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt
@@ -76,7 +76,7 @@ "drawsContent": false }, { - "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small phase-ready state-stopped'", + "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small phase-ready state-scrubbing'", "position": [8, 8], "bounds": [352, 288] },
diff --git a/third_party/blink/web_tests/platform/mac/virtual/gpu/fast/canvas/canvas-shadow-source-in-expected.png b/third_party/blink/web_tests/platform/mac/virtual/gpu/fast/canvas/canvas-shadow-source-in-expected.png index 3f829a1..15e7a7b 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/gpu/fast/canvas/canvas-shadow-source-in-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/gpu/fast/canvas/canvas-shadow-source-in-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/compositing/masks/mask-with-added-filters-expected.png b/third_party/blink/web_tests/platform/win/compositing/masks/mask-with-added-filters-expected.png index f130d554..ac55d93 100644 --- a/third_party/blink/web_tests/platform/win/compositing/masks/mask-with-added-filters-expected.png +++ b/third_party/blink/web_tests/platform/win/compositing/masks/mask-with-added-filters-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt index 1737809..fd66c2f 100644 --- a/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt +++ b/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt
@@ -76,7 +76,7 @@ "drawsContent": false }, { - "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small phase-ready state-stopped'", + "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small phase-ready state-scrubbing'", "position": [8, 8], "bounds": [352, 288] },
diff --git a/third_party/blink/web_tests/platform/win/virtual/gpu/fast/canvas/canvas-shadow-source-in-expected.png b/third_party/blink/web_tests/platform/win/virtual/gpu/fast/canvas/canvas-shadow-source-in-expected.png index 21da250..dd42c3e4 100644 --- a/third_party/blink/web_tests/platform/win/virtual/gpu/fast/canvas/canvas-shadow-source-in-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/gpu/fast/canvas/canvas-shadow-source-in-expected.png Binary files differ
diff --git a/third_party/libcxx-pretty-printers/printers.py b/third_party/libcxx-pretty-printers/printers.py index e59493f1..d975ef0 100644 --- a/third_party/libcxx-pretty-printers/printers.py +++ b/third_party/libcxx-pretty-printers/printers.py
@@ -602,7 +602,7 @@ # return 'set' -class RbtreeIterator: +class RbtreeIterator(Iterator): def __init__(self, rbtree): self.node = rbtree['__begin_node_'] self.size = pair_to_tuple(rbtree['__pair3_'])[0] @@ -705,7 +705,7 @@ return '[%s] %s' % (vals[0], vals[1]) -class HashtableIterator: +class HashtableIterator(Iterator): def __init__(self, hashtable): self.node = pair_to_tuple(hashtable['__p1_'])[0]['__next_'] self.size = pair_to_tuple(hashtable['__p2_'])[0]
diff --git a/third_party/libwebm/OWNERS b/third_party/libwebm/OWNERS index 43542744..a385efb 100644 --- a/third_party/libwebm/OWNERS +++ b/third_party/libwebm/OWNERS
@@ -1,9 +1,11 @@ # The following OWNERS refer to libwebm Chromium integration. emircan@chromium.org -mcasas@chromium.org niklase@chromium.org # The following OWNER refer to libwebm content. tomfinegan@chromium.org +# Original (legacy) owner. +mcasas@chromium.org + # COMPONENT: Blink>MediaRecording
diff --git a/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/arm64/ie_bho_idl.dlldata.c b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/arm64/ie_bho_idl.dlldata.c new file mode 100644 index 0000000..5d3e2a0 --- /dev/null +++ b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/arm64/ie_bho_idl.dlldata.c
@@ -0,0 +1,38 @@ +/********************************************************* + DllData file -- generated by MIDL compiler + + DO NOT ALTER THIS FILE + + This file is regenerated by MIDL on every IDL file compile. + + To completely reconstruct this file, delete it and rerun MIDL + on all the IDL files in this DLL, specifying this file for the + /dlldata command line option + +*********************************************************/ + +#define PROXY_DELEGATION + +#include <rpcproxy.h> + +#ifdef __cplusplus +extern "C" { +#endif + +EXTERN_PROXY_FILE( ie_bho_idl ) + + +PROXYFILE_LIST_START +/* Start of list */ + REFERENCE_PROXY_FILE( ie_bho_idl ), +/* End of list */ +PROXYFILE_LIST_END + + +DLLDATA_ROUTINES( aProxyFileList, GET_DLL_CLSID ) + +#ifdef __cplusplus +} /*extern "C" */ +#endif + +/* end of generated dlldata file */
diff --git a/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/arm64/ie_bho_idl.h b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/arm64/ie_bho_idl.h new file mode 100644 index 0000000..d1b4f0f2 --- /dev/null +++ b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/arm64/ie_bho_idl.h
@@ -0,0 +1,225 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 8.xx.xxxx */ +/* at a redacted point in time + */ +/* Compiler settings for ../../chrome/browser/browser_switcher/bho/ie_bho_idl.idl: + Oicf, W1, Zp8, env=Win64 (32b run), target_arch=ARM64 8.01.0622 + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the <rpcndr.h> version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of <rpcndr.h> +#endif /* __RPCNDR_H_VERSION__ */ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __ie_bho_idl_h__ +#define __ie_bho_idl_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __IBrowserSwitcherBHO_FWD_DEFINED__ +#define __IBrowserSwitcherBHO_FWD_DEFINED__ +typedef interface IBrowserSwitcherBHO IBrowserSwitcherBHO; + +#endif /* __IBrowserSwitcherBHO_FWD_DEFINED__ */ + + +#ifndef __BrowserSwitcherBHO_FWD_DEFINED__ +#define __BrowserSwitcherBHO_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class BrowserSwitcherBHO BrowserSwitcherBHO; +#else +typedef struct BrowserSwitcherBHO BrowserSwitcherBHO; +#endif /* __cplusplus */ + +#endif /* __BrowserSwitcherBHO_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +#ifndef __IBrowserSwitcherBHO_INTERFACE_DEFINED__ +#define __IBrowserSwitcherBHO_INTERFACE_DEFINED__ + +/* interface IBrowserSwitcherBHO */ +/* [unique][helpstring][nonextensible][dual][uuid][object] */ + + +EXTERN_C const IID IID_IBrowserSwitcherBHO; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("68CB9FDF-5E2E-41D7-A906-EF6C58AF0429") + IBrowserSwitcherBHO : public IDispatch + { + public: + }; + + +#else /* C style interface */ + + typedef struct IBrowserSwitcherBHOVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IBrowserSwitcherBHO * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IBrowserSwitcherBHO * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IBrowserSwitcherBHO * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IBrowserSwitcherBHO * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IBrowserSwitcherBHO * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IBrowserSwitcherBHO * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IBrowserSwitcherBHO * This, + /* [annotation][in] */ + _In_ DISPID dispIdMember, + /* [annotation][in] */ + _In_ REFIID riid, + /* [annotation][in] */ + _In_ LCID lcid, + /* [annotation][in] */ + _In_ WORD wFlags, + /* [annotation][out][in] */ + _In_ DISPPARAMS *pDispParams, + /* [annotation][out] */ + _Out_opt_ VARIANT *pVarResult, + /* [annotation][out] */ + _Out_opt_ EXCEPINFO *pExcepInfo, + /* [annotation][out] */ + _Out_opt_ UINT *puArgErr); + + END_INTERFACE + } IBrowserSwitcherBHOVtbl; + + interface IBrowserSwitcherBHO + { + CONST_VTBL struct IBrowserSwitcherBHOVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IBrowserSwitcherBHO_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IBrowserSwitcherBHO_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IBrowserSwitcherBHO_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IBrowserSwitcherBHO_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IBrowserSwitcherBHO_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IBrowserSwitcherBHO_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IBrowserSwitcherBHO_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IBrowserSwitcherBHO_INTERFACE_DEFINED__ */ + + + +#ifndef __BrowserSwitcherLib_LIBRARY_DEFINED__ +#define __BrowserSwitcherLib_LIBRARY_DEFINED__ + +/* library BrowserSwitcherLib */ +/* [helpstring][version][uuid] */ + + +EXTERN_C const IID LIBID_BrowserSwitcherLib; + +EXTERN_C const CLSID CLSID_BrowserSwitcherBHO; + +#ifdef __cplusplus + +class DECLSPEC_UUID("08B5789A-BD8E-4DAE-85DF-EF792C658B86") +BrowserSwitcherBHO; +#endif +#endif /* __BrowserSwitcherLib_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + +
diff --git a/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/arm64/ie_bho_idl.tlb b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/arm64/ie_bho_idl.tlb new file mode 100644 index 0000000..9b0ffebf --- /dev/null +++ b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/arm64/ie_bho_idl.tlb Binary files differ
diff --git a/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/arm64/ie_bho_idl_i.c b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/arm64/ie_bho_idl_i.c new file mode 100644 index 0000000..5e09afe --- /dev/null +++ b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/arm64/ie_bho_idl_i.c
@@ -0,0 +1,85 @@ + + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + + /* File created by MIDL compiler version 8.xx.xxxx */ +/* at a redacted point in time + */ +/* Compiler settings for ../../chrome/browser/browser_switcher/bho/ie_bho_idl.idl: + Oicf, W1, Zp8, env=Win64 (32b run), target_arch=ARM64 8.01.0622 + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +#ifdef __cplusplus +extern "C"{ +#endif + + +#include <rpc.h> +#include <rpcndr.h> + +#ifdef _MIDL_USE_GUIDDEF_ + +#ifndef INITGUID +#define INITGUID +#include <guiddef.h> +#undef INITGUID +#else +#include <guiddef.h> +#endif + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) + +#else // !_MIDL_USE_GUIDDEF_ + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + EXTERN_C __declspec(selectany) const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +#endif // !_MIDL_USE_GUIDDEF_ + +MIDL_DEFINE_GUID(IID, IID_IBrowserSwitcherBHO,0x68CB9FDF,0x5E2E,0x41D7,0xA9,0x06,0xEF,0x6C,0x58,0xAF,0x04,0x29); + + +MIDL_DEFINE_GUID(IID, LIBID_BrowserSwitcherLib,0xE042FD04,0x3D7E,0x4A3A,0x9B,0x9E,0xD4,0xD9,0xC7,0x0B,0x44,0x84); + + +MIDL_DEFINE_GUID(CLSID, CLSID_BrowserSwitcherBHO,0x08B5789A,0xBD8E,0x4DAE,0x85,0xDF,0xEF,0x79,0x2C,0x65,0x8B,0x86); + +#undef MIDL_DEFINE_GUID + +#ifdef __cplusplus +} +#endif + + +
diff --git a/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/arm64/ie_bho_idl_p.c b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/arm64/ie_bho_idl_p.c new file mode 100644 index 0000000..fda7541 --- /dev/null +++ b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/arm64/ie_bho_idl_p.c
@@ -0,0 +1,271 @@ + + +/* this ALWAYS GENERATED file contains the proxy stub code */ + + + /* File created by MIDL compiler version 8.xx.xxxx */ +/* at a redacted point in time + */ +/* Compiler settings for ../../chrome/browser/browser_switcher/bho/ie_bho_idl.idl: + Oicf, W1, Zp8, env=Win64 (32b run), target_arch=ARM64 8.01.0622 + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +/* @@MIDL_FILE_HEADING( ) */ + +#if defined(_M_ARM64) + + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif + +#pragma warning( disable: 4211 ) /* redefine extern to static */ +#pragma warning( disable: 4232 ) /* dllimport identity*/ +#pragma warning( disable: 4024 ) /* array to pointer mapping*/ +#pragma warning( disable: 4152 ) /* function/data pointer conversion in expression */ + +#define USE_STUBLESS_PROXY + + +/* verify that the <rpcproxy.h> version is high enough to compile this file*/ +#ifndef __REDQ_RPCPROXY_H_VERSION__ +#define __REQUIRED_RPCPROXY_H_VERSION__ 475 +#endif + + +#include "rpcproxy.h" +#ifndef __RPCPROXY_H_VERSION__ +#error this stub requires an updated version of <rpcproxy.h> +#endif /* __RPCPROXY_H_VERSION__ */ + + +#include "ie_bho_idl.h" + +#define TYPE_FORMAT_STRING_SIZE 3 +#define PROC_FORMAT_STRING_SIZE 1 +#define EXPR_FORMAT_STRING_SIZE 1 +#define TRANSMIT_AS_TABLE_SIZE 0 +#define WIRE_MARSHAL_TABLE_SIZE 0 + +typedef struct _ie_bho_idl_MIDL_TYPE_FORMAT_STRING + { + short Pad; + unsigned char Format[ TYPE_FORMAT_STRING_SIZE ]; + } ie_bho_idl_MIDL_TYPE_FORMAT_STRING; + +typedef struct _ie_bho_idl_MIDL_PROC_FORMAT_STRING + { + short Pad; + unsigned char Format[ PROC_FORMAT_STRING_SIZE ]; + } ie_bho_idl_MIDL_PROC_FORMAT_STRING; + +typedef struct _ie_bho_idl_MIDL_EXPR_FORMAT_STRING + { + long Pad; + unsigned char Format[ EXPR_FORMAT_STRING_SIZE ]; + } ie_bho_idl_MIDL_EXPR_FORMAT_STRING; + + +static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax = +{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}}; + + +extern const ie_bho_idl_MIDL_TYPE_FORMAT_STRING ie_bho_idl__MIDL_TypeFormatString; +extern const ie_bho_idl_MIDL_PROC_FORMAT_STRING ie_bho_idl__MIDL_ProcFormatString; +extern const ie_bho_idl_MIDL_EXPR_FORMAT_STRING ie_bho_idl__MIDL_ExprFormatString; + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +extern const MIDL_SERVER_INFO IBrowserSwitcherBHO_ServerInfo; +extern const MIDL_STUBLESS_PROXY_INFO IBrowserSwitcherBHO_ProxyInfo; + + + +#if !defined(__RPC_ARM64__) +#error Invalid build platform for this stub. +#endif + +static const ie_bho_idl_MIDL_PROC_FORMAT_STRING ie_bho_idl__MIDL_ProcFormatString = + { + 0, + { + + 0x0 + } + }; + +static const ie_bho_idl_MIDL_TYPE_FORMAT_STRING ie_bho_idl__MIDL_TypeFormatString = + { + 0, + { + NdrFcShort( 0x0 ), /* 0 */ + + 0x0 + } + }; + + +/* Object interface: IUnknown, ver. 0.0, + GUID={0x00000000,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: IDispatch, ver. 0.0, + GUID={0x00020400,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: IBrowserSwitcherBHO, ver. 0.0, + GUID={0x68CB9FDF,0x5E2E,0x41D7,{0xA9,0x06,0xEF,0x6C,0x58,0xAF,0x04,0x29}} */ + +#pragma code_seg(".orpc") +static const unsigned short IBrowserSwitcherBHO_FormatStringOffsetTable[] = + { + (unsigned short) -1, + (unsigned short) -1, + (unsigned short) -1, + (unsigned short) -1, + 0 + }; + +static const MIDL_STUBLESS_PROXY_INFO IBrowserSwitcherBHO_ProxyInfo = + { + &Object_StubDesc, + ie_bho_idl__MIDL_ProcFormatString.Format, + &IBrowserSwitcherBHO_FormatStringOffsetTable[-3], + 0, + 0, + 0 + }; + + +static const MIDL_SERVER_INFO IBrowserSwitcherBHO_ServerInfo = + { + &Object_StubDesc, + 0, + ie_bho_idl__MIDL_ProcFormatString.Format, + &IBrowserSwitcherBHO_FormatStringOffsetTable[-3], + 0, + 0, + 0, + 0}; +CINTERFACE_PROXY_VTABLE(7) _IBrowserSwitcherBHOProxyVtbl = +{ + 0, + &IID_IBrowserSwitcherBHO, + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + 0 /* IDispatch::GetTypeInfoCount */ , + 0 /* IDispatch::GetTypeInfo */ , + 0 /* IDispatch::GetIDsOfNames */ , + 0 /* IDispatch_Invoke_Proxy */ +}; + + +static const PRPC_STUB_FUNCTION IBrowserSwitcherBHO_table[] = +{ + STUB_FORWARDING_FUNCTION, + STUB_FORWARDING_FUNCTION, + STUB_FORWARDING_FUNCTION, + STUB_FORWARDING_FUNCTION +}; + +CInterfaceStubVtbl _IBrowserSwitcherBHOStubVtbl = +{ + &IID_IBrowserSwitcherBHO, + &IBrowserSwitcherBHO_ServerInfo, + 7, + &IBrowserSwitcherBHO_table[-3], + CStdStubBuffer_DELEGATING_METHODS +}; + +static const MIDL_STUB_DESC Object_StubDesc = + { + 0, + NdrOleAllocate, + NdrOleFree, + 0, + 0, + 0, + 0, + 0, + ie_bho_idl__MIDL_TypeFormatString.Format, + 1, /* -error bounds_check flag */ + 0x50002, /* Ndr library version */ + 0, + 0x801026e, /* MIDL Version 8.1.622 */ + 0, + 0, + 0, /* notify & notify_flag routine table */ + 0x1, /* MIDL flag */ + 0, /* cs routines */ + 0, /* proxy/server info */ + 0 + }; + +const CInterfaceProxyVtbl * const _ie_bho_idl_ProxyVtblList[] = +{ + ( CInterfaceProxyVtbl *) &_IBrowserSwitcherBHOProxyVtbl, + 0 +}; + +const CInterfaceStubVtbl * const _ie_bho_idl_StubVtblList[] = +{ + ( CInterfaceStubVtbl *) &_IBrowserSwitcherBHOStubVtbl, + 0 +}; + +PCInterfaceName const _ie_bho_idl_InterfaceNamesList[] = +{ + "IBrowserSwitcherBHO", + 0 +}; + +const IID * const _ie_bho_idl_BaseIIDList[] = +{ + &IID_IDispatch, + 0 +}; + + +#define _ie_bho_idl_CHECK_IID(n) IID_GENERIC_CHECK_IID( _ie_bho_idl, pIID, n) + +int __stdcall _ie_bho_idl_IID_Lookup( const IID * pIID, int * pIndex ) +{ + + if(!_ie_bho_idl_CHECK_IID(0)) + { + *pIndex = 0; + return 1; + } + + return 0; +} + +const ExtendedProxyFileInfo ie_bho_idl_ProxyFileInfo = +{ + (PCInterfaceProxyVtblList *) & _ie_bho_idl_ProxyVtblList, + (PCInterfaceStubVtblList *) & _ie_bho_idl_StubVtblList, + (const PCInterfaceName * ) & _ie_bho_idl_InterfaceNamesList, + (const IID ** ) & _ie_bho_idl_BaseIIDList, + & _ie_bho_idl_IID_Lookup, + 1, + 2, + 0, /* table of [async_uuid] interfaces */ + 0, /* Filler1 */ + 0, /* Filler2 */ + 0 /* Filler3 */ +}; +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif + + +#endif /* defined(_M_ARM64)*/ +
diff --git a/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x64/ie_bho_idl.dlldata.c b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x64/ie_bho_idl.dlldata.c new file mode 100644 index 0000000..5d3e2a0 --- /dev/null +++ b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x64/ie_bho_idl.dlldata.c
@@ -0,0 +1,38 @@ +/********************************************************* + DllData file -- generated by MIDL compiler + + DO NOT ALTER THIS FILE + + This file is regenerated by MIDL on every IDL file compile. + + To completely reconstruct this file, delete it and rerun MIDL + on all the IDL files in this DLL, specifying this file for the + /dlldata command line option + +*********************************************************/ + +#define PROXY_DELEGATION + +#include <rpcproxy.h> + +#ifdef __cplusplus +extern "C" { +#endif + +EXTERN_PROXY_FILE( ie_bho_idl ) + + +PROXYFILE_LIST_START +/* Start of list */ + REFERENCE_PROXY_FILE( ie_bho_idl ), +/* End of list */ +PROXYFILE_LIST_END + + +DLLDATA_ROUTINES( aProxyFileList, GET_DLL_CLSID ) + +#ifdef __cplusplus +} /*extern "C" */ +#endif + +/* end of generated dlldata file */
diff --git a/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x64/ie_bho_idl.h b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x64/ie_bho_idl.h new file mode 100644 index 0000000..520269c --- /dev/null +++ b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x64/ie_bho_idl.h
@@ -0,0 +1,225 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 8.xx.xxxx */ +/* at a redacted point in time + */ +/* Compiler settings for ../../chrome/browser/browser_switcher/bho/ie_bho_idl.idl: + Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.xx.xxxx + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the <rpcndr.h> version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of <rpcndr.h> +#endif /* __RPCNDR_H_VERSION__ */ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __ie_bho_idl_h__ +#define __ie_bho_idl_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __IBrowserSwitcherBHO_FWD_DEFINED__ +#define __IBrowserSwitcherBHO_FWD_DEFINED__ +typedef interface IBrowserSwitcherBHO IBrowserSwitcherBHO; + +#endif /* __IBrowserSwitcherBHO_FWD_DEFINED__ */ + + +#ifndef __BrowserSwitcherBHO_FWD_DEFINED__ +#define __BrowserSwitcherBHO_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class BrowserSwitcherBHO BrowserSwitcherBHO; +#else +typedef struct BrowserSwitcherBHO BrowserSwitcherBHO; +#endif /* __cplusplus */ + +#endif /* __BrowserSwitcherBHO_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +#ifndef __IBrowserSwitcherBHO_INTERFACE_DEFINED__ +#define __IBrowserSwitcherBHO_INTERFACE_DEFINED__ + +/* interface IBrowserSwitcherBHO */ +/* [unique][helpstring][nonextensible][dual][uuid][object] */ + + +EXTERN_C const IID IID_IBrowserSwitcherBHO; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("68CB9FDF-5E2E-41D7-A906-EF6C58AF0429") + IBrowserSwitcherBHO : public IDispatch + { + public: + }; + + +#else /* C style interface */ + + typedef struct IBrowserSwitcherBHOVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IBrowserSwitcherBHO * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IBrowserSwitcherBHO * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IBrowserSwitcherBHO * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IBrowserSwitcherBHO * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IBrowserSwitcherBHO * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IBrowserSwitcherBHO * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IBrowserSwitcherBHO * This, + /* [annotation][in] */ + _In_ DISPID dispIdMember, + /* [annotation][in] */ + _In_ REFIID riid, + /* [annotation][in] */ + _In_ LCID lcid, + /* [annotation][in] */ + _In_ WORD wFlags, + /* [annotation][out][in] */ + _In_ DISPPARAMS *pDispParams, + /* [annotation][out] */ + _Out_opt_ VARIANT *pVarResult, + /* [annotation][out] */ + _Out_opt_ EXCEPINFO *pExcepInfo, + /* [annotation][out] */ + _Out_opt_ UINT *puArgErr); + + END_INTERFACE + } IBrowserSwitcherBHOVtbl; + + interface IBrowserSwitcherBHO + { + CONST_VTBL struct IBrowserSwitcherBHOVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IBrowserSwitcherBHO_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IBrowserSwitcherBHO_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IBrowserSwitcherBHO_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IBrowserSwitcherBHO_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IBrowserSwitcherBHO_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IBrowserSwitcherBHO_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IBrowserSwitcherBHO_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IBrowserSwitcherBHO_INTERFACE_DEFINED__ */ + + + +#ifndef __BrowserSwitcherLib_LIBRARY_DEFINED__ +#define __BrowserSwitcherLib_LIBRARY_DEFINED__ + +/* library BrowserSwitcherLib */ +/* [helpstring][version][uuid] */ + + +EXTERN_C const IID LIBID_BrowserSwitcherLib; + +EXTERN_C const CLSID CLSID_BrowserSwitcherBHO; + +#ifdef __cplusplus + +class DECLSPEC_UUID("08B5789A-BD8E-4DAE-85DF-EF792C658B86") +BrowserSwitcherBHO; +#endif +#endif /* __BrowserSwitcherLib_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + +
diff --git a/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x64/ie_bho_idl.tlb b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x64/ie_bho_idl.tlb new file mode 100644 index 0000000..9b0ffebf --- /dev/null +++ b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x64/ie_bho_idl.tlb Binary files differ
diff --git a/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x64/ie_bho_idl_i.c b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x64/ie_bho_idl_i.c new file mode 100644 index 0000000..129edfa --- /dev/null +++ b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x64/ie_bho_idl_i.c
@@ -0,0 +1,85 @@ + + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + + /* File created by MIDL compiler version 8.xx.xxxx */ +/* at a redacted point in time + */ +/* Compiler settings for ../../chrome/browser/browser_switcher/bho/ie_bho_idl.idl: + Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.xx.xxxx + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +#ifdef __cplusplus +extern "C"{ +#endif + + +#include <rpc.h> +#include <rpcndr.h> + +#ifdef _MIDL_USE_GUIDDEF_ + +#ifndef INITGUID +#define INITGUID +#include <guiddef.h> +#undef INITGUID +#else +#include <guiddef.h> +#endif + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) + +#else // !_MIDL_USE_GUIDDEF_ + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + EXTERN_C __declspec(selectany) const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +#endif // !_MIDL_USE_GUIDDEF_ + +MIDL_DEFINE_GUID(IID, IID_IBrowserSwitcherBHO,0x68CB9FDF,0x5E2E,0x41D7,0xA9,0x06,0xEF,0x6C,0x58,0xAF,0x04,0x29); + + +MIDL_DEFINE_GUID(IID, LIBID_BrowserSwitcherLib,0xE042FD04,0x3D7E,0x4A3A,0x9B,0x9E,0xD4,0xD9,0xC7,0x0B,0x44,0x84); + + +MIDL_DEFINE_GUID(CLSID, CLSID_BrowserSwitcherBHO,0x08B5789A,0xBD8E,0x4DAE,0x85,0xDF,0xEF,0x79,0x2C,0x65,0x8B,0x86); + +#undef MIDL_DEFINE_GUID + +#ifdef __cplusplus +} +#endif + + +
diff --git a/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x64/ie_bho_idl_p.c b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x64/ie_bho_idl_p.c new file mode 100644 index 0000000..efd8c6f --- /dev/null +++ b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x64/ie_bho_idl_p.c
@@ -0,0 +1,271 @@ + + +/* this ALWAYS GENERATED file contains the proxy stub code */ + + + /* File created by MIDL compiler version 8.xx.xxxx */ +/* at a redacted point in time + */ +/* Compiler settings for ../../chrome/browser/browser_switcher/bho/ie_bho_idl.idl: + Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.xx.xxxx + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +/* @@MIDL_FILE_HEADING( ) */ + +#if defined(_M_AMD64) + + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif + +#pragma warning( disable: 4211 ) /* redefine extern to static */ +#pragma warning( disable: 4232 ) /* dllimport identity*/ +#pragma warning( disable: 4024 ) /* array to pointer mapping*/ +#pragma warning( disable: 4152 ) /* function/data pointer conversion in expression */ + +#define USE_STUBLESS_PROXY + + +/* verify that the <rpcproxy.h> version is high enough to compile this file*/ +#ifndef __REDQ_RPCPROXY_H_VERSION__ +#define __REQUIRED_RPCPROXY_H_VERSION__ 475 +#endif + + +#include "rpcproxy.h" +#ifndef __RPCPROXY_H_VERSION__ +#error this stub requires an updated version of <rpcproxy.h> +#endif /* __RPCPROXY_H_VERSION__ */ + + +#include "ie_bho_idl.h" + +#define TYPE_FORMAT_STRING_SIZE 3 +#define PROC_FORMAT_STRING_SIZE 1 +#define EXPR_FORMAT_STRING_SIZE 1 +#define TRANSMIT_AS_TABLE_SIZE 0 +#define WIRE_MARSHAL_TABLE_SIZE 0 + +typedef struct _ie_bho_idl_MIDL_TYPE_FORMAT_STRING + { + short Pad; + unsigned char Format[ TYPE_FORMAT_STRING_SIZE ]; + } ie_bho_idl_MIDL_TYPE_FORMAT_STRING; + +typedef struct _ie_bho_idl_MIDL_PROC_FORMAT_STRING + { + short Pad; + unsigned char Format[ PROC_FORMAT_STRING_SIZE ]; + } ie_bho_idl_MIDL_PROC_FORMAT_STRING; + +typedef struct _ie_bho_idl_MIDL_EXPR_FORMAT_STRING + { + long Pad; + unsigned char Format[ EXPR_FORMAT_STRING_SIZE ]; + } ie_bho_idl_MIDL_EXPR_FORMAT_STRING; + + +static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax = +{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}}; + + +extern const ie_bho_idl_MIDL_TYPE_FORMAT_STRING ie_bho_idl__MIDL_TypeFormatString; +extern const ie_bho_idl_MIDL_PROC_FORMAT_STRING ie_bho_idl__MIDL_ProcFormatString; +extern const ie_bho_idl_MIDL_EXPR_FORMAT_STRING ie_bho_idl__MIDL_ExprFormatString; + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +extern const MIDL_SERVER_INFO IBrowserSwitcherBHO_ServerInfo; +extern const MIDL_STUBLESS_PROXY_INFO IBrowserSwitcherBHO_ProxyInfo; + + + +#if !defined(__RPC_WIN64__) +#error Invalid build platform for this stub. +#endif + +static const ie_bho_idl_MIDL_PROC_FORMAT_STRING ie_bho_idl__MIDL_ProcFormatString = + { + 0, + { + + 0x0 + } + }; + +static const ie_bho_idl_MIDL_TYPE_FORMAT_STRING ie_bho_idl__MIDL_TypeFormatString = + { + 0, + { + NdrFcShort( 0x0 ), /* 0 */ + + 0x0 + } + }; + + +/* Object interface: IUnknown, ver. 0.0, + GUID={0x00000000,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: IDispatch, ver. 0.0, + GUID={0x00020400,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: IBrowserSwitcherBHO, ver. 0.0, + GUID={0x68CB9FDF,0x5E2E,0x41D7,{0xA9,0x06,0xEF,0x6C,0x58,0xAF,0x04,0x29}} */ + +#pragma code_seg(".orpc") +static const unsigned short IBrowserSwitcherBHO_FormatStringOffsetTable[] = + { + (unsigned short) -1, + (unsigned short) -1, + (unsigned short) -1, + (unsigned short) -1, + 0 + }; + +static const MIDL_STUBLESS_PROXY_INFO IBrowserSwitcherBHO_ProxyInfo = + { + &Object_StubDesc, + ie_bho_idl__MIDL_ProcFormatString.Format, + &IBrowserSwitcherBHO_FormatStringOffsetTable[-3], + 0, + 0, + 0 + }; + + +static const MIDL_SERVER_INFO IBrowserSwitcherBHO_ServerInfo = + { + &Object_StubDesc, + 0, + ie_bho_idl__MIDL_ProcFormatString.Format, + &IBrowserSwitcherBHO_FormatStringOffsetTable[-3], + 0, + 0, + 0, + 0}; +CINTERFACE_PROXY_VTABLE(7) _IBrowserSwitcherBHOProxyVtbl = +{ + 0, + &IID_IBrowserSwitcherBHO, + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + 0 /* IDispatch::GetTypeInfoCount */ , + 0 /* IDispatch::GetTypeInfo */ , + 0 /* IDispatch::GetIDsOfNames */ , + 0 /* IDispatch_Invoke_Proxy */ +}; + + +static const PRPC_STUB_FUNCTION IBrowserSwitcherBHO_table[] = +{ + STUB_FORWARDING_FUNCTION, + STUB_FORWARDING_FUNCTION, + STUB_FORWARDING_FUNCTION, + STUB_FORWARDING_FUNCTION +}; + +CInterfaceStubVtbl _IBrowserSwitcherBHOStubVtbl = +{ + &IID_IBrowserSwitcherBHO, + &IBrowserSwitcherBHO_ServerInfo, + 7, + &IBrowserSwitcherBHO_table[-3], + CStdStubBuffer_DELEGATING_METHODS +}; + +static const MIDL_STUB_DESC Object_StubDesc = + { + 0, + NdrOleAllocate, + NdrOleFree, + 0, + 0, + 0, + 0, + 0, + ie_bho_idl__MIDL_TypeFormatString.Format, + 1, /* -error bounds_check flag */ + 0x50002, /* Ndr library version */ + 0, + 0x801026e, /* MIDL Version 8.1.622 */ + 0, + 0, + 0, /* notify & notify_flag routine table */ + 0x1, /* MIDL flag */ + 0, /* cs routines */ + 0, /* proxy/server info */ + 0 + }; + +const CInterfaceProxyVtbl * const _ie_bho_idl_ProxyVtblList[] = +{ + ( CInterfaceProxyVtbl *) &_IBrowserSwitcherBHOProxyVtbl, + 0 +}; + +const CInterfaceStubVtbl * const _ie_bho_idl_StubVtblList[] = +{ + ( CInterfaceStubVtbl *) &_IBrowserSwitcherBHOStubVtbl, + 0 +}; + +PCInterfaceName const _ie_bho_idl_InterfaceNamesList[] = +{ + "IBrowserSwitcherBHO", + 0 +}; + +const IID * const _ie_bho_idl_BaseIIDList[] = +{ + &IID_IDispatch, + 0 +}; + + +#define _ie_bho_idl_CHECK_IID(n) IID_GENERIC_CHECK_IID( _ie_bho_idl, pIID, n) + +int __stdcall _ie_bho_idl_IID_Lookup( const IID * pIID, int * pIndex ) +{ + + if(!_ie_bho_idl_CHECK_IID(0)) + { + *pIndex = 0; + return 1; + } + + return 0; +} + +const ExtendedProxyFileInfo ie_bho_idl_ProxyFileInfo = +{ + (PCInterfaceProxyVtblList *) & _ie_bho_idl_ProxyVtblList, + (PCInterfaceStubVtblList *) & _ie_bho_idl_StubVtblList, + (const PCInterfaceName * ) & _ie_bho_idl_InterfaceNamesList, + (const IID ** ) & _ie_bho_idl_BaseIIDList, + & _ie_bho_idl_IID_Lookup, + 1, + 2, + 0, /* table of [async_uuid] interfaces */ + 0, /* Filler1 */ + 0, /* Filler2 */ + 0 /* Filler3 */ +}; +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif + + +#endif /* defined(_M_AMD64)*/ +
diff --git a/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x86/ie_bho_idl.dlldata.c b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x86/ie_bho_idl.dlldata.c new file mode 100644 index 0000000..5d3e2a0 --- /dev/null +++ b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x86/ie_bho_idl.dlldata.c
@@ -0,0 +1,38 @@ +/********************************************************* + DllData file -- generated by MIDL compiler + + DO NOT ALTER THIS FILE + + This file is regenerated by MIDL on every IDL file compile. + + To completely reconstruct this file, delete it and rerun MIDL + on all the IDL files in this DLL, specifying this file for the + /dlldata command line option + +*********************************************************/ + +#define PROXY_DELEGATION + +#include <rpcproxy.h> + +#ifdef __cplusplus +extern "C" { +#endif + +EXTERN_PROXY_FILE( ie_bho_idl ) + + +PROXYFILE_LIST_START +/* Start of list */ + REFERENCE_PROXY_FILE( ie_bho_idl ), +/* End of list */ +PROXYFILE_LIST_END + + +DLLDATA_ROUTINES( aProxyFileList, GET_DLL_CLSID ) + +#ifdef __cplusplus +} /*extern "C" */ +#endif + +/* end of generated dlldata file */
diff --git a/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x86/ie_bho_idl.h b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x86/ie_bho_idl.h new file mode 100644 index 0000000..5c86301 --- /dev/null +++ b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x86/ie_bho_idl.h
@@ -0,0 +1,225 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 8.xx.xxxx */ +/* at a redacted point in time + */ +/* Compiler settings for ../../chrome/browser/browser_switcher/bho/ie_bho_idl.idl: + Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.xx.xxxx + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the <rpcndr.h> version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of <rpcndr.h> +#endif /* __RPCNDR_H_VERSION__ */ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __ie_bho_idl_h__ +#define __ie_bho_idl_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __IBrowserSwitcherBHO_FWD_DEFINED__ +#define __IBrowserSwitcherBHO_FWD_DEFINED__ +typedef interface IBrowserSwitcherBHO IBrowserSwitcherBHO; + +#endif /* __IBrowserSwitcherBHO_FWD_DEFINED__ */ + + +#ifndef __BrowserSwitcherBHO_FWD_DEFINED__ +#define __BrowserSwitcherBHO_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class BrowserSwitcherBHO BrowserSwitcherBHO; +#else +typedef struct BrowserSwitcherBHO BrowserSwitcherBHO; +#endif /* __cplusplus */ + +#endif /* __BrowserSwitcherBHO_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +#ifndef __IBrowserSwitcherBHO_INTERFACE_DEFINED__ +#define __IBrowserSwitcherBHO_INTERFACE_DEFINED__ + +/* interface IBrowserSwitcherBHO */ +/* [unique][helpstring][nonextensible][dual][uuid][object] */ + + +EXTERN_C const IID IID_IBrowserSwitcherBHO; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("68CB9FDF-5E2E-41D7-A906-EF6C58AF0429") + IBrowserSwitcherBHO : public IDispatch + { + public: + }; + + +#else /* C style interface */ + + typedef struct IBrowserSwitcherBHOVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IBrowserSwitcherBHO * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IBrowserSwitcherBHO * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IBrowserSwitcherBHO * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IBrowserSwitcherBHO * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IBrowserSwitcherBHO * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IBrowserSwitcherBHO * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IBrowserSwitcherBHO * This, + /* [annotation][in] */ + _In_ DISPID dispIdMember, + /* [annotation][in] */ + _In_ REFIID riid, + /* [annotation][in] */ + _In_ LCID lcid, + /* [annotation][in] */ + _In_ WORD wFlags, + /* [annotation][out][in] */ + _In_ DISPPARAMS *pDispParams, + /* [annotation][out] */ + _Out_opt_ VARIANT *pVarResult, + /* [annotation][out] */ + _Out_opt_ EXCEPINFO *pExcepInfo, + /* [annotation][out] */ + _Out_opt_ UINT *puArgErr); + + END_INTERFACE + } IBrowserSwitcherBHOVtbl; + + interface IBrowserSwitcherBHO + { + CONST_VTBL struct IBrowserSwitcherBHOVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IBrowserSwitcherBHO_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IBrowserSwitcherBHO_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IBrowserSwitcherBHO_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IBrowserSwitcherBHO_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IBrowserSwitcherBHO_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IBrowserSwitcherBHO_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IBrowserSwitcherBHO_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IBrowserSwitcherBHO_INTERFACE_DEFINED__ */ + + + +#ifndef __BrowserSwitcherLib_LIBRARY_DEFINED__ +#define __BrowserSwitcherLib_LIBRARY_DEFINED__ + +/* library BrowserSwitcherLib */ +/* [helpstring][version][uuid] */ + + +EXTERN_C const IID LIBID_BrowserSwitcherLib; + +EXTERN_C const CLSID CLSID_BrowserSwitcherBHO; + +#ifdef __cplusplus + +class DECLSPEC_UUID("08B5789A-BD8E-4DAE-85DF-EF792C658B86") +BrowserSwitcherBHO; +#endif +#endif /* __BrowserSwitcherLib_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + +
diff --git a/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x86/ie_bho_idl.tlb b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x86/ie_bho_idl.tlb new file mode 100644 index 0000000..9098313 --- /dev/null +++ b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x86/ie_bho_idl.tlb Binary files differ
diff --git a/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x86/ie_bho_idl_i.c b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x86/ie_bho_idl_i.c new file mode 100644 index 0000000..b71f1c41 --- /dev/null +++ b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x86/ie_bho_idl_i.c
@@ -0,0 +1,85 @@ + + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + + /* File created by MIDL compiler version 8.xx.xxxx */ +/* at a redacted point in time + */ +/* Compiler settings for ../../chrome/browser/browser_switcher/bho/ie_bho_idl.idl: + Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.xx.xxxx + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +#ifdef __cplusplus +extern "C"{ +#endif + + +#include <rpc.h> +#include <rpcndr.h> + +#ifdef _MIDL_USE_GUIDDEF_ + +#ifndef INITGUID +#define INITGUID +#include <guiddef.h> +#undef INITGUID +#else +#include <guiddef.h> +#endif + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) + +#else // !_MIDL_USE_GUIDDEF_ + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + EXTERN_C __declspec(selectany) const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +#endif // !_MIDL_USE_GUIDDEF_ + +MIDL_DEFINE_GUID(IID, IID_IBrowserSwitcherBHO,0x68CB9FDF,0x5E2E,0x41D7,0xA9,0x06,0xEF,0x6C,0x58,0xAF,0x04,0x29); + + +MIDL_DEFINE_GUID(IID, LIBID_BrowserSwitcherLib,0xE042FD04,0x3D7E,0x4A3A,0x9B,0x9E,0xD4,0xD9,0xC7,0x0B,0x44,0x84); + + +MIDL_DEFINE_GUID(CLSID, CLSID_BrowserSwitcherBHO,0x08B5789A,0xBD8E,0x4DAE,0x85,0xDF,0xEF,0x79,0x2C,0x65,0x8B,0x86); + +#undef MIDL_DEFINE_GUID + +#ifdef __cplusplus +} +#endif + + +
diff --git a/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x86/ie_bho_idl_p.c b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x86/ie_bho_idl_p.c new file mode 100644 index 0000000..cc0b051 --- /dev/null +++ b/third_party/win_build_output/midl/chrome/browser/browser_switcher/bho/x86/ie_bho_idl_p.c
@@ -0,0 +1,282 @@ + + +/* this ALWAYS GENERATED file contains the proxy stub code */ + + + /* File created by MIDL compiler version 8.xx.xxxx */ +/* at a redacted point in time + */ +/* Compiler settings for ../../chrome/browser/browser_switcher/bho/ie_bho_idl.idl: + Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.xx.xxxx + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +/* @@MIDL_FILE_HEADING( ) */ + +#if !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_) + + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif + +#pragma warning( disable: 4211 ) /* redefine extern to static */ +#pragma warning( disable: 4232 ) /* dllimport identity*/ +#pragma warning( disable: 4024 ) /* array to pointer mapping*/ +#pragma warning( disable: 4152 ) /* function/data pointer conversion in expression */ +#pragma warning( disable: 4100 ) /* unreferenced arguments in x86 call */ + +#pragma optimize("", off ) + +#define USE_STUBLESS_PROXY + + +/* verify that the <rpcproxy.h> version is high enough to compile this file*/ +#ifndef __REDQ_RPCPROXY_H_VERSION__ +#define __REQUIRED_RPCPROXY_H_VERSION__ 475 +#endif + + +#include "rpcproxy.h" +#ifndef __RPCPROXY_H_VERSION__ +#error this stub requires an updated version of <rpcproxy.h> +#endif /* __RPCPROXY_H_VERSION__ */ + + +#include "ie_bho_idl.h" + +#define TYPE_FORMAT_STRING_SIZE 3 +#define PROC_FORMAT_STRING_SIZE 1 +#define EXPR_FORMAT_STRING_SIZE 1 +#define TRANSMIT_AS_TABLE_SIZE 0 +#define WIRE_MARSHAL_TABLE_SIZE 0 + +typedef struct _ie_bho_idl_MIDL_TYPE_FORMAT_STRING + { + short Pad; + unsigned char Format[ TYPE_FORMAT_STRING_SIZE ]; + } ie_bho_idl_MIDL_TYPE_FORMAT_STRING; + +typedef struct _ie_bho_idl_MIDL_PROC_FORMAT_STRING + { + short Pad; + unsigned char Format[ PROC_FORMAT_STRING_SIZE ]; + } ie_bho_idl_MIDL_PROC_FORMAT_STRING; + +typedef struct _ie_bho_idl_MIDL_EXPR_FORMAT_STRING + { + long Pad; + unsigned char Format[ EXPR_FORMAT_STRING_SIZE ]; + } ie_bho_idl_MIDL_EXPR_FORMAT_STRING; + + +static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax = +{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}}; + + +extern const ie_bho_idl_MIDL_TYPE_FORMAT_STRING ie_bho_idl__MIDL_TypeFormatString; +extern const ie_bho_idl_MIDL_PROC_FORMAT_STRING ie_bho_idl__MIDL_ProcFormatString; +extern const ie_bho_idl_MIDL_EXPR_FORMAT_STRING ie_bho_idl__MIDL_ExprFormatString; + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +extern const MIDL_SERVER_INFO IBrowserSwitcherBHO_ServerInfo; +extern const MIDL_STUBLESS_PROXY_INFO IBrowserSwitcherBHO_ProxyInfo; + + + +#if !defined(__RPC_WIN32__) +#error Invalid build platform for this stub. +#endif + +#if !(TARGET_IS_NT50_OR_LATER) +#error You need Windows 2000 or later to run this stub because it uses these features: +#error /robust command line switch. +#error However, your C/C++ compilation flags indicate you intend to run this app on earlier systems. +#error This app will fail with the RPC_X_WRONG_STUB_VERSION error. +#endif + + +static const ie_bho_idl_MIDL_PROC_FORMAT_STRING ie_bho_idl__MIDL_ProcFormatString = + { + 0, + { + + 0x0 + } + }; + +static const ie_bho_idl_MIDL_TYPE_FORMAT_STRING ie_bho_idl__MIDL_TypeFormatString = + { + 0, + { + NdrFcShort( 0x0 ), /* 0 */ + + 0x0 + } + }; + + +/* Object interface: IUnknown, ver. 0.0, + GUID={0x00000000,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: IDispatch, ver. 0.0, + GUID={0x00020400,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: IBrowserSwitcherBHO, ver. 0.0, + GUID={0x68CB9FDF,0x5E2E,0x41D7,{0xA9,0x06,0xEF,0x6C,0x58,0xAF,0x04,0x29}} */ + +#pragma code_seg(".orpc") +static const unsigned short IBrowserSwitcherBHO_FormatStringOffsetTable[] = + { + (unsigned short) -1, + (unsigned short) -1, + (unsigned short) -1, + (unsigned short) -1, + 0 + }; + +static const MIDL_STUBLESS_PROXY_INFO IBrowserSwitcherBHO_ProxyInfo = + { + &Object_StubDesc, + ie_bho_idl__MIDL_ProcFormatString.Format, + &IBrowserSwitcherBHO_FormatStringOffsetTable[-3], + 0, + 0, + 0 + }; + + +static const MIDL_SERVER_INFO IBrowserSwitcherBHO_ServerInfo = + { + &Object_StubDesc, + 0, + ie_bho_idl__MIDL_ProcFormatString.Format, + &IBrowserSwitcherBHO_FormatStringOffsetTable[-3], + 0, + 0, + 0, + 0}; +CINTERFACE_PROXY_VTABLE(7) _IBrowserSwitcherBHOProxyVtbl = +{ + 0, + &IID_IBrowserSwitcherBHO, + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + 0 /* IDispatch::GetTypeInfoCount */ , + 0 /* IDispatch::GetTypeInfo */ , + 0 /* IDispatch::GetIDsOfNames */ , + 0 /* IDispatch_Invoke_Proxy */ +}; + + +static const PRPC_STUB_FUNCTION IBrowserSwitcherBHO_table[] = +{ + STUB_FORWARDING_FUNCTION, + STUB_FORWARDING_FUNCTION, + STUB_FORWARDING_FUNCTION, + STUB_FORWARDING_FUNCTION +}; + +CInterfaceStubVtbl _IBrowserSwitcherBHOStubVtbl = +{ + &IID_IBrowserSwitcherBHO, + &IBrowserSwitcherBHO_ServerInfo, + 7, + &IBrowserSwitcherBHO_table[-3], + CStdStubBuffer_DELEGATING_METHODS +}; + +static const MIDL_STUB_DESC Object_StubDesc = + { + 0, + NdrOleAllocate, + NdrOleFree, + 0, + 0, + 0, + 0, + 0, + ie_bho_idl__MIDL_TypeFormatString.Format, + 1, /* -error bounds_check flag */ + 0x50002, /* Ndr library version */ + 0, + 0x801026e, /* MIDL Version 8.1.622 */ + 0, + 0, + 0, /* notify & notify_flag routine table */ + 0x1, /* MIDL flag */ + 0, /* cs routines */ + 0, /* proxy/server info */ + 0 + }; + +const CInterfaceProxyVtbl * const _ie_bho_idl_ProxyVtblList[] = +{ + ( CInterfaceProxyVtbl *) &_IBrowserSwitcherBHOProxyVtbl, + 0 +}; + +const CInterfaceStubVtbl * const _ie_bho_idl_StubVtblList[] = +{ + ( CInterfaceStubVtbl *) &_IBrowserSwitcherBHOStubVtbl, + 0 +}; + +PCInterfaceName const _ie_bho_idl_InterfaceNamesList[] = +{ + "IBrowserSwitcherBHO", + 0 +}; + +const IID * const _ie_bho_idl_BaseIIDList[] = +{ + &IID_IDispatch, + 0 +}; + + +#define _ie_bho_idl_CHECK_IID(n) IID_GENERIC_CHECK_IID( _ie_bho_idl, pIID, n) + +int __stdcall _ie_bho_idl_IID_Lookup( const IID * pIID, int * pIndex ) +{ + + if(!_ie_bho_idl_CHECK_IID(0)) + { + *pIndex = 0; + return 1; + } + + return 0; +} + +const ExtendedProxyFileInfo ie_bho_idl_ProxyFileInfo = +{ + (PCInterfaceProxyVtblList *) & _ie_bho_idl_ProxyVtblList, + (PCInterfaceStubVtblList *) & _ie_bho_idl_StubVtblList, + (const PCInterfaceName * ) & _ie_bho_idl_InterfaceNamesList, + (const IID ** ) & _ie_bho_idl_BaseIIDList, + & _ie_bho_idl_IID_Lookup, + 1, + 2, + 0, /* table of [async_uuid] interfaces */ + 0, /* Filler1 */ + 0, /* Filler2 */ + 0 /* Filler3 */ +}; +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif + + +#endif /* !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_) */ +
diff --git a/third_party/win_build_output/remidl.bat b/third_party/win_build_output/remidl.bat index 84f65b1..22cc017 100755 --- a/third_party/win_build_output/remidl.bat +++ b/third_party/win_build_output/remidl.bat
@@ -5,6 +5,7 @@ @REM midl.exe output is arch-specific, remember to run this for all supported @REM target_cpu, currently x86, x64 and arm64. ninja -C out\gn ^ + gen/browser_switcher/ie_bho/ie_bho_idl.h ^ gen/google_update/google_update_idl.h ^ gen/remoting/host/win/chromoting_lib.h ^ gen/third_party/iaccessible2/ia2_api_all.h ^
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py index cc8d6fe8..223d743 100644 --- a/tools/json_schema_compiler/cc_generator.py +++ b/tools/json_schema_compiler/cc_generator.py
@@ -319,9 +319,9 @@ 'static_cast<const base::DictionaryValue*>(&value);') if self._generate_error_messages: c.Append('std::set<std::string> keys;') - for prop in type_.properties.itervalues(): + for prop in type_.properties.values(): c.Concat(self._InitializePropertyToDefault(prop, 'out')) - for prop in type_.properties.itervalues(): + for prop in type_.properties.values(): if self._generate_error_messages: c.Append('keys.insert("%s");' % (prop.name)) c.Concat(self._GenerateTypePopulateProperty(prop, 'dict', 'out'))
diff --git a/tools/json_schema_compiler/compiler.py b/tools/json_schema_compiler/compiler.py index 257a0de9..1637ec3 100755 --- a/tools/json_schema_compiler/compiler.py +++ b/tools/json_schema_compiler/compiler.py
@@ -16,6 +16,8 @@ --namespace extensions windows.json tabs.json """ +from __future__ import print_function + import optparse import os import shlex @@ -204,11 +206,11 @@ include_rules = [] if opts.include_rules: - include_rules = map(split_path_and_namespace, - shlex.split(opts.include_rules)) + include_rules = list( + map(split_path_and_namespace, shlex.split(opts.include_rules))) result = GenerateSchema(opts.generator, file_paths, opts.root, opts.destdir, opts.namespace, opts.bundle_name, opts.impl_dir, include_rules) if not opts.destdir: - print result + print(result)
diff --git a/tools/json_schema_compiler/cpp_bundle_generator.py b/tools/json_schema_compiler/cpp_bundle_generator.py index 620b3f191..102b18c 100644 --- a/tools/json_schema_compiler/cpp_bundle_generator.py +++ b/tools/json_schema_compiler/cpp_bundle_generator.py
@@ -13,6 +13,7 @@ import json import os import re +import sys def _RemoveKey(node, key, type_restriction): @@ -32,7 +33,10 @@ # Return a copy so that we don't pollute the global api object, which may be # used elsewhere. ret = copy.deepcopy(schema) - _RemoveKey(ret, 'description', basestring) + if sys.version_info.major == 2: + _RemoveKey(ret, 'description', basestring) + else: + _RemoveKey(ret, 'description', str) _RemoveKey(ret, 'compiler_options', dict) _RemoveKey(ret, 'nodoc', bool) _RemoveKey(ret, 'nocompile', bool) @@ -53,7 +57,8 @@ assert not mandatory, ( 'Required key "%s" is not present in object.' % key) return - assert type(obj[key]) in [str, unicode] + assert type(obj[key]) is str or (sys.version_info.major == 2 and + isinstance(obj[key], basestring)) if obj[key].find('.') == -1: obj[key] = '%s.%s' % (namespace, obj[key]) @@ -340,9 +345,10 @@ # too large to compile on windows. Split the JSON up into several # strings, since apparently that helps. max_length = 8192 - segments = [json_content[i:i + max_length].replace('\\', '\\\\') - .replace('"', '\\"') - for i in xrange(0, len(json_content), max_length)] + segments = [ + json_content[i:i + max_length].replace('\\', '\\\\').replace( + '"', '\\"') for i in range(0, len(json_content), max_length) + ] c.Append('const char %s[] = "%s";' % (_FormatNameAsConstant(namespace.name), '" "'.join(segments))) c.Append('} // namespace')
diff --git a/tools/json_schema_compiler/cpp_type_generator.py b/tools/json_schema_compiler/cpp_type_generator.py index 888f1a7..7cfe961a 100644 --- a/tools/json_schema_compiler/cpp_type_generator.py +++ b/tools/json_schema_compiler/cpp_type_generator.py
@@ -139,7 +139,7 @@ """Returns the forward declarations for self._default_namespace. """ c = Code() - for namespace, deps in self._NamespaceTypeDependencies().iteritems(): + for namespace, deps in self._NamespaceTypeDependencies().items(): filtered_deps = [ dep for dep in deps # Add more ways to forward declare things as necessary.
diff --git a/tools/json_schema_compiler/feature_compiler.py b/tools/json_schema_compiler/feature_compiler.py index d08b7a6..1ee0478 100644 --- a/tools/json_schema_compiler/feature_compiler.py +++ b/tools/json_schema_compiler/feature_compiler.py
@@ -8,6 +8,7 @@ from functools import partial import os import re +import sys from code import Code import json_parse @@ -67,7 +68,7 @@ # Returns true if the list 'l' only contains strings that are a hex-encoded SHA1 # hashes. def ListContainsOnlySha1Hashes(l): - return len(filter(lambda s: not re.match("^[A-F0-9]{40}$", s), l)) == 0 + return len(list(filter(lambda s: not re.match("^[A-F0-9]{40}$", s), l))) == 0 # A "grammar" for what is and isn't allowed in the features.json files. This # grammar has to list all possible keys and the requirements for each. The @@ -77,7 +78,7 @@ # allowed_type_2: optional_properties, # } # |allowed_types| are the types of values that can be used for a given key. The -# possible values are list, unicode, bool, and int. +# possible values are list, str, bool, and int. # |optional_properties| provide more restrictions on the given type. The options # are: # 'subtype': Only applicable for lists. If provided, this enforces that each @@ -114,12 +115,12 @@ FEATURE_GRAMMAR = ( { 'alias': { - unicode: {}, + str: {}, 'shared': True }, 'blacklist': { list: { - 'subtype': unicode, + 'subtype': str, 'validators': [ (ListContainsOnlySha1Hashes, 'list should only have hex-encoded SHA1 hashes of extension ids') @@ -127,7 +128,7 @@ } }, 'channel': { - unicode: { + str: { 'enum_map': { 'trunk': 'version_info::Channel::UNKNOWN', 'canary': 'version_info::Channel::CANARY', @@ -138,7 +139,7 @@ } }, 'command_line_switch': { - unicode: {} + str: {} }, 'component_extensions_auto_granted': { bool: {} @@ -166,7 +167,7 @@ # We allow an empty list of dependencies for child features that want # to override their parents' dependency set. 'allow_empty': True, - 'subtype': unicode + 'subtype': str } }, 'extension_types': { @@ -183,7 +184,7 @@ }, }, 'location': { - unicode: { + str: { 'enum_map': { 'component': 'SimpleFeature::COMPONENT_LOCATION', 'external_component': 'SimpleFeature::EXTERNAL_COMPONENT_LOCATION', @@ -195,7 +196,7 @@ bool: {'values': [True]} }, 'matches': { - list: {'subtype': unicode} + list: {'subtype': str} }, 'max_manifest_version': { int: {'values': [1, 2]} @@ -226,12 +227,12 @@ } }, 'source': { - unicode: {}, + str: {}, 'shared': True }, 'whitelist': { list: { - 'subtype': unicode, + 'subtype': str, 'validators': [ (ListContainsOnlySha1Hashes, 'list should only have hex-encoded SHA1 hashes of extension ids') @@ -354,11 +355,6 @@ # can be disabled for testing. ENABLE_ASSERTIONS = True -# JSON parsing returns all strings of characters as unicode types. For testing, -# we can enable converting all string types to unicode to avoid writing u'' -# everywhere. -STRINGS_TO_UNICODE = False - def GetCodeForFeatureValues(feature_values): """ Gets the Code object for setting feature values for this object. """ c = Code() @@ -388,15 +384,14 @@ self.shared_values = {} def _GetType(self, value): - """Returns the type of the given value. This can be different than type() if - STRINGS_TO_UNICODE is enabled. + """Returns the type of the given value. """ - t = type(value) - if not STRINGS_TO_UNICODE: - return t - if t is str: - return unicode - return t + # For Py3 compatibility we use str in the grammar and treat unicode as str + # in Py2. + if sys.version_info.major == 2 and type(value) is unicode: + return str + + return type(value) def AddError(self, error): """Adds an error to the feature. If ENABLE_ASSERTIONS is active, this will @@ -444,7 +439,7 @@ if enum_map: return enum_map[value] - if t in [str, unicode]: + if t is str: return '"%s"' % str(value) if t is int: return str(value) @@ -494,7 +489,7 @@ expected_values = expected['values'] elif 'enum_map' in expected: enum_map = expected['enum_map'] - expected_values = enum_map.keys() + expected_values = list(enum_map) if is_all: v = copy.deepcopy(expected_values) @@ -552,7 +547,7 @@ for key in parsed_json.keys(): if key not in FEATURE_GRAMMAR: self._AddKeyError(key, 'Unrecognized key') - for key, key_grammar in FEATURE_GRAMMAR.iteritems(): + for key, key_grammar in FEATURE_GRAMMAR.items(): self._ParseKey(key, parsed_json, shared_values, key_grammar) def Validate(self, feature_type, shared_values):
diff --git a/tools/json_schema_compiler/feature_compiler_test.py b/tools/json_schema_compiler/feature_compiler_test.py index 3a1f500..896afdfc 100755 --- a/tools/json_schema_compiler/feature_compiler_test.py +++ b/tools/json_schema_compiler/feature_compiler_test.py
@@ -33,7 +33,6 @@ def setUp(self): feature_compiler.ENABLE_ASSERTIONS = False - feature_compiler.STRINGS_TO_UNICODE = True def testFeature(self): # Test some basic feature parsing for a sanity check.
diff --git a/tools/json_schema_compiler/features_compiler.py b/tools/json_schema_compiler/features_compiler.py index cb3f7ef..9552504 100755 --- a/tools/json_schema_compiler/features_compiler.py +++ b/tools/json_schema_compiler/features_compiler.py
@@ -31,7 +31,7 @@ # Generate a list of the features defined and a list of their models. feature_list = [] - for feature_def, feature in feature_defs.iteritems(): + for feature_def, feature in feature_defs.items(): feature_list.append(CreateFeature(feature_def, feature)) source_file_dir, _ = os.path.split(schema)
diff --git a/tools/json_schema_compiler/idl_schema.py b/tools/json_schema_compiler/idl_schema.py index cfa9e81..f52f7e3 100755 --- a/tools/json_schema_compiler/idl_schema.py +++ b/tools/json_schema_compiler/idl_schema.py
@@ -3,6 +3,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +from __future__ import print_function + import itertools import json import os.path @@ -10,6 +12,11 @@ import re import sys +if sys.version_info.major == 2: + from itertools import izip_longest as zip_longest +else: + from itertools import zip_longest + from json_parse import OrderedDict # This file is a peer to json_schema.py. Each of these files understands a @@ -80,8 +87,8 @@ .replace('\n', '')) params = OrderedDict() - for (cur_param, next_param) in itertools.izip_longest(parameter_starts, - parameter_starts[1:]): + for (cur_param, next_param) in zip_longest(parameter_starts, + parameter_starts[1:]): param_name = cur_param.group(1) # A parameter's comment goes from the end of its introduction to the @@ -434,9 +441,8 @@ # Properties are given as key-value pairs, but IDL will parse # it as a list. Convert back to key-value pairs. prop_name = prop.pop('name') - assert not self.properties.has_key(prop_name), ( - 'Property "%s" cannot be specified more than once.' % - prop_name) + assert not prop_name in self.properties, ( + 'Property "%s" cannot be specified more than once.' % prop_name) self.properties[prop_name] = prop elif node.cls == 'Enum': self.types.append(Enum(node).process()) @@ -568,12 +574,12 @@ if len(sys.argv) > 1: for filename in sys.argv[1:]: schema = Load(filename) - print json.dumps(schema, indent=2) + print(json.dumps(schema, indent=2)) else: contents = sys.stdin.read() idl = idl_parser.IDLParser().ParseData(contents, '<stdin>') schema = IDLSchema(idl).process() - print json.dumps(schema, indent=2) + print(json.dumps(schema, indent=2)) if __name__ == '__main__':
diff --git a/tools/json_schema_compiler/memoize.py b/tools/json_schema_compiler/memoize.py index 228e7e3..f08e9b7 100644 --- a/tools/json_schema_compiler/memoize.py +++ b/tools/json_schema_compiler/memoize.py
@@ -7,7 +7,7 @@ ''' memory = {} def impl(*args, **optargs): - full_args = args + tuple(optargs.iteritems()) + full_args = args + tuple(optargs.items()) if full_args not in memory: memory[full_args] = fn(*args, **optargs) return memory[full_args]
diff --git a/tools/json_schema_compiler/model.py b/tools/json_schema_compiler/model.py index b6126b8..020a3474 100644 --- a/tools/json_schema_compiler/model.py +++ b/tools/json_schema_compiler/model.py
@@ -465,6 +465,9 @@ def __str__(self): return repr(self) + def __hash__(self): + return hash(self.name) + class _PropertyTypeInfo(_Enum): def __init__(self, is_fundamental, name):
diff --git a/tools/json_schema_compiler/model_test.py b/tools/json_schema_compiler/model_test.py index 75ed9c58..bfe883d 100755 --- a/tools/json_schema_compiler/model_test.py +++ b/tools/json_schema_compiler/model_test.py
@@ -130,7 +130,7 @@ 'bar_': 'bar', 'bar_baz_': 'barBaz', } - for testcase, expected in expectations.iteritems(): + for testcase, expected in expectations.items(): self.assertEquals(expected, model.CamelName(testcase)) def testPlatforms(self):
diff --git a/tools/licenses.py b/tools/licenses.py index 3d193f4..2b226c1 100755 --- a/tools/licenses.py +++ b/tools/licenses.py
@@ -27,8 +27,8 @@ # TODO(agrieve): Move build_utils.WriteDepFile into a non-android directory. _REPOSITORY_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) -sys.path.append(os.path.join(_REPOSITORY_ROOT, 'build/android/gyp/util')) -import build_utils +sys.path.insert(0, os.path.join(_REPOSITORY_ROOT, 'build/android/gyp')) +from util import build_utils # Paths from the root of the tree to directories to skip.
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 27c3c103..a0d99d3 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -1991,13 +1991,15 @@ </enum> <enum name="AppListAppMovingType"> - <int value="0" label="MOVE_INTO_FOLDER"/> - <int value="1" label="MOVE_OUT_OF_FOLDER"/> + <int value="0" label="MOVE_BY_DRAG_INTO_FOLDER"/> + <int value="1" label="MOVE_BY_DRAG_OUT_OF_FOLDER"/> <int value="2" label="MOVE_INTO_ANOTHER_FOLDER"/> <int value="3" label="REORDER_BY_DRAG_IN_FOLDER"/> <int value="4" label="REORDER_BY_DRAG_IN_TOP_LEVEL"/> <int value="5" label="REORDER_BY_KEYBOARD_IN_FOLDER"/> <int value="6" label="REORDER_BY_KEYBOARD_IN_TOP_LEVEL"/> + <int value="7" label="MOVE_BY_KEYBOARD_INTO_FOLDER"/> + <int value="8" label="MOVE_BY_KEYBOARD_OUT_OF_FOLDER"/> </enum> <enum name="AppListAppType"> @@ -18953,6 +18955,7 @@ <int value="1327" label="AUTOTESTPRIVATE_IMPORTCROSTINI"/> <int value="1328" label="ACCESSIBILITY_PRIVATE_SETVIRTUALKEYBOARDVISIBLE"/> <int value="1329" label="AUTOTESTPRIVATE_SHOWVIRTUALKEYBOARDIFENABLED"/> + <int value="1330" label="FEEDBACKPRIVATE_LOGINFEEDBACKCOMPLETE"/> </enum> <enum name="ExtensionIconState">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 1ded1e5..c8e46f8 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -38784,7 +38784,9 @@ </histogram> <histogram name="FCMInvalidations.FCMMessageStatus" - enum="FCMInvalidationMessageStatus" expires_after="M75"> + enum="FCMInvalidationMessageStatus" expires_after="never"> +<!-- expires-never: For monitoring FCM based invalidations. --> + <owner>melandory@chromium.org</owner> <summary> Status of the message from the FCM channel. Recorded upon receiving response @@ -38793,7 +38795,9 @@ </histogram> <histogram name="FCMInvalidations.InitialTokenRetrievalStatus" - enum="InstanceIDResult" expires_after="M75"> + enum="InstanceIDResult" expires_after="never"> +<!-- expires-never: For monitoring FCM based invalidations. --> + <owner>melandory@chromium.org</owner> <summary> Status of the initial attempt to retrieve the instance id token. @@ -38801,7 +38805,9 @@ </histogram> <histogram name="FCMInvalidations.SubscriptionRequestStatus" - enum="FCMInvalidationSubscriptionStatus" expires_after="M75"> + enum="FCMInvalidationSubscriptionStatus" expires_after="never"> +<!-- expires-never: For monitoring FCM based invalidations. --> + <owner>melandory@chromium.org</owner> <summary> Status of subscription request to the Per User Topic server. Recorded upon @@ -38810,7 +38816,9 @@ </histogram> <histogram name="FCMInvalidations.SubscriptionResponseCode" - enum="HttpResponseCode"> + enum="HttpResponseCode" expires_after="never"> +<!-- expires-never: For monitoring FCM based invalidations. --> + <owner>melandory@chromium.org</owner> <summary> For each subcription request to the FCM Per-User-Topic server, log the @@ -38819,7 +38827,9 @@ </histogram> <histogram name="FCMInvalidations.SubscriptionResponseCodeForTopic" - enum="HttpResponseCode"> + enum="HttpResponseCode" expires_after="never"> +<!-- expires-never: For monitoring FCM based invalidations. --> + <owner>melandory@chromium.org</owner> <summary> For each subcription request to the FCM Per-User-Topic server, log the @@ -38829,7 +38839,9 @@ </histogram> <histogram name="FCMInvalidations.UnsubscriptionRequestStatus" - enum="FCMInvalidationSubscriptionStatus" expires_after="M75"> + enum="FCMInvalidationSubscriptionStatus" expires_after="never"> +<!-- expires-never: For monitoring FCM based invalidations. --> + <owner>melandory@chromium.org</owner> <summary> Status of unsubscription request to the Per User Topic server. Recorded upon @@ -40700,7 +40712,7 @@ </histogram> <histogram name="GCMInvalidations.IncomingMessageStatus" - enum="GCMInvalidationsIncomingMessageStatus"> + enum="GCMInvalidationsIncomingMessageStatus" expires_after="M76"> <owner>pavely@chromium.org</owner> <summary> Status of parsing incoming invalidations message from GCM channel. @@ -40708,7 +40720,7 @@ </histogram> <histogram name="GCMInvalidations.OutgoingMessageStatus" - enum="GCMInvalidationsOutgoingMessageStatus"> + enum="GCMInvalidationsOutgoingMessageStatus" expires_after="M76"> <owner>pavely@chromium.org</owner> <summary> Status of sending outgoing invalidations message through GCM. @@ -47044,17 +47056,19 @@ </histogram> <histogram name="Invalidations.GCMUpstreamRequest" - enum="GCMUpstreamMessageStatus"> + enum="GCMUpstreamMessageStatus" expires_after="M76"> <owner>nyquist@chromium.org</owner> <owner>khushalsagar@chromium.org</owner> + <owner>melandory@chromium.org</owner> <summary> Status of sending outgoing invalidation message through GCM upsteam. </summary> </histogram> <histogram name="Invalidations.NetworkChannel" - enum="InvalidationNetworkChannel"> + enum="InvalidationNetworkChannel" expires_after="M76"> <owner>pavely@chromium.org</owner> + <owner>melandory@chromium.org</owner> <summary>Network channel used for invalidations.</summary> </histogram> @@ -121961,7 +121975,7 @@ </summary> </histogram> -<histogram base="true" name="Sync.E2ELatency" units="ms" expires_after="M75"> +<histogram base="true" name="Sync.E2ELatency" units="ms" expires_after="M80"> <owner>mastiz@chromium.org</owner> <owner>melandory@chromium.org</owner> <summary> @@ -122378,8 +122392,10 @@ </summary> </histogram> -<histogram base="true" name="Sync.InvalidationPerModelType" - enum="SyncModelTypes" expires_after="M75"> +<histogram name="Sync.InvalidationPerModelType" enum="SyncModelTypes" + expires_after="never"> +<!-- expires-never: For monitoring FCM based invalidations. --> + <owner>melandory@chromium.org</owner> <summary> Histogram tracks the number of invalidations received per sync data type.
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index c0cd2be..b56102a 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -86,8 +86,6 @@ crbug.com/876636 [ ChromeOS ] loading.desktop/TheOnion_warm [ Skip ] crbug.com/876636 [ Win_10 ] loading.desktop/TheOnion_warm [ Skip ] crbug.com/876636 [ Win_7 ] loading.desktop/TheOnion_warm [ Skip ] -crbug.com/928796 [ All ] loading.desktop/TheOnion_warm [ Skip ] -crbug.com/928796 [ All ] loading.desktop/TheOnion_cold [ Skip ] crbug.com/876636 [ ChromeOS ] loading.desktop/AllRecipes_cold [ Skip ] crbug.com/876636 [ ChromeOS ] loading.desktop/AllRecipes_warm [ Skip ] crbug.com/879833 [ Mac_10.12 ] loading.desktop/AllRecipes_cold [ Skip ]
diff --git a/tools/vscode/cpp.json5 b/tools/vscode/cpp.json5 new file mode 100644 index 0000000..45360113 --- /dev/null +++ b/tools/vscode/cpp.json5
@@ -0,0 +1,38 @@ +{ + // This file contains snippets that might be useful to you for Chrome + // development. + "Chrome Header": { + "prefix": "hdr", + "body": [ + "// Copyright ${CURRENT_YEAR} 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.", + "${0:", + "#ifndef ${TM_FILEPATH/(^\\/.*\\/src\\/)|([^a-zA-Z0-9])|([a-zA-Z0-9])/${2:+_}${3:/upcase}/g}_", + "#define ${TM_FILEPATH/(^\\/.*\\/src\\/)|([^a-zA-Z0-9])|([a-zA-Z0-9])/${2:+_}${3:/upcase}/g}_", + "", + "#endif // ${TM_FILEPATH/(^\\/.*\\/src\\/)|([^a-zA-Z0-9])|([a-zA-Z0-9])/${2:+_}${3:/upcase}/g}_}", + ] + }, + "Chrome Copyright": { + "prefix": "copyright", + "body": [ + "// Copyright ${CURRENT_YEAR} 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.", + ] + }, + "Chrome Log": { + "prefix": "log", + "body": "LOG(ERROR) << \"${1:message}\";", + "description": "Chrome Log output to console" + }, + "Stack trace": { + "prefix": "st", + "body": "base::debug::StackTrace().Print();" + }, + "Stack trace header": { + "prefix": "sth", + "body": "#include \"base/debug/stack_trace.h\"" + } +}
diff --git a/ui/accessibility/ax_node_position_unittest.cc b/ui/accessibility/ax_node_position_unittest.cc index 31cd999..03c0f90 100644 --- a/ui/accessibility/ax_node_position_unittest.cc +++ b/ui/accessibility/ax_node_position_unittest.cc
@@ -115,10 +115,7 @@ static_text2_.id = STATIC_TEXT2_ID; inline_box2_.id = INLINE_BOX2_ID; - root_.role = ax::mojom::Role::kDialog; - root_.AddState(ax::mojom::State::kFocusable); - root_.SetName(std::string("ButtonCheck box") + TEXT_VALUE); - root_.relative_bounds.bounds = gfx::RectF(0, 0, 800, 600); + root_.role = ax::mojom::Role::kRootWebArea; button_.role = ax::mojom::Role::kButton; button_.SetHasPopup(ax::mojom::HasPopup::kMenu); @@ -1129,6 +1126,114 @@ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity()); } +TEST_F(AXPositionTest, CreatePositionAtStartOfDocumentWithNullPosition) { + TestPositionType null_position = AXNodePosition::CreateNullPosition(); + ASSERT_NE(nullptr, null_position); + TestPositionType test_position = + null_position->CreatePositionAtStartOfDocument(); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsNullPosition()); +} + +TEST_F(AXPositionTest, CreatePositionAtStartOfDocumentWithTreePosition) { + TestPositionType tree_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, root_.id, 0 /* child_index */); + ASSERT_NE(nullptr, tree_position); + TestPositionType test_position = + tree_position->CreatePositionAtStartOfDocument(); + EXPECT_NE(nullptr, test_position); + EXPECT_EQ(root_.id, test_position->anchor_id()); + + tree_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, root_.id, 1 /* child_index */); + ASSERT_NE(nullptr, tree_position); + test_position = tree_position->CreatePositionAtStartOfDocument(); + EXPECT_NE(nullptr, test_position); + EXPECT_EQ(root_.id, test_position->anchor_id()); + + tree_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, inline_box1_.id, 0 /* child_index */); + ASSERT_NE(nullptr, tree_position); + test_position = tree_position->CreatePositionAtStartOfDocument(); + EXPECT_NE(nullptr, test_position); + EXPECT_EQ(root_.id, test_position->anchor_id()); +} + +TEST_F(AXPositionTest, CreatePositionAtStartOfDocumentWithTextPosition) { + TestPositionType text_position = AXNodePosition::CreateTextPosition( + tree_.data().tree_id, inline_box1_.id, 0 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + ASSERT_NE(nullptr, text_position); + TestPositionType test_position = + text_position->CreatePositionAtStartOfDocument(); + EXPECT_NE(nullptr, test_position); + EXPECT_EQ(root_.id, test_position->anchor_id()); + + text_position = AXNodePosition::CreateTextPosition( + tree_.data().tree_id, inline_box1_.id, 1 /* text_offset */, + ax::mojom::TextAffinity::kUpstream); + ASSERT_NE(nullptr, text_position); + test_position = text_position->CreatePositionAtStartOfDocument(); + EXPECT_NE(nullptr, test_position); + EXPECT_EQ(root_.id, test_position->anchor_id()); + // Affinity should have been reset to the default value. + EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity()); +} + +TEST_F(AXPositionTest, CreatePositionAtEndOfDocumentWithNullPosition) { + TestPositionType null_position = AXNodePosition::CreateNullPosition(); + ASSERT_NE(nullptr, null_position); + TestPositionType test_position = + null_position->CreatePositionAtEndOfDocument(); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsNullPosition()); +} + +TEST_F(AXPositionTest, CreatePositionAtEndOfDocumentWithTreePosition) { + TestPositionType tree_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, root_.id, 3 /* child_index */); + ASSERT_NE(nullptr, tree_position); + TestPositionType test_position = + tree_position->CreatePositionAtEndOfDocument(); + EXPECT_NE(nullptr, test_position); + EXPECT_EQ(inline_box2_.id, test_position->anchor_id()); + + tree_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, root_.id, 1 /* child_index */); + ASSERT_NE(nullptr, tree_position); + test_position = tree_position->CreatePositionAtEndOfDocument(); + EXPECT_NE(nullptr, test_position); + EXPECT_EQ(inline_box2_.id, test_position->anchor_id()); + + tree_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, inline_box1_.id, 0 /* child_index */); + ASSERT_NE(nullptr, tree_position); + test_position = tree_position->CreatePositionAtEndOfDocument(); + EXPECT_NE(nullptr, test_position); + EXPECT_EQ(inline_box2_.id, test_position->anchor_id()); +} + +TEST_F(AXPositionTest, CreatePositionAtEndOfDocumentWithTextPosition) { + TestPositionType text_position = AXNodePosition::CreateTextPosition( + tree_.data().tree_id, inline_box1_.id, 6 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + ASSERT_NE(nullptr, text_position); + TestPositionType test_position = + text_position->CreatePositionAtEndOfDocument(); + EXPECT_NE(nullptr, test_position); + EXPECT_EQ(inline_box2_.id, test_position->anchor_id()); + + text_position = AXNodePosition::CreateTextPosition( + tree_.data().tree_id, inline_box1_.id, 5 /* text_offset */, + ax::mojom::TextAffinity::kUpstream); + ASSERT_NE(nullptr, text_position); + test_position = text_position->CreatePositionAtEndOfDocument(); + EXPECT_NE(nullptr, test_position); + EXPECT_EQ(inline_box2_.id, test_position->anchor_id()); + // Affinity should have been reset to the default value. + EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity()); +} + TEST_F(AXPositionTest, CreateChildPositionAtWithNullPosition) { TestPositionType null_position = AXNodePosition::CreateNullPosition(); ASSERT_NE(nullptr, null_position);
diff --git a/ui/accessibility/ax_position.h b/ui/accessibility/ax_position.h index 1a207a14..10b0795a 100644 --- a/ui/accessibility/ax_position.h +++ b/ui/accessibility/ax_position.h
@@ -21,6 +21,7 @@ #include "base/strings/utf_string_conversions.h" #include "ui/accessibility/ax_enum_util.h" #include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_role_properties.h" #include "ui/accessibility/ax_tree_id.h" namespace ui { @@ -330,6 +331,20 @@ return false; } + bool AtStartOfDocument() const { + if (IsNullPosition() || !GetAnchor()) + return false; + + return ui::IsDocument(GetAnchor()->data().role) && AtStartOfAnchor(); + } + + bool AtEndOfDocument() const { + if (IsNullPosition() || !GetAnchor()) + return false; + + return CreateNextAnchorPosition()->IsNullPosition() && AtEndOfAnchor(); + } + // This method returns a position instead of a node because this allows us to // return the corresponding text offset or child index in the ancestor that // relates to the current position. @@ -517,6 +532,44 @@ return CreateNullPosition(); } + AXPositionInstance CreatePositionAtStartOfDocument() const { + if (kind_ == AXPositionKind::NULL_POSITION) + return CreateNullPosition(); + + AXPositionInstance iterator = Clone(); + while (!iterator->IsNullPosition()) { + if (ui::IsDocument(iterator->GetAnchor()->data().role) && + iterator->CreateParentPosition()->IsNullPosition()) { + return iterator->CreatePositionAtStartOfAnchor(); + } + iterator = iterator->CreateParentPosition(); + } + return CreateNullPosition(); + } + + AXPositionInstance CreatePositionAtEndOfDocument() const { + if (kind_ == AXPositionKind::NULL_POSITION) + return CreateNullPosition(); + + AXPositionInstance iterator = Clone(); + while (!iterator->IsNullPosition()) { + if (ui::IsDocument(iterator->GetAnchor()->data().role) && + iterator->CreateParentPosition()->IsNullPosition()) { + AXPositionInstance tree_position = iterator->AsTreePosition(); + DCHECK(tree_position); + while (tree_position->AnchorChildCount()) { + tree_position = tree_position->CreateChildPositionAt( + tree_position->AnchorChildCount() - 1); + } + iterator = + tree_position->AsLeafTextPosition()->CreatePositionAtEndOfAnchor(); + return iterator; + } + iterator = iterator->CreateParentPosition(); + } + return CreateNullPosition(); + } + AXPositionInstance CreateChildPositionAt(int child_index) const { if (IsNullPosition()) return CreateNullPosition();
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc index 14a7849..0b3b0d8 100644 --- a/ui/accessibility/platform/ax_platform_node_base.cc +++ b/ui/accessibility/platform/ax_platform_node_base.cc
@@ -290,6 +290,30 @@ return GetData().GetString16Attribute(attribute, value); } +const std::string& AXPlatformNodeBase::GetInheritedStringAttribute( + ax::mojom::StringAttribute attribute) const { + const AXPlatformNodeBase* current_node = this; + + do { + if (!current_node->delegate_) { + return base::EmptyString(); + } + + if (current_node->GetData().HasStringAttribute(attribute)) { + return current_node->GetData().GetStringAttribute(attribute); + } + + current_node = FromNativeViewAccessible(current_node->GetParent()); + } while (current_node); + + return base::EmptyString(); +} + +const base::string16 AXPlatformNodeBase::GetInheritedString16Attribute( + ax::mojom::StringAttribute attribute) const { + return base::UTF8ToUTF16(GetInheritedStringAttribute(attribute)); +} + bool AXPlatformNodeBase::HasIntListAttribute( ax::mojom::IntListAttribute attribute) const { if (!delegate_)
diff --git a/ui/accessibility/platform/ax_platform_node_base.h b/ui/accessibility/platform/ax_platform_node_base.h index 5cd44c74..992f11a 100644 --- a/ui/accessibility/platform/ax_platform_node_base.h +++ b/ui/accessibility/platform/ax_platform_node_base.h
@@ -99,6 +99,10 @@ base::string16* value) const; base::string16 GetString16Attribute( ax::mojom::StringAttribute attribute) const; + const std::string& GetInheritedStringAttribute( + ax::mojom::StringAttribute attribute) const; + const base::string16 GetInheritedString16Attribute( + ax::mojom::StringAttribute attribute) const; bool HasIntListAttribute(ax::mojom::IntListAttribute attribute) const; const std::vector<int32_t>& GetIntListAttribute(
diff --git a/ui/accessibility/platform/ax_platform_node_delegate.h b/ui/accessibility/platform/ax_platform_node_delegate.h index 6126acfb..d335356 100644 --- a/ui/accessibility/platform/ax_platform_node_delegate.h +++ b/ui/accessibility/platform/ax_platform_node_delegate.h
@@ -237,6 +237,7 @@ virtual base::string16 GetLocalizedStringForImageAnnotationStatus( ax::mojom::ImageAnnotationStatus status) const = 0; virtual base::string16 GetLocalizedStringForLandmarkType() const = 0; + virtual base::string16 GetStyleNameAttributeAsLocalizedString() const = 0; // // Testing.
diff --git a/ui/accessibility/platform/ax_platform_node_delegate_base.cc b/ui/accessibility/platform/ax_platform_node_delegate_base.cc index e5252bf..82bdc23 100644 --- a/ui/accessibility/platform/ax_platform_node_delegate_base.cc +++ b/ui/accessibility/platform/ax_platform_node_delegate_base.cc
@@ -241,6 +241,11 @@ return base::string16(); } +base::string16 +AXPlatformNodeDelegateBase::GetStyleNameAttributeAsLocalizedString() const { + return base::string16(); +} + bool AXPlatformNodeDelegateBase::ShouldIgnoreHoveredStateForTesting() { return true; }
diff --git a/ui/accessibility/platform/ax_platform_node_delegate_base.h b/ui/accessibility/platform/ax_platform_node_delegate_base.h index 86ad39f1..4600f1a 100644 --- a/ui/accessibility/platform/ax_platform_node_delegate_base.h +++ b/ui/accessibility/platform/ax_platform_node_delegate_base.h
@@ -194,6 +194,7 @@ ax::mojom::ImageAnnotationStatus status) const override; base::string16 GetLocalizedRoleDescriptionForUnlabeledImage() const override; base::string16 GetLocalizedStringForLandmarkType() const override; + base::string16 GetStyleNameAttributeAsLocalizedString() const override; // // Testing.
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc index 2008808..93e2d52d 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc
@@ -286,7 +286,49 @@ int count, int* units_moved) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_MOVEENDPOINTBYUNIT); - return E_NOTIMPL; + UIA_VALIDATE_TEXTRANGEPROVIDER_CALL(); + + *units_moved = 0; + + // Per MSDN, MoveEndpointByUnit with zero count has no effect + if (count == 0) + return S_OK; + + bool is_start_endpoint = endpoint == TextPatternRangeEndpoint_Start; + AXPositionInstance& position_to_move = is_start_endpoint ? start_ : end_; + AXPositionInstance new_position; + + switch (unit) { + case TextUnit_Character: + case TextUnit_Format: + case TextUnit_Word: + case TextUnit_Paragraph: + case TextUnit_Line: + return E_NOTIMPL; + // Page unit is not supported. + // Substituting it by the next larger unit (Document). + case TextUnit_Page: + case TextUnit_Document: + new_position = + MoveEndpointByDocument(position_to_move, count, units_moved); + break; + + default: + return UIA_E_NOTSUPPORTED; + } + + position_to_move = std::move(new_position); + + if (*start_ > *end_) { + // If the start was moved past the end, create a degenerate range + // with the end equal to the start, and vice versa + if (is_start_endpoint) + end_ = start_->Clone(); + else + start_ = end_->Clone(); + } + + return S_OK; } STDMETHODIMP AXPlatformNodeTextRangeProviderWin::MoveEndpointByRange( @@ -403,4 +445,26 @@ return owner_; } +AXPlatformNodeTextRangeProviderWin::AXPositionInstance +AXPlatformNodeTextRangeProviderWin::MoveEndpointByDocument( + const AXPositionInstance& endpoint, + const int count, + int* units_moved) { + DCHECK_NE(count, 0); + + *units_moved = 0; + AXPositionInstance current_endpoint = endpoint->Clone(); + const bool forwards = count > 0; + + if (forwards && !current_endpoint->AtEndOfDocument()) { + current_endpoint = endpoint->CreatePositionAtEndOfDocument(); + *units_moved = 1; + } else if (!forwards && !current_endpoint->AtStartOfDocument()) { + current_endpoint = endpoint->CreatePositionAtStartOfDocument(); + *units_moved = -1; + } + + return current_endpoint; +} + } // namespace ui
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h index aa211d6..4b8972d 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h
@@ -88,6 +88,10 @@ using AXPositionInstance = AXNodePosition::AXPositionInstance; using AXNodeRange = AXRange<AXNodePosition::AXPositionInstance::element_type>; + AXPositionInstance MoveEndpointByDocument(const AXPositionInstance& endpoint, + const int count, + int* units_moved); + AXNodePosition::AXPositionInstance start_; AXNodePosition::AXPositionInstance end_; CComPtr<ui::AXPlatformNodeWin> owner_;
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc index 9592c8a3..7acdbe50 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc
@@ -593,6 +593,131 @@ AXNodePosition::SetTreeForTesting(nullptr); } +TEST_F(AXPlatformNodeTextRangeProviderTest, + TestITextRangeProviderMoveEndpointByDocument) { + ui::AXNodeData text_data; + text_data.id = 2; + text_data.role = ax::mojom::Role::kStaticText; + text_data.SetName("some text"); + + ui::AXNodeData more_text_data; + more_text_data.id = 3; + more_text_data.role = ax::mojom::Role::kStaticText; + more_text_data.SetName("more text"); + + ui::AXNodeData even_more_text_data; + even_more_text_data.id = 4; + even_more_text_data.role = ax::mojom::Role::kStaticText; + even_more_text_data.SetName("even more text"); + + ui::AXNodeData root_data; + root_data.id = 1; + root_data.role = ax::mojom::Role::kRootWebArea; + root_data.child_ids = {2, 3, 4}; + + ui::AXTreeUpdate update; + ui::AXTreeData tree_data; + tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID(); + update.tree_data = tree_data; + update.has_tree_data = true; + update.root_id = root_data.id; + update.nodes.push_back(root_data); + update.nodes.push_back(text_data); + update.nodes.push_back(more_text_data); + update.nodes.push_back(even_more_text_data); + + Init(update); + + AXNode* root_node = GetRootNode(); + AXNodePosition::SetTreeForTesting(tree_.get()); + AXNode* text_node = root_node->children()[1]; + + ComPtr<IRawElementProviderSimple> text_node_raw = + QueryInterfaceFromNode<IRawElementProviderSimple>(text_node); + + ComPtr<ITextProvider> text_provider; + EXPECT_HRESULT_SUCCEEDED( + text_node_raw->GetPatternProvider(UIA_TextPatternId, &text_provider)); + + // Run the test twice, one for TextUnit_Document and once for TextUnit_Page, + // since they should have identical behavior. + const TextUnit textunit_types[] = {TextUnit_Document, TextUnit_Page}; + for (auto& textunit : textunit_types) { + ComPtr<ITextRangeProvider> text_range_provider; + EXPECT_HRESULT_SUCCEEDED( + text_provider->get_DocumentRange(&text_range_provider)); + + // Verify MoveEndpointByUnit with zero count has no effect + int count; + ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit( + TextPatternRangeEndpoint_End, textunit, /*count*/ 0, &count)); + ASSERT_EQ(0, count); + + // Move the endpoint to the end of the document. Verify all text content. + ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit( + TextPatternRangeEndpoint_End, textunit, /*count*/ 1, &count)); + ASSERT_EQ(1, count); + + base::win::ScopedBstr text_content; + ASSERT_HRESULT_SUCCEEDED( + text_range_provider->GetText(-1, text_content.Receive())); + EXPECT_STREQ(L"more texteven more text", text_content); + text_content.Reset(); + + // Verify no moves occur since the end is already at the end of the document + ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit( + TextPatternRangeEndpoint_End, textunit, /*count*/ 5, &count)); + ASSERT_EQ(0, count); + + ASSERT_HRESULT_SUCCEEDED( + text_range_provider->GetText(-1, text_content.Receive())); + EXPECT_STREQ(L"more texteven more text", text_content); + text_content.Reset(); + + // Move the end before the start + ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit( + TextPatternRangeEndpoint_End, textunit, /*count*/ -4, &count)); + ASSERT_EQ(-1, count); + + ASSERT_HRESULT_SUCCEEDED( + text_range_provider->GetText(-1, text_content.Receive())); + EXPECT_STREQ(L"", text_content); + text_content.Reset(); + + // Move the end back to the end of the document. The text content + // should now include the entire document since end was previously + // moved before start. + ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit( + TextPatternRangeEndpoint_End, textunit, /*count*/ 1, &count)); + ASSERT_EQ(1, count); + + ASSERT_HRESULT_SUCCEEDED( + text_range_provider->GetText(-1, text_content.Receive())); + EXPECT_STREQ(L"some textmore texteven more text", text_content); + text_content.Reset(); + + // Move the start point to the end + ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit( + TextPatternRangeEndpoint_Start, textunit, /*count*/ 3, &count)); + ASSERT_EQ(1, count); + + ASSERT_HRESULT_SUCCEEDED( + text_range_provider->GetText(-1, text_content.Receive())); + EXPECT_STREQ(L"", text_content); + text_content.Reset(); + + // Move the start point back to the beginning + ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit( + TextPatternRangeEndpoint_Start, textunit, /*count*/ -3, &count)); + ASSERT_EQ(-1, count); + + ASSERT_HRESULT_SUCCEEDED( + text_range_provider->GetText(-1, text_content.Receive())); + EXPECT_STREQ(L"some textmore texteven more text", text_content); + text_content.Reset(); + } +} + TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderCompare) { ui::AXNodeData text_data; text_data.id = 2; @@ -1222,6 +1347,8 @@ ui::AXNodeData text_data; text_data.id = 2; text_data.role = ax::mojom::Role::kStaticText; + text_data.AddStringAttribute(ax::mojom::StringAttribute::kFontFamily, "sans"); + text_data.AddFloatAttribute(ax::mojom::FloatAttribute::kFontWeight, 300); text_data.SetName("some text"); ui::AXNodeData more_text_data; @@ -1230,10 +1357,20 @@ more_text_data.AddState(ax::mojom::State::kInvisible); more_text_data.SetName("more text"); + ui::AXNodeData mark_data; + mark_data.id = 4; + mark_data.role = ax::mojom::Role::kMark; + mark_data.child_ids = {5}; + + ui::AXNodeData mark_text_data; + mark_text_data.id = 5; + mark_text_data.role = ax::mojom::Role::kStaticText; + mark_text_data.SetName("marked text"); + ui::AXNodeData root_data; root_data.id = 1; root_data.role = ax::mojom::Role::kRootWebArea; - root_data.child_ids = {2, 3}; + root_data.child_ids = {2, 3, 4}; ui::AXTreeUpdate update; ui::AXTreeData tree_data; @@ -1244,12 +1381,16 @@ update.nodes.push_back(root_data); update.nodes.push_back(text_data); update.nodes.push_back(more_text_data); + update.nodes.push_back(mark_data); + update.nodes.push_back(mark_text_data); Init(update); AXNodePosition::SetTreeForTesting(tree_.get()); AXNode* text_node = GetRootNode()->children()[0]; + AXNode* mark_node = GetRootNode()->children()[2]; + AXNode* mark_text_node = mark_node->children()[0]; ComPtr<ITextProvider> document_provider; EXPECT_HRESULT_SUCCEEDED( @@ -1261,6 +1402,11 @@ QueryInterfaceFromNode<IRawElementProviderSimple>(text_node) ->GetPatternProvider(UIA_TextPatternId, &text_provider)); + ComPtr<ITextProvider> mark_text_provider; + EXPECT_HRESULT_SUCCEEDED( + QueryInterfaceFromNode<IRawElementProviderSimple>(mark_text_node) + ->GetPatternProvider(UIA_TextPatternId, &mark_text_provider)); + ComPtr<ITextRangeProvider> document_range_provider; EXPECT_HRESULT_SUCCEEDED( document_provider->get_DocumentRange(&document_range_provider)); @@ -1269,6 +1415,10 @@ EXPECT_HRESULT_SUCCEEDED( text_provider->get_DocumentRange(&text_range_provider)); + ComPtr<ITextRangeProvider> mark_text_range_provider; + EXPECT_HRESULT_SUCCEEDED( + mark_text_provider->get_DocumentRange(&mark_text_range_provider)); + base::win::ScopedVariant expected_mixed_variant; { VARIANT var; @@ -1280,6 +1430,17 @@ base::win::ScopedVariant expected_variant; + base::string16 font_name = base::UTF8ToUTF16("sans"); + expected_variant.Set(SysAllocString(font_name.c_str())); + EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider, UIA_FontNameAttributeId, + expected_variant); + expected_variant.Reset(); + + expected_variant.Set(300); + EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider, UIA_FontWeightAttributeId, + expected_variant); + expected_variant.Reset(); + expected_variant.Set(false); EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider, UIA_IsHiddenAttributeId, expected_variant); @@ -1287,6 +1448,19 @@ EXPECT_UIA_TEXTATTRIBUTE_EQ(document_range_provider, UIA_IsHiddenAttributeId, expected_mixed_variant); + expected_variant.Reset(); + + base::string16 style_name = base::UTF8ToUTF16(""); + expected_variant.Set(SysAllocString(style_name.c_str())); + EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider, UIA_StyleNameAttributeId, + expected_variant); + expected_variant.Reset(); + + style_name = base::UTF8ToUTF16("mark"); + expected_variant.Set(SysAllocString(style_name.c_str())); + EXPECT_UIA_TEXTATTRIBUTE_EQ(mark_text_range_provider, + UIA_StyleNameAttributeId, expected_variant); + expected_variant.Reset(); } TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderSelect) {
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index bbc7d8a..b920e84 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -4014,10 +4014,18 @@ } switch (attribute_id) { + case UIA_FontNameAttributeId: + V_VT(result) = VT_BSTR; + V_BSTR(result) = GetFontNameAttributeAsBSTR(); + break; case UIA_IsHiddenAttributeId: V_VT(result) = VT_BOOL; V_BOOL(result) = IsInvisibleOrIgnored() ? VARIANT_TRUE : VARIANT_FALSE; break; + case UIA_StyleNameAttributeId: + V_VT(result) = VT_BSTR; + V_BSTR(result) = GetStyleNameAttributeAsBSTR(); + break; default: V_VT(result) = VT_UNKNOWN; return ::UiaGetReservedNotSupportedValue(&V_UNKNOWN(result)); @@ -6534,6 +6542,20 @@ return 100.0 * (y - y_min) / (y_max - y_min); } +BSTR AXPlatformNodeWin::GetFontNameAttributeAsBSTR() const { + const base::string16 string = + GetInheritedString16Attribute(ax::mojom::StringAttribute::kFontFamily); + + return SysAllocString(string.c_str()); +} + +BSTR AXPlatformNodeWin::GetStyleNameAttributeAsBSTR() const { + base::string16 style_name = + GetDelegate()->GetStyleNameAttributeAsLocalizedString(); + + return SysAllocString(style_name.c_str()); +} + // IRawElementProviderSimple support methods. AXPlatformNodeWin::PatternProviderFactoryMethod
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h index 2eb9a14..4631c665 100644 --- a/ui/accessibility/platform/ax_platform_node_win.h +++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -1191,6 +1191,12 @@ // Helper method for getting the vertical scroll percent. double GetVerticalScrollPercent(); + // Helper to get the UIA FontName for this node as a BSTR. + BSTR GetFontNameAttributeAsBSTR() const; + + // Helper to get the UIA StyleName for this node as a BSTR. + BSTR GetStyleNameAttributeAsBSTR() const; + // IRawElementProviderSimple support methods. using PatternProviderFactoryMethod = HRESULT (*)(AXPlatformNodeWin*,
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.cc b/ui/accessibility/platform/test_ax_node_wrapper.cc index cb27fcb..2fcb1ba8c 100644 --- a/ui/accessibility/platform/test_ax_node_wrapper.cc +++ b/ui/accessibility/platform/test_ax_node_wrapper.cc
@@ -543,6 +543,17 @@ return base::string16(); } +base::string16 TestAXNodeWrapper::GetStyleNameAttributeAsLocalizedString() + const { + AXNode* current_node = node_; + while (current_node) { + if (current_node->data().role == ax::mojom::Role::kMark) + return base::ASCIIToUTF16("mark"); + current_node = current_node->parent(); + } + return base::string16(); +} + bool TestAXNodeWrapper::ShouldIgnoreHoveredStateForTesting() { return true; }
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.h b/ui/accessibility/platform/test_ax_node_wrapper.h index 05509b1e..e3cfad2 100644 --- a/ui/accessibility/platform/test_ax_node_wrapper.h +++ b/ui/accessibility/platform/test_ax_node_wrapper.h
@@ -100,6 +100,7 @@ base::string16 GetLocalizedStringForLandmarkType() const override; base::string16 GetLocalizedStringForImageAnnotationStatus( ax::mojom::ImageAnnotationStatus status) const override; + base::string16 GetStyleNameAttributeAsLocalizedString() const override; bool ShouldIgnoreHoveredStateForTesting() override; const ui::AXUniqueId& GetUniqueId() const override; std::set<AXPlatformNode*> GetReverseRelations(
diff --git a/ui/android/java/res/values/color_palette.xml b/ui/android/java/res/values/color_palette.xml index c1637a9b..9b0df2b 100644 --- a/ui/android/java/res/values/color_palette.xml +++ b/ui/android/java/res/values/color_palette.xml
@@ -17,6 +17,7 @@ <color name="modern_grey_800_alpha_38" tools:ignore="UnusedResources">#613C4043</color> <color name="modern_grey_900">#202124</color> + <color name="modern_grey_900_with_white_alpha_4" tools:ignore="UnusedResources">#28292C</color> <color name="modern_grey_900_with_white_alpha_6" tools:ignore="UnusedResources">#2D2E31</color> <color name="modern_grey_900_with_white_alpha_8" tools:ignore="UnusedResources">#313235</color> <color name="modern_grey_900_with_white_alpha_10">#36373A</color> @@ -24,6 +25,7 @@ <color name="black_alpha_38">#61000000</color> <color name="white_alpha_10" tools:ignore="UnusedResources">#1AFFFFFF</color> + <color name="white_alpha_12" tools:ignore="UnusedResources">#1FFFFFFF</color> <color name="white_alpha_20">#33FFFFFF</color> <color name="white_alpha_38" tools:ignore="UnusedResources">#61FFFFFF</color> <color name="white_alpha_50" tools:ignore="UnusedResources">#80FFFFFF</color> @@ -65,6 +67,9 @@ <color name="default_bg_color_dark" tools:ignore="UnusedResources"> @color/modern_grey_900 </color> + <color name="default_bg_color_dark_elev_1" tools:ignore="UnusedResources"> + @color/modern_grey_900_with_white_alpha_4 + </color> <color name="default_bg_color_dark_elev_2" tools:ignore="UnusedResources"> @color/modern_grey_900_with_white_alpha_6 </color>
diff --git a/ui/android/java/res/values/colors.xml b/ui/android/java/res/values/colors.xml index 9df073f..b06992e 100644 --- a/ui/android/java/res/values/colors.xml +++ b/ui/android/java/res/values/colors.xml
@@ -48,6 +48,9 @@ <color name="default_bg_color_elev_0" tools:ignore="UnusedResources"> @color/modern_grey_100 </color> + <color name="default_bg_color_elev_1" tools:ignore="UnusedResources"> + @color/default_bg_color_light + </color> <color name="default_bg_color_elev_2" tools:ignore="UnusedResources"> @color/default_bg_color_light </color> @@ -65,14 +68,15 @@ <!-- Ripple colors for clickable widgets --> <color name="ripple_color_blue">@color/modern_blue_600</color> + <!-- Chip colors --> + <color name="chip_text_color_default">@color/default_text_color_secondary</color> + <color name="chip_text_color_selected">@color/default_text_color_link</color> + <color name="chip_background_color_disabled">@color/modern_grey_100_alpha_38</color> + <!-- Other colors --> <color name="default_red">@color/default_red_dark</color> <color name="default_green" tools:ignore="UnusedResources">@color/default_green_dark</color> <color name="filled_button_bg_color">@color/modern_blue_600</color> <color name="filled_button_bg_color_disabled">@color/modern_grey_800_alpha_38</color> - - <!-- Chip colors --> - <color name="chip_text_color_default">@color/default_text_color_secondary</color> - <color name="chip_text_color_selected">@color/default_text_color_link</color> - <color name="chip_background_color_disabled">@color/modern_grey_100_alpha_38</color> + <color name="divider_bg_color" tools:ignore="UnusedResources">@color/modern_grey_300</color> </resources>
diff --git a/ui/android/java/res_night/values-night/colors.xml b/ui/android/java/res_night/values-night/colors.xml index 6f8aacf7..bd5d9864 100644 --- a/ui/android/java/res_night/values-night/colors.xml +++ b/ui/android/java/res_night/values-night/colors.xml
@@ -25,6 +25,7 @@ <color name="modern_primary_color">@color/default_bg_color_dark</color> <color name="modern_secondary_color">@color/modern_grey_800</color> <color name="default_bg_color_elev_0">@color/default_bg_color_dark</color> + <color name="default_bg_color_elev_1">@color/default_bg_color_dark_elev_1</color> <color name="default_bg_color_elev_2">@color/default_bg_color_dark_elev_2</color> <color name="default_bg_color_elev_3">@color/default_bg_color_dark_elev_3</color> <color name="default_bg_color_elev_4">@color/default_bg_color_dark_elev_4</color> @@ -32,14 +33,15 @@ <!-- Ripple colors for clickable widgets --> <color name="ripple_color_blue">@color/modern_blue_300</color> + <!-- Chip colors --> + <color name="chip_text_color_default">@color/default_text_color_dark_secondary</color> + <color name="chip_text_color_selected">@color/default_text_color_dark</color> + <color name="chip_background_color_disabled">@color/modern_grey_300_alpha_38</color> + <!-- Other colors --> <color name="default_red">@color/default_red_light</color> <color name="default_green">@color/default_green_light</color> <color name="filled_button_bg_color">@color/modern_blue_300</color> <color name="filled_button_bg_color_disabled">@color/modern_grey_300_alpha_38</color> - - <!-- Chip colors --> - <color name="chip_text_color_default">@color/default_text_color_dark_secondary</color> - <color name="chip_text_color_selected">@color/default_text_color_dark</color> - <color name="chip_background_color_disabled">@color/modern_grey_300_alpha_38</color> + <color name="divider_bg_color">@color/white_alpha_12</color> </resources>
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc index b9a4f57f..fdd132b 100644 --- a/ui/aura/mus/window_tree_client.cc +++ b/ui/aura/mus/window_tree_client.cc
@@ -1822,12 +1822,6 @@ drag_drop_controller_.get()); } -void WindowTreeClient::ConnectToImeEngine( - ime::mojom::ImeEngineRequest engine_request, - ime::mojom::ImeEngineClientPtr client) { - tree_->ConnectToImeEngine(std::move(engine_request), std::move(client)); -} - void WindowTreeClient::OnTransientChildWindowAdded(Window* parent, Window* transient_child) { // TransientWindowClient is a singleton and we allow multiple
diff --git a/ui/aura/mus/window_tree_client.h b/ui/aura/mus/window_tree_client.h index 04a0a3d..c9b3d24 100644 --- a/ui/aura/mus/window_tree_client.h +++ b/ui/aura/mus/window_tree_client.h
@@ -515,8 +515,6 @@ std::unique_ptr<WindowPortMus> CreateWindowPortForTopLevel( const std::map<std::string, std::vector<uint8_t>>* properties) override; void OnWindowTreeHostCreated(WindowTreeHostMus* window_tree_host) override; - void ConnectToImeEngine(ime::mojom::ImeEngineRequest engine_request, - ime::mojom::ImeEngineClientPtr client) override; // client::TransientWindowClientObserver: void OnTransientChildWindowAdded(Window* parent,
diff --git a/ui/aura/mus/window_tree_host_mus.cc b/ui/aura/mus/window_tree_host_mus.cc index a0f22f07..25ec88b 100644 --- a/ui/aura/mus/window_tree_host_mus.cc +++ b/ui/aura/mus/window_tree_host_mus.cc
@@ -390,13 +390,6 @@ WindowPortMus::Get(window())->SetImeVisibility(visible, std::move(state)); } -bool WindowTreeHostMus::ConnectToImeEngine( - ime::mojom::ImeEngineRequest engine_request, - ime::mojom::ImeEngineClientPtr client) { - delegate_->ConnectToImeEngine(std::move(engine_request), std::move(client)); - return true; -} - void WindowTreeHostMus::SetBoundsInPixels( const gfx::Rect& bounds, const viz::LocalSurfaceIdAllocation& local_surface_id_allocation) {
diff --git a/ui/aura/mus/window_tree_host_mus.h b/ui/aura/mus/window_tree_host_mus.h index a8afe3b..45cdbf0 100644 --- a/ui/aura/mus/window_tree_host_mus.h +++ b/ui/aura/mus/window_tree_host_mus.h
@@ -16,7 +16,6 @@ #include "ui/aura/aura_export.h" #include "ui/aura/mus/input_method_mus_delegate.h" #include "ui/aura/window_tree_host_platform.h" -#include "ui/base/ime/mojo/ime.mojom.h" #include "ui/base/mojo/ui_base_types.mojom.h" namespace display { @@ -119,8 +118,6 @@ void SetTextInputState(ui::mojom::TextInputStatePtr state) override; void SetImeVisibility(bool visible, ui::mojom::TextInputStatePtr state) override; - bool ConnectToImeEngine(ime::mojom::ImeEngineRequest engine_request, - ime::mojom::ImeEngineClientPtr client) override; protected: // This is in the protected section as SetBounds() is preferred.
diff --git a/ui/aura/mus/window_tree_host_mus_delegate.h b/ui/aura/mus/window_tree_host_mus_delegate.h index d45ed48..76f759a5 100644 --- a/ui/aura/mus/window_tree_host_mus_delegate.h +++ b/ui/aura/mus/window_tree_host_mus_delegate.h
@@ -12,7 +12,6 @@ #include <vector> #include "ui/aura/aura_export.h" -#include "ui/base/ime/mojo/ime.mojom.h" namespace gfx { class Rect; @@ -76,11 +75,6 @@ // created. virtual void OnWindowTreeHostCreated(WindowTreeHostMus* window_tree_host) = 0; - // Called when a client requests to connect to the active - // ime::mojom::ImeEngine. - virtual void ConnectToImeEngine(ime::mojom::ImeEngineRequest engine_request, - ime::mojom::ImeEngineClientPtr client) = 0; - protected: virtual ~WindowTreeHostMusDelegate() {} };
diff --git a/ui/base/ime/BUILD.gn b/ui/base/ime/BUILD.gn index 8826b212..5323a67 100644 --- a/ui/base/ime/BUILD.gn +++ b/ui/base/ime/BUILD.gn
@@ -13,47 +13,15 @@ ] } -jumbo_component("ime_types") { - output_name = "ui_base_ime_types" - sources = [ - "candidate_window.cc", - "candidate_window.h", - "composition_text.cc", - "composition_text.h", - "ime_text_span.cc", - "ime_text_span.h", - "infolist_entry.cc", - "infolist_entry.h", - ] - - defines = [ "IS_UI_BASE_IME_TYPES_IMPL" ] - - deps = [ - "//base", - "//ui/gfx/range", - ] - - public_deps = [ - ":text_input_types", - "//skia", - ] - - if (is_chromeos || use_ozone) { - sources += [ - "character_composer.cc", - "character_composer.h", - ] - deps += [ - "//ui/events:dom_keycode_converter", - "//ui/events:events", - "//ui/events:events_base", - ] - } -} - jumbo_component("ime") { output_name = "ui_base_ime" sources = [ + "candidate_window.cc", + "candidate_window.h", + "character_composer.cc", + "character_composer.h", + "composition_text.cc", + "composition_text.h", "constants.cc", "constants.h", "ime_bridge.cc", @@ -61,6 +29,10 @@ "ime_candidate_window_handler_interface.h", "ime_engine_handler_interface.h", "ime_input_context_handler_interface.h", + "ime_text_span.cc", + "ime_text_span.h", + "infolist_entry.cc", + "infolist_entry.h", "input_method.h", "input_method_base.cc", "input_method_base.h", @@ -85,13 +57,11 @@ defines = [ "IS_UI_BASE_IME_IMPL" ] public_deps = [ - ":ime_types", ":text_input_types", "//base", "//base:i18n", "//skia", "//third_party/icu", - "//ui/base/ime/mojo", "//ui/events", "//ui/events:dom_keycode_converter", "//ui/events:events",
diff --git a/ui/base/ime/candidate_window.h b/ui/base/ime/candidate_window.h index 82c3fac..57e40d04 100644 --- a/ui/base/ime/candidate_window.h +++ b/ui/base/ime/candidate_window.h
@@ -18,14 +18,14 @@ namespace ui { // CandidateWindow represents the structure of candidates generated from IME. -class COMPONENT_EXPORT(UI_BASE_IME_TYPES) CandidateWindow { +class COMPONENT_EXPORT(UI_BASE_IME) CandidateWindow { public: enum Orientation { HORIZONTAL = 0, VERTICAL = 1, }; - struct COMPONENT_EXPORT(UI_BASE_IME_TYPES) CandidateWindowProperty { + struct COMPONENT_EXPORT(UI_BASE_IME) CandidateWindowProperty { CandidateWindowProperty(); virtual ~CandidateWindowProperty(); int page_size; @@ -41,7 +41,7 @@ }; // Represents a candidate entry. - struct COMPONENT_EXPORT(UI_BASE_IME_TYPES) Entry { + struct COMPONENT_EXPORT(UI_BASE_IME) Entry { Entry(); Entry(const Entry& other); virtual ~Entry();
diff --git a/ui/base/ime/character_composer.h b/ui/base/ime/character_composer.h index 57642c4..42baf12 100644 --- a/ui/base/ime/character_composer.h +++ b/ui/base/ime/character_composer.h
@@ -20,7 +20,7 @@ // A class to recognize compose and dead key sequence. // Outputs composed character. -class COMPONENT_EXPORT(UI_BASE_IME_TYPES) CharacterComposer { +class COMPONENT_EXPORT(UI_BASE_IME) CharacterComposer { public: using ComposeBuffer = std::vector<DomKey>;
diff --git a/ui/base/ime/chromeos/BUILD.gn b/ui/base/ime/chromeos/BUILD.gn index 0c31364..aee4bc0 100644 --- a/ui/base/ime/chromeos/BUILD.gn +++ b/ui/base/ime/chromeos/BUILD.gn
@@ -57,7 +57,6 @@ "//services/ws/public/cpp/input_devices", "//third_party/icu", "//ui/base", - "//ui/base/ime/mojo", "//ui/chromeos/strings", ] }
diff --git a/ui/base/ime/chromeos/input_method_chromeos.cc b/ui/base/ime/chromeos/input_method_chromeos.cc index 587b0890..bc94b4eb 100644 --- a/ui/base/ime/chromeos/input_method_chromeos.cc +++ b/ui/base/ime/chromeos/input_method_chromeos.cc
@@ -19,15 +19,12 @@ #include "base/strings/utf_string_conversions.h" #include "base/third_party/icu/icu_utf.h" #include "chromeos/system/devicemode.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/interface_request.h" #include "ui/base/ime/chromeos/ime_keyboard.h" #include "ui/base/ime/chromeos/input_method_manager.h" #include "ui/base/ime/composition_text.h" #include "ui/base/ime/ime_bridge.h" #include "ui/base/ime/ime_engine_handler_interface.h" #include "ui/base/ime/input_method_delegate.h" -#include "ui/base/ime/mojo/ime.mojom.h" #include "ui/base/ime/text_input_client.h" #include "ui/events/event.h" #include "ui/gfx/geometry/rect.h" @@ -60,68 +57,6 @@ } // namespace -// The helper to make the InputMethodChromeOS as a ime::mojom::ImeEngineClient. -// It forwards the ime::mojom::ImeEngineClient method calls toi methods of -// ui::IMEInputContextHandlerInterface methods. -// Due to the method naming conflict, InputMethodChromeOS cannot directly -// inherit from ime::mojom::ImeEngineClient. -class InputMethodChromeOS::MojoHelper : public ime::mojom::ImeEngineClient { - public: - explicit MojoHelper(InputMethodChromeOS* im) : im_(im), binding_(this) {} - ~MojoHelper() override = default; - - ime::mojom::ImeEngineProxy* ime_engine() { return ime_engine_.get(); } - - bool connected() const { return connected_; } - - void Connect() { - ime::mojom::ImeEngineClientPtr client_ptr; - binding_.Bind(mojo::MakeRequest(&client_ptr)); - connected_ = im_->delegate()->ConnectToImeEngine( - mojo::MakeRequest(&ime_engine_), std::move(client_ptr)); - } - - void Reset() { - binding_.Close(); - ime_engine_.reset(); - connected_ = false; - } - - private: - // ime::mojom::ImeEngineClient: - void CommitText(const std::string& text) override { im_->CommitText(text); } - void UpdateCompositionText(const ui::CompositionText& composition_text, - uint32_t cursor_pos, - bool visible) override { - im_->UpdateCompositionText(composition_text, cursor_pos, visible); - } - void DeleteSurroundingText(int32_t offset, uint32_t length) override { - im_->DeleteSurroundingText(offset, length); - } - void SendKeyEvent(std::unique_ptr<ui::Event> key_event) override { - im_->SendKeyEvent(key_event->AsKeyEvent()); - } - void Reconnect() override { - // Don't reconnect when the |ime_engine_| has been reset, which means the - // InputMethodChromeOS is not focused. - if (ime_engine_) { - Reset(); - Connect(); - } - } - - InputMethodChromeOS* im_; - // Whether the mojo connection is enabled. - // If true, |InputMethodChromeOS| works with ime::mojom::ImeEngine. - // If false, |InputMethodChromeOS| works with ui::IMEEngineHandlerInterface. - bool connected_ = false; - - mojo::Binding<ime::mojom::ImeEngineClient> binding_; - ime::mojom::ImeEnginePtr ime_engine_; - - DISALLOW_COPY_AND_ASSIGN(MojoHelper); -}; - // InputMethodChromeOS implementation ----------------------------------------- InputMethodChromeOS::InputMethodChromeOS( internal::InputMethodDelegate* delegate) @@ -129,7 +64,6 @@ composing_text_(false), composition_changed_(false), handling_key_event_(false), - mojo_helper_(std::make_unique<MojoHelper>(this)), weak_ptr_factory_(this) { ui::IMEBridge::Get()->SetInputContextHandler(this); @@ -216,8 +150,7 @@ // normal input field (not a password field). // Note: We need to send the key event to ibus even if the |context_| is not // enabled, so that ibus can have a chance to enable the |context_|. - const bool has_engine = GetEngine() || mojo_helper_->connected(); - if (!IsNonPasswordInputFieldFocused() || !has_engine) { + if (!IsNonPasswordInputFieldFocused() || !GetEngine()) { if (event->type() == ET_KEY_PRESSED) { if (ExecuteCharacterComposer(*event)) { // Treating as PostIME event if character composer handles key event and @@ -232,17 +165,13 @@ } handling_key_event_ = true; - ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback = base::BindOnce( - &InputMethodChromeOS::KeyEventDoneCallback, - weak_ptr_factory_.GetWeakPtr(), - // Pass the ownership of the new copied event. - base::Owned(new ui::KeyEvent(*event)), std::move(result_callback)); - if (mojo_helper_->connected()) { - mojo_helper_->ime_engine()->ProcessKeyEvent(ui::Event::Clone(*event), - std::move(callback)); - return ui::EventDispatchDetails(); - } if (GetEngine()->IsInterestedInKeyEvent()) { + ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback = + base::BindOnce(&InputMethodChromeOS::KeyEventDoneCallback, + weak_ptr_factory_.GetWeakPtr(), + // Pass the ownership of the new copied event. + base::Owned(new ui::KeyEvent(*event)), + std::move(result_callback)); GetEngine()->ProcessKeyEvent(*event, std::move(callback)); return ui::EventDispatchDetails(); } @@ -298,23 +227,16 @@ UpdateContextFocusState(); - if (mojo_helper_->connected()) { - mojo_helper_->ime_engine()->FinishInput(); - mojo_helper_->ime_engine()->StartInput(ime::mojom::EditorInfo::New( + ui::IMEEngineHandlerInterface* engine = GetEngine(); + if (engine) { + // When focused input client is not changed, a text input type change should + // cause blur/focus events to engine. + // The focus in to or out from password field should also notify engine. + engine->FocusOut(); + ui::IMEEngineHandlerInterface::InputContext context( GetTextInputType(), GetTextInputMode(), GetTextInputFlags(), - GetClientFocusReason(), GetClientShouldDoLearning())); - } else { - ui::IMEEngineHandlerInterface* engine = GetEngine(); - if (engine) { - ui::IMEEngineHandlerInterface::InputContext context( - GetTextInputType(), GetTextInputMode(), GetTextInputFlags(), - GetClientFocusReason(), GetClientShouldDoLearning()); - // When focused input client is not changed, a text input type change - // should cause blur/focus events to engine. The focus in to or out from - // password field should also notify engine. - engine->FocusOut(); - engine->FocusIn(context); - } + GetClientFocusReason(), GetClientShouldDoLearning()); + engine->FocusIn(context); } OnCaretBoundsChanged(client); @@ -335,12 +257,8 @@ DCHECK(client == GetTextInputClient()); DCHECK(!IsTextInputTypeNone()); - if (mojo_helper_->connected()) { - mojo_helper_->ime_engine()->UpdateCompositionBounds( - GetCompositionBounds(client)); - } else if (GetEngine()) { + if (GetEngine()) GetEngine()->SetCompositionBounds(GetCompositionBounds(client)); - } chromeos::IMECandidateWindowHandlerInterface* candidate_window = ui::IMEBridge::Get()->GetCandidateWindowHandler(); @@ -387,17 +305,12 @@ // Here SetSurroundingText accepts relative position of |surrounding_text|, so // we have to convert |selection_range| from node coordinates to // |surrounding_text| coordinates. - if (mojo_helper_->connected()) { - mojo_helper_->ime_engine()->UpdateSurroundingInfo( - base::UTF16ToUTF8(surrounding_text), - selection_range.start() - text_range.start(), - selection_range.end() - text_range.start(), text_range.start()); - } else if (GetEngine()) { - GetEngine()->SetSurroundingText( - base::UTF16ToUTF8(surrounding_text), - selection_range.start() - text_range.start(), - selection_range.end() - text_range.start(), text_range.start()); - } + if (!GetEngine()) + return; + GetEngine()->SetSurroundingText(base::UTF16ToUTF8(surrounding_text), + selection_range.start() - text_range.start(), + selection_range.end() - text_range.start(), + text_range.start()); } void InputMethodChromeOS::CancelComposition(const TextInputClient* client) { @@ -421,26 +334,13 @@ return InputMethodBase::GetInputMethodKeyboardController(); } -void InputMethodChromeOS::OnFocus() { - InputMethodBase::OnFocus(); - mojo_helper_->Connect(); -} - -void InputMethodChromeOS::OnBlur() { - InputMethodBase::OnBlur(); - mojo_helper_->Reset(); -} - void InputMethodChromeOS::OnWillChangeFocusedClient( TextInputClient* focused_before, TextInputClient* focused) { ConfirmCompositionText(); - if (mojo_helper_->connected()) { - mojo_helper_->ime_engine()->FinishInput(); - } else if (GetEngine()) { + if (GetEngine()) GetEngine()->FocusOut(); - } } void InputMethodChromeOS::OnDidChangeFocusedClient( @@ -451,11 +351,7 @@ // focus and after it acquires focus again are the same. UpdateContextFocusState(); - if (mojo_helper_->connected()) { - mojo_helper_->ime_engine()->StartInput(ime::mojom::EditorInfo::New( - GetTextInputType(), GetTextInputMode(), GetTextInputFlags(), - GetClientFocusReason(), GetClientShouldDoLearning())); - } else if (GetEngine()) { + if (GetEngine()) { ui::IMEEngineHandlerInterface::InputContext context( GetTextInputType(), GetTextInputMode(), GetTextInputFlags(), GetClientFocusReason(), GetClientShouldDoLearning()); @@ -486,9 +382,7 @@ // Note: some input method engines may not support reset method, such as // ibus-anthy. But as we control all input method engines by ourselves, we can // make sure that all of the engines we are using support it correctly. - if (mojo_helper_->connected()) - mojo_helper_->ime_engine()->CancelInput(); - else if (GetEngine()) + if (GetEngine()) GetEngine()->Reset(); character_composer_.Reset();
diff --git a/ui/base/ime/chromeos/input_method_chromeos.h b/ui/base/ime/chromeos/input_method_chromeos.h index 41d809e..e7d968ca 100644 --- a/ui/base/ime/chromeos/input_method_chromeos.h +++ b/ui/base/ime/chromeos/input_method_chromeos.h
@@ -24,8 +24,6 @@ namespace ui { -class TestableInputMethodChromeOS; - // A ui::InputMethod implementation for ChromeOS. class COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) InputMethodChromeOS : public InputMethodBase, @@ -50,8 +48,6 @@ InputMethodKeyboardController* GetInputMethodKeyboardController() override; // Overridden from InputMethodBase: - void OnFocus() override; - void OnBlur() override; void OnWillChangeFocusedClient(TextInputClient* focused_before, TextInputClient* focused) override; void OnDidChangeFocusedClient(TextInputClient* focused_before, @@ -75,9 +71,7 @@ void ResetContext(); private: - class MojoHelper; class PendingKeyEvent; - friend TestableInputMethodChromeOS; ui::EventDispatchDetails DispatchKeyEventInternal(ui::KeyEvent* event, AckCallback ack_callback); @@ -186,8 +180,6 @@ // This is used in CommitText/UpdateCompositionText/etc. bool handling_key_event_; - std::unique_ptr<MojoHelper> mojo_helper_; - // Used for making callbacks. base::WeakPtrFactory<InputMethodChromeOS> weak_ptr_factory_;
diff --git a/ui/base/ime/chromeos/input_method_chromeos_unittest.cc b/ui/base/ime/chromeos/input_method_chromeos_unittest.cc index f456a48..07ad8b0 100644 --- a/ui/base/ime/chromeos/input_method_chromeos_unittest.cc +++ b/ui/base/ime/chromeos/input_method_chromeos_unittest.cc
@@ -15,8 +15,6 @@ #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "base/test/bind_test_util.h" -#include "base/test/scoped_task_environment.h" -#include "mojo/public/cpp/bindings/binding.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ime/chromeos/mock_ime_candidate_window_handler.h" @@ -27,7 +25,6 @@ #include "ui/base/ime/ime_bridge.h" #include "ui/base/ime/ime_engine_handler_interface.h" #include "ui/base/ime/input_method_delegate.h" -#include "ui/base/ime/mojo/ime.mojom.h" #include "ui/base/ime/text_input_client.h" #include "ui/events/event.h" #include "ui/events/event_utils.h" @@ -91,10 +88,6 @@ } return details; } - void CommitText(const std::string& text) override { - InputMethodChromeOS::CommitText(text); - text_committed_ = text; - } void ResetCallCount() { process_key_event_post_ime_call_count_ = 0; @@ -108,8 +101,6 @@ return process_key_event_post_ime_call_count_; } - const std::string& text_committed() const { return text_committed_; } - // Change access rights for testing. using InputMethodChromeOS::ExtractCompositionText; using InputMethodChromeOS::ResetContext; @@ -117,7 +108,6 @@ private: ProcessKeyEventPostIMEArgs process_key_event_post_ime_args_; int process_key_event_post_ime_call_count_; - std::string text_committed_; }; class SetSurroundingTextVerifier { @@ -234,53 +224,6 @@ DISALLOW_COPY_AND_ASSIGN(CachingInputMethodDelegate); }; -class MojoInputMethodDelegate : public ui::internal::InputMethodDelegate, - public ime::mojom::ImeEngine { - public: - MojoInputMethodDelegate() : engine_binding_(this) {} - ~MojoInputMethodDelegate() override = default; - - ime::mojom::ImeEngineClientProxy* engine_client() const { - return engine_client_.get(); - } - - void FlushForTesting() { engine_client_.FlushForTesting(); } - - private: - // Overridden from ui::internal::InputMethodDelegate: - ui::EventDispatchDetails DispatchKeyEventPostIME( - ui::KeyEvent* event, - DispatchKeyEventPostIMECallback callback) override { - event->StopPropagation(); - RunDispatchKeyEventPostIMECallback(event, std::move(callback)); - return ui::EventDispatchDetails(); - } - bool ConnectToImeEngine(ime::mojom::ImeEngineRequest engine_request, - ime::mojom::ImeEngineClientPtr client) override { - engine_binding_.Bind(std::move(engine_request)); - engine_client_ = std::move(client); - return true; - } - - // ime::mojom::ImeEngine: - void StartInput(ime::mojom::EditorInfoPtr info) override {} - void FinishInput() override {} - void CancelInput() override {} - void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event, - ProcessKeyEventCallback callback) override {} - void UpdateSurroundingInfo(const std::string& text, - int32_t cursor, - int32_t anchor, - int32_t offset) override {} - void UpdateCompositionBounds(const std::vector<gfx::Rect>& bounds) override {} - - mojo::Binding<ime::mojom::ImeEngine> engine_binding_; - - ime::mojom::ImeEngineClientPtr engine_client_; - - DISALLOW_COPY_AND_ASSIGN(MojoInputMethodDelegate); -}; - class InputMethodChromeOSTest : public internal::InputMethodDelegate, public testing::Test, public DummyTextInputClient { @@ -445,8 +388,6 @@ TestInputMethodManager* input_method_manager_; - base::test::ScopedTaskEnvironment scoped_task_environment_; - DISALLOW_COPY_AND_ASSIGN(InputMethodChromeOSTest); }; @@ -970,15 +911,6 @@ IMEBridge::Get()->SetCurrentEngineHandler(nullptr); } -TEST_F(InputMethodChromeOSTest, MojoInteractions) { - MojoInputMethodDelegate delegate; - TestableInputMethodChromeOS im(&delegate); - im.OnFocus(); - delegate.engine_client()->CommitText("test"); - delegate.FlushForTesting(); - EXPECT_EQ("test", im.text_committed()); -} - class InputMethodChromeOSKeyEventTest : public InputMethodChromeOSTest { public: InputMethodChromeOSKeyEventTest() {}
diff --git a/ui/base/ime/composition_text.h b/ui/base/ime/composition_text.h index cddf445e..ba7b76f 100644 --- a/ui/base/ime/composition_text.h +++ b/ui/base/ime/composition_text.h
@@ -15,7 +15,7 @@ namespace ui { // A struct represents the status of an ongoing composition text. -struct COMPONENT_EXPORT(UI_BASE_IME_TYPES) CompositionText { +struct COMPONENT_EXPORT(UI_BASE_IME) CompositionText { CompositionText(); CompositionText(const CompositionText& other); ~CompositionText();
diff --git a/ui/base/ime/ime_text_span.h b/ui/base/ime/ime_text_span.h index 4e449567..4125a3b 100644 --- a/ui/base/ime/ime_text_span.h +++ b/ui/base/ime/ime_text_span.h
@@ -18,7 +18,7 @@ // Intentionally keep sync with blink::WebImeTextSpan defined in: // third_party/WebKit/public/web/WebImeTextSpan.h -struct COMPONENT_EXPORT(UI_BASE_IME_TYPES) ImeTextSpan { +struct COMPONENT_EXPORT(UI_BASE_IME) ImeTextSpan { enum class Type { // Creates a composition marker. kComposition,
diff --git a/ui/base/ime/infolist_entry.h b/ui/base/ime/infolist_entry.h index 54d6320..107db39 100644 --- a/ui/base/ime/infolist_entry.h +++ b/ui/base/ime/infolist_entry.h
@@ -11,7 +11,7 @@ namespace ui { // The data model of infolist window. -struct COMPONENT_EXPORT(UI_BASE_IME_TYPES) InfolistEntry { +struct COMPONENT_EXPORT(UI_BASE_IME) InfolistEntry { base::string16 title; base::string16 body; bool highlighted;
diff --git a/ui/base/ime/input_method_delegate.cc b/ui/base/ime/input_method_delegate.cc index 92c25586..dc950847 100644 --- a/ui/base/ime/input_method_delegate.cc +++ b/ui/base/ime/input_method_delegate.cc
@@ -5,18 +5,11 @@ #include "ui/base/ime/input_method_delegate.h" #include "base/callback.h" -#include "ui/base/ime/mojo/ime.mojom.h" #include "ui/events/event.h" namespace ui { namespace internal { -bool InputMethodDelegate::ConnectToImeEngine( - ::ime::mojom::ImeEngineRequest engine_request, - ::ime::mojom::ImeEngineClientPtr client) { - return false; -} - // static void InputMethodDelegate::RunDispatchKeyEventPostIMECallback( KeyEvent* key_event,
diff --git a/ui/base/ime/input_method_delegate.h b/ui/base/ime/input_method_delegate.h index 324982e..a0bcccd2 100644 --- a/ui/base/ime/input_method_delegate.h +++ b/ui/base/ime/input_method_delegate.h
@@ -7,17 +7,6 @@ #include "base/callback_forward.h" #include "base/component_export.h" -#include "mojo/public/cpp/bindings/interface_ptr.h" -#include "mojo/public/cpp/bindings/interface_request.h" - -namespace ime { -namespace mojom { - -class ImeEngine; -class ImeEngineClient; - -} // namespace mojom -} // namespace ime namespace ui { @@ -45,10 +34,6 @@ KeyEvent* key_event, DispatchKeyEventPostIMECallback callback) = 0; - virtual bool ConnectToImeEngine( - mojo::InterfaceRequest<::ime::mojom::ImeEngine> engine_request, - mojo::InterfacePtr<::ime::mojom::ImeEngineClient> client); - protected: static void RunDispatchKeyEventPostIMECallback( KeyEvent* key_event,
diff --git a/ui/base/ime/mojo/ime.mojom b/ui/base/ime/mojo/ime.mojom index d28cbf8d..993922c4 100644 --- a/ui/base/ime/mojo/ime.mojom +++ b/ui/base/ime/mojo/ime.mojom
@@ -60,25 +60,6 @@ // (e.g. by IME's on-screen keyboard) // - later after the IME responds the |ProcessKeyEvent| with the result; interface ImeEngineClient { - // Called when the IME wants to insert the |text| to the input field. - CommitText(string text); - - // Called when the IME wants to generate/update the composition text to the - // input field. - UpdateCompositionText(ui.mojom.CompositionText composition_text, - uint32 cursor_pos, - bool visible); - - // Called when the IME wants to remove a piece of text in the input field. - DeleteSurroundingText(int32 offset, uint32 length); - - // Called when the IME wants to silumate a physical key event to the app. - // Usually this is for on-screen keyboard support (e.g. simulate Enter key). - SendKeyEvent(ui.mojom.Event key_event); - - // Called when the ImeEngine is deactivated and this client should reconnect - // for the new active ImeEngine. - Reconnect(); }; // Implemented by the IME.
diff --git a/ui/base/ime/mojo/ime_types.typemap b/ui/base/ime/mojo/ime_types.typemap index acdc8fff..4e800fc6 100644 --- a/ui/base/ime/mojo/ime_types.typemap +++ b/ui/base/ime/mojo/ime_types.typemap
@@ -15,7 +15,7 @@ "//ui/base/ime/mojo/ime_types_struct_traits.cc", ] public_deps = [ - "//ui/base/ime:ime_types", + "//ui/base/ime", ] deps = [ "//ui/gfx/range",
diff --git a/ui/keyboard/BUILD.gn b/ui/keyboard/BUILD.gn index 1cbb657..107da45 100644 --- a/ui/keyboard/BUILD.gn +++ b/ui/keyboard/BUILD.gn
@@ -171,7 +171,6 @@ "//base", "//base/test:test_support", "//components/ukm:test_support", - "//mojo/core/embedder", "//services/service_manager/public/cpp", "//testing/gmock", "//testing/gtest",
diff --git a/ui/keyboard/test/run_all_unittests.cc b/ui/keyboard/test/run_all_unittests.cc index 2b3a1706..9d0da8c 100644 --- a/ui/keyboard/test/run_all_unittests.cc +++ b/ui/keyboard/test/run_all_unittests.cc
@@ -8,7 +8,6 @@ #include "base/path_service.h" #include "base/test/launcher/unit_test_launcher.h" #include "base/test/test_suite.h" -#include "mojo/core/embedder/embedder.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/env.h" #include "ui/base/resource/resource_bundle.h" @@ -50,7 +49,6 @@ int main(int argc, char** argv) { KeyboardTestSuite test_suite(argc, argv); - mojo::core::Init(); return base::LaunchUnitTests( argc, argv, base::BindOnce(&KeyboardTestSuite::Run, base::Unretained(&test_suite)));
diff --git a/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc b/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc index 761a10c..7385a97 100644 --- a/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc +++ b/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc
@@ -286,7 +286,7 @@ const int hit; } kTestCases[] = { #if defined(OS_WIN) - {0, is_aero_glass_enabled ? HTTRANSPARENT : HTNOWHERE}, + {0, is_aero_glass_enabled ? HTTRANSPARENT : HTCAPTION}, #else {0, HTTRANSPARENT}, #endif
diff --git a/ui/views/bubble/bubble_frame_view.cc b/ui/views/bubble/bubble_frame_view.cc index 3828c024..a6a60190 100644 --- a/ui/views/bubble/bubble_frame_view.cc +++ b/ui/views/bubble/bubble_frame_view.cc
@@ -181,19 +181,6 @@ if (close_->visible() && close_->GetMirroredBounds().Contains(point)) return HTCLOSE; - // Allow dialogs to show the system menu and be dragged. - if (GetWidget()->widget_delegate()->AsDialogDelegate() && - !GetWidget()->widget_delegate()->AsBubbleDialogDelegate()) { - gfx::Rect bounds(GetContentsBounds()); - bounds.Inset(title_margins_); - gfx::Rect sys_rect(0, 0, bounds.x(), bounds.y()); - sys_rect.set_origin(gfx::Point(GetMirroredXForRect(sys_rect), 0)); - if (sys_rect.Contains(point)) - return HTSYSMENU; - if (point.y() < title()->bounds().bottom()) - return HTCAPTION; - } - // Convert to RRectF to accurately represent the rounded corners of the // dialog and allow events to pass through the shadows. gfx::RRectF round_contents_bounds(gfx::RectF(GetContentsBounds()), @@ -204,6 +191,16 @@ if (!round_contents_bounds.Contains(rectf_point)) return HTTRANSPARENT; + if (HasTitle() && point.y() < title()->bounds().bottom()) { + auto* dialog_delegate = GetWidget()->widget_delegate()->AsDialogDelegate(); + // Allow the dialog to be dragged if it is not modal. This can happen if the + // dialog has no parent browser window. + if (dialog_delegate && + dialog_delegate->GetModalType() == ui::MODAL_TYPE_NONE) { + return HTCAPTION; + } + } + return GetWidget()->client_view()->NonClientHitTest(point); }
diff --git a/ui/views/window/dialog_delegate_unittest.cc b/ui/views/window/dialog_delegate_unittest.cc index b8e92a1..f57ce79 100644 --- a/ui/views/window/dialog_delegate_unittest.cc +++ b/ui/views/window/dialog_delegate_unittest.cc
@@ -4,10 +4,12 @@ #include <stddef.h> +#include "base/command_line.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "ui/base/hit_test.h" +#include "ui/base/ui_base_switches.h" #include "ui/events/event_processor.h" #include "ui/views/bubble/bubble_border.h" #include "ui/views/bubble/bubble_frame_view.h" @@ -98,6 +100,13 @@ views::Textfield* input() { return input_; } + ui::ModalType GetModalType() const override { return modal_type_; } + void SetModal() { + // Use MODAL_TYPE_CHILD (tab-modal) since it behaves most consistently + // between platforms. + modal_type_ = ui::MODAL_TYPE_CHILD; + } + private: views::Textfield* input_; bool canceled_ = false; @@ -109,6 +118,7 @@ bool show_close_button_ = true; bool should_handle_escape_ = false; int dialog_buttons_ = ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL; + ui::ModalType modal_type_ = ui::MODAL_TYPE_NONE; DISALLOW_COPY_AND_ASSIGN(TestDialog); }; @@ -120,6 +130,10 @@ void SetUp() override { ViewsTestBase::SetUp(); +#if defined(OS_MACOSX) + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kDisableModalAnimations); +#endif InitializeDialog(); ShowDialog(); } @@ -216,22 +230,22 @@ const NonClientView* view = dialog()->GetWidget()->non_client_view(); BubbleFrameView* frame = static_cast<BubbleFrameView*>(view->frame_view()); - struct { + constexpr struct { const int point; const int hit; - } cases[] = { - {0, HTSYSMENU}, - {10, HTSYSMENU}, + } kCases[] = { + {0, HTTRANSPARENT}, + {10, HTNOWHERE}, {20, HTNOWHERE}, {50, HTCLIENT /* Space is reserved for the close button. */}, {60, HTCLIENT}, {1000, HTNOWHERE}, }; - for (size_t i = 0; i < base::size(cases); ++i) { - gfx::Point point(cases[i].point, cases[i].point); - EXPECT_EQ(cases[i].hit, frame->NonClientHitTest(point)) - << " case " << i << " at point " << cases[i].point; + for (const auto test_case : kCases) { + gfx::Point point(test_case.point, test_case.point); + EXPECT_EQ(test_case.hit, frame->NonClientHitTest(point)) + << " at point " << test_case.point; } } @@ -243,41 +257,67 @@ const NonClientView* view = dialog()->GetWidget()->non_client_view(); BubbleFrameView* frame = static_cast<BubbleFrameView*>(view->frame_view()); - struct { + constexpr struct { const int point; const int hit; - } cases[] = { - {0, HTSYSMENU}, {10, HTSYSMENU}, {20, HTCLIENT}, - {50, HTCLIENT}, {60, HTCLIENT}, {1000, HTNOWHERE}, + } kCases[] = { + {0, HTTRANSPARENT}, {10, HTCLIENT}, {20, HTCLIENT}, + {50, HTCLIENT}, {60, HTCLIENT}, {1000, HTNOWHERE}, }; - for (size_t i = 0; i < base::size(cases); ++i) { - gfx::Point point(cases[i].point, cases[i].point); - EXPECT_EQ(cases[i].hit, frame->NonClientHitTest(point)) - << " case " << i << " at point " << cases[i].point; + for (const auto test_case : kCases) { + gfx::Point point(test_case.point, test_case.point); + EXPECT_EQ(test_case.hit, frame->NonClientHitTest(point)) + << " at point " << test_case.point; } } -TEST_F(DialogTest, HitTest_WithTitle) { - // Ensure that BubbleFrameView hit-tests as expected when the title is shown. +TEST_F(DialogTest, HitTest_Modal_WithTitle) { + // Ensure that BubbleFrameView hit-tests as expected when the title is shown + // and the modal type is something other than not modal. + const NonClientView* view = dialog()->GetWidget()->non_client_view(); + dialog()->set_title(base::ASCIIToUTF16("Title")); + dialog()->GetWidget()->UpdateWindowTitle(); + dialog()->SetModal(); + dialog()->GetWidget()->LayoutRootViewIfNecessary(); + BubbleFrameView* frame = static_cast<BubbleFrameView*>(view->frame_view()); + + constexpr struct { + const int point; + const int hit; + } kCases[] = { + {0, HTTRANSPARENT}, {10, HTNOWHERE}, {20, HTNOWHERE}, + {50, HTCLIENT}, {60, HTCLIENT}, {1000, HTNOWHERE}, + }; + + for (const auto test_case : kCases) { + gfx::Point point(test_case.point, test_case.point); + EXPECT_EQ(test_case.hit, frame->NonClientHitTest(point)) + << " at point " << test_case.point; + } +} + +TEST_F(DialogTest, HitTest_ModalTypeNone_WithTitle) { + // Ensure that BubbleFrameView hit-tests as expected when the title is shown + // and the modal type is none. const NonClientView* view = dialog()->GetWidget()->non_client_view(); dialog()->set_title(base::ASCIIToUTF16("Title")); dialog()->GetWidget()->UpdateWindowTitle(); dialog()->GetWidget()->LayoutRootViewIfNecessary(); BubbleFrameView* frame = static_cast<BubbleFrameView*>(view->frame_view()); - struct { + constexpr struct { const int point; const int hit; - } cases[] = { - {0, HTSYSMENU}, {10, HTSYSMENU}, {20, HTCAPTION}, - {50, HTCLIENT}, {60, HTCLIENT}, {1000, HTNOWHERE}, + } kCases[] = { + {0, HTTRANSPARENT}, {10, HTCAPTION}, {20, HTCAPTION}, + {50, HTCLIENT}, {60, HTCLIENT}, {1000, HTNOWHERE}, }; - for (size_t i = 0; i < base::size(cases); ++i) { - gfx::Point point(cases[i].point, cases[i].point); - EXPECT_EQ(cases[i].hit, frame->NonClientHitTest(point)) - << " at point " << cases[i].point; + for (const auto test_case : kCases) { + gfx::Point point(test_case.point, test_case.point); + EXPECT_EQ(test_case.hit, frame->NonClientHitTest(point)) + << " at point " << test_case.point; } }