diff --git a/.gitignore b/.gitignore index 149a237..e4f6e92 100644 --- a/.gitignore +++ b/.gitignore
@@ -189,7 +189,6 @@ /chromeos/profiles/*.afdo.prof /cipd_cache/ /clank -/cloud_print/cloud_print_version_resources.xml /components/chrome_settings_proto_generated_compile.xml /components/cloud_policy_proto_generated_compile.xml /components/gcm_driver.xml
diff --git a/BUILD.gn b/BUILD.gn index cefda89..5371f24b 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -655,7 +655,6 @@ "//chrome/installer/setup:setup_unittests", "//chrome/notification_helper:notification_helper_unittests", "//chrome/test:delayloads_unittests", - "//cloud_print:cloud_print_unittests", "//components/wifi:wifi_test", "//components/zucchini", "//net:quic_client", @@ -925,8 +924,6 @@ "//chrome/installer/gcapi", "//chrome/installer/mini_installer", "//chrome/updater/win:updater_zip", - "//cloud_print", - "//cloud_print/virtual_driver/win/port_monitor:copy_gcp_portmon_binaries", "//components/policy:pack_policy_templates", "//components/zucchini", "//courgette",
diff --git a/DEPS b/DEPS index bae0e1a8..743a2d4 100644 --- a/DEPS +++ b/DEPS
@@ -253,15 +253,15 @@ # 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': '6ccc3b0658dfce3709f2e726059b695678b66f53', + 'skia_revision': '3b238ceae9c3381b2333e7bff794a0d88eb3fce9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '7d776826a3c4ae0878f026c00beab82765fb4d23', + 'v8_revision': '19907681704961ae0e5b537cfdcd7ad1b6bc83f1', # 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': 'fa5c349dc73cd4cc3e015d6e2da3ba0eb57ffe4e', + 'angle_revision': '18c36f8aa629231795c82831a2cf80e8f77f989a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -328,7 +328,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '5d3b98cdc169a5f77392478d26d3bb48bb31a1e4', + 'devtools_frontend_revision': '393848420284a7c004748a4ec078c51605337cbd', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -368,7 +368,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': 'c63ce343fd61623e4b254f9ec656543c30e3df6f', + 'dawn_revision': 'cbdde604b87f27128185c8f9393f2c3d2211b7fc', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -1140,7 +1140,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '62396c5a83595ec985578fe3e163fde931062615', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '01a4536ff80f24ef7cfc5b7f9f67938b1e8fc2bd', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1523,7 +1523,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '8eb58df9cb83670f3fd54cc99055f367de18a001', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '8c8fafb6ff4b4a715b868915840fc95040290ef7', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1744,7 +1744,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '981b513154230fb38aaa1d999d4c30bd7a3c3966', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'a6fcbb18303973f3164eb36a6339654cf7c4e73d', + Var('webrtc_git') + '/src.git' + '@' + 'ed4a5763f825b911978d2552554baaf14046cdf2', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1814,7 +1814,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@2d086936f183e0a680eb446aa79e72054a255482', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@f187e24914c62ce9b26be9bd23a548755a0e75ac', 'condition': 'checkout_src_internal', },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 293cb4c..ed7fc6f8 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -2298,7 +2298,6 @@ r"dll_hash_main\.cc$", r"^chrome[\\/]installer[\\/]setup[\\/].*", r"^chromecast[\\/]", - r"^cloud_print[\\/]", r"^components[\\/]browser_watcher[\\/]" r"dump_stability_report_main_win.cc$", r"^components[\\/]media_control[\\/]renderer[\\/]"
diff --git a/ash/app_list/views/app_list_toast_container_view.cc b/ash/app_list/views/app_list_toast_container_view.cc index 7d47079..4635fb8 100644 --- a/ash/app_list/views/app_list_toast_container_view.cc +++ b/ash/app_list/views/app_list_toast_container_view.cc
@@ -58,8 +58,12 @@ views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred, views::MaximumFlexSizeRule::kPreferred)); - context_menu_ = std::make_unique<AppsGridContextMenu>(); - set_context_menu_controller(context_menu_.get()); + if (!tablet_mode_) { + // `context_menu_` is only set in clamshell mode. The sort options in tablet + // mode are handled in RootWindowController with ShelfContextMenuModel. + context_menu_ = std::make_unique<AppsGridContextMenu>(); + set_context_menu_controller(context_menu_.get()); + } } AppListToastContainerView::~AppListToastContainerView() {
diff --git a/ash/app_list/views/apps_grid_context_menu.cc b/ash/app_list/views/apps_grid_context_menu.cc index efce0222..b7e0b5c 100644 --- a/ash/app_list/views/apps_grid_context_menu.cc +++ b/ash/app_list/views/apps_grid_context_menu.cc
@@ -8,6 +8,7 @@ #include "ash/app_list/model/app_list_model.h" #include "ash/constants/ash_features.h" #include "ash/public/cpp/app_list/app_list_model_delegate.h" +#include "ash/public/cpp/app_menu_constants.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/strings/grit/ash_strings.h" #include "ui/base/l10n/l10n_util.h" @@ -32,11 +33,11 @@ void AppsGridContextMenu::ExecuteCommand(int command_id, int event_flags) { switch (command_id) { - case AppsGridCommandId::kReorderByNameAlphabetical: + case REORDER_BY_NAME_ALPHABETICAL: AppListModelProvider::Get()->model()->delegate()->RequestAppListSort( AppListSortOrder::kNameAlphabetical); break; - case AppsGridCommandId::kReorderByColor: + case REORDER_BY_COLOR: AppListModelProvider::Get()->model()->delegate()->RequestAppListSort( AppListSortOrder::kColor); break; @@ -79,13 +80,13 @@ context_menu_model_->AddTitle(l10n_util::GetStringUTF16( IDS_ASH_LAUNCHER_APPS_GRID_CONTEXT_MENU_REORDER_TITLE)); context_menu_model_->AddItemWithIcon( - AppsGridCommandId::kReorderByNameAlphabetical, + REORDER_BY_NAME_ALPHABETICAL, l10n_util::GetStringUTF16( IDS_ASH_LAUNCHER_APPS_GRID_CONTEXT_MENU_REORDER_BY_NAME), ui::ImageModel::FromVectorIcon(kSortAlphabeticalIcon, ui::kColorAshSystemUIMenuIcon)); context_menu_model_->AddItemWithIcon( - AppsGridCommandId::kReorderByColor, + REORDER_BY_COLOR, l10n_util::GetStringUTF16( IDS_ASH_LAUNCHER_APPS_GRID_CONTEXT_MENU_REORDER_BY_COLOR), ui::ImageModel::FromVectorIcon(kSortColorIcon,
diff --git a/ash/app_list/views/apps_grid_context_menu.h b/ash/app_list/views/apps_grid_context_menu.h index ed8b26f..b510c11 100644 --- a/ash/app_list/views/apps_grid_context_menu.h +++ b/ash/app_list/views/apps_grid_context_menu.h
@@ -24,21 +24,6 @@ class ASH_EXPORT AppsGridContextMenu : public ui::SimpleMenuModel::Delegate, public views::ContextMenuController { public: - // List of command id used in apps grid context menu. - enum AppsGridCommandId { - // Command Id that contains a submenu with app name reorder options. - kReorderByName, - - // Command that will sort the name in alphabetical order. - kReorderByNameAlphabetical, - - // Command that will sort the name in reverse alphabetical order. - kReorderByNameReverseAlphabetical, - - // Command that will sort by icon color in rainbow order. - kReorderByColor - }; - AppsGridContextMenu(); AppsGridContextMenu(const AppsGridContextMenu&) = delete; AppsGridContextMenu& operator=(const AppsGridContextMenu&) = delete;
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index 0d484d9d..00aaaf9c 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc
@@ -369,8 +369,12 @@ l10n_util::GetStringUTF16(IDS_ALL_APPS_INDICATOR)); } - context_menu_ = std::make_unique<AppsGridContextMenu>(); - set_context_menu_controller(context_menu_.get()); + if (!IsTabletMode()) { + // `context_menu_` is only set in clamshell mode. The sort options in tablet + // mode are handled in RootWindowController with ShelfContextMenuModel. + context_menu_ = std::make_unique<AppsGridContextMenu>(); + set_context_menu_controller(context_menu_.get()); + } } AppsGridView::~AppsGridView() {
diff --git a/ash/app_list/views/apps_grid_view_unittest.cc b/ash/app_list/views/apps_grid_view_unittest.cc index e9caf56..6324e61 100644 --- a/ash/app_list/views/apps_grid_view_unittest.cc +++ b/ash/app_list/views/apps_grid_view_unittest.cc
@@ -48,6 +48,7 @@ #include "ash/public/cpp/shelf_item_delegate.h" #include "ash/public/cpp/shelf_model.h" #include "ash/public/cpp/test/test_shelf_item_delegate.h" +#include "ash/root_window_controller.h" #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_view.h" #include "ash/shell.h" @@ -5079,12 +5080,18 @@ test_api_->LayoutToIdealBounds(); } -TEST_P(AppsGridViewAppSortTest, ContextMenuInTopLevelAppListSortAllApps) { +TEST_P(AppsGridViewAppSortTest, + ContextMenuInTopLevelAppListSortAllAppsInClamshellMode) { // In this test, the sort algorithm is not tested. Instead, the context menu // that contains the options to sort is verified to be shown in apps grid // view. The menu option selecting is also simulated to ensure the sorting is // called. The actual sort algorithm is tested in // chrome/browser/ui/app_list/app_list_sort_browsertest.cc. + + // The AppsGridContextMenu is only used in clamshell mode. + if (create_as_tablet_mode_) + return; + model_->PopulateApps(1); AppsGridContextMenu* context_menu = apps_grid_view_->context_menu_for_test(); @@ -5128,6 +5135,75 @@ EXPECT_FALSE(context_menu->IsMenuShowing()); } +TEST_P(AppsGridViewAppSortTest, + ContextMenuInTopLevelAppListSortAllAppsInTabletMode) { + // This test checks the context menu on root window in tablet mode. + if (!create_as_tablet_mode_) + return; + + model_->PopulateApps(1); + EXPECT_EQ(AppListSortOrder::kCustom, model_->requested_sort_order()); + + // Get a point in `apps_grid_view_` that doesn't have an item on it. + const gfx::Point empty_space = + apps_grid_view_->GetBoundsInScreen().CenterPoint(); + + // Open the menu to test the alphabetical sort option. + SimulateRightClickOrLongPressAt(empty_space); + AppMenuModelAdapter* context_menu = + Shell::GetPrimaryRootWindowController()->menu_model_adapter_for_testing(); + EXPECT_TRUE(context_menu->IsShowingMenu()); + + // Cache the current context menu view. + views::MenuItemView* reorder_submenu = + context_menu->root_for_testing()->GetSubmenu()->GetMenuItemAt(2); + ASSERT_TRUE(reorder_submenu->title() == u"Sort by"); + + // Open the Sort by submenu. + gfx::Point reorder_submenu_point = + reorder_submenu->GetBoundsInScreen().CenterPoint(); + SimulateLeftClickOrTapAt(reorder_submenu_point); + + views::MenuItemView* reorder_option = + reorder_submenu->GetSubmenu()->GetMenuItemAt(0); + ASSERT_TRUE(reorder_option->title() == u"Name"); + gfx::Point reorder_option_point = + reorder_option->GetBoundsInScreen().CenterPoint(); + SimulateLeftClickOrTapAt(reorder_option_point); + + // Check that the apps are sorted and the menu is closed. + EXPECT_EQ(AppListSortOrder::kNameAlphabetical, + model_->requested_sort_order()); + EXPECT_EQ( + Shell::GetPrimaryRootWindowController()->menu_model_adapter_for_testing(), + nullptr); + + // Open the menu again to test the color sort option. + SimulateRightClickOrLongPressAt(empty_space); + context_menu = + Shell::GetPrimaryRootWindowController()->menu_model_adapter_for_testing(); + EXPECT_TRUE(context_menu->IsShowingMenu()); + + reorder_submenu = + context_menu->root_for_testing()->GetSubmenu()->GetMenuItemAt(2); + ASSERT_TRUE(reorder_submenu->title() == u"Sort by"); + + // Open the Sort by submenu. + reorder_submenu_point = reorder_submenu->GetBoundsInScreen().CenterPoint(); + SimulateLeftClickOrTapAt(reorder_submenu_point); + + reorder_option = reorder_submenu->GetSubmenu()->GetMenuItemAt(1); + ASSERT_TRUE(reorder_option->title() == u"Color"); + reorder_option_point = reorder_option->GetBoundsInScreen().CenterPoint(); + SimulateLeftClickOrTapAt(reorder_option_point); + + // Check that the apps are sorted and the menu is closed. + EXPECT_EQ(AppListSortOrder::kColor, model_->requested_sort_order()); + EXPECT_EQ( + Shell::GetPrimaryRootWindowController()->menu_model_adapter_for_testing(), + nullptr); +} + TEST_P(AppsGridViewAppSortTest, ContextMenuOnFolderItemSortAllApps) { // In this test, the sort algorithm is not tested. Instead, the context menu // that contains the options to sort is verified to be shown on folder app
diff --git a/ash/components/cryptohome/cryptohome_util.cc b/ash/components/cryptohome/cryptohome_util.cc index 396fe6d3f..d4b600f 100644 --- a/ash/components/cryptohome/cryptohome_util.cc +++ b/ash/components/cryptohome/cryptohome_util.cc
@@ -75,79 +75,66 @@ } // namespace +KeyDefinition KeyDataToKeyDefinition(const KeyData& key_data) { + CHECK(key_data.has_type()); + KeyDefinition result; + // Extract |type|, |label| and |revision|. + switch (key_data.type()) { + case KeyData::KEY_TYPE_PASSWORD: + result.type = KeyDefinition::TYPE_PASSWORD; + break; + case KeyData::KEY_TYPE_CHALLENGE_RESPONSE: + result.type = KeyDefinition::TYPE_CHALLENGE_RESPONSE; + break; + case KeyData::KEY_TYPE_FINGERPRINT: + // KEY_TYPE_FINGERPRINT means the key is a request for fingerprint auth + // and does not really carry any auth information. KEY_TYPE_FINGERPRINT + // is not expected to be used in GetKeyData. + NOTREACHED(); + break; + case KeyData::KEY_TYPE_KIOSK: + result.type = KeyDefinition::TYPE_PUBLIC_MOUNT; + break; + } + result.label = key_data.label(); + result.revision = key_data.revision(); + + // Extract |privileges|. + const KeyPrivileges& privileges = key_data.privileges(); + if (privileges.add()) + result.privileges |= PRIV_ADD; + if (privileges.remove()) + result.privileges |= PRIV_REMOVE; + if (privileges.update()) + result.privileges |= PRIV_MIGRATE; + + // Extract |policy|. + result.policy.low_entropy_credential = + key_data.policy().low_entropy_credential(); + result.policy.auth_locked = key_data.policy().auth_locked(); + + // Extract |provider_data|. + for (auto& provider_datum : key_data.provider_data().entry()) { + // We have either of two + DCHECK_NE(provider_datum.has_number(), provider_datum.has_bytes()); + + if (provider_datum.has_number()) { + result.provider_data.push_back(KeyDefinition::ProviderData( + provider_datum.name(), provider_datum.number())); + } else { + result.provider_data.push_back(KeyDefinition::ProviderData( + provider_datum.name(), provider_datum.bytes())); + } + } + return result; +} + std::vector<KeyDefinition> RepeatedKeyDataToKeyDefinitions( const RepeatedPtrField<KeyData>& key_data) { std::vector<KeyDefinition> key_definitions; for (RepeatedPtrField<KeyData>::const_iterator it = key_data.begin(); it != key_data.end(); ++it) { - // Extract |type|, |label| and |revision|. - KeyDefinition key_definition; - CHECK(it->has_type()); - switch (it->type()) { - case KeyData::KEY_TYPE_PASSWORD: - key_definition.type = KeyDefinition::TYPE_PASSWORD; - break; - case KeyData::KEY_TYPE_CHALLENGE_RESPONSE: - key_definition.type = KeyDefinition::TYPE_CHALLENGE_RESPONSE; - break; - case KeyData::KEY_TYPE_FINGERPRINT: - // KEY_TYPE_FINGERPRINT means the key is a request for fingerprint auth - // and does not really carry any auth information. KEY_TYPE_FINGERPRINT - // is not expected to be used in GetKeyData. - NOTREACHED(); - break; - case KeyData::KEY_TYPE_KIOSK: - key_definition.type = KeyDefinition::TYPE_PUBLIC_MOUNT; - break; - } - key_definition.label = it->label(); - key_definition.revision = it->revision(); - - // Extract |privileges|. - const KeyPrivileges& privileges = it->privileges(); - if (privileges.add()) - key_definition.privileges |= PRIV_ADD; - if (privileges.remove()) - key_definition.privileges |= PRIV_REMOVE; - if (privileges.update()) - key_definition.privileges |= PRIV_MIGRATE; - - // Extract |policy|. - key_definition.policy.low_entropy_credential = - it->policy().low_entropy_credential(); - key_definition.policy.auth_locked = it->policy().auth_locked(); - - // Extract |provider_data|. - for (RepeatedPtrField<KeyProviderData::Entry>::const_iterator - provider_data_it = it->provider_data().entry().begin(); - provider_data_it != it->provider_data().entry().end(); - ++provider_data_it) { - // Extract |name|. - key_definition.provider_data.push_back( - KeyDefinition::ProviderData(provider_data_it->name())); - KeyDefinition::ProviderData& provider_data = - key_definition.provider_data.back(); - - int data_items = 0; - - // Extract |number|. - if (provider_data_it->has_number()) { - provider_data.number = - std::make_unique<int64_t>(provider_data_it->number()); - ++data_items; - } - - // Extract |bytes|. - if (provider_data_it->has_bytes()) { - provider_data.bytes = - std::make_unique<std::string>(provider_data_it->bytes()); - ++data_items; - } - - DCHECK_EQ(1, data_items); - } - - key_definitions.push_back(std::move(key_definition)); + key_definitions.push_back(KeyDataToKeyDefinition(*it)); } return key_definitions; }
diff --git a/ash/components/cryptohome/cryptohome_util.h b/ash/components/cryptohome/cryptohome_util.h index 0fe119a..f53980b 100644 --- a/ash/components/cryptohome/cryptohome_util.h +++ b/ash/components/cryptohome/cryptohome_util.h
@@ -22,6 +22,11 @@ std::vector<KeyDefinition> RepeatedKeyDataToKeyDefinitions( const google::protobuf::RepeatedPtrField<KeyData>& key_data); +// Converts the single key metadata from cryptohome::KeyData> to +// cryptohome::KeyDefinition format. +COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME) +KeyDefinition KeyDataToKeyDefinition(const KeyData& key_data); + // Creates an AuthorizationRequest from the given secret and label. COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME) AuthorizationRequest CreateAuthorizationRequest(const std::string& label,
diff --git a/ash/components/cryptohome/userdataauth_util.cc b/ash/components/cryptohome/userdataauth_util.cc index ea4932c..9ea269f7 100644 --- a/ash/components/cryptohome/userdataauth_util.cc +++ b/ash/components/cryptohome/userdataauth_util.cc
@@ -70,6 +70,10 @@ ReplyToCryptohomeError(const absl::optional<AddAuthFactorReply>&); template COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME) CryptohomeErrorCode ReplyToCryptohomeError(const absl::optional<UnmountReply>&); +template COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME) CryptohomeErrorCode + ReplyToCryptohomeError(const absl::optional<RemoveReply>&); +template COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME) CryptohomeErrorCode + ReplyToCryptohomeError(const absl::optional<UpdateCredentialReply>&); std::vector<cryptohome::KeyDefinition> GetKeyDataReplyToKeyDefinitions( const absl::optional<GetKeyDataReply>& reply) {
diff --git a/ash/components/login/auth/BUILD.gn b/ash/components/login/auth/BUILD.gn index e1ae665..65262c3 100644 --- a/ash/components/login/auth/BUILD.gn +++ b/ash/components/login/auth/BUILD.gn
@@ -41,6 +41,8 @@ sources = [ "auth_attempt_state.cc", "auth_attempt_state.h", + "auth_factors_data.cc", + "auth_factors_data.h", "auth_session_authenticator.cc", "auth_session_authenticator.h", "auth_status_consumer.cc",
diff --git a/ash/components/login/auth/auth_factors_data.cc b/ash/components/login/auth/auth_factors_data.cc new file mode 100644 index 0000000..87712d3 --- /dev/null +++ b/ash/components/login/auth/auth_factors_data.cc
@@ -0,0 +1,36 @@ +// Copyright 2022 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/components/login/auth/auth_factors_data.h" + +#include "ash/components/cryptohome/cryptohome_parameters.h" +#include "ash/components/login/auth/cryptohome_key_constants.h" + +namespace ash { + +AuthFactorsData::AuthFactorsData(std::vector<cryptohome::KeyDefinition> keys) + : keys_(std::move(keys)) {} + +AuthFactorsData::AuthFactorsData() = default; +AuthFactorsData::AuthFactorsData(const AuthFactorsData&) = default; +AuthFactorsData::AuthFactorsData(AuthFactorsData&&) = default; +AuthFactorsData::~AuthFactorsData() = default; +AuthFactorsData& AuthFactorsData::operator=(const AuthFactorsData&) = default; + +const cryptohome::KeyDefinition* AuthFactorsData::FindOnlinePasswordKey() + const { + for (const cryptohome::KeyDefinition& key_def : keys_) { + if (key_def.label == kCryptohomeGaiaKeyLabel) + return &key_def; + } + for (const cryptohome::KeyDefinition& key_def : keys_) { + // Check if label starts with prefix and has required type. + if ((key_def.label.find(kCryptohomeGaiaKeyLegacyLabelPrefix) == 0) && + key_def.type == cryptohome::KeyDefinition::TYPE_PASSWORD) + return &key_def; + } + return nullptr; +} + +} // namespace ash
diff --git a/ash/components/login/auth/auth_factors_data.h b/ash/components/login/auth/auth_factors_data.h new file mode 100644 index 0000000..8a266c7 --- /dev/null +++ b/ash/components/login/auth/auth_factors_data.h
@@ -0,0 +1,42 @@ +// Copyright 2022 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 ASH_COMPONENTS_LOGIN_AUTH_AUTH_FACTORS_DATA_H_ +#define ASH_COMPONENTS_LOGIN_AUTH_AUTH_FACTORS_DATA_H_ + +#include <string> + +#include "ash/components/cryptohome/cryptohome_parameters.h" + +namespace ash { + +// Public information about authentication keys configured for particular user. +// This class partially encapsulates implementation details of key definition +// (cryptohome::KeyData vs cryptohome::AuthFactor). +// Note that this information does not contain any key secrets. +class COMPONENT_EXPORT(ASH_LOGIN_AUTH) AuthFactorsData { + public: + explicit AuthFactorsData(std::vector<cryptohome::KeyDefinition> keys); + + // Empty constructor is needed so that UserContext can be created. + AuthFactorsData(); + // Copy constructor (and operator) are needed because UserContext is copyable. + AuthFactorsData(const AuthFactorsData&); + AuthFactorsData(AuthFactorsData&&); + + ~AuthFactorsData(); + + AuthFactorsData& operator=(const AuthFactorsData&); + + // Returns metadata for the Password key, so that it can be identified for + // further operations. + const cryptohome::KeyDefinition* FindOnlinePasswordKey() const; + + private: + std::vector<cryptohome::KeyDefinition> keys_; +}; + +} // namespace ash + +#endif // ASH_COMPONENTS_LOGIN_AUTH_AUTH_FACTORS_DATA_H_
diff --git a/ash/components/login/auth/auth_session_authenticator.cc b/ash/components/login/auth/auth_session_authenticator.cc index ea74aee..c64df2ad 100644 --- a/ash/components/login/auth/auth_session_authenticator.cc +++ b/ash/components/login/auth/auth_session_authenticator.cc
@@ -95,7 +95,6 @@ void IgnoreHashing( std::unique_ptr<UserContext> context, - const user_data_auth::StartAuthSessionReply& reply, base::OnceCallback<void(std::unique_ptr<UserContext>)> consumer) { std::move(consumer).Run(std::move(context)); } @@ -112,7 +111,6 @@ void HashPassword( std::unique_ptr<UserContext> context, - const user_data_auth::StartAuthSessionReply& reply, base::OnceCallback<void(std::unique_ptr<UserContext>)> consumer) { if (context->GetKey()->GetKeyType() != Key::KEY_TYPE_PASSWORD_PLAIN) { std::move(consumer).Run(std::move(context)); @@ -140,6 +138,9 @@ // Completes online authentication: // * User is likely to be new // * Provided password is assumed to be just verified by online flow +// This method is also called in case of password change detection if user +// decides to remove old cryptohome and start anew, which can only happen +// as a result of prior CompleteLogin call. void AuthSessionAuthenticator::CompleteLogin( std::unique_ptr<UserContext> user_context) { DCHECK(user_context); @@ -149,7 +150,17 @@ user_manager::USER_TYPE_ACTIVE_DIRECTORY); PrepareForNewAttempt("CompleteLogin", "Regular user after online sign-in"); + CompleteLoginImpl(std::move(user_context)); +} +// Implementation part, shared by CompleteLogin and ResyncEncryptedData. +void AuthSessionAuthenticator::CompleteLoginImpl( + std::unique_ptr<UserContext> user_context) { + DCHECK(user_context); + DCHECK(user_context->GetUserType() == user_manager::USER_TYPE_REGULAR || + user_context->GetUserType() == user_manager::USER_TYPE_CHILD || + user_context->GetUserType() == + user_manager::USER_TYPE_ACTIVE_DIRECTORY); // For now we don't support empty passwords: if (user_context->GetKey()->GetKeyType() == Key::KEY_TYPE_PASSWORD_PLAIN) { if (user_context->GetKey()->GetSecret().empty()) { @@ -612,12 +623,103 @@ } void AuthSessionAuthenticator::RecoverEncryptedData( + std::unique_ptr<UserContext> user_context, const std::string& old_password) { - NOTIMPLEMENTED(); + LOGIN_LOG(USER) << "Attempting to update password"; + VLOG(1) << "AuthSessionAuthenticator::RecoverEncryptedData"; + + const cryptohome::KeyDefinition* password_key_def = + user_context->GetAuthFactorsData().FindOnlinePasswordKey(); + DCHECK(password_key_def); + const std::string key_label = password_key_def->label; + + if (!user_context->HasReplacementKey()) { + // Assume that there was an attempt to use the key, so it is was already + // hashed. + DCHECK(user_context->GetKey()->GetKeyType() != + Key::KEY_TYPE_PASSWORD_PLAIN); + // Make sure that the key has correct label. + user_context->GetKey()->SetLabel(key_label); + user_context->SaveKeyForReplacement(); + } + + chromeos::Key auth_key(old_password); + auth_key.SetLabel(key_label); + user_context->SetKey(auth_key); + + DCHECK(!user_context->GetAuthSessionId().empty()); + + // (1) Transform old password key (as a password) + // (2) Authenticate AuthSession + // (3) Replace key with the one that was validated by online sign-in + // (4) Mount directory + // (5) (Safe mode) Check ownership + // (#) Notify success + // (*) Errors are reported as COULD_NOT_MOUNT_CRYPTOHOME + + // Callbacks are created in reverse order: + + // (*) + auto error_handler_repeating = base::BindRepeating( + &AuthSessionAuthenticator::ProcessCryptohomeError, + weak_factory_.GetWeakPtr(), + /*default_reason=*/AuthFailure::COULD_NOT_MOUNT_CRYPTOHOME); + // (#) + auto success_notification = base::BindOnce( + &AuthSessionAuthenticator::NotifyAuthSuccess, weak_factory_.GetWeakPtr()); + // (5) + ContextCallback safe_mode_check = base::BindOnce( + &AuthSessionAuthenticator::RunSafeModeChecks, weak_factory_.GetWeakPtr(), + /*continuation=*/std::move(success_notification)); + // (4.1) + ConfigureMountCallback mount_regular_cfg = + base::BindOnce(&ConfigureGenericMount); + // (4) + ContextCallback mount_existing = base::BindOnce( + &AuthSessionAuthenticator::MountGeneric, weak_factory_.GetWeakPtr(), + /*error_handler=*/base::BindOnce(error_handler_repeating), + /*configurator=*/std::move(mount_regular_cfg), + /*continuation=*/std::move(safe_mode_check)); + // (3) + ContextCallback replace_key = + base::BindOnce(&AuthSessionAuthenticator::UpdateCredentialsGeneric, + weak_factory_.GetWeakPtr(), + /*error_handler=*/base::BindOnce(error_handler_repeating), + /*continuation=*/std::move(mount_existing)); + + // (2.1) + ErrorHandlingCallback auth_error_handler = + base::BindOnce(&AuthSessionAuthenticator:: + ExistingUserPasswordAuthenticationErrorHandling, + weak_factory_.GetWeakPtr(), + /*fallback=*/base::BindOnce(error_handler_repeating), + /*verified_password=*/true); + // (2) + ExistingUserAuthSessionCallback existing_user_flow = base::BindOnce( + &AuthSessionAuthenticator::AuthenticateSessionGeneric, + weak_factory_.GetWeakPtr(), + /*error_handler=*/std::move(auth_error_handler), + /*key_transformer=*/base::BindOnce(&TransformToWildcardKey), + /*continuation=*/std::move(replace_key)); + + // (1) + HashPassword(std::move(user_context), std::move(existing_user_flow)); } -void AuthSessionAuthenticator::ResyncEncryptedData() { - NOTIMPLEMENTED(); +void AuthSessionAuthenticator::ResyncEncryptedData( + std::unique_ptr<UserContext> user_context) { + LOGIN_LOG(USER) << "Attempting to re-create cryptohome"; + VLOG(1) << "AuthSessionAuthenticator::ResyncEncryptedData"; + auto error_handler = + base::BindOnce(&AuthSessionAuthenticator::ProcessCryptohomeError, + weak_factory_.GetWeakPtr(), + /*default_reason=*/AuthFailure::DATA_REMOVAL_FAILED); + + ContextCallback continuation = base::BindOnce( + &AuthSessionAuthenticator::CompleteLoginImpl, weak_factory_.GetWeakPtr()); + + RemoveGeneric(std::move(error_handler), std::move(continuation), + std::move(user_context)); } void AuthSessionAuthenticator::PrepareForNewAttempt( @@ -790,6 +892,14 @@ CHECK(reply.has_value()); context->SetAuthSessionId(reply->auth_session_id()); + std::vector<cryptohome::KeyDefinition> key_definitions; + for (const auto& [label, key_data] : reply->key_label_data()) { + key_definitions.push_back(KeyDataToKeyDefinition(key_data)); + } + + AuthFactorsData auth_factors_data(std::move(key_definitions)); + context->SetAuthFactorsData(std::move(auth_factors_data)); + ContextCallback consumer; if (reply->user_exists()) { consumer = std::move(existing_user_flow); @@ -797,8 +907,7 @@ LOGIN_LOG(EVENT) << "User is new"; consumer = std::move(new_user_flow); } - std::move(key_hasher) - .Run(std::move(context), reply.value(), std::move(consumer)); + std::move(key_hasher).Run(std::move(context), std::move(consumer)); } void AuthSessionAuthenticator::AuthenticateSessionGeneric( @@ -955,6 +1064,81 @@ std::move(continuation).Run(std::move(context)); } +void AuthSessionAuthenticator::RemoveGeneric( + ErrorHandlingCallback error_handler, + ContextCallback continuation, + std::unique_ptr<UserContext> context) { + VLOG(1) << "AuthSessionAuthenticator::Remove"; + + user_data_auth::RemoveRequest request; + request.set_auth_session_id(context->GetAuthSessionId()); + + UserDataAuthClient::Get()->Remove( + request, + base::BindOnce(&AuthSessionAuthenticator::OnRemoveGeneric, + weak_factory_.GetWeakPtr(), std::move(error_handler), + std::move(continuation), std::move(context))); +} + +void AuthSessionAuthenticator::OnRemoveGeneric( + ErrorHandlingCallback error_callback, + ContextCallback continuation, + std::unique_ptr<UserContext> context, + absl::optional<user_data_auth::RemoveReply> reply) { + VLOG(1) << "AuthSessionAuthenticator::OnRemove"; + auto error = user_data_auth::ReplyToCryptohomeError(reply); + if (error != user_data_auth::CRYPTOHOME_ERROR_NOT_SET) { + LOGIN_LOG(ERROR) << "Removal failed with error " << error; + std::move(error_callback).Run(std::move(context), error); + return; + } + CHECK(reply.has_value()); + // Removing user directory invalidates session. + context->ResetAuthSessionId(); + std::move(continuation).Run(std::move(context)); +} + +void AuthSessionAuthenticator::UpdateCredentialsGeneric( + ErrorHandlingCallback error_handler, + ContextCallback continuation, + std::unique_ptr<UserContext> context) { + VLOG(1) << "AuthSessionAuthenticator::UpdateCredentials"; + + user_data_auth::UpdateCredentialRequest request; + + request.set_auth_session_id(context->GetAuthSessionId()); + request.set_old_credential_label(context->GetKey()->GetLabel()); + DCHECK(context->HasReplacementKey()); + const Key* key = context->GetReplacementKey(); + CHECK_NE(Key::KEY_TYPE_PASSWORD_PLAIN, key->GetKeyType()); + cryptohome::KeyDefinitionToKey( + cryptohome::KeyDefinition::CreateForPassword( + key->GetSecret(), key->GetLabel(), cryptohome::PRIV_DEFAULT), + request.mutable_authorization()->mutable_key()); + + UserDataAuthClient::Get()->UpdateCredential( + request, + base::BindOnce(&AuthSessionAuthenticator::OnUpdateCredentialsGeneric, + weak_factory_.GetWeakPtr(), std::move(error_handler), + std::move(continuation), std::move(context))); +} + +void AuthSessionAuthenticator::OnUpdateCredentialsGeneric( + ErrorHandlingCallback error_callback, + ContextCallback continuation, + std::unique_ptr<UserContext> context, + absl::optional<user_data_auth::UpdateCredentialReply> reply) { + VLOG(1) << "AuthSessionAuthenticator::OnUpdateCredentials"; + auto error = user_data_auth::ReplyToCryptohomeError(reply); + if (error != user_data_auth::CRYPTOHOME_ERROR_NOT_SET) { + LOGIN_LOG(ERROR) << "Update failed with error " << error; + std::move(error_callback).Run(std::move(context), error); + return; + } + CHECK(reply.has_value()); + std::move(continuation).Run(std::move(context)); +} + void AuthSessionAuthenticator::ExistingUserPasswordAuthenticationErrorHandling( ErrorHandlingCallback fallback, bool verified_password,
diff --git a/ash/components/login/auth/auth_session_authenticator.h b/ash/components/login/auth/auth_session_authenticator.h index 1220ac79..ab22bf8 100644 --- a/ash/components/login/auth/auth_session_authenticator.h +++ b/ash/components/login/auth/auth_session_authenticator.h
@@ -63,8 +63,9 @@ void LoginAsWebKioskAccount(const AccountId& app_account_id) override; void OnAuthSuccess() override; void OnAuthFailure(const AuthFailure& error) override; - void RecoverEncryptedData(const std::string& old_password) override; - void ResyncEncryptedData() override; + void RecoverEncryptedData(std::unique_ptr<UserContext> user_context, + const std::string& old_password) override; + void ResyncEncryptedData(std::unique_ptr<UserContext> user_context) override; protected: ~AuthSessionAuthenticator() override; @@ -89,13 +90,13 @@ // Function that would hash a key inside `context` so that it can be safely // passed to cryptohome over DBus. - // Hashing uses system salt and optionally key metadata from `reply`. + // Hashing uses system salt and optionally key metadata + // (`UserKeys` in `context`). // As this operation might require getting of system salt, it is an // asynchronous operation. - using KeyHashingCallback = base::OnceCallback<void( - std::unique_ptr<UserContext> context, - const user_data_auth::StartAuthSessionReply& reply, - ContextCallback continuation)>; + using KeyHashingCallback = + base::OnceCallback<void(std::unique_ptr<UserContext> context, + ContextCallback continuation)>; // ------------------------------------------------------------------- // ---- Various synchronous callbacks that are used to configure ---- @@ -215,6 +216,35 @@ std::unique_ptr<UserContext> context, absl::optional<user_data_auth::UnmountReply> reply); + // Attempts to remove user home directory, and invokes `continuation` + // upon success. + void RemoveGeneric(ErrorHandlingCallback error_handler, + ContextCallback continuation, + std::unique_ptr<UserContext> context); + + // Internal callback for Remove call. + void OnRemoveGeneric(ErrorHandlingCallback error_handler, + ContextCallback continuation, + std::unique_ptr<UserContext> context, + absl::optional<user_data_auth::RemoveReply> reply); + + // Attempts to update user's password and calls `continuation` upon success. + // It is assumed that `context` has new password stored as `replacement key`, + // and authentication key as a regular `key`. + void UpdateCredentialsGeneric(ErrorHandlingCallback error_handler, + ContextCallback continuation, + std::unique_ptr<UserContext> context); + + // Internal callback for UpdateCredentials call. + void OnUpdateCredentialsGeneric( + ErrorHandlingCallback error_handler, + ContextCallback continuation, + std::unique_ptr<UserContext> context, + absl::optional<user_data_auth::UpdateCredentialReply> reply); + + // Common part of login logic shared by user creation flow and flow when + // user have changed password elsewhere and decides to re-create cryptohome. + void CompleteLoginImpl(std::unique_ptr<UserContext> user_context); void LoginAsKioskImpl(const AccountId& app_account_id, user_manager::UserType user_type, bool force_dircrypto);
diff --git a/ash/components/login/auth/authenticator.h b/ash/components/login/auth/authenticator.h index 67f80810..700336df 100644 --- a/ash/components/login/auth/authenticator.h +++ b/ash/components/login/auth/authenticator.h
@@ -75,11 +75,14 @@ // Call this method to migrate the user's encrypted data // forward to use their new password. |old_password| is the password // their data was last encrypted with. - virtual void RecoverEncryptedData(const std::string& old_password) = 0; + // |user_context| contains key with new password to be set up. + virtual void RecoverEncryptedData(std::unique_ptr<UserContext> user_context, + const std::string& old_password) = 0; // Call this method to erase the user's encrypted data // and create a new cryptohome. - virtual void ResyncEncryptedData() = 0; + virtual void ResyncEncryptedData( + std::unique_ptr<UserContext> user_context) = 0; // Sets consumer explicitly. void SetConsumer(AuthStatusConsumer* consumer);
diff --git a/ash/components/login/auth/cryptohome_authenticator.cc b/ash/components/login/auth/cryptohome_authenticator.cc index fa1b55d..165a90c0 100644 --- a/ash/components/login/auth/cryptohome_authenticator.cc +++ b/ash/components/login/auth/cryptohome_authenticator.cc
@@ -658,10 +658,12 @@ const std::string& old_password) { current_state_ = std::make_unique<AuthAttemptState>( std::make_unique<UserContext>(user_context)); - RecoverEncryptedData(old_password); + RecoverEncryptedData(std::make_unique<UserContext>(user_context), + old_password); } void CryptohomeAuthenticator::RecoverEncryptedData( + std::unique_ptr<UserContext> user_context, const std::string& old_password) { migrate_attempted_ = true; current_state_->ResetCryptohomeStatus(); @@ -678,7 +680,8 @@ scoped_refptr<CryptohomeAuthenticator>(this))); } -void CryptohomeAuthenticator::ResyncEncryptedData() { +void CryptohomeAuthenticator::ResyncEncryptedData( + std::unique_ptr<UserContext> user_context) { resync_attempted_ = true; current_state_->ResetCryptohomeStatus(); task_runner_->PostTask(
diff --git a/ash/components/login/auth/cryptohome_authenticator.h b/ash/components/login/auth/cryptohome_authenticator.h index 22213eb..cb47fc2 100644 --- a/ash/components/login/auth/cryptohome_authenticator.h +++ b/ash/components/login/auth/cryptohome_authenticator.h
@@ -150,8 +150,9 @@ // and also call back to the login UI. void OnAuthSuccess() override; void OnAuthFailure(const AuthFailure& error) override; - void RecoverEncryptedData(const std::string& old_password) override; - void ResyncEncryptedData() override; + void RecoverEncryptedData(std::unique_ptr<UserContext> user_context, + const std::string& old_password) override; + void ResyncEncryptedData(std::unique_ptr<UserContext> user_context) override; // Called after UnmountEx finishes. void OnUnmountEx(absl::optional<user_data_auth::UnmountReply> reply);
diff --git a/ash/components/login/auth/cryptohome_key_constants.cc b/ash/components/login/auth/cryptohome_key_constants.cc index fd63c868..4c08448c 100644 --- a/ash/components/login/auth/cryptohome_key_constants.cc +++ b/ash/components/login/auth/cryptohome_key_constants.cc
@@ -15,6 +15,8 @@ // key label. const char kCryptohomeGaiaKeyLabel[] = "gaia"; +const char kCryptohomeGaiaKeyLegacyLabelPrefix[] = "legacy-"; + const char kCryptohomePinLabel[] = "pin"; // The label used for the key generated by Cryptohome for public mount aka
diff --git a/ash/components/login/auth/cryptohome_key_constants.h b/ash/components/login/auth/cryptohome_key_constants.h index 772964d..50f9906 100644 --- a/ash/components/login/auth/cryptohome_key_constants.h +++ b/ash/components/login/auth/cryptohome_key_constants.h
@@ -13,6 +13,9 @@ extern const char kCryptohomeGaiaKeyLabel[]; COMPONENT_EXPORT(ASH_LOGIN_AUTH) +extern const char kCryptohomeGaiaKeyLegacyLabelPrefix[]; + +COMPONENT_EXPORT(ASH_LOGIN_AUTH) extern const char kCryptohomePinLabel[]; COMPONENT_EXPORT(ASH_LOGIN_AUTH)
diff --git a/ash/components/login/auth/login_performer.cc b/ash/components/login/auth/login_performer.cc index 42739ac..f77f1c9 100644 --- a/ash/components/login/auth/login_performer.cc +++ b/ash/components/login/auth/login_performer.cc
@@ -188,12 +188,16 @@ void LoginPerformer::RecoverEncryptedData(const std::string& old_password) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - authenticator_->RecoverEncryptedData(old_password); + authenticator_->RecoverEncryptedData( + std::make_unique<UserContext>(user_context_), old_password); + user_context_.ClearSecrets(); } void LoginPerformer::ResyncEncryptedData() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - authenticator_->ResyncEncryptedData(); + authenticator_->ResyncEncryptedData( + std::make_unique<UserContext>(user_context_)); + user_context_.ClearSecrets(); } //////////////////////////////////////////////////////////////////////////////// @@ -230,6 +234,7 @@ const UserContext& user_context) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(delegate_); + user_context_ = user_context; delegate_->OnPasswordChangeDetected(user_context); }
diff --git a/ash/components/login/auth/saml_password_attributes.cc b/ash/components/login/auth/saml_password_attributes.cc index 0b4ab6a..08fde06 100644 --- a/ash/components/login/auth/saml_password_attributes.cc +++ b/ash/components/login/auth/saml_password_attributes.cc
@@ -52,21 +52,21 @@ // static SamlPasswordAttributes SamlPasswordAttributes::FromJs( - const base::DictionaryValue& js_object) { + const base::Value::Dict& js_object) { base::Time modified_time; - const std::string* string_value = js_object.FindStringPath(kModifiedTimeKey); + const std::string* string_value = js_object.FindString(kModifiedTimeKey); if (string_value) { modified_time = ReadJsTime(*string_value); } base::Time expiration_time; - string_value = js_object.FindStringPath(kExpirationTimeKey); + string_value = js_object.FindString(kExpirationTimeKey); if (string_value) { expiration_time = ReadJsTime(*string_value); } std::string password_change_url; - string_value = js_object.FindStringPath(kPasswordChangeUrlKey); + string_value = js_object.FindString(kPasswordChangeUrlKey); if (string_value) { password_change_url = *string_value; }
diff --git a/ash/components/login/auth/saml_password_attributes.h b/ash/components/login/auth/saml_password_attributes.h index cf601d61..0fb19544 100644 --- a/ash/components/login/auth/saml_password_attributes.h +++ b/ash/components/login/auth/saml_password_attributes.h
@@ -9,14 +9,11 @@ #include "base/component_export.h" #include "base/time/time.h" +#include "base/values.h" class PrefRegistrySimple; class PrefService; -namespace base { -class DictionaryValue; -} // namespace base - namespace ash { // Struct which holds attributes about a user's password provided by the SAML @@ -37,7 +34,7 @@ // Initialize an instance of this class with data received from javascript. // The data must be a PasswordAttributes object as defined in // saml_password_attributes.js - static SamlPasswordAttributes FromJs(const base::DictionaryValue& js_object); + static SamlPasswordAttributes FromJs(const base::Value::Dict& js_object); // Load an instance of this class from the given |prefs|. static SamlPasswordAttributes LoadFromPrefs(const PrefService* prefs);
diff --git a/ash/components/login/auth/saml_password_attributes_unittest.cc b/ash/components/login/auth/saml_password_attributes_unittest.cc index 64dae2f..ed1009d 100644 --- a/ash/components/login/auth/saml_password_attributes_unittest.cc +++ b/ash/components/login/auth/saml_password_attributes_unittest.cc
@@ -28,26 +28,26 @@ } // namespace TEST(SamlPasswordAttributesTest, FromJs) { - base::DictionaryValue dict; + base::Value::Dict dict; SamlPasswordAttributes attrs = SamlPasswordAttributes::FromJs(dict); ExpectEmpty(attrs); - dict.SetStringKey("modifiedTime", ""); - dict.SetStringKey("expirationTime", ""); - dict.SetStringKey("passwordChangeUrl", ""); + dict.Set("modifiedTime", ""); + dict.Set("expirationTime", ""); + dict.Set("passwordChangeUrl", ""); attrs = SamlPasswordAttributes::FromJs(dict); ExpectEmpty(attrs); - dict.SetStringKey("modifiedTime", kModifiedStr); - dict.SetStringKey("expirationTime", kExpirationStr); - dict.SetStringKey("passwordChangeUrl", kPasswordChangeUrl); + dict.Set("modifiedTime", kModifiedStr); + dict.Set("expirationTime", kExpirationStr); + dict.Set("passwordChangeUrl", kPasswordChangeUrl); attrs = SamlPasswordAttributes::FromJs(dict); EXPECT_EQ(base::Time::FromJsTime(kModified), attrs.modified_time()); EXPECT_EQ(base::Time::FromJsTime(kExpiration), attrs.expiration_time()); EXPECT_EQ(kPasswordChangeUrl, attrs.password_change_url()); - dict.SetStringKey("passwordChangeUrl", ""); + dict.Set("passwordChangeUrl", ""); attrs = SamlPasswordAttributes::FromJs(dict); EXPECT_EQ(base::Time::FromJsTime(kModified), attrs.modified_time());
diff --git a/ash/components/login/auth/stub_authenticator.cc b/ash/components/login/auth/stub_authenticator.cc index 4844d840..0f93275 100644 --- a/ash/components/login/auth/stub_authenticator.cc +++ b/ash/components/login/auth/stub_authenticator.cc
@@ -139,7 +139,9 @@ consumer_->OnAuthFailure(failure); } -void StubAuthenticator::RecoverEncryptedData(const std::string& old_password) { +void StubAuthenticator::RecoverEncryptedData( + std::unique_ptr<UserContext> user_context, + const std::string& old_password) { if (old_password_ != old_password) { if (data_recovery_notifier_) data_recovery_notifier_.Run(DataRecoveryStatus::kRecoveryFailed); @@ -155,7 +157,8 @@ FROM_HERE, base::BindOnce(&StubAuthenticator::OnAuthSuccess, this)); } -void StubAuthenticator::ResyncEncryptedData() { +void StubAuthenticator::ResyncEncryptedData( + std::unique_ptr<UserContext> user_context) { if (data_recovery_notifier_) data_recovery_notifier_.Run(DataRecoveryStatus::kResynced); task_runner_->PostTask(
diff --git a/ash/components/login/auth/stub_authenticator.h b/ash/components/login/auth/stub_authenticator.h index 0ea0d53..a2a4aa2f 100644 --- a/ash/components/login/auth/stub_authenticator.h +++ b/ash/components/login/auth/stub_authenticator.h
@@ -49,8 +49,9 @@ void LoginAsWebKioskAccount(const AccountId& app_account_id) override; void OnAuthSuccess() override; void OnAuthFailure(const AuthFailure& failure) override; - void RecoverEncryptedData(const std::string& old_password) override; - void ResyncEncryptedData() override; + void RecoverEncryptedData(std::unique_ptr<UserContext> user_context, + const std::string& old_password) override; + void ResyncEncryptedData(std::unique_ptr<UserContext> user_context) override; void SetExpectedCredentials(const UserContext& user_context);
diff --git a/ash/components/login/auth/sync_trusted_vault_keys.cc b/ash/components/login/auth/sync_trusted_vault_keys.cc index e8f8bef..f2e96c8 100644 --- a/ash/components/login/auth/sync_trusted_vault_keys.cc +++ b/ash/components/login/auth/sync_trusted_vault_keys.cc
@@ -55,15 +55,15 @@ template <typename T> std::vector<T> ParseList( - const base::Value* list, + const base::Value::List* list, const base::RepeatingCallback<absl::optional<T>(const base::Value&)>& entry_parser) { - if (list == nullptr || !list->is_list()) { + if (list == nullptr) { return {}; } std::vector<T> parsed_list; - for (const base::Value& list_entry : list->GetListDeprecated()) { + for (const base::Value& list_entry : *list) { absl::optional<T> parsed_entry = entry_parser.Run(list_entry); if (parsed_entry.has_value()) { parsed_list.push_back(std::move(*parsed_entry)); @@ -103,15 +103,15 @@ // static SyncTrustedVaultKeys SyncTrustedVaultKeys::FromJs( - const base::DictionaryValue& js_object) { + const base::Value::Dict& js_object) { SyncTrustedVaultKeys result; - const std::string* gaia_id = js_object.FindStringKey(kGaiaIdDictKey); + const std::string* gaia_id = js_object.FindString(kGaiaIdDictKey); if (gaia_id) { result.gaia_id_ = *gaia_id; } const std::vector<KeyMaterialAndVersion> encryption_keys = - ParseList(js_object.FindListKey(kEncryptionKeysDictKey), + ParseList(js_object.FindList(kEncryptionKeysDictKey), base::BindRepeating(&ParseSingleEncryptionKey)); for (const KeyMaterialAndVersion& key : encryption_keys) { @@ -122,7 +122,7 @@ } result.trusted_recovery_methods_ = - ParseList(js_object.FindListKey(kTrustedRecoveryMethodsDictKey), + ParseList(js_object.FindList(kTrustedRecoveryMethodsDictKey), base::BindRepeating(&ParseSingleTrustedRecoveryMethod)); return result;
diff --git a/ash/components/login/auth/sync_trusted_vault_keys.h b/ash/components/login/auth/sync_trusted_vault_keys.h index b0346fc..c81234f 100644 --- a/ash/components/login/auth/sync_trusted_vault_keys.h +++ b/ash/components/login/auth/sync_trusted_vault_keys.h
@@ -9,10 +9,7 @@ #include <vector> #include "base/component_export.h" - -namespace base { -class DictionaryValue; -} // namespace base +#include "base/values.h" namespace ash { @@ -29,7 +26,7 @@ // Initialize an instance of this class with data received from javascript. // The input data must be of type SyncTrustedVaultKeys as defined in // authenticator.js. - static SyncTrustedVaultKeys FromJs(const base::DictionaryValue& js_object); + static SyncTrustedVaultKeys FromJs(const base::Value::Dict& js_object); const std::string& gaia_id() const;
diff --git a/ash/components/login/auth/sync_trusted_vault_keys_unittest.cc b/ash/components/login/auth/sync_trusted_vault_keys_unittest.cc index 13a50c0..19d5fd61 100644 --- a/ash/components/login/auth/sync_trusted_vault_keys_unittest.cc +++ b/ash/components/login/auth/sync_trusted_vault_keys_unittest.cc
@@ -57,20 +57,20 @@ } TEST(SyncTrustedVaultKeysTest, FromJsWithEmptyDictionary) { - EXPECT_THAT(SyncTrustedVaultKeys::FromJs(base::DictionaryValue()), + EXPECT_THAT(SyncTrustedVaultKeys::FromJs(base::Value::Dict()), HasEmptyValue()); } TEST(SyncTrustedVaultKeysTest, FromJsWithInvalidDictionary) { - base::DictionaryValue value; - value.SetStringKey("foo", "bar"); + base::Value::Dict value; + value.Set("foo", "bar"); EXPECT_THAT(SyncTrustedVaultKeys::FromJs(value), HasEmptyValue()); } TEST(SyncTrustedVaultKeysTest, FromJsWithGaiaId) { const std::string kGaiaId = "user1"; - base::DictionaryValue value; - value.SetStringKey("obfuscatedGaiaId", kGaiaId); + base::Value::Dict value; + value.Set("obfuscatedGaiaId", kGaiaId); EXPECT_THAT(SyncTrustedVaultKeys::FromJs(value).gaia_id(), Eq(kGaiaId)); } @@ -86,8 +86,8 @@ key_values.push_back( MakeKeyValue(kEncryptionKeyMaterial2, kEncryptionKeyVersion2)); - base::DictionaryValue root_value; - root_value.SetKey("encryptionKeys", base::Value(std::move(key_values))); + base::Value::Dict root_value; + root_value.Set("encryptionKeys", base::Value(std::move(key_values))); const SyncTrustedVaultKeys actual_converted_keys = SyncTrustedVaultKeys::FromJs(root_value); @@ -108,8 +108,8 @@ MakeKeyValue(kEncryptionKeyMaterial1, kEncryptionKeyVersion1)); key_values.push_back(MakeKeyValueWithoutVersion(kEncryptionKeyMaterial2)); - base::DictionaryValue root_value; - root_value.SetKey("encryptionKeys", base::Value(std::move(key_values))); + base::Value::Dict root_value; + root_value.Set("encryptionKeys", base::Value(std::move(key_values))); const SyncTrustedVaultKeys actual_converted_keys = SyncTrustedVaultKeys::FromJs(root_value); @@ -130,9 +130,8 @@ key_values.push_back(MakePublicKeyAndType(kPublicKeyMaterial1, kMethodType1)); key_values.push_back(MakePublicKeyAndType(kPublicKeyMaterial2, kMethodType2)); - base::DictionaryValue root_value; - root_value.SetKey("trustedRecoveryMethods", - base::Value(std::move(key_values))); + base::Value::Dict root_value; + root_value.Set("trustedRecoveryMethods", base::Value(std::move(key_values))); const SyncTrustedVaultKeys actual_converted_keys = SyncTrustedVaultKeys::FromJs(root_value);
diff --git a/ash/components/login/auth/user_context.cc b/ash/components/login/auth/user_context.cc index 0d684a12..5140ff6 100644 --- a/ash/components/login/auth/user_context.cc +++ b/ash/components/login/auth/user_context.cc
@@ -4,6 +4,7 @@ #include "ash/components/login/auth/user_context.h" +#include "ash/components/login/auth/auth_factors_data.h" #include "components/user_manager/user.h" #include "components/user_manager/user_manager.h" #include "components/user_manager/user_names.h" @@ -66,6 +67,10 @@ return &key_; } +const Key* UserContext::GetReplacementKey() const { + return &replacement_key_.value(); +} + const Key* UserContext::GetPasswordKey() const { return &password_key_; } @@ -168,6 +173,10 @@ !auth_code_.empty(); } +bool UserContext::HasReplacementKey() const { + return replacement_key_.has_value(); +} + bool UserContext::IsUnderAdvancedProtection() const { return is_under_advanced_protection_; } @@ -180,6 +189,12 @@ key_ = key; } +void UserContext::SaveKeyForReplacement() { + if (replacement_key_.has_value()) + return; + replacement_key_ = key_; +} + void UserContext::SetPasswordKey(const Key& key) { password_key_ = key; } @@ -281,6 +296,18 @@ authsession_id_ = authsession_id; } +void UserContext::ResetAuthSessionId() { + authsession_id_.clear(); +} + +void UserContext::SetAuthFactorsData(AuthFactorsData data) { + auth_factors_data_ = std::move(data); +} + +const AuthFactorsData& UserContext::GetAuthFactorsData() const { + return auth_factors_data_; +} + const std::string& UserContext::GetAuthSessionId() const { return authsession_id_; } @@ -288,6 +315,7 @@ void UserContext::ClearSecrets() { key_.ClearSecret(); password_key_.ClearSecret(); + replacement_key_ = absl::nullopt; auth_code_.clear(); refresh_token_.clear(); sync_trusted_vault_keys_.reset();
diff --git a/ash/components/login/auth/user_context.h b/ash/components/login/auth/user_context.h index 55acff11..acfa630 100644 --- a/ash/components/login/auth/user_context.h +++ b/ash/components/login/auth/user_context.h
@@ -7,6 +7,7 @@ #include <string> +#include "ash/components/login/auth/auth_factors_data.h" #include "ash/components/login/auth/challenge_response_key.h" #include "ash/components/login/auth/key.h" #include "ash/components/login/auth/saml_password_attributes.h" @@ -61,6 +62,10 @@ // its hashed/transformed representation. const Key* GetKey() const; Key* GetKey(); + // In password change scenario this is the key that would replace old Key + // used for authentication. + const Key* GetReplacementKey() const; + // The plain-text user password. See https://crbug.com/386606. const Key* GetPasswordKey() const; Key* GetMutablePasswordKey(); @@ -71,6 +76,8 @@ const std::vector<ChallengeResponseKey>& GetChallengeResponseKeys() const; std::vector<ChallengeResponseKey>* GetMutableChallengeResponseKeys(); + const AuthFactorsData& GetAuthFactorsData() const; + const std::string& GetAuthCode() const; const std::string& GetRefreshToken() const; const std::string& GetAccessToken() const; @@ -94,12 +101,25 @@ bool CanLockManagedGuestSession() const; bool HasCredentials() const; + bool HasReplacementKey() const; // If this user is under advanced protection. bool IsUnderAdvancedProtection() const; void SetAccountId(const AccountId& account_id); void SetKey(const Key& key); + + // This method is used in key replacement scenario, when user's online + // password was changed externally. Upon next online sign-in the new verified + // password is collected as Key/PasswordKey. But as cryptohome still has old + // key, old password is collected to access it and replace key. + // + // This method saves existing Key as ReplacementKey. PasswordKey is not + // affected, as it contains up-to-date password. As user can attempt to enter + // old password several times, this method would not overwrite ReplacementKey + // if it exists after previous attempts. + void SaveKeyForReplacement(); + // Saves the user's plaintext password for possible authentication by system // services: // - To networks. If the user's OpenNetworkConfiguration policy contains a @@ -137,12 +157,14 @@ const SyncTrustedVaultKeys& sync_trusted_vault_keys); void SetIsUnderAdvancedProtection(bool is_under_advanced_protection); void SetCanLockManagedGuestSession(bool can_lock_managed_guest_session); + void SetAuthFactorsData(AuthFactorsData keys); // We need to pull input method used to log in into the user session to make // it consistent. This method will remember given input method to be used // when session starts. void SetLoginInputMethodIdUsed(const std::string& input_method_id); const std::string& GetLoginInputMethodIdUsed() const; void SetAuthSessionId(const std::string& authsession_id); + void ResetAuthSessionId(); const std::string& GetAuthSessionId() const; void ClearSecrets(); @@ -151,6 +173,8 @@ AccountId account_id_; Key key_; Key password_key_; + absl::optional<Key> replacement_key_ = absl::nullopt; + AuthFactorsData auth_factors_data_; std::vector<ChallengeResponseKey> challenge_response_keys_; std::string auth_code_; std::string refresh_token_;
diff --git a/ash/public/cpp/app_menu_constants.h b/ash/public/cpp/app_menu_constants.h index 92b9a140..1a0f967 100644 --- a/ash/public/cpp/app_menu_constants.h +++ b/ash/public/cpp/app_menu_constants.h
@@ -59,7 +59,8 @@ USE_LAUNCH_TYPE_WINDOW = 203, USE_LAUNCH_TYPE_TABBED_WINDOW = 204, USE_LAUNCH_TYPE_COMMAND_END, - // The reorder submenu options used by AppServiceContextMenu. + // The reorder options used by AppsGridContextMenu, ShelfContextMenuModel and + // AppServiceContextMenu. REORDER_SUBMENU = 300, REORDER_BY_NAME_ALPHABETICAL = 301, REORDER_BY_NAME_REVERSE_ALPHABETICAL = 302,
diff --git a/ash/rgb_keyboard/rgb_keyboard_manager.cc b/ash/rgb_keyboard/rgb_keyboard_manager.cc index d77e902..cdab580 100644 --- a/ash/rgb_keyboard/rgb_keyboard_manager.cc +++ b/ash/rgb_keyboard/rgb_keyboard_manager.cc
@@ -4,6 +4,9 @@ #include "ash/rgb_keyboard/rgb_keyboard_manager.h" +#include <stdint.h> +#include <vector> + #include "base/check.h" #include "base/check_op.h" @@ -13,9 +16,12 @@ RgbKeyboardManager* g_instance = nullptr; +const int kRGBLength = 3; + } // namespace -RgbKeyboardManager::RgbKeyboardManager() { +RgbKeyboardManager::RgbKeyboardManager() + : recently_sent_rgb_for_testing_(kRGBLength) { DCHECK(!g_instance); g_instance = this; } @@ -30,6 +36,28 @@ return RgbKeyboardCapabilities::kNone; } +// TODO(jimmyxgong): This is a stub implementation, replace with real impl. +void RgbKeyboardManager::SetStaticBackgroundColor(uint8_t r, + uint8_t g, + uint8_t b) { + // Reset the rainbow mode state. + is_rainbow_mode_set_for_testing_ = false; + + recently_sent_rgb_for_testing_[0] = r; + recently_sent_rgb_for_testing_[1] = g; + recently_sent_rgb_for_testing_[2] = b; +} + +// TODO(jimmyxgong): This is a stub implementation, replace with real impl. +void RgbKeyboardManager::SetRainbowMode() { + is_rainbow_mode_set_for_testing_ = true; + + // Reset the stored static rgb values; + recently_sent_rgb_for_testing_[0] = 0u; + recently_sent_rgb_for_testing_[1] = 0u; + recently_sent_rgb_for_testing_[2] = 0u; +} + // static RgbKeyboardManager* RgbKeyboardManager::Get() { return g_instance;
diff --git a/ash/rgb_keyboard/rgb_keyboard_manager.h b/ash/rgb_keyboard/rgb_keyboard_manager.h index fbdf9ff..ee21c6b 100644 --- a/ash/rgb_keyboard/rgb_keyboard_manager.h +++ b/ash/rgb_keyboard/rgb_keyboard_manager.h
@@ -5,6 +5,9 @@ #ifndef ASH_RGB_KEYBOARD_RGB_KEYBOARD_MANAGER_H_ #define ASH_RGB_KEYBOARD_RGB_KEYBOARD_MANAGER_H_ +#include <stdint.h> +#include <vector> + #include "ash/ash_export.h" namespace ash { @@ -29,9 +32,23 @@ ~RgbKeyboardManager(); RgbKeyboardCapabilities GetRgbKeyboardCapabilities() const; + void SetStaticBackgroundColor(uint8_t r, uint8_t g, uint8_t b); + void SetRainbowMode(); // Returns the global instance if initialized. May return null. static RgbKeyboardManager* Get(); + + std::vector<uint8_t> recently_sent_rgb() const { + return recently_sent_rgb_for_testing_; + } + + bool is_rainbow_mode_set() const { return is_rainbow_mode_set_for_testing_; } + + private: + // TODO(jimmyxgong): Remove the following members after DBus client is + // available. + std::vector<uint8_t> recently_sent_rgb_for_testing_; + bool is_rainbow_mode_set_for_testing_ = false; }; } // namespace ash
diff --git a/ash/rgb_keyboard/rgb_keyboard_manager_unittest.cc b/ash/rgb_keyboard/rgb_keyboard_manager_unittest.cc index b099954..7cc5f94 100644 --- a/ash/rgb_keyboard/rgb_keyboard_manager_unittest.cc +++ b/ash/rgb_keyboard/rgb_keyboard_manager_unittest.cc
@@ -4,7 +4,9 @@ #include "ash/rgb_keyboard/rgb_keyboard_manager.h" +#include <stdint.h> #include <memory> +#include <vector> #include "base/test/scoped_feature_list.h" #include "testing/gtest/include/gtest/gtest.h" @@ -36,4 +38,66 @@ RgbKeyboardCapabilities::kNone); } +TEST_F(RgbKeyboardManagerTest, SetStaticRgbValues) { + const uint8_t expected_r = 1; + const uint8_t expected_g = 2; + const uint8_t expected_b = 3; + + manager_->SetStaticBackgroundColor(expected_r, expected_g, expected_b); + const std::vector<uint8_t> rgb_values = manager_->recently_sent_rgb(); + + EXPECT_EQ(expected_r, rgb_values[0]); + EXPECT_EQ(expected_g, rgb_values[1]); + EXPECT_EQ(expected_b, rgb_values[2]); +} + +TEST_F(RgbKeyboardManagerTest, SetRainbowMode) { + EXPECT_FALSE(manager_->is_rainbow_mode_set()); + + manager_->SetRainbowMode(); + + EXPECT_TRUE(manager_->is_rainbow_mode_set()); +} + +TEST_F(RgbKeyboardManagerTest, RainbowModeResetsStatic) { + EXPECT_FALSE(manager_->is_rainbow_mode_set()); + + const uint8_t expected_r = 1; + const uint8_t expected_g = 2; + const uint8_t expected_b = 3; + + manager_->SetStaticBackgroundColor(expected_r, expected_g, expected_b); + std::vector<uint8_t> rgb_values = manager_->recently_sent_rgb(); + + EXPECT_EQ(expected_r, rgb_values[0]); + EXPECT_EQ(expected_g, rgb_values[1]); + EXPECT_EQ(expected_b, rgb_values[2]); + + manager_->SetRainbowMode(); + EXPECT_TRUE(manager_->is_rainbow_mode_set()); + + rgb_values = manager_->recently_sent_rgb(); + EXPECT_EQ(0u, rgb_values[0]); + EXPECT_EQ(0u, rgb_values[1]); + EXPECT_EQ(0u, rgb_values[2]); +} + +TEST_F(RgbKeyboardManagerTest, StaticResetRainbowMode) { + EXPECT_FALSE(manager_->is_rainbow_mode_set()); + manager_->SetRainbowMode(); + EXPECT_TRUE(manager_->is_rainbow_mode_set()); + + const uint8_t expected_r = 1; + const uint8_t expected_g = 2; + const uint8_t expected_b = 3; + + manager_->SetStaticBackgroundColor(expected_r, expected_g, expected_b); + const std::vector<uint8_t> rgb_values = manager_->recently_sent_rgb(); + + EXPECT_EQ(expected_r, rgb_values[0]); + EXPECT_EQ(expected_g, rgb_values[1]); + EXPECT_EQ(expected_b, rgb_values[2]); + + EXPECT_FALSE(manager_->is_rainbow_mode_set()); +} } // namespace ash \ No newline at end of file
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index c301cf9..f5e3d19 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc
@@ -13,6 +13,7 @@ #include "ash/accessibility/chromevox/touch_exploration_manager.h" #include "ash/accessibility/ui/accessibility_panel_layout_manager.h" #include "ash/ambient/ambient_controller.h" +#include "ash/app_list/app_list_controller_impl.h" #include "ash/app_menu/app_menu_model_adapter.h" #include "ash/constants/ash_constants.h" #include "ash/constants/ash_features.h" @@ -28,9 +29,11 @@ #include "ash/keyboard/virtual_keyboard_container_layout_manager.h" #include "ash/lock_screen_action/lock_screen_action_background_controller.h" #include "ash/login_status.h" +#include "ash/public/cpp/app_menu_constants.h" #include "ash/public/cpp/shelf_types.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/window_properties.h" +#include "ash/resources/vector_icons/vector_icons.h" #include "ash/root_window_settings.h" #include "ash/scoped_animation_disabler.h" #include "ash/screen_util.h" @@ -41,6 +44,7 @@ #include "ash/shelf/shelf_widget.h" #include "ash/shelf/shelf_window_targeter.h" #include "ash/shell.h" +#include "ash/strings/grit/ash_strings.h" #include "ash/system/status_area_widget.h" #include "ash/system/tray/tray_background_view.h" #include "ash/system/unified/unified_system_tray.h" @@ -87,7 +91,9 @@ #include "ui/aura/window_event_dispatcher.h" #include "ui/aura/window_observer.h" #include "ui/aura/window_tracker.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/base/models/menu_model.h" +#include "ui/base/models/simple_menu_model.h" #include "ui/compositor/layer.h" #include "ui/display/types/display_constants.h" #include "ui/events/event_utils.h" @@ -779,13 +785,41 @@ ->GetDisplayNearestWindow(GetRootWindow()) .id(); + const bool tablet_mode = + Shell::Get()->tablet_mode_controller()->InTabletMode(); root_window_menu_model_adapter_ = std::make_unique<RootWindowMenuModelAdapter>( std::make_unique<ShelfContextMenuModel>(nullptr, display_id), wallpaper_widget_controller()->GetWidget(), source_type, base::BindOnce(&RootWindowController::OnMenuClosed, base::Unretained(this)), - Shell::Get()->tablet_mode_controller()->InTabletMode()); + tablet_mode); + + // Appends the apps sort options in ShelfContextMenuModel in tablet mode. Note + // that the launcher UI is fullscreen in tablet mode, so the whole root window + // can be perceived by users to be part of the launcher. + if (features::IsLauncherAppSortEnabled() && tablet_mode && + Shell::Get()->app_list_controller()->IsVisible(display_id)) { + ui::SimpleMenuModel* menu_model = root_window_menu_model_adapter_->model(); + sort_apps_submenu_ = std::make_unique<ui::SimpleMenuModel>( + static_cast<ShelfContextMenuModel*>(menu_model)); + sort_apps_submenu_->AddItemWithIcon( + REORDER_BY_NAME_ALPHABETICAL, + l10n_util::GetStringUTF16( + IDS_ASH_LAUNCHER_APPS_GRID_CONTEXT_MENU_REORDER_BY_NAME), + ui::ImageModel::FromVectorIcon(kSortAlphabeticalIcon)); + sort_apps_submenu_->AddItemWithIcon( + REORDER_BY_COLOR, + l10n_util::GetStringUTF16( + IDS_ASH_LAUNCHER_APPS_GRID_CONTEXT_MENU_REORDER_BY_COLOR), + ui::ImageModel::FromVectorIcon(kSortColorIcon)); + menu_model->AddSeparator(ui::NORMAL_SEPARATOR); + menu_model->AddSubMenuWithIcon( + REORDER_SUBMENU, + l10n_util::GetStringUTF16( + IDS_ASH_LAUNCHER_APPS_GRID_CONTEXT_MENU_REORDER_TITLE), + sort_apps_submenu_.get(), ui::ImageModel::FromVectorIcon(kReorderIcon)); + } root_window_menu_model_adapter_->Run( gfx::Rect(location_in_screen, gfx::Size()), @@ -1272,6 +1306,7 @@ void RootWindowController::OnMenuClosed() { root_window_menu_model_adapter_.reset(); + sort_apps_submenu_.reset(); shelf_->UpdateVisibilityState(); }
diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h index 63ecf91..03194bf 100644 --- a/ash/root_window_controller.h +++ b/ash/root_window_controller.h
@@ -26,6 +26,7 @@ namespace ui { class WindowTreeHost; +class SimpleMenuModel; } namespace views { @@ -231,6 +232,9 @@ void CloseAmbientWidget(bool immediately); views::Widget* ambient_widget_for_testing() { return ambient_widget_.get(); } + AppMenuModelAdapter* menu_model_adapter_for_testing() { + return root_window_menu_model_adapter_.get(); + } // Returns accessibility panel layout manager for this root window. AccessibilityPanelLayoutManager* GetAccessibilityPanelLayoutManagerForTest(); @@ -282,6 +286,7 @@ // Manages the context menu. std::unique_ptr<AppMenuModelAdapter> root_window_menu_model_adapter_; + std::unique_ptr<ui::SimpleMenuModel> sort_apps_submenu_; std::unique_ptr<StackingController> stacking_controller_;
diff --git a/ash/shelf/shelf_context_menu_model.cc b/ash/shelf/shelf_context_menu_model.cc index ce900836..231694eb 100644 --- a/ash/shelf/shelf_context_menu_model.cc +++ b/ash/shelf/shelf_context_menu_model.cc
@@ -10,6 +10,8 @@ #include "ash/app_list/app_list_controller_impl.h" #include "ash/app_list/app_list_metrics.h" +#include "ash/app_list/app_list_model_provider.h" +#include "ash/app_list/model/app_list_model.h" #include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" #include "ash/public/cpp/app_menu_constants.h" @@ -121,6 +123,15 @@ DCHECK(ash::features::IsPersonalizationHubEnabled()); NewWindowDelegate::GetPrimary()->OpenPersonalizationHub(); break; + // Using reorder CommandId in ash/public/cpp/app_menu_constants.h + case REORDER_BY_NAME_ALPHABETICAL: + AppListModelProvider::Get()->model()->delegate()->RequestAppListSort( + AppListSortOrder::kNameAlphabetical); + break; + case REORDER_BY_COLOR: + AppListModelProvider::Get()->model()->delegate()->RequestAppListSort( + AppListSortOrder::kColor); + break; default: if (delegate_) { if (IsCommandIdAnAppLaunch(command_id)) {
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc index 9de9260..7b80443 100644 --- a/ash/shelf/shelf_view.cc +++ b/ash/shelf/shelf_view.cc
@@ -1005,8 +1005,8 @@ const int button_size = GetButtonSize(); for (int i = 0; i < view_model_->view_size(); ++i) { if (view_model_->view_at(i)->GetVisible()) { - view_model_->set_ideal_bounds(i, - gfx::Rect(x, y, button_size, button_size)); + gfx::Rect ideal_view_bounds(x, y, button_size, button_size); + view_model_->set_ideal_bounds(i, ideal_view_bounds); if (view_model_->view_at(i) == drag_view_ && current_ghost_view_index_ != i && !dragged_off_shelf_) { if (current_ghost_view_) @@ -1015,9 +1015,14 @@ last_ghost_view_ = current_ghost_view_; auto current_ghost_view = std::make_unique<GhostImageView>(GridIndex()); - gfx::Rect ghost_view_bounds(x, y, button_size, button_size); + gfx::Size icon_size = drag_view_ + ->GetIdealIconBounds(ideal_view_bounds.size(), + /*icon_scale=*/1.0f) + .size(); + gfx::Rect ghost_view_bounds = ideal_view_bounds; + ghost_view_bounds.ClampToCenteredSize(icon_size); current_ghost_view->Init(ghost_view_bounds, - ShelfConfig::Get()->button_spacing()); + ghost_view_bounds.width() / 2); current_ghost_view_ = AddChildView(std::move(current_ghost_view)); current_ghost_view_->FadeIn();
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc index 9d7e2c6b..8722e0e 100644 --- a/ash/wallpaper/wallpaper_controller_impl.cc +++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -570,6 +570,27 @@ return user_manager::USER_TYPE_REGULAR; } +// Gets |account_id|'s custom wallpaper at |wallpaper_path|. Falls back to the +// original custom wallpaper. Verifies that the returned path exists. If a valid +// path cannot be found, returns an empty FilePath. Must run on wallpaper +// sequenced worker thread. +base::FilePath PathWithFallback(const AccountId& account_id, + const WallpaperInfo& info, + const base::FilePath& wallpaper_path) { + if (base::PathExists(wallpaper_path)) + return wallpaper_path; + + // Falls back to the original file if the file with correct resolution does + // not exist. This may happen when the original custom wallpaper is small or + // browser shutdown before resized wallpaper saved. + base::FilePath valid_path = + WallpaperControllerImpl::GetCustomWallpaperDir( + WallpaperControllerImpl::kOriginalWallpaperSubDir) + .Append(info.location); + + return base::PathExists(valid_path) ? valid_path : base::FilePath(); +} + // Populates online wallpaper related info in |info|. void PopulateOnlineWallpaperInfo(WallpaperInfo* info, const base::Value& info_dict) { @@ -816,38 +837,6 @@ return GlobalChromeOSCustomWallpapersDir().Append(sub_dir); } -// static -void WallpaperControllerImpl::SetWallpaperFromPath( - const AccountId& account_id, - const WallpaperInfo& info, - const base::FilePath& wallpaper_path, - bool show_wallpaper, - const scoped_refptr<base::SingleThreadTaskRunner>& reply_task_runner, - base::WeakPtr<WallpaperControllerImpl> weak_ptr) { - base::FilePath valid_path = wallpaper_path; - if (!base::PathExists(valid_path)) { - // Falls back to the original file if the file with correct resolution does - // not exist. This may happen when the original custom wallpaper is small or - // browser shutdown before resized wallpaper saved. - valid_path = - GetCustomWallpaperDir(kOriginalWallpaperSubDir).Append(info.location); - } - - if (!base::PathExists(valid_path)) { - LOG(ERROR) << "The path " << valid_path.value() - << " doesn't exist. Falls back to default wallpaper."; - reply_task_runner->PostTask( - FROM_HERE, - base::BindOnce(&WallpaperControllerImpl::SetDefaultWallpaperImpl, - weak_ptr, account_id, show_wallpaper)); - } else { - reply_task_runner->PostTask( - FROM_HERE, - base::BindOnce(&WallpaperControllerImpl::StartDecodeFromPath, weak_ptr, - account_id, valid_path, info, show_wallpaper)); - } -} - SkColor WallpaperControllerImpl::GetProminentColor( ColorProfile color_profile) const { ColorProfileType type = GetColorProfileType(color_profile); @@ -1121,9 +1110,15 @@ void WallpaperControllerImpl::StartDecodeFromPath( const AccountId& account_id, - const base::FilePath& wallpaper_path, const WallpaperInfo& info, - bool show_wallpaper) { + bool show_wallpaper, + const base::FilePath& wallpaper_path) { + if (wallpaper_path.empty()) { + // Fallback to default if the path is empty. + SetDefaultWallpaperImpl(account_id, show_wallpaper); + return; + } + ReadAndDecodeWallpaper( base::BindOnce(&WallpaperControllerImpl::OnWallpaperDecoded, weak_factory_.GetWeakPtr(), account_id, wallpaper_path, @@ -1524,12 +1519,12 @@ wallpaper_cache_map_[account_id] = CustomWallpaperElement(wallpaper_path, gfx::ImageSkia()); - sequenced_task_runner_->PostTask( + sequenced_task_runner_->PostTaskAndReplyWithResult( FROM_HERE, - base::BindOnce(&SetWallpaperFromPath, account_id, info, wallpaper_path, - /*show_wallpaper=*/true, - base::ThreadTaskRunnerHandle::Get(), - weak_factory_.GetWeakPtr())); + base::BindOnce(&PathWithFallback, account_id, info, wallpaper_path), + base::BindOnce(&WallpaperControllerImpl::StartDecodeFromPath, + weak_factory_.GetWeakPtr(), account_id, info, + /*show_wallpaper=*/true)); } void WallpaperControllerImpl::ShowSigninWallpaper() {
diff --git a/ash/wallpaper/wallpaper_controller_impl.h b/ash/wallpaper/wallpaper_controller_impl.h index c729c1c..2e9167a 100644 --- a/ash/wallpaper/wallpaper_controller_impl.h +++ b/ash/wallpaper/wallpaper_controller_impl.h
@@ -142,17 +142,6 @@ // Returns custom wallpaper directory by appending corresponding |sub_dir|. static base::FilePath GetCustomWallpaperDir(const std::string& sub_dir); - // Gets |account_id|'s custom wallpaper at |wallpaper_path|. Falls back to the - // original custom wallpaper. When |show_wallpaper| is true, shows the - // wallpaper immediately. Must run on wallpaper sequenced worker thread. - static void SetWallpaperFromPath( - const AccountId& account_id, - const WallpaperInfo& info, - const base::FilePath& wallpaper_path, - bool show_wallpaper, - const scoped_refptr<base::SingleThreadTaskRunner>& reply_task_runner, - base::WeakPtr<WallpaperControllerImpl> weak_ptr); - // Returns the prominent color based on |color_profile|. SkColor GetProminentColor(color_utils::ColorProfile color_profile) const; @@ -247,9 +236,9 @@ // A wrapper of |ReadAndDecodeWallpaper| used in |SetWallpaperFromPath|. void StartDecodeFromPath(const AccountId& account_id, - const base::FilePath& wallpaper_path, const WallpaperInfo& info, - bool show_wallpaper); + bool show_wallpaper, + const base::FilePath& wallpaper_path); // WallpaperController: void SetClient(WallpaperControllerClient* client) override;
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc index a258867..d160f89d 100644 --- a/ash/wallpaper/wallpaper_controller_unittest.cc +++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -55,6 +55,7 @@ #include "components/user_manager/scoped_user_manager.h" #include "components/user_manager/user_names.h" #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" +#include "testing/gmock/include/gmock/gmock-matchers.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/aura/window.h" @@ -1344,6 +1345,86 @@ EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kDefault); } +// Simulates the scenario where the wallpaper are not yet resized and only the +// original size image is available. +TEST_P(WallpaperControllerTest, ShowUserWallpaper_OriginalFallback) { + SetBypassDecode(); + CreateDefaultWallpapers(); + + // Simulate the login screen. + ClearLogin(); + + // Set a wallpaper. + CreateAndSaveWallpapers(account_id_1); + RunAllTasksUntilIdle(); + + // Verify the wallpaper was set. + WallpaperInfo wallpaper_info; + ASSERT_TRUE(controller_->GetUserWallpaperInfo(account_id_1, &wallpaper_info)); + ASSERT_EQ(WallpaperType::kCustomized, wallpaper_info.type); + ASSERT_EQ("user1@test.com-hash/user1@test.com-file", wallpaper_info.location); + + // Move the wallpaper file to the original folder. + base::FilePath saved_wallpaper = custom_wallpaper_dir_.GetPath().Append( + "small/user1@test.com-hash/user1@test.com-file"); + ASSERT_TRUE(base::PathExists(saved_wallpaper)); + base::CreateDirectory( + WallpaperControllerImpl::GetCustomWallpaperDir("original") + .Append("user1@test.com-hash")); + ASSERT_TRUE(base::PathExists( + WallpaperControllerImpl::GetCustomWallpaperDir("original"))); + ASSERT_TRUE( + base::Move(saved_wallpaper, + WallpaperControllerImpl::GetCustomWallpaperDir("original") + .Append(wallpaper_info.location))); + ASSERT_FALSE(base::PathExists(saved_wallpaper)); + ClearDecodeFilePaths(); + + // Show wallpaper + controller_->ShowUserWallpaper(account_id_1); + RunAllTasksUntilIdle(); + + // Verify the wallpaper was found in the original folder. + EXPECT_FALSE(GetDecodeFilePaths().empty()); + EXPECT_THAT( + GetDecodeFilePaths().back().value(), + testing::EndsWith("original/user1@test.com-hash/user1@test.com-file")); +} + +// Simulates a missing wallpaper due (possibly) an outdated preference. In this +// situation, we fallback to the default. +TEST_P(WallpaperControllerTest, ShowUserWallpaper_MissingFile) { + CreateDefaultWallpapers(); + + // Simulate the login screen. + ClearLogin(); + + // Set a wallpaper. + CreateAndSaveWallpapers(account_id_1); + RunAllTasksUntilIdle(); + + // Verify the wallpaper was set. + WallpaperInfo wallpaper_info; + ASSERT_TRUE(controller_->GetUserWallpaperInfo(account_id_1, &wallpaper_info)); + ASSERT_EQ(WallpaperType::kCustomized, wallpaper_info.type); + ASSERT_EQ("user1@test.com-hash/user1@test.com-file", wallpaper_info.location); + + // Delete wallpaper file. + EXPECT_TRUE(base::DeleteFile( + user_data_dir_.GetPath().Append(wallpaper_info.location))); + ClearDecodeFilePaths(); + + // Show wallpaper + controller_->ShowUserWallpaper(account_id_1); + RunAllTasksUntilIdle(); + + // Verify the default wallpaper was used because the stored wallpaper was + // missing. + EXPECT_FALSE(GetDecodeFilePaths().empty()); + EXPECT_THAT(GetDecodeFilePaths().back().value(), + testing::EndsWith(kDefaultSmallWallpaperName)); +} + TEST_P(WallpaperControllerTest, RemovePolicyWallpaperNoOp) { auto verify_custom_wallpaper_info = [&]() { EXPECT_EQ(WallpaperType::kCustomized, controller_->GetWallpaperType());
diff --git a/ash/webui/os_feedback_ui/resources/help_resources_icons.html b/ash/webui/os_feedback_ui/resources/help_resources_icons.html index 12a0e28..48b3cbb 100644 --- a/ash/webui/os_feedback_ui/resources/help_resources_icons.html +++ b/ash/webui/os_feedback_ui/resources/help_resources_icons.html
@@ -307,7 +307,7 @@ <defs> <g id="forum"> <path fill-rule="evenodd" clip-rule="evenodd" - d="M16 2H3.66667C2.75 2 2.00833 2.75 2.00833 3.66667L2 17.5L5 15H16C16.9167 15 18 14.4167 18 13.5V3.5C18 2.58333 16.9167 2 16 2ZM16 13H4V4H16V13ZM5 9H11V11H5V9ZM5 6H15V8H5V6Z" + d="M4 4V10H13V4H4ZM3 2C2.44772 2 2 2.44772 2 3V11V15L5 12H14C14.5523 12 15 11.5523 15 11V3C15 2.44772 14.5523 2 14 2H3ZM16 6V13H6V14C6 14.5523 6.44771 15 7 15H14L18 19V15V13V7C18 6.44772 17.5523 6 17 6H16Z" fill="#202124"></path> </g> </defs>
diff --git a/ash/webui/shimless_rma/resources/critical_error_page.js b/ash/webui/shimless_rma/resources/critical_error_page.js index 43177a6..d85ae71 100644 --- a/ash/webui/shimless_rma/resources/critical_error_page.js +++ b/ash/webui/shimless_rma/resources/critical_error_page.js
@@ -12,6 +12,7 @@ import {getShimlessRmaService} from './mojo_interface_provider.js'; import {ShimlessRmaServiceInterface} from './shimless_rma_types.js'; +import {disableAllButtons} from './shimless_rma_util.js'; /** * @fileoverview @@ -54,19 +55,13 @@ /** @protected */ onExitToLoginButtonClicked_() { this.shimlessRmaService_.criticalErrorExitToLogin(); - this.dispatchEvent(new CustomEvent( - 'disable-all-buttons', - {bubbles: true, composed: true, detail: true}, - )); + disableAllButtons(this, /* showBusyStateOverlay= */ true); } /** @protected */ onRebootButtonClicked_() { this.shimlessRmaService_.criticalErrorReboot(); - this.dispatchEvent(new CustomEvent( - 'disable-all-buttons', - {bubbles: true, composed: true, detail: true}, - )); + disableAllButtons(this, /* showBusyStateOverlay= */ true); } }
diff --git a/ash/webui/shimless_rma/resources/mojo_interface_provider.js b/ash/webui/shimless_rma/resources/mojo_interface_provider.js index 07a6fe4..beda46e 100644 --- a/ash/webui/shimless_rma/resources/mojo_interface_provider.js +++ b/ash/webui/shimless_rma/resources/mojo_interface_provider.js
@@ -48,7 +48,7 @@ service.setGetCurrentOsVersionResult(fakeChromeVersion[0]); service.setCheckForOsUpdatesResult('99.0.4844.74'); - service.setUpdateOsResult(false); + service.setUpdateOsResult(true); service.automaticallyTriggerOsUpdateObservation(); service.setGetComponentListResult(fakeComponents);
diff --git a/ash/webui/shimless_rma/resources/onboarding_update_page.js b/ash/webui/shimless_rma/resources/onboarding_update_page.js index adc0df7..1fc815cf 100644 --- a/ash/webui/shimless_rma/resources/onboarding_update_page.js +++ b/ash/webui/shimless_rma/resources/onboarding_update_page.js
@@ -16,7 +16,7 @@ import {getShimlessRmaService} from './mojo_interface_provider.js'; import {HardwareVerificationStatusObserverInterface, HardwareVerificationStatusObserverReceiver, OsUpdateObserverInterface, OsUpdateObserverReceiver, OsUpdateOperation, ShimlessRmaServiceInterface, StateResult} from './shimless_rma_types.js'; -import {enableNextButton} from './shimless_rma_util.js'; +import {disableAllButtons, enableAllButtons, enableNextButton} from './shimless_rma_util.js'; /** * @fileoverview @@ -250,11 +250,11 @@ /** @private */ onUpdateInProgressChange_() { - const shouldDisableAllButtons = this.updateInProgress_; - this.dispatchEvent(new CustomEvent( - 'disable-all-buttons', - {bubbles: true, composed: true, detail: shouldDisableAllButtons}, - )); + if (this.updateInProgress_) { + disableAllButtons(this, /*showBusyStateOverlay=*/ false); + } else { + enableAllButtons(this); + } } }
diff --git a/ash/webui/shimless_rma/resources/shimless_rma.html b/ash/webui/shimless_rma/resources/shimless_rma.html index 4d0cd3b..6693b3ca 100644 --- a/ash/webui/shimless_rma/resources/shimless_rma.html +++ b/ash/webui/shimless_rma/resources/shimless_rma.html
@@ -69,7 +69,7 @@ z-index: 1; } - :host([all-buttons-disabled_]) #busyStateOverlay { + :host([show-busy-state-overlay_]) #busyStateOverlay { display: block; } </style>
diff --git a/ash/webui/shimless_rma/resources/shimless_rma.js b/ash/webui/shimless_rma/resources/shimless_rma.js index 568c59d..7887dab 100644 --- a/ash/webui/shimless_rma/resources/shimless_rma.js +++ b/ash/webui/shimless_rma/resources/shimless_rma.js
@@ -279,6 +279,16 @@ }, /** + * Show busy state overlay while waiting for the service response. + * @protected + */ + showBusyStateOverlay_: { + type: Boolean, + value: false, + reflectToAttribute: true, + }, + + /** * After the next button is clicked, true until the next state is * processed. * @protected @@ -331,12 +341,8 @@ * @private {?Function} */ this.transitionState_ = (e) => { - // If already in a busy state, ignore requests. - if (this.allButtonsDisabled_) { - return; - } - - this.setAllButtonsDisabled_(/*disabled=*/ true); + this.setAllButtonsState_( + /* shouldDisableButtons= */ true, /* showBusyStateOverlay= */ true); e.detail().then((stateResult) => this.processStateResult_(stateResult)); }; @@ -353,12 +359,29 @@ }; /** - * The disableAllButtons callback is used by page elements to control the - * disabled state of all buttons. + * The enableAllButtons callback is used by page elements to enable all + * buttons. + * @private {?Function} + */ + this.enableAllButtonsCallback_ = () => { + this.setAllButtonsState_( + /* shouldDisableButtons= */ false, /* showBusyStateOverlay= */ false); + }; + + /** + * The disableAllButtons callback is used by page elements to disable all + * buttons and optionally show a busy overlay. * @private {?Function} */ this.disableAllButtonsCallback_ = (e) => { - this.setAllButtonsDisabled_(e.detail); + const customEvent = + /** + @type {!CustomEvent<{showBusyStateOverlay: boolean}>} + */ + (e); + this.setAllButtonsState_( + /* shouldDisableButtons= */ true, + customEvent.detail.showBusyStateOverlay); }; /** @@ -382,6 +405,8 @@ 'set-next-button-label', this.setNextButtonLabelCallback_); window.addEventListener( 'disable-all-buttons', this.disableAllButtonsCallback_); + window.addEventListener( + 'enable-all-buttons', this.enableAllButtonsCallback_); } /** @override */ @@ -394,6 +419,8 @@ 'set-next-button-label', this.setNextButtonLabelCallback_); window.removeEventListener( 'disable-all-buttons', this.disableAllButtonsCallback_); + window.removeEventListener( + 'enable-all-buttons', this.enableAllButtonsCallback_); } /** @override */ @@ -469,7 +496,8 @@ component = null; } } else if (pageInfo == this.currentPage_) { - this.setAllButtonsDisabled_(/*disabled=*/ false); + this.setAllButtonsState_( + /* shouldDisableButtons= */ false, /* showBusyStateOverlay= */ false); // Make sure all button states are correct. this.notifyPath('currentPage_.buttonNext'); this.notifyPath('currentPage_.buttonBack'); @@ -485,7 +513,8 @@ this.hideAllComponents_(); component.hidden = false; - this.setAllButtonsDisabled_(/*disabled=*/ false); + this.setAllButtonsState_( + /* shouldDisableButtons= */ false, /* showBusyStateOverlay= */ false); } /** @@ -529,10 +558,15 @@ /** * @protected - * @param {boolean} disabled + * @param {boolean} shouldDisableButtons + * @param {boolean} showBusyStateOverlay */ - setAllButtonsDisabled_(disabled) { - this.allButtonsDisabled_ = disabled; + setAllButtonsState_(shouldDisableButtons, showBusyStateOverlay) { + // `showBusyStateOverlay` should only be true when disabling all buttons. + assert(!showBusyStateOverlay || shouldDisableButtons); + + this.allButtonsDisabled_ = shouldDisableButtons; + this.showBusyStateOverlay_ = showBusyStateOverlay; const component = this.shadowRoot.querySelector(`#${this.currentPage_.componentIs}`); if (!component) { @@ -554,7 +588,8 @@ /** @protected */ onBackButtonClicked_() { this.backButtonClicked_ = true; - this.setAllButtonsDisabled_(/*disabled=*/ true); + this.setAllButtonsState_( + /* shouldDisableButtons= */ true, /* showBusyStateOverlay= */ true); this.shimlessRmaService_.transitionPreviousState().then( (stateResult) => this.processStateResult_(stateResult)); } @@ -571,7 +606,8 @@ 'onNextButtonClick not a function for ' + this.currentPage_.componentIs); this.nextButtonClicked_ = true; - this.setAllButtonsDisabled_(/*disabled=*/ true); + this.setAllButtonsState_( + /* shouldDisableButtons= */ true, /* showBusyStateOverlay= */ true); page.onNextButtonClick() .then((stateResult) => { this.processStateResult_(stateResult); @@ -579,14 +615,17 @@ // TODO(gavindodd): Better error handling. .catch((err) => { this.nextButtonClicked_ = false; - this.setAllButtonsDisabled_(/*disabled=*/ false); + this.setAllButtonsState_( + /* shouldDisableButtons= */ false, + /* showBusyStateOverlay= */ false); }); } /** @protected */ onCancelButtonClicked_() { this.cancelButtonClicked_ = true; - this.setAllButtonsDisabled_(/*disabled=*/ false); + this.setAllButtonsState_( + /* shouldDisableButtons= */ true, /* showBusyStateOverlay= */ true); this.shimlessRmaService_.abortRma().then((result) => { this.cancelButtonClicked_ = false; this.handleStandardAndCriticalError_(result.error);
diff --git a/ash/webui/shimless_rma/resources/shimless_rma_util.js b/ash/webui/shimless_rma/resources/shimless_rma_util.js index 53c22e2..dc47949 100644 --- a/ash/webui/shimless_rma/resources/shimless_rma_util.js +++ b/ash/webui/shimless_rma/resources/shimless_rma_util.js
@@ -23,3 +23,29 @@ {bubbles: true, composed: true, detail: false}, )); } + +/** + * Disables all inputs on the page. + * @param {!HTMLElement} element + * @param {boolean} showBusyStateOverlay + */ +export function disableAllButtons(element, showBusyStateOverlay) { + element.dispatchEvent(new CustomEvent( + 'disable-all-buttons', + {bubbles: true, composed: true, detail: {showBusyStateOverlay}}, + )); +} + +/** + * Enables all inputs on the page. + * @param {!HTMLElement} element + */ +export function enableAllButtons(element) { + element.dispatchEvent(new CustomEvent( + 'enable-all-buttons', + { + bubbles: true, + composed: true, + }, + )); +}
diff --git a/base/allocator/partition_allocator/partition_alloc_constants.h b/base/allocator/partition_allocator/partition_alloc_constants.h index e0c871d..d8eb68f 100644 --- a/base/allocator/partition_allocator/partition_alloc_constants.h +++ b/base/allocator/partition_allocator/partition_alloc_constants.h
@@ -151,6 +151,7 @@ // | Guard page (4 KiB) | // | Metadata page (4 KiB) | // | Guard pages (8 KiB) | +// | TagBitmap | // | *Scan State Bitmap | // | Slot span | // | Slot span | @@ -159,7 +160,9 @@ // | Guard pages (16 KiB) | // +-----------------------+ // -// State Bitmap is inserted for partitions that may have quarantine enabled. +// TagBitmap is only present when +// defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) is true. State Bitmap +// is inserted for partitions that may have quarantine enabled. // // If refcount_at_end_allocation is enabled, RefcountBitmap(4KiB) is inserted // after the Metadata page for BackupRefPtr. The guard pages after the bitmap @@ -353,7 +356,6 @@ // Intentionally set to less than 2GiB to make sure that a 2GiB allocation // fails. This is a security choice in Chrome, to help making size_t vs int bugs // harder to exploit. -// PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t MaxDirectMapped() {
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc index dc1cd262..977dc24 100644 --- a/base/allocator/partition_allocator/partition_alloc_unittest.cc +++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -29,6 +29,7 @@ #include "base/allocator/partition_allocator/partition_page.h" #include "base/allocator/partition_allocator/partition_ref_count.h" #include "base/allocator/partition_allocator/partition_root.h" +#include "base/allocator/partition_allocator/partition_tag_bitmap.h" #include "base/allocator/partition_allocator/reservation_offset_table.h" #include "base/allocator/partition_allocator/tagging.h" #include "base/bits.h" @@ -575,7 +576,9 @@ EXPECT_EQ(kPointerOffset, reinterpret_cast<size_t>(ptr) & PartitionPageOffsetMask()); // Check that the offset appears to include a guard page. - EXPECT_EQ(PartitionPageSize() + kPointerOffset, + EXPECT_EQ(PartitionPageSize() + + partition_alloc::internal::ReservedTagBitmapSize() + + kPointerOffset, reinterpret_cast<size_t>(ptr) & kSuperPageOffsetMask); allocator.root()->Free(ptr); @@ -853,9 +856,11 @@ // super page. TEST_P(PartitionAllocTest, MultiPageAllocs) { size_t num_pages_per_slot_span = GetNumPagesPerSlotSpan(kTestAllocSize); - // 1 super page has 2 guard partition pages. + // 1 super page has 2 guard partition pages and a tag bitmap. size_t num_slot_spans_needed = - (NumPartitionPagesPerSuperPage() - 2) / num_pages_per_slot_span; + (NumPartitionPagesPerSuperPage() - 2 - + partition_alloc::internal::NumPartitionPagesPerTagBitmap()) / + num_pages_per_slot_span; // We need one more slot span in order to cross super page boundary. ++num_slot_spans_needed; @@ -874,8 +879,11 @@ uintptr_t second_super_page_offset = slot_span_start & kSuperPageOffsetMask; EXPECT_FALSE(second_super_page_base == first_super_page_base); - // Check that we allocated a guard page for the second page. - EXPECT_EQ(PartitionPageSize(), second_super_page_offset); + // Check that we allocated a guard page and the reserved tag bitmap for + // the second page. + EXPECT_EQ(PartitionPageSize() + + partition_alloc::internal::ReservedTagBitmapSize(), + second_super_page_offset); } } for (i = 0; i < num_slot_spans_needed; ++i) @@ -1792,9 +1800,11 @@ TEST_P(PartitionAllocTest, MappingCollision) { size_t num_pages_per_slot_span = GetNumPagesPerSlotSpan(kTestAllocSize); // The -2 is because the first and last partition pages in a super page are - // guard pages. + // guard pages. We also discount the partition pages used for the tag bitmap. size_t num_slot_span_needed = - (NumPartitionPagesPerSuperPage() - 2) / num_pages_per_slot_span; + (NumPartitionPagesPerSuperPage() - 2 - + partition_alloc::internal::NumPartitionPagesPerTagBitmap()) / + num_pages_per_slot_span; size_t num_partition_pages_needed = num_slot_span_needed * num_pages_per_slot_span; @@ -1809,8 +1819,11 @@ uintptr_t slot_spart_start = SlotSpan::ToSlotSpanStart(first_super_page_pages[0]); - EXPECT_EQ(PartitionPageSize(), slot_spart_start & kSuperPageOffsetMask); - uintptr_t super_page = slot_spart_start - PartitionPageSize(); + EXPECT_EQ( + PartitionPageSize() + partition_alloc::internal::ReservedTagBitmapSize(), + slot_spart_start & kSuperPageOffsetMask); + uintptr_t super_page = slot_spart_start - PartitionPageSize() - + partition_alloc::internal::ReservedTagBitmapSize(); // Map a single system page either side of the mapping for our allocations, // with the goal of tripping up alignment of the next mapping. uintptr_t map1 = AllocPages( @@ -1831,9 +1844,11 @@ FreePages(map2, PageAllocationGranularity()); super_page = SlotSpan::ToSlotSpanStart(second_super_page_pages[0]); - EXPECT_EQ(PartitionPageSize(), - reinterpret_cast<uintptr_t>(super_page) & kSuperPageOffsetMask); - super_page -= PartitionPageSize(); + EXPECT_EQ( + PartitionPageSize() + partition_alloc::internal::ReservedTagBitmapSize(), + reinterpret_cast<uintptr_t>(super_page) & kSuperPageOffsetMask); + super_page -= + PartitionPageSize() - partition_alloc::internal::ReservedTagBitmapSize(); // Map a single system page either side of the mapping for our allocations, // with the goal of tripping up alignment of the next mapping. map1 = AllocPages(super_page - PageAllocationGranularity(), @@ -4402,6 +4417,74 @@ kMaxFreeableSpans * bucket_size); } +#if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + +// Verifies basic PA support for `MTECheckedPtr`. +TEST_P(PartitionAllocTest, PartitionTagBasic) { + const size_t alloc_size = 64 - kExtraAllocSize; + void* ptr1 = allocator.root()->Alloc(alloc_size, type_name); + void* ptr2 = allocator.root()->Alloc(alloc_size, type_name); + void* ptr3 = allocator.root()->Alloc(alloc_size, type_name); + EXPECT_TRUE(ptr1); + EXPECT_TRUE(ptr2); + EXPECT_TRUE(ptr3); + + auto* slot_span = SlotSpan::FromObject(ptr1); + EXPECT_TRUE(slot_span); + + char* char_ptr1 = reinterpret_cast<char*>(ptr1); + char* char_ptr2 = reinterpret_cast<char*>(ptr2); + char* char_ptr3 = reinterpret_cast<char*>(ptr3); + EXPECT_LT(kTestAllocSize, slot_span->bucket->slot_size); + EXPECT_EQ(char_ptr1 + slot_span->bucket->slot_size, char_ptr2); + EXPECT_EQ(char_ptr2 + slot_span->bucket->slot_size, char_ptr3); + constexpr partition_alloc::PartitionTag kTag1 = + static_cast<partition_alloc::PartitionTag>(0xBADA); + constexpr partition_alloc::PartitionTag kTag2 = + static_cast<partition_alloc::PartitionTag>(0xDB8A); + constexpr partition_alloc::PartitionTag kTag3 = + static_cast<partition_alloc::PartitionTag>(0xA3C4); + + partition_alloc::internal::PartitionTagSetValue( + ptr1, slot_span->bucket->slot_size, kTag1); + partition_alloc::internal::PartitionTagSetValue( + ptr2, slot_span->bucket->slot_size, kTag2); + partition_alloc::internal::PartitionTagSetValue( + ptr3, slot_span->bucket->slot_size, kTag3); + + memset(ptr1, 0, alloc_size); + memset(ptr2, 0, alloc_size); + memset(ptr3, 0, alloc_size); + + EXPECT_EQ(kTag1, partition_alloc::internal::PartitionTagGetValue(ptr1)); + EXPECT_EQ(kTag2, partition_alloc::internal::PartitionTagGetValue(ptr2)); + EXPECT_EQ(kTag3, partition_alloc::internal::PartitionTagGetValue(ptr3)); + + EXPECT_TRUE(!memchr(ptr1, static_cast<uint8_t>(kTag1), alloc_size)); + EXPECT_TRUE(!memchr(ptr2, static_cast<uint8_t>(kTag2), alloc_size)); + + allocator.root()->Free(ptr1); + EXPECT_EQ(kTag2, partition_alloc::internal::PartitionTagGetValue(ptr2)); + + size_t request_size = slot_span->bucket->slot_size - kExtraAllocSize; + void* new_ptr2 = allocator.root()->Realloc(ptr2, request_size, type_name); + EXPECT_EQ(ptr2, new_ptr2); + EXPECT_EQ(kTag3, partition_alloc::internal::PartitionTagGetValue(ptr3)); + + // Add 1B to ensure the object is rellocated to a larger slot. + request_size = slot_span->bucket->slot_size - kExtraAllocSize + 1; + new_ptr2 = allocator.root()->Realloc(ptr2, request_size, type_name); + EXPECT_TRUE(new_ptr2); + EXPECT_NE(ptr2, new_ptr2); + + allocator.root()->Free(new_ptr2); + + EXPECT_EQ(kTag3, partition_alloc::internal::PartitionTagGetValue(ptr3)); + allocator.root()->Free(ptr3); +} + +#endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + #if BUILDFLAG(IS_ANDROID) && BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && \ BUILDFLAG(IS_CHROMECAST) extern "C" {
diff --git a/base/allocator/partition_allocator/partition_bucket.cc b/base/allocator/partition_allocator/partition_bucket.cc index 8b0429a..7e753f8c 100644 --- a/base/allocator/partition_allocator/partition_bucket.cc +++ b/base/allocator/partition_allocator/partition_bucket.cc
@@ -19,6 +19,8 @@ #include "base/allocator/partition_allocator/partition_direct_map_extent.h" #include "base/allocator/partition_allocator/partition_oom.h" #include "base/allocator/partition_allocator/partition_page.h" +#include "base/allocator/partition_allocator/partition_tag.h" +#include "base/allocator/partition_allocator/partition_tag_bitmap.h" #include "base/allocator/partition_allocator/reservation_offset_table.h" #include "base/allocator/partition_allocator/starscan/state_bitmap.h" #include "base/allocator/partition_allocator/tagging.h" @@ -634,6 +636,28 @@ // Double check that we had enough space in the super page for the new slot // span. PA_DCHECK(root->next_partition_page <= root->next_partition_page_end); + +#if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + PA_DCHECK(root->next_tag_bitmap_page); + uintptr_t next_tag_bitmap_page = + base::bits::AlignUp(reinterpret_cast<uintptr_t>( + PartitionTagPointer(root->next_partition_page)), + SystemPageSize()); + if (root->next_tag_bitmap_page < next_tag_bitmap_page) { +#if DCHECK_IS_ON() + uintptr_t super_page = + reinterpret_cast<uintptr_t>(slot_span) & kSuperPageBaseMask; + uintptr_t tag_bitmap = super_page + PartitionPageSize(); + PA_DCHECK(next_tag_bitmap_page <= tag_bitmap + ActualTagBitmapSize()); + PA_DCHECK(next_tag_bitmap_page > tag_bitmap); +#endif + SetSystemPagesAccess(root->next_tag_bitmap_page, + next_tag_bitmap_page - root->next_tag_bitmap_page, + PageAccessibilityConfiguration::kReadWrite); + root->next_tag_bitmap_page = next_tag_bitmap_page; + } +#endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + return slot_span; } @@ -666,7 +690,9 @@ std::memory_order_relaxed); root->next_super_page = super_page + kSuperPageSize; - uintptr_t state_bitmap = super_page + PartitionPageSize(); + // TODO(crbug.com/1307514): Add direct map support. + uintptr_t state_bitmap = super_page + PartitionPageSize() + + (is_direct_mapped() ? 0 : ReservedTagBitmapSize()); PA_DCHECK(SuperPageStateBitmapAddr(super_page) == state_bitmap); const size_t state_bitmap_reservation_size = root->IsQuarantineAllowed() ? ReservedStateBitmapSize() : 0; @@ -745,6 +771,19 @@ payload < SuperPagesEndFromExtent(current_extent)); } +#if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + // `root->next_partition_page` currently points at the start of the + // super page payload. We point `root->next_tag_bitmap_page` to the + // corresponding point in the tag bitmap and let the caller + // (slot span allocation) take care of the rest. + root->next_tag_bitmap_page = + base::bits::AlignDown(reinterpret_cast<uintptr_t>( + PartitionTagPointer(root->next_partition_page)), + SystemPageSize()); + PA_DCHECK(root->next_tag_bitmap_page >= super_page + PartitionPageSize()) + << "tag bitmap can never intrude on metadata partition page"; +#endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + // If PCScan is used, commit the state bitmap. Otherwise, leave it uncommitted // and let PartitionRoot::RegisterScannableRoot() commit it when needed. Make // sure to register the super-page after it has been fully initialized. @@ -841,6 +880,9 @@ return_slot = ::partition_alloc::internal::TagMemoryRangeRandomly(return_slot, size); } +#if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + PartitionTagSetValue(return_slot, size, root->GetNewPartitionTag()); +#endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) // Add all slots that fit within so far committed pages to the free list. PartitionFreelistEntry* prev_entry = nullptr; @@ -851,6 +893,9 @@ next_slot = ::partition_alloc::internal::TagMemoryRangeRandomly(next_slot, size); } +#if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + PartitionTagSetValue(next_slot, size, root->GetNewPartitionTag()); +#endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) auto* entry = PartitionFreelistEntry::EmplaceAndInitNull(next_slot); if (!slot_span->get_freelist_head()) { PA_DCHECK(!prev_entry);
diff --git a/base/allocator/partition_allocator/partition_page.h b/base/allocator/partition_allocator/partition_page.h index 9419fa4c..89f6925b 100644 --- a/base/allocator/partition_allocator/partition_page.h +++ b/base/allocator/partition_allocator/partition_page.h
@@ -11,6 +11,7 @@ #include <limits> #include <utility> +#include "base/allocator/buildflags.h" #include "base/allocator/partition_allocator/address_pool_manager.h" #include "base/allocator/partition_allocator/address_pool_manager_types.h" #include "base/allocator/partition_allocator/partition_address_space.h" @@ -19,6 +20,7 @@ #include "base/allocator/partition_allocator/partition_alloc_forward.h" #include "base/allocator/partition_allocator/partition_bucket.h" #include "base/allocator/partition_allocator/partition_freelist_entry.h" +#include "base/allocator/partition_allocator/partition_tag_bitmap.h" #include "base/allocator/partition_allocator/reservation_offset_table.h" #include "base/allocator/partition_allocator/starscan/state_bitmap.h" #include "base/allocator/partition_allocator/tagging.h" @@ -410,17 +412,27 @@ // caller's responsibility to ensure that the bitmaps even exist. ALWAYS_INLINE uintptr_t SuperPageStateBitmapAddr(uintptr_t super_page) { PA_DCHECK(!(super_page % kSuperPageAlignment)); - return super_page + PartitionPageSize(); + return super_page + PartitionPageSize() + + (IsManagedByNormalBuckets(super_page) ? ReservedTagBitmapSize() : 0); } ALWAYS_INLINE AllocationStateMap* SuperPageStateBitmap(uintptr_t super_page) { return reinterpret_cast<AllocationStateMap*>( SuperPageStateBitmapAddr(super_page)); } +// Returns the address of the tag bitmap of the `super_page`. Caller must ensure +// that bitmap exists. +ALWAYS_INLINE uintptr_t SuperPageTagBitmapAddr(uintptr_t super_page) { + PA_DCHECK(IsReservationStart(super_page)); + // Skip over the guard pages / metadata. + return super_page + PartitionPageSize(); +} + ALWAYS_INLINE uintptr_t SuperPagePayloadBegin(uintptr_t super_page, bool with_quarantine) { PA_DCHECK(!(super_page % kSuperPageAlignment)); return super_page + PartitionPageSize() + + (IsManagedByNormalBuckets(super_page) ? ReservedTagBitmapSize() : 0) + (with_quarantine ? ReservedStateBitmapSize() : 0); }
diff --git a/base/allocator/partition_allocator/partition_root.h b/base/allocator/partition_allocator/partition_root.h index 30f1943..9de186d 100644 --- a/base/allocator/partition_allocator/partition_root.h +++ b/base/allocator/partition_allocator/partition_root.h
@@ -56,6 +56,7 @@ #include "base/allocator/partition_allocator/partition_oom.h" #include "base/allocator/partition_allocator/partition_page.h" #include "base/allocator/partition_allocator/partition_ref_count.h" +#include "base/allocator/partition_allocator/partition_tag.h" #include "base/allocator/partition_allocator/reservation_offset_table.h" #include "base/allocator/partition_allocator/starscan/pcscan.h" #include "base/allocator/partition_allocator/starscan/state_bitmap.h" @@ -333,6 +334,12 @@ bool quarantine_always_for_testing = false; +#if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + partition_alloc::PartitionTag current_partition_tag = 0; + // Points to the end of the committed tag bitmap region. + uintptr_t next_tag_bitmap_page = 0; +#endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + PartitionRoot() : quarantine_mode(QuarantineMode::kAlwaysDisabled), scan_mode(ScanMode::kDisabled) {} @@ -716,6 +723,17 @@ max_empty_slot_spans_dirty_bytes_shift = 0; } +#if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + ALWAYS_INLINE partition_alloc::PartitionTag GetNewPartitionTag() { + // TODO(crbug.com/1298696): performance is not an issue. We can use + // random tags in lieu of sequential ones. + auto tag = ++current_partition_tag; + tag += !tag; // Avoid 0. + current_partition_tag = tag; + return tag; + } +#endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + private: // |buckets| has `kNumBuckets` elements, but we sometimes access it at index // `kNumBuckets`, which is occupied by the sentinel bucket. The correct layout @@ -1119,6 +1137,15 @@ PA_PREFETCH(slot_span); #endif // defined(PA_HAS_MEMORY_TAGGING) +#if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + if (!root->IsDirectMappedBucket(slot_span->bucket)) { + size_t slot_size_less_extras = + root->AdjustSizeForExtrasSubtract(slot_span->bucket->slot_size); + partition_alloc::internal::PartitionTagIncrementValue( + object, slot_size_less_extras); + } +#endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + // TODO(bikineev): Change the condition to LIKELY once PCScan is enabled by // default. if (UNLIKELY(root->ShouldQuarantine(object))) {
diff --git a/base/allocator/partition_allocator/partition_tag.h b/base/allocator/partition_allocator/partition_tag.h index 25dde0d5..939defe 100644 --- a/base/allocator/partition_allocator/partition_tag.h +++ b/base/allocator/partition_allocator/partition_tag.h
@@ -14,11 +14,14 @@ #include "base/allocator/partition_allocator/partition_alloc_constants.h" #include "base/allocator/partition_allocator/partition_alloc_notreached.h" #include "base/allocator/partition_allocator/partition_cookie.h" +#include "base/allocator/partition_allocator/partition_page.h" #include "base/allocator/partition_allocator/partition_tag_bitmap.h" +#include "base/allocator/partition_allocator/reservation_offset_table.h" +#include "base/allocator/partition_allocator/tagging.h" #include "base/base_export.h" #include "build/build_config.h" -namespace partition_alloc::internal { +namespace partition_alloc { #if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) @@ -27,35 +30,40 @@ using PartitionTag = uint8_t; static_assert( - sizeof(PartitionTag) == tag_bitmap::kPartitionTagSize, + sizeof(PartitionTag) == internal::tag_bitmap::kPartitionTagSize, "sizeof(PartitionTag) must be equal to bitmap::kPartitionTagSize."); -static constexpr size_t kInSlotTagBufferSize = 0; +ALWAYS_INLINE PartitionTag* PartitionTagPointer(uintptr_t addr) { + // TODO(crbug.com/1307514): Add direct map support. For now, just assume + // that direct maps don't have tags. + PA_DCHECK(internal::IsManagedByNormalBuckets(addr)); -ALWAYS_INLINE PartitionTag* PartitionTagPointer(void* ptr) { - // See the comment explaining the layout in partition_tag_bitmap.h. - uintptr_t pointer_as_uintptr = reinterpret_cast<uintptr_t>(ptr); uintptr_t bitmap_base = - (pointer_as_uintptr & kSuperPageBaseMask) + PartitionPageSize(); - uintptr_t offset = - (pointer_as_uintptr & kSuperPageOffsetMask) - PartitionPageSize(); - // Not to depend on partition_address_space.h and PartitionAllocGigaCage - // feature, use "offset" to see whether the given ptr is_direct_mapped or not. - // DirectMap object should cause this PA_DCHECK's failure, as tags aren't - // currently supported there. - PA_DCHECK(offset >= ReservedTagBitmapSize()); - size_t bitmap_offset = (offset - ReservedTagBitmapSize()) >> - tag_bitmap::kBytesPerPartitionTagShift - << tag_bitmap::kPartitionTagSizeShift; - return reinterpret_cast<PartitionTag* const>(bitmap_base + bitmap_offset); + internal::SuperPageTagBitmapAddr(addr & internal::kSuperPageBaseMask); + const size_t bitmap_end_offset = + internal::PartitionPageSize() + internal::ReservedTagBitmapSize(); + PA_DCHECK((addr & internal::kSuperPageOffsetMask) >= bitmap_end_offset); + uintptr_t offset_in_super_page = + (addr & internal::kSuperPageOffsetMask) - bitmap_end_offset; + size_t offset_in_bitmap = offset_in_super_page >> + internal::tag_bitmap::kBytesPerPartitionTagShift + << internal::tag_bitmap::kPartitionTagSizeShift; + return reinterpret_cast<PartitionTag*>(bitmap_base + offset_in_bitmap); } -ALWAYS_INLINE void PartitionTagSetValue(void* ptr, +ALWAYS_INLINE PartitionTag* PartitionTagPointer(const void* ptr) { + return PartitionTagPointer( + internal::UnmaskPtr(reinterpret_cast<uintptr_t>(ptr))); +} + +namespace internal { + +ALWAYS_INLINE void PartitionTagSetValue(uintptr_t addr, size_t size, PartitionTag value) { PA_DCHECK((size % tag_bitmap::kBytesPerPartitionTag) == 0); size_t tag_count = size >> tag_bitmap::kBytesPerPartitionTagShift; - PartitionTag* tag_ptr = PartitionTagPointer(ptr); + PartitionTag* tag_ptr = PartitionTagPointer(addr); if (sizeof(PartitionTag) == 1) { memset(tag_ptr, value, tag_count); } else { @@ -64,6 +72,12 @@ } } +ALWAYS_INLINE void PartitionTagSetValue(void* ptr, + size_t size, + PartitionTag value) { + PartitionTagSetValue(reinterpret_cast<uintptr_t>(ptr), size, value); +} + ALWAYS_INLINE PartitionTag PartitionTagGetValue(void* ptr) { return *PartitionTagPointer(ptr); } @@ -93,17 +107,19 @@ PartitionTagSetValue(ptr, size, new_tag); } +} // namespace internal + #else // No-op versions using PartitionTag = uint8_t; -static constexpr size_t kInSlotTagBufferSize = 0; - ALWAYS_INLINE PartitionTag* PartitionTagPointer(void* ptr) { PA_NOTREACHED(); return nullptr; } +namespace internal { + ALWAYS_INLINE void PartitionTagSetValue(void*, size_t, PartitionTag) {} ALWAYS_INLINE PartitionTag PartitionTagGetValue(void*) { @@ -114,11 +130,10 @@ ALWAYS_INLINE void PartitionTagIncrementValue(void* ptr, size_t size) {} +} // namespace internal + #endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) -constexpr size_t kPartitionTagSizeAdjustment = kInSlotTagBufferSize; -constexpr size_t kPartitionTagOffsetAdjustment = kInSlotTagBufferSize; - -} // namespace partition_alloc::internal +} // namespace partition_alloc #endif // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_TAG_H_
diff --git a/base/memory/raw_ptr.h b/base/memory/raw_ptr.h index 0da2923..80ab0a7f6 100644 --- a/base/memory/raw_ptr.h +++ b/base/memory/raw_ptr.h
@@ -14,6 +14,7 @@ #include <utility> #include "base/allocator/buildflags.h" +#include "base/allocator/partition_allocator/partition_alloc_config.h" #include "base/check.h" #include "base/compiler_specific.h" #include "base/dcheck_is_on.h" @@ -21,15 +22,21 @@ #include "build/build_config.h" #include "build/buildflag.h" -#if BUILDFLAG(USE_BACKUP_REF_PTR) +#if BUILDFLAG(USE_BACKUP_REF_PTR) || \ + defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) // USE_BACKUP_REF_PTR implies USE_PARTITION_ALLOC, needed for code under // allocator/partition_allocator/ to be built. #include "base/allocator/partition_allocator/address_pool_manager_bitmap.h" #include "base/allocator/partition_allocator/partition_address_space.h" -#include "base/allocator/partition_allocator/partition_alloc_config.h" #include "base/allocator/partition_allocator/partition_alloc_constants.h" #include "base/base_export.h" -#endif // BUILDFLAG(USE_BACKUP_REF_PTR) +#endif // BUILDFLAG(USE_BACKUP_REF_PTR) || + // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + +#if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) +#include "base/allocator/partition_allocator/partition_tag.h" +#include "base/allocator/partition_allocator/tagging.h" +#endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) #if BUILDFLAG(IS_WIN) #include "base/win/windows_types.h" @@ -128,6 +135,164 @@ IncrementPointerToMemberOperatorCountForTest() {} }; +#if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + +constexpr int kValidAddressBits = 48; +constexpr uintptr_t kAddressMask = (1ull << kValidAddressBits) - 1; +constexpr int kTagBits = sizeof(uintptr_t) * 8 - kValidAddressBits; +constexpr uintptr_t kTagMask = ~kAddressMask; +constexpr int kTopBitShift = 63; +constexpr uintptr_t kTopBit = 1ull << kTopBitShift; +static_assert(kTopBit << 1 == 0, "kTopBit should really be the top bit"); +static_assert((kTopBit & kTagMask) > 0, + "kTopBit bit must be inside the tag region"); + +// This functionality is outside of MTECheckedPtrImpl, so that it can be +// overridden by tests. +struct MTECheckedPtrImplPartitionAllocSupport { + // Checks if the necessary support is enabled in PartitionAlloc for `ptr`. + template <typename T> + static ALWAYS_INLINE bool EnabledForPtr(T* ptr) { + auto as_uintptr = + partition_alloc::internal::UnmaskPtr(reinterpret_cast<uintptr_t>(ptr)); + // MTECheckedPtr algorithms work only when memory is + // allocated by PartitionAlloc, from normal buckets pool. + // + // TODO(crbug.com/1307514): Allow direct-map buckets. + return IsManagedByPartitionAlloc(as_uintptr) && + IsManagedByNormalBuckets(as_uintptr); + } + + // Returns pointer to the tag that protects are pointed by |ptr|. + static ALWAYS_INLINE void* TagPointer(uintptr_t ptr) { + return partition_alloc::PartitionTagPointer(ptr); + } +}; + +template <typename PartitionAllocSupport> +struct MTECheckedPtrImpl { + // This implementation assumes that pointers are 64 bits long and at least 16 + // top bits are unused. The latter is harder to verify statically, but this is + // true for all currently supported 64-bit architectures (DCHECK when wrapping + // will verify that). + static_assert(sizeof(void*) >= 8, "Need 64-bit pointers"); + + // Wraps a pointer, and returns its uintptr_t representation. + template <typename T> + static RAW_PTR_FUNC_ATTRIBUTES T* WrapRawPtr(T* ptr) { + uintptr_t addr = reinterpret_cast<uintptr_t>(ptr); + DCHECK_EQ(ExtractTag(addr), 0ull); + + // Return a not-wrapped |addr|, if it's either nullptr or if the protection + // for this pointer is disabled. + if (!PartitionAllocSupport::EnabledForPtr(ptr)) { + return reinterpret_cast<T*>(addr); + } + + // Read the tag and place it in the top bits of the address. + // Even if PartitionAlloc's tag has less than kTagBits, we'll read + // what's given and pad the rest with 0s. + static_assert(sizeof(partition_alloc::PartitionTag) * 8 <= kTagBits, ""); + uintptr_t tag = *(static_cast<volatile partition_alloc::PartitionTag*>( + PartitionAllocSupport::TagPointer(addr))); + + tag <<= kValidAddressBits; + addr |= tag; + return reinterpret_cast<T*>(addr); + } + + // Notifies the allocator when a wrapped pointer is being removed or replaced. + // No-op for MTECheckedPtrImpl. + template <typename T> + static RAW_PTR_FUNC_ATTRIBUTES void ReleaseWrappedPtr(T*) {} + + // Unwraps the pointer's uintptr_t representation, while asserting that memory + // hasn't been freed. The function is allowed to crash on nullptr. + template <typename T> + static RAW_PTR_FUNC_ATTRIBUTES T* SafelyUnwrapPtrForDereference( + T* wrapped_ptr) { + uintptr_t wrapped_addr = reinterpret_cast<uintptr_t>(wrapped_ptr); + uintptr_t tag = wrapped_addr >> kValidAddressBits; + if (tag > 0) { + // Read the tag provided by PartitionAlloc. + // + // Cast to volatile to ensure memory is read. E.g. in a tight loop, the + // compiler could cache the value in a register and thus could miss that + // another thread freed memory and changed tag. + uintptr_t read_tag = + *static_cast<volatile partition_alloc::PartitionTag*>( + PartitionAllocSupport::TagPointer(ExtractAddress(wrapped_addr))); + if (UNLIKELY(tag != read_tag)) + IMMEDIATE_CRASH(); + return reinterpret_cast<T*>(wrapped_addr & kAddressMask); + } + return wrapped_ptr; + } + + // Unwraps the pointer's uintptr_t representation, while asserting that memory + // hasn't been freed. The function must handle nullptr gracefully. + template <typename T> + static RAW_PTR_FUNC_ATTRIBUTES T* SafelyUnwrapPtrForExtraction( + T* wrapped_ptr) { + // SafelyUnwrapPtrForDereference handles nullptr case well. + return SafelyUnwrapPtrForDereference(wrapped_ptr); + } + + // Unwraps the pointer's uintptr_t representation, without making an assertion + // on whether memory was freed or not. + template <typename T> + static RAW_PTR_FUNC_ATTRIBUTES T* UnsafelyUnwrapPtrForComparison( + T* wrapped_ptr) { + return ExtractPtr(wrapped_ptr); + } + + // Upcasts the wrapped pointer. + template <typename To, typename From> + static RAW_PTR_FUNC_ATTRIBUTES constexpr To* Upcast(From* wrapped_ptr) { + static_assert(std::is_convertible<From*, To*>::value, + "From must be convertible to To."); + + // The top-bit tag must not affect the result of upcast. + return static_cast<To*>(wrapped_ptr); + } + + // Advance the wrapped pointer by |delta| bytes. + template <typename T> + static RAW_PTR_FUNC_ATTRIBUTES T* Advance(T* wrapped_ptr, + ptrdiff_t delta_elem) { + return wrapped_ptr + delta_elem; + } + + // Returns a copy of a wrapped pointer, without making an assertion + // on whether memory was freed or not. + template <typename T> + static RAW_PTR_FUNC_ATTRIBUTES T* Duplicate(T* wrapped_ptr) { + return wrapped_ptr; + } + + // This is for accounting only, used by unit tests. + static RAW_PTR_FUNC_ATTRIBUTES void IncrementSwapCountForTest() {} + static RAW_PTR_FUNC_ATTRIBUTES void + IncrementPointerToMemberOperatorCountForTest() {} + + private: + static ALWAYS_INLINE uintptr_t ExtractAddress(uintptr_t wrapped_ptr) { + return wrapped_ptr & kAddressMask; + } + + template <typename T> + static ALWAYS_INLINE T* ExtractPtr(T* wrapped_ptr) { + return reinterpret_cast<T*>( + ExtractAddress(reinterpret_cast<uintptr_t>(wrapped_ptr))); + } + + static ALWAYS_INLINE uintptr_t ExtractTag(uintptr_t wrapped_ptr) { + return wrapped_ptr & kTagMask; + } +}; + +#endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + #if BUILDFLAG(USE_BACKUP_REF_PTR) #if DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS) @@ -503,6 +668,11 @@ #elif BUILDFLAG(USE_ASAN_BACKUP_REF_PTR) using RawPtrMayDangle = internal::AsanBackupRefPtrImpl; using RawPtrBanDanglingIfSupported = internal::AsanBackupRefPtrImpl; +#elif defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) +using RawPtrMayDangle = internal::MTECheckedPtrImpl< + internal::MTECheckedPtrImplPartitionAllocSupport>; +using RawPtrBanDanglingIfSupported = internal::MTECheckedPtrImpl< + internal::MTECheckedPtrImplPartitionAllocSupport>; #else using RawPtrMayDangle = internal::RawPtrNoOpImpl; using RawPtrBanDanglingIfSupported = internal::RawPtrNoOpImpl;
diff --git a/base/memory/raw_ptr_unittest.cc b/base/memory/raw_ptr_unittest.cc index 4965ae68..cf79fa1 100644 --- a/base/memory/raw_ptr_unittest.cc +++ b/base/memory/raw_ptr_unittest.cc
@@ -14,6 +14,7 @@ #include "base/allocator/partition_alloc_support.h" #include "base/allocator/partition_allocator/dangling_raw_ptr_checks.h" #include "base/allocator/partition_allocator/partition_alloc.h" +#include "base/allocator/partition_allocator/partition_alloc_config.h" #include "base/logging.h" #include "build/build_config.h" #include "build/buildflag.h" @@ -24,6 +25,10 @@ #include "third_party/perfetto/include/perfetto/test/traced_value_test_support.h" // no-presubmit-check nogncheck #endif // BUILDFLAG(ENABLE_BASE_TRACING) +#if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) +#include "base/allocator/partition_allocator/partition_tag.h" +#endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + using testing::AllOf; using testing::HasSubstr; using testing::Test; @@ -1387,5 +1392,140 @@ } #endif +#if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + +static constexpr size_t kTagOffsetForTest = 2; + +struct MTECheckedPtrImplPartitionAllocSupportForTest { + static bool EnabledForPtr(void* ptr) { return !!ptr; } + + static ALWAYS_INLINE void* TagPointer(uintptr_t ptr) { + return reinterpret_cast<void*>(ptr - kTagOffsetForTest); + } +}; + +using MTECheckedPtrImplForTest = + MTECheckedPtrImpl<MTECheckedPtrImplPartitionAllocSupportForTest>; + +TEST(MTECheckedPtrImpl, WrapAndSafelyUnwrap) { + // Create a fake allocation, with first 2B for tag. + // It is ok to use a fake allocation, instead of PartitionAlloc, because + // MTECheckedPtrImplForTest fakes the functionality is enabled for this + // pointer and points to the tag appropriately. + unsigned char bytes[] = {0xBA, 0x42, 0x78, 0x89}; + void* ptr = bytes + kTagOffsetForTest; + ASSERT_EQ(0x78, *static_cast<char*>(ptr)); + uintptr_t addr = reinterpret_cast<uintptr_t>(ptr); + + uintptr_t mask = 0xFFFFFFFFFFFFFFFF; + if (sizeof(partition_alloc::PartitionTag) < 2) + mask = 0x00FFFFFFFFFFFFFF; + + uintptr_t wrapped = + reinterpret_cast<uintptr_t>(MTECheckedPtrImplForTest::WrapRawPtr(ptr)); + // The bytes before the allocation will be used as tag (in reverse + // order due to little-endianness). + ASSERT_EQ(wrapped, (addr | 0x42BA000000000000) & mask); + ASSERT_EQ(MTECheckedPtrImplForTest::SafelyUnwrapPtrForDereference( + reinterpret_cast<void*>(wrapped)), + ptr); + + // Modify the tag in the fake allocation. + bytes[0] |= 0x40; + wrapped = + reinterpret_cast<uintptr_t>(MTECheckedPtrImplForTest::WrapRawPtr(ptr)); + ASSERT_EQ(wrapped, (addr | 0x42FA000000000000) & mask); + ASSERT_EQ(MTECheckedPtrImplForTest::SafelyUnwrapPtrForDereference( + reinterpret_cast<void*>(wrapped)), + ptr); +} + +TEST(MTECheckedPtrImpl, SafelyUnwrapDisabled) { + // Create a fake allocation, with first 2B for tag. + // It is ok to use a fake allocation, instead of PartitionAlloc, because + // MTECheckedPtrImplForTest fakes the functionality is enabled for this + // pointer and points to the tag appropriately. + unsigned char bytes[] = {0xBA, 0x42, 0x78, 0x89}; + unsigned char* ptr = bytes + kTagOffsetForTest; + ASSERT_EQ(0x78, *ptr); + ASSERT_EQ(MTECheckedPtrImplForTest::SafelyUnwrapPtrForDereference(ptr), ptr); +} + +TEST(MTECheckedPtrImpl, CrashOnTagMismatch) { + // Create a fake allocation, using the first two bytes for the tag. + // It is ok to use a fake allocation, instead of PartitionAlloc, because + // MTECheckedPtrImplForTest fakes the functionality is enabled for this + // pointer and points to the tag appropriately. + unsigned char bytes[] = {0xBA, 0x42, 0x78, 0x89}; + unsigned char* ptr = + MTECheckedPtrImplForTest::WrapRawPtr(bytes + kTagOffsetForTest); + EXPECT_EQ(*MTECheckedPtrImplForTest::SafelyUnwrapPtrForDereference(ptr), + 0x78); + // Clobber the tag associated with the fake allocation. + bytes[0] = 0; + EXPECT_DEATH_IF_SUPPORTED( + if (*MTECheckedPtrImplForTest::SafelyUnwrapPtrForDereference(ptr) == + 0x78) return, + ""); +} + +#if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) && \ + BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) + +// This test works only when PartitionAlloc is used, when tags are enabled. +// Don't enable it when MEMORY_TOOL_REPLACES_ALLOCATOR is defined, because it +// makes PartitionAlloc take a different path that doesn't provide tags, thus no +// crash on UaF, thus missing the EXPECT_DEATH_IF_SUPPORTED expectation. +TEST(MTECheckedPtrImpl, CrashOnUseAfterFree) { + int* unwrapped_ptr = new int; + // Use the actual CheckedPtr implementation, not a test substitute, to + // exercise real PartitionAlloc paths. + raw_ptr<int> ptr = unwrapped_ptr; + *ptr = 42; + EXPECT_EQ(*ptr, 42); + delete unwrapped_ptr; + EXPECT_DEATH_IF_SUPPORTED(if (*ptr == 42) return, ""); +} + +TEST(MTECheckedPtrImpl, CrashOnUseAfterFree_WithOffset) { + const uint8_t kSize = 100; + uint8_t* unwrapped_ptr = new uint8_t[kSize]; + // Use the actual CheckedPtr implementation, not a test substitute, to + // exercise real PartitionAlloc paths. + raw_ptr<uint8_t> ptrs[kSize]; + for (uint8_t i = 0; i < kSize; ++i) { + ptrs[i] = static_cast<uint8_t*>(unwrapped_ptr) + i; + } + for (uint8_t i = 0; i < kSize; ++i) { + *ptrs[i] = 42 + i; + EXPECT_TRUE(*ptrs[i] == 42 + i); + } + delete[] unwrapped_ptr; + for (uint8_t i = 0; i < kSize; i += 15) { + EXPECT_DEATH_IF_SUPPORTED(if (*ptrs[i] == 42 + i) return, ""); + } +} + +TEST(MTECheckedPtrImpl, AdvancedPointerShiftedAppropriately) { + uint64_t* unwrapped_ptr = new uint64_t[6]; + raw_ptr<uint64_t> ptr = unwrapped_ptr; + + // This is unwrapped, but still useful for ensuring that the + // shift is sized in `uint64_t`s. + auto original_addr = reinterpret_cast<uintptr_t>(ptr.get()); + + ptr += 5; + EXPECT_EQ(reinterpret_cast<uintptr_t>(ptr.get()) - original_addr, + 5 * sizeof(uint64_t)); + delete[] unwrapped_ptr; + + EXPECT_DEATH_IF_SUPPORTED(*ptr, ""); +} + +#endif // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) && + // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) + +#endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) + } // namespace internal } // namespace base
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py index 7f2a86e..2744840d 100755 --- a/build/android/gyp/write_build_config.py +++ b/build/android/gyp/write_build_config.py
@@ -243,11 +243,7 @@ * `deps_info['public_deps_configs']`: List of paths to the `.build_config` files of *direct* dependencies of the current target which are exposed as part of the -current target's public API. This should be a subset of -deps_info['deps_configs']. - -* `deps_info['ignore_dependency_public_deps']`: If true, 'public_deps' will not -be collected from the current target's direct deps. +current target's public API. * `deps_info['unprocessed_jar_path']`: Path to the original .jar file for this target, before any kind of processing @@ -567,8 +563,6 @@ --------------- END_MARKDOWN --------------------------------------------------- """ -from __future__ import print_function - import collections import itertools import json @@ -1009,11 +1003,6 @@ parser.add_option('--public-deps-configs', help='GN list of config files of deps which are exposed as ' 'part of the target\'s public API.') - parser.add_option( - '--ignore-dependency-public-deps', - action='store_true', - help='If true, \'public_deps\' will not be collected from the current ' - 'target\'s direct deps.') parser.add_option('--aar-path', help='Path to containing .aar file.') parser.add_option('--device-jar-path', help='Path to .jar for dexing.') parser.add_option('--host-jar-path', help='Path to .jar for java_binary.') @@ -1613,13 +1602,9 @@ if is_java_target: - if options.ignore_dependency_public_deps: - classpath_direct_deps = deps.Direct() - classpath_direct_library_deps = deps.Direct('java_library') - else: - classpath_direct_deps = deps.DirectAndChildPublicDeps() - classpath_direct_library_deps = deps.DirectAndChildPublicDeps( - 'java_library') + classpath_direct_deps = deps.DirectAndChildPublicDeps() + classpath_direct_library_deps = deps.DirectAndChildPublicDeps( + 'java_library') # The classpath used to compile this target when annotation processors are # present.
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 9acbbcb..b38e998 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -186,11 +186,6 @@ _target_label, ] - if (defined(invoker.ignore_dependency_public_deps) && - invoker.ignore_dependency_public_deps) { - args += [ "--ignore-dependency-public-deps" ] - } - if (defined(invoker.aar_path)) { args += [ "--aar-path",
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index c9ffb547..191998b 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -1581,7 +1581,6 @@ requires_android = defined(invoker.requires_android) && invoker.requires_android possible_config_deps = _deps - ignore_dependency_public_deps = _direct_deps_only build_config = _build_config } @@ -1760,7 +1759,6 @@ possible_config_deps = _deps supports_android = true requires_android = true - ignore_dependency_public_deps = _direct_deps_only build_config = _build_config }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 0becd54d..0aa5b35 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1552,6 +1552,11 @@ if (enable_wmax_tokens) { cflags += [ "-Wmax-tokens" ] } + + if (llvm_force_head_revision) { + # TODO(https://crbug.com/1309955) Clean up and enable. + cflags += [ "-Wno-unused-but-set-variable" ] + } } } }
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index ff9bbd1..3aba158d 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -301,6 +301,7 @@ "//chrome/browser/feed/android:hooks_public_impl_java", "//chrome/browser/lens:delegate_public_impl_java", "//chrome/browser/locale:delegate_public_impl_java", + "//chrome/browser/partnerbookmarks:delegate_public_impl_java", "//chrome/browser/partnercustomizations:delegate_public_impl_java", "//chrome/browser/password_manager/android:backend_interface_public_impl_java", "//chrome/browser/password_manager/android:settings_interface_public_impl_java", @@ -397,6 +398,7 @@ "//chrome/browser/optimization_guide/android:java", "//chrome/browser/page_annotations/android:java", "//chrome/browser/paint_preview/android:java", + "//chrome/browser/partnerbookmarks:delegate_java", "//chrome/browser/partnercustomizations:delegate_java", "//chrome/browser/partnercustomizations:java", "//chrome/browser/password_check:public_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java index 127717d..11996086ac 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
@@ -36,6 +36,7 @@ import org.chromium.chrome.browser.download.DownloadManagerBridge.DownloadEnqueueRequest; import org.chromium.chrome.browser.download.DownloadManagerBridge.DownloadEnqueueResponse; import org.chromium.chrome.browser.download.DownloadNotificationUmaHelper.UmaDownloadResumption; +import org.chromium.chrome.browser.download.items.OfflineContentAggregatorFactory; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.incognito.IncognitoUtils; @@ -367,6 +368,8 @@ DownloadManagerService.getDownloadManagerService().checkForExternallyRemovedDownloads( ProfileKey.getLastUsedRegularProfileKey()); + + removeInterstitialDownloadPendingDeletion(); mActivityLaunched = true; } } @@ -433,6 +436,24 @@ } /** + * Remove downloads in the case that Chrome closes before a download interstitial can remove a + * deleted/cancelled download. + */ + private static void removeInterstitialDownloadPendingDeletion() { + String contentIdString = SharedPreferencesManager.getInstance().readString( + ChromePreferenceKeys.DOWNLOAD_INTERSTITIAL_DOWNLOAD_PENDING_REMOVAL, ""); + if (TextUtils.isEmpty(contentIdString)) return; + + String[] contentIdData = contentIdString.split(","); // { namespace, id } + assert contentIdData.length == 2; + + OfflineContentAggregatorFactory.get().removeItem( + new ContentId(contentIdData[0], contentIdData[1])); + SharedPreferencesManager.getInstance().removeKeySync( + ChromePreferenceKeys.DOWNLOAD_INTERSTITIAL_DOWNLOAD_PENDING_REMOVAL); + } + + /** * Updates notifications for a given list of downloads. * @param progresses A list of notifications to update. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java index 9805234..98604bb1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
@@ -605,6 +605,12 @@ } @Override + public void recordNativeAndPoliciesLoadedHistogram() { + RecordHistogram.recordTimesHistogram("MobileFre.FromLaunch.NativeAndPoliciesLoaded", + SystemClock.elapsedRealtime() - mIntentCreationElapsedRealtimeMs); + } + + @Override public void showInfoPage(@StringRes int url) { CustomTabActivity.showInfoPage( this, LocalizationUtils.substituteLocalePlaceholder(getString(url)));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java index b974414..cd40a51 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java
@@ -88,6 +88,9 @@ */ void recordFreProgressHistogram(@MobileFreProgress int state); + /** Records MobileFre.FromLaunch.NativeAndPoliciesLoaded histogram. **/ + void recordNativeAndPoliciesLoadedHistogram(); + /** * The supplier that supplies whether reading policy value is necessary. * See {@link PolicyLoadListener} for details.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/quickactionsearchwidget/QuickActionSearchWidgetProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/quickactionsearchwidget/QuickActionSearchWidgetProvider.java index c1d6193..1712425 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/quickactionsearchwidget/QuickActionSearchWidgetProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/quickactionsearchwidget/QuickActionSearchWidgetProvider.java
@@ -21,6 +21,8 @@ import org.chromium.base.ContextUtils; import org.chromium.base.IntentUtils; import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; +import org.chromium.base.task.TaskTraits; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.browserservices.intents.WebappConstants; import org.chromium.chrome.browser.document.ChromeLauncherActivity; @@ -207,6 +209,13 @@ QuickActionSearchWidgetProvider dinoWidget = new QuickActionSearchWidgetProviderDino(); QuickActionSearchWidgetProvider smallWidget = new QuickActionSearchWidgetProviderSearch(); + PostTask.postTask(TaskTraits.BEST_EFFORT, () -> { + // Make the Widget available to all Chrome users who participated in an experiment in + // the past. This can trigger disk access. Unfortunately, we need to keep it for a + // little bit longer -- see: https://crbug.com/1309116 + setWidgetEnabled(true, true); + }); + SearchActivityPreferencesManager.addObserver(prefs -> { Context context = ContextUtils.getApplicationContext(); if (context == null) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java index 5fb3c4e..2c92570 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java
@@ -230,6 +230,7 @@ && getPageDelegate().getPolicyLoadListener().get() != null) { mSigninFirstRunCoordinator.onNativeAndPolicyLoaded( getPageDelegate().getPolicyLoadListener().get()); + getPageDelegate().recordNativeAndPoliciesLoadedHistogram(); mAllowCrashUpload = !mSigninFirstRunCoordinator.isMetricsReportingDisabledByPolicy(); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java index 67ce1a3..a8931a0e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java
@@ -819,6 +819,7 @@ private void checkFragmentWithSelectedAccount(String email, String fullName, String givenName) { CriteriaHelper.pollUiThread( mFragment.getView().findViewById(R.id.signin_fre_selected_account)::isShown); + verify(mFirstRunPageDelegateMock).recordNativeAndPoliciesLoadedHistogram(); final DisplayableProfileData profileData = new DisplayableProfileData(email, mock(Drawable.class), fullName, givenName); onView(withText(R.string.fre_welcome)).check(matches(isDisplayed())); @@ -868,6 +869,7 @@ private void checkFragmentWithChildAccount() { CriteriaHelper.pollUiThread( mFragment.getView().findViewById(R.id.signin_fre_selected_account)::isShown); + verify(mFirstRunPageDelegateMock).recordNativeAndPoliciesLoadedHistogram(); onView(withText(R.string.fre_welcome)).check(matches(isDisplayed())); onView(withId(R.id.subtitle)).check(matches(not(isDisplayed()))); Assert.assertFalse( @@ -888,6 +890,7 @@ CriteriaHelper.pollUiThread(() -> { return !mFragment.getView().findViewById(R.id.signin_fre_selected_account).isShown(); }); + verify(mFirstRunPageDelegateMock).recordNativeAndPoliciesLoadedHistogram(); onView(withId(R.id.fre_browser_managed_by_organization)).check(matches(isDisplayed())); onView(withText(R.string.continue_button)).check(matches(isDisplayed())); onView(withId(R.id.signin_fre_footer)).check(matches(isDisplayed()));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrDeviceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrDeviceTest.java index c6bc22a..ff19142 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrDeviceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrDeviceTest.java
@@ -19,7 +19,6 @@ import org.chromium.base.test.params.ParameterSet; import org.chromium.base.test.params.ParameterizedRunner; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.vr.rules.XrActivityRestriction; import org.chromium.chrome.browser.vr.util.VrTestRuleUtils; @@ -62,7 +61,6 @@ */ @Test @MediumTest - @DisabledTest(message = "crbug.com/1302610") @CommandLineFlags.Add({"enable-features=WebXR"}) @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) public void testWebXrCapabilities() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrInputTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrInputTest.java index b846a08..3e396293 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrInputTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrInputTest.java
@@ -31,7 +31,6 @@ import org.chromium.base.test.params.ParameterSet; import org.chromium.base.test.params.ParameterizedRunner; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.vr.rules.XrActivityRestriction; @@ -92,7 +91,6 @@ */ @Test @MediumTest - @DisabledTest(message = "https://crbug.com/1300966") @Restriction(RESTRICTION_TYPE_SVR) @CommandLineFlags.Add({"enable-features=WebXR"}) @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) @@ -129,7 +127,6 @@ */ @Test @MediumTest - @DisabledTest(message = "https://crbug.com/1300966") @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM_OR_STANDALONE) @CommandLineFlags.Add({"enable-features=WebXR"}) @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) @@ -163,7 +160,6 @@ */ @Test @MediumTest - @DisabledTest(message = "crbug.com/1302610") @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM_OR_STANDALONE) @CommandLineFlags.Add({"enable-features=WebXR"}) @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) @@ -280,7 +276,6 @@ */ @Test @MediumTest - @DisabledTest(message = "crbug.com/1302610") @Restriction(RESTRICTION_TYPE_VIEWER_NON_DAYDREAM) @CommandLineFlags.Add({"enable-features=WebXR"}) @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) @@ -341,7 +336,6 @@ */ @Test @MediumTest - @DisabledTest(message = "crbug.com/1302610") @CommandLineFlags.Add({"enable-features=WebXR"}) @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) public void testPresentationLocksFocus_WebXr() { @@ -392,7 +386,6 @@ */ @Test @MediumTest - @DisabledTest(message = "https://crbug.com/1300966") @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM_OR_STANDALONE) @CommandLineFlags.Add({"enable-features=WebXR"}) @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) @@ -453,7 +446,6 @@ */ @Test @LargeTest - @DisabledTest(message = "crbug.com/1302610") @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM_OR_STANDALONE) @CommandLineFlags.Add({"enable-features=WebXR"}) @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL})
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTabTest.java index e534545..78e9a82 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTabTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTabTest.java
@@ -24,7 +24,6 @@ import org.chromium.base.test.params.ParameterSet; import org.chromium.base.test.params.ParameterizedRunner; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.flags.ChromeSwitches; @@ -73,7 +72,6 @@ */ @Test @MediumTest - @DisabledTest(message = "crbug.com/1302610") @Restriction(RESTRICTION_TYPE_SVR) @CommandLineFlags.Add({"enable-features=WebXR"}) public void testPoseDataUnfocusedTab_WebXr() { @@ -98,7 +96,6 @@ */ @Test @MediumTest - @DisabledTest(message = "crbug.com/1302610") @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM_OR_STANDALONE) @CommandLineFlags.Add({"enable-features=WebXR"}) public void testPermissionsInOtherTab() throws InterruptedException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTransitionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTransitionTest.java index 48f3874..1e6543e9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTransitionTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTransitionTest.java
@@ -36,7 +36,6 @@ import org.chromium.base.test.params.ParameterizedRunner; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CriteriaHelper; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.FlakyTest; import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.UrlUtils; @@ -161,7 +160,6 @@ @Restriction({RESTRICTION_TYPE_DEVICE_DAYDREAM, RESTRICTION_TYPE_VR_DON_ENABLED}) @CommandLineFlags.Add({"enable-features=WebXR"}) @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) - @DisabledTest(message = "https://crbug.com/1236093") public void testPresentationPromiseUnresolvedDuringDon_WebXr() { presentationPromiseUnresolvedDuringDonImpl( @@ -183,7 +181,6 @@ @Restriction({RESTRICTION_TYPE_DEVICE_DAYDREAM, RESTRICTION_TYPE_VR_DON_ENABLED}) @CommandLineFlags.Add({"enable-features=WebXR"}) @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) - @DisabledTest(message = "https://crbug.com/1246405") public void testPresentationPromiseRejectedIfDonCanceled_WebXr() { presentationPromiseRejectedIfDonCanceledImpl( @@ -246,7 +243,6 @@ */ @Test @MediumTest - @DisabledTest(message = "https://crbug.com/1300966") @CommandLineFlags.Add({"enable-features=WebXR"}) @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) public void testWindowRafStopsFiringWhilePresenting_WebXr() throws InterruptedException { @@ -311,7 +307,6 @@ */ @Test @MediumTest - @DisabledTest(message = "https://crbug.com/1300966") @CommandLineFlags.Add({"enable-features=WebXR"}) @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) public void testNonImmersiveStopsDuringImmersive() {
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 2655e56..de1bcf1 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3552,6 +3552,8 @@ "accessibility/live_caption_controller_factory.h", "accessibility/live_caption_speech_recognition_host.cc", "accessibility/live_caption_speech_recognition_host.h", + "accessibility/live_caption_unavailability_notifier.cc", + "accessibility/live_caption_unavailability_notifier.h", "accuracy_tips/accuracy_service_delegate.cc", "accuracy_tips/accuracy_service_delegate.h", "accuracy_tips/accuracy_service_factory.cc", @@ -5037,6 +5039,10 @@ } } else { # Non - Ash. sources += [ + "enterprise/reporting/cloud_profile_reporting_service.cc", + "enterprise/reporting/cloud_profile_reporting_service.h", + "enterprise/reporting/cloud_profile_reporting_service_factory.cc", + "enterprise/reporting/cloud_profile_reporting_service_factory.h", "fullscreen.h", "policy/browser_signin_policy_handler.cc", "policy/browser_signin_policy_handler.h", @@ -6418,13 +6424,6 @@ "printing/pwg_raster_converter.cc", "printing/pwg_raster_converter.h", ] - - if (is_win) { - sources += [ - "printing/print_dialog_cloud_win.cc", - "printing/print_dialog_cloud_win.h", - ] - } } else { # Partial - only printing support. sources += [
diff --git a/chrome/browser/accessibility/live_caption_controller_browsertest.cc b/chrome/browser/accessibility/live_caption_controller_browsertest.cc index 121db42..6479dbb4 100644 --- a/chrome/browser/accessibility/live_caption_controller_browsertest.cc +++ b/chrome/browser/accessibility/live_caption_controller_browsertest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/callback_forward.h" #include "base/feature_list.h" #include "base/files/file_path.h" #include "base/ranges/ranges.h" @@ -136,7 +137,9 @@ void OnError() { OnErrorOnProfile(browser()->profile()); } void OnErrorOnProfile(Profile* profile) { - GetControllerForProfile(profile)->OnError(GetCaptionBubbleContextBrowser()); + GetControllerForProfile(profile)->OnError(GetCaptionBubbleContextBrowser(), + CaptionBubbleErrorType::GENERIC, + base::RepeatingClosure()); } void OnAudioStreamEnd() { OnAudioStreamEndOnProfile(browser()->profile()); }
diff --git a/chrome/browser/accessibility/live_caption_controller_factory.cc b/chrome/browser/accessibility/live_caption_controller_factory.cc index 760ba16..4f64c63 100644 --- a/chrome/browser/accessibility/live_caption_controller_factory.cc +++ b/chrome/browser/accessibility/live_caption_controller_factory.cc
@@ -49,7 +49,7 @@ content::BrowserContext* context) const { return new LiveCaptionController( Profile::FromBrowserContext(context)->GetPrefs(), - g_browser_process->local_state()); + g_browser_process->local_state(), context); } } // namespace captions
diff --git a/chrome/browser/accessibility/live_caption_speech_recognition_host.cc b/chrome/browser/accessibility/live_caption_speech_recognition_host.cc index daa6352..9e1e4f9 100644 --- a/chrome/browser/accessibility/live_caption_speech_recognition_host.cc +++ b/chrome/browser/accessibility/live_caption_speech_recognition_host.cc
@@ -7,11 +7,13 @@ #include <memory> #include <utility> +#include "base/callback_forward.h" #include "build/build_config.h" #include "chrome/browser/accessibility/caption_bubble_context_browser.h" #include "chrome/browser/accessibility/live_caption_controller_factory.h" #include "chrome/browser/profiles/profile.h" #include "components/live_caption/live_caption_controller.h" +#include "components/live_caption/views/caption_bubble_model.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" @@ -72,7 +74,9 @@ void LiveCaptionSpeechRecognitionHost::OnSpeechRecognitionError() { LiveCaptionController* live_caption_controller = GetLiveCaptionController(); if (live_caption_controller) - live_caption_controller->OnError(context_.get()); + live_caption_controller->OnError(context_.get(), + CaptionBubbleErrorType::GENERIC, + base::RepeatingClosure()); } void LiveCaptionSpeechRecognitionHost::OnSpeechRecognitionStopped() {
diff --git a/chrome/browser/accessibility/live_caption_unavailability_notifier.cc b/chrome/browser/accessibility/live_caption_unavailability_notifier.cc new file mode 100644 index 0000000..04fa09ef --- /dev/null +++ b/chrome/browser/accessibility/live_caption_unavailability_notifier.cc
@@ -0,0 +1,95 @@ +// Copyright 2022 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/accessibility/live_caption_unavailability_notifier.h" + +#include <memory> +#include <utility> + +#include "base/memory/weak_ptr.h" +#include "chrome/browser/accessibility/caption_bubble_context_browser.h" +#include "chrome/browser/accessibility/live_caption_controller_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser_navigator.h" +#include "chrome/browser/ui/browser_navigator_params.h" +#include "components/live_caption/live_caption_controller.h" +#include "components/live_caption/views/caption_bubble.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" + +namespace captions { + +// static +void LiveCaptionUnavailabilityNotifier::Create( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver<media::mojom::MediaFoundationRendererNotifier> + receiver) { + // The object is bound to the lifetime of |frame_host| and the mojo + // connection. See DocumentService for details. + new LiveCaptionUnavailabilityNotifier(frame_host, std::move(receiver)); +} + +LiveCaptionUnavailabilityNotifier::LiveCaptionUnavailabilityNotifier( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver<media::mojom::MediaFoundationRendererNotifier> + receiver) + : DocumentService<media::mojom::MediaFoundationRendererNotifier>( + frame_host, + std::move(receiver)) { + content::WebContents* web_contents = GetWebContents(); + if (!web_contents) + return; + context_ = CaptionBubbleContextBrowser::Create(web_contents); +} + +LiveCaptionUnavailabilityNotifier::~LiveCaptionUnavailabilityNotifier() { + LiveCaptionController* live_caption_controller = GetLiveCaptionController(); + if (live_caption_controller) + live_caption_controller->OnAudioStreamEnd(context_.get()); +} + +void LiveCaptionUnavailabilityNotifier::MediaFoundationRendererCreated() { + LiveCaptionController* live_caption_controller = GetLiveCaptionController(); + if (live_caption_controller) { + // This will trigger the caption bubble to display a message informing the + // user that Live Caption is unavailable and link them to the settings page + // where they can disable the media foundation renderer to enable Live + // Caption. The error message may be overwritten if recognition events are + // received from another audio stream. + live_caption_controller->OnError( + context_.get(), + CaptionBubbleErrorType::MEDIA_FOUNDATION_RENDERER_UNSUPPORTED, + base::BindRepeating(&LiveCaptionUnavailabilityNotifier:: + OnMediaFoundationRendererErrorClicked, + weak_factory_.GetWeakPtr())); + } +} + +content::WebContents* LiveCaptionUnavailabilityNotifier::GetWebContents() { + return content::WebContents::FromRenderFrameHost(render_frame_host()); +} + +LiveCaptionController* +LiveCaptionUnavailabilityNotifier::GetLiveCaptionController() { + Profile* profile = + Profile::FromBrowserContext(render_frame_host()->GetBrowserContext()); + if (!profile) + return nullptr; + + return LiveCaptionControllerFactory::GetForProfile(profile); +} + +void LiveCaptionUnavailabilityNotifier:: + OnMediaFoundationRendererErrorClicked() { + NavigateParams params( + Profile::FromBrowserContext(render_frame_host()->GetBrowserContext()), + GURL("chrome://settings/content/protectedContent"), + ui::PAGE_TRANSITION_LINK); + params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; + Navigate(¶ms); +} + +} // namespace captions
diff --git a/chrome/browser/accessibility/live_caption_unavailability_notifier.h b/chrome/browser/accessibility/live_caption_unavailability_notifier.h new file mode 100644 index 0000000..fc64789c --- /dev/null +++ b/chrome/browser/accessibility/live_caption_unavailability_notifier.h
@@ -0,0 +1,65 @@ +// Copyright 2022 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_ACCESSIBILITY_LIVE_CAPTION_UNAVAILABILITY_NOTIFIER_H_ +#define CHROME_BROWSER_ACCESSIBILITY_LIVE_CAPTION_UNAVAILABILITY_NOTIFIER_H_ + +#include <memory> + +#include "base/memory/weak_ptr.h" +#include "content/public/browser/document_service.h" +#include "content/public/browser/web_contents_observer.h" +#include "media/mojo/mojom/speech_recognition_service.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" + +namespace content { +class RenderFrameHost; +} + +namespace captions { + +class CaptionBubbleContextBrowser; +class LiveCaptionController; + +// Used to notify the browser that the renderer does not support Live Caption. +class LiveCaptionUnavailabilityNotifier + : public content::DocumentService< + media::mojom::MediaFoundationRendererNotifier> { + public: + LiveCaptionUnavailabilityNotifier( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver<media::mojom::MediaFoundationRendererNotifier> + pending_receiver); + LiveCaptionUnavailabilityNotifier(const LiveCaptionUnavailabilityNotifier&) = + delete; + LiveCaptionUnavailabilityNotifier& operator=( + const LiveCaptionUnavailabilityNotifier&) = delete; + ~LiveCaptionUnavailabilityNotifier() override; + + // static + static void Create( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver<media::mojom::MediaFoundationRendererNotifier> + receiver); + + // media::mojom::MediaFoundationRendererNotifier: + void MediaFoundationRendererCreated() override; + + private: + content::WebContents* GetWebContents(); + + // Returns the LiveCaptionController for frame_host_. Returns nullptr if it + // does not exist. + LiveCaptionController* GetLiveCaptionController(); + + void OnMediaFoundationRendererErrorClicked(); + + std::unique_ptr<CaptionBubbleContextBrowser> context_; + + base::WeakPtrFactory<LiveCaptionUnavailabilityNotifier> weak_factory_{this}; +}; + +} // namespace captions + +#endif // CHROME_BROWSER_ACCESSIBILITY_LIVE_CAPTION_UNAVAILABILITY_NOTIFIER_H_
diff --git a/chrome/browser/ash/login/auth/cryptohome_authenticator_unittest.cc b/chrome/browser/ash/login/auth/cryptohome_authenticator_unittest.cc index 9746facc..784069c 100644 --- a/chrome/browser/ash/login/auth/cryptohome_authenticator_unittest.cc +++ b/chrome/browser/ash/login/auth/cryptohome_authenticator_unittest.cc
@@ -692,7 +692,7 @@ state_->PresetOnlineLoginComplete(); SetAttemptState(auth_.get(), state_.release()); - auth_->ResyncEncryptedData(); + auth_->ResyncEncryptedData(std::make_unique<UserContext>(user_context_)); run_loop_.Run(); } @@ -705,7 +705,7 @@ SetAttemptState(auth_.get(), state_.release()); - auth_->ResyncEncryptedData(); + auth_->ResyncEncryptedData(std::make_unique<UserContext>(user_context_)); run_loop_.Run(); } @@ -736,7 +736,8 @@ state_->PresetOnlineLoginComplete(); SetAttemptState(auth_.get(), state_.release()); - auth_->RecoverEncryptedData(std::string()); + auth_->RecoverEncryptedData(std::make_unique<UserContext>(user_context_), + std::string()); run_loop_.Run(); } @@ -747,7 +748,8 @@ SetAttemptState(auth_.get(), state_.release()); - auth_->RecoverEncryptedData(std::string()); + auth_->RecoverEncryptedData(std::make_unique<UserContext>(user_context_), + std::string()); run_loop_.Run(); }
diff --git a/chrome/browser/ash/login/screen_manager.cc b/chrome/browser/ash/login/screen_manager.cc index 98d0209..0f2b1f89 100644 --- a/chrome/browser/ash/login/screen_manager.cc +++ b/chrome/browser/ash/login/screen_manager.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ash/login/screen_manager.h" +#include <iostream> #include <utility> #include "base/memory/ptr_util.h"
diff --git a/chrome/browser/ash/login/screens/signin_fatal_error_screen.h b/chrome/browser/ash/login/screens/signin_fatal_error_screen.h index 5692713..d1db66b7 100644 --- a/chrome/browser/ash/login/screens/signin_fatal_error_screen.h +++ b/chrome/browser/ash/login/screens/signin_fatal_error_screen.h
@@ -8,6 +8,7 @@ #include <memory> #include <string> +#include "base/callback.h" #include "base/memory/scoped_refptr.h" #include "base/values.h" #include "chrome/browser/ash/login/help_app_launcher.h"
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc index 57e0723..ae8e7bb 100644 --- a/chrome/browser/autofill/autofill_interactive_uitest.cc +++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -65,8 +65,6 @@ #include "components/translate/core/browser/translate_manager.h" #include "components/translate/core/common/translate_switches.h" #include "content/public/browser/navigation_controller.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_view.h" @@ -2619,10 +2617,7 @@ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); ASSERT_TRUE(AutofillFlow(GetElementById("NAME_FIRST"), this)); - content::WindowedNotificationObserver load_stop_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &GetWebContents()->GetController())); + content::LoadStopObserver load_stop_observer(GetWebContents()); ASSERT_TRUE(content::ExecuteScript( GetWebContents(), "document.getElementById('testform').submit();"));
diff --git a/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc b/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc index 3277778..f17394b 100644 --- a/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc +++ b/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" #include "base/bind.h" -#include "base/metrics/histogram_macros.h" #include "base/threading/sequenced_task_runner_handle.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" @@ -61,8 +60,6 @@ if (net::DataURL::Parse(url_, &mime_type, &charset, &data)) response_body = std::make_unique<std::string>(std::move(data)); - // Set |start_time_| to null to exclude data URLs from the fetch histogram. - start_time_ = base::TimeTicks(); // Post a task to maintain our guarantee that the delegate will only be // called asynchronously. base::SequencedTaskRunnerHandle::Get()->PostTask( @@ -71,7 +68,6 @@ } if (simple_loader_) { - start_time_ = base::TimeTicks::Now(); simple_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( loader_factory, std::move(callback)); } @@ -79,12 +75,6 @@ void BitmapFetcher::OnSimpleLoaderComplete( std::unique_ptr<std::string> response_body) { - auto now = base::TimeTicks::Now(); - // |start_time_| will be null for data URLs. We don't want to include them in - // this fetch histogram as data URLs don't require fetching. - if (!start_time_.is_null()) - UMA_HISTOGRAM_TIMES("Browser.BitmapFetcher.Fetch", now - start_time_); - if (!response_body) { ReportFailure(); return; @@ -92,18 +82,12 @@ // Call start to begin decoding. The ImageDecoder will call OnImageDecoded // with the data when it is done. - start_time_ = now; ImageDecoder::Start(this, std::move(*response_body)); } // Methods inherited from ImageDecoder::ImageRequest. void BitmapFetcher::OnImageDecoded(const SkBitmap& decoded_image) { - // Report success. - auto now = base::TimeTicks::Now(); - DCHECK(!start_time_.is_null()); - UMA_HISTOGRAM_TIMES("Browser.BitmapFetcher.Decode", now - start_time_); - delegate_->OnFetchComplete(url_, &decoded_image); } @@ -114,7 +98,3 @@ void BitmapFetcher::ReportFailure() { delegate_->OnFetchComplete(url_, nullptr); } - -void BitmapFetcher::SetStartTimeForTesting() { - start_time_ = base::TimeTicks::Now(); -}
diff --git a/chrome/browser/bitmap_fetcher/bitmap_fetcher.h b/chrome/browser/bitmap_fetcher/bitmap_fetcher.h index 4051808..23bd64d2 100644 --- a/chrome/browser/bitmap_fetcher/bitmap_fetcher.h +++ b/chrome/browser/bitmap_fetcher/bitmap_fetcher.h
@@ -9,7 +9,6 @@ #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" -#include "base/time/time.h" #include "chrome/browser/bitmap_fetcher/bitmap_fetcher_delegate.h" #include "chrome/browser/image_decoder/image_decoder.h" #include "net/http/http_request_headers.h" @@ -68,9 +67,6 @@ // Called when decoding image failed. void OnDecodeImageFailed() override; - // Sets |start_time_| for tests. - void SetStartTimeForTesting(); - private: void OnSimpleLoaderComplete(std::unique_ptr<std::string> response_body); @@ -83,12 +79,6 @@ const raw_ptr<BitmapFetcherDelegate> delegate_; const net::NetworkTrafficAnnotationTag traffic_annotation_; - // Used to measure UMA histograms for fetching and decoding. Will be reset - // when either operation begins and measured in a histogram when the operation - // ends. Decoding doesn't begin until fetching completes, so there's no risk - // of the two measurements interfering. - base::TimeTicks start_time_; - base::WeakPtrFactory<BitmapFetcher> weak_factory_{this}; };
diff --git a/chrome/browser/bitmap_fetcher/bitmap_fetcher_browsertest.cc b/chrome/browser/bitmap_fetcher/bitmap_fetcher_browsertest.cc index 916ebf402..dc877086 100644 --- a/chrome/browser/bitmap_fetcher/bitmap_fetcher_browsertest.cc +++ b/chrome/browser/bitmap_fetcher/bitmap_fetcher_browsertest.cc
@@ -179,7 +179,6 @@ BitmapFetcher fetcher(url, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); - fetcher.SetStartTimeForTesting(); fetcher.OnImageDecoded(image); // Ensure image is marked as succeeded.
diff --git a/chrome/browser/bitmap_fetcher/bitmap_fetcher_service_unittest.cc b/chrome/browser/bitmap_fetcher/bitmap_fetcher_service_unittest.cc index 4c63706..a7adeef 100644 --- a/chrome/browser/bitmap_fetcher/bitmap_fetcher_service_unittest.cc +++ b/chrome/browser/bitmap_fetcher/bitmap_fetcher_service_unittest.cc
@@ -73,7 +73,6 @@ image.allocN32Pixels(2, 2); image.eraseColor(SK_ColorGREEN); - fetcher->SetStartTimeForTesting(); fetcher->OnImageDecoded(image); } @@ -81,7 +80,6 @@ BitmapFetcher* fetcher = const_cast<BitmapFetcher*>(service_->FindFetcherForUrl(url)); ASSERT_TRUE(fetcher); - fetcher->SetStartTimeForTesting(); fetcher->OnImageDecoded(SkBitmap()); }
diff --git a/chrome/browser/browsing_data/navigation_entry_remover_browsertest.cc b/chrome/browser/browsing_data/navigation_entry_remover_browsertest.cc index 7e373c81..1b34624 100644 --- a/chrome/browser/browsing_data/navigation_entry_remover_browsertest.cc +++ b/chrome/browser/browsing_data/navigation_entry_remover_browsertest.cc
@@ -15,8 +15,6 @@ #include "components/sessions/core/tab_restore_service.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test.h" #include "content/public/test/test_navigation_observer.h" @@ -64,9 +62,7 @@ } void GoBack(content::WebContents* web_contents) { - content::WindowedNotificationObserver load_stop_observer( - content::NOTIFICATION_LOAD_STOP, - content::NotificationService::AllSources()); + content::LoadStopObserver load_stop_observer(web_contents); web_contents->GetController().GoBack(); load_stop_observer.Wait(); }
diff --git a/chrome/browser/cart/cart_handler.cc b/chrome/browser/cart/cart_handler.cc index 12b4c047..2564cf0 100644 --- a/chrome/browser/cart/cart_handler.cc +++ b/chrome/browser/cart/cart_handler.cc
@@ -116,6 +116,11 @@ cart_service_->ShouldShowDiscountConsent(std::move(callback)); } +void CartHandler::GetDiscountToggleVisible( + GetDiscountToggleVisibleCallback callback) { + std::move(callback).Run(cart_service_->ShouldShowDiscountToggle()); +} + void CartHandler::OnDiscountConsentAcknowledged(bool accept) { cart_service_->AcknowledgeDiscountConsent(accept); }
diff --git a/chrome/browser/cart/cart_handler.h b/chrome/browser/cart/cart_handler.h index d808c45..3e6378b 100644 --- a/chrome/browser/cart/cart_handler.h +++ b/chrome/browser/cart/cart_handler.h
@@ -35,6 +35,8 @@ GetDiscountURLCallback callback) override; void GetDiscountConsentCardVisible( GetDiscountConsentCardVisibleCallback callback) override; + void GetDiscountToggleVisible( + GetDiscountToggleVisibleCallback callback) override; void OnDiscountConsentAcknowledged(bool accept) override; void OnDiscountConsentDismissed() override; void OnDiscountConsentContinued() override;
diff --git a/chrome/browser/cart/cart_service.cc b/chrome/browser/cart/cart_service.cc index 1545467..ce8f344 100644 --- a/chrome/browser/cart/cart_service.cc +++ b/chrome/browser/cart/cart_service.cc
@@ -451,6 +451,10 @@ std::move(callback).Run(should_show); } +bool CartService::ShouldShowDiscountToggle() { + return profile_->GetPrefs()->GetBoolean(prefs::kCartDiscountAcknowledged); +} + bool CartService::IsCartDiscountEnabled() { if (!commerce::IsCartDiscountFeatureEnabled()) { return false;
diff --git a/chrome/browser/cart/cart_service.h b/chrome/browser/cart/cart_service.h index 3106dd3..bffc189 100644 --- a/chrome/browser/cart/cart_service.h +++ b/chrome/browser/cart/cart_service.h
@@ -102,6 +102,9 @@ // Decides whether to show the consent card in module for rule-based discount, // and returns it in the callback. void ShouldShowDiscountConsent(base::OnceCallback<void(bool)> callback); + // Decides whether to show the discount toggle in the customize_modules + // setting page. + bool ShouldShowDiscountToggle(); // Returns whether the rule-based discount feature in cart module is enabled, // and user has chosen to opt-in the feature. bool IsCartDiscountEnabled();
diff --git a/chrome/browser/cart/chrome_cart.mojom b/chrome/browser/cart/chrome_cart.mojom index c19e6050..57b42d23 100644 --- a/chrome/browser/cart/chrome_cart.mojom +++ b/chrome/browser/cart/chrome_cart.mojom
@@ -44,6 +44,8 @@ GetDiscountURL(url.mojom.Url cart_url) => (url.mojom.Url discount_url); // Returns whether to show discount consent card in the module. GetDiscountConsentCardVisible() => (bool consent_visible); + // Returns whether to show the discount toggle in the customize setting page. + GetDiscountToggleVisible() => (bool toggle_visible); // TODO(crbug.com/1298116): Merge OnDiscountConsentAcknowledged and // OnDiscountConsentDismissed. // Stores in profile prefs that user has acknowledged
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc index 2b46aad..f4650bd8 100644 --- a/chrome/browser/chrome_browser_interface_binders.cc +++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -125,6 +125,7 @@ #include "third_party/blink/public/mojom/installedapp/installed_app_provider.mojom.h" #else #include "chrome/browser/accessibility/live_caption_speech_recognition_host.h" +#include "chrome/browser/accessibility/live_caption_unavailability_notifier.h" #include "chrome/browser/badging/badge_manager.h" #include "chrome/browser/cart/chrome_cart.mojom.h" #include "chrome/browser/cart/commerce_hint_service.h" @@ -582,6 +583,20 @@ std::move(receiver)); } } + +void BindMediaFoundationRendererNotifierHandler( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver<media::mojom::MediaFoundationRendererNotifier> + receiver) { + Profile* profile = Profile::FromBrowserContext( + frame_host->GetProcess()->GetBrowserContext()); + PrefService* profile_prefs = profile->GetPrefs(); + if (profile_prefs->GetBoolean(prefs::kLiveCaptionEnabled) && + media::IsLiveCaptionFeatureEnabled()) { + captions::LiveCaptionUnavailabilityNotifier::Create(frame_host, + std::move(receiver)); + } +} #endif #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) @@ -713,6 +728,8 @@ base::BindRepeating(&BindSpeechRecognitionClientBrowserInterfaceHandler)); map->Add<media::mojom::SpeechRecognitionRecognizerClient>( base::BindRepeating(&BindSpeechRecognitionRecognizerClientHandler)); + map->Add<media::mojom::MediaFoundationRendererNotifier>( + base::BindRepeating(&BindMediaFoundationRendererNotifierHandler)); #endif #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
diff --git a/chrome/browser/chromeos/extensions/info_private_api.cc b/chrome/browser/chromeos/extensions/info_private_api.cc index efea3e36..4a530b36 100644 --- a/chrome/browser/chromeos/extensions/info_private_api.cc +++ b/chrome/browser/chromeos/extensions/info_private_api.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" +#include "chromeos/components/chromebox_for_meetings/buildflags/buildflags.h" #include "chromeos/constants/devicetype.h" #include "chromeos/network/device_state.h" #include "chromeos/network/network_handler.h" @@ -56,6 +57,9 @@ // Key which corresponds to the oem_device_requisition setting. const char kPropertyDeviceRequisition[] = "deviceRequisition"; +// Key which corresponds to the isMeetDevice property in JS. +const char kPropertyMeetDevice[] = "isMeetDevice"; + // Key which corresponds to the home provider property. const char kPropertyHomeProvider[] = "homeProvider"; @@ -309,6 +313,14 @@ return std::make_unique<base::Value>(device_requisition); } + if (property_name == kPropertyMeetDevice) { +#if BUILDFLAG(PLATFORM_CFM) + return std::make_unique<base::Value>(true); +#else + return std::make_unique<base::Value>(false); +#endif + } + if (property_name == kPropertyHomeProvider) { const chromeos::DeviceState* cellular_device = NetworkHandler::Get()->network_state_handler()->GetDeviceStateByType(
diff --git a/chrome/browser/chromeos/extensions/info_private_apitest.cc b/chrome/browser/chromeos/extensions/info_private_apitest.cc index 31a17c3..c332c7d3 100644 --- a/chrome/browser/chromeos/extensions/info_private_apitest.cc +++ b/chrome/browser/chromeos/extensions/info_private_apitest.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" +#include "chromeos/components/chromebox_for_meetings/buildflags/buildflags.h" #include "components/prefs/pref_service.h" #include "content/public/test/browser_test.h" #include "ui/aura/window.h" @@ -217,6 +218,20 @@ << message_; } +IN_PROC_BROWSER_TEST_F(ChromeOSInfoPrivateTest, TestGetIsMeetDevice) { + const char* custom_arg = +#if BUILDFLAG(PLATFORM_CFM) + "Is Meet Device - True"; +#else + "Is Meet Device - False"; +#endif + + ASSERT_TRUE(RunExtensionTest( + "chromeos_info_private/extended", + {.custom_arg = custom_arg, .launch_as_platform_app = true})) + << message_; +} + class ChromeOSInfoPrivateInternalStylusTest : public ChromeOSInfoPrivateTest { public: ChromeOSInfoPrivateInternalStylusTest() = default;
diff --git a/chrome/browser/component_updater/cros_component_installer_chromeos.cc b/chrome/browser/component_updater/cros_component_installer_chromeos.cc index 8849aa2..1bb3136 100644 --- a/chrome/browser/component_updater/cros_component_installer_chromeos.cc +++ b/chrome/browser/component_updater/cros_component_installer_chromeos.cc
@@ -44,6 +44,8 @@ "c93c3e1013c52100a20038b405ac854d69fa889f6dc4fa6f188267051e05e444"}, {"demo-mode-resources", ComponentConfig::PolicyType::kEnvVersion, "1.0", "93c093ebac788581389015e9c59c5af111d2fa5174d206eb795042e6376cbd10"}, + {"demo-mode-app", ComponentConfig::PolicyType::kDemoApp, nullptr, + "b6c5ce9f03b0ce830eb5f9f92ed3016cfdb7a2327330f0187adbe9a00ddfd34d"}, // NOTE: If you change the lacros component names, you must also update // chrome/browser/ash/crosapi/browser_loader.cc. {"lacros-dogfood-canary", ComponentConfig::PolicyType::kLacros, nullptr, @@ -249,6 +251,24 @@ g_ash_version_for_test = version; } +DemoAppInstallerPolicy::DemoAppInstallerPolicy( + const ComponentConfig& config, + CrOSComponentInstaller* cros_component_installer) + : CrOSComponentInstallerPolicy(config, cros_component_installer) {} + +DemoAppInstallerPolicy::~DemoAppInstallerPolicy() = default; + +void DemoAppInstallerPolicy::ComponentReady(const base::Version& version, + const base::FilePath& path, + base::Value manifest) { + cros_component_installer_->RegisterCompatiblePath(GetName(), path); +} + +update_client::InstallerAttributes +DemoAppInstallerPolicy::GetInstallerAttributes() const { + return {}; +} + CrOSComponentInstaller::CrOSComponentInstaller( std::unique_ptr<MetadataTable> metadata_table, ComponentUpdateService* component_updater) @@ -350,6 +370,9 @@ case ComponentConfig::PolicyType::kLacros: policy = std::make_unique<LacrosInstallerPolicy>(config, this); break; + case ComponentConfig::PolicyType::kDemoApp: + policy = std::make_unique<DemoAppInstallerPolicy>(config, this); + break; } auto installer = base::MakeRefCounted<ComponentInstaller>(std::move(policy)); installer->Register(component_updater_, std::move(register_callback));
diff --git a/chrome/browser/component_updater/cros_component_installer_chromeos.h b/chrome/browser/component_updater/cros_component_installer_chromeos.h index fe7950e2..127897bc 100644 --- a/chrome/browser/component_updater/cros_component_installer_chromeos.h +++ b/chrome/browser/component_updater/cros_component_installer_chromeos.h
@@ -39,6 +39,7 @@ enum class PolicyType { kEnvVersion, // Checks env_version, see below. kLacros, // Uses special lacros compatibility rules. + kDemoApp, // Adds demo-mode-specific install attributes }; PolicyType policy_type; // This is used for ABI compatibility checks. It is compared against the @@ -133,6 +134,24 @@ static void SetAshVersionForTest(const char* version); }; +// An installer policy for the ChromeOS Demo Mode app, which includes special +// system-sourced installer attributes in the request to receive customized +// app versions +class DemoAppInstallerPolicy : public CrOSComponentInstallerPolicy { + public: + DemoAppInstallerPolicy(const ComponentConfig& config, + CrOSComponentInstaller* cros_component_installer); + DemoAppInstallerPolicy(const DemoAppInstallerPolicy&) = delete; + DemoAppInstallerPolicy& operator=(const DemoAppInstallerPolicy&) = delete; + ~DemoAppInstallerPolicy() override; + + // ComponentInstallerPolicy: + void ComponentReady(const base::Version& version, + const base::FilePath& path, + base::Value manifest) override; + update_client::InstallerAttributes GetInstallerAttributes() const override; +}; + // This class contains functions used to register and install a component. class CrOSComponentInstaller : public CrOSComponentManager { public:
diff --git a/chrome/browser/download/internal/android/BUILD.gn b/chrome/browser/download/internal/android/BUILD.gn index 8e45d5f..d43af597 100644 --- a/chrome/browser/download/internal/android/BUILD.gn +++ b/chrome/browser/download/internal/android/BUILD.gn
@@ -111,6 +111,7 @@ "//base:base_java", "//chrome/browser/download/android:file_provider_java", "//chrome/browser/download/android:java", + "//chrome/browser/preferences:java", "//chrome/browser/profiles/android:java", "//chrome/browser/thumbnail:java", "//chrome/browser/ui/messages/android:java",
diff --git a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/interstitial/DownloadInterstitialCoordinatorImpl.java b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/interstitial/DownloadInterstitialCoordinatorImpl.java index 03bf1e4..f0467869d 100644 --- a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/interstitial/DownloadInterstitialCoordinatorImpl.java +++ b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/interstitial/DownloadInterstitialCoordinatorImpl.java
@@ -7,6 +7,7 @@ import android.content.Context; import android.view.View; +import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.components.offline_items_collection.OfflineContentProvider; import org.chromium.ui.modelutil.PropertyModel; @@ -33,7 +34,8 @@ mView = DownloadInterstitialView.create(context); PropertyModel model = new PropertyModel.Builder(DownloadInterstitialProperties.ALL_KEYS).build(); - mMediator = new DownloadInterstitialMediator(context, model, provider, snackbarManager); + mMediator = new DownloadInterstitialMediator( + context, model, provider, snackbarManager, SharedPreferencesManager.getInstance()); mModelChangeProcessor = PropertyModelChangeProcessor.create( model, mView, DownloadInterstitialViewBinder::bind); }
diff --git a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/interstitial/DownloadInterstitialMediator.java b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/interstitial/DownloadInterstitialMediator.java index 680d407..f20fda0 100644 --- a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/interstitial/DownloadInterstitialMediator.java +++ b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/interstitial/DownloadInterstitialMediator.java
@@ -26,6 +26,8 @@ import org.chromium.chrome.browser.download.home.rename.RenameDialogManager; import org.chromium.chrome.browser.download.internal.R; import org.chromium.chrome.browser.download.interstitial.DownloadInterstitialProperties.State; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; +import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.components.browser_ui.modaldialog.AppModalPresenter; @@ -56,6 +58,7 @@ private final OfflineContentProvider mProvider; private final SnackbarManager mSnackbarManager; private final OfflineContentProvider.Observer mObserver; + private final SharedPreferencesManager mSharedPrefs; private boolean mDownloadIsComplete; private boolean mPendingDeletion; @@ -70,11 +73,13 @@ * download interstitial view. */ DownloadInterstitialMediator(Context context, PropertyModel model, - OfflineContentProvider provider, SnackbarManager snackbarManager) { + OfflineContentProvider provider, SnackbarManager snackbarManager, + SharedPreferencesManager sharedPrefs) { mContext = context; mModel = model; mProvider = provider; mSnackbarManager = snackbarManager; + mSharedPrefs = sharedPrefs; mModel.set(ListProperties.ENABLE_ITEM_ANIMATIONS, true); mModel.set(ListProperties.CALLBACK_OPEN, this::onOpenItem); @@ -103,6 +108,7 @@ mProvider.cancelDownload(mModel.get(DOWNLOAD_ITEM).id); } } + clearDownloadPendingRemoval(); } private void setState(@State int state) { @@ -152,16 +158,19 @@ private void onResumeItem(OfflineItem item) { setState(mDownloadIsComplete ? State.SUCCESSFUL : State.IN_PROGRESS); mPendingDeletion = false; + clearDownloadPendingRemoval(); mProvider.resumeDownload(item.id, true /* hasUserGesture */); } private void onCancelItem(OfflineItem item) { setState(State.CANCELLED); + storeDownloadPendingRemoval(item.id); mProvider.pauseDownload(item.id); } private void onDeleteItem(OfflineItem item) { mPendingDeletion = true; + storeDownloadPendingRemoval(item.id); showDeletedSnackbar(); setState(State.CANCELLED); } @@ -247,4 +256,27 @@ } }; } + + private void storeDownloadPendingRemoval(ContentId downloadId) { + final String key = ChromePreferenceKeys.DOWNLOAD_INTERSTITIAL_DOWNLOAD_PENDING_REMOVAL; + boolean success = mSharedPrefs.writeStringSync( + key, String.format("%s,%s", downloadId.namespace, downloadId.id)); + + if (!success) { + // Write synchronously because it might be used on restart and needs to stay + // up-to-date. + Log.e(TAG, "Failed to write DownloadInfo " + key); + } + } + + private void clearDownloadPendingRemoval() { + final String key = ChromePreferenceKeys.DOWNLOAD_INTERSTITIAL_DOWNLOAD_PENDING_REMOVAL; + boolean success = mSharedPrefs.removeKeySync(key); + + if (!success) { + // Write synchronously because it might be used on restart and needs to stay + // up-to-date. + Log.e(TAG, "Failed to clear DownloadInfo " + key); + } + } } \ No newline at end of file
diff --git a/chrome/browser/enterprise/reporting/cloud_profile_reporting_browsertest.cc b/chrome/browser/enterprise/reporting/cloud_profile_reporting_browsertest.cc new file mode 100644 index 0000000..862d81d --- /dev/null +++ b/chrome/browser/enterprise/reporting/cloud_profile_reporting_browsertest.cc
@@ -0,0 +1,70 @@ +// Copyright 2022 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 "build/build_config.h" +#include "build/chromeos_buildflags.h" +#include "chrome/browser/enterprise/reporting/cloud_profile_reporting_service.h" +#include "chrome/browser/enterprise/reporting/cloud_profile_reporting_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/test/base/chrome_test_utils.h" +#include "components/enterprise/browser/reporting/common_pref_names.h" +#include "components/policy/core/common/cloud/cloud_policy_store.h" +#include "components/policy/core/common/cloud/user_cloud_policy_manager.h" +#include "components/policy/proto/device_management_backend.pb.h" +#include "components/prefs/pref_service.h" +#include "content/public/test/browser_test.h" + +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "components/policy/core/common/policy_loader_lacros.h" +#endif + +namespace enterprise_reporting { + +namespace em = enterprise_management; + +class CloudProfileReportingServiceTest : public PlatformBrowserTest { + public: + CloudProfileReportingServiceTest() = default; + ~CloudProfileReportingServiceTest() override = default; + + void SetUpOnMainThread() override { + Profile* profile = chrome_test_utils::GetProfile(this); + EnableProfileManagement(profile); + EnableReportingPolicy(profile); + } + + void EnableProfileManagement(Profile* profile) { + em::PolicyData policy_data; + policy_data.set_request_token("dm-token"); + policy_data.set_device_id("device-id"); +#if BUILDFLAG(IS_CHROMEOS_LACROS) + ASSERT_TRUE(profile->IsMainProfile()); + policy::PolicyLoaderLacros::set_main_user_policy_data_for_testing( + policy_data); +#else + profile->GetUserCloudPolicyManager() + ->core() + ->store() + ->set_policy_data_for_testing( + std::make_unique<em::PolicyData>(policy_data)); +#endif + } + + void EnableReportingPolicy(Profile* profile) { + profile->GetPrefs()->SetBoolean(kCloudProfileReportingEnabled, true); + } +}; + +IN_PROC_BROWSER_TEST_F(CloudProfileReportingServiceTest, LaunchTest) { + ReportScheduler* report_scheduler = + CloudProfileReportingServiceFactory::GetForProfile( + chrome_test_utils::GetProfile(this)) + ->report_scheduler(); + ASSERT_TRUE(report_scheduler); + EXPECT_TRUE(report_scheduler->IsNextReportScheduledForTesting() || + report_scheduler->GetActiveTriggerForTesting() == + ReportScheduler::kTriggerTimer); +} + +} // namespace enterprise_reporting
diff --git a/chrome/browser/enterprise/reporting/cloud_profile_reporting_service.cc b/chrome/browser/enterprise/reporting/cloud_profile_reporting_service.cc new file mode 100644 index 0000000..1b23de0 --- /dev/null +++ b/chrome/browser/enterprise/reporting/cloud_profile_reporting_service.cc
@@ -0,0 +1,72 @@ +// Copyright 2022 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/enterprise/reporting/cloud_profile_reporting_service.h" + +#include <utility> + +#include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" +#include "build/chromeos_buildflags.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_attributes_entry.h" +#include "chrome/browser/profiles/profile_attributes_storage.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "components/enterprise/browser/reporting/chrome_profile_request_generator.h" +#include "components/enterprise/browser/reporting/report_scheduler.h" +#include "components/policy/core/common/cloud/cloud_policy_client.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" + +#if BUILDFLAG(IS_ANDROID) +#include "chrome/browser/enterprise/reporting/reporting_delegate_factory_android.h" +#else +#include "chrome/browser/enterprise/reporting/reporting_delegate_factory_desktop.h" +#endif + +namespace enterprise_reporting { + +namespace { + +std::string GetProfileName(raw_ptr<Profile> profile) { + ProfileManager* profile_manager = g_browser_process->profile_manager(); + // profile manager may not be available in test. + if (!profile_manager) + return std::string(); + ProfileAttributesStorage& storage = + profile_manager->GetProfileAttributesStorage(); + ProfileAttributesEntry* entry = + storage.GetProfileAttributesWithPath(profile->GetPath()); + if (!entry) + return std::string(); + return base::UTF16ToUTF8(entry->GetName()); +} + +} // namespace + +CloudProfileReportingService::CloudProfileReportingService( + raw_ptr<Profile> profile, + raw_ptr<policy::DeviceManagementService> device_management_service, + scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory) { + cloud_policy_client_ = std::make_unique<policy::CloudPolicyClient>( + device_management_service, system_url_loader_factory, + policy::CloudPolicyClient::DeviceDMTokenCallback()); + +#if BUILDFLAG(IS_ANDROID) + ReportingDelegateFactoryAndroid delegate_factory; +#else + ReportingDelegateFactoryDesktop delegate_factory; +#endif // !BUILDFLAG(IS_ANDROID) + ReportScheduler::CreateParams params; + params.client = cloud_policy_client_.get(); + params.delegate = delegate_factory.GetReportSchedulerDelegate(profile); + params.profile_request_generator = + std::make_unique<ChromeProfileRequestGenerator>( + profile->GetPath(), GetProfileName(profile), &delegate_factory); + report_scheduler_ = std::make_unique<ReportScheduler>(std::move(params)); +} + +CloudProfileReportingService::~CloudProfileReportingService() = default; + +} // namespace enterprise_reporting
diff --git a/chrome/browser/enterprise/reporting/cloud_profile_reporting_service.h b/chrome/browser/enterprise/reporting/cloud_profile_reporting_service.h new file mode 100644 index 0000000..0ef9fad --- /dev/null +++ b/chrome/browser/enterprise/reporting/cloud_profile_reporting_service.h
@@ -0,0 +1,43 @@ +// Copyright 2022 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_ENTERPRISE_REPORTING_CLOUD_PROFILE_REPORTING_SERVICE_H_ +#define CHROME_BROWSER_ENTERPRISE_REPORTING_CLOUD_PROFILE_REPORTING_SERVICE_H_ + +#include <memory> + +#include "base/memory/raw_ptr.h" +#include "components/enterprise/browser/reporting/report_scheduler.h" +#include "components/keyed_service/core/keyed_service.h" +#include "components/policy/core/common/cloud/cloud_policy_client.h" + +class Profile; + +namespace policy { +class DeviceManagementService; +} + +namespace enterprise_reporting { + +class CloudProfileReportingService : public KeyedService { + public: + CloudProfileReportingService( + raw_ptr<Profile> profile, + raw_ptr<policy::DeviceManagementService> device_management_service, + scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory); + CloudProfileReportingService(const CloudProfileReportingService&) = delete; + CloudProfileReportingService& operator=(const CloudProfileReportingService&) = + delete; + ~CloudProfileReportingService() override; + + ReportScheduler* report_scheduler() { return report_scheduler_.get(); } + + private: + std::unique_ptr<policy::CloudPolicyClient> cloud_policy_client_; + std::unique_ptr<ReportScheduler> report_scheduler_; +}; + +} // namespace enterprise_reporting + +#endif // CHROME_BROWSER_ENTERPRISE_REPORTING_CLOUD_PROFILE_REPORTING_SERVICE_H_
diff --git a/chrome/browser/enterprise/reporting/cloud_profile_reporting_service_factory.cc b/chrome/browser/enterprise/reporting/cloud_profile_reporting_service_factory.cc new file mode 100644 index 0000000..f915d293f --- /dev/null +++ b/chrome/browser/enterprise/reporting/cloud_profile_reporting_service_factory.cc
@@ -0,0 +1,56 @@ +// Copyright 2022 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/enterprise/reporting/cloud_profile_reporting_service_factory.h" + +#include "chrome/browser/browser_process.h" +#include "chrome/browser/enterprise/reporting/cloud_profile_reporting_service.h" +#include "chrome/browser/policy/chrome_browser_policy_connector.h" +#include "chrome/browser/profiles/profile.h" +#include "components/enterprise/browser/reporting/report_scheduler.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" + +namespace enterprise_reporting { + +// static +CloudProfileReportingServiceFactory* +CloudProfileReportingServiceFactory::GetInstance() { + return base::Singleton<CloudProfileReportingServiceFactory>::get(); +} + +// static +CloudProfileReportingService* +CloudProfileReportingServiceFactory::GetForProfile(Profile* profile) { + return static_cast<CloudProfileReportingService*>( + GetInstance()->GetServiceForBrowserContext(profile, /*create=*/true)); +} + +KeyedService* CloudProfileReportingServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + Profile* profile = Profile::FromBrowserContext(context); + if (!profile->IsRegularProfile()) + return nullptr; + + return new CloudProfileReportingService( + profile, + g_browser_process->browser_policy_connector() + ->device_management_service(), + g_browser_process->shared_url_loader_factory()); +} +bool CloudProfileReportingServiceFactory::ServiceIsCreatedWithBrowserContext() + const { + return true; +} + +CloudProfileReportingServiceFactory::CloudProfileReportingServiceFactory() + : BrowserContextKeyedServiceFactory( + "CloudProfileReporting", + BrowserContextDependencyManager::GetInstance()) {} + +CloudProfileReportingServiceFactory::~CloudProfileReportingServiceFactory() = + default; + +} // namespace enterprise_reporting
diff --git a/chrome/browser/enterprise/reporting/cloud_profile_reporting_service_factory.h b/chrome/browser/enterprise/reporting/cloud_profile_reporting_service_factory.h new file mode 100644 index 0000000..19ddb56 --- /dev/null +++ b/chrome/browser/enterprise/reporting/cloud_profile_reporting_service_factory.h
@@ -0,0 +1,45 @@ +// Copyright 2022 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_ENTERPRISE_REPORTING_CLOUD_PROFILE_REPORTING_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_ENTERPRISE_REPORTING_CLOUD_PROFILE_REPORTING_SERVICE_FACTORY_H_ + +#include "base/memory/singleton.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +class Profile; + +namespace enterprise_reporting { + +class CloudProfileReportingService; + +class CloudProfileReportingServiceFactory + : public BrowserContextKeyedServiceFactory { + public: + static CloudProfileReportingServiceFactory* GetInstance(); + + static CloudProfileReportingService* GetForProfile(Profile* profile); + + CloudProfileReportingServiceFactory( + const CloudProfileReportingServiceFactory&) = delete; + CloudProfileReportingServiceFactory& operator=( + const CloudProfileReportingServiceFactory&) = delete; + + protected: + // BrowserContextKeyedServiceFactory implementation. + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + bool ServiceIsCreatedWithBrowserContext() const override; + + private: + friend struct base::DefaultSingletonTraits< + CloudProfileReportingServiceFactory>; + + CloudProfileReportingServiceFactory(); + ~CloudProfileReportingServiceFactory() override; +}; + +} // namespace enterprise_reporting + +#endif // CHROME_BROWSER_ENTERPRISE_REPORTING_CLOUD_PROFILE_REPORTING_SERVICE_FACTORY_H_
diff --git a/chrome/browser/enterprise/reporting/report_scheduler_android.cc b/chrome/browser/enterprise/reporting/report_scheduler_android.cc index 6ebf98a..0a4daf8 100644 --- a/chrome/browser/enterprise/reporting/report_scheduler_android.cc +++ b/chrome/browser/enterprise/reporting/report_scheduler_android.cc
@@ -5,14 +5,17 @@ #include "chrome/browser/enterprise/reporting/report_scheduler_android.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/reporting_util.h" +#include "components/policy/core/common/cloud/dm_token.h" #include "components/prefs/pref_service.h" namespace enterprise_reporting { ReportSchedulerAndroid::ReportSchedulerAndroid() - : ReportSchedulerAndroid(g_browser_process->local_state()) {} -ReportSchedulerAndroid::ReportSchedulerAndroid(raw_ptr<PrefService> prefs) - : prefs_(prefs) {} + : profile_(nullptr), prefs_(g_browser_process->local_state()) {} +ReportSchedulerAndroid::ReportSchedulerAndroid(raw_ptr<Profile> profile) + : profile_(profile), prefs_(profile_->GetPrefs()) {} ReportSchedulerAndroid::~ReportSchedulerAndroid() = default; @@ -46,4 +49,15 @@ // No-op because extensions are not supported on Android. } +policy::DMToken ReportSchedulerAndroid::GetProfileDMToken() { + absl::optional<std::string> dm_token = reporting::GetUserDmToken(profile_); + if (!dm_token || dm_token->empty()) + return policy::DMToken(); + return policy::DMToken(policy::DMToken::Status::kValid, *dm_token); +} + +std::string ReportSchedulerAndroid::GetProfileClientId() { + return reporting::GetUserClientId(profile_).value_or(std::string()); +} + } // namespace enterprise_reporting
diff --git a/chrome/browser/enterprise/reporting/report_scheduler_android.h b/chrome/browser/enterprise/reporting/report_scheduler_android.h index b848bc2..e059120 100644 --- a/chrome/browser/enterprise/reporting/report_scheduler_android.h +++ b/chrome/browser/enterprise/reporting/report_scheduler_android.h
@@ -7,13 +7,15 @@ #include "components/enterprise/browser/reporting/report_scheduler.h" +class Profile; + namespace enterprise_reporting { // Android implementation of the ReportScheduler delegate. class ReportSchedulerAndroid : public ReportScheduler::Delegate { public: ReportSchedulerAndroid(); - explicit ReportSchedulerAndroid(raw_ptr<PrefService> prefs); + explicit ReportSchedulerAndroid(raw_ptr<Profile> profile); ReportSchedulerAndroid(const ReportSchedulerAndroid&) = delete; ReportSchedulerAndroid& operator=(const ReportSchedulerAndroid&) = delete; @@ -28,8 +30,11 @@ void StartWatchingExtensionRequestIfNeeded() override; void StopWatchingExtensionRequest() override; void OnExtensionRequestUploaded() override; + policy::DMToken GetProfileDMToken() override; + std::string GetProfileClientId() override; private: + raw_ptr<Profile> profile_; raw_ptr<PrefService> prefs_; };
diff --git a/chrome/browser/enterprise/reporting/report_scheduler_desktop.cc b/chrome/browser/enterprise/reporting/report_scheduler_desktop.cc index 9f7b140..5f56be0b 100644 --- a/chrome/browser/enterprise/reporting/report_scheduler_desktop.cc +++ b/chrome/browser/enterprise/reporting/report_scheduler_desktop.cc
@@ -7,17 +7,21 @@ #include "base/bind.h" #include "base/feature_list.h" #include "base/metrics/field_trial_params.h" +#include "base/notreached.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/enterprise/reporting/extension_request/extension_request_report_generator.h" #include "chrome/browser/enterprise/reporting/prefs.h" +#include "chrome/browser/profiles/reporting_util.h" #include "chrome/browser/upgrade_detector/build_state.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "components/enterprise/browser/reporting/report_scheduler.h" +#include "components/policy/core/common/cloud/dm_token.h" #include "components/prefs/pref_service.h" #include "components/reporting/client/report_queue_provider.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace em = enterprise_management; @@ -44,14 +48,26 @@ } // namespace ReportSchedulerDesktop::ReportSchedulerDesktop() - : ReportSchedulerDesktop(nullptr, LocalState()) {} - -ReportSchedulerDesktop::ReportSchedulerDesktop(raw_ptr<Profile> profile) - : ReportSchedulerDesktop(profile, LocalState()) {} + : ReportSchedulerDesktop(nullptr, false) {} ReportSchedulerDesktop::ReportSchedulerDesktop(raw_ptr<Profile> profile, - raw_ptr<PrefService> prefs) - : prefs_(prefs), extension_request_observer_factory_(profile) {} + bool profile_reporting) { + if (profile_reporting) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Profile reporting is on LaCrOs instead of Ash. + NOTREACHED(); +#endif + profile_ = profile; + prefs_ = profile->GetPrefs(); + // Extension request hasn't support profile report yet. When we do, we also + // need to refactor the code to avoid multiple extension request observer. + } else { + profile_ = nullptr; + prefs_ = LocalState(); + extension_request_observer_factory_ = + std::make_unique<ExtensionRequestObserverFactory>(profile); + } +} ReportSchedulerDesktop::~ReportSchedulerDesktop() { // If new profiles have been added since the last report was sent, they won't @@ -106,21 +122,36 @@ } void ReportSchedulerDesktop::StartWatchingExtensionRequestIfNeeded() { - // On CrOS, the function may be called twice during startup. - if (extension_request_observer_factory_.IsReportEnabled()) + if (!extension_request_observer_factory_) return; - extension_request_observer_factory_.EnableReport( + // On CrOS, the function may be called twice during startup. + if (extension_request_observer_factory_->IsReportEnabled()) + return; + + extension_request_observer_factory_->EnableReport( base::BindRepeating(&ReportSchedulerDesktop::TriggerExtensionRequest, base::Unretained(this))); } void ReportSchedulerDesktop::StopWatchingExtensionRequest() { - extension_request_observer_factory_.DisableReport(); + if (extension_request_observer_factory_) + extension_request_observer_factory_->DisableReport(); } void ReportSchedulerDesktop::OnExtensionRequestUploaded() {} +policy::DMToken ReportSchedulerDesktop::GetProfileDMToken() { + absl::optional<std::string> dm_token = reporting::GetUserDmToken(profile_); + if (!dm_token || dm_token->empty()) + return policy::DMToken(); + return policy::DMToken(policy::DMToken::Status::kValid, *dm_token); +} + +std::string ReportSchedulerDesktop::GetProfileClientId() { + return reporting::GetUserClientId(profile_).value_or(std::string()); +} + void ReportSchedulerDesktop::OnUpdate(const BuildState* build_state) { DCHECK(ShouldReportUpdates()); // A new version has been detected on the machine and a restart is now needed
diff --git a/chrome/browser/enterprise/reporting/report_scheduler_desktop.h b/chrome/browser/enterprise/reporting/report_scheduler_desktop.h index c2f1403..d8aa07b 100644 --- a/chrome/browser/enterprise/reporting/report_scheduler_desktop.h +++ b/chrome/browser/enterprise/reporting/report_scheduler_desktop.h
@@ -20,10 +20,10 @@ public BuildStateObserver { public: ReportSchedulerDesktop(); - // Chrome OS user session report - explicit ReportSchedulerDesktop(raw_ptr<Profile> profile); - // Profile reporting - ReportSchedulerDesktop(raw_ptr<Profile> profile, raw_ptr<PrefService> prefs); + /* `profile` is used for profile reporting or Chrome OS session. + * `profile_reporting` should be set to false for Chrome OS only.*/ + explicit ReportSchedulerDesktop(raw_ptr<Profile> profile, + bool profile_reporting = false); ReportSchedulerDesktop(const ReportSchedulerDesktop&) = delete; ReportSchedulerDesktop& operator=(const ReportSchedulerDesktop&) = delete; @@ -39,6 +39,8 @@ void StartWatchingExtensionRequestIfNeeded() override; void StopWatchingExtensionRequest() override; void OnExtensionRequestUploaded() override; + policy::DMToken GetProfileDMToken() override; + std::string GetProfileClientId() override; // BuildStateObserver implementation. void OnUpdate(const BuildState* build_state) override; @@ -46,8 +48,10 @@ void TriggerExtensionRequest(Profile* profile); private: + raw_ptr<Profile> profile_; raw_ptr<PrefService> prefs_; - ExtensionRequestObserverFactory extension_request_observer_factory_; + std::unique_ptr<ExtensionRequestObserverFactory> + extension_request_observer_factory_; }; } // namespace enterprise_reporting
diff --git a/chrome/browser/enterprise/reporting/report_scheduler_unittest.cc b/chrome/browser/enterprise/reporting/report_scheduler_unittest.cc index e8d1553..7512c5c 100644 --- a/chrome/browser/enterprise/reporting/report_scheduler_unittest.cc +++ b/chrome/browser/enterprise/reporting/report_scheduler_unittest.cc
@@ -229,21 +229,24 @@ std::move(extension_request_uploader_ptr_)); } +#if !BUILDFLAG(IS_CHROMEOS_ASH) void CreateSchedulerForProfileReporting(Profile* profile) { ReportScheduler::CreateParams params; params.client = client_; client_->SetDMToken("dm-token"); params.delegate = #if BUILDFLAG(IS_ANDROID) - std::make_unique<ReportSchedulerAndroid>(profile->GetPrefs()); + std::make_unique<ReportSchedulerAndroid>(profile); #else - std::make_unique<ReportSchedulerDesktop>(profile, profile->GetPrefs()); + std::make_unique<ReportSchedulerDesktop>(profile, + /*profile_reporting=*/true); #endif // BUILDFLAG(IS_ANDROID) params.profile_request_generator = std::move(profile_request_generator_ptr_); scheduler_ = std::make_unique<ReportScheduler>(std::move(params)); scheduler_->SetReportUploaderForTesting(std::move(uploader_ptr_)); } +#endif // !BUILDFLAG(IS_CHROMEOS_ASH) void SetLastUploadInHour(base::TimeDelta gap) { previous_set_last_upload_timestamp_ = base::Time::Now() - gap; @@ -390,6 +393,8 @@ ::testing::Mock::VerifyAndClearExpectations(generator_); } +// Profile reporting does not support ash. +#if !BUILDFLAG(IS_CHROMEOS_ASH) TEST_F(ReportSchedulerTest, UploadReportSucceededForProfileReporting) { EXPECT_CALL(*profile_request_generator_, OnGenerate(_)) .WillOnce(WithArgs<0>(ScheduleProfileRequestGeneratorCallback())); @@ -414,6 +419,7 @@ ::testing::Mock::VerifyAndClearExpectations(client_); ::testing::Mock::VerifyAndClearExpectations(profile_request_generator_); } +#endif // !BUILDFLAG(IS_CHROMEOS_ASH) TEST_F(ReportSchedulerTest, UploadReportTransientError) { EXPECT_CALL_SetupRegistration();
diff --git a/chrome/browser/enterprise/reporting/reporting_delegate_factory_android.cc b/chrome/browser/enterprise/reporting/reporting_delegate_factory_android.cc index 8f4c0f5..802ac5f 100644 --- a/chrome/browser/enterprise/reporting/reporting_delegate_factory_android.cc +++ b/chrome/browser/enterprise/reporting/reporting_delegate_factory_android.cc
@@ -39,4 +39,9 @@ return nullptr; } +std::unique_ptr<ReportScheduler::Delegate> +ReportingDelegateFactoryAndroid::GetReportSchedulerDelegate(Profile* profile) { + return std::make_unique<ReportSchedulerAndroid>(profile); +} + } // namespace enterprise_reporting
diff --git a/chrome/browser/enterprise/reporting/reporting_delegate_factory_android.h b/chrome/browser/enterprise/reporting/reporting_delegate_factory_android.h index 86cc0f9..9a24c43 100644 --- a/chrome/browser/enterprise/reporting/reporting_delegate_factory_android.h +++ b/chrome/browser/enterprise/reporting/reporting_delegate_factory_android.h
@@ -5,8 +5,12 @@ #ifndef CHROME_BROWSER_ENTERPRISE_REPORTING_REPORTING_DELEGATE_FACTORY_ANDROID_H_ #define CHROME_BROWSER_ENTERPRISE_REPORTING_REPORTING_DELEGATE_FACTORY_ANDROID_H_ +#include <memory> + #include "components/enterprise/browser/reporting/reporting_delegate_factory.h" +class Profile; + namespace enterprise_reporting { // Android implementation of the reporting delegate factory. Creates android- @@ -31,6 +35,9 @@ override; std::unique_ptr<RealTimeReportGenerator::Delegate> GetRealTimeReportGeneratorDelegate() override; + + std::unique_ptr<ReportScheduler::Delegate> GetReportSchedulerDelegate( + Profile* profile); }; } // namespace enterprise_reporting
diff --git a/chrome/browser/enterprise/reporting/reporting_delegate_factory_desktop.cc b/chrome/browser/enterprise/reporting/reporting_delegate_factory_desktop.cc index 2c67467f..fb1ea36 100644 --- a/chrome/browser/enterprise/reporting/reporting_delegate_factory_desktop.cc +++ b/chrome/browser/enterprise/reporting/reporting_delegate_factory_desktop.cc
@@ -37,4 +37,10 @@ return std::make_unique<RealTimeReportGeneratorDesktop>(); } +std::unique_ptr<ReportScheduler::Delegate> +ReportingDelegateFactoryDesktop::GetReportSchedulerDelegate(Profile* profile) { + return std::make_unique<ReportSchedulerDesktop>(profile, + /*profile_reporting=*/true); +} + } // namespace enterprise_reporting
diff --git a/chrome/browser/enterprise/reporting/reporting_delegate_factory_desktop.h b/chrome/browser/enterprise/reporting/reporting_delegate_factory_desktop.h index 13604c8..823058c 100644 --- a/chrome/browser/enterprise/reporting/reporting_delegate_factory_desktop.h +++ b/chrome/browser/enterprise/reporting/reporting_delegate_factory_desktop.h
@@ -15,6 +15,8 @@ #include "components/enterprise/browser/reporting/report_generator.h" #include "components/enterprise/browser/reporting/report_scheduler.h" +class Profile; + namespace enterprise_reporting { // Desktop implementation of the reporting delegate factory. Creates desktop- @@ -42,6 +44,9 @@ std::unique_ptr<RealTimeReportGenerator::Delegate> GetRealTimeReportGeneratorDelegate() override; + + std::unique_ptr<ReportScheduler::Delegate> GetReportSchedulerDelegate( + Profile* profile); }; } // namespace enterprise_reporting
diff --git a/chrome/browser/extensions/app_process_apitest.cc b/chrome/browser/extensions/app_process_apitest.cc index f2089ac..abef001 100644 --- a/chrome/browser/extensions/app_process_apitest.cc +++ b/chrome/browser/extensions/app_process_apitest.cc
@@ -21,7 +21,6 @@ #include "components/embedder_support/switches.h" #include "components/sync/model/string_ordinal.h" #include "content/public/browser/navigation_entry.h" -#include "content/public/browser/notification_service.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" @@ -414,11 +413,8 @@ LOG(INFO) << "Enabling extension."; EnableExtension(app->id()); LOG(INFO) << "Enabling extension - done."; - content::WindowedNotificationObserver reload_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>( - &browser()->tab_strip_model()->GetActiveWebContents()-> - GetController())); + content::LoadStopObserver reload_observer( + browser()->tab_strip_model()->GetActiveWebContents()); LOG(INFO) << "Reloading."; chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); reload_observer.Wait(); @@ -433,11 +429,8 @@ LOG(INFO) << "Disabling extension."; DisableExtension(app->id()); LOG(INFO) << "Disabling extension - done."; - content::WindowedNotificationObserver reload_observer2( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>( - &browser()->tab_strip_model()->GetActiveWebContents()-> - GetController())); + content::LoadStopObserver reload_observer2( + browser()->tab_strip_model()->GetActiveWebContents()); LOG(INFO) << "Reloading."; chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); reload_observer2.Wait(); @@ -481,11 +474,8 @@ LOG(INFO) << "Enabling extension."; EnableExtension(app->id()); LOG(INFO) << "Enabling extension - done."; - content::WindowedNotificationObserver js_reload_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>( - &browser()->tab_strip_model()->GetActiveWebContents()-> - GetController())); + content::LoadStopObserver js_reload_observer( + browser()->tab_strip_model()->GetActiveWebContents()); LOG(INFO) << "Executing location.reload()."; ASSERT_TRUE(content::ExecuteScript(contents, "location.reload();")); js_reload_observer.Wait(); @@ -497,11 +487,8 @@ LOG(INFO) << "Disabling extension."; DisableExtension(app->id()); LOG(INFO) << "Disabling extension - done."; - content::WindowedNotificationObserver js_reload_observer2( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>( - &browser()->tab_strip_model()->GetActiveWebContents()-> - GetController())); + content::LoadStopObserver js_reload_observer2( + browser()->tab_strip_model()->GetActiveWebContents()); LOG(INFO) << "Executing location = location."; ASSERT_TRUE(content::ExecuteScript(contents, "location = location;")); js_reload_observer2.Wait(); @@ -659,11 +646,8 @@ // Crash the tab and reload it, chrome.app.isInstalled should still be true. content::CrashTab(browser()->tab_strip_model()->GetActiveWebContents()); - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>( - &browser()->tab_strip_model()->GetActiveWebContents()-> - GetController())); + content::LoadStopObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); observer.Wait(); ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
diff --git a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc index 963221e..5f40896 100644 --- a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc +++ b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc
@@ -16,7 +16,6 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/navigation_controller.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" @@ -473,12 +472,8 @@ extensions::TestExtensionRegistryObserver observer(GetExtensionRegistry()); { - content::WindowedNotificationObserver notification_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>(&browser() - ->tab_strip_model() - ->GetActiveWebContents() - ->GetController())); + content::LoadStopObserver notification_observer( + browser()->tab_strip_model()->GetActiveWebContents()); chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); notification_observer.Wait(); }
diff --git a/chrome/browser/extensions/isolated_app_browsertest.cc b/chrome/browser/extensions/isolated_app_browsertest.cc index f9506df..d1f44e6 100644 --- a/chrome/browser/extensions/isolated_app_browsertest.cc +++ b/chrome/browser/extensions/isolated_app_browsertest.cc
@@ -177,11 +177,8 @@ // Using JavaScript to navigate to app2 page, // after the non_app page has finished loading. - content::WindowedNotificationObserver observer1( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>( - &browser()->tab_strip_model()->GetActiveWebContents()-> - GetController())); + content::LoadStopObserver observer1( + browser()->tab_strip_model()->GetActiveWebContents()); std::string script = base::StringPrintf( "document.location.href=\"%s\";", base_url.Resolve("app2/main.html").spec().c_str()); @@ -283,11 +280,8 @@ // Check that isolation persists even if the tab crashes and is reloaded. chrome::SelectNumberedTab(browser(), 0); content::CrashTab(tab0); - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>( - &browser()->tab_strip_model()->GetActiveWebContents()-> - GetController())); + content::LoadStopObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); observer.Wait(); EXPECT_TRUE(HasCookie(tab0, "app1=3"));
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 67bbfda..a085cd5 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -605,17 +605,17 @@ { "name": "bookmark-bottom-sheet", "owners": [ "wylieb" ], - "expiry_milestone": 102 + "expiry_milestone": 107 }, { "name": "bookmarks-improved-save-flow", "owners": ["wylieb", "fgorski", "mdjones"], - "expiry_milestone": 102 + "expiry_milestone": 107 }, { "name": "bookmarks-refresh", "owners": ["wylieb", "fgorski", "mdjones"], - "expiry_milestone": 102 + "expiry_milestone": 107 }, { "name": "borealis-big-gl",
diff --git a/chrome/browser/local_discovery/OWNERS b/chrome/browser/local_discovery/OWNERS index be0f423b..1967bf5 100644 --- a/chrome/browser/local_discovery/OWNERS +++ b/chrome/browser/local_discovery/OWNERS
@@ -1 +1 @@ -file://cloud_print/OWNERS +thestig@chromium.org
diff --git a/chrome/browser/net/errorpage_browsertest.cc b/chrome/browser/net/errorpage_browsertest.cc index 668937cf..382c86c6 100644 --- a/chrome/browser/net/errorpage_browsertest.cc +++ b/chrome/browser/net/errorpage_browsertest.cc
@@ -57,8 +57,6 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/browsing_data_remover.h" #include "content/public/browser/navigation_handle.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/storage_partition.h" @@ -538,9 +536,7 @@ "document.body.appendChild(frame);"; { TestFailProvisionalLoadObserver fail_observer(wc); - content::WindowedNotificationObserver load_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>(&wc->GetController())); + content::LoadStopObserver load_observer(wc); wc->GetMainFrame()->ExecuteJavaScriptForTests(base::ASCIIToUTF16(script), base::NullCallback()); load_observer.Wait(); @@ -559,9 +555,7 @@ "frame.id = 'target_frame';" "document.body.appendChild(frame);"; { - content::WindowedNotificationObserver load_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>(&wc->GetController())); + content::LoadStopObserver load_observer(wc); wc->GetMainFrame()->ExecuteJavaScriptForTests(base::ASCIIToUTF16(script), base::NullCallback()); load_observer.Wait(); @@ -571,9 +565,7 @@ "f.src = '" + fail_url.spec() + "';"; { TestFailProvisionalLoadObserver fail_observer(wc); - content::WindowedNotificationObserver load_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>(&wc->GetController())); + content::LoadStopObserver load_observer(wc); wc->GetMainFrame()->ExecuteJavaScriptForTests(base::ASCIIToUTF16(script), base::NullCallback()); load_observer.Wait();
diff --git a/chrome/browser/paint_preview/paint_preview_browsertest.cc b/chrome/browser/paint_preview/paint_preview_browsertest.cc index ccacd925..68c7feec 100644 --- a/chrome/browser/paint_preview/paint_preview_browsertest.cc +++ b/chrome/browser/paint_preview/paint_preview_browsertest.cc
@@ -22,7 +22,6 @@ #include "components/paint_preview/common/serialized_recording.h" #include "components/paint_preview/common/test_utils.h" #include "components/ukm/test_ukm_recorder.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/render_process_host.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" @@ -143,10 +142,7 @@ // if the tab still has a pending navigation. auto* web_contents = GetWebContents(); if (web_contents->IsLoading()) { - content::WindowedNotificationObserver load_stop_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &web_contents->GetController())); + content::LoadStopObserver load_stop_observer(web_contents); load_stop_observer.Wait(); } }
diff --git a/chrome/browser/partnerbookmarks/BUILD.gn b/chrome/browser/partnerbookmarks/BUILD.gn new file mode 100644 index 0000000..613dc43 --- /dev/null +++ b/chrome/browser/partnerbookmarks/BUILD.gn
@@ -0,0 +1,30 @@ +# Copyright 2022 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/config/android/rules.gni") + +android_library("delegate_java") { + sources = [ + "java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarkIterator.java", + "java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksDelegate.java", + "java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksDelegateImpl.java", + ] + + deps = [ "//third_party/androidx:androidx_annotation_annotation_java" ] + + resources_package = "org.chromium.chrome.browser.partnerbookmarks" + + # Add the actual implementation where necessary so that downstream targets + # can provide their own implementations. + jar_excluded_patterns = [ "*/PartnerBookmarksDelegateImpl.class" ] +} + +android_library("delegate_public_impl_java") { + sources = [ "java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksDelegateImpl.java" ] + + deps = [ + ":delegate_java", + "//third_party/androidx:androidx_annotation_annotation_java", + ] +}
diff --git a/chrome/browser/partnerbookmarks/COMMON_METADATA b/chrome/browser/partnerbookmarks/COMMON_METADATA new file mode 100644 index 0000000..dd75416 --- /dev/null +++ b/chrome/browser/partnerbookmarks/COMMON_METADATA
@@ -0,0 +1,4 @@ +monorail { + component: "UI>Browser>Bookmarks" +} +os: ANDROID \ No newline at end of file
diff --git a/cloud_print/DIR_METADATA b/chrome/browser/partnerbookmarks/DIR_METADATA similarity index 85% rename from cloud_print/DIR_METADATA rename to chrome/browser/partnerbookmarks/DIR_METADATA index 5a10f9d..db0b302 100644 --- a/cloud_print/DIR_METADATA +++ b/chrome/browser/partnerbookmarks/DIR_METADATA
@@ -6,4 +6,4 @@ # For the schema of this file, see Metadata message: # https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto -mixins: "//cloud_print/COMMON_METADATA" +mixins: "//chrome/browser/partnerbookmarks/COMMON_METADATA"
diff --git a/chrome/browser/partnerbookmarks/OWNERS b/chrome/browser/partnerbookmarks/OWNERS new file mode 100644 index 0000000..728ebe2 --- /dev/null +++ b/chrome/browser/partnerbookmarks/OWNERS
@@ -0,0 +1,3 @@ +bttk@chromium.org +wychen@chromium.org +wylieb@chromium.org
diff --git a/chrome/browser/partnerbookmarks/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarkIterator.java b/chrome/browser/partnerbookmarks/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarkIterator.java new file mode 100644 index 0000000..f4d1c23 --- /dev/null +++ b/chrome/browser/partnerbookmarks/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarkIterator.java
@@ -0,0 +1,8 @@ +// Copyright 2022 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.partnerbookmarks; + +/** For now a placeholder. Intended to replace {@link PartnerBookmark.BookmarkIterator}. */ +public interface PartnerBookmarkIterator {}
diff --git a/chrome/browser/partnerbookmarks/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksDelegate.java b/chrome/browser/partnerbookmarks/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksDelegate.java new file mode 100644 index 0000000..c4c9d4c7 --- /dev/null +++ b/chrome/browser/partnerbookmarks/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksDelegate.java
@@ -0,0 +1,17 @@ +// Copyright 2022 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.partnerbookmarks; + +import androidx.annotation.Nullable; + +/** + * Base class for defining methods where different behavior is required by downstream targets. + * The correct version of {@link PartnerBookmarksDelegateImpl} will be determined at compile time + * via build rules. + */ +public interface PartnerBookmarksDelegate { + @Nullable + PartnerBookmarkIterator createIterator(); +} \ No newline at end of file
diff --git a/chrome/browser/partnerbookmarks/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksDelegateImpl.java b/chrome/browser/partnerbookmarks/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksDelegateImpl.java new file mode 100644 index 0000000..f5d90b5 --- /dev/null +++ b/chrome/browser/partnerbookmarks/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksDelegateImpl.java
@@ -0,0 +1,16 @@ +// Copyright 2022 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.partnerbookmarks; + +import androidx.annotation.Nullable; + +/** Default {@link PartnerBookmarksDelegate} implementation. */ +public class PartnerBookmarksDelegateImpl implements PartnerBookmarksDelegate { + @Override + @Nullable + public PartnerBookmarkIterator createIterator() { + return null; + } +} \ No newline at end of file
diff --git a/chrome/browser/password_manager/android/BUILD.gn b/chrome/browser/password_manager/android/BUILD.gn index e78de97d..d2145ba 100644 --- a/chrome/browser/password_manager/android/BUILD.gn +++ b/chrome/browser/password_manager/android/BUILD.gn
@@ -6,7 +6,6 @@ java_cpp_enum("android_backend_java_enums_srcjar") { sources = [ - "android_backend_error.h", "chromesync_status_code.h", "password_manager_setting.h", "password_store_operation_target.h", @@ -27,8 +26,6 @@ ] sources = [ - "android_backend_error.cc", - "android_backend_error.h", "password_manager_lifecycle_helper.cc", "password_manager_lifecycle_helper.h", "password_manager_lifecycle_helper_impl.cc", @@ -223,6 +220,7 @@ deps = [ ":android_backend_java_enums", "//base:base_java", + "//components/password_manager/core/browser:password_manager_java_enums", "//third_party/android_deps:guava_android_java", ] sources = [
diff --git a/chrome/browser/password_manager/android/password_store_android_backend_bridge.h b/chrome/browser/password_manager/android/password_store_android_backend_bridge.h index 94353cf18..086ca40 100644 --- a/chrome/browser/password_manager/android/password_store_android_backend_bridge.h +++ b/chrome/browser/password_manager/android/password_store_android_backend_bridge.h
@@ -8,8 +8,8 @@ #include <vector> #include "base/types/strong_alias.h" -#include "chrome/browser/password_manager/android/android_backend_error.h" #include "chrome/browser/password_manager/android/password_store_operation_target.h" +#include "components/password_manager/core/browser/android_backend_error.h" #include "components/password_manager/core/browser/password_form.h" #include "components/password_manager/core/browser/password_store_change.h"
diff --git a/chrome/browser/password_manager/android/password_sync_controller_delegate_android.cc b/chrome/browser/password_manager/android/password_sync_controller_delegate_android.cc index 8e8414dc..c9ae0d0 100644 --- a/chrome/browser/password_manager/android/password_sync_controller_delegate_android.cc +++ b/chrome/browser/password_manager/android/password_sync_controller_delegate_android.cc
@@ -6,8 +6,9 @@ #include "base/memory/weak_ptr.h" #include "base/metrics/histogram_functions.h" -#include "chrome/browser/password_manager/android/android_backend_error.h" +#include "components/password_manager/core/browser/android_backend_error.h" #include "components/password_manager/core/browser/password_sync_util.h" +#include "components/sync/base/user_selectable_type.h" #include "components/sync/driver/sync_service.h" #include "components/sync/engine/data_type_activation_response.h" #include "components/sync/model/model_type_controller_delegate.h"
diff --git a/chrome/browser/password_manager/android/password_sync_controller_delegate_android_unittest.cc b/chrome/browser/password_manager/android/password_sync_controller_delegate_android_unittest.cc index 1123fe2..cd32bf52 100644 --- a/chrome/browser/password_manager/android/password_sync_controller_delegate_android_unittest.cc +++ b/chrome/browser/password_manager/android/password_sync_controller_delegate_android_unittest.cc
@@ -8,8 +8,8 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" -#include "chrome/browser/password_manager/android/android_backend_error.h" #include "chrome/browser/password_manager/android/mock_password_sync_controller_delegate_bridge.h" +#include "components/password_manager/core/browser/android_backend_error.h" #include "components/password_manager/core/browser/mock_password_store_backend.h" #include "components/sync/driver/test_sync_service.h" #include "components/sync/engine/data_type_activation_response.h"
diff --git a/chrome/browser/password_manager/android/password_sync_controller_delegate_bridge_impl.cc b/chrome/browser/password_manager/android/password_sync_controller_delegate_bridge_impl.cc index 1e684fe..a001831 100644 --- a/chrome/browser/password_manager/android/password_sync_controller_delegate_bridge_impl.cc +++ b/chrome/browser/password_manager/android/password_sync_controller_delegate_bridge_impl.cc
@@ -5,8 +5,8 @@ #include "chrome/browser/password_manager/android/password_sync_controller_delegate_bridge_impl.h" #include "base/android/jni_android.h" -#include "chrome/browser/password_manager/android/android_backend_error.h" #include "chrome/browser/password_manager/android/jni_headers/PasswordSyncControllerDelegateBridgeImpl_jni.h" +#include "components/password_manager/core/browser/android_backend_error.h" #include "components/password_manager/core/common/password_manager_features.h" using password_manager::AndroidBackendError;
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index de360a1..2674f8da 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -185,6 +185,11 @@ #include "chrome/browser/ui/side_search/side_search_prefs.h" #endif // BUILDFLAG(ENABLE_SIDE_SEARCH) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_FUCHSIA) +#include "chrome/browser/web_applications/policy/web_app_settings_policy_handler.h" +#endif + namespace policy { namespace { @@ -2265,11 +2270,8 @@ #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ BUILDFLAG(IS_FUCHSIA) - handlers->AddHandler(std::make_unique<SimpleSchemaValidatingPolicyHandler>( - key::kWebAppSettings, prefs::kWebAppSettings, chrome_schema, - SCHEMA_ALLOW_UNKNOWN, - SimpleSchemaValidatingPolicyHandler::RECOMMENDED_PROHIBITED, - SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED)); + handlers->AddHandler( + std::make_unique<web_app::WebAppSettingsPolicyHandler>(chrome_schema)); #endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || // BUILDFLAG(IS_FUCHSIA)
diff --git a/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder_unittest.cc b/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder_unittest.cc index 6e62e55..6375f03 100644 --- a/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder_unittest.cc +++ b/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder_unittest.cc
@@ -166,7 +166,9 @@ // Finish correctly setting encryption info - expect complete call. encryption_info->set_public_key_id(1234); - EXPECT_TRUE(EncryptedRecordDictionaryBuilder(record).Build().has_value()); + const auto record_dict = EncryptedRecordDictionaryBuilder(record).Build(); + ASSERT_TRUE(record_dict.has_value()); + EXPECT_THAT(record_dict.value(), IsRecordValid<>()); } TEST_P(RecordUploadRequestBuilderTest, AcceptRequestId) { @@ -202,24 +204,29 @@ TEST_P(RecordUploadRequestBuilderTest, DontBuildCompressionRequestIfNoInformation) { EncryptedRecord compressionless_record = GenerateEncryptedRecord("TEST_INFO"); - EXPECT_FALSE(compressionless_record.has_compression_information()); + ASSERT_FALSE(compressionless_record.has_compression_information()); absl::optional<base::Value::Dict> compressionless_payload = EncryptedRecordDictionaryBuilder(std::move(compressionless_record)) .Build(); ASSERT_TRUE(compressionless_payload.has_value()); + EXPECT_THAT(compressionless_payload.value(), IsRecordValid<>()); EXPECT_FALSE(compressionless_payload.value().Find( EncryptedRecordDictionaryBuilder::GetCompressionInformationPath())); EncryptedRecord compressed_record = GenerateEncryptedRecord("TEST_INFO", true); - EXPECT_TRUE(compressed_record.has_compression_information()); + ASSERT_TRUE(compressed_record.has_compression_information()); absl::optional<base::Value::Dict> compressed_record_payload = EncryptedRecordDictionaryBuilder(std::move(compressed_record)).Build(); ASSERT_TRUE(compressed_record_payload.has_value()); - EXPECT_TRUE(compressed_record_payload.value().Find( - EncryptedRecordDictionaryBuilder::GetCompressionInformationPath())); + EXPECT_THAT( + compressed_record_payload.value(), + RequestValidityMatcherBuilder<>::CreateRecord() + .AppendMatcher(RecordMatcher::SetMode( + CompressionInformationMatcher(), RecordMatcher::Mode::RecordOnly)) + .Build()); } INSTANTIATE_TEST_SUITE_P(NeedOrNoNeedKey,
diff --git a/chrome/browser/policy/messaging_layer/util/test.cc b/chrome/browser/policy/messaging_layer/util/test.cc index cf32c5b..062a7ad 100644 --- a/chrome/browser/policy/messaging_layer/util/test.cc +++ b/chrome/browser/policy/messaging_layer/util/test.cc
@@ -89,6 +89,18 @@ return "no-attach-encryption-settings-matcher"; } +void CompressionInformationMatcher::DescribeTo(std::ostream* os) const { + *os << "has a valid compression information field."; +} + +void CompressionInformationMatcher::DescribeNegationTo(std::ostream* os) const { + *os << "has an invalid compression information field."; +} + +std::string CompressionInformationMatcher::Name() const { + return "encrypted-record-matcher"; +} + bool EncryptedRecordMatcher::MatchAndExplain( const base::Value::Dict& arg, MatchResultListener* listener) const { @@ -143,21 +155,70 @@ bool RecordMatcher::MatchAndExplain(const base::Value::Dict& arg, MatchResultListener* listener) const { - const auto* record_list = GetRecordList(arg, listener); - if (record_list == nullptr) { + switch (mode_) { + case Mode::FullRequest: { + const auto* record_list = GetRecordList(arg, listener); + if (record_list == nullptr) { + return false; + } + + for (const auto& record : *record_list) { + const auto* record_dict = record.GetIfDict(); + if (record_dict == nullptr) { + *listener << "Record " << record << " is not a dict."; + return false; + } + if (!this->MatchAndExplainRecord(*record_dict, listener)) { + return false; + } + } + return true; + } + case Mode::RecordOnly: { + return this->MatchAndExplainRecord(arg, listener); + } + default: { + // Should never reach here. + *listener << "Invalid mode of RecordMatcher encountered: " + << static_cast<std::underlying_type_t<Mode>>(mode_); + return false; + } + } +} + +RecordMatcher& RecordMatcher::SetMode(RecordMatcher::Mode mode) { + mode_ = mode; + return *this; +} + +bool CompressionInformationMatcher::MatchAndExplainRecord( + const base::Value::Dict& record, + MatchResultListener* listener) const { + const auto* const compression_info = + record.FindDict("compressionInformation"); + if (compression_info == nullptr) { + *listener << "No key named \"compressionInformation\" or the value is " + "not a dict in record " + << record << '.'; return false; } - for (const auto& record : *record_list) { - const auto* record_dict = record.GetIfDict(); - if (record_dict == nullptr) { - *listener << "Record " << record << " is not a dict."; - return false; - } - if (!this->MatchAndExplainRecord(*record_dict, listener)) { - return false; - } + const auto compression_algorithm = + compression_info->FindInt("compressionAlgorithm"); + if (!compression_algorithm.has_value()) { + *listener << "No key named \"compressionAlgorithm\" under " + "compressionInformation " + "or the value is not an integer in record " + << record << '.'; + return false; } + if (compression_algorithm.value() > 1 || compression_algorithm < 0) { + *listener << "The value of \"compressionInformation/compressionAlgorithm\" " + "is neither 0 nor 1 in record " + << record << '.'; + return false; + } + return true; }
diff --git a/chrome/browser/policy/messaging_layer/util/test.h b/chrome/browser/policy/messaging_layer/util/test.h index 4573bac2..c38f4c69 100644 --- a/chrome/browser/policy/messaging_layer/util/test.h +++ b/chrome/browser/policy/messaging_layer/util/test.h
@@ -84,11 +84,38 @@ // Base class of all matchers that verify one aspect of a record. class RecordMatcher : public RequestValidityMatcherInterface { public: + enum class Mode : char { + // The default. Match the content of each record in a full request payload + // in "encryptedRecord". The argument is a dict that represents a full + // request payload. This is typically switched on if the test case is + // verifying a full request payload. + FullRequest = 'f', + // Directly match the content of a single record assuming no + // "encryptedRecord" key wrapping it. The argument is a dict that contains + // the record. This is typically switched on if the test case is verifying a + // single record. + RecordOnly = 'r' + }; bool MatchAndExplain(const base::Value::Dict& arg, MatchResultListener* listener) const final; // Match and explain the given record. virtual bool MatchAndExplainRecord(const base::Value::Dict& arg, MatchResultListener* listener) const = 0; + // Change mode. See the doc of |Mode| above. + RecordMatcher& SetMode(Mode mode); + + // A helper function that calls |SetMode| above and casts the type back to the + // derived class. + template <class DerivedRecordMatcher> + static DerivedRecordMatcher& SetMode(DerivedRecordMatcher record_matcher, + Mode mode) { + static_assert(std::is_base_of<RecordMatcher, DerivedRecordMatcher>::value, + "record_matcher must be of type RecordMatcher."); + return static_cast<DerivedRecordMatcher&>(record_matcher.SetMode(mode)); + } + + private: + Mode mode_ = Mode::FullRequest; }; // Verify the encryptedWrappedRecord field of each record. @@ -121,6 +148,16 @@ std::string Name() const override; }; +// Verify the compressionInformation field of each record. +class CompressionInformationMatcher : public RecordMatcher { + public: + bool MatchAndExplainRecord(const base::Value::Dict& arg, + MatchResultListener* listener) const override; + void DescribeTo(std::ostream* os) const override; + void DescribeNegationTo(std::ostream* os) const override; + std::string Name() const override; +}; + // Build a matcher that can be used to verify the general validity of a // request matcher while accommodating the variety of requirements (e.g., // some verification must be loosen because the request is intentionally @@ -184,6 +221,18 @@ } // Creates and returns a |RequestValidityMatcherBuilder| instance that + // contains a matcher that is suited for verifying a single record. + static RequestValidityMatcherBuilder<T> CreateRecord() { + return std::move(RequestValidityMatcherBuilder<T>::CreateEmpty() + .AppendMatcher(RecordMatcher::SetMode( + EncryptedWrappedRecordRecordMatcher(), + RecordMatcher::Mode::RecordOnly)) + .AppendMatcher(RecordMatcher::SetMode( + SequenceInformationRecordMatcher(), + RecordMatcher::Mode::RecordOnly))); + } + + // Creates and returns a |RequestValidityMatcherBuilder| instance that // contains a matcher that is suited for verifying a gap upload request. static RequestValidityMatcherBuilder<T> CreateGapUpload() { // A gap upload is a data upload with no encryptedWrappedRecord. @@ -196,8 +245,7 @@ // Builds and returns the |Matcher<T>| object. [[nodiscard]] Matcher<T> Build() const { return AllOfArray(matchers_); } - // Append a matcher. This object will take over the ownership of matcher and - // matcher must be allocated on heap (e.g., by using the "new" operator). + // Append a matcher. template <class RequestValidityMatcher> RequestValidityMatcherBuilder<T>& AppendMatcher( const RequestValidityMatcher& matcher) { @@ -291,6 +339,12 @@ return RequestValidityMatcherBuilder<T>::CreateGapUpload().Build(); } +// Match a single record within a payload that is valid. +template <class T = base::Value::Dict> +Matcher<T> IsRecordValid() { + return RequestValidityMatcherBuilder<T>::CreateRecord().Build(); +} + // Match a request that contains the given record |matched_record_json|. The // match will be successful as long as any record in the request contains // |matched_record_json| as a sub-dictionary -- they are not required to equal.
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java index d8aec50..f791de6 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -311,6 +311,8 @@ public static final String DOWNLOAD_FOREGROUND_SERVICE_OBSERVERS = "ForegroundServiceObservers"; public static final String DOWNLOAD_IS_DOWNLOAD_HOME_ENABLED = "org.chromium.chrome.browser.download.IS_DOWNLOAD_HOME_ENABLED"; + public static final String DOWNLOAD_INTERSTITIAL_DOWNLOAD_PENDING_REMOVAL = + "Chrome.DownloadInterstitial.PendingRemoval"; public static final String DOWNLOAD_NEXT_DOWNLOAD_NOTIFICATION_ID = "NextDownloadNotificationId"; public static final String DOWNLOAD_PENDING_DOWNLOAD_NOTIFICATIONS = @@ -1043,6 +1045,7 @@ DEFAULT_BROWSER_PROMO_PROMOED_BY_SYSTEM_SETTINGS, DEFAULT_BROWSER_PROMO_PROMOED_COUNT, DEFAULT_BROWSER_PROMO_SESSION_COUNT, + DOWNLOAD_INTERSTITIAL_DOWNLOAD_PENDING_REMOVAL, EXPLORE_OFFLINE_CONTENT_AVAILABILITY_STATUS, FEED_ARTICLES_LIST_VISIBLE, FIRST_RUN_FIELD_TRIAL_GROUP,
diff --git a/chrome/browser/printing/print_backend_service_manager.cc b/chrome/browser/printing/print_backend_service_manager.cc index ef24d1b..7df299af 100644 --- a/chrome/browser/printing/print_backend_service_manager.cc +++ b/chrome/browser/printing/print_backend_service_manager.cc
@@ -27,8 +27,10 @@ #include "printing/backend/print_backend.h" #if BUILDFLAG(IS_WIN) +#include "base/win/win_util.h" #include "printing/backend/win_helper.h" #include "printing/printed_page_win.h" +#include "ui/views/win/hwnd_util.h" #endif namespace printing { @@ -58,6 +60,14 @@ return 0; } +#if BUILDFLAG(IS_WIN) +// TODO(crbug.com/809738): Update for other platforms as they are made able +// to support modal dialogs from OOP. +uint32_t NativeViewToUint(gfx::NativeView view) { + return base::win::HandleToUint32(views::HWNDForNativeView(view)); +} +#endif + } // namespace PrintBackendServiceManager::PrintBackendServiceManager() = default; @@ -242,6 +252,32 @@ base::Unretained(this), context)); } +#if BUILDFLAG(IS_WIN) +void PrintBackendServiceManager::AskUserForSettings( + const std::string& printer_name, + gfx::NativeView parent_view, + int max_pages, + bool has_selection, + bool is_scripted, + mojom::PrintBackendService::AskUserForSettingsCallback callback) { + CallbackContext context; + auto& service = GetServiceAndCallbackContext( + printer_name, ClientType::kQueryWithUi, context); + + SaveCallback(GetRemoteSavedAskUserForSettingsCallbacks(context.is_sandboxed), + context.remote_id, context.saved_callback_id, + std::move(callback)); + + SetCrashKeys(printer_name); + + LogCallToRemote("AskUserForSettings", context); + service->AskUserForSettings( + NativeViewToUint(parent_view), max_pages, has_selection, is_scripted, + base::BindOnce(&PrintBackendServiceManager::OnDidAskUserForSettings, + base::Unretained(this), context)); +} +#endif // BUILDFLAG(IS_WIN) + void PrintBackendServiceManager::UpdatePrintSettings( const std::string& printer_name, base::flat_map<std::string, base::Value> job_settings, @@ -819,6 +855,11 @@ RunSavedCallbacksStructResult( GetRemoteSavedUseDefaultSettingsCallbacks(sandboxed), remote_id, mojom::PrintSettingsResult::NewResultCode(mojom::ResultCode::kFailed)); +#if BUILDFLAG(IS_WIN) + RunSavedCallbacksStructResult( + GetRemoteSavedAskUserForSettingsCallbacks(sandboxed), remote_id, + mojom::PrintSettingsResult::NewResultCode(mojom::ResultCode::kFailed)); +#endif RunSavedCallbacksStructResult( GetRemoteSavedUpdatePrintSettingsCallbacks(sandboxed), remote_id, mojom::PrintSettingsResult::NewResultCode(mojom::ResultCode::kFailed)); @@ -870,6 +911,15 @@ : unsandboxed_saved_use_default_settings_callbacks_; } +#if BUILDFLAG(IS_WIN) +PrintBackendServiceManager::RemoteSavedAskUserForSettingsCallbacks& +PrintBackendServiceManager::GetRemoteSavedAskUserForSettingsCallbacks( + bool sandboxed) { + return sandboxed ? sandboxed_saved_ask_user_for_settings_callbacks_ + : unsandboxed_saved_ask_user_for_settings_callbacks_; +} +#endif + PrintBackendServiceManager::RemoteSavedUpdatePrintSettingsCallbacks& PrintBackendServiceManager::GetRemoteSavedUpdatePrintSettingsCallbacks( bool sandboxed) { @@ -986,6 +1036,17 @@ context.remote_id, context.saved_callback_id, std::move(settings)); } +#if BUILDFLAG(IS_WIN) +void PrintBackendServiceManager::OnDidAskUserForSettings( + const CallbackContext& context, + mojom::PrintSettingsResultPtr settings) { + LogCallbackFromRemote("AskUserForSettings", context); + ServiceCallbackDone( + GetRemoteSavedAskUserForSettingsCallbacks(context.is_sandboxed), + context.remote_id, context.saved_callback_id, std::move(settings)); +} +#endif // BUILDFLAG(IS_WIN) + void PrintBackendServiceManager::OnDidUpdatePrintSettings( const CallbackContext& context, mojom::PrintSettingsResultPtr settings) {
diff --git a/chrome/browser/printing/print_backend_service_manager.h b/chrome/browser/printing/print_backend_service_manager.h index 9b511ea..d5a1ca8 100644 --- a/chrome/browser/printing/print_backend_service_manager.h +++ b/chrome/browser/printing/print_backend_service_manager.h
@@ -21,6 +21,10 @@ #include "printing/buildflags/buildflags.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#if BUILDFLAG(IS_WIN) +#include "ui/gfx/native_widget_types.h" +#endif + #if !BUILDFLAG(ENABLE_OOP_PRINTING) #error "Out-of-process printing must be enabled." #endif @@ -85,6 +89,15 @@ void UseDefaultSettings( const std::string& printer_name, mojom::PrintBackendService::UseDefaultSettingsCallback callback); +#if BUILDFLAG(IS_WIN) + void AskUserForSettings( + const std::string& printer_name, + gfx::NativeView parent_view, + int max_pages, + bool has_selection, + bool is_scripted, + mojom::PrintBackendService::AskUserForSettingsCallback callback); +#endif void UpdatePrintSettings( const std::string& printer_name, base::flat_map<std::string, base::Value> job_settings, @@ -187,6 +200,10 @@ RemoteSavedStructCallbacks<mojom::PrinterSemanticCapsAndDefaultsResult>; using RemoteSavedUseDefaultSettingsCallbacks = RemoteSavedStructCallbacks<mojom::PrintSettingsResult>; +#if BUILDFLAG(IS_WIN) + using RemoteSavedAskUserForSettingsCallbacks = + RemoteSavedStructCallbacks<mojom::PrintSettingsResult>; +#endif using RemoteSavedUpdatePrintSettingsCallbacks = RemoteSavedStructCallbacks<mojom::PrintSettingsResult>; using RemoteSavedStartPrintingCallbacks = @@ -314,6 +331,10 @@ GetRemoteSavedGetPrinterSemanticCapsAndDefaultsCallbacks(bool sandboxed); RemoteSavedUseDefaultSettingsCallbacks& GetRemoteSavedUseDefaultSettingsCallbacks(bool sandboxed); +#if BUILDFLAG(IS_WIN) + RemoteSavedAskUserForSettingsCallbacks& + GetRemoteSavedAskUserForSettingsCallbacks(bool sandboxed); +#endif RemoteSavedUpdatePrintSettingsCallbacks& GetRemoteSavedUpdatePrintSettingsCallbacks(bool sandboxed); RemoteSavedStartPrintingCallbacks& GetRemoteSavedStartPrintingCallbacks( @@ -360,6 +381,10 @@ mojom::PrinterSemanticCapsAndDefaultsResultPtr printer_caps); void OnDidUseDefaultSettings(const CallbackContext& context, mojom::PrintSettingsResultPtr settings); +#if BUILDFLAG(IS_WIN) + void OnDidAskUserForSettings(const CallbackContext& context, + mojom::PrintSettingsResultPtr settings); +#endif void OnDidUpdatePrintSettings(const CallbackContext& context, mojom::PrintSettingsResultPtr printer_caps); void OnDidStartPrinting(const CallbackContext& context, @@ -434,6 +459,12 @@ sandboxed_saved_use_default_settings_callbacks_; RemoteSavedUseDefaultSettingsCallbacks unsandboxed_saved_use_default_settings_callbacks_; +#if BUILDFLAG(IS_WIN) + RemoteSavedAskUserForSettingsCallbacks + sandboxed_saved_ask_user_for_settings_callbacks_; + RemoteSavedAskUserForSettingsCallbacks + unsandboxed_saved_ask_user_for_settings_callbacks_; +#endif RemoteSavedUpdatePrintSettingsCallbacks sandboxed_saved_update_print_settings_callbacks_; RemoteSavedUpdatePrintSettingsCallbacks
diff --git a/chrome/browser/printing/print_dialog_cloud_win.cc b/chrome/browser/printing/print_dialog_cloud_win.cc deleted file mode 100644 index e1f8dd52..0000000 --- a/chrome/browser/printing/print_dialog_cloud_win.cc +++ /dev/null
@@ -1,164 +0,0 @@ -// 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 "chrome/browser/printing/print_dialog_cloud_win.h" - -#include <stddef.h> -#include <stdint.h> - -#include "base/base64.h" -#include "base/bind.h" -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/json/json_writer.h" -#include "base/memory/ref_counted_memory.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" -#include "base/task/thread_pool.h" -#include "base/threading/thread_task_runner_handle.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" -#include "chrome/common/chrome_switches.h" -#include "components/cloud_devices/common/cloud_devices_urls.h" -#include "components/google/core/common/google_util.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/message_port_provider.h" -#include "content/public/browser/render_frame_host.h" - -namespace print_dialog_cloud { - -namespace { - -// Limit is used only to allocate memory. Cloud has own small limit. -const int kMaxFileSize = 1024 * 1024 * 1024; - -// Sets print data into Cloud Print widget. -class PrintDataSetter : public content::WebContentsObserver { - public: - PrintDataSetter(content::WebContents* web_contents, - scoped_refptr<base::RefCountedMemory> data, - const std::wstring& print_job_title, - const std::wstring& print_ticket, - const std::string& file_type) - : WebContentsObserver(web_contents) { - DCHECK_NE(data->size(), 0u); - std::string base64_data; - base::Base64Encode(base::StringPiece(data->front_as<char>(), data->size()), - &base64_data); - std::string header("data:"); - header.append(file_type); - header.append(";base64,"); - base64_data.insert(0, header); - - base::DictionaryValue message_data; - message_data.SetString("type", "dataUrl"); - message_data.SetString("title", base::AsString16(print_job_title)); - message_data.SetString("content", base64_data); - std::string json_data; - base::JSONWriter::Write(message_data, &json_data); - message_data_ = u"cp-dialog-set-print-document::"; - message_data_.append(base::UTF8ToUTF16(json_data)); - } - - PrintDataSetter(const PrintDataSetter&) = delete; - PrintDataSetter& operator=(const PrintDataSetter&) = delete; - - private: - // Overridden from content::WebContentsObserver: - void DOMContentLoaded(content::RenderFrameHost* render_frame_host) override { - GURL url = web_contents()->GetURL(); - if (cloud_devices::IsCloudPrintURL(url)) { - std::u16string origin = - base::UTF8ToUTF16(url.DeprecatedGetOriginAsURL().spec()); - content::MessagePortProvider::PostMessageToFrame( - web_contents()->GetPrimaryPage(), origin, origin, message_data_); - } - } - - void WebContentsDestroyed() override { delete this; } - - std::u16string message_data_; -}; - -void CreatePrintDialog(content::BrowserContext* browser_context, - const std::wstring& print_job_title, - const std::wstring& print_ticket, - const std::string& file_type, - scoped_refptr<base::RefCountedMemory> data) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - Profile* profile = Profile::FromBrowserContext(browser_context); - chrome::ScopedTabbedBrowserDisplayer displayer(profile); - GURL url = cloud_devices::GetCloudPrintRelativeURL("client/dialog.html"); - content::WebContents* web_contents = - displayer.browser()->OpenURL(content::OpenURLParams( - google_util::AppendGoogleLocaleParam( - url, g_browser_process->GetApplicationLocale()), - content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB, - ui::PAGE_TRANSITION_AUTO_BOOKMARK, false)); - if (data && data->size()) { - new PrintDataSetter(web_contents, data, print_job_title, print_ticket, - file_type); - } -} - -scoped_refptr<base::RefCountedMemory> ReadFile( - const base::FilePath& path_to_file) { - scoped_refptr<base::RefCountedMemory> data; - int64_t file_size = 0; - if (base::GetFileSize(path_to_file, &file_size) && file_size != 0) { - if (file_size > kMaxFileSize) { - DLOG(WARNING) << " print data file too large to reserve space"; - return data; - } - std::string file_data; - file_data.reserve(static_cast<size_t>(file_size)); - if (base::ReadFileToString(path_to_file, &file_data)) - data = base::RefCountedString::TakeString(&file_data); - } - base::DeleteFile(path_to_file); - return data; -} - -void CreatePrintDialogForFile(content::BrowserContext* browser_context, - const base::FilePath& path_to_file, - const std::wstring& print_job_title, - const std::wstring& print_ticket, - const std::string& file_type) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING}, - base::BindOnce(&ReadFile, path_to_file), - base::BindOnce(&CreatePrintDialog, browser_context, print_job_title, - print_ticket, file_type)); -} - -} // namespace - -bool CreatePrintDialogFromCommandLine(Profile* profile, - const base::CommandLine& command_line) { - base::FilePath cloud_print_file = - command_line.GetSwitchValuePath(switches::kCloudPrintFile); - DCHECK(!cloud_print_file.empty()); - if (cloud_print_file.empty()) - return false; - std::wstring print_job_title = - command_line.GetSwitchValueNative(switches::kCloudPrintJobTitle); - std::wstring print_job_print_ticket = - command_line.GetSwitchValueNative(switches::kCloudPrintPrintTicket); - std::string file_type = - command_line.GetSwitchValueASCII(switches::kCloudPrintFileType); - if (file_type.empty()) - file_type = "application/pdf"; - CreatePrintDialogForFile(profile, cloud_print_file, print_job_title, - print_job_print_ticket, file_type); - return true; -} - -} // namespace print_dialog_cloud
diff --git a/chrome/browser/printing/print_dialog_cloud_win.h b/chrome/browser/printing/print_dialog_cloud_win.h deleted file mode 100644 index e2a6753..0000000 --- a/chrome/browser/printing/print_dialog_cloud_win.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PRINTING_PRINT_DIALOG_CLOUD_WIN_H_ -#define CHROME_BROWSER_PRINTING_PRINT_DIALOG_CLOUD_WIN_H_ - -class Profile; - -namespace base { -class CommandLine; -} - -namespace print_dialog_cloud { - -// Parse switches from command_line and display the print dialog as appropriate. -bool CreatePrintDialogFromCommandLine(Profile* profile, - const base::CommandLine& command_line); - -} // namespace print_dialog_cloud - -#endif // CHROME_BROWSER_PRINTING_PRINT_DIALOG_CLOUD_WIN_H_
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 5c60bd2..671a217 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -35,6 +35,7 @@ #include "chrome/browser/download/background_download_service_factory.h" #include "chrome/browser/download/download_core_service_factory.h" #include "chrome/browser/engagement/site_engagement_service_factory.h" +#include "chrome/browser/enterprise/reporting/cloud_profile_reporting_service_factory.h" #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/favicon/history_ui_favicon_request_handler_factory.h" #include "chrome/browser/feature_engagement/tracker_factory.h" @@ -444,6 +445,10 @@ #if !BUILDFLAG(IS_CHROMEOS_ASH) policy::UserPolicySigninServiceFactory::GetInstance(); #endif + +#if !BUILDFLAG(IS_CHROMEOS_ASH) + enterprise_reporting::CloudProfileReportingServiceFactory::GetInstance(); +#endif #if BUILDFLAG(BUILD_WITH_TFLITE_LIB) if (base::FeatureList::IsEnabled( permissions::features::kPermissionOnDeviceNotificationPredictions)) {
diff --git a/chrome/browser/resources/new_tab_page/customize_modules.ts b/chrome/browser/resources/new_tab_page/customize_modules.ts index e06638b2..9d8c321e 100644 --- a/chrome/browser/resources/new_tab_page/customize_modules.ts +++ b/chrome/browser/resources/new_tab_page/customize_modules.ts
@@ -111,16 +111,18 @@ }); }); NewTabPageProxy.getInstance().handler.updateDisabledModules(); - this.set( - 'discountToggleEligible_', - loadTimeData.getBoolean('ruleBasedDiscountEnabled')); - if (!this.discountToggleEligible_) { - return; + + if (this.modules_.some(module => module.id === 'chrome_cart')) { + ChromeCartProxy.getHandler().getDiscountToggleVisible().then( + ({toggleVisible}) => { + this.set('discountToggleEligible_', toggleVisible); + }); + + ChromeCartProxy.getHandler().getDiscountEnabled().then(({enabled}) => { + this.set('discountToggle_.enabled', enabled); + this.discountToggle_.initiallyEnabled = enabled; + }); } - ChromeCartProxy.getHandler().getDiscountEnabled().then(({enabled}) => { - this.set('discountToggle_.enabled', enabled); - this.discountToggle_.initiallyEnabled = enabled; - }); } override disconnectedCallback() {
diff --git a/chrome/browser/resources/new_tab_page/modules/modules.ts b/chrome/browser/resources/new_tab_page/modules/modules.ts index fb1c65a73..7bc04e98 100644 --- a/chrome/browser/resources/new_tab_page/modules/modules.ts +++ b/chrome/browser/resources/new_tab_page/modules/modules.ts
@@ -14,7 +14,7 @@ import {loadTimeData} from '../i18n_setup.js'; import {NewTabPageProxy} from '../new_tab_page_proxy.js'; -import {ModuleHeight} from './module_descriptor.js'; +import {Module, ModuleHeight} from './module_descriptor.js'; import {ModuleRegistry} from './module_registry.js'; import {ModuleWrapperElement} from './module_wrapper.js'; import {getTemplate} from './modules.html.js'; @@ -264,11 +264,29 @@ moduleContainer.appendChild(moduleWrapper); return moduleContainer; }); + + chrome.metricsPrivate.recordSmallCount( + 'NewTabPage.Modules.LoadedModulesCount', modules.length); + + this.logModuleLoadedWithModules_(modules); this.appendModuleContainers_(moduleContainers); this.onModulesLoaded_(); } } + private logModuleLoadedWithModules_(modules: Module[]) { + const moduleDescriptorIds = modules.map(m => m.descriptor.id); + + for (const moduleDescriptorId of moduleDescriptorIds) { + moduleDescriptorIds.forEach(id => { + if (id !== moduleDescriptorId) { + chrome.metricsPrivate.recordSparseHashable( + `NewTabPage.Modules.LoadedWith.${moduleDescriptorId}`, id); + } + }); + } + } + private onWindowKeydown_(e: KeyboardEvent) { let ctrlKeyPressed = e.ctrlKey; // <if expr="is_macosx">
diff --git a/chrome/browser/resources/settings/autofill_page/password_remove_dialog.ts b/chrome/browser/resources/settings/autofill_page/password_remove_dialog.ts index 05343af..51090374 100644 --- a/chrome/browser/resources/settings/autofill_page/password_remove_dialog.ts +++ b/chrome/browser/resources/settings/autofill_page/password_remove_dialog.ts
@@ -16,6 +16,7 @@ import 'chrome://resources/cr_elements/shared_style_css.m.js'; import './avatar_icon.js'; +import {CrCheckboxElement} from 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js'; import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; import {assert} from 'chrome://resources/js/assert.m.js'; import {I18nMixin} from 'chrome://resources/js/i18n_mixin.js'; @@ -30,15 +31,19 @@ export type PasswordRemoveDialogPasswordsRemovedEvent = CustomEvent<{removedFromAccount: boolean, removedFromDevice: boolean}>; -interface PasswordRemoveDialogElement { +export interface PasswordRemoveDialogElement { $: { dialog: CrDialogElement, + removeButton: HTMLElement, + removeFromAccountCheckbox: CrCheckboxElement, + removeFromDeviceCheckbox: CrCheckboxElement, }; } const PasswordRemoveDialogElementBase = I18nMixin(PolymerElement); -class PasswordRemoveDialogElement extends PasswordRemoveDialogElementBase { +export class PasswordRemoveDialogElement extends + PasswordRemoveDialogElementBase { static get is() { return 'password-remove-dialog'; } @@ -135,5 +140,11 @@ } } +declare global { + interface HTMLElementTagNameMap { + 'password-remove-dialog': PasswordRemoveDialogElement; + } +} + customElements.define( PasswordRemoveDialogElement.is, PasswordRemoveDialogElement);
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_list_handler.ts b/chrome/browser/resources/settings/autofill_page/passwords_list_handler.ts index 3c055176..4691401 100644 --- a/chrome/browser/resources/settings/autofill_page/passwords_list_handler.ts +++ b/chrome/browser/resources/settings/autofill_page/passwords_list_handler.ts
@@ -55,7 +55,11 @@ $: { copyToast: CrToastElement, menu: CrActionMenuElement, + menuCopyPassword: HTMLElement, + menuEditPassword: HTMLElement, menuMovePasswordToAccount: HTMLElement, + menuRemovePassword: HTMLElement, + removalNotification: HTMLElement, removalToast: CrToastElement, }; }
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_section.ts b/chrome/browser/resources/settings/autofill_page/passwords_section.ts index 3bcd011d9..148f8db 100644 --- a/chrome/browser/resources/settings/autofill_page/passwords_section.ts +++ b/chrome/browser/resources/settings/autofill_page/passwords_section.ts
@@ -31,13 +31,14 @@ import './avatar_icon.js'; import {CrActionMenuElement} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js'; +import {CrLinkRowElement} from 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js'; import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js'; import {I18nMixin} from 'chrome://resources/js/i18n_mixin.js'; import {getDeepActiveElement} from 'chrome://resources/js/util.m.js'; import {WebUIListenerMixin} from 'chrome://resources/js/web_ui_listener_mixin.js'; import {IronA11yAnnouncer} from 'chrome://resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.js'; -import {afterNextRender, DomRepeatEvent, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {afterNextRender, DomRepeat, DomRepeatEvent, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {GlobalScrollTargetMixin} from '../global_scroll_target_mixin.js'; import {HatsBrowserProxyImpl, TrustSafetyInteraction} from '../hats_browser_proxy.js'; @@ -56,7 +57,7 @@ import {MultiStoreExceptionEntry} from './multi_store_exception_entry.js'; import {MultiStorePasswordUiEntry} from './multi_store_password_ui_entry.js'; import {PasswordCheckMixin} from './password_check_mixin.js'; -import {AddCredentialFromSettingsUserInteractions} from './password_edit_dialog.js'; +import {AddCredentialFromSettingsUserInteractions, PasswordEditDialogElement} from './password_edit_dialog.js'; import {PasswordCheckReferrer, PasswordExceptionListChangedListener, PasswordManagerImpl, PasswordManagerProxy} from './password_manager_proxy.js'; import {PasswordsListHandlerElement} from './passwords_list_handler.js'; import {getTemplate} from './passwords_section.html.js'; @@ -78,8 +79,31 @@ export interface PasswordsSectionElement { $: { + accountEmail: HTMLElement, + accountStorageButtonsContainer: HTMLElement, + accountStorageOptInBody: HTMLElement, + accountStorageOptOutBody: HTMLElement, + addPasswordDialog: PasswordEditDialogElement, + checkPasswordLeakCount: HTMLElement, + checkPasswordLeakDescription: HTMLElement, + checkPasswordWarningIcon: HTMLElement, + checkPasswordsBannerContainer: HTMLElement, + checkPasswordsButtonRow: HTMLElement, + checkPasswordsLinkRow: HTMLElement, + devicePasswordsLink: HTMLElement, exportImportMenu: CrActionMenuElement, + manageLink: HTMLElement, + menuEditPassword: HTMLElement, + menuExportPassword: HTMLElement, + noExceptionsLabel: HTMLElement, + noPasswordsLabel: HTMLElement, + optInToAccountStorageButton: HTMLElement, + optOutOfAccountStorageButton: HTMLElement, + passwordExceptionsList: HTMLElement, + passwordList: DomRepeat, passwordsListHandler: PasswordsListHandlerElement, + savedPasswordsHeaders: HTMLElement, + trustedVaultBanner: CrLinkRowElement, }; }
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pwa_detail_view.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pwa_detail_view.html index 4ae2e8bf..b140281d 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pwa_detail_view.html +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pwa_detail_view.html
@@ -42,6 +42,10 @@ app="[[app_]]" more-permissions-label="$i18n{appManagementMorePermissionsLabel}"> </app-management-more-permissions-item> + <app-management-file-handling-item + class="permission-card-row separated-row" + app="[[app_]]"> + </app-management-file-handling-item> <app-management-supported-links-item id="supportedLinksSetting" class="permission-card-row"
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pwa_detail_view.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pwa_detail_view.js index 546297a..61355e18 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pwa_detail_view.js +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/pwa_detail_view.js
@@ -5,6 +5,7 @@ import './pin_to_shelf_item.js'; import './supported_links_item.js'; import './shared_style.js'; +import '//resources/cr_components/app_management/file_handling_item.js'; import '//resources/cr_components/app_management/icons.js'; import '//resources/cr_components/app_management/more_permissions_item.js'; import '//resources/cr_components/app_management/permission_item.js';
diff --git a/chrome/browser/resources/settings/lazy_load.ts b/chrome/browser/resources/settings/lazy_load.ts index 53981d3..82f9730 100644 --- a/chrome/browser/resources/settings/lazy_load.ts +++ b/chrome/browser/resources/settings/lazy_load.ts
@@ -88,6 +88,7 @@ export {PasswordMoveMultiplePasswordsToAccountDialogElement} from './autofill_page/password_move_multiple_passwords_to_account_dialog.js'; export {PasswordMoveToAccountDialogElement} from './autofill_page/password_move_to_account_dialog.js'; export {SettingsPasswordRemoveConfirmationDialogElement} from './autofill_page/password_remove_confirmation_dialog.js'; +export {PasswordRemoveDialogElement} from './autofill_page/password_remove_dialog.js'; export {PasswordsDeviceSectionElement} from './autofill_page/passwords_device_section.js'; export {PasswordsExportDialogElement} from './autofill_page/passwords_export_dialog.js'; export {PasswordsSectionElement} from './autofill_page/passwords_section.js';
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc index aa68f47..2c3ebfb67 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -771,10 +771,7 @@ .Times(1); WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); - content::WindowedNotificationObserver load_stop_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &contents->GetController())); + content::LoadStopObserver load_stop_observer(contents); // Run javascript function in the page which starts a timer to load the // malware image, and also starts a renderer-initiated top-level navigation to // a site that does not respond. Should show interstitial and have first page @@ -822,10 +819,7 @@ WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); content::RenderFrameHost* rfh = contents->GetMainFrame(); - content::WindowedNotificationObserver load_stop_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &contents->GetController())); + content::LoadStopObserver load_stop_observer(contents); // Start a browser initiated top-level navigation to a site that does not // respond. ui_test_utils::NavigateToURLWithDisposition(
diff --git a/chrome/browser/sessions/tab_restore_browsertest.cc b/chrome/browser/sessions/tab_restore_browsertest.cc index 2e3b031..9f91d31 100644 --- a/chrome/browser/sessions/tab_restore_browsertest.cc +++ b/chrome/browser/sessions/tab_restore_browsertest.cc
@@ -254,17 +254,15 @@ } void GoBack(Browser* browser) { - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::NotificationService::AllSources()); + content::LoadStopObserver observer( + browser->tab_strip_model()->GetActiveWebContents()); chrome::GoBack(browser, WindowOpenDisposition::CURRENT_TAB); observer.Wait(); } void GoForward(Browser* browser) { - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::NotificationService::AllSources()); + content::LoadStopObserver observer( + browser->tab_strip_model()->GetActiveWebContents()); chrome::GoForward(browser, WindowOpenDisposition::CURRENT_TAB); observer.Wait(); } @@ -275,9 +273,7 @@ !tab->IsLoading()) return; - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>(controller)); + content::LoadStopObserver observer(tab); observer.Wait(); } @@ -857,9 +853,7 @@ // Navigate to another same-site URL. content::WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1); - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::NotificationService::AllSources()); + content::LoadStopObserver observer(tab); static_cast<content::WebContentsDelegate*>(browser())->OpenURLFromTab( tab, content::OpenURLParams(http_url2, content::Referrer(), WindowOpenDisposition::CURRENT_TAB,
diff --git a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc index 7acf966b..5212fb63 100644 --- a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc +++ b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
@@ -62,8 +62,6 @@ #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/network_service_instance.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/reload_type.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/ssl_status.h" @@ -1356,10 +1354,7 @@ EXPECT_EQ(security_state::SecurityLevel::DANGEROUS, observer.latest_security_level()); - content::WindowedNotificationObserver back_nav_load_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &web_contents->GetController())); + content::LoadStopObserver back_nav_load_observer(web_contents); chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB); back_nav_load_observer.Wait();
diff --git a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc index f254e7d171..b1702b92 100644 --- a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc +++ b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
@@ -55,8 +55,6 @@ #include "components/subresource_filter/core/mojom/subresource_filter.mojom.h" #include "components/url_pattern_index/proto/rules.pb.h" #include "content/public/browser/navigation_handle.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/page_navigator.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" @@ -413,18 +411,14 @@ EXPECT_EQ(1u, console_observer.messages().size()); ASSERT_TRUE(web_contents()->GetController().CanGoBack()); - content::WindowedNotificationObserver back_navigation_stop_observer( - content::NOTIFICATION_LOAD_STOP, - content::NotificationService::AllSources()); + content::LoadStopObserver back_navigation_stop_observer(web_contents()); web_contents()->GetController().GoBack(); back_navigation_stop_observer.Wait(); ASSERT_NO_FATAL_FAILURE(ExpectParsedScriptElementLoadedStatusInFrames( kSubframeNames, kExpectScriptInFrameToLoadWithoutActivation)); ASSERT_TRUE(web_contents()->GetController().CanGoForward()); - content::WindowedNotificationObserver forward_navigation_stop_observer( - content::NOTIFICATION_LOAD_STOP, - content::NotificationService::AllSources()); + content::LoadStopObserver forward_navigation_stop_observer(web_contents()); web_contents()->GetController().GoForward(); forward_navigation_stop_observer.Wait(); ASSERT_NO_FATAL_FAILURE(ExpectParsedScriptElementLoadedStatusInFrames(
diff --git a/chrome/browser/supervised_user/supervised_user_url_filter_browsertest.cc b/chrome/browser/supervised_user/supervised_user_url_filter_browsertest.cc index d67902c..57ff0b8 100644 --- a/chrome/browser/supervised_user/supervised_user_url_filter_browsertest.cc +++ b/chrome/browser/supervised_user/supervised_user_url_filter_browsertest.cc
@@ -443,9 +443,7 @@ content::TestNavigationObserver block_observer(web_contents); block_observer.Wait(); - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::NotificationService::AllSources()); + content::LoadStopObserver observer(web_contents); GoBack(web_contents); observer.Wait(); @@ -538,9 +536,7 @@ ASSERT_TRUE(ShownPageIsInterstitial(browser())); - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::NotificationService::AllSources()); + content::LoadStopObserver observer(web_contents); // Set the host as allowed. std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
diff --git a/chrome/browser/tab_contents/view_source_browsertest.cc b/chrome/browser/tab_contents/view_source_browsertest.cc index 5d525c8..b765a852 100644 --- a/chrome/browser/tab_contents/view_source_browsertest.cc +++ b/chrome/browser/tab_contents/view_source_browsertest.cc
@@ -20,8 +20,6 @@ #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/back_forward_cache.h" #include "content/public/browser/navigation_entry.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" @@ -173,9 +171,8 @@ GURL url_viewsource(content::kViewSourceScheme + std::string(":") + embedded_test_server()->GetURL(kTestHtml).spec()); - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::NotificationService::AllSources()); + content::LoadStopObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_viewsource)); observer.Wait(); @@ -183,9 +180,8 @@ content::ExecuteScript(browser()->tab_strip_model()->GetWebContentsAt(0), "window.location.reload();")); - content::WindowedNotificationObserver observer2( - content::NOTIFICATION_LOAD_STOP, - content::NotificationService::AllSources()); + content::LoadStopObserver observer2( + browser()->tab_strip_model()->GetWebContentsAt(0)); observer2.Wait(); ASSERT_TRUE(browser()->tab_strip_model()->GetWebContentsAt(0)-> GetController().GetActiveEntry()->IsViewSourceMode());
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 367a197..2b4e204 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -4925,7 +4925,7 @@ "//components/content_settings/browser/ui", "//components/fullscreen_control", "//components/global_media_controls", - "//components/live_caption", + "//components/live_caption:constants", "//components/media_message_center", "//components/page_info", "//components/page_info/core",
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc index b7118c8..59b9cf3 100644 --- a/chrome/browser/ui/browser_browsertest.cc +++ b/chrome/browser/ui/browser_browsertest.cc
@@ -97,8 +97,6 @@ #include "content/public/browser/host_zoom_map.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_handle.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/reload_type.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" @@ -570,9 +568,7 @@ // sticks around so that the user can edit it. GURL abort_url(embedded_test_server()->GetURL("/nocontent")); { - content::WindowedNotificationObserver stop_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>(&web_contents->GetController())); + content::LoadStopObserver stop_observer(web_contents); browser()->OpenURL(OpenURLParams(abort_url, Referrer(), WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false)); @@ -588,9 +584,7 @@ // Now navigating to a 204 URL should clear the pending entry. { - content::WindowedNotificationObserver stop_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>(&web_contents->GetController())); + content::LoadStopObserver stop_observer(web_contents); browser()->OpenURL(OpenURLParams(abort_url, Referrer(), WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false)); @@ -1658,23 +1652,15 @@ base::FilePath(base::FilePath::kCurrentDirectory), base::FilePath(kTitle1File)))); - content::WindowedNotificationObserver back_nav_load_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>(&browser() - ->tab_strip_model() - ->GetActiveWebContents() - ->GetController())); + content::LoadStopObserver back_nav_load_observer( + browser()->tab_strip_model()->GetActiveWebContents()); chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB); back_nav_load_observer.Wait(); CommandUpdater* command_updater = browser()->command_controller(); EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_FORWARD)); - content::WindowedNotificationObserver forward_nav_load_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>(&browser() - ->tab_strip_model() - ->GetActiveWebContents() - ->GetController())); + content::LoadStopObserver forward_nav_load_observer( + browser()->tab_strip_model()->GetActiveWebContents()); chrome::GoForward(browser(), WindowOpenDisposition::CURRENT_TAB); // This check will happen before the navigation completes, since the browser // won't process the renderer's response until the Wait() call below.
diff --git a/chrome/browser/ui/browser_focus_uitest.cc b/chrome/browser/ui/browser_focus_uitest.cc index 7f70920..9e1dec2 100644 --- a/chrome/browser/ui/browser_focus_uitest.cc +++ b/chrome/browser/ui/browser_focus_uitest.cc
@@ -492,13 +492,8 @@ content::RunAllPendingInMessageLoop(); { - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &browser() - ->tab_strip_model() - ->GetActiveWebContents() - ->GetController())); + content::LoadStopObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); observer.Wait(); } @@ -511,13 +506,8 @@ chrome::FocusLocationBar(browser()); ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); { - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &browser() - ->tab_strip_model() - ->GetActiveWebContents() - ->GetController())); + content::LoadStopObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); observer.Wait(); } @@ -542,13 +532,8 @@ browser(), embedded_test_server()->GetURL(kSimplePage))); content::CrashTab(browser()->tab_strip_model()->GetActiveWebContents()); { - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &browser() - ->tab_strip_model() - ->GetActiveWebContents() - ->GetController())); + content::LoadStopObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); observer.Wait(); }
diff --git a/chrome/browser/ui/browser_tabrestore_browsertest.cc b/chrome/browser/ui/browser_tabrestore_browsertest.cc index f33cbda..99028954 100644 --- a/chrome/browser/ui/browser_tabrestore_browsertest.cc +++ b/chrome/browser/ui/browser_tabrestore_browsertest.cc
@@ -108,10 +108,7 @@ EXPECT_EQ("about:blank", about_blank_contents->GetURL().spec()); if (about_blank_contents->IsLoading() || about_blank_contents->GetController().NeedsReload()) { - content::WindowedNotificationObserver load_stop_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &about_blank_contents->GetController())); + content::LoadStopObserver load_stop_observer(about_blank_contents); load_stop_observer.Wait(); } } @@ -215,10 +212,7 @@ EXPECT_EQ("about:blank", about_blank_contents->GetURL().spec()); if (about_blank_contents->IsLoading() || about_blank_contents->GetController().NeedsReload()) { - content::WindowedNotificationObserver load_stop_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &about_blank_contents->GetController())); + content::LoadStopObserver load_stop_observer(about_blank_contents); load_stop_observer.Wait(); } }
diff --git a/chrome/browser/ui/color/chrome_color_id.h b/chrome/browser/ui/color/chrome_color_id.h index 5fd75dcf..18993df 100644 --- a/chrome/browser/ui/color/chrome_color_id.h +++ b/chrome/browser/ui/color/chrome_color_id.h
@@ -46,6 +46,8 @@ /* Window caption colors. */ \ E(kColorCaptionButtonBackground, \ ThemeProperties::COLOR_CONTROL_BUTTON_BACKGROUND) \ + /* Captured tab colors. */ \ + E_CPONLY(kColorCapturedTabContentsBorder) \ /* Desktop media tab list colors. */ \ E_CPONLY(kColorDesktopMediaTabListBorder) \ E_CPONLY(kColorDesktopMediaTabListPreviewBackground) \ @@ -59,9 +61,13 @@ ThemeProperties::COLOR_DOWNLOAD_SHELF_CONTENT_AREA_SEPARATOR) \ E(kColorDownloadShelfForeground, \ ThemeProperties::COLOR_DOWNLOAD_SHELF_FOREGROUND) \ + E_CPONLY(kColorDownloadStartedAnimationForeground) \ E_CPONLY(kColorDownloadToolbarButtonActive) \ E_CPONLY(kColorDownloadToolbarButtonInactive) \ E_CPONLY(kColorDownloadToolbarButtonRingBackground) \ + /* Extension colors. */ \ + E_CPONLY(kColorExtensionIconBadgeBackgroundDefault) \ + E_CPONLY(kColorExtensionIconBadgeForegroundDefault) \ /* Eyedropper colors. */ \ E_CPONLY(kColorEyedropperBoundary) \ E_CPONLY(kColorEyedropperCentralPixelInnerRing) \ @@ -99,6 +105,10 @@ E(kColorLocationBarBorder, ThemeProperties::COLOR_LOCATION_BAR_BORDER) \ E(kColorLocationBarBorderOpaque, \ ThemeProperties::COLOR_LOCATION_BAR_BORDER_OPAQUE) \ + /* Media router colors. */ \ + E_CPONLY(kColorMediaRouterIconActive) \ + E_CPONLY(kColorMediaRouterIconError) \ + E_CPONLY(kColorMediaRouterIconWarning) \ /* New Tab Page colors. */ \ E(kColorNewTabPageBackground, ThemeProperties::COLOR_NTP_BACKGROUND) \ E(kColorNewTabPageHeader, ThemeProperties::COLOR_NTP_HEADER) \ @@ -202,6 +212,9 @@ /* QR code colors. */ \ E_CPONLY(kColorQrCodeBackground) \ E_CPONLY(kColorQrCodeBorder) \ + /* Quick Answers colors. */ \ + E_CPONLY(kColorQuickAnswersReportQueryButtonBackground) \ + E_CPONLY(kColorQuickAnswersReportQueryButtonForeground) \ /* Read Later button colors. */ \ E(kColorReadLaterButtonHighlight, \ ThemeProperties::COLOR_READ_LATER_BUTTON_HIGHLIGHT) \ @@ -341,6 +354,8 @@ ThemeProperties::COLOR_TAB_STROKE_FRAME_ACTIVE) \ E(kColorTabStrokeFrameInactive, \ ThemeProperties::COLOR_TAB_STROKE_FRAME_INACTIVE) \ + E_CPONLY(kColorTabstripLoadingProgressBackground) \ + E_CPONLY(kColorTabstripLoadingProgressForeground) \ /* Thumbnail tab colors. */ \ E_CPONLY(kColorThumbnailTabBackground) \ E_CPONLY(kColorThumbnailTabForeground) \ @@ -369,6 +384,8 @@ ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR_FRAME_ACTIVE) \ E(kColorToolbarTopSeparatorFrameInactive, \ ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR_FRAME_INACTIVE) \ + /* WebAuthn colors. */ \ + E_CPONLY(kColorWebAuthnPinTextfieldBottomBorder) \ /* Web contents colors. */ \ E_CPONLY(kColorWebContentsBackground) \ E_CPONLY(kColorWebContentsBackgroundLetterboxing) \
diff --git a/chrome/browser/ui/color/chrome_color_mixer.cc b/chrome/browser/ui/color/chrome_color_mixer.cc index 4d3ff0e..3cdf2715 100644 --- a/chrome/browser/ui/color/chrome_color_mixer.cc +++ b/chrome/browser/ui/color/chrome_color_mixer.cc
@@ -223,6 +223,7 @@ mixer[kColorBookmarkDragImageIconBackground] = { kColorBookmarkDragImageForeground}; mixer[kColorCaptionButtonBackground] = {SK_ColorTRANSPARENT}; + mixer[kColorCapturedTabContentsBorder] = {ui::kColorAccent}; mixer[kColorDesktopMediaTabListBorder] = {ui::kColorMidground}; mixer[kColorDesktopMediaTabListPreviewBackground] = {ui::kColorMidground}; mixer[kColorDownloadShelfBackground] = {kColorToolbar}; @@ -233,10 +234,14 @@ mixer[kColorDownloadShelfContentAreaSeparator] = ui::AlphaBlend( kColorToolbarButtonIcon, kColorDownloadShelfBackground, 0x3A); mixer[kColorDownloadShelfForeground] = {kColorToolbarText}; + mixer[kColorDownloadStartedAnimationForeground] = {ui::kColorAccent}; mixer[kColorDownloadToolbarButtonActive] = {ui::kColorThrobber}; mixer[kColorDownloadToolbarButtonInactive] = {kColorToolbarButtonIcon}; mixer[kColorDownloadToolbarButtonRingBackground] = { SkColorSetA(kColorDownloadToolbarButtonInactive, 0x33)}; + mixer[kColorExtensionIconBadgeBackgroundDefault] = {ui::kColorAccent}; + mixer[kColorExtensionIconBadgeForegroundDefault] = + ui::GetColorWithMaxContrast(kColorExtensionIconBadgeBackgroundDefault); mixer[kColorEyedropperBoundary] = {SK_ColorDKGRAY}; mixer[kColorEyedropperCentralPixelInnerRing] = {SK_ColorBLACK}; mixer[kColorEyedropperCentralPixelOuterRing] = {SK_ColorWHITE}; @@ -266,6 +271,9 @@ mixer[kColorLocationBarBorder] = {SkColorSetA(SK_ColorBLACK, 0x4D)}; mixer[kColorLocationBarBorderOpaque] = ui::GetResultingPaintColor(kColorLocationBarBorder, kColorToolbar); + mixer[kColorMediaRouterIconActive] = {ui::kColorAccent}; + mixer[kColorMediaRouterIconError] = {ui::kColorAlertHighSeverity}; + mixer[kColorMediaRouterIconWarning] = {ui::kColorAlertMediumSeverity}; mixer[kColorNewTabPageBackground] = {kColorToolbar}; mixer[kColorNewTabPageHeader] = {SkColorSetRGB(0x96, 0x96, 0x96)}; mixer[kColorNewTabPageLink] = {dark_mode ? gfx::kGoogleBlue300 @@ -325,6 +333,9 @@ : gfx::kGoogleGreen600}; mixer[kColorQrCodeBackground] = {SK_ColorWHITE}; mixer[kColorQrCodeBorder] = {ui::kColorMidground}; + mixer[kColorQuickAnswersReportQueryButtonBackground] = + ui::SetAlpha(ui::kColorAccent, 0x0A); + mixer[kColorQuickAnswersReportQueryButtonForeground] = {ui::kColorAccent}; mixer[kColorReadLaterButtonHighlight] = {kColorAvatarButtonHighlightNormal}; mixer[kColorScreenshotCapturedImageBackground] = {ui::kColorBubbleBackground}; mixer[kColorScreenshotCapturedImageBorder] = {ui::kColorMidground}; @@ -500,6 +511,9 @@ mixer[kColorTabStrokeFrameActive] = {kColorToolbarTopSeparatorFrameActive}; mixer[kColorTabStrokeFrameInactive] = { kColorToolbarTopSeparatorFrameInactive}; + mixer[kColorTabstripLoadingProgressBackground] = + ui::AlphaBlend(ui::kColorAccent, kColorToolbar, 0x32); + mixer[kColorTabstripLoadingProgressForeground] = {ui::kColorAccent}; mixer[kColorThumbnailTabBackground] = ui::BlendForMinContrast( ui::kColorAccent, ui::kColorFrameActive, absl::nullopt, color_utils::kMinimumVisibleContrastRatio); @@ -532,6 +546,7 @@ mixer[kColorToolbarTopSeparatorFrameInactive] = GetToolbarTopSeparatorColorTransform(kColorToolbar, ui::kColorFrameInactive); + mixer[kColorWebAuthnPinTextfieldBottomBorder] = {ui::kColorAccent}; mixer[kColorWebContentsBackground] = {kColorNewTabPageBackground}; mixer[kColorWebContentsBackgroundLetterboxing] = ui::AlphaBlend(kColorWebContentsBackground, SK_ColorBLACK, 0x33);
diff --git a/chrome/browser/ui/extensions/extension_action_view_controller.cc b/chrome/browser/ui/extensions/extension_action_view_controller.cc index cc187d5..8a65c53 100644 --- a/chrome/browser/ui/extensions/extension_action_view_controller.cc +++ b/chrome/browser/ui/extensions/extension_action_view_controller.cc
@@ -37,8 +37,10 @@ #include "extensions/common/manifest_constants.h" #include "extensions/common/permissions/api_permission.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/color/color_provider_manager.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia_operations.h" +#include "ui/native_theme/native_theme.h" using extensions::ActionInfo; using extensions::CommandService; @@ -462,8 +464,16 @@ content::WebContents* web_contents, const gfx::Size& size) { int tab_id = sessions::SessionTabHelper::IdForTab(web_contents).id(); - std::unique_ptr<IconWithBadgeImageSource> image_source( - new IconWithBadgeImageSource(size)); + // `web_contents` may be null during tab closure or in tests. Fall back on a + // generic color provider. + const auto* const color_provider = + web_contents + ? &web_contents->GetColorProvider() + : ui::ColorProviderManager::Get().GetColorProviderFor( + ui::NativeTheme::GetInstanceForNativeUi()->GetColorProviderKey( + nullptr)); + auto image_source = + std::make_unique<IconWithBadgeImageSource>(size, color_provider); image_source->SetIcon(icon_factory_.GetIcon(tab_id));
diff --git a/chrome/browser/ui/extensions/icon_with_badge_image_source.cc b/chrome/browser/ui/extensions/icon_with_badge_image_source.cc index 898bb77..536d512b 100644 --- a/chrome/browser/ui/extensions/icon_with_badge_image_source.cc +++ b/chrome/browser/ui/extensions/icon_with_badge_image_source.cc
@@ -11,11 +11,13 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "cc/paint/paint_flags.h" +#include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/grit/theme_resources.h" #include "extensions/browser/extension_action.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/ui_base_features.h" +#include "ui/color/color_provider.h" #include "ui/gfx/canvas.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/font.h" @@ -55,8 +57,12 @@ IconWithBadgeImageSource::Badge::~Badge() {} -IconWithBadgeImageSource::IconWithBadgeImageSource(const gfx::Size& size) - : gfx::CanvasImageSource(size) {} +IconWithBadgeImageSource::IconWithBadgeImageSource( + const gfx::Size& size, + const ui::ColorProvider* color_provider) + : gfx::CanvasImageSource(size), color_provider_(color_provider) { + DCHECK(color_provider_); +} IconWithBadgeImageSource::~IconWithBadgeImageSource() {} @@ -71,9 +77,10 @@ return; // Generate the badge's render text. - SkColor text_color = SkColorGetA(badge_->text_color) == SK_AlphaTRANSPARENT - ? SK_ColorWHITE - : badge_->text_color; + SkColor text_color = + SkColorGetA(badge_->text_color) == SK_AlphaTRANSPARENT + ? color_provider_->GetColor(kColorExtensionIconBadgeForegroundDefault) + : badge_->text_color; constexpr int kBadgeHeight = 12; ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); @@ -172,7 +179,7 @@ // Make sure the background color is opaque. See http://crbug.com/619499 SkColor background_color = SkColorGetA(badge_->background_color) == SK_AlphaTRANSPARENT - ? gfx::kGoogleBlue500 + ? color_provider_->GetColor(kColorExtensionIconBadgeBackgroundDefault) : SkColorSetA(badge_->background_color, SK_AlphaOPAQUE); cc::PaintFlags rect_flags; rect_flags.setStyle(cc::PaintFlags::kFill_Style);
diff --git a/chrome/browser/ui/extensions/icon_with_badge_image_source.h b/chrome/browser/ui/extensions/icon_with_badge_image_source.h index d4d71e6..eaffb48 100644 --- a/chrome/browser/ui/extensions/icon_with_badge_image_source.h +++ b/chrome/browser/ui/extensions/icon_with_badge_image_source.h
@@ -17,6 +17,10 @@ class Size; } +namespace ui { +class ColorProvider; +} + // CanvasImageSource for creating extension icon with a badge. class IconWithBadgeImageSource : public gfx::CanvasImageSource { public: @@ -36,7 +40,8 @@ SkColor background_color; }; - explicit IconWithBadgeImageSource(const gfx::Size& size); + IconWithBadgeImageSource(const gfx::Size& size, + const ui::ColorProvider* color_provider); IconWithBadgeImageSource(const IconWithBadgeImageSource&) = delete; IconWithBadgeImageSource& operator=(const IconWithBadgeImageSource&) = delete; @@ -76,6 +81,8 @@ // https://crbug.com/831946. gfx::Rect GetIconAreaRect() const; + const ui::ColorProvider* const color_provider_; + // The base icon to draw. gfx::Image icon_;
diff --git a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc index db7d2d2..f4f0b05 100644 --- a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc +++ b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
@@ -965,11 +965,8 @@ EXPECT_TRUE(fully_visible); // Reload and make sure the find window goes away. - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>( - &browser()->tab_strip_model()->GetActiveWebContents()-> - GetController())); + content::LoadStopObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); observer.Wait(); EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible)); @@ -1455,9 +1452,7 @@ EXPECT_EQ(ordinal, 1); // End the find session, click on the link. - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>(&web_contents->GetController())); + content::LoadStopObserver observer(web_contents); find_tab_helper->StopFinding(find_in_page::SelectionAction::kActivate); observer.Wait(); }
diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_client.cc b/chrome/browser/ui/omnibox/chrome_omnibox_client.cc index dc6e631..707ae1b 100644 --- a/chrome/browser/ui/omnibox/chrome_omnibox_client.cc +++ b/chrome/browser/ui/omnibox/chrome_omnibox_client.cc
@@ -254,8 +254,6 @@ bool default_match_changed, bool should_prerender, const BitmapFetchedCallback& on_bitmap_fetched) { - auto now = base::TimeTicks::Now(); - BitmapFetcherService* bitmap_fetcher_service = BitmapFetcherServiceFactory::GetForBrowserContext(profile_); @@ -283,11 +281,9 @@ } request_ids_.push_back(bitmap_fetcher_service->RequestImage( - match.ImageUrl(), - base::BindOnce( - &ChromeOmniboxClient::OnBitmapFetched, weak_factory_.GetWeakPtr(), - on_bitmap_fetched, result_index, - bitmap_fetcher_service->IsCached(match.ImageUrl()), now))); + match.ImageUrl(), base::BindOnce(&ChromeOmniboxClient::OnBitmapFetched, + weak_factory_.GetWeakPtr(), + on_bitmap_fetched, result_index))); } } @@ -466,15 +462,7 @@ void ChromeOmniboxClient::OnBitmapFetched(const BitmapFetchedCallback& callback, int result_index, - bool is_cached, - base::TimeTicks start_time, const SkBitmap& bitmap) { - auto time_delta = base::TimeTicks::Now() - start_time; - UMA_HISTOGRAM_TIMES("Omnibox.BitmapFetchLatency", time_delta); - if (is_cached) - UMA_HISTOGRAM_TIMES("Omnibox.BitmapFetchLatency.Cached", time_delta); - else - UMA_HISTOGRAM_TIMES("Omnibox.BitmapFetchLatency.Uncached", time_delta); callback.Run(result_index, bitmap); }
diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_client.h b/chrome/browser/ui/omnibox/chrome_omnibox_client.h index 1dc6472..31ee938 100644 --- a/chrome/browser/ui/omnibox/chrome_omnibox_client.h +++ b/chrome/browser/ui/omnibox/chrome_omnibox_client.h
@@ -99,8 +99,6 @@ void OnBitmapFetched(const BitmapFetchedCallback& callback, int result_index, - bool is_cached, - base::TimeTicks start_time, const SkBitmap& bitmap); raw_ptr<ChromeOmniboxEditController> controller_;
diff --git a/chrome/browser/ui/quick_answers/BUILD.gn b/chrome/browser/ui/quick_answers/BUILD.gn index 7a18cc28..27a86a4 100644 --- a/chrome/browser/ui/quick_answers/BUILD.gn +++ b/chrome/browser/ui/quick_answers/BUILD.gn
@@ -40,6 +40,7 @@ deps += [ "//ash", "//chrome/browser/chromeos", + "//chrome/browser/ui/color:color_headers", ] } }
diff --git a/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc b/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc index 3acaad9d..50bed82 100644 --- a/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc +++ b/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/quick_answers/quick_answers_ui_controller.h" #include "chrome/browser/ui/quick_answers/ui/quick_answers_pre_target_handler.h" #include "chromeos/components/quick_answers/quick_answers_model.h" @@ -216,6 +217,9 @@ explicit ReportQueryView(PressedCallback callback) : Button(std::move(callback)) { + SetBackground(views::CreateThemedSolidBackground( + this, kColorQuickAnswersReportQueryButtonBackground)); + auto* layout = SetLayoutManager(std::make_unique<views::FlexLayout>()); layout->SetOrientation(views::LayoutOrientation::kHorizontal) .SetMainAxisAlignment(views::LayoutAlignment::kStart); @@ -259,17 +263,9 @@ void OnThemeChanged() override { views::Button::OnThemeChanged(); - const bool should_use_dark_colors = GetNativeTheme()->ShouldUseDarkColors(); - - // Hard code color for dark mode since we use special specs for this - // temporary view. Will remove the usage after we remove this view. - const auto background_color = - should_use_dark_colors ? SkColorSetA(gfx::kGoogleBlue300, 0x4C /*30%*/) - : gfx::kGoogleBlue050; - const auto foreground_color = - should_use_dark_colors ? gfx::kGoogleBlue300 : gfx::kGoogleBlue600; - - SetBackground(views::CreateSolidBackground(background_color)); + const auto* const color_provider = GetColorProvider(); + const SkColor foreground_color = + color_provider->GetColor(kColorQuickAnswersReportQueryButtonForeground); dogfood_icon_->SetImage(gfx::CreateVectorIcon( vector_icons::kDogfoodIcon, kDogfoodIconSizeDip, foreground_color)); description_label_->SetEnabledColor(foreground_color);
diff --git a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc index c351762..31a7fc82 100644 --- a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc +++ b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc
@@ -177,10 +177,7 @@ content::WebContents* active_tab = browser()->tab_strip_model()->GetActiveWebContents(); EXPECT_TRUE(active_tab->GetController().CanGoBack()); - content::WindowedNotificationObserver load_stop_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &active_tab->GetController())); + content::LoadStopObserver load_stop_observer(active_tab); active_tab->GetController().GoBack(); load_stop_observer.Wait(); @@ -204,19 +201,15 @@ EXPECT_TRUE(UpdateSearchState(active_tab)); EXPECT_EQ(1, on_most_visited_change_calls_); - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::NotificationService::AllSources()); + content::LoadStopObserver observer(active_tab); // Set the text and press enter to navigate from NTP. SetOmniboxText("Pen"); PressEnterAndWaitForNavigation(); observer.Wait(); // Navigate back to NTP. - content::WindowedNotificationObserver back_observer( - content::NOTIFICATION_LOAD_STOP, - content::NotificationService::AllSources()); active_tab = browser()->tab_strip_model()->GetActiveWebContents(); + content::LoadStopObserver back_observer(active_tab); EXPECT_TRUE(active_tab->GetController().CanGoBack()); active_tab->GetController().GoBack(); back_observer.Wait();
diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc index 431e25c97..9f5eae3 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.cc +++ b/chrome/browser/ui/startup/startup_browser_creator.cc
@@ -121,9 +121,6 @@ #include "chrome/browser/ui/webui/settings/reset_settings_handler.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/credential_provider/common/gcp_strings.h" -#if BUILDFLAG(ENABLE_PRINT_PREVIEW) -#include "chrome/browser/printing/print_dialog_cloud_win.h" -#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) #endif // BUILDFLAG(IS_WIN) #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) @@ -860,16 +857,6 @@ Profile* privacy_safe_profile = GetPrivateProfileIfRequested(command_line, profile_info); -#if BUILDFLAG(IS_WIN) && BUILDFLAG(ENABLE_PRINT_PREVIEW) - // If we are just displaying a print dialog we shouldn't open browser - // windows. - if (command_line.HasSwitch(switches::kCloudPrintFile) && can_use_profile && - print_dialog_cloud::CreatePrintDialogFromCommandLine(privacy_safe_profile, - command_line)) { - silent_launch = true; - } -#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(ENABLE_PRINT_PREVIEW) - if (command_line.HasSwitch(switches::kValidateCrx)) { if (process_startup == chrome::startup::IsProcessStartup::kNo) { LOG(ERROR) << "chrome is already running; you must close all running "
diff --git a/chrome/browser/ui/tabs/existing_base_sub_menu_model.cc b/chrome/browser/ui/tabs/existing_base_sub_menu_model.cc index f8cbadac..9dec4757 100644 --- a/chrome/browser/ui/tabs/existing_base_sub_menu_model.cc +++ b/chrome/browser/ui/tabs/existing_base_sub_menu_model.cc
@@ -11,12 +11,14 @@ ui::SimpleMenuModel::Delegate* parent_delegate, TabStripModel* model, int context_index, - int min_command_id) + int min_command_id, + int parent_new_command_id) : SimpleMenuModel(this), parent_delegate_(parent_delegate), model_(model), context_contents_(model->GetWebContentsAt(context_index)), - min_command_id_(min_command_id) {} + min_command_id_(min_command_id), + parent_new_command_id_(parent_new_command_id) {} bool ExistingBaseSubMenuModel::GetAcceleratorForCommandId( int command_id, @@ -33,6 +35,11 @@ return nullptr; } +bool ExistingBaseSubMenuModel::IsCommandIdAlerted(int command_id) const { + return IsNewCommand(command_id) && + parent_delegate()->IsCommandIdAlerted(parent_new_command_id_); +} + bool ExistingBaseSubMenuModel::IsCommandIdChecked(int command_id) const { return false; } @@ -46,7 +53,7 @@ void ExistingBaseSubMenuModel::ExecuteCommand(int command_id, int event_flags) { if (IsNewCommand(command_id)) { - ExecuteNewCommand(event_flags); + parent_delegate()->ExecuteCommand(parent_new_command_id_, event_flags); return; } ExecuteExistingCommand(command_id_to_target_index_[command_id]); @@ -110,7 +117,9 @@ command_id_to_target_index_.clear(); } -void ExistingBaseSubMenuModel::ExecuteNewCommand(int event_flags) {} +bool ExistingBaseSubMenuModel::IsNewCommand(int command_id) const { + return command_id == min_command_id_; +} void ExistingBaseSubMenuModel::ExecuteExistingCommand(int target_index) {}
diff --git a/chrome/browser/ui/tabs/existing_base_sub_menu_model.h b/chrome/browser/ui/tabs/existing_base_sub_menu_model.h index 7ed082e..4aa0e15 100644 --- a/chrome/browser/ui/tabs/existing_base_sub_menu_model.h +++ b/chrome/browser/ui/tabs/existing_base_sub_menu_model.h
@@ -32,7 +32,8 @@ ExistingBaseSubMenuModel(ui::SimpleMenuModel::Delegate* parent_delegate, TabStripModel* model, int context_index, - int min_command_id); + int min_command_id, + int parent_new_command_id_); // ui::SimpleMenuModel bool GetAcceleratorForCommandId(int command_id, @@ -40,6 +41,7 @@ const gfx::FontList* GetLabelFontListAt(int index) const override; // ui::SimpleMenuModel::Delegate + bool IsCommandIdAlerted(int command_id) const override; bool IsCommandIdChecked(int command_id) const override; bool IsCommandIdEnabled(int command_id) const override; void ExecuteCommand(int command_id, int event_flags) final; @@ -94,13 +96,7 @@ // Helper method for checking if the command is to add a tab to a new object // model. - bool IsNewCommand(int command_id) const { - return command_id == min_command_id_; - } - - // Performs the action for adding the tab to a new object model (e.g. group or - // window). - virtual void ExecuteNewCommand(int event_flags); + bool IsNewCommand(int command_id) const; // Performs the action for adding the tab to an existing object model (e.g. // group or window) at |target_index|. @@ -120,6 +116,7 @@ const raw_ptr<TabStripModel> model_; const raw_ptr<const content::WebContents> context_contents_; const int min_command_id_; + const int parent_new_command_id_; // Stores a mapping from a menu item's command id to its target index (e.g. // tab-group index or browser index).
diff --git a/chrome/browser/ui/tabs/existing_base_sub_menu_model_unittest.cc b/chrome/browser/ui/tabs/existing_base_sub_menu_model_unittest.cc new file mode 100644 index 0000000..3c85af6 --- /dev/null +++ b/chrome/browser/ui/tabs/existing_base_sub_menu_model_unittest.cc
@@ -0,0 +1,131 @@ +// Copyright 2020 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/tabs/existing_base_sub_menu_model.h" + +#include <memory> +#include <vector> + +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/grit/generated_resources.h" +#include "chrome/test/base/browser_with_test_window_test.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "ui/base/models/simple_menu_model.h" +#include "url/gurl.h" + +namespace { + +constexpr int kMinCommandId = 1000; +constexpr int kParentNewCommandId = 999; +constexpr int kExpectedFlags = 0xABCD; +constexpr char16_t kItem1Text[] = u"Item1"; +constexpr char16_t kTitleText[] = u"Title"; +constexpr char16_t kItem2Text[] = u"Item2"; + +class TestDelegate : public ui::SimpleMenuModel::Delegate { + public: + ~TestDelegate() override = default; + + bool new_command_alerted() const { return new_command_alerted_; } + void set_new_command_alerted(bool alerted) { new_command_alerted_ = alerted; } + int execute_count() { return execute_count_; } + + bool IsCommandIdAlerted(int command_id) const override { + EXPECT_EQ(kParentNewCommandId, command_id); + return new_command_alerted(); + } + + void ExecuteCommand(int command_id, int event_flags) override { + EXPECT_EQ(kParentNewCommandId, command_id); + EXPECT_EQ(kExpectedFlags, event_flags); + ++execute_count_; + } + + private: + bool new_command_alerted_ = false; + int execute_count_ = 0; +}; + +class TestModel : public ExistingBaseSubMenuModel { + public: + TestModel(ui::SimpleMenuModel::Delegate* test_delegate, TabStripModel* model) + : ExistingBaseSubMenuModel(test_delegate, + model, + 0, + kMinCommandId, + kParentNewCommandId) { + MenuItemInfo info1(kItem1Text); + info1.target_index = 1; + infos_.push_back(info1); + MenuItemInfo title(kTitleText); + infos_.push_back(title); + MenuItemInfo info2(kItem2Text); + info2.target_index = 2; + infos_.push_back(info2); + Build(IDS_TAB_CXMENU_SUBMENU_NEW_GROUP, infos_); + } + + const std::vector<int> existing_commands() const { + return existing_commands_; + } + + protected: + void ExecuteExistingCommand(int target_index) override { + existing_commands_.push_back(target_index); + } + + private: + std::vector<int> existing_commands_; + std::vector<MenuItemInfo> infos_; +}; + +} // namespace + +class ExistingBaseSubMenuModelTest : public BrowserWithTestWindowTest { + public: + ExistingBaseSubMenuModelTest() = default; + ~ExistingBaseSubMenuModelTest() override = default; + + void SetUp() override { + BrowserWithTestWindowTest::SetUp(); + AddTab(browser(), GURL("chrome://newtab")); + test_delegate_ = std::make_unique<TestDelegate>(); + test_model_ = std::make_unique<TestModel>(test_delegate_.get(), + browser()->tab_strip_model()); + } + + TestDelegate* test_delegate() const { return test_delegate_.get(); } + TestModel* test_model() const { return test_model_.get(); } + + private: + std::unique_ptr<TestDelegate> test_delegate_; + std::unique_ptr<TestModel> test_model_; +}; + +// TODO(dfried): Verify that label font list is overridden for title elements. +// Note that we can't test this because UI style info isn't loaded for unit +// tests so it still returns null. + +TEST_F(ExistingBaseSubMenuModelTest, IsCommandIdAlerted) { + EXPECT_FALSE(test_model()->IsCommandIdAlerted(kMinCommandId)); + EXPECT_FALSE(test_model()->IsCommandIdAlerted(kMinCommandId + 1)); + EXPECT_FALSE(test_model()->IsCommandIdAlerted(kMinCommandId + 2)); + + test_delegate()->set_new_command_alerted(true); + EXPECT_TRUE(test_model()->IsCommandIdAlerted(kMinCommandId)); + EXPECT_FALSE(test_model()->IsCommandIdAlerted(kMinCommandId + 1)); + EXPECT_FALSE(test_model()->IsCommandIdAlerted(kMinCommandId + 2)); +} + +TEST_F(ExistingBaseSubMenuModelTest, ExecuteCommand_New) { + EXPECT_EQ(0, test_delegate()->execute_count()); + test_model()->ExecuteCommand(kMinCommandId, kExpectedFlags); + EXPECT_EQ(1, test_delegate()->execute_count()); +} + +TEST_F(ExistingBaseSubMenuModelTest, ExecuteCommand_Existing) { + test_model()->ExecuteCommand(kMinCommandId + 1, kExpectedFlags); + test_model()->ExecuteCommand(kMinCommandId + 2, kExpectedFlags); + EXPECT_THAT(test_model()->existing_commands(), testing::ElementsAre(1, 2)); +}
diff --git a/chrome/browser/ui/tabs/existing_tab_group_sub_menu_model.cc b/chrome/browser/ui/tabs/existing_tab_group_sub_menu_model.cc index acb64b85e..5cbf1a5 100644 --- a/chrome/browser/ui/tabs/existing_tab_group_sub_menu_model.cc +++ b/chrome/browser/ui/tabs/existing_tab_group_sub_menu_model.cc
@@ -32,7 +32,8 @@ : ExistingBaseSubMenuModel(parent_delegate, model, context_index, - kMinExistingTabGroupCommandId) { + kMinExistingTabGroupCommandId, + TabStripModel::CommandAddToNewGroup) { DCHECK(model->SupportsTabGroups()); const ui::ColorProvider& color_provider = model->GetWebContentsAt(context_index)->GetColorProvider(); @@ -93,11 +94,6 @@ return false; } -void ExistingTabGroupSubMenuModel::ExecuteNewCommand(int event_flags) { - parent_delegate()->ExecuteCommand(TabStripModel::CommandAddToNewGroup, - event_flags); -} - void ExistingTabGroupSubMenuModel::ExecuteExistingCommand(int target_index) { TabGroupModel* group_model = model()->group_model(); if (!group_model)
diff --git a/chrome/browser/ui/tabs/existing_tab_group_sub_menu_model.h b/chrome/browser/ui/tabs/existing_tab_group_sub_menu_model.h index 4ac2d5b..8313fd2 100644 --- a/chrome/browser/ui/tabs/existing_tab_group_sub_menu_model.h +++ b/chrome/browser/ui/tabs/existing_tab_group_sub_menu_model.h
@@ -32,7 +32,6 @@ private: // ExistingBaseSubMenuModel - void ExecuteNewCommand(int event_flags) override; void ExecuteExistingCommand(int target_index) override; // Returns the group ids that appear in the submenu in the order that they
diff --git a/chrome/browser/ui/tabs/existing_window_sub_menu_model.cc b/chrome/browser/ui/tabs/existing_window_sub_menu_model.cc index bfce20d..d66eb29d0 100644 --- a/chrome/browser/ui/tabs/existing_window_sub_menu_model.cc +++ b/chrome/browser/ui/tabs/existing_window_sub_menu_model.cc
@@ -50,7 +50,8 @@ : ExistingBaseSubMenuModel(parent_delegate, model, context_index, - kMinExistingWindowCommandId) { + kMinExistingWindowCommandId, + TabStripModel::CommandMoveTabsToNewWindow) { Build(IDS_TAB_CXMENU_MOVETOANOTHERNEWWINDOW, BuildMenuItemInfoVectorForBrowsers( tab_menu_model_delegate->GetExistingWindowsForMoveMenu())); @@ -111,11 +112,6 @@ return menu_item_infos; } -void ExistingWindowSubMenuModel::ExecuteNewCommand(int event_flags) { - parent_delegate()->ExecuteCommand(TabStripModel::CommandMoveTabsToNewWindow, - event_flags); -} - void ExistingWindowSubMenuModel::ExecuteExistingCommand(int target_index) { model()->ExecuteAddToExistingWindowCommand(GetContextIndex(), target_index); }
diff --git a/chrome/browser/ui/tabs/existing_window_sub_menu_model.h b/chrome/browser/ui/tabs/existing_window_sub_menu_model.h index f95cad2..8b1b5bc 100644 --- a/chrome/browser/ui/tabs/existing_window_sub_menu_model.h +++ b/chrome/browser/ui/tabs/existing_window_sub_menu_model.h
@@ -66,7 +66,6 @@ private: // ExistingBaseSubMenuModel: - void ExecuteNewCommand(int event_flags) override; void ExecuteExistingCommand(int target_index) override; };
diff --git a/chrome/browser/ui/thumbnails/thumbnail_tab_helper_interactive_uitest.cc b/chrome/browser/ui/thumbnails/thumbnail_tab_helper_interactive_uitest.cc index 782ab14..1f79919 100644 --- a/chrome/browser/ui/thumbnails/thumbnail_tab_helper_interactive_uitest.cc +++ b/chrome/browser/ui/thumbnails/thumbnail_tab_helper_interactive_uitest.cc
@@ -17,9 +17,6 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/navigation_controller.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/notification_types.h" #include "content/public/test/browser_test.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/gurl.h" @@ -123,10 +120,7 @@ !tab->IsLoading()) return; - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>(controller)); - observer.Wait(); + content::LoadStopObserver(tab).Wait(); } void WaitForAndVerifyThumbnail(Browser* browser, int tab_index) {
diff --git a/chrome/browser/ui/views/accessibility/caption_bubble_controller_views_browsertest.cc b/chrome/browser/ui/views/accessibility/caption_bubble_controller_views_browsertest.cc index 80fbd8a..016e0694 100644 --- a/chrome/browser/ui/views/accessibility/caption_bubble_controller_views_browsertest.cc +++ b/chrome/browser/ui/views/accessibility/caption_bubble_controller_views_browsertest.cc
@@ -4,6 +4,7 @@ #include <memory> +#include "base/callback_forward.h" #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_mock_time_message_loop_task_runner.h" #include "build/build_config.h" @@ -100,17 +101,18 @@ } views::View* GetErrorMessage() { - return controller_ ? controller_->caption_bubble_->error_message_.get() - : nullptr; + return controller_ + ? controller_->caption_bubble_->generic_error_message_.get() + : nullptr; } views::Label* GetErrorText() { - return controller_ ? controller_->caption_bubble_->error_text_.get() + return controller_ ? controller_->caption_bubble_->generic_error_text_.get() : nullptr; } views::ImageView* GetErrorIcon() { - return controller_ ? controller_->caption_bubble_->error_icon_.get() + return controller_ ? controller_->caption_bubble_->generic_error_icon_.get() : nullptr; } @@ -166,7 +168,9 @@ void OnError() { OnError(GetCaptionBubbleContext()); } void OnError(CaptionBubbleContext* caption_bubble_context) { - GetController()->OnError(caption_bubble_context); + GetController()->OnError(caption_bubble_context, + CaptionBubbleErrorType::GENERIC, + base::RepeatingClosure()); } void OnAudioStreamEnd() {
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc index a5e0a97..bc57a8d2 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -215,6 +215,14 @@ #endif } + if (icon_str == "googlePasswordManager") { +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + return ImageViewFromVectorIcon(kGooglePasswordManagerIcon); +#else + return ImageViewFromVectorIcon(kKeyIcon); +#endif + } + #if !BUILDFLAG(GOOGLE_CHROME_BRANDING) if (icon_str == "googlePay" || icon_str == "googlePayDark") { return nullptr; @@ -236,9 +244,9 @@ return GetIconImageViewByName(suggestion.icon); } -std::unique_ptr<views::ImageView> GetStoreIndicatorIconImageView( +std::unique_ptr<views::ImageView> GetTrailingIconImageView( const autofill::Suggestion& suggestion) { - return GetIconImageViewByName(suggestion.store_indicator_icon); + return GetIconImageViewByName(suggestion.trailing_icon); } // Creates a label with a specific context and style. @@ -787,12 +795,12 @@ } AddChildView(std::move(all_labels)); - std::unique_ptr<views::ImageView> store_indicator_icon = - GetStoreIndicatorIconImageView(suggestions[GetLineNumber()]); - if (store_indicator_icon) { + std::unique_ptr<views::ImageView> trailing_icon = + GetTrailingIconImageView(suggestions[GetLineNumber()]); + if (trailing_icon) { AddSpacerWithSize(GetHorizontalMargin(), /*resize=*/true, layout_manager); - AddChildView(std::move(store_indicator_icon)); + AddChildView(std::move(trailing_icon)); } } @@ -1155,11 +1163,11 @@ AddChildView(std::move(icon)); } - std::unique_ptr<views::ImageView> store_indicator_icon = - GetStoreIndicatorIconImageView(suggestion); - if (store_indicator_icon) { + std::unique_ptr<views::ImageView> trailing_icon = + GetTrailingIconImageView(suggestion); + if (trailing_icon) { AddSpacerWithSize(GetHorizontalMargin(), /*resize=*/true, layout_manager); - AddChildView(std::move(store_indicator_icon)); + AddChildView(std::move(trailing_icon)); } }
diff --git a/chrome/browser/ui/views/download/download_started_animation_views.cc b/chrome/browser/ui/views/download/download_started_animation_views.cc index 1633889..6cbb2bd 100644 --- a/chrome/browser/ui/views/download/download_started_animation_views.cc +++ b/chrome/browser/ui/views/download/download_started_animation_views.cc
@@ -8,6 +8,7 @@ #include "base/i18n/rtl.h" #include "base/time/time.h" #include "chrome/app/vector_icons/vector_icons.h" +#include "chrome/browser/ui/color/chrome_color_id.h" #include "content/public/browser/web_contents.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/base/metadata/metadata_impl_macros.h" @@ -66,16 +67,16 @@ DownloadStartedAnimationViews::DownloadStartedAnimationViews( content::WebContents* web_contents) : gfx::LinearAnimation(kMoveTime, kFrameRateHz, nullptr), popup_(nullptr) { - gfx::ImageSkia download_image = - gfx::CreateVectorIcon(kFileDownloadShelfIcon, 72, gfx::kGoogleBlue500); + auto download_image = ui::ImageModel::FromVectorIcon( + kFileDownloadShelfIcon, kColorDownloadStartedAnimationForeground, 72); // If we're too small to show the download image, then don't bother - // the shelf will be enough. web_contents_bounds_ = web_contents->GetContainerBounds(); - if (web_contents_bounds_.height() < download_image.height()) + if (web_contents_bounds_.height() < download_image.Size().height()) return; - SetImage(&download_image); + SetImage(download_image); popup_ = new views::Widget;
diff --git a/chrome/browser/ui/views/frame/top_container_loading_bar.cc b/chrome/browser/ui/views/frame/top_container_loading_bar.cc index dc9c718..838fbc55 100644 --- a/chrome/browser/ui/views/frame/top_container_loading_bar.cc +++ b/chrome/browser/ui/views/frame/top_container_loading_bar.cc
@@ -6,8 +6,10 @@ #include "chrome/browser/favicon/favicon_utils.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/tab_ui_helper.h" #include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/color/color_provider.h" #include "ui/compositor/layer.h" #include "ui/gfx/animation/tween.h" #include "ui/gfx/canvas.h" @@ -70,11 +72,16 @@ void LoadingBarView::OnPaint(gfx::Canvas* canvas) { if (is_shown_when_not_animating_ || animation_.is_animating()) { - canvas->FillRect(GetLocalBounds(), gfx::kGoogleBlue100); + const auto* const color_provider = GetColorProvider(); + canvas->FillRect( + GetLocalBounds(), + color_provider->GetColor(kColorTabstripLoadingProgressBackground)); gfx::Rect progress_bounds(GetLocalBounds()); progress_bounds.set_width(gfx::Tween::IntValueBetween( GetDisplayedLoadingProgress(), 0, progress_bounds.width())); - canvas->FillRect(progress_bounds, gfx::kGoogleBlue500); + canvas->FillRect( + progress_bounds, + color_provider->GetColor(kColorTabstripLoadingProgressForeground)); } }
diff --git a/chrome/browser/ui/views/lens/lens_side_panel_controller.cc b/chrome/browser/ui/views/lens/lens_side_panel_controller.cc index af42ff0..0ec960a51 100644 --- a/chrome/browser/ui/views/lens/lens_side_panel_controller.cc +++ b/chrome/browser/ui/views/lens/lens_side_panel_controller.cc
@@ -152,8 +152,12 @@ ui::PageTransition transition, bool started_from_context_menu, bool renderer_initiated) { - content::OpenURLParams params(url, content::Referrer(), disposition, - transition, renderer_initiated); + content::OpenURLParams params(url, referrer, disposition, transition, + renderer_initiated); + // If the navigation is initiated by the renderer process, we must set an + // initiator origin. + if (renderer_initiated) + params.initiator_origin = url::Origin::Create(url); browser_view_->browser()->OpenURL(params); base::RecordAction(base::UserMetricsAction("LensSidePanel.ResultLinkClick")); }
diff --git a/chrome/browser/ui/views/media_router/cast_toolbar_button.cc b/chrome/browser/ui/views/media_router/cast_toolbar_button.cc index 0a5dc68..52f50b6 100644 --- a/chrome/browser/ui/views/media_router/cast_toolbar_button.cc +++ b/chrome/browser/ui/views/media_router/cast_toolbar_button.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/media_router/media_router_ui_service.h" #include "chrome/grit/generated_resources.h" @@ -166,18 +167,19 @@ const gfx::VectorIcon* new_icon = nullptr; SkColor icon_color; + const auto* const color_provider = GetColorProvider(); if (severity == Severity::NOTIFICATION && !has_local_route_) { new_icon = &vector_icons::kMediaRouterIdleIcon; icon_color = gfx::kPlaceholderColor; } else if (severity == Severity::FATAL) { new_icon = &vector_icons::kMediaRouterErrorIcon; - icon_color = GetColorProvider()->GetColor(ui::kColorAlertHighSeverity); + icon_color = color_provider->GetColor(kColorMediaRouterIconError); } else if (severity == Severity::WARNING) { new_icon = &vector_icons::kMediaRouterWarningIcon; - icon_color = GetColorProvider()->GetColor(ui::kColorAlertMediumSeverity); + icon_color = color_provider->GetColor(kColorMediaRouterIconWarning); } else { new_icon = &vector_icons::kMediaRouterActiveIcon; - icon_color = gfx::kGoogleBlue500; + icon_color = color_provider->GetColor(kColorMediaRouterIconActive); } // This function is called when system theme changes. If an idle icon is
diff --git a/chrome/browser/ui/views/media_router/cast_toolbar_button_unittest.cc b/chrome/browser/ui/views/media_router/cast_toolbar_button_unittest.cc index cc7b2f69..63a9e09 100644 --- a/chrome/browser/ui/views/media_router/cast_toolbar_button_unittest.cc +++ b/chrome/browser/ui/views/media_router/cast_toolbar_button_unittest.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/themes/theme_service.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/media_router/media_router_ui_service.h" #include "chrome/browser/ui/media_router/media_router_ui_service_factory.h" #include "chrome/browser/ui/toolbar/media_router_contextual_menu.h" @@ -108,12 +109,13 @@ ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON))); warning_icon_ = gfx::Image(gfx::CreateVectorIcon( vector_icons::kMediaRouterWarningIcon, - color_provider->GetColor(ui::kColorAlertMediumSeverity))); + color_provider->GetColor(kColorMediaRouterIconWarning))); error_icon_ = gfx::Image(gfx::CreateVectorIcon( vector_icons::kMediaRouterErrorIcon, - color_provider->GetColor(ui::kColorAlertHighSeverity))); + color_provider->GetColor(kColorMediaRouterIconError))); active_icon_ = gfx::Image(gfx::CreateVectorIcon( - vector_icons::kMediaRouterActiveIcon, gfx::kGoogleBlue500)); + vector_icons::kMediaRouterActiveIcon, + color_provider->GetColor(kColorMediaRouterIconActive))); } void TearDown() override {
diff --git a/chrome/browser/ui/views/passwords/password_items_view.cc b/chrome/browser/ui/views/passwords/password_items_view.cc index 66a2992..ea6e1167 100644 --- a/chrome/browser/ui/views/passwords/password_items_view.cc +++ b/chrome/browser/ui/views/passwords/password_items_view.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "components/password_manager/core/browser/password_form.h" +#include "components/password_manager/core/common/password_manager_features.h" #include "components/password_manager/core/common/password_manager_ui.h" #include "components/vector_icons/vector_icons.h" #include "ui/base/l10n/l10n_util.h" @@ -48,6 +49,8 @@ namespace { +constexpr int kIconHeight = 20; + // Column set identifiers for displaying or undoing removal of credentials. // All of them allocate space differently. enum PasswordItemsViewColumnSetType { @@ -287,6 +290,9 @@ } RecreateLayout(); } + + SetShowIcon(base::FeatureList::IsEnabled( + password_manager::features::kUnifiedPasswordManagerDesktop)); } PasswordItemsView::~PasswordItemsView() = default; @@ -299,6 +305,15 @@ return &controller_; } +ui::ImageModel PasswordItemsView::GetWindowIcon() { +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + return ui::ImageModel::FromVectorIcon(kGooglePasswordManagerIcon, + ui::kColorIcon, kIconHeight); +#else + return ui::ImageModel::FromVectorIcon(kKeyIcon, ui::kColorIcon, kIconHeight); +#endif +} + void PasswordItemsView::RecreateLayout() { // This method should only be used when we have password rows, otherwise the // dialog should only show the no-passwords title and doesn't need to be
diff --git a/chrome/browser/ui/views/passwords/password_items_view.h b/chrome/browser/ui/views/passwords/password_items_view.h index 7978604..39d78466 100644 --- a/chrome/browser/ui/views/passwords/password_items_view.h +++ b/chrome/browser/ui/views/passwords/password_items_view.h
@@ -32,6 +32,7 @@ // PasswordBubbleViewBase PasswordBubbleControllerBase* GetController() override; const PasswordBubbleControllerBase* GetController() const override; + ui::ImageModel GetWindowIcon() override; void NotifyPasswordFormAction( const password_manager::PasswordForm& password_form,
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc index f3f4ae26..9d427ad 100644 --- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -876,9 +876,6 @@ }, dialog())); - // TODO(pbos): Investigate whether this override is necessary. - link_style.override_color = gfx::kGoogleBlue700; - return views::Builder<views::BoxLayoutView>() .SetOrientation(views::BoxLayout::Orientation::kVertical) .SetInsideBorderInsets(gfx::Insets(0, kPaymentRequestRowHorizontalInsets))
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc index f7435aca..6c68e38 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc +++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
@@ -162,6 +162,7 @@ global_registry_->ResetActiveEntry(); if (auto* contextual_registry = GetActiveContextualRegistry()) contextual_registry->ResetActiveEntry(); + ClearCachedEntryViews(); // TODO(pbos): Make this button observe panel-visibility state instead. browser_view_->toolbar()->side_panel_button()->SetTooltipText( @@ -227,13 +228,37 @@ views::View* content_wrapper = GetContentView()->GetViewByID(kSidePanelContentWrapperViewId); DCHECK(content_wrapper); - content_wrapper->RemoveAllChildViews(); - content_wrapper->AddChildView(entry->CreateContent()); + // |content_wrapper| should have either no child views or one child view for + // the currently hosted SidePanelEntry. + DCHECK(content_wrapper->children().size() <= 1); + if (content_wrapper->children().size()) { + DCHECK(GetLastActiveEntryId().has_value()); + SidePanelEntry* current_entry = + GetEntryForId(GetLastActiveEntryId().value()); + DCHECK(current_entry); + auto current_entry_view = + content_wrapper->RemoveChildViewT(content_wrapper->children().front()); + current_entry->CacheView(std::move(current_entry_view)); + } + content_wrapper->AddChildView(entry->GetContent()); if (auto* contextual_registry = GetActiveContextualRegistry()) contextual_registry->ResetActiveEntry(); entry->OnEntryShown(); } +void SidePanelCoordinator::ClearCachedEntryViews() { + global_registry_->ClearCachedEntryViews(); + TabStripModel* model = browser_view_->browser()->tab_strip_model(); + if (!model) + return; + for (int index = 0; index < model->count(); ++index) { + auto* web_contents = + browser_view_->browser()->tab_strip_model()->GetWebContentsAt(index); + if (auto* registry = SidePanelRegistry::Get(web_contents)) + registry->ClearCachedEntryViews(); + } +} + absl::optional<SidePanelEntry::Id> SidePanelCoordinator::GetLastActiveEntryId() const { // If a contextual entry is active, return that. If not, return the last @@ -356,9 +381,15 @@ void SidePanelCoordinator::OnEntryWillDeregister(SidePanelEntry* entry) { combobox_model_->RemoveItem(entry->id()); // Update the current entry to make sure we don't show an entry that is being - // removed. - if (GetContentView()) - Show(GetLastActiveEntryId().value_or(kDefaultEntry)); + // removed or close the panel if the entry being deregistered is the only one + // that has been visible. + if (GetContentView()) { + if (global_registry_->active_entry().has_value()) { + Show(GetLastActiveEntryId().value_or(kDefaultEntry)); + } else { + Close(); + } + } } void SidePanelCoordinator::OnTabStripModelChanged(
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator.h b/chrome/browser/ui/views/side_panel/side_panel_coordinator.h index c146d10a..83b462f2 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_coordinator.h +++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator.h
@@ -57,6 +57,10 @@ // and populates the side panel with the provided SidePanelEntry. void PopulateSidePanel(SidePanelEntry* entry); + // Clear cached views for registry entries for global and contextual + // registries. + void ClearCachedEntryViews(); + // Returns the last active entry or the reading list entry if no last active // entry exists. absl::optional<SidePanelEntry::Id> GetLastActiveEntryId() const;
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc b/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc index 3cc04f1..8385bad 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc +++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc
@@ -174,11 +174,21 @@ TEST_F(SidePanelCoordinatorTest, ContextualEntryDeregisteredWhileVisible) { browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + coordinator_->Show(SidePanelEntry::Id::kReadingList); + EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kReadingList); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kReadingList); + EXPECT_FALSE(contextual_registries_[0]->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + coordinator_->Show(SidePanelEntry::Id::kSideSearch); EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); EXPECT_TRUE(GetLastActiveEntryId().has_value()); EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kSideSearch); - EXPECT_FALSE(global_registry_->active_entry().has_value()); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kReadingList); VerifyEntryExistanceAndValue(contextual_registries_[0]->active_entry(), SidePanelEntry::Id::kSideSearch); EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); @@ -198,6 +208,33 @@ EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); } +// Test that the side panel closes if a contextual entry is deregistered while +// visible when no globel entries have been shown since the panel was opened. +TEST_F( + SidePanelCoordinatorTest, + ContextualEntryDeregisteredWhileVisibleClosesPanelIfNoLastSeenGlobalEntryExists) { + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + coordinator_->Show(SidePanelEntry::Id::kSideSearch); + EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(global_registry_->active_entry().has_value()); + VerifyEntryExistanceAndValue(contextual_registries_[0]->active_entry(), + SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Deregister kSideSearch from the first tab. + contextual_registries_[0]->Deregister(SidePanelEntry::Id::kSideSearch); + EXPECT_EQ(contextual_registries_[0]->entries().size(), 0u); + + // Verify the panel closes. + EXPECT_FALSE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_FALSE(GetLastActiveEntryId().has_value()); + EXPECT_FALSE(global_registry_->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[0]->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); +} + TEST_F(SidePanelCoordinatorTest, ShowContextualEntry) { browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); coordinator_->Show(SidePanelEntry::Id::kSideSearch);
diff --git a/chrome/browser/ui/views/side_panel/side_panel_entry.cc b/chrome/browser/ui/views/side_panel/side_panel_entry.cc index 0ae2e91..3b373e2 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_entry.cc +++ b/chrome/browser/ui/views/side_panel/side_panel_entry.cc
@@ -22,10 +22,20 @@ SidePanelEntry::~SidePanelEntry() = default; -std::unique_ptr<views::View> SidePanelEntry::CreateContent() { +std::unique_ptr<views::View> SidePanelEntry::GetContent() { + if (content_view_) + return std::move(content_view_); return create_content_callback_.Run(); } +void SidePanelEntry::CacheView(std::unique_ptr<views::View> view) { + content_view_ = std::move(view); +} + +void SidePanelEntry::ClearCachedView() { + content_view_.reset(nullptr); +} + void SidePanelEntry::OnEntryShown() { for (SidePanelEntryObserver& observer : observers_) observer.OnEntryShown(this);
diff --git a/chrome/browser/ui/views/side_panel/side_panel_entry.h b/chrome/browser/ui/views/side_panel/side_panel_entry.h index b2e1d55..151b907b 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_entry.h +++ b/chrome/browser/ui/views/side_panel/side_panel_entry.h
@@ -34,7 +34,10 @@ // Creates the content to be shown inside the side panel when this entry is // shown. - std::unique_ptr<views::View> CreateContent(); + std::unique_ptr<views::View> GetContent(); + void CacheView(std::unique_ptr<views::View> view); + void ClearCachedView(); + // Called when the entry has been shown in the side panel. void OnEntryShown(); @@ -49,6 +52,7 @@ const Id id_; const std::u16string name_; const ui::ImageModel icon_; + std::unique_ptr<views::View> content_view_; base::RepeatingCallback<std::unique_ptr<views::View>()> create_content_callback_;
diff --git a/chrome/browser/ui/views/side_panel/side_panel_registry.cc b/chrome/browser/ui/views/side_panel/side_panel_registry.cc index ab95f075..1dfa98d 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_registry.cc +++ b/chrome/browser/ui/views/side_panel/side_panel_registry.cc
@@ -43,6 +43,11 @@ active_entry_.reset(); } +void SidePanelRegistry::ClearCachedEntryViews() { + for (auto const& entry : entries_) + entry.get()->ClearCachedView(); +} + void SidePanelRegistry::AddObserver(SidePanelRegistryObserver* observer) { observers_.AddObserver(observer); }
diff --git a/chrome/browser/ui/views/side_panel/side_panel_registry.h b/chrome/browser/ui/views/side_panel/side_panel_registry.h index 9cec2b1..1891606 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_registry.h +++ b/chrome/browser/ui/views/side_panel/side_panel_registry.h
@@ -36,6 +36,9 @@ SidePanelEntry* GetEntryForId(SidePanelEntry::Id entry_id); void ResetActiveEntry(); + // Clear cached view for all owned entries. + void ClearCachedEntryViews(); + void AddObserver(SidePanelRegistryObserver* observer); void RemoveObserver(SidePanelRegistryObserver* observer);
diff --git a/chrome/browser/ui/views/tab_sharing/tab_capture_contents_border_helper.cc b/chrome/browser/ui/views/tab_sharing/tab_capture_contents_border_helper.cc index 2845388..793de00 100644 --- a/chrome/browser/ui/views/tab_sharing/tab_capture_contents_border_helper.cc +++ b/chrome/browser/ui/views/tab_sharing/tab_capture_contents_border_helper.cc
@@ -9,6 +9,7 @@ #include "build/chromeos_buildflags.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "ui/gfx/color_palette.h" @@ -18,17 +19,28 @@ namespace { -#if !BUILDFLAG(IS_CHROMEOS_ASH) -constexpr int kContentsBorderThickness = 5; -constexpr float kContentsBorderOpacity = 0.50; -constexpr SkColor kContentsBorderColor = gfx::kGoogleBlue500; -#endif - constexpr int kMinContentsBorderWidth = 20; constexpr int kMinContentsBorderHeight = 20; // TODO(https://crbug.com/1030925): Fix contents border on ChromeOS. #if !BUILDFLAG(IS_CHROMEOS_ASH) +class BorderView : public views::View { + public: + BorderView() = default; + BorderView(const BorderView&) = delete; + BorderView& operator=(const BorderView&) = delete; + ~BorderView() override = default; + + void OnThemeChanged() override { + views::View::OnThemeChanged(); + + constexpr int kContentsBorderThickness = 5; + SetBorder(views::CreateSolidBorder( + kContentsBorderThickness, + GetColorProvider()->GetColor(kColorCapturedTabContentsBorder))); + } +}; + void InitContentsBorderWidget(content::WebContents* web_contents) { Browser* const browser = chrome::FindBrowserWithWebContents(web_contents); if (!browser) { @@ -60,12 +72,9 @@ #endif // BUILDFLAG(IS_WIN) widget->Init(std::move(params)); - auto border_view = std::make_unique<views::View>(); - border_view->SetBorder( - views::CreateSolidBorder(kContentsBorderThickness, kContentsBorderColor)); - widget->SetContentsView(std::move(border_view)); + widget->SetContentsView(std::make_unique<BorderView>()); widget->SetVisibilityChangedAnimationsEnabled(false); - widget->SetOpacity(kContentsBorderOpacity); + widget->SetOpacity(0.50f); // TODO(crbug.com/1276822): Associate each captured tab with its own widget. // Otherwise, if tab A captures B, and tab C captures D, and all are in
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc index 07d4861..9b9c3fa5 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
@@ -741,10 +741,10 @@ run_loop.QuitClosure()); GURL url = GetAppStartURL(site_mode); { - DictionaryPrefUpdate updateDict(profile()->GetPrefs(), - prefs::kWebAppSettings); - base::Value* dict = updateDict.Get(); - dict->RemoveKey(url.spec()); + ListPrefUpdate updateList(profile()->GetPrefs(), prefs::kWebAppSettings); + updateList->GetList().EraseIf([&](const base::Value& item) { + return item.FindKey(kManifestId)->GetString() == url.spec(); + }); } run_loop.Run(); AfterStateChangeAction(); @@ -2021,12 +2021,16 @@ run_loop.QuitClosure()); GURL url = GetAppStartURL(site_mode); { + ListPrefUpdate updateList(profile()->GetPrefs(), prefs::kWebAppSettings); + updateList->EraseListValueIf([&](const base::Value& item) { + return item.FindKey(kManifestId)->GetString() == url.spec(); + }); + base::Value dictItem(base::Value::Type::DICTIONARY); + dictItem.SetKey(kManifestId, base::Value(url.spec())); dictItem.SetKey(kRunOnOsLogin, base::Value(policy)); - DictionaryPrefUpdate updateDict(profile()->GetPrefs(), - prefs::kWebAppSettings); - base::Value* dict = updateDict.Get(); - dict->SetKey(url.spec(), std::move(dictItem)); + + updateList.Get()->Append(std::move(dictItem)); } run_loop.Run(); }
diff --git a/chrome/browser/ui/views/webauthn/authenticator_client_pin_entry_view.cc b/chrome/browser/ui/views/webauthn/authenticator_client_pin_entry_view.cc index 2047358b..0dad97b 100644 --- a/chrome/browser/ui/views/webauthn/authenticator_client_pin_entry_view.cc +++ b/chrome/browser/ui/views/webauthn/authenticator_client_pin_entry_view.cc
@@ -8,11 +8,13 @@ #include <utility> #include "base/strings/string_number_conversions.h" +#include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/color/color_provider.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/geometry/insets.h" #include "ui/views/border.h" @@ -24,23 +26,28 @@ namespace { -std::unique_ptr<views::Textfield> MakePinTextField( - views::TextfieldController* controller, - views::View* label) { - constexpr int kMinWidthInChars = 6; - constexpr int kDefaultWidthInChars = 20; - constexpr int kBottomBorderThickness = 2; +class PinTextfield : public views::Textfield { + public: + PinTextfield(views::TextfieldController* controller, views::View* label) { + SetTextInputType(ui::TextInputType::TEXT_INPUT_TYPE_PASSWORD); + SetMinimumWidthInChars(6); + SetDefaultWidthInChars(20); - auto field = std::make_unique<views::Textfield>(); - field->SetTextInputType(ui::TextInputType::TEXT_INPUT_TYPE_PASSWORD); - field->SetMinimumWidthInChars(kMinWidthInChars); - field->SetDefaultWidthInChars(kDefaultWidthInChars); - field->SetBorder(views::CreateSolidSidedBorder(0, 0, kBottomBorderThickness, - 0, gfx::kGoogleBlue500)); - field->set_controller(controller); - field->SetAssociatedLabel(label); - return field; -} + set_controller(controller); + SetAssociatedLabel(label); + } + PinTextfield(const PinTextfield&) = delete; + PinTextfield& operator=(const PinTextfield&) = delete; + ~PinTextfield() override = default; + + void OnThemeChanged() override { + views::Textfield::OnThemeChanged(); + constexpr int kBottomBorderThickness = 2; + SetBorder(views::CreateSolidSidedBorder( + 0, 0, kBottomBorderThickness, 0, + GetColorProvider()->GetColor(kColorWebAuthnPinTextfieldBottomBorder))); + } +}; } // namespace @@ -81,13 +88,13 @@ AddChildView(std::make_unique<views::View>()); } - pin_text_field_ = AddChildView(MakePinTextField(this, pin_label)); + pin_text_field_ = + AddChildView(std::make_unique<PinTextfield>(this, pin_label)); if (show_confirmation_text_field_) { DCHECK(confirmation_label_ptr); - auto confirmation_text_field = - MakePinTextField(this, confirmation_label_ptr); - confirmation_text_field_ = AddChildView(std::move(confirmation_text_field)); + confirmation_text_field_ = AddChildView( + std::make_unique<PinTextfield>(this, confirmation_label_ptr)); } else { AddChildView(std::make_unique<views::View>()); }
diff --git a/chrome/browser/ui/webui/app_management/app_management_page_handler.cc b/chrome/browser/ui/webui/app_management/app_management_page_handler.cc index aa49670..fba61a9 100644 --- a/chrome/browser/ui/webui/app_management/app_management_page_handler.cc +++ b/chrome/browser/ui/webui/app_management/app_management_page_handler.cc
@@ -64,7 +64,7 @@ #if BUILDFLAG(IS_WIN) const char kFileHandlingLearnMore[] = ""; -#elif !BUILDFLAG(IS_CHROMEOS) +#else const char kFileHandlingLearnMore[] = "https://support.google.com/chrome/?p=pwa_default_associations"; #endif @@ -401,16 +401,16 @@ std::move(run_on_os_login.value())); } -// TODO(crbug/1245293): implement on Chrome OS. -#if !BUILDFLAG(IS_CHROMEOS) if (update.AppType() == apps::AppType::kWeb) { - auto* provider = web_app::WebAppProvider::GetForWebApps(profile_); + auto* provider = + web_app::WebAppProvider::GetForLocalAppsUnchecked(profile_); const bool fh_enabled = !provider->registrar().IsAppFileHandlerPermissionBlocked(app->id); std::string file_handling_types; std::string file_handling_types_label; if (provider->os_integration_manager().IsFileHandlingAPIAvailable( app->id) && + !provider->registrar().IsSystemApp(app->id) && !provider->registrar().GetAppFileHandlers(app->id)->empty()) { auto [file_handling_types16, count] = web_app::GetFileTypeAssociationsHandledByWebAppForDisplay(profile_, @@ -439,7 +439,6 @@ fh_enabled, /*is_managed=*/false, file_handling_types, file_handling_types_label, GURL(kFileHandlingLearnMore)); } -#endif return app; }
diff --git a/chrome/browser/ui/webui/certificate_provisioning_ui_handler_unittest.cc b/chrome/browser/ui/webui/certificate_provisioning_ui_handler_unittest.cc index 2ed26e3d..9971a3a 100644 --- a/chrome/browser/ui/webui/certificate_provisioning_ui_handler_unittest.cc +++ b/chrome/browser/ui/webui/certificate_provisioning_ui_handler_unittest.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/webui/certificate_provisioning_ui_handler.h" #include <algorithm> +#include <memory> #include <string> #include <utility> #include <vector> @@ -134,7 +135,7 @@ base::Value GetByProfileId(const base::Value& all_processes, const std::string& profile_id) { for (const base::Value& process : all_processes.GetListDeprecated()) { - if (profile_id == *process.FindStringKey("certProfileId")) + if (profile_id == *process.GetDict().FindString("certProfileId")) return process.Clone(); } return base::Value(); @@ -202,7 +203,8 @@ return; out_profile_ids->clear(); for (const base::Value& process : out_all_processes->GetListDeprecated()) { - const std::string* profile_id = process.FindStringKey("certProfileId"); + const std::string* profile_id = + process.GetDict().FindString("certProfileId"); ASSERT_TRUE(profile_id); out_profile_ids->push_back(*profile_id); }
diff --git a/chrome/browser/ui/webui/certificates_handler.cc b/chrome/browser/ui/webui/certificates_handler.cc index 916cde1..10eb3e1 100644 --- a/chrome/browser/ui/webui/certificates_handler.cc +++ b/chrome/browser/ui/webui/certificates_handler.cc
@@ -11,6 +11,7 @@ #include <algorithm> #include <map> #include <utility> +#include <vector> #include "base/bind.h" #include "base/callback_helpers.h" @@ -100,10 +101,10 @@ std::u16string a_str; std::u16string b_str; const std::string* ptr = - a_dict->FindStringKey(kCertificatesHandlerNameField); + a_dict->GetDict().FindString(kCertificatesHandlerNameField); if (ptr) a_str = base::UTF8ToUTF16(*ptr); - ptr = b_dict->FindStringKey(kCertificatesHandlerNameField); + ptr = b_dict->GetDict().FindString(kCertificatesHandlerNameField); if (ptr) b_str = base::UTF8ToUTF16(*ptr); if (collator_ == nullptr) @@ -437,13 +438,13 @@ net::CA_CERT); std::unique_ptr<base::DictionaryValue> ca_trust_info( new base::DictionaryValue); - ca_trust_info->SetBoolKey( + ca_trust_info->GetDict().Set( kCertificatesHandlerSslField, static_cast<bool>(trust_bits & net::NSSCertDatabase::TRUSTED_SSL)); - ca_trust_info->SetBoolKey( + ca_trust_info->GetDict().Set( kCertificatesHandlerEmailField, static_cast<bool>(trust_bits & net::NSSCertDatabase::TRUSTED_EMAIL)); - ca_trust_info->SetBoolKey( + ca_trust_info->GetDict().Set( kCertificatesHandlerObjSignField, static_cast<bool>(trust_bits & net::NSSCertDatabase::TRUSTED_OBJ_SIGN)); ResolveCallback(*ca_trust_info); @@ -1017,10 +1018,11 @@ for (auto& org_grouping_map_entry : org_grouping_map) { // Populate first level (org name). base::DictionaryValue org_dict; - org_dict.SetKey(kCertificatesHandlerKeyField, - base::Value(OrgNameToId(org_grouping_map_entry.first))); - org_dict.SetKey(kCertificatesHandlerNameField, - base::Value(org_grouping_map_entry.first)); + org_dict.GetDict().Set( + kCertificatesHandlerKeyField, + base::Value(OrgNameToId(org_grouping_map_entry.first))); + org_dict.GetDict().Set(kCertificatesHandlerNameField, + base::Value(org_grouping_map_entry.first)); // Populate second level (certs). base::ListValue subnodes; @@ -1032,26 +1034,26 @@ base::NumberToString(cert_info_id_map_.Add(std::move(org_cert))); base::DictionaryValue cert_dict; - cert_dict.SetKey(kCertificatesHandlerKeyField, base::Value(id)); - cert_dict.SetKey(kCertificatesHandlerNameField, - base::Value(cert_info->name())); - cert_dict.SetKey(kCertificatesHandlerCanBeDeletedField, - base::Value(CanDeleteCertificate(cert_info))); - cert_dict.SetKey(kCertificatesHandlerCanBeEditedField, - base::Value(CanEditCertificate(cert_info))); - cert_dict.SetKey(kCertificatesHandlerUntrustedField, - base::Value(cert_info->untrusted())); - cert_dict.SetKey( + cert_dict.GetDict().Set(kCertificatesHandlerKeyField, base::Value(id)); + cert_dict.GetDict().Set(kCertificatesHandlerNameField, + base::Value(cert_info->name())); + cert_dict.GetDict().Set(kCertificatesHandlerCanBeDeletedField, + base::Value(CanDeleteCertificate(cert_info))); + cert_dict.GetDict().Set(kCertificatesHandlerCanBeEditedField, + base::Value(CanEditCertificate(cert_info))); + cert_dict.GetDict().Set(kCertificatesHandlerUntrustedField, + base::Value(cert_info->untrusted())); + cert_dict.GetDict().Set( kCertificatesHandlerPolicyInstalledField, base::Value(cert_info->source() == CertificateManagerModel::CertInfo::Source::kPolicy)); - cert_dict.SetKey(kCertificatesHandlerWebTrustAnchorField, - base::Value(cert_info->web_trust_anchor())); + cert_dict.GetDict().Set(kCertificatesHandlerWebTrustAnchorField, + base::Value(cert_info->web_trust_anchor())); // TODO(hshi): This should be determined by testing for PKCS #11 // CKA_EXTRACTABLE attribute. We may need to use the NSS function // PK11_ReadRawAttribute to do that. - cert_dict.SetKey(kCertificatesHandlerExtractableField, - base::Value(!cert_info->hardware_backed())); + cert_dict.GetDict().Set(kCertificatesHandlerExtractableField, + base::Value(!cert_info->hardware_backed())); // TODO(mattm): Other columns. subnodes.Append(std::move(cert_dict)); @@ -1062,9 +1064,10 @@ std::sort(subnodes.GetListDeprecated().begin(), subnodes.GetListDeprecated().end(), comparator); - org_dict.SetKey(kCertificatesHandlerContainsPolicyCertsField, - base::Value(contains_policy_certs)); - org_dict.SetKey(kCertificatesHandlerSubnodesField, std::move(subnodes)); + org_dict.GetDict().Set(kCertificatesHandlerContainsPolicyCertsField, + base::Value(contains_policy_certs)); + org_dict.GetDict().Set(kCertificatesHandlerSubnodesField, + std::move(subnodes)); nodes.Append(std::move(org_dict)); } std::sort(nodes.GetListDeprecated().begin(), nodes.GetListDeprecated().end(), @@ -1091,8 +1094,8 @@ void CertificatesHandler::RejectCallbackWithError(const std::string& title, const std::string& error) { std::unique_ptr<base::DictionaryValue> error_info(new base::DictionaryValue); - error_info->SetStringKey(kCertificatesHandlerErrorTitle, title); - error_info->SetStringKey(kCertificatesHandlerErrorDescription, error); + error_info->GetDict().Set(kCertificatesHandlerErrorTitle, title); + error_info->GetDict().Set(kCertificatesHandlerErrorDescription, error); RejectCallback(*error_info); } @@ -1115,17 +1118,17 @@ for (size_t i = 0; i < not_imported.size(); ++i) { const net::NSSCertDatabase::ImportCertFailure& failure = not_imported[i]; std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue); - dict->SetStringKey(kCertificatesHandlerNameField, - x509_certificate_model::GetSubjectDisplayName( - failure.certificate.get())); - dict->SetStringKey(kCertificatesHandlerErrorField, - NetErrorToString(failure.net_error)); + dict->GetDict().Set(kCertificatesHandlerNameField, + x509_certificate_model::GetSubjectDisplayName( + failure.certificate.get())); + dict->GetDict().Set(kCertificatesHandlerErrorField, + NetErrorToString(failure.net_error)); cert_error_list->Append(std::move(dict)); } std::unique_ptr<base::DictionaryValue> error_info(new base::DictionaryValue); - error_info->SetStringKey(kCertificatesHandlerErrorTitle, title); - error_info->SetStringKey(kCertificatesHandlerErrorDescription, error); + error_info->GetDict().Set(kCertificatesHandlerErrorTitle, title); + error_info->GetDict().Set(kCertificatesHandlerErrorDescription, error); error_info->Set(kCertificatesHandlerCertificateErrors, std::move(cert_error_list)); RejectCallback(*error_info);
diff --git a/chrome/browser/ui/webui/chromeos/edu_account_login_handler_chromeos.cc b/chrome/browser/ui/webui/chromeos/edu_account_login_handler_chromeos.cc index 2b22733..a45e6fea 100644 --- a/chrome/browser/ui/webui/chromeos/edu_account_login_handler_chromeos.cc +++ b/chrome/browser/ui/webui/chromeos/edu_account_login_handler_chromeos.cc
@@ -182,7 +182,7 @@ args[1].GetAsDictionary(&parent); CHECK(parent); const base::Value* obfuscated_gaia_id_value = - parent->FindKey(kObfuscatedGaiaIdKey); + parent->GetDict().Find(kObfuscatedGaiaIdKey); DCHECK(obfuscated_gaia_id_value); std::string obfuscated_gaia_id = obfuscated_gaia_id_value->GetString(); @@ -269,9 +269,9 @@ } base::DictionaryValue parent; - parent.SetStringKey("email", member.email); - parent.SetStringKey("displayName", member.display_name); - parent.SetStringKey(kObfuscatedGaiaIdKey, member.obfuscated_gaia_id); + parent.GetDict().Set("email", member.email); + parent.GetDict().Set("displayName", member.display_name); + parent.GetDict().Set(kObfuscatedGaiaIdKey, member.obfuscated_gaia_id); parents.Append(std::move(parent)); profile_image_urls[member.obfuscated_gaia_id] = @@ -295,7 +295,7 @@ for (auto& parent : parents.GetListDeprecated()) { const std::string* obfuscated_gaia_id = - parent.FindStringKey(kObfuscatedGaiaIdKey); + parent.GetDict().FindString(kObfuscatedGaiaIdKey); DCHECK(obfuscated_gaia_id); std::string profile_image; if (profile_images[*obfuscated_gaia_id].IsEmpty()) { @@ -309,7 +309,7 @@ profile_image = webui::GetBitmapDataUrl( profile_images[*obfuscated_gaia_id].AsBitmap()); } - parent.SetStringKey("profileImage", profile_image); + parent.GetDict().Set("profileImage", profile_image); } ResolveJavascriptCallback(base::Value(get_parents_callback_id_), parents); @@ -329,7 +329,7 @@ << "Could not get access token to create ReAuthProofToken for parent" << error.ToString(); base::DictionaryValue result; - result.SetBoolKey("isWrongPassword", false); + result.GetDict().Set("isWrongPassword", false); RejectJavascriptCallback(base::Value(parent_signin_callback_id_), result); parent_signin_callback_id_.clear(); return; @@ -354,7 +354,7 @@ gaia_auth_fetcher_.reset(); base::DictionaryValue result; - result.SetBoolKey( + result.GetDict().Set( "isWrongPassword", error == GaiaAuthConsumer::ReAuthProofTokenStatus::kInvalidGrant); RejectJavascriptCallback(base::Value(parent_signin_callback_id_), result);
diff --git a/chrome/browser/ui/webui/chromeos/edu_account_login_handler_unittest.cc b/chrome/browser/ui/webui/chromeos/edu_account_login_handler_unittest.cc index 7112b87..f39dfffb 100644 --- a/chrome/browser/ui/webui/chromeos/edu_account_login_handler_unittest.cc +++ b/chrome/browser/ui/webui/chromeos/edu_account_login_handler_unittest.cc
@@ -89,15 +89,15 @@ base::ListValue parents; base::DictionaryValue parent1; - parent1.SetStringKey("email", "homer@simpson.com"); - parent1.SetStringKey("displayName", "Homer Simpson"); - parent1.SetStringKey("obfuscatedGaiaId", kFakeParentGaiaId); + parent1.GetDict().Set("email", "homer@simpson.com"); + parent1.GetDict().Set("displayName", "Homer Simpson"); + parent1.GetDict().Set("obfuscatedGaiaId", kFakeParentGaiaId); parents.Append(std::move(parent1)); base::DictionaryValue parent2; - parent2.SetStringKey("email", std::string()); - parent2.SetStringKey("displayName", "Marge Simpson"); - parent2.SetStringKey("obfuscatedGaiaId", kFakeParentGaiaId2); + parent2.GetDict().Set("email", std::string()); + parent2.GetDict().Set("displayName", "Marge Simpson"); + parent2.GetDict().Set("obfuscatedGaiaId", kFakeParentGaiaId2); parents.Append(std::move(parent2)); return parents; @@ -109,7 +109,7 @@ for (auto& parent : parents.GetListDeprecated()) { const std::string* obfuscated_gaia_id = - parent.FindStringKey("obfuscatedGaiaId"); + parent.GetDict().FindString("obfuscatedGaiaId"); DCHECK(obfuscated_gaia_id); std::string profile_image; if (profile_images[*obfuscated_gaia_id].IsEmpty()) { @@ -123,7 +123,7 @@ profile_image = webui::GetBitmapDataUrl( profile_images[*obfuscated_gaia_id].AsBitmap()); } - parent.SetStringKey("profileImage", profile_image); + parent.GetDict().Set("profileImage", profile_image); } return parents; @@ -131,10 +131,10 @@ base::DictionaryValue GetFakeParent() { base::DictionaryValue parent; - parent.SetStringKey("email", "homer@simpson.com"); - parent.SetStringKey("displayName", "Homer Simpson"); - parent.SetStringKey("profileImageUrl", "http://profile.url/homer/image"); - parent.SetStringKey("obfuscatedGaiaId", kFakeParentGaiaId); + parent.GetDict().Set("email", "homer@simpson.com"); + parent.GetDict().Set("displayName", "Homer Simpson"); + parent.GetDict().Set("profileImageUrl", "http://profile.url/homer/image"); + parent.GetDict().Set("obfuscatedGaiaId", kFakeParentGaiaId); return parent; } @@ -333,7 +333,7 @@ VerifyJavascriptCallbackResolved(data, callback_id, false /*success*/); base::DictionaryValue result; - result.SetBoolKey("isWrongPassword", false); + result.GetDict().Set("isWrongPassword", false); ASSERT_EQ(result, *data.arg3()); } @@ -367,7 +367,7 @@ VerifyJavascriptCallbackResolved(data, callback_id, false); base::DictionaryValue result; - result.SetBoolKey("isWrongPassword", true); + result.GetDict().Set("isWrongPassword", true); ASSERT_EQ(result, *data.arg3()); }
diff --git a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc index 49aaa0f..a9e5dd5 100644 --- a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc +++ b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
@@ -5,7 +5,10 @@ #include "chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.h" #include <stdint.h> + +#include <string> #include <utility> +#include <vector> #include "base/bind.h" #include "base/callback_helpers.h" @@ -62,7 +65,7 @@ base::StringPiece key, std::string* result) { CHECK(result); - const std::string* value = dict.FindStringKey(key); + const std::string* value = dict.GetDict().FindString(key); if (value) { *result = *value; } @@ -176,15 +179,16 @@ const power_manager::PowerSupplyProperties& proto) { base::DictionaryValue power_properties; - power_properties.SetIntKey("battery_percent", proto.battery_percent()); - power_properties.SetIntKey("battery_state", proto.battery_state()); - power_properties.SetIntKey("external_power", proto.external_power()); - power_properties.SetIntKey("battery_time_to_empty_sec", - proto.battery_time_to_empty_sec()); - power_properties.SetIntKey("battery_time_to_full_sec", - proto.battery_time_to_full_sec()); - power_properties.SetStringKey("external_power_source_id", - proto.external_power_source_id()); + power_properties.GetDict().Set("battery_percent", + int(proto.battery_percent())); + power_properties.GetDict().Set("battery_state", int(proto.battery_state())); + power_properties.GetDict().Set("external_power", int(proto.external_power())); + power_properties.GetDict().Set("battery_time_to_empty_sec", + int(proto.battery_time_to_empty_sec())); + power_properties.GetDict().Set("battery_time_to_full_sec", + int(proto.battery_time_to_full_sec())); + power_properties.GetDict().Set("external_power_source_id", + proto.external_power_source_id()); owner_->FireWebUIListener("power-properties-updated", power_properties); } @@ -269,10 +273,12 @@ bluez::FakeBluetoothDeviceClient::kPairingActionFail); base::Value info(base::Value::Type::DICTIONARY); - info.SetKey("predefined_devices", std::move(predefined_devices)); - info.SetKey("devices", std::move(devices)); - info.SetKey("pairing_method_options", std::move(pairing_method_options)); - info.SetKey("pairing_action_options", std::move(pairing_action_options)); + info.GetDict().Set("predefined_devices", std::move(predefined_devices)); + info.GetDict().Set("devices", std::move(devices)); + info.GetDict().Set("pairing_method_options", + std::move(pairing_method_options)); + info.GetDict().Set("pairing_action_options", + std::move(pairing_action_options)); // Send the list of devices to the view. FireWebUIListener("bluetooth-info-updated", info); @@ -307,11 +313,11 @@ CHECK(device_value.is_dict()); const base::DictionaryValue& device_dict = base::Value::AsDictionaryValue(device_value); - audio_node.is_input = device_dict.FindBoolKey("isInput").value(); + audio_node.is_input = device_dict.GetDict().FindBool("isInput").value(); CHECK(GetString(device_dict, "deviceName", &audio_node.device_name)); CHECK(GetString(device_dict, "type", &audio_node.type)); CHECK(GetString(device_dict, "name", &audio_node.name)); - audio_node.active = device_dict.FindBoolKey("active").value(); + audio_node.active = device_dict.GetDict().FindBool("active").value(); std::string tmp_id; CHECK(GetString(device_dict, "id", &tmp_id)); @@ -414,21 +420,21 @@ CHECK(val.is_dict()); power_manager::PowerSupplyProperties_PowerSource* source = props.add_available_external_power_source(); - const std::string* id = val.FindStringKey("id"); + const std::string* id = val.GetDict().FindString("id"); CHECK(id); source->set_id(*id); - const std::string* device_type = val.FindStringKey("type"); + const std::string* device_type = val.GetDict().FindString("type"); CHECK(device_type); bool dual_role = *device_type == "DualRoleUSB"; source->set_active_by_default(!dual_role); if (dual_role) props.set_supports_dual_role_devices(true); - absl::optional<int> port = val.FindIntKey("port"); + absl::optional<int> port = val.GetDict().FindInt("port"); CHECK(port.has_value()); source->set_port( static_cast<power_manager::PowerSupplyProperties_PowerSource_Port>( port.value())); - const std::string* power_level = val.FindStringKey("power"); + const std::string* power_level = val.GetDict().FindString("power"); CHECK(power_level); source->set_max_power(*power_level == "high" ? kPowerLevelHigh : kPowerLevelLow); @@ -569,12 +575,12 @@ CHECK(GetString(device_dict, "pairingAuthToken", &props.pairing_auth_token)); CHECK(GetString(device_dict, "pairingAction", &props.pairing_action)); - absl::optional<int> class_value = device_dict.FindIntKey("classValue"); + absl::optional<int> class_value = device_dict.GetDict().FindInt("classValue"); CHECK(class_value); props.device_class = *class_value; - props.is_trusted = device_dict.FindBoolKey("isTrusted").value(); - props.incoming = device_dict.FindBoolKey("incoming").value(); + props.is_trusted = device_dict.GetDict().FindBool("isTrusted").value(); + props.incoming = device_dict.GetDict().FindBool("incoming").value(); // Create the device and store it in the FakeBluetoothDeviceClient's observed // list of devices. @@ -593,27 +599,27 @@ fake_bluetooth_device_client_->GetPairingOptions(object_path); base::Value device(base::Value::Type::DICTIONARY); - device.SetStringKey("path", object_path.value()); - device.SetStringKey("name", props->name.value()); - device.SetStringKey("alias", props->alias.value()); - device.SetStringKey("address", props->address.value()); + device.GetDict().Set("path", object_path.value()); + device.GetDict().Set("name", props->name.value()); + device.GetDict().Set("alias", props->alias.value()); + device.GetDict().Set("address", props->address.value()); if (options) { - device.SetStringKey("pairingMethod", options->pairing_method); - device.SetStringKey("pairingAuthToken", options->pairing_auth_token); - device.SetStringKey("pairingAction", options->pairing_action); + device.GetDict().Set("pairingMethod", options->pairing_method); + device.GetDict().Set("pairingAuthToken", options->pairing_auth_token); + device.GetDict().Set("pairingAction", options->pairing_action); } else { - device.SetStringKey("pairingMethod", ""); - device.SetStringKey("pairingAuthToken", ""); - device.SetStringKey("pairingAction", ""); + device.GetDict().Set("pairingMethod", ""); + device.GetDict().Set("pairingAuthToken", ""); + device.GetDict().Set("pairingAction", ""); } - device.SetIntKey("classValue", props->bluetooth_class.value()); - device.SetBoolKey("isTrusted", props->trusted.value()); - device.SetBoolKey("incoming", false); + device.GetDict().Set("classValue", int(props->bluetooth_class.value())); + device.GetDict().Set("isTrusted", bool(props->trusted.value())); + device.GetDict().Set("incoming", false); base::Value uuids(base::Value::Type::LIST); for (const std::string& uuid : props->uuids.value()) uuids.Append(uuid); - device.SetKey("uuids", std::move(uuids)); + device.GetDict().Set("uuids", std::move(uuids)); return device; } @@ -665,12 +671,12 @@ chromeos::FakeCrasAudioClient::Get()->node_list()) { base::Value audio_node(base::Value::Type::DICTIONARY); - audio_node.SetBoolKey("isInput", node.is_input); - audio_node.SetStringKey("id", base::NumberToString(node.id)); - audio_node.SetStringKey("deviceName", node.device_name); - audio_node.SetStringKey("type", node.type); - audio_node.SetStringKey("name", node.name); - audio_node.SetBoolKey("active", node.active); + audio_node.GetDict().Set("isInput", node.is_input); + audio_node.GetDict().Set("id", base::NumberToString(node.id)); + audio_node.GetDict().Set("deviceName", node.device_name); + audio_node.GetDict().Set("type", node.type); + audio_node.GetDict().Set("name", node.name); + audio_node.GetDict().Set("active", node.active); audio_nodes.Append(std::move(audio_node)); }
diff --git a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc index 57485a92..2dcae7bc 100644 --- a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc +++ b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc
@@ -36,21 +36,6 @@ namespace chromeos { namespace { -std::vector<std::string> ConvertToVector(const base::Value& list) { - std::vector<std::string> string_list; - if (!list.is_list()) { - return string_list; - } - - for (const base::Value& value : list.GetListDeprecated()) { - if (value.is_string()) { - string_list.push_back(value.GetString()); - } - } - - return string_list; -} - bool ShouldDoSamlRedirect(const std::string& email) { if (email.empty()) return false; @@ -248,14 +233,12 @@ CHECK_EQ(params.size(), 6u); std::string gaia_id, email, password; bool using_saml; - ::login::StringList services = ::login::StringList(); - const base::DictionaryValue* password_attributes; gaia_id = params[0].GetString(); email = params[1].GetString(); password = params[2].GetString(); using_saml = params[3].GetBool(); - services = ConvertToVector(params[4]); - params[5].GetAsDictionary(&password_attributes); + const auto services = ::login::ConvertToStringList(params[4].GetList()); + const auto& password_attributes = params[5].GetDict(); if (gaia::CanonicalizeEmail(email) != gaia::CanonicalizeEmail(email_)) { // The authenticated user email doesn't match the current user's email. @@ -283,7 +266,7 @@ user_manager::known_user::GetAccountId(email, gaia_id, AccountType::GOOGLE), using_saml, false /* using_saml_api */, password, - SamlPasswordAttributes::FromJs(*password_attributes), + SamlPasswordAttributes::FromJs(password_attributes), /*sync_trusted_vault_keys=*/absl::nullopt, *extension_provided_client_cert_usage_observer_, pending_user_context_.get(), nullptr)) {
diff --git a/chrome/browser/ui/webui/chromeos/login/base_webui_handler.h b/chrome/browser/ui/webui/chromeos/login/base_webui_handler.h index d1b76af0..b3ee3108 100644 --- a/chrome/browser/ui/webui/chromeos/login/base_webui_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/base_webui_handler.h
@@ -20,7 +20,6 @@ namespace base { class DictionaryValue; -class ListValue; } // namespace base namespace login { @@ -115,10 +114,7 @@ void (T::*method)(Args...)) { base::RepeatingCallback<void(Args...)> callback = base::BindRepeating(method, base::Unretained(static_cast<T*>(this))); - web_ui()->RegisterDeprecatedMessageCallback( - function_name, - base::BindRepeating(&BaseWebUIHandler::OnCallback<Args...>, - base::Unretained(this), function_name, callback)); + web_ui()->RegisterHandlerCallback(function_name, callback); } // Called when the page is ready and handler can do initialization. @@ -146,13 +142,6 @@ private: friend class OobeUI; - template <typename... Args> - void OnCallback(const std::string& function_name, - const base::RepeatingCallback<void(Args...)>& callback, - const base::ListValue* args) { - ::login::CallbackWrapper<Args...>(callback, args); - } - // Keeps whether page is ready. bool page_is_ready_ = false;
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc index e488988..28082e7 100644 --- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
@@ -317,7 +317,7 @@ CallJS("cr.ui.Oobe.updateOobeConfiguration", std::move(configuration)); } -void CoreOobeHandler::HandleLaunchHelpApp(double help_topic_id) { +void CoreOobeHandler::HandleLaunchHelpApp(int help_topic_id) { if (!help_app_.get()) help_app_ = new HelpAppLauncher( LoginDisplayHost::default_host()->GetNativeWindow());
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h index 72a76ae..adfd182 100644 --- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h
@@ -118,7 +118,7 @@ void HandleInitialized(); void HandleUpdateCurrentScreen(const std::string& screen); void HandleSkipToLoginForTesting(); - void HandleLaunchHelpApp(double help_topic_id); + void HandleLaunchHelpApp(int help_topic_id); void HandleToggleResetScreen(); // Handles demo mode setup for tests. Accepts 'online' and 'offline' as // `demo_config`.
diff --git a/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc index ee72ac7..17473d1 100644 --- a/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc
@@ -6,6 +6,7 @@ #include <string> +#include "base/logging.h" #include "chrome/browser/ash/login/oobe_screen.h" #include "chrome/browser/ash/login/screens/enable_debugging_screen.h" #include "chrome/browser/browser_process.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc index 7afc1b7..d1ad162e 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -86,6 +86,7 @@ #include "chromeos/constants/devicetype.h" #include "chromeos/dbus/util/version_loader.h" #include "chromeos/strings/grit/chromeos_strings.h" +#include "components/login/base_screen_handler_utils.h" #include "components/login/localized_values_builder.h" #include "components/policy/proto/chrome_device_policy.pb.h" #include "components/prefs/pref_service.h" @@ -119,19 +120,14 @@ const char kEndpointGen[] = "1.0"; absl::optional<SyncTrustedVaultKeys> GetSyncTrustedVaultKeysForUserContext( - const base::DictionaryValue* js_object, + const base::Value::Dict& js_object, const std::string& gaia_id) { if (!base::FeatureList::IsEnabled( ::syncer::kSyncTrustedVaultPassphraseRecovery)) { return absl::nullopt; } - // |js_object| is not expected to be null, but as extra precaution, guard - // against crashes. - if (!js_object) - return absl::nullopt; - - SyncTrustedVaultKeys parsed_keys = SyncTrustedVaultKeys::FromJs(*js_object); + SyncTrustedVaultKeys parsed_keys = SyncTrustedVaultKeys::FromJs(js_object); if (parsed_keys.gaia_id() != gaia_id) return absl::nullopt; @@ -781,9 +777,9 @@ const std::string& email, const std::string& password, bool using_saml, - const ::login::StringList& services, - const base::DictionaryValue* password_attributes, - const base::DictionaryValue* sync_trusted_vault_keys) { + const base::Value::List& services_list, + const base::Value::Dict& password_attributes, + const base::Value::Dict& sync_trusted_vault_keys) { if (!LoginDisplayHost::default_host()) return; @@ -794,6 +790,7 @@ base::UmaHistogramEnumeration("OOBE.GaiaScreen.SuccessLoginRequests", login_request_variant_); } + const auto services = ::login::ConvertToStringList(services_list); // Execute delayed allowlist check that is based on user type. const user_manager::UserType user_type = @@ -836,7 +833,7 @@ login::GetUsertypeFromServicesString(services), GetAccountId(email, gaia_id, AccountType::GOOGLE), using_saml, using_saml_api_, password, - SamlPasswordAttributes::FromJs(*password_attributes), + SamlPasswordAttributes::FromJs(password_attributes), GetSyncTrustedVaultKeysForUserContext(sync_trusted_vault_keys, gaia_id), *extension_provided_client_cert_usage_observer_, user_context.get(), @@ -1001,13 +998,14 @@ } } -void GaiaScreenHandler::HandleOnFatalError( - int error_code, - const base::DictionaryValue* params) { +void GaiaScreenHandler::HandleOnFatalError(int error_code, + const base::Value::Dict& params) { + const base::Value params_value = base::Value(params.Clone()); LoginDisplayHost::default_host() ->GetWizardController() - ->ShowSignInFatalErrorScreen(SignInFatalErrorScreen::Error(error_code), - params); + ->ShowSignInFatalErrorScreen( + static_cast<SignInFatalErrorScreen::Error>(error_code), + ¶ms_value); } void GaiaScreenHandler::HandleUserRemoved(const std::string& email) {
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h index 37173d1..3afda0fd 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
@@ -213,9 +213,9 @@ const std::string& email, const std::string& password, bool using_saml, - const ::login::StringList& services, - const base::DictionaryValue* password_attributes, - const base::DictionaryValue* sync_trusted_vault_keys); + const base::Value::List& services_list, + const base::Value::Dict& password_attributes, + const base::Value::Dict& sync_trusted_vault_keys); void HandleCompleteLogin(const std::string& gaia_id, const std::string& typed_email, const std::string& password, @@ -250,7 +250,7 @@ // Called to deliver the result of the security token PIN request. Called with // an empty string when the request is canceled. void HandleSecurityTokenPinEntered(const std::string& user_input); - void HandleOnFatalError(int error_code, const base::DictionaryValue* params); + void HandleOnFatalError(int error_code, const base::Value::Dict& params); // Called when the user is removed. void HandleUserRemoved(const std::string& email);
diff --git a/chrome/browser/ui/webui/chromeos/login/pin_setup_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/pin_setup_screen_handler.cc index 4a4151c..d9930b0 100644 --- a/chrome/browser/ui/webui/chromeos/login/pin_setup_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/pin_setup_screen_handler.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/webui/chromeos/login/pin_setup_screen_handler.h" #include "base/i18n/number_formatting.h" +#include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "chrome/browser/ash/login/screens/pin_setup_screen.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/recommend_apps_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/recommend_apps_screen_handler.cc index 671d1c0e..834a1361 100644 --- a/chrome/browser/ui/webui/chromeos/login/recommend_apps_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/recommend_apps_screen_handler.cc
@@ -167,9 +167,7 @@ screen_->OnSkip(); } -void RecommendAppsScreenHandler::HandleInstall( - const base::ListValue* apps_arg) { - base::Value::List apps = apps_arg->GetList().Clone(); +void RecommendAppsScreenHandler::HandleInstall(const base::Value::List& apps) { if (recommended_app_count_ != 0) { int selected_app_count = static_cast<int>(apps.size()); int selected_recommended_percentage = @@ -188,7 +186,7 @@ RecordUmaScreenAction(RecommendAppsScreenAction::APP_SELECTED); pref_service_->Set(arc::prefs::kArcFastAppReinstallPackages, - base::Value(std::move(apps))); + base::Value(apps.Clone())); arc::ArcFastAppReinstallStarter* fast_app_reinstall_starter = arc::ArcSessionManager::Get()->fast_app_resintall_starter();
diff --git a/chrome/browser/ui/webui/chromeos/login/recommend_apps_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/recommend_apps_screen_handler.h index 8ae6729d..a3ae64b 100644 --- a/chrome/browser/ui/webui/chromeos/login/recommend_apps_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/recommend_apps_screen_handler.h
@@ -78,7 +78,7 @@ void HandleSkip(); void HandleRetry(); - void HandleInstall(const base::ListValue* args); + void HandleInstall(const base::Value::List& args); ash::RecommendAppsScreen* screen_ = nullptr;
diff --git a/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc index 862c18b..caba7654 100644 --- a/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc
@@ -197,17 +197,15 @@ void SyncConsentScreenHandler::RegisterMessages() { AddCallback("login.SyncConsentScreen.nonSplitSettingsContinue", &SyncConsentScreenHandler::HandleNonSplitSettingsContinue); - AddCallback("login.SyncConsentScreen.acceptAndContinue", - &SyncConsentScreenHandler::HandleAcceptAndContinue); - AddCallback("login.SyncConsentScreen.declineAndContinue", - &SyncConsentScreenHandler::HandleDeclineAndContinue); } void SyncConsentScreenHandler::HandleNonSplitSettingsContinue( const bool opted_in, const bool review_sync, - const login::StringList& consent_description, + const base::Value::List& consent_description_list, const std::string& consent_confirmation) { + auto consent_description = + login::ConvertToStringList(consent_description_list); std::vector<int> consent_description_ids; int consent_confirmation_id; GetConsentIDs(known_strings_, consent_description, consent_confirmation, @@ -222,18 +220,4 @@ } } -void SyncConsentScreenHandler::HandleAcceptAndContinue( - const login::StringList& consent_description, - const std::string& consent_confirmation) { - NOTREACHED(); - // TODO(https://crbug.com/1278325): Remove this. -} - -void SyncConsentScreenHandler::HandleDeclineAndContinue( - const login::StringList& consent_description, - const std::string& consent_confirmation) { - NOTREACHED(); - // TODO(https://crbug.com/1278325): Remove this. -} - } // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.h index 52f8c30f..d8561122 100644 --- a/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.h
@@ -8,6 +8,7 @@ #include <string> #include <unordered_map> +#include "base/values.h" #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" namespace ash { @@ -79,16 +80,9 @@ void HandleNonSplitSettingsContinue( const bool opted_in, const bool review_sync, - const ::login::StringList& consent_description, + const base::Value::List& consent_description_list, const std::string& consent_confirmation); - // WebUI message handlers for SplitSettingsSync. - // TODO(https://crbug.com/1278325): Remove these. - void HandleAcceptAndContinue(const ::login::StringList& consent_description, - const std::string& consent_confirmation); - void HandleDeclineAndContinue(const ::login::StringList& consent_description, - const std::string& consent_confirmation); - // Adds resource `resource_id` both to `builder` and to `known_string_ids_`. void RememberLocalizedValue(const std::string& name, const int resource_id,
diff --git a/chrome/browser/ui/webui/internals/lens/lens_internals_ui_message_handler.cc b/chrome/browser/ui/webui/internals/lens/lens_internals_ui_message_handler.cc index ee99348..cdeb3277 100644 --- a/chrome/browser/ui/webui/internals/lens/lens_internals_ui_message_handler.cc +++ b/chrome/browser/ui/webui/internals/lens/lens_internals_ui_message_handler.cc
@@ -22,35 +22,35 @@ LensInternalsUIMessageHandler::~LensInternalsUIMessageHandler() = default; void LensInternalsUIMessageHandler::RegisterMessages() { - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "startDebugMode", base::BindRepeating(&LensInternalsUIMessageHandler::HandleStartDebugMode, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "refreshDebugData", base::BindRepeating( &LensInternalsUIMessageHandler::HandleRefreshDebugData, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "stopDebugMode", base::BindRepeating(&LensInternalsUIMessageHandler::HandleStopDebugMode, base::Unretained(this))); } void LensInternalsUIMessageHandler::HandleStartDebugMode( - const base::ListValue* args) { + const base::Value::List& args) { JNIEnv* env = base::android::AttachCurrentThread(); Java_LensDebugBridge_startProactiveDebugMode(env); - const base::Value& callback_id = args->GetListDeprecated()[0]; + const base::Value& callback_id = args[0]; ResolveJavascriptCallback(callback_id, base::Value()); } void LensInternalsUIMessageHandler::HandleRefreshDebugData( - const base::ListValue* args) { + const base::Value::List& args) { // Only needs to be called once. AllowJavascript(); JNIEnv* env = base::android::AttachCurrentThread(); @@ -72,17 +72,17 @@ base::Value(row_as_list_storage)); } - const base::Value& callback_id = args->GetListDeprecated()[0]; + const base::Value& callback_id = args[0]; ResolveJavascriptCallback(callback_id, base::Value(debug_data_as_vector_of_values)); } void LensInternalsUIMessageHandler::HandleStopDebugMode( - const base::ListValue* args) { + const base::Value::List& args) { JNIEnv* env = base::android::AttachCurrentThread(); Java_LensDebugBridge_stopProactiveDebugMode(env); - const base::Value& callback_id = args->GetListDeprecated()[0]; + const base::Value& callback_id = args[0]; ResolveJavascriptCallback(callback_id, base::Value()); }
diff --git a/chrome/browser/ui/webui/internals/lens/lens_internals_ui_message_handler.h b/chrome/browser/ui/webui/internals/lens/lens_internals_ui_message_handler.h index 3dd579a..b60cf3c 100644 --- a/chrome/browser/ui/webui/internals/lens/lens_internals_ui_message_handler.h +++ b/chrome/browser/ui/webui/internals/lens/lens_internals_ui_message_handler.h
@@ -10,10 +10,6 @@ #include "base/scoped_observation.h" #include "content/public/browser/web_ui_message_handler.h" -namespace base { -class ListValue; -} // namespace base - class Profile; class LensInternalsUIMessageHandler : public content::WebUIMessageHandler { @@ -26,9 +22,9 @@ private: // Logger::Observer implementation. - void HandleStartDebugMode(const base::ListValue* args); - void HandleRefreshDebugData(const base::ListValue* args); - void HandleStopDebugMode(const base::ListValue* args); + void HandleStartDebugMode(const base::Value::List& args); + void HandleRefreshDebugData(const base::Value::List& args); + void HandleStopDebugMode(const base::Value::List& args); base::android::ScopedJavaGlobalRef<jobject> java_ref_; };
diff --git a/chrome/browser/ui/webui/invalidations/invalidations_message_handler.cc b/chrome/browser/ui/webui/invalidations/invalidations_message_handler.cc index cb56c3a8..cd6f28ac 100644 --- a/chrome/browser/ui/webui/invalidations/invalidations_message_handler.cc +++ b/chrome/browser/ui/webui/invalidations/invalidations_message_handler.cc
@@ -41,10 +41,10 @@ } void InvalidationsMessageHandler::RegisterMessages() { - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "doneLoading", base::BindRepeating(&InvalidationsMessageHandler::UIReady, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "requestDetailedStatus", base::BindRepeating( &InvalidationsMessageHandler::HandleRequestDetailedStatus, @@ -56,7 +56,7 @@ logger_->UnregisterObserver(this); } -void InvalidationsMessageHandler::UIReady(const base::ListValue* args) { +void InvalidationsMessageHandler::UIReady(const base::Value::List& args) { AllowJavascript(); invalidation::ProfileInvalidationProvider* invalidation_provider = GetInvalidationProvider(Profile::FromWebUI(web_ui())); @@ -70,7 +70,7 @@ } void InvalidationsMessageHandler::HandleRequestDetailedStatus( - const base::ListValue* args) { + const base::Value::List& args) { invalidation::ProfileInvalidationProvider* invalidation_provider = GetInvalidationProvider(Profile::FromWebUI(web_ui())); if (invalidation_provider) { @@ -80,7 +80,7 @@ } } -void InvalidationsMessageHandler::UpdateContent(const base::ListValue* args) { +void InvalidationsMessageHandler::UpdateContent(const base::Value::List& args) { if (logger_) logger_->EmitContent(); }
diff --git a/chrome/browser/ui/webui/invalidations/invalidations_message_handler.h b/chrome/browser/ui/webui/invalidations/invalidations_message_handler.h index 5a3da7f3..60993ddb 100644 --- a/chrome/browser/ui/webui/invalidations/invalidations_message_handler.h +++ b/chrome/browser/ui/webui/invalidations/invalidations_message_handler.h
@@ -49,13 +49,13 @@ void OnJavascriptDisallowed() override; // Triggers the logger to send the current state and objects ids. - void UpdateContent(const base::ListValue* args); + void UpdateContent(const base::Value::List& args); // Called by the javascript whenever the page is ready to receive messages. - void UIReady(const base::ListValue* args); + void UIReady(const base::Value::List& args); // Calls the InvalidationService for any internal details. - void HandleRequestDetailedStatus(const base::ListValue* args); + void HandleRequestDetailedStatus(const base::Value::List& args); private: // The pointer to the internal InvalidatorService InvalidationLogger.
diff --git a/chrome/browser/ui/webui/metrics_handler.cc b/chrome/browser/ui/webui/metrics_handler.cc index 7f997d2..78189d0 100644 --- a/chrome/browser/ui/webui/metrics_handler.cc +++ b/chrome/browser/ui/webui/metrics_handler.cc
@@ -25,42 +25,41 @@ MetricsHandler::~MetricsHandler() {} void MetricsHandler::RegisterMessages() { - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "metricsHandler:recordAction", base::BindRepeating(&MetricsHandler::HandleRecordAction, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "metricsHandler:recordInHistogram", base::BindRepeating(&MetricsHandler::HandleRecordInHistogram, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "metricsHandler:recordBooleanHistogram", base::BindRepeating(&MetricsHandler::HandleRecordBooleanHistogram, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "metricsHandler:recordTime", base::BindRepeating(&MetricsHandler::HandleRecordTime, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "metricsHandler:recordMediumTime", base::BindRepeating(&MetricsHandler::HandleRecordMediumTime, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "metricsHandler:recordSparseHistogram", base::BindRepeating(&MetricsHandler::HandleRecordSparseHistogram, base::Unretained(this))); } -void MetricsHandler::HandleRecordAction(const base::ListValue* args) { +void MetricsHandler::HandleRecordAction(const base::Value::List& args) { std::string string_action = base::UTF16ToUTF8(ExtractStringValue(args)); base::RecordComputedAction(string_action); } -void MetricsHandler::HandleRecordInHistogram(const base::ListValue* args) { - base::Value::ConstListView list = args->GetListDeprecated(); - const std::string& histogram_name = list[0].GetString(); - int int_value = static_cast<int>(list[1].GetDouble()); - int int_boundary_value = static_cast<int>(list[2].GetDouble()); +void MetricsHandler::HandleRecordInHistogram(const base::Value::List& args) { + const std::string& histogram_name = args[0].GetString(); + int int_value = static_cast<int>(args[1].GetDouble()); + int int_boundary_value = static_cast<int>(args[2].GetDouble()); DCHECK_GE(int_value, 0); DCHECK_LE(int_value, int_boundary_value); @@ -80,23 +79,23 @@ counter->Add(int_value); } -void MetricsHandler::HandleRecordBooleanHistogram(const base::ListValue* args) { - const auto& list = args->GetListDeprecated(); - if (list.size() < 2 || !list[0].is_string() || !list[1].is_bool()) { +void MetricsHandler::HandleRecordBooleanHistogram( + const base::Value::List& args) { + if (args.size() < 2 || !args[0].is_string() || !args[1].is_bool()) { NOTREACHED(); return; } - const std::string histogram_name = list[0].GetString(); - const bool value = list[1].GetBool(); + const std::string histogram_name = args[0].GetString(); + const bool value = args[1].GetBool(); base::HistogramBase* counter = base::BooleanHistogram::FactoryGet( histogram_name, base::HistogramBase::kUmaTargetedHistogramFlag); counter->AddBoolean(value); } -void MetricsHandler::HandleRecordTime(const base::ListValue* args) { - const std::string& histogram_name = args->GetListDeprecated()[0].GetString(); - double value = args->GetListDeprecated()[1].GetDouble(); +void MetricsHandler::HandleRecordTime(const base::Value::List& args) { + const std::string& histogram_name = args[0].GetString(); + double value = args[1].GetDouble(); DCHECK_GE(value, 0); @@ -108,18 +107,19 @@ counter->AddTime(time_value); } -void MetricsHandler::HandleRecordMediumTime(const base::ListValue* args) { - const std::string& histogram_name = args->GetListDeprecated()[0].GetString(); - double value = args->GetListDeprecated()[1].GetDouble(); +void MetricsHandler::HandleRecordMediumTime(const base::Value::List& args) { + const std::string& histogram_name = args[0].GetString(); + double value = args[1].GetDouble(); DCHECK_GE(value, 0); base::UmaHistogramMediumTimes(histogram_name, base::Milliseconds(value)); } -void MetricsHandler::HandleRecordSparseHistogram(const base::ListValue* args) { - const std::string& histogram_name = args->GetListDeprecated()[0].GetString(); - int sample = args->GetListDeprecated()[1].GetInt(); +void MetricsHandler::HandleRecordSparseHistogram( + const base::Value::List& args) { + const std::string& histogram_name = args[0].GetString(); + int sample = args[1].GetInt(); base::UmaHistogramSparse(histogram_name, sample); }
diff --git a/chrome/browser/ui/webui/metrics_handler.h b/chrome/browser/ui/webui/metrics_handler.h index 5a21cf002..a0a9c3c 100644 --- a/chrome/browser/ui/webui/metrics_handler.h +++ b/chrome/browser/ui/webui/metrics_handler.h
@@ -17,10 +17,6 @@ // dashboard with the action names you use, as our processor won't catch that // information (treat it as RecordComputedMetrics) -namespace base { -class ListValue; -} - class MetricsHandler : public content::WebUIMessageHandler { public: MetricsHandler(); @@ -35,7 +31,7 @@ // Callback for the "metricsHandler:recordAction" message. This records a // user action. - void HandleRecordAction(const base::ListValue* args); + void HandleRecordAction(const base::Value::List& args); // TODO(dbeam): http://crbug.com/104338 @@ -44,27 +40,27 @@ // and the maximum allowed value, which can be at most 4000. The histogram // will use at most 100 buckets, one for each 1, 10, or 100 different values, // depending on the maximum value. - void HandleRecordInHistogram(const base::ListValue* args); + void HandleRecordInHistogram(const base::Value::List& args); // Callback for the "metricsHandler:recordBooleanHistogram" message. This // records into a boolean histogram. |args| contains the histogram name, and // the value to record. - void HandleRecordBooleanHistogram(const base::ListValue* args); + void HandleRecordBooleanHistogram(const base::Value::List& args); // Records a millisecond time value in a histogram, similar to // UMA_HISTOGRAM_TIMES. Handles times between 1ms and 10sec. |args| // contains the histogram name and a value in milliseconds. - void HandleRecordTime(const base::ListValue* args); + void HandleRecordTime(const base::Value::List& args); // Records a millisecond time value in a histogram, similar to // UmaHistogramMedium. Handles times up to 3 minutes. |args| contains the // histogram name and a value in milliseconds. - void HandleRecordMediumTime(const base::ListValue* args); + void HandleRecordMediumTime(const base::Value::List& args); // Callback for the "metricsHandler:recordSparseHistogram" message. This // records into a sparse histogram. |args| contains the histogram name and // the sample value to record. - void HandleRecordSparseHistogram(const base::ListValue* args); + void HandleRecordSparseHistogram(const base::Value::List& args); }; #endif // CHROME_BROWSER_UI_WEBUI_METRICS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/plural_string_handler.cc b/chrome/browser/ui/webui/plural_string_handler.cc index d5f7c41..e05a723e 100644 --- a/chrome/browser/ui/webui/plural_string_handler.cc +++ b/chrome/browser/ui/webui/plural_string_handler.cc
@@ -17,18 +17,18 @@ PluralStringHandler::~PluralStringHandler() {} void PluralStringHandler::RegisterMessages() { - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "getPluralString", base::BindRepeating(&PluralStringHandler::HandleGetPluralString, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "getPluralStringTupleWithComma", base::BindRepeating( &PluralStringHandler::HandleGetPluralStringTupleWithComma, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "getPluralStringTupleWithPeriods", base::BindRepeating( &PluralStringHandler::HandleGetPluralStringTupleWithPeriods, @@ -39,14 +39,13 @@ name_to_id_[name] = id; } -void PluralStringHandler::HandleGetPluralString(const base::ListValue* args) { +void PluralStringHandler::HandleGetPluralString(const base::Value::List& args) { AllowJavascript(); - const auto& list = args->GetListDeprecated(); - CHECK_EQ(3U, list.size()); + CHECK_EQ(3U, args.size()); - const base::Value& callback_id = list[0]; - std::string message_name = list[1].GetString(); - int count = list[2].GetInt(); + const base::Value& callback_id = args[0]; + std::string message_name = args[1].GetString(); + int count = args[2].GetInt(); auto string = GetPluralizedStringForMessageName(message_name, count); @@ -54,26 +53,25 @@ } void PluralStringHandler::HandleGetPluralStringTupleWithComma( - const base::ListValue* args) { + const base::Value::List& args) { GetPluralStringTuple(args, IDS_CONCAT_TWO_STRINGS_WITH_COMMA); } void PluralStringHandler::HandleGetPluralStringTupleWithPeriods( - const base::ListValue* args) { + const base::Value::List& args) { GetPluralStringTuple(args, IDS_CONCAT_TWO_STRINGS_WITH_PERIODS); } -void PluralStringHandler::GetPluralStringTuple(const base::ListValue* args, +void PluralStringHandler::GetPluralStringTuple(const base::Value::List& args, int string_tuple_id) { AllowJavascript(); - const auto& list = args->GetListDeprecated(); - CHECK_EQ(5U, list.size()); + CHECK_EQ(5U, args.size()); - const base::Value& callback_id = list[0]; - std::string message_name1 = list[1].GetString(); - int count1 = list[2].GetInt(); - std::string message_name2 = list[3].GetString(); - int count2 = list[4].GetInt(); + const base::Value& callback_id = args[0]; + std::string message_name1 = args[1].GetString(); + int count1 = args[2].GetInt(); + std::string message_name2 = args[3].GetString(); + int count2 = args[4].GetInt(); auto string1 = GetPluralizedStringForMessageName(message_name1, count1); auto string2 = GetPluralizedStringForMessageName(message_name2, count2);
diff --git a/chrome/browser/ui/webui/plural_string_handler.h b/chrome/browser/ui/webui/plural_string_handler.h index f587d6e..e8308f5 100644 --- a/chrome/browser/ui/webui/plural_string_handler.h +++ b/chrome/browser/ui/webui/plural_string_handler.h
@@ -26,22 +26,22 @@ void RegisterMessages() override; private: - void HandleGetPluralString(const base::ListValue* args); + void HandleGetPluralString(const base::Value::List& args); // Constructs two pluralized strings from the received arguments for the two // strings, and then concatenates those with comma and whitespace in between. - void HandleGetPluralStringTupleWithComma(const base::ListValue* args); + void HandleGetPluralStringTupleWithComma(const base::Value::List& args); // Constructs two pluralized strings from the received arguments for the two // strings, and then concatenates those with period and whitespace in between, // and a period afterwards. - void HandleGetPluralStringTupleWithPeriods(const base::ListValue* args); + void HandleGetPluralStringTupleWithPeriods(const base::Value::List& args); // Constructs two pluralized strings from the received arguments for the two // strings, and then concatenates those using the concatenation template // specified. This method should only be called from within the // |HandleGetPluralStringTuple*| methods above. - void GetPluralStringTuple(const base::ListValue* args, int string_tuple_id); + void GetPluralStringTuple(const base::Value::List& args, int string_tuple_id); std::u16string GetPluralizedStringForMessageName(std::string message_name, int count);
diff --git a/chrome/browser/ui/webui/policy/policy_ui_handler.cc b/chrome/browser/ui/webui/policy/policy_ui_handler.cc index 63b799ad..a67aba7 100644 --- a/chrome/browser/ui/webui/policy/policy_ui_handler.cc +++ b/chrome/browser/ui/webui/policy/policy_ui_handler.cc
@@ -919,19 +919,19 @@ ->registry(); registry->AddObserver(this); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "exportPoliciesJSON", base::BindRepeating(&PolicyUIHandler::HandleExportPoliciesJson, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "listenPoliciesUpdates", base::BindRepeating(&PolicyUIHandler::HandleListenPoliciesUpdates, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "reloadPolicies", base::BindRepeating(&PolicyUIHandler::HandleReloadPolicies, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "copyPoliciesJSON", base::BindRepeating(&PolicyUIHandler::HandleCopyPoliciesJson, base::Unretained(this))); @@ -1153,7 +1153,7 @@ return status; } -void PolicyUIHandler::HandleExportPoliciesJson(const base::ListValue* args) { +void PolicyUIHandler::HandleExportPoliciesJson(const base::Value::List& args) { #if BUILDFLAG(IS_ANDROID) // TODO(crbug.com/1228691): Unify download logic between all platforms to // use the WebUI download solution (and remove the Android check). @@ -1193,12 +1193,13 @@ #endif } -void PolicyUIHandler::HandleListenPoliciesUpdates(const base::ListValue* args) { +void PolicyUIHandler::HandleListenPoliciesUpdates( + const base::Value::List& args) { AllowJavascript(); OnRefreshPoliciesDone(); } -void PolicyUIHandler::HandleReloadPolicies(const base::ListValue* args) { +void PolicyUIHandler::HandleReloadPolicies(const base::Value::List& args) { #if BUILDFLAG(IS_CHROMEOS_ASH) // Allow user to manually fetch remote commands. Useful for testing or when // the invalidation service is not working properly. @@ -1241,7 +1242,7 @@ &PolicyUIHandler::OnRefreshPoliciesDone, weak_factory_.GetWeakPtr())); } -void PolicyUIHandler::HandleCopyPoliciesJson(const base::ListValue* args) { +void PolicyUIHandler::HandleCopyPoliciesJson(const base::Value::List& args) { std::string policies_json = GetPoliciesAsJson(); ui::ScopedClipboardWriter scw(ui::ClipboardBuffer::kCopyPaste); scw.WriteText(base::UTF8ToUTF16(policies_json));
diff --git a/chrome/browser/ui/webui/policy/policy_ui_handler.h b/chrome/browser/ui/webui/policy/policy_ui_handler.h index 9dde924..53295d0 100644 --- a/chrome/browser/ui/webui/policy/policy_ui_handler.h +++ b/chrome/browser/ui/webui/policy/policy_ui_handler.h
@@ -91,10 +91,10 @@ void AddExtensionPolicyNames(base::Value* names, policy::PolicyDomain policy_domain); - void HandleExportPoliciesJson(const base::ListValue* args); - void HandleListenPoliciesUpdates(const base::ListValue* args); - void HandleReloadPolicies(const base::ListValue* args); - void HandleCopyPoliciesJson(const base::ListValue* args); + void HandleExportPoliciesJson(const base::Value::List& args); + void HandleListenPoliciesUpdates(const base::Value::List& args); + void HandleReloadPolicies(const base::Value::List& args); + void HandleCopyPoliciesJson(const base::Value::List& args); // Send information about the current policy values to the UI. For each policy // whose value has been set, a dictionary containing the value and additional
diff --git a/chrome/browser/ui/webui/settings/chromeos/apps_section.cc b/chrome/browser/ui/webui/settings/chromeos/apps_section.cc index 744e33e4..b78661ce 100644 --- a/chrome/browser/ui/webui/settings/chromeos/apps_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/apps_section.cc
@@ -30,6 +30,7 @@ #include "chrome/grit/os_settings_resources.h" #include "components/app_restore/features.h" #include "components/prefs/pref_service.h" +#include "components/strings/grit/components_strings.h" #include "content/public/browser/web_ui_data_source.h" #include "ui/accessibility/accessibility_features.h" #include "ui/base/l10n/l10n_util.h" @@ -197,6 +198,8 @@ IDS_APP_MANAGEMENT_POLICY_APP_POLICY_STRING}, {"appManagementCameraPermissionLabel", IDS_APP_MANAGEMENT_CAMERA}, {"appManagementContactsPermissionLabel", IDS_APP_MANAGEMENT_CONTACTS}, + {"appManagementFileHandlingHeader", + IDS_APP_MANAGEMENT_FILE_HANDLING_HEADER}, {"appManagementIntentOverlapChangeButton", IDS_APP_MANAGEMENT_INTENT_OVERLAP_CHANGE_BUTTON}, {"appManagementIntentOverlapDialogText1App", @@ -248,6 +251,11 @@ {"appManagementSearchPrompt", IDS_APP_MANAGEMENT_SEARCH_PROMPT}, {"appManagementStoragePermissionLabel", IDS_APP_MANAGEMENT_STORAGE}, {"appManagementUninstallLabel", IDS_APP_MANAGEMENT_UNINSTALL_APP}, + {"close", IDS_CLOSE}, + {"fileHandlingOverflowDialogTitle", + IDS_APP_MANAGEMENT_FILE_HANDLING_OVERFLOW_DIALOG_TITLE}, + {"fileHandlingSetDefaults", + IDS_APP_MANAGEMENT_FILE_HANDLING_SET_DEFAULTS_LINK}, }; html_source->AddLocalizedStrings(kLocalizedStrings); }
diff --git a/chrome/browser/ui/webui/signin_internals_ui.cc b/chrome/browser/ui/webui/signin_internals_ui.cc index 4ed3e56..a06dec4 100644 --- a/chrome/browser/ui/webui/signin_internals_ui.cc +++ b/chrome/browser/ui/webui/signin_internals_ui.cc
@@ -81,14 +81,15 @@ } void SignInInternalsHandler::RegisterMessages() { - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "getSigninInfo", base::BindRepeating(&SignInInternalsHandler::HandleGetSignInInfo, base::Unretained(this))); } -void SignInInternalsHandler::HandleGetSignInInfo(const base::ListValue* args) { - std::string callback_id = args->GetListDeprecated()[0].GetString(); +void SignInInternalsHandler::HandleGetSignInInfo( + const base::Value::List& args) { + std::string callback_id = args[0].GetString(); AllowJavascript(); Profile* profile = Profile::FromWebUI(web_ui());
diff --git a/chrome/browser/ui/webui/signin_internals_ui.h b/chrome/browser/ui/webui/signin_internals_ui.h index 16e4193..3a2320d9 100644 --- a/chrome/browser/ui/webui/signin_internals_ui.h +++ b/chrome/browser/ui/webui/signin_internals_ui.h
@@ -34,7 +34,7 @@ void OnJavascriptAllowed() override; void OnJavascriptDisallowed() override; - void HandleGetSignInInfo(const base::ListValue* args); + void HandleGetSignInInfo(const base::Value::List& args); // AboutSigninInternals::Observer::OnSigninStateChanged implementation. void OnSigninStateChanged(const base::Value* info) override;
diff --git a/chrome/browser/ui/webui/theme_handler.cc b/chrome/browser/ui/webui/theme_handler.cc index 3840305b..a98b4db 100644 --- a/chrome/browser/ui/webui/theme_handler.cc +++ b/chrome/browser/ui/webui/theme_handler.cc
@@ -30,7 +30,7 @@ // constructor since they need the web_ui value to be set, which is done // post-construction, but before registering messages. InitializeCSSCaches(); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "observeThemeChanges", base::BindRepeating(&ThemeHandler::HandleObserveThemeChanges, base::Unretained(this))); @@ -69,7 +69,8 @@ SendThemeChanged(); } -void ThemeHandler::HandleObserveThemeChanges(const base::ListValue* /*args*/) { +void ThemeHandler::HandleObserveThemeChanges( + const base::Value::List& /*args*/) { AllowJavascript(); }
diff --git a/chrome/browser/ui/webui/theme_handler.h b/chrome/browser/ui/webui/theme_handler.h index 2a63ba2..0d1c94e 100644 --- a/chrome/browser/ui/webui/theme_handler.h +++ b/chrome/browser/ui/webui/theme_handler.h
@@ -45,7 +45,7 @@ void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override; // Handler for "observeThemeChanges" chrome.send() message. No arguments. - void HandleObserveThemeChanges(const base::ListValue* args); + void HandleObserveThemeChanges(const base::Value::List& args); // Notify the page (if allowed) that the theme has changed. void SendThemeChanged();
diff --git a/chrome/browser/ui/webui/user_actions/user_actions_ui_handler.cc b/chrome/browser/ui/webui/user_actions/user_actions_ui_handler.cc index 669577a..e7c7224 100644 --- a/chrome/browser/ui/webui/user_actions/user_actions_ui_handler.cc +++ b/chrome/browser/ui/webui/user_actions/user_actions_ui_handler.cc
@@ -19,12 +19,12 @@ } void UserActionsUIHandler::RegisterMessages() { - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "pageLoaded", base::BindRepeating(&UserActionsUIHandler::HandlePageLoaded, base::Unretained(this))); } -void UserActionsUIHandler::HandlePageLoaded(const base::ListValue* args) { +void UserActionsUIHandler::HandlePageLoaded(const base::Value::List& args) { AllowJavascript(); }
diff --git a/chrome/browser/ui/webui/user_actions/user_actions_ui_handler.h b/chrome/browser/ui/webui/user_actions/user_actions_ui_handler.h index 0b1d57c..22759ba 100644 --- a/chrome/browser/ui/webui/user_actions/user_actions_ui_handler.h +++ b/chrome/browser/ui/webui/user_actions/user_actions_ui_handler.h
@@ -9,7 +9,6 @@ #include "content/public/browser/web_ui_message_handler.h" namespace base { -class ListValue; class TimeTicks; } // namespace base @@ -31,7 +30,7 @@ void OnJavascriptDisallowed() override; private: - void HandlePageLoaded(const base::ListValue* args); + void HandlePageLoaded(const base::Value::List& args); void OnUserAction(const std::string& action, base::TimeTicks action_time); base::ActionCallback action_callback_;
diff --git a/chrome/browser/ui/webui/version/version_handler.cc b/chrome/browser/ui/webui/version/version_handler.cc index fdf3efe26..ef7fe92 100644 --- a/chrome/browser/ui/webui/version/version_handler.cc +++ b/chrome/browser/ui/webui/version/version_handler.cc
@@ -62,21 +62,21 @@ } void VersionHandler::RegisterMessages() { - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( version_ui::kRequestVersionInfo, base::BindRepeating(&VersionHandler::HandleRequestVersionInfo, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( version_ui::kRequestVariationInfo, base::BindRepeating(&VersionHandler::HandleRequestVariationInfo, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( version_ui::kRequestPathInfo, base::BindRepeating(&VersionHandler::HandleRequestPathInfo, base::Unretained(this))); } -void VersionHandler::HandleRequestVersionInfo(const base::ListValue* args) { +void VersionHandler::HandleRequestVersionInfo(const base::Value::List& args) { // This method is overridden by platform-specific handlers which may still // use |CallJavascriptFunction|. Main version info is returned by promise // using handlers below. @@ -86,13 +86,12 @@ AllowJavascript(); } -void VersionHandler::HandleRequestVariationInfo(const base::ListValue* args) { +void VersionHandler::HandleRequestVariationInfo(const base::Value::List& args) { AllowJavascript(); - const auto& list = args->GetListDeprecated(); - CHECK_EQ(2U, list.size()); - const std::string& callback_id = list[0].GetString(); - const bool include_variations_cmd = list[1].GetBool(); + CHECK_EQ(2U, args.size()); + const std::string& callback_id = args[0].GetString(); + const bool include_variations_cmd = args[1].GetBool(); base::Value response(base::Value::Type::DICTIONARY); response.SetKey(version_ui::kKeyVariationsList, @@ -104,11 +103,11 @@ ResolveJavascriptCallback(base::Value(callback_id), response); } -void VersionHandler::HandleRequestPathInfo(const base::ListValue* args) { +void VersionHandler::HandleRequestPathInfo(const base::Value::List& args) { AllowJavascript(); - CHECK_EQ(1U, args->GetListDeprecated().size()); - const std::string& callback_id = args->GetListDeprecated()[0].GetString(); + CHECK_EQ(1U, args.size()); + const std::string& callback_id = args[0].GetString(); // Grab the executable path on the FILE thread. It is returned in // OnGotFilePaths.
diff --git a/chrome/browser/ui/webui/version/version_handler.h b/chrome/browser/ui/webui/version/version_handler.h index 7b528b8..415a0699 100644 --- a/chrome/browser/ui/webui/version/version_handler.h +++ b/chrome/browser/ui/webui/version/version_handler.h
@@ -29,15 +29,15 @@ // This is still supported for platform-specific asynchronous calls (see // derived classes) but the main version information is now retrieved with // below messages using |cr.sendWithPromise|. - virtual void HandleRequestVersionInfo(const base::ListValue* args); + virtual void HandleRequestVersionInfo(const base::Value::List& args); // Callback for the "requestVariationInfo" message. This resolves immediately // with variations list as well as command variations if requested. - virtual void HandleRequestVariationInfo(const base::ListValue* args); + virtual void HandleRequestVariationInfo(const base::Value::List& args); // Callback for the "requestPathInfo" message. This resolves asynchronously // with |OnGotFilePaths|. - virtual void HandleRequestPathInfo(const base::ListValue* args); + virtual void HandleRequestPathInfo(const base::Value::List& args); private: // Callback which handles returning the executable and profile paths to the
diff --git a/chrome/browser/ui/webui/version/version_handler_chromeos.cc b/chrome/browser/ui/webui/version/version_handler_chromeos.cc index ff1c4bd..08b5ff57 100644 --- a/chrome/browser/ui/webui/version/version_handler_chromeos.cc +++ b/chrome/browser/ui/webui/version/version_handler_chromeos.cc
@@ -36,7 +36,7 @@ } void VersionHandlerChromeOS::HandleRequestVersionInfo( - const base::ListValue* args) { + const base::Value::List& args) { VersionHandler::HandleRequestVersionInfo(args); #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -69,14 +69,14 @@ void VersionHandlerChromeOS::RegisterMessages() { VersionHandler::RegisterMessages(); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( kCrosUrlVersionRedirect, base::BindRepeating(&VersionHandlerChromeOS::HandleCrosUrlVersionRedirect, base::Unretained(this))); } void VersionHandlerChromeOS::HandleCrosUrlVersionRedirect( - const base::ListValue* args) { + const base::Value::List& args) { #if BUILDFLAG(IS_CHROMEOS_LACROS) lacros_url_handling::NavigateInAsh(GURL(chrome::kOsUIVersionURL)); #else
diff --git a/chrome/browser/ui/webui/version/version_handler_chromeos.h b/chrome/browser/ui/webui/version/version_handler_chromeos.h index 55dfc38..80e6e7b 100644 --- a/chrome/browser/ui/webui/version/version_handler_chromeos.h +++ b/chrome/browser/ui/webui/version/version_handler_chromeos.h
@@ -24,7 +24,7 @@ // VersionHandler overrides: void OnJavascriptDisallowed() override; - void HandleRequestVersionInfo(const base::ListValue* args) override; + void HandleRequestVersionInfo(const base::Value::List& args) override; void RegisterMessages() override; // Callbacks from chromeos::VersionLoader. @@ -33,7 +33,7 @@ void OnARCVersion(const std::string& version); // Callback for the "crosUrlVersionRedirect" message. - void HandleCrosUrlVersionRedirect(const base::ListValue* args); + void HandleCrosUrlVersionRedirect(const base::Value::List& args); private: base::WeakPtrFactory<VersionHandlerChromeOS> weak_factory_{this};
diff --git a/chrome/browser/ui/webui/version/version_handler_win.cc b/chrome/browser/ui/webui/version/version_handler_win.cc index 5af22228..1cb06bcf 100644 --- a/chrome/browser/ui/webui/version/version_handler_win.cc +++ b/chrome/browser/ui/webui/version/version_handler_win.cc
@@ -16,7 +16,7 @@ VersionHandlerWindows::~VersionHandlerWindows() {} void VersionHandlerWindows::HandleRequestVersionInfo( - const base::ListValue* args) { + const base::Value::List& args) { VersionHandler::HandleRequestVersionInfo(args); // Start the asynchronous load of the versions.
diff --git a/chrome/browser/ui/webui/version/version_handler_win.h b/chrome/browser/ui/webui/version/version_handler_win.h index ea31701..e6ed457 100644 --- a/chrome/browser/ui/webui/version/version_handler_win.h +++ b/chrome/browser/ui/webui/version/version_handler_win.h
@@ -21,7 +21,7 @@ ~VersionHandlerWindows() override; // VersionHandler overrides: - void HandleRequestVersionInfo(const base::ListValue* args) override; + void HandleRequestVersionInfo(const base::Value::List& args) override; // Callbacks from windows::VersionLoader. void OnVersion(const std::string& version);
diff --git a/chrome/browser/ui/webui/webapks/webapks_handler.cc b/chrome/browser/ui/webui/webapks/webapks_handler.cc index 90ffbee..336d6e3a1 100644 --- a/chrome/browser/ui/webui/webapks/webapks_handler.cc +++ b/chrome/browser/ui/webui/webapks/webapks_handler.cc
@@ -21,24 +21,24 @@ WebApksHandler::~WebApksHandler() {} void WebApksHandler::RegisterMessages() { - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "requestWebApksInfo", base::BindRepeating(&WebApksHandler::HandleRequestWebApksInfo, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "requestWebApkUpdate", base::BindRepeating(&WebApksHandler::HandleRequestWebApkUpdate, base::Unretained(this))); } -void WebApksHandler::HandleRequestWebApksInfo(const base::ListValue* args) { +void WebApksHandler::HandleRequestWebApksInfo(const base::Value::List& args) { AllowJavascript(); delegate_.RetrieveWebApks(); } -void WebApksHandler::HandleRequestWebApkUpdate(const base::ListValue* args) { +void WebApksHandler::HandleRequestWebApkUpdate(const base::Value::List& args) { AllowJavascript(); - for (const auto& val : args->GetListDeprecated()) { + for (const auto& val : args) { if (val.is_string()) ShortcutHelper::SetForceWebApkUpdate(val.GetString()); }
diff --git a/chrome/browser/ui/webui/webapks/webapks_handler.h b/chrome/browser/ui/webui/webapks/webapks_handler.h index a9c2885..7cf9c68 100644 --- a/chrome/browser/ui/webui/webapks/webapks_handler.h +++ b/chrome/browser/ui/webui/webapks/webapks_handler.h
@@ -10,10 +10,6 @@ #include "chrome/browser/android/webapk/webapk_info.h" #include "content/public/browser/web_ui_message_handler.h" -namespace base { -class ListValue; -} // namespace base - // Handles JavaScript messages from the chrome://webapks page. class WebApksHandler : public content::WebUIMessageHandler { public: @@ -30,12 +26,12 @@ // Handler for the "requestWebApksInfo" message. This requests // information for the installed WebAPKs and returns it to JS using // OnWebApkInfoReceived(). - void HandleRequestWebApksInfo(const base::ListValue* args); + void HandleRequestWebApksInfo(const base::Value::List& args); // Handler for the "requestWebApkUpdate" message. This sets the // update flag for a set of WebAPKs. |args| should contain the // webapp IDs of the WebAPKs to update. - void HandleRequestWebApkUpdate(const base::ListValue* args); + void HandleRequestWebApkUpdate(const base::Value::List& args); private: // Called once for each installed WebAPK when the WebAPK Info is retrieved.
diff --git a/chrome/browser/ui/webui/whats_new/whats_new_handler.cc b/chrome/browser/ui/webui/whats_new/whats_new_handler.cc index 5a42cbd..ac1f3bd 100644 --- a/chrome/browser/ui/webui/whats_new/whats_new_handler.cc +++ b/chrome/browser/ui/webui/whats_new/whats_new_handler.cc
@@ -26,15 +26,14 @@ WhatsNewHandler::~WhatsNewHandler() = default; void WhatsNewHandler::RegisterMessages() { - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "initialize", base::BindRepeating(&WhatsNewHandler::HandleInitialize, base::Unretained(this))); } -void WhatsNewHandler::HandleInitialize(const base::ListValue* args) { - const auto& list = args->GetListDeprecated(); - CHECK_EQ(1U, list.size()); - const std::string& callback_id = list[0].GetString(); +void WhatsNewHandler::HandleInitialize(const base::Value::List& args) { + CHECK_EQ(1U, args.size()); + const std::string& callback_id = args[0].GetString(); AllowJavascript(); ResolveJavascriptCallback(
diff --git a/chrome/browser/ui/webui/whats_new/whats_new_handler.h b/chrome/browser/ui/webui/whats_new/whats_new_handler.h index 6efa0b1..c1cbd0e 100644 --- a/chrome/browser/ui/webui/whats_new/whats_new_handler.h +++ b/chrome/browser/ui/webui/whats_new/whats_new_handler.h
@@ -7,10 +7,6 @@ #include "content/public/browser/web_ui_message_handler.h" -namespace base { -class ListValue; -} - // Page handler for chrome://whats-new. class WhatsNewHandler : public content::WebUIMessageHandler { public: @@ -20,7 +16,7 @@ WhatsNewHandler& operator=(const WhatsNewHandler&) = delete; private: - void HandleInitialize(const base::ListValue* args); + void HandleInitialize(const base::Value::List& args); // content::WebUIMessageHandler: void RegisterMessages() override;
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn index dfb54420..a4019745 100644 --- a/chrome/browser/web_applications/BUILD.gn +++ b/chrome/browser/web_applications/BUILD.gn
@@ -74,6 +74,8 @@ "policy/web_app_policy_constants.h", "policy/web_app_policy_manager.cc", "policy/web_app_policy_manager.h", + "policy/web_app_settings_policy_handler.cc", + "policy/web_app_settings_policy_handler.h", "preinstalled_app_install_features.cc", "preinstalled_app_install_features.h", "preinstalled_web_app_manager.cc", @@ -246,6 +248,7 @@ "//chrome/common:non_code_constants", "//components/content_settings/core/browser", "//components/custom_handlers", + "//components/policy/core/browser:browser", "//components/resources:components_resources_grit", # TODO(crbug.com/1225132): Clean up this legacy crx dependency. @@ -530,6 +533,7 @@ if (is_win || is_mac || (is_linux && !is_chromeos_lacros)) { sources += [ "os_integration/url_handler_manager_impl_unittest.cc", + "policy/web_app_settings_policy_handler_unittest.cc", "url_handler_prefs_unittest.cc", ] }
diff --git a/chrome/browser/web_applications/commands/run_on_os_login_command_unittest.cc b/chrome/browser/web_applications/commands/run_on_os_login_command_unittest.cc index 70e81f0..e9bdaea 100644 --- a/chrome/browser/web_applications/commands/run_on_os_login_command_unittest.cc +++ b/chrome/browser/web_applications/commands/run_on_os_login_command_unittest.cc
@@ -274,19 +274,22 @@ } TEST_F(RunOnOsLoginCommandUnitTest, SyncRunOnOsLoginOsIntegrationState) { - const char kWebAppSettingWithDefaultConfiguration[] = R"({ - "https://windowed.example/": { + const char kWebAppSettingWithDefaultConfiguration[] = R"([ + { + "manifest_id": "https://windowed.example/", "run_on_os_login": "run_windowed" }, - "https://allowed.example/": { + { + "manifest_id": "https://allowed.example/", "run_on_os_login": "allowed" }, - "*": { + { + "manifest_id": "*", "run_on_os_login": "blocked" } - })"; + ])"; - test::SetWebAppSettingsDictPref(profile(), + test::SetWebAppSettingsListPref(profile(), kWebAppSettingWithDefaultConfiguration); provider()->policy_manager().RefreshPolicySettingsForTesting(); @@ -380,22 +383,26 @@ // value. A null value can be returned if a web app was installed prior to the // completion of the work associated with https://crbug.com/1280773. This test // validates that both states are handled properly. - const char kWebAppSettingWithDefaultConfiguration[] = R"({ - "https://windowed.example/": { + const char kWebAppSettingWithDefaultConfiguration[] = R"([ + { + "manifest_id": "https://windowed.example/", "run_on_os_login": "run_windowed" }, - "https://allowed.example/": { + { + "manifest_id": "https://allowed.example/", "run_on_os_login": "allowed" }, - "https://allowed2.example/": { + { + "manifest_id": "https://allowed2.example/", "run_on_os_login": "allowed" }, - "*": { + { + "manifest_id": "*", "run_on_os_login": "blocked" } - })"; + ])"; - test::SetWebAppSettingsDictPref(profile(), + test::SetWebAppSettingsListPref(profile(), kWebAppSettingWithDefaultConfiguration); provider()->policy_manager().RefreshPolicySettingsForTesting(); @@ -507,19 +514,22 @@ TEST_F(RunOnOsLoginCommandUnitTest, SyncRunOnOsLoginOsIntegrationStateAppNotLocallyInstalled) { - const char kWebAppSettingWithDefaultConfiguration[] = R"({ - "https://windowed.example/": { + const char kWebAppSettingWithDefaultConfiguration[] = R"([ + { + "manifest_id": "https://windowed.example/", "run_on_os_login": "run_windowed" }, - "https://allowed.example/": { + { + "manifest_id": "https://allowed.example/", "run_on_os_login": "allowed" }, - "*": { + { + "manifest_id": "*", "run_on_os_login": "blocked" } - })"; + ])"; - test::SetWebAppSettingsDictPref(profile(), + test::SetWebAppSettingsListPref(profile(), kWebAppSettingWithDefaultConfiguration); provider()->policy_manager().RefreshPolicySettingsForTesting();
diff --git a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc index df241488..efcc7aec 100644 --- a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc +++ b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
@@ -54,23 +54,28 @@ namespace { -const char kWebAppSettingWithDefaultConfiguration[] = R"({ - "https://windowed.example/": { +const char kWebAppSettingWithDefaultConfiguration[] = R"([ + { + "manifest_id": "https://windowed.example/", "run_on_os_login": "run_windowed" }, - "https://tabbed.example/": { + { + "manifest_id": "https://tabbed.example/", "run_on_os_login": "allowed" }, - "https://no-container.example/" : { + { + "manifest_id": "https://no-container.example/", "run_on_os_login": "unsupported_value" }, - "bad.uri" : { + { + "manifest_id": "bad.uri", "run_on_os_login": "allowed" }, - "*": { + { + "manifest_id": "*", "run_on_os_login": "blocked" } -})"; +])"; const char kDefaultFallbackAppName[] = "fallback app name"; @@ -437,11 +442,11 @@ return *fake_registry_controller_; } - void SetWebAppSettingsDictPref(const base::StringPiece pref) { + void SetWebAppSettingsListPref(const base::StringPiece pref) { base::JSONReader::ValueWithError result = base::JSONReader::ReadAndReturnValueWithError( pref, base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS); - ASSERT_TRUE(result.value && result.value->is_dict()) + ASSERT_TRUE(result.value && result.value->is_list()) << result.error_message; profile()->GetPrefs()->Set(prefs::kWebAppSettings, std::move(*result.value)); @@ -519,7 +524,7 @@ if (ShouldSkipPWASpecificTest()) return; profile()->GetPrefs()->Set(prefs::kWebAppSettings, - base::Value(base::Value::Type::DICTIONARY)); + base::Value(base::Value::Type::LIST)); policy_manager().Start(); AwaitPolicyManagerRefreshPolicySettings(); @@ -529,13 +534,14 @@ TEST_P(WebAppPolicyManagerTest, WebAppSettingsInvalidDefaultConfiguration) { if (ShouldSkipPWASpecificTest()) return; - const char kWebAppSettingInvalidDefaultConfiguration[] = R"({ - "*" : { + const char kWebAppSettingInvalidDefaultConfiguration[] = R"([ + { + "manifest_id": "*", "run_on_os_login": "unsupported_value" } - })"; + ])"; - SetWebAppSettingsDictPref(kWebAppSettingInvalidDefaultConfiguration); + SetWebAppSettingsListPref(kWebAppSettingInvalidDefaultConfiguration); policy_manager().Start(); AwaitPolicyManagerRefreshPolicySettings(); ValidateEmptyWebAppSettingsPolicy(); @@ -545,16 +551,18 @@ WebAppSettingsInvalidDefaultConfigurationWithValidAppPolicy) { if (ShouldSkipPWASpecificTest()) return; - const char kWebAppSettingInvalidDefaultConfiguration[] = R"({ - "https://windowed.example/": { + const char kWebAppSettingInvalidDefaultConfiguration[] = R"([ + { + "manifest_id": "https://windowed.example/", "run_on_os_login": "run_windowed" }, - "*" : { + { + "manifest_id": "*", "run_on_os_login": "unsupported_value" } - })"; + ])"; - SetWebAppSettingsDictPref(kWebAppSettingInvalidDefaultConfiguration); + SetWebAppSettingsListPref(kWebAppSettingInvalidDefaultConfiguration); policy_manager().Start(); AwaitPolicyManagerRefreshPolicySettings(); EXPECT_EQ(GetUrlRunOnOsLoginPolicy(kWindowedUrl), @@ -569,22 +577,26 @@ TEST_P(WebAppPolicyManagerTest, WebAppSettingsNoDefaultConfiguration) { if (ShouldSkipPWASpecificTest()) return; - const char kWebAppSettingNoDefaultConfiguration[] = R"({ - "https://windowed.example/": { + const char kWebAppSettingNoDefaultConfiguration[] = R"([ + { + "manifest_id": "https://windowed.example/", "run_on_os_login": "run_windowed" }, - "https://tabbed.example/": { + { + "manifest_id": "https://tabbed.example/", "run_on_os_login": "blocked" }, - "https://no-container.example/" : { + { + "manifest_id": "https://no-container.example/", "run_on_os_login": "unsupported_value" }, - "bad.uri" : { + { + "manifest_id": "bad.uri", "run_on_os_login": "allowed" } - })"; + ])"; - SetWebAppSettingsDictPref(kWebAppSettingNoDefaultConfiguration); + SetWebAppSettingsListPref(kWebAppSettingNoDefaultConfiguration); policy_manager().Start(); AwaitPolicyManagerRefreshPolicySettings(); @@ -600,7 +612,7 @@ TEST_P(WebAppPolicyManagerTest, WebAppSettingsWithDefaultConfiguration) { if (ShouldSkipPWASpecificTest()) return; - SetWebAppSettingsDictPref(kWebAppSettingWithDefaultConfiguration); + SetWebAppSettingsListPref(kWebAppSettingWithDefaultConfiguration); policy_manager().Start(); AwaitPolicyManagerRefreshPolicySettings(); @@ -1126,15 +1138,16 @@ TEST_P(WebAppPolicyManagerTest, WebAppSettingsDynamicRefresh) { if (ShouldSkipPWASpecificTest()) return; - const char kWebAppSettingInitialConfiguration[] = R"({ - "https://windowed.example/": { + const char kWebAppSettingInitialConfiguration[] = R"([ + { + "manifest_id": "https://windowed.example/", "run_on_os_login": "blocked" } - })"; + ])"; MockAppRegistrarObserver mock_observer; app_registrar().AddObserver(&mock_observer); - SetWebAppSettingsDictPref(kWebAppSettingInitialConfiguration); + SetWebAppSettingsListPref(kWebAppSettingInitialConfiguration); policy_manager().Start(); AwaitPolicyManagerRefreshPolicySettings(); EXPECT_EQ(GetUrlRunOnOsLoginPolicy(kWindowedUrl), @@ -1144,7 +1157,7 @@ RunOnOsLoginPolicy::kAllowed); EXPECT_EQ(1, mock_observer.GetOnWebAppSettingsPolicyChangedCalledCount()); - SetWebAppSettingsDictPref(kWebAppSettingWithDefaultConfiguration); + SetWebAppSettingsListPref(kWebAppSettingWithDefaultConfiguration); EXPECT_EQ(GetUrlRunOnOsLoginPolicy(kWindowedUrl), RunOnOsLoginPolicy::kRunWindowed); EXPECT_EQ(GetUrlRunOnOsLoginPolicy(kTabbedUrl), RunOnOsLoginPolicy::kAllowed); @@ -1187,7 +1200,7 @@ // Now apply WebSettings policy MockAppRegistrarObserver mock_observer; app_registrar().AddObserver(&mock_observer); - SetWebAppSettingsDictPref(kWebAppSettingWithDefaultConfiguration); + SetWebAppSettingsListPref(kWebAppSettingWithDefaultConfiguration); EXPECT_EQ(1, mock_observer.GetOnWebAppSettingsPolicyChangedCalledCount()); EXPECT_EQ(GetUrlRunOnOsLoginPolicy(kWindowedUrl), RunOnOsLoginPolicy::kRunWindowed); @@ -1205,7 +1218,7 @@ // Apply WebAppSettings Policy MockAppRegistrarObserver mock_observer; app_registrar().AddObserver(&mock_observer); - SetWebAppSettingsDictPref(kWebAppSettingWithDefaultConfiguration); + SetWebAppSettingsListPref(kWebAppSettingWithDefaultConfiguration); policy_manager().Start(); AwaitPolicyManagerAppsSynchronized(); EXPECT_EQ(1, mock_observer.GetOnWebAppSettingsPolicyChangedCalledCount());
diff --git a/chrome/browser/web_applications/policy/web_app_policy_constants.cc b/chrome/browser/web_applications/policy/web_app_policy_constants.cc index 99f023b..0cf2bbfd 100644 --- a/chrome/browser/web_applications/policy/web_app_policy_constants.cc +++ b/chrome/browser/web_applications/policy/web_app_policy_constants.cc
@@ -19,6 +19,7 @@ const char kWildcard[] = "*"; +const char kManifestId[] = "manifest_id"; const char kRunOnOsLogin[] = "run_on_os_login"; const char kAllowed[] = "allowed"; const char kBlocked[] = "blocked";
diff --git a/chrome/browser/web_applications/policy/web_app_policy_constants.h b/chrome/browser/web_applications/policy/web_app_policy_constants.h index 6ea189c..898ef6a 100644 --- a/chrome/browser/web_applications/policy/web_app_policy_constants.h +++ b/chrome/browser/web_applications/policy/web_app_policy_constants.h
@@ -21,6 +21,7 @@ extern const char kWildcard[]; +extern const char kManifestId[]; extern const char kRunOnOsLogin[]; extern const char kAllowed[]; extern const char kBlocked[];
diff --git a/chrome/browser/web_applications/policy/web_app_policy_manager.cc b/chrome/browser/web_applications/policy/web_app_policy_manager.cc index 2c9797f..48046e8c 100644 --- a/chrome/browser/web_applications/policy/web_app_policy_manager.cc +++ b/chrome/browser/web_applications/policy/web_app_policy_manager.cc
@@ -140,7 +140,7 @@ void WebAppPolicyManager::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { registry->RegisterListPref(prefs::kWebAppInstallForceList); - registry->RegisterDictionaryPref(prefs::kWebAppSettings); + registry->RegisterListPref(prefs::kWebAppSettings); } void WebAppPolicyManager::InitChangeRegistrarAndRefreshPolicy( @@ -261,43 +261,49 @@ void WebAppPolicyManager::RefreshPolicySettings() { // No need to validate the types or values of the policy members because we - // are using a SimpleSchemaValidatingPolicyHandler which should validate them - // for us. - const base::Value* web_app_dict = - pref_service_->GetDictionary(prefs::kWebAppSettings); + // are using a WebAppSettingsPolicyHandler which should validate them for us. + const base::Value* web_app_settings = + pref_service_->GetList(prefs::kWebAppSettings); settings_by_url_.clear(); default_settings_ = std::make_unique<WebAppPolicyManager::WebAppSetting>(); - if (!web_app_dict) + if (!web_app_settings) return; + const auto& web_apps_list = web_app_settings->GetList(); + // Read default policy, if provided. - const base::Value* default_settings_dict = - web_app_dict->FindDictKey(kWildcard); - if (default_settings_dict) { - if (!default_settings_->Parse(*default_settings_dict, true)) { + const auto it = std::find_if( + web_apps_list.begin(), web_apps_list.end(), [](const base::Value& entry) { + return entry.FindKey(kManifestId)->GetString() == kWildcard; + }); + + if (it != web_apps_list.end() && it->is_dict()) { + if (!default_settings_->Parse(*it, true)) { SYSLOG(WARNING) << "Malformed default web app management setting."; default_settings_->ResetSettings(); } } // Read policy for individual web apps - for (const auto iter : web_app_dict->DictItems()) { - if (iter.first == kWildcard) + for (const auto& iter : web_apps_list) { + const std::string* web_app_id_str = iter.FindStringKey(kManifestId); + + if (*web_app_id_str == kWildcard) continue; - if (!iter.second.is_dict()) + if (!iter.is_dict()) continue; - GURL url = GURL(iter.first); + GURL url = GURL(*web_app_id_str); if (!url.is_valid()) { - LOG(WARNING) << "Invalid URL: " << iter.first; + LOG(WARNING) << "Invalid URL: " << *web_app_id_str; continue; } WebAppPolicyManager::WebAppSetting by_url(*default_settings_); - if (by_url.Parse(iter.second, false)) { + if (by_url.Parse(iter, false)) { settings_by_url_[url.spec()] = by_url; } else { LOG(WARNING) << "Malformed web app settings for " << url;
diff --git a/chrome/browser/web_applications/policy/web_app_settings_policy_handler.cc b/chrome/browser/web_applications/policy/web_app_settings_policy_handler.cc new file mode 100644 index 0000000..ac149b3 --- /dev/null +++ b/chrome/browser/web_applications/policy/web_app_settings_policy_handler.cc
@@ -0,0 +1,59 @@ +// Copyright 2022 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/web_applications/policy/web_app_settings_policy_handler.h" + +#include "chrome/browser/web_applications/policy/web_app_policy_constants.h" +#include "chrome/common/pref_names.h" +#include "components/policy/core/browser/policy_error_map.h" +#include "components/policy/core/common/policy_map.h" +#include "components/policy/policy_constants.h" + +namespace web_app { + +WebAppSettingsPolicyHandler::WebAppSettingsPolicyHandler(policy::Schema schema) + : policy::SimpleSchemaValidatingPolicyHandler( + policy::key::kWebAppSettings, + prefs::kWebAppSettings, + schema, + policy::SchemaOnErrorStrategy::SCHEMA_ALLOW_UNKNOWN, + SimpleSchemaValidatingPolicyHandler::RECOMMENDED_PROHIBITED, + SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED) {} + +WebAppSettingsPolicyHandler::~WebAppSettingsPolicyHandler() = default; + +bool WebAppSettingsPolicyHandler::CheckPolicySettings( + const policy::PolicyMap& policies, + policy::PolicyErrorMap* errors) { + if (!policy::SimpleSchemaValidatingPolicyHandler::CheckPolicySettings( + policies, errors)) { + return false; + } + + const policy::PolicyMap::Entry* policy_entry = policies.Get(policy_name()); + if (!policy_entry) + return true; + + const auto& web_apps_list = policy_entry->value()->GetList(); + const auto it = std::find_if( + web_apps_list.begin(), web_apps_list.end(), [](const base::Value& entry) { + return entry.FindKey(kManifestId)->GetString() == kWildcard; + }); + + if (it != web_apps_list.end() && it->is_dict()) { + const std::string* run_on_os_login_str = it->FindStringKey(kRunOnOsLogin); + if (run_on_os_login_str && *run_on_os_login_str != kAllowed && + *run_on_os_login_str != kBlocked) { + errors->AddError(policy_name(), kWildcard, + "The default configuration contains an unsupported " + "value for the run_on_os_login field:" + + *run_on_os_login_str); + return false; + } + } + + return true; +} + +} // namespace web_app
diff --git a/chrome/browser/web_applications/policy/web_app_settings_policy_handler.h b/chrome/browser/web_applications/policy/web_app_settings_policy_handler.h new file mode 100644 index 0000000..8b5b4b7a --- /dev/null +++ b/chrome/browser/web_applications/policy/web_app_settings_policy_handler.h
@@ -0,0 +1,27 @@ +// Copyright 2022 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_WEB_APPLICATIONS_POLICY_WEB_APP_SETTINGS_POLICY_HANDLER_H_ +#define CHROME_BROWSER_WEB_APPLICATIONS_POLICY_WEB_APP_SETTINGS_POLICY_HANDLER_H_ + +#include "components/policy/core/browser/configuration_policy_handler.h" + +namespace web_app { + +// Maps policy to pref like SimpleSchemaValidatingPolicyHandler, with additional +// validation for WebAppSettings policy. +class WebAppSettingsPolicyHandler + : public policy::SimpleSchemaValidatingPolicyHandler { + public: + explicit WebAppSettingsPolicyHandler(policy::Schema schema); + ~WebAppSettingsPolicyHandler() override; + + // ConfigurationPolicyHandler: + bool CheckPolicySettings(const policy::PolicyMap& policies, + policy::PolicyErrorMap* errors) override; +}; + +} // namespace web_app + +#endif // CHROME_BROWSER_WEB_APPLICATIONS_POLICY_WEB_APP_SETTINGS_POLICY_HANDLER_H_
diff --git a/chrome/browser/web_applications/policy/web_app_settings_policy_handler_unittest.cc b/chrome/browser/web_applications/policy/web_app_settings_policy_handler_unittest.cc new file mode 100644 index 0000000..7e53e7b --- /dev/null +++ b/chrome/browser/web_applications/policy/web_app_settings_policy_handler_unittest.cc
@@ -0,0 +1,140 @@ +// Copyright 2022 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/web_applications/policy/web_app_settings_policy_handler.h" + +#include "base/json/json_reader.h" +#include "components/policy/core/browser/policy_error_map.h" +#include "components/policy/core/common/policy_map.h" +#include "components/policy/policy_constants.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace web_app { + +namespace { + +const char kWebAppSettingWithDefaultConfiguration_Blocked[] = R"([ + { + "manifest_id": "https://windowed.example/", + "run_on_os_login": "run_windowed" + }, + { + "manifest_id": "https://allowed.example/", + "run_on_os_login": "allowed" + }, + { + "manifest_id": "*", + "run_on_os_login": "blocked" + } +])"; + +const char kWebAppSettingWithDefaultConfiguration_Allowed[] = R"([ + { + "manifest_id": "https://windowed.example/", + "run_on_os_login": "run_windowed" + }, + { + "manifest_id": "https://allowed.example/", + "run_on_os_login": "blocked" + }, + { + "manifest_id": "*", + "run_on_os_login": "allowed" + } +])"; + +const char kWebAppSettingNoDefaultConfiguration[] = R"([ + { + "manifest_id": "https://windowed.example/", + "run_on_os_login": "run_windowed" + } +])"; + +const char kWebAppSettingDefaultConfiguration_RunOnOsLoginInvalid[] = R"([ + { + "manifest_id": "*", + "run_on_os_login": "unsupported_value" + } +])"; + +const char kWebAppSettingDefaultConfiguration_MissingManifestId[] = R"([ + { + "run_on_os_login": "unsupported_value" + } +])"; + +base::Value ReturnPolicyValueFromJson(base::StringPiece policy) { + base::JSONReader::ValueWithError result = + base::JSONReader::ReadAndReturnValueWithError( + policy, base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS); + DCHECK(result.value && result.value->is_list()) << result.error_message; + return std::move(*result.value); +} + +} // namespace + +TEST(WebAppSettingsPolicyHandlerTest, CheckPolicySettings_ValidPatterns) { + policy::Schema chrome_schema = + policy::Schema::Wrap(policy::GetChromeSchemaData()); + WebAppSettingsPolicyHandler handler(chrome_schema); + + auto valid_configs = {kWebAppSettingWithDefaultConfiguration_Blocked, + kWebAppSettingWithDefaultConfiguration_Allowed, + kWebAppSettingNoDefaultConfiguration}; + + for (const char* config : valid_configs) { + policy::PolicyErrorMap errors; + policy::PolicyMap policy; + + policy.Set(policy::key::kWebAppSettings, policy::POLICY_LEVEL_MANDATORY, + policy::POLICY_SCOPE_USER, + policy::POLICY_SOURCE_ENTERPRISE_DEFAULT, + ReturnPolicyValueFromJson(config), nullptr); + + EXPECT_TRUE(handler.CheckPolicySettings(policy, &errors)); + EXPECT_TRUE(errors.empty()); + } +} + +TEST(WebAppSettingsPolicyHandlerTest, CheckPolicySettings_RunOnOsLoginInvalid) { + policy::Schema chrome_schema = + policy::Schema::Wrap(policy::GetChromeSchemaData()); + WebAppSettingsPolicyHandler handler(chrome_schema); + + policy::PolicyErrorMap errors; + policy::PolicyMap policy; + + policy.Set(policy::key::kWebAppSettings, policy::POLICY_LEVEL_MANDATORY, + policy::POLICY_SCOPE_USER, + policy::POLICY_SOURCE_ENTERPRISE_DEFAULT, + ReturnPolicyValueFromJson( + kWebAppSettingDefaultConfiguration_RunOnOsLoginInvalid), + nullptr); + + EXPECT_FALSE(handler.CheckPolicySettings(policy, &errors)); + EXPECT_FALSE(errors.empty()); + EXPECT_FALSE(errors.GetErrors(policy::key::kWebAppSettings).empty()); +} + +TEST(WebAppSettingsPolicyHandlerTest, CheckPolicySettings_MissingManifestId) { + policy::Schema chrome_schema = + policy::Schema::Wrap(policy::GetChromeSchemaData()); + WebAppSettingsPolicyHandler handler(chrome_schema); + + policy::PolicyErrorMap errors; + policy::PolicyMap policy; + + policy.Set(policy::key::kWebAppSettings, policy::POLICY_LEVEL_MANDATORY, + policy::POLICY_SCOPE_USER, + policy::POLICY_SOURCE_ENTERPRISE_DEFAULT, + ReturnPolicyValueFromJson( + kWebAppSettingDefaultConfiguration_MissingManifestId), + nullptr); + + EXPECT_FALSE(handler.CheckPolicySettings(policy, &errors)); + EXPECT_FALSE(errors.empty()); + EXPECT_FALSE(errors.GetErrors(policy::key::kWebAppSettings).empty()); +} + +} // namespace web_app
diff --git a/chrome/browser/web_applications/test/web_app_test_utils.cc b/chrome/browser/web_applications/test/web_app_test_utils.cc index fed9c03e..f7bb1b2 100644 --- a/chrome/browser/web_applications/test/web_app_test_utils.cc +++ b/chrome/browser/web_applications/test/web_app_test_utils.cc
@@ -544,11 +544,11 @@ run_loop.Run(); } -void SetWebAppSettingsDictPref(Profile* profile, const base::StringPiece pref) { +void SetWebAppSettingsListPref(Profile* profile, const base::StringPiece pref) { base::JSONReader::ValueWithError result = base::JSONReader::ReadAndReturnValueWithError( pref, base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS); - DCHECK(result.value && result.value->is_dict()) << result.error_message; + DCHECK(result.value && result.value->is_list()) << result.error_message; profile->GetPrefs()->Set(prefs::kWebAppSettings, std::move(*result.value)); }
diff --git a/chrome/browser/web_applications/test/web_app_test_utils.h b/chrome/browser/web_applications/test/web_app_test_utils.h index ee108dfd..0f64576b 100644 --- a/chrome/browser/web_applications/test/web_app_test_utils.h +++ b/chrome/browser/web_applications/test/web_app_test_utils.h
@@ -46,7 +46,7 @@ content::StoragePartition* storage_partition, content::ServiceWorkerCapability status); -void SetWebAppSettingsDictPref(Profile* profile, base::StringPiece pref); +void SetWebAppSettingsListPref(Profile* profile, base::StringPiece pref); } // namespace test } // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_install_task_unittest.cc b/chrome/browser/web_applications/web_app_install_task_unittest.cc index 3edc667..9949e46 100644 --- a/chrome/browser/web_applications/web_app_install_task_unittest.cc +++ b/chrome/browser/web_applications/web_app_install_task_unittest.cc
@@ -1434,16 +1434,18 @@ CreateRendererAppInfo(url, name, description, /*scope=*/GURL{}, theme_color, /*user_display_mode=*/DisplayMode::kStandalone); - const char kWebAppSettingWithDefaultConfiguration[] = R"({ - "https://example.com/scope/path": { + const char kWebAppSettingWithDefaultConfiguration[] = R"([ + { + "manifest_id": "https://example.com/scope/path", "run_on_os_login": "run_windowed" }, - "*": { + { + "manifest_id": "*", "run_on_os_login": "blocked" } - })"; + ])"; - test::SetWebAppSettingsDictPref(profile(), + test::SetWebAppSettingsListPref(profile(), kWebAppSettingWithDefaultConfiguration); controller().policy_manager().RefreshPolicySettingsForTesting();
diff --git a/chrome/browser/web_applications/web_app_registrar_unittest.cc b/chrome/browser/web_applications/web_app_registrar_unittest.cc index 23d8282..b0071719 100644 --- a/chrome/browser/web_applications/web_app_registrar_unittest.cc +++ b/chrome/browser/web_applications/web_app_registrar_unittest.cc
@@ -987,19 +987,22 @@ EXPECT_EQ(RunOnOsLoginMode::kWindowed, registrar().GetAppRunOnOsLoginMode(app_id_allowed).value); - const char kWebAppSettingWithDefaultConfiguration[] = R"({ - "https://windowed.example/": { + const char kWebAppSettingWithDefaultConfiguration[] = R"([ + { + "manifest_id": "https://windowed.example/", "run_on_os_login": "run_windowed" }, - "https://allowed.example/": { + { + "manifest_id": "https://allowed.example/", "run_on_os_login": "allowed" }, - "*": { + { + "manifest_id": "*", "run_on_os_login": "blocked" } - })"; + ])"; - test::SetWebAppSettingsDictPref(profile(), + test::SetWebAppSettingsListPref(profile(), kWebAppSettingWithDefaultConfiguration); controller().policy_manager().RefreshPolicySettingsForTesting();
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index b7345b1..c2632e3 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1648123130-de2ce5f37901865e245fbd32b9b3173c7722846d.profdata +chrome-linux-main-1648144749-ccfe60ff8537a513b27416548f37272ec8626ab2.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 7ab64e02..f20ea03 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1648123130-1b9f5c0fd113bc823ee08534d0111f6eb0fa4fd5.profdata +chrome-mac-arm-main-1648144749-e50da85dc22932c4d917580e7bd267cfe889b31b.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 949fc085..b72f566 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1648123130-8fe31eae566b2ade3fe3bddea44e0a8519c91885.profdata +chrome-mac-main-1648144749-c9baea862655d2ef23474abda8fce3ac8875e181.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index e42e06e2..607781f 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1648123130-101892ec63ad9eed8e4c1f181424fb203c623d67.profdata +chrome-win32-main-1648133989-84788d19695d4ddcb485bf65f608066e5f6d319d.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index a81ef5f..a18a8698 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1648123130-14e10beecf0809cd8f85066955cc621fea800720.profdata +chrome-win64-main-1648144804-ce09408549800609c8c3db07d2b084d099da417c.profdata
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 67f93d2..360023b7 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -115,22 +115,6 @@ // Comma-separated list of SSL cipher suites to disable. const char kCipherSuiteBlacklist[] = "cipher-suite-blacklist"; -// Tells chrome to display the cloud print dialog and upload the specified file -// for printing. -const char kCloudPrintFile[] = "cloud-print-file"; - -// Specifies the mime type to be used when uploading data from the file -// referenced by cloud-print-file. Defaults to "application/pdf" if -// unspecified. -const char kCloudPrintFileType[] = "cloud-print-file-type"; - -// Used with kCloudPrintFile to specify a title for the resulting print job. -const char kCloudPrintJobTitle[] = "cloud-print-job-title"; - -// Used with kCloudPrintFile to specify a JSON print ticket for the resulting -// print job. Defaults to null if unspecified. -const char kCloudPrintPrintTicket[] = "cloud-print-print-ticket"; - // Comma-separated list of BrowserThreads that cause browser process to crash if // the given browser thread is not responsive. UI/IO are the BrowserThreads that // are supported.
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index f79266e8..92d1116 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -57,10 +57,6 @@ extern const char kAutoSelectTabCaptureSourceByTitle[]; extern const char kCheckForUpdateIntervalSec[]; extern const char kCipherSuiteBlacklist[]; -extern const char kCloudPrintFile[]; -extern const char kCloudPrintFileType[]; -extern const char kCloudPrintJobTitle[]; -extern const char kCloudPrintPrintTicket[]; extern const char kCrashOnHangThreads[]; extern const char kCreateBrowserOnStartupForTests[]; extern const char kCustomDevtoolsFrontend[];
diff --git a/chrome/common/extensions/api/chromeos_info_private.json b/chrome/common/extensions/api/chromeos_info_private.json index 74fe3e7..9fd131f 100644 --- a/chrome/common/extensions/api/chromeos_info_private.json +++ b/chrome/common/extensions/api/chromeos_info_private.json
@@ -93,6 +93,7 @@ "customizationId": {"type": "string", "optional": true, "description": "Customization ID"}, "homeProvider" : {"type": "string", "optional": true, "description": "Home provider which is used by the cellular device"}, "hwid": {"type": "string", "optional": true, "description": "Hardware ID"}, + "isMeetDevice": {"type": "boolean", "optional": true, "description": "True if Chrome is built with is_cfm build flag"}, "initialLocale" : {"type": "string", "optional": true, "description": "Initial locale for the device"}, "isOwner" : {"type": "boolean", "optional": true, "description": "True if current logged in user is device owner"}, "sessionType": {"$ref": "SessionType", "optional": true},
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index fd6157e..66376f1 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -611,6 +611,7 @@ "views/chrome_views_test_base.cc", "views/chrome_views_test_base.h", ] + deps += [ "//chrome/browser/ui/color:mixers" ] } if (enable_extensions) { @@ -2508,6 +2509,7 @@ if (!is_chromeos_ash) { sources += [ "../browser/chrome_multiprofile_startup_browsertest.cc", + "../browser/enterprise/reporting/cloud_profile_reporting_browsertest.cc", "../browser/external_protocol/external_protocol_handler_browsertest.cc", "../browser/policy/test/variation_restrict_parameter_policy_browsertest.cc", "../browser/profiles/profile_window_browsertest.cc", @@ -3042,6 +3044,7 @@ deps += [ "../browser/chromeos/extensions/telemetry/api:browser_tests", "//chrome/browser/error_reporting:test_support", + "//chromeos/components/chromebox_for_meetings/buildflags", "//chromeos/dbus/dlp:dlp", ] @@ -4279,9 +4282,12 @@ use_cfv2 = false additional_manifest_fragments = [ + "//build/config/fuchsia/test/audio_capabilities.test-cmx", "//build/config/fuchsia/test/font_capabilities.test-cmx", "//build/config/fuchsia/test/jit_capabilities.test-cmx", "//build/config/fuchsia/test/network_capabilities.test-cmx", + "//build/config/fuchsia/test/present_view_capabilities.test-cmx", + "//build/config/fuchsia/test/vulkan_capabilities.test-cmx", ] # TODO(crbug.com/931218): Ninja cannot handle certain characters appearing @@ -6462,6 +6468,7 @@ "../browser/ui/tab_contents/chrome_web_contents_view_handle_drop_unittest.cc", "../browser/ui/tab_contents/tab_contents_iterator_unittest.cc", "../browser/ui/tab_sharing/tab_sharing_infobar_delegate_unittest.cc", + "../browser/ui/tabs/existing_base_sub_menu_model_unittest.cc", "../browser/ui/tabs/existing_tab_group_sub_menu_model_unittest.cc", "../browser/ui/tabs/existing_window_sub_menu_model_unittest.cc", "../browser/ui/tabs/pinned_tab_codec_unittest.cc",
diff --git a/chrome/test/data/extensions/api_test/chromeos_info_private/basic/background.js b/chrome/test/data/extensions/api_test/chromeos_info_private/basic/background.js index 590f713..3b14248 100644 --- a/chrome/test/data/extensions/api_test/chromeos_info_private/basic/background.js +++ b/chrome/test/data/extensions/api_test/chromeos_info_private/basic/background.js
@@ -103,6 +103,7 @@ // Generated chrome.chromeosInfoPrivate.get() tests. tests = generateTestsForKeys([ 'hwid', + 'isMeetDevice', 'customizationId', 'homeProvider', 'initialLocale',
diff --git a/chrome/test/data/extensions/api_test/chromeos_info_private/extended/background.js b/chrome/test/data/extensions/api_test/chromeos_info_private/extended/background.js index 282c9c1..b6749d2e 100644 --- a/chrome/test/data/extensions/api_test/chromeos_info_private/extended/background.js +++ b/chrome/test/data/extensions/api_test/chromeos_info_private/extended/background.js
@@ -16,6 +16,7 @@ 'deviceType', 'stylusStatus', 'assistantStatus', + 'isMeetDevice', ], chrome.test.callbackPass(function(values) { switch (testName) { case 'kiosk': @@ -60,6 +61,12 @@ case 'assistant supported': chrome.test.assertEq('supported', values['assistantStatus']); break; + case 'Is Meet Device - True' : + chrome.test.assertTrue(values['isMeetDevice']); + break; + case 'Is Meet Device - False' : + chrome.test.assertFalse(values['isMeetDevice']); + break; } })); });
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index b490416..3dba549 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -16421,20 +16421,24 @@ "policy_pref_mapping_tests": [ { "policies": { - "WebAppSettings": { - "https://foo.example": { + "WebAppSettings": [ + { + "manifest_id": "https://foo.example/index.html", "run_on_os_login": "allowed" }, - "https://bar.example": { + { + "manifest_id": "https://bar.example/index.html", "run_on_os_login": "blocked" }, - "https://foobar.example": { + { + "manifest_id": "https://foobar.example/index.html", "run_on_os_login": "run_windowed" }, - "*": { + { + "manifest_id": "*", "run_on_os_login": "blocked" } - } + ] }, "prefs": { "profile.web_app.policy_settings": {}
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/critical_error_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/critical_error_page_test.js index a536fd3f..b1caacb 100644 --- a/chrome/test/data/webui/chromeos/shimless_rma/critical_error_page_test.js +++ b/chrome/test/data/webui/chromeos/shimless_rma/critical_error_page_test.js
@@ -65,14 +65,12 @@ test('ClickExitToLoginButton', async () => { await initializeCriticalErrorPage(); assertTrue(!!component); - component.addEventListener('disable-all-buttons', (e) => { - component.allButtonsDisabled = e.detail; - }); const resolver = new PromiseResolver(); let allButtonsDisabled = false; component.addEventListener('disable-all-buttons', (e) => { - allButtonsDisabled = e.detail; + allButtonsDisabled = true; + component.allButtonsDisabled = allButtonsDisabled; resolver.resolve(); }); @@ -88,14 +86,12 @@ test('ClickRebootButton', async () => { await initializeCriticalErrorPage(); assertTrue(!!component); - component.addEventListener('disable-all-buttons', (e) => { - component.allButtonsDisabled = e.detail; - }); const resolver = new PromiseResolver(); let allButtonsDisabled = false; component.addEventListener('disable-all-buttons', (e) => { - allButtonsDisabled = e.detail; + allButtonsDisabled = true; + component.allButtonsDisabled = allButtonsDisabled; resolver.resolve(); });
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_update_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_update_page_test.js index 5b3569bc..899f3df 100644 --- a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_update_page_test.js +++ b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_update_page_test.js
@@ -95,7 +95,7 @@ return initializeUpdatePage(version) .then(() => { component.addEventListener('disable-all-buttons', (e) => { - component.allButtonsDisabled = e.detail; + component.allButtonsDisabled = true; }); return flushTasks(); @@ -179,7 +179,10 @@ return initializeUpdatePage(version).then(() => { let allButtonsDisabled = false; component.addEventListener('disable-all-buttons', (e) => { - allButtonsDisabled = e.detail; + allButtonsDisabled = true; + }); + component.addEventListener('enable-all-buttons', (e) => { + allButtonsDisabled = false; }); return clickPerformUpdateButton()
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js index 196b8a3..8b184d2 100644 --- a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js +++ b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js
@@ -9,6 +9,7 @@ import {setShimlessRmaServiceForTesting} from 'chrome://shimless-rma/mojo_interface_provider.js'; import {ButtonState, ShimlessRma} from 'chrome://shimless-rma/shimless_rma.js'; import {RmadErrorCode, State, StateResult} from 'chrome://shimless-rma/shimless_rma_types.js'; +import {disableAllButtons, enableAllButtons} from 'chrome://shimless-rma/shimless_rma_util.js'; import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js'; import {flushTasks, isVisible} from '../../test_util.js'; @@ -177,7 +178,7 @@ await flushTasks(); assertEquals(1, abortRmaCount); - assertFalse(initialPage.allButtonsDisabled); + assertTrue(initialPage.allButtonsDisabled); }); test('NextButtonClickedOnReady', async () => { @@ -404,25 +405,26 @@ const nextButton = component.shadowRoot.querySelector('#next'); const backButton = component.shadowRoot.querySelector('#back'); const cancelButton = component.shadowRoot.querySelector('#cancel'); + const busyStateOverlay = /** @type {!HTMLElement} */ ( + component.shadowRoot.querySelector('#busyStateOverlay')); assertFalse(nextButton.disabled); assertFalse(backButton.disabled); assertFalse(cancelButton.disabled); - component.dispatchEvent(new CustomEvent( - 'disable-all-buttons', - {bubbles: true, composed: true, detail: true}, - )); + disableAllButtons(component, /*showBusyStateOverlay=*/ false); assertTrue(nextButton.disabled); assertTrue(backButton.disabled); assertTrue(cancelButton.disabled); + assertFalse(isVisible(busyStateOverlay)); - component.dispatchEvent(new CustomEvent( - 'disable-all-buttons', - {bubbles: true, composed: true, detail: false}, - )); + disableAllButtons(component, /*showBusyStateOverlay=*/ true); + assertTrue(isVisible(busyStateOverlay)); + + enableAllButtons(component); assertFalse(nextButton.disabled); assertFalse(backButton.disabled); assertFalse(cancelButton.disabled); + assertFalse(isVisible(busyStateOverlay)); }); }
diff --git a/chrome/test/data/webui/new_tab_page/customize_modules_test.ts b/chrome/test/data/webui/new_tab_page/customize_modules_test.ts index 83036935..6fa4982 100644 --- a/chrome/test/data/webui/new_tab_page/customize_modules_test.ts +++ b/chrome/test/data/webui/new_tab_page/customize_modules_test.ts
@@ -57,6 +57,8 @@ cartHandler = installMock(CartHandlerRemote, ChromeCartProxy.setHandler); cartHandler.setResultFor( 'getDiscountEnabled', Promise.resolve({enabled: false})); + cartHandler.setResultFor( + 'getDiscountToggleVisible', Promise.resolve({toggleVisible: false})); }); [true, false].forEach(visible => { @@ -183,7 +185,8 @@ test('discount toggle shows correct config', async () => { // Arrange. - loadTimeData.overrideValues({ruleBasedDiscountEnabled: true}); + cartHandler.setResultFor( + 'getDiscountToggleVisible', Promise.resolve({toggleVisible: true})); cartHandler.setResultFor( 'getDiscountEnabled', Promise.resolve({enabled: true})); const customizeModules = await createCustomizeModules(false, [ @@ -214,7 +217,8 @@ test(`discount toggle sets discount status`, async () => { // Arrange. - loadTimeData.overrideValues({ruleBasedDiscountEnabled: true}); + cartHandler.setResultFor( + 'getDiscountToggleVisible', Promise.resolve({toggleVisible: true})); cartHandler.setResultFor( 'getDiscountEnabled', Promise.resolve({enabled: true})); const customizeModules = await createCustomizeModules(false, [ @@ -234,7 +238,8 @@ test(`toggling off cart module hides discount toggle`, async () => { // Arrange. - loadTimeData.overrideValues({ruleBasedDiscountEnabled: true}); + cartHandler.setResultFor( + 'getDiscountToggleVisible', Promise.resolve({toggleVisible: true})); cartHandler.setResultFor( 'getDiscountEnabled', Promise.resolve({enabled: true})); const customizeModules = await createCustomizeModules(false, [ @@ -285,7 +290,8 @@ test('record disable discount', async () => { // Arrange. - loadTimeData.overrideValues({ruleBasedDiscountEnabled: true}); + cartHandler.setResultFor( + 'getDiscountToggleVisible', Promise.resolve({toggleVisible: true})); cartHandler.setResultFor( 'getDiscountEnabled', Promise.resolve({enabled: true})); const customizeModules = await createCustomizeModules(false, [ @@ -307,7 +313,8 @@ test('record enable discount', async () => { // Arrange. - loadTimeData.overrideValues({ruleBasedDiscountEnabled: true}); + cartHandler.setResultFor( + 'getDiscountToggleVisible', Promise.resolve({toggleVisible: true})); cartHandler.setResultFor( 'getDiscountEnabled', Promise.resolve({enabled: false})); const customizeModules = await createCustomizeModules(false, [ @@ -326,4 +333,36 @@ assertDeepEquals(true, cartHandler.getArgs('setDiscountEnabled')[0]); assertEquals(1, metrics.count('NewTabPage.Carts.EnableDiscount')); }); + + test('discount toggle is visible', async () => { + // Arrange. + cartHandler.setResultFor( + 'getDiscountToggleVisible', Promise.resolve({toggleVisible: true})); + cartHandler.setResultFor( + 'getDiscountEnabled', Promise.resolve({enabled: false})); + const customizeModules = await createCustomizeModules(false, [ + {id: 'chrome_cart', name: 'foo name', disabled: false}, + ]); + const subToggleRows = + customizeModules.shadowRoot!.querySelectorAll('.discount-toggle-row'); + + // Assert. + assertEquals(1, subToggleRows.length); + }); + + test('discount toggle is not visible', async () => { + // Arrange. + cartHandler.setResultFor( + 'getDiscountToggleVisible', Promise.resolve({toggleVisible: false})); + cartHandler.setResultFor( + 'getDiscountEnabled', Promise.resolve({enabled: false})); + const customizeModules = await createCustomizeModules(false, [ + {id: 'chrome_cart', name: 'foo name', disabled: false}, + ]); + const subToggleRows = + customizeModules.shadowRoot!.querySelectorAll('.discount-toggle-row'); + + // Assert. + assertEquals(0, subToggleRows.length); + }); });
diff --git a/chrome/test/data/webui/new_tab_page/modules/modules_test.ts b/chrome/test/data/webui/new_tab_page/modules/modules_test.ts index d465b2e..316543f 100644 --- a/chrome/test/data/webui/new_tab_page/modules/modules_test.ts +++ b/chrome/test/data/webui/new_tab_page/modules/modules_test.ts
@@ -583,6 +583,53 @@ // Assert: no crash. }); + test('record number of loaded modules', async () => { + // Arrange. + const fooDescriptor = new ModuleDescriptor('foo', 'Foo', initNullModule); + const barDescriptor = new ModuleDescriptor('bar', 'Bar', initNullModule); + moduleRegistry.setResultFor( + 'getDescriptors', [fooDescriptor, barDescriptor]); + await createModulesElement([ + { + descriptor: fooDescriptor, + element: createElement(), + }, + { + descriptor: barDescriptor, + element: createElement(), + } + ]); + + // Assert. + assertEquals( + 1, metrics.count('NewTabPage.Modules.LoadedModulesCount', 2), + 'Rendered count is 2 should be recored once'); + }); + + test('record module loaded with other modules', async () => { + // Arrange. + const fooDescriptor = new ModuleDescriptor('foo', 'Foo', initNullModule); + const barDescriptor = new ModuleDescriptor('bar', 'Bar', initNullModule); + moduleRegistry.setResultFor( + 'getDescriptors', [fooDescriptor, barDescriptor]); + await createModulesElement([ + { + descriptor: fooDescriptor, + element: createElement(), + }, + { + descriptor: barDescriptor, + element: createElement(), + } + ]); + + // Assert. + assertEquals(1, metrics.count('NewTabPage.Modules.LoadedWith.foo', 'bar')); + assertEquals(0, metrics.count('NewTabPage.Modules.LoadedWith.foo', 'foo')); + assertEquals(1, metrics.count('NewTabPage.Modules.LoadedWith.bar', 'foo')); + assertEquals(0, metrics.count('NewTabPage.Modules.LoadedWith.bar', 'bar')); + }); + suite('modules drag and drop', () => { suiteSetup(() => { loadTimeData.overrideValues({
diff --git a/chrome/test/data/webui/settings/BUILD.gn b/chrome/test/data/webui/settings/BUILD.gn index c23eaf1c..79976cb 100644 --- a/chrome/test/data/webui/settings/BUILD.gn +++ b/chrome/test/data/webui/settings/BUILD.gn
@@ -73,7 +73,7 @@ "passwords_and_autofill_fake_data.ts", "passwords_device_section_test.ts", "passwords_export_test.ts", - "passwords_section_test.js", + "passwords_section_test.ts", "payments_section_interactive_test.ts", "payments_section_test.ts", "people_page_sync_controls_test.ts",
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn index 8c12ceb..f629d27 100644 --- a/chrome/test/data/webui/settings/chromeos/BUILD.gn +++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -53,6 +53,7 @@ "app_management/reducers_test.js", "app_management/resize_lock_item_test.js", "app_management/supported_links_item_test.js", + "app_management/file_handling_item_test.js", "app_management/test_plugin_vm_browser_proxy.js", "app_management/toggle_row_test.js", "app_management/test_store.js",
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/file_handling_item_test.js b/chrome/test/data/webui/settings/chromeos/app_management/file_handling_item_test.js new file mode 100644 index 0000000..3a4356d --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/app_management/file_handling_item_test.js
@@ -0,0 +1,65 @@ +// Copyright 2021 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. + +// clang-format off +// #import 'chrome://os-settings/chromeos/os_settings.js'; + +// #import {AppManagementStore, FakePageHandler, updateSelectedAppId, addApp} from 'chrome://os-settings/chromeos/os_settings.js'; +// #import {setupFakeHandler, replaceStore, replaceBody} from './test_util.m.js'; +// #import {flushTasks} from 'chrome://test/test_util.js'; +// clang-format on + +'use strict'; + +suite('<app-management-file-handling-item>', () => { + let fileHandlingItem; + let fakeHandler; + + setup(async function() { + fakeHandler = setupFakeHandler(); + replaceStore(); + + fileHandlingItem = + document.createElement('app-management-file-handling-item'); + + replaceBody(fileHandlingItem); + test_util.flushTasks(); + }); + + // Simple test that just verifies the file handling item is present and + // doesn't throw errors. More comprehensive testing is in cross platform + // app_management tests. + test('PWA - basic file handling test', async function() { + const pwaOptions = { + type: appManagement.mojom.AppType.kWeb, + fileHandlingState: { + enabled: false, + isManaged: false, + userVisibleTypes: 'TXT', + userVisibleTypesLabel: 'Supported type: TXT', + learnMoreUrl: {url: 'https://google.com/'}, + }, + }; + + // Add PWA app, and make it the currently selected app. + const app = await fakeHandler.addApp('app1', pwaOptions); + + app_management.AppManagementStore.getInstance().dispatch( + app_management.actions.updateSelectedAppId(app.id)); + + await fakeHandler.flushPipesForTesting(); + + assertTrue( + !!app_management.AppManagementStore.getInstance().data.apps[app.id]); + + fileHandlingItem.app = app; + + replaceBody(fileHandlingItem); + fakeHandler.flushPipesForTesting(); + test_util.flushTasks(); + + expectFalse( + fileHandlingItem.shadowRoot.querySelector('#toggle-row').isChecked()); + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js index b33c93a..9e9b87c 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -356,6 +356,7 @@ ['AppManagementBorealisDetailView', 'borealis_detail_view_test.m.js'], ['AppManagementChromeAppDetailView', 'chrome_app_detail_view_test.m.js'], ['AppManagementDomSwitch', 'dom_switch_test.m.js'], + ['AppManagementFileHandlingItem', 'file_handling_item_test.m.js'], ['AppManagementMainView', 'main_view_test.m.js'], ['AppManagementManagedApp', 'managed_apps_test.m.js'], ['AppManagementPage', 'app_management_page_tests.m.js'],
diff --git a/chrome/test/data/webui/settings/passwords_section_test.js b/chrome/test/data/webui/settings/passwords_section_test.ts similarity index 77% rename from chrome/test/data/webui/settings/passwords_section_test.js rename to chrome/test/data/webui/settings/passwords_section_test.ts index 54ccc4f..dbc3592 100644 --- a/chrome/test/data/webui/settings/passwords_section_test.js +++ b/chrome/test/data/webui/settings/passwords_section_test.ts
@@ -10,8 +10,9 @@ import {isChromeOS, isLacros, webUIListenerCallback} from 'chrome://resources/js/cr.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {PasswordDialogMode} from 'chrome://settings/lazy_load.js'; -import {HatsBrowserProxyImpl, MultiStoreExceptionEntry, MultiStorePasswordUiEntry, PasswordCheckReferrer, PasswordManagerImpl, Router, routes, SettingsPluralStringProxyImpl, TrustedVaultBannerState, TrustSafetyInteraction} from 'chrome://settings/settings.js'; +import {CrDialogElement, PasswordDialogMode, PasswordsSectionElement} from 'chrome://settings/lazy_load.js'; +import {HatsBrowserProxyImpl, MultiStoreExceptionEntry, MultiStorePasswordUiEntry, PasswordCheckReferrer, PasswordManagerImpl, Router, routes, SettingsPluralStringProxyImpl,StatusAction, TrustedVaultBannerState, TrustSafetyInteraction} from 'chrome://settings/settings.js'; +import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {TestPluralStringProxy} from 'chrome://webui-test/test_plural_string_proxy.js'; import {eventToPromise} from 'chrome://webui-test/test_util.js'; @@ -28,31 +29,33 @@ /** * Helper method that validates a that elements in the password list match * the expected data. - * @param {!Element} passwordsSection The passwords section element that will - * be checked. - * @param {!Array<!MultiStorePasswordUiEntry>} expectedPasswords The expected - * data. - * @private + * @param passwordsSection The passwords section element that will be checked. + * @param expectedPasswords The expected data. */ -function validateMultiStorePasswordList(passwordsSection, expectedPasswords) { +function validateMultiStorePasswordList( + passwordsSection: PasswordsSectionElement, + expectedPasswords: MultiStorePasswordUiEntry[]) { const passwordList = passwordsSection.$.passwordList; if (passwordList.filter) { // `passwordList.items` will always contain all items, even when there is a // filter to be applied. Thus apply `passwordList.filter` to obtain the list // of items that are user visible. assertDeepEquals( - expectedPasswords, passwordList.items.filter(passwordList.filter)); + expectedPasswords, + passwordList.items!.filter( + passwordList.filter as (item: MultiStorePasswordUiEntry) => + boolean)); } else { assertDeepEquals(expectedPasswords, passwordList.items); } const listItems = - passwordsSection.shadowRoot.querySelectorAll('password-list-item'); + passwordsSection.shadowRoot!.querySelectorAll('password-list-item'); for (let index = 0; index < expectedPasswords.length; ++index) { - const expected = expectedPasswords[index]; - const listItem = listItems[index]; + const expected = expectedPasswords[index]!; + const listItem = listItems[index]!; assertTrue(!!listItem); - assertEquals(expected.urls.shown, listItem.$.originUrl.textContent.trim()); + assertEquals(expected.urls.shown, listItem.$.originUrl.textContent!.trim()); assertEquals(expected.urls.link, listItem.$.originUrl.href); assertEquals(expected.username, listItem.$.username.value); } @@ -61,13 +64,12 @@ /** * Convenience version of validateMultiStorePasswordList() for when store * duplicates don't exist. - * @param {!Element} passwordsSection The passwords section element that will - * be checked. - * @param {!Array<!chrome.passwordsPrivate.PasswordUiEntry>} passwordList The - * expected data. - * @private + * @param passwordsSection The passwords section element that will be checked. + * @param passwordList The expected data. */ -function validatePasswordList(passwordsSection, passwordList) { +function validatePasswordList( + passwordsSection: PasswordsSectionElement, + passwordList: chrome.passwordsPrivate.PasswordUiEntry[]) { validateMultiStorePasswordList( passwordsSection, passwordList.map(entry => new MultiStorePasswordUiEntry(entry))); @@ -76,91 +78,81 @@ /** * Helper method that validates a that elements in the exception list match * the expected data. - * @param {!Array<!Element>} nodes The nodes that will be checked. - * @param {!Array<!MultiStoreExceptionEntry>} exceptionList The expected data. - * @private + * @param nodes The nodes that will be checked. + * @param exceptionList The expected data. */ -function validateMultiStoreExceptionList(nodes, exceptionList) { +function validateMultiStoreExceptionList( + nodes: NodeListOf<HTMLElement>, exceptionList: MultiStoreExceptionEntry[]) { assertEquals(exceptionList.length, nodes.length); for (let index = 0; index < exceptionList.length; ++index) { - const node = nodes[index]; - const exception = exceptionList[index]; + const node = nodes[index]!; + const exception = exceptionList[index]!; assertEquals( exception.urls.shown, - node.querySelector('#exception').textContent.trim()); + node.querySelector<HTMLElement>('#exception')!.textContent!.trim()); assertEquals( exception.urls.link.toLowerCase(), - node.querySelector('#exception').href); + node.querySelector<HTMLAnchorElement>('#exception')!.href); } } /** * Convenience version of validateMultiStoreExceptionList() for when store * duplicates do not exist. - * @param {!Array<!Element>} nodes The nodes that will be checked. - * @param {!Array<!chrome.passwordsPrivate.ExceptionEntry>} exceptionList The - * expected data. - * @private + * @param nodes The nodes that will be checked. + * @param exceptionList The expected data. */ -function validateExceptionList(nodes, exceptionList) { +function validateExceptionList( + nodes: NodeListOf<HTMLElement>, + exceptionList: chrome.passwordsPrivate.ExceptionEntry[]) { validateMultiStoreExceptionList( nodes, exceptionList.map(entry => new MultiStoreExceptionEntry(entry))); } /** * Returns all children of an element that has children added by a dom-repeat. - * @param {!Element} element - * @return {!Array<!Element>} - * @private */ -function getDomRepeatChildren(element) { - const nodes = element.querySelectorAll('.list-item:not([id])'); +function getDomRepeatChildren(element: HTMLElement): NodeListOf<HTMLElement> { + const nodes = element.querySelectorAll<HTMLElement>('.list-item:not([id])'); return nodes; } /** * Extracts the first password-list-item in the a password-section element. - * @param {!Element} passwordsSection */ -function getFirstPasswordListItem(passwordsSection) { - // The first child is a template, skip and get the real 'first child'. - return passwordsSection.shadowRoot.querySelector('password-list-item'); +function getFirstPasswordListItem(passwordsSection: HTMLElement) { + return passwordsSection.shadowRoot!.querySelector('password-list-item')!; } /** * Helper method used to test for a url in a list of passwords. - * @param {!Array<!chrome.passwordsPrivate.PasswordUiEntry>} passwordList - * @param {string} url The URL that is being searched for. + * @param url The URL that is being searched for. */ -function listContainsUrl(passwordList, url) { - for (let i = 0; i < passwordList.length; ++i) { - if (passwordList[i].urls.origin === url) { - return true; - } - } - return false; +function listContainsUrl( + passwordList: + (MultiStorePasswordUiEntry[]|chrome.passwordsPrivate.PasswordUiEntry[]), + url: string): boolean { + return passwordList.some(item => item.urls.origin === url); } /** * Helper method used to test for a url in a list of passwords. - * @param {!Array<!chrome.passwordsPrivate.ExceptionEntry>} exceptionList - * @param {string} url The URL that is being searched for. + * @param url The URL that is being searched for. */ -function exceptionsListContainsUrl(exceptionList, url) { - for (let i = 0; i < exceptionList.length; ++i) { - if (exceptionList[i].urls.orginUrl === url) { - return true; - } - } - return false; +function exceptionsListContainsUrl( + exceptionList: + (MultiStoreExceptionEntry[]|chrome.passwordsPrivate.ExceptionEntry[]), + url: string): boolean { + return exceptionList.some( + item => (item.urls as unknown as {originUrl: string}).originUrl === url); } /** * Helper function to check password visibility when open password-edit-dialog. - * @param {TestPasswordManagerProxy} passwordManager - * @param {PasswordSectionElementFactory} elementFactory */ -async function openPasswordEditDialogHelper(passwordManager, elementFactory) { +async function openPasswordEditDialogHelper( + passwordManager: TestPasswordManagerProxy, + elementFactory: PasswordSectionElementFactory) { const PASSWORD = 'p4ssw0rd'; const passwordList = [ createPasswordEntry({username: 'user0', id: 0}), @@ -171,17 +163,23 @@ elementFactory.createPasswordsSection(passwordManager, passwordList, []); const passwordListItem = getFirstPasswordListItem(passwordsSection); - passwordListItem.shadowRoot.querySelector('#showPasswordButton').click(); + passwordListItem.shadowRoot! + .querySelector<HTMLElement>('#showPasswordButton')!.click(); flush(); await passwordManager.whenCalled('requestPlaintextPassword'); passwordManager.resetResolver('requestPlaintextPassword'); flush(); assertEquals( - 'text', passwordListItem.shadowRoot.querySelector('#password').type); - assertFalse(passwordListItem.shadowRoot.querySelector('#password').disabled); - assertTrue(passwordListItem.shadowRoot.querySelector('#showPasswordButton') - .classList.contains('icon-visibility-off')); + 'text', + passwordListItem.shadowRoot!.querySelector<HTMLInputElement>( + '#password')!.type); + assertFalse( + passwordListItem.shadowRoot!.querySelector<HTMLInputElement>( + '#password')!.disabled); + assertTrue(passwordListItem.shadowRoot! + .querySelector<HTMLElement>('#showPasswordButton')!.classList + .contains('icon-visibility-off')); // Open Edit Dialog. passwordListItem.$.moreActionsButton.click(); @@ -193,21 +191,28 @@ flush(); assertEquals( - 'password', passwordListItem.shadowRoot.querySelector('#password').type); - assertTrue(passwordListItem.shadowRoot.querySelector('#password').disabled); - assertTrue(passwordListItem.shadowRoot.querySelector('#showPasswordButton') - .classList.contains('icon-visibility')); + 'password', + passwordListItem.shadowRoot!.querySelector<HTMLInputElement>( + '#password')!.type); + assertTrue( + passwordListItem.shadowRoot!.querySelector<HTMLInputElement>( + '#password')!.disabled); + assertTrue( + passwordListItem.shadowRoot! + .querySelector<HTMLElement>( + '#showPasswordButton')!.classList.contains('icon-visibility')); // Verify that edit dialog password is hidden. const passwordEditDialog = - passwordsSection.$.passwordsListHandler.shadowRoot.querySelector( - '#passwordEditDialog'); + passwordsSection.$.passwordsListHandler.shadowRoot!.querySelector( + 'password-edit-dialog')!; const showPasswordButton = - passwordEditDialog.shadowRoot.querySelector('#showPasswordButton'); + passwordEditDialog.shadowRoot!.querySelector<HTMLElement>( + '#showPasswordButton')!; assertEquals('password', passwordEditDialog.$.passwordInput.type); assertTrue(showPasswordButton.classList.contains('icon-visibility')); - passwordEditDialog.shadowRoot.querySelector('#showPasswordButton').click(); + showPasswordButton.click(); flush(); assertEquals('text', passwordEditDialog.$.passwordInput.type); @@ -221,19 +226,24 @@ assertEquals('', passwordListItem.entry.password); assertEquals( - 'password', passwordListItem.shadowRoot.querySelector('#password').type); - assertTrue(passwordListItem.shadowRoot.querySelector('#password').disabled); - assertTrue(passwordListItem.shadowRoot.querySelector('#showPasswordButton') - .classList.contains('icon-visibility')); + 'password', + passwordListItem.shadowRoot!.querySelector<HTMLInputElement>( + '#password')!.type); + assertTrue( + passwordListItem.shadowRoot!.querySelector<HTMLInputElement>( + '#password')!.disabled); + assertTrue( + passwordListItem.shadowRoot! + .querySelector<HTMLElement>( + '#showPasswordButton')!.classList.contains('icon-visibility')); } /** * Simulates user who is eligible and opted-in for account storage. Should be * called after the PasswordsSection element is created. - * @param {TestPasswordManagerProxy} passwordManager */ -function simulateAccountStorageUser(passwordManager) { - simulateSyncStatus({signedIn: false}); +function simulateAccountStorageUser(passwordManager: TestPasswordManagerProxy) { + simulateSyncStatus({signedIn: false, statusAction: StatusAction.NO_ACTION}); simulateStoredAccounts([{email: 'john@gmail.com'}]); passwordManager.setIsOptedInForAccountStorageAndNotify(true); @@ -242,20 +252,16 @@ // TODO(crbug.com/1260310): Split into multiple test suits. suite('PasswordsSection', function() { - /** @type {TestPasswordManagerProxy} */ - let passwordManager = null; + let passwordManager: TestPasswordManagerProxy; - /** @type {PasswordSectionElementFactory} */ - let elementFactory = null; + let elementFactory: PasswordSectionElementFactory; - /** @type {TestPluralStringProxy} */ - let pluralString = null; + let pluralString: TestPluralStringProxy; - /** @type {TestHatsBrowserProxy} */ - let testHatsBrowserProxy = null; + let testHatsBrowserProxy: TestHatsBrowserProxy; setup(function() { - PolymerTest.clearBody(); + document.body.innerHTML = ''; // Override the PasswordManagerImpl for testing. passwordManager = new TestPasswordManagerProxy(); pluralString = new TestPluralStringProxy(); @@ -280,12 +286,12 @@ document.body.appendChild(element); assertFalse( - !!element.shadowRoot.querySelector('#passwordsExtensionIndicator')); + !!element.shadowRoot!.querySelector('#passwordsExtensionIndicator')); element.set('prefs.credentials_enable_service.extensionId', 'test-id'); flush(); assertTrue( - !!element.shadowRoot.querySelector('#passwordsExtensionIndicator')); + !!element.shadowRoot!.querySelector('#passwordsExtensionIndicator')); }); test('verifyNoSavedPasswords', function() { @@ -378,8 +384,8 @@ validatePasswordList(passwordsSection, passwordList); // Simulate 'longwebsite.com' being removed from the list. passwordList.splice(1, 1); - passwordManager.lastCallback.addSavedPasswordListChangedListener( - passwordList); + passwordManager.lastCallback.addSavedPasswordListChangedListener! + (passwordList); flush(); assertFalse( @@ -404,41 +410,40 @@ passwordManager, passwordList, []); const passwordListItems = - passwordsSection.root.querySelectorAll('password-list-item'); + passwordsSection.shadowRoot!.querySelectorAll('password-list-item'); assertEquals(2, passwordListItems.length); - passwordListItems[0] - .shadowRoot.querySelector('#showPasswordButton') - .click(); + passwordListItems[0]!.shadowRoot! + .querySelector<HTMLElement>('#showPasswordButton')!.click(); flush(); await passwordManager.whenCalled('requestPlaintextPassword'); passwordManager.resetResolver('requestPlaintextPassword'); flush(); - passwordListItems[1] - .shadowRoot.querySelector('#showPasswordButton') - .click(); + passwordListItems[1]!.shadowRoot! + .querySelector<HTMLElement>('#showPasswordButton')!.click(); await passwordManager.whenCalled('requestPlaintextPassword'); flush(); assertEquals( 'text', - passwordListItems[0].shadowRoot.querySelector('#password').type); + passwordListItems[0]!.shadowRoot! + .querySelector<HTMLInputElement>('#password')!.type); assertEquals( 'text', - passwordListItems[1].shadowRoot.querySelector('#password').type); + passwordListItems[1]!.shadowRoot! + .querySelector<HTMLInputElement>('#password')!.type); // Remove first row and verify that the remaining password is hidden. passwordList.splice(0, 1); - passwordManager.lastCallback.addSavedPasswordListChangedListener( - passwordList); + passwordManager.lastCallback.addSavedPasswordListChangedListener! + (passwordList); flush(); assertEquals('', getFirstPasswordListItem(passwordsSection).entry.password); assertEquals( 'password', getFirstPasswordListItem(passwordsSection) - .shadowRoot.querySelector('#password') - .type); + .shadowRoot!.querySelector<HTMLInputElement>('#password')!.type); assertEquals( 'user1', getFirstPasswordListItem(passwordsSection).entry.username); }); @@ -463,8 +468,8 @@ [createMultiStorePasswordEntry({accountId: 0, deviceId: 1})]); // Simulate account copy being removed from the list. passwordList.splice(0, 1); - passwordManager.lastCallback.addSavedPasswordListChangedListener( - passwordList); + passwordManager.lastCallback.addSavedPasswordListChangedListener! + (passwordList); flush(); validateMultiStorePasswordList( @@ -487,8 +492,8 @@ [createMultiStorePasswordEntry({accountId: 0, deviceId: 1})]); // Simulate device copy being removed from the list. passwordList.splice(1, 1); - passwordManager.lastCallback.addSavedPasswordListChangedListener( - passwordList); + passwordManager.lastCallback.addSavedPasswordListChangedListener! + (passwordList); flush(); validateMultiStorePasswordList( @@ -511,8 +516,8 @@ [createMultiStorePasswordEntry({accountId: 0, deviceId: 1})]); // Simulate both copies being removed from the list. passwordList.splice(0, 2); - passwordManager.lastCallback.addSavedPasswordListChangedListener( - passwordList); + passwordManager.lastCallback.addSavedPasswordListChangedListener! + (passwordList); flush(); validateMultiStorePasswordList(passwordsSection, []); @@ -533,8 +538,8 @@ // Simulate 'website.com' being added to the list. passwordList.unshift( createPasswordEntry({url: 'website.com', username: 'mario', id: 2})); - passwordManager.lastCallback.addSavedPasswordListChangedListener( - passwordList); + passwordManager.lastCallback.addSavedPasswordListChangedListener! + (passwordList); flush(); validatePasswordList(passwordsSection, passwordList); @@ -555,8 +560,8 @@ passwordList.unshift( createPasswordEntry({frontendId: 0, fromAccountStore: true, id: 1})); - passwordManager.lastCallback.addSavedPasswordListChangedListener( - passwordList); + passwordManager.lastCallback.addSavedPasswordListChangedListener! + (passwordList); flush(); validateMultiStorePasswordList( @@ -579,8 +584,8 @@ passwordList.unshift( createPasswordEntry({frontendId: 0, fromAccountStore: false, id: 1})); - passwordManager.lastCallback.addSavedPasswordListChangedListener( - passwordList); + passwordManager.lastCallback.addSavedPasswordListChangedListener! + (passwordList); flush(); validateMultiStorePasswordList( @@ -600,22 +605,22 @@ createPasswordEntry({url: 'website.com', username: 'luigi', id: 1}) ]; - passwordManager.lastCallback.addSavedPasswordListChangedListener( - passwordList); + passwordManager.lastCallback.addSavedPasswordListChangedListener! + (passwordList); flush(); validatePasswordList(passwordsSection, passwordList); // Simulate '(website.com, mario)' being removed from the list. passwordList.shift(); - passwordManager.lastCallback.addSavedPasswordListChangedListener( - passwordList); + passwordManager.lastCallback.addSavedPasswordListChangedListener! + (passwordList); flush(); validatePasswordList(passwordsSection, passwordList); // Simulate '(website.com, luigi)' being removed from the list as well. passwordList = []; - passwordManager.lastCallback.addSavedPasswordListChangedListener( - passwordList); + passwordManager.lastCallback.addSavedPasswordListChangedListener! + (passwordList); flush(); validatePasswordList(passwordsSection, passwordList); }); @@ -637,7 +642,7 @@ const firstNode = getFirstPasswordListItem(passwordsSection); assertTrue(!!firstNode); - const firstPassword = passwordList[0]; + const firstPassword = passwordList[0]!; // Click the remove button on the first password. firstNode.$.moreActionsButton.click(); @@ -664,9 +669,8 @@ getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click(); flush(); - assertTrue(passwordsSection.$.passwordsListHandler.shadowRoot - .querySelector('#menuCopyPassword') - .hidden); + assertTrue( + passwordsSection.$.passwordsListHandler.$.menuCopyPassword.hidden); }); // Test verifies that 'Copy password' button is not hidden for common @@ -680,9 +684,8 @@ getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click(); flush(); - assertFalse(passwordsSection.$.passwordsListHandler.shadowRoot - .querySelector('#menuCopyPassword') - .hidden); + assertFalse( + passwordsSection.$.passwordsListHandler.$.menuCopyPassword.hidden); }); // Test verifies that 'Edit' button is replaced to 'Details' for Federated @@ -698,30 +701,27 @@ flush(); assertEquals( passwordsSection.i18n('passwordViewDetails'), - passwordsSection.$.passwordsListHandler.shadowRoot - .querySelector('#menuEditPassword') - .textContent.trim()); + passwordsSection.$.passwordsListHandler.$.menuEditPassword.textContent! + .trim()); }); // Test verifies that 'Edit' button is replaced to 'Details' for Federated // (passwordless) credentials. // Does not test Details and Edit button. - test( - 'verifyDetailsForFederatedPasswordInMenu', function() { - const passwordList = [ - createPasswordEntry({federationText: 'with chromium.org'}), - ]; - const passwordsSection = elementFactory.createPasswordsSection( - passwordManager, passwordList, []); + test('verifyDetailsForFederatedPasswordInMenu', function() { + const passwordList = [ + createPasswordEntry({federationText: 'with chromium.org'}), + ]; + const passwordsSection = elementFactory.createPasswordsSection( + passwordManager, passwordList, []); - getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click(); - flush(); - assertEquals( - passwordsSection.i18n('passwordViewDetails'), - passwordsSection.$.passwordsListHandler.shadowRoot - .querySelector('#menuEditPassword') - .textContent.trim()); - }); + getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click(); + flush(); + assertEquals( + passwordsSection.i18n('passwordViewDetails'), + passwordsSection.$.passwordsListHandler.$.menuEditPassword.textContent! + .trim()); + }); // Test verifies that 'Edit' button is shown instead of 'Details' for // common credentials. @@ -737,9 +737,8 @@ flush(); assertEquals( passwordsSection.i18n('editPassword'), - passwordsSection.$.passwordsListHandler.shadowRoot - .querySelector('#menuEditPassword') - .textContent.trim()); + passwordsSection.$.passwordsListHandler.$.menuEditPassword.textContent! + .trim()); }); test('verifyFilterPasswords', function() { @@ -801,8 +800,8 @@ createPasswordEntry({url: 'six-show.com', username: 'one', id: 5}), ]; - passwordManager.lastCallback.addSavedPasswordListChangedListener( - passwordList); + passwordManager.lastCallback.addSavedPasswordListChangedListener! + (passwordList); flush(); validatePasswordList(passwordsSection, expectedList); }); @@ -965,23 +964,25 @@ let item = 0; const clickRemoveButton = function() { - exceptions[item].querySelector('#removeExceptionButton').click(); + exceptions[item]!.querySelector<HTMLElement>( + '#removeExceptionButton')!.click(); }; // Removes the next exception item, verifies that the expected method was // called on |passwordManager| and continues recursively until no more items // exist. - function removeNextRecursive() { + function removeNextRecursive(): Promise<void> { passwordManager.resetResolver('removeExceptions'); clickRemoveButton(); return passwordManager.whenCalled('removeExceptions').then(ids => { // Verify that the event matches the expected value. assertTrue(item < exceptionList.length); - assertDeepEquals(ids, [exceptionList[item].id]); + assertDeepEquals(ids, [exceptionList[item]!.id]); if (++item < exceptionList.length) { return removeNextRecursive(); } + return Promise.resolve(); }); } @@ -1003,7 +1004,7 @@ const [mergedEntry] = getDomRepeatChildren(passwordsSection.$.passwordExceptionsList); - mergedEntry.querySelector('#removeExceptionButton').click(); + mergedEntry!.querySelector<HTMLElement>('#removeExceptionButton')!.click(); // Verify both ids get passed to the proxy. const ids = await passwordManager.whenCalled('removeExceptions'); @@ -1019,9 +1020,11 @@ const passwordListItem = elementFactory.createPasswordListItem(item); // Hidden passwords should be disabled. - assertTrue(passwordListItem.shadowRoot.querySelector('#password').disabled); + assertTrue(passwordListItem.shadowRoot! + .querySelector<HTMLInputElement>('#password')!.disabled); - passwordListItem.shadowRoot.querySelector('#showPasswordButton').click(); + passwordListItem.shadowRoot! + .querySelector<HTMLElement>('#showPasswordButton')!.click(); const {id, reason} = await passwordManager.whenCalled('requestPlaintextPassword'); flush(); @@ -1029,28 +1032,38 @@ assertEquals('VIEW', reason); assertEquals( - PASSWORD, passwordListItem.shadowRoot.querySelector('#password').value); + PASSWORD, + passwordListItem.shadowRoot! + .querySelector<HTMLInputElement>('#password')!.value); // Password should be visible. assertEquals( - 'text', passwordListItem.shadowRoot.querySelector('#password').type); + 'text', + passwordListItem.shadowRoot! + .querySelector<HTMLInputElement>('#password')!.type); // Visible passwords should not be disabled. - assertFalse( - passwordListItem.shadowRoot.querySelector('#password').disabled); + assertFalse(passwordListItem.shadowRoot! + .querySelector<HTMLInputElement>('#password')!.disabled); // Hide Password Button should be shown. - assertTrue(passwordListItem.shadowRoot.querySelector('#showPasswordButton') - .classList.contains('icon-visibility-off')); + assertTrue(passwordListItem.shadowRoot! + .querySelector<HTMLElement>('#showPasswordButton')!.classList + .contains('icon-visibility-off')); // Hide the Password again. - passwordListItem.shadowRoot.querySelector('#showPasswordButton').click(); + passwordListItem.shadowRoot! + .querySelector<HTMLElement>('#showPasswordButton')!.click(); flush(); assertEquals( 'password', - passwordListItem.shadowRoot.querySelector('#password').type); - assertTrue(passwordListItem.shadowRoot.querySelector('#password').disabled); - assertTrue(passwordListItem.shadowRoot.querySelector('#showPasswordButton') - .classList.contains('icon-visibility')); + passwordListItem.shadowRoot! + .querySelector<HTMLInputElement>('#password')!.type); + assertTrue(passwordListItem.shadowRoot! + .querySelector<HTMLInputElement>('#password')!.disabled); + assertTrue( + passwordListItem.shadowRoot! + .querySelector<HTMLElement>( + '#showPasswordButton')!.classList.contains('icon-visibility')); }); test('showPasswordOpensViewDialogWhenNotesEnabled', async function() { @@ -1062,7 +1075,8 @@ const passwordSection = elementFactory.createPasswordsSection(passwordManager, [item], []); const passwordListItem = getFirstPasswordListItem(passwordSection); - passwordListItem.shadowRoot.querySelector('#showPasswordButton').click(); + passwordListItem.shadowRoot! + .querySelector<HTMLElement>('#showPasswordButton')!.click(); const {id, reason} = await passwordManager.whenCalled('requestPlaintextPassword'); flush(); @@ -1073,27 +1087,29 @@ assertEquals( 'password', - passwordListItem.shadowRoot.querySelector('#password').type); - assertTrue(passwordListItem.shadowRoot.querySelector('#password').disabled); + passwordListItem.shadowRoot! + .querySelector<HTMLInputElement>('#password')!.type); + assertTrue(passwordListItem.shadowRoot! + .querySelector<HTMLInputElement>('#password')!.disabled); - assertFalse(!!passwordListItem.shadowRoot.querySelector( + assertFalse(!!passwordListItem.shadowRoot!.querySelector( '#showPasswordButton.icon-visibility-off')); const passwordEditDialog = - passwordSection.$.passwordsListHandler.shadowRoot.querySelector( - '#passwordEditDialog'); + passwordSection.$.passwordsListHandler.shadowRoot!.querySelector( + 'password-edit-dialog')!; assertEquals( PasswordDialogMode.PASSWORD_VIEW, passwordEditDialog.dialogMode); assertEquals( - item.urls.shown, passwordEditDialog.$.title.textContent.trim()); + item.urls.shown, passwordEditDialog.$.title.textContent!.trim()); assertEquals('text', passwordEditDialog.$.passwordInput.type); assertEquals(PASSWORD, passwordEditDialog.$.passwordInput.value); - assertTrue( - passwordEditDialog.shadowRoot.querySelector('#showPasswordButton') - .classList.contains('icon-visibility-off')); + assertTrue(passwordEditDialog.shadowRoot! + .querySelector<HTMLElement>('#showPasswordButton')!.classList + .contains('icon-visibility-off')); }); // Tests that pressing 'Edit password' sets the corresponding password. @@ -1116,13 +1132,14 @@ assertEquals('EDIT', reason); const passwordEditDialog = - passwordSection.$.passwordsListHandler.shadowRoot.querySelector( - '#passwordEditDialog'); + passwordSection.$.passwordsListHandler.shadowRoot!.querySelector( + 'password-edit-dialog')!; assertEquals('password', passwordEditDialog.$.passwordInput.type); assertEquals(PASSWORD, passwordEditDialog.$.passwordInput.value); assertTrue( - passwordEditDialog.shadowRoot.querySelector('#showPasswordButton') - .classList.contains('icon-visibility')); + passwordEditDialog.shadowRoot! + .querySelector<HTMLElement>( + '#showPasswordButton')!.classList.contains('icon-visibility')); }); test('onShowSavedPasswordListItem', function() { @@ -1133,7 +1150,8 @@ assertEquals('', passwordListItem.entry.password); passwordManager.setPlaintextPassword('password'); - passwordListItem.shadowRoot.querySelector('#showPasswordButton').click(); + passwordListItem.shadowRoot! + .querySelector<HTMLElement>('#showPasswordButton')!.click(); return passwordManager.whenCalled('requestPlaintextPassword') .then(({id, reason}) => { assertEquals(1, id); @@ -1149,9 +1167,7 @@ passwordManager, [expectedItem], []); getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click(); - passwordsSection.$.passwordsListHandler.shadowRoot - .querySelector('#menuCopyPassword') - .click(); + passwordsSection.$.passwordsListHandler.$.menuCopyPassword.click(); return passwordManager.whenCalled('requestPlaintextPassword') .then(({id, reason}) => { @@ -1167,9 +1183,7 @@ passwordManager, [expectedItem], []); getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click(); - passwordsSection.$.passwordsListHandler.shadowRoot - .querySelector('#menuEditPassword') - .click(); + passwordsSection.$.passwordsListHandler.$.menuEditPassword.click(); return passwordManager.whenCalled('requestPlaintextPassword') .then(({id, reason}) => { @@ -1198,8 +1212,8 @@ flush(); const passwordEditDialog = - passwordsSection.$.passwordsListHandler.shadowRoot.querySelector( - '#passwordEditDialog'); + passwordsSection.$.passwordsListHandler.shadowRoot!.querySelector( + 'password-edit-dialog')!; assertEquals(PasswordDialogMode.EDIT, passwordEditDialog.dialogMode); }); @@ -1240,7 +1254,7 @@ // Chrome shouldn't offer the option to export passwords if there are no // passwords. test('noExportIfNoPasswords', function() { - const passwordList = []; + const passwordList: chrome.passwordsPrivate.PasswordUiEntry[] = []; const passwordsSection = elementFactory.createPasswordsSection( passwordManager, passwordList, []); @@ -1335,8 +1349,11 @@ elementFactory.createPasswordsSection(passwordManager, [], []); // Sync is disabled and the user is initially signed out. - simulateSyncStatus({signedIn: false}); - const isDisplayed = element => !!element && !element.hidden; + simulateSyncStatus( + {signedIn: false, statusAction: StatusAction.NO_ACTION}); + function isDisplayed(element: HTMLElement): boolean { + return !!element && !element.hidden; + } assertFalse( isDisplayed(passwordsSection.$.accountStorageButtonsContainer)); @@ -1374,7 +1391,8 @@ const passwordsSection = elementFactory.createPasswordsSection(passwordManager, [], []); - simulateSyncStatus({signedIn: false}); + simulateSyncStatus( + {signedIn: false, statusAction: StatusAction.NO_ACTION}); simulateStoredAccounts([{email: 'john@gmail.com'}]); // Simulate custom passphrase. const syncPrefs = getSyncAllPrefs(); @@ -1394,12 +1412,15 @@ elementFactory.createPasswordsSection(passwordManager, [], []); simulateAccountStorageUser(passwordManager); - const isDisplayed = element => !!element && !element.hidden; + function isDisplayed(element: HTMLElement): boolean { + return element && !element.hidden; + } assertTrue( isDisplayed(passwordsSection.$.accountStorageButtonsContainer)); // Enable sync. - simulateSyncStatus({signedIn: true}); + simulateSyncStatus( + {signedIn: true, statusAction: StatusAction.NO_ACTION}); assertFalse( isDisplayed(passwordsSection.$.accountStorageButtonsContainer)); }); @@ -1413,7 +1434,8 @@ [createPasswordEntry({fromAccountStore: true, id: 10})]; const passwordsSection = elementFactory.createPasswordsSection( passwordManager, passwordList, []); - simulateSyncStatus({signedIn: false}); + simulateSyncStatus( + {signedIn: false, statusAction: StatusAction.NO_ACTION}); simulateStoredAccounts([{email: 'john@gmail.com'}]); assertTrue(passwordsSection.$.devicePasswordsLink.hidden); @@ -1426,8 +1448,8 @@ // Add a device password. The button shows up. passwordList.unshift( createPasswordEntry({fromAccountStore: false, id: 20})); - passwordManager.lastCallback.addSavedPasswordListChangedListener( - passwordList); + passwordManager.lastCallback.addSavedPasswordListChangedListener! + (passwordList); flush(); assertFalse(passwordsSection.$.devicePasswordsLink.hidden); }); @@ -1451,8 +1473,9 @@ // No removal actually happens, so all passwords keep their position. const passwordListItems = - passwordsSection.root.querySelectorAll('password-list-item'); - passwordListItems[0].$.moreActionsButton.click(); + passwordsSection.shadowRoot!.querySelectorAll( + 'password-list-item'); + passwordListItems[0]!.$.moreActionsButton.click(); passwordsSection.$.passwordsListHandler.$.menuRemovePassword.click(); flush(); assertEquals( @@ -1460,7 +1483,7 @@ passwordsSection.$.passwordsListHandler.$.removalNotification .textContent); - passwordListItems[1].$.moreActionsButton.click(); + passwordListItems[1]!.$.moreActionsButton.click(); passwordsSection.$.passwordsListHandler.$.menuRemovePassword.click(); flush(); assertEquals( @@ -1485,16 +1508,16 @@ // At first the dialog is not shown. assertTrue( - !passwordsSection.$.passwordsListHandler.shadowRoot.querySelector( - '#passwordRemoveDialog')); + !passwordsSection.$.passwordsListHandler.shadowRoot!.querySelector( + 'password-remove-dialog')); // Clicking remove in the overflow menu shows the dialog. getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click(); passwordsSection.$.passwordsListHandler.$.menuRemovePassword.click(); flush(); const removeDialog = - passwordsSection.$.passwordsListHandler.shadowRoot.querySelector( - '#passwordRemoveDialog'); + passwordsSection.$.passwordsListHandler.shadowRoot!.querySelector( + 'password-remove-dialog'); assertTrue(!!removeDialog); // Both checkboxes are selected by default. Confirming removes from both @@ -1524,7 +1547,7 @@ // At first the dialog is not shown. assertTrue( - !passwordsSection.$.passwordsListHandler.shadowRoot.querySelector( + !passwordsSection.$.passwordsListHandler.shadowRoot!.querySelector( '#passwordRemoveDialog')); // Clicking remove in the overflow menu shows the dialog. @@ -1532,8 +1555,8 @@ passwordsSection.$.passwordsListHandler.$.menuRemovePassword.click(); flush(); const removeDialog = - passwordsSection.$.passwordsListHandler.shadowRoot.querySelector( - '#passwordRemoveDialog'); + passwordsSection.$.passwordsListHandler.shadowRoot!.querySelector( + 'password-remove-dialog'); assertTrue(!!removeDialog); // Uncheck the account checkboxes then confirm. Only the device copy is @@ -1555,17 +1578,20 @@ const exportDialog = elementFactory.createExportPasswordsDialog(passwordManager); - assertTrue(exportDialog.shadowRoot.querySelector('#dialog_start').open); - exportDialog.shadowRoot.querySelector('#cancelButton').click(); + assertTrue(exportDialog.shadowRoot! + .querySelector<CrDialogElement>('#dialog_start')!.open); + exportDialog.shadowRoot!.querySelector<HTMLElement>( + '#cancelButton')!.click(); flush(); - assertFalse(!!exportDialog.shadowRoot.querySelector('#dialog_start')); + assertFalse(!!exportDialog.shadowRoot!.querySelector('#dialog_start')); }); test('fires close event when canceled', () => { const exportDialog = elementFactory.createExportPasswordsDialog(passwordManager); const wait = eventToPromise('passwords-export-dialog-close', exportDialog); - exportDialog.shadowRoot.querySelector('#cancelButton').click(); + exportDialog.shadowRoot!.querySelector<HTMLElement>( + '#cancelButton')!.click(); return wait; }); @@ -1575,7 +1601,7 @@ const syncPrefs = getSyncAllPrefs(); syncPrefs.encryptAllData = true; webUIListenerCallback('sync-prefs-changed', syncPrefs); - simulateSyncStatus({signedIn: true}); + simulateSyncStatus({signedIn: true, statusAction: StatusAction.NO_ACTION}); flush(); assertTrue(passwordsSection.$.manageLink.hidden); }); @@ -1601,7 +1627,7 @@ const passwordsSection = elementFactory.createPasswordsSection(passwordManager, [], []); const syncPrefs = getSyncAllPrefs(); - simulateSyncStatus({signedIn: false}); + simulateSyncStatus({signedIn: false, statusAction: StatusAction.NO_ACTION}); webUIListenerCallback('sync-prefs-changed', syncPrefs); flush(); assertFalse(passwordsSection.$.manageLink.hidden); @@ -1622,15 +1648,9 @@ passwordManager, passwordList, []); return passwordManager.whenCalled('getPasswordCheckStatus').then(() => { flush(); - assertFalse(passwordsSection.shadowRoot - .querySelector('#checkPasswordsBannerContainer') - .hidden); - assertFalse(passwordsSection.shadowRoot - .querySelector('#checkPasswordsButtonRow') - .hidden); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordsLinkRow') - .hidden); + assertFalse(passwordsSection.$.checkPasswordsBannerContainer.hidden); + assertFalse(passwordsSection.$.checkPasswordsButtonRow.hidden); + assertTrue(passwordsSection.$.checkPasswordsLinkRow.hidden); }); }); @@ -1648,7 +1668,9 @@ ]; passwordManager.data.checkStatus.state = PasswordCheckState.CANCELED; passwordManager.data.leakedCredentials = [ - makeCompromisedCredential('site1.com', 'luigi', 'LEAKED'), + makeCompromisedCredential( + 'site1.com', 'luigi', + chrome.passwordsPrivate.CompromiseType.LEAKED), ]; pluralString.text = '1 compromised password'; @@ -1659,19 +1681,14 @@ await pluralString.whenCalled('getPluralString'); flush(); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordsBannerContainer') - .hidden); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordsButtonRow') - .hidden); - assertFalse( - passwordsSection.shadowRoot.querySelector('#checkPasswordsLinkRow') - .hidden); + assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden); + assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden); + assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden); assertEquals( pluralString.text, - passwordsSection.shadowRoot.querySelector('#checkPasswordLeakCount') - .innerText.trim()); + passwordsSection.shadowRoot! + .querySelector<HTMLElement>( + '#checkPasswordLeakCount')!.innerText!.trim()); }); test('showPasswordCheckLinkButtonWithoutWarningWhenNotSignedIn', function() { @@ -1684,18 +1701,12 @@ ]; const passwordsSection = elementFactory.createPasswordsSection( passwordManager, passwordList, []); - simulateSyncStatus({signedIn: false}); + simulateSyncStatus({signedIn: false, statusAction: StatusAction.NO_ACTION}); return passwordManager.whenCalled('getPasswordCheckStatus').then(() => { flush(); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordsBannerContainer') - .hidden); - assertTrue( - passwordsSection.shadowRoot.querySelector('#checkPasswordsButtonRow') - .hidden); - assertFalse( - passwordsSection.shadowRoot.querySelector('#checkPasswordsLinkRow') - .hidden); + assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden); + assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden); + assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden); }); }); @@ -1708,15 +1719,9 @@ elementFactory.createPasswordsSection(passwordManager, [], []); return passwordManager.whenCalled('getPasswordCheckStatus').then(() => { flush(); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordsBannerContainer') - .hidden); - assertTrue( - passwordsSection.shadowRoot.querySelector('#checkPasswordsButtonRow') - .hidden); - assertFalse( - passwordsSection.shadowRoot.querySelector('#checkPasswordsLinkRow') - .hidden); + assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden); + assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden); + assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden); }); }); @@ -1734,24 +1739,12 @@ passwordManager, passwordList, []); return passwordManager.whenCalled('getPasswordCheckStatus').then(() => { flush(); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordsBannerContainer') - .hidden); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordsButtonRow') - .hidden); - assertFalse(passwordsSection.shadowRoot - .querySelector('#checkPasswordsLinkRow') - .hidden); - assertFalse(passwordsSection.shadowRoot - .querySelector('#checkPasswordLeakDescription') - .hidden); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordWarningIcon') - .hidden); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordLeakCount') - .hidden); + assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden); + assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden); + assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden); + assertFalse(passwordsSection.$.checkPasswordLeakDescription.hidden); + assertTrue(passwordsSection.$.checkPasswordWarningIcon.hidden); + assertTrue(passwordsSection.$.checkPasswordLeakCount.hidden); }); }); @@ -1760,8 +1753,12 @@ function() { // Suppose no leaks initially, non-empty list of passwords, signed in. passwordManager.data.leakedCredentials = [ - makeCompromisedCredential('one.com', 'test4', 'LEAKED'), - makeCompromisedCredential('two.com', 'test3', 'PHISHED'), + makeCompromisedCredential( + 'one.com', 'test4', + chrome.passwordsPrivate.CompromiseType.LEAKED), + makeCompromisedCredential( + 'two.com', 'test3', + chrome.passwordsPrivate.CompromiseType.PHISHED), ]; passwordManager.data.checkStatus.elapsedTimeSinceLastCheck = '5 min ago'; @@ -1772,24 +1769,12 @@ passwordManager, passwordList, []); return passwordManager.whenCalled('getPasswordCheckStatus').then(() => { flush(); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordsBannerContainer') - .hidden); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordsButtonRow') - .hidden); - assertFalse(passwordsSection.shadowRoot - .querySelector('#checkPasswordsLinkRow') - .hidden); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordLeakDescription') - .hidden); - assertFalse(passwordsSection.shadowRoot - .querySelector('#checkPasswordWarningIcon') - .hidden); - assertFalse(passwordsSection.shadowRoot - .querySelector('#checkPasswordLeakCount') - .hidden); + assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden); + assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden); + assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden); + assertTrue(passwordsSection.$.checkPasswordLeakDescription.hidden); + assertFalse(passwordsSection.$.checkPasswordWarningIcon.hidden); + assertFalse(passwordsSection.$.checkPasswordLeakCount.hidden); }); }); @@ -1808,60 +1793,38 @@ passwordManager, passwordList, []); return passwordManager.whenCalled('getPasswordCheckStatus').then(() => { flush(); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordsBannerContainer') - .hidden); - assertTrue( - passwordsSection.shadowRoot.querySelector('#checkPasswordsButtonRow') - .hidden); - assertFalse( - passwordsSection.shadowRoot.querySelector('#checkPasswordsLinkRow') - .hidden); - assertFalse(passwordsSection.shadowRoot - .querySelector('#checkPasswordLeakDescription') - .hidden); - assertTrue( - passwordsSection.shadowRoot.querySelector('#checkPasswordWarningIcon') - .hidden); - assertTrue( - passwordsSection.shadowRoot.querySelector('#checkPasswordLeakCount') - .hidden); + assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden); + assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden); + assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden); + assertFalse(passwordsSection.$.checkPasswordLeakDescription.hidden); + assertTrue(passwordsSection.$.checkPasswordWarningIcon.hidden); + assertTrue(passwordsSection.$.checkPasswordLeakCount.hidden); // Suppose two newly detected leaks come in. const leakedCredentials = [ - makeCompromisedCredential('one.com', 'test4', 'LEAKED'), - makeCompromisedCredential('two.com', 'test3', 'PHISHED'), + makeCompromisedCredential( + 'one.com', 'test4', chrome.passwordsPrivate.CompromiseType.LEAKED), + makeCompromisedCredential( + 'two.com', 'test3', chrome.passwordsPrivate.CompromiseType.PHISHED), ]; const elapsedTimeSinceLastCheck = 'just now'; passwordManager.data.leakedCredentials = leakedCredentials; passwordManager.data.checkStatus.elapsedTimeSinceLastCheck = elapsedTimeSinceLastCheck; - passwordManager.lastCallback.addCompromisedCredentialsListener( - leakedCredentials); - passwordManager.lastCallback.addPasswordCheckStatusListener( - makePasswordCheckStatus( + passwordManager.lastCallback.addCompromisedCredentialsListener! + (leakedCredentials); + passwordManager.lastCallback.addPasswordCheckStatusListener! + (makePasswordCheckStatus( /*state=*/ PasswordCheckState.RUNNING, /*checked=*/ 2, /*remaining=*/ 0, /*elapsedTime=*/ elapsedTimeSinceLastCheck)); flush(); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordsBannerContainer') - .hidden); - assertTrue( - passwordsSection.shadowRoot.querySelector('#checkPasswordsButtonRow') - .hidden); - assertFalse( - passwordsSection.shadowRoot.querySelector('#checkPasswordsLinkRow') - .hidden); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordLeakDescription') - .hidden); - assertFalse( - passwordsSection.shadowRoot.querySelector('#checkPasswordWarningIcon') - .hidden); - assertFalse( - passwordsSection.shadowRoot.querySelector('#checkPasswordLeakCount') - .hidden); + assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden); + assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden); + assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden); + assertTrue(passwordsSection.$.checkPasswordLeakDescription.hidden); + assertFalse(passwordsSection.$.checkPasswordWarningIcon.hidden); + assertFalse(passwordsSection.$.checkPasswordLeakCount.hidden); }); }); @@ -1876,33 +1839,23 @@ passwordManager, passwordList, []); return passwordManager.whenCalled('getPasswordCheckStatus').then(() => { flush(); - assertFalse(passwordsSection.shadowRoot - .querySelector('#checkPasswordsBannerContainer') - .hidden); - assertFalse( - passwordsSection.shadowRoot.querySelector('#checkPasswordsButtonRow') - .hidden); - assertTrue( - passwordsSection.shadowRoot.querySelector('#checkPasswordsLinkRow') - .hidden); + assertFalse(passwordsSection.$.checkPasswordsBannerContainer.hidden); + assertFalse(passwordsSection.$.checkPasswordsButtonRow.hidden); + assertTrue(passwordsSection.$.checkPasswordsLinkRow.hidden); - simulateSyncStatus({signedIn: false}); - assertTrue(passwordsSection.shadowRoot - .querySelector('#checkPasswordsBannerContainer') - .hidden); - assertTrue( - passwordsSection.shadowRoot.querySelector('#checkPasswordsButtonRow') - .hidden); - assertFalse( - passwordsSection.shadowRoot.querySelector('#checkPasswordsLinkRow') - .hidden); + simulateSyncStatus( + {signedIn: false, statusAction: StatusAction.NO_ACTION}); + assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden); + assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden); + assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden); }); }); test('clickingCheckPasswordsButtonStartsCheck', async function() { const passwordsSection = elementFactory.createPasswordsSection(passwordManager, [], []); - passwordsSection.shadowRoot.querySelector('#checkPasswordsButton').click(); + passwordsSection.shadowRoot! + .querySelector<HTMLElement>('#checkPasswordsButton')!.click(); flush(); const router = Router.getInstance(); assertEquals(routes.CHECK_PASSWORDS, router.currentRoute); @@ -1915,7 +1868,8 @@ test('clickingCheckPasswordsRowStartsCheck', async function() { const passwordsSection = elementFactory.createPasswordsSection(passwordManager, [], []); - passwordsSection.shadowRoot.querySelector('#checkPasswordsLinkRow').click(); + passwordsSection.shadowRoot! + .querySelector<HTMLElement>('#checkPasswordsLinkRow')!.click(); flush(); const router = Router.getInstance(); assertEquals(routes.CHECK_PASSWORDS, router.currentRoute); @@ -1926,8 +1880,7 @@ }); test('hatsInformedOnOpen', async function() { - const passwordsSection = - elementFactory.createPasswordsSection(passwordManager, [], []); + elementFactory.createPasswordsSection(passwordManager, [], []); const interaction = await testHatsBrowserProxy.whenCalled('trustSafetyInteractionOccurred'); assertEquals(TrustSafetyInteraction.OPENED_PASSWORD_MANAGER, interaction); @@ -1940,14 +1893,14 @@ const passwordsSectionAddPasswordsDisabled = elementFactory.createPasswordsSection(passwordManager, [], []); assertFalse( - !!passwordsSectionAddPasswordsDisabled.shadowRoot.querySelector( + !!passwordsSectionAddPasswordsDisabled.shadowRoot!.querySelector( '#addPasswordButton')); loadTimeData.overrideValues({addPasswordsInSettingsEnabled: true}); const passwordsSectionAddPasswordsEnabled = elementFactory.createPasswordsSection(passwordManager, [], []); assertTrue( - !!passwordsSectionAddPasswordsEnabled.shadowRoot.querySelector( + !!passwordsSectionAddPasswordsEnabled.shadowRoot!.querySelector( '#addPasswordButton')); }); @@ -1958,7 +1911,8 @@ const passwordsSection = elementFactory.createPasswordsSection(passwordManager, [], []); const addButton = - passwordsSection.shadowRoot.querySelector('#addPasswordButton'); + passwordsSection.shadowRoot!.querySelector<HTMLElement>( + '#addPasswordButton')!; passwordsSection.set('prefs.credentials_enable_service', { enforcement: chrome.settingsPrivate.Enforcement.ENFORCED, @@ -1976,13 +1930,14 @@ loadTimeData.overrideValues({addPasswordsInSettingsEnabled: true}); const passwordsSection = elementFactory.createPasswordsSection(passwordManager, [], []); - assertFalse( - !!passwordsSection.shadowRoot.querySelector('#addPasswordDialog')); + assertFalse(!!passwordsSection.shadowRoot!.querySelector<HTMLElement>( + '#addPasswordDialog')); - passwordsSection.shadowRoot.querySelector('#addPasswordButton').click(); + passwordsSection.shadowRoot! + .querySelector<HTMLElement>('#addPasswordButton')!.click(); flush(); - const addDialog = - passwordsSection.shadowRoot.querySelector('#addPasswordDialog'); + const addDialog = passwordsSection.shadowRoot!.querySelector<HTMLElement>( + '#addPasswordDialog'); assertTrue(!!addDialog); });
diff --git a/chrome/test/gpu/webgl_infobar_browsertest.cc b/chrome/test/gpu/webgl_infobar_browsertest.cc index f85a9261..62616137 100644 --- a/chrome/test/gpu/webgl_infobar_browsertest.cc +++ b/chrome/test/gpu/webgl_infobar_browsertest.cc
@@ -23,8 +23,6 @@ #include "components/infobars/core/confirm_infobar_delegate.h" #include "components/infobars/core/infobar.h" #include "content/public/browser/gpu_data_manager.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/common/content_paths.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" @@ -69,9 +67,8 @@ return; // Load page and wait for it to load. - content::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::NotificationService::AllSources()); + content::LoadStopObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); ASSERT_TRUE(ui_test_utils::NavigateToURL( browser(), content::GetFileUrlWithQuery( gpu_test_dir_.AppendASCII("webgl.html"), "query=kill")));
diff --git a/chrome/test/views/chrome_views_test_base.cc b/chrome/test/views/chrome_views_test_base.cc index 1cb1d4a..baf1841 100644 --- a/chrome/test/views/chrome_views_test_base.cc +++ b/chrome/test/views/chrome_views_test_base.cc
@@ -7,6 +7,7 @@ #include <memory> #include "build/chromeos_buildflags.h" +#include "chrome/browser/ui/color/chrome_color_mixers.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/test/views/chrome_test_widget.h" #include "content/public/test/browser_task_environment.h" @@ -47,6 +48,9 @@ // base. test_views_delegate()->set_layout_provider( ChromeLayoutProvider::CreateLayoutProvider()); + + ui::ColorProviderManager::Get().AppendColorProviderInitializer( + base::BindRepeating(AddChromeColorMixers)); } #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/tools/build/win/FILES.cfg b/chrome/tools/build/win/FILES.cfg index d8546442..e9d3257 100644 --- a/chrome/tools/build/win/FILES.cfg +++ b/chrome/tools/build/win/FILES.cfg
@@ -558,46 +558,6 @@ 'archive': 'gcp_installer.exe', 'filegroup': ['symsrc'], }, - # Cloud Print files: - { - 'filename': 'gcp_portmon.dll', - 'buildtype': ['official'], - 'archive': 'cloud_print.zip', - 'filegroup': ['symsrc'], - }, - { - 'filename': 'gcp_portmon.dll.pdb', - 'buildtype': ['official'], - 'archive': 'cloud_print.zip', - 'optional': ['official'], - }, - { - 'filename': 'gcp_portmon64.dll', - 'buildtype': ['official'], - 'archive': 'cloud_print.zip', - 'filegroup': ['symsrc'], - }, - { - 'filename': 'gcp_driver.inf', - 'buildtype': ['official'], - 'archive': 'cloud_print.zip', - }, - { - 'filename': 'gcp_driver.gpd', - 'buildtype': ['official'], - 'archive': 'cloud_print.zip', - }, - { - 'filename': 'virtual_driver_setup.exe', - 'buildtype': ['official'], - 'archive': 'cloud_print.zip', - 'filegroup': ['symsrc'], - }, - { - 'filename': 'virtual_driver_setup.exe.pdb', - 'buildtype': ['official'], - 'archive': 'cloud_print.zip', - }, # Test binaries for external QA: { 'filename': 'interactive_ui_tests.exe',
diff --git a/chrome/tools/service_discovery_sniffer/OWNERS b/chrome/tools/service_discovery_sniffer/OWNERS index be0f423b..1967bf5 100644 --- a/chrome/tools/service_discovery_sniffer/OWNERS +++ b/chrome/tools/service_discovery_sniffer/OWNERS
@@ -1 +1 @@ -file://cloud_print/OWNERS +thestig@chromium.org
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn index 4f11cdb..805bae4 100644 --- a/chrome/utility/BUILD.gn +++ b/chrome/utility/BUILD.gn
@@ -175,6 +175,8 @@ "//chromeos/assistant:buildflags", "//chromeos/components/local_search_service:local_search_service", "//chromeos/components/local_search_service/public/mojom", + "//chromeos/components/quick_answers/public/cpp", + "//chromeos/components/quick_answers/public/mojom", "//chromeos/services/tts", "//chromeos/services/tts/public/mojom", ]
diff --git a/chrome/utility/DEPS b/chrome/utility/DEPS index 0ba4d051..a1ff8fab 100644 --- a/chrome/utility/DEPS +++ b/chrome/utility/DEPS
@@ -30,6 +30,7 @@ "+chromeos/assistant/buildflags.h", "+chromeos/components/local_search_service/local_search_service.h", "+chromeos/components/local_search_service/public/mojom", + "+chromeos/components/quick_answers/public", "+chromeos/services/assistant", "+chromeos/services/libassistant/libassistant_service.h", "+chromeos/services/tts",
diff --git a/chrome/utility/services.cc b/chrome/utility/services.cc index da71bb4..97aaeac 100644 --- a/chrome/utility/services.cc +++ b/chrome/utility/services.cc
@@ -110,6 +110,8 @@ #include "chromeos/assistant/buildflags.h" // nogncheck #include "chromeos/components/local_search_service/local_search_service.h" #include "chromeos/components/local_search_service/public/mojom/local_search_service.mojom.h" +#include "chromeos/components/quick_answers/public/cpp/service/spell_check_service.h" +#include "chromeos/components/quick_answers/public/mojom/spell_check.mojom.h" #include "chromeos/services/tts/public/mojom/tts_service.mojom.h" #include "chromeos/services/tts/tts_service.h" @@ -333,6 +335,12 @@ std::move(receiver)); } +auto RunQuickAnswersSpellCheckService( + mojo::PendingReceiver<quick_answers::mojom::SpellCheckService> receiver) { + return std::make_unique<quick_answers::SpellCheckService>( + std::move(receiver)); +} + #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) auto RunAssistantAudioDecoder( mojo::PendingReceiver< @@ -436,6 +444,7 @@ services.Add(RunTtsService); services.Add(RunLocalSearchService); services.Add(RunQuickPairService); + services.Add(RunQuickAnswersSpellCheckService); #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) services.Add(RunAssistantAudioDecoder); services.Add(RunLibassistantService);
diff --git a/chromecast/graphics/accessibility/fullscreen_magnification_controller.cc b/chromecast/graphics/accessibility/fullscreen_magnification_controller.cc index eb8162d..db142f2 100644 --- a/chromecast/graphics/accessibility/fullscreen_magnification_controller.cc +++ b/chromecast/graphics/accessibility/fullscreen_magnification_controller.cc
@@ -102,7 +102,10 @@ this, gesture_provider_client_.get()); } -FullscreenMagnificationController::~FullscreenMagnificationController() {} +FullscreenMagnificationController::~FullscreenMagnificationController() { + // Destroy `gesture_provider_` before `gesture_provider_client_`. + gesture_provider_.reset(); +} void FullscreenMagnificationController::SetEnabled(bool enabled) { if (is_enabled_ == enabled)
diff --git a/chromeos/components/quick_answers/DEPS b/chromeos/components/quick_answers/DEPS index 6a96639..34c2af07 100644 --- a/chromeos/components/quick_answers/DEPS +++ b/chromeos/components/quick_answers/DEPS
@@ -2,6 +2,7 @@ "+ash/public", "+components/language/core/browser", "+services/data_decoder/public", + "+third_party/hunspell", "+ui/base/l10n", "+ui/base/resource/resource_bundle.h", "+ui/color",
diff --git a/chromeos/components/quick_answers/public/cpp/BUILD.gn b/chromeos/components/quick_answers/public/cpp/BUILD.gn index ac7970b..a791fc2ea 100644 --- a/chromeos/components/quick_answers/public/cpp/BUILD.gn +++ b/chromeos/components/quick_answers/public/cpp/BUILD.gn
@@ -8,14 +8,20 @@ "controller/quick_answers_controller.h", "quick_answers_state.cc", "quick_answers_state.h", + "service/spell_check_dictionary.cc", + "service/spell_check_dictionary.h", + "service/spell_check_service.cc", + "service/spell_check_service.h", ] deps = [ "//base", "//chromeos/components/quick_answers/public/cpp:prefs", + "//chromeos/components/quick_answers/public/mojom", "//components/language/core/browser:browser", "//components/pref_registry", "//components/prefs", + "//third_party/hunspell", "//ui/base", "//ui/gfx", ]
diff --git a/chromeos/components/quick_answers/public/cpp/service/spell_check_dictionary.cc b/chromeos/components/quick_answers/public/cpp/service/spell_check_dictionary.cc new file mode 100644 index 0000000..686de11 --- /dev/null +++ b/chromeos/components/quick_answers/public/cpp/service/spell_check_dictionary.cc
@@ -0,0 +1,45 @@ +// Copyright 2022 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 "chromeos/components/quick_answers/public/cpp/service/spell_check_dictionary.h" + +#include "base/files/memory_mapped_file.h" +#include "base/logging.h" +#include "third_party/hunspell/src/hunspell/hunspell.hxx" + +namespace quick_answers { + +SpellCheckDictionary::SpellCheckDictionary() = default; + +SpellCheckDictionary::~SpellCheckDictionary() = default; + +bool SpellCheckDictionary::Initialize(base::File file) { + mapped_dict_file_ = std::make_unique<base::MemoryMappedFile>(); + + if (!mapped_dict_file_->Initialize(std::move(file))) { + LOG(ERROR) << "Failed to mmap dictionary file."; + return false; + } + + if (!hunspell::BDict::Verify( + reinterpret_cast<const char*>(mapped_dict_file_->data()), + mapped_dict_file_->length())) { + LOG(ERROR) << "Failed to verify dictionary file."; + return false; + } + + hunspell_ = std::make_unique<Hunspell>(mapped_dict_file_->data(), + mapped_dict_file_->length()); + + return true; +} + +void SpellCheckDictionary::CheckSpelling(const std::string& word, + CheckSpellingCallback callback) { + DCHECK(hunspell_); + + std::move(callback).Run(hunspell_->spell(word) != 0); +} + +} // namespace quick_answers
diff --git a/chromeos/components/quick_answers/public/cpp/service/spell_check_dictionary.h b/chromeos/components/quick_answers/public/cpp/service/spell_check_dictionary.h new file mode 100644 index 0000000..8c34621 --- /dev/null +++ b/chromeos/components/quick_answers/public/cpp/service/spell_check_dictionary.h
@@ -0,0 +1,44 @@ +// Copyright 2022 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 CHROMEOS_COMPONENTS_QUICK_ANSWERS_PUBLIC_CPP_SERVICE_SPELL_CHECK_DICTIONARY_H_ +#define CHROMEOS_COMPONENTS_QUICK_ANSWERS_PUBLIC_CPP_SERVICE_SPELL_CHECK_DICTIONARY_H_ + +#include <memory> +#include <string> + +#include "base/memory/weak_ptr.h" +#include "chromeos/components/quick_answers/public/mojom/spell_check.mojom.h" + +class Hunspell; + +namespace base { +class MemoryMappedFile; +} // namespace base + +namespace quick_answers { + +// Utility class for spell check ran in renderer process. +class SpellCheckDictionary : public mojom::SpellCheckDictionary { + public: + SpellCheckDictionary(); + + SpellCheckDictionary(const SpellCheckDictionary&) = delete; + SpellCheckDictionary& operator=(const SpellCheckDictionary&) = delete; + + ~SpellCheckDictionary() override; + + bool Initialize(base::File file); + + void CheckSpelling(const std::string& word, + CheckSpellingCallback callback) override; + + private: + std::unique_ptr<base::MemoryMappedFile> mapped_dict_file_; + std::unique_ptr<Hunspell> hunspell_; +}; + +} // namespace quick_answers + +#endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_PUBLIC_CPP_SERVICE_SPELL_CHECK_DICTIONARY_H_
diff --git a/chromeos/components/quick_answers/public/cpp/service/spell_check_service.cc b/chromeos/components/quick_answers/public/cpp/service/spell_check_service.cc new file mode 100644 index 0000000..87e5571 --- /dev/null +++ b/chromeos/components/quick_answers/public/cpp/service/spell_check_service.cc
@@ -0,0 +1,33 @@ +// Copyright 2022 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 "chromeos/components/quick_answers/public/cpp/service/spell_check_service.h" + +#include "base/logging.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" + +namespace quick_answers { + +SpellCheckService::SpellCheckService( + mojo::PendingReceiver<quick_answers::mojom::SpellCheckService> + pending_receiver) + : receiver_(this, std::move(pending_receiver)) {} + +SpellCheckService::~SpellCheckService() = default; + +void SpellCheckService::CreateDictionary(base::File file, + CreateDictionaryCallback callback) { + auto dictionary = std::make_unique<SpellCheckDictionary>(); + if (!dictionary->Initialize(std::move(file))) { + std::move(callback).Run(std::move(mojo::NullRemote())); + return; + } + + mojo::PendingRemote<mojom::SpellCheckDictionary> pending_remote; + mojo::MakeSelfOwnedReceiver(std::move(dictionary), + pending_remote.InitWithNewPipeAndPassReceiver()); + std::move(callback).Run(std::move(pending_remote)); +} + +} // namespace quick_answers
diff --git a/chromeos/components/quick_answers/public/cpp/service/spell_check_service.h b/chromeos/components/quick_answers/public/cpp/service/spell_check_service.h new file mode 100644 index 0000000..28702fd2 --- /dev/null +++ b/chromeos/components/quick_answers/public/cpp/service/spell_check_service.h
@@ -0,0 +1,41 @@ +// Copyright 2022 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 CHROMEOS_COMPONENTS_QUICK_ANSWERS_PUBLIC_CPP_SERVICE_SPELL_CHECK_SERVICE_H_ +#define CHROMEOS_COMPONENTS_QUICK_ANSWERS_PUBLIC_CPP_SERVICE_SPELL_CHECK_SERVICE_H_ + +#include <memory> +#include <string> + +#include "base/memory/weak_ptr.h" +#include "chromeos/components/quick_answers/public/cpp/service/spell_check_dictionary.h" +#include "chromeos/components/quick_answers/public/mojom/spell_check.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver.h" + +namespace quick_answers { + +// Utility class for spell check ran in renderer process. +class SpellCheckService : public mojom::SpellCheckService { + public: + explicit SpellCheckService( + mojo::PendingReceiver<mojom::SpellCheckService> pending_receiver); + + SpellCheckService(const SpellCheckService&) = delete; + SpellCheckService& operator=(const SpellCheckService&) = delete; + + ~SpellCheckService() override; + + void CreateDictionary(base::File file, + CreateDictionaryCallback callback) override; + + private: + std::unique_ptr<SpellCheckDictionary> dictionary_; + + mojo::Receiver<mojom::SpellCheckService> receiver_; +}; + +} // namespace quick_answers + +#endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_PUBLIC_CPP_SERVICE_SPELL_CHECK_SERVICE_H_
diff --git a/chromeos/components/quick_answers/public/mojom/BUILD.gn b/chromeos/components/quick_answers/public/mojom/BUILD.gn new file mode 100644 index 0000000..e65f819 --- /dev/null +++ b/chromeos/components/quick_answers/public/mojom/BUILD.gn
@@ -0,0 +1,14 @@ +# Copyright 2022 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("//mojo/public/tools/bindings/mojom.gni") + +mojom("mojom") { + sources = [ "spell_check.mojom" ] + + public_deps = [ + "//mojo/public/mojom/base", + "//sandbox/policy/mojom", + ] +}
diff --git a/chromeos/components/quick_answers/public/mojom/OWNERS b/chromeos/components/quick_answers/public/mojom/OWNERS new file mode 100644 index 0000000..08850f4 --- /dev/null +++ b/chromeos/components/quick_answers/public/mojom/OWNERS
@@ -0,0 +1,2 @@ +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromeos/components/quick_answers/public/mojom/spell_check.mojom b/chromeos/components/quick_answers/public/mojom/spell_check.mojom new file mode 100644 index 0000000..93121c5 --- /dev/null +++ b/chromeos/components/quick_answers/public/mojom/spell_check.mojom
@@ -0,0 +1,29 @@ +// Copyright 2022 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. + +module quick_answers.mojom; + +import "mojo/public/mojom/base/read_only_file.mojom"; +import "sandbox/policy/mojom/sandbox.mojom"; + +// Provides a way to query hunspell in a sandboxed utility process, since +// the inputs may be untrustworthy and hunspell library is somewhat prone +// to crashes. +[ServiceSandbox=sandbox.mojom.Sandbox.kService] +interface SpellCheckService { + // Creates a new SpellCheckerDictionary instance from |dictionary_file|. + // If hunspell initialization failed, returns a null remote. + // Can be called multiple times if the dictionary file changes or the + // previous call did not success. + CreateDictionary(mojo_base.mojom.ReadOnlyFile dictionary_file) + => (pending_remote<SpellCheckDictionary>? dictionary); +}; + +// Handles spell check requests for a hunspell dictionary loaded via +// |CreateDictionary()|. +interface SpellCheckDictionary { + // Check spelling of the given word, |correctness| is true if the word is + // spelled correctly. + CheckSpelling(string word) => (bool correctness); +};
diff --git a/chromeos/dbus/userdataauth/fake_userdataauth_client.cc b/chromeos/dbus/userdataauth/fake_userdataauth_client.cc index 81a0352..4053e4e1 100644 --- a/chromeos/dbus/userdataauth/fake_userdataauth_client.cc +++ b/chromeos/dbus/userdataauth/fake_userdataauth_client.cc
@@ -304,6 +304,26 @@ ReturnProtobufMethodCallback(reply, std::move(callback)); } +void FakeUserDataAuthClient::UpdateCredential( + const ::user_data_auth::UpdateCredentialRequest& request, + UpdateCredentialCallback callback) { + ::user_data_auth::UpdateCredentialReply reply; + + const std::string auth_session_id = request.auth_session_id(); + + const auto it = auth_sessions_.find(auth_session_id); + if (it == auth_sessions_.end()) { + reply.set_error(::user_data_auth::CryptohomeErrorCode:: + CRYPTOHOME_INVALID_AUTH_SESSION_TOKEN); + } else if (!it->second.authenticated) { + reply.set_error(::user_data_auth::CryptohomeErrorCode:: + CRYPTOHOME_ERROR_UNAUTHENTICATED_AUTH_SESSION); + } else { + reply.set_error(cryptohome_error_); + } + ReturnProtobufMethodCallback(reply, std::move(callback)); +} + void FakeUserDataAuthClient::PrepareGuestVault( const ::user_data_auth::PrepareGuestVaultRequest& request, PrepareGuestVaultCallback callback) {
diff --git a/chromeos/dbus/userdataauth/fake_userdataauth_client.h b/chromeos/dbus/userdataauth/fake_userdataauth_client.h index c5e4bba..8708e9c 100644 --- a/chromeos/dbus/userdataauth/fake_userdataauth_client.h +++ b/chromeos/dbus/userdataauth/fake_userdataauth_client.h
@@ -95,6 +95,9 @@ AuthenticateAuthSessionCallback callback) override; void AddCredentials(const ::user_data_auth::AddCredentialsRequest& request, AddCredentialsCallback callback) override; + void UpdateCredential( + const ::user_data_auth::UpdateCredentialRequest& request, + UpdateCredentialCallback callback) override; void PrepareGuestVault( const ::user_data_auth::PrepareGuestVaultRequest& request, PrepareGuestVaultCallback callback) override;
diff --git a/chromeos/dbus/userdataauth/userdataauth_client.cc b/chromeos/dbus/userdataauth/userdataauth_client.cc index 091fbd37..ad2a5004 100644 --- a/chromeos/dbus/userdataauth/userdataauth_client.cc +++ b/chromeos/dbus/userdataauth/userdataauth_client.cc
@@ -235,6 +235,14 @@ std::move(callback)); } + void UpdateCredential( + const ::user_data_auth::UpdateCredentialRequest& request, + UpdateCredentialCallback callback) override { + CallProtoMethod(::user_data_auth::kUpdateCredential, + ::user_data_auth::kUserDataAuthInterface, request, + std::move(callback)); + } + void PrepareGuestVault( const ::user_data_auth::PrepareGuestVaultRequest& request, PrepareGuestVaultCallback callback) override {
diff --git a/chromeos/dbus/userdataauth/userdataauth_client.h b/chromeos/dbus/userdataauth/userdataauth_client.h index 8d98518e..706f908 100644 --- a/chromeos/dbus/userdataauth/userdataauth_client.h +++ b/chromeos/dbus/userdataauth/userdataauth_client.h
@@ -69,6 +69,9 @@ DBusMethodCallback<::user_data_auth::AuthenticateAuthSessionReply>; using AddCredentialsCallback = DBusMethodCallback<::user_data_auth::AddCredentialsReply>; + using UpdateCredentialCallback = + DBusMethodCallback<::user_data_auth::UpdateCredentialReply>; + using PrepareGuestVaultCallback = DBusMethodCallback<::user_data_auth::PrepareGuestVaultReply>; using PrepareEphemeralVaultCallback = @@ -210,6 +213,12 @@ const ::user_data_auth::AddCredentialsRequest& request, AddCredentialsCallback callback) = 0; + // Attempts to update credentials in the vault identified/authorized by auth + // session. + virtual void UpdateCredential( + const ::user_data_auth::UpdateCredentialRequest& request, + UpdateCredentialCallback callback) = 0; + // This request is intended to happen when a user wants // to login to ChromeOS as a guest. virtual void PrepareGuestVault(
diff --git a/cloud_print/BRANDING b/cloud_print/BRANDING deleted file mode 100644 index 0ab41da..0000000 --- a/cloud_print/BRANDING +++ /dev/null
@@ -1,3 +0,0 @@ -PRODUCT_FULLNAME=Google Cloud Print -PRODUCT_SHORTNAME=GCP -PRODUCT_DESCRIPTION=Google Cloud Print (GCP) enables any app on any device to print to any cloud-connected printer.
diff --git a/cloud_print/BUILD.gn b/cloud_print/BUILD.gn deleted file mode 100644 index 6f855cba..0000000 --- a/cloud_print/BUILD.gn +++ /dev/null
@@ -1,39 +0,0 @@ -# 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. - -import("//testing/test.gni") - -group("cloud_print") { - if (is_win) { - public_deps = [ - "//cloud_print/virtual_driver/win/install:virtual_driver_setup", - "//cloud_print/virtual_driver/win/port_monitor", - ] - - # When compiling 32-bit, also reference the 64-bit driver for installing on - # 64-bit systems. - if (target_cpu == "x86" && current_cpu == "x86") { - if (is_clang) { - win64 = "//build/toolchain/win:win_clang_x64" - } else { - win64 = "//build/toolchain/win:x64" - } - public_deps += [ "//cloud_print/virtual_driver/win/port_monitor($win64)" ] - } - } -} - -test("cloud_print_unittests") { - sources = [ "virtual_driver/win/port_monitor/port_monitor_unittest.cc" ] - - deps = [ - "//base", - "//base/test:run_all_unittests", - "//cloud_print/virtual_driver/win/port_monitor:lib", - "//testing/gmock", - "//testing/gtest", - ] - - libs = [ "secur32.lib" ] -}
diff --git a/cloud_print/COMMON_METADATA b/cloud_print/COMMON_METADATA deleted file mode 100644 index c3c4f77..0000000 --- a/cloud_print/COMMON_METADATA +++ /dev/null
@@ -1,3 +0,0 @@ -monorail { - component: "Services>CloudPrint" -} \ No newline at end of file
diff --git a/cloud_print/DEPS b/cloud_print/DEPS deleted file mode 100644 index 51643dee..0000000 --- a/cloud_print/DEPS +++ /dev/null
@@ -1,4 +0,0 @@ -include_rules = [ - "+chrome/common", - "+chrome/installer/launcher_support", -]
diff --git a/cloud_print/OWNERS b/cloud_print/OWNERS deleted file mode 100644 index 923d7cd..0000000 --- a/cloud_print/OWNERS +++ /dev/null
@@ -1,7 +0,0 @@ -set noparent - -# Cloud Print is temporarily owned by the Chrome Print team. -file://printing/OWNERS - -# Translation artifacts: -per-file ....xtb=file://tools/translation/TRANSLATION_OWNERS
diff --git a/cloud_print/common/BUILD.gn b/cloud_print/common/BUILD.gn deleted file mode 100644 index 258cc4e..0000000 --- a/cloud_print/common/BUILD.gn +++ /dev/null
@@ -1,24 +0,0 @@ -# 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. - -source_set("common") { - sources = [ - "win/cloud_print_utils.cc", - "win/cloud_print_utils.h", - ] - - deps = [ "//base" ] -} - -source_set("install_utils") { - sources = [ - "win/install_utils.cc", - "win/install_utils.h", - ] - - deps = [ - ":common", - "//base", - ] -}
diff --git a/cloud_print/common/win/cloud_print_utils.cc b/cloud_print/common/win/cloud_print_utils.cc deleted file mode 100644 index c1d52ca..0000000 --- a/cloud_print/common/win/cloud_print_utils.cc +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright 2013 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 "cloud_print/common/win/cloud_print_utils.h" - -#include <windows.h> - -#include "base/logging.h" -#include "base/win/registry.h" - -namespace cloud_print { - -namespace { - -// Google Update related constants. -const wchar_t kClientStateKey[] = L"SOFTWARE\\Google\\Update\\ClientState\\"; -const wchar_t* kUsageKey = L"dr"; - -} // namespace - -HRESULT GetLastHResult() { - DWORD error_code = GetLastError(); - return error_code ? HRESULT_FROM_WIN32(error_code) : E_FAIL; -} - -std::wstring LoadLocalString(DWORD id) { - static wchar_t dummy = L'\0'; - HMODULE module = NULL; - ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | - GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - &dummy, &module); - LPCWSTR buffer = NULL; - // If the last parameter is 0, LoadString assume that 3rd parameter type is - // LPCWSTR* and assign pointer to read-only memory with resource. - int count = ::LoadString(module, id, reinterpret_cast<LPWSTR>(&buffer), 0); - if (!buffer) - return std::wstring(); - return std::wstring(buffer, buffer + count); -} - -std::wstring GetErrorMessage(HRESULT hr) { - LPWSTR buffer = NULL; - ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_ALLOCATE_BUFFER, - 0, hr, 0, reinterpret_cast<LPWSTR>(&buffer), 0, NULL); - std::wstring result(buffer); - ::LocalFree(buffer); - return result; -} - -void SetGoogleUpdateUsage(const std::wstring& product_id) { - // Set appropriate key to 1 to let Omaha record usage. - base::win::RegKey key; - if (key.Create(HKEY_CURRENT_USER, (kClientStateKey + product_id).c_str(), - KEY_SET_VALUE) != ERROR_SUCCESS || - key.WriteValue(kUsageKey, L"1") != ERROR_SUCCESS) { - LOG(ERROR) << "Unable to set usage key"; - } -} - -} // namespace cloud_print
diff --git a/cloud_print/common/win/cloud_print_utils.h b/cloud_print/common/win/cloud_print_utils.h deleted file mode 100644 index 0d5d4b0..0000000 --- a/cloud_print/common/win/cloud_print_utils.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2013 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 CLOUD_PRINT_COMMON_WIN_CLOUD_PRINT_UTILS_H_ -#define CLOUD_PRINT_COMMON_WIN_CLOUD_PRINT_UTILS_H_ - -#include <wtypes.h> - -#include <string> - - -namespace cloud_print { - -// Similar to the Windows API call GetLastError but returns an HRESULT. -HRESULT GetLastHResult(); - -// Convert an HRESULT to a localized string. -std::wstring GetErrorMessage(HRESULT hr); - -// Retrieves a string from the string table of the module that contains the -// calling code. -std::wstring LoadLocalString(DWORD id); - -// Sets registry value to notify Google Update that product was used. -void SetGoogleUpdateUsage(const std::wstring& product_id); - -} // namespace cloud_print - -#endif // CLOUD_PRINT_COMMON_WIN_CLOUD_PRINT_UTILS_H_
diff --git a/cloud_print/common/win/install_utils.cc b/cloud_print/common/win/install_utils.cc deleted file mode 100644 index 5ba9db4..0000000 --- a/cloud_print/common/win/install_utils.cc +++ /dev/null
@@ -1,213 +0,0 @@ -// Copyright 2013 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 "cloud_print/common/win/install_utils.h" - -#include <windows.h> - -#include "base/command_line.h" -#include "base/file_version_info.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/path_service.h" -#include "base/process/launch.h" -#include "base/strings/string_util.h" -#include "base/win/current_module.h" -#include "base/win/registry.h" -#include "cloud_print/common/win/cloud_print_utils.h" - -namespace cloud_print { - -namespace { - -// Google Update related constants. -const wchar_t kClientsKey[] = L"SOFTWARE\\Google\\Update\\Clients\\"; -const wchar_t kClientStateKey[] = L"SOFTWARE\\Google\\Update\\ClientState\\"; -const wchar_t kVersionKey[] = L"pv"; -const wchar_t kNameKey[] = L"name"; - -enum InstallerResult { - INSTALLER_RESULT_FAILED_CUSTOM_ERROR = 1, - INSTALLER_RESULT_FAILED_SYSTEM_ERROR = 3, -}; - -const wchar_t kRegValueInstallerResult[] = L"InstallerResult"; -const wchar_t kRegValueInstallerResultUIString[] = L"InstallerResultUIString"; -const wchar_t kRegValueInstallerError[] = L"InstallerError"; - -// Uninstall related constants. -const wchar_t kUninstallKey[] = - L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"; -const wchar_t kInstallLocation[] = L"InstallLocation"; -const wchar_t kUninstallString[] = L"UninstallString"; -const wchar_t kDisplayVersion[] = L"DisplayVersion"; -const wchar_t kDisplayIcon[] = L"DisplayIcon"; -const wchar_t kDisplayName[] = L"DisplayName"; -const wchar_t kPublisher[] = L"Publisher"; -const wchar_t kNoModify[] = L"NoModify"; -const wchar_t kNoRepair[] = L"NoRepair"; - -} // namespace - -void SetGoogleUpdateKeys(const std::wstring& product_id, - const std::wstring& product_name) { - base::win::RegKey key; - if (key.Create(HKEY_LOCAL_MACHINE, - (cloud_print::kClientsKey + product_id).c_str(), - KEY_SET_VALUE) != ERROR_SUCCESS) { - LOG(ERROR) << "Unable to open key"; - } - - // Get the version from the resource file. - std::wstring version_string; - std::unique_ptr<FileVersionInfo> version_info = - FileVersionInfo::CreateFileVersionInfoForModule(CURRENT_MODULE()); - if (version_info) { - version_string = base::AsWString(version_info->product_version()); - } else { - LOG(ERROR) << "Unable to get version string"; - // Use a random version string so that Google Update has something to go by. - version_string = L"0.0.0.99"; - } - - if (key.WriteValue(kVersionKey, version_string.c_str()) != ERROR_SUCCESS || - key.WriteValue(kNameKey, product_name.c_str()) != ERROR_SUCCESS) { - LOG(ERROR) << "Unable to set registry keys"; - } -} - -void SetGoogleUpdateError(const std::wstring& product_id, - const std::wstring& message) { - LOG(ERROR) << message; - base::win::RegKey key; - if (key.Create(HKEY_LOCAL_MACHINE, - (cloud_print::kClientStateKey + product_id).c_str(), - KEY_SET_VALUE) != ERROR_SUCCESS) { - LOG(ERROR) << "Unable to open key"; - } - - if (key.WriteValue(kRegValueInstallerResult, - INSTALLER_RESULT_FAILED_CUSTOM_ERROR) != ERROR_SUCCESS || - key.WriteValue(kRegValueInstallerResultUIString, message.c_str()) != - ERROR_SUCCESS) { - LOG(ERROR) << "Unable to set registry keys"; - } -} - -void SetGoogleUpdateError(const std::wstring& product_id, HRESULT hr) { - LOG(ERROR) << cloud_print::GetErrorMessage(hr); - base::win::RegKey key; - if (key.Create(HKEY_LOCAL_MACHINE, - (cloud_print::kClientStateKey + product_id).c_str(), - KEY_SET_VALUE) != ERROR_SUCCESS) { - LOG(ERROR) << "Unable to open key"; - } - - if (key.WriteValue(kRegValueInstallerResult, - INSTALLER_RESULT_FAILED_SYSTEM_ERROR) != ERROR_SUCCESS || - key.WriteValue(kRegValueInstallerError, hr) != ERROR_SUCCESS) { - LOG(ERROR) << "Unable to set registry keys"; - } -} - -void DeleteGoogleUpdateKeys(const std::wstring& product_id) { - base::win::RegKey key; - if (key.Open(HKEY_LOCAL_MACHINE, - (cloud_print::kClientsKey + product_id).c_str(), - DELETE) != ERROR_SUCCESS) { - LOG(ERROR) << "Unable to open key to delete"; - return; - } - if (key.DeleteKey(L"") != ERROR_SUCCESS) { - LOG(ERROR) << "Unable to delete key"; - } -} - -void CreateUninstallKey(const std::wstring& uninstall_id, - const std::wstring& product_name, - const std::string& uninstall_switch) { - // Now write the Windows Uninstall entries - // Minimal error checking here since the install can continue - // if this fails. - base::win::RegKey key; - if (key.Create(HKEY_LOCAL_MACHINE, - (cloud_print::kUninstallKey + uninstall_id).c_str(), - KEY_SET_VALUE) != ERROR_SUCCESS) { - LOG(ERROR) << "Unable to open key"; - return; - } - - base::FilePath unstall_binary; - CHECK(base::PathService::Get(base::FILE_EXE, &unstall_binary)); - - base::CommandLine uninstall_command(unstall_binary); - uninstall_command.AppendSwitch(uninstall_switch); - key.WriteValue(kUninstallString, - uninstall_command.GetCommandLineString().c_str()); - key.WriteValue(kInstallLocation, unstall_binary.DirName().value().c_str()); - - // Get the version resource. - std::unique_ptr<FileVersionInfo> version_info = - FileVersionInfo::CreateFileVersionInfoForModule(CURRENT_MODULE()); - - if (version_info) { - key.WriteValue(kDisplayVersion, - base::as_wcstr(version_info->file_version())); - key.WriteValue(kPublisher, base::as_wcstr(version_info->company_name())); - } else { - LOG(ERROR) << "Unable to get version string"; - } - key.WriteValue(kDisplayName, product_name.c_str()); - key.WriteValue(kDisplayIcon, unstall_binary.value().c_str()); - key.WriteValue(kNoModify, 1); - key.WriteValue(kNoRepair, 1); -} - -void DeleteUninstallKey(const std::wstring& uninstall_id) { - ::RegDeleteKey(HKEY_LOCAL_MACHINE, - (cloud_print::kUninstallKey + uninstall_id).c_str()); -} - -base::FilePath GetInstallLocation(const std::wstring& uninstall_id) { - base::win::RegKey key; - if (key.Open(HKEY_LOCAL_MACHINE, - (cloud_print::kUninstallKey + uninstall_id).c_str(), - KEY_QUERY_VALUE) != ERROR_SUCCESS) { - // Not installed. - return base::FilePath(); - } - std::wstring install_path_value; - key.ReadValue(kInstallLocation, &install_path_value); - return base::FilePath(install_path_value); -} - -void DeleteProgramDir(const std::string& delete_switch) { - base::FilePath installer_source; - if (!base::PathService::Get(base::FILE_EXE, &installer_source)) - return; - // Deletes only subdirs of program files. - if (!IsProgramsFilesParent(installer_source)) - return; - base::FilePath temp_path; - if (!base::CreateTemporaryFile(&temp_path)) - return; - base::CopyFile(installer_source, temp_path); - base::DeleteFileAfterReboot(temp_path); - base::CommandLine command_line(temp_path); - command_line.AppendSwitchPath(delete_switch, installer_source.DirName()); - base::LaunchOptions options; - if (!base::LaunchProcess(command_line, options).IsValid()) { - LOG(ERROR) << "Unable to launch child uninstall."; - } -} - -bool IsProgramsFilesParent(const base::FilePath& path) { - base::FilePath program_files; - if (!base::PathService::Get(base::DIR_PROGRAM_FILESX86, &program_files)) - return false; - return program_files.IsParent(path); -} - -} // namespace cloud_print
diff --git a/cloud_print/common/win/install_utils.h b/cloud_print/common/win/install_utils.h deleted file mode 100644 index ec6a6a9..0000000 --- a/cloud_print/common/win/install_utils.h +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2013 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 CLOUD_PRINT_COMMON_WIN_INSTALL_UTILS_H_ -#define CLOUD_PRINT_COMMON_WIN_INSTALL_UTILS_H_ - -#include <wtypes.h> -#include <string> - -#include "base/files/file_path.h" - -namespace cloud_print { - -// Sets Google Update registry keys after install or update. -void SetGoogleUpdateKeys(const std::wstring& product_id, - const std::wstring& product_name); - -// Sets custom error message to show by Google Update installer -void SetGoogleUpdateError(const std::wstring& product_id, - const std::wstring& message); - -// Sets custom system error code to show by Google Update installer -void SetGoogleUpdateError(const std::wstring& product_id, HRESULT hr); - -// Deletes Google Update reg keys on product uninstall. -void DeleteGoogleUpdateKeys(const std::wstring& product_id); - -// Creates control panel uninstall item. -void CreateUninstallKey(const std::wstring& uninstall_id, - const std::wstring& product_name, - const std::string& uninstall_switch); - -// Deletes control panel uninstall item. -void DeleteUninstallKey(const std::wstring& uninstall_id); - -// Returns install location retrieved from control panel uninstall key. -base::FilePath GetInstallLocation(const std::wstring& uninstall_id); - -// Returns install location retrieved from control panel uninstall key. -void DeleteProgramDir(const std::string& delete_switch); - -// Returns true if path is part of program files. -bool IsProgramsFilesParent(const base::FilePath& path); - -} // namespace cloud_print - -#endif // CLOUD_PRINT_COMMON_WIN_INSTALL_UTILS_H_
diff --git a/cloud_print/virtual_driver/win/BUILD.gn b/cloud_print/virtual_driver/win/BUILD.gn deleted file mode 100644 index 110b5a36..0000000 --- a/cloud_print/virtual_driver/win/BUILD.gn +++ /dev/null
@@ -1,19 +0,0 @@ -# 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. - -assert(is_win) - -source_set("win") { - sources = [ - "virtual_driver_consts.cc", - "virtual_driver_consts.h", - "virtual_driver_helpers.cc", - "virtual_driver_helpers.h", - ] - - deps = [ - "//base", - "//cloud_print/common", - ] -}
diff --git a/cloud_print/virtual_driver/win/gcp_portmon_dll.ver b/cloud_print/virtual_driver/win/gcp_portmon_dll.ver deleted file mode 100644 index dd75a0f1..0000000 --- a/cloud_print/virtual_driver/win/gcp_portmon_dll.ver +++ /dev/null
@@ -1,3 +0,0 @@ -INTERNAL_NAME=gcp_portmon.dll -ORIGINAL_FILENAME=gcp_portmon.dll -FILETYPE=0x2L
diff --git a/cloud_print/virtual_driver/win/install/BUILD.gn b/cloud_print/virtual_driver/win/install/BUILD.gn deleted file mode 100644 index 3359f20..0000000 --- a/cloud_print/virtual_driver/win/install/BUILD.gn +++ /dev/null
@@ -1,106 +0,0 @@ -# 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. - -import("//chrome/process_version_rc_template.gni") -import("//tools/grit/grit_rule.gni") - -assert(is_win) - -executable("virtual_driver_setup") { - sources = [ "setup.cc" ] - - configs -= [ "//build/config/win:console" ] - configs += [ "//build/config/win:windowed" ] - - deps = [ - ":copy_gcp_driver_gpd", - ":copy_gcp_driver_inf", - ":resources", - ":setup_version", - "//base", - "//cloud_print/common", - "//cloud_print/common:install_utils", - "//cloud_print/virtual_driver/win", - ] - - libs = [ "setupapi.lib" ] - ldflags = [ "/DELAYLOAD:winspool.drv" ] -} - -copy("copy_gcp_driver_gpd") { - sources = [ "inf/gcp_driver.gpd" ] - outputs = [ "$root_build_dir/gcp_driver.gpd" ] -} - -copy("copy_gcp_driver_inf") { - sources = [ "inf/gcp_driver.inf" ] - outputs = [ "$root_build_dir/gcp_driver.inf" ] -} - -process_version_rc_template("setup_version") { - sources = [ "virtual_driver_setup_exe.ver" ] - output = "$target_gen_dir/virtual_driver_setup.rc" -} - -grit("resources") { - visibility = [ ":*" ] - - source = "virtual_driver_setup_resources.grd" - - outputs = [ - "grit/virtual_driver_setup_resources.h", - "virtual_driver_setup_resources_ar.rc", - "virtual_driver_setup_resources_bg.rc", - "virtual_driver_setup_resources_bn.rc", - "virtual_driver_setup_resources_ca.rc", - "virtual_driver_setup_resources_cs.rc", - "virtual_driver_setup_resources_da.rc", - "virtual_driver_setup_resources_de.rc", - "virtual_driver_setup_resources_el.rc", - "virtual_driver_setup_resources_en.rc", - "virtual_driver_setup_resources_en-GB.rc", - "virtual_driver_setup_resources_es.rc", - "virtual_driver_setup_resources_es-419.rc", - "virtual_driver_setup_resources_et.rc", - "virtual_driver_setup_resources_fa.rc", - "virtual_driver_setup_resources_fi.rc", - "virtual_driver_setup_resources_fil.rc", - "virtual_driver_setup_resources_fr.rc", - "virtual_driver_setup_resources_gu.rc", - "virtual_driver_setup_resources_he.rc", - "virtual_driver_setup_resources_hi.rc", - "virtual_driver_setup_resources_hr.rc", - "virtual_driver_setup_resources_hu.rc", - "virtual_driver_setup_resources_id.rc", - "virtual_driver_setup_resources_it.rc", - "virtual_driver_setup_resources_ja.rc", - "virtual_driver_setup_resources_kn.rc", - "virtual_driver_setup_resources_ko.rc", - "virtual_driver_setup_resources_lt.rc", - "virtual_driver_setup_resources_lv.rc", - "virtual_driver_setup_resources_ml.rc", - "virtual_driver_setup_resources_mr.rc", - "virtual_driver_setup_resources_ms.rc", - "virtual_driver_setup_resources_nl.rc", - "virtual_driver_setup_resources_nb.rc", - "virtual_driver_setup_resources_pl.rc", - "virtual_driver_setup_resources_pt-BR.rc", - "virtual_driver_setup_resources_pt-PT.rc", - "virtual_driver_setup_resources_ro.rc", - "virtual_driver_setup_resources_ru.rc", - "virtual_driver_setup_resources_sk.rc", - "virtual_driver_setup_resources_sl.rc", - "virtual_driver_setup_resources_sr.rc", - "virtual_driver_setup_resources_sv.rc", - "virtual_driver_setup_resources_sw.rc", - "virtual_driver_setup_resources_ta.rc", - "virtual_driver_setup_resources_te.rc", - "virtual_driver_setup_resources_th.rc", - "virtual_driver_setup_resources_tr.rc", - "virtual_driver_setup_resources_uk.rc", - "virtual_driver_setup_resources_vi.rc", - "virtual_driver_setup_resources_zh-CN.rc", - "virtual_driver_setup_resources_zh-TW.rc", - ] -}
diff --git a/cloud_print/virtual_driver/win/install/inf/gcp_driver.gpd b/cloud_print/virtual_driver/win/install/inf/gcp_driver.gpd deleted file mode 100644 index 3e853d6..0000000 --- a/cloud_print/virtual_driver/win/install/inf/gcp_driver.gpd +++ /dev/null
@@ -1,1034 +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. - -*GPDFileVersion: "1.0" -*GPDSpecVersion: "1.0" -*Include: "StdNames.gpd" -*ResourceDLL: "unires.dll" -*ModelName: "Google Cloud Printer" -*MasterUnits: PAIR(1200, 1200) -*MaxCopies: 1 -*PrintRatePPM: 200 -*PrinterType: PAGE -*IsXPSDriver?: TRUE - -*Feature: ColorMode { - *rcNameID: =COLOR_PRINTING_MODE_DISPLAY - *DefaultOption: 24bpp - *ConcealFromUI?: TRUE - *Option: 24bpp { - *rcNameID: =24BPP_DISPLAY - *DevNumOfPlanes: 1 - *DevBPP: 24 - *DrvBPP: 24 - } -} - -*Feature: Memory { - *rcNameID: =PRINTER_MEMORY_DISPLAY - *DefaultOption: 65536KB - *Option: 16384KB { - *Name: "16MB" - *MemoryConfigKB: PAIR(16384, 16384) - } - *Option: 65536KB { - *Name: "64MB" - *MemoryConfigKB: PAIR(65536, 65536) - } -} - -*Feature: Orientation { - *rcNameID: =ORIENTATION_DISPLAY - *DefaultOption: PORTRAIT - *Option: PORTRAIT { - *rcNameID: =PORTRAIT_DISPLAY - } - *Option: LANDSCAPE_CC270 { - *rcNameID: =LANDSCAPE_DISPLAY - } -} - -*Feature: PaperSize { - *rcNameID: =PAPER_SIZE_DISPLAY - *DefaultOption: LETTER - - *Option: A2 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(19842, 28062) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(28062, 19842) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: A3 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(14031, 19842) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(19842, 14031) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: A4 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(9921, 14031) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(14031, 9921) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: A5 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(6992, 9921) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(9921, 6992) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: A6 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(4960, 6992) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(6992, 4960) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: A4_PLUS { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(9921, 15590) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(15590, 9921) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: A3_EXTRA { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(15212, 21023) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(21023, 15212) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: A4_EXTRA { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(11102, 15212) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(15212, 11102) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: A5_EXTRA { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(8220, 11102) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(11102, 8220) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: B4 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(12141, 17196) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(17196, 12141) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: B5 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(8598, 12141) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(12141, 8598) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_B4 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(11811, 16677) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(16677, 11811) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_B5 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(8314, 11811) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(11811, 8314) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_B6 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(5905, 8314) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(8314, 5905) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: B6_JIS { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(6047, 8598) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(8598, 6047) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: B5_EXTRA { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(9496, 13039) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(13039, 9496) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_C3 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(15307, 21637) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(21637, 15307) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_C4 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(10818, 15307) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(15307, 10818) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_C5 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(7653, 10818) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(10818, 7653) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_C6 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(5385, 7653) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(7653, 5385) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_C65 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(5385, 10818) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(10818, 5385) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_DL { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(5196, 10393) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(10393, 5196) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: JENV_CHOU3 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(5669, 11102) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(11102, 5669) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: JENV_CHOU4 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(4251, 9685) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(9685, 4251) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: JAPANESE_POSTCARD { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(4724, 6992) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(6992, 4724) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: JENV_KAKU2 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(11338, 15685) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(15685, 11338) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: DBL_JAPANESE_POSTCARD { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(6992, 9448) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(9448, 6992) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: JENV_YOU4 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(4960, 11102) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(11102, 4960) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: 10X11 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(12000, 13200) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(13200, 12000) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: 10X14 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(12000, 16800) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(16800, 12000) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: 9X11 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(10800, 13200) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(13200, 10800) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: CSHEET { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(20400, 26400) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(26400, 20400) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: DSHEET { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(26400, 40800) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(40800, 26400) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ESHEET { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(40800, 52800) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(52800, 40800) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: EXECUTIVE { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(8700, 12600) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(12600, 8700) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: FANFOLD_STD_GERMAN { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(10200, 14400) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(14400, 10200) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: FANFOLD_US { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(13200, 17850) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(17850, 13200) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: FOLIO { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(10200, 15600) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(15600, 10200) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: STATEMENT { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(6600, 10200) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(10200, 6600) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: TABLOID { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(13200, 20400) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(20400, 13200) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: LEGAL { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(10200, 16800) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(16800, 10200) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: LEGAL_EXTRA { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(11400, 18000) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(18000, 11400) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: LETTER { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(10200, 13200) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(13200, 10200) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: LETTER_EXTRA { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(11400, 14400) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(14400, 11400) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: LETTER_PLUS { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(10200, 15228) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(15228, 10200) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_MONARCH { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(4650, 9000) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(9000, 4650) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_9 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(4650, 10650) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(10650, 4650) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_10 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(4950, 11400) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(11400, 4950) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_11 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(5400, 12450) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(12450, 5400) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_12 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(5700, 13200) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(13200, 5700) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_14 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(6000, 13800) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(13800, 6000) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: ENV_INVITE { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(10393, 10393) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(10393, 10393) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: PENV_1 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(4818, 7795) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(7795, 4818) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: PENV_3 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(5905, 8314) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(8314, 5905) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: PENV_4 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(5196, 9826) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(9826, 5196) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: PENV_5 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(5196, 10393) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(10393, 5196) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: PENV_6 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(5669, 10866) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(10866, 5669) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: PENV_7 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(7559, 10866) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(10866, 7559) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: PENV_8 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(5669, 14598) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(14598, 5669) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } - - *Option: PENV_10 { - *rcNameID: =RCID_DMPAPER_SYSTEM_NAME - *switch: Orientation { - *case: PORTRAIT { - *PrintableArea: PAIR(15307, 21637) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - *case: LANDSCAPE_CC270 { - *PrintableArea: PAIR(21637, 15307) - *PrintableOrigin: PAIR(0, 0) - *CursorOrigin: PAIR(0, 0) - } - } - } -} - -*Feature: Resolution { - *rcNameID: =RESOLUTION_DISPLAY - *DefaultOption: 600dpi - - *Option: 600dpi { - *Name: "600 x 600 " =DOTS_PER_INCH - *DPI: PAIR(600, 600) - *TextDPI: PAIR(600, 600) - *SpotDiameter: 100 - *Command: CmdBeginRaster { *Cmd: "<1B>*v7S<1B>*r1A" } - *Command: CmdEndRaster { *Cmd: "<1B>*rC" } - *Command: CmdSendBlockData { *Cmd: "<1B>*b" %d {NumOfDataBytes}"W" } - } -} - -*Command: CmdCR { *Cmd: "<0D>" } -*Command: CmdLF { *Cmd: "<0A>" } -*Command: CmdFF { *Cmd: "<0C>" }
diff --git a/cloud_print/virtual_driver/win/install/inf/gcp_driver.inf b/cloud_print/virtual_driver/win/install/inf/gcp_driver.inf deleted file mode 100644 index ad57e0a..0000000 --- a/cloud_print/virtual_driver/win/install/inf/gcp_driver.inf +++ /dev/null Binary files differ
diff --git a/cloud_print/virtual_driver/win/install/resources/cloudprint.ico b/cloud_print/virtual_driver/win/install/resources/cloudprint.ico deleted file mode 100644 index e362c72..0000000 --- a/cloud_print/virtual_driver/win/install/resources/cloudprint.ico +++ /dev/null Binary files differ
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ar.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ar.xtb deleted file mode 100644 index 8a494d57..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ar.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ar"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>برنامج تشغيل XPS<ph name="XPS_URL_END"/> غير مثبّت.</translation> -<translation id="4983496916481712098">طابعة متوافقة مع خدمة طباعة في السحاب من Google</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_bg.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_bg.xtb deleted file mode 100644 index cfc0956..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_bg.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="bg"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>Драйверът XPS<ph name="XPS_URL_END"/> не е инсталиран.</translation> -<translation id="4983496916481712098">Google Cloud Printer</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_bn.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_bn.xtb deleted file mode 100644 index 67e55574..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_bn.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="bn"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS ড্রাইভার<ph name="XPS_URL_END"/> ইনস্টল করা নেই৷</translation> -<translation id="4983496916481712098">Google মেঘ মুদ্রণ</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ca.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ca.xtb deleted file mode 100644 index 7709263b..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ca.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ca"> -<translation id="4659506378548526631">El <ph name="XPS_URL"/>controlador XPS<ph name="XPS_URL_END"/> no està instal·lat.</translation> -<translation id="4983496916481712098">Impressora de Google Cloud</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_cs.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_cs.xtb deleted file mode 100644 index 3ea6cb49d..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_cs.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="cs"> -<translation id="4659506378548526631">Není nainstalován <ph name="XPS_URL"/>ovladač XPS<ph name="XPS_URL_END"/>.</translation> -<translation id="4983496916481712098">Tiskárna v cloudu Google</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_da.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_da.xtb deleted file mode 100644 index c0f9c34..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_da.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="da"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS-driver<ph name="XPS_URL_END"/> er ikke installeret.</translation> -<translation id="4983496916481712098">Google Cloudprinter</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_de.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_de.xtb deleted file mode 100644 index 09daae63..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_de.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="de"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS-Treiber<ph name="XPS_URL_END"/> ist nicht installiert.</translation> -<translation id="4983496916481712098">Google Cloud Printer</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_el.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_el.xtb deleted file mode 100644 index 428c5e6..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_el.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="el"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>Το πρόγραμμα οδήγησης XPS<ph name="XPS_URL_END"/> δεν είναι εγκατεστημένο.</translation> -<translation id="4983496916481712098">Εκτυπωτής Google Cloud</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_en-GB.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_en-GB.xtb deleted file mode 100644 index fa23175..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_en-GB.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="en-GB"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS driver<ph name="XPS_URL_END"/> is not installed.</translation> -<translation id="4983496916481712098">Google Cloud Printer</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_es-419.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_es-419.xtb deleted file mode 100644 index e8685de..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_es-419.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="es-419"> -<translation id="4659506378548526631">El <ph name="XPS_URL"/>controlador XPS<ph name="XPS_URL_END"/> no está instalado.</translation> -<translation id="4983496916481712098">Impresora de Google Cloud</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_es.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_es.xtb deleted file mode 100644 index a021491..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_es.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="es"> -<translation id="4659506378548526631">El <ph name="XPS_URL"/>controlador XPS<ph name="XPS_URL_END"/> no está instalado.</translation> -<translation id="4983496916481712098">Impresora en la nube de Google</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_et.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_et.xtb deleted file mode 100644 index 67319bf61..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_et.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="et"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS-draiver<ph name="XPS_URL_END"/> on installimata.</translation> -<translation id="4983496916481712098">Google'i pilvprinter</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_fa.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_fa.xtb deleted file mode 100644 index 8cee134..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_fa.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="fa"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>راهانداز XPS<ph name="XPS_URL_END"/> نصب نشده است.</translation> -<translation id="4983496916481712098">Google Cloud Printer</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_fi.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_fi.xtb deleted file mode 100644 index c56f62f..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_fi.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="fi"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS-ajuria<ph name="XPS_URL_END"/> ei ole asennettu.</translation> -<translation id="4983496916481712098">Google Cloud -tulostin</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_fil.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_fil.xtb deleted file mode 100644 index 56a8cf9..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_fil.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="fil"> -<translation id="4659506378548526631">Hindi naka-install ang <ph name="XPS_URL"/>XPS driver<ph name="XPS_URL_END"/>.</translation> -<translation id="4983496916481712098">Google Cloud Printer</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_fr.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_fr.xtb deleted file mode 100644 index f928f81..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_fr.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="fr"> -<translation id="4659506378548526631">Le <ph name="XPS_URL"/>pilote XPS<ph name="XPS_URL_END"/> n'est pas installé.</translation> -<translation id="4983496916481712098">Google Cloud Printer</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_gu.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_gu.xtb deleted file mode 100644 index 1446cb8e..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_gu.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="gu"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS ડ્રાઇવર<ph name="XPS_URL_END"/> ઇન્સ્ટોલ કરેલું નથી.</translation> -<translation id="4983496916481712098">Google મેઘ મુદ્રણ</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_he.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_he.xtb deleted file mode 100644 index 49c7b8b..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_he.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="he"> -<translation id="4659506378548526631"><ph name="XPS_URL"/> מנהל ההתקן של XPS<ph name="XPS_URL_END"/> לא מותקן.</translation> -<translation id="4983496916481712098">מדפסת Google Cloud Print</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_hi.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_hi.xtb deleted file mode 100644 index ecf98ae4..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_hi.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="hi"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS ड्राइवर<ph name="XPS_URL_END"/> इंस्टॉल नहीं है.</translation> -<translation id="4983496916481712098">Google क्लाउड प्रिंटर</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_hr.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_hr.xtb deleted file mode 100644 index 763791b..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_hr.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="hr"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>Upravljački program za XPS<ph name="XPS_URL_END"/> nije instaliran.</translation> -<translation id="4983496916481712098">Google pisač u oblaku</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_hu.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_hu.xtb deleted file mode 100644 index a871cf4..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_hu.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="hu"> -<translation id="4659506378548526631">Nincs telepítve <ph name="XPS_URL"/>XPS illesztőprogram<ph name="XPS_URL_END"/>.</translation> -<translation id="4983496916481712098">Google Cloud Printer</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_id.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_id.xtb deleted file mode 100644 index dbdc14e..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_id.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="id"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>Driver XPS<ph name="XPS_URL_END"/> tidak terpasang.</translation> -<translation id="4983496916481712098">Google Cloud Printer</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_it.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_it.xtb deleted file mode 100644 index 7d6b3fa..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_it.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="it"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>Il driver XPS<ph name="XPS_URL_END"/> non è installato.</translation> -<translation id="4983496916481712098">Google Cloud Print</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ja.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ja.xtb deleted file mode 100644 index e2a1155..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ja.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ja"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS ドライバ<ph name="XPS_URL_END"/>がインストールされていません。</translation> -<translation id="4983496916481712098">Google クラウド プリンタ</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_kn.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_kn.xtb deleted file mode 100644 index af30a4d..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_kn.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="kn"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS ಡ್ರೈವರ್<ph name="XPS_URL_END"/> ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿಲ್ಲ.</translation> -<translation id="4983496916481712098">Google ಮೇಘ ಮುದ್ರಕ</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ko.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ko.xtb deleted file mode 100644 index 9a3686e8..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ko.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ko"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS 드라이버<ph name="XPS_URL_END"/>가 설치되지 않았습니다.</translation> -<translation id="4983496916481712098">Google 클라우드 프린터</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_lt.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_lt.xtb deleted file mode 100644 index fa40997..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_lt.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="lt"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS tvarkyklė<ph name="XPS_URL_END"/> neįdiegta.</translation> -<translation id="4983496916481712098">„Google“ spausdinimo iš debesies programa</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_lv.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_lv.xtb deleted file mode 100644 index 61d8225..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_lv.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="lv"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS dzinis<ph name="XPS_URL_END"/> nav instalēts.</translation> -<translation id="4983496916481712098">Google mākoņprinteris</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ml.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ml.xtb deleted file mode 100644 index b57290c..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ml.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ml"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS ഡ്രൈവർ<ph name="XPS_URL_END"/> ഇൻസ്റ്റാളുചെയ്തിട്ടില്ല.</translation> -<translation id="4983496916481712098">Google ക്ലൗഡ് പ്രിന്റർ</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_mr.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_mr.xtb deleted file mode 100644 index a93c0e4..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_mr.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="mr"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS ड्राइव्हर<ph name="XPS_URL_END"/> स्थापित केलेला नाही.</translation> -<translation id="4983496916481712098">Google मेघ प्रिंटर</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ms.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ms.xtb deleted file mode 100644 index 810d740..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ms.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ms"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>Pemacu XPS<ph name="XPS_URL_END"/> tidak dipasang.</translation> -<translation id="4983496916481712098">Pencetak Awan Google</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_nl.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_nl.xtb deleted file mode 100644 index 48389ca..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_nl.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="nl"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS-stuurprogramma<ph name="XPS_URL_END"/> is niet geïnstalleerd.</translation> -<translation id="4983496916481712098">Google Cloudprinter</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_no.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_no.xtb deleted file mode 100644 index 2797459..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_no.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="no"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS-driveren<ph name="XPS_URL_END"/> er ikke installert.</translation> -<translation id="4983496916481712098">Google Cloud Printer</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_pl.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_pl.xtb deleted file mode 100644 index a84a993..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_pl.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="pl"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>Sterownik XPS<ph name="XPS_URL_END"/> nie jest zainstalowany.</translation> -<translation id="4983496916481712098">Drukarka Google Cloud</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_pt-BR.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_pt-BR.xtb deleted file mode 100644 index e9a4f35..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_pt-BR.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="pt-BR"> -<translation id="4659506378548526631">O <ph name="XPS_URL"/>driver XPS<ph name="XPS_URL_END"/> não está instalado.</translation> -<translation id="4983496916481712098">Google Cloud Printer</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_pt-PT.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_pt-PT.xtb deleted file mode 100644 index ffeafd96..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_pt-PT.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="pt-PT"> -<translation id="4659506378548526631">O <ph name="XPS_URL"/>controlador XPS<ph name="XPS_URL_END"/> não está instalado.</translation> -<translation id="4983496916481712098">Impressora do Google Cloud Print</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ro.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ro.xtb deleted file mode 100644 index 2677e952..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ro.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ro"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>Driverul XPS<ph name="XPS_URL_END"/> nu este instalat.</translation> -<translation id="4983496916481712098">Imprimanta Google Cloud Print</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ru.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ru.xtb deleted file mode 100644 index 2e5ae1a..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ru.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ru"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>Драйвер XPS<ph name="XPS_URL_END"/> не установлен.</translation> -<translation id="4983496916481712098">Виртуальный принтер Google</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_sk.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_sk.xtb deleted file mode 100644 index fbb2135..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_sk.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="sk"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>Ovládač XPS<ph name="XPS_URL_END"/> nie je nainštalovaný.</translation> -<translation id="4983496916481712098">Google Cloud Printer</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_sl.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_sl.xtb deleted file mode 100644 index 0d2d286..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_sl.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="sl"> -<translation id="4659506378548526631">Gonilnik <ph name="XPS_URL"/>XPS<ph name="XPS_URL_END"/> ni nameščen.</translation> -<translation id="4983496916481712098">Tiskalnik za Google Tiskanje v oblaku</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_sr.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_sr.xtb deleted file mode 100644 index ad5c724..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_sr.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="sr"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>Управљачки програм за XPS<ph name="XPS_URL_END"/> није инсталиран.</translation> -<translation id="4983496916481712098">Google Cloud штампач</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_sv.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_sv.xtb deleted file mode 100644 index de6b601..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_sv.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="sv"> -<translation id="4659506378548526631">Ingen <ph name="XPS_URL"/>XPS-drivrutin<ph name="XPS_URL_END"/> är installerad.</translation> -<translation id="4983496916481712098">Google Cloud Printer</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_sw.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_sw.xtb deleted file mode 100644 index fca4065..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_sw.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="sw"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS driver<ph name="XPS_URL_END"/> is not installed.</translation> -<translation id="4983496916481712098">Google Cloud Printer</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ta.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ta.xtb deleted file mode 100644 index e0d2f3f..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_ta.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ta"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS இயக்கி<ph name="XPS_URL_END"/> நிறுவப்படவில்லை.</translation> -<translation id="4983496916481712098">Google மேகக்கணி அச்சுப்பொறி</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_te.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_te.xtb deleted file mode 100644 index 6f22db1e..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_te.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="te"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS డ్రైవర్<ph name="XPS_URL_END"/> ఇన్స్టాల్ చేయబడలేదు.</translation> -<translation id="4983496916481712098">Google మేఘ ప్రింటర్</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_th.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_th.xtb deleted file mode 100644 index 82622972..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_th.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="th"> -<translation id="4659506378548526631">ไม่ได้ติดตั้ง<ph name="XPS_URL"/>ไดรเวอร์ XPS<ph name="XPS_URL_END"/></translation> -<translation id="4983496916481712098">Google เครื่องพิมพ์ระบบคลาวด์</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_tr.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_tr.xtb deleted file mode 100644 index 06f6187..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_tr.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="tr"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>XPS sürücüsü<ph name="XPS_URL_END"/> yüklü değil.</translation> -<translation id="4983496916481712098">Google Cloud Printer</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_uk.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_uk.xtb deleted file mode 100644 index aa33a6f..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_uk.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="uk"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>Драйвер XPS<ph name="XPS_URL_END"/> не встановлено.</translation> -<translation id="4983496916481712098">Веб-доступний принтер Google</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_vi.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_vi.xtb deleted file mode 100644 index 72ed681..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_vi.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="vi"> -<translation id="4659506378548526631"><ph name="XPS_URL"/>Trình điều khiển XPS<ph name="XPS_URL_END"/> chưa được cài đặt.</translation> -<translation id="4983496916481712098">Google Cloud Printer</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_zh-CN.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_zh-CN.xtb deleted file mode 100644 index 259b52b..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_zh-CN.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="zh-CN"> -<translation id="4659506378548526631">未安装 <ph name="XPS_URL"/>XPS 驱动程序<ph name="XPS_URL_END"/>。</translation> -<translation id="4983496916481712098">Google 云端打印机</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_zh-HK.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_zh-HK.xtb deleted file mode 100644 index 820244f9..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_zh-HK.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="zh-HK"> -<translation id="4659506378548526631">未安裝 <ph name="XPS_URL"/>XPS 驅動程式<ph name="XPS_URL_END"/>。</translation> -<translation id="4983496916481712098">Google 雲端印表機</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_zh-TW.xtb b/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_zh-TW.xtb deleted file mode 100644 index 00dad44..0000000 --- a/cloud_print/virtual_driver/win/install/resources/virtual_driver_setup_resources_zh-TW.xtb +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="zh-TW"> -<translation id="4659506378548526631">未安裝 <ph name="XPS_URL"/>XPS 驅動程式<ph name="XPS_URL_END"/>。</translation> -<translation id="4983496916481712098">Google 雲端印表機</translation> -</translationbundle>
diff --git a/cloud_print/virtual_driver/win/install/setup.cc b/cloud_print/virtual_driver/win/install/setup.cc deleted file mode 100644 index 5f56f30..0000000 --- a/cloud_print/virtual_driver/win/install/setup.cc +++ /dev/null
@@ -1,434 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <windows.h> -#include <setupapi.h> // Must be included after windows.h -#include <winspool.h> -#include <stddef.h> - -#include <iomanip> -#include <string> - -#include "base/at_exit.h" -#include "base/command_line.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/path_service.h" -#include "base/process/launch.h" -#include "base/process/process.h" -#include "base/strings/string_util.h" -#include "base/win/windows_version.h" -#include "cloud_print/common/win/cloud_print_utils.h" -#include "cloud_print/common/win/install_utils.h" -#include "cloud_print/virtual_driver/win/install/grit/virtual_driver_setup_resources.h" -#include "cloud_print/virtual_driver/win/virtual_driver_consts.h" -#include "cloud_print/virtual_driver/win/virtual_driver_helpers.h" - -#include <strsafe.h> // Must be after base headers to avoid deprecation - // warnings. - -namespace cloud_print { - -namespace { - -const wchar_t kNameValue[] = L"GCP Virtual Driver"; -const wchar_t kUninstallId[] = L"{74AA24E0-AC50-4B28-BA46-9CF05467C9B7}"; -const wchar_t kGcpUrl[] = L"https://www.google.com/cloudprint"; - -const wchar_t kInfFileName[] = L"gcp_driver.inf"; - -const char kDelete[] = "delete"; -const char kInstallSwitch[] = "install"; -const char kRegisterSwitch[] = "register"; -const char kUninstallSwitch[] = "uninstall"; -const char kUnregisterSwitch[] = "unregister"; - -base::FilePath GetSystemPath(const std::wstring& binary) { - base::FilePath path; - if (!base::PathService::Get(base::DIR_SYSTEM, &path)) { - LOG(ERROR) << "Unable to get system path."; - return path; - } - return path.Append(binary); -} - -base::FilePath GetNativeSystemPath(const std::wstring& binary) { - if (!IsSystem64Bit()) - return GetSystemPath(binary); - base::FilePath path; - // Sysnative will bypass filesystem redirection and give us - // the location of the 64bit system32 from a 32 bit process. - if (!base::PathService::Get(base::DIR_WINDOWS, &path)) { - LOG(ERROR) << "Unable to get windows path."; - return path; - } - return path.Append(L"sysnative").Append(binary); -} - -void SpoolerServiceCommand(const char* command) { - base::FilePath net_path = GetNativeSystemPath(L"net"); - if (net_path.empty()) - return; - base::CommandLine command_line(net_path); - command_line.AppendArg(command); - command_line.AppendArg("spooler"); - command_line.AppendArg("/y"); - - base::LaunchOptions options; - options.wait = true; - options.start_hidden = true; - VLOG(0) << command_line.GetCommandLineString(); - base::LaunchProcess(command_line, options); -} - -HRESULT RegisterPortMonitor(bool install, const base::FilePath& install_path) { - DCHECK(install || install_path.empty()); - base::FilePath target_path = GetNativeSystemPath(GetPortMonitorDllName()); - if (target_path.empty()) { - LOG(ERROR) << "Unable to get port monitor target path."; - return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND); - } - if (install) { - base::FilePath source_path = install_path.Append(GetPortMonitorDllName()); - if (!base::CopyFile(source_path, target_path)) { - LOG(ERROR) << "Unable copy port monitor dll from " << source_path.value() - << " to " << target_path.value(); - return GetLastHResult(); - } - } else if (!base::PathExists(target_path)) { - // Already removed. Just "succeed" silently. - return S_OK; - } - - base::FilePath regsvr32_path = GetNativeSystemPath(L"regsvr32.exe"); - if (regsvr32_path.empty()) { - LOG(ERROR) << "Can't find regsvr32.exe."; - return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND); - } - - base::CommandLine command_line(regsvr32_path); - command_line.AppendArg("/s"); - if (!install) { - command_line.AppendArg("/u"); - } - - // Use system32 path here because otherwise ::AddMonitor would fail. - command_line.AppendArgPath(GetSystemPath(GetPortMonitorDllName())); - - base::LaunchOptions options; - options.wait = true; - - base::Process regsvr32_process = - base::LaunchProcess(command_line.GetCommandLineString(), options); - if (!regsvr32_process.IsValid()) { - LOG(ERROR) << "Unable to launch regsvr32.exe."; - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); - } - - DWORD exit_code = S_OK; - if (install) { - if (!GetExitCodeProcess(regsvr32_process.Handle(), &exit_code)) { - LOG(ERROR) << "Unable to get regsvr32.exe exit code."; - return GetLastHResult(); - } - if (exit_code != 0) { - LOG(ERROR) << "Regsvr32.exe failed with " << exit_code; - return HRESULT_FROM_WIN32(exit_code); - } - } else { - if (!base::DeleteFile(target_path)) { - SpoolerServiceCommand("stop"); - bool deleted = base::DeleteFile(target_path); - SpoolerServiceCommand("start"); - - if (!deleted) { - LOG(ERROR) << "Unable to delete " << target_path.value(); - return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED); - } - } - } - return S_OK; -} - -HRESULT InstallDriver(const base::FilePath& install_path) { - DWORD size = MAX_PATH * 10; - wchar_t package_path[MAX_PATH * 10] = {0}; - - base::FilePath inf_file = install_path.Append(kInfFileName); - std::wstring driver_name = LoadLocalString(IDS_DRIVER_NAME); - - HRESULT result = UploadPrinterDriverPackage( - NULL, inf_file.value().c_str(), NULL, - UPDP_SILENT_UPLOAD | UPDP_UPLOAD_ALWAYS, NULL, package_path, &size); - if (FAILED(result)) { - LOG(WARNING) - << "Uploading the printer driver package to the driver cache silently " - << "failed. Will retry with user UI. HRESULT=0x" << std::setbase(16) - << result; - - result = UploadPrinterDriverPackage( - NULL, inf_file.value().c_str(), NULL, UPDP_UPLOAD_ALWAYS, - GetForegroundWindow(), package_path, &size); - - if (FAILED(result)) { - LOG(WARNING) - << "Uploading the printer driver package to the driver cache failed" - << "with user UI. Aborting."; - return result; - } - } - - result = InstallPrinterDriverFromPackage( - NULL, package_path, driver_name.c_str(), NULL, IPDFP_COPY_ALL_FILES); - if (FAILED(result)) { - LOG(ERROR) << "Installing the printer driver failed."; - } - return result; -} - -HRESULT UninstallDriver(const base::FilePath& install_path) { - base::FilePath inf_file = install_path.Append(kInfFileName); - int tries = 3; - - while (!DeletePrinterDriverPackage(NULL, inf_file.value().c_str(), NULL)) { - if (GetLastError() == ERROR_UNKNOWN_PRINTER_DRIVER) { - LOG(WARNING) << "Print driver is already uninstalled."; - return S_OK; - } - // After deleting the printer it can take a few seconds before - // the driver is free for deletion. Retry a few times before giving up. - LOG(WARNING) << "Attempt to delete printer driver failed. Retrying."; - tries--; - Sleep(2000); - } - if (tries <= 0) { - HRESULT result = GetLastHResult(); - LOG(ERROR) << "Unable to delete printer driver."; - return result; - } - return S_OK; -} - -HRESULT InstallPrinter(void) { - PRINTER_INFO_2 printer_info = {0}; - - // None of the print API structures likes constant strings even though they - // don't modify the string. const_casting is the cleanest option. - std::wstring driver_name = LoadLocalString(IDS_DRIVER_NAME); - printer_info.pDriverName = const_cast<LPWSTR>(driver_name.c_str()); - printer_info.pPrinterName = const_cast<LPWSTR>(driver_name.c_str()); - printer_info.pComment = const_cast<LPWSTR>(driver_name.c_str()); - printer_info.pLocation = const_cast<LPWSTR>(kGcpUrl); - std::u16string port_name; - printer_info.pPortName = const_cast<LPWSTR>(kPortName); - printer_info.Attributes = PRINTER_ATTRIBUTE_DIRECT | PRINTER_ATTRIBUTE_LOCAL; - printer_info.pPrintProcessor = const_cast<LPWSTR>(L"winprint"); - HANDLE handle = AddPrinter(NULL, 2, reinterpret_cast<BYTE*>(&printer_info)); - if (handle == NULL) { - HRESULT result = GetLastHResult(); - LOG(ERROR) << "Unable to add printer"; - return result; - } - ClosePrinter(handle); - return S_OK; -} - -HRESULT UninstallPrinter(void) { - HANDLE handle = NULL; - PRINTER_DEFAULTS printer_defaults = {0}; - printer_defaults.DesiredAccess = PRINTER_ALL_ACCESS; - std::wstring driver_name = LoadLocalString(IDS_DRIVER_NAME); - if (!OpenPrinter(const_cast<LPWSTR>(driver_name.c_str()), &handle, - &printer_defaults)) { - // If we can't open the printer, it was probably already removed. - LOG(WARNING) << "Unable to open printer"; - return S_OK; - } - if (!DeletePrinter(handle)) { - HRESULT result = GetLastHResult(); - LOG(ERROR) << "Unable to delete printer"; - ClosePrinter(handle); - return result; - } - ClosePrinter(handle); - return S_OK; -} - -bool IsOSSupported() { - // We don't support Vista or older. - return base::win::GetVersion() >= base::win::Version::WIN7; -} - -HRESULT RegisterVirtualDriver(const base::FilePath& install_path) { - HRESULT result = S_OK; - - DCHECK(base::DirectoryExists(install_path)); - if (!IsOSSupported()) { - LOG(ERROR) << "Requires Windows 7 or later."; - return HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION); - } - - result = InstallDriver(install_path); - if (FAILED(result)) { - LOG(ERROR) << "Unable to install driver."; - return result; - } - - result = RegisterPortMonitor(true, install_path); - if (FAILED(result)) { - LOG(ERROR) << "Unable to register port monitor."; - return result; - } - - result = InstallPrinter(); - if (FAILED(result) && - result != HRESULT_FROM_WIN32(ERROR_PRINTER_ALREADY_EXISTS)) { - LOG(ERROR) << "Unable to install printer."; - return result; - } - return S_OK; -} - -HRESULT TryUnregisterVirtualDriver(const base::FilePath& install_path) { - HRESULT result = S_OK; - result = UninstallPrinter(); - if (FAILED(result)) { - LOG(ERROR) << "Unable to delete printer."; - return result; - } - result = UninstallDriver(install_path); - if (FAILED(result)) { - LOG(ERROR) << "Unable to remove driver."; - return result; - } - // The second argument is ignored if the first is false. - result = RegisterPortMonitor(false, base::FilePath()); - if (FAILED(result)) { - LOG(ERROR) << "Unable to remove port monitor."; - return result; - } - return S_OK; -} - -HRESULT UnregisterVirtualDriver(const base::FilePath& install_path) { - HRESULT hr = S_FALSE; - for (int i = 0; i < 2; ++i) { - hr = TryUnregisterVirtualDriver(install_path); - if (SUCCEEDED(hr)) { - break; - } - // Restart spooler and try again. - SpoolerServiceCommand("stop"); - SpoolerServiceCommand("start"); - } - return hr; -} - -HRESULT DoUninstall(const base::FilePath& install_path) { - DeleteGoogleUpdateKeys(kGoogleUpdateProductId); - HRESULT result = UnregisterVirtualDriver(install_path); - if (FAILED(result)) - return result; - DeleteUninstallKey(kUninstallId); - DeleteProgramDir(kDelete); - return S_OK; -} - -HRESULT DoUnregister(const base::FilePath& install_path) { - return UnregisterVirtualDriver(install_path); -} - -HRESULT DoRegister(const base::FilePath& install_path) { - HRESULT result = UnregisterVirtualDriver(install_path); - if (FAILED(result)) - return result; - return RegisterVirtualDriver(install_path); -} - -HRESULT DoDelete(const base::FilePath& install_path) { - if (install_path.value().empty()) - return E_INVALIDARG; - if (!base::DirectoryExists(install_path)) - return S_FALSE; - Sleep(5000); // Give parent some time to exit. - return base::DeletePathRecursively(install_path) ? S_OK : E_FAIL; -} - -HRESULT DoInstall(const base::FilePath& install_path) { - HRESULT result = UnregisterVirtualDriver(install_path); - if (FAILED(result)) { - LOG(ERROR) << "Unable to unregister."; - return result; - } - base::FilePath old_install_path = GetInstallLocation(kUninstallId); - if (!old_install_path.value().empty() && install_path != old_install_path) { - if (base::DirectoryExists(old_install_path)) - base::DeletePathRecursively(old_install_path); - } - CreateUninstallKey(kUninstallId, LoadLocalString(IDS_DRIVER_NAME), - kUninstallSwitch); - result = RegisterVirtualDriver(install_path); - if (FAILED(result)) - return result; - SetGoogleUpdateKeys(kGoogleUpdateProductId, kNameValue); - return result; -} - -HRESULT ExecuteCommands() { - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - - base::FilePath exe_path; - if (!base::PathService::Get(base::DIR_EXE, &exe_path) || - !base::DirectoryExists(exe_path)) { - return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND); - } - - if (command_line.HasSwitch(kDelete)) { - return DoDelete(command_line.GetSwitchValuePath(kDelete)); - } else if (command_line.HasSwitch(kUninstallSwitch)) { - return DoUninstall(exe_path); - } else if (command_line.HasSwitch(kInstallSwitch)) { - return DoInstall(exe_path); - } else if (command_line.HasSwitch(kUnregisterSwitch)) { - return DoUnregister(exe_path); - } else if (command_line.HasSwitch(kRegisterSwitch)) { - return DoRegister(exe_path); - } - - return E_INVALIDARG; -} - -} // namespace - -} // namespace cloud_print - -int WINAPI WinMain(__in HINSTANCE hInstance, - __in HINSTANCE hPrevInstance, - __in LPSTR lpCmdLine, - __in int nCmdShow) { - base::AtExitManager at_exit_manager; - base::CommandLine::Init(0, nullptr); - - HRESULT retval = cloud_print::ExecuteCommands(); - - if (retval == HRESULT_FROM_WIN32(ERROR_BAD_DRIVER)) { - cloud_print::SetGoogleUpdateError( - cloud_print::kGoogleUpdateProductId, - cloud_print::LoadLocalString(IDS_ERROR_NO_XPS)); - } else if (FAILED(retval)) { - cloud_print::SetGoogleUpdateError(cloud_print::kGoogleUpdateProductId, - retval); - } - - VLOG(0) << cloud_print::GetErrorMessage(retval) << " HRESULT=0x" - << std::setbase(16) << retval; - - // Installer is silent by default as required by Google Update. - if (base::CommandLine::ForCurrentProcess()->HasSwitch("verbose")) { - cloud_print::DisplayWindowsMessage( - nullptr, retval, cloud_print::LoadLocalString(IDS_DRIVER_NAME)); - } - return retval; -}
diff --git a/cloud_print/virtual_driver/win/install/virtual_driver_setup_exe.ver b/cloud_print/virtual_driver/win/install/virtual_driver_setup_exe.ver deleted file mode 100644 index 1667c07..0000000 --- a/cloud_print/virtual_driver/win/install/virtual_driver_setup_exe.ver +++ /dev/null
@@ -1,3 +0,0 @@ -INTERNAL_NAME=virtual_driver_setup.exe -ORIGINAL_FILENAME=virtual_driver_setup.exe -FILETYPE=0x1L
diff --git a/cloud_print/virtual_driver/win/install/virtual_driver_setup_resources.grd b/cloud_print/virtual_driver/win/install/virtual_driver_setup_resources.grd deleted file mode 100644 index 1113da1..0000000 --- a/cloud_print/virtual_driver/win/install/virtual_driver_setup_resources.grd +++ /dev/null
@@ -1,140 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- -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. ---> - - -<grit latest_public_release="0" current_release="1" - output_all_resource_defines="false"> - <outputs> - <output filename="grit/virtual_driver_setup_resources.h" type="rc_header"> - <emit emit_type='prepend'></emit> - </output> - <output filename="virtual_driver_setup_resources_ar.rc" type="rc_all" lang="ar" language_section="lang"/> - <output filename="virtual_driver_setup_resources_bg.rc" type="rc_all" lang="bg" language_section="lang"/> - <output filename="virtual_driver_setup_resources_bn.rc" type="rc_all" lang="bn" language_section="lang"/> - <output filename="virtual_driver_setup_resources_ca.rc" type="rc_all" lang="ca" language_section="lang"/> - <output filename="virtual_driver_setup_resources_cs.rc" type="rc_all" lang="cs" language_section="lang"/> - <output filename="virtual_driver_setup_resources_da.rc" type="rc_all" lang="da" language_section="lang"/> - <output filename="virtual_driver_setup_resources_de.rc" type="rc_all" lang="de" language_section="lang"/> - <output filename="virtual_driver_setup_resources_el.rc" type="rc_all" lang="el" language_section="lang"/> - <output filename="virtual_driver_setup_resources_en.rc" type="rc_all" lang="en" language_section="lang"/> - <output filename="virtual_driver_setup_resources_en-GB.rc" type="rc_all" lang="en-GB" language_section="lang"/> - <output filename="virtual_driver_setup_resources_es.rc" type="rc_all" lang="es" language_section="lang"/> - <output filename="virtual_driver_setup_resources_es-419.rc" type="rc_all" lang="es-419" language_section="lang"/> - <output filename="virtual_driver_setup_resources_et.rc" type="rc_all" lang="et" language_section="lang"/> - <output filename="virtual_driver_setup_resources_fa.rc" type="rc_all" lang="fa" language_section="lang"/> - <output filename="virtual_driver_setup_resources_fi.rc" type="rc_all" lang="fi" language_section="lang"/> - <output filename="virtual_driver_setup_resources_fil.rc" type="rc_all" lang="fil" language_section="lang"/> - <output filename="virtual_driver_setup_resources_fr.rc" type="rc_all" lang="fr" language_section="lang"/> - <output filename="virtual_driver_setup_resources_gu.rc" type="rc_all" lang="gu" language_section="lang"/> - <output filename="virtual_driver_setup_resources_he.rc" type="rc_all" lang="he" language_section="lang"/> - <output filename="virtual_driver_setup_resources_hi.rc" type="rc_all" lang="hi" language_section="lang"/> - <output filename="virtual_driver_setup_resources_hr.rc" type="rc_all" lang="hr" language_section="lang"/> - <output filename="virtual_driver_setup_resources_hu.rc" type="rc_all" lang="hu" language_section="lang"/> - <output filename="virtual_driver_setup_resources_id.rc" type="rc_all" lang="id" language_section="lang"/> - <output filename="virtual_driver_setup_resources_it.rc" type="rc_all" lang="it" language_section="lang"/> - <output filename="virtual_driver_setup_resources_ja.rc" type="rc_all" lang="ja" language_section="lang"/> - <output filename="virtual_driver_setup_resources_kn.rc" type="rc_all" lang="kn" language_section="lang"/> - <output filename="virtual_driver_setup_resources_ko.rc" type="rc_all" lang="ko" language_section="lang"/> - <output filename="virtual_driver_setup_resources_lt.rc" type="rc_all" lang="lt" language_section="lang"/> - <output filename="virtual_driver_setup_resources_lv.rc" type="rc_all" lang="lv" language_section="lang"/> - <output filename="virtual_driver_setup_resources_ml.rc" type="rc_all" lang="ml" language_section="lang"/> - <output filename="virtual_driver_setup_resources_mr.rc" type="rc_all" lang="mr" language_section="lang"/> - <output filename="virtual_driver_setup_resources_ms.rc" type="rc_all" lang="ms" language_section="lang"/> - <output filename="virtual_driver_setup_resources_nl.rc" type="rc_all" lang="nl" language_section="lang"/> - <!-- The translation console uses 'no' for Norwegian Bokmål. It should be 'nb'. --> - <output filename="virtual_driver_setup_resources_nb.rc" type="rc_all" lang="no" language_section="lang"/> - <output filename="virtual_driver_setup_resources_pl.rc" type="rc_all" lang="pl" language_section="lang"/> - <output filename="virtual_driver_setup_resources_pt-BR.rc" type="rc_all" lang="pt-BR" language_section="lang"/> - <output filename="virtual_driver_setup_resources_pt-PT.rc" type="rc_all" lang="pt-PT" language_section="lang"/> - <output filename="virtual_driver_setup_resources_ro.rc" type="rc_all" lang="ro" language_section="lang"/> - <output filename="virtual_driver_setup_resources_ru.rc" type="rc_all" lang="ru" language_section="lang"/> - <output filename="virtual_driver_setup_resources_sk.rc" type="rc_all" lang="sk" language_section="lang"/> - <output filename="virtual_driver_setup_resources_sl.rc" type="rc_all" lang="sl" language_section="lang"/> - <output filename="virtual_driver_setup_resources_sr.rc" type="rc_all" lang="sr" language_section="lang"/> - <output filename="virtual_driver_setup_resources_sv.rc" type="rc_all" lang="sv" language_section="lang"/> - <output filename="virtual_driver_setup_resources_sw.rc" type="rc_all" lang="sw" language_section="lang"/> - <output filename="virtual_driver_setup_resources_ta.rc" type="rc_all" lang="ta" language_section="lang"/> - <output filename="virtual_driver_setup_resources_te.rc" type="rc_all" lang="te" language_section="lang"/> - <output filename="virtual_driver_setup_resources_th.rc" type="rc_all" lang="th" language_section="lang"/> - <output filename="virtual_driver_setup_resources_tr.rc" type="rc_all" lang="tr" language_section="lang"/> - <output filename="virtual_driver_setup_resources_uk.rc" type="rc_all" lang="uk" language_section="lang"/> - <output filename="virtual_driver_setup_resources_vi.rc" type="rc_all" lang="vi" language_section="lang"/> - <output filename="virtual_driver_setup_resources_zh-CN.rc" type="rc_all" lang="zh-CN" language_section="lang"/> - <output filename="virtual_driver_setup_resources_zh-TW.rc" type="rc_all" lang="zh-TW" language_section="lang"/> - </outputs> - <translations> - <file path="resources/virtual_driver_setup_resources_ar.xtb" lang="ar"/> - <file path="resources/virtual_driver_setup_resources_bg.xtb" lang="bg"/> - <file path="resources/virtual_driver_setup_resources_bn.xtb" lang="bn"/> - <file path="resources/virtual_driver_setup_resources_ca.xtb" lang="ca"/> - <file path="resources/virtual_driver_setup_resources_cs.xtb" lang="cs"/> - <file path="resources/virtual_driver_setup_resources_da.xtb" lang="da"/> - <file path="resources/virtual_driver_setup_resources_de.xtb" lang="de"/> - <file path="resources/virtual_driver_setup_resources_el.xtb" lang="el"/> - <file path="resources/virtual_driver_setup_resources_en-GB.xtb" lang="en-GB"/> - <file path="resources/virtual_driver_setup_resources_es.xtb" lang="es"/> - <file path="resources/virtual_driver_setup_resources_es-419.xtb" lang="es-419"/> - <file path="resources/virtual_driver_setup_resources_et.xtb" lang="et"/> - <file path="resources/virtual_driver_setup_resources_fa.xtb" lang="fa"/> - <file path="resources/virtual_driver_setup_resources_fi.xtb" lang="fi"/> - <file path="resources/virtual_driver_setup_resources_fil.xtb" lang="fil" /> - <file path="resources/virtual_driver_setup_resources_fr.xtb" lang="fr" /> - <file path="resources/virtual_driver_setup_resources_gu.xtb" lang="gu" /> - <file path="resources/virtual_driver_setup_resources_he.xtb" lang="he" /> - <file path="resources/virtual_driver_setup_resources_hi.xtb" lang="hi" /> - <file path="resources/virtual_driver_setup_resources_hr.xtb" lang="hr" /> - <file path="resources/virtual_driver_setup_resources_hu.xtb" lang="hu" /> - <file path="resources/virtual_driver_setup_resources_id.xtb" lang="id" /> - <file path="resources/virtual_driver_setup_resources_it.xtb" lang="it" /> - <file path="resources/virtual_driver_setup_resources_ja.xtb" lang="ja" /> - <file path="resources/virtual_driver_setup_resources_kn.xtb" lang="kn" /> - <file path="resources/virtual_driver_setup_resources_ko.xtb" lang="ko" /> - <file path="resources/virtual_driver_setup_resources_lt.xtb" lang="lt" /> - <file path="resources/virtual_driver_setup_resources_lv.xtb" lang="lv" /> - <file path="resources/virtual_driver_setup_resources_ml.xtb" lang="ml" /> - <file path="resources/virtual_driver_setup_resources_mr.xtb" lang="mr" /> - <file path="resources/virtual_driver_setup_resources_ms.xtb" lang="ms" /> - <file path="resources/virtual_driver_setup_resources_nl.xtb" lang="nl" /> - <file path="resources/virtual_driver_setup_resources_no.xtb" lang="no" /> - <file path="resources/virtual_driver_setup_resources_pl.xtb" lang="pl" /> - <file path="resources/virtual_driver_setup_resources_pt-BR.xtb" lang="pt-BR" /> - <file path="resources/virtual_driver_setup_resources_pt-PT.xtb" lang="pt-PT" /> - <file path="resources/virtual_driver_setup_resources_ro.xtb" lang="ro" /> - <file path="resources/virtual_driver_setup_resources_ru.xtb" lang="ru" /> - <file path="resources/virtual_driver_setup_resources_sk.xtb" lang="sk" /> - <file path="resources/virtual_driver_setup_resources_sl.xtb" lang="sl" /> - <file path="resources/virtual_driver_setup_resources_sr.xtb" lang="sr" /> - <file path="resources/virtual_driver_setup_resources_sv.xtb" lang="sv" /> - <file path="resources/virtual_driver_setup_resources_sw.xtb" lang="sw" /> - <file path="resources/virtual_driver_setup_resources_ta.xtb" lang="ta" /> - <file path="resources/virtual_driver_setup_resources_te.xtb" lang="te" /> - <file path="resources/virtual_driver_setup_resources_th.xtb" lang="th" /> - <file path="resources/virtual_driver_setup_resources_tr.xtb" lang="tr" /> - <file path="resources/virtual_driver_setup_resources_uk.xtb" lang="uk" /> - <file path="resources/virtual_driver_setup_resources_vi.xtb" lang="vi" /> - <file path="resources/virtual_driver_setup_resources_zh-CN.xtb" lang="zh-CN" /> - <file path="resources/virtual_driver_setup_resources_zh-TW.xtb" lang="zh-TW" /> - </translations> - <release seq="1"> - <messages> - <message name="IDS_DRIVER_NAME" - meaning="Driver Name" desc="The user visible name of the printer we create and its associated driver."> - Google Cloud Printer - </message> - <message name="IDS_ERROR_NO_XPS" - meaning="Error message" desc="XPS driver is not installed."> - <ph name="xps_url"><a href="https://www.microsoft.com/download/details.aspx?id=11816"><ex><a href="https://www.microsoft.com/download/details.aspx?id=11816"></ex></ph>XPS driver<ph name="xps_url_end"></a><ex></a></ex></ph> is not installed. - </message> - </messages> - <includes> - <if expr="lang == 'en'"> - <include name="IDI_ICON" file="resources/cloudprint.ico" type="ICON" translateable="false" /> - </if> - </includes> - </release> -</grit>
diff --git a/cloud_print/virtual_driver/win/port_monitor/BUILD.gn b/cloud_print/virtual_driver/win/port_monitor/BUILD.gn deleted file mode 100644 index cf9bdb9..0000000 --- a/cloud_print/virtual_driver/win/port_monitor/BUILD.gn +++ /dev/null
@@ -1,102 +0,0 @@ -# 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. - -import("//build/config/compiler/compiler.gni") -import("//chrome/process_version_rc_template.gni") - -assert(is_win) - -group("port_monitor") { - public_deps = [ ":port_monitor_dll" ] -} - -shared_library("port_monitor_dll") { - output_name = "gcp_portmon" - if (current_cpu == "x64") { - output_name = "gcp_portmon64" - } - - sources = [ - "port_monitor.def", - "port_monitor_dll.cc", - ] - - deps = [ - ":lib", - ":resources", - "//base", - "//chrome/common:constants", - "//chrome/common:version_header", - "//cloud_print/common", - "//cloud_print/virtual_driver/win", - ] - - libs = [ "userenv.lib" ] -} - -group("copy_gcp_portmon_binaries") { - deps = [ ":copy_gcp_portmon_dll" ] - # TODO(pastarmovj): Find some way to reference the pdb file for the 64bit dll - # simply using it in the sources directive causes gn to error when generating - # the build files. -} - -if (current_cpu == "x64") { - copy("copy_gcp_portmon_dll") { - sources = [ "$root_out_dir/gcp_portmon64.dll" ] - outputs = [ "$root_out_dir/gcp_portmon.dll" ] - deps = [ ":port_monitor_dll" ] - } -} else { - # Make sure that we have a copy of gcp_portmon64.dll in the root out - # directory. - if (is_clang) { - gcp_portmon64_toolchain = "//build/toolchain/win:win_clang_x64" - } else { - gcp_portmon64_toolchain = "//build/toolchain/win:x64" - } - gcp_portmon64_label = ":port_monitor_dll($gcp_portmon64_toolchain)" - - gcp_portmon64_out_dir = get_label_info(gcp_portmon64_label, "root_out_dir") - - if (symbol_level > 0) { - copy("copy_gcp_portmon_pdb") { - visibility = [ ":copy_gcp_portmon_dll" ] - sources = [ "$gcp_portmon64_out_dir/gcp_portmon64.dll.pdb" ] - outputs = [ "$root_out_dir/{{source_file_part}}" ] - deps = [ gcp_portmon64_label ] - } - } - copy("copy_gcp_portmon_dll") { - sources = [ "$gcp_portmon64_out_dir/gcp_portmon64.dll" ] - outputs = [ "$root_out_dir/{{source_file_part}}" ] - deps = [ gcp_portmon64_label ] - if (symbol_level > 0) { - deps += [ ":copy_gcp_portmon_pdb" ] - } - } -} - -source_set("lib") { - sources = [ - "port_monitor.cc", - "port_monitor.h", - ] - - deps = [ - "//base", - "//chrome/common:constants", - "//chrome/installer/launcher_support", - "//cloud_print/common", - "//cloud_print/virtual_driver/win", - ] -} - -process_version_rc_template("resources") { - sources = [ "../gcp_portmon_dll.ver" ] - - # Note: target_gen_dir will be different for each toolchain so the output - # name doesn't need mangling. - output = "$target_gen_dir/gcp_portmon_dll.rc" -}
diff --git a/cloud_print/virtual_driver/win/port_monitor/port_monitor.cc b/cloud_print/virtual_driver/win/port_monitor/port_monitor.cc deleted file mode 100644 index a25a6d7..0000000 --- a/cloud_print/virtual_driver/win/port_monitor/port_monitor.cc +++ /dev/null
@@ -1,683 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "cloud_print/virtual_driver/win/port_monitor/port_monitor.h" - -#include <windows.h> -#include <lmcons.h> -#include <shellapi.h> -#include <shlobj.h> -#include <stddef.h> -#include <stdint.h> -#include <strsafe.h> -#include <userenv.h> -#include <winspool.h> - -#include <memory> -#include <string> - -#include "base/at_exit.h" -#include "base/command_line.h" -#include "base/files/file_enumerator.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/memory/raw_ptr.h" -#include "base/path_service.h" -#include "base/process/launch.h" -#include "base/process/process.h" -#include "base/strings/string_util.h" -#include "base/win/registry.h" -#include "base/win/scoped_handle.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/installer/launcher_support/chrome_launcher_support.h" -#include "cloud_print/common/win/cloud_print_utils.h" -#include "cloud_print/virtual_driver/win/port_monitor/spooler_win.h" -#include "cloud_print/virtual_driver/win/virtual_driver_consts.h" -#include "cloud_print/virtual_driver/win/virtual_driver_helpers.h" - -namespace cloud_print { - -namespace { - -const wchar_t kIePath[] = L"Internet Explorer\\iexplore.exe"; - -const char kChromeInstallUrl[] = - "https://google.com/cloudprint/learn/chrome.html"; - -const wchar_t kCloudPrintRegKey[] = L"Software\\Google\\CloudPrint"; - -const wchar_t kXpsMimeType[] = L"application/vnd.ms-xpsdocument"; - -const wchar_t kAppDataDir[] = L"Google\\Cloud Printer"; - -const wchar_t kDocumentPathPlaceHolder[] = L"%%Document_Path%%"; - -const wchar_t kDocumentTypePlaceHolder[] = L"%%Document_Type%%"; - -const wchar_t kJobTitlePlaceHolder[] = L"%%Job_Title%%"; - -struct MonitorData { - std::unique_ptr<base::AtExitManager> at_exit_manager; -}; - -struct PortData { - PortData() : job_id(0), printer_handle(NULL), file(nullptr) {} - ~PortData() { Close(); } - void Close() { - if (printer_handle) { - ClosePrinter(printer_handle); - printer_handle = NULL; - } - if (file) { - base::CloseFile(file); - file = nullptr; - } - } - DWORD job_id; - HANDLE printer_handle; - raw_ptr<FILE> file; - base::FilePath file_path; -}; - -typedef struct { ACCESS_MASK granted_access; } XcvUiData; - -MONITORUI g_monitor_ui = {sizeof(MONITORUI), MonitorUiAddPortUi, - MonitorUiConfigureOrDeletePortUI, - MonitorUiConfigureOrDeletePortUI}; - -MONITOR2 g_monitor_2 = {sizeof(MONITOR2), - Monitor2EnumPorts, - Monitor2OpenPort, - nullptr, // OpenPortEx is not supported. - Monitor2StartDocPort, - Monitor2WritePort, - Monitor2ReadPort, - Monitor2EndDocPort, - Monitor2ClosePort, - nullptr, // AddPort is not supported. - nullptr, // AddPortEx is not supported. - nullptr, // ConfigurePort is not supported. - nullptr, // DeletePort is not supported. - nullptr, - nullptr, // SetPortTimeOuts is not supported. - Monitor2XcvOpenPort, - Monitor2XcvDataPort, - Monitor2XcvClosePort, - Monitor2Shutdown}; - -base::FilePath GetLocalAppDataLow() { - wchar_t system_buffer[MAX_PATH]; - if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, - system_buffer))) - return base::FilePath(); - return base::FilePath(system_buffer).DirName().AppendASCII("LocalLow"); -} - -base::FilePath GetAppDataDir() { - base::FilePath file_path = GetLocalAppDataLow(); - if (file_path.empty()) { - LOG(ERROR) << "Can't get app data dir"; - } - return file_path.Append(kAppDataDir); -} - -// Delete files which where not deleted by chrome. -void DeleteLeakedFiles(const base::FilePath& dir) { - base::Time delete_before = base::Time::Now() - base::Days(1); - base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES); - for (base::FilePath file_path = enumerator.Next(); !file_path.empty(); - file_path = enumerator.Next()) { - if (enumerator.GetInfo().GetLastModifiedTime() < delete_before) - base::DeleteFile(file_path); - } -} - -// Attempts to retrieve the title of the specified print job. -// On success returns TRUE and the first title_chars characters of the job title -// are copied into title. -// On failure returns FALSE and title is unmodified. -bool GetJobTitle(HANDLE printer_handle, DWORD job_id, std::wstring* title) { - DCHECK(printer_handle != NULL); - DCHECK(title != NULL); - DWORD bytes_needed = 0; - GetJob(printer_handle, job_id, 1, NULL, 0, &bytes_needed); - if (bytes_needed == 0) { - LOG(ERROR) << "Unable to get bytes needed for job info."; - return false; - } - std::unique_ptr<BYTE[]> buffer(new BYTE[bytes_needed]); - if (!GetJob(printer_handle, job_id, 1, buffer.get(), bytes_needed, - &bytes_needed)) { - LOG(ERROR) << "Unable to get job info."; - return false; - } - JOB_INFO_1* job_info = reinterpret_cast<JOB_INFO_1*>(buffer.get()); - *title = job_info->pDocument; - return true; -} - -// Handler for the UI functions exported by the port monitor. -// Verifies that a valid parent Window exists and then just displays an -// error message to let the user know that there is no interactive -// configuration. -void HandlePortUi(HWND hwnd, const std::wstring& caption) { - if (hwnd != NULL && IsWindow(hwnd)) { - DisplayWindowsMessage(hwnd, CO_E_NOT_SUPPORTED, cloud_print::kPortName); - } -} - -// Gets the primary token for the user that submitted the print job. -bool GetUserToken(HANDLE* primary_token) { - HANDLE token = NULL; - if (!OpenThreadToken(GetCurrentThread(), - TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, - FALSE, &token)) { - LOG(ERROR) << "Unable to get thread token."; - return false; - } - base::win::ScopedHandle token_scoped(token); - if (!DuplicateTokenEx( - token, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, NULL, - SecurityImpersonation, TokenPrimary, primary_token)) { - LOG(ERROR) << "Unable to get primary thread token."; - return false; - } - return true; -} - -bool LaunchCommandAsUser(const base::CommandLine& command) { - HANDLE token = NULL; - if (!GetUserToken(&token)) { - LOG(ERROR) << "Unable to get user token."; - return false; - } - base::win::ScopedHandle primary_token_scoped(token); - base::LaunchOptions options; - options.as_user = primary_token_scoped.Get(); - base::LaunchProcess(command, options); - return true; -} - -// Escape the command line argument as necessary per Microsoft rules. -// See QuoteForCommandLineToArgvW in base/command_line.cc -std::wstring EscapeCommandLineArg(const std::wstring& arg) { - std::wstring quotable_chars(L" \\\""); - if (arg.find_first_of(quotable_chars) == std::wstring::npos) { - // No quoting necessary. - return arg; - } - - std::wstring out; - out.push_back(L'"'); - for (size_t i = 0; i < arg.size(); ++i) { - if (arg[i] == '\\') { - // Find the extent of this run of backslashes. - size_t start = i, end = start + 1; - for (; end < arg.size() && arg[end] == '\\'; ++end) { - } - size_t backslash_count = end - start; - - // Backslashes are escapes only if the run is followed by a double quote. - // Since we also will end the string with a double quote, we escape for - // either a double quote or the end of the string. - if (end == arg.size() || arg[end] == '"') { - // To quote, we need to output 2x as many backslashes. - backslash_count *= 2; - } - for (size_t j = 0; j < backslash_count; ++j) - out.push_back('\\'); - - // Advance i to one before the end to balance i++ in loop. - i = end - 1; - } else if (arg[i] == '"') { - out.push_back('\\'); - out.push_back('"'); - } else { - out.push_back(arg[i]); - } - } - out.push_back('"'); - - return out; -} - -// Launch the print command as specified in the cloud print registry. -bool LaunchPrintCommandFromTemplate(const std::wstring& command_template, - const base::FilePath& xps_path, - const std::wstring& job_title) { - std::wstring command_string(command_template); - // Substitude the place holder with the document path wrapped in quotes. - base::ReplaceFirstSubstringAfterOffset( - &command_string, 0, kDocumentPathPlaceHolder, - EscapeCommandLineArg(xps_path.value())); - // Substitude the place holder with the document type wrapped in quotes. - base::ReplaceFirstSubstringAfterOffset( - &command_string, 0, kDocumentTypePlaceHolder, kXpsMimeType); - // Substitude the place holder with the job title wrapped in quotes. - base::ReplaceFirstSubstringAfterOffset(&command_string, 0, - kJobTitlePlaceHolder, - EscapeCommandLineArg(job_title)); - - base::CommandLine command = base::CommandLine::FromString(command_string); - - return LaunchCommandAsUser(command); -} - -// Launches a page to allow the user to download chrome. -// TODO(abodenha@chromium.org) Point to a custom page explaining what's wrong -// rather than the generic chrome download page. See -// http://code.google.com/p/chromium/issues/detail?id=112019 -void LaunchChromeDownloadPage() { - if (kIsUnittest) - return; - HANDLE token = NULL; - if (!GetUserToken(&token)) { - LOG(ERROR) << "Unable to get user token."; - return; - } - base::win::ScopedHandle token_scoped(token); - - // Consider using the shell to invoke the default browser instead of hardcoded - // reference to IE which might not be available on the system. - base::FilePath ie_path; - base::PathService::Get(base::DIR_PROGRAM_FILESX86, &ie_path); - ie_path = ie_path.Append(kIePath); - base::CommandLine command_line(ie_path); - command_line.AppendArg(kChromeInstallUrl); - - base::LaunchOptions options; - options.as_user = token_scoped.Get(); - base::LaunchProcess(command_line, options); -} - -// Returns false if the print job is being run in a context -// that shouldn't be launching Chrome. -bool ValidateCurrentUser() { - HANDLE token = NULL; - if (!GetUserToken(&token)) { - // If we can't get the token we're probably not impersonating - // the user, so validation should fail. - return false; - } - base::win::ScopedHandle token_scoped(token); - - DWORD session_id = 0; - DWORD dummy = 0; - if (!::GetTokenInformation(token_scoped.Get(), TokenSessionId, - reinterpret_cast<void*>(&session_id), - sizeof(DWORD), &dummy)) { - return false; - } - - return session_id != 0; -} -} // namespace - -std::wstring ReadStringFromRegistry(HKEY root, const wchar_t* path_name) { - base::win::RegKey gcp_key(root, kCloudPrintRegKey, KEY_READ); - std::wstring data; - gcp_key.ReadValue(path_name, &data); - return data; -} - -std::wstring ReadStringFromAnyRegistry(const wchar_t* path_name) { - std::wstring result = ReadStringFromRegistry(HKEY_CURRENT_USER, path_name); - if (!result.empty()) - return result; - return ReadStringFromRegistry(HKEY_LOCAL_MACHINE, path_name); -} - -base::FilePath GetChromeExePath() { - std::wstring value = ReadStringFromAnyRegistry(kChromeExePathRegValue); - if (!value.empty() && base::PathExists(base::FilePath(value))) - return base::FilePath(value); - return chrome_launcher_support::GetAnyChromePath(false /* is_sxs */); -} - -base::FilePath GetChromeProfilePath() { - std::wstring value = ReadStringFromAnyRegistry(kChromeProfilePathRegValue); - if (!value.empty() && base::DirectoryExists(base::FilePath(value))) - return base::FilePath(value); - return base::FilePath(); -} - -// Launches the Cloud Print dialog in Chrome. -bool LaunchChromePrintDialog(const base::FilePath& xps_path, - const std::wstring& job_title) { - base::FilePath chrome_path = GetChromeExePath(); - if (chrome_path.empty()) { - LOG(ERROR) << "Unable to get chrome exe path."; - LaunchChromeDownloadPage(); - return false; - } - - base::CommandLine command_line(chrome_path); - - base::FilePath chrome_profile = GetChromeProfilePath(); - if (!chrome_profile.empty()) - command_line.AppendSwitchPath(switches::kUserDataDir, chrome_profile); - - command_line.AppendSwitchPath(switches::kCloudPrintFile, xps_path); - command_line.AppendSwitchNative(switches::kCloudPrintFileType, kXpsMimeType); - command_line.AppendSwitchNative(switches::kCloudPrintJobTitle, job_title); - - return LaunchCommandAsUser(command_line); -} - -std::wstring GetPrintCommandTemplate() { - return ReadStringFromAnyRegistry(kPrintCommandRegValue); -} - -// Launches the print command. This will either launch Chrome to display the -// Cloud Print dialog or another exe as specified in the cloud print registry. -// xps_path references a file to print. -// job_title is the title to be used for the resulting print job. -bool LaunchPrintCommand(const base::FilePath& xps_path, - const std::wstring& job_title) { - std::wstring command_template = GetPrintCommandTemplate(); - if (!command_template.empty()) { - return LaunchPrintCommandFromTemplate(command_template, xps_path, - job_title); - } else { - return LaunchChromePrintDialog(xps_path, job_title); - } -} - -BOOL WINAPI Monitor2EnumPorts(HANDLE, - wchar_t*, - DWORD level, - BYTE* ports, - DWORD ports_size, - DWORD* needed_bytes, - DWORD* returned) { - if (needed_bytes == NULL) { - LOG(ERROR) << "needed_bytes should not be NULL."; - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - if (level == 1) { - *needed_bytes = sizeof(PORT_INFO_1); - } else if (level == 2) { - *needed_bytes = sizeof(PORT_INFO_2); - } else { - LOG(ERROR) << "Level " << level << "is not supported."; - SetLastError(ERROR_INVALID_LEVEL); - return FALSE; - } - *needed_bytes += static_cast<DWORD>(cloud_print::kPortNameSize); - if (ports_size < *needed_bytes) { - LOG(WARNING) << *needed_bytes << " bytes are required. Only " << ports_size - << " were allocated."; - SetLastError(ERROR_INSUFFICIENT_BUFFER); - return FALSE; - } - if (ports == NULL) { - LOG(ERROR) << "ports should not be NULL."; - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - if (returned == NULL) { - LOG(ERROR) << "returned should not be NULL."; - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - // Windows expects any strings refernced by PORT_INFO_X structures to - // appear at the END of the buffer referenced by ports. Placing - // strings immediately after the PORT_INFO_X structure will cause - // EnumPorts to fail until the spooler is restarted. - // This is NOT mentioned in the documentation. - wchar_t* string_target = reinterpret_cast<wchar_t*>( - ports + ports_size - cloud_print::kPortNameSize); - if (level == 1) { - PORT_INFO_1* port_info = reinterpret_cast<PORT_INFO_1*>(ports); - port_info->pName = string_target; - StringCbCopy(port_info->pName, cloud_print::kPortNameSize, - cloud_print::kPortName); - } else { - PORT_INFO_2* port_info = reinterpret_cast<PORT_INFO_2*>(ports); - port_info->pPortName = string_target; - StringCbCopy(port_info->pPortName, cloud_print::kPortNameSize, - cloud_print::kPortName); - port_info->pMonitorName = NULL; - port_info->pDescription = NULL; - port_info->fPortType = PORT_TYPE_WRITE; - port_info->Reserved = 0; - } - *returned = 1; - return TRUE; -} - -BOOL WINAPI Monitor2OpenPort(HANDLE, wchar_t*, HANDLE* handle) { - if (handle == NULL) { - LOG(ERROR) << "handle should not be NULL."; - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - *handle = new PortData(); - return TRUE; -} - -BOOL WINAPI Monitor2StartDocPort(HANDLE port_handle, - wchar_t* printer_name, - DWORD job_id, - DWORD, - BYTE*) { - SetGoogleUpdateUsage(kGoogleUpdateProductId); - if (port_handle == NULL) { - LOG(ERROR) << "port_handle should not be NULL."; - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - if (printer_name == NULL) { - LOG(ERROR) << "printer_name should not be NULL."; - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - if (!ValidateCurrentUser()) { - // TODO(abodenha@chromium.org) Abort the print job. - return FALSE; - } - PortData* port_data = reinterpret_cast<PortData*>(port_handle); - port_data->job_id = job_id; - if (!OpenPrinter(printer_name, &(port_data->printer_handle), NULL)) { - LOG(WARNING) << "Unable to open printer " << printer_name << "."; - // We can continue without a handle to the printer. - // It just means we can't get the job title or tell the spooler that - // the print job is complete. - // This is the normal flow during a unit test. - port_data->printer_handle = NULL; - } - base::FilePath& file_path = port_data->file_path; - base::FilePath app_data_dir = GetAppDataDir(); - if (app_data_dir.empty()) - return FALSE; - DeleteLeakedFiles(app_data_dir); - if (!base::CreateDirectory(app_data_dir) || - !base::CreateTemporaryFileInDir(app_data_dir, &file_path)) { - LOG(ERROR) << "Can't create temporary file in " << app_data_dir.value(); - return FALSE; - } - port_data->file = base::OpenFile(file_path, "wb+"); - if (port_data->file == nullptr) { - LOG(ERROR) << "Error opening file " << file_path.value() << "."; - return FALSE; - } - return TRUE; -} - -BOOL WINAPI Monitor2WritePort(HANDLE port_handle, - BYTE* buffer, - DWORD buffer_size, - DWORD* bytes_written) { - PortData* port_data = reinterpret_cast<PortData*>(port_handle); - if (!ValidateCurrentUser()) { - // TODO(abodenha@chromium.org) Abort the print job. - return FALSE; - } - *bytes_written = - static_cast<DWORD>(fwrite(buffer, 1, buffer_size, port_data->file)); - if (*bytes_written > 0) { - return TRUE; - } else { - return FALSE; - } -} - -BOOL WINAPI Monitor2ReadPort(HANDLE, BYTE*, DWORD, DWORD* read_bytes) { - LOG(ERROR) << "Read is not supported."; - *read_bytes = 0; - SetLastError(ERROR_NOT_SUPPORTED); - return FALSE; -} - -BOOL WINAPI Monitor2EndDocPort(HANDLE port_handle) { - if (!ValidateCurrentUser()) { - // TODO(abodenha@chromium.org) Abort the print job. - return FALSE; - } - PortData* port_data = reinterpret_cast<PortData*>(port_handle); - if (port_data == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - if (port_data->file != nullptr) { - base::CloseFile(port_data->file); - port_data->file = nullptr; - bool delete_file = true; - int64_t file_size = 0; - base::GetFileSize(port_data->file_path, &file_size); - if (file_size > 0) { - std::wstring job_title; - if (port_data->printer_handle != NULL) { - GetJobTitle(port_data->printer_handle, port_data->job_id, &job_title); - } - if (LaunchPrintCommand(port_data->file_path, job_title)) { - delete_file = false; - } - } - if (delete_file) - base::DeleteFile(port_data->file_path); - } - if (port_data->printer_handle != NULL) { - // Tell the spooler that the job is complete. - SetJob(port_data->printer_handle, port_data->job_id, 0, NULL, - JOB_CONTROL_SENT_TO_PRINTER); - } - port_data->Close(); - // Return success even if we can't display the dialog. - // TODO(abodenha@chromium.org) Come up with a better way of handling - // this situation. - return TRUE; -} - -BOOL WINAPI Monitor2ClosePort(HANDLE port_handle) { - if (port_handle == NULL) { - LOG(ERROR) << "port_handle should not be NULL."; - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - delete reinterpret_cast<PortData*>(port_handle); - return TRUE; -} - -VOID WINAPI Monitor2Shutdown(HANDLE monitor_handle) { - if (monitor_handle != NULL) { - delete reinterpret_cast<MonitorData*>(monitor_handle); - } -} - -BOOL WINAPI Monitor2XcvOpenPort(HANDLE, - const wchar_t*, - ACCESS_MASK granted_access, - HANDLE* handle) { - if (handle == NULL) { - LOG(ERROR) << "handle should not be NULL."; - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - XcvUiData* xcv_data = new XcvUiData(); - xcv_data->granted_access = granted_access; - *handle = xcv_data; - return TRUE; -} - -DWORD WINAPI Monitor2XcvDataPort(HANDLE xcv_handle, - const wchar_t* data_name, - BYTE*, - DWORD, - BYTE* output_data, - DWORD output_data_bytes, - DWORD* output_data_bytes_needed) { - XcvUiData* xcv_data = reinterpret_cast<XcvUiData*>(xcv_handle); - DWORD ret_val = ERROR_SUCCESS; - if ((xcv_data->granted_access & SERVER_ACCESS_ADMINISTER) == 0) { - return ERROR_ACCESS_DENIED; - } - if (output_data == NULL || output_data_bytes == 0) { - return ERROR_INVALID_PARAMETER; - } - // We don't handle AddPort or DeletePort since we don't support - // dynamic creation of ports. - if (lstrcmp(L"MonitorUI", data_name) == 0) { - DWORD dll_path_len = 0; - base::FilePath dll_path(cloud_print::GetPortMonitorDllName()); - dll_path_len = static_cast<DWORD>(dll_path.value().length()); - if (output_data_bytes_needed != NULL) { - *output_data_bytes_needed = dll_path_len; - } - if (output_data_bytes < dll_path_len) { - return ERROR_INSUFFICIENT_BUFFER; - } else { - ret_val = StringCbCopy(reinterpret_cast<wchar_t*>(output_data), - output_data_bytes, dll_path.value().c_str()); - } - } else { - return ERROR_INVALID_PARAMETER; - } - return ret_val; -} - -BOOL WINAPI Monitor2XcvClosePort(HANDLE handle) { - delete reinterpret_cast<XcvUiData*>(handle); - return TRUE; -} - -BOOL WINAPI MonitorUiAddPortUi(const wchar_t*, - HWND hwnd, - const wchar_t* monitor_name, - wchar_t**) { - HandlePortUi(hwnd, monitor_name); - return TRUE; -} - -BOOL WINAPI MonitorUiConfigureOrDeletePortUI(const wchar_t*, - HWND hwnd, - const wchar_t* port_name) { - HandlePortUi(hwnd, port_name); - return TRUE; -} - -} // namespace cloud_print - -MONITOR2* WINAPI InitializePrintMonitor2(MONITORINIT*, HANDLE* handle) { - if (handle == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); - return NULL; - } - cloud_print::MonitorData* monitor_data = new cloud_print::MonitorData; - *handle = monitor_data; - if (!cloud_print::kIsUnittest) { - // Unit tests set up their own AtExitManager - monitor_data->at_exit_manager = std::make_unique<base::AtExitManager>(); - // Single spooler.exe handles verbose users. - base::PathService::DisableCache(); - } - return &cloud_print::g_monitor_2; -} - -MONITORUI* WINAPI InitializePrintMonitorUI(void) { - return &cloud_print::g_monitor_ui; -}
diff --git a/cloud_print/virtual_driver/win/port_monitor/port_monitor.def b/cloud_print/virtual_driver/win/port_monitor/port_monitor.def deleted file mode 100644 index 3b2cd17..0000000 --- a/cloud_print/virtual_driver/win/port_monitor/port_monitor.def +++ /dev/null
@@ -1,9 +0,0 @@ -; Copyright (c) 2011 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. - -EXPORTS - InitializePrintMonitor2 - InitializePrintMonitorUI - DllRegisterServer PRIVATE - DllUnregisterServer PRIVATE
diff --git a/cloud_print/virtual_driver/win/port_monitor/port_monitor.h b/cloud_print/virtual_driver/win/port_monitor/port_monitor.h deleted file mode 100644 index e5407694..0000000 --- a/cloud_print/virtual_driver/win/port_monitor/port_monitor.h +++ /dev/null
@@ -1,93 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CLOUD_PRINT_VIRTUAL_DRIVER_WIN_PORT_MONITOR_PORT_MONITOR_H_ -#define CLOUD_PRINT_VIRTUAL_DRIVER_WIN_PORT_MONITOR_PORT_MONITOR_H_ - -#include <windows.h> -#include <string> -#include "base/files/file_util.h" -#include "base/process/process.h" - -namespace cloud_print { - -// Returns path to be used for launching Chrome. -base::FilePath GetChromeExePath(); - -// Returns path to user profile to be used for launching Chrome. -base::FilePath GetChromeProfilePath(); - -// Returns the print command to launch, if set, instead of Chrome. -std::wstring GetPrintCommandTemplate(); - -// Implementations for the function pointers in the MONITOR2 structure -// returned by InitializePrintMonitor2. The prototypes and behaviors -// are as described in the MONITOR2 documentation from Microsoft. - -BOOL WINAPI Monitor2EnumPorts(HANDLE, - wchar_t*, - DWORD level, - BYTE* ports, - DWORD ports_size, - DWORD* needed_bytes, - DWORD* returned); - -BOOL WINAPI Monitor2OpenPort(HANDLE monitor_data, wchar_t*, HANDLE* handle); - -BOOL WINAPI Monitor2StartDocPort(HANDLE port_handle, - wchar_t* printer_name, - DWORD job_id, - DWORD, - BYTE*); - -BOOL WINAPI Monitor2WritePort(HANDLE port, - BYTE* buffer, - DWORD buffer_size, - DWORD* bytes_written); - -BOOL WINAPI Monitor2ReadPort(HANDLE, BYTE*, DWORD, DWORD* bytes_read); - -BOOL WINAPI Monitor2EndDocPort(HANDLE port_handle); - -BOOL WINAPI Monitor2ClosePort(HANDLE port_handle); - -VOID WINAPI Monitor2Shutdown(HANDLE monitor_handle); - -BOOL WINAPI Monitor2XcvOpenPort(HANDLE monitor, - const wchar_t*, - ACCESS_MASK granted_access, - HANDLE* handle); - -DWORD WINAPI Monitor2XcvDataPort(HANDLE xcv_handle, - const wchar_t* data_name, - BYTE*, - DWORD, - BYTE* output_data, - DWORD output_data_bytes, - DWORD* output_data_bytes_needed); - -BOOL WINAPI Monitor2XcvClosePort(HANDLE handle); - -// Implementations for the function pointers in the MONITORUI structure -// returned by InitializePrintMonitorUI. The prototypes and behaviors -// are as described in the MONITORUI documentation from Microsoft. - -BOOL WINAPI MonitorUiAddPortUi(const wchar_t*, - HWND hwnd, - const wchar_t* monitor_name, - wchar_t**); - -BOOL WINAPI MonitorUiConfigureOrDeletePortUI(const wchar_t*, - HWND hwnd, - const wchar_t* port_name); - -extern const wchar_t kChromeExePath[]; -extern const wchar_t kChromeExePathRegValue[]; -extern const wchar_t kChromeProfilePathRegValue[]; -extern const wchar_t kPrintCommandRegValue[]; -extern const bool kIsUnittest; - -} // namespace cloud_print - -#endif // CLOUD_PRINT_VIRTUAL_DRIVER_WIN_PORT_MONITOR_PORT_MONITOR_H_
diff --git a/cloud_print/virtual_driver/win/port_monitor/port_monitor_dll.cc b/cloud_print/virtual_driver/win/port_monitor/port_monitor_dll.cc deleted file mode 100644 index e32f673..0000000 --- a/cloud_print/virtual_driver/win/port_monitor/port_monitor_dll.cc +++ /dev/null
@@ -1,87 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "cloud_print/virtual_driver/win/port_monitor/port_monitor.h" - -#include <windows.h> -#include <lmcons.h> -#include <shellapi.h> -#include <shlobj.h> -#include <strsafe.h> -#include <userenv.h> -#include <winspool.h> - -#include <string> - -#include "base/at_exit.h" -#include "base/command_line.h" -#include "base/files/file_util.h" -#include "base/process/process_info.h" -#include "base/win/registry.h" -#include "base/win/scoped_handle.h" -#include "chrome/common/chrome_switches.h" -#include "cloud_print/common/win/cloud_print_utils.h" -#include "cloud_print/virtual_driver/win/port_monitor/spooler_win.h" -#include "cloud_print/virtual_driver/win/virtual_driver_consts.h" -#include "cloud_print/virtual_driver/win/virtual_driver_helpers.h" - -namespace cloud_print { - -const wchar_t kChromeExePath[] = L"google\\chrome\\application\\chrome.exe"; -const wchar_t kChromeExePathRegValue[] = L"PathToChromeExe"; -const wchar_t kChromeProfilePathRegValue[] = L"PathToChromeProfile"; -const wchar_t kPrintCommandRegValue[] = L"PrintCommand"; -const bool kIsUnittest = false; - -namespace { - -// Returns true if Xps support is installed. -bool XpsIsInstalled() { - base::FilePath xps_path; - if (!SUCCEEDED(GetPrinterDriverDir(&xps_path))) - return false; - - xps_path = xps_path.Append(L"mxdwdrv.dll"); - return base::PathExists(xps_path); -} - -// Returns true if registration/unregistration can be attempted. -bool CanRegister() { - if (!XpsIsInstalled()) - return false; - return base::GetCurrentProcessIntegrityLevel() == base::HIGH_INTEGRITY; -} - -} // namespace - -} // namespace cloud_print - -HRESULT WINAPI DllRegisterServer(void) { - base::AtExitManager at_exit_manager; - if (!cloud_print::CanRegister()) { - return E_ACCESSDENIED; - } - MONITOR_INFO_2 monitor_info = {0}; - // YUCK!!! I can either copy the constant, const_cast, or define my own - // MONITOR_INFO_2 that will take const strings. - base::FilePath dll_path(cloud_print::GetPortMonitorDllName()); - monitor_info.pDLLName = const_cast<LPWSTR>(dll_path.value().c_str()); - monitor_info.pName = const_cast<LPWSTR>(dll_path.value().c_str()); - if (AddMonitor(NULL, 2, reinterpret_cast<BYTE*>(&monitor_info))) { - return S_OK; - } - return cloud_print::GetLastHResult(); -} - -HRESULT WINAPI DllUnregisterServer(void) { - base::AtExitManager at_exit_manager; - if (!cloud_print::CanRegister()) { - return E_ACCESSDENIED; - } - base::FilePath dll_path(cloud_print::GetPortMonitorDllName()); - if (DeleteMonitor(NULL, NULL, const_cast<LPWSTR>(dll_path.value().c_str()))) { - return S_OK; - } - return cloud_print::GetLastHResult(); -}
diff --git a/cloud_print/virtual_driver/win/port_monitor/port_monitor_unittest.cc b/cloud_print/virtual_driver/win/port_monitor/port_monitor_unittest.cc deleted file mode 100644 index 0fe45b23..0000000 --- a/cloud_print/virtual_driver/win/port_monitor/port_monitor_unittest.cc +++ /dev/null
@@ -1,246 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "cloud_print/virtual_driver/win/port_monitor/port_monitor.h" - -#include <stddef.h> -#include <winspool.h> - -#include <string> - -#include "base/files/file_util.h" -#include "base/path_service.h" -#include "base/win/registry.h" -#include "base/win/scoped_handle.h" -#include "cloud_print/virtual_driver/win/port_monitor/spooler_win.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace cloud_print { - -const wchar_t kChromeExePath[] = L"google\\chrome\\application\\chrometest.exe"; -const wchar_t kChromeExePathRegValue[] = L"PathToChromeTestExe"; -const wchar_t kChromeProfilePathRegValue[] = L"PathToChromeTestProfile"; -const wchar_t kPrintCommandRegValue[] = L"TestPrintCommand"; -const bool kIsUnittest = true; - -namespace { - -const wchar_t kAlternateChromeExePath[] = - L"google\\chrome\\application\\chrometestalternate.exe"; -const wchar_t kTestPrintCommand[] = L"testprintcommand.exe"; - -const wchar_t kCloudPrintRegKey[] = L"Software\\Google\\CloudPrint"; - -} // namespace - -class PortMonitorTest : public testing::Test { - public: - PortMonitorTest() = default; - PortMonitorTest(const PortMonitorTest&) = delete; - PortMonitorTest& operator=(const PortMonitorTest&) = delete; - - protected: - // Creates a registry entry pointing at a chrome - virtual void SetUpChromeExeRegistry() { - // Create a temporary chrome.exe location value. - base::win::RegKey key(HKEY_CURRENT_USER, cloud_print::kCloudPrintRegKey, - KEY_ALL_ACCESS); - - base::FilePath path; - base::PathService::Get(base::DIR_LOCAL_APP_DATA, &path); - path = path.Append(kAlternateChromeExePath); - ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(cloud_print::kChromeExePathRegValue, - path.value().c_str())); - base::FilePath temp; - base::PathService::Get(base::DIR_TEMP, &temp); - // Write any dir here. - ASSERT_EQ(ERROR_SUCCESS, - key.WriteValue(cloud_print::kChromeProfilePathRegValue, - temp.value().c_str())); - - ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(cloud_print::kPrintCommandRegValue, - kTestPrintCommand)); - } - // Deletes the registry entry created in SetUpChromeExeRegistry - virtual void DeleteChromeExeRegistry() { - base::win::RegKey key(HKEY_CURRENT_USER, cloud_print::kCloudPrintRegKey, - KEY_ALL_ACCESS); - key.DeleteValue(cloud_print::kChromeExePathRegValue); - key.DeleteValue(cloud_print::kChromeProfilePathRegValue); - key.DeleteValue(cloud_print::kPrintCommandRegValue); - } - - virtual void CreateTempChromeExeFiles() { - base::FilePath path; - base::PathService::Get(base::DIR_LOCAL_APP_DATA, &path); - base::FilePath main_path = path.Append(kChromeExePath); - ASSERT_TRUE(base::CreateDirectory(main_path)); - base::FilePath alternate_path = path.Append(kAlternateChromeExePath); - ASSERT_TRUE(base::CreateDirectory(alternate_path)); - } - - virtual void DeleteTempChromeExeFiles() { - base::FilePath path; - base::PathService::Get(base::DIR_LOCAL_APP_DATA, &path); - base::FilePath main_path = path.Append(kChromeExePath); - ASSERT_TRUE(base::DeletePathRecursively(main_path)); - base::PathService::Get(base::DIR_LOCAL_APP_DATA, &path); - base::FilePath alternate_path = path.Append(kAlternateChromeExePath); - ASSERT_TRUE(base::DeletePathRecursively(alternate_path)); - } - - void SetUp() override { SetUpChromeExeRegistry(); } - - void TearDown() override { DeleteChromeExeRegistry(); } -}; - -TEST_F(PortMonitorTest, GetChromeExePathTest) { - CreateTempChromeExeFiles(); - base::FilePath chrome_path = cloud_print::GetChromeExePath(); - EXPECT_FALSE(chrome_path.empty()); - EXPECT_TRUE(chrome_path.value().rfind(kAlternateChromeExePath) != - std::string::npos); - EXPECT_TRUE(base::PathExists(chrome_path)); - DeleteChromeExeRegistry(); - chrome_path = cloud_print::GetChromeExePath(); - // No Chrome or regular chrome path. - EXPECT_TRUE(chrome_path.empty() || - chrome_path.value().rfind(kChromeExePath) == std::string::npos); -} - -TEST_F(PortMonitorTest, GetPrintCommandTemplateTest) { - std::wstring print_command = cloud_print::GetPrintCommandTemplate(); - EXPECT_FALSE(print_command.empty()); - EXPECT_EQ(print_command, kTestPrintCommand); - DeleteChromeExeRegistry(); - print_command = cloud_print::GetPrintCommandTemplate(); - EXPECT_TRUE(print_command.empty()); -} - -TEST_F(PortMonitorTest, GetChromeProfilePathTest) { - base::FilePath data_path = cloud_print::GetChromeProfilePath(); - EXPECT_FALSE(data_path.empty()); - base::FilePath temp; - base::PathService::Get(base::DIR_TEMP, &temp); - EXPECT_EQ(data_path, temp); - EXPECT_TRUE(base::DirectoryExists(data_path)); - DeleteChromeExeRegistry(); - data_path = cloud_print::GetChromeProfilePath(); - EXPECT_TRUE(data_path.empty()); -} - -TEST_F(PortMonitorTest, EnumPortsTest) { - DWORD needed_bytes = 0; - DWORD returned = 0; - EXPECT_FALSE( - Monitor2EnumPorts(NULL, NULL, 1, NULL, 0, &needed_bytes, &returned)); - EXPECT_EQ(static_cast<DWORD>(ERROR_INSUFFICIENT_BUFFER), GetLastError()); - EXPECT_NE(0u, needed_bytes); - EXPECT_EQ(0u, returned); - - BYTE* buffer = new BYTE[needed_bytes]; - ASSERT_TRUE(buffer != NULL); - EXPECT_TRUE(Monitor2EnumPorts(NULL, NULL, 1, buffer, needed_bytes, - &needed_bytes, &returned)); - EXPECT_NE(0u, needed_bytes); - EXPECT_EQ(1u, returned); - PORT_INFO_1* port_info_1 = reinterpret_cast<PORT_INFO_1*>(buffer); - EXPECT_TRUE(port_info_1->pName != NULL); - delete[] buffer; - - returned = 0; - needed_bytes = 0; - EXPECT_FALSE( - Monitor2EnumPorts(NULL, NULL, 2, NULL, 0, &needed_bytes, &returned)); - EXPECT_EQ(static_cast<DWORD>(ERROR_INSUFFICIENT_BUFFER), GetLastError()); - EXPECT_NE(0u, needed_bytes); - EXPECT_EQ(0u, returned); - - buffer = new BYTE[needed_bytes]; - ASSERT_TRUE(buffer != NULL); - EXPECT_TRUE(Monitor2EnumPorts(NULL, NULL, 2, buffer, needed_bytes, - &needed_bytes, &returned)); - EXPECT_NE(0u, needed_bytes); - EXPECT_EQ(1u, returned); - PORT_INFO_2* port_info_2 = reinterpret_cast<PORT_INFO_2*>(buffer); - EXPECT_TRUE(port_info_2->pPortName != NULL); - delete[] buffer; -} - -TEST_F(PortMonitorTest, FlowTest) { - const wchar_t kXcvDataItem[] = L"MonitorUI"; - MONITORINIT monitor_init = {0}; - HANDLE monitor_handle = NULL; - HANDLE port_handle = NULL; - HANDLE xcv_handle = NULL; - DWORD bytes_processed = 0; - DWORD bytes_needed = 0; - const size_t kBufferSize = 100; - BYTE buffer[kBufferSize] = {0}; - - // Initialize the print monitor - MONITOR2* monitor2 = InitializePrintMonitor2(&monitor_init, &monitor_handle); - EXPECT_TRUE(monitor2 != NULL); - EXPECT_TRUE(monitor_handle != NULL); - - // Test the XCV functions. Used for reporting the location of the - // UI portion of the port monitor. - EXPECT_TRUE(monitor2->pfnXcvOpenPort != NULL); - EXPECT_TRUE(monitor2->pfnXcvOpenPort(monitor_handle, NULL, 0, &xcv_handle)); - EXPECT_TRUE(xcv_handle != NULL); - EXPECT_TRUE(monitor2->pfnXcvDataPort != NULL); - EXPECT_EQ(static_cast<DWORD>(ERROR_ACCESS_DENIED), - monitor2->pfnXcvDataPort(xcv_handle, kXcvDataItem, NULL, 0, buffer, - kBufferSize, &bytes_needed)); - EXPECT_TRUE(monitor2->pfnXcvClosePort != NULL); - EXPECT_TRUE(monitor2->pfnXcvClosePort(xcv_handle)); - EXPECT_TRUE(monitor2->pfnXcvOpenPort(monitor_handle, NULL, - SERVER_ACCESS_ADMINISTER, &xcv_handle)); - EXPECT_TRUE(xcv_handle != NULL); - EXPECT_TRUE(monitor2->pfnXcvDataPort != NULL); - EXPECT_EQ(static_cast<DWORD>(ERROR_SUCCESS), - monitor2->pfnXcvDataPort(xcv_handle, kXcvDataItem, NULL, 0, buffer, - kBufferSize, &bytes_needed)); - EXPECT_TRUE(monitor2->pfnXcvClosePort != NULL); - EXPECT_TRUE(monitor2->pfnXcvClosePort(xcv_handle)); - - // Test opening the port and running a print job. - EXPECT_TRUE(monitor2->pfnOpenPort != NULL); - EXPECT_TRUE(monitor2->pfnOpenPort(monitor_handle, NULL, &port_handle)); - EXPECT_TRUE(port_handle != NULL); - EXPECT_TRUE(monitor2->pfnStartDocPort != NULL); - EXPECT_TRUE(monitor2->pfnWritePort != NULL); - EXPECT_TRUE(monitor2->pfnReadPort != NULL); - EXPECT_TRUE(monitor2->pfnEndDocPort != NULL); - - // These functions should fail if we have not impersonated the user. - EXPECT_FALSE(monitor2->pfnStartDocPort(port_handle, const_cast<wchar_t*>(L""), - 0, 0, NULL)); - EXPECT_FALSE(monitor2->pfnWritePort(port_handle, buffer, kBufferSize, - &bytes_processed)); - EXPECT_EQ(0u, bytes_processed); - EXPECT_FALSE(monitor2->pfnReadPort(port_handle, buffer, sizeof(buffer), - &bytes_processed)); - EXPECT_EQ(0u, bytes_processed); - EXPECT_FALSE(monitor2->pfnEndDocPort(port_handle)); - - // Now impersonate so we can test the success case. - ASSERT_TRUE(ImpersonateSelf(SecurityImpersonation)); - EXPECT_TRUE(monitor2->pfnStartDocPort(port_handle, const_cast<wchar_t*>(L""), - 0, 0, NULL)); - EXPECT_TRUE(monitor2->pfnWritePort(port_handle, buffer, kBufferSize, - &bytes_processed)); - EXPECT_EQ(kBufferSize, bytes_processed); - EXPECT_FALSE(monitor2->pfnReadPort(port_handle, buffer, sizeof(buffer), - &bytes_processed)); - EXPECT_EQ(0u, bytes_processed); - EXPECT_TRUE(monitor2->pfnEndDocPort(port_handle)); - RevertToSelf(); - EXPECT_TRUE(monitor2->pfnClosePort != NULL); - EXPECT_TRUE(monitor2->pfnClosePort(port_handle)); - // Shutdown the port monitor. - Monitor2Shutdown(monitor_handle); -} - -} // namespace cloud_print
diff --git a/cloud_print/virtual_driver/win/port_monitor/spooler_win.h b/cloud_print/virtual_driver/win/port_monitor/spooler_win.h deleted file mode 100644 index 0add066..0000000 --- a/cloud_print/virtual_driver/win/port_monitor/spooler_win.h +++ /dev/null
@@ -1,100 +0,0 @@ -// Copyright (c) 2011 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 CLOUD_PRINT_VIRTUAL_DRIVER_WIN_PORT_MONITOR_SPOOLER_WIN_H_ -#define CLOUD_PRINT_VIRTUAL_DRIVER_WIN_PORT_MONITOR_SPOOLER_WIN_H_ - -#include <windows.h> - -#include "base/memory/raw_ptr.h" - -// Compatible structures and prototypes are also defined in the Windows DDK in -// winsplp.h. -#ifndef _WINSPLP_ - -typedef struct { - DWORD size; - BOOL(WINAPI* pfnEnumPorts) - (HANDLE, - wchar_t*, - DWORD level, - BYTE* ports, - DWORD ports_size, - DWORD* needed_bytes, - DWORD* returned); - - BOOL(WINAPI* pfnOpenPort)(HANDLE monitor_data, wchar_t*, HANDLE* handle); - - void* pfnOpenPortEx; // Unused. - - BOOL(WINAPI* pfnStartDocPort) - (HANDLE port_handle, wchar_t* printer_name, DWORD job_id, DWORD, BYTE*); - - BOOL(WINAPI* pfnWritePort) - (HANDLE port, BYTE* buffer, DWORD buffer_size, DWORD* bytes_written); - - BOOL(WINAPI* pfnReadPort)(HANDLE, BYTE*, DWORD, DWORD* bytes_read); - - BOOL(WINAPI* pfnEndDocPort)(HANDLE port_handle); - - BOOL(WINAPI* pfnClosePort)(HANDLE port_handle); - - void* pfnAddPort; // Unused. - - void* pfnAddPortEx; // Unused. - - void* pfnConfigurePort; // Unused. - - void* pfnDeletePort; // Unused. - - void* pfnGetPrinterDataFromPort; // Unused. - - void* pfnSetPortTimeOuts; // Unusued. - - BOOL(WINAPI* pfnXcvOpenPort) - (HANDLE monitor, const wchar_t*, ACCESS_MASK granted_access, HANDLE* handle); - - DWORD(WINAPI* pfnXcvDataPort) - (HANDLE xcv_handle, - const wchar_t* data_name, - BYTE*, - DWORD, - BYTE* output_data, - DWORD output_data_bytes, - DWORD* output_data_bytes_needed); - - BOOL(WINAPI* pfnXcvClosePort)(HANDLE handle); - - VOID(WINAPI* pfnShutdown)(HANDLE monitor_handle); -} MONITOR2; - -typedef struct { - DWORD size; - - BOOL(WINAPI* pfnAddPortUI) - (const wchar_t*, HWND hwnd, const wchar_t* monitor_name, wchar_t**); - - BOOL(WINAPI* pfnConfigurePortUI) - (const wchar_t*, HWND hwnd, const wchar_t* port_name); - - BOOL(WINAPI* pfnDeletePortUI) - (const wchar_t*, HWND hwnd, const wchar_t* port_name); -} MONITORUI; - -typedef struct { - DWORD cbSize; - HANDLE hSpooler; - HKEY hckRegistryRoot; - raw_ptr<void> pMonitorReg; // Unused - BOOL bLocal; - LPCWSTR pszServerName; -} MONITORINIT; - -MONITOR2* WINAPI InitializePrintMonitor2(MONITORINIT* monitor_init, - HANDLE* monitor_handle); - -MONITORUI* WINAPI InitializePrintMonitorUI(void); - -#endif // ifdef USE_WIN_DDK -#endif // CLOUD_PRINT_VIRTUAL_DRIVER_WIN_PORT_MONITOR_SPOOLER_WIN_H_
diff --git a/cloud_print/virtual_driver/win/virtual_driver_consts.cc b/cloud_print/virtual_driver/win/virtual_driver_consts.cc deleted file mode 100644 index ffa975f..0000000 --- a/cloud_print/virtual_driver/win/virtual_driver_consts.cc +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright (c) 2011 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 "cloud_print/virtual_driver/win/virtual_driver_consts.h" - -#include <windows.h> -#include <stddef.h> - -#include "cloud_print/virtual_driver/win/virtual_driver_helpers.h" - -namespace cloud_print { - -const wchar_t kPortName[] = L"GCP:"; -const size_t kPortNameSize = sizeof(kPortName); -const wchar_t kGoogleUpdateProductId[] = - L"{9B13FA92-1F73-4761-AB78-2C6ADAC3660D}"; - -} // namespace cloud_print
diff --git a/cloud_print/virtual_driver/win/virtual_driver_consts.h b/cloud_print/virtual_driver/win/virtual_driver_consts.h deleted file mode 100644 index f97022d..0000000 --- a/cloud_print/virtual_driver/win/virtual_driver_consts.h +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright (c) 2011 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 CLOUD_PRINT_VIRTUAL_DRIVER_WIN_VIRTUAL_DRIVER_CONSTS_H_ -#define CLOUD_PRINT_VIRTUAL_DRIVER_WIN_VIRTUAL_DRIVER_CONSTS_H_ - -namespace cloud_print { - -extern const wchar_t kPortName[]; -extern const size_t kPortNameSize; -extern const wchar_t kGoogleUpdateProductId[]; - -} // namespace cloud_print - -#endif // CLOUD_PRINT_VIRTUAL_DRIVER_WIN_VIRTUAL_DRIVER_CONSTS_H_
diff --git a/cloud_print/virtual_driver/win/virtual_driver_helpers.cc b/cloud_print/virtual_driver/win/virtual_driver_helpers.cc deleted file mode 100644 index 709389d..0000000 --- a/cloud_print/virtual_driver/win/virtual_driver_helpers.cc +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "cloud_print/virtual_driver/win/virtual_driver_helpers.h" - -#include <windows.h> -#include <winspool.h> - -#include <string> - -#include "base/files/file_util.h" -#include "base/win/windows_version.h" -#include "cloud_print/common/win/cloud_print_utils.h" - -namespace cloud_print { - -void DisplayWindowsMessage(HWND hwnd, HRESULT hr, const std::wstring& caption) { - ::MessageBox(hwnd, GetErrorMessage(hr).c_str(), caption.c_str(), MB_OK); -} - -std::wstring GetPortMonitorDllName() { - if (IsSystem64Bit()) { - return std::wstring(L"gcp_portmon64.dll"); - } else { - return std::wstring(L"gcp_portmon.dll"); - } -} - -HRESULT GetPrinterDriverDir(base::FilePath* path) { - BYTE driver_dir_buffer[MAX_PATH * sizeof(wchar_t)]; - DWORD needed = 0; - if (!GetPrinterDriverDirectory(NULL, NULL, 1, driver_dir_buffer, - MAX_PATH * sizeof(wchar_t), &needed)) { - // We could try to allocate a larger buffer if needed > MAX_PATH - // but that really shouldn't happen. - return cloud_print::GetLastHResult(); - } - *path = base::FilePath(reinterpret_cast<wchar_t*>(driver_dir_buffer)); - - // The XPS driver is a "Level 3" driver - *path = path->Append(L"3"); - return S_OK; -} - -bool IsSystem64Bit() { - base::win::OSInfo::WindowsArchitecture arch = - base::win::OSInfo::GetArchitecture(); - return (arch == base::win::OSInfo::X64_ARCHITECTURE) || - (arch == base::win::OSInfo::IA64_ARCHITECTURE); -} -} // namespace cloud_print
diff --git a/cloud_print/virtual_driver/win/virtual_driver_helpers.h b/cloud_print/virtual_driver/win/virtual_driver_helpers.h deleted file mode 100644 index 8d98d2a..0000000 --- a/cloud_print/virtual_driver/win/virtual_driver_helpers.h +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright (c) 2011 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 CLOUD_PRINT_VIRTUAL_DRIVER_WIN_VIRTUAL_DRIVER_HELPERS_H_ -#define CLOUD_PRINT_VIRTUAL_DRIVER_WIN_VIRTUAL_DRIVER_HELPERS_H_ - -#include <windows.h> - -#include <string> - - -namespace base { -class FilePath; -} - -namespace cloud_print { - -// Convert an HRESULT to a localized string and display it in a message box. -void DisplayWindowsMessage(HWND hwnd, - HRESULT hr, - const std::wstring& caption); - -// Returns the correct port monitor DLL file name for the current machine. -std::wstring GetPortMonitorDllName(); - -// Gets the standard install path for "version 3" print drivers. -HRESULT GetPrinterDriverDir(base::FilePath* path); - -// Returns TRUE if the current OS is 64 bit. -bool IsSystem64Bit(); - -} // namespace cloud_print - -#endif // CLOUD_PRINT_VIRTUAL_DRIVER_WIN_VIRTUAL_DRIVER_HELPERS_H_
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc index 2539d00..930ea6fd 100644 --- a/components/autofill/core/browser/autofill_external_delegate.cc +++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -432,7 +432,7 @@ #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) suggestions->back().icon = "googlePay"; #else - suggestions->back().store_indicator_icon = + suggestions->back().trailing_icon = ui::NativeTheme::GetInstanceForNativeUi()->ShouldUseDarkColors() ? "googlePayDark" : "googlePay";
diff --git a/components/autofill/core/browser/ui/suggestion.h b/components/autofill/core/browser/ui/suggestion.h index 6cf75f5..1d5665c 100644 --- a/components/autofill/core/browser/ui/suggestion.h +++ b/components/autofill/core/browser/ui/suggestion.h
@@ -74,11 +74,13 @@ // TODO(crbug.com/1019660): Identify icons with enum instead of strings. // If |custom_icon| is empty, the name of the fallback built-in icon. std::string icon; - // For passwords, this icon string shows whether the suggestion originates - // from local or account store. It is also used on the settings entry for - // the credit card Autofill popup to indicate if all credit cards are server - // cards. - std::string store_indicator_icon; + // An icon that appears after the suggestion in the suggestion view. For + // passwords, this icon string shows whether the suggestion originates from + // local or account store. It is also used on the settings entry for the + // credit card Autofill popup to indicate if all credit cards are server + // cards. It also holds Google Password Manager icon on the settings entry for + // the passwords Autofill popup. + std::string trailing_icon; MatchMode match = PREFIX_MATCH; // Whether |value| should be displayed as secondary text. bool is_value_secondary = false;
diff --git a/components/autofill/core/browser/ui/suggestion_test_helpers.h b/components/autofill/core/browser/ui/suggestion_test_helpers.h index e38dc3a..de639bc 100644 --- a/components/autofill/core/browser/ui/suggestion_test_helpers.h +++ b/components/autofill/core/browser/ui/suggestion_test_helpers.h
@@ -87,13 +87,13 @@ &Suggestion::icon)); } -// Like SuggestionVectorIdsAre above, but tests the store_indicator_icon. +// Like SuggestionVectorIdsAre above, but tests the trailing_icon. template <class EltsAreMatcher> inline testing::Matcher<const std::vector<Suggestion>&> SuggestionVectorStoreIndicatorIconsAre(const EltsAreMatcher& elts_are_matcher) { return testing::MakeMatcher( new SuggestionVectorMembersAreMatcher<std::string>( - elts_are_matcher, &Suggestion::store_indicator_icon)); + elts_are_matcher, &Suggestion::trailing_icon)); } } // namespace autofill
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn index 24f6c17..ccfa5769 100644 --- a/components/cronet/android/BUILD.gn +++ b/components/cronet/android/BUILD.gn
@@ -679,6 +679,11 @@ "org/chromium/base/memory/MemoryPressureMonitor*.class", ] +# Excluded from repackage_jars, but not from jar_src(). +_build_jar_excluded_patterns = [ + "org/chromium/build/NativeLibraries.class", +] + template("repackage_jars") { dist_jar(target_name) { requires_android = true @@ -718,7 +723,7 @@ ":cronet_jni_registration_java", ":repackage_native_java", ] - jar_excluded_patterns = _jar_excluded_patterns + jar_excluded_patterns = _jar_excluded_patterns + _build_jar_excluded_patterns } _native_intermediate_jar_path = "$target_out_dir/repackage_native_impl.jar" @@ -728,7 +733,7 @@ output = _native_intermediate_jar_path deps = cronet_impl_native_java_deps_to_package + [ ":cronet_impl_native_base_java" ] - jar_excluded_patterns = _jar_excluded_patterns + jar_excluded_patterns = _jar_excluded_patterns + _build_jar_excluded_patterns } # Do not depend on this target directly. Use :repackage_native.
diff --git a/components/enterprise/browser/reporting/report_scheduler.cc b/components/enterprise/browser/reporting/report_scheduler.cc index 6376af74..945dea0 100644 --- a/components/enterprise/browser/reporting/report_scheduler.cc +++ b/components/enterprise/browser/reporting/report_scheduler.cc
@@ -9,6 +9,7 @@ #include <vector> #include "base/metrics/histogram_functions.h" +#include "base/notreached.h" #include "base/syslog_logging.h" #include "base/task/post_task.h" #include "base/time/time.h" @@ -217,25 +218,33 @@ if (cloud_policy_client_->is_registered()) return true; + policy::DMToken dm_token; + std::string client_id; + if (profile_request_generator_) { + // Get token for profile reporting + dm_token = delegate_->GetProfileDMToken(); + client_id = delegate_->GetProfileClientId(); + } else { + // Get token for browser reporting #if !BUILDFLAG(IS_CHROMEOS_ASH) - policy::DMToken browser_dm_token = - policy::BrowserDMTokenStorage::Get()->RetrieveDMToken(); - std::string client_id = - policy::BrowserDMTokenStorage::Get()->RetrieveClientId(); - - if (!browser_dm_token.is_valid() || client_id.empty()) { + dm_token = policy::BrowserDMTokenStorage::Get()->RetrieveDMToken(); + client_id = policy::BrowserDMTokenStorage::Get()->RetrieveClientId(); +#else + NOTREACHED(); + return true; +#endif + } + if (!dm_token.is_valid() || client_id.empty()) { VLOG(1) - << "Enterprise reporting is disabled because device is not enrolled."; + << "Enterprise reporting is disabled because device or profile is not " + "enrolled."; return false; } - cloud_policy_client_->SetupRegistration(browser_dm_token.value(), client_id, - std::vector<std::string>()); + cloud_policy_client_->SetupRegistration( + dm_token.value(), client_id, + /*user_affiliation_ids=*/std::vector<std::string>()); return true; -#else - NOTREACHED(); - return true; -#endif } void ReportScheduler::Start(base::Time last_upload_time) {
diff --git a/components/enterprise/browser/reporting/report_scheduler.h b/components/enterprise/browser/reporting/report_scheduler.h index 85b14284..7264dcf 100644 --- a/components/enterprise/browser/reporting/report_scheduler.h +++ b/components/enterprise/browser/reporting/report_scheduler.h
@@ -5,19 +5,19 @@ #ifndef COMPONENTS_ENTERPRISE_BROWSER_REPORTING_REPORT_SCHEDULER_H_ #define COMPONENTS_ENTERPRISE_BROWSER_REPORTING_REPORT_SCHEDULER_H_ -#include <stdint.h> #include <memory> +#include <string> -#include "base/callback.h" +#include "base/callback_forward.h" #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" -#include "base/observer_list_types.h" #include "base/time/time.h" #include "base/timer/wall_clock_timer.h" #include "components/enterprise/browser/reporting/chrome_profile_request_generator.h" #include "components/enterprise/browser/reporting/real_time_report_generator.h" #include "components/enterprise/browser/reporting/report_generator.h" #include "components/enterprise/browser/reporting/report_uploader.h" +#include "components/policy/core/common/cloud/dm_token.h" #include "components/prefs/pref_change_registrar.h" namespace policy { @@ -77,6 +77,9 @@ virtual void StopWatchingExtensionRequest() = 0; virtual void OnExtensionRequestUploaded() = 0; + virtual policy::DMToken GetProfileDMToken() = 0; + virtual std::string GetProfileClientId() = 0; + protected: ReportTriggerCallback trigger_report_callback_; RealtimeReportTriggerCallback trigger_realtime_report_callback_;
diff --git a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java index 739bb31f..e2eecbc 100644 --- a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java +++ b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java
@@ -368,7 +368,7 @@ } if (canLaunchExternalFallback) { - if (shouldBlockAllExternalAppLaunches(params)) { + if (shouldBlockAllExternalAppLaunches(params, false /* incomingIntentRedirect */)) { throw new SecurityException("Context is not allowed to launch an external app."); } if (!params.isIncognito()) { @@ -472,7 +472,12 @@ /** * http://crbug.com/441284 : Disallow firing external intent while the app is in the background. */ - private boolean blockExternalNavWhileBackgrounded(ExternalNavigationParams params) { + private boolean blockExternalNavWhileBackgrounded( + ExternalNavigationParams params, boolean incomingIntentRedirect) { + // If the redirect is from an intent Chrome could still be transitioning to the foreground. + // Alternatively, the user may have sent Chrome to the background by this point, but for + // navigations started by another app that should still be safe. + if (incomingIntentRedirect) return false; if (params.isApplicationMustBeInForeground() && !mDelegate.isApplicationInForeground()) { if (DEBUG) Log.i(TAG, "App is not in foreground"); return true; @@ -481,7 +486,12 @@ } /** http://crbug.com/464669 : Disallow firing external intent from background tab. */ - private boolean blockExternalNavFromBackgroundTab(ExternalNavigationParams params) { + private boolean blockExternalNavFromBackgroundTab( + ExternalNavigationParams params, boolean incomingIntentRedirect) { + // See #blockExternalNavWhileBackgrounded - isBackgroundTabNavigation is effectively + // checking both that the tab is foreground, and the app is foreground, so we can skip it + // for intent launches for the same reason. + if (incomingIntentRedirect) return false; if (params.isBackgroundTabNavigation() && !params.areIntentLaunchesAllowedInBackgroundTabs()) { if (DEBUG) Log.i(TAG, "Navigation in background tab"); @@ -1265,9 +1275,12 @@ } // Check if we're navigating under conditions that should never launch an external app. - private boolean shouldBlockAllExternalAppLaunches(ExternalNavigationParams params) { - return blockExternalNavFromAutoSubframe(params) || blockExternalNavWhileBackgrounded(params) - || blockExternalNavFromBackgroundTab(params) || ignoreBackForwardNav(params); + private boolean shouldBlockAllExternalAppLaunches( + ExternalNavigationParams params, boolean incomingIntentRedirect) { + return blockExternalNavFromAutoSubframe(params) + || blockExternalNavWhileBackgrounded(params, incomingIntentRedirect) + || blockExternalNavFromBackgroundTab(params, incomingIntentRedirect) + || ignoreBackForwardNav(params); } private void recordIntentSelectorMetrics(GURL targetUrl, Intent targetIntent) { @@ -1286,7 +1299,20 @@ // Don't allow external fallback URLs by default. canLaunchExternalFallbackResult.set(false); - if (shouldBlockAllExternalAppLaunches(params)) { + int pageTransitionCore = params.getPageTransition() & PageTransition.CORE_MASK; + boolean isLink = pageTransitionCore == PageTransition.LINK; + boolean isFromIntent = (params.getPageTransition() & PageTransition.FROM_API) != 0; + + boolean isOnEffectiveIntentRedirect = params.getRedirectHandler() == null + ? false + : params.getRedirectHandler().isOnEffectiveIntentRedirectChain(); + + // http://crbug.com/170925: We need to show the intent picker when we receive an intent from + // another app that 30x redirects to a YouTube/Google Maps/Play Store/Google+ URL etc. + boolean incomingIntentRedirect = + (isLink && isFromIntent && params.isRedirect()) || isOnEffectiveIntentRedirect; + + if (shouldBlockAllExternalAppLaunches(params, incomingIntentRedirect)) { return OverrideUrlLoadingResult.forNoOverride(); } @@ -1318,21 +1344,9 @@ return OverrideUrlLoadingResult.forNoOverride(); } - int pageTransitionCore = params.getPageTransition() & PageTransition.CORE_MASK; - boolean isLink = pageTransitionCore == PageTransition.LINK; boolean isFormSubmit = pageTransitionCore == PageTransition.FORM_SUBMIT; - boolean isFromIntent = (params.getPageTransition() & PageTransition.FROM_API) != 0; boolean linkNotFromIntent = isLink && !isFromIntent; - boolean isOnEffectiveIntentRedirect = params.getRedirectHandler() == null - ? false - : params.getRedirectHandler().isOnEffectiveIntentRedirectChain(); - - // http://crbug.com/170925: We need to show the intent picker when we receive an intent from - // another app that 30x redirects to a YouTube/Google Maps/Play Store/Google+ URL etc. - boolean incomingIntentRedirect = - (isLink && isFromIntent && params.isRedirect()) || isOnEffectiveIntentRedirect; - if (handleCCTRedirectsToInstantApps(params, isExternalProtocol, incomingIntentRedirect)) { return OverrideUrlLoadingResult.forExternalIntent(); } else if (redirectShouldStayInApp(params, isExternalProtocol, targetIntent)) {
diff --git a/components/history_clusters/core/config.cc b/components/history_clusters/core/config.cc index 34699a1..82f8cbe 100644 --- a/components/history_clusters/core/config.cc +++ b/components/history_clusters/core/config.cc
@@ -232,17 +232,21 @@ // is enabled. DCHECK(GetConfig().is_journeys_enabled_no_locale_check); - // Default to "", because defaulting it to a specific locale makes it hard - // to allow all locales, since the FeatureParam code interprets an empty - // string as undefined, and instead returns the default value. + // Note, we now set a default value for the allowlist, which means that when + // the feature parameter is undefined, the below allowlist is enabled. const base::FeatureParam<std::string> kLocaleOrLanguageAllowlist{ - &internal::kJourneys, "JourneysLocaleOrLanguageAllowlist", ""}; + &internal::kJourneys, "JourneysLocaleOrLanguageAllowlist", + "de:en:es:fr:it:nl:pt:tr"}; + + // To allow for using any locale, we also interpret the special '*' value. + auto allowlist_string = kLocaleOrLanguageAllowlist.Get(); + if (allowlist_string == "*") + return true; // Allow comma and colon as delimiters to the language list. - auto allowlist = - base::SplitString(kLocaleOrLanguageAllowlist.Get(), - ",:", base::WhitespaceHandling::TRIM_WHITESPACE, - base::SplitResult::SPLIT_WANT_NONEMPTY); + auto allowlist = base::SplitString( + allowlist_string, ",:", base::WhitespaceHandling::TRIM_WHITESPACE, + base::SplitResult::SPLIT_WANT_NONEMPTY); // Allow any exact locale matches, and also allow any users where the // primary language subtag, e.g. "en" from "en-US" to match any element of
diff --git a/components/history_clusters/core/config.h b/components/history_clusters/core/config.h index ecdc99a..78276e41 100644 --- a/components/history_clusters/core/config.h +++ b/components/history_clusters/core/config.h
@@ -67,7 +67,7 @@ // If enabled, changes the History Clusters omnibox action text to be: // "Resume your research" instead of "Resume your journey". - bool alternate_omnibox_action_text = true; + bool alternate_omnibox_action_text = false; // Enables the Journeys Omnibox Action chip. `kJourneys` must also be enabled // for this to take effect. @@ -107,7 +107,7 @@ // Returns whether content clustering is enabled and // should be performed by the clustering backend. - bool content_clustering_enabled = true; + bool content_clustering_enabled = false; // Returns the weight that should be placed on entity similarity for // determining if two clusters are similar enough to be combined into one.
diff --git a/components/history_clusters/core/config_unittest.cc b/components/history_clusters/core/config_unittest.cc index 473000c..637183f 100644 --- a/components/history_clusters/core/config_unittest.cc +++ b/components/history_clusters/core/config_unittest.cc
@@ -10,19 +10,18 @@ namespace history_clusters { -TEST(HistoryClustersConfigTest, OmniboxAction) { +TEST(HistoryClustersConfigTest, LocaleOrLanguageAllowlistDefault) { base::test::ScopedFeatureList features; - features.InitWithFeatures({internal::kJourneys, internal::kOmniboxAction}, - {}); + features.InitAndEnableFeature(internal::kJourneys); const struct { const std::string locale; bool expected_is_journeys_enabled; - } kLocaleTestCases[] = {{"", true}, + } kLocaleTestCases[] = {{"", false}, {"en", true}, {"fr", true}, - {"zh-TW", true}, - {" random junk ", true}}; + {"zh-TW", false}, + {" random junk ", false}}; for (const auto& test : kLocaleTestCases) { EXPECT_EQ(test.expected_is_journeys_enabled, @@ -31,6 +30,22 @@ } } +TEST(HistoryClustersConfigTest, LocaleOrLanguageWildcard) { + base::test::ScopedFeatureList features; + features.InitWithFeaturesAndParameters( + {{ + internal::kJourneys, + {{"JourneysLocaleOrLanguageAllowlist", "*"}}, + }}, + {}); + + EXPECT_TRUE(IsApplicationLocaleSupportedByJourneys("")); + EXPECT_TRUE(IsApplicationLocaleSupportedByJourneys("*")); + EXPECT_TRUE(IsApplicationLocaleSupportedByJourneys("en")); + EXPECT_TRUE(IsApplicationLocaleSupportedByJourneys("zh-TW")); + EXPECT_TRUE(IsApplicationLocaleSupportedByJourneys("random junk")); +} + TEST(HistoryClustersConfigTest, LocaleOrLanguageAllowlist) { base::test::ScopedFeatureList features; features.InitWithFeaturesAndParameters(
diff --git a/components/history_clusters/core/features.cc b/components/history_clusters/core/features.cc index e9da9d8..44e9130 100644 --- a/components/history_clusters/core/features.cc +++ b/components/history_clusters/core/features.cc
@@ -27,10 +27,10 @@ namespace internal { -const base::Feature kJourneys{"Journeys", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kJourneys{"Journeys", enabled_by_default_desktop_only}; const base::Feature kOmniboxAction{"JourneysOmniboxAction", - base::FEATURE_DISABLED_BY_DEFAULT}; + enabled_by_default_desktop_only}; const base::Feature kNonUserVisibleDebug{"JourneysNonUserVisibleDebug", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/history_clusters/core/history_clusters_service.cc b/components/history_clusters/core/history_clusters_service.cc index f490fafe..bd0bfd5 100644 --- a/components/history_clusters/core/history_clusters_service.cc +++ b/components/history_clusters/core/history_clusters_service.cc
@@ -125,6 +125,7 @@ debug_entities.Append(std::move(debug_entity)); } debug_visit.SetKey("entities", std::move(debug_entities)); + debug_visit.SetDoubleKey("site_engagement_score", visit.engagement_score); base::ListValue debug_duplicate_visits; for (const auto& duplicate_visit : visit.duplicate_visits) {
diff --git a/components/live_caption/BUILD.gn b/components/live_caption/BUILD.gn index 09fbc4d..dbc5192 100644 --- a/components/live_caption/BUILD.gn +++ b/components/live_caption/BUILD.gn
@@ -48,6 +48,7 @@ "//ui/strings:ui_strings_grit", "//ui/views", ] + } # toolkit_views } } # !is_android
diff --git a/components/live_caption/caption_bubble_controller.h b/components/live_caption/caption_bubble_controller.h index c433cd8..a07afdd 100644 --- a/components/live_caption/caption_bubble_controller.h +++ b/components/live_caption/caption_bubble_controller.h
@@ -8,10 +8,15 @@ #include <memory> #include <string> +#include "components/live_caption/views/caption_bubble.h" #include "media/mojo/mojom/speech_recognition_service.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/native_theme/caption_style.h" +namespace content { +class BrowserContext; +} + namespace captions { class CaptionBubbleContext; @@ -27,7 +32,7 @@ // class CaptionBubbleController { public: - CaptionBubbleController() = default; + explicit CaptionBubbleController() = default; virtual ~CaptionBubbleController() = default; CaptionBubbleController(const CaptionBubbleController&) = delete; CaptionBubbleController& operator=(const CaptionBubbleController&) = delete; @@ -42,7 +47,9 @@ const media::SpeechRecognitionResult& result) = 0; // Called when the speech service has an error. - virtual void OnError(CaptionBubbleContext* caption_bubble_context) = 0; + virtual void OnError(CaptionBubbleContext* caption_bubble_context, + CaptionBubbleErrorType error_type, + OnErrorClickedCallback error_clicked_callback) = 0; // Called when the audio stream has ended. virtual void OnAudioStreamEnd(
diff --git a/components/live_caption/live_caption_controller.cc b/components/live_caption/live_caption_controller.cc index 7f1ffc01..b09edb7f 100644 --- a/components/live_caption/live_caption_controller.cc +++ b/components/live_caption/live_caption_controller.cc
@@ -14,6 +14,7 @@ #include "components/live_caption/caption_bubble_controller.h" #include "components/live_caption/caption_util.h" #include "components/live_caption/pref_names.h" +#include "components/live_caption/views/caption_bubble.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_change_registrar.h" #include "components/soda/constants.h" @@ -37,9 +38,13 @@ namespace captions { -LiveCaptionController::LiveCaptionController(PrefService* profile_prefs, - PrefService* global_prefs) - : profile_prefs_(profile_prefs), global_prefs_(global_prefs) {} +LiveCaptionController::LiveCaptionController( + PrefService* profile_prefs, + PrefService* global_prefs, + content::BrowserContext* browser_context) + : profile_prefs_(profile_prefs), + global_prefs_(global_prefs), + browser_context_(browser_context) {} LiveCaptionController::~LiveCaptionController() { if (enabled_) { @@ -203,10 +208,13 @@ } void LiveCaptionController::OnError( - CaptionBubbleContext* caption_bubble_context) { + CaptionBubbleContext* caption_bubble_context, + CaptionBubbleErrorType error_type, + OnErrorClickedCallback error_clicked_callback) { if (!caption_bubble_controller_) return; - caption_bubble_controller_->OnError(caption_bubble_context); + caption_bubble_controller_->OnError(caption_bubble_context, error_type, + std::move(error_clicked_callback)); } void LiveCaptionController::OnAudioStreamEnd(
diff --git a/components/live_caption/live_caption_controller.h b/components/live_caption/live_caption_controller.h index f568c8a..0272281 100644 --- a/components/live_caption/live_caption_controller.h +++ b/components/live_caption/live_caption_controller.h
@@ -10,6 +10,7 @@ #include "base/memory/raw_ptr.h" #include "build/build_config.h" #include "components/keyed_service/core/keyed_service.h" +#include "components/live_caption/views/caption_bubble.h" #include "components/soda/constants.h" #include "components/soda/soda_installer.h" #include "media/mojo/mojom/speech_recognition_service.mojom.h" @@ -18,6 +19,10 @@ class PrefChangeRegistrar; +namespace content { +class BrowserContext; +} + namespace ui { class NativeTheme; } @@ -45,7 +50,8 @@ public ui::NativeThemeObserver { public: explicit LiveCaptionController(PrefService* profile_prefs, - PrefService* global_prefs); + PrefService* global_prefs, + content::BrowserContext* browser_context); ~LiveCaptionController() override; LiveCaptionController(const LiveCaptionController&) = delete; LiveCaptionController& operator=(const LiveCaptionController&) = delete; @@ -65,7 +71,9 @@ // Alerts the CaptionBubbleController that there is an error in the speech // recognition service. - void OnError(CaptionBubbleContext* caption_bubble_context); + void OnError(CaptionBubbleContext* caption_bubble_context, + CaptionBubbleErrorType error_type, + OnErrorClickedCallback error_clicked_callback); // Alerts the CaptionBubbleController that the audio stream has ended. void OnAudioStreamEnd(CaptionBubbleContext* caption_bubble_context); @@ -102,6 +110,7 @@ raw_ptr<PrefService> profile_prefs_; raw_ptr<PrefService> global_prefs_; + raw_ptr<content::BrowserContext> browser_context_; std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_; std::unique_ptr<CaptionBubbleController> caption_bubble_controller_; absl::optional<ui::CaptionStyle> caption_style_;
diff --git a/components/live_caption/views/caption_bubble.cc b/components/live_caption/views/caption_bubble.cc index 9228212..c5ccaba 100644 --- a/components/live_caption/views/caption_bubble.cc +++ b/components/live_caption/views/caption_bubble.cc
@@ -21,6 +21,7 @@ #include "components/strings/grit/components_strings.h" #include "components/vector_icons/vector_icons.h" #include "third_party/re2/src/re2/re2.h" +#include "ui/accessibility/ax_action_data.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/buildflags.h" @@ -42,6 +43,8 @@ #include "ui/views/controls/highlight_path_generator.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" +#include "ui/views/controls/link.h" +#include "ui/views/controls/styled_label.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/flex_layout.h" #include "ui/views/layout/flex_layout_types.h" @@ -165,6 +168,31 @@ } // namespace namespace captions { + +#if BUILDFLAG(IS_WIN) +class MediaFoundationRendererErrorMessageView : public views::StyledLabel { + public: + explicit MediaFoundationRendererErrorMessageView( + CaptionBubble* caption_bubble) + : caption_bubble_(caption_bubble) {} + + // views::View: + bool HandleAccessibleAction(const ui::AXActionData& action_data) override { + switch (action_data.action) { + case ax::mojom::Action::kDoDefault: + caption_bubble_->OnContentSettingsLinkClicked(); + return true; + default: + break; + } + return views::StyledLabel::HandleAccessibleAction(action_data); + } + + private: + CaptionBubble* const caption_bubble_; // Not owned. +}; +#endif + // CaptionBubble implementation of BubbleFrameView. This class takes care // of making the caption draggable. class CaptionBubbleFrameView : public views::BubbleFrameView { @@ -467,20 +495,72 @@ title->SetText(l10n_util::GetStringUTF16(IDS_LIVE_CAPTION_BUBBLE_TITLE)); title->GetViewAccessibility().OverrideIsIgnored(true); - auto error_text = std::make_unique<views::Label>(); - error_text->SetBackgroundColor(SK_ColorTRANSPARENT); - error_text->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); - error_text->SetText(l10n_util::GetStringUTF16(IDS_LIVE_CAPTION_BUBBLE_ERROR)); - - auto error_icon = std::make_unique<views::ImageView>(); - - auto error_message = std::make_unique<views::View>(); - error_message + // Define an error message that will be displayed in the caption bubble if a + // generic error is encountered. + auto generic_error_text = std::make_unique<views::Label>(); + generic_error_text->SetBackgroundColor(SK_ColorTRANSPARENT); + generic_error_text->SetHorizontalAlignment( + gfx::HorizontalAlignment::ALIGN_LEFT); + generic_error_text->SetText( + l10n_util::GetStringUTF16(IDS_LIVE_CAPTION_BUBBLE_ERROR)); + auto generic_error_message = std::make_unique<views::View>(); + generic_error_message ->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), kErrorMessageBetweenChildSpacingDip)) ->set_cross_axis_alignment(views::BoxLayout::CrossAxisAlignment::kCenter); - error_message->SetVisible(false); + generic_error_message->SetVisible(false); + auto generic_error_icon = std::make_unique<views::ImageView>(); + +#if BUILDFLAG(IS_WIN) + // Define an error message that will be displayed in the caption bubble if the + // renderer is using hardware-based decryption. + auto media_foundation_renderer_error_message = + std::make_unique<views::View>(); + media_foundation_renderer_error_message + ->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), + kErrorMessageBetweenChildSpacingDip)) + ->set_cross_axis_alignment(views::BoxLayout::CrossAxisAlignment::kCenter); + media_foundation_renderer_error_message->SetVisible(false); + auto media_foundation_renderer_error_icon = + std::make_unique<views::ImageView>(); + const std::u16string link = + l10n_util::GetStringUTF16(IDS_LIVE_CAPTION_BUBBLE_CONTENT_SETTINGS); + size_t offset; + const std::u16string text = l10n_util::GetStringFUTF16( + IDS_LIVE_CAPTION_BUBBLE_MEDIA_FOUNDATION_RENDERER_ERROR, link, &offset); + auto media_foundation_renderer_error_text = + std::make_unique<MediaFoundationRendererErrorMessageView>(this); + media_foundation_renderer_error_text->SetText(text); + media_foundation_renderer_error_text->SetAutoColorReadabilityEnabled(false); + media_foundation_renderer_error_text->SetFocusBehavior(FocusBehavior::ALWAYS); + + // Make the whole text view behave as a link for accessibility. + media_foundation_renderer_error_text->GetViewAccessibility().OverrideRole( + ax::mojom::Role::kLink); + + auto custom_view = std::make_unique<views::Link>(link); + custom_view->SetCallback(base::BindRepeating( + &CaptionBubble::OnContentSettingsLinkClicked, base::Unretained(this))); + custom_view->SetFontList(GetFontList()); + custom_view->SetEnabledColor(gfx::kGoogleBlue300); + + views::StyledLabel::RangeStyleInfo error_message_style; + error_message_style.override_color = SK_ColorWHITE; + error_message_style.custom_font = GetFontList(); + media_foundation_renderer_error_text->AddStyleRange(gfx::Range(0, offset), + error_message_style); + + views::StyledLabel::RangeStyleInfo link_style = error_message_style; + link_style.custom_view = custom_view.get(); + + media_foundation_renderer_error_text->AddCustomView(std::move(custom_view)); + media_foundation_renderer_error_text->AddStyleRange( + gfx::Range(offset + link.length(), text.length()), error_message_style); + media_foundation_renderer_error_text->AddStyleRange( + gfx::Range(offset, offset + link.length()), link_style); +#endif views::Button::PressedCallback expand_or_collapse_callback = base::BindRepeating(&CaptionBubble::ExpandOrCollapseButtonPressed, @@ -511,9 +591,23 @@ title_ = content_container->AddChildView(std::move(title)); label_ = content_container->AddChildView(std::move(label)); - error_icon_ = error_message->AddChildView(std::move(error_icon)); - error_text_ = error_message->AddChildView(std::move(error_text)); - error_message_ = content_container->AddChildView(std::move(error_message)); + generic_error_icon_ = + generic_error_message->AddChildView(std::move(generic_error_icon)); + generic_error_text_ = + generic_error_message->AddChildView(std::move(generic_error_text)); + generic_error_message_ = + content_container->AddChildView(std::move(generic_error_message)); + +#if BUILDFLAG(IS_WIN) + media_foundation_renderer_error_icon_ = + media_foundation_renderer_error_message->AddChildView( + std::move(media_foundation_renderer_error_icon)); + media_foundation_renderer_error_text_ = + media_foundation_renderer_error_message->AddChildView( + std::move(media_foundation_renderer_error_text)); + media_foundation_renderer_error_message_ = content_container->AddChildView( + std::move(media_foundation_renderer_error_message)); +#endif expand_button_ = content_container->AddChildView(std::move(expand_button)); collapse_button_ = @@ -634,18 +728,39 @@ inactivity_timer_->Reset(); } -void CaptionBubble::OnErrorChanged() { +void CaptionBubble::OnErrorChanged(CaptionBubbleErrorType error_type, + OnErrorClickedCallback callback) { DCHECK(model_); + error_clicked_callback_ = std::move(callback); bool has_error = model_->HasError(); label_->SetVisible(!has_error); - error_message_->SetVisible(has_error); expand_button_->SetVisible(!has_error && !is_expanded_); collapse_button_->SetVisible(!has_error && is_expanded_); - // The error is only 1 line, so redraw the bubble. +#if BUILDFLAG(IS_WIN) + if (error_type == + CaptionBubbleErrorType::MEDIA_FOUNDATION_RENDERER_UNSUPPORTED) { + media_foundation_renderer_error_message_->SetVisible(has_error); + generic_error_message_->SetVisible(false); + } else { + generic_error_message_->SetVisible(has_error); + media_foundation_renderer_error_message_->SetVisible(false); + } +#else + generic_error_message_->SetVisible(has_error); +#endif + Redraw(); } +#if BUILDFLAG(IS_WIN) +void CaptionBubble::OnContentSettingsLinkClicked() { + if (error_clicked_callback_) { + error_clicked_callback_.Run(); + } +} +#endif + void CaptionBubble::OnIsExpandedChanged() { expand_button_->SetVisible(!is_expanded_); collapse_button_->SetVisible(is_expanded_); @@ -728,10 +843,7 @@ } return textScaleFactor; } - -void CaptionBubble::SetTextSizeAndFontFamily() { - double textScaleFactor = GetTextScaleFactor(); - +const gfx::FontList CaptionBubble::GetFontList() { std::vector<std::string> font_names; if (caption_style_) { std::string font_family = @@ -743,19 +855,37 @@ font_names.push_back(kSecondaryFont); font_names.push_back(kTertiaryFont); - const gfx::FontList font_list = - gfx::FontList(font_names, gfx::Font::FontStyle::NORMAL, - kFontSizePx * textScaleFactor, gfx::Font::Weight::NORMAL); + const gfx::FontList font_list = gfx::FontList( + font_names, gfx::Font::FontStyle::NORMAL, + kFontSizePx * GetTextScaleFactor(), gfx::Font::Weight::NORMAL); + return font_list; +} + +void CaptionBubble::SetTextSizeAndFontFamily() { + double textScaleFactor = GetTextScaleFactor(); + const gfx::FontList font_list = GetFontList(); + label_->SetFontList(font_list); title_->SetFontList(font_list.DeriveWithStyle(gfx::Font::FontStyle::ITALIC)); - error_text_->SetFontList(font_list); + generic_error_text_->SetFontList(font_list); label_->SetLineHeight(kLineHeightDip * textScaleFactor); label_->SetMaximumWidth(kMaxWidthDip * textScaleFactor - kSidePaddingDip * 2); title_->SetLineHeight(kLineHeightDip * textScaleFactor); - error_text_->SetLineHeight(kLineHeightDip * textScaleFactor); - error_icon_->SetImageSize(gfx::Size(kErrorImageSizeDip * textScaleFactor, - kErrorImageSizeDip * textScaleFactor)); + generic_error_text_->SetLineHeight(kLineHeightDip * textScaleFactor); + generic_error_icon_->SetImageSize( + gfx::Size(kErrorImageSizeDip * textScaleFactor, + kErrorImageSizeDip * textScaleFactor)); + +#if BUILDFLAG(IS_WIN) + media_foundation_renderer_error_icon_->SetImageSize( + gfx::Size(kErrorImageSizeDip * textScaleFactor, + kErrorImageSizeDip * textScaleFactor)); + media_foundation_renderer_error_text_->SizeToFit( + kMaxWidthDip * textScaleFactor - kSidePaddingDip * 2); + media_foundation_renderer_error_text_->SetLineHeight(kLineHeightDip * + textScaleFactor); +#endif } void CaptionBubble::SetTextColor() { @@ -765,10 +895,14 @@ &text_color); label_->SetEnabledColor(text_color); title_->SetEnabledColor(text_color); - error_text_->SetEnabledColor(text_color); + generic_error_text_->SetEnabledColor(text_color); - error_icon_->SetImage( + generic_error_icon_->SetImage( gfx::CreateVectorIcon(vector_icons::kErrorOutlineIcon, text_color)); +#if BUILDFLAG(IS_WIN) + media_foundation_renderer_error_icon_->SetImage( + gfx::CreateVectorIcon(vector_icons::kErrorOutlineIcon, text_color)); +#endif views::SetImageFromVectorIcon(back_to_tab_button_, vector_icons::kLaunchIcon, kButtonDip, text_color); views::SetImageFromVectorIcon(close_button_, vector_icons::kCloseRoundedIcon, @@ -801,9 +935,7 @@ double text_scale_factor = GetTextScaleFactor(); int width = kMaxWidthDip * text_scale_factor; int content_height = - (model_ && model_->HasError()) - ? kLineHeightDip * text_scale_factor - : kLineHeightDip * GetNumLinesVisible() * text_scale_factor; + kLineHeightDip * GetNumLinesVisible() * text_scale_factor; // The title takes up 1 line. int label_height = title_->GetVisible() ? content_height - kLineHeightDip * text_scale_factor
diff --git a/components/live_caption/views/caption_bubble.h b/components/live_caption/views/caption_bubble.h index f7e7950..14416b75 100644 --- a/components/live_caption/views/caption_bubble.h +++ b/components/live_caption/views/caption_bubble.h
@@ -8,13 +8,17 @@ #include <memory> #include <string> +#include "base/callback.h" #include "base/callback_helpers.h" #include "base/memory/raw_ptr.h" +#include "build/buildflag.h" #include "components/live_caption/views/caption_bubble_model.h" #include "ui/base/metadata/metadata_header_macros.h" +#include "ui/gfx/font_list.h" #include "ui/native_theme/caption_style.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" #include "ui/views/controls/button/button.h" +#include "ui/views/controls/styled_label.h" #include "ui/views/metadata/view_factory.h" namespace base { @@ -75,6 +79,10 @@ tick_clock_ = tick_clock; } +#if BUILDFLAG(IS_WIN) + void OnContentSettingsLinkClicked(); +#endif + protected: // views::BubbleDialogDelegateView: void Init() override; @@ -105,7 +113,8 @@ // Called by CaptionBubbleModel to notify this object that the model's error // state has changed. Makes the caption bubble display an error message if // the model has an error, otherwise displays the latest text. - void OnErrorChanged(); + void OnErrorChanged(CaptionBubbleErrorType error_type, + OnErrorClickedCallback callback); // Called when the caption bubble expanded state has changed. Changes the // number of lines displayed. @@ -135,6 +144,7 @@ // preferences, which are stored in `caption_style_`. void SetCaptionBubbleStyle(); double GetTextScaleFactor(); + const gfx::FontList GetFontList(); void SetTextSizeAndFontFamily(); void SetTextColor(); void SetBackgroundColor(); @@ -147,18 +157,25 @@ // Unowned. Owned by views hierarchy. raw_ptr<CaptionBubbleLabel> label_; raw_ptr<views::Label> title_; - raw_ptr<views::Label> error_text_; - raw_ptr<views::ImageView> error_icon_; - raw_ptr<views::View> error_message_; + raw_ptr<views::Label> generic_error_text_; + raw_ptr<views::ImageView> generic_error_icon_; + raw_ptr<views::View> generic_error_message_; raw_ptr<views::ImageButton> back_to_tab_button_; raw_ptr<views::ImageButton> close_button_; raw_ptr<views::ImageButton> expand_button_; raw_ptr<views::ImageButton> collapse_button_; raw_ptr<CaptionBubbleFrameView> frame_; +#if BUILDFLAG(IS_WIN) + raw_ptr<views::StyledLabel> media_foundation_renderer_error_text_; + raw_ptr<views::ImageView> media_foundation_renderer_error_icon_; + raw_ptr<views::View> media_foundation_renderer_error_message_; +#endif + absl::optional<ui::CaptionStyle> caption_style_; raw_ptr<CaptionBubbleModel> model_ = nullptr; + OnErrorClickedCallback error_clicked_callback_; base::ScopedClosureRunner destroyed_callback_; // Whether the caption bubble is expanded to show more lines of text.
diff --git a/components/live_caption/views/caption_bubble_controller_views.cc b/components/live_caption/views/caption_bubble_controller_views.cc index 340e2eb..77fe19c1 100644 --- a/components/live_caption/views/caption_bubble_controller_views.cc +++ b/components/live_caption/views/caption_bubble_controller_views.cc
@@ -64,13 +64,15 @@ } void CaptionBubbleControllerViews::OnError( - CaptionBubbleContext* caption_bubble_context) { + CaptionBubbleContext* caption_bubble_context, + CaptionBubbleErrorType error_type, + OnErrorClickedCallback error_clicked_callback) { if (!caption_bubble_) return; SetActiveModel(caption_bubble_context); if (active_model_->IsClosed()) return; - active_model_->OnError(); + active_model_->OnError(error_type, std::move(error_clicked_callback)); } void CaptionBubbleControllerViews::OnAudioStreamEnd(
diff --git a/components/live_caption/views/caption_bubble_controller_views.h b/components/live_caption/views/caption_bubble_controller_views.h index ddb9658..a09619f2 100644 --- a/components/live_caption/views/caption_bubble_controller_views.h +++ b/components/live_caption/views/caption_bubble_controller_views.h
@@ -11,6 +11,7 @@ #include "base/memory/raw_ptr.h" #include "components/live_caption/caption_bubble_controller.h" +#include "components/live_caption/views/caption_bubble.h" namespace views { class Widget; @@ -28,7 +29,7 @@ // class CaptionBubbleControllerViews : public CaptionBubbleController { public: - CaptionBubbleControllerViews(); + explicit CaptionBubbleControllerViews(); ~CaptionBubbleControllerViews() override; CaptionBubbleControllerViews(const CaptionBubbleControllerViews&) = delete; CaptionBubbleControllerViews& operator=(const CaptionBubbleControllerViews&) = @@ -41,7 +42,9 @@ const media::SpeechRecognitionResult& result) override; // Called when the speech service has an error. - void OnError(CaptionBubbleContext* caption_bubble_context) override; + void OnError(CaptionBubbleContext* caption_bubble_context, + CaptionBubbleErrorType error_type, + OnErrorClickedCallback error_clicked_callback) override; // Called when the audio stream has ended. void OnAudioStreamEnd(CaptionBubbleContext* caption_bubble_context) override;
diff --git a/components/live_caption/views/caption_bubble_model.cc b/components/live_caption/views/caption_bubble_model.cc index 0fa8a51..9fc87e9 100644 --- a/components/live_caption/views/caption_bubble_model.cc +++ b/components/live_caption/views/caption_bubble_model.cc
@@ -4,6 +4,7 @@ #include "components/live_caption/views/caption_bubble_model.h" +#include "base/callback_forward.h" #include "components/live_caption/caption_bubble_context.h" #include "components/live_caption/views/caption_bubble.h" @@ -31,7 +32,8 @@ observer_ = observer; if (observer_) { observer_->OnTextChanged(); - observer_->OnErrorChanged(); + observer_->OnErrorChanged(CaptionBubbleErrorType::GENERIC, + base::RepeatingClosure()); } } @@ -50,7 +52,8 @@ if (has_error_) { has_error_ = false; if (observer_) - observer_->OnErrorChanged(); + observer_->OnErrorChanged(CaptionBubbleErrorType::GENERIC, + base::RepeatingClosure()); } } @@ -64,10 +67,12 @@ OnTextChanged(); } -void CaptionBubbleModel::OnError() { +void CaptionBubbleModel::OnError( + CaptionBubbleErrorType error_type, + OnErrorClickedCallback error_clicked_callback) { has_error_ = true; if (observer_) - observer_->OnErrorChanged(); + observer_->OnErrorChanged(error_type, std::move(error_clicked_callback)); } void CaptionBubbleModel::ClearText() {
diff --git a/components/live_caption/views/caption_bubble_model.h b/components/live_caption/views/caption_bubble_model.h index 4245465a..cf24d78 100644 --- a/components/live_caption/views/caption_bubble_model.h +++ b/components/live_caption/views/caption_bubble_model.h
@@ -7,6 +7,7 @@ #include <string> +#include "base/callback.h" #include "base/memory/raw_ptr.h" namespace captions { @@ -14,6 +15,9 @@ class CaptionBubble; class CaptionBubbleContext; +enum CaptionBubbleErrorType { GENERIC, MEDIA_FOUNDATION_RENDERER_UNSUPPORTED }; +using OnErrorClickedCallback = base::RepeatingCallback<void()>; + /////////////////////////////////////////////////////////////////////////////// // Caption Bubble Model // @@ -53,7 +57,8 @@ void CommitPartialText(); // Set that the bubble has an error and alert the observer. - void OnError(); + void OnError(CaptionBubbleErrorType error_type, + OnErrorClickedCallback error_clicked_callback); // Mark the bubble as closed, clear the partial and final text, and alert the // observer.
diff --git a/components/live_caption_strings.grdp b/components/live_caption_strings.grdp index f9a2e414..7bb8b49 100644 --- a/components/live_caption_strings.grdp +++ b/components/live_caption_strings.grdp
@@ -19,6 +19,12 @@ <message name="IDS_LIVE_CAPTION_BUBBLE_ERROR" desc="Error message for the Live Caption bubble when Live Captions are unavailable."> Live Caption is not available right now </message> + <message name="IDS_LIVE_CAPTION_BUBBLE_CONTENT_SETTINGS" desc="Text of Content Settings links."> + protected content IDs + </message> + <message name="IDS_LIVE_CAPTION_BUBBLE_MEDIA_FOUNDATION_RENDERER_ERROR" desc="Error message for the Live Caption bubble when Live Captions are unavailable because the renderer is using hardware-based decryption."> + Live Caption is not available for this media. To get captions, block <ph name="CONTENT_SETTINGS">$1<ex>protected content IDs</ex></ph> for this site. + </message> <message name="IDS_LIVE_CAPTION_BUBBLE_APPEAR_SCREENREADER_ANNOUNCEMENT" desc="Announcement to screen readers on ChromeOS when the Live Caption bubble appears to inform users of how to focus the bubble."> Live Caption visible, use window switcher to focus </message>
diff --git a/components/live_caption_strings_grdp/IDS_LIVE_CAPTION_BUBBLE_CONTENT_SETTINGS.png.sha1 b/components/live_caption_strings_grdp/IDS_LIVE_CAPTION_BUBBLE_CONTENT_SETTINGS.png.sha1 new file mode 100644 index 0000000..6701013 --- /dev/null +++ b/components/live_caption_strings_grdp/IDS_LIVE_CAPTION_BUBBLE_CONTENT_SETTINGS.png.sha1
@@ -0,0 +1 @@ +715c38ef9567b9c39e45c319d9c811830b6fcb8f \ No newline at end of file
diff --git a/components/live_caption_strings_grdp/IDS_LIVE_CAPTION_BUBBLE_MEDIA_FOUNDATION_RENDERER_ERROR.png.sha1 b/components/live_caption_strings_grdp/IDS_LIVE_CAPTION_BUBBLE_MEDIA_FOUNDATION_RENDERER_ERROR.png.sha1 new file mode 100644 index 0000000..6701013 --- /dev/null +++ b/components/live_caption_strings_grdp/IDS_LIVE_CAPTION_BUBBLE_MEDIA_FOUNDATION_RENDERER_ERROR.png.sha1
@@ -0,0 +1 @@ +715c38ef9567b9c39e45c319d9c811830b6fcb8f \ No newline at end of file
diff --git a/components/login/base_screen_handler_utils.cc b/components/login/base_screen_handler_utils.cc index da1a5c2..760d3b8 100644 --- a/components/login/base_screen_handler_utils.cc +++ b/components/login/base_screen_handler_utils.cc
@@ -4,118 +4,18 @@ #include "components/login/base_screen_handler_utils.h" -#include "base/strings/utf_string_conversions.h" +#include <string> +#include <vector> + #include "base/values.h" -#include "components/account_id/account_id.h" namespace login { -namespace { - -// Helpers to let ParseListString produce output of appropriate type. -void ConvertFromUTF8(const std::string& in, std::string& out) { - out = in; +StringList ConvertToStringList(const base::Value::List& list) { + StringList result; + for (const auto& val : list) + result.push_back(val.GetString()); + return result; } -void ConvertFromUTF8(const std::string& in, std::u16string& out) { - out = base::UTF8ToUTF16(in); -} - -template <typename StringListType> -bool ParseStringList(const base::Value* value, StringListType* out_value) { - if (!value->is_list()) - return false; - base::Value::ConstListView list = value->GetListDeprecated(); - out_value->resize(list.size()); - for (size_t i = 0; i < list.size(); ++i) { - if (!list[i].is_string()) - return false; - ConvertFromUTF8(list[i].GetString(), (*out_value)[i]); - } - return true; -} - -} // namespace - -bool ParseValue(const base::Value* value, bool* out_value) { - if (out_value && value->is_bool()) { - *out_value = value->GetBool(); - return true; - } - return value->is_bool(); -} - -bool ParseValue(const base::Value* value, int* out_value) { - if (out_value && value->is_int()) { - *out_value = value->GetInt(); - return true; - } - return value->is_int(); -} - -bool ParseValue(const base::Value* value, double* out_value) { - if (out_value && (value->is_double() || value->is_int())) { - *out_value = value->GetDouble(); - return true; - } - return value->is_double() || value->is_int(); -} - -bool ParseValue(const base::Value* value, std::string* out_value) { - if (out_value && value->is_string()) { - *out_value = value->GetString(); - return true; - } - return value->is_string(); -} - -bool ParseValue(const base::Value* value, std::u16string* out_value) { - if (out_value && value->is_string()) { - *out_value = base::UTF8ToUTF16(value->GetString()); - return true; - } - return value->is_string(); -} - -bool ParseValue(const base::Value* value, - const base::DictionaryValue** out_value) { - if (out_value && value->is_dict()) { - *out_value = static_cast<const base::DictionaryValue*>(value); - return true; - } - return value->is_dict(); -} - -bool ParseValue(const base::Value* value, StringList* out_value) { - return ParseStringList(value, out_value); -} - -bool ParseValue(const base::Value* value, String16List* out_value) { - return ParseStringList(value, out_value); -} - -bool ParseValue(const base::Value* value, AccountId* out_value) { - if (!value->is_string()) - return false; - - std::string serialized = value->GetString(); - if (AccountId::Deserialize(serialized, out_value)) - return true; - - *out_value = AccountId::FromUserEmail(serialized); - LOG(ERROR) << "Failed to deserialize, parse as email, valid=" - << out_value->is_valid(); - return true; -} - -bool ParseValue(const base::Value* value, const base::ListValue** out_value) { - if (out_value && value->is_list()) { - *out_value = static_cast<const base::ListValue*>(value); - return true; - } - return false; -} - -ParsedValueContainer<AccountId>::ParsedValueContainer() = default; - } // namespace login
diff --git a/components/login/base_screen_handler_utils.h b/components/login/base_screen_handler_utils.h index d2bbf35..a95f43b 100644 --- a/components/login/base_screen_handler_utils.h +++ b/components/login/base_screen_handler_utils.h
@@ -5,88 +5,17 @@ #ifndef COMPONENTS_LOGIN_BASE_SCREEN_HANDLER_UTILS_H_ #define COMPONENTS_LOGIN_BASE_SCREEN_HANDLER_UTILS_H_ -#include <stddef.h> - #include <string> -#include <utility> +#include <vector> -#include "base/callback.h" -#include "base/logging.h" #include "base/values.h" -#include "components/account_id/account_id.h" #include "components/login/login_export.h" namespace login { -typedef std::vector<std::string> StringList; -typedef std::vector<std::u16string> String16List; +using StringList = std::vector<std::string>; -template <typename T> -struct LOGIN_EXPORT UnwrapConstRef { - typedef T Type; -}; - -template <typename T> -struct UnwrapConstRef<const T&> { - typedef T Type; -}; - -bool LOGIN_EXPORT ParseValue(const base::Value* value, bool* out_value); -bool LOGIN_EXPORT ParseValue(const base::Value* value, int* out_value); -bool LOGIN_EXPORT ParseValue(const base::Value* value, double* out_value); -bool LOGIN_EXPORT ParseValue(const base::Value* value, std::string* out_value); -bool LOGIN_EXPORT ParseValue(const base::Value* value, - std::u16string* out_value); -bool LOGIN_EXPORT ParseValue(const base::Value* value, - const base::DictionaryValue** out_value); -bool LOGIN_EXPORT ParseValue(const base::Value* value, StringList* out_value); -bool LOGIN_EXPORT ParseValue(const base::Value* value, String16List* out_value); -bool LOGIN_EXPORT ParseValue(const base::Value* value, AccountId* out_value); -bool LOGIN_EXPORT ParseValue(const base::Value* value, - const base::ListValue** out_value); - -template <typename T> -inline bool GetArg(const base::ListValue* args, size_t index, T* out_value) { - const auto& list = args->GetListDeprecated(); - if (list.size() <= index) - return false; - return ParseValue(&list[index], out_value); -} - -template <typename T> -struct ParsedValueContainer { - T value; -}; - -template <> -struct LOGIN_EXPORT ParsedValueContainer<AccountId> { - ParsedValueContainer(); - AccountId value = EmptyAccountId(); -}; - -template <typename Arg, size_t index> -typename UnwrapConstRef<Arg>::Type ParseArg(const base::ListValue* args) { - ParsedValueContainer<typename UnwrapConstRef<Arg>::Type> parsed; - CHECK(GetArg(args, index, &parsed.value)); - return parsed.value; -} - -template <typename... Args, size_t... Ns> -inline void DispatchToCallback( - const base::RepeatingCallback<void(Args...)>& callback, - const base::ListValue* args, - std::index_sequence<Ns...> indexes) { - DCHECK(args); - DCHECK_EQ(sizeof...(Args), args->GetListDeprecated().size()); - - callback.Run(ParseArg<Args, Ns>(args)...); -} - -template <typename... Args> -void CallbackWrapper(const base::RepeatingCallback<void(Args...)>& callback, - const base::ListValue* args) { - DispatchToCallback(callback, args, std::index_sequence_for<Args...>()); -} +StringList LOGIN_EXPORT ConvertToStringList(const base::Value::List& list); } // namespace login
diff --git a/components/omnibox/browser/search_provider.cc b/components/omnibox/browser/search_provider.cc index 5e70f6a..d79dac5 100644 --- a/components/omnibox/browser/search_provider.cc +++ b/components/omnibox/browser/search_provider.cc
@@ -1597,11 +1597,6 @@ suggestion.answer()->AddImageURLsTo(&prefetch_image_urls); } - UMA_HISTOGRAM_EXACT_LINEAR( - "Omnibox.SuggestRequest.Success.PrefetchImagesCount", - prefetch_image_urls.size(), - AutocompleteResult::kMaxAutocompletePositionValue); - for (const GURL& url : prefetch_image_urls) client()->PrefetchImage(url); }
diff --git a/components/page_load_metrics/OWNERS b/components/page_load_metrics/OWNERS index c30b360..ac1e8d0 100644 --- a/components/page_load_metrics/OWNERS +++ b/components/page_load_metrics/OWNERS
@@ -1,5 +1,6 @@ npm@chromium.org sullivan@chromium.org +yoavweiss@chromium.org csharrison@chromium.org jkarlin@chromium.org ryansturm@chromium.org
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index 144d60b..bd1bb74 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn
@@ -36,6 +36,8 @@ "android_affiliation/facet_manager_host.h", "android_affiliation/lookup_affiliation_response_parser.cc", "android_affiliation/lookup_affiliation_response_parser.h", + "android_backend_error.cc", + "android_backend_error.h", "browser_save_password_progress_logger.cc", "browser_save_password_progress_logger.h", "bulk_leak_check_service.cc", @@ -463,6 +465,7 @@ java_cpp_enum("password_manager_java_enums_srcjar") { sources = [ + "android_backend_error.h", "manage_passwords_referrer.h", "password_manager_metrics_util.h", ]
diff --git a/chrome/browser/password_manager/android/android_backend_error.cc b/components/password_manager/core/browser/android_backend_error.cc similarity index 84% rename from chrome/browser/password_manager/android/android_backend_error.cc rename to components/password_manager/core/browser/android_backend_error.cc index c655c233..7421ec2 100644 --- a/chrome/browser/password_manager/android/android_backend_error.cc +++ b/components/password_manager/core/browser/android_backend_error.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/password_manager/android/android_backend_error.h" +#include "components/password_manager/core/browser/android_backend_error.h" namespace password_manager {
diff --git a/chrome/browser/password_manager/android/android_backend_error.h b/components/password_manager/core/browser/android_backend_error.h similarity index 86% rename from chrome/browser/password_manager/android/android_backend_error.h rename to components/password_manager/core/browser/android_backend_error.h index b48bf9474..85783f07 100644 --- a/chrome/browser/password_manager/android/android_backend_error.h +++ b/components/password_manager/core/browser/android_backend_error.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_ANDROID_BACKEND_ERROR_H_ -#define CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_ANDROID_BACKEND_ERROR_H_ +#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_ANDROID_BACKEND_ERROR_H_ +#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_ANDROID_BACKEND_ERROR_H_ #include "third_party/abseil-cpp/absl/types/optional.h" @@ -47,4 +47,4 @@ } // namespace password_manager -#endif // CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_ANDROID_BACKEND_ERROR_H_ +#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_ANDROID_BACKEND_ERROR_H_
diff --git a/components/password_manager/core/browser/password_autofill_manager.cc b/components/password_manager/core/browser/password_autofill_manager.cc index 6e2a026..606755f 100644 --- a/components/password_manager/core/browser/password_autofill_manager.cc +++ b/components/password_manager/core/browser/password_autofill_manager.cc
@@ -154,7 +154,7 @@ suggestion.custom_icon = custom_icon; // The UI code will pick up an icon from the resources based on the string. suggestion.icon = "globeIcon"; - suggestion.store_indicator_icon = CreateStoreIcon(from_account_store); + suggestion.trailing_icon = CreateStoreIcon(from_account_store); suggestions->push_back(suggestion); } } @@ -234,6 +234,11 @@ // The UI code will pick up an icon from the resources based on the string. suggestion.icon = "settingsIcon"; } + if (base::FeatureList::IsEnabled( + password_manager::features::kUnifiedPasswordManagerDesktop)) { + // The UI code will pick up an icon from the resources based on the string. + suggestion.trailing_icon = "googlePasswordManager"; + } suggestions->push_back(std::move(suggestion)); }
diff --git a/components/password_manager/core/browser/password_autofill_manager_unittest.cc b/components/password_manager/core/browser/password_autofill_manager_unittest.cc index e438754..cdd00337361 100644 --- a/components/password_manager/core/browser/password_autofill_manager_unittest.cc +++ b/components/password_manager/core/browser/password_autofill_manager_unittest.cc
@@ -1488,7 +1488,7 @@ autofill::ShowPasswordSuggestionsOptions(), element_bounds); ASSERT_THAT(open_args.suggestions.size(), testing::Ge(1u)); // No footer on Android. - EXPECT_THAT(open_args.suggestions[0].store_indicator_icon, "google"); + EXPECT_THAT(open_args.suggestions[0].trailing_icon, "google"); EXPECT_FALSE(open_args.autoselect_first_suggestion); EXPECT_EQ(open_args.popup_type, PopupType::kPasswords); }
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 20afada..2163303 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -26584,7 +26584,7 @@ }, { 'name': 'LocalDiscoveryEnabled', - 'owners': ['file://cloud_print/OWNERS', 'weili@chromium.org'], + 'owners': ['thestig@chromium.org', 'weili@chromium.org'], 'type': 'main', 'schema': { 'type': 'boolean' }, 'supported_on': ['chrome.*:81-87', 'chrome_os:81-87'], @@ -28432,28 +28432,17 @@ 'owners': ['mjackson@microsoft.com', 'cmp@chromium.org', 'file://chrome/browser/web_applications/OWNERS', 'tapted@chromium.org'], 'type': 'dict', 'schema': { - 'type': 'object', - 'patternProperties': { - '^.+$': { - 'type': 'object', - 'properties': { - 'run_on_os_login': { - 'type': 'string', - 'enum': ['allowed', 'blocked', 'run_windowed'] - } - }, - } - }, - 'properties': { - '*': { - 'type': 'object', - 'properties': { - 'run_on_os_login': { - 'type': 'string', - 'enum': ['allowed', 'blocked'] - } + 'type': 'array', + 'items': { + 'type': 'object', + 'properties': { + 'manifest_id': { 'type': 'string', }, + 'run_on_os_login': { + 'type': 'string', + 'enum': ['allowed', 'blocked', 'run_windowed'] }, }, + 'required': ['manifest_id'] }, }, 'future_on': ['chrome.*'], @@ -28461,28 +28450,32 @@ 'dynamic_refresh': True, 'per_profile': False, }, - 'example_value': { - 'https://foo.example' : { - 'run_on_os_login': 'allowed', + 'example_value': [ + { + 'manifest_id': 'https://foo.example/index.html', + 'run_on_os_login': 'allowed' }, - 'https://bar.example' : { - 'run_on_os_login': 'blocked', + { + 'manifest_id': 'https://bar.example/index.html', + 'run_on_os_login': 'allowed' }, - 'https://foobar.example' : { - 'run_on_os_login': 'run_windowed', + { + 'manifest_id': 'https://foobar.example/index.html', + 'run_on_os_login': 'run_windowed' }, - '*': { - 'run_on_os_login': 'blocked', - }, - }, + { + 'manifest_id': '*', + 'run_on_os_login': 'blocked' + } + ], 'id': 824, 'caption': 'Web App management settings', 'tags': [], 'desc': '''This policy allows an admin to specify settings for installed web apps. - This policy maps a Web App ID to its specific setting. See <ph name="WEB_APP_ID_REFERENCE_URL">https://developer.chrome.com/blog/pwa-manifest-id/<ex>https://developer.chrome.com/blog/pwa-manifest-id/</ex></ph> for instructions on how to determine the id for an installed web app. - A default configuration can be set using the special ID <ph name="DEFAULT_SCOPE">"*"</ph>, which applies to all web apps without a custom configuration in this policy. + This policy maps a Web App ID to its specific setting. A default configuration can be set using the special ID <ph name="DEFAULT_SCOPE">"*"</ph>, which applies to all web apps without a custom configuration in this policy. + The <ph name="MANIFEST_ID_FIELD">"manifest_id"</ph> field is the Manifest ID for the Web App. See <ph name="WEB_APP_ID_REFERENCE_URL">https://developer.chrome.com/blog/pwa-manifest-id/<ex>https://developer.chrome.com/blog/pwa-manifest-id/</ex></ph> for instructions on how to determine the Manifest ID for an installed web app. The <ph name="RUN_ON_OS_LOGIN_FIELD">"run_on_os_login"</ph> field specifies if a web app can be run during OS login. If this field is set to <ph name="BLOCKED">"blocked"</ph>, the web app will not run during OS login and the user will not be able to enable this later. If this field is set to <ph name="RUN_WINDOWED">"run_windowed"</ph>, the web app will run during OS login and the user will not be able to disable this later. If this field is set to <ph name="ALLOWED">"allowed"</ph>, the user will be able to configure the web app to run at OS login. The default configuration only allows the <ph name="ALLOWED">"allowed"</ph> and <ph name="BLOCKED">"blocked"</ph> values. ''', },
diff --git a/components/reporting/storage/storage_queue_unittest.cc b/components/reporting/storage/storage_queue_unittest.cc index 35bfe77..1cfaacf0 100644 --- a/components/reporting/storage/storage_queue_unittest.cc +++ b/components/reporting/storage/storage_queue_unittest.cc
@@ -354,8 +354,7 @@ : uploader_id_(next_uploader_id.fetch_add(1)), last_record_digest_map_(&self->last_record_digest_map_), mock_upload_(&self->mock_upload_), - sequence_bound_upload_(self->main_thread_task_runner_, - &self->mock_upload_) { + sequence_bound_upload_(self->main_task_runner_, &self->mock_upload_) { DETACH_FROM_SEQUENCE(test_uploader_checker_); } @@ -590,7 +589,7 @@ void AsyncStartMockUploader( UploaderInterface::UploadReason reason, UploaderInterface::UploaderInterfaceResultCb start_uploader_cb) { - main_thread_task_runner_->PostTask( + main_task_runner_->PostTask( FROM_HERE, base::BindOnce( [](UploaderInterface::UploadReason reason, @@ -649,9 +648,9 @@ std::string dm_token_; base::test::TaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; - // Single task runner where all EXPECTs will happen - main thread. - const scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_{ - base::ThreadTaskRunnerHandle::Get()}; + // Sequenced task runner where all EXPECTs will happen. + const scoped_refptr<base::SequencedTaskRunner> main_task_runner_{ + base::SequencedTaskRunnerHandle::Get()}; base::test::ScopedFeatureList scoped_feature_list_; base::ScopedTempDir location_;
diff --git a/components/reporting/storage/storage_unittest.cc b/components/reporting/storage/storage_unittest.cc index 2d40093..b817988c 100644 --- a/components/reporting/storage/storage_unittest.cc +++ b/components/reporting/storage/storage_unittest.cc
@@ -527,8 +527,7 @@ : uploader_id_(next_uploader_id.fetch_add(1)), last_record_digest_map_(&self->last_record_digest_map_), mock_upload_(&self->mock_upload_), - sequence_bound_upload_(self->main_thread_task_runner_, - &self->mock_upload_), + sequence_bound_upload_(self->main_task_runner_, &self->mock_upload_), decryptor_(self->decryptor_) { DETACH_FROM_SEQUENCE(test_uploader_checker_); } @@ -794,7 +793,7 @@ void AsyncStartMockUploader( UploaderInterface::UploadReason reason, UploaderInterface::UploaderInterfaceResultCb start_uploader_cb) { - main_thread_task_runner_->PostTask( + main_task_runner_->PostTask( FROM_HERE, base::BindOnce( [](UploaderInterface::UploadReason reason, @@ -913,9 +912,9 @@ base::test::TaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; - // Single task runner where all EXPECTs will happen - main thread. - const scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_{ - base::ThreadTaskRunnerHandle::Get()}; + // Sequenced task runner where all EXPECTs will happen - main thread. + const scoped_refptr<base::SequencedTaskRunner> main_task_runner_{ + base::SequencedTaskRunnerHandle::Get()}; base::test::ScopedFeatureList scoped_feature_list_;
diff --git a/components/safe_browsing/content/browser/client_side_detection_host.cc b/components/safe_browsing/content/browser/client_side_detection_host.cc index 49a84af..e1f77601 100644 --- a/components/safe_browsing/content/browser/client_side_detection_host.cc +++ b/components/safe_browsing/content/browser/client_side_detection_host.cc
@@ -380,9 +380,19 @@ // We want to accurately track all active RenderFrameHosts, so make sure we // know about any pre-existings ones. - web_contents()->ForEachRenderFrameHost( - base::BindRepeating(&ClientSideDetectionHost::InitializePhishingDetector, - base::Unretained(this))); + web_contents()->ForEachRenderFrameHost(base::BindRepeating( + [](ClientSideDetectionHost* csdh, + const content::WebContents* web_contents, + content::RenderFrameHost* rfh) { + // Don't cross into inner WebContents since we wouldn't be notified of + // its changes. See https://crbug.com/1308829 + if (content::WebContents::FromRenderFrameHost(rfh) != web_contents) { + return content::RenderFrameHost::FrameIterationAction::kSkipChildren; + } + csdh->InitializePhishingDetector(rfh); + return content::RenderFrameHost::FrameIterationAction::kContinue; + }, + base::Unretained(this), web_contents())); } ClientSideDetectionHost::~ClientSideDetectionHost() { @@ -478,7 +488,7 @@ void ClientSideDetectionHost::RenderFrameDeleted( content::RenderFrameHost* render_frame_host) { - phishing_detectors_.erase(render_frame_host); + ClearPhishingDetector(render_frame_host->GetGlobalId()); } void ClientSideDetectionHost::OnPhishingPreClassificationDone( @@ -486,7 +496,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); if (should_classify) { content::RenderFrameHost* rfh = web_contents()->GetMainFrame(); - auto it = phishing_detectors_.find(rfh); + auto it = phishing_detectors_.find(rfh->GetGlobalId()); bool remote_valid = (it != phishing_detectors_.end() && it->second.is_connected()); @@ -642,17 +652,24 @@ void ClientSideDetectionHost::InitializePhishingDetector( content::RenderFrameHost* render_frame_host) { if (render_frame_host->IsRenderFrameCreated()) { + const content::GlobalRenderFrameHostId rfh_id = + render_frame_host->GetGlobalId(); mojo::Remote<mojom::PhishingDetector> new_detector; render_frame_host->GetRemoteInterfaces()->GetInterface( new_detector.BindNewPipeAndPassReceiver()); new_detector.set_disconnect_handler( - base::BindOnce(&ClientSideDetectionHost::RenderFrameDeleted, - weak_factory_.GetWeakPtr(), render_frame_host)); - phishing_detectors_[render_frame_host] = std::move(new_detector); - SetPhishingModel(phishing_detectors_[render_frame_host]); + base::BindOnce(&ClientSideDetectionHost::ClearPhishingDetector, + weak_factory_.GetWeakPtr(), rfh_id)); + phishing_detectors_[rfh_id] = std::move(new_detector); + SetPhishingModel(phishing_detectors_[rfh_id]); } } +void ClientSideDetectionHost::ClearPhishingDetector( + content::GlobalRenderFrameHostId rfh_id) { + phishing_detectors_.erase(rfh_id); +} + bool ClientSideDetectionHost::CanGetAccessToken() { if (is_off_the_record_) return false;
diff --git a/components/safe_browsing/content/browser/client_side_detection_host.h b/components/safe_browsing/content/browser/client_side_detection_host.h index f3190bcf..fdf45fa8 100644 --- a/components/safe_browsing/content/browser/client_side_detection_host.h +++ b/components/safe_browsing/content/browser/client_side_detection_host.h
@@ -30,10 +30,6 @@ class TickClock; } -namespace content { -struct GlobalRenderFrameHostId; -} - namespace safe_browsing { class ClientPhishingRequest; class ClientSideDetectionService; @@ -190,6 +186,8 @@ // Setup a PhishingDetector Mojo connection for the given render frame. void InitializePhishingDetector(content::RenderFrameHost* render_frame_host); + void ClearPhishingDetector(content::GlobalRenderFrameHostId rfh_id); + // This pointer may be nullptr if client-side phishing detection is // disabled. raw_ptr<ClientSideDetectionService> csd_service_; @@ -208,7 +206,7 @@ // A map from the live RenderFrameHosts to their PhishingDetector. These // correspond to the `phishing_detector_receiver_` in the // PhishingClassifierDelegate. - base::flat_map<content::RenderFrameHost*, + base::flat_map<content::GlobalRenderFrameHostId, mojo::Remote<mojom::PhishingDetector>> phishing_detectors_;
diff --git a/components/segmentation_platform/components_unittests.filter b/components/segmentation_platform/components_unittests.filter index 1649eab5..14bfe5a 100644 --- a/components/segmentation_platform/components_unittests.filter +++ b/components/segmentation_platform/components_unittests.filter
@@ -28,7 +28,7 @@ SignalKeyTest.* SignalStorageConfigTest.* StatsTest.* -TrainingDataCollectorTest.* +TrainingDataCollectorImplTest.* UkmConfigTest.* UkmObserverTest.* UrlSignalHandlerTest.*
diff --git a/components/segmentation_platform/internal/BUILD.gn b/components/segmentation_platform/internal/BUILD.gn index b4ba1e3..a24fca41 100644 --- a/components/segmentation_platform/internal/BUILD.gn +++ b/components/segmentation_platform/internal/BUILD.gn
@@ -21,6 +21,8 @@ "data_collection/dummy_training_data_collector.h", "data_collection/training_data_collector.cc", "data_collection/training_data_collector.h", + "data_collection/training_data_collector_impl.cc", + "data_collection/training_data_collector_impl.h", "database/database_maintenance.h", "database/database_maintenance_impl.cc", "database/database_maintenance_impl.h", @@ -181,7 +183,7 @@ # IMPORTANT NOTE: When adding new tests, also remember to update the list of # tests in //components/segmentation_platform/components_unittests.filter sources = [ - "data_collection/training_data_collector_unittest.cc", + "data_collection/training_data_collector_impl_unittest.cc", "database/database_maintenance_impl_unittest.cc", "database/metadata_utils_unittest.cc", "database/mock_signal_database.cc",
diff --git a/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.cc b/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.cc index 4ce0ebd2..a4e7b8fb 100644 --- a/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.cc +++ b/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.cc
@@ -14,8 +14,4 @@ void DummyTrainingDataCollector::OnServiceInitialized() {} -void DummyTrainingDataCollector::OnHistogramSignalUpdated( - const std::string& histogram_name, - base::HistogramBase::Sample sample) {} - } // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.h b/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.h index 8fc2d364..5acdeff 100644 --- a/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.h +++ b/components/segmentation_platform/internal/data_collection/dummy_training_data_collector.h
@@ -7,8 +7,6 @@ #include "components/segmentation_platform/internal/data_collection/training_data_collector.h" -#include <string> - namespace segmentation_platform { // Dummy TrainingDataCollector implementation that does nothing, used when @@ -21,8 +19,6 @@ // TrainingDataCollector implementation. void OnModelMetadataUpdated() override; void OnServiceInitialized() override; - void OnHistogramSignalUpdated(const std::string& histogram_name, - base::HistogramBase::Sample sample) override; }; } // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector.cc b/components/segmentation_platform/internal/data_collection/training_data_collector.cc index f43ac8d4..46f207e 100644 --- a/components/segmentation_platform/internal/data_collection/training_data_collector.cc +++ b/components/segmentation_platform/internal/data_collection/training_data_collector.cc
@@ -4,248 +4,14 @@ #include "components/segmentation_platform/internal/data_collection/training_data_collector.h" -#include "base/containers/flat_map.h" -#include "base/containers/flat_set.h" +#include <utility> + #include "base/feature_list.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/metrics/histogram_base.h" -#include "base/metrics/metrics_hashes.h" -#include "base/notreached.h" -#include "base/time/clock.h" -#include "components/optimization_guide/proto/models.pb.h" #include "components/segmentation_platform/internal/data_collection/dummy_training_data_collector.h" -#include "components/segmentation_platform/internal/database/metadata_utils.h" -#include "components/segmentation_platform/internal/database/segment_info_database.h" -#include "components/segmentation_platform/internal/database/signal_storage_config.h" -#include "components/segmentation_platform/internal/execution/feature_list_query_processor.h" -#include "components/segmentation_platform/internal/proto/model_metadata.pb.h" -#include "components/segmentation_platform/internal/proto/model_prediction.pb.h" -#include "components/segmentation_platform/internal/segmentation_ukm_helper.h" -#include "components/segmentation_platform/internal/stats.h" +#include "components/segmentation_platform/internal/data_collection/training_data_collector_impl.h" #include "components/segmentation_platform/public/features.h" -using optimization_guide::proto::OptimizationTarget; - namespace segmentation_platform { -namespace { - -// Parse outputs into a map of metric hash of the uma output and its index in -// the output list. -std::map<uint64_t, int> ParseUmaOutputs( - const proto::SegmentationModelMetadata& metadata) { - std::map<uint64_t, int> hash_index_map; - if (!metadata.has_training_outputs()) - return hash_index_map; - - const auto& training_outputs = metadata.training_outputs(); - for (int i = 0; i < training_outputs.outputs_size(); ++i) { - const auto output = training_outputs.outputs(i); - if (!output.has_uma_output() || !output.uma_output().has_uma_feature()) - continue; - - hash_index_map[output.uma_output().uma_feature().name_hash()] = i; - } - return hash_index_map; -} - -} // namespace - -class TrainingDataCollectorImpl : public TrainingDataCollector { - public: - TrainingDataCollectorImpl(SegmentInfoDatabase* segment_info_database, - FeatureListQueryProcessor* processor, - HistogramSignalHandler* histogram_signal_handler, - SignalStorageConfig* signal_storage_config, - base::Clock* clock) - : segment_info_database_(segment_info_database), - feature_list_query_processor_(processor), - histogram_signal_handler_(histogram_signal_handler), - signal_storage_config_(signal_storage_config), - clock_(clock) {} - - ~TrainingDataCollectorImpl() override { - histogram_signal_handler_->RemoveObserver(this); - } - - private: - // TrainingDataCollector implementation. - void OnModelMetadataUpdated() override { NOTIMPLEMENTED(); } - - void OnServiceInitialized() override { - segment_info_database_->GetAllSegmentInfo( - base::BindOnce(&TrainingDataCollectorImpl::OnGetSegmentsInfoList, - weak_ptr_factory_.GetWeakPtr())); - } - - void OnGetSegmentsInfoList( - std::unique_ptr<SegmentInfoDatabase::SegmentInfoList> segments) { - histogram_signal_handler_->AddObserver(this); - - DCHECK(segments); - for (const auto& segment : *segments) { - const proto::SegmentInfo& segment_info = segment.second; - // Validate segment info. - auto validation_result = - metadata_utils::ValidateSegmentInfo(segment_info); - if (validation_result != - metadata_utils::ValidationResult::kValidationSuccess) { - VLOG(1) << "Segment info validation failed for optimization target: " - << segment.first << ", validation result:" - << static_cast<int>(validation_result); - RecordTrainingDataCollectionEvent( - segment.first, - stats::TrainingDataCollectionEvent::kMetadataValidationFailed); - continue; - } - - // Cache the histograms as outputs of training data, which needs to be - // immediately reported when the histogram is recorded. - auto hash_index_map = ParseUmaOutputs(segment_info.model_metadata()); - for (const auto& hash_index : hash_index_map) { - const auto& output = - segment_info.model_metadata().training_outputs().outputs( - hash_index.second); - // Ignore continuous collection UMA. - if (output.uma_output().has_duration()) - continue; - immediate_collection_histograms_[hash_index.first].emplace( - segment.first); - } - } - } - - // HistogramSignalHandler::Observer implementation. - void OnHistogramSignalUpdated(const std::string& histogram_name, - base::HistogramBase::Sample sample) override { - auto hash = base::HashMetricName(histogram_name); - auto it = immediate_collection_histograms_.find(hash); - // Report training data for all models that are interested in - // |histogram_name| as output. - if (it != immediate_collection_histograms_.end()) { - std::vector<OptimizationTarget> optimization_targets(it->second.begin(), - it->second.end()); - segment_info_database_->GetSegmentInfoForSegments( - optimization_targets, - base::BindOnce(&TrainingDataCollectorImpl::ReportForSegmentsInfoList, - weak_ptr_factory_.GetWeakPtr(), hash, sample)); - } - } - - void ReportForSegmentsInfoList( - uint64_t output_metric_hash, - base::HistogramBase::Sample output_metric_sample, - std::unique_ptr<SegmentInfoDatabase::SegmentInfoList> segments) { - DCHECK(segments); - for (const auto& segment : *segments) { - RecordTrainingDataCollectionEvent( - segment.first, - stats::TrainingDataCollectionEvent::kImmediateCollectionStart); - const proto::SegmentInfo& segment_info = segment.second; - // Figure out the output index. - auto hash_index_map = ParseUmaOutputs(segment_info.model_metadata()); - if (hash_index_map.find(output_metric_hash) == hash_index_map.end()) - continue; - - if (!CanReportImmediateTrainingData(segment.second)) - continue; - - // Generate training data input. - // TODO(xingliu): Validate immediate output is not included in the input - // features and update the comment in model_metadata.proto. - feature_list_query_processor_->ProcessFeatureList( - segment_info.model_metadata(), segment_info.segment_id(), - clock_->Now(), - base::BindOnce(&TrainingDataCollectorImpl::OnGetInputTensor, - weak_ptr_factory_.GetWeakPtr(), - static_cast<float>(output_metric_sample), - hash_index_map[output_metric_hash], - segment_info.segment_id(), - segment_info.model_version())); - } - } - - bool CanReportImmediateTrainingData(const proto::SegmentInfo& segment_info) { - if (!segment_info.has_model_version() || - !segment_info.has_model_update_time_s() || - segment_info.model_update_time_s() == 0) { - RecordTrainingDataCollectionEvent( - segment_info.segment_id(), - stats::TrainingDataCollectionEvent::kModelInfoMissing); - return false; - } - - base::TimeDelta min_signal_collection_length = - segment_info.model_metadata().min_signal_collection_length() * - metadata_utils::GetTimeUnit(segment_info.model_metadata()); - base::Time model_update_time = base::Time::FromDeltaSinceWindowsEpoch( - base::Seconds(segment_info.model_update_time_s())); - - // Data must be collected for enough time after a new model is downloaded. - // It's recommended to get the A/B testing experiment fully ramped up before - // deploying a new model. Or the data collected might be partially based on - // old behavior of Chrome. - if (model_update_time + min_signal_collection_length >= clock_->Now()) { - RecordTrainingDataCollectionEvent( - segment_info.segment_id(), - stats::TrainingDataCollectionEvent::kNotEnoughCollectionTime); - return false; - } - - // Each input must be collected for enough time. - if (!signal_storage_config_->MeetsSignalCollectionRequirement( - segment_info.model_metadata())) { - RecordTrainingDataCollectionEvent( - segment_info.segment_id(), - stats::TrainingDataCollectionEvent::kNotEnoughCollectionTime); - return false; - } - - return true; - } - - void OnGetInputTensor(float output_value, - int output_index, - OptimizationTarget segment_id, - int64_t model_version, - bool success, - const std::vector<float>& inputs) { - if (!success) { - RecordTrainingDataCollectionEvent( - segment_id, - stats::TrainingDataCollectionEvent::kGetInputTensorsFailed); - return; - } - - auto ukm_source_id = - SegmentationUkmHelper::GetInstance()->RecordTrainingData( - segment_id, model_version, inputs, {output_value}, {output_index}); - if (ukm_source_id == ukm::kInvalidSourceId) { - VLOG(1) << "Failed to collect training data for segment:" << segment_id; - RecordTrainingDataCollectionEvent( - segment_id, stats::TrainingDataCollectionEvent::kUkmReportingFailed); - } else { - RecordTrainingDataCollectionEvent( - segment_id, - stats::TrainingDataCollectionEvent::kImmediateCollectionSuccess); - } - } - - raw_ptr<SegmentInfoDatabase> segment_info_database_; - raw_ptr<FeatureListQueryProcessor> feature_list_query_processor_; - raw_ptr<HistogramSignalHandler> histogram_signal_handler_; - raw_ptr<SignalStorageConfig> signal_storage_config_; - raw_ptr<base::Clock> clock_; - - // Hash of histograms for immediate training data collection. When any - // histogram hash contained in the map is recorded, a UKM message is reported - // right away. - base::flat_map<uint64_t, - base::flat_set<optimization_guide::proto::OptimizationTarget>> - immediate_collection_histograms_; - - base::WeakPtrFactory<TrainingDataCollectorImpl> weak_ptr_factory_{this}; -}; // static std::unique_ptr<TrainingDataCollector> TrainingDataCollector::Create( @@ -264,4 +30,8 @@ return std::make_unique<DummyTrainingDataCollector>(); } +TrainingDataCollector::TrainingDataCollector() = default; + +TrainingDataCollector::~TrainingDataCollector() = default; + } // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector.h b/components/segmentation_platform/internal/data_collection/training_data_collector.h index d25717c..62c076d 100644 --- a/components/segmentation_platform/internal/data_collection/training_data_collector.h +++ b/components/segmentation_platform/internal/data_collection/training_data_collector.h
@@ -21,9 +21,9 @@ class SignalStorageConfig; // Collect training data and report as Ukm message. Live on main thread. -// TODO(xingliu): Make a new class that owns the training data collector and +// TODO(ssid): Make a new class that owns the training data collector and // model execution collector. -class TrainingDataCollector : public HistogramSignalHandler::Observer { +class TrainingDataCollector { public: static std::unique_ptr<TrainingDataCollector> Create( SegmentInfoDatabase* segment_info_database, @@ -40,14 +40,14 @@ // to Ukm for |UMAOutput| in |SegmentationModelMetadata|. virtual void OnServiceInitialized() = 0; - ~TrainingDataCollector() override = default; + virtual ~TrainingDataCollector(); // Disallow copy/assign. TrainingDataCollector(const TrainingDataCollector&) = delete; TrainingDataCollector& operator=(const TrainingDataCollector&) = delete; protected: - TrainingDataCollector() = default; + TrainingDataCollector(); }; } // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector_impl.cc b/components/segmentation_platform/internal/data_collection/training_data_collector_impl.cc new file mode 100644 index 0000000..afc38e6 --- /dev/null +++ b/components/segmentation_platform/internal/data_collection/training_data_collector_impl.cc
@@ -0,0 +1,221 @@ +// Copyright 2022 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/segmentation_platform/internal/data_collection/training_data_collector_impl.h" + +#include "base/logging.h" +#include "base/metrics/metrics_hashes.h" +#include "base/notreached.h" +#include "base/time/clock.h" +#include "components/segmentation_platform/internal/database/metadata_utils.h" +#include "components/segmentation_platform/internal/database/signal_storage_config.h" +#include "components/segmentation_platform/internal/execution/feature_list_query_processor.h" +#include "components/segmentation_platform/internal/proto/model_metadata.pb.h" +#include "components/segmentation_platform/internal/proto/model_prediction.pb.h" +#include "components/segmentation_platform/internal/segmentation_ukm_helper.h" +#include "components/segmentation_platform/internal/stats.h" + +using optimization_guide::proto::OptimizationTarget; + +namespace segmentation_platform { +namespace { + +// Parse outputs into a map of metric hash of the uma output and its index in +// the output list. +std::map<uint64_t, int> ParseUmaOutputs( + const proto::SegmentationModelMetadata& metadata) { + std::map<uint64_t, int> hash_index_map; + if (!metadata.has_training_outputs()) + return hash_index_map; + + const auto& training_outputs = metadata.training_outputs(); + for (int i = 0; i < training_outputs.outputs_size(); ++i) { + const auto& output = training_outputs.outputs(i); + if (!output.has_uma_output() || !output.uma_output().has_uma_feature()) + continue; + + hash_index_map[output.uma_output().uma_feature().name_hash()] = i; + } + return hash_index_map; +} + +} // namespace + +TrainingDataCollectorImpl::TrainingDataCollectorImpl( + SegmentInfoDatabase* segment_info_database, + FeatureListQueryProcessor* processor, + HistogramSignalHandler* histogram_signal_handler, + SignalStorageConfig* signal_storage_config, + base::Clock* clock) + : segment_info_database_(segment_info_database), + feature_list_query_processor_(processor), + histogram_signal_handler_(histogram_signal_handler), + signal_storage_config_(signal_storage_config), + clock_(clock) {} + +TrainingDataCollectorImpl::~TrainingDataCollectorImpl() { + histogram_signal_handler_->RemoveObserver(this); +} + +void TrainingDataCollectorImpl::OnModelMetadataUpdated() { + NOTIMPLEMENTED(); +} + +void TrainingDataCollectorImpl::OnServiceInitialized() { + segment_info_database_->GetAllSegmentInfo( + base::BindOnce(&TrainingDataCollectorImpl::OnGetSegmentsInfoList, + weak_ptr_factory_.GetWeakPtr())); +} + +void TrainingDataCollectorImpl::OnGetSegmentsInfoList( + std::unique_ptr<SegmentInfoDatabase::SegmentInfoList> segments) { + histogram_signal_handler_->AddObserver(this); + + DCHECK(segments); + for (const auto& segment : *segments) { + const proto::SegmentInfo& segment_info = segment.second; + // Validate segment info. + auto validation_result = metadata_utils::ValidateSegmentInfo(segment_info); + if (validation_result != + metadata_utils::ValidationResult::kValidationSuccess) { + VLOG(1) << "Segment info validation failed for optimization target: " + << segment.first + << ", validation result:" << static_cast<int>(validation_result); + RecordTrainingDataCollectionEvent( + segment.first, + stats::TrainingDataCollectionEvent::kMetadataValidationFailed); + continue; + } + + // Cache the histograms as outputs of training data, which needs to be + // immediately reported when the histogram is recorded. + auto hash_index_map = ParseUmaOutputs(segment_info.model_metadata()); + for (const auto& hash_index : hash_index_map) { + const auto& output = + segment_info.model_metadata().training_outputs().outputs( + hash_index.second); + // Ignore continuous collection UMA. + if (output.uma_output().has_duration()) + continue; + immediate_collection_histograms_[hash_index.first].emplace(segment.first); + } + } +} + +void TrainingDataCollectorImpl::OnHistogramSignalUpdated( + const std::string& histogram_name, + base::HistogramBase::Sample sample) { + auto hash = base::HashMetricName(histogram_name); + auto it = immediate_collection_histograms_.find(hash); + // Report training data for all models that are interested in + // |histogram_name| as output. + if (it != immediate_collection_histograms_.end()) { + std::vector<OptimizationTarget> optimization_targets(it->second.begin(), + it->second.end()); + segment_info_database_->GetSegmentInfoForSegments( + optimization_targets, + base::BindOnce(&TrainingDataCollectorImpl::ReportForSegmentsInfoList, + weak_ptr_factory_.GetWeakPtr(), hash, sample)); + } +} + +void TrainingDataCollectorImpl::ReportForSegmentsInfoList( + uint64_t output_metric_hash, + base::HistogramBase::Sample output_metric_sample, + std::unique_ptr<SegmentInfoDatabase::SegmentInfoList> segments) { + DCHECK(segments); + for (const auto& segment : *segments) { + RecordTrainingDataCollectionEvent( + segment.first, + stats::TrainingDataCollectionEvent::kImmediateCollectionStart); + const proto::SegmentInfo& segment_info = segment.second; + // Figure out the output index. + auto hash_index_map = ParseUmaOutputs(segment_info.model_metadata()); + if (hash_index_map.find(output_metric_hash) == hash_index_map.end()) + continue; + + if (!CanReportImmediateTrainingData(segment.second)) + continue; + + // Generate training data input. + // TODO(ssid): Validate immediate output is not included in the input + // features and update the comment in model_metadata.proto. + feature_list_query_processor_->ProcessFeatureList( + segment_info.model_metadata(), segment_info.segment_id(), clock_->Now(), + base::BindOnce(&TrainingDataCollectorImpl::OnGetInputTensor, + weak_ptr_factory_.GetWeakPtr(), + static_cast<float>(output_metric_sample), + hash_index_map[output_metric_hash], + segment_info.segment_id(), + segment_info.model_version())); + } +} + +bool TrainingDataCollectorImpl::CanReportImmediateTrainingData( + const proto::SegmentInfo& segment_info) { + if (!segment_info.has_model_version() || + !segment_info.has_model_update_time_s() || + segment_info.model_update_time_s() == 0) { + RecordTrainingDataCollectionEvent( + segment_info.segment_id(), + stats::TrainingDataCollectionEvent::kModelInfoMissing); + return false; + } + + base::TimeDelta min_signal_collection_length = + segment_info.model_metadata().min_signal_collection_length() * + metadata_utils::GetTimeUnit(segment_info.model_metadata()); + base::Time model_update_time = base::Time::FromDeltaSinceWindowsEpoch( + base::Seconds(segment_info.model_update_time_s())); + + // Data must be collected for enough time after a new model is downloaded. + // It's recommended to get the A/B testing experiment fully ramped up before + // deploying a new model. Or the data collected might be partially based on + // old behavior of Chrome. + if (model_update_time + min_signal_collection_length >= clock_->Now()) { + RecordTrainingDataCollectionEvent( + segment_info.segment_id(), + stats::TrainingDataCollectionEvent::kNotEnoughCollectionTime); + return false; + } + + // Each input must be collected for enough time. + if (!signal_storage_config_->MeetsSignalCollectionRequirement( + segment_info.model_metadata())) { + RecordTrainingDataCollectionEvent( + segment_info.segment_id(), + stats::TrainingDataCollectionEvent::kNotEnoughCollectionTime); + return false; + } + + return true; +} + +void TrainingDataCollectorImpl::OnGetInputTensor( + float output_value, + int output_index, + OptimizationTarget segment_id, + int64_t model_version, + bool success, + const std::vector<float>& inputs) { + if (!success) { + RecordTrainingDataCollectionEvent( + segment_id, stats::TrainingDataCollectionEvent::kGetInputTensorsFailed); + return; + } + + auto ukm_source_id = SegmentationUkmHelper::GetInstance()->RecordTrainingData( + segment_id, model_version, inputs, {output_value}, {output_index}); + if (ukm_source_id == ukm::kInvalidSourceId) { + VLOG(1) << "Failed to collect training data for segment:" << segment_id; + RecordTrainingDataCollectionEvent( + segment_id, stats::TrainingDataCollectionEvent::kUkmReportingFailed); + } else { + RecordTrainingDataCollectionEvent( + segment_id, + stats::TrainingDataCollectionEvent::kImmediateCollectionSuccess); + } +} + +} // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector_impl.h b/components/segmentation_platform/internal/data_collection/training_data_collector_impl.h new file mode 100644 index 0000000..14a667b7 --- /dev/null +++ b/components/segmentation_platform/internal/data_collection/training_data_collector_impl.h
@@ -0,0 +1,76 @@ +// Copyright 2022 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_SEGMENTATION_PLATFORM_INTERNAL_DATA_COLLECTION_TRAINING_DATA_COLLECTOR_IMPL_H_ +#define COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_DATA_COLLECTION_TRAINING_DATA_COLLECTOR_IMPL_H_ + +#include "components/segmentation_platform/internal/data_collection/training_data_collector.h" + +#include "base/containers/flat_map.h" +#include "base/containers/flat_set.h" +#include "base/memory/raw_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/metrics/histogram_base.h" +#include "components/optimization_guide/proto/models.pb.h" +#include "components/segmentation_platform/internal/database/segment_info_database.h" +#include "components/segmentation_platform/internal/signals/histogram_signal_handler.h" + +namespace segmentation_platform { + +// Implementation of TrainingDataCollector. +class TrainingDataCollectorImpl : public TrainingDataCollector, + public HistogramSignalHandler::Observer { + public: + TrainingDataCollectorImpl(SegmentInfoDatabase* segment_info_database, + FeatureListQueryProcessor* processor, + HistogramSignalHandler* histogram_signal_handler, + SignalStorageConfig* signal_storage_config, + base::Clock* clock); + ~TrainingDataCollectorImpl() override; + + // TrainingDataCollector implementation. + void OnModelMetadataUpdated() override; + void OnServiceInitialized() override; + + // HistogramSignalHandler::Observer implementation. + void OnHistogramSignalUpdated(const std::string& histogram_name, + base::HistogramBase::Sample sample) override; + + private: + void OnGetSegmentsInfoList( + std::unique_ptr<SegmentInfoDatabase::SegmentInfoList> segments); + + void ReportForSegmentsInfoList( + uint64_t output_metric_hash, + base::HistogramBase::Sample output_metric_sample, + std::unique_ptr<SegmentInfoDatabase::SegmentInfoList> segments); + + void OnGetInputTensor(float output_value, + int output_index, + OptimizationTarget segment_id, + int64_t model_version, + bool success, + const std::vector<float>& inputs); + + bool CanReportImmediateTrainingData(const proto::SegmentInfo& segment_info); + + raw_ptr<SegmentInfoDatabase> segment_info_database_; + raw_ptr<FeatureListQueryProcessor> feature_list_query_processor_; + raw_ptr<HistogramSignalHandler> histogram_signal_handler_; + raw_ptr<SignalStorageConfig> signal_storage_config_; + raw_ptr<base::Clock> clock_; + + // Hash of histograms for immediate training data collection. When any + // histogram hash contained in the map is recorded, a UKM message is reported + // right away. + base::flat_map<uint64_t, + base::flat_set<optimization_guide::proto::OptimizationTarget>> + immediate_collection_histograms_; + + base::WeakPtrFactory<TrainingDataCollectorImpl> weak_ptr_factory_{this}; +}; + +} // namespace segmentation_platform + +#endif // COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_DATA_COLLECTION_TRAINING_DATA_COLLECTOR_IMPL_H_
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector_unittest.cc b/components/segmentation_platform/internal/data_collection/training_data_collector_impl_unittest.cc similarity index 91% rename from components/segmentation_platform/internal/data_collection/training_data_collector_unittest.cc rename to components/segmentation_platform/internal/data_collection/training_data_collector_impl_unittest.cc index 50ffce9..1efe6cb 100644 --- a/components/segmentation_platform/internal/data_collection/training_data_collector_unittest.cc +++ b/components/segmentation_platform/internal/data_collection/training_data_collector_impl_unittest.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 "components/segmentation_platform/internal/data_collection/training_data_collector.h" +#include "components/segmentation_platform/internal/data_collection/training_data_collector_impl.h" #include <map> @@ -44,10 +44,10 @@ namespace segmentation_platform { namespace { -class TrainingDataCollectorTest : public ::testing::Test { +class TrainingDataCollectorImplTest : public ::testing::Test { public: - TrainingDataCollectorTest() = default; - ~TrainingDataCollectorTest() override = default; + TrainingDataCollectorImplTest() = default; + ~TrainingDataCollectorImplTest() override = default; void SetUp() override { test_recorder_.Purge(); @@ -66,13 +66,13 @@ .WillByDefault(Return(true)); test_segment_info_db_ = std::make_unique<test::TestSegmentInfoDatabase>(); - collector_ = TrainingDataCollector::Create( + collector_ = std::make_unique<TrainingDataCollectorImpl>( test_segment_info_db_.get(), &feature_list_processor_, &histogram_signal_handler_, &signal_storage_config_, &clock_); } protected: - TrainingDataCollector* collector() { return collector_.get(); } + TrainingDataCollectorImpl* collector() { return collector_.get(); } test::TestSegmentInfoDatabase* test_segment_db() { return test_segment_info_db_.get(); } @@ -159,11 +159,11 @@ NiceMock<MockHistogramSignalHandler> histogram_signal_handler_; NiceMock<MockSignalStorageConfig> signal_storage_config_; std::unique_ptr<test::TestSegmentInfoDatabase> test_segment_info_db_; - std::unique_ptr<TrainingDataCollector> collector_; + std::unique_ptr<TrainingDataCollectorImpl> collector_; }; // No segment info in database. Do nothing. -TEST_F(TrainingDataCollectorTest, NoSegment) { +TEST_F(TrainingDataCollectorImplTest, NoSegment) { Init(); collector()->OnHistogramSignalUpdated(kHistogramName0, kSample); task_environment()->RunUntilIdle(); @@ -171,7 +171,7 @@ } // Histogram not in the output list will not trigger a training data report.. -TEST_F(TrainingDataCollectorTest, IrrelevantHistogramNotReported) { +TEST_F(TrainingDataCollectorImplTest, IrrelevantHistogramNotReported) { CreateSegmentInfo(); Init(); collector()->OnHistogramSignalUpdated("irrelevant_histogram", kSample); @@ -186,7 +186,7 @@ // Immediate training data collection for a certain histogram will be reported // as a UKM. -TEST_F(TrainingDataCollectorTest, HistogramImmediatelyReported) { +TEST_F(TrainingDataCollectorImplTest, HistogramImmediatelyReported) { CreateSegmentInfo(); Init(); WaitForHistogramSignalUpdated(kHistogramName0, kSample); @@ -198,7 +198,8 @@ } // A histogram interested by multiple model will trigger multiple UKM reports. -TEST_F(TrainingDataCollectorTest, HistogramImmediatelyReported_MultipleModel) { +TEST_F(TrainingDataCollectorImplTest, + HistogramImmediatelyReported_MultipleModel) { CreateSegmentInfo(); // Segment 1 contains 1 immediate collection uma output for for // |kHistogramName0| @@ -210,7 +211,7 @@ } // No UKM report due to minimum data collection time not met. -TEST_F(TrainingDataCollectorTest, SignalCollectionRequirementNotMet) { +TEST_F(TrainingDataCollectorImplTest, SignalCollectionRequirementNotMet) { EXPECT_CALL(*signal_storage_config(), MeetsSignalCollectionRequirement(_)) .WillOnce(Return(false)); @@ -222,7 +223,7 @@ } // No UKM report due to model updated recently. -TEST_F(TrainingDataCollectorTest, ModelUpdatedRecently) { +TEST_F(TrainingDataCollectorImplTest, ModelUpdatedRecently) { auto* segment_info = CreateSegmentInfo(); base::TimeDelta min_signal_collection_length = segment_info->model_metadata().min_signal_collection_length() *
diff --git a/content/browser/attribution_reporting/attribution_manager_impl.cc b/content/browser/attribution_reporting/attribution_manager_impl.cc index 9a1c5a3..4cef56a 100644 --- a/content/browser/attribution_reporting/attribution_manager_impl.cc +++ b/content/browser/attribution_reporting/attribution_manager_impl.cc
@@ -505,15 +505,20 @@ } if (result.event_level_status() != - AttributionTrigger::EventLevelResult::kInternalError || - result.aggregatable_status() != - AttributionTrigger::AggregatableResult::kInternalError) { - // Sources are changed here because storing a report can cause sources to be - // deleted or become associated with a dedup key. + AttributionTrigger::EventLevelResult::kInternalError) { + // Sources are changed here because storing an event-level report can + // cause sources to reach event-level attribution limit or become + // associated with a dedup key. NotifySourcesChanged(); NotifyReportsChanged(AttributionReport::ReportType::kEventLevel); } + if (result.aggregatable_status() == + AttributionTrigger::AggregatableResult::kSuccess) { + NotifyReportsChanged( + AttributionReport::ReportType::kAggregatableAttribution); + } + for (auto& observer : observers_) observer.OnTriggerHandled(result); } @@ -760,7 +765,8 @@ // TODO(apaseltiner): Consider surfacing retry attempts in internals UI. if (info.status != SendResult::Status::kSent && info.status != SendResult::Status::kFailure && - info.status != SendResult::Status::kDropped) { + info.status != SendResult::Status::kDropped && + info.status != SendResult::Status::kFailedToAssemble) { return; }
diff --git a/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc b/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc index 462e716..691d8dc3 100644 --- a/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc +++ b/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc
@@ -1108,7 +1108,7 @@ &observer); observation.Observe(attribution_manager_.get()); - SourceBuilder builder; + SourceBuilder builder = TestAggregatableSourceProvider().GetBuilder(); builder.SetExpiry(kImpressionExpiry).SetSourceEventId(7); StorableSource source = builder.Build(); @@ -1125,17 +1125,32 @@ // Each stored report should notify sources changed one time. for (size_t i = 1; i <= 3; i++) { EXPECT_CALL(observer, OnSourcesChanged); - EXPECT_CALL(observer, OnReportsChanged); + EXPECT_CALL(observer, + OnReportsChanged(AttributionReport::ReportType::kEventLevel)); + EXPECT_CALL(observer, + OnReportsChanged( + AttributionReport::ReportType::kAggregatableAttribution)); } EXPECT_CALL(observer, OnSourceDeactivated).Times(0); EXPECT_CALL(checkpoint, Call(2)); - EXPECT_CALL(observer, OnReportsChanged).Times(3); + EXPECT_CALL(observer, + OnReportsChanged(AttributionReport::ReportType::kEventLevel)) + .Times(3); + EXPECT_CALL(observer, + OnReportsChanged( + AttributionReport::ReportType::kAggregatableAttribution)) + .Times(3); EXPECT_CALL(checkpoint, Call(3)); EXPECT_CALL(observer, OnSourcesChanged); - EXPECT_CALL(observer, OnReportsChanged); + EXPECT_CALL(observer, + OnReportsChanged(AttributionReport::ReportType::kEventLevel)); + EXPECT_CALL(observer, + OnReportsChanged( + AttributionReport::ReportType::kAggregatableAttribution)) + .Times(0); } attribution_manager_->HandleSource(source); @@ -1144,24 +1159,32 @@ // Store the maximum number of reports for the source. for (size_t i = 1; i <= 3; i++) { - attribution_manager_->HandleTrigger(DefaultTrigger()); - EXPECT_THAT(StoredReports(), SizeIs(i)); + attribution_manager_->HandleTrigger( + DefaultAggregatableTriggerBuilder().Build()); + // i event-level reports and i aggregatable reports. + EXPECT_THAT(StoredReports(), SizeIs(i * 2)); } checkpoint.Call(2); // Simulate the reports being sent and removed from storage. task_environment_.FastForwardBy(kFirstReportingWindow); - EXPECT_THAT(report_sender_->calls(), SizeIs(3)); - report_sender_->RunCallbacksAndReset({SendResult::Status::kSent, - SendResult::Status::kSent, - SendResult::Status::kSent}); + EXPECT_THAT(aggregation_service_->calls(), SizeIs(3)); + for (size_t i = 0; i < 3; i++) { + aggregation_service_->RunCallback(i, CreateExampleAggregatableReport(), + AggregationService::AssemblyStatus::kOk); + } + EXPECT_THAT(report_sender_->calls(), SizeIs(6)); + report_sender_->RunCallbacksAndReset( + {SendResult::Status::kSent, SendResult::Status::kSent, + SendResult::Status::kSent, SendResult::Status::kSent, + SendResult::Status::kSent, SendResult::Status::kSent}); EXPECT_THAT(StoredReports(), IsEmpty()); checkpoint.Call(3); - // The next report should cause the source to be deactivated; the report - // itself shouldn't be stored as we've already reached the maximum number of - // conversions per source. + // The next event-level report should cause the source to reach the + // event-level attribution limit; the report itself shouldn't be stored as + // we've already reached the maximum number of event-level reports per source. attribution_manager_->HandleTrigger(DefaultTrigger()); EXPECT_THAT(StoredReports(), IsEmpty()); } @@ -1760,16 +1783,27 @@ attribution_manager_->HandleSource(SourceBuilder().Build()); - attribution_manager_->AddAggregatableAttributionForTesting( - ReportBuilder( - AttributionInfoBuilder( - SourceBuilder().SetSourceId(StoredSource::Id(1)).BuildStored()) - .SetTime(base::Time::Now()) - .Build()) + const auto aggregatable_attribution = + ReportBuilder(AttributionInfoBuilder(SourceBuilder() + .SetSourceId(StoredSource::Id(1)) + .SetDefaultFilterData() + .BuildStored()) + .SetTime(base::Time::Now()) + .Build()) .SetReportTime(base::Time::Now() + base::Hours(1)) .SetAggregatableHistogramContributions( {AggregatableHistogramContribution(/*key=*/1, /*value=*/2)}) - .BuildAggregatableAttribution()); + .BuildAggregatableAttribution(); + attribution_manager_->AddAggregatableAttributionForTesting( + aggregatable_attribution); + + MockAttributionObserver observer; + base::ScopedObservation<AttributionManager, AttributionObserver> observation( + &observer); + observation.Observe(attribution_manager_.get()); + + EXPECT_CALL(observer, OnReportSent(aggregatable_attribution, + /*is_debug_report=*/false, _)); // Make sure the report is not sent earlier than its report time. task_environment_.FastForwardBy(base::Hours(1) - base::Microseconds(1));
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index 5662a8c..3401a2c 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc
@@ -1093,6 +1093,8 @@ base::BindRepeating( &EmptyBinderForFrame< media::mojom::SpeechRecognitionClientBrowserInterface>)); + map->Add<media::mojom::MediaFoundationRendererNotifier>(base::BindRepeating( + &EmptyBinderForFrame<media::mojom::MediaFoundationRendererNotifier>)); map->Add<media::mojom::MediaPlayerObserverClient>(base::BindRepeating( &EmptyBinderForFrame<media::mojom::MediaPlayerObserverClient>)); #endif
diff --git a/content/browser/font_access/font_access_manager_impl_browsertest.cc b/content/browser/font_access/font_access_manager_impl_browsertest.cc index 160b6037..99dd6ca 100644 --- a/content/browser/font_access/font_access_manager_impl_browsertest.cc +++ b/content/browser/font_access/font_access_manager_impl_browsertest.cc
@@ -124,12 +124,12 @@ " return fonts.length;" "})()"); - if (FontEnumerationDataSource::IsOsSupportedForTesting()) { + if (FontEnumerationDataSource::IsOsSupported()) { EXPECT_LT(0, result.ExtractInt()) << "Enumeration should return at least one font on supported OS."; } else { - // TODO(crbug.com/1296792): Figure out Android situation. - EXPECT_TRUE(!result.error.empty()); + EXPECT_EQ(0, result.ExtractInt()) + << "Enumeration should return no font on non-supported OS."; } } @@ -146,13 +146,8 @@ " return fonts.length;" "})()"); - if (FontEnumerationDataSource::IsOsSupportedForTesting()) { - EXPECT_EQ(0, result.ExtractInt()) - << "Enumeration should return no fonts with an invalid select query."; - } else { - // TODO(crbug.com/1296792): Figure out Android situation. - EXPECT_TRUE(!result.error.empty()); - } + EXPECT_EQ(0, result.ExtractInt()) + << "Enumeration should return no fonts with an invalid select query."; } #if BUILDFLAG(IS_WIN)
diff --git a/content/browser/font_access/font_access_manager_impl_unittest.cc b/content/browser/font_access/font_access_manager_impl_unittest.cc index ac768c5..f53eba1b 100644 --- a/content/browser/font_access/font_access_manager_impl_unittest.cc +++ b/content/browser/font_access/font_access_manager_impl_unittest.cc
@@ -221,12 +221,11 @@ { const auto [status, region] = manager_sync_->EnumerateLocalFonts(); - if (FontEnumerationDataSource::IsOsSupportedForTesting()) { + if (FontEnumerationDataSource::IsOsSupported()) { EXPECT_EQ(status, FontEnumerationStatus::kOk) << "Font Enumeration was successful."; } else { - // TODO(crbug.com/1296792): Figure out Android situation. - EXPECT_EQ(status, FontEnumerationStatus::kUnexpectedError); + EXPECT_EQ(status, FontEnumerationStatus::kUnimplemented); } } @@ -243,12 +242,11 @@ SimulateUserActivation(); auto [status, region] = manager_sync_->EnumerateLocalFonts(); - if (FontEnumerationDataSource::IsOsSupportedForTesting()) { + if (FontEnumerationDataSource::IsOsSupported()) { EXPECT_EQ(status, FontEnumerationStatus::kOk); ValidateFontEnumerationBasic(std::move(status), std::move(region)); } else { - // TODO(crbug.com/1296792): Figure out Android situation. - EXPECT_EQ(status, FontEnumerationStatus::kUnexpectedError); + EXPECT_EQ(status, FontEnumerationStatus::kUnimplemented); } } @@ -257,11 +255,10 @@ SimulateUserActivation(); const auto [status, region] = manager_sync_->EnumerateLocalFonts(); - if (FontEnumerationDataSource::IsOsSupportedForTesting()) { + if (FontEnumerationDataSource::IsOsSupported()) { EXPECT_EQ(status, FontEnumerationStatus::kOk); } else { - // TODO(crbug.com/1296792): Figure out Android situation. - EXPECT_EQ(status, FontEnumerationStatus::kUnexpectedError); + EXPECT_EQ(status, FontEnumerationStatus::kUnimplemented); } }
diff --git a/content/browser/font_access/font_enumeration_cache.cc b/content/browser/font_access/font_enumeration_cache.cc index 699ad3fc..27acd8b 100644 --- a/content/browser/font_access/font_enumeration_cache.cc +++ b/content/browser/font_access/font_enumeration_cache.cc
@@ -78,6 +78,11 @@ blink::FontEnumerationTable& table) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!FontEnumerationDataSource::IsOsSupported()) { + data_.status = blink::mojom::FontEnumerationStatus::kUnimplemented; + return; + } + // Postscript names, according to spec, are expected to be encoded in a subset // of ASCII. See: // https://docs.microsoft.com/en-us/typography/opentype/spec/name This is why
diff --git a/content/browser/font_access/font_enumeration_data_source.cc b/content/browser/font_access/font_enumeration_data_source.cc index 452fa51..91e4c63 100644 --- a/content/browser/font_access/font_enumeration_data_source.cc +++ b/content/browser/font_access/font_enumeration_data_source.cc
@@ -69,7 +69,7 @@ } // static -bool FontEnumerationDataSource::IsOsSupportedForTesting() { +bool FontEnumerationDataSource::IsOsSupported() { // The structure below parallels Create(), for ease of maintenance. #if BUILDFLAG(IS_WIN)
diff --git a/content/browser/font_access/font_enumeration_data_source.h b/content/browser/font_access/font_enumeration_data_source.h index b81cb66..6d09d2d 100644 --- a/content/browser/font_access/font_enumeration_data_source.h +++ b/content/browser/font_access/font_enumeration_data_source.h
@@ -48,7 +48,7 @@ // // Tests can expect that GetData() returns a non-empty list on supported // operating systems. - static bool IsOsSupportedForTesting(); + static bool IsOsSupported(); }; } // namespace content
diff --git a/content/browser/font_access/font_enumeration_data_source_unittest.cc b/content/browser/font_access/font_enumeration_data_source_unittest.cc index 5c881fd..00161c5 100644 --- a/content/browser/font_access/font_enumeration_data_source_unittest.cc +++ b/content/browser/font_access/font_enumeration_data_source_unittest.cc
@@ -27,7 +27,7 @@ TEST_F(FontEnumerationDataSourceTest, GetFonts_EnUsLocale) { blink::FontEnumerationTable font_table = data_source_->GetFonts("en-us"); - if (FontEnumerationDataSource::IsOsSupportedForTesting()) { + if (FontEnumerationDataSource::IsOsSupported()) { EXPECT_GT(font_table.fonts_size(), 0); } else { EXPECT_EQ(font_table.fonts_size(), 0); @@ -38,7 +38,7 @@ std::string locale = base::i18n::GetConfiguredLocale(); blink::FontEnumerationTable font_table = data_source_->GetFonts(locale); - if (FontEnumerationDataSource::IsOsSupportedForTesting()) { + if (FontEnumerationDataSource::IsOsSupported()) { EXPECT_GT(font_table.fonts_size(), 0); } else { EXPECT_EQ(font_table.fonts_size(), 0);
diff --git a/content/public/browser/web_ui.h b/content/public/browser/web_ui.h index d3fac8a..ca541aa 100644 --- a/content/public/browser/web_ui.h +++ b/content/public/browser/web_ui.h
@@ -180,6 +180,18 @@ return value.GetString(); } +template <> +inline const base::Value::Dict& WebUI::GetValue<const base::Value::Dict&>( + const base::Value& value) { + return value.GetDict(); +} + +template <> +inline const base::Value::List& WebUI::GetValue<const base::Value::List&>( + const base::Value& value) { + return value.GetList(); +} + } // namespace content #endif // CONTENT_PUBLIC_BROWSER_WEB_UI_H_
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc index 0aab039..c1f2e0ed 100644 --- a/content/renderer/media/media_factory.cc +++ b/content/renderer/media/media_factory.cc
@@ -124,6 +124,7 @@ #include "media/base/win/mf_feature_checks.h" #include "media/cdm/win/media_foundation_cdm.h" #include "media/mojo/clients/win/media_foundation_renderer_client_factory.h" +#include "media/mojo/mojom/speech_recognition_service.mojom.h" #endif // BUILDFLAG(IS_WIN) namespace { @@ -673,11 +674,16 @@ render_thread->GetDCOMPTextureFactory(), render_thread->GetMediaThreadTaskRunner()); + mojo::Remote<media::mojom::MediaFoundationRendererNotifier> + media_foundation_renderer_notifier; + interface_broker_->GetInterface( + media_foundation_renderer_notifier.BindNewPipeAndPassReceiver()); factory_selector->AddFactory( RendererType::kMediaFoundation, std::make_unique<media::MediaFoundationRendererClientFactory>( media_log, std::move(dcomp_texture_creation_cb), - CreateMojoRendererFactory())); + CreateMojoRendererFactory(), + std::move(media_foundation_renderer_notifier))); if (use_mf_for_clear) { // We want to use Media Foundation even for non-explicit Media Foundation
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt index c88ad33..a156cdc 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -713,6 +713,9 @@ crbug.com/1099959 [ swiftshader-gl no-passthrough ] WebglExtension_EXT_sRGB [ Failure ] crbug.com/1099959 [ swiftshader-gl no-passthrough ] WebglExtension_EXT_texture_compression_rgtc [ Failure ] +# All platforms, Vulkan backend +crbug.com/1309304 [ angle-swiftshader passthrough ] conformance/rendering/out-of-bounds-array-buffers.html [ Failure ] + ####################################################################### # Automated Entries After This Point - Do Not Manually Add Below Here # #######################################################################
diff --git a/docs/design/gpu_synchronization.md b/docs/design/gpu_synchronization.md index 76bada51..6d6b5b3 100644 --- a/docs/design/gpu_synchronization.md +++ b/docs/design/gpu_synchronization.md
@@ -167,7 +167,7 @@ glA->GenUnverifiedSyncTokenCHROMIUM(out_sync_token); // stream B -glB->WaitSyncTokenCHROMIUM(); +glB->WaitSyncTokenCHROMIUM(sync_token); Render2(glB); // will happen after Render1. ``` @@ -183,7 +183,7 @@ glX->GenSyncTokenCHROMIUM(out_sync_token); // IPC channel in process Y -glY->WaitSyncTokenCHROMIUM(); +glY->WaitSyncTokenCHROMIUM(sync_token); Render2(glY); // will happen after Render1. ``` @@ -380,5 +380,5 @@ It is legal to create the GpuFence on a separate command buffer context instead of on the command buffer channel that did the drawing operations, but in that -case gl->WaitSyncTokenCHROMIUM() or equivalent must be used to sequence the +case `gl->WaitSyncTokenCHROMIUM()` or equivalent must be used to sequence the operations between the distinct command buffer contexts as usual.
diff --git a/ios/chrome/browser/policy/reporting/report_scheduler_ios.h b/ios/chrome/browser/policy/reporting/report_scheduler_ios.h index a568c844..7934c71f 100644 --- a/ios/chrome/browser/policy/reporting/report_scheduler_ios.h +++ b/ios/chrome/browser/policy/reporting/report_scheduler_ios.h
@@ -31,6 +31,8 @@ void StartWatchingExtensionRequestIfNeeded() override; void StopWatchingExtensionRequest() override; void OnExtensionRequestUploaded() override; + policy::DMToken GetProfileDMToken() override; + std::string GetProfileClientId() override; }; } // namespace enterprise_reporting
diff --git a/ios/chrome/browser/policy/reporting/report_scheduler_ios.mm b/ios/chrome/browser/policy/reporting/report_scheduler_ios.mm index d4295c7..585c8c3 100644 --- a/ios/chrome/browser/policy/reporting/report_scheduler_ios.mm +++ b/ios/chrome/browser/policy/reporting/report_scheduler_ios.mm
@@ -4,8 +4,8 @@ #include "ios/chrome/browser/policy/reporting/report_scheduler_ios.h" +#include "components/policy/core/common/cloud/dm_token.h" #include "ios/chrome/browser/application_context.h" - #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif @@ -46,4 +46,13 @@ // Not used on iOS because there is no extension. } +policy::DMToken ReportSchedulerIOS::GetProfileDMToken() { + // Profile reporting is not supported. + return policy::DMToken(); +} +std::string ReportSchedulerIOS::GetProfileClientId() { + // Profile reporting is not supported. + return std::string(); +} + } // namespace enterprise_reporting
diff --git a/ios/chrome/browser/ui/bubble/BUILD.gn b/ios/chrome/browser/ui/bubble/BUILD.gn index 1559332..270c7e7 100644 --- a/ios/chrome/browser/ui/bubble/BUILD.gn +++ b/ios/chrome/browser/ui/bubble/BUILD.gn
@@ -18,6 +18,7 @@ "bubble_view_controller_presenter.mm", ] deps = [ + "resources:password_suggestion_icon", "//base", "//base:i18n", "//components/feature_engagement/public",
diff --git a/ios/chrome/browser/ui/bubble/bubble_view.mm b/ios/chrome/browser/ui/bubble/bubble_view.mm index 686e2b6..06fa6ef3 100644 --- a/ios/chrome/browser/ui/bubble/bubble_view.mm +++ b/ios/chrome/browser/ui/bubble/bubble_view.mm
@@ -85,8 +85,6 @@ const CGFloat kImageViewTrailingMargin = 12.0f; // Height and Width of imageView. const CGFloat kImageViewSize = 60.0f; -// Alpha of imageView background. -const CGFloat kImageViewAlpha = 0.3f; // Corner radius of imageView. const CGFloat kImageViewCornerRadius = 13.0f; @@ -230,8 +228,6 @@ // Returns a image view used for the BubbleViews's imageView. UIImageView* BubbleImageViewWithImage(UIImage* image) { UIImageView* imageView = [[UIImageView alloc] initWithImage:image]; - [imageView setBackgroundColor:UIColor.blackColor]; - [imageView setAlpha:kImageViewAlpha]; [imageView.layer setCornerRadius:kImageViewCornerRadius]; [imageView.layer setMasksToBounds:YES]; [imageView setContentMode:UIViewContentModeCenter]; @@ -507,11 +503,13 @@ NSArray<NSLayoutConstraint*>* constraints = @[ [imageView.widthAnchor constraintEqualToConstant:kImageViewSize], [imageView.heightAnchor constraintEqualToConstant:kImageViewSize], - [imageView.topAnchor constraintEqualToAnchor:background.topAnchor - constant:kBubbleVerticalPadding], + [imageView.topAnchor + constraintGreaterThanOrEqualToAnchor:background.topAnchor + constant:kBubbleVerticalPadding], [background.bottomAnchor constraintGreaterThanOrEqualToAnchor:imageView.bottomAnchor constant:kBubbleVerticalPadding], + [imageView.centerYAnchor constraintEqualToAnchor:background.centerYAnchor], [imageView.leadingAnchor constraintEqualToAnchor:background.leadingAnchor constant:kImageViewLeadingMargin], [self.label.leadingAnchor constraintEqualToAnchor:imageView.trailingAnchor
diff --git a/ios/chrome/browser/ui/bubble/resources/BUILD.gn b/ios/chrome/browser/ui/bubble/resources/BUILD.gn new file mode 100644 index 0000000..2317b01e --- /dev/null +++ b/ios/chrome/browser/ui/bubble/resources/BUILD.gn
@@ -0,0 +1,14 @@ +# Copyright 2022 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/config/ios/asset_catalog.gni") + +imageset("password_suggestion_icon") { + sources = [ + "password_suggestion_icon.imageset/Contents.json", + "password_suggestion_icon.imageset/password_suggestion_icon.png", + "password_suggestion_icon.imageset/password_suggestion_icon@2x.png", + "password_suggestion_icon.imageset/password_suggestion_icon@3x.png", + ] +}
diff --git a/ios/chrome/browser/ui/bubble/resources/password_suggestion_icon.imageset/Contents.json b/ios/chrome/browser/ui/bubble/resources/password_suggestion_icon.imageset/Contents.json new file mode 100644 index 0000000..110e3b7 --- /dev/null +++ b/ios/chrome/browser/ui/bubble/resources/password_suggestion_icon.imageset/Contents.json
@@ -0,0 +1,24 @@ +{ + "images": [ + { + "idiom": "universal", + "scale": "1x", + "filename": "password_suggestion_icon.png" + }, + { + "idiom": "universal", + "scale": "2x", + "filename": "password_suggestion_icon@2x.png" + }, + { + "idiom": "universal", + "scale": "3x", + "filename": "password_suggestion_icon@3x.png" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} +
diff --git a/ios/chrome/browser/ui/bubble/resources/password_suggestion_icon.imageset/password_suggestion_icon.png b/ios/chrome/browser/ui/bubble/resources/password_suggestion_icon.imageset/password_suggestion_icon.png new file mode 100644 index 0000000..ceed562 --- /dev/null +++ b/ios/chrome/browser/ui/bubble/resources/password_suggestion_icon.imageset/password_suggestion_icon.png Binary files differ
diff --git a/ios/chrome/browser/ui/bubble/resources/password_suggestion_icon.imageset/password_suggestion_icon@2x.png b/ios/chrome/browser/ui/bubble/resources/password_suggestion_icon.imageset/password_suggestion_icon@2x.png new file mode 100644 index 0000000..81946259 --- /dev/null +++ b/ios/chrome/browser/ui/bubble/resources/password_suggestion_icon.imageset/password_suggestion_icon@2x.png Binary files differ
diff --git a/ios/chrome/browser/ui/bubble/resources/password_suggestion_icon.imageset/password_suggestion_icon@3x.png b/ios/chrome/browser/ui/bubble/resources/password_suggestion_icon.imageset/password_suggestion_icon@3x.png new file mode 100644 index 0000000..7dc03f3 --- /dev/null +++ b/ios/chrome/browser/ui/bubble/resources/password_suggestion_icon.imageset/password_suggestion_icon@3x.png Binary files differ
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn index 7120b9ea..183aa16 100644 --- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -142,7 +142,6 @@ deps = [ ":constants", ":content_suggestions_constant", - ":content_suggestions_ui_util", ":feature_flags", ":public", "resources:content_suggestions_no_image", @@ -177,7 +176,10 @@ "//ios/web/common", "//ui/base", ] - public_deps = [ "//ios/third_party/material_components_ios" ] + public_deps = [ + ":content_suggestions_ui_util", + "//ios/third_party/material_components_ios", + ] configs += [ "//build/config/compiler:enable_arc" ] }
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h index d51f7ac..7f48e977 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h
@@ -51,6 +51,9 @@ BOOL toolbarPresent, CGFloat topInset, UITraitCollection* traitCollection); +// Returns the bottom padding for the header. This represents the spacing +// between the fake omnibox and the content suggestions tiles. +CGFloat headerBottomPadding(); // Configure the |searchHintLabel| for the fake omnibox. |hintLabelContainer| // is added to the |searchTapTarget| with autolayout and |searchHintLabel| is // added to |hintLabelContainer| with autoresizing. This is done due to the
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm index 5f80aa6..ee331c7e 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm
@@ -128,16 +128,13 @@ BOOL toolbarPresent, CGFloat topInset, UITraitCollection* traitCollection) { - CGFloat bottomPadding = ShouldShowReturnToMostRecentTabForStartSurface() - ? kNTPShrunkLogoSearchFieldBottomPadding - : kNTPSearchFieldBottomPadding; CGFloat headerHeight = doodleTopMargin(toolbarPresent, topInset, traitCollection) + doodleHeight(logoIsShowing, doodleIsShowing, traitCollection) + searchFieldTopMargin() + ToolbarExpandedHeight( [UIApplication sharedApplication].preferredContentSizeCategory) + - bottomPadding; + headerBottomPadding(); if (!IsRegularXRegularSizeClass(traitCollection)) { return headerHeight; } @@ -154,6 +151,12 @@ return headerHeight; } +CGFloat headerBottomPadding() { + return ShouldShowReturnToMostRecentTabForStartSurface() + ? kNTPShrunkLogoSearchFieldBottomPadding + : kNTPSearchFieldBottomPadding; +} + void configureSearchHintLabel(UILabel* searchHintLabel, UIView* searchTapTarget) { [searchHintLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm index 206e756..3abb23bd 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
@@ -542,11 +542,15 @@ [[ActivityParams alloc] initWithURL:URL title:title scenario:ActivityScenario::MostVisitedEntry]; - self.sharingCoordinator = - [[SharingCoordinator alloc] initWithBaseViewController:self.viewController - browser:self.browser - params:params - originView:view]; + UIViewController* contentSuggestionsVC = + IsContentSuggestionsUIViewControllerMigrationEnabled() + ? self.contentSuggestionsViewController + : self.collectionViewController; + self.sharingCoordinator = [[SharingCoordinator alloc] + initWithBaseViewController:contentSuggestionsVC + browser:self.browser + params:params + originView:view]; [self.sharingCoordinator start]; }
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm index 30ceb26c..820d7aa 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm
@@ -210,12 +210,8 @@ } - (CGFloat)pinnedOffsetY { - CGFloat headerHeight = content_suggestions::heightForLogoHeader( - self.logoIsShowing, self.logoVendor.isShowingDoodle, self.promoCanShow, - YES, [self topInset], self.traitCollection); - CGFloat offsetY = - headerHeight - ntp_header::kScrolledToTopOmniboxBottomMargin; + [self headerHeight] - ntp_header::kScrolledToTopOmniboxBottomMargin; if (IsSplitToolbarMode(self)) { offsetY -= ToolbarExpandedHeight( self.traitCollection.preferredContentSizeCategory) +
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm index e042975..9ec755e 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
@@ -8,6 +8,7 @@ #import "base/check.h" #import "ios/chrome/browser/ui/bubble/bubble_presenter.h" +#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizing.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.h" @@ -728,7 +729,8 @@ self.feedHeaderConstraints = @[ [self.feedHeaderViewController.view.topAnchor - constraintEqualToAnchor:self.headerController.view.bottomAnchor], + constraintEqualToAnchor:self.headerController.view.bottomAnchor + constant:-content_suggestions::headerBottomPadding()], [self.collectionView.topAnchor constraintEqualToAnchor:[self contentSuggestionsViewController] .view.bottomAnchor], @@ -962,7 +964,8 @@ // the Feed. - (CGFloat)offsetWhenScrolledIntoFeed { return -(self.headerController.view.frame.size.height - - [self stickyOmniboxHeight]); + [self stickyOmniboxHeight] - + content_suggestions::headerBottomPadding()); } // The y-position content offset for when the fake omnibox
diff --git a/ios/web/js_messaging/web_view_js_utils_unittest.mm b/ios/web/js_messaging/web_view_js_utils_unittest.mm index d8ab5c86..b198449 100644 --- a/ios/web/js_messaging/web_view_js_utils_unittest.mm +++ b/ios/web/js_messaging/web_view_js_utils_unittest.mm
@@ -8,7 +8,6 @@ #include "base/bind.h" #include "base/callback_helpers.h" -#include "base/ios/ios_util.h" #import "base/test/ios/wait_util.h" #include "base/values.h" #import "ios/web/test/fakes/crw_fake_script_message_handler.h" @@ -238,41 +237,35 @@ // Tests that javascript can be executed in the page content world when no // content world or web frame are specified. TEST_F(WebViewJsUtilsTest, ExecuteJavaScriptPageContentWorldByDefault) { - if (!base::ios::IsRunningOnIOS14OrLater()) { - return; - } - __block bool complete = false; __block id result = nil; __block NSError* error = nil; WKWebView* web_view = [[WKWebView alloc] init]; - if (@available(iOS 14, *)) { - __block bool set_value_complete = false; - __block NSError* set_value_error = nil; + __block bool set_value_complete = false; + __block NSError* set_value_error = nil; - // Set |value| in the page content world. - web::ExecuteJavaScript(web_view, WKContentWorld.pageWorld, - /*frame_info=*/nil, @"var value = 3;", - ^(id result, NSError* error) { - set_value_error = [error copy]; - set_value_complete = true; - }); + // Set |value| in the page content world. + web::ExecuteJavaScript(web_view, WKContentWorld.pageWorld, + /*frame_info=*/nil, @"var value = 3;", + ^(id result, NSError* error) { + set_value_error = [error copy]; + set_value_complete = true; + }); - ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ - return set_value_complete; - })); - ASSERT_FALSE(set_value_error); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return set_value_complete; + })); + ASSERT_FALSE(set_value_error); - // Retrieve the value without specifying the content world to verify that - // ExecuteJavaScript defaults to the page content world. - web::ExecuteJavaScript(web_view, /*content_world=*/nil, /*frame_info=*/nil, - @"value", ^(id block_result, NSError* block_error) { - result = [block_result copy]; - error = [block_error copy]; - complete = true; - }); - } + // Retrieve the value without specifying the content world to verify that + // ExecuteJavaScript defaults to the page content world. + web::ExecuteJavaScript(web_view, /*content_world=*/nil, /*frame_info=*/nil, + @"value", ^(id block_result, NSError* block_error) { + result = [block_result copy]; + error = [block_error copy]; + complete = true; + }); ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ return complete; @@ -286,41 +279,35 @@ // Tests that javascript can be executed when the page content world is // explicitly specified but no frame info is given, implying the main frame. TEST_F(WebViewJsUtilsTest, ExecuteJavaScriptInPageWorldWithoutFrameInfo) { - if (!base::ios::IsRunningOnIOS14OrLater()) { - return; - } - __block bool complete = false; __block id result = nil; __block NSError* error = nil; WKWebView* web_view = [[WKWebView alloc] init]; - if (@available(iOS 14, *)) { - __block bool set_value_complete = false; - __block NSError* set_value_error = nil; + __block bool set_value_complete = false; + __block NSError* set_value_error = nil; - // Set |value| in the page content world. - web::ExecuteJavaScript(web_view, WKContentWorld.pageWorld, - /*frame_info=*/nil, @"var value = 3;", - ^(id result, NSError* error) { - set_value_error = [error copy]; - set_value_complete = true; - }); + // Set |value| in the page content world. + web::ExecuteJavaScript(web_view, WKContentWorld.pageWorld, + /*frame_info=*/nil, @"var value = 3;", + ^(id result, NSError* error) { + set_value_error = [error copy]; + set_value_complete = true; + }); - ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ - return set_value_complete; - })); - ASSERT_FALSE(set_value_error); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return set_value_complete; + })); + ASSERT_FALSE(set_value_error); - // Ensure the value can be accessed when specifying the content world. - web::ExecuteJavaScript(web_view, WKContentWorld.pageWorld, - /*frame_info=*/nil, @"value", - ^(id block_result, NSError* block_error) { - result = [block_result copy]; - error = [block_error copy]; - complete = true; - }); - } + // Ensure the value can be accessed when specifying the content world. + web::ExecuteJavaScript(web_view, WKContentWorld.pageWorld, + /*frame_info=*/nil, @"value", + ^(id block_result, NSError* block_error) { + result = [block_result copy]; + error = [block_error copy]; + complete = true; + }); ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ return complete; @@ -334,10 +321,6 @@ // Tests that javascript can be executed in the page content world when the page // content world and web frame are both specified. TEST_F(WebViewJsUtilsTest, ExecuteJavaScriptPageContentWorld) { - if (!base::ios::IsRunningOnIOS14OrLater()) { - return; - } - CRWFakeScriptMessageHandler* script_message_handler = [[CRWFakeScriptMessageHandler alloc] init]; WKWebView* web_view = [[WKWebView alloc] init]; @@ -361,30 +344,28 @@ __block id result = nil; __block NSError* error = nil; - if (@available(iOS 14, *)) { - __block bool set_value_complete = false; - __block NSError* set_value_error = nil; + __block bool set_value_complete = false; + __block NSError* set_value_error = nil; - // Set |value| in the page content world. - web::ExecuteJavaScript(web_view, WKContentWorld.pageWorld, frame_info, - @"var value = 3;", ^(id result, NSError* error) { - set_value_error = [error copy]; - set_value_complete = true; - }); + // Set |value| in the page content world. + web::ExecuteJavaScript(web_view, WKContentWorld.pageWorld, frame_info, + @"var value = 3;", ^(id result, NSError* error) { + set_value_error = [error copy]; + set_value_complete = true; + }); - ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ - return set_value_complete; - })); - ASSERT_FALSE(set_value_error); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return set_value_complete; + })); + ASSERT_FALSE(set_value_error); - // Ensure the value can be accessed when specifying |frame_info|. - web::ExecuteJavaScript(web_view, WKContentWorld.pageWorld, frame_info, - @"value", ^(id block_result, NSError* block_error) { - result = [block_result copy]; - error = [block_error copy]; - complete = true; - }); - } + // Ensure the value can be accessed when specifying |frame_info|. + web::ExecuteJavaScript(web_view, WKContentWorld.pageWorld, frame_info, + @"value", ^(id block_result, NSError* block_error) { + result = [block_result copy]; + error = [block_error copy]; + complete = true; + }); ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ return complete; @@ -398,10 +379,6 @@ // Tests that javascript can be executed in an isolated content world and that // it can not be accessed from the page content world. TEST_F(WebViewJsUtilsTest, ExecuteJavaScriptIsolatedWorld) { - if (!base::ios::IsRunningOnIOS14OrLater()) { - return; - } - CRWFakeScriptMessageHandler* script_message_handler = [[CRWFakeScriptMessageHandler alloc] init]; WKWebView* web_view = [[WKWebView alloc] init]; @@ -421,63 +398,61 @@ WKFrameInfo* frame_info = script_message_handler.lastReceivedScriptMessage.frameInfo; - if (@available(iOS 14, *)) { - __block bool set_value_complete = false; - __block NSError* set_value_error = nil; - // Set |value| in the page content world. - web::ExecuteJavaScript(web_view, WKContentWorld.defaultClientWorld, - frame_info, @"var value = 3;", - ^(id result, NSError* error) { - set_value_error = [error copy]; - set_value_complete = true; - }); + __block bool set_value_complete = false; + __block NSError* set_value_error = nil; + // Set |value| in the page content world. + web::ExecuteJavaScript(web_view, WKContentWorld.defaultClientWorld, + frame_info, @"var value = 3;", + ^(id result, NSError* error) { + set_value_error = [error copy]; + set_value_complete = true; + }); - ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ - return set_value_complete; - })); - ASSERT_FALSE(set_value_error); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return set_value_complete; + })); + ASSERT_FALSE(set_value_error); - __block bool isolated_world_complete = false; - __block id isolated_world_result = nil; - __block NSError* isolated_world_error = nil; - // Ensure the value can be accessed when specifying an isolated world and - // |frame_info|. - web::ExecuteJavaScript(web_view, WKContentWorld.defaultClientWorld, - frame_info, @"value", - ^(id block_result, NSError* block_error) { - isolated_world_result = [block_result copy]; - isolated_world_error = [block_error copy]; - isolated_world_complete = true; - }); + __block bool isolated_world_complete = false; + __block id isolated_world_result = nil; + __block NSError* isolated_world_error = nil; + // Ensure the value can be accessed when specifying an isolated world and + // |frame_info|. + web::ExecuteJavaScript(web_view, WKContentWorld.defaultClientWorld, + frame_info, @"value", + ^(id block_result, NSError* block_error) { + isolated_world_result = [block_result copy]; + isolated_world_error = [block_error copy]; + isolated_world_complete = true; + }); - ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ - return isolated_world_complete; - })); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return isolated_world_complete; + })); - EXPECT_FALSE(isolated_world_error); - EXPECT_TRUE(isolated_world_result); - EXPECT_NSEQ(@(3), isolated_world_result); + EXPECT_FALSE(isolated_world_error); + EXPECT_TRUE(isolated_world_result); + EXPECT_NSEQ(@(3), isolated_world_result); - __block bool page_world_complete = false; - __block id page_world_result = nil; - __block NSError* page_world_error = nil; - // The value should not be accessible from the page content world. - web::ExecuteJavaScript(web_view, WKContentWorld.pageWorld, frame_info, - @"try { value } catch (error) { false }", - ^(id block_result, NSError* block_error) { - page_world_result = [block_result copy]; - page_world_error = [block_error copy]; - page_world_complete = true; - }); + __block bool page_world_complete = false; + __block id page_world_result = nil; + __block NSError* page_world_error = nil; + // The value should not be accessible from the page content world. + web::ExecuteJavaScript(web_view, WKContentWorld.pageWorld, frame_info, + @"try { value } catch (error) { false }", + ^(id block_result, NSError* block_error) { + page_world_result = [block_result copy]; + page_world_error = [block_error copy]; + page_world_complete = true; + }); - ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ - return page_world_complete; - })); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return page_world_complete; + })); - EXPECT_FALSE(page_world_error); - EXPECT_TRUE(page_world_result); - EXPECT_FALSE([page_world_result boolValue]); - } + EXPECT_FALSE(page_world_error); + EXPECT_TRUE(page_world_result); + EXPECT_FALSE([page_world_result boolValue]); } } // namespace web
diff --git a/media/audio/fuchsia/audio_input_stream_fuchsia.cc b/media/audio/fuchsia/audio_input_stream_fuchsia.cc index f72dce8..01b1c95 100644 --- a/media/audio/fuchsia/audio_input_stream_fuchsia.cc +++ b/media/audio/fuchsia/audio_input_stream_fuchsia.cc
@@ -71,6 +71,7 @@ // Allocate shared buffer. size_t capture_buffer_size = parameters_.GetBytesPerBuffer(kSampleFormatF32) * kBufferPacketCapacity; + capture_buffer_size = base::bits::AlignUp(capture_buffer_size, ZX_PAGE_SIZE); zx::vmo buffer_vmo; zx_status_t status = zx::vmo::create(capture_buffer_size, 0, &buffer_vmo);
diff --git a/media/mojo/clients/mojo_cdm_factory.cc b/media/mojo/clients/mojo_cdm_factory.cc index 16b8665..32bd6e5a 100644 --- a/media/mojo/clients/mojo_cdm_factory.cc +++ b/media/mojo/clients/mojo_cdm_factory.cc
@@ -17,6 +17,7 @@ #include "media/mojo/clients/mojo_cdm.h" #include "media/mojo/mojom/content_decryption_module.mojom.h" #include "media/mojo/mojom/interface_factory.mojom.h" +#include "mojo/public/cpp/bindings/callback_helpers.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" @@ -82,11 +83,15 @@ return; } + // Use `mojo::WrapCallbackWithDefaultInvokeIfNotRun()` in case the CDM process + // crashes. interface_factory_->CreateCdm( cdm_config, - base::BindOnce(&OnCdmCreated, session_message_cb, session_closed_cb, - session_keys_change_cb, session_expiration_update_cb, - std::move(cdm_created_cb))); + mojo::WrapCallbackWithDefaultInvokeIfNotRun( + base::BindOnce(&OnCdmCreated, session_message_cb, session_closed_cb, + session_keys_change_cb, session_expiration_update_cb, + std::move(cdm_created_cb)), + mojo::NullRemote(), nullptr, "disconnection error")); } } // namespace media
diff --git a/media/mojo/clients/win/media_foundation_renderer_client_factory.cc b/media/mojo/clients/win/media_foundation_renderer_client_factory.cc index 92ad767..1ee87a057 100644 --- a/media/mojo/clients/win/media_foundation_renderer_client_factory.cc +++ b/media/mojo/clients/win/media_foundation_renderer_client_factory.cc
@@ -11,8 +11,10 @@ #include "media/mojo/clients/mojo_renderer_factory.h" #include "media/mojo/clients/win/media_foundation_renderer_client.h" #include "media/mojo/mojom/renderer_extensions.mojom.h" +#include "media/mojo/mojom/speech_recognition_service.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" namespace media { @@ -20,10 +22,14 @@ MediaFoundationRendererClientFactory::MediaFoundationRendererClientFactory( MediaLog* media_log, GetDCOMPTextureWrapperCB get_dcomp_texture_cb, - std::unique_ptr<media::MojoRendererFactory> mojo_renderer_factory) + std::unique_ptr<media::MojoRendererFactory> mojo_renderer_factory, + mojo::Remote<media::mojom::MediaFoundationRendererNotifier> + media_foundation_renderer_notifier) : media_log_(media_log), get_dcomp_texture_cb_(std::move(get_dcomp_texture_cb)), - mojo_renderer_factory_(std::move(mojo_renderer_factory)) { + mojo_renderer_factory_(std::move(mojo_renderer_factory)), + media_foundation_renderer_notifier_( + std::move(media_foundation_renderer_notifier)) { DVLOG_FUNC(1); } @@ -78,6 +84,11 @@ std::move(client_extension_remote), media_task_runner, video_renderer_sink); + // Notify the browser that a Media Foundation Renderer has been created. Live + // Caption supports muted media so this is run regardless of whether the media + // is audible. + media_foundation_renderer_notifier_->MediaFoundationRendererCreated(); + // mojo_renderer's ownership is passed to MediaFoundationRendererClient. return std::make_unique<MediaFoundationRendererClient>( media_task_runner, media_log_->Clone(), std::move(mojo_renderer),
diff --git a/media/mojo/clients/win/media_foundation_renderer_client_factory.h b/media/mojo/clients/win/media_foundation_renderer_client_factory.h index 2e9b561..4c6d589 100644 --- a/media/mojo/clients/win/media_foundation_renderer_client_factory.h +++ b/media/mojo/clients/win/media_foundation_renderer_client_factory.h
@@ -11,6 +11,8 @@ #include "media/base/renderer_factory.h" #include "media/base/win/dcomp_texture_wrapper.h" #include "media/mojo/clients/mojo_renderer_factory.h" +#include "media/mojo/mojom/speech_recognition_service.mojom.h" +#include "mojo/public/cpp/bindings/remote.h" namespace media { @@ -26,7 +28,9 @@ MediaFoundationRendererClientFactory( MediaLog* media_log, GetDCOMPTextureWrapperCB get_dcomp_texture_cb, - std::unique_ptr<media::MojoRendererFactory> mojo_renderer_factory); + std::unique_ptr<media::MojoRendererFactory> mojo_renderer_factory, + mojo::Remote<media::mojom::MediaFoundationRendererNotifier> + media_foundation_renderer_notifier); ~MediaFoundationRendererClientFactory() override; std::unique_ptr<media::Renderer> CreateRenderer( @@ -47,6 +51,8 @@ GetDCOMPTextureWrapperCB get_dcomp_texture_cb_; std::unique_ptr<media::MojoRendererFactory> mojo_renderer_factory_; + mojo::Remote<media::mojom::MediaFoundationRendererNotifier> + media_foundation_renderer_notifier_; }; } // namespace media
diff --git a/media/mojo/mojom/speech_recognition_service.mojom b/media/mojo/mojom/speech_recognition_service.mojom index c7046d30..b359fab0 100644 --- a/media/mojo/mojom/speech_recognition_service.mojom +++ b/media/mojo/mojom/speech_recognition_service.mojom
@@ -223,3 +223,15 @@ // and Dictation via OnDeviceSpeechRecognizer in Chrome OS. string? language; }; + +// This interface is used to notify the browser that the renderer is using the +// Media Foundation Renderer which uses MediaFoundation to render audio +// directly. Live Caption will not work in this case because Chrome is unable +// to tap into the audio rendering pipeline. The remote lives in the renderer +// process and the receiver lives in the browser process. +interface MediaFoundationRendererNotifier { + // Notify the browser than a Media Foundation Renderer has been created. The + // browser will use this event to notify the user that some features + // incompatible with the Media Foundation Renderer may not work. + MediaFoundationRendererCreated(); +};
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc index 03acedeb..bdaaf118 100644 --- a/media/renderers/paint_canvas_video_renderer.cc +++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -312,10 +312,21 @@ }; } +libyuv::FilterMode ToLibyuvFilterMode( + PaintCanvasVideoRenderer::FilterMode filter) { + switch (filter) { + case PaintCanvasVideoRenderer::kFilterNone: + return libyuv::kFilterNone; + case PaintCanvasVideoRenderer::kFilterBilinear: + return libyuv::kFilterBilinear; + } +} + void ConvertVideoFrameToRGBPixelsTask(const VideoFrame* video_frame, void* rgb_pixels, size_t row_bytes, bool premultiply_alpha, + libyuv::FilterMode filter, size_t task_index, size_t n_tasks, base::RepeatingClosure* done) { @@ -413,6 +424,17 @@ pixels, row_bytes, matrix, width, rows); }; + auto convert_yuv_with_filter = [&](const libyuv::YuvConstants* matrix, + auto&& func) { + func(YUV_ORDER(plane_meta[VideoFrame::kYPlane].data, + plane_meta[VideoFrame::kYPlane].stride, + plane_meta[VideoFrame::kUPlane].data, + plane_meta[VideoFrame::kUPlane].stride, + plane_meta[VideoFrame::kVPlane].data, + plane_meta[VideoFrame::kVPlane].stride), + pixels, row_bytes, matrix, width, rows, filter); + }; + auto convert_yuva = [&](const libyuv::YuvConstants* matrix, auto&& func) { func(YUV_ORDER(plane_meta[VideoFrame::kYPlane].data, plane_meta[VideoFrame::kYPlane].stride, @@ -425,6 +447,19 @@ width, rows, premultiply_alpha); }; + auto convert_yuva_with_filter = [&](const libyuv::YuvConstants* matrix, + auto&& func) { + func(YUV_ORDER(plane_meta[VideoFrame::kYPlane].data, + plane_meta[VideoFrame::kYPlane].stride, + plane_meta[VideoFrame::kUPlane].data, + plane_meta[VideoFrame::kUPlane].stride, + plane_meta[VideoFrame::kVPlane].data, + plane_meta[VideoFrame::kVPlane].stride), + plane_meta[VideoFrame::kAPlane].data, + plane_meta[VideoFrame::kAPlane].stride, pixels, row_bytes, matrix, + width, rows, premultiply_alpha, filter); + }; + auto convert_yuv16 = [&](const libyuv::YuvConstants* matrix, auto&& func) { func(YUV_ORDER(reinterpret_cast<const uint16_t*>( plane_meta[VideoFrame::kYPlane].data), @@ -438,6 +473,20 @@ pixels, row_bytes, matrix, width, rows); }; + auto convert_yuv16_with_filter = [&](const libyuv::YuvConstants* matrix, + auto&& func) { + func(YUV_ORDER(reinterpret_cast<const uint16_t*>( + plane_meta[VideoFrame::kYPlane].data), + plane_meta[VideoFrame::kYPlane].stride / 2, + reinterpret_cast<const uint16_t*>( + plane_meta[VideoFrame::kUPlane].data), + plane_meta[VideoFrame::kUPlane].stride / 2, + reinterpret_cast<const uint16_t*>( + plane_meta[VideoFrame::kVPlane].data), + plane_meta[VideoFrame::kVPlane].stride / 2), + pixels, row_bytes, matrix, width, rows, filter); + }; + auto convert_yuva16 = [&](const libyuv::YuvConstants* matrix, auto&& func) { func( YUV_ORDER(reinterpret_cast<const uint16_t*>( @@ -454,13 +503,30 @@ width, rows, premultiply_alpha); }; + auto convert_yuva16_with_filter = [&](const libyuv::YuvConstants* matrix, + auto&& func) { + func( + YUV_ORDER(reinterpret_cast<const uint16_t*>( + plane_meta[VideoFrame::kYPlane].data), + plane_meta[VideoFrame::kYPlane].stride / 2, + reinterpret_cast<const uint16_t*>( + plane_meta[VideoFrame::kUPlane].data), + plane_meta[VideoFrame::kUPlane].stride / 2, + reinterpret_cast<const uint16_t*>( + plane_meta[VideoFrame::kVPlane].data), + plane_meta[VideoFrame::kVPlane].stride / 2), + reinterpret_cast<const uint16_t*>(plane_meta[VideoFrame::kAPlane].data), + plane_meta[VideoFrame::kAPlane].stride / 2, pixels, row_bytes, matrix, + width, rows, premultiply_alpha, filter); + }; + switch (format) { case PIXEL_FORMAT_YV12: case PIXEL_FORMAT_I420: - convert_yuv(matrix, libyuv::I420ToARGBMatrix); + convert_yuv_with_filter(matrix, libyuv::I420ToARGBMatrixFilter); break; case PIXEL_FORMAT_I422: - convert_yuv(matrix, libyuv::I422ToARGBMatrix); + convert_yuv_with_filter(matrix, libyuv::I422ToARGBMatrixFilter); break; case PIXEL_FORMAT_I444: // Special case for 4:4:4 RGB encoded videos. @@ -481,10 +547,10 @@ } break; case PIXEL_FORMAT_YUV420P10: - convert_yuv16(matrix, libyuv::I010ToARGBMatrix); + convert_yuv16_with_filter(matrix, libyuv::I010ToARGBMatrixFilter); break; case PIXEL_FORMAT_YUV422P10: - convert_yuv16(matrix, libyuv::I210ToARGBMatrix); + convert_yuv16_with_filter(matrix, libyuv::I210ToARGBMatrixFilter); break; case PIXEL_FORMAT_YUV444P10: convert_yuv16(matrix, libyuv::I410ToARGBMatrix); @@ -493,19 +559,21 @@ convert_yuv16(matrix, libyuv::I012ToARGBMatrix); break; case PIXEL_FORMAT_I420A: - convert_yuva(matrix, libyuv::I420AlphaToARGBMatrix); + convert_yuva_with_filter(matrix, libyuv::I420AlphaToARGBMatrixFilter); break; case PIXEL_FORMAT_I422A: - convert_yuva(matrix, libyuv::I422AlphaToARGBMatrix); + convert_yuva_with_filter(matrix, libyuv::I422AlphaToARGBMatrixFilter); break; case PIXEL_FORMAT_I444A: convert_yuva(matrix, libyuv::I444AlphaToARGBMatrix); break; case PIXEL_FORMAT_YUV420AP10: + // TODO(wtc): Use libyuv::I010AlphaToARGBMatrixFilter after + // https://crbug.com/libyuv/922 is fixed. convert_yuva16(matrix, libyuv::I010AlphaToARGBMatrix); break; case PIXEL_FORMAT_YUV422AP10: - convert_yuva16(matrix, libyuv::I210AlphaToARGBMatrix); + convert_yuva16_with_filter(matrix, libyuv::I210AlphaToARGBMatrixFilter); break; case PIXEL_FORMAT_YUV444AP10: convert_yuva16(matrix, libyuv::I410AlphaToARGBMatrix); @@ -1213,7 +1281,8 @@ const VideoFrame* video_frame, void* rgb_pixels, size_t row_bytes, - bool premultiply_alpha) { + bool premultiply_alpha, + FilterMode filter) { if (!video_frame->IsMappable()) { NOTREACHED() << "Cannot extract pixels from non-CPU frame formats."; return; @@ -1264,15 +1333,17 @@ n_tasks, base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&event))); + const libyuv::FilterMode libyuv_filter = ToLibyuvFilterMode(filter); for (size_t i = 1; i < n_tasks; ++i) { base::ThreadPool::PostTask( FROM_HERE, base::BindOnce(ConvertVideoFrameToRGBPixelsTask, base::Unretained(video_frame), rgb_pixels, row_bytes, - premultiply_alpha, i, n_tasks, &barrier)); + premultiply_alpha, libyuv_filter, i, n_tasks, &barrier)); } ConvertVideoFrameToRGBPixelsTask(video_frame, rgb_pixels, row_bytes, - premultiply_alpha, 0, n_tasks, &barrier); + premultiply_alpha, libyuv_filter, 0, n_tasks, + &barrier); { base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait; event.Wait();
diff --git a/media/renderers/paint_canvas_video_renderer.h b/media/renderers/paint_canvas_video_renderer.h index 2b743d1..58369a6 100644 --- a/media/renderers/paint_canvas_video_renderer.h +++ b/media/renderers/paint_canvas_video_renderer.h
@@ -44,6 +44,15 @@ // Handles rendering of VideoFrames to PaintCanvases. class MEDIA_EXPORT PaintCanvasVideoRenderer { public: + // Specifies the chroma upsampling filter used for pixel formats with chroma + // subsampling (YUV 4:2:0 and YUV 4:2:2). + // + // NOTE: Keep the numeric values in sync with libyuv::FilterMode. + enum FilterMode { + kFilterNone = 0, // Nearest neighbor. + kFilterBilinear = 2, // Bilinear interpolation. + }; + PaintCanvasVideoRenderer(); PaintCanvasVideoRenderer(const PaintCanvasVideoRenderer&) = delete; @@ -79,7 +88,9 @@ // should point into a buffer large enough to hold as many 32 bit RGBA pixels // as are in the visible_rect() area of the frame. |premultiply_alpha| // indicates whether the R, G, B samples in |rgb_pixels| should be multiplied - // by alpha. + // by alpha. |filter| specifies the chroma upsampling filter used for pixel + // formats with chroma subsampling. If chroma planes in the pixel format are + // not subsampled, |filter| is ignored. // // NOTE: If |video_frame| doesn't have an alpha plane, all the A samples in // |rgb_pixels| will be 255 (equivalent to an alpha of 1.0) and therefore the @@ -88,7 +99,8 @@ static void ConvertVideoFrameToRGBPixels(const media::VideoFrame* video_frame, void* rgb_pixels, size_t row_bytes, - bool premultiply_alpha = true); + bool premultiply_alpha = true, + FilterMode filter = kFilterNone); // Copy the contents of |video_frame| to |texture| of |destination_gl|. //
diff --git a/media/renderers/paint_canvas_video_renderer_unittest.cc b/media/renderers/paint_canvas_video_renderer_unittest.cc index 731ed86..98363ec 100644 --- a/media/renderers/paint_canvas_video_renderer_unittest.cc +++ b/media/renderers/paint_canvas_video_renderer_unittest.cc
@@ -30,10 +30,12 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/libyuv/include/libyuv/convert.h" #include "third_party/libyuv/include/libyuv/scale.h" +#include "third_party/skia/include/core/SkColorPriv.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" +#include "ui/gfx/color_space.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/test/gl_surface_test_support.h" @@ -729,6 +731,110 @@ } } +TEST_F(PaintCanvasVideoRendererTest, I420WithFilters) { + // Allocate the Y, U, V planes for a 4x4 8-bit YUV 4:2:0 image. Note that + // there are no padding bytes after each row. + constexpr int kImgWidth = 4; + constexpr int kImgHeight = 4; + constexpr int kUvWidth = (kImgWidth + 1) / 2; + constexpr int kUvHeight = (kImgHeight + 1) / 2; + std::unique_ptr<uint8_t[]> y_plane = + std::make_unique<uint8_t[]>(kImgWidth * kImgHeight); + std::unique_ptr<uint8_t[]> u_plane = + std::make_unique<uint8_t[]>(kUvWidth * kUvHeight); + std::unique_ptr<uint8_t[]> v_plane = + std::make_unique<uint8_t[]>(kUvWidth * kUvHeight); + // In the JPEG color space (K_R = 0.299, K_B = 0.114, full range), red + // (R = 255, G = 0, B = 0) is Y = 76, U = 85, V = 255. + // + // Set Y to 76 for all pixels. + memset(y_plane.get(), 76, kImgWidth * kImgHeight); + // Set U = 85 and V = 255 for the upperleft pixel. Then vary U and V with a + // linear, diagonal slope over the UV planes with a step size of 4 and -4, + // respectively. + // + // The full U plane is + // 85 89 93 97 + // 89 93 97 101 + // 93 97 101 105 + // 97 101 105 109 + // The subsampled U plane is + // 89 97 + // 97 105 + // + // The full V plane is + // 255 251 247 243 + // 251 247 243 239 + // 247 243 239 235 + // 243 239 235 231 + // The subsampled V plane is + // 251 243 + // 243 235 + for (int i = 0; i < kUvHeight; ++i) { + for (int j = 0; j < kUvWidth; ++j) { + u_plane[i * kUvWidth + j] = 89 + 8 * i + 8 * j; + v_plane[i * kUvWidth + j] = 251 - 8 * i - 8 * j; + } + } + + auto size = gfx::Size(kImgWidth, kImgHeight); + scoped_refptr<VideoFrame> frame = VideoFrame::WrapExternalYuvData( + PIXEL_FORMAT_I420, size, gfx::Rect(size), size, kImgWidth, kUvWidth, + kUvWidth, y_plane.get(), u_plane.get(), v_plane.get(), base::TimeDelta()); + frame->set_color_space(gfx::ColorSpace::CreateJpeg()); + + std::unique_ptr<uint32_t[]> rgba = + std::make_unique<uint32_t[]>(kImgWidth * kImgHeight); + + // First convert with kFilterNone (nearest neighbor). + PaintCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( + frame.get(), rgba.get(), frame->visible_rect().width() * 4, + /*premultiply_alpha=*/true); + + // The pixel at coordinates (1, 1) will have U = 89 and V = 251 if nearest + // neighbor is used. (The correct values are U = 93 and V = 247.) + int i = 1; + int j = 1; + uint32_t color = rgba[i * kImgWidth + j]; + EXPECT_EQ(SkGetPackedA32(color), 255u); + EXPECT_EQ(SkGetPackedR32(color), 249u); + EXPECT_EQ(SkGetPackedG32(color), 1u); + EXPECT_EQ(SkGetPackedB32(color), 7u); + // The pixel at coordinates (2, 2) will have U = 105 and V = 235 if nearest + // neighbor is used. (The correct values are U = 101 and V = 239.) + i = 2; + j = 2; + color = rgba[i * kImgWidth + j]; + EXPECT_EQ(SkGetPackedA32(color), 255u); + EXPECT_EQ(SkGetPackedR32(color), 226u); + EXPECT_EQ(SkGetPackedG32(color), 7u); + EXPECT_EQ(SkGetPackedB32(color), 35u); + + // Then convert with kFilterBilinear (bilinear interpolation). + PaintCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( + frame.get(), rgba.get(), frame->visible_rect().width() * 4, + /*premultiply_alpha=*/true, PaintCanvasVideoRenderer::kFilterBilinear); + + // The pixel at coordinates (1, 1) will have the correct values U = 93 and + // V = 247 if bilinear interpolation is used. + i = 1; + j = 1; + color = rgba[i * kImgWidth + j]; + EXPECT_EQ(SkGetPackedA32(color), 255u); + EXPECT_EQ(SkGetPackedR32(color), 243u); + EXPECT_EQ(SkGetPackedG32(color), 2u); + EXPECT_EQ(SkGetPackedB32(color), 14u); + // The pixel at coordinates (2, 2) will have the correct values U = 101 and + // V = 239 if bilinear interpolation is used. + i = 2; + j = 2; + color = rgba[i * kImgWidth + j]; + EXPECT_EQ(SkGetPackedA32(color), 255u); + EXPECT_EQ(SkGetPackedR32(color), 232u); + EXPECT_EQ(SkGetPackedG32(color), 5u); + EXPECT_EQ(SkGetPackedB32(color), 28u); +} + namespace { class TestGLES2Interface : public gpu::gles2::GLES2InterfaceStub { public:
diff --git a/services/tracing/perfetto/privacy_filtered_fields-inl.h b/services/tracing/perfetto/privacy_filtered_fields-inl.h index 763a0f4..a510d2d 100644 --- a/services/tracing/perfetto/privacy_filtered_fields-inl.h +++ b/services/tracing/perfetto/privacy_filtered_fields-inl.h
@@ -285,16 +285,26 @@ constexpr int kChromeExtensionIdIndices[] = {2, -1}; constexpr MessageInfo kChromeExtensionId = {kChromeExtensionIdIndices, nullptr}; +// Proto Message: SiteInstanceGroup +constexpr int kSiteInstanceGroupIndices[] = {1, 2, 3, -1}; +constexpr MessageInfo const* kSiteInstanceGroupComplexMessages[] = { + nullptr, nullptr, &kRenderProcessHost}; +constexpr MessageInfo kSiteInstanceGroup = {kSiteInstanceGroupIndices, + kSiteInstanceGroupComplexMessages}; + // Proto Message: SiteInstance -constexpr int kSiteInstanceIndices[] = {1, 2, 3, 4, 5, 6, -1}; -constexpr MessageInfo kSiteInstance = {kSiteInstanceIndices, nullptr}; +constexpr int kSiteInstanceIndices[] = {1, 2, 3, 4, 5, 6, 7, -1}; +constexpr MessageInfo const* kSiteInstanceComplexMessages[] = { + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, &kSiteInstanceGroup}; +constexpr MessageInfo kSiteInstance = {kSiteInstanceIndices, + kSiteInstanceComplexMessages}; // Proto Message: RenderViewHost constexpr int kRenderViewHostIndices[] = {1, 2, 3, 4, 5, -1}; constexpr MessageInfo kRenderViewHost = {kRenderViewHostIndices, nullptr}; // Proto Message: RenderFrameProxyHost -constexpr int kRenderFrameProxyHostIndices[] = {1, 2, 3, 4, 5, -1}; +constexpr int kRenderFrameProxyHostIndices[] = {1, 2, 3, 4, 5, 6, -1}; constexpr MessageInfo kRenderFrameProxyHost = {kRenderFrameProxyHostIndices, nullptr}; @@ -333,7 +343,7 @@ 33, 34, 35, 36, 38, 39, 40, 41, 42, 43, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1023, 1024, - 1025, 1031, 1032, 1033, 1036, -1}; + 1025, 1031, 1032, 1033, 1034, 1036, -1}; constexpr MessageInfo const* kTrackEventComplexMessages[] = { nullptr, nullptr, @@ -394,6 +404,7 @@ &kRendererMainThreadTaskExecution, &kEventLatency, &kProcessSingleton, + &kSiteInstanceGroup, nullptr}; constexpr MessageInfo kTrackEvent = {kTrackEventIndices, kTrackEventComplexMessages};
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 8bf9d039..b138a6b 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -1600,15 +1600,6 @@ } ] }, - "linux-chromeos-annotator-rel": { - "scripts": [ - { - "name": "test_traffic_annotation_auditor", - "script": "test_traffic_annotation_auditor.py", - "swarming": {} - } - ] - }, "linux-chromeos-dbg": { "gtest_tests": [ { @@ -5804,7 +5795,7 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4960.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4962.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "isolate_profile_data": true, @@ -5812,14 +5803,14 @@ "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 102.0.4960.0", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 102.0.4962.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v102.0.4960.0", - "revision": "version:102.0.4960.0" + "location": "lacros_version_skew_tests_v102.0.4962.0", + "revision": "version:102.0.4962.0" } ], "dimension_sets": [ @@ -5946,7 +5937,7 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4960.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4962.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "isolate_profile_data": true, @@ -5954,14 +5945,14 @@ "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 102.0.4960.0", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 102.0.4962.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v102.0.4960.0", - "revision": "version:102.0.4960.0" + "location": "lacros_version_skew_tests_v102.0.4962.0", + "revision": "version:102.0.4962.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 3ddae05..86cec13 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -80426,6 +80426,15 @@ } ] }, + "linux-chromeos-annotator-rel": { + "scripts": [ + { + "name": "test_traffic_annotation_auditor", + "script": "test_traffic_annotation_auditor.py", + "swarming": {} + } + ] + }, "linux-chromeos-code-coverage": { "additional_compile_targets": [ "gn_all" @@ -85105,7 +85114,7 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4960.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4962.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "isolate_profile_data": true, @@ -85113,14 +85122,14 @@ "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 102.0.4960.0", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 102.0.4962.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v102.0.4960.0", - "revision": "version:102.0.4960.0" + "location": "lacros_version_skew_tests_v102.0.4962.0", + "revision": "version:102.0.4962.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -85222,7 +85231,7 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4960.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4962.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "isolate_profile_data": true, @@ -85230,14 +85239,14 @@ "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 102.0.4960.0", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 102.0.4962.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v102.0.4960.0", - "revision": "version:102.0.4960.0" + "location": "lacros_version_skew_tests_v102.0.4962.0", + "revision": "version:102.0.4962.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -86604,21 +86613,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4960.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4962.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 102.0.4960.0", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 102.0.4962.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v102.0.4960.0", - "revision": "version:102.0.4960.0" + "location": "lacros_version_skew_tests_v102.0.4962.0", + "revision": "version:102.0.4962.0" } ], "dimension_sets": [ @@ -86746,21 +86755,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4960.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4962.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 102.0.4960.0", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 102.0.4962.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v102.0.4960.0", - "revision": "version:102.0.4960.0" + "location": "lacros_version_skew_tests_v102.0.4962.0", + "revision": "version:102.0.4962.0" } ], "dimension_sets": [ @@ -88301,21 +88310,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4960.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4962.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 102.0.4960.0", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 102.0.4962.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v102.0.4960.0", - "revision": "version:102.0.4960.0" + "location": "lacros_version_skew_tests_v102.0.4962.0", + "revision": "version:102.0.4962.0" } ], "dimension_sets": [ @@ -88443,21 +88452,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4960.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4962.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 102.0.4960.0", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 102.0.4962.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v102.0.4960.0", - "revision": "version:102.0.4960.0" + "location": "lacros_version_skew_tests_v102.0.4962.0", + "revision": "version:102.0.4962.0" } ], "dimension_sets": [ @@ -89194,21 +89203,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4960.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4962.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 102.0.4960.0", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 102.0.4962.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v102.0.4960.0", - "revision": "version:102.0.4960.0" + "location": "lacros_version_skew_tests_v102.0.4962.0", + "revision": "version:102.0.4962.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -89290,21 +89299,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4960.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4962.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 102.0.4960.0", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 102.0.4962.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v102.0.4960.0", - "revision": "version:102.0.4960.0" + "location": "lacros_version_skew_tests_v102.0.4962.0", + "revision": "version:102.0.4962.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/testing/buildbot/filters/fuchsia.browser_tests.filter b/testing/buildbot/filters/fuchsia.browser_tests.filter index 467e8b94..69c8cfb 100644 --- a/testing/buildbot/filters/fuchsia.browser_tests.filter +++ b/testing/buildbot/filters/fuchsia.browser_tests.filter
@@ -32,8 +32,6 @@ -All/ManifestUpdateManagerBrowserTest_UpdateDialog.Shortcut* -All/MediaEngagementAutoplayBrowserTest.Preloaded* -All/MediaEngagementAutoplayBrowserTest.Use* --All/MediaHistoryBrowserTest.Do* --All/MediaHistoryBrowserTest.Record* -All/NetworkRequestMetricsBrowserTest.Cancel* -All/NetworkRequestMetricsBrowserTest.Download/1 -All/NetworkRequestMetricsBrowserTest.File* @@ -46,7 +44,6 @@ -All/PermissionPromptBubbleViewBrowserTest.Invoke* -All/PopupBrowserTest.Move* -All/RendererEventInjectionTest.TestRootTransform/0 --All/ReportingBrowserTest.Crash* -All/SearchPrefetchServiceEnabledBrowserTest.Back* -All/TabCapturePerformanceTest.Performance* -All/ViewSourceWithSplitCacheEnabledTest.NetworkIsolationKeyReusedForBackNavigation/0 @@ -58,7 +55,6 @@ -AppSettingsAppTest.All -AppWindowApiTest.On* -AskGoogleForSuggestionsDialogTest.InvokeUi_default --AudibleContentsTrackerTest.TestAudioNotifications -AuthenticatorDialogTest.Invoke* -AuthenticatorDialogViewTest.Invoke* -AutofillErrorDialogViewNativeViewsBrowserTest.Invoke* @@ -272,9 +268,7 @@ -LargeStickyAdViolationBrowserTest.NoLargeStickyAd_AdInterventionNotTriggered -LargeStickyAdViolationBrowserTestWithoutEnforcement.LargeStickyAd_NoAdInterventionTriggered -LoadImageBrowserTest.Load* --LoadingPredictorBrowserTestWithOptimizationGuide.NavigationWithBothLocalPredictionAndOptimizationHint/2 -LoadingPredictorBrowserTestWithProxy.Prepare* --LoadingPredictorPrefetchCounterfactualBrowserTest.PrepareForPageLoadWithPredictionForPrefetchHasLocalHint/0 -LocalCardMigrationBrowserTest.AcceptingDialogAddsLocalCardMigrationStrikes -LocalCardMigrationBrowserTest.CardIdentifierString -LocalCardMigrationBrowserTest.Clicking* @@ -297,16 +291,8 @@ -ManifestUpdateManagerHandleLinksBrowserTest.CheckFindsHandleLinksChange -ManifestUpdateManagerIconUpdatingBrowserTest.CheckFindsIconUrlChange -ManifestUpdateManagerLaunchHandlerBrowserTest.CheckFindsLaunchHandlerChange --MediaEngagementBrowserTest.ClearBrowsingHistoryBeforePlayback --MediaEngagementBrowserTest.Do* --MediaEngagementBrowserTest.IFrame* --MediaEngagementBrowserTest.MultipleElements --MediaEngagementBrowserTest.Record* --MediaEngagementBrowserTest.Session* -MediaEngagementPreloadBrowserTest.EnsureSingletonListIsLoaded --MediaEngagementSessionRestoreBrowserTest.RestoredSession_Playback_MEI -MediaGalleriesInteractiveDialogTest.InvokeUi_DisplayDialog --MediaHistoryForPrerenderBrowserTest.KeepRecordingMediaSession -MyIpAddressProxyScriptBrowserTest.Verify -NavigationPredictorBrowserTest.ClickAnchorElement -NavigationPredictorBrowserTest.MultipleNavigations @@ -402,6 +388,7 @@ -ProfileMainNetworkContext/NetworkContextConfigurationManagedProxySettingsBrowserTest.Max* -ProfileMainNetworkContext/NetworkContextConfigurationProxySettingsBrowserTest.Max* -ProfileMainNetworkContext/NetworkContextConfigurationReportingAndNelBrowserTest.Persist* +-ProfileMenuClickTest_WithUnconsentedPrimaryAccount.ProfileMenuClickTest_WithUnconsentedPrimaryAccount/1 -ProfileMenuViewExtensionsTest.CloseIPH -ProfileNetworkContextServiceBrowsertest.DefaultCacheSize -ProfileNetworkContextServiceDiskCacheBrowsertest.DiskCacheLocation @@ -434,12 +421,12 @@ -RestartTest.SessionCookies -RestoreOnStartupPolicyTestInstance/RestoreOnStartupPolicyTest.Run* -RssLinksFetcherTest.Fetch* --SSLUITest.TestBrokenHTTPSWithActiveInsecureContent -SafeBrowsingNetworkContext/NetworkContextConfigurationBrowserTest.CookiesEnabled/1 -SafeBrowsingNetworkContext/NetworkContextConfigurationDataPacBrowserTest.Data* -SafeBrowsingNetworkContext/NetworkContextConfigurationHttpPacBrowserTest.Http* -SafeBrowsingNetworkContext/NetworkContextConfigurationManagedProxySettingsBrowserTest.Max* --SafeBrowsingNetworkContext/NetworkContextConfigurationProxySettingsBrowserTest.Max* +-SafeBrowsingNetworkContext/NetworkContextConfigurationProxySettingsBrowserTest.MaxConnectionsPerProxy/0 +-SafeBrowsingNetworkContext/NetworkContextConfigurationProxySettingsBrowserTest.MaxConnectionsPerProxy/1 -SafetyTipPageInfoBubbleViewDialogTest.Invoke* -SaveCardBubbleControllerImplTest.Invoke* -SaveCardBubbleViewsFullFormBrowserTest.AlertAccessibleEvent @@ -569,7 +556,6 @@ -WebViewTest.NoPrerenderer -WebViewTest.Permissions* -WebViewTest.ReloadAfterCrash --WebViewTest.Shim_TestRemoveWebviewOnExit -WebViewTest.TouchpadPinchSyntheticWheelEvents -WebViewWithZoomForDSFTest.Shim* -WebauthnDialogBrowserTest.Invoke*
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 0d9a264..79f722b 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -28,16 +28,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4960.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.4962.0/test_ash_chrome', '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter', ], - 'identifier': 'Lacros version skew testing ash 102.0.4960.0', + 'identifier': 'Lacros version skew testing ash 102.0.4962.0', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v102.0.4960.0', - 'revision': 'version:102.0.4960.0', + 'location': 'lacros_version_skew_tests_v102.0.4962.0', + 'revision': 'version:102.0.4962.0', }, ], },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index fbdaf70..68ce8c47d 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -1639,11 +1639,6 @@ 'gtest_tests': 'linux_cfm_gtests', }, }, - 'linux-chromeos-annotator-rel': { - 'test_suites': { - 'scripts': 'test_traffic_annotation_auditor_script' - }, - }, 'linux-chromeos-dbg': { 'mixins': [ 'linux-bionic', @@ -3383,6 +3378,11 @@ 'isolated_scripts': 'chromium_webkit_isolated_scripts', }, }, + 'linux-chromeos-annotator-rel': { + 'test_suites': { + 'scripts': 'test_traffic_annotation_auditor_script' + }, + }, 'linux-chromeos-code-coverage': { 'mixins': [ 'isolate_profile_data',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index de3265b..9c153053 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -223,32 +223,36 @@ ], "experiments": [ { - "name": "Enabled_10000_2022-01-18", - "params": { - "save_card_message_use_followup_button_text": "false", - "save_card_message_use_gpay_icon": "true" - }, - "enable_features": [ - "MessagesForAndroidInfrastructure", - "MessagesForAndroidSaveCard" - ] - }, - { - "name": "Enabled_15000_2022-01-18", - "params": { - "autodismiss_duration_ms_SaveCard": "15000", - "save_card_message_use_followup_button_text": "false", - "save_card_message_use_gpay_icon": "true" - }, - "enable_features": [ - "MessagesForAndroidInfrastructure", - "MessagesForAndroidSaveCard" - ] - }, - { - "name": "Enabled_20000_2022-01-18", + "name": "Enabled_20000_2022-03-18", "params": { "autodismiss_duration_ms_SaveCard": "20000", + "save_card_dialog_explanation": "true", + "save_card_message_use_followup_button_text": "false", + "save_card_message_use_gpay_icon": "true" + }, + "enable_features": [ + "MessagesForAndroidInfrastructure", + "MessagesForAndroidSaveCard" + ] + }, + { + "name": "Enabled_30000_2022-03-18", + "params": { + "autodismiss_duration_ms_SaveCard": "30000", + "save_card_dialog_explanation": "true", + "save_card_message_use_followup_button_text": "false", + "save_card_message_use_gpay_icon": "true" + }, + "enable_features": [ + "MessagesForAndroidInfrastructure", + "MessagesForAndroidSaveCard" + ] + }, + { + "name": "Enabled_60000_2022-03-18", + "params": { + "autodismiss_duration_ms_SaveCard": "60000", + "save_card_dialog_explanation": "true", "save_card_message_use_followup_button_text": "false", "save_card_message_use_gpay_icon": "true" }, @@ -5097,7 +5101,6 @@ { "name": "PageContentAnnotationsWithVisibility_JourneysWithOmniboxAction_20211202", "params": { - "JourneysAlternateOmniboxActionText": "false", "annotate_title_instead_of_page_content": "true", "bag_of_words_entities": "false", "content_clustering_enabled": "false", @@ -5107,9 +5110,6 @@ "write_to_history_service": "true" }, "enable_features": [ - "HistoryClustersOnDeviceClustering", - "Journeys", - "JourneysOmniboxAction", "PageContentAnnotations", "PageEntitiesPageContentAnnotations" ] @@ -7912,6 +7912,24 @@ ] } ], + "WebRTC-Video-VariableStartScaleFactor": [ + { + "platforms": [ + "windows", + "mac", + "linux", + "ios", + "chromeos", + "android_webview", + "android" + ], + "experiments": [ + { + "name": "Enabled,_20220315" + } + ] + } + ], "WebRTC-Vp9ExternalRefCtrl": [ { "platforms": [
diff --git a/third_party/blink/public/mojom/font_access/font_access.mojom b/third_party/blink/public/mojom/font_access/font_access.mojom index 5185728b..5d6f598 100644 --- a/third_party/blink/public/mojom/font_access/font_access.mojom +++ b/third_party/blink/public/mojom/font_access/font_access.mojom
@@ -19,8 +19,6 @@ kNotVisible, // The site doesn't have permission for the requested operation. kPermissionDenied, - // The user canceled the operation. - kCanceled, }; // Bag of data representing a font, used to pass structured data from
diff --git a/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.cc b/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.cc index 4f059d9..06ccc36 100644 --- a/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.cc +++ b/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.cc
@@ -384,10 +384,19 @@ } if (found_new_tags) { - VectorOf<AtomicString> new_tags; - new_tags.push_back(RootTag()); - // TODO(vmpstr): We probably want to sort this on `element_index`. + VectorOf<std::pair<AtomicString, int>> new_tag_pairs; + new_tag_pairs.push_back(std::make_pair(RootTag(), root_index)); for (auto& [tag, data] : element_data_map_) + new_tag_pairs.push_back(std::make_pair(tag, data->element_index)); + + std::sort(new_tag_pairs.begin(), new_tag_pairs.end(), + [](const std::pair<AtomicString, int>& left, + const std::pair<AtomicString, int>& right) { + return left.second < right.second; + }); + + VectorOf<AtomicString> new_tags; + for (auto& [tag, index] : new_tag_pairs) new_tags.push_back(tag); document_->GetStyleEngine().SetDocumentTransitionTags(new_tags);
diff --git a/third_party/blink/renderer/core/html/html_link_element.cc b/third_party/blink/renderer/core/html/html_link_element.cc index 9810c69..7401af7 100644 --- a/third_party/blink/renderer/core/html/html_link_element.cc +++ b/third_party/blink/renderer/core/html/html_link_element.cc
@@ -76,8 +76,7 @@ HTMLLinkElement::HTMLLinkElement(Document& document, const CreateElementFlags flags) : HTMLElement(html_names::kLinkTag, document), - link_loader_( - MakeGarbageCollected<LinkLoader>(this, GetLoadingTaskRunner())), + link_loader_(MakeGarbageCollected<LinkLoader>(this)), sizes_(MakeGarbageCollected<DOMTokenList>(*this, html_names::kSizesAttr)), rel_list_(MakeGarbageCollected<RelList>(this)), blocking_attribute_(MakeGarbageCollected<BlockingAttribute>(this)),
diff --git a/third_party/blink/renderer/core/loader/link_loader.cc b/third_party/blink/renderer/core/loader/link_loader.cc index 881b99bd..4562308 100644 --- a/third_party/blink/renderer/core/loader/link_loader.cc +++ b/third_party/blink/renderer/core/loader/link_loader.cc
@@ -118,9 +118,7 @@ Member<Resource> resource_; }; -LinkLoader::LinkLoader(LinkLoaderClient* client, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : client_(client) { +LinkLoader::LinkLoader(LinkLoaderClient* client) : client_(client) { DCHECK(client_); }
diff --git a/third_party/blink/renderer/core/loader/link_loader.h b/third_party/blink/renderer/core/loader/link_loader.h index aa10afa..faa2b9a 100644 --- a/third_party/blink/renderer/core/loader/link_loader.h +++ b/third_party/blink/renderer/core/loader/link_loader.h
@@ -49,7 +49,7 @@ // prerender. class CORE_EXPORT LinkLoader final : public SingleModuleClient { public: - LinkLoader(LinkLoaderClient*, scoped_refptr<base::SingleThreadTaskRunner>); + explicit LinkLoader(LinkLoaderClient*); ~LinkLoader() override; void Abort();
diff --git a/third_party/blink/renderer/core/loader/link_loader_test.cc b/third_party/blink/renderer/core/loader/link_loader_test.cc index 3f5f008..bac02cc 100644 --- a/third_party/blink/renderer/core/loader/link_loader_test.cc +++ b/third_party/blink/renderer/core/loader/link_loader_test.cc
@@ -117,8 +117,7 @@ Persistent<MockLinkLoaderClient> loader_client = MakeGarbageCollected<MockLinkLoaderClient>( expected.link_loader_should_load_value); - auto* loader = MakeGarbageCollected<LinkLoader>( - loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner()); + auto* loader = MakeGarbageCollected<LinkLoader>(loader_client.Get()); // TODO(crbug.com/751425): We should use the mock functionality // via |dummy_page_holder_|. url_test_helpers::RegisterMockedErrorURLLoad(params.href); @@ -526,8 +525,7 @@ modulator); Persistent<MockLinkLoaderClient> loader_client = MakeGarbageCollected<MockLinkLoaderClient>(true); - auto* loader = MakeGarbageCollected<LinkLoader>( - loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner()); + auto* loader = MakeGarbageCollected<LinkLoader>(loader_client.Get()); KURL href_url = KURL(NullURL(), test_case.href); LinkLoadParameters params( LinkRelAttribute("modulepreload"), test_case.cross_origin, @@ -578,8 +576,7 @@ dummy_page_holder->GetFrame().GetSettings()->SetScriptEnabled(true); Persistent<MockLinkLoaderClient> loader_client = MakeGarbageCollected<MockLinkLoaderClient>(true); - auto* loader = MakeGarbageCollected<LinkLoader>( - loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner()); + auto* loader = MakeGarbageCollected<LinkLoader>(loader_client.Get()); KURL href_url = KURL(NullURL(), "http://example.test/cat.jpg"); // TODO(crbug.com/751425): We should use the mock functionality // via |dummy_page_holder|. @@ -647,8 +644,7 @@ Persistent<MockLinkLoaderClient> loader_client = MakeGarbageCollected<MockLinkLoaderClient>( test_case.link_loader_should_load_value); - auto* loader = MakeGarbageCollected<LinkLoader>( - loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner()); + auto* loader = MakeGarbageCollected<LinkLoader>(loader_client.Get()); KURL href_url = KURL(NullURL(), test_case.href); // TODO(crbug.com/751425): We should use the mock functionality // via |dummy_page_holder|. @@ -701,8 +697,7 @@ dummy_page_holder->GetFrame().PrescientNetworking()); Persistent<MockLinkLoaderClient> loader_client = MakeGarbageCollected<MockLinkLoaderClient>(test_case.should_load); - auto* loader = MakeGarbageCollected<LinkLoader>( - loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner()); + auto* loader = MakeGarbageCollected<LinkLoader>(loader_client.Get()); KURL href_url = KURL(KURL(String("http://example.com")), test_case.href); LinkLoadParameters params( LinkRelAttribute("dns-prefetch"), kCrossOriginAttributeNotSet, String(), @@ -741,8 +736,7 @@ dummy_page_holder->GetFrame().PrescientNetworking()); Persistent<MockLinkLoaderClient> loader_client = MakeGarbageCollected<MockLinkLoaderClient>(test_case.should_load); - auto* loader = MakeGarbageCollected<LinkLoader>( - loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner()); + auto* loader = MakeGarbageCollected<LinkLoader>(loader_client.Get()); KURL href_url = KURL(KURL(String("http://example.com")), test_case.href); LinkLoadParameters params( LinkRelAttribute("preconnect"), test_case.cross_origin, String(), @@ -770,8 +764,7 @@ dummy_page_holder->GetFrame().GetSettings()->SetScriptEnabled(true); Persistent<MockLinkLoaderClient> loader_client = MakeGarbageCollected<MockLinkLoaderClient>(true); - auto* loader = MakeGarbageCollected<LinkLoader>( - loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner()); + auto* loader = MakeGarbageCollected<LinkLoader>(loader_client.Get()); KURL href_url = KURL(KURL(), "https://www.example.com/"); // TODO(crbug.com/751425): We should use the mock functionality // via |dummy_page_holder|.
diff --git a/third_party/blink/renderer/modules/font_access/font_manager.cc b/third_party/blink/renderer/modules/font_access/font_manager.cc index d949fe5..6c29fa9 100644 --- a/third_party/blink/renderer/modules/font_access/font_manager.cc +++ b/third_party/blink/renderer/modules/font_access/font_manager.cc
@@ -76,6 +76,16 @@ if (RejectPromiseIfNecessary(status, resolver)) return; + // Return an empty font list if user has denied the permission request, + // or it is not implemented for this platform. + if (status == FontEnumerationStatus::kUnimplemented || + status == FontEnumerationStatus::kPermissionDenied) { + HeapVector<Member<FontMetadata>> entries; + resolver->Resolve(std::move(entries)); + return; + } + + // Font data exists; process and fill in the data. base::ReadOnlySharedMemoryMapping mapping = region.Map(); FontEnumerationTable table; @@ -120,18 +130,9 @@ ScriptPromiseResolver* resolver) { switch (status) { case FontEnumerationStatus::kOk: - break; case FontEnumerationStatus::kUnimplemented: - resolver->Reject(V8ThrowDOMException::CreateOrDie( - resolver->GetScriptState()->GetIsolate(), - DOMExceptionCode::kNotSupportedError, - "Not yet supported on this platform.")); - return true; - case FontEnumerationStatus::kCanceled: - resolver->Reject(V8ThrowDOMException::CreateOrDie( - resolver->GetScriptState()->GetIsolate(), - DOMExceptionCode::kAbortError, "The user canceled the operation.")); - return true; + case FontEnumerationStatus::kPermissionDenied: + break; case FontEnumerationStatus::kNeedsUserActivation: resolver->Reject(V8ThrowDOMException::CreateOrDie( resolver->GetScriptState()->GetIsolate(), @@ -142,11 +143,6 @@ resolver->GetScriptState()->GetIsolate(), DOMExceptionCode::kSecurityError, "Page needs to be visible.")); return true; - case FontEnumerationStatus::kPermissionDenied: - resolver->Reject(V8ThrowDOMException::CreateOrDie( - resolver->GetScriptState()->GetIsolate(), - DOMExceptionCode::kNotAllowedError, "Permission not granted.")); - return true; case FontEnumerationStatus::kUnexpectedError: default: resolver->Reject(V8ThrowDOMException::CreateOrDie(
diff --git a/third_party/blink/renderer/modules/idle/idle_detector.cc b/third_party/blink/renderer/modules/idle/idle_detector.cc index 923a117..e2e1cc4 100644 --- a/third_party/blink/renderer/modules/idle/idle_detector.cc +++ b/third_party/blink/renderer/modules/idle/idle_detector.cc
@@ -31,7 +31,6 @@ using mojom::blink::IdleManagerError; -const char kAbortMessage[] = "Idle detection aborted."; const char kFeaturePolicyBlocked[] = "Access to the feature \"idle-detection\" is disallowed by permissions " "policy."; @@ -134,9 +133,7 @@ } if (signal_ && signal_->aborted()) { - exception_state.ThrowDOMException(DOMExceptionCode::kAbortError, - kAbortMessage); - return ScriptPromise(); + return ScriptPromise::Reject(script_state, signal_->reason(script_state)); } mojo::PendingRemote<mojom::blink::IdleMonitor> remote; @@ -165,15 +162,13 @@ if (signal_ != signal) return; - ScriptState* resolver_script_state(nullptr); - - if (resolver_ && (resolver_script_state = resolver_->GetScriptState()) && - IsInParallelAlgorithmRunnable(resolver_->GetExecutionContext(), - resolver_script_state)) { - ScriptState::Scope script_state_scope(resolver_->GetScriptState()); - resolver_->Reject(V8ThrowDOMException::CreateOrDie( - resolver_->GetScriptState()->GetIsolate(), - DOMExceptionCode::kAbortError, kAbortMessage)); + if (resolver_) { + ScriptState* script_state = resolver_->GetScriptState(); + if (IsInParallelAlgorithmRunnable(resolver_->GetExecutionContext(), + script_state)) { + ScriptState::Scope script_state_scope(script_state); + resolver_->Reject(signal_->reason(script_state)); + } } resolver_ = nullptr;
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc index 0bd53de..a44f62f 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
@@ -222,7 +222,6 @@ &max_uniform_buffer_bindings); bound_indexed_uniform_buffers_.clear(); bound_indexed_uniform_buffers_.resize(max_uniform_buffer_bindings); - max_bound_uniform_buffer_index_ = 0; pack_row_length_ = 0; pack_skip_pixels_ = 0; @@ -5569,20 +5568,6 @@ } bound_indexed_uniform_buffers_[index] = buffer; bound_uniform_buffer_ = buffer; - - // Keep track of what the maximum bound uniform buffer index is - if (buffer) { - if (index > max_bound_uniform_buffer_index_) - max_bound_uniform_buffer_index_ = index; - } else if (max_bound_uniform_buffer_index_ > 0 && - index == max_bound_uniform_buffer_index_) { - wtf_size_t i = max_bound_uniform_buffer_index_ - 1; - for (; i > 0; --i) { - if (bound_indexed_uniform_buffers_[i].Get()) - break; - } - max_bound_uniform_buffer_index_ = i; - } break; default: NOTREACHED();
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h index 4a92db97..79339b5 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h
@@ -1187,7 +1187,6 @@ HeapVector<Member<WebGLBuffer>> bound_indexed_uniform_buffers_; GLint max_transform_feedback_separate_attribs_; - wtf_size_t max_bound_uniform_buffer_index_; Member<WebGLQuery> current_boolean_occlusion_query_; Member<WebGLQuery> current_transform_feedback_primitives_written_query_;
diff --git a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc index b9c90d73..5efa98e1 100644 --- a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc +++ b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc
@@ -192,7 +192,7 @@ ImageDecoder::kAlphaNotPremultiplied, ColorBehavior::Tag(), ImageOrientationEnum::kOriginTopLeft, - 1, + 0, { {gfx::Point(0, 0), SkColorSetARGB(255, 255, 0, 0)}, {gfx::Point(1, 1), SkColorSetARGB(255, 255, 0, 0)}, @@ -205,7 +205,7 @@ ImageDecoder::kAlphaNotPremultiplied, ColorBehavior::Tag(), ImageOrientationEnum::kOriginTopLeft, - 1, + 0, { {gfx::Point(0, 0), SkColorSetARGB(255, 192, 192, 192)}, {gfx::Point(1, 1), SkColorSetARGB(255, 192, 192, 192)}, @@ -416,7 +416,7 @@ ImageDecoder::kAlphaNotPremultiplied, ColorBehavior::Tag(), ImageOrientationEnum::kOriginTopLeft, - 1, + 0, { {gfx::Point(0, 0), SkColorSetARGB(255, 255, 0, 0)}, {gfx::Point(1, 1), SkColorSetARGB(255, 255, 0, 0)}, @@ -489,7 +489,7 @@ ImageDecoder::kAlphaNotPremultiplied, ColorBehavior::Tag(), ImageOrientationEnum::kOriginLeftBottom, - 1, + 0, { {gfx::Point(0, 0), SkColorSetARGB(255, 255, 0, 0)}, {gfx::Point(1, 1), SkColorSetARGB(255, 255, 0, 0)}, @@ -502,7 +502,7 @@ ImageDecoder::kAlphaNotPremultiplied, ColorBehavior::Tag(), ImageOrientationEnum::kOriginBottomLeft, - 1, + 0, { {gfx::Point(0, 0), SkColorSetARGB(255, 255, 0, 0)}, {gfx::Point(1, 1), SkColorSetARGB(255, 255, 0, 0)}, @@ -515,7 +515,7 @@ ImageDecoder::kAlphaNotPremultiplied, ColorBehavior::Tag(), ImageOrientationEnum::kOriginTopRight, - 1, + 0, { {gfx::Point(0, 0), SkColorSetARGB(255, 255, 0, 0)}, {gfx::Point(1, 1), SkColorSetARGB(255, 255, 0, 0)}, @@ -528,7 +528,7 @@ ImageDecoder::kAlphaNotPremultiplied, ColorBehavior::Tag(), ImageOrientationEnum::kOriginTopRight, - 1, + 0, { {gfx::Point(0, 0), SkColorSetARGB(255, 255, 0, 0)}, {gfx::Point(1, 1), SkColorSetARGB(255, 255, 0, 0)}, @@ -541,7 +541,7 @@ ImageDecoder::kAlphaNotPremultiplied, ColorBehavior::Tag(), ImageOrientationEnum::kOriginLeftTop, - 1, + 0, { {gfx::Point(0, 0), SkColorSetARGB(255, 255, 0, 0)}, {gfx::Point(1, 1), SkColorSetARGB(255, 255, 0, 0)},
diff --git a/third_party/blink/web_tests/FlagExpectations/highdpi b/third_party/blink/web_tests/FlagExpectations/highdpi index 26e9e16..b462ddb 100644 --- a/third_party/blink/web_tests/FlagExpectations/highdpi +++ b/third_party/blink/web_tests/FlagExpectations/highdpi
@@ -331,6 +331,71 @@ transforms/3d/general/perspective-units.html [ Pass ] transforms/3d/hit-testing/backface-hit-test.html [ Pass ] +virtual/backface-visibility-interop/transforms/2d/compound-transforms-vs-containers.html [ Pass ] +virtual/backface-visibility-interop/transforms/2d/zoom-menulist.html [ Pass ] +virtual/compositor-threaded-percent-based-scrolling/fast/events/wheel/continuous-platform-wheelevent-in-scrolling-div.html [ Pass ] +virtual/compositor_threaded_scrollbar_scrolling/paint/invalidation/scroll/sticky/invalidate-after-composited-scroll-with-sticky.html [ Pass ] +virtual/eye-dropper/fast/forms/color-scheme/color/color-picker-appearance.html [ Pass ] +virtual/eye-dropper/fast/forms/color-scheme/color/color-suggestion-picker-appearance-with-scrollbar.html [ Pass ] +virtual/forced-high-contrast-colors/fast/css/forced-colors-mode/backplate/forced-colors-mode-backplate-11.html [ Pass ] +virtual/forced-high-contrast-colors/html/details_summary/color-scheme-validation/details-with-summary-open.html [ Pass ] +virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/color-profile-image.html [ Pass ] +virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/jpeg-missing-eoi.html [ Pass ] +virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-color-profile-lossy.html [ Pass ] +virtual/jxl-enabled/images/jxl/jxl-images.html [ Pass ] +virtual/layout_ng_printing/printing/3d-rotate-under-perspective.html [ Pass ] +virtual/layout_ng_printing/printing/allowed-page-breaks.html [ Pass ] +virtual/layout_ng_printing/printing/avoid-setting-header-offset-on-header.html [ Pass ] +virtual/layout_ng_printing/printing/composited-thead-tfoot-repeat.html [ Pass ] +virtual/layout_ng_printing/printing/ellipsis-printing-style.html [ Pass ] +virtual/layout_ng_printing/printing/forced-break-tree-dump-only.html [ Pass ] +virtual/layout_ng_printing/printing/multi-page-background.html [ Pass ] +virtual/layout_ng_printing/printing/page-format-data.html [ Pass ] +virtual/main-threaded-percent-based-scrolling/fast/events/wheel/continuous-platform-wheelevent-in-scrolling-div.html [ Pass ] +virtual/off-main-thread-css-paint/http/tests/csspaint/border-color.html [ Pass ] +virtual/scroll-unification/fast/events/event-listener-on-link.html [ Pass ] +virtual/scroll-unification/fast/events/mouseclick-target-and-positioning.html [ Pass ] +virtual/scroll-unification/fast/events/reveal-link-when-focused.html [ Pass ] +virtual/scroll-unification/http/tests/misc/favicon-as-image.html [ Pass ] +virtual/scroll-unification/http/tests/misc/frame-access-during-load.html [ Pass ] +virtual/scroll-unification/http/tests/misc/slow-loading-image-in-pattern.html [ Pass ] +virtual/scroll-unification-layout_ng_block_frag/fast/forms/fieldset/fieldset-align.html [ Pass ] +virtual/scroll-unification-layout_ng_block_frag/fast/forms/fieldset/fieldset-with-float.html [ Pass ] +virtual/stable/compositing/filters/sw-layer-overlaps-hw-shadow.html [ Pass ] +virtual/stable/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow.html [ Pass ] +virtual/stable/inspector-protocol/dom-snapshot/captureSnapshot-ua-shadow-tree3.js [ Pass ] +virtual/stable/inspector-protocol/dom-snapshot/dom-snapshot-captureSnapshot-details.js [ Pass ] +virtual/text-antialias/align-center-rtl-spill.html [ Pass ] +virtual/text-antialias/apply-start-width-after-skipped-text.html [ Pass ] +virtual/text-antialias/bidi-embedding-pop-and-push-same.html [ Pass ] +virtual/text-antialias/complex-text-opacity.html [ Pass ] +virtual/text-antialias/ellipsis-ltr-text-in-ltr-flow-underline.html [ Pass ] +virtual/text-antialias/ellipsis-mixed-text-in-ltr-flow-underline.html [ Pass ] +virtual/text-antialias/ellipsis-mixed-text-in-rtl-flow-underline.html [ Pass ] +virtual/text-antialias/basic/001.html [ Pass ] +virtual/text-antialias/basic/002.html [ Pass ] +virtual/text-antialias/firstline/001.html [ Pass ] +virtual/text-antialias/firstline/002.html [ Pass ] +virtual/text-antialias/font-features/caps-casemapping.html [ Pass ] +virtual/text-antialias/international/bidi-layout-across-linebreak.html [ Pass ] +virtual/text-antialias/international/bidi-linebreak-001.html [ Pass ] +virtual/text-antialias/international/unicode-bidi-plaintext-in-textarea.html [ Pass ] +virtual/text-antialias/selection/atsui-partial-selection.html [ Pass ] +virtual/text-antialias/selection/flexbox-selection-nested.html [ Pass ] +virtual/text-antialias/selection/selection-multiple-runs.html [ Pass ] +virtual/text-antialias/selection/selection-painted-separately.html [ Pass ] +virtual/text-antialias/selection/selection-painting-hidpi.html [ Pass ] +virtual/text-antialias/shaping/same-script-different-lang.html [ Pass ] +virtual/text-antialias/sub-pixel/text-scaling-rtl.html [ Pass ] +virtual/text-antialias/sub-pixel/text-scaling-vertical.html [ Pass ] +virtual/text-antialias/whitespace/002.html [ Pass ] +virtual/text-antialias/whitespace/004.html [ Pass ] +virtual/text-antialias/whitespace/005.html [ Pass ] +virtual/text-antialias/whitespace/024.html [ Pass ] +virtual/text-antialias/whitespace/025.html [ Pass ] +virtual/text-antialias/whitespace/nowrap-clear-float.html [ Pass ] +virtual/text-antialias/whitespace/pre-newline-box-test.html [ Pass ] + # Layout tests significatly differ from non scale baseline crbug.com/1105168 fast/sub-pixel/sub-pixel-accumulates-to-layers.html [ Failure ] crbug.com/1107570 fast/text-autosizing/* [ Failure ] @@ -796,3 +861,5 @@ crbug.com/1266821 virtual/backface-visibility-interop/transforms/3d/point-mapping/3d-point-mapping.html [ Failure ] crbug.com/1196414 compositing/gestures/gesture-tapHighlight-imagemap.html [ Failure ] + +crbug.com/1310040 virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/color-profile-layer.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index aa6877c..313b46c5 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -842,6 +842,7 @@ "external/wpt/webstorage/localstorage-basic-partitioned.tentative.sub.html", "external/wpt/webmessaging/broadcastchannel/cross-partition.https.tentative.html", "external/wpt/IndexedDB/idb-partitioned-basic.tentative.sub.html", + "external/wpt/IndexedDB/idb-partitioned-persistence.tentative.sub.html", "external/wpt/webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.tentative.html" ], "args": [ "--enable-features=ThirdPartyStoragePartitioning" ]
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/idb-partitioned-basic.tentative.sub.html b/third_party/blink/web_tests/external/wpt/IndexedDB/idb-partitioned-basic.tentative.sub.html index 326d1f4..16bdacf 100644 --- a/third_party/blink/web_tests/external/wpt/IndexedDB/idb-partitioned-basic.tentative.sub.html +++ b/third_party/blink/web_tests/external/wpt/IndexedDB/idb-partitioned-basic.tentative.sub.html
@@ -4,7 +4,7 @@ <meta name=help href="https://privacycg.github.io/storage-partitioning/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<iframe id="shared-iframe" src="http://{{host}}:{{ports[http][0]}}/IndexedDB/resources/idb-partitioned-iframe.tentative.html"></iframe> +<iframe id="shared-iframe" src="http://{{host}}:{{ports[http][0]}}/IndexedDB/resources/idb-partitioned-basic-iframe.tentative.html"></iframe> <body> <script> // Here's the set-up for this test:
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/idb-partitioned-persistence.tentative.sub.html b/third_party/blink/web_tests/external/wpt/IndexedDB/idb-partitioned-persistence.tentative.sub.html new file mode 100644 index 0000000..54f76f5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/IndexedDB/idb-partitioned-persistence.tentative.sub.html
@@ -0,0 +1,60 @@ +<!doctype html> +<meta charset=utf-8> +<title>IndexedDB: partitioned storage test</title> +<meta name=help href="https://privacycg.github.io/storage-partitioning/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<iframe id="iframe1" src="http://{{hosts[alt][]}}:{{ports[http][0]}}/IndexedDB/resources/idb-partitioned-persistence-iframe.tentative.html"></iframe> +<iframe id="iframe2" src="http://{{hosts[alt][]}}:{{ports[http][0]}}/IndexedDB/resources/idb-partitioned-persistence-iframe.tentative.html"></iframe> +<body> +<script> +// Here's the set-up for this test: +// Step 1. (window) set up listeners for main window. +// Step 2. (iframe1 & iframe2) loads and sends "iframe loaded" message. +// Step 3. (window) receives two "iframe loaded" message and sends "create database" message to iframe1. +// Step 4. (iframe1) receives "create database", creates database, and sends "database created" message. +// Step 5. (window) receives "database created" message and sends "check database" message to iframe2. +// Step 6. (iframe2) receives "check database" message, checks if database exists, sends "database checked" message. +// Step 7. (window) receives the "database checked" message, asserts database existed, and then exits. + +async_test(t => { + const iframe1 = document.getElementById("iframe1"); + const iframe2 = document.getElementById("iframe2"); + let iframes_loaded = 0; + + // Step 1 + window.addEventListener("message", t.step_func(e => { + + // Step 3 + if (e.data.message === "iframe loaded") { + iframes_loaded++; + if (iframes_loaded === 2) { + iframe1.contentWindow.postMessage( + {message: "create database"}, + "*", + ); + } + } + + // Step 5 + if (e.data.message === "database created") { + iframe2.contentWindow.postMessage( + {message: "check database"}, + "*", + ); + } + + // Step 7 + if (e.data.message === "database checked") { + t.step(() => { + assert_true( + e.data.doesDatabaseExist, + "The same database should exist in both frames", + ); + }); + t.done(); + } + })); +}, "Persistence test for partitioned IndexedDB"); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/resources/idb-partitioned-iframe.tentative.html b/third_party/blink/web_tests/external/wpt/IndexedDB/resources/idb-partitioned-basic-iframe.tentative.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/IndexedDB/resources/idb-partitioned-iframe.tentative.html rename to third_party/blink/web_tests/external/wpt/IndexedDB/resources/idb-partitioned-basic-iframe.tentative.html
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/resources/idb-partitioned-persistence-iframe.tentative.html b/third_party/blink/web_tests/external/wpt/IndexedDB/resources/idb-partitioned-persistence-iframe.tentative.html new file mode 100644 index 0000000..ad6869f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/IndexedDB/resources/idb-partitioned-persistence-iframe.tentative.html
@@ -0,0 +1,76 @@ +<!doctype html> +<meta charset="utf-8"> +<script> +const dbName = "users"; + +// Create the database at v1 and detect success via `onsuccess`. +function createDatabase() { + return new Promise((resolve, reject) => { + var dbRequest = window.indexedDB.open(dbName, 1); + dbRequest.onblocked = () => reject(); + dbRequest.onerror = () => reject(); + dbRequest.onsuccess = (e) => { + e.target.result.close(); + resolve(); + } + }); +} + +// Open the database at v2 and detect existance via `onupgradeneeded`. +function doesDatabaseExist() { + let didExist = false; + return new Promise((resolve, reject) => { + var dbRequest = window.indexedDB.open(dbName, 2); + dbRequest.onblocked = () => reject(); + dbRequest.onerror = () => reject(); + dbRequest.onsuccess = (e) => { + e.target.result.close(); + deleteDatabase().then(() => resolve(didExist)); + }; + dbRequest.onupgradeneeded = (e) => { + didExist = e.oldVersion != 0; + }; + }); +} + +// Delete the database and detect success via `onsuccess`. +function deleteDatabase() { + return new Promise((resolve, reject) => { + var dbRequest = window.indexedDB.deleteDatabase(dbName); + dbRequest.onblocked = () => reject(); + dbRequest.onerror = () => reject(); + dbRequest.onsuccess = () => resolve(); + }); +} + +// Step 2 +window.addEventListener("load", () => { + parent.postMessage( + {message: "iframe loaded"}, + "*", + ); +}); + +window.addEventListener("message", (e) => { + if (e.data.message == "create database") { + // Step 4 + createDatabase().then(() => { + parent.postMessage( + {message: "database created"}, + "*", + ); + }); + } else if (e.data.message == "check database") { + // Step 6 + doesDatabaseExist().then((result) => { + parent.postMessage( + { + message: "database checked", + doesDatabaseExist: result, + }, + "*", + ); + }); + } +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/font-access/font_access_permission.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/font-access/font_access_permission.tentative.https.window.js index 6826f10..db395c2 100644 --- a/third_party/blink/web_tests/external/wpt/font-access/font_access_permission.tentative.https.window.js +++ b/third_party/blink/web_tests/external/wpt/font-access/font_access_permission.tentative.https.window.js
@@ -4,12 +4,16 @@ 'use strict'; promise_test(async t => { - await promise_rejects_dom(t, 'NotAllowedError', navigator.fonts.query()); + const fonts = await navigator.fonts.query(); + assert_equals( + fonts.length, 0, 'Fonts are not returned with permission not given.'); }, 'query(): permission not given'); promise_test(async t => { await test_driver.set_permission({name: 'font-access'}, 'denied'); - await promise_rejects_dom(t, 'NotAllowedError', navigator.fonts.query()); + const fonts = await navigator.fonts.query(); + assert_equals( + fonts.length, 0, 'Fonts are not returned with permission denied.'); }, 'query(): permission denied'); promise_test(async t => {
diff --git a/third_party/blink/web_tests/external/wpt/font-access/resources/font-test-utils.js b/third_party/blink/web_tests/external/wpt/font-access/resources/font-test-utils.js index 84dade8..1a5f385 100644 --- a/third_party/blink/web_tests/external/wpt/font-access/resources/font-test-utils.js +++ b/third_party/blink/web_tests/external/wpt/font-access/resources/font-test-utils.js
@@ -91,8 +91,9 @@ function font_access_test(test_function, name, properties) { return promise_test(async (t) => { if (!isPlatformSupported()) { - await promise_rejects_dom( - t, 'NotSupportedError', navigator.fonts.query()); + const fonts = navigator.fonts.query(); + assert_equals( + fonts.length, 0, 'Fonts are not returned on non-supported platform.'); return; } await test_driver.set_permission({name: 'font-access'}, 'granted');
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-cached-images.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-cached-images.https.html index f5eaddbd..269698bc 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-cached-images.https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-cached-images.https.html
@@ -4,6 +4,7 @@ <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="/common/get-host-info.sub.js"></script> +<script src="/common/utils.js"></script> <script> function remote(path) { @@ -12,7 +13,7 @@ } // -// This test loads a same-orign iframe resources/load_corp_images.html with +// This test loads a same-origin iframe resources/load-corp-images.html with // Cross-Origin-Embedder-Policy: require-corp // The iframe loads two cross origin images, one with a // Cross-Origin-Resource-Policy: cross-origin header, and one without. @@ -22,13 +23,14 @@ // for the image loads when they are loaded from the cache. // -const image_path = "/html/cross-origin-embedder-policy/resources/corp-image.py"; +const RUNS = ["NETWORK", "CACHED"]; +const RESOURCE_DESC = ["No CORP image", "CORP image"]; let EXPECTED_LOADS = { - [`NETWORK-${remote(image_path)}`]: false, - [`NETWORK-${remote(image_path)}?corp-cross-origin=1`]: true, - [`CACHED-${remote(image_path)}`]: false, - [`CACHED-${remote(image_path)}?corp-cross-origin=1`]: true, + [`${RUNS[0]} - ${RESOURCE_DESC[0]}`]: false, + [`${RUNS[0]} - ${RESOURCE_DESC[1]}`]: true, + [`${RUNS[1]} - ${RESOURCE_DESC[0]}`]: false, + [`${RUNS[1]} - ${RESOURCE_DESC[1]}`]: true, } let TESTS = {}; @@ -37,37 +39,36 @@ } window.addEventListener("load", async () => { - let iframe = document.createElement("iframe"); - let firstRun = true; - let t = async_test("main_test"); - await new Promise((resolve, reject) => { - iframe.src = "resources/load-corp-images.html"; - iframe.onload = () => { resolve() }; - iframe.onerror = (e) => { reject(); }; - window.addEventListener("message", (event) => { - // After the first done event we reload the iframe. - if (event.data.done) { - if (firstRun) { - firstRun = false; - iframe.contentWindow.location.reload(); - } else { - // After the second done event the test is finished. - t.done(); - } + const t = async_test("main_test"); + const iframe = document.createElement("iframe"); + // The token attribute is used to ensure the resource has never been seen by + // the HTTP cache. This can be useful if the cache isn't properly flushed in + // between two tests. + iframe.src = `resources/load-corp-images.html?revalidate=false&token=${token()}`; + let runCount = 0; + window.addEventListener("message", (event) => { + // After the first done event we reload the iframe. + if (event.data.done) { + ++runCount; + if (runCount < RUNS.length) { + iframe.contentWindow.location.reload(); } else { - // Check that each image either loads or doesn't based on the expectations - let testName = `${firstRun ? "NETWORK-" : "CACHED-"}${event.data.src}`; - let test = TESTS[testName]; - test.step(() => { - assert_equals(event.data.loaded, EXPECTED_LOADS[testName], `${firstRun ? "NETWORK" : "CACHED"} load of ${event.data.src} should ${EXPECTED_LOADS[testName] ? "" : "not"} succeed`); - }); - test.done(); + // After the second done event the test is finished. + t.done(); } - }, false); - document.body.appendChild(iframe); - }) -}); + return; + } + // Check that each image either loads or doesn't based on the expectations + let testName = `${RUNS[runCount]} - ${event.data.corp ? RESOURCE_DESC[1] : RESOURCE_DESC[0]}`; + let test = TESTS[testName]; + test.step(() => { + assert_equals(event.data.loaded, EXPECTED_LOADS[testName], `${testName} should ${EXPECTED_LOADS[testName] ? "" : "not"} succeed`); + }); + test.done(); + }, false); + document.body.appendChild(iframe); +}); </script> </html>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-revalidated-images.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-revalidated-images.https-expected.txt new file mode 100644 index 0000000..4c2cceb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-revalidated-images.https-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +PASS NETWORK - No CORP image +PASS NETWORK - CORP image +PASS CACHED - No CORP image +FAIL CACHED - CORP image assert_equals: CACHED - CORP image should succeed expected true but got false +PASS main_test +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-revalidated-images.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-revalidated-images.https.html new file mode 100644 index 0000000..420190a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-revalidated-images.https.html
@@ -0,0 +1,76 @@ +<!doctype html> +<html> +<title> Images on a page Cross-Origin-Embedder-Policy: require-corp should load the same from the cache or network, even with revalidation</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="/common/utils.js"></script> +<script> + +function remote(path) { + const REMOTE_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN; + return new URL(path, REMOTE_ORIGIN); +} + +// +// This test loads a same-origin iframe resources/load-corp-images.html with +// Cross-Origin-Embedder-Policy: require-corp +// The iframe loads two cross origin images, one with a +// Cross-Origin-Resource-Policy: cross-origin header, and one without. +// We expect the image with the header to load successfully and the one without +// to fail to load. +// After the first load we then reload the iframe, with the same expectations +// for the image loads when they are loaded from the cache. Because of the +// revalidate directive, we will receive a 304 response instead of directly +// using the cache response. +// + +const RUNS = ["NETWORK", "CACHED"]; +const RESOURCE_DESC = ["No CORP image", "CORP image"]; + +let EXPECTED_LOADS = { + [`${RUNS[0]} - ${RESOURCE_DESC[0]}`]: false, + [`${RUNS[0]} - ${RESOURCE_DESC[1]}`]: true, + [`${RUNS[1]} - ${RESOURCE_DESC[0]}`]: false, + [`${RUNS[1]} - ${RESOURCE_DESC[1]}`]: true, +} + +let TESTS = {}; +for (let t in EXPECTED_LOADS) { + TESTS[t] = async_test(t); +} + +window.addEventListener("load", async () => { + const t = async_test("main_test"); + const iframe = document.createElement("iframe"); + // The token attribute is used to ensure the resource has never been seen by + // the HTTP cache. This can be useful if the cache isn't properly flushed in + // between two tests. + iframe.src = `resources/load-corp-images.html?revalidate=true&token=${token()}`; + let runCount = 0; + window.addEventListener("message", (event) => { + // After the first done event we reload the iframe. + if (event.data.done) { + ++runCount; + if (runCount < RUNS.length) { + iframe.contentWindow.location.reload(); + } else { + // After the second done event the test is finished. + t.done(); + } + return; + } + + // Check that each image either loads or doesn't based on the expectations + let testName = `${RUNS[runCount]} - ${event.data.corp ? RESOURCE_DESC[1] : RESOURCE_DESC[0]}`; + let test = TESTS[testName]; + test.step(() => { + assert_equals(event.data.loaded, EXPECTED_LOADS[testName], `${testName} should ${EXPECTED_LOADS[testName] ? "" : "not"} succeed`); + }); + test.done(); + }, false); + document.body.appendChild(iframe); +}); + +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/corp-image.py b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/corp-image.py index 29689c4..e507846 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/corp-image.py +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/corp-image.py
@@ -10,16 +10,20 @@ response.headers.set(b'Access-Control-Allow-Methods', b'OPTIONS, GET, POST') response.headers.set(b'Access-Control-Allow-Headers', b'Content-Type') - response.headers.set(b"Cache-Control", b"max-age=3600"); # CORS preflight if request.method == u'OPTIONS': return u'' - if b'some-etag' == request.headers.get(b"If-None-Match", None): + if b'true' == request.GET.get(b'revalidate', None): + response.headers.set(b'Cache-Control', b'max-age=0, must-revalidate') + else: + response.headers.set(b'Cache-Control', b'max-age=3600'); + + if b'some-etag' == request.headers.get(b'If-None-Match', None): response.status = 304 return u'' - if request.GET.first(b"corp-cross-origin", default=b""): + if request.GET.get(b'corp-cross-origin', None): response.headers.set(b'Cross-Origin-Resource-Policy', b'cross-origin') response.headers.set(b'Etag', b'some-etag')
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/load-corp-images.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/load-corp-images.html index 1251b8c..2886100 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/load-corp-images.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/load-corp-images.html
@@ -8,22 +8,26 @@ return new URL(path, REMOTE_ORIGIN); } -const image_path = "/html/cross-origin-embedder-policy/resources/corp-image.py"; +let params = new URLSearchParams(location.search); +let token = params.get('token'); +let revalidate = params.get('revalidate'); + +let image_path = `/html/cross-origin-embedder-policy/resources/corp-image.py?token=${token}&revalidate=${revalidate}`; window.addEventListener("load", async () => { await new Promise(resolve => { let img = document.createElement("img"); img.src = remote(image_path); - img.onload = () => { window.parent.postMessage({loaded: true, src: img.src}, "*"); resolve(); }; - img.onerror = (e) => { window.parent.postMessage({loaded: false, src: img.src}, "*"); resolve(); }; + img.onload = () => { window.parent.postMessage({corp: false, loaded: true}, "*"); resolve(); }; + img.onerror = (e) => { window.parent.postMessage({corp: false, loaded: false}, "*"); resolve(); }; document.body.appendChild(img); }); await new Promise(resolve => { let img = document.createElement("img"); - img.src = remote(image_path + "?corp-cross-origin=1"); - img.onload = () => { window.parent.postMessage({loaded: true, src: img.src}, "*"); resolve(); }; - img.onerror = (e) => { window.parent.postMessage({loaded: false, src: img.src}, "*"); resolve(); }; + img.src = remote(image_path + "&corp-cross-origin=1"); + img.onload = () => { window.parent.postMessage({corp: true, loaded: true}, "*"); resolve(); }; + img.onerror = (e) => { window.parent.postMessage({corp: true, loaded: false}, "*"); resolve(); }; document.body.appendChild(img); });
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/color-profile-image-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/color-profile-image-expected.png index 327f50f0..85382509 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/color-profile-image-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/color-profile-image-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/color-profile-layer-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/color-profile-layer-expected.png new file mode 100644 index 0000000..f38a13b --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/color-profile-layer-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/jpeg-missing-eoi-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/jpeg-missing-eoi-expected.png index 0bce2d4..afc58c3 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/jpeg-missing-eoi-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/jpeg-missing-eoi-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-color-profile-lossy-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-color-profile-lossy-expected.png index c369b24..d1b3295 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-color-profile-lossy-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/webp-color-profile-lossy-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/jxl-enabled/images/jxl/jxl-images-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/virtual/jxl-enabled/images/jxl/jxl-images-expected.png index 7656943..27c5227 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/virtual/jxl-enabled/images/jxl/jxl-images-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/jxl-enabled/images/jxl/jxl-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/layout_ng_printing/printing/forced-break-tree-dump-only-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/virtual/layout_ng_printing/printing/forced-break-tree-dump-only-expected.txt index 5527475de..158bf5ec 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/virtual/layout_ng_printing/printing/forced-break-tree-dump-only-expected.txt +++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/layout_ng_printing/printing/forced-break-tree-dump-only-expected.txt
@@ -1,16 +1,14 @@ layer at (0,0) size 1200x900 scrollHeight 1226 - LayoutView at (0,0) size 1600x1200 + LayoutNGView at (0,0) size 1600x1200 layer at (0,0) size 1600x1226 - LayoutBlockFlow {HTML} at (0,0) size 1600x1226 - LayoutBlockFlow {BODY} at (8,16) size 1584x1202 - LayoutBlockFlow {P} at (0,0) size 1584x18 + LayoutNGBlockFlow {HTML} at (0,0) size 1600x1226 + LayoutNGBlockFlow {BODY} at (8,16) size 1584x1202 + LayoutNGBlockFlow {P} at (0,0) size 1584x18 LayoutText {#text} at (0,0) size 1330x17 - text run at (0,0) width 554: "This is a test that only dumps the layout tree, and doesn't actually display the page. This " - text run at (554,0) width 562: "tests some peculiarities in the test framework for printing. To run this test manually, run it " - text run at (1116,0) width 214: "with content_shell --run-web-tests" - LayoutBlockFlow {DIV} at (0,34) size 1584x18 + text run at (0,0) width 1330: "This is a test that only dumps the layout tree, and doesn't actually display the page. This tests some peculiarities in the test framework for printing. To run this test manually, run it with content_shell --run-web-tests" + LayoutNGBlockFlow {DIV} at (0,34) size 1584x18 LayoutText {#text} at (0,0) size 163x17 text run at (0,0) width 163: "This should be on page 1." - LayoutBlockFlow {DIV} at (0,1184) size 1584x18 + LayoutNGBlockFlow {DIV} at (0,1184) size 1584x18 LayoutText {#text} at (0,0) size 163x17 text run at (0,0) width 163: "This should be on page 2."
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/layout_ng_printing/printing/multi-page-background-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/virtual/layout_ng_printing/printing/multi-page-background-expected.png index 1da99ce..beade21 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/virtual/layout_ng_printing/printing/multi-page-background-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/layout_ng_printing/printing/multi-page-background-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/scalefactor200/css3/filters/composited-layer-child-bounds-after-composited-to-sw-shadow-change-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/virtual/scalefactor200/css3/filters/composited-layer-child-bounds-after-composited-to-sw-shadow-change-expected.txt new file mode 100644 index 0000000..c64caf55 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/scalefactor200/css3/filters/composited-layer-child-bounds-after-composited-to-sw-shadow-change-expected.txt
@@ -0,0 +1,76 @@ +{ + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [1600, 1200], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='composited-parent' class='compositor-painted-shadow'", + "bounds": [200, 200], + "contentsOpaque": true, + "backgroundColor": "#FF0000", + "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='absolutely-positioned-composited-child'", + "bounds": [200, 200], + "contentsOpaque": true, + "backgroundColor": "#008000", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [200, 200, 0, 1] + ] + } + ] +} +{ + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [1744, 1170], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='composited-parent' class='software-painted-shadow'", + "bounds": [200, 200], + "contentsOpaque": true, + "backgroundColor": "#FF0000", + "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='absolutely-positioned-composited-child'", + "bounds": [200, 200], + "contentsOpaque": true, + "backgroundColor": "#008000", + "transform": 1 + }, + { + "name": "HorizontalScrollbar", + "position": [0, 1170], + "bounds": [1600, 30] + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [200, 200, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance-expected.png new file mode 100644 index 0000000..7522161 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/scroll-unification/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/virtual/scroll-unification/http/tests/misc/slow-loading-image-in-pattern-expected.png index 8916ed9..814f31a 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/virtual/scroll-unification/http/tests/misc/slow-loading-image-in-pattern-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/scroll-unification/http/tests/misc/slow-loading-image-in-pattern-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/text-antialias/international/bidi-layout-across-linebreak-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/virtual/text-antialias/international/bidi-layout-across-linebreak-expected.png index 7b212f3..a784225 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/virtual/text-antialias/international/bidi-layout-across-linebreak-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/text-antialias/international/bidi-layout-across-linebreak-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/IndexedDB/idb-partitioned-persistence.tentative.sub-expected.txt b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/IndexedDB/idb-partitioned-persistence.tentative.sub-expected.txt new file mode 100644 index 0000000..c06bd21 --- /dev/null +++ b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/IndexedDB/idb-partitioned-persistence.tentative.sub-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +PASS Persistence test for partitioned IndexedDB +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/css-tags-paint-order-with-entry-ref.html b/third_party/blink/web_tests/wpt_internal/document-transition/css-tags-paint-order-with-entry-ref.html new file mode 100644 index 0000000..74f32f8 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/document-transition/css-tags-paint-order-with-entry-ref.html
@@ -0,0 +1,41 @@ +<!DOCTYPE html> +<title>Shared transitions: css tags generate pseudo elements in paint order (ref)</title> +<link rel="help" href="https://github.com/WICG/shared-element-transitions"> +<link rel="author" href="mailto:vmpstr@chromium.org"> + +<script src="/common/reftest-wait.js"></script> +<style> +div { + contain: paint; + position: absolute; + top: 50px; + width: 100px; + height: 100px; +} +#one { + background: green; + left: 50px; + z-index: 1; +} +#two { + background: yellow; + left: 125px; + z-index: -1; +} +#three { + background: blue; + left: 200px; + z-index: 0; +} +#four { + background: lightgreen; + left: 275px; + z-index: 0; +} +body { background: lightpink; } +</style> + +<div id=one></div> +<div id=two></div> +<div id=three></div> +<div id=four></div>
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/css-tags-paint-order-with-entry.html b/third_party/blink/web_tests/wpt_internal/document-transition/css-tags-paint-order-with-entry.html new file mode 100644 index 0000000..2fb54f7 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/document-transition/css-tags-paint-order-with-entry.html
@@ -0,0 +1,109 @@ +<!DOCTYPE html> +<html class=reftest-wait> +<title>Shared transitions: css tags generate pseudo elements in paint order</title> +<link rel="help" href="https://github.com/WICG/shared-element-transitions"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<link rel="match" href="css-tags-paint-order-with-entry-ref.html"> + +<script src="/common/reftest-wait.js"></script> +<style> +div { contain: paint; } +#one { + background: green; + width: 100px; + height: 100px; + position: relative; + z-index: 1; + page-transition-tag: one; +} +#two { + background: yellow; + width: 100px; + height: 100px; + page-transition-tag: two; +} +#three { + background: blue; + width: 100px; + height: 100px; + page-transition-tag: three; +} +#four { + position: absolute; + background: lightgreen; + width: 100px; + height: 100px; + top: 50px; + left: 275px; + page-transition-tag: four; +} + +.hidden { + background: pink; + width: 10px; + height: 10px; + page-transition-tag: hidden; +} + +html::page-transition-container(hidden) { animation-duration: 300s; } +html::page-transition-image-wrapper(hidden) { animation: unset; opacity: 0; } + +html::page-transition-container(one) { + animation: unset; + transform: unset; + position: absolute; + top: 50px; + left: 50px; +} +html::page-transition-container(two) { + animation: unset; + transform: unset; + position: absolute; + top: 50px; + left: 125px; +} +html::page-transition-container(three) { + animation: unset; + transform: unset; + position: absolute; + top: 50px; + left: 200px; +} +html::page-transition-incoming-image(four) { + animation: unset; + opacity: 1; +} + +html::page-transition-incoming-image(one), +html::page-transition-incoming-image(two), +html::page-transition-incoming-image(three) { animation: unset; opacity: 0; } + +html::page-transition-outgoing-image(one), +html::page-transition-outgoing-image(two), +html::page-transition-outgoing-image(three) { animation: unset; opacity: 1; } + +html::page-transition-container(root) { animation: unset; opacity: 0; } +html::page-transition { background: lightpink; } + +</style> + +<div id=one></div> +<div id=two></div> +<div id=three></div> + +<div id=hidden class=hidden></div> + +<script> +async function runTest() { + let t = document.createDocumentTransition(); + t.start(() => { + const f = document.createElement("div"); + f.id = "four"; + document.body.appendChild(f); + + requestAnimationFrame(() => requestAnimationFrame(takeScreenshot)); + }); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +
diff --git a/third_party/closure_compiler/externs/chromeos_info_private.js b/third_party/closure_compiler/externs/chromeos_info_private.js index 8930a5f..7066b12 100644 --- a/third_party/closure_compiler/externs/chromeos_info_private.js +++ b/third_party/closure_compiler/externs/chromeos_info_private.js
@@ -99,6 +99,7 @@ * customizationId: (string|undefined), * homeProvider: (string|undefined), * hwid: (string|undefined), + * isMeetDevice: (boolean|undefined), * initialLocale: (string|undefined), * isOwner: (boolean|undefined), * sessionType: (!chrome.chromeosInfoPrivate.SessionType|undefined),
diff --git a/tools/grit/grit/testdata/tools/grit/resource_ids b/tools/grit/grit/testdata/tools/grit/resource_ids index 8a2b608d..460bb5c 100644 --- a/tools/grit/grit/testdata/tools/grit/resource_ids +++ b/tools/grit/grit/testdata/tools/grit/resource_ids
@@ -157,9 +157,6 @@ "META": {"join": 2}, "includes": [21500], }, - "cloud_print/virtual_driver/win/install/virtual_driver_setup_resources.grd": { - "messages": [22500], - }, "chrome/browser/resources/quota_internals_resources.grd": { "includes": [23000], },
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec index 22896db0..862a5fa 100644 --- a/tools/gritsettings/resource_ids.spec +++ b/tools/gritsettings/resource_ids.spec
@@ -823,11 +823,6 @@ "includes": [4180], }, - "cloud_print/virtual_driver/win/install/virtual_driver_setup_resources.grd": { - "includes": [4200], - "messages": [4220], - }, - "device/bluetooth/bluetooth_strings.grd": { "messages": [4240], },
diff --git a/tools/gritsettings/translation_expectations.pyl b/tools/gritsettings/translation_expectations.pyl index 489c672..ca720fe 100644 --- a/tools/gritsettings/translation_expectations.pyl +++ b/tools/gritsettings/translation_expectations.pyl
@@ -120,7 +120,6 @@ "chrome/app/resources/locale_settings_win.grd": "Not UI strings; localized separately", "chrome/test/data/chrome_test_resources.grd": "Test data", "chromecast/app/resources/chromecast_settings.grd": "Not UI strings; localized separately", - "cloud_print/virtual_driver/win/install/virtual_driver_setup_resources.grd": "Separate release process", "components/components_locale_settings.grd": "Not UI strings; localized separately", "components/omnibox/resources/omnibox_resources.grd": "Not UI strings; localized separately", "tools/grit/grit/testdata/allowlist_resources.grd": "Test data",
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index b3aed02..aa8731a 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -2476,7 +2476,6 @@ <action name="Android.BookmarkPage.ReadingList.MarkAsRead"> <owner>shaktisahu@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <description> User marked an item as read in the Reading List page from the Android bookmark page by clicking "Mark As Read" from the "more" @@ -2486,7 +2485,6 @@ <action name="Android.BookmarkPage.ReadingList.OpenReadingList"> <owner>shaktisahu@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <description> User navigated to the Reading List page from the Android bookmark page by clicking on reading list folder. @@ -2495,7 +2493,6 @@ <action name="Android.BookmarkPage.ReadingList.RemoveItem"> <owner>shaktisahu@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <description> User removed an item from the Reading List page from the Android bookmarks page by clicking "delete" from the "more" menu. @@ -2504,7 +2501,6 @@ <action name="Android.BookmarkPage.ReadingList.SelectFromMenu"> <owner>shaktisahu@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <description> User selected an item from the Reading List page from the Android bookmark page by clicking "select" from the "more" menu. @@ -2531,7 +2527,6 @@ <action name="Android.Bookmarks.BottomSheet.Open"> <owner>shaktisahu@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <description> User tapped on the star icon from the app menu to bookmark a page. This resulted in opening the bookmarks bottom sheet that presents a list of @@ -2866,7 +2861,7 @@ </action> <action name="Android.DownloadManager.Item.ExternallyDeletedKeepRecord"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <description> A download file was externally deleted by other application, e.g. through a third-party download manager. However the associated database record will @@ -7621,7 +7616,6 @@ </action> <action name="Downloads_OpenUrlOfDownloadedItem"> - <owner>xingliu@chromium.org</owner> <owner>chrome-analysis-team@google.com</owner> <description> Records clicks on the URL of download items in chrome://downloads page. @@ -7632,7 +7626,6 @@ </action> <action name="Downloads_OpenUrlOfDownloadedItemFromContextMenu"> - <owner>xingliu@chromium.org</owner> <owner>chrome-analysis-team@google.com</owner> <description> Records open a URL of download items in chrome://downloads page from context @@ -16415,7 +16408,6 @@ </action> <action name="Mobile.SystemNotification.Content.Click.Downloads_Files"> - <owner>xingliu@chromium.org</owner> <owner>chrome-analysis-team@google.com</owner> <description> The user clicked on the body of an Android notification for a file download. @@ -18992,7 +18984,7 @@ </action> <action name="MobileTabClosedUndoShortCut"> - <owner>xingliu@chromium.org</owner> + <owner>dtrainor@chromium.org</owner> <description> Undo tab closure by keyboard shortcut ctrl+shift+T, for Android only. </description>
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index 5b19d2d6..b9bac47 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -821,7 +821,7 @@ enum="DownloadNotificationForegroundLifecycle" expires_after="never"> <!-- expires-never: Download foreground notification stability metric. --> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> Records instances where the foreground undergoes a lifecycle change (when @@ -905,7 +905,7 @@ <histogram name="Android.DownloadManager.NotificationInteraction" enum="DownloadNotificationInteractions" expires_after="2022-08-28"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> Records instances where a user interacts with a download notification (ie. @@ -915,14 +915,14 @@ <histogram name="Android.DownloadManager.OpenSource.Audio" enum="AndroidDownloadOpenSource" expires_after="2022-08-28"> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary>Records how users open audio download files on Android.</summary> </histogram> <histogram name="Android.DownloadManager.OpenSource.Other" enum="AndroidDownloadOpenSource" expires_after="2022-08-14"> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> Records the entry point for users opening downloaded files on Android, that @@ -932,14 +932,14 @@ <histogram name="Android.DownloadManager.OpenSource.Video" enum="AndroidDownloadOpenSource" expires_after="2022-08-14"> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary>Records how users open video download files on Android.</summary> </histogram> <histogram name="Android.DownloadManager.ServiceStopped.DownloadForeground" enum="DownloadNotificationServiceStopped" expires_after="never"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <!-- expires-never: Download foreground notification stability metric. --> @@ -958,7 +958,6 @@ <histogram name="Android.DownloadManager.Share.Count" units="units" expires_after="M86"> <owner>twellington@chromium.org</owner> - <owner>ianwen@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary>The number of downloads shared at the same time.</summary> </histogram> @@ -966,7 +965,6 @@ <histogram name="Android.DownloadManager.Share.FileTypes" enum="AndroidDownloadFilterType" expires_after="2020-03-01"> <owner>twellington@chromium.org</owner> - <owner>ianwen@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> Recorded when downloads are shared through the download manager. A recorded @@ -978,7 +976,6 @@ <histogram name="Android.DownloadManager.SpaceUsed" units="%" expires_after="M81"> <owner>twellington@chromium.org</owner> - <owner>ianwen@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary>The percentage of total storage downloads consume.</summary> </histogram> @@ -997,7 +994,7 @@ <histogram name="Android.DownloadPage.OpenSource" enum="AndroidDownloadOpenSource" expires_after="2023-02-16"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> Records the entry point for users opening the download page on Android.
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index 18a5b8f..13bc63de 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -123,7 +123,7 @@ </histogram> <histogram name="Ash.Accelerators.Rotation.Usage" - enum="ScreenRotationAcceleratorAction" expires_after="2022-03-15"> + enum="ScreenRotationAcceleratorAction" expires_after="2023-03-15"> <owner>zentaro@chromium.org</owner> <owner>cros-peripherals@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/bookmarks/histograms.xml b/tools/metrics/histograms/metadata/bookmarks/histograms.xml index 5ec23f5..5547398 100644 --- a/tools/metrics/histograms/metadata/bookmarks/histograms.xml +++ b/tools/metrics/histograms/metadata/bookmarks/histograms.xml
@@ -132,7 +132,6 @@ <histogram name="Bookmarks.BottomSheet.DestinationFolder" enum="BookmarkType" expires_after="2022-06-01"> <owner>wylieb@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <component>UI>Browser>Bookmarks</component> <summary> Logs the destination directory chosen by the user when saving a bookmark via @@ -616,7 +615,6 @@ <histogram name="Bookmarks.OpenBookmarkTimeInterval2.{BookmarkType}" units="ms" expires_after="2022-02-15"> <owner>dtrainor@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <component>UI>Browser>Bookmarks</component> <summary> A new version of Bookmarks.OpenBookmarkTimeInterval.{BookmarkType}, to rule @@ -642,7 +640,6 @@ <histogram name="Bookmarks.ReadingList.NumberOfItems" units="items" expires_after="2022-08-14"> <owner>shaktisahu@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <component>UI>Browser>Bookmarks</component> <component>UI>Browser>Mobile>ReadingList</component> <summary> @@ -654,7 +651,6 @@ <histogram name="Bookmarks.ReadingList.NumberOfReadItems" units="items" expires_after="2022-08-14"> <owner>shaktisahu@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <component>UI>Browser>Bookmarks</component> <component>UI>Browser>Mobile>ReadingList</component> <summary> @@ -666,7 +662,6 @@ <histogram name="Bookmarks.ReadingList.NumberOfUnreadItems" units="items" expires_after="2022-08-28"> <owner>shaktisahu@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <component>UI>Browser>Bookmarks</component> <component>UI>Browser>Mobile>ReadingList</component> <summary>
diff --git a/tools/metrics/histograms/metadata/browser/histograms.xml b/tools/metrics/histograms/metadata/browser/histograms.xml index b7d62712..2f0407b 100644 --- a/tools/metrics/histograms/metadata/browser/histograms.xml +++ b/tools/metrics/histograms/metadata/browser/histograms.xml
@@ -50,6 +50,9 @@ <histogram name="Browser.BitmapFetcher.Decode" units="ms" expires_after="2022-09-18"> + <obsolete> + 3/2022; feature launched. + </obsolete> <owner>manukh@chromium.org</owner> <owner>jdonnelly@chromium.org</owner> <owner>chrome-omnibox-team@google.com</owner> @@ -58,6 +61,9 @@ <histogram name="Browser.BitmapFetcher.Fetch" units="ms" expires_after="2022-03-06"> + <obsolete> + 3/2022; feature launched. + </obsolete> <owner>manukh@chromium.org</owner> <owner>jdonnelly@chromium.org</owner> <owner>chrome-omnibox-team@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/download/histograms.xml b/tools/metrics/histograms/metadata/download/histograms.xml index e34949b..2c7b799 100644 --- a/tools/metrics/histograms/metadata/download/histograms.xml +++ b/tools/metrics/histograms/metadata/download/histograms.xml
@@ -50,7 +50,6 @@ <histogram name="Download.BandwidthOverallBytesPerSecond2" units="bytes/second" expires_after="2022-09-11"> <owner>qinmin@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Overall bandwidth seen for a completed download. This includes all file downloads going through the download subsystem, but excludes all the page @@ -63,7 +62,7 @@ <histogram name="Download.CancelReason" enum="DownloadCancelReason" expires_after="2022-09-18"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary>Records why the download is canceled.</summary> </histogram> @@ -72,7 +71,8 @@ expires_after="never"> <!-- expires-never: Monitors download system health. --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <summary>Types of audio files that are downloaded.</summary> </histogram> @@ -88,7 +88,8 @@ expires_after="never"> <!-- expires-never: Monitors download system health. --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <summary>Types of text files that are downloaded.</summary> </histogram> @@ -96,7 +97,8 @@ expires_after="never"> <!-- expires-never: Monitors download system health. --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <summary>Types of video files that are downloaded.</summary> </histogram> @@ -104,7 +106,8 @@ expires_after="2022-07-24"> <!-- Name completed by histogram_suffixes name="DownloadSource" --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <summary> Various individual counts in the download system; see DownloadCountType for details. @@ -123,7 +126,6 @@ <histogram name="Download.DangerousDialog.Events" enum="DangerousDownloadDialogEvent" expires_after="2022-08-21"> <owner>qinmin@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records user interactions with the dangerous download dialog on Android. Records when the dialog is shown, or when user clicks on a button or @@ -145,7 +147,6 @@ expires_after="never"> <!-- expires-never: Helpful to track download database issue. --> - <owner>xingliu@chromium.org</owner> <owner>qinmin@chromium.org</owner> <summary> Records whether the download database is available when database startup @@ -157,7 +158,8 @@ <histogram name="Download.DeleteRetentionTime.Audio" units="hours" expires_after="2020-01-30"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <summary> How long users keep downloaded audio files on disk. Recorded when the downloaded file is deleted. @@ -166,7 +168,8 @@ <histogram name="Download.DeleteRetentionTime.Video" units="hours" expires_after="2020-01-30"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <summary> How long users keep downloaded video files on disk. Recorded when the downloaded file is deleted. @@ -265,7 +268,8 @@ expires_after="never"> <!-- expires-never: Used to monitor download system health. --> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <summary>The count of HTTP Response codes for download requests.</summary> </histogram> @@ -306,7 +310,7 @@ <!-- expires-never: Core download metrics, used in go/chrome-download-dashboard. --> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary>The reason that a download was interrupted.</summary> </histogram> @@ -453,7 +457,7 @@ <histogram name="Download.Later.Events" enum="DownloadLaterEvent" expires_after="2022-07-17"> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> Records events for download later feature in download core code. @@ -462,7 +466,7 @@ <histogram name="Download.Later.ScheduledDownloadSize" units="Mb" expires_after="2022-05-01"> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> The size of downloads when the user tries to download at a scheduled time. @@ -474,7 +478,7 @@ enum="DownloadLaterDialogChoice" expires_after="2022-08-07"> <!-- Name completed by histogram_suffixes name="DownloadDialogSource" --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> The user selection in the download later dialog. Recorded when the user @@ -485,7 +489,7 @@ <histogram name="Download.Later.UI.Events" enum="DownloadLaterUiEvent" expires_after="2022-08-14"> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> Records events for download later feature in download Android UI. @@ -498,7 +502,6 @@ <owner>dtrainor@chromium.org</owner> <owner>qinmin@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary>Records events for local media metadata parsing.</summary> </histogram> @@ -508,7 +511,6 @@ <owner>dtrainor@chromium.org</owner> <owner>qinmin@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records events when using media parser to analyze local media files. </summary> @@ -517,7 +519,6 @@ <histogram name="Download.MixedContentDialog.Events" enum="MixedContentDownloadDialogEvent" expires_after="2022-08-07"> <owner>qinmin@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records user interactions with the mixed content download dialog on Android. Records when the dialog is shown, or when user clicks on a button or @@ -539,7 +540,6 @@ <!-- Name completed by histogram_suffixes name="DownloadSource" --> <owner>dtrainor@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary>Network connection type when a download is completed.</summary> </histogram> @@ -548,7 +548,6 @@ <!-- Name completed by histogram_suffixes name="DownloadSource" --> <owner>dtrainor@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary>Network connection type when starting a new download.</summary> </histogram> @@ -619,7 +618,6 @@ <histogram name="Download.ParallelDownload.CreationFailureReason" enum="InterruptReason" expires_after="2021-04-25"> <owner>qinmin@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records the received failure reason after sending a parallel download request. @@ -629,7 +627,6 @@ <histogram name="Download.ParallelDownloadRequestCount" units="requests" expires_after="2022-04-01"> <owner>qinmin@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> The total number of requests sent for a parallel download, including the initial request. @@ -642,7 +639,8 @@ <!-- Name completed by histogram_suffixes name="DownloadType" --> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <owner>clank-downloads@google.com</owner> <summary> The download path generation behavior which happens before download path @@ -656,7 +654,7 @@ <!-- Name completed by histogram_suffixes name="DownloadType" --> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> The download path validation result before the final download target is @@ -739,7 +737,6 @@ <histogram name="Download.ResumptionRestart.Reason" enum="InterruptReason" expires_after="2021-02-28"> <owner>qinmin@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records the interrupt reason when download is restarting from the beginning during resumption. @@ -759,7 +756,7 @@ units="KB" expires_after="never"> <!-- expires-never: Download service stability metric. --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@chromium.org</owner> <summary> The file size of completed background download. Recorded when background @@ -774,7 +771,7 @@ enum="Download.Service.ModelAction" expires_after="never"> <!-- expires-never: Monitor background download system database stability. --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary>Records a failed database operation.</summary> </histogram> @@ -783,7 +780,7 @@ enum="Download.Service.ModelAction" expires_after="never"> <!-- expires-never: Monitor background download system database stability. --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary>Records a successful database operation.</summary> </histogram> @@ -795,7 +792,7 @@ <!-- Name completed by histogram_suffixes name="Download.Service.EntryState" --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> The total number of database records used by download service, and the @@ -807,7 +804,7 @@ enum="InterruptReason" expires_after="never"> <!-- expires-never: Monitor background download system errors. --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> The interrupt reason for failed downloads in download service. @@ -817,14 +814,12 @@ <histogram name="Download.Service.Entry.Event" enum="Download.Service.EntryEvent" expires_after="M88"> <owner>dtrainor@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary>An action the download service took on an active download.</summary> </histogram> <histogram name="Download.Service.Entry.RetryCount" units="attempts" expires_after="M88"> <owner>dtrainor@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records how many attempts have taken place at the time of a retry for a download in the Download Service. This differs from @@ -840,7 +835,7 @@ <!-- Name completed by histogram_suffixes name="Download.Service.CleanupReason" --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> The number of files that have been deleted by external application or the @@ -855,7 +850,7 @@ <!-- Name completed by histogram_suffixes name="Download.Service.CleanupReason" --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> The number of failed file deletion attempts, when performing clean up tasks @@ -870,7 +865,7 @@ <!-- Name completed by histogram_suffixes name="Download.Service.CleanupReason" --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> The number of files successfully deleted, when performing clean up tasks in @@ -882,7 +877,8 @@ enum="PlatformFileError" expires_after="never"> <!-- expires-never: Download service stability metric. --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <summary> The error code when failed to create the download directory. </summary> @@ -892,7 +888,8 @@ expires_after="never"> <!-- expires-never: Download service stability metric. --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <summary> The lifestime of a download file, which begins from the download completion to the file being deleted by the clean up task. @@ -904,13 +901,15 @@ <!-- Name completed by histogram_suffixes name="Download.Service.CompletionType" --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <summary>The time to complete the download in download service.</summary> </histogram> <histogram name="Download.Service.Finish.Type" enum="Download.Service.CompletionType" expires_after="2022-08-14"> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <summary>The completion type for downloads in download service.</summary> </histogram> @@ -944,7 +943,7 @@ <!-- Name completed by histogram_suffixes name="Download.Service.Client" --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary>Records the API calls on download service.</summary> </histogram> @@ -956,7 +955,7 @@ <!-- expires-never: Monitors download service system health. --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary>The start up result of the download service.</summary> </histogram> @@ -968,7 +967,7 @@ <!-- Name completed by histogram_suffixes name="Download.Service.TaskType" --> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> The platform background tasks used by download service will invoke native @@ -1138,7 +1137,7 @@ expires_after="never"> <!-- expires-never: Monitors download system health. --> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> The initiation source (if initiated within the above-content layer of @@ -1189,7 +1188,6 @@ <owner>dtrainor@chromium.org</owner> <owner>qinmin@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary>Records events for local video thumbnail retrieval.</summary> </histogram>
diff --git a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml index feb3339..8df8972 100644 --- a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml +++ b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
@@ -233,7 +233,6 @@ <histogram name="InProductHelp.Config.ParsingEvent" enum="ConfigParsingEvent" expires_after="2022-09-11"> <owner>nyquist@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records if in-product help configuration is parsed correctly, and the failure reasons for parsing failures. @@ -243,7 +242,6 @@ <histogram name="InProductHelp.Db.Init.{IPHDatabase}" enum="BooleanSuccess" expires_after="2022-12-26"> <owner>nyquist@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records if {IPHDatabase} database initialization succeeds for in-product help. @@ -254,7 +252,6 @@ <histogram name="InProductHelp.Db.Load.{IPHDatabase}" enum="BooleanSuccess" expires_after="2022-12-26"> <owner>nyquist@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records if {IPHDatabase} database successfully loads the data for in-product help. @@ -265,7 +262,6 @@ <histogram name="InProductHelp.Db.TotalEvents" units="events" expires_after="2022-05-01"> <owner>nyquist@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records the total number of event records in the database for in-product help after the event model is loaded. @@ -275,7 +271,6 @@ <histogram name="InProductHelp.Db.Update.{IPHDatabase}" enum="BooleanSuccess" expires_after="2022-12-26"> <owner>nyquist@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records if {IPHDatabase} database update succeeds for in-product help. </summary> @@ -285,7 +280,6 @@ <histogram name="InProductHelp.NotifyEventReadyState.{IPHFeature}" enum="BooleanSuccess" expires_after="2022-12-26"> <owner>nyquist@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records if the model is ready when in-product help event happens for {IPHFeature}. @@ -356,7 +350,6 @@ <histogram name="InProductHelp.ShouldTriggerHelpUI.{IPHFeature}" enum="TriggerHelpUIResult" expires_after="2022-12-26"> <owner>nyquist@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records if in-product help for {IPHFeature} is shown to the user, and the failure reasons if in-product help is not shown. Recorded on its own across
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml index 353cbeb4..a2cf83d 100644 --- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -5950,6 +5950,8 @@ <affected-histogram name="NewTabPage.LogoShown"/> </histogram_suffixes> +<!-- TODO(crbug.com/1309706): Migrate these histograms to use the patterned histograms instead. --> + <histogram_suffixes name="NewTabPageModules" separator="."> <suffix name="chrome_cart" label="Module ID for Chrome Cart"/> <suffix name="drive" label="Module ID for Google Drive module"/>
diff --git a/tools/metrics/histograms/metadata/image/histograms.xml b/tools/metrics/histograms/metadata/image/histograms.xml index 92a2b2d..b9c151c 100644 --- a/tools/metrics/histograms/metadata/image/histograms.xml +++ b/tools/metrics/histograms/metadata/image/histograms.xml
@@ -317,7 +317,6 @@ units="records" expires_after="2022-06-01"> <owner>fgorski@chromium.org</owner> <owner>wylieb@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> The total number of metadata entries in the image fetcher cache metadata database for a given cache strategy. Recorded during cache eviction process. @@ -330,7 +329,6 @@ expires_after="2022-06-01"> <owner>fgorski@chromium.org</owner> <owner>wylieb@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> The total size of the cache for a given cache strategy. Recorded during cache eviction process. {ImageFetcherCacheStrategy}
diff --git a/tools/metrics/histograms/metadata/mobile/histograms.xml b/tools/metrics/histograms/metadata/mobile/histograms.xml index cdabf9f..54d8d53e 100644 --- a/tools/metrics/histograms/metadata/mobile/histograms.xml +++ b/tools/metrics/histograms/metadata/mobile/histograms.xml
@@ -387,7 +387,6 @@ <!-- expires-never: Core Android notification metrics. Used by multiple teams. --> <owner>dtrainor@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records which Android notifications users interact with. Recorded when an user taps the button in a notification, for any Chrome-generated @@ -403,7 +402,6 @@ <!-- expires-never: Core Android notification metrics. Used by multiple teams. --> <owner>dtrainor@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records the duration in minutes from the time when the system notification is shown to the time that the user clicked on an action button on the @@ -416,7 +414,6 @@ <!-- expires-never: Core Android notification metrics. Used by multiple teams. --> <owner>dtrainor@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Android: Represents the number of system notifications that were blocked and could not be shown by type. @@ -428,7 +425,6 @@ <!-- expires-never: Core Android notification metrics. Used by multiple teams. --> <owner>dtrainor@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Android: Represents the type of notification that was last shown before the user disabled notification permissions on Chrome. This is only logged the @@ -441,7 +437,6 @@ <!-- expires-never: Core Android notification metrics. Used by multiple teams. --> <owner>peter@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Android: Represents the number of system notifications by type that we attempted to show but were blocked, due to their notification channel being @@ -453,7 +448,7 @@ enum="SystemNotificationType" expires_after="never"> <!-- expires-never: part of top-line metric (internal: go/chrome-browser-nsm) --> - <owner>xingliu@chromium.org</owner> + <owner>dtrainor@chromium.org</owner> <owner>chrome-analysis-team@google.com</owner> <summary> Records the type of notification when the user clicks the body of Android @@ -472,7 +467,6 @@ <!-- expires-never: Core Android notification metrics. Used by multiple teams. --> <owner>dtrainor@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records the duration in minutes from the time when the system notification is shown to the time that the user clicked the notification on Android. @@ -484,7 +478,6 @@ <!-- expires-never: Core Android notification metrics. Used by multiple teams. --> <owner>dtrainor@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records the type of notification when the user dismisses the Android notification. @@ -499,7 +492,6 @@ <!-- expires-never: Core Android notification metrics. Used by multiple teams. --> <owner>dtrainor@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Records the duration in minutes from the time when the system notification is shown to the time that the user dismissed the notification on Android. @@ -564,7 +556,6 @@ <!-- expires-never: Core Android notification metrics. Used by multiple teams. --> <owner>dtrainor@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Android: Represents the number of system notifications that will be successfully shown to the user by type. @@ -585,7 +576,6 @@ enum="MobileDownloadBackgroundTargetDeterminationResult" expires_after="2020-12-13"> <owner>qinmin@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> Android: Records the target determination result for downloads started in the background, that is, while the browser process is not running. @@ -603,7 +593,7 @@ <histogram name="MobileDownload.DownloadLaterPromptStatus" enum="DownloadLaterPromptStatus" expires_after="2023-02-06"> - <owner>xingliu@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> Android: Records whether download later dialog will be shown to the user. @@ -613,7 +603,7 @@ <histogram name="MobileDownload.DownloadPromptStatus" enum="DownloadPromptStatus" expires_after="2023-02-16"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> Android: Records whether download dialog will be shown to the user. Recorded @@ -623,7 +613,7 @@ <histogram name="MobileDownload.Location.Dialog.DirectoryType" enum="DownloadLocationDirectoryType" expires_after="2022-02-16"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> Records the directory type when the user selects the download directory @@ -634,7 +624,7 @@ <histogram name="MobileDownload.Location.Dialog.Result" enum="DownloadLocationDialogResult" expires_after="2022-02-16"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> Records whether the user accepted or dismissed the dialog to select a @@ -644,21 +634,21 @@ <histogram name="MobileDownload.Location.Dialog.Suggestion.Events" enum="DownloadLocationSuggestionEvent" expires_after="2023-02-16"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary>Records the download location suggestion event.</summary> </histogram> <histogram name="MobileDownload.Location.Dialog.SuggestionSelected" enum="BooleanSelected" expires_after="2023-02-16"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary>Records the download location suggestion choice.</summary> </histogram> <histogram name="MobileDownload.Location.Dialog.Type" enum="DownloadLocationDialogType" expires_after="2023-02-16"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> Records the download location dialog type when the dialog is shown to the @@ -668,7 +658,6 @@ <histogram name="MobileDownload.Location.DirectoryType" enum="DownloadLocationDirectoryType" expires_after="2023-02-16"> - <owner>xingliu@chromium.org</owner> <owner>dtrainor@chromium.org</owner> <owner>qinmin@chromium.org</owner> <summary> @@ -680,14 +669,14 @@ <histogram name="MobileDownload.Location.Download.DirectoryType" enum="DownloadLocationDirectoryType" expires_after="2023-02-16"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary>Records the directory type when download is completed.</summary> </histogram> <histogram name="MobileDownload.Location.Setting.DirectoryType" enum="DownloadLocationDirectoryType" expires_after="2023-02-16"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>clank-downloads@google.com</owner> <summary> Records the directory type when the user selects the download directory @@ -793,6 +782,8 @@ meaningful paint. Version V2 fixed an issue that previous data was not recording the time duration from FRE launched"/> <variant name="FreCompleted" summary="the entire FRE is completed"/> + <variant name="NativeAndPoliciesLoaded" + summary="the native code and policies are loaded."/> <variant name="TosAccepted" summary="the ToS is accepted"/> <variant name="TriggerLayoutInflation" summary="layout inflation is triggered"/>
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml index 5a7298f..bd153d3 100644 --- a/tools/metrics/histograms/metadata/net/histograms.xml +++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -1797,7 +1797,6 @@ <histogram name="Net.HttpResponseCode.CustomHttpClient" enum="HttpResponseCode" expires_after="2022-07-31"> <owner>wenyufu@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <owner>twellington@chromium.org</owner> <summary> Http response code accepted by the request sent from a custom HttpClient, if
diff --git a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml index fa39747..b14f4a4 100644 --- a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml +++ b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
@@ -1162,6 +1162,38 @@ </summary> </histogram> +<histogram name="NewTabPage.Modules.LoadedModulesCount" units="count" + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> + <owner>tiborg@chromium.org</owner> + <owner>chrome-desktop-ntp@google.com</owner> + <summary> + The number of rendered modules in the NTP. Only logged on the 1P NTP. Note + that even if the user has Google as their default search engine, Incognito + and Guest mode NTPs are not considered 1P and don't log this histogram. + </summary> +</histogram> + +<histogram name="NewTabPage.Modules.LoadedWith.{NtpModule}" enum="NtpModules" + expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> + <owner>tiborg@chromium.org</owner> + <owner>chrome-desktop-ntp@google.com</owner> + <summary> + This records the what other modules are loaded with {NtpModule} together. + Logged when the module is loaded. Only logged on the 1P NTP. Note that even + if the user has Google as their default search engine, Incognito and Guest + mode NTPs are not considered 1P and don't log this histogram. + </summary> + <token key="NtpModule"> + <variant name="chrome_cart" summary="the Chrome Cart module"/> + <variant name="drive" summary="the Drive module"/> + <variant name="photos" summary="the Photos module"/> + <variant name="recipe_tasks" summary="the Recipe module"/> + <variant name="shopping_tasks" summary="the Shopping Tasks module"/> + </token> +</histogram> + <histogram name="NewTabPage.Modules.Restored" units="count" expires_after="2022-07-01"> <owner>danpeng@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/notifications/histograms.xml b/tools/metrics/histograms/metadata/notifications/histograms.xml index e3171b92..8dbee91 100644 --- a/tools/metrics/histograms/metadata/notifications/histograms.xml +++ b/tools/metrics/histograms/metadata/notifications/histograms.xml
@@ -199,8 +199,8 @@ <histogram name="Notifications.Chime.Android.Events" enum="ChimeEvent" expires_after="never"> - <owner>hesen@chromium.org</owner> - <owner>xingliu@chromium.org</owner> + <owner>dtrainor@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <!-- expires-never: Monitors Chime notification stability. --> <summary> @@ -212,8 +212,8 @@ <histogram name="Notifications.Chime.Android.Registration" enum="BooleanSuccess" expires_after="never"> - <owner>hesen@chromium.org</owner> - <owner>xingliu@chromium.org</owner> + <owner>dtrainor@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <!-- expires-never: Monitors Chime notification stability. --> <summary> @@ -727,8 +727,8 @@ <histogram name="Notifications.Scheduler.BackgroundTask.Event" enum="NotificationSchedulerBackgroundTaskEvent" expires_after="2022-12-31"> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records the various events when running the background task in notification scheduling system. @@ -737,8 +737,8 @@ <histogram name="Notifications.Scheduler.BackgroundTask.NotificationShown" units="notifications" expires_after="2022-12-31"> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records the number of notifications shown in each background task run. </summary> @@ -746,8 +746,8 @@ <histogram name="Notifications.Scheduler.BackgroundTask.Start" units="hours" expires_after="2022-12-31"> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records the hour (0-23) when the notification scheduler background task starts. @@ -756,8 +756,8 @@ <histogram name="Notifications.Scheduler.IconDb.InitResult" enum="BooleanSuccess" expires_after="2022-12-31"> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records the initialization result of icon database for the notification scheduling system. @@ -766,8 +766,8 @@ <histogram name="Notifications.Scheduler.IconDb.OperationResult" enum="BooleanSuccess" expires_after="2022-12-31"> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records the database operation result (except initialization) of icon database for the notification scheduling system. @@ -776,8 +776,8 @@ <histogram name="Notifications.Scheduler.IconDb.RecordCount" units="records" expires_after="2022-09-11"> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records the number of records of icon database for the notification scheduling system when the icon database is initialized. @@ -788,8 +788,8 @@ enum="NotificationSchedulerActionButtonEvent" expires_after="2022-12-31"> <!-- Name completed by histogram_suffixes name="NotificationSchedulerClientType" --> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records events for inline helpful/unhelpful action buttons on the notification when the buttons are shown or clicked. @@ -800,8 +800,8 @@ expires_after="2022-12-31"> <!-- Name completed by histogram_suffixes name="NotificationSchedulerClientType" --> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records the number of impression records in impression db right after the impression database is initialized. @@ -810,8 +810,8 @@ <histogram name="Notifications.Scheduler.Impression.Event" enum="NotificationSchedulerImpressionEvent" expires_after="2022-12-31"> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records various events in impression history tracker in notification scheduling system when the user interacts with the notification. @@ -820,8 +820,8 @@ <histogram name="Notifications.Scheduler.ImpressionDb.InitResult" enum="BooleanSuccess" expires_after="2022-12-31"> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records the initialization result of impression database for the notification scheduling system. @@ -830,8 +830,8 @@ <histogram name="Notifications.Scheduler.ImpressionDb.OperationResult" enum="BooleanSuccess" expires_after="2022-12-31"> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records the database operation result (except initialization) of impression database for the notification scheduling system. @@ -840,8 +840,8 @@ <histogram name="Notifications.Scheduler.ImpressionDb.RecordCount" units="records" expires_after="2022-12-31"> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records the number of records of impression database for the notification scheduling system when the impression database is initialized. @@ -850,8 +850,8 @@ <histogram name="Notifications.Scheduler.NotificationDb.InitResult" enum="BooleanSuccess" expires_after="2022-12-31"> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records the initialization result of notification database for the notification scheduling system. @@ -860,8 +860,8 @@ <histogram name="Notifications.Scheduler.NotificationDb.OperationResult" enum="BooleanSuccess" expires_after="2022-12-31"> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records the database operation result (except initialization) of notification database for the notification scheduling system. @@ -870,8 +870,8 @@ <histogram name="Notifications.Scheduler.NotificationDb.RecordCount" units="records" expires_after="2022-12-31"> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records the number of records of notification database for the notification scheduling system when the notification database is initialized. @@ -883,8 +883,8 @@ expires_after="2022-12-31"> <!-- Name completed by histogram_suffixes name="NotificationSchedulerClientType" --> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records life cycle events for a scheduled notification, when notification is scheduled, shown or encountering any error. @@ -893,8 +893,8 @@ <histogram name="Notifications.Scheduler.PngIconConverter.DecodeResult" enum="BooleanSuccess" expires_after="2022-12-31"> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records the result of png icon converter decoding process in icon store for the notification scheduling system. It will be logged typically when @@ -905,8 +905,8 @@ <histogram name="Notifications.Scheduler.PngIconConverter.EncodeResult" enum="BooleanSuccess" expires_after="2022-12-31"> - <owner>xingliu@chromium.org</owner> - <owner>hesen@chromium.org</owner> + <owner>shaktisahu@chromium.org</owner> + <owner>nyquist@chromium.org</owner> <summary> Records the result of png icon converter encoding process in icon store for the notification scheduling system. It will be logged typically when the @@ -919,7 +919,6 @@ enum="NotificationSchedulerUserActionType" expires_after="2022-12-31"> <!-- Name completed by histogram_suffixes name="NotificationSchedulerClientType" --> - <owner>xingliu@chromium.org</owner> <owner>dtrainor@chromium.org</owner> <summary> Records the type of user action when the user interacts with notification
diff --git a/tools/metrics/histograms/metadata/omnibox/histograms.xml b/tools/metrics/histograms/metadata/omnibox/histograms.xml index 5cb95b8e..03afb89 100644 --- a/tools/metrics/histograms/metadata/omnibox/histograms.xml +++ b/tools/metrics/histograms/metadata/omnibox/histograms.xml
@@ -76,6 +76,9 @@ <histogram name="Omnibox.BitmapFetchLatency" units="ms" expires_after="2022-09-11"> + <obsolete> + 3/2022; feature launched. + </obsolete> <!-- Name completed by histogram_suffixes name="Omnibox.BitmapFetchLatencyCacheSplit" --> <owner>manukh@chromium.org</owner> @@ -1123,6 +1126,9 @@ <histogram name="Omnibox.SuggestRequest.Success.PrefetchImagesCount" units="count" expires_after="2022-05-01"> + <obsolete> + 3/2022; feature launched. + </obsolete> <owner>manukh@chromium.org</owner> <owner>jdonnelly@chromium.org</owner> <owner>chrome-omnibox-team@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/optimization/histograms.xml b/tools/metrics/histograms/metadata/optimization/histograms.xml index 14a0eaf..bcfc0cf7 100644 --- a/tools/metrics/histograms/metadata/optimization/histograms.xml +++ b/tools/metrics/histograms/metadata/optimization/histograms.xml
@@ -1113,7 +1113,7 @@ <histogram name="OptimizationGuide.PushNotifications.ReceivedNotificationType" enum="OptimizationType" expires_after="M106"> - <owner>xingliu@chromium.org</owner> + <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> Records the OptimizationType of the push notification. Recorded when the
diff --git a/tools/metrics/histograms/metadata/search/histograms.xml b/tools/metrics/histograms/metadata/search/histograms.xml index 369381a7..23d8a13 100644 --- a/tools/metrics/histograms/metadata/search/histograms.xml +++ b/tools/metrics/histograms/metadata/search/histograms.xml
@@ -1374,7 +1374,7 @@ <histogram name="Search.QueryTiles.ImagePreloadingEvent" enum="QueryTilesImageLoadingEvent" expires_after="2022-04-01"> - <owner>xingliu@chromium.org</owner> + <owner>qinmin@chromium.org</owner> <owner>chrome-upboarding-eng@google.com</owner> <summary> Records the image preloading events when the query tile images are fetched
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 64889fc..4ab3e439 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -5602,8 +5602,7 @@ </event> <event name="Download.Completed"> - <owner>jming@chromium.org</owner> - <owner>xingliu@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <summary> Metrics taken when a download completes. Its parent event is Download.Started. @@ -5634,8 +5633,7 @@ </event> <event name="Download.Interrupted"> - <owner>jming@chromium.org</owner> - <owner>xingliu@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <summary> Metrics taken when a download is interrupted. Its parent event is Download.Started. @@ -5679,8 +5677,7 @@ </event> <event name="Download.Resumed"> - <owner>jming@chromium.org</owner> - <owner>xingliu@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <summary> Metrics taken when a download is resumed. Its parent event is Download.Started. @@ -5705,8 +5702,7 @@ </event> <event name="Download.Started"> - <owner>jming@chromium.org</owner> - <owner>xingliu@chromium.org</owner> + <owner>clank-downloads@google.com</owner> <summary> Metrics taken when a download begins. It has one Download.Ended and none to multiple Download.Interrupted/Download.Resumed events associated with it. @@ -12301,7 +12297,6 @@ <event name="Omnibox.EditUrlSuggestion.Share"> <owner>nyquist@chromium.org</owner> <owner>ssid@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> User pressed 'Share' while viewing edit URL suggestions which shares the current URL. @@ -18885,7 +18880,6 @@ <event name="TopToolbar.Share"> <owner>nyquist@chromium.org</owner> <owner>ssid@chromium.org</owner> - <owner>xingliu@chromium.org</owner> <summary> User pressed the 'Share' in the top toolbar, which shares the current URL. </summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 0d2a4b1c..0d1dc6c1 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,23 +6,23 @@ }, "win": { "hash": "e83825f7eb252fa86e2a07f9f4a2f1b1e980ecee", - "remote_path": "perfetto_binaries/trace_processor_shell/win/a8f0cd2c06fe26eb10b280c3c25db17b5d45519e/trace_processor_shell.exe" + "remote_path": "perfetto_binaries/trace_processor_shell/win/0c2a0d0a169256990c11edeaf23c477693472df4/trace_processor_shell.exe" }, "linux_arm": { "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893", "remote_path": "perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell" }, "mac": { - "hash": "df94dde1ea4a7138d9df81d95a418eed9cb7a95e", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/23ee97c98d29fd98ab4aaedc6cecee966ba80dd9/trace_processor_shell" + "hash": "58ad8635ba37cb2bcef7982fa53084a2a9f74214", + "remote_path": "perfetto_binaries/trace_processor_shell/mac/8eb58df9cb83670f3fd54cc99055f367de18a001/trace_processor_shell" }, "mac_arm64": { "hash": "c0397e87456ad6c6a7aa0133e5b81c97adbab4ab", "remote_path": "perfetto_binaries/trace_processor_shell/mac_arm64/cefb3e0ec3a0580c996f801e854fe02963c03d5c/trace_processor_shell" }, "linux": { - "hash": "55ba8e9a82e96509045055b626380f4a5d1ef87d", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/23ee97c98d29fd98ab4aaedc6cecee966ba80dd9/trace_processor_shell" + "hash": "7e8ec049a560f4aa91c912f2041ebddcfe84c7ae", + "remote_path": "perfetto_binaries/trace_processor_shell/linux/6c4a33cc8d5b0640ce6c86413fa93b99aa7851b4/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/aura/gestures/gesture_recognizer_unittest.cc b/ui/aura/gestures/gesture_recognizer_unittest.cc index 96494b7..8f728b8 100644 --- a/ui/aura/gestures/gesture_recognizer_unittest.cc +++ b/ui/aura/gestures/gesture_recognizer_unittest.cc
@@ -29,6 +29,7 @@ #include "ui/events/event_utils.h" #include "ui/events/gesture_detection/gesture_configuration.h" #include "ui/events/gesture_detection/gesture_provider.h" +#include "ui/events/gestures/gesture_recognizer_impl.h" #include "ui/events/gestures/gesture_types.h" #include "ui/events/test/event_generator.h" #include "ui/events/test/events_test_utils.h" @@ -1748,6 +1749,75 @@ EXPECT_TRUE(delegate->fling()); } +// Verifies that destroying a gesture provider aura instance before a touch +// event is ACKed works as expected (see https://crbug.com/1292264). +TEST_F(GestureRecognizerTest, DestroyGestureProviderAuraBeforeAck) { + TimedEvents tes; + const int kTouchId = 4; + std::unique_ptr<GestureEventConsumeDelegate> delegate( + new GestureEventConsumeDelegate()); + std::unique_ptr<aura::Window> window1(CreateTestWindowWithDelegate( + delegate.get(), /*id=*/-2345, /*bounds=*/gfx::Rect(0, 0, 50, 50), + /*parent=*/root_window())); + + // Touch press then release on `window1`. + constexpr gfx::Point touch_location(/*x=*/10, /*y=*/20); + ui::TouchEvent press( + ui::ET_TOUCH_PRESSED, touch_location, /*time_stamp=*/tes.Now(), + ui::PointerDetails(ui::EventPointerType::kTouch, kTouchId)); + delegate->Reset(); + DispatchEventUsingWindowDispatcher(&press); + EXPECT_TRUE(delegate->tap_down()); + delegate->Reset(); + ui::TouchEvent release( + ui::ET_TOUCH_RELEASED, touch_location, + /*time_stamp=*/press.time_stamp() + base::Milliseconds(50), + ui::PointerDetails(ui::EventPointerType::kTouch, kTouchId)); + DispatchEventUsingWindowDispatcher(&release); + EXPECT_FALSE(delegate->tap_down()); + + // Verify that the gesture provider for `window1` is created. + auto* gesture_recognizer = static_cast<ui::GestureRecognizerImpl*>( + aura::Env::GetInstance()->gesture_recognizer()); + const auto& consumer_provider_mappings = + gesture_recognizer->consumer_gesture_provider_; + EXPECT_NE(consumer_provider_mappings.cend(), + consumer_provider_mappings.find(window1.get())); + + // Create a second window for handling touch events. + std::unique_ptr<QueueTouchEventDelegate> delegate2( + new QueueTouchEventDelegate(host()->dispatcher())); + const int kTouchId2 = 4; + std::unique_ptr<aura::Window> window2(CreateTestWindowWithDelegate( + delegate2.get(), /*id=*/-1234, /*bounds=*/gfx::Rect(100, 100, 500, 500), + root_window())); + delegate2->set_window(window2.get()); + + // Send a press event on `window2`. Verify that the gesture provider for + // `window2` is created. + ui::TouchEvent press2( + ui::ET_TOUCH_PRESSED, /*location=*/gfx::Point(200, 200), + /*time_stamp=*/tes.Now(), + ui::PointerDetails(ui::EventPointerType::kTouch, kTouchId2)); + DispatchEventUsingWindowDispatcher(&press2); + EXPECT_NE(consumer_provider_mappings.cend(), + consumer_provider_mappings.find(window2.get())); + + // Verify that `press2` is associated with a gesture provider raw pointer. + const auto& event_provider_mappings = + gesture_recognizer->event_to_gesture_provider_; + EXPECT_NE(event_provider_mappings.cend(), + event_provider_mappings.find(press2.unique_event_id())); + + // Before ACKing `press2`, replacing the gesture provider of `window2` with a + // new value through event transferal. + aura::Env::GetInstance()->gesture_recognizer()->TransferEventsTo( + window1.get(), window2.get(), ui::TransferTouchesBehavior::kCancel); + + // ACK the press event. + delegate2->ReceivedAck(); +} + TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { std::unique_ptr<QueueTouchEventDelegate> queued_delegate( new QueueTouchEventDelegate(host()->dispatcher()));
diff --git a/ui/base/models/simple_menu_model.cc b/ui/base/models/simple_menu_model.cc index 746dffb1..a787411 100644 --- a/ui/base/models/simple_menu_model.cc +++ b/ui/base/models/simple_menu_model.cc
@@ -469,6 +469,15 @@ if (!delegate_ || command_id == kSeparatorId || command_id == kTitleId) return false; + // This method needs to be recursive, because if the highlighted command is + // in a submenu then the submenu item should also be highlighted. + if (auto* const submenu = GetSubmenuModelAt(index)) { + for (int i = 0; i < submenu->GetItemCount(); ++i) { + if (submenu->IsAlertedAt(i)) + return true; + } + } + return delegate_->IsCommandIdAlerted(command_id); }
diff --git a/ui/base/models/simple_menu_model_unittest.cc b/ui/base/models/simple_menu_model_unittest.cc index 048f7885..6f030477 100644 --- a/ui/base/models/simple_menu_model_unittest.cc +++ b/ui/base/models/simple_menu_model_unittest.cc
@@ -223,6 +223,23 @@ EXPECT_TRUE(simple_menu_model.HasIcons()); } +TEST(SimpleMenuModelTest, InheritsSubMenuAlert) { + DelegateBase delegate; + SimpleMenuModel submenu_model(&delegate); + submenu_model.AddItem(kAlertedCommandId + 1, u"menu item"); + + // The alerted menu item is not present in the submenu. + SimpleMenuModel parent_menu_model(&delegate); + parent_menu_model.AddSubMenu(/*command_id*/ 10, u"submenu", &submenu_model); + EXPECT_FALSE(parent_menu_model.IsAlertedAt(0)); + + // Add the alerted menu item to the submenu. Now both the submenu item and + // the item in the submenu should show as alerted. + submenu_model.AddItem(kAlertedCommandId, u"alerted item"); + EXPECT_TRUE(submenu_model.IsAlertedAt(1)); + EXPECT_TRUE(parent_menu_model.IsAlertedAt(0)); +} + } // namespace } // namespace ui
diff --git a/ui/events/gestures/gesture_provider_aura.cc b/ui/events/gestures/gesture_provider_aura.cc index 0efa5721..943230a 100644 --- a/ui/events/gestures/gesture_provider_aura.cc +++ b/ui/events/gestures/gesture_provider_aura.cc
@@ -39,7 +39,9 @@ kDoubleTapPlatformSupport); } -GestureProviderAura::~GestureProviderAura() {} +GestureProviderAura::~GestureProviderAura() { + client_->OnGestureProviderAuraWillBeDestroyed(this); +} bool GestureProviderAura::OnTouchEvent(TouchEvent* event) { if (!pointer_state_.OnTouch(*event)) @@ -114,4 +116,4 @@ false /* is_source_touch_event_set_blocking */); } -} // namespace content +} // namespace ui
diff --git a/ui/events/gestures/gesture_provider_aura.h b/ui/events/gestures/gesture_provider_aura.h index aa44807..52bebca 100644 --- a/ui/events/gestures/gesture_provider_aura.h +++ b/ui/events/gestures/gesture_provider_aura.h
@@ -27,6 +27,10 @@ virtual ~GestureProviderAuraClient() {} virtual void OnGestureEvent(GestureConsumer* consumer, GestureEvent* event) = 0; + + // Called when `gesture_provider` will be destroyed. + virtual void OnGestureProviderAuraWillBeDestroyed( + GestureProviderAura* gesture_provider) {} }; // Provides gesture detection and dispatch given a sequence of touch events
diff --git a/ui/events/gestures/gesture_recognizer_impl.cc b/ui/events/gestures/gesture_recognizer_impl.cc index a295c346..be062ddc 100644 --- a/ui/events/gestures/gesture_recognizer_impl.cc +++ b/ui/events/gestures/gesture_recognizer_impl.cc
@@ -399,6 +399,18 @@ DispatchGestureEvent(raw_input_consumer, event); } +void GestureRecognizerImpl::OnGestureProviderAuraWillBeDestroyed( + GestureProviderAura* gesture_provider) { + // Clean `event_to_gesture_provider_` by removing invalid raw pointers. + for (auto iter = event_to_gesture_provider_.begin(); + iter != event_to_gesture_provider_.end();) { + if (iter->second == gesture_provider) + iter = event_to_gesture_provider_.erase(iter); + else + ++iter; + } +} + GestureEventHelper* GestureRecognizerImpl::FindDispatchHelperForConsumer( GestureConsumer* consumer) { for (GestureEventHelper* helper : helpers_) {
diff --git a/ui/events/gestures/gesture_recognizer_impl.h b/ui/events/gestures/gesture_recognizer_impl.h index 61d86c1..d03d63889 100644 --- a/ui/events/gestures/gesture_recognizer_impl.h +++ b/ui/events/gestures/gesture_recognizer_impl.h
@@ -18,6 +18,11 @@ #include "ui/events/types/event_type.h" #include "ui/gfx/geometry/point.h" +namespace aura::test { +FORWARD_DECLARE_TEST(GestureRecognizerTest, + DestroyGestureProviderAuraBeforeAck); +} // namespace aura::test + namespace ui { class GestureConsumer; class GestureEvent; @@ -76,6 +81,9 @@ GestureConsumer* consumer) override; private: + FRIEND_TEST_ALL_PREFIXES(aura::test::GestureRecognizerTest, + DestroyGestureProviderAuraBeforeAck); + // Sets up the target consumer for gestures based on the touch-event. void SetupTargets(const TouchEvent& event, GestureConsumer* consumer); @@ -99,6 +107,8 @@ // Overridden from GestureProviderAuraClient void OnGestureEvent(GestureConsumer* raw_input_consumer, GestureEvent* event) override; + void OnGestureProviderAuraWillBeDestroyed( + GestureProviderAura* gesture_provider) override; // Convenience method to find the GestureEventHelper that can dispatch events // to a specific |consumer|.
diff --git a/ui/webui/resources/cr_components/app_management/file_handling_item.html b/ui/webui/resources/cr_components/app_management/file_handling_item.html index 55446f89..72e367c 100644 --- a/ui/webui/resources/cr_components/app_management/file_handling_item.html +++ b/ui/webui/resources/cr_components/app_management/file_handling_item.html
@@ -22,7 +22,8 @@ id="toggle-row" label="[[i18n('appManagementFileHandlingHeader')]]" managed="[[isManaged_(app)]]" - value="[[getValue_(app)]]"> + value="[[getValue_(app)]]" + class="header-text"> </app-management-toggle-row> <p> <localized-link id="type-list"