diff --git a/DEPS b/DEPS index a066c6f6..42fe2c3 100644 --- a/DEPS +++ b/DEPS
@@ -222,11 +222,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '6c2764b93c06f9f1052c2dd438ee90a6078d7225', + 'skia_revision': '49c417621bf80dd5dac67118f81eb63e72519ab8', # 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': 'c698872624bae2861671f8b5573de671c813a8ca', + 'v8_revision': '9137c5db7413639cd1274cb1047c2a7c9ce3a315', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -234,7 +234,7 @@ # 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': '04cb5e1d7d8917fb2bcd6d806afd6263f8c1e573', + 'angle_revision': 'b7cfbac4f8c5f77a1e45064ea9decb6bf654544c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -301,7 +301,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': '8b8c67e57fb6b53670382ab9f6aa413d82005b5b', + 'devtools_frontend_revision': '74835cce21f84484f9e2624e56b5b989c4007923', # 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. @@ -651,7 +651,7 @@ 'packages': [ { 'package': 'chromium/rts/model/linux-amd64', - 'version': 'GTpANs0YNFUNxMMTjDT3vBa-yrDzj0-S3vvytwnEjokC', + 'version': '0Tbib1-PZNdMMhl5wW4fDCC86_oI83GeHrU4cR8MUyQC', }, ], 'dep_type': 'cipd', @@ -662,7 +662,7 @@ 'packages': [ { 'package': 'chromium/rts/model/mac-amd64', - 'version': 'SbuZWuVQVjXuVxrdc7Cs2UypoQp2AxefcyIg4nc3hHYC', + 'version': '15xpSlPwmZptGdsI6WJnlBQ50DWMb54hBq2Emn9xKT0C', }, ], 'dep_type': 'cipd', @@ -673,7 +673,7 @@ 'packages': [ { 'package': 'chromium/rts/model/windows-amd64', - 'version': 'CFDm-IBP2ay-3oZqHxg3Z6-XaIVecx-pEx3bgrQw1SQC', + 'version': 'DlZaWOK4caKpdY19CEAp9ie7XlfCLOlqFsyjABr54Y8C', }, ], 'dep_type': 'cipd', @@ -738,7 +738,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': '_LKV6brUkzjMrW14NMWFjfj_r6ivlu8sDlRiEfRmsO4C', + 'version': 'gzeKboANx6mGXwrAAyzTn8vZ21URSzhIsHXcKEfxIr0C', }, ], 'condition': 'checkout_android', @@ -954,7 +954,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '65b7b24c002d0a5f488459d0ec27baa9ca7bc7f7', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'bb2bbaee0f48a65f562b01bedb0b93ba1a07f7da', 'condition': 'checkout_chromeos', }, @@ -1360,7 +1360,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'd04538362330bd3ae3d534c542fb71ead7b8f28a', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '9d04c12dbe18118cc78c8584508f9eac5ff757f9', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1653,7 +1653,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c3449215be2c0b688da367c3f6b7d5875dd2967d', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@6ff12cf5eca72717dd17002f8f8710a2afc5dafa', 'condition': 'checkout_src_internal', }, @@ -1672,7 +1672,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'KnR77yUi7s3TwENpPmONnzxH6YueZhCzt4qUgIlK3_EC', + 'version': 'N-71TcWQy-V0Y3W_Ha8EH-EdWTHJE7kOos2Hlq0z8C8C', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1683,7 +1683,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': '8OlY1Eg5cnFEdto94hB8UEyg7-I2O6lm7e_AS6CKR9UC', + 'version': 'zYE4hb3r66pj55eKLN8KCScYBEIB4-LivvEUMOr7XG0C', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index 25fbf39..60f5d14 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -705,7 +705,7 @@ # ProductConfig.java is excluded from the generated .jar # (via. jar_excluded_patterns) and the final version is inserted at the APK # level - with the list of pak locales populated by looking at the assets that -# are listed in the final APK's .build_config. +# are listed in the final APK's .build_config.json. android_library("android_webview_product_config_java") { sources = [ "java/src/org/chromium/android_webview/AwLocaleConfig.java" ] srcjar_deps = [ ":webview_product_config" ]
diff --git a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc index ca817b28..16c391a 100644 --- a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc +++ b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc
@@ -77,6 +77,13 @@ auto* metrics_service_client = AwMetricsServiceClient::GetInstance(); DCHECK(metrics_service_client); metrics_service_client->SetShouldRecordPackageName(expiry_date); + + if (expiry_date.has_value()) { + VLOG(2) << "WebView apps package allowlist is loaded, expiry_date =" + << (expiry_date.value() - base::Time::UnixEpoch()).InMilliseconds(); + } else { + VLOG(2) << "Failed to load WebView apps package allowlist"; + } } } // namespace
diff --git a/android_webview/system_webview_bundle.gni b/android_webview/system_webview_bundle.gni index 7edfdcde..ad3abe8 100644 --- a/android_webview/system_webview_bundle.gni +++ b/android_webview/system_webview_bundle.gni
@@ -11,7 +11,7 @@ _base_target_gen_dir = get_label_info(invoker.base_module_target, "target_gen_dir") _base_module_build_config = - "$_base_target_gen_dir/${_base_target_name}.build_config" + "$_base_target_gen_dir/${_base_target_name}.build_config.json" _rebased_base_module_build_config = rebase_path(_base_module_build_config, root_build_dir) _base_module_version_code =
diff --git a/ash/app_list/bubble/app_list_bubble_assistant_page.cc b/ash/app_list/bubble/app_list_bubble_assistant_page.cc index d5851eb..e128c118 100644 --- a/ash/app_list/bubble/app_list_bubble_assistant_page.cc +++ b/ash/app_list/bubble/app_list_bubble_assistant_page.cc
@@ -5,31 +5,43 @@ #include "ash/app_list/bubble/app_list_bubble_assistant_page.h" #include <memory> -#include <utility> +#include "ash/app_list/views/assistant/assistant_dialog_plate.h" +#include "ash/app_list/views/assistant/assistant_main_stage.h" +#include "third_party/skia/include/core/SkColor.h" #include "ui/base/metadata/metadata_impl_macros.h" -#include "ui/views/controls/label.h" +#include "ui/compositor/layer.h" +#include "ui/views/background.h" #include "ui/views/layout/box_layout.h" using views::BoxLayout; namespace ash { -AppListBubbleAssistantPage::AppListBubbleAssistantPage() { - SetLayoutManager( +AppListBubbleAssistantPage::AppListBubbleAssistantPage( + AssistantViewDelegate* delegate) { + auto* layout = SetLayoutManager( std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical)); + layout->set_cross_axis_alignment( + views::BoxLayout::CrossAxisAlignment::kCenter); - // TODO(https://crbug.com/1204551): Sort out whether this view needs its own - // search box, or if it can use the one owned by the parent. The assistant - // page in the tablet launcher owns its own search box, but that may be a side - // effect of animations or the historical need to host assistant in a widget. + // TODO(crbug.com/1216098): Dark background support. The assistant answer + // cards currently assume they are placed within a white container. + SetBackground(views::CreateSolidBackground(SK_ColorWHITE)); - // TODO(https://crbug.com/1204551): Embed the assistant. - AddChildView(std::make_unique<views::Label>(u"Assistant")); + dialog_plate_ = + AddChildView(std::make_unique<AssistantDialogPlate>(delegate)); + main_stage_ = + AddChildView(std::make_unique<AppListAssistantMainStage>(delegate)); + layout->SetFlexForView(main_stage_, 1); } AppListBubbleAssistantPage::~AppListBubbleAssistantPage() = default; +void AppListBubbleAssistantPage::RequestFocus() { + dialog_plate_->RequestFocus(); +} + BEGIN_METADATA(AppListBubbleAssistantPage, views::View) END_METADATA
diff --git a/ash/app_list/bubble/app_list_bubble_assistant_page.h b/ash/app_list/bubble/app_list_bubble_assistant_page.h index ad5cd2fd..fab9255 100644 --- a/ash/app_list/bubble/app_list_bubble_assistant_page.h +++ b/ash/app_list/bubble/app_list_bubble_assistant_page.h
@@ -11,16 +11,31 @@ namespace ash { -// The assistant page for the app list bubble / clamshell launcher. +class AppListAssistantMainStage; +class AssistantDialogPlate; +class AssistantViewDelegate; + +// The assistant page for the app list bubble / clamshell launcher. Similar to +// AssistantMainView in the fullscreen launcher. class ASH_EXPORT AppListBubbleAssistantPage : public views::View { public: METADATA_HEADER(AppListBubbleAssistantPage); - AppListBubbleAssistantPage(); + explicit AppListBubbleAssistantPage(AssistantViewDelegate* delegate); AppListBubbleAssistantPage(const AppListBubbleAssistantPage&) = delete; AppListBubbleAssistantPage& operator=(const AppListBubbleAssistantPage&) = delete; ~AppListBubbleAssistantPage() override; + + // views::View: + void RequestFocus() override; + + private: + // The text and microphone input area. Owned by views hierarchy. + AssistantDialogPlate* dialog_plate_; + + // The query and response output area. Owned by views hierarchy. + AppListAssistantMainStage* main_stage_; }; } // namespace ash
diff --git a/ash/app_list/bubble/app_list_bubble_view.cc b/ash/app_list/bubble/app_list_bubble_view.cc index 4785317..b5e9e5e 100644 --- a/ash/app_list/bubble/app_list_bubble_view.cc +++ b/ash/app_list/bubble/app_list_bubble_view.cc
@@ -24,6 +24,7 @@ #include "ui/base/ui_base_types.h" #include "ui/display/display.h" #include "ui/display/screen.h" +#include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/rect.h" #include "ui/views/bubble/bubble_border.h" #include "ui/views/controls/scroll_view.h" @@ -42,9 +43,6 @@ // least this value plus the shelf height. constexpr int kExtraTopOfScreenSpacing = 16; -// Insets for the bubble contents. -constexpr gfx::Insets kContentMargins(16); - gfx::Rect GetWorkAreaForBubble(aura::Window* root_window) { display::Display display = display::Screen::GetScreen()->GetDisplayNearestWindow(root_window); @@ -109,7 +107,9 @@ // Match the system tray bubble radius. set_corner_radius(kUnifiedTrayCornerRadius); - set_margins(kContentMargins); + + // Remove the default margins so the content fills the bubble. + set_margins(gfx::Insets()); // TODO(https://crbug.com/1218229): Add background blur. See TrayBubbleView // and BubbleBorder. @@ -137,8 +137,8 @@ view_delegate, search_box_view_)); search_page_->SetVisible(false); - assistant_page_ = - AddChildView(std::make_unique<AppListBubbleAssistantPage>()); + assistant_page_ = AddChildView(std::make_unique<AppListBubbleAssistantPage>( + view_delegate->GetAssistantViewDelegate())); assistant_page_->SetVisible(false); } @@ -183,16 +183,26 @@ void AppListBubbleView::QueryChanged(SearchBoxViewBase* sender) { DCHECK_EQ(sender, search_box_view_); // TODO(https://crbug.com/1204551): Animated transitions. - // TODO(https://crbug.com/1204551): Handle assistant view. const bool has_search = search_box_view_->HasSearch(); apps_page_->SetVisible(!has_search); search_page_->SetVisible(has_search); + assistant_page_->SetVisible(false); // Ask the controller to start the search. std::u16string query = view_delegate_->GetSearchModel()->search_box()->text(); view_delegate_->StartSearch(query); } +void AppListBubbleView::AssistantButtonPressed() { + // The assistant has its own text input field. + search_box_view_->SetVisible(false); + + apps_page_->SetVisible(false); + search_page_->SetVisible(false); + assistant_page_->SetVisible(true); + assistant_page_->RequestFocus(); +} + void AppListBubbleView::CloseButtonPressed() { // Activate and focus the search box. search_box_view_->SetSearchBoxActive(true, /*event_type=*/ui::ET_UNKNOWN);
diff --git a/ash/app_list/bubble/app_list_bubble_view.h b/ash/app_list/bubble/app_list_bubble_view.h index 439f8c97..74d42b5 100644 --- a/ash/app_list/bubble/app_list_bubble_view.h +++ b/ash/app_list/bubble/app_list_bubble_view.h
@@ -43,7 +43,7 @@ // SearchBoxViewDelegate: void QueryChanged(SearchBoxViewBase* sender) override; - void AssistantButtonPressed() override {} + void AssistantButtonPressed() override; void BackButtonPressed() override {} void CloseButtonPressed() override; void ActiveChanged(SearchBoxViewBase* sender) override {}
diff --git a/ash/app_list/bubble/app_list_bubble_view_unittest.cc b/ash/app_list/bubble/app_list_bubble_view_unittest.cc index 14c8f34..f8ffa666 100644 --- a/ash/app_list/bubble/app_list_bubble_view_unittest.cc +++ b/ash/app_list/bubble/app_list_bubble_view_unittest.cc
@@ -11,6 +11,7 @@ #include "ash/app_list/app_list_bubble_presenter.h" #include "ash/app_list/app_list_controller_impl.h" #include "ash/app_list/bubble/app_list_bubble_apps_page.h" +#include "ash/app_list/bubble/app_list_bubble_assistant_page.h" #include "ash/app_list/bubble/app_list_bubble_search_page.h" #include "ash/app_list/model/app_list_item.h" #include "ash/app_list/model/search/test_search_result.h" @@ -84,6 +85,15 @@ ->GetWindowBoundsInScreen(); } +// Simulates the Assistant being enabled. +void SimulateAssistantEnabled() { + Shell::Get() + ->app_list_controller() + ->GetSearchModel() + ->search_box() + ->SetShowAssistantButton(true); +} + class AppListBubbleViewTest : public AshTestBase { public: AppListBubbleViewTest() { @@ -117,6 +127,10 @@ return GetAppListTestHelper()->GetBubbleSearchPage(); } + AppListBubbleAssistantPage* GetAssistantPage() { + return GetAppListTestHelper()->GetBubbleAssistantPage(); + } + base::test::ScopedFeatureList scoped_features_; }; @@ -174,13 +188,7 @@ } TEST_F(AppListBubbleViewTest, SearchBoxShowsAssistantButton) { - // Simulate assistant being enabled. - Shell::Get() - ->app_list_controller() - ->GetSearchModel() - ->search_box() - ->SetShowAssistantButton(true); - + SimulateAssistantEnabled(); ShowAppList(); // By default the assistant button is visible. @@ -194,6 +202,19 @@ EXPECT_TRUE(view->close_button()->GetVisible()); } +TEST_F(AppListBubbleViewTest, ClickingAssistantButtonShowsAssistantPage) { + SimulateAssistantEnabled(); + ShowAppList(); + + SearchBoxView* search_box = GetSearchBoxView(); + ClickButton(search_box->assistant_button()); + + EXPECT_FALSE(search_box->GetVisible()); + EXPECT_FALSE(GetAppsPage()->GetVisible()); + EXPECT_FALSE(GetSearchPage()->GetVisible()); + EXPECT_TRUE(GetAssistantPage()->GetVisible()); +} + TEST_F(AppListBubbleViewTest, SearchBoxCloseButton) { ShowAppList(); PressAndReleaseKey(ui::VKEY_A);
diff --git a/ash/app_list/test/app_list_test_helper.cc b/ash/app_list/test/app_list_test_helper.cc index b1bbe4a..cb3cabd 100644 --- a/ash/app_list/test/app_list_test_helper.cc +++ b/ash/app_list/test/app_list_test_helper.cc
@@ -113,4 +113,10 @@ ->search_page_; } +AppListBubbleAssistantPage* AppListTestHelper::GetBubbleAssistantPage() { + return app_list_controller_->bubble_presenter_for_test() + ->bubble_view_for_test() + ->assistant_page_; +} + } // namespace ash
diff --git a/ash/app_list/test/app_list_test_helper.h b/ash/app_list/test/app_list_test_helper.h index ea95209a..689c95d1 100644 --- a/ash/app_list/test/app_list_test_helper.h +++ b/ash/app_list/test/app_list_test_helper.h
@@ -13,6 +13,7 @@ namespace ash { class AppListBubbleAppsPage; +class AppListBubbleAssistantPage; class AppListBubbleSearchPage; class AppListControllerImpl; class AppListView; @@ -76,6 +77,7 @@ RecentAppsView* GetBubbleRecentAppsView(); ScrollableAppsGridView* GetScrollableAppsGridView(); AppListBubbleSearchPage* GetBubbleSearchPage(); + AppListBubbleAssistantPage* GetBubbleAssistantPage(); TestAppListClient* app_list_client() { return app_list_client_.get(); }
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index be80b54..201a888e 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -635,6 +635,9 @@ // Enables or disables the second language settings update. const base::Feature kLanguageSettingsUpdate2{"LanguageSettingsUpdate2", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enables new flow for license packaged devices with enterprise license. +const base::Feature kLicensePackagedOobeFlow{"LicensePackagedOobeFlow", + base::FEATURE_DISABLED_BY_DEFAULT}; // Limits the windows listed in Alt-Tab to the ones in the currently active // desk. @@ -713,6 +716,10 @@ // also making the Nearby Connections WebRTC defaults longer. const base::Feature kNearbyKeepAliveFix{"NearbyKeepAliveFix", base::FEATURE_DISABLED_BY_DEFAULT}; + +// Controls whether new Lockscreen reauth layout is shown or not. +const base::Feature kNewLockScreenReauthLayout{ + "NewLockScreenReauthLayout", base::FEATURE_DISABLED_BY_DEFAULT}; // Controls whether new OOBE layout is shown or not. const base::Feature kNewOobeLayout{"NewOobeLayout", @@ -946,6 +953,11 @@ const base::Feature kSmartLockUIRevamp{"SmartLockUIRevamp", base::FEATURE_DISABLED_BY_DEFAULT}; +// Deprecated. Use kSyncSettingsCategorization and kSyncConsentOptional instead. +// TODO(https://crbug.com/1227417): Remove this after completing the migration. +const base::Feature kSplitSettingsSync{"SplitSettingsSync", + base::FEATURE_DISABLED_BY_DEFAULT}; + // This feature: // - Creates a new "Sync your settings" section in Chrome OS settings // - Moves app, wallpaper and Wi-Fi sync to OS settings @@ -953,13 +965,16 @@ // preferences // - Makes the OS ModelTypes run in sync transport mode, controlled by a single // pref for the entire OS sync feature -// - Updates the OOBE sync consent screen +const base::Feature kSyncSettingsCategorization{ + "SyncSettingsCategorization", base::FEATURE_DISABLED_BY_DEFAULT}; + +// Updates the OOBE sync consent screen // -// NOTE: The feature is rolling out via a client-side Finch trial, so the actual -// state will vary. See config in +// NOTE: The feature will be rolled out via a client-side Finch trial, so the +// actual state will vary. TODO(https://crbug.com/1227417): Migrate config in // chrome/browser/ash/sync/split_settings_sync_field_trial.cc -const base::Feature kSplitSettingsSync{"SplitSettingsSync", - base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSyncConsentOptional{"SyncConsentOptional", + base::FEATURE_DISABLED_BY_DEFAULT}; // Enables battery indicator for styluses in the palette tray const base::Feature kStylusBatteryStatus{"StylusBatteryStatus", @@ -1298,6 +1313,10 @@ kKeyboardBasedDisplayArrangementInSettings); } +bool IsLicensePackagedOobeFlowEnabled() { + return base::FeatureList::IsEnabled(kLicensePackagedOobeFlow); +} + bool IsLockScreenHideSensitiveNotificationsSupported() { return base::FeatureList::IsEnabled( kLockScreenHideSensitiveNotificationsSupport); @@ -1344,6 +1363,10 @@ return base::FeatureList::IsEnabled(kEnableOAuthIpp); } +bool IsNewLockScreenReauthLayoutEnabled() { + return base::FeatureList::IsEnabled(kNewLockScreenReauthLayout); +} + bool IsNewOobeLayoutEnabled() { return base::FeatureList::IsEnabled(kNewOobeLayout); } @@ -1479,6 +1502,14 @@ return base::FeatureList::IsEnabled(kSplitSettingsSync); } +bool IsSyncSettingsCategorizationEnabled() { + return base::FeatureList::IsEnabled(kSyncSettingsCategorization); +} + +bool IsSyncConsentOptionalEnabled() { + return base::FeatureList::IsEnabled(kSyncConsentOptional); +} + bool IsStylusBatteryStatusEnabled() { return base::FeatureList::IsEnabled(kStylusBatteryStatus); }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index a9d3b9f..17dec39 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -239,6 +239,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kLanguageSettingsUpdate2; COMPONENT_EXPORT(ASH_CONSTANTS) +extern const base::Feature kLicensePackagedOobeFlow; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kLimitAltTabToActiveDesk; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kLockScreenHideSensitiveNotificationsSupport; @@ -264,6 +266,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kMojoDBusRelay; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kMultilingualTyping; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kNearbyKeepAliveFix; +COMPONENT_EXPORT(ASH_CONSTANTS) +extern const base::Feature kNewLockScreenReauthLayout; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kNewOobeLayout; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kNightLight; COMPONENT_EXPORT(ASH_CONSTANTS) @@ -461,6 +465,7 @@ bool IsInstantTetheringBackgroundAdvertisingSupported(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsKeyboardBasedDisplayArrangementInSettingsEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsLicensePackagedOobeFlowEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsLockScreenHideSensitiveNotificationsSupported(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsLockScreenInlineReplyEnabled(); @@ -472,6 +477,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsMinorModeRestrictionEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsNearbyKeepAliveFixEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsNetworkingInDiagnosticsAppEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsNewLockScreenReauthLayoutEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsNewOobeLayoutEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsNotificationExpansionAnimationEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) @@ -510,6 +516,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsShimlessRMAFlowEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsShowDateInTrayButtonEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSplitSettingsSyncEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSyncSettingsCategorizationEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSyncConsentOptionalEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsStylusBatteryStatusEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSystemLatinPhysicalTypingEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsTabClusterUIEnabled();
diff --git a/ash/public/cpp/quick_answers/quick_answers_state.cc b/ash/public/cpp/quick_answers/quick_answers_state.cc index 56c4f6a..36a9a16 100644 --- a/ash/public/cpp/quick_answers/quick_answers_state.cc +++ b/ash/public/cpp/quick_answers/quick_answers_state.cc
@@ -23,6 +23,8 @@ using chromeos::quick_answers::prefs::kQuickAnswersConsentStatus; using chromeos::quick_answers::prefs::kQuickAnswersDefinitionEnabled; using chromeos::quick_answers::prefs::kQuickAnswersEnabled; +using chromeos::quick_answers::prefs::kQuickAnswersNoticeImpressionCount; +using chromeos::quick_answers::prefs::kQuickAnswersNoticeImpressionDuration; using chromeos::quick_answers::prefs::kQuickAnswersTranslationEnabled; using chromeos::quick_answers::prefs::kQuickAnswersUnitConverstionEnabled; @@ -56,10 +58,19 @@ } else { // Set the consent status to unknown for new users. prefs->SetInteger(kQuickAnswersConsentStatus, ConsentStatus::kUnknown); + // Reset the impression count and duration for new users. + prefs->SetInteger(kQuickAnswersNoticeImpressionCount, 0); + prefs->SetInteger(kQuickAnswersNoticeImpressionDuration, 0); } } } +void IncrementPrefCounter(PrefService* prefs, + const std::string& path, + int count) { + prefs->SetInteger(path, prefs->GetInteger(path) + count); +} + } // namespace // static @@ -151,6 +162,49 @@ UpdateEligibility(); } +void QuickAnswersState::StartConsent() { + // Increments impression count. + IncrementPrefCounter(pref_change_registrar_->prefs(), + kQuickAnswersNoticeImpressionCount, 1); + + consent_start_time_ = base::TimeTicks::Now(); +} + +void QuickAnswersState::OnConsentResult(ConsentResultType result) { + auto* prefs = pref_change_registrar_->prefs(); + + // Increments impression duration. + DCHECK(!consent_start_time_.is_null()); + auto duration = base::TimeTicks::Now() - consent_start_time_; + IncrementPrefCounter(prefs, kQuickAnswersNoticeImpressionDuration, + duration.InSeconds()); + + switch (result) { + case ConsentResultType::kAllow: + prefs->SetInteger(kQuickAnswersConsentStatus, ConsentStatus::kAccepted); + break; + case ConsentResultType::kNoThanks: + prefs->SetInteger(kQuickAnswersConsentStatus, ConsentStatus::kRejected); + prefs->SetBoolean(kQuickAnswersEnabled, false); + break; + case ConsentResultType::kDismiss: + // If the count or duration cap is reached, set the consented status to + // false; + bool impression_cap_reached = + prefs->GetInteger(kQuickAnswersNoticeImpressionCount) >= + kConsentImpressionCap; + bool duration_cap_reached = + prefs->GetInteger(kQuickAnswersNoticeImpressionDuration) >= + kConsentDurationCap; + if (impression_cap_reached || duration_cap_reached) { + prefs->SetInteger(kQuickAnswersConsentStatus, ConsentStatus::kRejected); + prefs->SetBoolean(kQuickAnswersEnabled, false); + } + } + + consent_start_time_ = base::TimeTicks(); +} + void QuickAnswersState::InitializeObserver( QuickAnswersStateObserver* observer) { if (prefs_initialized_)
diff --git a/ash/public/cpp/quick_answers/quick_answers_state.h b/ash/public/cpp/quick_answers/quick_answers_state.h index 91996b6..eec9bb9 100644 --- a/ash/public/cpp/quick_answers/quick_answers_state.h +++ b/ash/public/cpp/quick_answers/quick_answers_state.h
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/observer_list.h" #include "base/observer_list_types.h" +#include "base/timer/timer.h" #include "chromeos/components/quick_answers/public/cpp/quick_answers_prefs.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -21,6 +22,21 @@ namespace ash { +// The consent will appear up to a total of 3 times. +constexpr int kConsentImpressionCap = 3; +// The consent will appear until viewed for a cumulative 8 seconds. +constexpr int kConsentDurationCap = 8; + +// Consent result of the consent-view. +enum class ConsentResultType { + // When user clicks on the "Allow" button. + kAllow = 0, + // When user clicks on the "No thanks" button. + kNoThanks = 1, + // When user dismisses or ignores the consent-view. + kDismiss = 2 +}; + // A checked observer which receives Quick Answers state change. class ASH_PUBLIC_EXPORT QuickAnswersStateObserver : public base::CheckedObserver { @@ -52,6 +68,9 @@ void OnAssistantContextEnabled(bool enabled) override; void OnLocaleChanged(const std::string& locale) override; + void StartConsent(); + void OnConsentResult(ConsentResultType result); + bool settings_enabled() const { return settings_enabled_; } chromeos::quick_answers::prefs::ConsentStatus consent_status() const { return consent_status_; @@ -101,6 +120,9 @@ // Whether the pref values has been initialized. bool prefs_initialized_ = false; + // Time when the notice is shown. + base::TimeTicks consent_start_time_; + // Observes user profile prefs for the Assistant. std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
diff --git a/ash/quick_answers/quick_answers_controller_impl.cc b/ash/quick_answers/quick_answers_controller_impl.cc index 23bc4bd..68b87a2 100644 --- a/ash/quick_answers/quick_answers_controller_impl.cc +++ b/ash/quick_answers/quick_answers_controller_impl.cc
@@ -129,7 +129,7 @@ void QuickAnswersControllerImpl::DismissQuickAnswers(bool is_active) { visibility_ = QuickAnswersVisibility::kClosed; MaybeDismissQuickAnswersNotice(); - quick_answers_ui_controller_->CloseUserConsentView(); + MaybeDismissQuickAnswersConsent(); bool closed = quick_answers_ui_controller_->CloseQuickAnswersView(); // |quick_answer_| could be null before we receive the result from the server. // Do not send the signal since the quick answer is dismissed before ready. @@ -254,13 +254,8 @@ void QuickAnswersControllerImpl::OnUserConsentResult(bool consented) { quick_answers_ui_controller_->CloseUserConsentView(); - auto* prefs = Shell::Get()->session_controller()->GetPrimaryUserPrefService(); - prefs->SetBoolean( - chromeos::quick_answers::prefs::kQuickAnswersConsentStatus, - consented ? chromeos::quick_answers::prefs::ConsentStatus::kAccepted - : chromeos::quick_answers::prefs::ConsentStatus::kRejected); - prefs->SetBoolean(chromeos::quick_answers::prefs::kQuickAnswersEnabled, - consented); + ash::QuickAnswersState::Get()->OnConsentResult( + consented ? ConsentResultType::kAllow : ConsentResultType::kNoThanks); if (consented) { // Display Quick-Answer for the cached query when user consent has @@ -285,6 +280,12 @@ quick_answers_ui_controller_->CloseUserNoticeView(); } +void QuickAnswersControllerImpl::MaybeDismissQuickAnswersConsent() { + if (quick_answers_ui_controller_->is_showing_user_consent_view()) + ash::QuickAnswersState::Get()->OnConsentResult(ConsentResultType::kDismiss); + quick_answers_ui_controller_->CloseUserConsentView(); +} + bool QuickAnswersControllerImpl::ShouldShowUserNotice() const { return notice_controller_->ShouldShowNotice(); } @@ -307,6 +308,7 @@ if (!quick_answers_ui_controller_->is_showing_user_consent_view()) { quick_answers_ui_controller_->CreateUserConsentView( anchor_bounds_, intent_type, intent_text); + QuickAnswersState::Get()->StartConsent(); } }
diff --git a/ash/quick_answers/quick_answers_controller_impl.h b/ash/quick_answers/quick_answers_controller_impl.h index 2edbae8..2b484721 100644 --- a/ash/quick_answers/quick_answers_controller_impl.h +++ b/ash/quick_answers/quick_answers_controller_impl.h
@@ -104,6 +104,7 @@ private: void MaybeDismissQuickAnswersNotice(); + void MaybeDismissQuickAnswersConsent(); void HandleQuickAnswerRequest( const chromeos::quick_answers::QuickAnswersRequest& request);
diff --git a/ash/webui/diagnostics_ui/backend/network_health_provider.cc b/ash/webui/diagnostics_ui/backend/network_health_provider.cc index 0fdb1de4..01dc6a0 100644 --- a/ash/webui/diagnostics_ui/backend/network_health_provider.cc +++ b/ash/webui/diagnostics_ui/backend/network_health_provider.cc
@@ -18,20 +18,18 @@ namespace { namespace network_mojom = ::chromeos::network_config::mojom; -using network_mojom::ConnectionStateType; -using network_mojom::NetworkType; bool IsSupportedNetworkType(network_mojom::NetworkType type) { switch (type) { - case NetworkType::kWiFi: - case NetworkType::kCellular: - case NetworkType::kEthernet: + case network_mojom::NetworkType::kWiFi: + case network_mojom::NetworkType::kCellular: + case network_mojom::NetworkType::kEthernet: return true; - case NetworkType::kMobile: - case NetworkType::kTether: - case NetworkType::kVPN: - case NetworkType::kAll: - case NetworkType::kWireless: + case network_mojom::NetworkType::kMobile: + case network_mojom::NetworkType::kTether: + case network_mojom::NetworkType::kVPN: + case network_mojom::NetworkType::kAll: + case network_mojom::NetworkType::kWireless: return false; } } @@ -41,40 +39,41 @@ } constexpr mojom::NetworkState ConnectionStateToNetworkState( - ConnectionStateType connection_state) { + network_mojom::ConnectionStateType connection_state) { switch (connection_state) { - case ConnectionStateType::kOnline: + case network_mojom::ConnectionStateType::kOnline: return mojom::NetworkState::kOnline; - case ConnectionStateType::kConnected: + case network_mojom::ConnectionStateType::kConnected: return mojom::NetworkState::kConnected; - case ConnectionStateType::kPortal: + case network_mojom::ConnectionStateType::kPortal: return mojom::NetworkState::kPortal; - case ConnectionStateType::kConnecting: + case network_mojom::ConnectionStateType::kConnecting: return mojom::NetworkState::kConnecting; - case ConnectionStateType::kNotConnected: + case network_mojom::ConnectionStateType::kNotConnected: return mojom::NetworkState::kNotConnected; } } -constexpr mojom::NetworkType GetNetworkType(NetworkType type) { +constexpr mojom::NetworkType ConvertNetworkType( + network_mojom::NetworkType type) { switch (type) { - case NetworkType::kWiFi: + case network_mojom::NetworkType::kWiFi: return mojom::NetworkType::kWiFi; - case NetworkType::kCellular: + case network_mojom::NetworkType::kCellular: return mojom::NetworkType::kCellular; - case NetworkType::kEthernet: + case network_mojom::NetworkType::kEthernet: return mojom::NetworkType::kEthernet; - case NetworkType::kMobile: - case NetworkType::kTether: - case NetworkType::kVPN: - case NetworkType::kAll: - case NetworkType::kWireless: + case network_mojom::NetworkType::kMobile: + case network_mojom::NetworkType::kTether: + case network_mojom::NetworkType::kVPN: + case network_mojom::NetworkType::kAll: + case network_mojom::NetworkType::kWireless: NOTREACHED(); return mojom::NetworkType::kUnsupported; } } -mojom::IPConfigPropertiesPtr GetIPConfigProperties( +mojom::IPConfigPropertiesPtr PopulateIPConfigProperties( network_mojom::IPConfigProperties* ip_config_props) { mojom::IPConfigPropertiesPtr ip_config = mojom::IPConfigProperties::New(); ip_config->ip_address = ip_config_props->ip_address; @@ -84,7 +83,7 @@ return ip_config; } -mojom::WiFiStatePropertiesPtr PopulateNetworkStateProperties( +mojom::WiFiStatePropertiesPtr PopulateWiFiStateProperties( network_mojom::NetworkTypeStateProperties* network_type_props) { auto wifi_props = mojom::WiFiStateProperties::New(); wifi_props->signal_strength = network_type_props->get_wifi()->signal_strength; @@ -108,28 +107,23 @@ // Uses the network type to determine which network properties to // add the mojom::Network struct. -mojom::NetworkTypePropertiesPtr GetNetworkTypeProperties( +mojom::NetworkTypePropertiesPtr PopulateNetworkTypeProperties( network_mojom::NetworkTypeStateProperties* network_type_props, mojom::NetworkType type) { auto type_properties = mojom::NetworkTypeProperties::New(); switch (type) { - case mojom::NetworkType::kWiFi: { + case mojom::NetworkType::kWiFi: type_properties->set_wifi( - PopulateNetworkStateProperties(network_type_props)); + PopulateWiFiStateProperties(network_type_props)); break; - } - case mojom::NetworkType::kEthernet: { - auto ethernet_props = mojom::EthernetStateProperties::New(); + case mojom::NetworkType::kEthernet: type_properties->set_ethernet( PopulateEthernetStateProperties(network_type_props)); break; - } - case mojom::NetworkType::kCellular: { - auto cellular_props = mojom::CellularStateProperties::New(); + case mojom::NetworkType::kCellular: type_properties->set_cellular( PopulateCellularStateProperties(network_type_props)); break; - } case mojom::NetworkType::kUnsupported: NOTREACHED(); break; @@ -144,13 +138,13 @@ network->name = network_props.network_state->name; network->state = ConnectionStateToNetworkState( network_props.network_state->connection_state); - network->type = GetNetworkType(network_props.network_state->type); - network->type_properties = GetNetworkTypeProperties( + network->type = ConvertNetworkType(network_props.network_state->type); + network->type_properties = PopulateNetworkTypeProperties( network_props.network_state->type_state.get(), network->type); - bool has_ip_config = network_props.managed_properties && - network_props.managed_properties->saved_ip_config; + const bool has_ip_config = network_props.managed_properties && + network_props.managed_properties->saved_ip_config; if (has_ip_config) { - network->ip_config = GetIPConfigProperties( + network->ip_config = PopulateIPConfigProperties( network_props.managed_properties->saved_ip_config.get()); }
diff --git a/base/check_op.cc b/base/check_op.cc index 4f887fc..454e044 100644 --- a/base/check_op.cc +++ b/base/check_op.cc
@@ -64,6 +64,10 @@ return strdup("nullptr"); } +char* CheckOpValueStr(const std::string& v) { + return strdup(v.c_str()); +} + char* CheckOpValueStr(double v) { char buf[50]; snprintf(buf, sizeof(buf), "%.6lf", v);
diff --git a/base/check_op.h b/base/check_op.h index 1acfa614..14dd479 100644 --- a/base/check_op.h +++ b/base/check_op.h
@@ -6,6 +6,7 @@ #define BASE_CHECK_OP_H_ #include <cstddef> +#include <string> #include <type_traits> #include "base/check.h" @@ -42,6 +43,7 @@ BASE_EXPORT char* CheckOpValueStr(const void* v); BASE_EXPORT char* CheckOpValueStr(std::nullptr_t v); BASE_EXPORT char* CheckOpValueStr(double v); +BASE_EXPORT char* CheckOpValueStr(const std::string& v); // Convert a streamable value to string out-of-line to avoid <sstream>. BASE_EXPORT char* StreamValToStr(const void* v,
diff --git a/base/process/process_handle_win.cc b/base/process/process_handle_win.cc index ccc7590..e33b8d87 100644 --- a/base/process/process_handle_win.cc +++ b/base/process/process_handle_win.cc
@@ -7,6 +7,8 @@ #include <windows.h> #include <tlhelp32.h> +#include <ostream> + #include "base/win/scoped_handle.h" #include "base/win/windows_version.h"
diff --git a/base/profiler/native_unwinder_mac.cc b/base/profiler/native_unwinder_mac.cc index e644ee7a6..f3ec279f 100644 --- a/base/profiler/native_unwinder_mac.cc +++ b/base/profiler/native_unwinder_mac.cc
@@ -4,6 +4,8 @@ #include "base/profiler/native_unwinder_mac.h" +#include <sys/types.h> // This needs to come before sys/ptrace.h + #include <mach-o/compact_unwind_encoding.h> #include <mach/mach.h> #include <mach/vm_map.h>
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h index 85a63d1..5ceb3a40 100644 --- a/base/strings/string_piece.h +++ b/base/strings/string_piece.h
@@ -25,7 +25,6 @@ #include <iosfwd> #include <limits> -#include <ostream> #include <string> #include <type_traits>
diff --git a/base/strings/utf_string_conversions.cc b/base/strings/utf_string_conversions.cc index 46ca92d..8269b8ef 100644 --- a/base/strings/utf_string_conversions.cc +++ b/base/strings/utf_string_conversions.cc
@@ -7,6 +7,7 @@ #include <limits.h> #include <stdint.h> +#include <ostream> #include <type_traits> #include "base/strings/string_piece.h"
diff --git a/base/trace_event/trace_arguments.cc b/base/trace_event/trace_arguments.cc index 13626351..7dbb3cd 100644 --- a/base/trace_event/trace_arguments.cc +++ b/base/trace_event/trace_arguments.cc
@@ -10,6 +10,7 @@ #include <string.h> #include <cmath> +#include <ostream> #include "base/check_op.h" #include "base/json/string_escape.h"
diff --git a/base/version.cc b/base/version.cc index d084912e..ce791d8 100644 --- a/base/version.cc +++ b/base/version.cc
@@ -7,6 +7,7 @@ #include <stddef.h> #include <algorithm> +#include <ostream> #include "base/check_op.h" #include "base/strings/string_number_conversions.h"
diff --git a/base/win/i18n.cc b/base/win/i18n.cc index 936d7e6..851da4da 100644 --- a/base/win/i18n.cc +++ b/base/win/i18n.cc
@@ -6,6 +6,8 @@ #include <windows.h> +#include <ostream> + #include "base/check_op.h" #include "base/strings/string_piece.h" #include "base/strings/string_split.h"
diff --git a/build/android/adb_logcat_monitor.py b/build/android/adb_logcat_monitor.py index de1573c..a919722 100755 --- a/build/android/adb_logcat_monitor.py +++ b/build/android/adb_logcat_monitor.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be
diff --git a/build/android/adb_logcat_printer.py b/build/android/adb_logcat_printer.py index daa4ddb..a715170 100755 --- a/build/android/adb_logcat_printer.py +++ b/build/android/adb_logcat_printer.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be
diff --git a/build/android/asan_symbolize.py b/build/android/asan_symbolize.py index 60d4d44d..65850898 100755 --- a/build/android/asan_symbolize.py +++ b/build/android/asan_symbolize.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # # Copyright 2013 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be
diff --git a/build/android/diff_resource_sizes.py b/build/android/diff_resource_sizes.py index f9f7b8c..eefb6cd 100755 --- a/build/android/diff_resource_sizes.py +++ b/build/android/diff_resource_sizes.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # Copyright 2017 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/build/android/docs/build_config.md b/build/android/docs/build_config.md index 06a4873c..8f752a66 100644 --- a/build/android/docs/build_config.md +++ b/build/android/docs/build_config.md
@@ -1,19 +1,19 @@ # Introduction -This document describes the `.build_config` files that are used by the +This document describes the `.build_config.json` files that are used by the Chromium build system for Android-specific targets like APK, resources, and more. [TOC] -# I. Overview of .build_config files: +# I. Overview of .build_config.json files: The Android build requires performing computations about dependencies in various targets, which are not possible with the GN build language. To address -this, `.build_config` files are written during the build to store the needed +this, `.build_config.json` files are written during the build to store the needed per-target information as JSON files. -They are always written to `$target_gen_dir/${target_name}.build_config`. +They are always written to `$target_gen_dir/${target_name}.build_config.json`. Many scripts under [`build/android/gyp/`](build/android_gyp/), which are used during the build, can also accept parameter arguments using @@ -25,7 +25,7 @@ return the value at `[key1][key2]...[keyN]` for the `--some-param` option. Apart from that, the scripts do not need to know anything about the structure -of `.build_config` files (but the GN rules that invoke them do and select +of `.build_config.json` files (but the GN rules that invoke them do and select which `@FileArg()` references to use). For a concrete example, consider the following GN fragment: @@ -42,17 +42,17 @@ ``` This will end up generating the following JSON file under -`$CHROMIUM_OUTPUT_DIR/gen/ui/android/ui_java_resources.build_config`: +`$CHROMIUM_OUTPUT_DIR/gen/ui/android/ui_java_resources.build_config.json`: ```json { "deps_info": { "deps_configs": [ - "gen/ui/android/ui_strings_grd.build_config" + "gen/ui/android/ui_strings_grd.build_config.json" ], - "name": "ui_java_resources.build_config", + "name": "ui_java_resources.build_config.json", "package_name": "org.chromium.ui", - "path": "gen/ui/android/ui_java_resources.build_config", + "path": "gen/ui/android/ui_java_resources.build_config.json", "r_text": "gen/ui/android/ui_java_resources_R.txt", "resources_dirs": [ "../../ui/android/java/res" @@ -71,10 +71,10 @@ } ``` -NOTE: All path values in `.build_config` files are relative to your +NOTE: All path values in `.build_config.json` files are relative to your `$CHROMIUM_OUTPUT_DIR`. -# II. Generation of .build_config files: +# II. Generation of .build_config.json files: They are generated by the GN [`write_build_config()`](gn_write_build_config) internal template, which ends up invoking @@ -85,8 +85,8 @@ python ../../build/android/gyp/write_build_config.py \ --type=android_resources \ --depfile gen/ui/android/ui_java_resources__build_config_crbug_908819.d \ - --deps-configs=\[\"gen/ui/android/ui_strings_grd.build_config\"\] \ - --build-config gen/ui/android/ui_java_resources.build_config \ + --deps-configs=\[\"gen/ui/android/ui_strings_grd.build_config.json\"\] \ + --build-config gen/ui/android/ui_java_resources.build_config.json \ --resources-zip resource_zips/ui/android/ui_java_resources.resources.zip \ --package-name org.chromium.ui \ --r-text gen/ui/android/ui_java_resources_R.txt \ @@ -99,10 +99,10 @@ In particular, the `resources['dependency_zips']` entry was computed by inspecting the content of all dependencies (here, only -`ui_string_grd.build_config`), and collecting their +`ui_string_grd.build_config.json`), and collecting their `deps_configs['resources_zip']` values. -Because a target's `.build_config` file will always be generated after +Because a target's `.build_config.json` file will always be generated after that of all of its dependencies, [`write_build_config.py`](write_build_config_py) can traverse the whole (transitive) set of direct *and* indirect dependencies for a given target @@ -112,10 +112,10 @@ and is very powerful for Android builds. -# III. Usage of .build_config files: +# III. Usage of .build_config.json files: In addition to being parsed by `write_build_config.py`, when they are listed -in the `--deps-configs` of a given target, the `.build_config` files are used +in the `--deps-configs` of a given target, the `.build_config.json` files are used by other scripts under [build/android/gyp/] to build stuff. For example, the GN `android_resources` template uses it to invoke the @@ -127,8 +127,8 @@ --depfile gen/ui/android/ui_java_resources_1.d \ --android-sdk-jar ../../third_party/android_sdk/public/platforms/android-29/android.jar \ --aapt-path ../../third_party/android_sdk/public/build-tools/29.0.2/aapt \ - --dependencies-res-zips=@FileArg\(gen/ui/android/ui_java_resources.build_config:resources:dependency_zips\) \ - --extra-res-packages=@FileArg\(gen/ui/android/ui_java_resources.build_config:resources:extra_package_names\) \ + --dependencies-res-zips=@FileArg\(gen/ui/android/ui_java_resources.build_config.json:resources:dependency_zips\) \ + --extra-res-packages=@FileArg\(gen/ui/android/ui_java_resources.build_config.json:resources:extra_package_names\) \ --resource-dirs=\[\"../../ui/android/java/res\"\] \ --debuggable \ --resource-zip-out resource_zips/ui/android/ui_java_resources.resources.zip \ @@ -143,11 +143,11 @@ the information it needs. -# IV. Format of .build_config files: +# IV. Format of .build_config.json files: Thanks to `@FileArg()` references, Python build scripts under [`build/android/gyp/`](build/android/gyp/) do not need to know anything -about the internal format of `.build_config` files. +about the internal format of `.build_config.json` files. This format is decided between internal GN build rules and [`write_build_config.py`][write_build_config_py]. Since these changes rather @@ -155,7 +155,7 @@ can be extracted as a Markdown file and visualized with the following commands: ```sh -# Extract .build_config format documentation +# Extract .build_config.json format documentation build/android/gyp/write_build_config.py \ --generate-markdown-format-doc > /tmp/format.md
diff --git a/build/android/docs/life_of_a_resource.md b/build/android/docs/life_of_a_resource.md index 8b2b8e0..5e46ef6 100644 --- a/build/android/docs/life_of_a_resource.md +++ b/build/android/docs/life_of_a_resource.md
@@ -38,10 +38,10 @@ Inputs: * GN target metadata -* Other `.build_config` files +* Other `.build_config.json` files Outputs: -* Target-specific `.build_config` file +* Target-specific `.build_config.json` file `write_build_config.py` is run to record target metadata needed by future steps. For more details, see [build_config.md](build_config.md). @@ -50,7 +50,7 @@ ### 2. Prepares resources: Inputs: -* Target-specific `.build_config` file +* Target-specific `.build_config.json` file * Files listed as `sources` Outputs: @@ -93,7 +93,7 @@ ### 4. Finalizes apk resources: Inputs: -* Target-specific `.build_config` file +* Target-specific `.build_config.json` file * Dependencies' `R.txt` files * Dependencies' `resources.zip` files
diff --git a/build/android/download_doclava.py b/build/android/download_doclava.py index 059d1cb..1982fdb8 100755 --- a/build/android/download_doclava.py +++ b/build/android/download_doclava.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # Copyright 2016 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.
diff --git a/build/android/gradle/generate_gradle.py b/build/android/gradle/generate_gradle.py index d38c2a6..4a8d6ca 100755 --- a/build/android/gradle/generate_gradle.py +++ b/build/android/gradle/generate_gradle.py
@@ -160,7 +160,7 @@ @classmethod def FromBuildConfigPath(cls, path): prefix = 'gen/' - suffix = '.build_config' + suffix = '.build_config.json' assert path.startswith(prefix) and path.endswith(suffix), path subdir = path[len(prefix):-len(suffix)] gn_target = '//%s:%s' % (os.path.split(subdir)) @@ -195,9 +195,9 @@ return self.GradleSubdir().replace(os.path.sep, '.') def BuildConfig(self): - """Reads and returns the project's .build_config JSON.""" + """Reads and returns the project's .build_config.json JSON.""" if not self._build_config: - path = os.path.join('gen', self.GradleSubdir() + '.build_config') + path = os.path.join('gen', self.GradleSubdir() + '.build_config.json') with open(_RebasePath(path)) as jsonfile: self._build_config = json.load(jsonfile) return self._build_config
diff --git a/build/android/gradle/gn_to_cmake.py b/build/android/gradle/gn_to_cmake.py index 7289825..d3e80ae 100755 --- a/build/android/gradle/gn_to_cmake.py +++ b/build/android/gradle/gn_to_cmake.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # Copyright 2016 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.
diff --git a/build/android/gyp/apkbuilder.py b/build/android/gyp/apkbuilder.py index 262cc834..c355fdf 100755 --- a/build/android/gyp/apkbuilder.py +++ b/build/android/gyp/apkbuilder.py
@@ -341,13 +341,13 @@ depfile_deps += secondary_native_libs if options.java_resources: - # Included via .build_config, so need to write it to depfile. + # Included via .build_config.json, so need to write it to depfile. depfile_deps.extend(options.java_resources) assets = _ExpandPaths(options.assets) uncompressed_assets = _ExpandPaths(options.uncompressed_assets) - # Included via .build_config, so need to write it to depfile. + # Included via .build_config.json, so need to write it to depfile. depfile_deps.extend(x[0] for x in assets) depfile_deps.extend(x[0] for x in uncompressed_assets) depfile_deps.append(options.resource_apk)
diff --git a/build/android/gyp/create_apk_operations_script.py b/build/android/gyp/create_apk_operations_script.py index 82a6e5be..660567f0 100755 --- a/build/android/gyp/create_apk_operations_script.py +++ b/build/android/gyp/create_apk_operations_script.py
@@ -12,7 +12,7 @@ from util import build_utils SCRIPT_TEMPLATE = string.Template("""\ -#!/usr/bin/env python3 +#!/usr/bin/env python # # This file was generated by build/android/gyp/create_apk_operations_script.py
diff --git a/build/android/gyp/create_bundle_wrapper_script.py b/build/android/gyp/create_bundle_wrapper_script.py index 1bdb767..282e206 100755 --- a/build/android/gyp/create_bundle_wrapper_script.py +++ b/build/android/gyp/create_bundle_wrapper_script.py
@@ -13,7 +13,7 @@ from util import build_utils SCRIPT_TEMPLATE = string.Template("""\ -#!/usr/bin/env python3 +#!/usr/bin/env python # # This file was generated by build/android/gyp/create_bundle_wrapper_script.py
diff --git a/build/android/gyp/create_java_binary_script.py b/build/android/gyp/create_java_binary_script.py index 91fe600..5bc9d08 100755 --- a/build/android/gyp/create_java_binary_script.py +++ b/build/android/gyp/create_java_binary_script.py
@@ -21,7 +21,7 @@ # to the directory that the script is written in and then, when run, must # recalculate the paths relative to the current directory. script_template = """\ -#!/usr/bin/env python3 +#!/usr/bin/env python # # This file was generated by build/android/gyp/create_java_binary_script.py
diff --git a/build/android/incremental_install/generate_android_manifest.py b/build/android/incremental_install/generate_android_manifest.py index 8b938a3..e069dab 100755 --- a/build/android/incremental_install/generate_android_manifest.py +++ b/build/android/incremental_install/generate_android_manifest.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # # Copyright 2015 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be
diff --git a/build/android/incremental_install/write_installer_json.py b/build/android/incremental_install/write_installer_json.py index ce88e8a..cf1d2d4 100755 --- a/build/android/incremental_install/write_installer_json.py +++ b/build/android/incremental_install/write_installer_json.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # Copyright 2017 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be
diff --git a/build/android/lighttpd_server.py b/build/android/lighttpd_server.py index e656e860..42fbcdbe6 100755 --- a/build/android/lighttpd_server.py +++ b/build/android/lighttpd_server.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be
diff --git a/build/android/list_java_targets.py b/build/android/list_java_targets.py index 3e486e0..7534f6a 100755 --- a/build/android/list_java_targets.py +++ b/build/android/list_java_targets.py
@@ -104,23 +104,23 @@ @property def build_config_path(self): - """Returns the filepath of the project's .build_config.""" + """Returns the filepath of the project's .build_config.json.""" ninja_target = self.ninja_target # Support targets at the root level. e.g. //:foo if ninja_target[0] == ':': ninja_target = ninja_target[1:] - subpath = ninja_target.replace(':', os.path.sep) + '.build_config' + subpath = ninja_target.replace(':', os.path.sep) + '.build_config.json' return os.path.join(constants.GetOutDirectory(), 'gen', subpath) def build_config(self): - """Reads and returns the project's .build_config JSON.""" + """Reads and returns the project's .build_config.json JSON.""" if not self._build_config: with open(self.build_config_path) as jsonfile: self._build_config = json.load(jsonfile) return self._build_config def get_type(self): - """Returns the target type from its .build_config.""" + """Returns the target type from its .build_config.json.""" return self.build_config()['deps_info']['type'] def proguard_enabled(self): @@ -149,12 +149,13 @@ parser.add_argument('--print-types', action='store_true', help='Print type of each target') - parser.add_argument('--print-build-config-paths', - action='store_true', - help='Print path to the .build_config of each target') + parser.add_argument( + '--print-build-config-paths', + action='store_true', + help='Print path to the .build_config.json of each target') parser.add_argument('--build', action='store_true', - help='Build all .build_config files.') + help='Build all .build_config.json files.') parser.add_argument('--type', action='append', help='Restrict to targets of given type', @@ -184,7 +185,7 @@ entries = [_TargetEntry(t) for t in targets] if args.build: - logging.warning('Building %d .build_config files...', len(entries)) + logging.warning('Building %d .build_config.json files...', len(entries)) _run_ninja(output_dir, [e.ninja_build_config_target for e in entries]) if args.type:
diff --git a/build/android/method_count.py b/build/android/method_count.py index 80d0073..a39a390 100755 --- a/build/android/method_count.py +++ b/build/android/method_count.py
@@ -1,4 +1,4 @@ -#! /usr/bin/env python3 +#! /usr/bin/env python # 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.
diff --git a/build/android/native_flags/argcapture.py b/build/android/native_flags/argcapture.py index b0e2acd9..159b03ab 100755 --- a/build/android/native_flags/argcapture.py +++ b/build/android/native_flags/argcapture.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # 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.
diff --git a/build/android/pylib/dex/dex_parser.py b/build/android/pylib/dex/dex_parser.py index 1ff8d2527..be5f1af 100755 --- a/build/android/pylib/dex/dex_parser.py +++ b/build/android/pylib/dex/dex_parser.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # Copyright 2019 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/build/android/pylib/results/presentation/standard_gtest_merge.py b/build/android/pylib/results/presentation/standard_gtest_merge.py index d458223..64f40e6 100755 --- a/build/android/pylib/results/presentation/standard_gtest_merge.py +++ b/build/android/pylib/results/presentation/standard_gtest_merge.py
@@ -1,4 +1,4 @@ -#! /usr/bin/env python3 +#! /usr/bin/env python # # Copyright 2017 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be
diff --git a/build/android/pylib/results/presentation/test_results_presentation.py b/build/android/pylib/results/presentation/test_results_presentation.py index fc14b8b..2fd98b11 100755 --- a/build/android/pylib/results/presentation/test_results_presentation.py +++ b/build/android/pylib/results/presentation/test_results_presentation.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # # Copyright 2017 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be
diff --git a/build/android/pylib/symbols/apk_lib_dump.py b/build/android/pylib/symbols/apk_lib_dump.py index f40c758..933a0ab 100755 --- a/build/android/pylib/symbols/apk_lib_dump.py +++ b/build/android/pylib/symbols/apk_lib_dump.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # Copyright 2018 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be
diff --git a/build/android/test/nocompile_gn/BUILD.gn b/build/android/test/nocompile_gn/BUILD.gn index e5e2374..933812c 100644 --- a/build/android/test/nocompile_gn/BUILD.gn +++ b/build/android/test/nocompile_gn/BUILD.gn
@@ -31,7 +31,7 @@ deps = [ "${_apk_target}__java" ] build_config_dep = "$_apk_target$build_config_target_suffix" build_config = get_label_info(_apk_target, "target_gen_dir") + "/" + - get_label_info(_apk_target, "name") + ".build_config" + get_label_info(_apk_target, "name") + ".build_config.json" if (enable_android_nocompile_tests) { skip_build_server = true }
diff --git a/build/android/update_deps/update_third_party_deps.py b/build/android/update_deps/update_third_party_deps.py index c03fec5d..3a869c4 100755 --- a/build/android/update_deps/update_third_party_deps.py +++ b/build/android/update_deps/update_third_party_deps.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # Copyright 2016 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.
diff --git a/build/chromeos/test_runner.py b/build/chromeos/test_runner.py index 0e433775..edd30a8 100755 --- a/build/chromeos/test_runner.py +++ b/build/chromeos/test_runner.py
@@ -970,7 +970,7 @@ '-t', action='append', dest='tests', - help='A Tast test to run in the device (eg: "ui.ChromeLogin").') + help='A Tast test to run in the device (eg: "login.Chrome").') tast_test_parser.add_argument( '--gtest_filter', type=str,
diff --git a/build/chromeos/test_runner_test.py b/build/chromeos/test_runner_test.py index 15d1b1f..fc38178 100755 --- a/build/chromeos/test_runner_test.py +++ b/build/chromeos/test_runner_test.py
@@ -19,7 +19,7 @@ import test_runner _TAST_TEST_RESULTS_JSON = { - "name": "ui.ChromeLogin", + "name": "login.Chrome", "errors": None, "start": "2020-01-01T15:41:30.799228462-08:00", "end": "2020-01-01T15:41:53.318914698-08:00", @@ -101,7 +101,7 @@ args = self.get_common_tast_args(False) + [ '--attr-expr=( "group:mainline" && "dep:chrome" && !informational)', - '--gtest_filter=ui.ChromeLogin:ui.WindowControl', + '--gtest_filter=login.Chrome:ui.WindowControl', ] with mock.patch.object(sys, 'argv', args),\ mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen: @@ -111,7 +111,7 @@ # The gtest filter should cause the Tast expr to be replaced with a list # of the tests in the filter. expected_cmd = self.get_common_tast_expectations(False) + [ - '--tast=("name:ui.ChromeLogin" || "name:ui.WindowControl")' + '--tast=("name:login.Chrome" || "name:ui.WindowControl")' ] self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0]) @@ -179,7 +179,7 @@ json.dump(_TAST_TEST_RESULTS_JSON, f) args = self.get_common_tast_args(use_vm) + [ - '-t=ui.ChromeLogin', + '-t=login.Chrome', '--tast-var=key=value', ] with mock.patch.object(sys, 'argv', args),\ @@ -187,7 +187,7 @@ mock_popen.return_value.returncode = 0 test_runner.main() expected_cmd = self.get_common_tast_expectations(use_vm) + [ - '--tast', 'ui.ChromeLogin', '--tast-var', 'key=value' + '--tast', 'login.Chrome', '--tast-var', 'key=value' ] self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0]) @@ -202,7 +202,7 @@ json.dump(_TAST_TEST_RESULTS_JSON, f) args = self.get_common_tast_args(use_vm) + [ - '-t=ui.ChromeLogin', + '-t=login.Chrome', ] with mock.patch.object(sys, 'argv', args),\ mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen: @@ -210,7 +210,7 @@ test_runner.main() expected_cmd = self.get_common_tast_expectations(use_vm) + [ - '--tast', 'ui.ChromeLogin' + '--tast', 'login.Chrome' ] self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0])
diff --git a/build/config/android/config.gni b/build/config/android/config.gni index cbfbba9..898d9e82 100644 --- a/build/config/android/config.gni +++ b/build/config/android/config.gni
@@ -272,10 +272,6 @@ # Use hashed symbol names to reduce JNI symbol overhead. use_hashed_jni_names = !is_java_debug - # Desugar lambdas and interfaces methods using Desugar.jar rather than - # D8/R8. D8/R8 will still be used for backported method desugaring. - enable_bazel_desugar = false - # Enables Java library desugaring. # This will cause an extra classes.dex file to appear in every apk. enable_jdk_library_desugaring = true
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 622f815..8958c5c 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -76,7 +76,7 @@ "//android_webview/glue:glue", ] -# These identify all non-leaf targets that have .build_config files. This is the +# These identify all non-leaf targets that have .build_config.json files. This is the # set of patterns that other targets can use to filter out java targets. java_target_patterns = _java_library_patterns + _java_resource_patterns @@ -138,7 +138,7 @@ # the error message about why non-existent dependencies are there. build_config_target_suffix = "__build_config_crbug_908819" -# Write the target's .build_config file. This is a json file that contains a +# Write the target's .build_config.json file. This is a json file that contains a # dictionary of information about how to build this target (things that # require knowledge about this target's dependencies and cannot be calculated # at gn-time). There is a special syntax to add a value in that dictionary to @@ -206,7 +206,7 @@ deps += [ "$_dep_label$build_config_target_suffix" ] _dep_gen_dir = get_label_info(_possible_dep, "target_gen_dir") _dep_name = get_label_info(_possible_dep, "name") - _dep_config = "$_dep_gen_dir/$_dep_name.build_config" + _dep_config = "$_dep_gen_dir/$_dep_name.build_config.json" _deps_configs += [ _dep_config ] if (defined(invoker.possible_config_public_deps)) { @@ -289,7 +289,7 @@ _dep_gen_dir = get_label_info(_processor_dep, "target_gen_dir") _dep_name = get_label_info(_processor_dep, "name") deps += [ "$_dep_label$build_config_target_suffix" ] - _processor_configs += [ "$_dep_gen_dir/$_dep_name.build_config" ] + _processor_configs += [ "$_dep_gen_dir/$_dep_name.build_config.json" ] } _rebased_processor_configs = rebase_path(_processor_configs, root_build_dir) @@ -331,7 +331,7 @@ get_label_info(invoker.apk_under_test, "target_gen_dir") apk_under_test_name = get_label_info(invoker.apk_under_test, "name") apk_under_test_config = - "$apk_under_test_gen_dir/$apk_under_test_name.build_config" + "$apk_under_test_gen_dir/$apk_under_test_name.build_config.json" args += [ "--tested-apk-config", rebase_path(apk_under_test_config, root_build_dir), @@ -560,8 +560,8 @@ deps += [ "$_dep_label$build_config_target_suffix" ] _dep_gen_dir = get_label_info(_dep_name, "target_gen_dir") _dep_name = get_label_info(_dep_name, "name") - _config = - rebase_path("$_dep_gen_dir/$_dep_name.build_config", root_build_dir) + _config = rebase_path("$_dep_gen_dir/$_dep_name.build_config.json", + root_build_dir) _dependent_configs += [ _config ] } args += [ "--static-library-dependent-configs=$_dependent_configs" ] @@ -582,7 +582,7 @@ _dep_gen_dir = get_label_info(_base_label, "target_gen_dir") _dep_name = get_label_info(_base_label, "name") deps += [ "$_base_label$build_config_target_suffix" ] - _base_module_build_config = "$_dep_gen_dir/$_dep_name.build_config" + _base_module_build_config = "$_dep_gen_dir/$_dep_name.build_config.json" inputs += [ _base_module_build_config ] args += [ "--base-module-build-config", @@ -783,7 +783,7 @@ deps += [ "${invoker.apk_target}$build_config_target_suffix" ] _apk_build_config = get_label_info(invoker.apk_target, "target_gen_dir") + "/" + - get_label_info(invoker.apk_target, "name") + ".build_config" + get_label_info(invoker.apk_target, "name") + ".build_config.json" _rebased_apk_build_config = rebase_path(_apk_build_config, root_build_dir) not_needed([ "_rebased_apk_build_config" ]) } else if (_test_type == "gtest") { @@ -832,7 +832,8 @@ deps += [ "${invoker.apk_under_test}$build_config_target_suffix" ] _apk_under_test_build_config = get_label_info(invoker.apk_under_test, "target_gen_dir") + "/" + - get_label_info(invoker.apk_under_test, "name") + ".build_config" + get_label_info(invoker.apk_under_test, "name") + + ".build_config.json" _rebased_apk_under_test_build_config = rebase_path(_apk_under_test_build_config, root_build_dir) _apk_under_test = "@WrappedPath(@FileArg($_rebased_apk_under_test_build_config:deps_info:incremental_apk_path))" @@ -853,7 +854,7 @@ _build_config = get_label_info(invoker.use_webview_provider, "target_gen_dir") + "/" + get_label_info(invoker.use_webview_provider, "name") + - ".build_config" + ".build_config.json" _rebased_build_config = rebase_path(_build_config, root_build_dir) executable_args += [ "--use-webview-provider", @@ -884,7 +885,7 @@ deps += [ ":${invoker.test_suite}$build_config_target_suffix" ] _junit_binary_build_config = - "${target_gen_dir}/${invoker.test_suite}.build_config" + "${target_gen_dir}/${invoker.test_suite}.build_config.json" _rebased_robolectric_runtime_deps_dir = rebase_path("$root_build_dir/lib.java/third_party/robolectric", @@ -918,8 +919,9 @@ if (defined(invoker.additional_apks)) { foreach(additional_apk, invoker.additional_apks) { deps += [ "$additional_apk$build_config_target_suffix" ] - _build_config = get_label_info(additional_apk, "target_gen_dir") + "/" + - get_label_info(additional_apk, "name") + ".build_config" + _build_config = + get_label_info(additional_apk, "target_gen_dir") + "/" + + get_label_info(additional_apk, "name") + ".build_config.json" _rebased_build_config = rebase_path(_build_config, root_build_dir) executable_args += [ "--additional-apk", @@ -1282,7 +1284,7 @@ _ignore_desugar_missing_deps = defined(invoker.ignore_desugar_missing_deps) && invoker.ignore_desugar_missing_deps - if (!_ignore_desugar_missing_deps && !enable_bazel_desugar) { + if (!_ignore_desugar_missing_deps) { _args += [ "--show-desugar-default-interface-warnings" ] } @@ -1366,7 +1368,7 @@ # # Variables # main_class: The class containing the program entry point. - # build_config: Path to .build_config for the jar (contains classpath). + # build_config: Path to .build_config.json for the jar (contains classpath). # script_name: Name of the script to generate. # wrapper_script_args: List of extra arguments to pass to the executable. # tiered_stop_at_level_one: Whether to pass --tiered-stop-at-level-one @@ -1430,8 +1432,8 @@ !defined(invoker.enable_multidex) || invoker.enable_multidex _enable_main_dex_list = _enable_multidex && _min_sdk_version < 21 _enable_desugar = !defined(invoker.enable_desugar) || invoker.enable_desugar - _use_classic_desugar = (defined(invoker.use_classic_desugar) && - invoker.use_classic_desugar) || enable_bazel_desugar + _use_classic_desugar = + defined(invoker.use_classic_desugar) && invoker.use_classic_desugar _desugar_needs_classpath = _enable_desugar && !_use_classic_desugar # It's not safe to dex merge with libraries dex'ed at higher api versions. @@ -2029,7 +2031,7 @@ # Input variables: # deps: Specifies the input dependencies for this target. # - # build_config: Path to the .build_config file corresponding to the target. + # build_config: Path to the .build_config.json file corresponding to the target. # # sources: # List of input resource files. @@ -2114,9 +2116,9 @@ # # deps: Specifies the input dependencies for this target. # - # build_config: Path to the .build_config file corresponding to the target. + # build_config: Path to the .build_config.json file corresponding to the target. # - # build_config_dep: Dep target to generate the .build_config file. + # build_config_dep: Dep target to generate the .build_config.json file. # # android_manifest: Path to root manifest for the binary. # @@ -2708,7 +2710,7 @@ # Variables # apk_name: (optional) APK name (without .apk suffix). If provided, will # be used to generate .info files later used by the supersize tool. - # assets_build_config: Path to android_apk .build_config containing merged + # assets_build_config: Path to android_apk .build_config.json containing merged # asset information. # deps: Specifies the dependencies of this target. # dex_path: Path to classes.dex file to include (optional). @@ -2937,7 +2939,7 @@ # java_sources_file: Optional path to file containing list of Java source # file paths. This must always be provided if java_files is not empty # and must match it exactly. - # build_config: Path to the .build_config file of the corresponding + # build_config: Path to the .build_config.json file of the corresponding # java_library_impl() target. The following entries will be used by this # template: javac:srcjars, deps_info:javac_full_classpath, # deps_info:javac_full_interface_classpath, javac:processor_classpath, @@ -3118,7 +3120,8 @@ _dep_gen_dir = get_label_info(_errorprone_dep, "target_gen_dir") _dep_name = get_label_info(_errorprone_dep, "name") _rebased_errorprone_buildconfig = - rebase_path("$_dep_gen_dir/$_dep_name.build_config", root_build_dir) + rebase_path("$_dep_gen_dir/$_dep_name.build_config.json", + root_build_dir) args += [ "--processorpath=@FileArg($_rebased_errorprone_buildconfig:deps_info:host_classpath)", "--enable-errorprone", @@ -3418,7 +3421,7 @@ # Define build_config_deps which will be a list of targets required to # build the _build_config. - _build_config = "$target_gen_dir/$_main_target_name.build_config" + _build_config = "$target_gen_dir/$_main_target_name.build_config.json" _build_config_target_name = "${_main_target_name}$build_config_target_suffix" @@ -3454,13 +3457,12 @@ _enable_desugar = !defined(invoker.enable_desugar) || invoker.enable_desugar _use_classic_desugar = - (defined(invoker.use_classic_desugar) && - invoker.use_classic_desugar) || enable_bazel_desugar + defined(invoker.use_classic_desugar) && invoker.use_classic_desugar } # For static libraries, the javac jar output is created at the intermediate # path so that it can be processed by another target and moved to the final - # spot that the .build_config knows about. Technically this should be done + # spot that the .build_config.json knows about. Technically this should be done # for the ijar as well, but this is only used for APK targets where # the ijar path isn't actually used. if (_has_sources) { @@ -4104,7 +4106,7 @@ # by apkbuild.py --format=bundle-module. This means not using # apksigner and zipalign as well, nor the keystore. Other # dependencies like extra native libraries are all pulled from the - # .build_config through @FileArg() references (see below) and + # .build_config.json through @FileArg() references (see below) and # will be listed in the generated depfile instead. _inputs = [ invoker.build_config, @@ -4250,7 +4252,7 @@ # feature_jars_args: Optional list of args to be passed to dexsplitter.py. # If used should include the jars owned by each feature (in the same order # as all_modules). Allows invoker to pull the list of jars from a different -# .build_config than the module's .build_config. +# .build_config.json than the module's .build_config. template("dexsplitter") { action_with_pydeps(target_name) { forward_variables_from(invoker, [ "deps" ])
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 912fde8..3ee387c 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -297,7 +297,7 @@ # about the format of the header file. # # Variables - # targets: List of .build_config supported targets to provide java sources. + # targets: List of .build_config.json supported targets to provide java sources. # header_output: Path to the generated .h file (optional). # sources_exclusions: List of .java files that should be skipped. (optional) # namespace: Registration functions will be wrapped into this. (optional) @@ -341,7 +341,7 @@ _build_config = get_label_info("${_target}($default_toolchain)", "target_gen_dir") + "/" + get_label_info("${_target}($default_toolchain)", "name") + - ".build_config" + ".build_config.json" _rebased_build_config = rebase_path(_build_config, root_build_dir) inputs += [ _build_config ] @@ -788,7 +788,7 @@ # template("android_generated_resources") { forward_variables_from(invoker, [ "testonly" ]) - _build_config = "$target_gen_dir/${target_name}.build_config" + _build_config = "$target_gen_dir/${target_name}.build_config.json" _rtxt_out_path = "$target_gen_dir/${target_name}.R.txt" write_build_config("$target_name$build_config_target_suffix") { forward_variables_from(invoker, [ "resource_overlay" ]) @@ -998,7 +998,7 @@ _resources_zip = "$target_out_dir/$target_name.resources.zip" _r_text_out_path = _base_path + "_R.txt" - _build_config = _base_path + ".build_config" + _build_config = _base_path + ".build_config.json" _build_config_target_name = "$target_name$build_config_target_suffix" _deps = [] @@ -1121,7 +1121,7 @@ template("android_assets") { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) - _build_config = "$target_gen_dir/$target_name.build_config" + _build_config = "$target_gen_dir/$target_name.build_config.json" _build_config_target_name = "$target_name$build_config_target_suffix" write_build_config(_build_config_target_name) { @@ -1183,7 +1183,7 @@ write_build_config("$target_name$build_config_target_suffix") { forward_variables_from(invoker, _build_config_vars) type = "group" - build_config = "$target_gen_dir/${invoker.target_name}.build_config" + build_config = "$target_gen_dir/${invoker.target_name}.build_config.json" supports_android = true if (defined(invoker.deps)) { possible_config_deps = invoker.deps @@ -1298,7 +1298,7 @@ _test_runner_target_name = "${target_name}__test_runner_script" _main_class = "org.chromium.testing.local.JunitTestMain" - _build_config = "$target_gen_dir/$target_name.build_config" + _build_config = "$target_gen_dir/$target_name.build_config.json" _build_config_target_name = "$target_name$build_config_target_suffix" _deps = [ "//testing/android/junit:junit_test_support", @@ -1558,7 +1558,7 @@ if (defined(invoker.override_build_config)) { _build_config = invoker.override_build_config } else { - _build_config = "$target_gen_dir/$target_name.build_config" + _build_config = "$target_gen_dir/$target_name.build_config.json" _build_config_target_name = "$target_name$build_config_target_suffix" write_build_config(_build_config_target_name) { @@ -1648,7 +1648,7 @@ _deps += invoker.deps } - _build_config = "$target_gen_dir/$target_name.build_config" + _build_config = "$target_gen_dir/$target_name.build_config.json" _build_config_target_name = "$target_name$build_config_target_suffix" write_build_config(_build_config_target_name) { @@ -1737,7 +1737,7 @@ _direct_deps_only = defined(invoker.direct_deps_only) && invoker.direct_deps_only - _build_config = "$target_gen_dir/$target_name.build_config" + _build_config = "$target_gen_dir/$target_name.build_config.json" _build_config_target_name = "$target_name$build_config_target_suffix" write_build_config(_build_config_target_name) { @@ -2142,7 +2142,7 @@ forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) assert(defined(invoker.android_manifest)) _base_path = "$target_out_dir/$target_name/$target_name" - _build_config = "$target_gen_dir/$target_name.build_config" + _build_config = "$target_gen_dir/$target_name.build_config.json" _build_config_target = "$target_name$build_config_target_suffix" _min_sdk_version = default_min_sdk_version @@ -2377,7 +2377,7 @@ if (!_incremental_apk) { # Bundle modules don't build the dex here, but need to write this path - # to their .build_config file. + # to their .build_config.json file. if (_proguard_enabled) { _final_dex_path = "$_base_path.r8dex.jar" } else { @@ -2413,7 +2413,7 @@ if (_generate_buildconfig_java && defined(invoker.product_version_resources_dep)) { - # Needs to be added as a .build_config dep to pick up resources. + # Needs to be added as a .build_config.json dep to pick up resources. _deps += [ invoker.product_version_resources_dep ] } @@ -2849,7 +2849,7 @@ uncompress_shared_libraries = _uncompress_shared_libraries if (defined(_allowlist_r_txt_path) && _is_bundle_module) { - # Used to write the file path to the target's .build_config only. + # Used to write the file path to the target's .build_config.json only. base_allowlist_rtxt_path = _allowlist_r_txt_path } } @@ -2921,7 +2921,7 @@ } if (_is_static_library_provider) { - # The list of input jars is already recorded in the .build_config, but + # The list of input jars is already recorded in the .build_config.json, but # we need to explicitly add the java deps here to ensure they're # available to be used as inputs to the dex step. foreach(_dep, invoker.static_library_dependent_targets) { @@ -2962,7 +2962,7 @@ _module_config_target = "${_apk_as_module}$build_config_target_suffix" _module_gen_dir = get_label_info(_apk_as_module, "target_gen_dir") _module_name = get_label_info(_apk_as_module, "name") - _module_config = "$_module_gen_dir/$_module_name.build_config" + _module_config = "$_module_gen_dir/$_module_name.build_config.json" _static_library_modules += [ { name = _module_name @@ -4545,7 +4545,7 @@ _base_target_gen_dir = get_label_info(invoker.base_module_target, "target_gen_dir") _base_module_build_config = - "$_base_target_gen_dir/${_base_target_name}.build_config" + "$_base_target_gen_dir/${_base_target_name}.build_config.json" _base_module_build_config_target = "${invoker.base_module_target}$build_config_target_suffix" _rebased_base_module_build_config = @@ -4604,7 +4604,7 @@ _module_target_gen_dir = get_label_info(_module_target, "target_gen_dir") _module.build_config = - "$_module_target_gen_dir/${_module_target_name}.build_config" + "$_module_target_gen_dir/${_module_target_name}.build_config.json" _module.build_config_target = "$_module_target$build_config_target_suffix" _module.parent = "base" @@ -4630,8 +4630,7 @@ get_label_info(invoker.static_library_provider, "name") _static_library_gen_dir = get_label_info(invoker.static_library_provider, "target_gen_dir") - _lib_proxy_module.build_config = - "$_static_library_gen_dir/$_static_library_target_name.build_config" + _lib_proxy_module.build_config = "$_static_library_gen_dir/$_static_library_target_name.build_config.json" _lib_proxy_module.build_config_target = "${invoker.static_library_provider}$build_config_target_suffix" } @@ -4682,7 +4681,7 @@ deps = [ "${invoker.base_module_target}__compile_resources" ] } - _build_config = "$target_gen_dir/${_target_name}.build_config" + _build_config = "$target_gen_dir/${_target_name}.build_config.json" _rebased_build_config = rebase_path(_build_config, root_build_dir) _build_config_target = "$_target_name$build_config_target_suffix" if (defined(invoker.proguard_android_sdk_dep)) {
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni index 8ce1002b..32e1200 100644 --- a/build/config/compiler/compiler.gni +++ b/build/config/compiler/compiler.gni
@@ -69,7 +69,7 @@ # Chrome's clang. crbug.com/1033839 use_thin_lto = is_cfi || - (is_official_build && + (is_official_build && chrome_pgo_phase != 1 && (is_linux || is_win || (is_android && target_os != "chromeos") || ((is_chromeos_ash || is_chromeos_lacros) && is_chromeos_device))) @@ -196,7 +196,7 @@ # Set to true to use lld, the LLVM linker. # In late bring-up on macOS (see docs/mac_lld.md), and not functional at all for # iOS. The default linker everywhere else. - use_lld = is_clang && (!is_apple || (is_mac && chrome_pgo_phase != 1)) + use_lld = is_clang && (!is_apple || (target_os == "mac" && chrome_pgo_phase != 1)) } declare_args() {
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index a2f380f..8725ceb 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -5.20210712.0.1 +5.20210712.1.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index a2f380f..8725ceb 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -5.20210712.0.1 +5.20210712.1.1
diff --git a/build/toolchain/apple/toolchain.gni b/build/toolchain/apple/toolchain.gni index 9e9c52c..50a968cf 100644 --- a/build/toolchain/apple/toolchain.gni +++ b/build/toolchain/apple/toolchain.gni
@@ -83,11 +83,6 @@ } else { toolchain_cc_wrapper = cc_wrapper } - if (defined(toolchain_args.use_lld)) { - toolchain_uses_lld = toolchain_args.use_lld - } else { - toolchain_uses_lld = use_lld - } if (defined(toolchain_args.use_xcode_clang)) { toolchain_uses_xcode_clang = toolchain_args.use_xcode_clang } else { @@ -124,7 +119,7 @@ # Set the explicit search path for clang++ so it uses the right linker # binary. - if (!toolchain_uses_lld) { + if (!use_lld) { ld += " -B " + invoker.bin_path } @@ -249,7 +244,7 @@ tool("alink") { rspfile = "{{output}}.rsp" - if (!toolchain_uses_lld) { + if (!use_lld) { # Note about -filelist: Apple's linker reads the file list file and # interprets each newline-separated chunk of text as a file name. It # doesn't do the things one would expect from the shell like unescaping
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn index 70274fa..1d0f2a2 100644 --- a/build/toolchain/mac/BUILD.gn +++ b/build/toolchain/mac/BUILD.gn
@@ -21,9 +21,6 @@ current_os = "mac" if (target_os == "ios") { - # Use LLD for the host part of a chrome/ios build. - use_lld = true - # TODO(crbug.com/753445): the use_sanitizer_coverage arg is currently # not supported by the Chromium mac_clang_x64 toolchain on iOS # distribution.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java index 606084c0..dad88fe 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java
@@ -11,6 +11,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.text.TextUtils; @@ -166,7 +167,8 @@ * default handler, this method will return false. */ private boolean hasDefaultHandler(Intent intent) { - ResolveInfo info = PackageManagerUtils.resolveActivity(intent, 0); + ResolveInfo info = + PackageManagerUtils.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); if (info == null) return false; final String chromePackage = mApplicationContext.getPackageName();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java index 5566b82..f000726 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java
@@ -225,7 +225,9 @@ if (mFetchedInfo != null) { buildUpdateRequestAndSchedule(mFetchedInfo, mFetchedPrimaryIconUrl, - mFetchedSplashIconUrl, false /* isManifestStale */, mUpdateReasons); + mFetchedSplashIconUrl, false /* isManifestStale */, + iconOrNameUpdateDialogEnabled() /* appIdentityUpdateSupported */, + mUpdateReasons); return; } @@ -233,7 +235,8 @@ // our Web Manifest data if the server's Web Manifest data is newer. This scenario can // occur if the Web Manifest is temporarily unreachable. buildUpdateRequestAndSchedule(mInfo, "" /* primaryIconUrl */, "" /* splashIconUrl */, - true /* isManifestStale */, mUpdateReasons); + true /* isManifestStale */, + iconOrNameUpdateDialogEnabled() /* appIdentityUpdateSupported */, mUpdateReasons); } /** @@ -245,7 +248,8 @@ /** Builds proto to send to the WebAPK server. */ private void buildUpdateRequestAndSchedule(WebappInfo info, String primaryIconUrl, - String splashIconUrl, boolean isManifestStale, List<Integer> updateReasons) { + String splashIconUrl, boolean isManifestStale, boolean appIdentityUpdateSupported, + List<Integer> updateReasons) { Callback<Boolean> callback = (success) -> { if (!success) { onFinishedUpdate(mStorage, WebApkInstallResult.FAILURE, false /* relaxUpdates*/); @@ -255,7 +259,7 @@ }; String updateRequestPath = mStorage.createAndSetUpdateRequestFilePath(info); storeWebApkUpdateRequestToFile(updateRequestPath, info, primaryIconUrl, splashIconUrl, - isManifestStale, updateReasons, callback); + isManifestStale, appIdentityUpdateSupported, updateReasons, callback); } /** Schedules update for when WebAPK is not running. */ @@ -487,7 +491,8 @@ protected void storeWebApkUpdateRequestToFile(String updateRequestPath, WebappInfo info, String primaryIconUrl, String splashIconUrl, boolean isManifestStale, - List<Integer> updateReasons, Callback<Boolean> callback) { + boolean isAppIdentityUpdateSupported, List<Integer> updateReasons, + Callback<Boolean> callback) { int versionCode = info.webApkVersionCode(); int size = info.iconUrlToMurmur2HashMap().size(); String[] iconUrls = new String[size]; @@ -538,7 +543,8 @@ shareTargetAction, shareTargetParamTitle, shareTargetParamText, shareTargetIsMethodPost, shareTargetIsEncTypeMultipart, shareTargetParamFileNames, shareTargetParamAccepts, shortcuts, info.manifestUrl(), info.webApkPackageName(), - versionCode, isManifestStale, updateReasonsArray, callback); + versionCode, isManifestStale, isAppIdentityUpdateSupported, updateReasonsArray, + callback); } @NativeMethods @@ -553,7 +559,8 @@ boolean shareTargetParamIsMethodPost, boolean shareTargetParamIsEncTypeMultipart, String[] shareTargetParamFileNames, Object[] shareTargetParamAccepts, String[][] shortcuts, String manifestUrl, String webApkPackage, int webApkVersion, - boolean isManifestStale, int[] updateReasons, Callback<Boolean> callback); + boolean isManifestStale, boolean isAppIdentityUpdateSupported, int[] updateReasons, + Callback<Boolean> callback); public void updateWebApkFromFile(String updateRequestPath, WebApkUpdateCallback callback); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/FakeSyncServiceImpl.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/FakeSyncServiceImpl.java index 52ad4cb..008cc7f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/FakeSyncServiceImpl.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/FakeSyncServiceImpl.java
@@ -61,6 +61,7 @@ @Override public boolean isUsingExplicitPassphrase() { + ThreadUtils.assertOnUiThread(); return true; } @@ -81,18 +82,25 @@ @Override public boolean isTrustedVaultKeyRequired() { + ThreadUtils.assertOnUiThread(); return mTrustedVaultKeyRequired; } + @AnyThread public void setTrustedVaultKeyRequired(boolean trustedVaultKeyRequired) { - mTrustedVaultKeyRequired = trustedVaultKeyRequired; + TestThreadUtils.runOnUiThreadBlocking(() -> { + mTrustedVaultKeyRequired = trustedVaultKeyRequired; + syncStateChanged(); + }); } @Override public boolean isTrustedVaultKeyRequiredForPreferredDataTypes() { + ThreadUtils.assertOnUiThread(); return mTrustedVaultKeyRequiredForPreferredDataTypes; } + @AnyThread public void setTrustedVaultKeyRequiredForPreferredDataTypes( boolean trustedVaultKeyRequiredForPreferredDataTypes) { TestThreadUtils.runOnUiThreadBlocking(() -> { @@ -104,9 +112,11 @@ @Override public boolean isTrustedVaultRecoverabilityDegraded() { + ThreadUtils.assertOnUiThread(); return mTrustedVaultRecoverabilityDegraded; } + @AnyThread public void setTrustedVaultRecoverabilityDegraded(boolean recoverabilityDegraded) { TestThreadUtils.runOnUiThreadBlocking(() -> { mTrustedVaultRecoverabilityDegraded = recoverabilityDegraded; @@ -116,16 +126,22 @@ @Override public boolean isEncryptEverythingEnabled() { + ThreadUtils.assertOnUiThread(); return mEncryptEverythingEnabled; } @Override public boolean canSyncFeatureStart() { + ThreadUtils.assertOnUiThread(); return mCanSyncFeatureStart; } + @AnyThread public void setCanSyncFeatureStart(boolean canSyncFeatureStart) { - mCanSyncFeatureStart = canSyncFeatureStart; + TestThreadUtils.runOnUiThreadBlocking(() -> { + mCanSyncFeatureStart = canSyncFeatureStart; + syncStateChanged(); + }); } @Override @@ -142,7 +158,9 @@ }); } + @AnyThread public void setEncryptEverythingEnabled(boolean encryptEverythingEnabled) { - mEncryptEverythingEnabled = encryptEverythingEnabled; + TestThreadUtils.runOnUiThreadBlocking( + () -> { mEncryptEverythingEnabled = encryptEverythingEnabled; }); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java index ede3db8..011d9e4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java
@@ -126,7 +126,8 @@ @Override protected void storeWebApkUpdateRequestToFile(String updateRequestPath, WebappInfo info, String primaryIconUrl, String splashIconUrl, boolean isManifestStale, - List<Integer> updateReasons, Callback<Boolean> callback) { + boolean isAppIdentityUpdateSupported, List<Integer> updateReasons, + Callback<Boolean> callback) { mLastUpdateReasons = updateReasons; }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java index 74820b9..ec7fbab 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java
@@ -146,7 +146,8 @@ boolean shareTargetParamIsMethodPost, boolean shareTargetParamIsEncTypeMultipart, String[] shareTargetParamFileNames, Object[] shareTargetParamAccepts, String[][] shortcuts, String manifestUrl, String webApkPackage, int webApkVersion, - boolean isManifestStale, int[] updateReasons, Callback<Boolean> callback) {} + boolean isManifestStale, boolean isAppIdentityUpdateSupported, int[] updateReasons, + Callback<Boolean> callback) {} @Override public void updateWebApkFromFile( @@ -220,7 +221,8 @@ @Override protected void storeWebApkUpdateRequestToFile(String updateRequestPath, WebappInfo info, String primaryIconUrl, String splashIconUrl, boolean isManifestStale, - List<Integer> updateReasons, Callback<Boolean> callback) { + boolean isAppIdentityUpdateSupported, List<Integer> updateReasons, + Callback<Boolean> callback) { mStoreUpdateRequestCallback = callback; mUpdateName = info.name(); writeRandomTextToFile(updateRequestPath);
diff --git a/chrome/android/trichrome/static_library_shared_java_code.md b/chrome/android/trichrome/static_library_shared_java_code.md index 47e214c..a288902 100644 --- a/chrome/android/trichrome/static_library_shared_java_code.md +++ b/chrome/android/trichrome/static_library_shared_java_code.md
@@ -48,14 +48,14 @@ "deps_info": { ... "static_library_dependent_classpath_configs": { - "gen/android_webview/trichrome_webview_apk.build_config": [ + "gen/android_webview/trichrome_webview_apk.build_config.json": [ "obj/android_webview/trichrome_webview_apk/trichrome_webview_apk.jar", ... ], - "gen/chrome/android/trichrome_chrome_bundle.build_config": [ + "gen/chrome/android/trichrome_chrome_bundle.build_config.json": [ "lib.java/chrome/android/app_hooks_java.jar", ... - "gen/chrome/android/trichrome_library_apk.build_config": [ + "gen/chrome/android/trichrome_library_apk.build_config.json": [ "lib.java/base/base_java.jar", ... ] @@ -68,10 +68,10 @@ TrichromeChromeBundle (base module) and TrichromeWebview do not have a final `dex` or `proguard` step. Instead the library APK creates a "fat" dex from the -`.build_config:deps_info:java_runtime_classpath`. +`.build_config.json:deps_info:java_runtime_classpath`. -Then, the mapping of `.build_config` -> owned input jars stored in the -`.build_config` is used by `dexsplitter` to generate final .dex files for +Then, the mapping of `.build_config.json` -> owned input jars stored in the +`.build_config.json` is used by `dexsplitter` to generate final .dex files for TrichromeLibrary, TrichromeChrome, and TrichromeWebview. ### Resources @@ -97,4 +97,4 @@ * Using the generated wrapper script from the main APK is sufficient (no need to explicitly install the library). * `bin/trichrome_chrome_bundle run` will ensure TrichromeChromeBundle and - TrichromeLibrary are installed before launching Chrome. \ No newline at end of file + TrichromeLibrary are installed before launching Chrome.
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 6f11584..36b55b9 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -2788,6 +2788,9 @@ <message name="IDS_ENTERPRISE_ENROLLMENT_CONSUMER_ACCOUNT_WITH_PACKAGED_LICENSE" desc="Error message to show when the user tries to enroll a device with a packaged license using a consumer account."> Your device includes a Chrome Enterprise Upgrade, but your username is not associated with an enterprise account. Please create an enterprise account by visiting g.co/ChromeEnterpriseAccount on a secondary device. </message> + <message name="IDS_ENTERPRISE_ENROLLMENT_CONSUMER_ACCOUNT_BUSINESS_DOMAIN_WITH_PACKAGED_LICENSE" desc="Error message to show when the user tries to enroll a device with a packaged license using a consumer account with business domain."> + <ph name="DOMAIN">$1<ex>gmail.com</ex></ph> isn't a valid organization. Contact your administator. If you are an administator, you can set up your organization by visiting: g.co/ChromeEnterpriseAccount + </message> <message name="IDS_ENTERPRISE_ENROLLMENT_ENTERPRISE_ACCOUNT_IS_NOT_ELIGIBLE_TO_ENROLL" desc="Error message to show when the user tries to enroll a device with an ineligible enterprise account."> Your username belongs to your organization's enterprise account. To enroll devices to the account, first verify domain ownership in the Admin console. You will need administrative privileges on the account to verify. </message> @@ -2818,6 +2821,9 @@ <message name="IDS_ENTERPRISE_ENROLLMENT_SCREEN_TITLE" desc="The title on the enterprise enrollment dialog."> Enterprise enrollment </message> + <message name="IDS_ENTERPRISE_ACCOUNT_CHECK_TITLE" desc="The title of spinner dialog shown during account check."> + Checking eligibility + </message> <message name="IDS_ENTERPRISE_ENROLLMENT_DEVICE_INFORMATION" desc="The subtitle on the device attribute prompt screen."> Device information </message>
diff --git a/chrome/app/chromeos_strings_grdp/IDS_ENTERPRISE_ACCOUNT_CHECK_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_ENTERPRISE_ACCOUNT_CHECK_TITLE.png.sha1 new file mode 100644 index 0000000..1149da4 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_ENTERPRISE_ACCOUNT_CHECK_TITLE.png.sha1
@@ -0,0 +1 @@ +d5b14552eb26a2db4ba3d5e7bfba47d955f20821 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_ENTERPRISE_ENROLLMENT_CONSUMER_ACCOUNT_BUSINESS_DOMAIN_WITH_PACKAGED_LICENSE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_ENTERPRISE_ENROLLMENT_CONSUMER_ACCOUNT_BUSINESS_DOMAIN_WITH_PACKAGED_LICENSE.png.sha1 new file mode 100644 index 0000000..d25ff482 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_ENTERPRISE_ENROLLMENT_CONSUMER_ACCOUNT_BUSINESS_DOMAIN_WITH_PACKAGED_LICENSE.png.sha1
@@ -0,0 +1 @@ +518bd46108a1dab32aaed77445f097b991a49ebe \ No newline at end of file
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index 0711d03..535ec70 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -745,15 +745,9 @@ <if expr="not chromeos and not is_android"> <!-- Dice Web Signin Interception Bubble--> - <message name="IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V1" desc="Title of the web signin interception bubble"> + <message name="IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE" desc="Title of the web signin interception bubble"> Continue in a new Chromium profile? </message> - <message name="IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V2" desc="Title of the web signin interception bubble"> - Move account to a new Chromium profile? - </message> - <message name="IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V3" desc="Title of the web signin interception bubble"> - Separate Chromium profile? - </message> <message name="IDS_SIGNIN_DICE_WEB_INTERCEPT_SWITCH_BUBBLE_TITLE" desc="Title for the profile switch interception bubble"> Switch to existing Chromium profile? </message>
diff --git a/chrome/app/chromium_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V1.png.sha1 b/chrome/app/chromium_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE.png.sha1 similarity index 100% rename from chrome/app/chromium_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V1.png.sha1 rename to chrome/app/chromium_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE.png.sha1
diff --git a/chrome/app/chromium_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V2.png.sha1 b/chrome/app/chromium_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V2.png.sha1 deleted file mode 100644 index b3b67c6b..0000000 --- a/chrome/app/chromium_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V2.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -e1b3d8f599d8e554b4efa2b85e2289020e17f846 \ No newline at end of file
diff --git a/chrome/app/chromium_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V3.png.sha1 b/chrome/app/chromium_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V3.png.sha1 deleted file mode 100644 index c8de42c..0000000 --- a/chrome/app/chromium_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V3.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -7d40a8bbb90c63280555096b5ddf7c3edda5e105 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_SHARING_INFOBAR_SWITCH_TO_CAPTURED_BUTTON.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_SHARING_INFOBAR_SWITCH_TO_CAPTURED_BUTTON.png.sha1 index b80f93b..e3637306 100644 --- a/chrome/app/generated_resources_grd/IDS_TAB_SHARING_INFOBAR_SWITCH_TO_CAPTURED_BUTTON.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_TAB_SHARING_INFOBAR_SWITCH_TO_CAPTURED_BUTTON.png.sha1
@@ -1 +1 @@ -234cd83c9ed395dbb3fd40b38ee23db32cbeed28 \ No newline at end of file +b7a411a673517b789b5d1f5882f0962caa63546a \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_SHARING_INFOBAR_SWITCH_TO_CAPTURER_BUTTON.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_SHARING_INFOBAR_SWITCH_TO_CAPTURER_BUTTON.png.sha1 index 89e5a6c..287c947 100644 --- a/chrome/app/generated_resources_grd/IDS_TAB_SHARING_INFOBAR_SWITCH_TO_CAPTURER_BUTTON.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_TAB_SHARING_INFOBAR_SWITCH_TO_CAPTURER_BUTTON.png.sha1
@@ -1 +1 @@ -73b15720228b88b5f99bfeb7d1bc1ceebe828b64 \ No newline at end of file +d95746ca266dbd8934dfb363d33c63fcc3734b31 \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index c0b1747..087433e6 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -753,15 +753,9 @@ <if expr="not chromeos and not is_android"> <!-- Dice Web Signin Interception Bubble--> - <message name="IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V1" desc="Title of the web signin interception bubble"> + <message name="IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE" desc="Title of the web signin interception bubble"> Continue in a new Chrome profile? </message> - <message name="IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V2" desc="Title of the web signin interception bubble"> - Move account to a new Chrome profile? - </message> - <message name="IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V3" desc="Title of the web signin interception bubble"> - Separate Chrome profile? - </message> <message name="IDS_SIGNIN_DICE_WEB_INTERCEPT_SWITCH_BUBBLE_TITLE" desc="Title for the profile switch interception bubble"> Switch to existing Chrome profile? </message>
diff --git a/chrome/app/google_chrome_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V1.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE.png.sha1 similarity index 100% rename from chrome/app/google_chrome_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V1.png.sha1 rename to chrome/app/google_chrome_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE.png.sha1
diff --git a/chrome/app/google_chrome_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V2.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V2.png.sha1 deleted file mode 100644 index b3b67c6b..0000000 --- a/chrome/app/google_chrome_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V2.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -e1b3d8f599d8e554b4efa2b85e2289020e17f846 \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V3.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V3.png.sha1 deleted file mode 100644 index c8de42c..0000000 --- a/chrome/app/google_chrome_strings_grd/IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V3.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -7d40a8bbb90c63280555096b5ddf7c3edda5e105 \ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 4312f60..b5e4a4d2 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -6521,13 +6521,6 @@ flag_descriptions::kPermissionQuietChipDescription, kOsDesktop, FEATURE_VALUE_TYPE(permissions::features::kPermissionQuietChip)}, -#if BUILDFLAG(ENABLE_DICE_SUPPORT) - {"dice-web-signin-interception", - flag_descriptions::kDiceWebSigninInterceptionName, - flag_descriptions::kDiceWebSigninInterceptionDescription, - kOsMac | kOsWin | kOsLinux, - FEATURE_VALUE_TYPE(kDiceWebSigninInterceptionFeature)}, -#endif // ENABLE_DICE_SUPPORT {"canvas-2d-layers", flag_descriptions::kCanvas2DLayersName, flag_descriptions::kCanvas2DLayersDescription, kOsAll, SINGLE_VALUE_TYPE(switches::kEnableCanvas2DLayers)},
diff --git a/chrome/browser/android/webapk/webapk_installer.cc b/chrome/browser/android/webapk/webapk_installer.cc index 68de665..0a12b0e9 100644 --- a/chrome/browser/android/webapk/webapk_installer.cc +++ b/chrome/browser/android/webapk/webapk_installer.cc
@@ -187,13 +187,14 @@ std::map<std::string, webapps::WebApkIconHasher::Icon> icon_url_to_murmur2_hash, bool is_manifest_stale, + bool is_app_identity_update_supported, base::OnceCallback<void(std::unique_ptr<std::string>)> callback) { base::PostTaskAndReplyWithResult( GetBackgroundTaskRunner().get(), FROM_HERE, base::BindOnce(&webapps::BuildProtoInBackground, shortcut_info, primary_icon, is_primary_icon_maskable, splash_icon, package_name, version, std::move(icon_url_to_murmur2_hash), - is_manifest_stale, + is_manifest_stale, is_app_identity_update_supported, std::vector<webapps::WebApkUpdateReason>()), std::move(callback)); } @@ -210,6 +211,7 @@ std::map<std::string, webapps::WebApkIconHasher::Icon> icon_url_to_murmur2_hash, bool is_manifest_stale, + bool is_app_identity_update_supported, std::vector<webapps::WebApkUpdateReason> update_reasons, base::OnceCallback<void(bool)> callback) { base::PostTaskAndReplyWithResult( @@ -218,7 +220,8 @@ update_request_path, shortcut_info, primary_icon, is_primary_icon_maskable, splash_icon, package_name, version, std::move(icon_url_to_murmur2_hash), - is_manifest_stale, std::move(update_reasons)), + is_manifest_stale, is_app_identity_update_supported, + std::move(update_reasons)), std::move(callback)); } @@ -453,6 +456,7 @@ is_primary_icon_maskable_, SkBitmap() /* splash_icon */, "" /* package_name */, "" /* version */, std::move(*hashes), false /* is_manifest_stale */, + false /* is_app_identity_update_supported */, base::BindOnce(&WebApkInstaller::SendRequest, weak_ptr_factory_.GetWeakPtr())); }
diff --git a/chrome/browser/android/webapk/webapk_installer.h b/chrome/browser/android/webapk/webapk_installer.h index f279c48..51e77c1b 100644 --- a/chrome/browser/android/webapk/webapk_installer.h +++ b/chrome/browser/android/webapk/webapk_installer.h
@@ -118,6 +118,7 @@ std::map<std::string, webapps::WebApkIconHasher::Icon> icon_url_to_murmur2_hash, bool is_manifest_stale, + bool is_app_identity_update_supported, base::OnceCallback<void(std::unique_ptr<std::string>)> callback); // Builds the WebAPK proto for an update or an install request and stores it @@ -134,6 +135,7 @@ std::map<std::string, webapps::WebApkIconHasher::Icon> icon_url_to_murmur2_hash, bool is_manifest_stale, + bool is_app_identity_update_supported, std::vector<webapps::WebApkUpdateReason> update_reasons, base::OnceCallback<void(bool)> callback);
diff --git a/chrome/browser/android/webapk/webapk_installer_unittest.cc b/chrome/browser/android/webapk/webapk_installer_unittest.cc index b7db4d2..f936297 100644 --- a/chrome/browser/android/webapk/webapk_installer_unittest.cc +++ b/chrome/browser/android/webapk/webapk_installer_unittest.cc
@@ -167,7 +167,7 @@ WebApkInstaller::StoreUpdateRequestToFile( update_request_path, webapps::ShortcutInfo((GURL())), SkBitmap(), false, SkBitmap(), "", "", - std::map<std::string, webapps::WebApkIconHasher::Icon>(), false, + std::map<std::string, webapps::WebApkIconHasher::Icon>(), false, false, {webapps::WebApkUpdateReason::PRIMARY_ICON_HASH_DIFFERS}, base::BindOnce(&UpdateRequestStorer::OnComplete, base::Unretained(this))); @@ -211,6 +211,7 @@ std::map<std::string, webapps::WebApkIconHasher::Icon> icon_url_to_murmur2_hash, bool is_manifest_stale, + bool is_app_identity_update_supported, const std::vector<GURL>& best_shortcut_icon_urls) { webapps::ShortcutInfo info(GURL::EmptyGURL()); info.best_primary_icon_url = best_primary_icon_url; @@ -231,6 +232,7 @@ info, primary_icon, false /* is_primary_icon_maskable */, splash_icon, "" /* package_name */, "" /* version */, std::move(icon_url_to_murmur2_hash), is_manifest_stale, + is_app_identity_update_supported, base::BindOnce(&BuildProtoRunner::OnBuiltWebApkProto, base::Unretained(this))); @@ -538,7 +540,8 @@ std::unique_ptr<BuildProtoRunner> runner = CreateBuildProtoRunner(); runner->BuildSync(GURL(), GURL(), std::move(icon_url_to_murmur2_hash), - true /* is_manifest_stale*/, {}); + true /* is_manifest_stale */, + true /* is_app_identity_update_supported */, {}); webapk::WebApk* webapk_request = runner->GetWebApkRequest(); ASSERT_NE(nullptr, webapk_request); @@ -586,6 +589,7 @@ std::unique_ptr<BuildProtoRunner> runner = CreateBuildProtoRunner(); runner->BuildSync(GURL(best_primary_icon_url), GURL(best_splash_icon_url), icon_url_to_murmur2_hash, false /* is_manifest_stale*/, + false /* is_app_identity_update_supported */, {GURL(best_shortcut_icon_url)}); webapk::WebApk* webapk_request = runner->GetWebApkRequest(); ASSERT_NE(nullptr, webapk_request); @@ -638,6 +642,7 @@ std::unique_ptr<BuildProtoRunner> runner = CreateBuildProtoRunner(); runner->BuildSync(GURL(best_icon_url), GURL(best_icon_url), icon_url_to_murmur2_hash, false /* is_manifest_stale*/, + false /* is_app_identity_update_supported */, {GURL(best_icon_url)}); webapk::WebApk* webapk_request = runner->GetWebApkRequest(); ASSERT_NE(nullptr, webapk_request); @@ -690,6 +695,7 @@ std::unique_ptr<BuildProtoRunner> runner = CreateBuildProtoRunner(); runner->BuildSync( GURL(), GURL(), icon_url_to_murmur2_hash, false /* is_manifest_stale*/, + false /* is_app_identity_update_supported */, {GURL(best_shortcut_icon_url1), GURL(best_shortcut_icon_url2)}); webapk::WebApk* webapk_request = runner->GetWebApkRequest(); ASSERT_NE(nullptr, webapk_request); @@ -724,6 +730,7 @@ std::unique_ptr<BuildProtoRunner> runner = CreateBuildProtoRunner(); runner->BuildSync( GURL(), GURL(), icon_url_to_murmur2_hash, false /* is_manifest_stale*/, + false /* is_app_identity_update_supported */, {GURL(best_shortcut_icon_url), GURL(best_shortcut_icon_url)}); webapk::WebApk* webapk_request = runner->GetWebApkRequest(); ASSERT_NE(nullptr, webapk_request); @@ -758,6 +765,7 @@ std::unique_ptr<BuildProtoRunner> runner = CreateBuildProtoRunner(); runner->BuildSync(GURL(icon_url_1), GURL(best_icon_url), icon_url_to_murmur2_hash, false /* is_manifest_stale*/, + true /* is_app_identity_update_supported */, {GURL(best_icon_url)}); webapk::WebApk* webapk_request = runner->GetWebApkRequest(); ASSERT_NE(nullptr, webapk_request);
diff --git a/chrome/browser/android/webapk/webapk_update_manager.cc b/chrome/browser/android/webapk/webapk_update_manager.cc index fa02bcd..22c39ad 100644 --- a/chrome/browser/android/webapk/webapk_update_manager.cc +++ b/chrome/browser/android/webapk/webapk_update_manager.cc
@@ -80,6 +80,7 @@ const JavaParamRef<jstring>& java_webapk_package, jint java_webapk_version, jboolean java_is_manifest_stale, + jboolean java_is_app_identity_update_supported, const JavaParamRef<jintArray>& java_update_reasons, const JavaParamRef<jobject>& java_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -212,7 +213,7 @@ java_is_primary_icon_maskable, splash_icon, webapk_package, base::NumberToString(java_webapk_version), std::move(icon_url_to_murmur2_hash), java_is_manifest_stale, - std::move(update_reasons), + java_is_app_identity_update_supported, std::move(update_reasons), base::BindOnce(&base::android::RunBooleanCallbackAndroid, ScopedJavaGlobalRef<jobject>(java_callback))); }
diff --git a/chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer.cc b/chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer.cc index 56bb07e..73057f82 100644 --- a/chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer.cc +++ b/chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer.cc
@@ -19,16 +19,14 @@ #include "chrome/browser/net/nss_context.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/net/x509_certificate_model_nss.h" -#include "chrome/services/keymaster/public/mojom/cert_store.mojom.h" #include "crypto/rsa_private_key.h" #include "net/cert/x509_util_nss.h" namespace arc { CertDescription::CertDescription(crypto::RSAPrivateKey* placeholder_key, - CERTCertificate* nss_cert, - keymaster::mojom::ChapsSlot slot) - : placeholder_key(placeholder_key), nss_cert(nss_cert), slot(slot) {} + CERTCertificate* nss_cert) + : placeholder_key(placeholder_key), nss_cert(nss_cert) {} CertDescription::CertDescription(CertDescription&& other) = default;
diff --git a/chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer.h b/chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer.h index 59037c4..7c783575 100644 --- a/chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer.h +++ b/chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer.h
@@ -12,7 +12,6 @@ #include <vector> #include "base/memory/weak_ptr.h" -#include "chrome/services/keymaster/public/mojom/cert_store.mojom.h" #include "components/policy/core/common/remote_commands/remote_command_job.h" #include "components/policy/core/common/remote_commands/remote_commands_queue.h" #include "crypto/rsa_private_key.h" @@ -28,24 +27,17 @@ namespace arc { -// This class is basically a value holder associating metadata relevant to an -// NSS CERTCertificate. struct CertDescription { CertDescription(crypto::RSAPrivateKey* placeholder_key, - CERTCertificate* nss_cert, - keymaster::mojom::ChapsSlot slot); + CERTCertificate* nss_cert); CertDescription(CertDescription&& other); CertDescription(const CertDescription& other) = delete; CertDescription& operator=(CertDescription&& other); CertDescription& operator=(const CertDescription& other) = delete; ~CertDescription(); - // The dummy key to be installed in ARC as a placeholder for |nss_cert|. std::unique_ptr<crypto::RSAPrivateKey> placeholder_key; - // The NSS certificate that corresponds to this object. net::ScopedCERTCertificate nss_cert; - // The chaps slot where this key is stored. - keymaster::mojom::ChapsSlot slot; }; // This class manages the certificates, available to ARC.
diff --git a/chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer_unittest.cc b/chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer_unittest.cc index a2d7bc32..b145f151 100644 --- a/chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer_unittest.cc +++ b/chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer_unittest.cc
@@ -76,8 +76,7 @@ cert = net::x509_util::CreateCERTCertificateFromBytes( reinterpret_cast<const uint8_t*>(der_cert.data()), der_cert.size()); ASSERT_TRUE(cert); - certs->push_back(CertDescription(key.release(), cert.release(), - keymaster::mojom::ChapsSlot::kUser)); + certs->push_back(CertDescription(key.release(), cert.release())); } } // namespace
diff --git a/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service.cc b/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service.cc index f209a5a..963ba0dd 100644 --- a/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service.cc +++ b/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service.cc
@@ -32,8 +32,6 @@ #include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_namespace.h" #include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" #include "crypto/rsa_private_key.h" #include "net/cert/x509_util_nss.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -79,144 +77,6 @@ } }; -// The following series of functions related to ListCerts make use of the -// NSSCertDatabase to fulfill its goal of listing certificates. The cert -// database is accessed through a raw pointer with limited lifetime guarantees -// and is not thread safe. Namely, the cert database is guaranteed valid for the -// single IO thread task where it was received. -// -// Furthermore, creating an NssCertDatabaseGetter requires a BrowserContext, -// which can only be accessed on the UI thread. -// -// ListCerts and related functions are implemented to make sure the above -// requirements are respected. Here's a diagram of the interaction between UI -// and IO threads. -// -// UI Thread IO Thread -// -// ListCerts -// | -// CreateNSSCertDatabaseGetter -// | -// \----------------------------v -// ListCertsWithDbGetterOnIO -// | -// database_getter.Run() -// | -// ListCertsOnIO -// | -// ListCertsInSlot -// | -// PostListedCertsBackToOriginalTaskRunner -// | -// v----------------------------/ -// Process certs / Repeat ListCerts for system slot -// -// ARC requires certs from both the 'user' and 'system' chaps slots to be -// processed. Because ListCertsInSlot is asynchronous, it's not possible to -// guarantee that both ListCertsInSlot calls happen in the same task execution, -// so this entire process is performed twice: first for the user slot, then for -// the system slot. The ordering of the calls is not important, other than the -// implementation lists the 'user' slot first, and uses the 'system' slot to -// signal the process is complete. -// -// The current user may not have access to the system slot, but that is only -// discoverable on the IO thread. In that case, the sequence for the system slot -// becomes: -// -// UI Thread IO Thread -// -// ListCerts -// | -// CreateNSSCertDatabaseGetter -// | -// \----------------------------v -// ListCertsWithDbGetterOnIO -// | -// database_getter.Run() -// | -// ListCertsOnIO -// | -// (Determine system slot isn't allowed) -// | -// PostListedCertsBackToOriginalTaskRunner -// | -// v----------------------------/ -// Process list of certs... - -void PostListedCertsBackToOriginalTaskRunner( - scoped_refptr<base::TaskRunner> original_task_runner, - net::NSSCertDatabase::ListCertsCallback callback, - net::ScopedCERTCertificateList cert_list) { - original_task_runner->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), std::move(cert_list))); -} - -void ListCertsOnIO(scoped_refptr<base::TaskRunner> original_task_runner, - keymaster::mojom::ChapsSlot slot, - net::NSSCertDatabase::ListCertsCallback callback, - net::NSSCertDatabase* database) { - // |database->ListCertsInSlot| must be called from the IO thread. - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - - if (slot == keymaster::mojom::ChapsSlot::kSystem && - !database->GetSystemSlot()) { - // Trying to list system slot when it's not available, return empty list. - PostListedCertsBackToOriginalTaskRunner(original_task_runner, - std::move(callback), - net::ScopedCERTCertificateList()); - return; - } - - // List the certs on |database|, which may dispatch to a worker thread to - // avoid blocking. The actual result needs to make it back to the UI thread, - // but the callback will be invoked on the IO thread, so the results need - // to be forwarded onwards. - database->ListCertsInSlot( - base::BindOnce(&PostListedCertsBackToOriginalTaskRunner, - original_task_runner, std::move(callback)), - slot == keymaster::mojom::ChapsSlot::kUser - ? database->GetPrivateSlot().get() - : database->GetSystemSlot().get()); -} - -void ListCertsWithDbGetterOnIO( - scoped_refptr<base::TaskRunner> original_task_runner, - keymaster::mojom::ChapsSlot slot, - net::NSSCertDatabase::ListCertsCallback callback, - NssCertDatabaseGetter database_getter) { - // |database_getter| must be run from the IO thread. - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - - // Running |database_getter| may either return a non-null pointer - // synchronously or invoke the given callback asynchronously with a non-null - // pointer. |split_callback| is used here to handle both cases. - auto split_callback = base::SplitOnceCallback( - base::BindOnce(&ListCertsOnIO, std::move(original_task_runner), slot, - std::move(callback))); - - net::NSSCertDatabase* database = - std::move(database_getter).Run(std::move(split_callback.first)); - if (database) - std::move(split_callback.second).Run(database); -} - -// Returns the list of certificates in |slot|, making sure to fetch the cert -// database and list certs from the IO thread, while posting |callback| with the -// output list to the original caller thread. -void ListCerts(content::BrowserContext* const context, - keymaster::mojom::ChapsSlot slot, - net::NSSCertDatabase::ListCertsCallback callback) { - // |context| must be accessed on the UI thread. - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - // The NssCertDatabaseGetter must be posted to the IO thread immediately. - content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&ListCertsWithDbGetterOnIO, - base::ThreadTaskRunnerHandle::Get(), slot, - std::move(callback), - CreateNSSCertDatabaseGetter(context))); -} - using IsCertificateAllowedCallback = base::OnceCallback<void(bool allowed)>; void CheckCorporateFlag( @@ -233,18 +93,26 @@ std::move(callback).Run(/* allowed */ corporate_key.value()); } -// Returns true if the certificate is allowed to be used by ARC. The certificate -// is allowed to be used by ARC if its key is marked for corporate usage. |cert| -// must be non-null. -void IsCertificateAllowed(IsCertificateAllowedCallback callback, - scoped_refptr<net::X509Certificate> cert, - content::BrowserContext* const context) { - // |context| must be accessed on the UI thread. - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(cert); +void CheckKeyLocationAndCorporateFlag( + IsCertificateAllowedCallback callback, + const std::string& public_key_spki_der, + content::BrowserContext* const context, + absl::optional<bool> key_on_user_token, + chromeos::platform_keys::Status is_key_on_token_status) { + if (is_key_on_token_status != chromeos::platform_keys::Status::kSuccess) { + LOG(WARNING) << "Error while checking key location: " + << chromeos::platform_keys::StatusToString( + is_key_on_token_status); + std::move(callback).Run(/* allowed */ false); + return; + } - std::string public_key_spki_der = - chromeos::platform_keys::GetSubjectPublicKeyInfo(cert); + DCHECK(key_on_user_token.has_value()); + + if (!key_on_user_token.value_or(false)) { + std::move(callback).Run(/* allowed */ false); + return; + } // Check if the key is marked for corporate usage. chromeos::platform_keys::KeyPermissionsServiceFactory::GetForBrowserContext( @@ -254,11 +122,29 @@ base::BindOnce(&CheckCorporateFlag, std::move(callback))); } -// Appends the given |nss_certs| into |cert_descriptions| along with new -// placeholder keys for each. Certs in |nss_certs| come from the given |slot|. -void PrepareCertDescriptions(net::ScopedCERTCertificateList nss_certs, - keymaster::mojom::ChapsSlot slot, - std::vector<CertDescription>* cert_descriptions) { +// Returns true if the certificate is allowed to be used by ARC. The certificate +// is allowed to be used by ARC if its key is marked for corporate usage and +// resides on a user token. |cert| must be non-null. +void IsCertificateAllowed(IsCertificateAllowedCallback callback, + scoped_refptr<net::X509Certificate> cert, + content::BrowserContext* const context) { + DCHECK(cert); + + const std::string public_key_spki_der = + chromeos::platform_keys::GetSubjectPublicKeyInfo(cert); + + // Check if the key is on the user token. + chromeos::platform_keys::PlatformKeysServiceFactory::GetForBrowserContext( + context) + ->IsKeyOnToken( + chromeos::platform_keys::TokenId::kUser, public_key_spki_der, + base::BindOnce(&CheckKeyLocationAndCorporateFlag, std::move(callback), + public_key_spki_der, context)); +} + +std::vector<CertDescription> PrepareCertDescriptions( + net::ScopedCERTCertificateList nss_certs) { + std::vector<CertDescription> certificates; for (auto& nss_cert : nss_certs) { if (!nss_cert) continue; @@ -266,21 +152,15 @@ auto placeholder_key = crypto::RSAPrivateKey::Create(2048); DCHECK(placeholder_key); - cert_descriptions->emplace_back(placeholder_key.release(), - nss_cert.release(), slot); + certificates.emplace_back(placeholder_key.release(), nss_cert.release()); } + return certificates; } -// Returns the list of Chrome OS keys with the data arc-keymasterd needs to find -// and execute operations on the certs in |cert_descriptions| through chaps. -// Each ChromeOsKey instance contains a ChapsKeyData with its CKA_LABEL, -// CKA_ID, and the slot where it's stored. Note this slot is NOT the PKCS#11 -// CK_SLOT_ID, but a more abstract representation that can be used to find a -// CK_SLOT_ID at runtime. std::vector<keymaster::mojom::ChromeOsKeyPtr> PrepareChromeOsKeys( - const std::vector<CertDescription>& cert_descriptions) { + const std::vector<CertDescription>& certificates) { std::vector<keymaster::mojom::ChromeOsKeyPtr> chrome_os_keys; - for (const auto& certificate : cert_descriptions) { + for (const auto& certificate : certificates) { CERTCertificate* nss_cert = certificate.nss_cert.get(); DCHECK(nss_cert); @@ -305,8 +185,7 @@ // Build a mojo ChromeOsKey and store it in the output vector. keymaster::mojom::ChapsKeyDataPtr key_data = - keymaster::mojom::ChapsKeyData::New(pkcs11_label, pkcs11_id, - certificate.slot); + keymaster::mojom::ChapsKeyData::New(pkcs11_label, pkcs11_id); keymaster::mojom::ChromeOsKeyPtr key = keymaster::mojom::ChromeOsKey::New( ExportSpki(certificate.placeholder_key.get()), keymaster::mojom::KeyData::NewChapsKeyData(std::move(key_data))); @@ -360,11 +239,10 @@ } void CertStoreService::UpdateCertificates() { - ListCerts(context_, keymaster::mojom::ChapsSlot::kUser, - base::BindOnce(&CertStoreService::OnCertificatesListed, - weak_ptr_factory_.GetWeakPtr(), - keymaster::mojom::ChapsSlot::kUser, - std::vector<CertDescription>())); + GetNSSCertDatabaseForProfile( + Profile::FromBrowserContext(context_), + base::BindOnce(&CertStoreService::OnGetNSSCertDatabaseForProfile, + weak_ptr_factory_.GetWeakPtr())); } void CertStoreService::FilterAllowedCertificatesRecursively( @@ -409,9 +287,16 @@ std::move(callback), std::move(cert_queue), std::move(allowed_certs)); } +void CertStoreService::OnGetNSSCertDatabaseForProfile( + net::NSSCertDatabase* database) { + DCHECK(database); + database->ListCertsInSlot( + base::BindOnce(&CertStoreService::OnCertificatesListed, + weak_ptr_factory_.GetWeakPtr()), + database->GetPrivateSlot().get()); +} + void CertStoreService::OnCertificatesListed( - keymaster::mojom::ChapsSlot slot, - std::vector<CertDescription> cert_descriptions, net::ScopedCERTCertificateList cert_list) { base::queue<net::ScopedCERTCertificate> cert_queue; for (auto& cert : cert_list) { @@ -421,14 +306,11 @@ net::ScopedCERTCertificateList allowed_certs; FilterAllowedCertificatesRecursively( base::BindOnce(&CertStoreService::OnFilteredAllowedCertificates, - weak_ptr_factory_.GetWeakPtr(), slot, - std::move(cert_descriptions)), + weak_ptr_factory_.GetWeakPtr()), std::move(cert_queue), std::move(allowed_certs)); } void CertStoreService::OnFilteredAllowedCertificates( - keymaster::mojom::ChapsSlot slot, - std::vector<CertDescription> cert_descriptions, net::ScopedCERTCertificateList allowed_certs) { ArcKeymasterBridge* const keymaster_bridge = ArcKeymasterBridge::GetForBrowserContext(context_); @@ -437,31 +319,15 @@ return; } - PrepareCertDescriptions(std::move(allowed_certs), slot, &cert_descriptions); - - if (slot == keymaster::mojom::ChapsSlot::kUser) { - // Done with the user slot, so try to process additional certs in the - // system slot. If there is no system slot (e.g. the user is not allowed - // to access it), this call won't mutate |cert_descriptions|, and only - // return the user slot certificates. However, it's necessary to perform - // this check asynchronously on the IO thread (through ListCerts), because - // that's the only thread that knows if the system slot is enabled. - ListCerts(context_, keymaster::mojom::ChapsSlot::kSystem, - base::BindOnce(&CertStoreService::OnCertificatesListed, - weak_ptr_factory_.GetWeakPtr(), - keymaster::mojom::ChapsSlot::kSystem, - std::move(cert_descriptions))); - return; - } - // At this point certs have been gathered from all available slots (i.e. user - // slot and potentially system slot if access is allowed to this user), - // proceed to send them to arc-keymaster and ARC. + std::vector<CertDescription> certificates = + PrepareCertDescriptions(std::move(allowed_certs)); std::vector<keymaster::mojom::ChromeOsKeyPtr> keys = - PrepareChromeOsKeys(cert_descriptions); + PrepareChromeOsKeys(certificates); + keymaster_bridge->UpdatePlaceholderKeys( - std::move(keys), base::BindOnce(&CertStoreService::OnUpdatedKeymasterKeys, - weak_ptr_factory_.GetWeakPtr(), - std::move(cert_descriptions))); + std::move(keys), + base::BindOnce(&CertStoreService::OnUpdatedKeymasterKeys, + weak_ptr_factory_.GetWeakPtr(), std::move(certificates))); } void CertStoreService::OnUpdatedKeymasterKeys( @@ -489,11 +355,11 @@ CertStoreService::CertificateCache::~CertificateCache() = default; void CertStoreService::CertificateCache::Update( - const std::vector<CertDescription>& cert_descriptions) { + const std::vector<CertDescription>& certificates) { // Map cert name to real SPKI. key_info_by_name_cache_.clear(); std::set<std::string> new_required_cert_names; - for (const auto& certificate : cert_descriptions) { + for (const auto& certificate : certificates) { CERTCertificate* nss_cert = certificate.nss_cert.get(); DCHECK(nss_cert);
diff --git a/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service.h b/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service.h index 4a5fd6e2..cc6e9bf 100644 --- a/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service.h +++ b/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service.h
@@ -14,7 +14,6 @@ #include "base/containers/queue.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer.h" -#include "chrome/services/keymaster/public/mojom/cert_store.mojom.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "components/keyed_service/core/keyed_service.h" #include "content/public/browser/browser_context.h" @@ -121,14 +120,9 @@ net::ScopedCERTCertificate cert, bool certificate_allowed) const; - void OnCertificatesListed(keymaster::mojom::ChapsSlot slot, - std::vector<CertDescription> certificates, - net::ScopedCERTCertificateList cert_list); - // Processes metadata from |allowed_certs| stored in the given |slot| and - // appends them to |certificates|. + void OnGetNSSCertDatabaseForProfile(net::NSSCertDatabase* database); + void OnCertificatesListed(net::ScopedCERTCertificateList cert_list); void OnFilteredAllowedCertificates( - keymaster::mojom::ChapsSlot slot, - std::vector<CertDescription> certificates, net::ScopedCERTCertificateList allowed_certs); void OnUpdatedKeymasterKeys(std::vector<CertDescription> certificates, bool success);
diff --git a/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service_browsertest.cc b/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service_browsertest.cc index 4dad718..c63bf775 100644 --- a/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service_browsertest.cc +++ b/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service_browsertest.cc
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <algorithm> #include <map> #include <string> #include <vector> @@ -16,8 +15,8 @@ #include "chrome/browser/ash/arc/enterprise/cert_store/cert_store_service.h" #include "chrome/browser/ash/arc/keymaster/arc_keymaster_bridge.h" #include "chrome/browser/ash/arc/session/arc_service_launcher.h" -#include "chrome/browser/ash/policy/affiliation/affiliation_mixin.h" -#include "chrome/browser/ash/policy/affiliation/affiliation_test_helper.h" +#include "chrome/browser/ash/login/test/local_policy_test_server_mixin.h" +#include "chrome/browser/ash/policy/core/user_policy_test_helper.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_service_factory.h" #include "chrome/browser/chromeos/platform_keys/platform_keys_service_factory.h" @@ -38,10 +37,8 @@ #include "components/arc/test/arc_util_test_support.h" #include "components/policy/policy_constants.h" #include "components/prefs/pref_service.h" -#include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/browser_test.h" -#include "content/public/test/test_launcher.h" #include "crypto/scoped_test_system_nss_key_slot.h" #include "extensions/browser/extension_system.h" #include "net/cert/nss_cert_database.h" @@ -54,42 +51,10 @@ namespace { -constexpr char kFileName1[] = "client_1"; -constexpr char kFileName2[] = "client_2"; -constexpr char kFileName3[] = "client_3"; -constexpr char kFileName4[] = "client_4"; - +constexpr char kFakeUserName[] = "test@example.com"; constexpr char kFakeExtensionId[] = "fakeextensionid"; -// Contains information needed for test cert parameters. -struct TestCertData { - TestCertData(const std::string& file_name, - bool is_corporate_usage, - keymaster::mojom::ChapsSlot slot) - : file_name(file_name), - is_corporate_usage(is_corporate_usage), - slot(slot) { - // Keys in system slot must be corporate usage. - DCHECK(slot != keymaster::mojom::ChapsSlot::kSystem || is_corporate_usage); - } - TestCertData(const TestCertData&) = default; - bool operator==(const TestCertData& other) const { - return std::tie(file_name, is_corporate_usage, slot) == - std::tie(other.file_name, other.is_corporate_usage, other.slot); - } - - std::string file_name; - bool is_corporate_usage; - keymaster::mojom::ChapsSlot slot; -}; - -// Associates a |test_data| to its |nss_cert| once installed. -struct InstalledTestCert { - InstalledTestCert(TestCertData test_data, net::ScopedCERTCertificate nss_cert) - : test_data(test_data), nss_cert(std::move(nss_cert)) {} - TestCertData test_data; - net::ScopedCERTCertificate nss_cert; -}; +const std::vector<std::string> kCertFiles = {"client_1", "client_2"}; std::string GetDerCert64(CERTCertificate* cert) { std::string der_cert; @@ -175,536 +140,353 @@ return std::make_unique<CertStoreService>(profile, std::move(installer)); } -// The following series of functions related to IsSystemSlotAvailable use the -// NSSCertDatabase. The cert database is accessed through a raw pointer with -// limited lifetime guarantees and is not thread safe. Namely, the cert database -// is guaranteed valid for the single IO thread task where it was received. -// -// Furthermore, creating an NssCertDatabaseGetter requires a BrowserContext, -// which can only be accessed on the UI thread. -// -// ListCerts and related functions are implemented to make sure the above -// requirements are respected. Here's a diagram of the interaction between UI -// and IO threads. -// -// UI Thread IO Thread -// -// IsSystemSlotAvailable -// | -// run_loop.QuitClosure -// | -// CreateNSSCertDatabaseGetter -// | -// \--------------------------------v -// IsSystemSlotAvailableWithDbGetterOnIO -// | -// database_getter.Run -// | -// IsSystemSlotAvailableOnIO -// | -// GetSystemSlot -// | -// quit_closure.Run - -void IsSystemSlotAvailableOnIO(bool* out_system_slot_available, - base::OnceClosure done_closure, - net::NSSCertDatabase* cert_db) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - *out_system_slot_available = cert_db->GetSystemSlot() != nullptr; - std::move(done_closure).Run(); -} - -void IsSystemSlotAvailableWithDbGetterOnIO( - NssCertDatabaseGetter database_getter, - bool* out_system_slot_available, - base::OnceClosure done_closure) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - auto did_get_cert_db_split_callback = base::SplitOnceCallback( - base::BindOnce(&IsSystemSlotAvailableOnIO, out_system_slot_available, - std::move(done_closure))); - net::NSSCertDatabase* cert_db = - std::move(database_getter) - .Run(std::move(did_get_cert_db_split_callback.first)); - if (cert_db) { - std::move(did_get_cert_db_split_callback.second).Run(cert_db); - } -} - -// Returns trus if the test system slot was setup correctly and is available. -bool IsSystemSlotAvailable(Profile* profile) { - // |profile| must be accessed on the UI thread. - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - base::RunLoop run_loop; - bool system_slot_available = false; - // The NssCertDatabaseGetter must be posted to the IO thread immediately. - content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce(IsSystemSlotAvailableWithDbGetterOnIO, - CreateNSSCertDatabaseGetter(profile), - &system_slot_available, run_loop.QuitClosure())); - run_loop.Run(); - return system_slot_available; -} - -// Returns the number of corporate usage certs in |test_certs|. -size_t CountCorporateUsage(const std::vector<TestCertData>& test_certs) { - return std::count_if(test_certs.begin(), test_certs.end(), - [](const TestCertData& test_data) { - return test_data.is_corporate_usage; - }); -} - -// Deletes the given |cert| from |cert_db|. -void DeleteCertAndKey(CERTCertificate* cert, - base::OnceClosure done_callback, - net::NSSCertDatabase* cert_db) { - base::ScopedAllowBlockingForTesting allow_io; - EXPECT_TRUE(cert_db->DeleteCertAndKey(cert)); - std::move(done_callback).Run(); -} - -// Called once a key has been registered as corporate usage. -void OnKeyRegisteredForCorporateUsage(base::OnceClosure done_callback, - bool is_error, - crosapi::mojom::KeystoreError error) { - ASSERT_FALSE(is_error) << static_cast<int>(error); - std::move(done_callback).Run(); -} - -// Uses |service| to register |cert| as corporate usage. -void RegisterCorporateKeyWithService( - CERTCertificate* cert, - base::OnceClosure done_callback, - std::unique_ptr<chromeos::platform_keys::ExtensionKeyPermissionsService> - service) { - std::string client_cert_spki( - cert->derPublicKey.data, - cert->derPublicKey.data + cert->derPublicKey.len); - service->RegisterKeyForCorporateUsage( - client_cert_spki, base::BindOnce(&OnKeyRegisteredForCorporateUsage, - std::move(done_callback))); -} - } // namespace -class CertStoreServiceTest - : public MixinBasedInProcessBrowserTest, - public ::testing::WithParamInterface<std::vector<TestCertData>> { - public: - CertStoreServiceTest() = default; - CertStoreServiceTest(const CertStoreServiceTest& other) = delete; - CertStoreServiceTest& operator=(const CertStoreServiceTest&) = delete; - +class CertStoreServiceTest : public MixinBasedInProcessBrowserTest { protected: - void SetUpCommandLine(base::CommandLine* command_line) override; + // MixinBasedInProcessBrowserTest: + void SetUpCommandLine(base::CommandLine* command_line) override { + MixinBasedInProcessBrowserTest::SetUpCommandLine(command_line); - void SetUpInProcessBrowserTestFixture() override; + arc::SetArcAvailableCommandLineForTesting(command_line); - void SetUpOnMainThread() override; + policy_helper_ = std::make_unique<policy::UserPolicyTestHelper>( + kFakeUserName, &local_policy_server_); + policy_helper_->SetPolicy( + base::DictionaryValue() /* empty mandatory policy */, + base::DictionaryValue() /* empty recommended policy */); - void TearDownOnMainThread() override; + command_line->AppendSwitchASCII(chromeos::switches::kLoginUser, + kFakeUserName); + command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, + TestingProfile::kTestUserProfileDir); + // Don't require policy for our sessions - this is required because + // this test creates a secondary profile synchronously, so we need to + // let the policy code know not to expect cached policy. + command_line->AppendSwitchASCII(chromeos::switches::kProfileRequiresPolicy, + "false"); - void TearDownInProcessBrowserTestFixture() override; + // Tell the policy subsystem to wait for an initial policy load, even + // though we are using a synchronously loaded profile. + // TODO(edmanp): `Update this test to properly use an asynchronously loaded + // user profile and remove the use of this flag (crbug.com/795737). + command_line->AppendSwitchASCII( + chromeos::switches::kWaitForInitialPolicyFetchForTest, "true"); + } - // Installs the given |certs_to_setup| in the NSS database. - void SetUpCerts(const std::vector<TestCertData>& certs_to_setup); + void SetUp() override { + chromeos::platform_keys::PlatformKeysServiceFactory::GetInstance() + ->SetTestingMode(true); - // Registers the given |cert| as corporate usage through platform keys. - void RegisterCorporateKey(CERTCertificate* cert); + MixinBasedInProcessBrowserTest::SetUp(); + } - // Deletes the given |cert| from the NSS cert database. - void DeleteCert(CERTCertificate* cert); + void SetUpOnMainThread() override { + MixinBasedInProcessBrowserTest::SetUpOnMainThread(); - // Verifies the expected |test_certs| are installed correctly. - void CheckInstalledCerts(std::vector<TestCertData> test_certs, - CertStoreService* service); + policy_helper_->WaitForInitialPolicy(browser()->profile()); - // Returns the profile for the |affiliation_mixin_| account. - Profile* profile(); + // Init ArcSessionManager for testing. + ArcServiceLauncher::Get()->ResetForTesting(); - // Owned by the CertStoreService instance. - FakeArcCertInstaller* installer_; + chromeos::ProfileHelper::SetAlwaysReturnPrimaryUserForTesting(true); - std::vector<InstalledTestCert> installed_certs_; + browser()->profile()->GetPrefs()->SetBoolean(prefs::kArcSignedIn, true); + browser()->profile()->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, + true); - chromeos::DeviceStateMixin device_state_{ - &mixin_host_, - chromeos::DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED}; - policy::DevicePolicyCrosTestHelper device_policy_helper_; - policy::AffiliationMixin affiliation_mixin_{&mixin_host_, - &device_policy_helper_}; + ArcKeymasterBridge::GetFactory()->SetTestingFactoryAndUse( + browser()->profile(), + base::BindRepeating(&BuildFakeArcKeymasterBridge)); + auto* keymaster_bridge = + ArcKeymasterBridge::GetForBrowserContext(browser()->profile()); + keymaster_bridge_ = static_cast<FakeArcKeymasterBridge*>(keymaster_bridge); + + auto installer = std::make_unique<FakeArcCertInstaller>( + browser()->profile(), std::make_unique<policy::RemoteCommandsQueue>()); + installer_ = installer.get(); + CertStoreService::GetFactory()->SetTestingFactoryAndUse( + browser()->profile(), + base::BindRepeating(&BuildCertStoreService, + base::Passed(std::move(installer)))); + + ArcServiceLauncher::Get()->OnPrimaryUserProfilePrepared( + browser()->profile()); + } + + void TearDownOnMainThread() override { + // Since ArcServiceLauncher is (re-)set up with profile() in + // SetUpOnMainThread() it is necessary to Shutdown() before the profile() + // is destroyed. ArcServiceLauncher::Shutdown() will be called again on + // fixture destruction (because it is initialized with the original Profile + // instance in fixture, once), but it should be no op. + ArcServiceLauncher::Get()->Shutdown(); + chromeos::ProfileHelper::SetAlwaysReturnPrimaryUserForTesting(false); + MixinBasedInProcessBrowserTest::TearDownOnMainThread(); + } + + void TearDown() override { + MixinBasedInProcessBrowserTest::TearDown(); + + chromeos::platform_keys::PlatformKeysServiceFactory::GetInstance() + ->SetTestingMode(false); + } + + void RegisterCorporateKey(CERTCertificate* cert) { + base::RunLoop run_loop; + chromeos::platform_keys::ExtensionKeyPermissionsServiceFactory:: + GetForBrowserContextAndExtension( + base::BindOnce(&CertStoreServiceTest::GotPermissionsForExtension, + base::Unretained(this), cert, + run_loop.QuitClosure()), + browser()->profile(), kFakeExtensionId); + run_loop.Run(); + } + + void SetUpCerts(const std::vector<std::string>& keys_file_names, + bool is_corporate_usage_key) { + // Read certs from files. + base::RunLoop loop; + GetNSSCertDatabaseForProfile( + browser()->profile(), + base::BindOnce(&CertStoreServiceTest::SetUpTestClientCerts, + base::Unretained(this), keys_file_names, + loop.QuitClosure())); + loop.Run(); + // Register certs for corporate usage if needed. + for (auto& cert : client_certs_) { + // Certificates must be imported. + ASSERT_TRUE(cert); + if (is_corporate_usage_key) + RegisterCorporateKey(cert.get()); + } + + // Import certs into database. + { + base::RunLoop loop; + GetNSSCertDatabaseForProfile( + browser()->profile(), + base::BindOnce(&CertStoreServiceTest::ImportTestClientCerts, + base::Unretained(this), loop.QuitClosure())); + loop.Run(); + } + } + + void DeleteCert(CERTCertificate* cert) { + base::RunLoop loop; + GetNSSCertDatabaseForProfile( + browser()->profile(), + base::BindOnce(&CertStoreServiceTest::DeleteCertAndKey, + base::Unretained(this), cert, loop.QuitClosure())); + loop.Run(); + } + + bool PlaceholdersContainId(const std::string& id) { + for (const auto& key : keymaster_bridge()->placeholder_keys()) { + if (key->key_data->is_chaps_key_data() && + key->key_data->get_chaps_key_data()->id == id) { + return true; + } + } + return false; + } + + void CheckInstalledCerts(size_t installed_cert_num, + CertStoreService* service) { + EXPECT_EQ(installed_cert_num, client_certs_.size()); + EXPECT_EQ(installed_cert_num, installer()->certs().size()); + EXPECT_EQ(installed_cert_num, service->get_required_cert_names().size()); + EXPECT_EQ(installed_cert_num, + keymaster_bridge()->placeholder_keys().size()); + + for (const auto& cert_name : service->get_required_cert_names()) { + bool found = false; + // Check the required cert is installed. + ASSERT_TRUE(installer()->certs().count(cert_name)); + for (const auto& cert : client_certs_) { + // Check the required cert is one of the imported for the test + // certificates. + if (GetDerCert64(cert.get()) == installer()->certs()[cert_name]) { + // Check nickname. + EXPECT_EQ(x509_certificate_model::GetCertNameOrNickname(cert.get()), + cert_name); + found = true; + // Check KeyInfo. + auto key_info = + service->GetKeyInfoForDummySpki(installer()->certs()[cert_name]); + EXPECT_TRUE(key_info.has_value()); + EXPECT_EQ(key_info.value().nickname, cert_name); + int slot_id; + // Check CKA_ID. + std::string hex_encoded_id = base::HexEncode( + key_info.value().id.data(), key_info.value().id.size()); + EXPECT_EQ(hex_encoded_id, + chromeos::NetworkCertLoader::GetPkcs11IdAndSlotForCert( + cert.get(), &slot_id)); + EXPECT_TRUE(PlaceholdersContainId(key_info.value().id)); + break; + } + } + // Check the required cert was found. + EXPECT_TRUE(found); + } + } + + FakeArcCertInstaller* installer() { return installer_; } + + FakeArcKeymasterBridge* keymaster_bridge() { return keymaster_bridge_; } + + net::ScopedCERTCertificateList client_certs_; private: - // Creates ScopedCERTCertificates for each |certs_to_setup| and appends them - // to |installed_certs_|. - void SetUpTestClientCerts(const std::vector<TestCertData>& certs_to_setup, + void OnKeyRegisteredForCorporateUsage( + std::unique_ptr<chromeos::platform_keys::ExtensionKeyPermissionsService> + extension_key_permissions_service, + base::OnceClosure done_callback, + bool is_error, + crosapi::mojom::KeystoreError error) { + ASSERT_FALSE(is_error) << static_cast<int>(error); + std::move(done_callback).Run(); + } + + // Register only client_cert1_ for corporate usage to test that + // client_cert2_ is not allowed. + void GotPermissionsForExtension( + CERTCertificate* cert, + base::OnceClosure done_callback, + std::unique_ptr<chromeos::platform_keys::ExtensionKeyPermissionsService> + extension_key_permissions_service) { + auto* extension_key_permissions_service_unowned = + extension_key_permissions_service.get(); + std::string client_cert_spki( + cert->derPublicKey.data, + cert->derPublicKey.data + cert->derPublicKey.len); + extension_key_permissions_service_unowned->RegisterKeyForCorporateUsage( + client_cert_spki, + base::BindOnce(&CertStoreServiceTest::OnKeyRegisteredForCorporateUsage, + base::Unretained(this), + std::move(extension_key_permissions_service), + std::move(done_callback))); + } + + void SetUpTestClientCerts(const std::vector<std::string>& key_file_names, base::OnceClosure done_callback, - net::NSSCertDatabase* cert_db); + net::NSSCertDatabase* cert_db) { + for (const auto& file_name : key_file_names) { + base::ScopedAllowBlockingForTesting allow_io; + net::ImportSensitiveKeyFromFile(net::GetTestCertsDirectory(), + file_name + ".pk8", + cert_db->GetPrivateSlot().get()); + net::ScopedCERTCertificateList certs = + net::CreateCERTCertificateListFromFile( + net::GetTestCertsDirectory(), file_name + ".pem", + net::X509Certificate::FORMAT_AUTO); + EXPECT_EQ(1U, certs.size()); + if (certs.size() != 1U) { + std::move(done_callback).Run(); + return; + } - // Imports the list of |installed_certs_| into the NSS |cert_db|. + client_certs_.emplace_back( + net::x509_util::DupCERTCertificate(certs[0].get())); + } + std::move(done_callback).Run(); + } + void ImportTestClientCerts(base::OnceClosure done_callback, - net::NSSCertDatabase* cert_db); + net::NSSCertDatabase* cert_db) { + for (const auto& cert : client_certs_) { + // Import user certificate properly how it's done in PlatfromKeys. + cert_db->ImportUserCert(cert.get()); + } + std::move(done_callback).Run(); + } - // Checks that |keymaster_bridge_->placeholder_keys()| contains a key with - // given |id| and |slot|. - bool PlaceholdersContainIdAndSlot(const std::string& id, - keymaster::mojom::ChapsSlot slot); + void DeleteCertAndKey(CERTCertificate* cert, + base::OnceClosure done_callback, + net::NSSCertDatabase* cert_db) { + base::ScopedAllowBlockingForTesting allow_io; + EXPECT_TRUE(cert_db->DeleteCertAndKey(cert)); + std::move(done_callback).Run(); + } - // Initializes |test_system_slot_|. - void SetUpTestSystemSlot(); + std::unique_ptr<policy::UserPolicyTestHelper> policy_helper_; + chromeos::LocalPolicyTestServerMixin local_policy_server_{&mixin_host_}; - void SetUpTestSystemSlotOnIO(bool* out_system_slot_constructed_successfully); - - // Destroys |test_system_slot_|. - void TearDownTestSystemSlot(); - - void TearDownTestSystemSlotOnIO(); - - std::unique_ptr<crypto::ScopedTestSystemNSSKeySlot> test_system_slot_; - - // Owned by the CertStoreService instance. + // Owned by service. + FakeArcCertInstaller* installer_; FakeArcKeymasterBridge* keymaster_bridge_; }; -void CertStoreServiceTest::SetUpCommandLine(base::CommandLine* command_line) { - MixinBasedInProcessBrowserTest::SetUpCommandLine(command_line); - arc::SetArcAvailableCommandLineForTesting(command_line); - policy::AffiliationTestHelper::AppendCommandLineSwitchesForLoginManager( - command_line); -} - -void CertStoreServiceTest::SetUpInProcessBrowserTestFixture() { - MixinBasedInProcessBrowserTest::SetUpInProcessBrowserTestFixture(); - chromeos::platform_keys::PlatformKeysServiceFactory::GetInstance() - ->SetTestingMode(true); -} - -void CertStoreServiceTest::SetUpOnMainThread() { - MixinBasedInProcessBrowserTest::SetUpOnMainThread(); - - // Pre tests need no further setup. - if (content::IsPreTest()) - return; - - policy::AffiliationTestHelper::LoginUser(affiliation_mixin_.account_id()); - - // Use fake ArcKeymasterBridge. - ArcKeymasterBridge::GetFactory()->SetTestingFactoryAndUse( - profile(), base::BindRepeating(&BuildFakeArcKeymasterBridge)); - auto* keymaster_bridge = ArcKeymasterBridge::GetForBrowserContext(profile()); - keymaster_bridge_ = static_cast<FakeArcKeymasterBridge*>(keymaster_bridge); - - // Use fake ArcCertInstaller in CertStoreService. - auto installer = std::make_unique<FakeArcCertInstaller>( - profile(), std::make_unique<policy::RemoteCommandsQueue>()); - installer_ = installer.get(); - CertStoreService::GetFactory()->SetTestingFactoryAndUse( - profile(), base::BindRepeating(&BuildCertStoreService, - base::Passed(std::move(installer)))); - - // Set up a system slot so tests can access device certs. - ASSERT_NO_FATAL_FAILURE(SetUpTestSystemSlot()); - ASSERT_TRUE(IsSystemSlotAvailable(profile())); -} - -void CertStoreServiceTest::TearDownOnMainThread() { - TearDownTestSystemSlot(); - MixinBasedInProcessBrowserTest::TearDownOnMainThread(); -} - -void CertStoreServiceTest::TearDownInProcessBrowserTestFixture() { - chromeos::platform_keys::PlatformKeysServiceFactory::GetInstance() - ->SetTestingMode(false); - MixinBasedInProcessBrowserTest::TearDownInProcessBrowserTestFixture(); -} - -void CertStoreServiceTest::SetUpCerts( - const std::vector<TestCertData>& certs_to_setup) { - // Remember current size of |installed_certs_| before new certs. - size_t initial_size = installed_certs_.size(); - - // Read certs from files. - base::RunLoop loop; - GetNSSCertDatabaseForProfile( - profile(), base::BindOnce(&CertStoreServiceTest::SetUpTestClientCerts, - base::Unretained(this), certs_to_setup, - loop.QuitClosure())); - loop.Run(); - - // Verify |certs_to_setup.size()| new certs have been installed. - ASSERT_EQ(installed_certs_.size(), certs_to_setup.size() + initial_size); - - // Register newly installed certs for corporate usage if needed. - for (size_t i = initial_size; i < installed_certs_.size(); ++i) { - const InstalledTestCert& cert = installed_certs_[i]; - if (cert.test_data.is_corporate_usage) - RegisterCorporateKey(cert.nss_cert.get()); - } - - // Import certs into database. - { - base::RunLoop loop; - GetNSSCertDatabaseForProfile( - profile(), base::BindOnce(&CertStoreServiceTest::ImportTestClientCerts, - base::Unretained(this), loop.QuitClosure())); - loop.Run(); - } -} - -void CertStoreServiceTest::RegisterCorporateKey(CERTCertificate* cert) { - base::RunLoop run_loop; - chromeos::platform_keys::ExtensionKeyPermissionsServiceFactory:: - GetForBrowserContextAndExtension( - base::BindOnce(&RegisterCorporateKeyWithService, cert, - run_loop.QuitClosure()), - profile(), kFakeExtensionId); - run_loop.Run(); -} - -void CertStoreServiceTest::DeleteCert(CERTCertificate* cert) { - base::RunLoop loop; - GetNSSCertDatabaseForProfile( - profile(), base::BindOnce(&DeleteCertAndKey, cert, loop.QuitClosure())); - loop.Run(); - installed_certs_.pop_back(); -} - -void CertStoreServiceTest::CheckInstalledCerts( - std::vector<TestCertData> test_certs, - CertStoreService* service) { - // Verify the number of corporate usage certs reported is correct. - EXPECT_EQ(CountCorporateUsage(test_certs), installer_->certs().size()); - EXPECT_EQ(CountCorporateUsage(test_certs), - service->get_required_cert_names().size()); - EXPECT_EQ(CountCorporateUsage(test_certs), - keymaster_bridge_->placeholder_keys().size()); - - // Verify |test_certs| and |installed_certs_| have matching elements. - ASSERT_EQ(test_certs.size(), installed_certs_.size()); - for (size_t i = 0; i < installed_certs_.size(); ++i) - EXPECT_EQ(test_certs[i], installed_certs_[i].test_data); - - for (const auto& cert_name : service->get_required_cert_names()) { - bool found = false; - // Check the required cert is installed. - ASSERT_TRUE(installer_->certs().count(cert_name)); - for (const auto& cert : installed_certs_) { - // Check the required cert is one of the installed test certificates. - const net::ScopedCERTCertificate& nss_cert = cert.nss_cert; - - // Skip until |cert| corresponds to the current |cert_name|. - if (GetDerCert64(nss_cert.get()) != installer_->certs()[cert_name]) - continue; - - // Check nickname. - EXPECT_EQ(x509_certificate_model::GetCertNameOrNickname(nss_cert.get()), - cert_name); - found = true; - // Check KeyInfo. - auto key_info = - service->GetKeyInfoForDummySpki(installer_->certs()[cert_name]); - EXPECT_TRUE(key_info.has_value()); - EXPECT_EQ(key_info.value().nickname, cert_name); - // Check CKA_ID and slot. - int slot_id; - std::string hex_encoded_id = base::HexEncode(key_info.value().id.data(), - key_info.value().id.size()); - EXPECT_EQ(hex_encoded_id, - chromeos::NetworkCertLoader::GetPkcs11IdAndSlotForCert( - nss_cert.get(), &slot_id)); - EXPECT_TRUE(PlaceholdersContainIdAndSlot(key_info.value().id, - cert.test_data.slot)); - break; - } - // Check the required cert was found. - EXPECT_TRUE(found); - } -} - -Profile* CertStoreServiceTest::profile() { - return chromeos::ProfileHelper::Get()->GetProfileByAccountId( - affiliation_mixin_.account_id()); -} - -void CertStoreServiceTest::SetUpTestClientCerts( - const std::vector<TestCertData>& certs_to_setup, - base::OnceClosure done_callback, - net::NSSCertDatabase* cert_db) { - for (const auto& test_data : certs_to_setup) { - base::ScopedAllowBlockingForTesting allow_io; - net::ImportSensitiveKeyFromFile( - net::GetTestCertsDirectory(), test_data.file_name + ".pk8", - test_data.slot == keymaster::mojom::ChapsSlot::kUser - ? cert_db->GetPrivateSlot().get() - : cert_db->GetSystemSlot().get()); - net::ScopedCERTCertificateList certs = - net::CreateCERTCertificateListFromFile( - net::GetTestCertsDirectory(), test_data.file_name + ".pem", - net::X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, certs.size()); - - installed_certs_.emplace_back( - test_data, net::x509_util::DupCERTCertificate(certs[0].get())); - } - std::move(done_callback).Run(); -} - -void CertStoreServiceTest::ImportTestClientCerts( - base::OnceClosure done_callback, - net::NSSCertDatabase* cert_db) { - for (const auto& cert : installed_certs_) { - // Import user certificate properly how it's done in PlatformKeys. - cert_db->ImportUserCert(cert.nss_cert.get()); - } - std::move(done_callback).Run(); -} - -bool CertStoreServiceTest::PlaceholdersContainIdAndSlot( - const std::string& id, - keymaster::mojom::ChapsSlot slot) { - for (const auto& key : keymaster_bridge_->placeholder_keys()) { - if (key->key_data->is_chaps_key_data() && - key->key_data->get_chaps_key_data()->id == id && - key->key_data->get_chaps_key_data()->slot == slot) { - return true; - } - } - return false; -} - -void CertStoreServiceTest::SetUpTestSystemSlot() { - bool system_slot_constructed_successfully = false; - base::RunLoop loop; - content::GetIOThreadTaskRunner({})->PostTaskAndReply( - FROM_HERE, - base::BindOnce(&CertStoreServiceTest::SetUpTestSystemSlotOnIO, - base::Unretained(this), - &system_slot_constructed_successfully), - loop.QuitClosure()); - loop.Run(); - ASSERT_TRUE(system_slot_constructed_successfully); -} - -void CertStoreServiceTest::SetUpTestSystemSlotOnIO( - bool* out_system_slot_constructed_successfully) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - test_system_slot_ = std::make_unique<crypto::ScopedTestSystemNSSKeySlot>(); - *out_system_slot_constructed_successfully = - test_system_slot_->ConstructedSuccessfully(); -} - -void CertStoreServiceTest::TearDownTestSystemSlot() { - if (!test_system_slot_) - return; - - base::RunLoop loop; - content::GetIOThreadTaskRunner({})->PostTaskAndReply( - FROM_HERE, - base::BindOnce(&CertStoreServiceTest::TearDownTestSystemSlotOnIO, - base::Unretained(this)), - loop.QuitClosure()); - loop.Run(); -} - -void CertStoreServiceTest::TearDownTestSystemSlotOnIO() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - test_system_slot_.reset(); -} - -IN_PROC_BROWSER_TEST_P(CertStoreServiceTest, PRE_HandlesCorporateUsageCerts) { - policy::AffiliationTestHelper::PreLoginUser(affiliation_mixin_.account_id()); -} - -IN_PROC_BROWSER_TEST_P(CertStoreServiceTest, HandlesCorporateUsageCerts) { - CertStoreService* service = CertStoreService::GetForBrowserContext(profile()); +// Test no corporate usage keys. +IN_PROC_BROWSER_TEST_F(CertStoreServiceTest, Basic) { + CertStoreService* service = + CertStoreService::GetForBrowserContext(browser()->profile()); ASSERT_TRUE(service); - // Install all certs from parameter at once. - ASSERT_NO_FATAL_FAILURE(SetUpCerts(GetParam())); - installer_->Wait(); - installer_->RunCompletionCallback(true /* success */); + // Import 2 certs into DB. No corporate usage keys. + ASSERT_NO_FATAL_FAILURE( + SetUpCerts(kCertFiles, false /* is_corporate_usage */)); + installer()->Wait(); + installer()->RunCompletionCallback(true /* success */); - // Verify all certs are installed correctly. - ASSERT_NO_FATAL_FAILURE(CheckInstalledCerts(GetParam(), service)); + EXPECT_EQ(kCertFiles.size(), client_certs_.size()); + // No corporate usage keys installed. + EXPECT_TRUE(installer()->certs().empty()); + EXPECT_TRUE(service->get_required_cert_names().empty()); + EXPECT_TRUE(keymaster_bridge()->placeholder_keys().empty()); } -IN_PROC_BROWSER_TEST_P(CertStoreServiceTest, - PRE_InstallsAndDeletesCorporateUsageCerts) { - policy::AffiliationTestHelper::PreLoginUser(affiliation_mixin_.account_id()); -} - -IN_PROC_BROWSER_TEST_P(CertStoreServiceTest, - InstallsAndDeletesCorporateUsageCerts) { - CertStoreService* service = CertStoreService::GetForBrowserContext(profile()); +// Test installation of 2 corporate usage keys. +IN_PROC_BROWSER_TEST_F(CertStoreServiceTest, InstalledCorporateUsageKeys) { + CertStoreService* service = + CertStoreService::GetForBrowserContext(browser()->profile()); + EXPECT_EQ(browser()->profile(), + Profile::FromBrowserContext(browser()->profile())); ASSERT_TRUE(service); - // Install certs from parameter one by one. - for (size_t i = 0; i < GetParam().size(); ++i) { - ASSERT_NO_FATAL_FAILURE(SetUpCerts({GetParam()[i]})); - installer_->Wait(); - installer_->RunCompletionCallback(true /* success */); + size_t installed_cert_num = 0; - // Verify only the first (i+1) certs are installed so far. + // Import and register corporate certificates. + for (const auto& file : kCertFiles) { ASSERT_NO_FATAL_FAILURE( - CheckInstalledCerts(std::vector<TestCertData>( - GetParam().begin(), GetParam().begin() + i + 1), - service)); - } + SetUpCerts({file}, true /* is_corporate_usage_key */)); + installer()->Wait(); + installer()->RunCompletionCallback(true /* success */); - // Uninstall certs from parameter one by one, from last to first. - for (size_t i = GetParam().size(); i--;) { - DeleteCert(installed_certs_.back().nss_cert.get()); - installer_->Wait(); - installer_->RunCompletionCallback(true /* success */); - - // Verify only the first i certs are left after the uninstall. - ASSERT_NO_FATAL_FAILURE(CheckInstalledCerts( - std::vector<TestCertData>(GetParam().begin(), GetParam().begin() + i), - service)); + installed_cert_num++; + CheckInstalledCerts(installed_cert_num, service); } } -INSTANTIATE_TEST_SUITE_P( - CertStoreTests, - CertStoreServiceTest, - ::testing::Values( - // No corporate usage keys. - std::vector<TestCertData>{ - TestCertData(kFileName1, - false /* is_corporate_usage */, - keymaster::mojom::ChapsSlot::kUser), - TestCertData(kFileName2, - false /* is_corporate_usage */, - keymaster::mojom::ChapsSlot::kUser)}, - // Corporate usage keys in user slot. - std::vector<TestCertData>{ - TestCertData(kFileName1, - true /* is_corporate_usage */, - keymaster::mojom::ChapsSlot::kUser), - TestCertData(kFileName2, - true /* is_corporate_usage */, - keymaster::mojom::ChapsSlot::kUser)}, - // Corporate usage keys in system slot. - std::vector<TestCertData>{ - TestCertData(kFileName1, - true /* is_corporate_usage */, - keymaster::mojom::ChapsSlot::kSystem), - TestCertData(kFileName2, - true /* is_corporate_usage */, - keymaster::mojom::ChapsSlot::kSystem)}, - // Corporate usage keys in both slots. - std::vector<TestCertData>{ - TestCertData(kFileName1, - true /* is_corporate_usage */, - keymaster::mojom::ChapsSlot::kUser), - TestCertData(kFileName2, - true /* is_corporate_usage */, - keymaster::mojom::ChapsSlot::kSystem), - TestCertData(kFileName3, - false /* is_corporate_usage */, - keymaster::mojom::ChapsSlot::kUser), - TestCertData(kFileName4, - true /* is_corporate_usage */, - keymaster::mojom::ChapsSlot::kSystem)})); +// Test uninstallation of 2 corporate usage keys. +IN_PROC_BROWSER_TEST_F(CertStoreServiceTest, UninstalledCorporateUsageKeys) { + CertStoreService* service = + CertStoreService::GetForBrowserContext(browser()->profile()); + EXPECT_EQ(browser()->profile(), + Profile::FromBrowserContext(browser()->profile())); + ASSERT_TRUE(service); + + installer()->Wait(); + installer()->RunCompletionCallback(true /* success */); + + CheckInstalledCerts(0, service); + ASSERT_NO_FATAL_FAILURE( + SetUpCerts({kCertFiles}, true /* is_corporate_usage_key */)); + installer()->Wait(); + installer()->RunCompletionCallback(true /* success */); + CheckInstalledCerts(kCertFiles.size(), service); + + size_t installed_cert_num = kCertFiles.size(); + while (!client_certs_.empty()) { + DeleteCert(client_certs_.back().get()); + installer()->Wait(); + installer()->RunCompletionCallback(true /* success */); + + client_certs_.pop_back(); + installed_cert_num--; + CheckInstalledCerts(installed_cert_num, service); + } +} } // namespace arc
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen.cc b/chrome/browser/ash/login/enrollment/enrollment_screen.cc index 15cb3f3c..b6a02bb 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_screen.cc +++ b/chrome/browser/ash/login/enrollment/enrollment_screen.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "ash/constants/ash_features.h" #include "base/bind.h" #include "base/callback.h" #include "base/callback_helpers.h" @@ -21,6 +22,8 @@ #include "chrome/browser/ash/login/wizard_context.h" #include "chrome/browser/ash/login/wizard_controller.h" #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h" +#include "chrome/browser/ash/policy/enrollment/account_status_check_fetcher.h" +#include "chrome/browser/ash/policy/enrollment/enrollment_requisition_manager.h" #include "chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" @@ -37,6 +40,7 @@ namespace ash { namespace { +using ::policy::AccountStatusCheckFetcher; using ::policy::EnrollmentConfig; // Do not change the UMA histogram parameters without renaming the histograms! @@ -164,7 +168,7 @@ ? policy::EnrollmentConfig::MODE_ATTESTATION_LOCAL_FORCED : policy::EnrollmentConfig::MODE_ATTESTATION; } - view_->SetEnrollmentConfig(this, config_); + view_->SetEnrollmentConfig(config_); enrollment_helper_ = nullptr; } @@ -213,9 +217,26 @@ return false; } +void EnrollmentScreen::UpdateFlowType() { + if (features::IsLicensePackagedOobeFlowEnabled() && + config_.license_type == + policy::EnrollmentConfig::LicenseType::kEnterprise) { + view_->SetFlowType(EnrollmentScreenView::FlowType::kEnterpriseLicense); + return; + } + const bool cfm = policy::EnrollmentRequisitionManager::IsRemoraRequisition(); + if (cfm) { + view_->SetFlowType(EnrollmentScreenView::FlowType::kCFM); + } else { + view_->SetFlowType(EnrollmentScreenView::FlowType::kEnterprise); + } +} + void EnrollmentScreen::ShowImpl() { VLOG(1) << "Show enrollment screen"; + view_->SetEnrollmentController(this); UMA(policy::kMetricEnrollmentTriggered); + UpdateFlowType(); switch (current_auth_) { case AUTH_OAUTH: ShowInteractiveScreen(); @@ -380,6 +401,42 @@ ->GetTPMAutoUpdateModePolicyHandler() ->UpdateOnEnrollmentIfNeeded(); } +void EnrollmentScreen::OnIdentifierEntered(const std::string& email) { + auto callback = base::BindOnce(&EnrollmentScreen::OnAccountStatusFetched, + base::Unretained(this), email); + status_checker_.reset(); + status_checker_ = std::make_unique<policy::AccountStatusCheckFetcher>(email); + status_checker_->Fetch(std::move(callback)); +} + +void EnrollmentScreen::OnAccountStatusFetched( + const std::string& email, + bool result, + policy::AccountStatusCheckFetcher::AccountStatus status) { + if (!view_) + return; + if (status == AccountStatusCheckFetcher::AccountStatus::kDasher || + status == AccountStatusCheckFetcher::AccountStatus::kUnknown || + result == false) { + view_->ShowSigninScreen(); + return; + } + if (status == + AccountStatusCheckFetcher::AccountStatus::kConsumerWithConsumerDomain) { + view_->ShowUserError(EnrollmentScreenView::UserErrorType::kConsumerDomain, + email); + return; + } + if (status == + AccountStatusCheckFetcher::AccountStatus::kConsumerWithBusinessDomain) { + view_->ShowUserError(EnrollmentScreenView::UserErrorType::kBusinessDomain, + email); + return; + } + + // For all other types just show signin screen. + view_->ShowSigninScreen(); +} void EnrollmentScreen::OnActiveDirectoryCredsProvided( const std::string& machine_name,
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen.h b/chrome/browser/ash/login/enrollment/enrollment_screen.h index 4bc5d65..90c2d92 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_screen.h +++ b/chrome/browser/ash/login/enrollment/enrollment_screen.h
@@ -22,6 +22,7 @@ #include "chrome/browser/ash/login/screens/base_screen.h" #include "chrome/browser/ash/login/wizard_context.h" #include "chrome/browser/ash/policy/active_directory/active_directory_join_delegate.h" +#include "chrome/browser/ash/policy/enrollment/account_status_check_fetcher.h" #include "chrome/browser/ash/policy/enrollment/enrollment_config.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "components/policy/core/common/cloud/enterprise_metrics.h" @@ -74,6 +75,7 @@ const std::string& password) override; void OnDeviceAttributeProvided(const std::string& asset_id, const std::string& location) override; + void OnIdentifierEntered(const std::string& email) override; // EnterpriseEnrollmentHelper::EnrollmentStatusConsumer implementation: void OnAuthError(const GoogleServiceAuthError& error) override; @@ -129,9 +131,19 @@ AUTH_OAUTH, }; + // Updates view GAIA flow type which is used to modify visual appearance + // of GAIA webview, + void UpdateFlowType(); + // Sets the current config to use for enrollment. void SetConfig(); + // Called after account status is fetched. + void OnAccountStatusFetched( + const std::string& email, + bool result, + policy::AccountStatusCheckFetcher::AccountStatus status); + // Creates an enrollment helper if needed. void CreateEnrollmentHelper(); @@ -203,6 +215,7 @@ int num_retries_ = 0; std::unique_ptr<EnterpriseEnrollmentHelper> enrollment_helper_; policy::OnDomainJoinedCallback on_joined_callback_; + std::unique_ptr<policy::AccountStatusCheckFetcher> status_checker_; // Helper to call AuthPolicyClient and cancel calls if needed. Used to join // Active Directory domain.
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen_unittest.cc b/chrome/browser/ash/login/enrollment/enrollment_screen_unittest.cc index 3e2a72c..d683df91 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_screen_unittest.cc +++ b/chrome/browser/ash/login/enrollment/enrollment_screen_unittest.cc
@@ -16,10 +16,14 @@ #include "chrome/browser/ash/login/enrollment/mock_enrollment_screen.h" #include "chrome/browser/ash/login/wizard_context.h" #include "chrome/browser/ash/policy/enrollment/enrollment_config.h" +#include "chrome/browser/ash/policy/enrollment/enrollment_requisition_manager.h" #include "chrome/browser/policy/enrollment_status.h" +#include "chrome/browser/prefs/browser_prefs.h" #include "chrome/test/base/testing_browser_process.h" #include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/system/fake_statistics_provider.h" #include "chromeos/tpm/stub_install_attributes.h" +#include "components/prefs/testing_pref_service.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -54,13 +58,18 @@ // testing::Test: void SetUp() override { - // Initialize the thread manager. + RegisterLocalState(pref_service_.registry()); + TestingBrowserProcess::GetGlobal()->SetLocalState(&pref_service_); + chromeos::system::StatisticsProvider::SetTestProvider( + &statistics_provider_); DBusThreadManager::Initialize(); + policy::EnrollmentRequisitionManager::Initialize(); } void TearDown() override { TestingBrowserProcess::GetGlobal()->SetShuttingDown(true); DBusThreadManager::Shutdown(); + TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr); } protected: @@ -84,6 +93,10 @@ ScopedStubInstallAttributes test_install_attributes_; + TestingPrefServiceSimple pref_service_; + + chromeos::system::FakeStatisticsProvider statistics_provider_; + // Objects required by the EnrollmentScreen that can be re-used. MockEnrollmentScreenView mock_view_;
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen_view.h b/chrome/browser/ash/login/enrollment/enrollment_screen_view.h index 90cd2cf..d8f1801 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_screen_view.h +++ b/chrome/browser/ash/login/enrollment/enrollment_screen_view.h
@@ -43,20 +43,27 @@ virtual void OnDeviceAttributeProvided(const std::string& asset_id, const std::string& location) = 0; + virtual void OnIdentifierEntered(const std::string& email) = 0; }; constexpr static StaticOobeScreenId kScreenId{"enterprise-enrollment"}; virtual ~EnrollmentScreenView() {} + enum class FlowType { kEnterprise, kCFM, kEnterpriseLicense }; + enum class UserErrorType { kConsumerDomain, kBusinessDomain }; + // Initializes the view with parameters. - virtual void SetEnrollmentConfig(Controller* controller, - const policy::EnrollmentConfig& config) = 0; + virtual void SetEnrollmentConfig(const policy::EnrollmentConfig& config) = 0; + virtual void SetEnrollmentController(Controller* controller) = 0; // Sets the enterprise manager and the device type to be shown for the user. virtual void SetEnterpriseDomainInfo(const std::string& manager, const std::u16string& device_type) = 0; + // Sets which flow should GAIA show. + virtual void SetFlowType(FlowType flow_type) = 0; + // Shows the contents of the screen. virtual void Show() = 0; @@ -66,6 +73,10 @@ // Shows the signin screen. virtual void ShowSigninScreen() = 0; + // Shows error related to user account eligibility. + virtual void ShowUserError(UserErrorType error_type, + const std::string& email) = 0; + // Shows the Active Directory domain joining screen. virtual void ShowActiveDirectoryScreen(const std::string& domain_join_config, const std::string& machine_name,
diff --git a/chrome/browser/ash/login/enrollment/mock_enrollment_screen.h b/chrome/browser/ash/login/enrollment/mock_enrollment_screen.h index 1bf2a2b..c9b1b47 100644 --- a/chrome/browser/ash/login/enrollment/mock_enrollment_screen.h +++ b/chrome/browser/ash/login/enrollment/mock_enrollment_screen.h
@@ -33,14 +33,19 @@ MOCK_METHOD(void, SetEnrollmentConfig, - (Controller*, const policy::EnrollmentConfig& config)); + (const policy::EnrollmentConfig& config)); + MOCK_METHOD(void, SetEnrollmentController, (Controller*)); MOCK_METHOD(void, SetEnterpriseDomainInfo, (const std::string& manager, const std::u16string& device_type)); + MOCK_METHOD(void, SetFlowType, (FlowType flow_type)); MOCK_METHOD(void, Show, ()); MOCK_METHOD(void, Hide, ()); MOCK_METHOD(void, ShowSigninScreen, ()); MOCK_METHOD(void, + ShowUserError, + (UserErrorType error_type, const std::string& email)); + MOCK_METHOD(void, ShowLicenseTypeSelectionScreen, (const base::DictionaryValue&)); MOCK_METHOD(void,
diff --git a/chrome/browser/ash/login/screens/assistant_optin_flow_screen_browsertest.cc b/chrome/browser/ash/login/screens/assistant_optin_flow_screen_browsertest.cc index ab7c03a..6cd3ceb1 100644 --- a/chrome/browser/ash/login/screens/assistant_optin_flow_screen_browsertest.cc +++ b/chrome/browser/ash/login/screens/assistant_optin_flow_screen_browsertest.cc
@@ -32,7 +32,6 @@ #include "chromeos/services/assistant/public/cpp/assistant_prefs.h" #include "chromeos/services/assistant/public/cpp/assistant_settings.h" #include "chromeos/services/assistant/public/cpp/features.h" -#include "chromeos/services/assistant/public/proto/get_settings_ui.pb.h" #include "chromeos/services/assistant/public/proto/settings_ui.pb.h" #include "chromeos/services/assistant/service.h" #include "components/prefs/pref_service.h" @@ -160,8 +159,6 @@ void set_setting_zippy_size(int size) { setting_zippy_size_ = size; } - void set_is_minor_user(bool is_minor_user) { is_minor_user_ = is_minor_user; } - const std::set<OptIn>& collected_optins() const { return collected_optins_; } // Advances speaker ID enrollment to the next state. @@ -206,10 +203,7 @@ // chromeos::assistant::AssistantSettings: void GetSettings(const std::string& selector, - GetSettingsCallback callback) override {} - - void GetSettingsWithHeader(const std::string& selector, - GetSettingsCallback callback) override { + GetSettingsCallback callback) override { chromeos::assistant::SettingsUiSelector selector_proto; ASSERT_TRUE(selector_proto.ParseFromString(selector)); EXPECT_FALSE(selector_proto.about_me_settings()); @@ -218,24 +212,15 @@ ASSISTANT_SUW_ONBOARDING_ON_CHROME_OS, selector_proto.consent_flow_ui_selector().flow_id()); - chromeos::assistant::GetSettingsUiResponse response; - - if (is_minor_user_) { - auto* header = response.mutable_header(); - header->set_footer_button_layout( - chromeos::assistant:: - SettingsResponseHeader_AcceptRejectLayout_EQUAL_WEIGHT); - } - - auto* settings_ui = response.mutable_settings(); - auto* gaia_user_context_ui = settings_ui->mutable_gaia_user_context_ui(); + chromeos::assistant::SettingsUi settings_ui; + auto* gaia_user_context_ui = settings_ui.mutable_gaia_user_context_ui(); gaia_user_context_ui->set_is_gaia_user(true); gaia_user_context_ui->set_waa_disabled_by_dasher_domain( (consent_ui_flags_ & CONSENT_UI_FLAG_WAA_DISABLED_BY_POLICY)); gaia_user_context_ui->set_assistant_disabled_by_dasher_domain( (consent_ui_flags_ & CONSENT_UI_FLAG_ASSISTANT_DISABLED_BY_POLICY)); - auto* consent_flow_ui = settings_ui->mutable_consent_flow_ui(); + auto* consent_flow_ui = settings_ui.mutable_consent_flow_ui(); consent_flow_ui->set_consent_status( chromeos::assistant::ConsentFlowUi_ConsentStatus_ASK_FOR_CONSENT); consent_flow_ui->mutable_consent_ui()->set_accept_button_text("OK"); @@ -266,7 +251,7 @@ if (selector_proto.email_opt_in() && (consent_ui_flags_ & CONSENT_UI_FLAG_ASK_EMAIL_OPT_IN)) { - auto* email_opt_in = settings_ui->mutable_email_opt_in_ui(); + auto* email_opt_in = settings_ui.mutable_email_opt_in_ui(); email_opt_in->set_title("Receive email upfates"); email_opt_in->set_description("It might be useful"); email_opt_in->set_legal_text("And you can opt out"); @@ -276,7 +261,7 @@ } std::string message; - EXPECT_TRUE(response.SerializeToString(&message)); + EXPECT_TRUE(settings_ui.SerializeToString(&message)); std::move(callback).Run(message); } @@ -381,7 +366,6 @@ std::set<OptIn> collected_optins_; int setting_zippy_size_ = 1; - bool is_minor_user_ = false; DISALLOW_COPY_AND_ASSIGN(ScopedAssistantSettings); }; @@ -546,17 +530,12 @@ screen_waiter.Wait(); test::OobeJS().CreateVisibilityWaiter(true, kAssistantValueProp)->Wait(); - EXPECT_TRUE(test::OobeJS().GetAttributeBool("inverse", kValuePropNextButton)); TapWhenEnabled(kValuePropNextButton); test::OobeJS().CreateVisibilityWaiter(true, kAssistantRelatedInfo)->Wait(); - EXPECT_TRUE( - test::OobeJS().GetAttributeBool("inverse", kRelatedInfoNextButton)); TapWhenEnabled(kRelatedInfoNextButton); test::OobeJS().CreateVisibilityWaiter(true, kAssistantVoiceMatch)->Wait(); - EXPECT_TRUE( - test::OobeJS().GetAttributeBool("inverse", kVoiceMatchAgreeButton)); TapWhenEnabled(kVoiceMatchAgreeButton); WaitForScreenExit(); @@ -1134,11 +1113,6 @@ scoped_feature_list_.Reset(); scoped_feature_list_.InitAndEnableFeature(features::kMinorModeRestriction); } - - void SetUpOnMainThread() override { - AssistantOptInFlowTest::SetUpOnMainThread(); - assistant_settings_->set_is_minor_user(true); - } }; IN_PROC_BROWSER_TEST_F(AssistantOptInFlowMinorModeTest, @@ -1157,21 +1131,13 @@ screen_waiter.Wait(); test::OobeJS().CreateVisibilityWaiter(true, kAssistantValueProp)->Wait(); - EXPECT_FALSE( - test::OobeJS().GetAttributeBool("inverse", kValuePropNextButton)); TapWhenEnabled(kValuePropNextButton); - EXPECT_FALSE( - test::OobeJS().GetAttributeBool("inverse", kValuePropNextButton)); TapWhenEnabled(kValuePropNextButton); test::OobeJS().CreateVisibilityWaiter(true, kAssistantRelatedInfo)->Wait(); - EXPECT_FALSE( - test::OobeJS().GetAttributeBool("inverse", kRelatedInfoNextButton)); TapWhenEnabled(kRelatedInfoNextButton); test::OobeJS().CreateVisibilityWaiter(true, kAssistantVoiceMatch)->Wait(); - EXPECT_FALSE( - test::OobeJS().GetAttributeBool("inverse", kVoiceMatchAgreeButton)); TapWhenEnabled(kVoiceMatchAgreeButton); WaitForScreenExit();
diff --git a/chrome/browser/ash/login/screens/packaged_license_screen.cc b/chrome/browser/ash/login/screens/packaged_license_screen.cc index f9690cb..4712a1b 100644 --- a/chrome/browser/ash/login/screens/packaged_license_screen.cc +++ b/chrome/browser/ash/login/screens/packaged_license_screen.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ash/login/screens/packaged_license_screen.h" +#include "ash/constants/ash_features.h" #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h" #include "chrome/browser/ash/policy/enrollment/enrollment_config.h" #include "chrome/browser/browser_process.h" @@ -27,6 +28,8 @@ return "Enroll"; case Result::NOT_APPLICABLE: return BaseScreen::kNotApplicable; + case Result::NOT_APPLICABLE_SKIP_TO_ENROLL: + return BaseScreen::kNotApplicable; } } @@ -46,14 +49,19 @@ } bool PackagedLicenseScreen::MaybeSkip(WizardContext* context) { - policy::EnrollmentConfig enrollment_config = - g_browser_process->platform_part() - ->browser_policy_connector_chromeos() - ->GetPrescribedEnrollmentConfig(); + policy::EnrollmentConfig config = g_browser_process->platform_part() + ->browser_policy_connector_chromeos() + ->GetPrescribedEnrollmentConfig(); // License screen should be shown when device packed with license and other // enrollment flows are not triggered by the device state. - if (enrollment_config.is_license_packaged_with_device && - !enrollment_config.should_enroll()) { + if (config.is_license_packaged_with_device && !config.should_enroll()) { + // Skip to enroll since GAIA form has welcoming text for enterprise license. + if (features::IsLicensePackagedOobeFlowEnabled() && + config.license_type == + policy::EnrollmentConfig::LicenseType::kEnterprise) { + exit_callback_.Run(Result::NOT_APPLICABLE_SKIP_TO_ENROLL); + return true; + } return false; } exit_callback_.Run(Result::NOT_APPLICABLE);
diff --git a/chrome/browser/ash/login/screens/packaged_license_screen.h b/chrome/browser/ash/login/screens/packaged_license_screen.h index 0a84d9d4..204c017 100644 --- a/chrome/browser/ash/login/screens/packaged_license_screen.h +++ b/chrome/browser/ash/login/screens/packaged_license_screen.h
@@ -25,7 +25,11 @@ // Show enterprise enrollment screen ENROLL, // No information about license in the `enrollment_config_` - NOT_APPLICABLE + NOT_APPLICABLE, + // Enterprise license should start from GAIA enrollment screen. This result + // is different from Enroll since in this case the screen is skipped and + // should not be recorded in metrics. + NOT_APPLICABLE_SKIP_TO_ENROLL }; static std::string GetResultString(Result result);
diff --git a/chrome/browser/ash/login/wizard_controller.cc b/chrome/browser/ash/login/wizard_controller.cc index da40143..2e80a4d3 100644 --- a/chrome/browser/ash/login/wizard_controller.cc +++ b/chrome/browser/ash/login/wizard_controller.cc
@@ -1599,6 +1599,7 @@ ShowLoginScreen(); break; case PackagedLicenseScreen::Result::ENROLL: + case PackagedLicenseScreen::Result::NOT_APPLICABLE_SKIP_TO_ENROLL: ShowEnrollmentScreen(); break; }
diff --git a/chrome/browser/ash/login/wizard_controller_browsertest.cc b/chrome/browser/ash/login/wizard_controller_browsertest.cc index 765f3319..84298bf 100644 --- a/chrome/browser/ash/login/wizard_controller_browsertest.cc +++ b/chrome/browser/ash/login/wizard_controller_browsertest.cc
@@ -871,7 +871,6 @@ ->wizard_context_->enrollment_triggered_early = true; EXPECT_CALL(*mock_enrollment_screen_view_, SetEnrollmentConfig( - mock_enrollment_screen_, EnrollmentModeMatches(policy::EnrollmentConfig::MODE_MANUAL))) .Times(1); EXPECT_CALL(*mock_auto_enrollment_check_screen_, ShowImpl()).Times(1); @@ -918,7 +917,6 @@ EXPECT_CALL(*mock_update_screen_, ShowImpl()).Times(0); EXPECT_CALL(*mock_enrollment_screen_view_, SetEnrollmentConfig( - mock_enrollment_screen_, EnrollmentModeMatches(policy::EnrollmentConfig::MODE_MANUAL))) .Times(1); EXPECT_CALL(*mock_enrollment_screen_, ShowImpl()).Times(1); @@ -1308,7 +1306,6 @@ EXPECT_CALL( *mock_enrollment_screen_view_, SetEnrollmentConfig( - mock_enrollment_screen_, EnrollmentModeMatches(policy::EnrollmentConfig::MODE_SERVER_FORCED))) .Times(1); mock_auto_enrollment_check_screen_->ExitScreen(); @@ -1391,11 +1388,9 @@ g_browser_process->local_state()->Set(prefs::kServerBackedDeviceState, device_state); EXPECT_CALL(*mock_enrollment_screen_, ShowImpl()).Times(1); - EXPECT_CALL( - *mock_enrollment_screen_view_, - SetEnrollmentConfig(mock_enrollment_screen_, - EnrollmentModeMatches( - policy::EnrollmentConfig::MODE_SERVER_FORCED))) + EXPECT_CALL(*mock_enrollment_screen_view_, + SetEnrollmentConfig(EnrollmentModeMatches( + policy::EnrollmentConfig::MODE_SERVER_FORCED))) .Times(1); fake_auto_enrollment_client->SetState( policy::AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT); @@ -1502,11 +1497,9 @@ g_browser_process->local_state()->Set(prefs::kServerBackedDeviceState, device_state); EXPECT_CALL(*mock_enrollment_screen_, ShowImpl()).Times(1); - EXPECT_CALL( - *mock_enrollment_screen_view_, - SetEnrollmentConfig(mock_enrollment_screen_, - EnrollmentModeMatches( - policy::EnrollmentConfig::MODE_SERVER_FORCED))) + EXPECT_CALL(*mock_enrollment_screen_view_, + SetEnrollmentConfig(EnrollmentModeMatches( + policy::EnrollmentConfig::MODE_SERVER_FORCED))) .Times(1); mock_auto_enrollment_check_screen_->ExitScreen(); @@ -1617,7 +1610,6 @@ EXPECT_CALL( *mock_enrollment_screen_view_, SetEnrollmentConfig( - mock_enrollment_screen_, EnrollmentModeMatches(policy::EnrollmentConfig::MODE_SERVER_FORCED))) .Times(1); fake_auto_enrollment_client->SetState( @@ -1838,7 +1830,6 @@ EXPECT_CALL( *mock_enrollment_screen_view_, SetEnrollmentConfig( - mock_enrollment_screen_, EnrollmentModeMatches(policy::EnrollmentConfig::MODE_SERVER_FORCED))) .Times(1); mock_auto_enrollment_check_screen_->ExitScreen(); @@ -2056,7 +2047,6 @@ EXPECT_CALL( *mock_enrollment_screen_view_, SetEnrollmentConfig( - mock_enrollment_screen_, EnrollmentModeMatches(policy::EnrollmentConfig::MODE_LOCAL_FORCED))) .Times(1); CheckCurrentScreen(WelcomeView::kScreenId); @@ -2102,7 +2092,6 @@ EXPECT_CALL( *mock_enrollment_screen_view_, SetEnrollmentConfig( - mock_enrollment_screen_, EnrollmentModeMatches(policy::EnrollmentConfig::MODE_LOCAL_FORCED))) .Times(1); @@ -2715,7 +2704,6 @@ CheckCurrentScreen(WelcomeView::kScreenId); EXPECT_CALL(*mock_enrollment_screen_view_, SetEnrollmentConfig( - mock_enrollment_screen_, EnrollmentModeMatches(policy::EnrollmentConfig::MODE_MANUAL))) .Times(1); EXPECT_CALL(*mock_enrollment_screen_, ShowImpl()).Times(1);
diff --git a/chrome/browser/ash/policy/core/device_local_account_policy_provider.cc b/chrome/browser/ash/policy/core/device_local_account_policy_provider.cc index fe290fa9..6cc036b6 100644 --- a/chrome/browser/ash/policy/core/device_local_account_policy_provider.cc +++ b/chrome/browser/ash/policy/core/device_local_account_policy_provider.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/values.h" #include "chrome/browser/ash/policy/external_data/device_local_account_external_data_manager.h" +#include "chrome/browser/ash/settings/cros_settings.h" #include "chromeos/dbus/power/power_policy_controller.h" #include "components/policy/core/common/cloud/cloud_policy_core.h" #include "components/policy/core/common/cloud/cloud_policy_service.h" @@ -157,7 +158,57 @@ } } + bool restricted_managed_guest_session_enabled = false; + ash::CrosSettings::Get()->GetBoolean( + chromeos::kRestrictedManagedGuestSessionEnabled, + &restricted_managed_guest_session_enabled); + if (restricted_managed_guest_session_enabled) { + ApplyRestrictedManagedGuestSessionOverride(&chrome_policy); + } + UpdatePolicy(std::move(bundle)); } +// Details about the restricted managed guest session and the overridden +// policies can be found here: go/restricted-managed-guest-session. +void DeviceLocalAccountPolicyProvider:: + ApplyRestrictedManagedGuestSessionOverride(PolicyMap* chrome_policy) { + const std::pair<std::string, bool> kRestrictedModeBooleanPolicyOverrides[] = { + {key::kPasswordManagerEnabled, false}, + {key::kAllowDeletingBrowserHistory, true}, + {key::kArcEnabled, false}, + {key::kCrostiniAllowed, false}, + {key::kUserPluginVmAllowed, false}, + {key::kNetworkFileSharesAllowed, false}, + {key::kCACertificateManagementAllowed, false}, + {key::kClientCertificateManagementAllowed, false}, + {key::kEnableMediaRouter, false}, + {key::kScreenCaptureAllowed, false}, + {key::kKerberosEnabled, false}, + {key::kUserBorealisAllowed, false}, + {key::kDeletePrintJobHistoryAllowed, true}, + {key::kLacrosAllowed, false}, + {key::kLacrosSecondaryProfilesAllowed, false}}; + const std::pair<std::string, std::string> + kRestrictedModeStringPolicyOverrides[] = { + {key::kLacrosAvailability, "lacros_disallowed"}}; + + for (const auto& restricted_mode_boolean_policy_override : + kRestrictedModeBooleanPolicyOverrides) { + chrome_policy->Set( + restricted_mode_boolean_policy_override.first, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(restricted_mode_boolean_policy_override.second), nullptr); + } + for (const auto& restricted_mode_string_policy_override : + kRestrictedModeStringPolicyOverrides) { + chrome_policy->Set( + restricted_mode_string_policy_override.first, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(restricted_mode_string_policy_override.second), nullptr); + } +} + } // namespace policy
diff --git a/chrome/browser/ash/policy/core/device_local_account_policy_provider.h b/chrome/browser/ash/policy/core/device_local_account_policy_provider.h index 5199ec0..0d3e126 100644 --- a/chrome/browser/ash/policy/core/device_local_account_policy_provider.h +++ b/chrome/browser/ash/policy/core/device_local_account_policy_provider.h
@@ -65,6 +65,10 @@ // policy from the broker if available or keeping the current policy. void UpdateFromBroker(); + // Applies the policy restrictions related to the restricted managed guest + // session override. + void ApplyRestrictedManagedGuestSessionOverride(PolicyMap* chrome_policy); + const std::string user_id_; scoped_refptr<DeviceLocalAccountExternalDataManager> external_data_manager_;
diff --git a/chrome/browser/ash/policy/core/device_local_account_policy_service_unittest.cc b/chrome/browser/ash/policy/core/device_local_account_policy_service_unittest.cc index 029f8c1..439ba8a 100644 --- a/chrome/browser/ash/policy/core/device_local_account_policy_service_unittest.cc +++ b/chrome/browser/ash/policy/core/device_local_account_policy_service_unittest.cc
@@ -804,6 +804,7 @@ SchemaRegistry schema_registry_; std::unique_ptr<DeviceLocalAccountPolicyProvider> provider_; MockConfigurationPolicyObserver provider_observer_; + std::unique_ptr<ash::ScopedCrosSettingsTestHelper> cros_settings_helper_; private: DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountPolicyProviderTest); @@ -821,6 +822,9 @@ service_.get(), false /*force_immediate_load*/); provider_->Init(&schema_registry_); provider_->AddObserver(&provider_observer_); + cros_settings_helper_ = std::make_unique<ash::ScopedCrosSettingsTestHelper>( + false /*create_service*/); + cros_settings_helper_->ReplaceDeviceSettingsProviderWithStub(); // Values implicitly enforced for public accounts. expected_policy_map_.Set( @@ -839,6 +843,7 @@ provider_->RemoveObserver(&provider_observer_); provider_->Shutdown(); provider_.reset(); + cros_settings_helper_.reset(); DeviceLocalAccountPolicyServiceTestBase::TearDown(); } @@ -1018,6 +1023,129 @@ Mock::VerifyAndClearExpectations(&provider_observer_); } +TEST_F(DeviceLocalAccountPolicyProviderTest, + RestrictedManagedGuestSessionEnabled) { + EXPECT_CALL(provider_observer_, OnUpdatePolicy(provider_.get())) + .Times(AtLeast(1)); + InstallDeviceLocalAccountPolicy(kAccount1); + AddDeviceLocalAccountToPolicy(kAccount1); + InstallDevicePolicy(); + Mock::VerifyAndClearExpectations(&provider_observer_); + DeviceLocalAccountPolicyBroker* broker = + service_->GetBrokerForUser(account_1_user_id_); + ASSERT_TRUE(broker); + + // Disabled RestrictedManagedGuestSessionEnabled policy does not + // change other policy values. + EXPECT_CALL(provider_observer_, OnUpdatePolicy(provider_.get())) + .Times(AtLeast(1)); + cros_settings_helper_->SetBoolean( + chromeos::kRestrictedManagedGuestSessionEnabled, false); + InstallDeviceLocalAccountPolicy(kAccount1); + broker->core()->store()->Load(); + FlushDeviceSettings(); + Mock::VerifyAndClearExpectations(&provider_observer_); + + PolicyBundle expected_policy_bundle; + expected_policy_bundle.Get(PolicyNamespace( + POLICY_DOMAIN_CHROME, std::string())) = expected_policy_map_.Clone(); + EXPECT_TRUE(expected_policy_bundle.Equals(provider_->policies())); + + // Enabled RestrictedManagedGuestSessionEnabled policy overrides + // certain policies. + EXPECT_CALL(provider_observer_, OnUpdatePolicy(provider_.get())) + .Times(AtLeast(1)); + cros_settings_helper_->SetBoolean( + chromeos::kRestrictedManagedGuestSessionEnabled, true); + device_local_account_policy_.payload() + .mutable_passwordmanagerenabled() + ->set_value(true); + device_local_account_policy_.payload() + .mutable_allowdeletingbrowserhistory() + ->set_value(false); + device_local_account_policy_.payload().mutable_arcenabled()->set_value(true); + InstallDeviceLocalAccountPolicy(kAccount1); + broker->core()->store()->Load(); + FlushDeviceSettings(); + Mock::VerifyAndClearExpectations(&provider_observer_); + + PolicyMap expected_policy_map_restricted = expected_policy_map_.Clone(); + expected_policy_map_restricted.Set( + key::kPasswordManagerEnabled, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(false), nullptr); + expected_policy_map_restricted.Set( + key::kAllowDeletingBrowserHistory, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(true), nullptr); + expected_policy_map_restricted.Set( + key::kArcEnabled, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(false), nullptr); + expected_policy_map_restricted.Set( + key::kCrostiniAllowed, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(false), nullptr); + expected_policy_map_restricted.Set( + key::kUserPluginVmAllowed, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(false), nullptr); + expected_policy_map_restricted.Set( + key::kNetworkFileSharesAllowed, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(false), nullptr); + expected_policy_map_restricted.Set( + key::kCACertificateManagementAllowed, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(false), nullptr); + expected_policy_map_restricted.Set( + key::kClientCertificateManagementAllowed, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(false), nullptr); + expected_policy_map_restricted.Set( + key::kEnableMediaRouter, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(false), nullptr); + expected_policy_map_restricted.Set( + key::kScreenCaptureAllowed, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(false), nullptr); + expected_policy_map_restricted.Set( + key::kKerberosEnabled, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(false), nullptr); + expected_policy_map_restricted.Set( + key::kUserBorealisAllowed, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(false), nullptr); + expected_policy_map_restricted.Set( + key::kDeletePrintJobHistoryAllowed, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(true), nullptr); + expected_policy_map_restricted.Set( + key::kLacrosAllowed, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(false), nullptr); + expected_policy_map_restricted.Set( + key::kLacrosSecondaryProfilesAllowed, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value(false), nullptr); + expected_policy_map_restricted.Set( + key::kLacrosAvailability, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE, + base::Value("lacros_disallowed"), nullptr); + + expected_policy_bundle.Get( + PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) = + expected_policy_map_restricted.Clone(); + EXPECT_TRUE(expected_policy_bundle.Equals(provider_->policies())); +} + class DeviceLocalAccountPolicyProviderLoadImmediateTest : public DeviceLocalAccountPolicyServiceTestBase { protected:
diff --git a/chrome/browser/ash/policy/core/device_policy_decoder_chromeos.cc b/chrome/browser/ash/policy/core/device_policy_decoder_chromeos.cc index 00154db..4b0e729 100644 --- a/chrome/browser/ash/policy/core/device_policy_decoder_chromeos.cc +++ b/chrome/browser/ash/policy/core/device_policy_decoder_chromeos.cc
@@ -1956,6 +1956,17 @@ policies); } } + + if (policy.has_device_restricted_managed_guest_session_enabled()) { + const em::DeviceRestrictedManagedGuestSessionEnabledProto& container( + policy.device_restricted_managed_guest_session_enabled()); + if (container.has_enabled()) { + policies->Set(key::kRestrictedManagedGuestSessionEnabled, + POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_CLOUD, base::Value(container.enabled()), + nullptr); + } + } } } // namespace
diff --git a/chrome/browser/ash/settings/device_settings_provider.cc b/chrome/browser/ash/settings/device_settings_provider.cc index 9739411..8bd8f35 100644 --- a/chrome/browser/ash/settings/device_settings_provider.cc +++ b/chrome/browser/ash/settings/device_settings_provider.cc
@@ -145,6 +145,7 @@ kReportOsUpdateStatus, kReportRunningKioskApp, kReportUploadFrequency, + kRestrictedManagedGuestSessionEnabled, kSamlLoginAuthenticationType, kServiceAccountIdentity, kSignedDataRoamingEnabled, @@ -1090,6 +1091,15 @@ new_values_cache); } } + + if (policy.has_device_restricted_managed_guest_session_enabled()) { + const em::DeviceRestrictedManagedGuestSessionEnabledProto& container( + policy.device_restricted_managed_guest_session_enabled()); + if (container.has_enabled()) { + new_values_cache->SetValue(kRestrictedManagedGuestSessionEnabled, + base::Value(container.enabled())); + } + } } void DecodeLogUploadPolicies(const em::ChromeDeviceSettingsProto& policy,
diff --git a/chrome/browser/ash/settings/device_settings_provider_unittest.cc b/chrome/browser/ash/settings/device_settings_provider_unittest.cc index dbf876c..130e964 100644 --- a/chrome/browser/ash/settings/device_settings_provider_unittest.cc +++ b/chrome/browser/ash/settings/device_settings_provider_unittest.cc
@@ -1311,4 +1311,23 @@ EXPECT_FALSE(value->GetBool()); } +TEST_F(DeviceSettingsProviderTest, DeviceRestrictedManagedGuestSessionEnabled) { + device_policy_->payload() + .mutable_device_restricted_managed_guest_session_enabled() + ->set_enabled(true); + BuildAndInstallDevicePolicy(); + EXPECT_EQ(base::Value(true), + *provider_->Get(kRestrictedManagedGuestSessionEnabled)); +} + +TEST_F(DeviceSettingsProviderTest, + DeviceRestrictedManagedGuestSessionDisabled) { + device_policy_->payload() + .mutable_device_restricted_managed_guest_session_enabled() + ->set_enabled(false); + BuildAndInstallDevicePolicy(); + EXPECT_EQ(base::Value(false), + *provider_->Get(kRestrictedManagedGuestSessionEnabled)); +} + } // namespace ash
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc index 0f388a1..8ac7b7f 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -1166,6 +1166,30 @@ return completion_observer.failed_data_types(); } + void ExpectRemoveLoginsByURLAndTime( + password_manager::MockPasswordStore* store) { + EXPECT_CALL(*store, RemoveLoginsByURLAndTime) + .WillOnce( + testing::WithArgs<3, 4>([](auto callback, auto sync_callback) { + std::move(callback).Run(); + if (sync_callback) + std::move(sync_callback).Run(false); + })); + } + + void ExpectRemoveLoginsByURLAndTimeWithFilter( + password_manager::MockPasswordStore* store, + base::RepeatingCallback<bool(const GURL&)> filter) { + EXPECT_CALL(*store, RemoveLoginsByURLAndTime(ProbablySameFilter(filter), _, + _, _, _)) + .WillOnce( + testing::WithArgs<3, 4>([](auto callback, auto sync_callback) { + std::move(callback).Run(); + if (sync_callback) + std::move(sync_callback).Run(false); + })); + } + void BlockUntilOriginDataRemoved( const base::Time& delete_begin, const base::Time& delete_end, @@ -1418,7 +1442,7 @@ // Expect that passwords will be deleted, as they do not depend // on |prefs::kAllowDeletingBrowserHistory|. RemovePasswordsTester tester(GetProfile()); - EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)); + ExpectRemoveLoginsByURLAndTime(tester.profile_store()); uint64_t removal_mask = constants::DATA_TYPE_HISTORY | constants::DATA_TYPE_PASSWORDS; @@ -1994,9 +2018,7 @@ base::RepeatingCallback<bool(const GURL&)> filter = BrowsingDataFilterBuilder::BuildNoopFilter(); - EXPECT_CALL(*tester.profile_store(), - RemoveLoginsByURLAndTimeImpl(ProbablySameFilter(filter), _, _)) - .WillOnce(Return(password_manager::PasswordStoreChangeList())); + ExpectRemoveLoginsByURLAndTimeWithFilter(tester.profile_store(), filter); BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), constants::DATA_TYPE_PASSWORDS, false); @@ -2012,9 +2034,7 @@ builder->AddRegisterableDomain(kTestRegisterableDomain1); base::RepeatingCallback<bool(const GURL&)> filter = builder->BuildUrlFilter(); - EXPECT_CALL(*tester.profile_store(), - RemoveLoginsByURLAndTimeImpl(ProbablySameFilter(filter), _, _)) - .WillOnce(Return(password_manager::PasswordStoreChangeList())); + ExpectRemoveLoginsByURLAndTimeWithFilter(tester.profile_store(), filter); BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), constants::DATA_TYPE_PASSWORDS, std::move(builder)); @@ -2040,8 +2060,7 @@ base::RepeatingCallback<bool(const GURL&)> empty_filter = BrowsingDataFilterBuilder::BuildNoopFilter(); - EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)) - .WillOnce(Return(password_manager::PasswordStoreChangeList())); + ExpectRemoveLoginsByURLAndTime(tester.profile_store()); EXPECT_CALL(*tester.profile_store(), DisableAutoSignInForOriginsImpl(ProbablySameFilter(empty_filter))) .WillOnce(Return(password_manager::PasswordStoreChangeList())); @@ -3081,12 +3100,9 @@ RemovePasswordsByTimeOnly_WithAccountStore) { RemovePasswordsTester tester(GetProfile()); - EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)) - .WillOnce(Return(password_manager::PasswordStoreChangeList())); - + ExpectRemoveLoginsByURLAndTime(tester.profile_store()); // Only DATA_TYPE_PASSWORDS is cleared. Accounts passwords are not affected. - EXPECT_CALL(*tester.account_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)) - .Times(0); + EXPECT_CALL(*tester.account_store(), RemoveLoginsByURLAndTime).Times(0); BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), constants::DATA_TYPE_PASSWORDS, false); @@ -3096,11 +3112,8 @@ RemoveAccountPasswordsByTimeOnly_WithAccountStore) { RemovePasswordsTester tester(GetProfile()); - EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)) - .Times(0); - - EXPECT_CALL(*tester.account_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)) - .WillOnce(Return(password_manager::PasswordStoreChangeList())); + EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTime).Times(0); + ExpectRemoveLoginsByURLAndTime(tester.account_store()); // For the account store, the remover delegate also waits until all the // deletions have propagated to the Sync server. Pretend that happens // immediately. @@ -3115,19 +3128,13 @@ RemoveAccountPasswordsByTimeOnly_WithAccountStore_Failure) { RemovePasswordsTester tester(GetProfile()); - EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)) - .Times(0); - - EXPECT_CALL(*tester.account_store(), RemoveLoginsByURLAndTimeImpl(_, _, _)) - .WillOnce(Return(password_manager::PasswordStoreChangeList())); + EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTime).Times(0); + ExpectRemoveLoginsByURLAndTime(tester.account_store()); // For the account store, the remover delegate also waits until all the // deletions have propagated to the Sync server. In this test, that never // happens. EXPECT_CALL(*tester.account_metadata_store(), HasUnsyncedDeletions()) .WillRepeatedly(Return(true)); - // Bypass the (usually 30-second) timeout until the PasswordStore reports - // failure. - tester.account_store()->SetSyncTaskTimeoutForTest(base::TimeDelta()); uint64_t failed_data_types = BlockUntilBrowsingDataRemoved( base::Time(), base::Time::Max(), constants::DATA_TYPE_ACCOUNT_PASSWORDS,
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index d0f4e61..4ea5a46 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -5857,7 +5857,7 @@ if (enterprise_connectors::ContentAnalysisDelegate::IsEnabled( profile, url, &dialog_data, enterprise_connectors::AnalysisConnector::BULK_DATA_ENTRY)) { - dialog_data.text.push_back(base::UTF8ToUTF16(data)); + dialog_data.text.push_back(data); enterprise_connectors::ContentAnalysisDelegate::CreateForWebContents( web_contents, std::move(dialog_data), base::BindOnce(
diff --git a/chrome/browser/component_updater/cros_component_installer_chromeos.cc b/chrome/browser/component_updater/cros_component_installer_chromeos.cc index 9dcef12..9943e59 100644 --- a/chrome/browser/component_updater/cros_component_installer_chromeos.cc +++ b/chrome/browser/component_updater/cros_component_installer_chromeos.cc
@@ -37,7 +37,7 @@ const ComponentConfig kConfigs[] = { {"epson-inkjet-printer-escpr", ComponentConfig::PolicyType::kEnvVersion, "5.0", "1913a5e0a6cad30b6f03e176177e0d7ed62c5d6700a9c66da556d7c3f5d6a47e"}, - {"cros-termina", ComponentConfig::PolicyType::kEnvVersion, "900.1", + {"cros-termina", ComponentConfig::PolicyType::kEnvVersion, "930.1", "e9d960f84f628e1f42d05de4046bb5b3154b6f1f65c08412c6af57a29aecaffb"}, {"rtanalytics-light", ComponentConfig::PolicyType::kEnvVersion, "92.0", "69f09d33c439c2ab55bbbe24b47ab55cb3f6c0bd1f1ef46eefea3216ec925038"},
diff --git a/chrome/browser/content_settings/chrome_content_settings_utils.cc b/chrome/browser/content_settings/chrome_content_settings_utils.cc index d70afb8..7f6b81f 100644 --- a/chrome/browser/content_settings/chrome_content_settings_utils.cc +++ b/chrome/browser/content_settings/chrome_content_settings_utils.cc
@@ -56,15 +56,9 @@ case ContentSettingsType::FILE_HANDLING: return web_app::GetFileTypeAssociationsHandledByWebAppsForDisplay(profile, url); - break; - case ContentSettingsType::ADS: - return l10n_util::GetStringUTF16(IDS_PAGE_INFO_PERMISSION_ADS_SUBTITLE); - break; default: - break; + return {}; } - - return {}; } #endif
diff --git a/chrome/browser/content_settings/content_settings_browsertest.cc b/chrome/browser/content_settings/content_settings_browsertest.cc index 87ee96b..d392fe29a 100644 --- a/chrome/browser/content_settings/content_settings_browsertest.cc +++ b/chrome/browser/content_settings/content_settings_browsertest.cc
@@ -1347,9 +1347,49 @@ content::test::PrerenderTestHelper prerender_test_helper_; }; -// Flaky on all platforms, see https://crbug.com/1225428 +// Used to wait for a prerendering page to set a cookie. +class PrerenderCookieObserver : public content::WebContentsObserver { + public: + explicit PrerenderCookieObserver(content::WebContents* web_contents) + : content::WebContentsObserver(web_contents) {} + ~PrerenderCookieObserver() override = default; + + void OnCookiesAccessed(content::NavigationHandle* navigation_handle, + const content::CookieAccessDetails& details) override { + bool is_in_primary_frame = + navigation_handle->GetParentFrame() + ? navigation_handle->GetParentFrame()->GetPage().IsPrimary() + : navigation_handle->IsInPrimaryMainFrame(); + if (is_in_primary_frame) { + cookie_accessed_in_primary_page_ = true; + } else { + run_loop_.Quit(); + } + } + + void OnCookiesAccessed(content::RenderFrameHost* rfh, + const content::CookieAccessDetails& details) override { + if (rfh->GetPage().IsPrimary()) { + cookie_accessed_in_primary_page_ = true; + } else { + run_loop_.Quit(); + } + } + + bool CookieAccessedByPrimaryPage() const { + return cookie_accessed_in_primary_page_; + } + + // Waits for the prerendering page to set a cookie. + void Wait() { run_loop_.Run(); } + + private: + bool cookie_accessed_in_primary_page_ = false; + base::RunLoop run_loop_; +}; + IN_PROC_BROWSER_TEST_F(ContentSettingsWithPrerenderingBrowserTest, - DISABLED_PrerenderingPageSetsCookie) { + PrerenderingPageSetsCookie) { const GURL main_url = embedded_test_server()->GetURL("/empty.html"); const GURL prerender_url = embedded_test_server()->GetURL("/set_cookie_header.html"); @@ -1360,22 +1400,28 @@ GetWebContents()->GetMainFrame()); ASSERT_FALSE(main_pscs->IsContentAllowed(ContentSettingsType::COOKIES)); - CookieChangeObserver cookie_change_observer(GetWebContents()); - prerender_test_helper().AddPrerenderAsync(prerender_url); - cookie_change_observer.Wait(); - prerender_test_helper().WaitForPrerenderLoadCompletion(prerender_url); - int host_id = prerender_test_helper().GetHostForUrl(prerender_url); - content::RenderFrameHost* prerender_frame = - prerender_test_helper().GetPrerenderedMainFrameHost(host_id); - EXPECT_NE(prerender_frame, nullptr); + { + PrerenderCookieObserver cookie_observer(GetWebContents()); + prerender_test_helper().AddPrerender(prerender_url); + int host_id = prerender_test_helper().GetHostForUrl(prerender_url); + content::RenderFrameHost* prerender_frame = + prerender_test_helper().GetPrerenderedMainFrameHost(host_id); + EXPECT_NE(prerender_frame, nullptr); + // Ensure notification for cookie access by prerendering page has been sent. + cookie_observer.Wait(); - auto* prerender_pscs = - PageSpecificContentSettings::GetForFrame(prerender_frame); - EXPECT_TRUE(prerender_pscs->IsContentAllowed(ContentSettingsType::COOKIES)); - EXPECT_EQ(prerender_pscs->allowed_local_shared_objects().GetObjectCount(), - 1u); - EXPECT_FALSE(main_pscs->IsContentAllowed(ContentSettingsType::COOKIES)); - EXPECT_EQ(main_pscs->allowed_local_shared_objects().GetObjectCount(), 0u); + auto* prerender_pscs = + PageSpecificContentSettings::GetForFrame(prerender_frame); + EXPECT_TRUE(prerender_pscs->IsContentAllowed(ContentSettingsType::COOKIES)); + EXPECT_EQ(prerender_pscs->allowed_local_shared_objects().GetObjectCount(), + 1u); + // Between when the cookie was set by the prerendering page and now, the + // main page might have accessed the cookie (for instance, when sending a + // request for a favicon) - check for the appropriate value based on + // observed behavior. + EXPECT_EQ(main_pscs->allowed_local_shared_objects().GetObjectCount(), + cookie_observer.CookieAccessedByPrimaryPage() ? 1u : 0u); + } prerender_test_helper().NavigatePrimaryPage(prerender_url); @@ -1407,7 +1453,7 @@ content::TestNavigationManager navigation_manager(GetWebContents(), iframe_url); - CookieChangeObserver cookie_observer(GetWebContents()); + PrerenderCookieObserver cookie_observer(GetWebContents()); EXPECT_TRUE(content::ExecJs( prerender_frame, content::JsReplace("const iframe = document.createElement('iframe');" @@ -1424,6 +1470,10 @@ EXPECT_TRUE(prerender_pscs->IsContentAllowed(ContentSettingsType::COOKIES)); EXPECT_EQ(prerender_pscs->allowed_local_shared_objects().GetObjectCount(), 1u); - EXPECT_FALSE(main_pscs->IsContentAllowed(ContentSettingsType::COOKIES)); - EXPECT_EQ(main_pscs->allowed_local_shared_objects().GetObjectCount(), 0u); + // Between when the cookie was set by the prerendering page and now, the + // main page might have accessed the cookie (for instance, when sending a + // request for a favicon) - check for the appropriate value based on observed + // behavior. + EXPECT_EQ(main_pscs->allowed_local_shared_objects().GetObjectCount(), + cookie_observer.CookieAccessedByPrimaryPage() ? 1u : 0u); }
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc index 979f9b8..93042fff 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc
@@ -10,10 +10,7 @@ #include <utility> #include "base/feature_list.h" -#include "base/files/file.h" #include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/platform_file.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/metrics/histogram_functions.h" @@ -176,8 +173,8 @@ std::fill(result_.text_results.begin(), result_.text_results.end(), true); int64_t content_size = 0; - for (const std::u16string& entry : data_.text) - content_size += (entry.size() * sizeof(char16_t)); + for (const std::string& entry : data_.text) + content_size += entry.size(); ReportAnalysisConnectorWarningBypass( profile_, url_, "Text data", std::string(), "text/plain", @@ -392,8 +389,8 @@ BinaryUploadService::Result result, enterprise_connectors::ContentAnalysisResponse response) { int64_t content_size = 0; - for (const std::u16string& entry : data_.text) - content_size += (entry.size() * sizeof(char16_t)); + for (const std::string& entry : data_.text) + content_size += entry.size(); RecordDeepScanMetrics(access_point_, base::TimeTicks::Now() - upload_start_time_, content_size, result, response); @@ -503,8 +500,8 @@ void ContentAnalysisDelegate::PrepareTextRequest() { std::string full_text; - for (const auto& text : data_.text) - full_text.append(base::UTF16ToUTF8(text)); + for (const std::string& text : data_.text) + full_text.append(text); // The request is considered complete if there is no text or if the text is // too small compared to the minimum size. This means a minimum_data_size of
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h index d76f2d3..cc78a14 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h
@@ -72,8 +72,8 @@ // URL of the page that is to receive sensitive data. GURL url; - // Text data to scan, such as plain text, URLs, HTML content, etc. - std::vector<std::u16string> text; + // UTF-8 encoded text data to scan, such as plain text, URLs, HTML, etc. + std::vector<std::string> text; // List of files to scan. std::vector<base::FilePath> paths;
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc index decae58..8993a4c 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc
@@ -43,8 +43,8 @@ constexpr char kScanId1[] = "scan id 1"; constexpr char kScanId2[] = "scan id 2"; -std::u16string text() { - return base::UTF8ToUTF16(std::string(100, 'a')); +std::string text() { + return std::string(100, 'a'); } class FakeBinaryUploadService : public BinaryUploadService { @@ -469,8 +469,7 @@ BinaryUploadService::Result::SUCCESS, response); // The DLP verdict means an event should be reported. The content size is - // equal to the length of the concatenated texts (2 * 100 * 'a') times - // 2 since they are wide characters ((100 + 100) * 2 = 400). + // equal to the length of the concatenated texts (2 * 100 * 'a'). validator.ExpectSensitiveDataEvent( /*url*/ "about:blank", /*filename*/ "Text data", @@ -479,7 +478,7 @@ /*trigger*/ SafeBrowsingPrivateEventRouter::kTriggerWebContentUpload, /*dlp_verdict*/ *result, /*mimetype*/ TextMimeTypes(), - /*size*/ 400, + /*size*/ 200, /*result*/ safe_browsing::EventResultToString(safe_browsing::EventResult::BLOCKED), /*username*/ kUserName,
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_unittest.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_unittest.cc index 9d4546c..c6934fd6 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_unittest.cc +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_unittest.cc
@@ -708,7 +708,7 @@ ASSERT_TRUE(ContentAnalysisDelegate::IsEnabled(profile(), url, &data, BULK_DATA_ENTRY)); - data.text.emplace_back(base::UTF8ToUTF16(large_text())); + data.text.emplace_back(large_text()); bool called = false; ScanUpload(contents(), std::move(data), @@ -733,8 +733,8 @@ ASSERT_TRUE(ContentAnalysisDelegate::IsEnabled(profile(), url, &data, BULK_DATA_ENTRY)); - data.text.emplace_back(base::UTF8ToUTF16(large_text())); - data.text.emplace_back(base::UTF8ToUTF16(large_text())); + data.text.emplace_back(large_text()); + data.text.emplace_back(large_text()); bool called = false; ScanUpload(contents(), std::move(data), @@ -762,8 +762,8 @@ // Because the strings are small, they are exempt from scanning and will be // allowed even when a negative verdict is mocked. - data.text.emplace_back(base::UTF8ToUTF16(small_text())); - data.text.emplace_back(base::UTF8ToUTF16(small_text())); + data.text.emplace_back(small_text()); + data.text.emplace_back(small_text()); SetDLPResponse(FakeContentAnalysisDelegate::DlpResponse( ContentAnalysisResponse::Result::SUCCESS, "rule", TriggeredRule::BLOCK)); @@ -1093,7 +1093,7 @@ ASSERT_TRUE(ContentAnalysisDelegate::IsEnabled(profile(), url, &data, BULK_DATA_ENTRY)); - data.text.emplace_back(base::UTF8ToUTF16(large_text())); + data.text.emplace_back(large_text()); CreateFilesForTest( {FILE_PATH_LITERAL("foo.doc"), FILE_PATH_LITERAL("bar.doc")}, &data); @@ -1124,8 +1124,8 @@ ASSERT_TRUE(ContentAnalysisDelegate::IsEnabled(profile(), url, &data, BULK_DATA_ENTRY)); - data.text.emplace_back(base::UTF8ToUTF16(large_text())); - data.text.emplace_back(base::UTF8ToUTF16(large_text())); + data.text.emplace_back(large_text()); + data.text.emplace_back(large_text()); CreateFilesForTest( {FILE_PATH_LITERAL("foo.doc"), FILE_PATH_LITERAL("bar.doc")}, &data); @@ -1156,8 +1156,8 @@ ASSERT_TRUE(ContentAnalysisDelegate::IsEnabled(profile(), url, &data, BULK_DATA_ENTRY)); - data.text.emplace_back(base::UTF8ToUTF16(large_text())); - data.text.emplace_back(base::UTF8ToUTF16(large_text())); + data.text.emplace_back(large_text()); + data.text.emplace_back(large_text()); SetDLPResponse(FakeContentAnalysisDelegate::DlpResponse( ContentAnalysisResponse::Result::SUCCESS, "rule", TriggeredRule::BLOCK)); @@ -1186,7 +1186,7 @@ ASSERT_TRUE(ContentAnalysisDelegate::IsEnabled(profile(), url, &data, BULK_DATA_ENTRY)); - data.text.emplace_back(base::UTF8ToUTF16(large_text())); + data.text.emplace_back(large_text()); CreateFilesForTest({FILE_PATH_LITERAL("foo.doc"), FILE_PATH_LITERAL("foo_fail_malware_1.doc"), FILE_PATH_LITERAL("foo_fail_malware_2.doc"), @@ -1245,7 +1245,7 @@ ASSERT_TRUE( ContentAnalysisDelegate::IsEnabled(profile(), url, &data, FILE_ATTACHED)); - data.text.emplace_back(u"dlp_text"); + data.text.emplace_back("dlp_text"); CreateFilesForTest({FILE_PATH_LITERAL("foo_fail_malware_0.doc"), FILE_PATH_LITERAL("foo_fail_malware_1.doc"), FILE_PATH_LITERAL("foo_fail_malware_2.doc"),
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog_browsertest.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog_browsertest.cc index 1885b1d..7e2045f 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog_browsertest.cc +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog_browsertest.cc
@@ -74,8 +74,8 @@ }] })"; -std::u16string text() { - return base::UTF8ToUTF16(std::string(100, 'a')); +std::string text() { + return std::string(100, 'a'); } // Tests the behavior of the dialog in the following ways:
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc index 89f5bba4..fd6b807 100644 --- a/chrome/browser/extensions/extension_browsertest.cc +++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -359,11 +359,23 @@ // This dir will contain all files for the Service Worker based extension. base::FilePath temp_extension_container; - if (!base::CreateTemporaryDirInDir(temp_dir_.GetPath(), - base::FilePath::StringType(), + base::FilePath temp_dir; + // Tests that have a PRE_ stage that are being converted to use + // a service worker-based extension need to exist in a temporary + // directory that persists after the test fixture is destroyed. + // The test bots are configured to use a unique temp directory that's + // cleaned up after the tests run, so this won't pollute the system + // tmp directory. + if (GetTestPreCount() == 0) { + temp_dir = temp_dir_.GetPath(); + } else if (!base::GetTempDir(&temp_dir)) { + ADD_FAILURE() << "Could not get temporary dir for test."; + return false; + } + if (!base::CreateTemporaryDirInDir(temp_dir, base::FilePath::StringType(), &temp_extension_container)) { ADD_FAILURE() << "Could not create temporary dir for test under " - << temp_dir_.GetPath(); + << temp_dir; return false; }
diff --git a/chrome/browser/extensions/extension_context_menu_browsertest.cc b/chrome/browser/extensions/extension_context_menu_browsertest.cc index d4fef05..2a62bab19 100644 --- a/chrome/browser/extensions/extension_context_menu_browsertest.cc +++ b/chrome/browser/extensions/extension_context_menu_browsertest.cc
@@ -96,7 +96,7 @@ base::ScopedObservation<StateStore, StateStore::TestObserver> observed_{this}; }; -constexpr char kPersistentExtensionId[] = "cmgkkmeeoiceijkpmaabbmpgnkpaaela"; +constexpr char kPersistentExtensionId[] = "knldjmfmopnpolahpmmgbagdohdnhkik"; } // namespace @@ -312,13 +312,6 @@ {.allow_in_incognito = true}); } - base::FilePath GetDirForContext(base::StringPiece subdirectory) { - const char* context_dir = GetParam() == ContextType::kServiceWorker - ? "service_worker" - : "event_page"; - return GetRootDir().AppendASCII(subdirectory).AppendASCII(context_dir); - } - // This creates an extension that starts |enabled| and then switches to // |!enabled|. void TestEnabledContextMenu(bool enabled) { @@ -397,9 +390,8 @@ IN_PROC_BROWSER_TEST_P(ExtensionContextMenuLazyTest, PRE_Persistent) { StateStoreObserver observer(profile()); ResultCatcher catcher; - base::FilePath path = - GetDirForContext("persistent").AddExtensionASCII(".crx"); - const extensions::Extension* extension = LoadExtension(path); + const extensions::Extension* extension = + LoadContextMenuExtension("persistent"); ASSERT_TRUE(extension); // Wait for the extension to tell us it's been installed and the
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index e198f67..55d87e6 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1040,11 +1040,6 @@ "expiry_milestone": 99 }, { - "name": "dice-web-signin-interception", - "owners": [ "droger", "my-chrome-everywhere@google.com" ], - "expiry_milestone": 92 - }, - { "name": "disable-accelerated-2d-canvas", "owners": [ "fserb" ], "expiry_milestone": -1
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 919b4f7..fecc01c 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -5310,12 +5310,6 @@ "Adds image decoding support for the JPEG XL image format."; #endif // BUILDFLAG(ENABLE_JXL_DECODER) -#if BUILDFLAG(ENABLE_DICE_SUPPORT) -const char kDiceWebSigninInterceptionName[] = "Dice Web-Signin Interception"; -const char kDiceWebSigninInterceptionDescription[] = - "If enabled, Chrome may promote profile creation after signin on the web."; -#endif - #if BUILDFLAG(ENABLE_NACL) const char kNaclName[] = "Native Client"; const char kNaclDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index a6a1e2d..9da2ec5 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -3091,11 +3091,6 @@ extern const char kEnableJXLDescription[]; #endif // BUILDFLAG(ENABLE_JXL_DECODER) -#if BUILDFLAG(ENABLE_DICE_SUPPORT) -extern const char kDiceWebSigninInterceptionName[]; -extern const char kDiceWebSigninInterceptionDescription[]; -#endif // ENABLE_DICE_SUPPORT - #if BUILDFLAG(ENABLE_NACL) extern const char kNaclName[]; extern const char kNaclDescription[];
diff --git a/chrome/browser/metrics/perf/random_selector.cc b/chrome/browser/metrics/perf/random_selector.cc index eeab449..484c793 100644 --- a/chrome/browser/metrics/perf/random_selector.cc +++ b/chrome/browser/metrics/perf/random_selector.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/metrics/perf/random_selector.h" +#include <ostream> + #include "base/check_op.h" #include "base/notreached.h" #include "base/rand_util.h"
diff --git a/chrome/browser/password_manager/multi_profile_credentials_filter.cc b/chrome/browser/password_manager/multi_profile_credentials_filter.cc index be31eec..79877450 100644 --- a/chrome/browser/password_manager/multi_profile_credentials_filter.cc +++ b/chrome/browser/password_manager/multi_profile_credentials_filter.cc
@@ -4,10 +4,8 @@ #include "chrome/browser/password_manager/multi_profile_credentials_filter.h" -#include "base/feature_list.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/signin/dice_web_signin_interceptor.h" -#include "chrome/browser/signin/signin_features.h" #include "components/password_manager/core/browser/password_sync_util.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -28,8 +26,6 @@ return true; // This happens in incognito. if (!password_manager::sync_util::IsGaiaCredentialPage(form.signon_realm)) return true; - if (!base::FeatureList::IsEnabled(kDiceWebSigninInterceptionFeature)) - return true; // Note: this function is only called for "Save" bubbles, but not for "Update" // bubbles.
diff --git a/chrome/browser/password_manager/multi_profile_credentials_filter_unittest.cc b/chrome/browser/password_manager/multi_profile_credentials_filter_unittest.cc index 7d0e7cd6..2f2df4d 100644 --- a/chrome/browser/password_manager/multi_profile_credentials_filter_unittest.cc +++ b/chrome/browser/password_manager/multi_profile_credentials_filter_unittest.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/callback.h" #include "base/callback_helpers.h" -#include "base/test/scoped_feature_list.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile_attributes_entry.h" #include "chrome/browser/profiles/profile_attributes_storage.h" @@ -17,7 +16,6 @@ #include "chrome/browser/signin/chrome_signin_client_test_util.h" #include "chrome/browser/signin/dice_web_signin_interceptor.h" #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" -#include "chrome/browser/signin/signin_features.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/browser_with_test_window_test.h" @@ -74,7 +72,6 @@ public: MultiProfileCredentialsFilterTest() : sync_filter_(&test_password_manager_client_, GetSyncServiceCallback()) { - feature_list_.InitAndEnableFeature(kDiceWebSigninInterceptionFeature); } password_manager::SyncCredentialsFilter::SyncServiceFactoryFunction @@ -151,7 +148,6 @@ protected: const syncer::SyncService* sync_service() { return &sync_service_; } - base::test::ScopedFeatureList feature_list_; network::TestURLLoaderFactory test_url_loader_factory_; TestPasswordManagerClient test_password_manager_client_; std::unique_ptr<IdentityTestEnvironmentProfileAdaptor>
diff --git a/chrome/browser/password_manager/password_manager_signin_intercept_test_helper.cc b/chrome/browser/password_manager/password_manager_signin_intercept_test_helper.cc index 51438b8..5492d309 100644 --- a/chrome/browser/password_manager/password_manager_signin_intercept_test_helper.cc +++ b/chrome/browser/password_manager/password_manager_signin_intercept_test_helper.cc
@@ -15,7 +15,6 @@ #include "chrome/browser/signin/dice_web_signin_interceptor.h" #include "chrome/browser/signin/dice_web_signin_interceptor_factory.h" #include "chrome/browser/signin/identity_manager_factory.h" -#include "chrome/browser/signin/signin_features.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/common/pref_names.h" @@ -46,7 +45,6 @@ PasswordManagerSigninInterceptTestHelper( net::test_server::EmbeddedTestServer* https_test_server) : https_test_server_(https_test_server) { - feature_list_.InitAndEnableFeature(kDiceWebSigninInterceptionFeature); } PasswordManagerSigninInterceptTestHelper::
diff --git a/chrome/browser/password_manager/password_manager_signin_intercept_test_helper.h b/chrome/browser/password_manager/password_manager_signin_intercept_test_helper.h index ed64dee..86e7b8bc 100644 --- a/chrome/browser/password_manager/password_manager_signin_intercept_test_helper.h +++ b/chrome/browser/password_manager/password_manager_signin_intercept_test_helper.h
@@ -8,7 +8,6 @@ #include <string> #include "base/memory/scoped_refptr.h" -#include "base/test/scoped_feature_list.h" #include "components/password_manager/core/browser/test_password_store.h" #include "google_apis/gaia/core_account_id.h" @@ -63,7 +62,6 @@ std::string gaia_id() const; private: - base::test::ScopedFeatureList feature_list_; const net::test_server::EmbeddedTestServer* https_test_server_; };
diff --git a/chrome/browser/performance_manager/policies/bfcache_policy_browsertest.cc b/chrome/browser/performance_manager/policies/bfcache_policy_browsertest.cc index c061d76..f9230c7 100644 --- a/chrome/browser/performance_manager/policies/bfcache_policy_browsertest.cc +++ b/chrome/browser/performance_manager/policies/bfcache_policy_browsertest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <memory> +#include <string> #include "base/callback_forward.h" #include "base/files/file_path.h" @@ -14,6 +15,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/performance_manager/public/features.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/visibility.h" #include "content/public/browser/web_contents.h" @@ -28,19 +30,36 @@ namespace { +struct PolicyTestParams { + const std::string scenario; + bool enable_policy = false; + bool enable_trim_on_moderate_pressure = false; +}; + class BFCachePolicyBrowserTest : public InProcessBrowserTest, - public ::testing::WithParamInterface<std::string> { + public ::testing::WithParamInterface<PolicyTestParams> { public: ~BFCachePolicyBrowserTest() override = default; void SetUpCommandLine(base::CommandLine* command_line) override { - feature_list_.InitWithFeaturesAndParameters( - {{features::kBackForwardCache, - {{"TimeToLiveInBackForwardCacheInSeconds", "3600"}, - {"ignore_outstanding_network_request_for_testing", "true"}}}}, - {features::kBackForwardCacheMemoryControls}); + EnableFeature(::features::kBackForwardCache, + {{"TimeToLiveInBackForwardCacheInSeconds", "3600"}, + {"ignore_outstanding_network_request_for_testing", "true"}}); + DisableFeature(::features::kBackForwardCacheMemoryControls); + if (GetParam().enable_policy) { + EnableFeature( + performance_manager::features::kBFCachePerformanceManagerPolicy, + {{"flush_on_moderate_pressure", + GetParam().enable_trim_on_moderate_pressure ? "true" : "false"}}); + } else { + DisableFeature( + performance_manager::features::kBFCachePerformanceManagerPolicy); + } + + feature_list_.InitWithFeaturesAndParameters(enabled_features_, + disabled_features_); InProcessBrowserTest::SetUpCommandLine(command_line); } @@ -51,6 +70,15 @@ } protected: + void EnableFeature(const base::Feature& feature, + const base::FieldTrialParams& params) { + enabled_features_.emplace_back(feature, params); + } + + void DisableFeature(const base::Feature& feature) { + disabled_features_.emplace_back(feature); + } + content::WebContents* web_contents() const { return browser()->tab_strip_model()->GetActiveWebContents(); } @@ -59,7 +87,22 @@ return web_contents()->GetMainFrame(); } + void VerifyEvictionExpectation(bool should_be_evicted, + content::RenderFrameHostWrapper& rfh) { + if (should_be_evicted) { + // When the page is evicted the RenderFrame will be deleted. + rfh.WaitUntilRenderFrameDeleted(); + } else { + EXPECT_EQ(rfh->GetLifecycleState(), + content::RenderFrameHost::LifecycleState::kInBackForwardCache); + } + } + + private: base::test::ScopedFeatureList feature_list_; + std::vector<base::test::ScopedFeatureList::FeatureAndParams> + enabled_features_; + std::vector<base::Feature> disabled_features_; }; } // namespace @@ -83,12 +126,12 @@ EXPECT_EQ(rfh_a->GetLifecycleState(), content::RenderFrameHost::LifecycleState::kInBackForwardCache); - if (GetParam() == "FlushWhenTabBackgrounded") { + if (GetParam().scenario == "FlushWhenTabBackgrounded") { // Backgrounding the page will evict it from BFCache. web_contents()->WasHidden(); - // When the page is evicted the RenderFrame will be deleted. - rfh_a.WaitUntilRenderFrameDeleted(); - } else if (GetParam() == "FlushWhenTabBackgroundDuringNavigation") { + VerifyEvictionExpectation( + /* should_be_evicted = */ GetParam().enable_policy, rfh_a); + } else if (GetParam().scenario == "FlushWhenTabBackgroundDuringNavigation") { web_contents()->GetController().GoBack(); // Make the tab backgrounded before the back navigation completes. |rfh_a| // will become the active frame and the cache will be flushed (i.e. |rfh_b| @@ -96,27 +139,48 @@ web_contents()->WasHidden(); EXPECT_TRUE(WaitForLoadStop(web_contents())); EXPECT_EQ(rfh_a.get(), top_frame_host()); - rfh_b.WaitUntilRenderFrameDeleted(); - } else if (GetParam() == "FlushOnModerateMemoryPressure") { + VerifyEvictionExpectation( + /* should_be_evicted = */ GetParam().enable_policy, rfh_b); + } else if (GetParam().scenario == "FlushOnModerateMemoryPressure") { // A moderate memory pressure signal will evict the page from BFCache. fake_memory_pressure_monitor.SetAndNotifyMemoryPressure( base::MemoryPressureListener::MemoryPressureLevel:: MEMORY_PRESSURE_LEVEL_MODERATE); - // When the page is evicted the RenderFrame will be deleted. - rfh_a.WaitUntilRenderFrameDeleted(); - } else if (GetParam() == "FlushOnCriticalMemoryPressure") { + VerifyEvictionExpectation( + /* should_be_evicted = */ (GetParam().enable_policy && + GetParam().enable_trim_on_moderate_pressure), + rfh_a); + } else if (GetParam().scenario == "FlushOnCriticalMemoryPressure") { // A critical memory pressure signal will evict the page from BFCache. fake_memory_pressure_monitor.SetAndNotifyMemoryPressure( base::MemoryPressureListener::MemoryPressureLevel:: MEMORY_PRESSURE_LEVEL_CRITICAL); - // When the page is evicted the RenderFrame will be deleted. - rfh_a.WaitUntilRenderFrameDeleted(); + VerifyEvictionExpectation( + /* should_be_evicted = */ GetParam().enable_policy, rfh_a); } } -std::vector<std::string> BFCachePolicyBrowserTestValues() { - return {"FlushWhenTabBackgrounded", "FlushWhenTabBackgroundDuringNavigation", - "FlushOnModerateMemoryPressure", "FlushOnCriticalMemoryPressure"}; +std::vector<PolicyTestParams> BFCachePolicyBrowserTestValues() { + const std::vector<std::string> kTestScenarios = { + "FlushWhenTabBackgrounded", "FlushWhenTabBackgroundDuringNavigation", + "FlushOnModerateMemoryPressure", "FlushOnCriticalMemoryPressure"}; + std::vector<PolicyTestParams> test_cases; + + for (const auto& test_scenario : kTestScenarios) { + test_cases.push_back({.scenario = test_scenario, .enable_policy = false}); + + // Test the policy with |flush_on_moderate_pressure| enabled. + test_cases.push_back({.scenario = test_scenario, + .enable_policy = true, + .enable_trim_on_moderate_pressure = true}); + + // Test the policy with |flush_on_moderate_pressure| disabled. + test_cases.push_back({.scenario = test_scenario, + .enable_policy = true, + .enable_trim_on_moderate_pressure = false}); + } + + return test_cases; } INSTANTIATE_TEST_SUITE_P(All,
diff --git a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h index b37461b..31d377ce 100644 --- a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h +++ b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h
@@ -17,7 +17,6 @@ #include "components/reporting/proto/record.pb.h" #include "components/reporting/proto/record_constants.pb.h" #include "components/reporting/util/status.h" -#include "components/reporting/util/status_macros.h" #include "components/reporting/util/statusor.h" #include "components/reporting/util/task_runner_context.h" #include "net/base/backoff_entry.h"
diff --git a/chrome/browser/policy/messaging_layer/upload/record_handler_impl.h b/chrome/browser/policy/messaging_layer/upload/record_handler_impl.h index 669e211..3f5c50b 100644 --- a/chrome/browser/policy/messaging_layer/upload/record_handler_impl.h +++ b/chrome/browser/policy/messaging_layer/upload/record_handler_impl.h
@@ -18,7 +18,6 @@ #include "components/reporting/proto/record.pb.h" #include "components/reporting/util/shared_queue.h" #include "components/reporting/util/status.h" -#include "components/reporting/util/status_macros.h" #include "components/reporting/util/statusor.h" #include "components/reporting/util/task_runner_context.h" #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/chrome/browser/predictors/predictor_database.cc b/chrome/browser/predictors/predictor_database.cc index 2c85006dd..55ee5863 100644 --- a/chrome/browser/predictors/predictor_database.cc +++ b/chrome/browser/predictors/predictor_database.cc
@@ -73,7 +73,11 @@ Profile* profile, scoped_refptr<base::SequencedTaskRunner> db_task_runner) : db_path_(profile->GetPath().Append(kPredictorDatabaseName)), - db_(std::make_unique<sql::Database>()), + db_(std::make_unique<sql::Database>(sql::DatabaseOptions{ + .exclusive_locking = true, + .page_size = 4096, + .cache_size = 500, + })), db_task_runner_(db_task_runner), autocomplete_table_( new AutocompleteActionPredictorTable(db_task_runner_)),
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc index 59d8f28..95e75d6 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc
@@ -396,6 +396,11 @@ } void ResourcePrefetchPredictorTablesTest::ReopenDatabase() { + // Ensure that the database is closed before attempting to reopen it. + db_ = nullptr; + tables_ = nullptr; + content::RunAllTasksUntilIdle(); + db_ = std::make_unique<PredictorDatabase>(&profile_, task_runner_); content::RunAllTasksUntilIdle(); tables_ = db_->resource_prefetch_tables();
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 0266019..7686eabe 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -141,6 +141,7 @@ #include "components/security_interstitials/content/stateful_ssl_host_state_delegate.h" #include "components/segmentation_platform/public/segmentation_platform_service.h" #include "components/sessions/core/session_id_generator.h" +#include "components/signin/public/base/signin_buildflags.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "components/site_engagement/content/site_engagement_service.h" #include "components/subresource_filter/content/browser/ruleset_service.h" @@ -619,14 +620,16 @@ #if defined(OS_MAC) const char kPasswordRecovery[] = "password_manager.password_recovery"; #endif - -// Deprecated 07/2021. const char kWasSignInPasswordPromoClicked[] = "profile.was_sign_in_password_promo_clicked"; const char kNumberSignInPasswordPromoShown[] = "profile.number_sign_in_password_promo_shown"; const char kSignInPasswordPromoRevive[] = "profile.sign_in_password_promo_revive"; +#if BUILDFLAG(ENABLE_DICE_SUPPORT) +constexpr char kProfileSwitchInterceptionDeclinedPref[] = + "signin.ProfileSwitchInterceptionDeclinedPref"; +#endif // Register local state used only for migration (clearing or moving to a new // key). @@ -800,6 +803,10 @@ registry->RegisterBooleanPref(kWasSignInPasswordPromoClicked, false); registry->RegisterIntegerPref(kNumberSignInPasswordPromoShown, 0); registry->RegisterBooleanPref(kSignInPasswordPromoRevive, false); + +#if BUILDFLAG(ENABLE_DICE_SUPPORT) + registry->RegisterDictionaryPref(kProfileSwitchInterceptionDeclinedPref); +#endif } } // namespace @@ -1572,11 +1579,12 @@ #if defined(OS_MAC) profile_prefs->ClearPref(kPasswordRecovery); #endif - - // Added 07/2021 profile_prefs->ClearPref(kWasSignInPasswordPromoClicked); profile_prefs->ClearPref(kNumberSignInPasswordPromoShown); profile_prefs->ClearPref(kSignInPasswordPromoRevive); +#if BUILDFLAG(ENABLE_DICE_SUPPORT) + profile_prefs->ClearPref(kProfileSwitchInterceptionDeclinedPref); +#endif // Please don't delete the following line. It is used by PRESUBMIT.py. // END_MIGRATE_OBSOLETE_PROFILE_PREFS
diff --git a/chrome/browser/profiling_host/memlog_browsertest.cc b/chrome/browser/profiling_host/memlog_browsertest.cc index 00ff0c0..d98b769 100644 --- a/chrome/browser/profiling_host/memlog_browsertest.cc +++ b/chrome/browser/profiling_host/memlog_browsertest.cc
@@ -56,15 +56,10 @@ } }; -// Flaky on Android and Mac: crbug.com/1223739. -#if defined(OS_ANDROID) || defined(OS_MAC) -#define MAYBE_EndToEnd DISABLED_EndToEnd -#else -#define MAYBE_EndToEnd EndToEnd -#endif +// TODO(crbug.com/1223739) Disabled due to flakiness. // Ensure invocations via TracingController can generate a valid JSON file with // expected data. -IN_PROC_BROWSER_TEST_P(MemlogBrowserTest, MAYBE_EndToEnd) { +IN_PROC_BROWSER_TEST_P(MemlogBrowserTest, DISABLED_EndToEnd) { LOG(INFO) << "Memlog mode: " << static_cast<int>(GetParam().mode); LOG(INFO) << "Memlog stack mode: " << static_cast<int>(GetParam().stack_mode); LOG(INFO) << "Started via command line flag: "
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_optin_flow.js b/chrome/browser/resources/chromeos/assistant_optin/assistant_optin_flow.js index 38fcdf7..568c6e6f 100644 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_optin_flow.js +++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_optin_flow.js
@@ -136,7 +136,6 @@ data['flowType'] = this.flowType; this.$.valueProp.reloadContent(data); this.$.relatedInfo.reloadContent(data); - this.$.voiceMatch.reloadContent(data); this.$.thirdParty.reloadContent(data); this.$.getMore.reloadContent(data); },
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_related_info.html b/chrome/browser/resources/chromeos/assistant_optin/assistant_related_info.html index 0b34f7d..468b0f9 100644 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_related_info.html +++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_related_info.html
@@ -83,7 +83,7 @@ <oobe-text-button id="skip-button" disabled="[[loading]]" text-key="assistantOptinNoThanksButton" on-click="onSkipTap_"> </oobe-text-button> - <oobe-text-button id="next-button" inverse="[[!equalWeightButtons_]]" + <oobe-text-button id="next-button" inverse="[[!isMinorMode_]]" disabled="[[loading]]" text-key="assistantOptinAgreeButton" on-click="onNextTap_"> </oobe-text-button>
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_related_info.js b/chrome/browser/resources/chromeos/assistant_optin/assistant_related_info.js index 9f24cea..528ef1ec 100644 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_related_info.js +++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_related_info.js
@@ -47,11 +47,14 @@ }, /** - * Indicates whether to use same design for accept/decline buttons. + * Indicates whether user is minor mode user (e.g. under age of 18). */ - equalWeightButtons_: { + isMinorMode_: { type: Boolean, - value: false, + value() { + return loadTimeData.valueExists('isMinorMode') && + loadTimeData.getBoolean('isMinorMode'); + } }, }, @@ -237,8 +240,6 @@ 'https://www.gstatic.com/images/icons/material/system/2x/' + 'info_outline_grey600_24dp.png', this.i18n('assistantScreenContextTitle')))); - this.equalWeightButtons_ = data['equalWeightButtons']; - this.consentStringLoaded_ = true; if (this.webViewLoaded_) { this.onPageLoaded();
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.html b/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.html index f739276..da18cf2 100644 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.html +++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.html
@@ -51,7 +51,7 @@ disabled="[[buttonsDisabled]]"> <div id="skip-button-text" slot="text"></div> </oobe-text-button> - <oobe-text-button id="next-button" inverse="[[!equalWeightButtons_]]" + <oobe-text-button id="next-button" inverse="[[!isMinorMode_]]" on-click="onNextTap_" disabled="[[buttonsDisabled]]"> <div id="next-button-text" slot="text"></div> </oobe-text-button>
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.js b/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.js index 40f94332..5af2e4b 100644 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.js +++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.js
@@ -58,15 +58,10 @@ */ isMinorMode_: { type: Boolean, - value: false, - }, - - /** - * Indicates whether to use same design for accept/decline buttons. - */ - equalWeightButtons_: { - type: Boolean, - value: false, + value() { + return loadTimeData.valueExists('isMinorMode') && + loadTimeData.getBoolean('isMinorMode'); + } }, /** @@ -305,7 +300,6 @@ this.$['skip-button-text'].textContent = data['valuePropSkipButton']; this.$['footer-text'].innerHTML = this.sanitizer_.sanitizeHtml(data['valuePropFooter']); - this.equalWeightButtons_ = data['equalWeightButtons']; this.consentStringLoaded_ = true; if (this.settingZippyLoaded_) { @@ -332,9 +326,6 @@ // `zippy_data` contains a list of lists, where each list contains the // setting zippys that should be shown on the same screen. - // `isMinorMode` is the same for all data in `zippy_data`. We could use the - // first one and set `isMinorMode_` flag. - this.isMinorMode_ = zippy_data[0][0]['isMinorMode']; for (var i in zippy_data) { for (var j in zippy_data[i]) { var data = zippy_data[i][j];
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html index 0d5699c..a2a97fa 100644 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html +++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html
@@ -48,7 +48,7 @@ disabled="[[buttonsDisabled]]" text-key="assistantOptinNoThanksButton"> </oobe-text-button> - <oobe-text-button id="agree-button" inverse="[[!equalWeightButtons_]]" + <oobe-text-button id="agree-button" inverse="[[!isMinorMode_]]" on-click="onAgreeTap_" disabled="[[buttonsDisabled]]" text-key="assistantOptinAgreeButton"> </oobe-text-button>
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.js b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.js index 02234b9..45a1035 100644 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.js +++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.js
@@ -30,11 +30,14 @@ properties: { /** - * Indicates whether to use same design for accept/decline buttons. + * Indicates whether user is minor mode user (e.g. under age of 18). */ - equalWeightButtons_: { + isMinorMode_: { type: Boolean, - value: false, + value() { + return loadTimeData.valueExists('isMinorMode') && + loadTimeData.getBoolean('isMinorMode'); + } }, }, @@ -121,13 +124,6 @@ }, /** - * Reload the page with the given settings data. - */ - reloadContent(data) { - this.equalWeightButtons_ = data['equalWeightButtons']; - }, - - /** * Reloads voice match flow. */ reloadPage() {
diff --git a/chrome/browser/resources/chromeos/login/enterprise_enrollment.html b/chrome/browser/resources/chromeos/login/enterprise_enrollment.html index be8a692..c521226 100644 --- a/chrome/browser/resources/chromeos/login/enterprise_enrollment.html +++ b/chrome/browser/resources/chromeos/login/enterprise_enrollment.html
@@ -58,6 +58,7 @@ on-authcompleted="onAuthCompleted_" on-backcancel="cancel" on-closesaml="cancel" + on-identifierentered="onIdentifierEnteredMessage_" on-ready="onReady"> </gaia-dialog> @@ -67,6 +68,12 @@ <iron-icon slot="icon" icon="oobe-32:enterprise"></iron-icon> </oobe-loading-dialog> + <!-- ACCOUNT CHECK IN PROGRESS (SPINNER) DIALOG --> + <oobe-loading-dialog title-key="enrollmentAccountCheckTitle" + id="step-checking" for-step="checking"> + <iron-icon slot="icon" icon="oobe-32:enterprise"></iron-icon> + </oobe-loading-dialog> + <offline-ad-login-element id="step-ad-join" is-domain-join for-step="ad-join" class="fit"
diff --git a/chrome/browser/resources/chromeos/login/enterprise_enrollment.js b/chrome/browser/resources/chromeos/login/enterprise_enrollment.js index fda0706..a412ffb7 100644 --- a/chrome/browser/resources/chromeos/login/enterprise_enrollment.js +++ b/chrome/browser/resources/chromeos/login/enterprise_enrollment.js
@@ -30,6 +30,7 @@ ATTRIBUTE_PROMPT: 'attribute-prompt', ERROR: 'error', SUCCESS: 'success', + CHECKING: 'checking', /* TODO(dzhioev): define this step on C++ side. */ @@ -119,6 +120,14 @@ }, /** + * Whether account identifier should be sent for check. + */ + hasAccountCheck_: { + type: Boolean, + value: false, + }, + + /** * Whether the enrollment is automatic * * True: Automatic (Attestation-based) @@ -224,9 +233,6 @@ chrome.send( 'oauthEnrollAdUnlockConfiguration', [e.detail.unlock_password]); }.bind(this)); - - - this.authenticator_.insecureContentBlockedCallback = (function(url) { this.showError( @@ -285,6 +291,8 @@ data.is_enrollment_enforced : undefined; this.isAutoEnroll_ = 'attestationBased' in data ? data.attestationBased : undefined; + this.hasAccountCheck_ = + 'flow' in data ? (data.flow == 'enterpriseLicense') : false; cr.ui.login.invokePolymerMethod(this.$["step-ad-join"], 'onBeforeShow'); if (!this.uiStep) { @@ -324,6 +332,19 @@ }, /** + * Invoked when identifierEntered message received. + * @param {!CustomEvent<!{accountIdentifier: string}>} e Event with payload + * containing: {string} accountIdentifier User identifier. + * @private + */ + onIdentifierEnteredMessage_(e) { + if (this.hasAccountCheck_) { + this.showStep(ENROLLMENT_STEP.CHECKING); + chrome.send('enterpriseIdentifierEntered', [e.detail.accountIdentifier]); + } + }, + + /** * Cancels the current authentication and drops the user back to the next * screen (either the next authentication or the login screen). */
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.js b/chrome/browser/resources/gaia_auth_host/authenticator.js index f276780..83317ac 100644 --- a/chrome/browser/resources/gaia_auth_host/authenticator.js +++ b/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -164,8 +164,8 @@ // If this set to |false|, |confirmPasswordCallback| is // not called before dispatching |authCopleted|. // Default is |true|. - 'flow', // One of 'default', 'enterprise', or - // 'theftprotection'. + 'flow', // One of 'default', 'enterprise', or + // 'cfm' or 'enterpriseLicense'. 'enterpriseDisplayDomain', // Current domain name to be displayed. 'enterpriseDomainManager', // Manager of the current domain. Can be // either a domain name (foo.com) or an email @@ -207,9 +207,7 @@ // can still change it and then proceed. This is used on desktop when the // user disconnects their profile then reconnects, to encourage them to use // the same account. - 'email', - 'readOnlyEmail', - 'realm', + 'email', 'readOnlyEmail', 'realm', // If the authentication is done via external IdP, 'startsOnSamlPage' // indicates whether the flow should start on the IdP page. 'startsOnSamlPage',
diff --git a/chrome/browser/resources/ntp4/OWNERS b/chrome/browser/resources/ntp4/OWNERS index bf9aa61e..3c5e993 100644 --- a/chrome/browser/resources/ntp4/OWNERS +++ b/chrome/browser/resources/ntp4/OWNERS
@@ -1,3 +1,2 @@ file://components/search/OWNERS estade@chromium.org -rbyers@chromium.org
diff --git a/chrome/browser/resources/settings/autofill_page/autofill_page.js b/chrome/browser/resources/settings/autofill_page/autofill_page.js index fadcd816..fc7b63c86 100644 --- a/chrome/browser/resources/settings/autofill_page/autofill_page.js +++ b/chrome/browser/resources/settings/autofill_page/autofill_page.js
@@ -21,17 +21,17 @@ import {routes} from '../route.js'; import {Router} from '../router.js'; -import {PasswordCheckBehavior, PasswordCheckBehaviorInterface} from './password_check_behavior.js'; +import {PasswordCheckMixin, PasswordCheckMixinInterface} from './password_check_behavior.js'; import {PasswordManagerImpl} from './password_manager_proxy.js'; /** * @constructor * @extends {PolymerElement} - * @implements {PasswordCheckBehaviorInterface} + * @implements {PasswordCheckMixinInterface} */ const SettingsAutofillPageElementBase = - mixinBehaviors([PrefsBehavior, PasswordCheckBehavior], PolymerElement); + mixinBehaviors([PrefsBehavior], PasswordCheckMixin(PolymerElement)); /** @polymer */ class SettingsAutofillPageElement extends SettingsAutofillPageElementBase {
diff --git a/chrome/browser/resources/settings/autofill_page/password_check.js b/chrome/browser/resources/settings/autofill_page/password_check.js index 0515966..e8bf8618b 100644 --- a/chrome/browser/resources/settings/autofill_page/password_check.js +++ b/chrome/browser/resources/settings/autofill_page/password_check.js
@@ -34,12 +34,12 @@ import {SyncBrowserProxyImpl, SyncPrefs, SyncStatus} from '../people_page/sync_browser_proxy.js'; import {PrefsBehavior, PrefsBehaviorInterface} from '../prefs/prefs_behavior.js'; import {routes} from '../route.js'; -import {Route, RouteObserverBehavior, Router} from '../router.js'; +import {Route, RouteObserverMixin, Router} from '../router.js'; // <if expr="chromeos"> import {BlockingRequestManager} from './blocking_request_manager.js'; // </if> -import {PasswordCheckBehavior, PasswordCheckBehaviorInterface} from './password_check_behavior.js'; +import {PasswordCheckMixin, PasswordCheckMixinInterface} from './password_check_behavior.js'; import {PasswordManagerImpl, PasswordManagerProxy} from './password_manager_proxy.js'; @@ -50,16 +50,13 @@ * @constructor * @extends {PolymerElement} * @implements {I18nBehaviorInterface} - * @implements {PasswordCheckBehaviorInterface} + * @implements {PasswordCheckMixinInterface} * @implements {PrefsBehaviorInterface} * @implements {WebUIListenerBehaviorInterface} */ const SettingsPasswordCheckElementBase = mixinBehaviors( - [ - I18nBehavior, PasswordCheckBehavior, PrefsBehavior, RouteObserverBehavior, - WebUIListenerBehavior - ], - PolymerElement); + [I18nBehavior, PrefsBehavior, WebUIListenerBehavior], + RouteObserverMixin(PasswordCheckMixin((PolymerElement)))); /** @polymer */ class SettingsPasswordCheckElement extends SettingsPasswordCheckElementBase {
diff --git a/chrome/browser/resources/settings/autofill_page/password_check_behavior.js b/chrome/browser/resources/settings/autofill_page/password_check_behavior.js index 7fd41a9..c82bcda0 100644 --- a/chrome/browser/resources/settings/autofill_page/password_check_behavior.js +++ b/chrome/browser/resources/settings/autofill_page/password_check_behavior.js
@@ -5,6 +5,7 @@ import {assert} from 'chrome://resources/js/assert.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {PluralStringProxyImpl} from 'chrome://resources/js/plural_string_proxy.js'; +import {dedupingMixin} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {PasswordManagerImpl, PasswordManagerProxy} from './password_manager_proxy.js'; @@ -13,229 +14,247 @@ * status of password check. It is used by <settings-password-check> * <passwords-section> and <settings-autofill-page>. * - * @polymerBehavior + * @polymer + * @mixinFunction */ - -export const PasswordCheckBehavior = { - - properties: { - /** - * The number of compromised passwords as a formatted string. - */ - compromisedPasswordsCount: String, - - /** - * The number of weak passwords as a formatted string. - */ - weakPasswordsCount: String, - - /** - * The number of insecure passwords as a formatted string. - */ - insecurePasswordsCount: String, - - /** - * An array of leaked passwords to display. - * @type {!Array<!PasswordManagerProxy.InsecureCredential>} - */ - leakedPasswords: { - type: Array, - value: () => [], - }, - - /** - * An array of weak passwords to display. - * @type {!Array<!PasswordManagerProxy.InsecureCredential>} - */ - weakPasswords: { - type: Array, - value: () => [], - }, - - /** - * The status indicates progress and affects banner, title and icon. - * @type {!PasswordManagerProxy.PasswordCheckStatus} - */ - status: { - type: Object, - value: () => ({state: chrome.passwordsPrivate.PasswordCheckState.IDLE}), - }, - - /** - * Stores whether the status was fetched from the backend. - * @type {boolean} - */ - isInitialStatus: { - type: Boolean, - value: true, - }, - }, - +export const PasswordCheckMixin = dedupingMixin(superClass => { /** - * @private {?function(!PasswordManagerProxy.InsecureCredentials):void} + * @polymer + * @mixinClass */ - leakedCredentialsListener_: null, + class PasswordCheckMixin extends superClass { + static get properties() { + return { + /** + * The number of compromised passwords as a formatted string. + */ + compromisedPasswordsCount: String, - /** - * @private {?function(!PasswordManagerProxy.InsecureCredentials):void} - */ - weakCredentialsListener_: null, + /** + * The number of weak passwords as a formatted string. + */ + weakPasswordsCount: String, - /** - * @private {?function(!PasswordManagerProxy.PasswordCheckStatus):void} - */ - statusChangedListener_: null, + /** + * The number of insecure passwords as a formatted string. + */ + insecurePasswordsCount: String, - /** @type {?PasswordManagerProxy} */ - passwordManager: null, + /** + * An array of leaked passwords to display. + * @type {!Array<!PasswordManagerProxy.InsecureCredential>} + */ + leakedPasswords: { + type: Array, + value: () => [], + }, - /** @override */ - attached() { - this.statusChangedListener_ = status => { - this.status = status; - this.isInitialStatus = false; - }; + /** + * An array of weak passwords to display. + * @type {!Array<!PasswordManagerProxy.InsecureCredential>} + */ + weakPasswords: { + type: Array, + value: () => [], + }, - this.leakedCredentialsListener_ = compromisedCredentials => { - this.updateCompromisedPasswordList(compromisedCredentials); - this.fetchPluralizedStrings_(); - }; + /** + * The status indicates progress and affects banner, title and icon. + * @type {!PasswordManagerProxy.PasswordCheckStatus} + */ + status: { + type: Object, + value: () => + ({state: chrome.passwordsPrivate.PasswordCheckState.IDLE}), + }, - this.weakCredentialsListener_ = weakCredentials => { - this.weakPasswords = weakCredentials; - this.fetchPluralizedStrings_(); - }; - - this.passwordManager = PasswordManagerImpl.getInstance(); - this.passwordManager.getPasswordCheckStatus().then( - this.statusChangedListener_); - this.passwordManager.getCompromisedCredentials().then( - this.leakedCredentialsListener_); - this.passwordManager.getWeakCredentials().then( - this.weakCredentialsListener_); - - this.passwordManager.addPasswordCheckStatusListener( - this.statusChangedListener_); - this.passwordManager.addCompromisedCredentialsListener( - this.leakedCredentialsListener_); - this.passwordManager.addWeakCredentialsListener( - this.weakCredentialsListener_); - }, - - /** @override */ - detached() { - this.passwordManager.removeCompromisedCredentialsListener( - assert(this.statusChangedListener_)); - this.statusChangedListener_ = null; - this.passwordManager.removeCompromisedCredentialsListener( - assert(this.leakedCredentialsListener_)); - this.leakedCredentialsListener_ = null; - this.passwordManager.removeWeakCredentialsListener( - assert(this.weakCredentialsListener_)); - this.weakCredentialsListener_ = null; - }, - - /** - * True if weak passwords are shown in SC, in which case the PW check UI - * adapts a bit to show the information in the same form as SC. - * @return {boolean} - * @private - */ - safetyCheckWeakPasswordsEnabled_() { - return loadTimeData.getBoolean('safetyCheckWeakPasswordsEnabled'); - }, - - /** - * Helper that fetches pluralized strings corresponding to the number of - * compromised, weak and insecure credentials. - * @private - */ - fetchPluralizedStrings_() { - const proxy = PluralStringProxyImpl.getInstance(); - const compromised = this.leakedPasswords.length; - const weak = this.weakPasswords.length; - - proxy.getPluralString('compromisedPasswords', compromised) - .then(count => this.compromisedPasswordsCount = count); - - proxy.getPluralString('weakPasswords', weak) - .then(count => this.weakPasswordsCount = count); - - (() => { - if (!this.safetyCheckWeakPasswordsEnabled_()) { - // Old code path: adds up compromised and weak passwords. - return proxy.getPluralString('insecurePasswords', compromised + weak); - } - if (compromised > 0 && weak > 0) { - return proxy.getPluralStringTupleWithComma( - 'safetyCheckPasswordsCompromised', compromised, - 'safetyCheckPasswordsWeak', weak); - } - if (compromised > 0) { - // Only compromised and no weak passwords. - return proxy.getPluralString( - 'safetyCheckPasswordsCompromised', compromised); - } - if (weak > 0) { - // Only weak and no compromised passwords. - return proxy.getPluralString('safetyCheckPasswordsWeak', weak); - } - // No security issues. - return proxy.getPluralString('compromisedPasswords', 0); - })().then(count => this.insecurePasswordsCount = count); - }, - - /** - * Function to update compromised credentials in a proper way. New entities - * should appear in the bottom. - * @param {!Array<!PasswordManagerProxy.InsecureCredential>} newList - * @private - */ - updateCompromisedPasswordList(newList) { - const oldList = this.leakedPasswords.slice(); - const map = new Map(newList.map(item => ([item.id, item]))); - - const resultList = []; - - for (const item of oldList) { - // If element is present in newList - if (map.has(item.id)) { - // Replace old version with new - resultList.push(map.get(item.id)); - map.delete(item.id); - } + /** + * Stores whether the status was fetched from the backend. + * @type {boolean} + */ + isInitialStatus: { + type: Boolean, + value: true, + }, + }; } - const addedResults = Array.from(map.values()); - addedResults.sort((lhs, rhs) => { - // Phished passwords are always shown above leaked passwords. - const isPhished = cred => cred.compromisedInfo.compromiseType !== - chrome.passwordsPrivate.CompromiseType.LEAKED; - if (isPhished(lhs) !== isPhished(rhs)) { - return isPhished(lhs) ? -1 : 1; + constructor() { + super(); + + /** + * @private {?function(!PasswordManagerProxy.InsecureCredentials):void} + */ + this.leakedCredentialsListener_ = null; + + /** + * @private {?function(!PasswordManagerProxy.InsecureCredentials):void} + */ + this.weakCredentialsListener_ = null; + + /** + * @private {?function(!PasswordManagerProxy.PasswordCheckStatus):void} + */ + this.statusChangedListener_ = null; + + /** @type {?PasswordManagerProxy} */ + this.passwordManager = null; + } + + /** @override */ + connectedCallback() { + super.connectedCallback(); + + this.statusChangedListener_ = status => { + this.status = status; + this.isInitialStatus = false; + }; + + this.leakedCredentialsListener_ = compromisedCredentials => { + this.updateCompromisedPasswordList(compromisedCredentials); + this.fetchPluralizedStrings_(); + }; + + this.weakCredentialsListener_ = weakCredentials => { + this.weakPasswords = weakCredentials; + this.fetchPluralizedStrings_(); + }; + + this.passwordManager = PasswordManagerImpl.getInstance(); + this.passwordManager.getPasswordCheckStatus().then( + this.statusChangedListener_); + this.passwordManager.getCompromisedCredentials().then( + this.leakedCredentialsListener_); + this.passwordManager.getWeakCredentials().then( + this.weakCredentialsListener_); + + this.passwordManager.addPasswordCheckStatusListener( + this.statusChangedListener_); + this.passwordManager.addCompromisedCredentialsListener( + this.leakedCredentialsListener_); + this.passwordManager.addWeakCredentialsListener( + this.weakCredentialsListener_); + } + + /** @override */ + disconnectedCallback() { + super.disconnectedCallback(); + + this.passwordManager.removePasswordCheckStatusListener( + assert(this.statusChangedListener_)); + this.statusChangedListener_ = null; + this.passwordManager.removeCompromisedCredentialsListener( + assert(this.leakedCredentialsListener_)); + this.leakedCredentialsListener_ = null; + this.passwordManager.removeWeakCredentialsListener( + assert(this.weakCredentialsListener_)); + this.weakCredentialsListener_ = null; + } + + /** + * True if weak passwords are shown in SC, in which case the PW check UI + * adapts a bit to show the information in the same form as SC. + * @return {boolean} + * @private + */ + safetyCheckWeakPasswordsEnabled_() { + return loadTimeData.getBoolean('safetyCheckWeakPasswordsEnabled'); + } + + /** + * Helper that fetches pluralized strings corresponding to the number of + * compromised, weak and insecure credentials. + * @private + */ + fetchPluralizedStrings_() { + const proxy = PluralStringProxyImpl.getInstance(); + const compromised = this.leakedPasswords.length; + const weak = this.weakPasswords.length; + + proxy.getPluralString('compromisedPasswords', compromised) + .then(count => this.compromisedPasswordsCount = count); + + proxy.getPluralString('weakPasswords', weak) + .then(count => this.weakPasswordsCount = count); + + (() => { + if (!this.safetyCheckWeakPasswordsEnabled_()) { + // Old code path: adds up compromised and weak passwords. + return proxy.getPluralString('insecurePasswords', compromised + weak); + } + if (compromised > 0 && weak > 0) { + return proxy.getPluralStringTupleWithComma( + 'safetyCheckPasswordsCompromised', compromised, + 'safetyCheckPasswordsWeak', weak); + } + if (compromised > 0) { + // Only compromised and no weak passwords. + return proxy.getPluralString( + 'safetyCheckPasswordsCompromised', compromised); + } + if (weak > 0) { + // Only weak and no compromised passwords. + return proxy.getPluralString('safetyCheckPasswordsWeak', weak); + } + // No security issues. + return proxy.getPluralString('compromisedPasswords', 0); + })().then(count => this.insecurePasswordsCount = count); + } + + /** + * Function to update compromised credentials in a proper way. New entities + * should appear in the bottom. + * @param {!Array<!PasswordManagerProxy.InsecureCredential>} newList + * @private + */ + updateCompromisedPasswordList(newList) { + const oldList = this.leakedPasswords.slice(); + const map = new Map(newList.map(item => ([item.id, item]))); + + const resultList = []; + + for (const item of oldList) { + // If element is present in newList + if (map.has(item.id)) { + // Replace old version with new + resultList.push(map.get(item.id)); + map.delete(item.id); + } } - // Sort by time only if the displayed elapsed time since compromise is - // different. - if (lhs.compromisedInfo.elapsedTimeSinceCompromise !== - rhs.compromisedInfo.elapsedTimeSinceCompromise) { - return rhs.compromisedInfo.compromiseTime - - lhs.compromisedInfo.compromiseTime; - } + const addedResults = Array.from(map.values()); + addedResults.sort((lhs, rhs) => { + // Phished passwords are always shown above leaked passwords. + const isPhished = cred => cred.compromisedInfo.compromiseType !== + chrome.passwordsPrivate.CompromiseType.LEAKED; + if (isPhished(lhs) !== isPhished(rhs)) { + return isPhished(lhs) ? -1 : 1; + } - // Otherwise sort by origin, or by username in case the origin is the - // same. - return lhs.formattedOrigin.localeCompare(rhs.formattedOrigin) || - lhs.username.localeCompare(rhs.username); - }); - resultList.push(...addedResults); - this.leakedPasswords = resultList; - }, -}; + // Sort by time only if the displayed elapsed time since compromise is + // different. + if (lhs.compromisedInfo.elapsedTimeSinceCompromise !== + rhs.compromisedInfo.elapsedTimeSinceCompromise) { + return rhs.compromisedInfo.compromiseTime - + lhs.compromisedInfo.compromiseTime; + } + + // Otherwise sort by origin, or by username in case the origin is the + // same. + return lhs.formattedOrigin.localeCompare(rhs.formattedOrigin) || + lhs.username.localeCompare(rhs.username); + }); + resultList.push(...addedResults); + this.leakedPasswords = resultList; + } + } + + return PasswordCheckMixin; +}); /** @interface */ -export class PasswordCheckBehaviorInterface { - /** @type {?PasswordManagerProxy} */ +export class PasswordCheckMixinInterface { + /** @return {?PasswordManagerProxy} */ get passwordManager() {} /** @return {!Array<!PasswordManagerProxy.InsecureCredential>} */ @@ -253,9 +272,9 @@ /** @return {string} */ get insecurePasswordsCount() {} - /** return {!PasswordManagerProxy.PasswordCheckStatus} */ + /** @return {!PasswordManagerProxy.PasswordCheckStatus} */ get status() {} - /** return {boolean} */ + /** @return {boolean} */ get isInitialStatus() {} }
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_section.js b/chrome/browser/resources/settings/autofill_page/passwords_section.js index ec0c007..5329360 100644 --- a/chrome/browser/resources/settings/autofill_page/passwords_section.js +++ b/chrome/browser/resources/settings/autofill_page/passwords_section.js
@@ -43,7 +43,7 @@ import {Router} from '../router.js'; import '../settings_shared_css.js'; import '../site_favicon.js'; -import {PasswordCheckBehavior, PasswordCheckBehaviorInterface} from './password_check_behavior.js'; +import {PasswordCheckMixin, PasswordCheckMixinInterface} from './password_check_behavior.js'; import './password_list_item.js'; import './passwords_list_handler.js'; import {PasswordManagerImpl, PasswordManagerProxy} from './password_manager_proxy.js'; @@ -76,7 +76,7 @@ * @implements {I18nBehaviorInterface} * @implements {MergePasswordsStoreCopiesBehaviorInterface} * @implements {MergeExceptionsStoreCopiesBehaviorInterface} - * @implements {PasswordCheckBehaviorInterface} + * @implements {PasswordCheckMixinInterface} * @implements {WebUIListenerBehaviorInterface} */ const PasswordsSectionElementBase = mixinBehaviors( @@ -85,11 +85,10 @@ WebUIListenerBehavior, MergeExceptionsStoreCopiesBehavior, MergePasswordsStoreCopiesBehavior, - PasswordCheckBehavior, GlobalScrollTargetBehavior, PrefsBehavior, ], - PolymerElement); + PasswordCheckMixin(PolymerElement)); /** @polymer */ class PasswordsSectionElement extends PasswordsSectionElementBase {
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.js b/chrome/browser/resources/settings/basic_page/basic_page.js index 0b4e93e..30fb080e 100644 --- a/chrome/browser/resources/settings/basic_page/basic_page.js +++ b/chrome/browser/resources/settings/basic_page/basic_page.js
@@ -39,9 +39,9 @@ import {PrefsBehavior, PrefsBehaviorInterface} from '../prefs/prefs_behavior.js'; // </if> import {routes} from '../route.js'; -import {Route, RouteObserverBehavior, Router} from '../router.js'; +import {Route, RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js'; import {getSearchManager, SearchResult} from '../search_settings.js'; -import {MainPageBehavior} from '../settings_page/main_page_behavior.js'; +import {MainPageMixin, MainPageMixinInterface} from '../settings_page/main_page_behavior.js'; // <if expr="chromeos or lacros"> const OS_BANNER_INTERACTION_METRIC_NAME = @@ -64,16 +64,17 @@ /** * @constructor * @extends {PolymerElement} + * @implements {MainPageMixinInterface} + * @implements {RouteObserverMixinInterface} * @implements {PrefsBehaviorInterface} */ const SettingsBasicPageElementBase = mixinBehaviors( [ - MainPageBehavior, RouteObserverBehavior, // <if expr="chromeos or lacros"> PrefsBehavior, // </if> ], - PolymerElement); + MainPageMixin(RouteObserverMixin(PolymerElement))); /** @polymer */ export class SettingsBasicPageElement extends SettingsBasicPageElementBase { @@ -182,10 +183,7 @@ this.currentRoute_ = Router.getInstance().getCurrentRoute(); } - /** - * @param {!Route} newRoute - * @param {Route} oldRoute - */ + /** @override */ currentRouteChanged(newRoute, oldRoute) { this.currentRoute_ = newRoute; @@ -203,10 +201,13 @@ assert(!this.hasExpandedSection_); } - MainPageBehavior.currentRouteChanged.call(this, newRoute, oldRoute); + super.currentRouteChanged(newRoute, oldRoute); } - // Override MainPageBehavior method. + /** + * Override MainPageMixin method. + * @override + */ containsRoute(route) { return !route || routes.BASIC.contains(route) || routes.ADVANCED.contains(route);
diff --git a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js index 424dfcf..825cebc 100644 --- a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js +++ b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js
@@ -30,7 +30,7 @@ import {loadTimeData} from '../i18n_setup.js'; import {StatusAction, SyncBrowserProxy, SyncBrowserProxyImpl, SyncStatus} from '../people_page/sync_browser_proxy.js'; import {routes} from '../route.js'; -import {Route, RouteObserverBehavior, RouteObserverBehaviorInterface, Router} from '../router.js'; +import {Route, RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js'; import {ClearBrowsingDataBrowserProxy, ClearBrowsingDataBrowserProxyImpl, InstalledApp} from './clear_browsing_data_browser_proxy.js'; @@ -91,12 +91,11 @@ * @constructor * @extends {PolymerElement} * @implements {I18nBehaviorInterface} + * @implements {RouteObserverMixinInterface} * @implements {WebUIListenerBehaviorInterface} - * @implements {RouteObserverBehaviorInterface} */ const SettingsClearBrowsingDataDialogElementBase = mixinBehaviors( - [I18nBehavior, WebUIListenerBehavior, RouteObserverBehavior], - PolymerElement); + [I18nBehavior, WebUIListenerBehavior], RouteObserverMixin(PolymerElement)); /** @polymer */ class SettingsClearBrowsingDataDialogElement extends @@ -370,9 +369,8 @@ /** * Record visits to the CBD dialog. * - * RouteObserverBehavior - * @param {!Route} currentRoute - * @protected + * RouteObserverMixin + * @override */ currentRouteChanged(currentRoute) { if (currentRoute === routes.CLEAR_BROWSER_DATA) {
diff --git a/chrome/browser/resources/settings/people_page/manage_profile.js b/chrome/browser/resources/settings/people_page/manage_profile.js index ec42ada..cd7f069 100644 --- a/chrome/browser/resources/settings/people_page/manage_profile.js +++ b/chrome/browser/resources/settings/people_page/manage_profile.js
@@ -21,7 +21,7 @@ import {loadTimeData} from '../i18n_setup.js'; import {routes} from '../route.js'; -import {RouteObserverBehavior, RouteObserverBehaviorInterface, Router} from '../router.js'; +import {RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js'; import {ManageProfileBrowserProxy, ManageProfileBrowserProxyImpl, ProfileShortcutStatus} from './manage_profile_browser_proxy.js'; import {SyncStatus} from './sync_browser_proxy.js'; @@ -29,11 +29,11 @@ /** * @constructor * @extends {PolymerElement} - * @implements {RouteObserverBehaviorInterface} + * @implements {RouteObserverMixinInterface} * @implements {WebUIListenerBehaviorInterface} */ -const SettingsManageProfileElementBase = mixinBehaviors( - [WebUIListenerBehavior, RouteObserverBehavior], PolymerElement); +const SettingsManageProfileElementBase = + mixinBehaviors([WebUIListenerBehavior], RouteObserverMixin(PolymerElement)); /** @polymer */ class SettingsManageProfileElement extends SettingsManageProfileElementBase {
diff --git a/chrome/browser/resources/settings/people_page/people_page.js b/chrome/browser/resources/settings/people_page/people_page.js index dd1a113..e0e2864 100644 --- a/chrome/browser/resources/settings/people_page/people_page.js +++ b/chrome/browser/resources/settings/people_page/people_page.js
@@ -36,7 +36,7 @@ import {OpenWindowProxyImpl} from '../open_window_proxy.js'; import {PageVisibility} from '../page_visibility.js'; import {routes} from '../route.js'; -import {RouteObserverBehavior, RouteObserverBehaviorInterface, Router} from '../router.js'; +import {RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js'; // <if expr="chromeos"> import {AccountManagerBrowserProxyImpl} from './account_manager_browser_proxy.js'; @@ -48,11 +48,11 @@ /** * @constructor * @extends {PolymerElement} - * @implements {RouteObserverBehaviorInterface} + * @implements {RouteObserverMixinInterface} * @implements {WebUIListenerBehaviorInterface} */ -const SettingsPeoplePageElementBase = mixinBehaviors( - [RouteObserverBehavior, WebUIListenerBehavior], PolymerElement); +const SettingsPeoplePageElementBase = + mixinBehaviors([WebUIListenerBehavior], RouteObserverMixin(PolymerElement)); /** @polymer */ class SettingsPeoplePageElement extends SettingsPeoplePageElementBase {
diff --git a/chrome/browser/resources/settings/people_page/sync_page.js b/chrome/browser/resources/settings/people_page/sync_page.js index b8b750e9..afe7ede 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.js +++ b/chrome/browser/resources/settings/people_page/sync_page.js
@@ -30,7 +30,7 @@ import {loadTimeData} from '../i18n_setup.js'; import {SettingsPersonalizationOptionsElement} from '../privacy_page/personalization_options.js'; -import {Route, RouteObserverBehavior, RouteObserverBehaviorInterface, Router} from '../router.js'; +import {Route, RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js'; import {PageStatus, StatusAction, SyncBrowserProxy, SyncBrowserProxyImpl, SyncPrefs, SyncStatus} from './sync_browser_proxy.js'; import {SettingsSyncEncryptionOptionsElement} from './sync_encryption_options.js'; @@ -62,12 +62,11 @@ * @constructor * @extends {PolymerElement} * @implements {I18nBehaviorInterface} - * @implements {RouteObserverBehaviorInterface} + * @implements {RouteObserverMixinInterface} * @implements {WebUIListenerBehaviorInterface} */ const SettingsSyncPageElementBase = mixinBehaviors( - [WebUIListenerBehavior, RouteObserverBehavior, I18nBehavior], - PolymerElement); + [WebUIListenerBehavior, I18nBehavior], RouteObserverMixin(PolymerElement)); /** @polymer */ export class SettingsSyncPageElement extends SettingsSyncPageElementBase {
diff --git a/chrome/browser/resources/settings/privacy_page/cookies_page.js b/chrome/browser/resources/settings/privacy_page/cookies_page.js index 7f15984..b83f70d 100644 --- a/chrome/browser/resources/settings/privacy_page/cookies_page.js +++ b/chrome/browser/resources/settings/privacy_page/cookies_page.js
@@ -28,7 +28,7 @@ import {MetricsBrowserProxy, MetricsBrowserProxyImpl, PrivacyElementInteractions} from '../metrics_browser_proxy.js'; import {PrefsBehavior, PrefsBehaviorInterface} from '../prefs/prefs_behavior.js'; import {routes} from '../route.js'; -import {Route, RouteObserverBehavior, RouteObserverBehaviorInterface, Router} from '../router.js'; +import {Route, RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js'; import {ContentSetting, ContentSettingsTypes} from '../site_settings/constants.js'; /** @@ -61,12 +61,11 @@ * @constructor * @extends {PolymerElement} * @implements {PrefsBehaviorInterface} - * @implements {RouteObserverBehaviorInterface} + * @implements {RouteObserverMixinInterface} * @implements {WebUIListenerBehaviorInterface} */ const SettingsCookiesPageElementBase = mixinBehaviors( - [PrefsBehavior, RouteObserverBehavior, WebUIListenerBehavior], - PolymerElement); + [PrefsBehavior, WebUIListenerBehavior], RouteObserverMixin(PolymerElement)); /** @polymer */ export class SettingsCookiesPageElement extends SettingsCookiesPageElementBase {
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.js b/chrome/browser/resources/settings/privacy_page/privacy_page.js index 550f542f..8a9c4a08 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.js +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.js
@@ -31,7 +31,7 @@ import {MetricsBrowserProxy, MetricsBrowserProxyImpl, PrivacyElementInteractions} from '../metrics_browser_proxy.js'; import {PrefsBehavior, PrefsBehaviorInterface} from '../prefs/prefs_behavior.js'; import {routes} from '../route.js'; -import {RouteObserverBehavior, RouteObserverBehaviorInterface, Router} from '../router.js'; +import {RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js'; import {ChooserType, ContentSettingsTypes, CookieControlsMode, NotificationSetting} from '../site_settings/constants.js'; import {SiteSettingsPrefsBrowserProxyImpl} from '../site_settings/site_settings_prefs_browser_proxy.js'; @@ -50,12 +50,12 @@ * @extends {PolymerElement} * @implements {I18nBehaviorInterface} * @implements {PrefsBehaviorInterface} - * @implements {RouteObserverBehaviorInterface} + * @implements {RouteObserverMixinInterface} * @implements {WebUIListenerBehaviorInterface} */ const SettingsPrivacyPageElementBase = mixinBehaviors( - [PrefsBehavior, RouteObserverBehavior, I18nBehavior, WebUIListenerBehavior], - PolymerElement); + [PrefsBehavior, I18nBehavior, WebUIListenerBehavior], + RouteObserverMixin(PolymerElement)); /** @polymer */ export class SettingsPrivacyPageElement extends SettingsPrivacyPageElementBase {
diff --git a/chrome/browser/resources/settings/privacy_page/security_page.js b/chrome/browser/resources/settings/privacy_page/security_page.js index 4f6036f..8e80b970 100644 --- a/chrome/browser/resources/settings/privacy_page/security_page.js +++ b/chrome/browser/resources/settings/privacy_page/security_page.js
@@ -22,7 +22,7 @@ import {MetricsBrowserProxy, MetricsBrowserProxyImpl, PrivacyElementInteractions, SafeBrowsingInteractions} from '../metrics_browser_proxy.js'; import {PrefsBehavior, PrefsBehaviorInterface} from '../prefs/prefs_behavior.js'; import {routes} from '../route.js'; -import {Route, RouteObserverBehavior, RouteObserverBehaviorInterface, Router} from '../router.js'; +import {Route, RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js'; import {SettingsDisableSafebrowsingDialogElement} from './disable_safebrowsing_dialog.js'; import {PrivacyPageBrowserProxy, PrivacyPageBrowserProxyImpl} from './privacy_page_browser_proxy.js'; @@ -44,10 +44,10 @@ * @extends {PolymerElement} * @implements {I18nBehaviorInterface} * @implements {PrefsBehaviorInterface} - * @implements {RouteObserverBehaviorInterface} + * @implements {RouteObserverMixinInterface} */ const SettingsSecurityPageElementBase = mixinBehaviors( - [I18nBehavior, PrefsBehavior, RouteObserverBehavior], PolymerElement); + [I18nBehavior, PrefsBehavior], RouteObserverMixin(PolymerElement)); /** @polymer */ export class SettingsSecurityPageElement extends @@ -171,9 +171,8 @@ } /** - * RouteObserverBehavior - * @param {!Route} route - * @protected + * RouteObserverMixin + * @override */ currentRouteChanged(route) { if (route === routes.SECURITY) {
diff --git a/chrome/browser/resources/settings/reset_page/reset_page.js b/chrome/browser/resources/settings/reset_page/reset_page.js index 1a26537..7f37e97a 100644 --- a/chrome/browser/resources/settings/reset_page/reset_page.js +++ b/chrome/browser/resources/settings/reset_page/reset_page.js
@@ -18,11 +18,11 @@ import {assert} from 'chrome://resources/js/assert.m.js'; import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js'; -import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {loadTimeData} from '../i18n_setup.js'; import {routes} from '../route.js'; -import {Route, RouteObserverBehavior, RouteObserverBehaviorInterface, Router} from '../router.js'; +import {Route, RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js'; import {SettingsResetProfileDialogElement} from './reset_profile_dialog.js'; @@ -30,10 +30,9 @@ /** * @constructor * @extends {PolymerElement} - * @implements {RouteObserverBehaviorInterface} + * @implements {RouteObserverMixinInterface} */ -const SettingsResetPageElementBase = - mixinBehaviors([RouteObserverBehavior], PolymerElement); +const SettingsResetPageElementBase = RouteObserverMixin(PolymerElement); /** @polymer */ class SettingsResetPageElement extends SettingsResetPageElementBase { @@ -63,9 +62,8 @@ } /** - * RouteObserverBehavior - * @param {!Route} route - * @protected + * RouteObserverMixin + * @override */ currentRouteChanged(route) { const lazyRender =
diff --git a/chrome/browser/resources/settings/router.js b/chrome/browser/resources/settings/router.js index ea04e102..da457105 100644 --- a/chrome/browser/resources/settings/router.js +++ b/chrome/browser/resources/settings/router.js
@@ -2,9 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import './i18n_setup.js'; + import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; -import './i18n_setup.js'; +import {dedupingMixin} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; /** * @typedef {{ @@ -354,6 +356,46 @@ } } + /** + * @polymer + * @mixinFunction + */ + export const RouteObserverMixin = dedupingMixin(superClass => { + /** + * @polymer + * @mixinClass + */ + class RouteObserverMixin extends superClass { + /** @override */ + connectedCallback() { + super.connectedCallback(); + + routerInstance.addObserver(this); + + // Emulating Polymer data bindings, the observer is called when the + // element starts observing the route. + this.currentRouteChanged(routerInstance.currentRoute, undefined); + } + + /** @override */ + disconnectedCallback() { + super.disconnectedCallback(); + + routerInstance.removeObserver(this); + } + + /** + * @param {!Route} newRoute + * @param {!Route=} opt_oldRoute + */ + currentRouteChanged(newRoute, opt_oldRoute) { + assertNotReached(); + } + } + + return RouteObserverMixin; + }); + /** @polymerBehavior */ export const RouteObserverBehavior = { /** @override */ @@ -387,3 +429,6 @@ */ currentRouteChanged(newRoute, opt_oldRoute) {} } + + /** @interface */ + export const RouteObserverMixinInterface = RouteObserverBehaviorInterface;
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.js b/chrome/browser/resources/settings/settings_main/settings_main.js index 5c7d641..2a67c52 100644 --- a/chrome/browser/resources/settings/settings_main/settings_main.js +++ b/chrome/browser/resources/settings/settings_main/settings_main.js
@@ -22,13 +22,13 @@ import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; import {IronA11yAnnouncer} from 'chrome://resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.js'; -import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {SettingsBasicPageElement} from '../basic_page/basic_page.js'; import {loadTimeData} from '../i18n_setup.js'; import {PageVisibility} from '../page_visibility.js'; import {routes} from '../route.js'; -import {Route, RouteObserverBehavior, RouteObserverBehaviorInterface, Router} from '../router.js'; +import {Route, RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js'; /** * @typedef {{about: boolean, settings: boolean}} @@ -39,10 +39,9 @@ /** * @constructor * @extends {PolymerElement} - * @implements {RouteObserverBehaviorInterface} + * @implements {RouteObserverMixinInterface} */ -const SettingsMainElementBase = - mixinBehaviors([RouteObserverBehavior], PolymerElement); +const SettingsMainElementBase = RouteObserverMixin(PolymerElement); /** @polymer */ export class SettingsMainElement extends SettingsMainElementBase {
diff --git a/chrome/browser/resources/settings/settings_menu/settings_menu.js b/chrome/browser/resources/settings/settings_menu/settings_menu.js index 0f6fa34a..0f9d896 100644 --- a/chrome/browser/resources/settings/settings_menu/settings_menu.js +++ b/chrome/browser/resources/settings/settings_menu/settings_menu.js
@@ -17,19 +17,18 @@ import '../settings_shared_css.js'; import {assert} from 'chrome://resources/js/assert.m.js'; -import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {loadTimeData} from '../i18n_setup.js'; import {PageVisibility} from '../page_visibility.js'; -import {Route, RouteObserverBehavior, RouteObserverBehaviorInterface, Router} from '../router.js'; +import {Route, RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js'; /** * @constructor * @extends {PolymerElement} - * @implements {RouteObserverBehaviorInterface} + * @implements {RouteObserverMixinInterface} */ -const SettingsMenuElementBase = - mixinBehaviors([RouteObserverBehavior], PolymerElement); +const SettingsMenuElementBase = RouteObserverMixin(PolymerElement); /** @polymer */ export class SettingsMenuElement extends SettingsMenuElementBase {
diff --git a/chrome/browser/resources/settings/settings_page/main_page_behavior.js b/chrome/browser/resources/settings/settings_page/main_page_behavior.js index 285265ef..be16837 100644 --- a/chrome/browser/resources/settings/settings_page/main_page_behavior.js +++ b/chrome/browser/resources/settings/settings_page/main_page_behavior.js
@@ -4,7 +4,7 @@ // clang-format off import {assert} from 'chrome://resources/js/assert.m.js'; -import {beforeNextRender} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {beforeNextRender, dedupingMixin} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {ensureLazyLoaded} from '../ensure_lazy_loaded.js'; import {loadTimeData} from '../i18n_setup.js'; @@ -61,518 +61,546 @@ * Responds to route changes by expanding, collapsing, or scrolling to * sections on the page. Expanded sections take up the full height of the * container. At most one section should be expanded at any given time. - * @polymerBehavior + * @polymer + * @mixinFunction */ - export const MainPageBehavior = { - properties: { - /** - * Whether a search operation is in progress or previous search results - * are being displayed. - * @private {boolean} - */ - inSearchMode: { - type: Boolean, - value: false, - observer: 'inSearchModeChanged_', - reflectToAttribute: true, - }, - }, - - /** @type {?HTMLElement} */ - scroller: null, - + export const MainPageMixin = dedupingMixin(superClass => { /** - * A map holding all valid state transitions. - * @private {!Map<!RouteState, !RouteState>} + * @polymer + * @mixinClass */ - validTransitions_: (function() { - const allStates = new Set([ - RouteState.DIALOG, - RouteState.SECTION, - RouteState.SUBPAGE, - RouteState.TOP_LEVEL, - ]); + class MainPageMixin extends superClass { + static get properties() { + return { + /** + * Whether a search operation is in progress or previous search + * results are being displayed. + * @private + */ + inSearchMode: { + type: Boolean, + value: false, + observer: 'inSearchModeChanged_', + reflectToAttribute: true, + }, + }; + } - return new Map([ - [RouteState.INITIAL, allStates], - [ - RouteState.DIALOG, new Set([ + constructor() { + super(); + + /** @type {?HTMLElement} */ + this.scroller = null; + + /** + * A map holding all valid state transitions. + * @private {!Map<!RouteState, !Set<RouteState>>} + */ + this.validTransitions_ = (function() { + const allStates = new Set([ + RouteState.DIALOG, RouteState.SECTION, RouteState.SUBPAGE, RouteState.TOP_LEVEL, - ]) - ], - [RouteState.SECTION, allStates], - [RouteState.SUBPAGE, allStates], - [RouteState.TOP_LEVEL, allStates], - ]); - })(), + ]); - /** @override */ - attached() { - this.scroller = this.domHost ? this.domHost.parentNode : document.body; - }, - - /** - * Method to be defined by users of MainPageBehavior. - * @param {!Route} route - * @return {boolean} Whether the given route is part of |this| page. - */ - containsRoute(route) { - return false; - }, - - /** - * @param {boolean} current - * @param {boolean} previous - * @private - */ - inSearchModeChanged_(current, previous) { - if (loadTimeData.getBoolean('enableLandingPageRedesign')) { - // No need to deal with overscroll, as only one section is shown at any - // given time. - return; + return new Map([ + [RouteState.INITIAL, allStates], + [ + RouteState.DIALOG, new Set([ + RouteState.SECTION, + RouteState.SUBPAGE, + RouteState.TOP_LEVEL, + ]) + ], + [RouteState.SECTION, allStates], + [RouteState.SUBPAGE, allStates], + [RouteState.TOP_LEVEL, allStates], + ]); + })(); } - // Ignore 1st occurrence which happens while the element is being - // initialized. - if (previous === undefined) { - return; + /** @override */ + connectedCallback() { + this.scroller = this.domHost ? this.domHost.parentNode : document.body; + + // Purposefully calling this after |scroller| has been initialized. + super.connectedCallback(); } - if (!this.inSearchMode) { - const route = Router.getInstance().getCurrentRoute(); - if (this.containsRoute(route) && - classifyRoute(route) === RouteState.SECTION) { - // Re-fire the showing-section event to trigger settings-main - // recalculation of the overscroll, now that sections are not - // hidden-by-search. - this.fire('showing-section', this.getSection(route.section)); + /** + * Method to be overridden by users of MainPageMixin. + * @param {Route} route + * @return {boolean} Whether the given route is part of |this| page. + */ + containsRoute(route) { + return false; + } + + /** + * @param {boolean} current + * @param {boolean} previous + * @private + */ + inSearchModeChanged_(current, previous) { + if (loadTimeData.getBoolean('enableLandingPageRedesign')) { + // No need to deal with overscroll, as only one section is shown at + // any given time. + return; + } + + // Ignore 1st occurrence which happens while the element is being + // initialized. + if (previous === undefined) { + return; + } + + if (!this.inSearchMode) { + const route = Router.getInstance().getCurrentRoute(); + if (this.containsRoute(route) && + classifyRoute(route) === RouteState.SECTION) { + // Re-fire the showing-section event to trigger settings-main + // recalculation of the overscroll, now that sections are not + // hidden-by-search. + this.fire('showing-section', this.getSection(route.section)); + } } } - }, - /** - * @param {!Route} route - * @return {boolean} - * @private - */ - shouldExpandAdvanced_(route) { - const routes = /** @type {!MinimumRoutes} */ ( - Router.getInstance().getRoutes()); - return this.tagName === 'SETTINGS-BASIC-PAGE' && - routes.ADVANCED && routes.ADVANCED.contains(route); - }, - - /** - * Finds the settings section corresponding to the given route. If the - * section is lazily loaded it force-renders it. - * Note: If the section resides within "advanced" settings, a - * 'hide-container' event is fired (necessary to avoid flashing). Callers - * are responsible for firing a 'show-container' event. - * @param {!Route} route - * @return {!Promise<!SettingsSectionElement>} - * @private - */ - ensureSectionForRoute_(route) { - const section = this.getSection(route.section); - if (section !== null) { - return Promise.resolve(section); + /** + * @param {!Route} route + * @return {boolean} + * @private + */ + shouldExpandAdvanced_(route) { + const routes = + /** @type {!MinimumRoutes} */ (Router.getInstance().getRoutes()); + return this.tagName === 'SETTINGS-BASIC-PAGE' && routes.ADVANCED && + routes.ADVANCED.contains(route); } - // The function to use to wait for <dom-if>s to render. - const waitFn = beforeNextRender.bind(null, this); + /** + * Finds the settings section corresponding to the given route. If the + * section is lazily loaded it force-renders it. + * Note: If the section resides within "advanced" settings, a + * 'hide-container' event is fired (necessary to avoid flashing). Callers + * are responsible for firing a 'show-container' event. + * @param {!Route} route + * @return {!Promise<!SettingsSectionElement>} + * @private + */ + ensureSectionForRoute_(route) { + const section = this.getSection(route.section); + if (section !== null) { + return Promise.resolve(section); + } - return new Promise(resolve => { - if (this.shouldExpandAdvanced_(route)) { - this.fire('hide-container'); - waitFn(() => { - this.$$('#advancedPageTemplate').get().then(() => { + // The function to use to wait for <dom-if>s to render. + const waitFn = beforeNextRender.bind(null, this); + + return new Promise(resolve => { + if (this.shouldExpandAdvanced_(route)) { + this.fire('hide-container'); + waitFn(() => { + this.$$('#advancedPageTemplate').get().then(() => { + resolve(this.getSection(route.section)); + }); + }); + } else { + waitFn(() => { resolve(this.getSection(route.section)); }); - }); - } else { - waitFn(() => { - resolve(this.getSection(route.section)); - }); - } - }); - }, - - /** - * Finds the settings-section instances corresponding to the given route. If - * the section is lazily loaded it force-renders it. - * Note: If the section resides within "advanced" settings, a - * 'hide-container' event is fired (necessary to avoid flashing). Callers - * are responsible for firing a 'show-container' event. - * @param {!Route} route - * @return {!Promise<!Array<!SettingsSectionElement>>} - * @private - */ - ensureSectionsForRoute_(route) { - const sections = this.querySettingsSections_(route.section); - if (sections.length > 0) { - return Promise.resolve(sections); + } + }); } - // The function to use to wait for <dom-if>s to render. - const waitFn = beforeNextRender.bind(null, this); + /** + * Finds the settings-section instances corresponding to the given route. + * If the section is lazily loaded it force-renders it. Note: If the + * section resides within "advanced" settings, a 'hide-container' event is + * fired (necessary to avoid flashing). Callers are responsible for firing + * a 'show-container' event. + * @param {!Route} route + * @return {!Promise<!Array<!SettingsSectionElement>>} + * @private + */ + ensureSectionsForRoute_(route) { + const sections = this.querySettingsSections_(route.section); + if (sections.length > 0) { + return Promise.resolve(sections); + } - return new Promise(resolve => { - if (this.shouldExpandAdvanced_(route)) { - this.fire('hide-container'); - waitFn(() => { - this.$$('#advancedPageTemplate').get().then(() => { + // The function to use to wait for <dom-if>s to render. + const waitFn = beforeNextRender.bind(null, this); + + return new Promise(resolve => { + if (this.shouldExpandAdvanced_(route)) { + this.fire('hide-container'); + waitFn(() => { + this.$$('#advancedPageTemplate').get().then(() => { + resolve(this.querySettingsSections_(route.section)); + }); + }); + } else { + waitFn(() => { resolve(this.querySettingsSections_(route.section)); }); - }); - } else { - waitFn(() => { - resolve(this.querySettingsSections_(route.section)); - }); - } - }); - }, - - /** - * @param {!Route} route - * @private - */ - enterSubpage_(route) { - this.lastScrollTop_ = this.scroller.scrollTop; - this.scroller.scrollTop = 0; - this.classList.add('showing-subpage'); - this.fire('subpage-expand'); - - // Explicitly load the lazy_load.html module, since all subpages reside in - // the lazy loaded module. - ensureLazyLoaded(); - - this.ensureSectionForRoute_(route).then(section => { - section.classList.add('expanded'); - // Fire event used by a11y tests only. - this.fire('settings-section-expanded'); - - this.fire('show-container'); - }); - }, - - /** - * @param {!Route} oldRoute - * @return {!Promise<void>} - * @private - */ - enterMainPage_(oldRoute) { - const oldSection = this.getSection(oldRoute.section); - oldSection.classList.remove('expanded'); - this.classList.remove('showing-subpage'); - return new Promise((res, rej) => { - requestAnimationFrame(() => { - if (Router.getInstance().lastRouteChangeWasPopstate()) { - this.scroller.scrollTop = this.lastScrollTop_; } - this.fire('showing-main-page'); - res(); }); - }); - }, + } - /** - * @param {!Route} route - * @private - */ - scrollToSection_(route) { - this.ensureSectionForRoute_(route).then(section => { - if (!this.inSearchMode) { - this.fire('showing-section', section); - } - this.fire('show-container'); - }); - }, + /** + * @param {!Route} route + * @private + */ + enterSubpage_(route) { + this.lastScrollTop_ = this.scroller.scrollTop; + this.scroller.scrollTop = 0; + this.classList.add('showing-subpage'); + this.fire('subpage-expand'); - /** - * Shows the section(s) corresponding to |newRoute| and hides the previously - * |active| section(s), if any. - * @param {!Route} newRoute - */ - switchToSections_(newRoute) { - this.ensureSectionsForRoute_(newRoute).then(sections => { - // Clear any previously |active| section. - const oldSections = - this.shadowRoot.querySelectorAll(`settings-section[active]`); - for (const s of oldSections) { - s.toggleAttribute('active', false); + // Explicitly load the lazy_load.html module, since all subpages reside + // in the lazy loaded module. + ensureLazyLoaded(); + + this.ensureSectionForRoute_(route).then(section => { + section.classList.add('expanded'); + // Fire event used by a11y tests only. + this.fire('settings-section-expanded'); + + this.fire('show-container'); + }); + } + + /** + * @param {!Route} oldRoute + * @return {!Promise<void>} + * @private + */ + enterMainPage_(oldRoute) { + const oldSection = this.getSection(oldRoute.section); + oldSection.classList.remove('expanded'); + this.classList.remove('showing-subpage'); + return new Promise((res, rej) => { + requestAnimationFrame(() => { + if (Router.getInstance().lastRouteChangeWasPopstate()) { + this.scroller.scrollTop = this.lastScrollTop_; + } + this.fire('showing-main-page'); + res(); + }); + }); + } + + /** + * @param {!Route} route + * @private + */ + scrollToSection_(route) { + this.ensureSectionForRoute_(route).then(section => { + if (!this.inSearchMode) { + this.fire('showing-section', section); + } + this.fire('show-container'); + }); + } + + /** + * Shows the section(s) corresponding to |newRoute| and hides the + * previously |active| section(s), if any. + * @param {!Route} newRoute + */ + switchToSections_(newRoute) { + this.ensureSectionsForRoute_(newRoute).then(sections => { + // Clear any previously |active| section. + const oldSections = + this.shadowRoot.querySelectorAll(`settings-section[active]`); + for (const s of oldSections) { + s.toggleAttribute('active', false); + } + + for (const s of sections) { + s.toggleAttribute('active', true); + } + + this.fire('show-container'); + }); + } + + /** + * Detects which state transition is appropriate for the given new/old + * routes. + * @param {!Route} newRoute + * @param {Route} oldRoute + * @private + */ + getStateTransition_(newRoute, oldRoute) { + const containsNew = this.containsRoute(newRoute); + const containsOld = this.containsRoute(oldRoute); + + if (!containsNew && !containsOld) { + // Nothing to do, since none of the old/new routes belong to this + // page. + return null; } - for (const s of sections) { - s.toggleAttribute('active', true); + // Case where going from |this| page to an unrelated page. For example: + // |this| is settings-basic-page AND + // oldRoute is /searchEngines AND + // newRoute is /help. + if (containsOld && !containsNew) { + return [classifyRoute(oldRoute), RouteState.TOP_LEVEL]; } - this.fire('show-container'); - }); - }, - - /** - * Detects which state transition is appropriate for the given new/old - * routes. - * @param {!Route} newRoute - * @param {Route} oldRoute - * @private - */ - getStateTransition_(newRoute, oldRoute) { - const containsNew = this.containsRoute(newRoute); - const containsOld = this.containsRoute(oldRoute); - - if (!containsNew && !containsOld) { - // Nothing to do, since none of the old/new routes belong to this page. - return null; - } - - // Case where going from |this| page to an unrelated page. For example: - // |this| is settings-basic-page AND - // oldRoute is /searchEngines AND - // newRoute is /help. - if (containsOld && !containsNew) { - return [classifyRoute(oldRoute), RouteState.TOP_LEVEL]; - } - - // Case where return from an unrelated page to |this| page. For example: - // |this| is settings-basic-page AND - // oldRoute is /help AND - // newRoute is /searchEngines - if (!containsOld && containsNew) { - return [RouteState.TOP_LEVEL, classifyRoute(newRoute)]; - } - - // Case where transitioning between routes that both belong to |this| - // page. - return [classifyRoute(oldRoute), classifyRoute(newRoute)]; - }, - - /** - * @param {!Route} newRoute - * @param {Route} oldRoute - */ - currentRouteChanged(newRoute, oldRoute) { - const transition = this.getStateTransition_(newRoute, oldRoute); - if (transition === null) { - return; - } - - const oldState = transition[0]; - const newState = transition[1]; - assert(this.validTransitions_.get(oldState).has(newState)); - - loadTimeData.getBoolean('enableLandingPageRedesign') ? - this.processTransitionRedesign_( - oldRoute, newRoute, oldState, newState) : - this.processTransition_(oldRoute, newRoute, oldState, newState); - }, - - /** - * @param {Route} oldRoute - * @param {!Route} newRoute - * @param {!RouteState} oldState - * @param {!RouteState} newState - * @private - */ - processTransition_(oldRoute, newRoute, oldState, newState) { - if (oldState === RouteState.TOP_LEVEL) { - if (newState === RouteState.SECTION) { - this.scrollToSection_(newRoute); - } else if (newState === RouteState.SUBPAGE) { - this.enterSubpage_(newRoute); + // Case where return from an unrelated page to |this| page. For example: + // |this| is settings-basic-page AND + // oldRoute is /help AND + // newRoute is /searchEngines + if (!containsOld && containsNew) { + return [RouteState.TOP_LEVEL, classifyRoute(newRoute)]; } - // Nothing to do here for the case of RouteState.DIALOG or TOP_LEVEL. - // The latter happens when navigating from '/?search=foo' to '/' - // (clearing search results). - return; + + // Case where transitioning between routes that both belong to |this| + // page. + return [classifyRoute(oldRoute), classifyRoute(newRoute)]; } - if (oldState === RouteState.SECTION) { - if (newState === RouteState.SECTION) { - this.scrollToSection_(newRoute); - } else if (newState === RouteState.SUBPAGE) { - this.enterSubpage_(newRoute); - } else if (newState === RouteState.TOP_LEVEL) { - this.scroller.scrollTop = 0; + /** + * @param {!Route} newRoute + * @param {Route} oldRoute + */ + currentRouteChanged(newRoute, oldRoute) { + const transition = this.getStateTransition_(newRoute, oldRoute); + if (transition === null) { + return; } - // Nothing to do here for the case of RouteState.DIALOG. - return; + + const oldState = transition[0]; + const newState = transition[1]; + assert(this.validTransitions_.get(oldState).has(newState)); + + loadTimeData.getBoolean('enableLandingPageRedesign') ? + this.processTransitionRedesign_( + oldRoute, newRoute, oldState, newState) : + this.processTransition_(oldRoute, newRoute, oldState, newState); } - if (oldState === RouteState.SUBPAGE) { - if (newState === RouteState.SECTION) { - this.enterMainPage_(/** @type {!Route} */ (oldRoute)); - - // Scroll to the corresponding section, only if the user explicitly - // navigated to a section (via the menu). - if (!Router.getInstance().lastRouteChangeWasPopstate()) { + /** + * @param {Route} oldRoute + * @param {!Route} newRoute + * @param {!RouteState} oldState + * @param {!RouteState} newState + * @private + */ + processTransition_(oldRoute, newRoute, oldState, newState) { + if (oldState === RouteState.TOP_LEVEL) { + if (newState === RouteState.SECTION) { this.scrollToSection_(newRoute); + } else if (newState === RouteState.SUBPAGE) { + this.enterSubpage_(newRoute); } - } else if (newState === RouteState.SUBPAGE) { - // Handle case where the two subpages belong to - // different sections, but are linked to each other. For example - // /storage and /accounts (in ChromeOS). - if (!oldRoute.contains(newRoute) && !newRoute.contains(oldRoute)) { - this.enterMainPage_(oldRoute).then(() => { - this.enterSubpage_(newRoute); - }); - return; - } + // Nothing to do here for the case of RouteState.DIALOG or TOP_LEVEL. + // The latter happens when navigating from '/?search=foo' to '/' + // (clearing search results). + return; + } - // Handle case of subpage to sub-subpage navigation. - if (oldRoute.contains(newRoute)) { + if (oldState === RouteState.SECTION) { + if (newState === RouteState.SECTION) { + this.scrollToSection_(newRoute); + } else if (newState === RouteState.SUBPAGE) { + this.enterSubpage_(newRoute); + } else if (newState === RouteState.TOP_LEVEL) { this.scroller.scrollTop = 0; - return; } - // When going from a sub-subpage to its parent subpage, scroll - // position is automatically restored, because we focus the - // sub-subpage entry point. - } else if (newState === RouteState.TOP_LEVEL) { - this.enterMainPage_(/** @type {!Route} */ (oldRoute)); - } else if (newState === RouteState.DIALOG) { - // The only known case currently for such a transition is from - // /syncSetup to /signOut. - this.enterMainPage_(/** @type {!Route} */ (oldRoute)); + // Nothing to do here for the case of RouteState.DIALOG. + return; } - return; - } - if (oldState === RouteState.INITIAL) { - if (newState === RouteState.SECTION) { - this.scrollToSection_(newRoute); - } else if (newState === RouteState.SUBPAGE) { - this.enterSubpage_(newRoute); - } - // Nothing to do here for the case of RouteState.DIALOG and TOP_LEVEL. - return; - } + if (oldState === RouteState.SUBPAGE) { + if (newState === RouteState.SECTION) { + this.enterMainPage_(/** @type {!Route} */ (oldRoute)); - if (oldState === RouteState.DIALOG) { - if (newState === RouteState.SUBPAGE) { - // The only known case currently for such a transition is from - // /signOut to /syncSetup. - this.enterSubpage_(newRoute); - } - // Nothing to do for all other cases. - } + // Scroll to the corresponding section, only if the user explicitly + // navigated to a section (via the menu). + if (!Router.getInstance().lastRouteChangeWasPopstate()) { + this.scrollToSection_(newRoute); + } + } else if (newState === RouteState.SUBPAGE) { + // Handle case where the two subpages belong to + // different sections, but are linked to each other. For example + // /storage and /accounts (in ChromeOS). + if (!oldRoute.contains(newRoute) && !newRoute.contains(oldRoute)) { + this.enterMainPage_(oldRoute).then(() => { + this.enterSubpage_(newRoute); + }); + return; + } - // Nothing to do for when oldState === RouteState.DIALOG. - }, - - /** - * @param {Route} oldRoute - * @param {!Route} newRoute - * @param {!RouteState} oldState - * @param {!RouteState} newState - * @private - */ - processTransitionRedesign_(oldRoute, newRoute, oldState, newState) { - if (oldState === RouteState.TOP_LEVEL) { - if (newState === RouteState.SECTION) { - this.switchToSections_(newRoute); - } else if (newState === RouteState.SUBPAGE) { - this.enterSubpage_(newRoute); - } else if (newState === RouteState.TOP_LEVEL) { - // Case when navigating from '/?search=foo' to '/' (clearing search - // results). - this.switchToSections_(TOP_LEVEL_EQUIVALENT_ROUTE); - } - // Nothing to do here for the case of RouteState.DIALOG. - return; - } - - if (oldState === RouteState.SECTION) { - if (newState === RouteState.SECTION) { - this.switchToSections_(newRoute); - } else if (newState === RouteState.SUBPAGE) { - this.switchToSections_(newRoute); - this.enterSubpage_(newRoute); - } else if (newState === RouteState.TOP_LEVEL) { - this.switchToSections_(TOP_LEVEL_EQUIVALENT_ROUTE); - this.scroller.scrollTop = 0; - } - // Nothing to do here for the case of RouteState.DIALOG. - return; - } - - if (oldState === RouteState.SUBPAGE) { - if (newState === RouteState.SECTION) { - this.enterMainPage_(/** @type {!Route} */ (oldRoute)); - this.switchToSections_(newRoute); - } else if (newState === RouteState.SUBPAGE) { - // Handle case where the two subpages belong to - // different sections, but are linked to each other. For example - // /storage and /accounts (in ChromeOS). - if (!oldRoute.contains(newRoute) && !newRoute.contains(oldRoute)) { - this.enterMainPage_(oldRoute).then(() => { - this.enterSubpage_(newRoute); - }); - return; + // Handle case of subpage to sub-subpage navigation. + if (oldRoute.contains(newRoute)) { + this.scroller.scrollTop = 0; + return; + } + // When going from a sub-subpage to its parent subpage, scroll + // position is automatically restored, because we focus the + // sub-subpage entry point. + } else if (newState === RouteState.TOP_LEVEL) { + this.enterMainPage_(/** @type {!Route} */ (oldRoute)); + } else if (newState === RouteState.DIALOG) { + // The only known case currently for such a transition is from + // /syncSetup to /signOut. + this.enterMainPage_(/** @type {!Route} */ (oldRoute)); } + return; + } - // Handle case of subpage to sub-subpage navigation. - if (oldRoute.contains(newRoute)) { + if (oldState === RouteState.INITIAL) { + if (newState === RouteState.SECTION) { + this.scrollToSection_(newRoute); + } else if (newState === RouteState.SUBPAGE) { + this.enterSubpage_(newRoute); + } + // Nothing to do here for the case of RouteState.DIALOG and TOP_LEVEL. + return; + } + + if (oldState === RouteState.DIALOG) { + if (newState === RouteState.SUBPAGE) { + // The only known case currently for such a transition is from + // /signOut to /syncSetup. + this.enterSubpage_(newRoute); + } + // Nothing to do for all other cases. + } + + // Nothing to do for when oldState === RouteState.DIALOG. + } + + /** + * @param {Route} oldRoute + * @param {!Route} newRoute + * @param {!RouteState} oldState + * @param {!RouteState} newState + * @private + */ + processTransitionRedesign_(oldRoute, newRoute, oldState, newState) { + if (oldState === RouteState.TOP_LEVEL) { + if (newState === RouteState.SECTION) { + this.switchToSections_(newRoute); + } else if (newState === RouteState.SUBPAGE) { + this.enterSubpage_(newRoute); + } else if (newState === RouteState.TOP_LEVEL) { + // Case when navigating from '/?search=foo' to '/' (clearing search + // results). + this.switchToSections_(TOP_LEVEL_EQUIVALENT_ROUTE); + } + // Nothing to do here for the case of RouteState.DIALOG. + return; + } + + if (oldState === RouteState.SECTION) { + if (newState === RouteState.SECTION) { + this.switchToSections_(newRoute); + } else if (newState === RouteState.SUBPAGE) { + this.switchToSections_(newRoute); + this.enterSubpage_(newRoute); + } else if (newState === RouteState.TOP_LEVEL) { + this.switchToSections_(TOP_LEVEL_EQUIVALENT_ROUTE); this.scroller.scrollTop = 0; - return; } - // When going from a sub-subpage to its parent subpage, scroll - // position is automatically restored, because we focus the - // sub-subpage entry point. - } else if (newState === RouteState.TOP_LEVEL) { - this.enterMainPage_(/** @type {!Route} */ (oldRoute)); + // Nothing to do here for the case of RouteState.DIALOG. + return; } - return; - } - if (oldState === RouteState.INITIAL) { - if ([RouteState.SECTION, RouteState.DIALOG].includes(newState)) { - this.switchToSections_(newRoute); - } else if (newState === RouteState.SUBPAGE) { - this.switchToSections_(newRoute); - this.enterSubpage_(newRoute); - } else if (newState === RouteState.TOP_LEVEL) { - this.switchToSections_(TOP_LEVEL_EQUIVALENT_ROUTE); + if (oldState === RouteState.SUBPAGE) { + if (newState === RouteState.SECTION) { + this.enterMainPage_(/** @type {!Route} */ (oldRoute)); + this.switchToSections_(newRoute); + } else if (newState === RouteState.SUBPAGE) { + // Handle case where the two subpages belong to + // different sections, but are linked to each other. For example + // /storage and /accounts (in ChromeOS). + if (!oldRoute.contains(newRoute) && !newRoute.contains(oldRoute)) { + this.enterMainPage_(oldRoute).then(() => { + this.enterSubpage_(newRoute); + }); + return; + } + + // Handle case of subpage to sub-subpage navigation. + if (oldRoute.contains(newRoute)) { + this.scroller.scrollTop = 0; + return; + } + // When going from a sub-subpage to its parent subpage, scroll + // position is automatically restored, because we focus the + // sub-subpage entry point. + } else if (newState === RouteState.TOP_LEVEL) { + this.enterMainPage_(/** @type {!Route} */ (oldRoute)); + } + return; } - return; + + if (oldState === RouteState.INITIAL) { + if ([RouteState.SECTION, RouteState.DIALOG].includes(newState)) { + this.switchToSections_(newRoute); + } else if (newState === RouteState.SUBPAGE) { + this.switchToSections_(newRoute); + this.enterSubpage_(newRoute); + } else if (newState === RouteState.TOP_LEVEL) { + this.switchToSections_(TOP_LEVEL_EQUIVALENT_ROUTE); + } + return; + } + + // Nothing to do for when oldState === RouteState.DIALOG. } - // Nothing to do for when oldState === RouteState.DIALOG. - }, - - /** - * TODO(dpapad): Rename this to |querySection| to distinguish it from - * ensureSectionForRoute_() which force-renders the section as needed. - * Helper function to get a section from the local DOM. - * @param {string} section Section name of the element to get. - * @return {?SettingsSectionElement} - */ - getSection(section) { - if (!section) { - return null; - } - return /** @type {?SettingsSectionElement} */ ( - this.$$(`settings-section[section="${section}"]`)); - }, - - /* - * @param {string} sectionName Section name of the element to get. - * @return {!Array<!SettingsSectionElement>} - */ - querySettingsSections_(sectionName) { - const result = []; - const section = this.getSection(sectionName); - - if (section) { - result.push(section); + /** + * TODO(dpapad): Rename this to |querySection| to distinguish it from + * ensureSectionForRoute_() which force-renders the section as needed. + * Helper function to get a section from the local DOM. + * @param {string} section Section name of the element to get. + * @return {?SettingsSectionElement} + */ + getSection(section) { + if (!section) { + return null; + } + return /** @type {?SettingsSectionElement} */ ( + this.$$(`settings-section[section="${section}"]`)); } - const extraSections = this.shadowRoot.querySelectorAll( - `settings-section[nest-under-section="${sectionName}"]`); - if (extraSections.length > 0) { - result.push(...extraSections); + /* + * @param {string} sectionName Section name of the element to get. + * @return {!Array<!SettingsSectionElement>} + */ + querySettingsSections_(sectionName) { + const result = []; + const section = this.getSection(sectionName); + + if (section) { + result.push(section); + } + + const extraSections = this.shadowRoot.querySelectorAll( + `settings-section[nest-under-section="${sectionName}"]`); + if (extraSections.length > 0) { + result.push(...extraSections); + } + return result; } - return result; } - }; + + return MainPageMixin; + }); + + /** @interface */ + export class MainPageMixinInterface { + /** + * @param {Route} route + * @return {boolean} + */ + containsRoute(route) {} + }
diff --git a/chrome/browser/resources/settings/settings_page/settings_animated_pages.js b/chrome/browser/resources/settings/settings_page/settings_animated_pages.js index 01fca15..95872c46 100644 --- a/chrome/browser/resources/settings/settings_page/settings_animated_pages.js +++ b/chrome/browser/resources/settings/settings_page/settings_animated_pages.js
@@ -19,9 +19,9 @@ import {assert} from '//resources/js/assert.m.js'; import {focusWithoutInk} from '//resources/js/cr/ui/focus_without_ink.m.js'; import {loadTimeData} from '//resources/js/load_time_data.m.js'; -import {dom, DomIf, html, microTask, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {dom, DomIf, html, microTask, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {Route, RouteObserverBehavior, Router} from '../router.js'; +import {Route, RouteObserverMixin, Router} from '../router.js'; import {getSettingIdParameter} from '../setting_id_param_util.js'; @@ -29,8 +29,7 @@ * @constructor * @extends {PolymerElement} */ -const SettingsAnimatedPagesElementBase = - mixinBehaviors([RouteObserverBehavior], PolymerElement); +const SettingsAnimatedPagesElementBase = RouteObserverMixin(PolymerElement); /** @polymer */ class SettingsAnimatedPagesElement extends SettingsAnimatedPagesElementBase {
diff --git a/chrome/browser/resources/settings/settings_page/settings_section.js b/chrome/browser/resources/settings/settings_page/settings_section.js index 651701b..5e46476 100644 --- a/chrome/browser/resources/settings/settings_page/settings_section.js +++ b/chrome/browser/resources/settings/settings_page/settings_section.js
@@ -34,7 +34,7 @@ return { /** * The section name should match a name specified in route.js. The - * MainPageBehavior will expand this section if this section name matches + * MainPageBeMixin will expand this section if this section name matches * currentRoute.section. */ section: String,
diff --git a/chrome/browser/resources/settings/settings_page/settings_subpage.js b/chrome/browser/resources/settings/settings_page/settings_subpage.js index 8c4b1f6..a098a285 100644 --- a/chrome/browser/resources/settings/settings_page/settings_subpage.js +++ b/chrome/browser/resources/settings/settings_page/settings_subpage.js
@@ -25,7 +25,7 @@ import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; import {loadTimeData} from '../i18n_setup.js'; -import {RouteObserverBehavior, Router} from '../router.js'; +import {RouteObserverMixin, Router} from '../router.js'; import {getSettingIdParameter} from '../setting_id_param_util.js'; @@ -36,11 +36,8 @@ * @implements {FindShortcutBehaviorInterface} */ const SettingsSubpageElementBase = mixinBehaviors( - [ - FindShortcutBehavior, I18nBehavior, IronResizableBehavior, - RouteObserverBehavior - ], - PolymerElement); + [FindShortcutBehavior, I18nBehavior, IronResizableBehavior], + RouteObserverMixin(PolymerElement)); /** @polymer */ class SettingsSubpageElement extends SettingsSubpageElementBase {
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.js b/chrome/browser/resources/settings/settings_ui/settings_ui.js index 05e73d2..65ab978 100644 --- a/chrome/browser/resources/settings/settings_ui/settings_ui.js +++ b/chrome/browser/resources/settings/settings_ui/settings_ui.js
@@ -35,7 +35,7 @@ import {PageVisibility, pageVisibility} from '../page_visibility.js'; import {SettingsPrefsElement} from '../prefs/prefs.js'; import {routes} from '../route.js'; -import {Route, RouteObserverBehavior, Router} from '../router.js'; +import {Route, RouteObserverMixin, Router} from '../router.js'; /** @@ -43,8 +43,8 @@ * @extends {PolymerElement} */ const SettingsUiElementBase = mixinBehaviors( - [RouteObserverBehavior, CrContainerShadowBehavior, FindShortcutBehavior], - PolymerElement); + [CrContainerShadowBehavior, FindShortcutBehavior], + RouteObserverMixin(PolymerElement)); /** @polymer */ export class SettingsUiElement extends SettingsUiElementBase { @@ -313,7 +313,7 @@ */ onMenuClose_() { if (!this.$.drawer.wasCanceled()) { - // If a navigation happened, MainPageBehavior#currentRouteChanged + // If a navigation happened, MainPageMixin#currentRouteChanged // handles focusing the corresponding section. return; }
diff --git a/chrome/browser/resources/settings/site_settings/site_data_details_subpage.js b/chrome/browser/resources/settings/site_settings/site_data_details_subpage.js index bc63c102..93b6366f 100644 --- a/chrome/browser/resources/settings/site_settings/site_data_details_subpage.js +++ b/chrome/browser/resources/settings/site_settings/site_data_details_subpage.js
@@ -15,7 +15,7 @@ import {loadTimeData} from '../i18n_setup.js'; import {MetricsBrowserProxyImpl, PrivacyElementInteractions} from '../metrics_browser_proxy.js'; import {routes} from '../route.js'; -import {Route, RouteObserverBehavior, Router} from '../router.js'; +import {Route, RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js'; import {CookieDataForDisplay, CookieDetails, getCookieData} from './cookie_info.js'; import {LocalDataBrowserProxy, LocalDataBrowserProxyImpl} from './local_data_browser_proxy.js'; @@ -41,10 +41,11 @@ /** * @constructor * @extends {PolymerElement} + * @implements {RouteObserverMixinInterface} * @implements {WebUIListenerBehaviorInterface} */ -const SiteDataDetailsSubpageElementBase = mixinBehaviors( - [RouteObserverBehavior, WebUIListenerBehavior], PolymerElement); +const SiteDataDetailsSubpageElementBase = + mixinBehaviors([WebUIListenerBehavior], RouteObserverMixin(PolymerElement)); /** @polymer */ class SiteDataDetailsSubpageElement extends SiteDataDetailsSubpageElementBase { @@ -95,9 +96,8 @@ } /** - * RouteObserverBehavior - * @param {!Route} route - * @protected + * RouteObserverMixin + * @override */ currentRouteChanged(route) { if (Router.getInstance().getCurrentRoute() !==
diff --git a/chrome/browser/resources/settings/site_settings/site_details.js b/chrome/browser/resources/settings/site_settings/site_details.js index 8a6934e..aff5f14 100644 --- a/chrome/browser/resources/settings/site_settings/site_details.js +++ b/chrome/browser/resources/settings/site_settings/site_details.js
@@ -32,7 +32,7 @@ import {loadTimeData} from '../i18n_setup.js'; import {MetricsBrowserProxyImpl, PrivacyElementInteractions} from '../metrics_browser_proxy.js'; import {routes} from '../route.js'; -import {Route, RouteObserverBehavior, Router} from '../router.js'; +import {Route, RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js'; import {ContentSetting, ContentSettingsTypes} from './constants.js'; import {SiteDetailsPermissionElement} from './site_details_permission.js'; @@ -43,14 +43,12 @@ * @constructor * @extends {PolymerElement} * @implements {SiteSettingsBehaviorInterface} + * @implements {RouteObserverMixinInterface} * @implements {WebUIListenerBehaviorInterface} */ const SiteDetailsElementBase = mixinBehaviors( - [ - I18nBehavior, SiteSettingsBehavior, RouteObserverBehavior, - WebUIListenerBehavior - ], - PolymerElement); + [I18nBehavior, SiteSettingsBehavior, WebUIListenerBehavior], + RouteObserverMixin(PolymerElement)); /** @polymer */ class SiteDetailsElement extends SiteDetailsElementBase { @@ -153,9 +151,8 @@ } /** - * RouteObserverBehavior - * @param {!Route} route - * @protected + * RouteObserverMixin + * @override */ currentRouteChanged(route) { if (route !== routes.SITE_SETTINGS_SITE_DETAILS) {
diff --git a/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js b/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js index 44d99a2..3c6935a 100644 --- a/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js +++ b/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js
@@ -15,7 +15,7 @@ import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {routes} from '../route.js'; -import {Route, RouteObserverBehavior, Router} from '../router.js'; +import {Route, RouteObserverMixin, Router} from '../router.js'; import {AllSitesAction2, ContentSetting, ContentSettingsTypes, SiteSettingSource} from '../site_settings/constants.js'; import {SiteSettingsBehavior, SiteSettingsBehaviorInterface} from '../site_settings/site_settings_behavior.js'; import {RawSiteException, RecentSitePermissions} from '../site_settings/site_settings_prefs_browser_proxy.js'; @@ -28,11 +28,8 @@ * @implements {WebUIListenerBehaviorInterface} */ const SettingsRecentSitePermissionsElementBase = mixinBehaviors( - [ - RouteObserverBehavior, SiteSettingsBehavior, WebUIListenerBehavior, - I18nBehavior - ], - PolymerElement); + [SiteSettingsBehavior, WebUIListenerBehavior, I18nBehavior], + RouteObserverMixin(PolymerElement)); /** @polymer */ export class SettingsRecentSitePermissionsElement extends
diff --git a/chrome/browser/signin/dice_web_signin_interceptor.cc b/chrome/browser/signin/dice_web_signin_interceptor.cc index c82b404..f68f8d8 100644 --- a/chrome/browser/signin/dice_web_signin_interceptor.cc +++ b/chrome/browser/signin/dice_web_signin_interceptor.cc
@@ -15,7 +15,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" -#include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/password_manager/chrome_password_manager_client.h" #include "chrome/browser/policy/profile_policy_connector.h" @@ -61,8 +60,6 @@ constexpr char kProfileCreationInterceptionDeclinedPref[] = "signin.ProfileCreationInterceptionDeclinedPref"; -constexpr char kProfileSwitchInterceptionDeclinedPref[] = - "signin.ProfileSwitchInterceptionDeclinedPref"; void RecordSigninInterceptionHeuristicOutcome( SigninInterceptionHeuristicOutcome outcome) { @@ -125,14 +122,11 @@ void DiceWebSigninInterceptor::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { registry->RegisterDictionaryPref(kProfileCreationInterceptionDeclinedPref); - registry->RegisterDictionaryPref(kProfileSwitchInterceptionDeclinedPref); registry->RegisterBooleanPref(prefs::kSigninInterceptionEnabled, true); -#if !defined(OS_ANDROID) registry->RegisterStringPref(prefs::kManagedAccountsSigninRestriction, std::string()); registry->RegisterBooleanPref( prefs::kManagedAccountsSigninRestrictionScopeMachine, false); -#endif } absl::optional<SigninInterceptionHeuristicOutcome> @@ -170,10 +164,6 @@ email, &g_browser_process->profile_manager()->GetProfileAttributesStorage()); if (switch_to_entry) { - if (HasUserDeclinedProfileSwitch(email)) { - return SigninInterceptionHeuristicOutcome:: - kAbortUserDeclinedProfileForAccount; - } if (entry) *entry = switch_to_entry; return SigninInterceptionHeuristicOutcome::kInterceptProfileSwitch; @@ -208,9 +198,6 @@ CoreAccountId account_id, bool is_new_account, bool is_sync_signin) { - if (!base::FeatureList::IsEnabled(kDiceWebSigninInterceptionFeature)) - return; - if (is_interception_in_progress_) { // Multiple concurrent interceptions are not supported. RecordSigninInterceptionHeuristicOutcome( @@ -549,8 +536,6 @@ const base::FilePath& profile_path, SigninInterceptionResult switch_profile) { if (switch_profile != SigninInterceptionResult::kAccepted) { - if (switch_profile == SigninInterceptionResult::kDeclined) - RecordProfileSwitchDeclined(email); Reset(); return; } @@ -694,31 +679,3 @@ return declined_count && declined_count.value() >= kMaxProfileCreationDeclinedCount; } - -void DiceWebSigninInterceptor::RecordProfileSwitchDeclined( - const std::string& email) { - DictionaryPrefUpdate update(profile_->GetPrefs(), - kProfileSwitchInterceptionDeclinedPref); - std::string key = GetPersistentEmailHash(email); - absl::optional<int> declined_count = update->FindIntKey(key); - update->SetIntKey(key, declined_count.value_or(0) + 1); -} - -bool DiceWebSigninInterceptor::HasUserDeclinedProfileSwitch( - const std::string& email) const { - const base::DictionaryValue* pref_data = profile_->GetPrefs()->GetDictionary( - kProfileSwitchInterceptionDeclinedPref); - absl::optional<int> declined_count = - pref_data->FindIntKey(GetPersistentEmailHash(email)); - - // The limit is controlled by an experiment. Zero value completely turns off - // the profile switch bubble. Negative values mean there is no limit. By - // default, there is no limit. - int max_profile_switch_declined_count = - base::GetFieldTrialParamByFeatureAsInt( - kDiceWebSigninInterceptionFeature, - "max_profile_switch_declined_count", -1); - - return max_profile_switch_declined_count >= 0 && - declined_count.value_or(0) >= max_profile_switch_declined_count; -}
diff --git a/chrome/browser/signin/dice_web_signin_interceptor.h b/chrome/browser/signin/dice_web_signin_interceptor.h index 1a6ad94..be8db648 100644 --- a/chrome/browser/signin/dice_web_signin_interceptor.h +++ b/chrome/browser/signin/dice_web_signin_interceptor.h
@@ -322,23 +322,17 @@ // Returns a 8-bit hash of the email that can be persisted. static std::string GetPersistentEmailHash(const std::string& email); - // Should be called when the user declines profile creation or profile switch, - // in order to remember their decision. This information is stored in prefs. - // Only a hash of the email is saved, as Chrome does not need to store the - // actual email, but only need to compare emails. The hash has low entropy to - // ensure it cannot be reversed. + // Should be called when the user declines profile creation, in order to + // remember their decision. This information is stored in prefs. Only a hash + // of the email is saved, as Chrome does not need to store the actual email, + // but only need to compare emails. The hash has low entropy to ensure it + // cannot be reversed. void RecordProfileCreationDeclined(const std::string& email); - void RecordProfileSwitchDeclined(const std::string& email); // Checks if the user previously declined 2 times creating a new profile for // this account. bool HasUserDeclinedProfileCreation(const std::string& email) const; - // Checks if the user previously declined more than a threshold number of - // times switching to a new profile for this account. The limit is set up - // via an experiment parameter. - bool HasUserDeclinedProfileSwitch(const std::string& email) const; - Profile* const profile_; signin::IdentityManager* const identity_manager_; std::unique_ptr<Delegate> delegate_;
diff --git a/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc b/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc index c1011b3c..3fe1a23 100644 --- a/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc +++ b/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc
@@ -224,8 +224,7 @@ class DiceWebSigninInterceptorBrowserTest : public InProcessBrowserTest { public: - DiceWebSigninInterceptorBrowserTest() - : feature_list_(kDiceWebSigninInterceptionFeature) {} + DiceWebSigninInterceptorBrowserTest() = default; Profile* profile() { return browser()->profile(); } @@ -253,9 +252,6 @@ return interceptor_delegate; } - protected: - base::test::ScopedFeatureList feature_list_; - private: // InProcessBrowserTest: void SetUpOnMainThread() override {
diff --git a/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc b/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc index ebc4acd..3c5475dd 100644 --- a/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc +++ b/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc
@@ -176,20 +176,9 @@ EXPECT_TRUE(interceptor()->is_interception_in_progress()); } - protected: - virtual void InitFeatures() { - InitWithEnabledFeatures({kDiceWebSigninInterceptionFeature}); - } - - void InitWithEnabledFeatures( - const std::vector<base::Feature>& enabled_features) { - feature_list_.InitWithFeatures(enabled_features, {}); - } - private: // testing::Test: void SetUp() override { - InitFeatures(); BrowserWithTestWindowTest::SetUp(); identity_test_env_profile_adaptor_ = @@ -224,7 +213,6 @@ return factories; } - base::test::ScopedFeatureList feature_list_; network::TestURLLoaderFactory test_url_loader_factory_; std::unique_ptr<IdentityTestEnvironmentProfileAdaptor> identity_test_env_profile_adaptor_; @@ -385,11 +373,12 @@ } class DiceWebSigninInterceptorReauthTest : public DiceWebSigninInterceptorTest { - protected: - void InitFeatures() override { - InitWithEnabledFeatures( - {kDiceWebSigninInterceptionFeature, kAccountPoliciesLoadedWithoutSync}); - } + public: + DiceWebSigninInterceptorReauthTest() + : feature_list_(kAccountPoliciesLoadedWithoutSync) {} + + private: + base::test::ScopedFeatureList feature_list_; }; TEST_F(DiceWebSigninInterceptorReauthTest, @@ -790,110 +779,6 @@ } } -TEST_F(DiceWebSigninInterceptorTest, - DeclineSwitchRepeatedly_LimitedByExperiment) { - const int kMaxProfileSwitchDeclinedCount = 3; - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeatureWithParameters( - kDiceWebSigninInterceptionFeature, - {{"max_profile_switch_declined_count", - base::NumberToString(kMaxProfileSwitchDeclinedCount)}}); - - base::HistogramTester histogram_tester; - // Setup for profile switch interception. - std::string email = "bob@example.com"; - AccountInfo account_info = identity_test_env()->MakeAccountAvailable(email); - Profile* profile_2 = CreateTestingProfile("Profile 2"); - ProfileAttributesEntry* entry = - profile_attributes_storage()->GetProfileAttributesWithPath( - profile_2->GetPath()); - ASSERT_NE(entry, nullptr); - entry->SetAuthInfo(account_info.gaia, base::UTF8ToUTF16(email), - /*is_consented_primary_account=*/false); - - // Decline the interception kMaxProfileSwitchDeclinedCount times. - DiceWebSigninInterceptor::Delegate::BubbleParameters expected_parameters = { - DiceWebSigninInterceptor::SigninInterceptionType::kProfileSwitch, - account_info, AccountInfo(), SkColor()}; - for (int i = 0; i < kMaxProfileSwitchDeclinedCount; ++i) { - EXPECT_CALL(*mock_delegate(), - ShowSigninInterceptionBubble( - web_contents(), MatchBubbleParameters(expected_parameters), - testing::_)) - .WillOnce(testing::WithArg<2>(testing::Invoke( - [](base::OnceCallback<void(SigninInterceptionResult)> callback) { - std::move(callback).Run(SigninInterceptionResult::kDeclined); - return nullptr; - }))); - MaybeIntercept(account_info.account_id); - EXPECT_EQ(interceptor()->is_interception_in_progress(), false); - histogram_tester.ExpectUniqueSample( - "Signin.Intercept.HeuristicOutcome", - SigninInterceptionHeuristicOutcome::kInterceptProfileSwitch, i + 1); - } - - // Next time the interception is not shown again. - MaybeIntercept(account_info.account_id); - EXPECT_EQ(interceptor()->is_interception_in_progress(), false); - histogram_tester.ExpectBucketCount( - "Signin.Intercept.HeuristicOutcome", - SigninInterceptionHeuristicOutcome::kAbortUserDeclinedProfileForAccount, - 1); - - // Another account can still be intercepted. - account_info.email = "oscar@example.com"; - identity_test_env()->UpdateAccountInfoForAccount(account_info); - Profile* profile_3 = CreateTestingProfile("Profile 3"); - ProfileAttributesEntry* entry_2 = - profile_attributes_storage()->GetProfileAttributesWithPath( - profile_3->GetPath()); - ASSERT_NE(entry_2, nullptr); - entry_2->SetAuthInfo(account_info.gaia, base::UTF8ToUTF16(account_info.email), - /*is_consented_primary_account=*/false); - - expected_parameters = { - DiceWebSigninInterceptor::SigninInterceptionType::kProfileSwitch, - account_info, AccountInfo(), SkColor()}; - EXPECT_CALL(*mock_delegate(), - ShowSigninInterceptionBubble( - web_contents(), MatchBubbleParameters(expected_parameters), - testing::_)); - MaybeIntercept(account_info.account_id); - histogram_tester.ExpectBucketCount( - "Signin.Intercept.HeuristicOutcome", - SigninInterceptionHeuristicOutcome::kInterceptProfileSwitch, - kMaxProfileSwitchDeclinedCount + 1); - EXPECT_EQ(interceptor()->is_interception_in_progress(), true); -} - -TEST_F(DiceWebSigninInterceptorTest, - DeclineSwitchRepeatedly_DisabledByExperiment) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeatureWithParameters( - kDiceWebSigninInterceptionFeature, - {{"max_profile_switch_declined_count", "0"}}); - - base::HistogramTester histogram_tester; - // Setup for profile switch interception. - std::string email = "bob@example.com"; - AccountInfo account_info = identity_test_env()->MakeAccountAvailable(email); - Profile* profile_2 = CreateTestingProfile("Profile 2"); - ProfileAttributesEntry* entry = - profile_attributes_storage()->GetProfileAttributesWithPath( - profile_2->GetPath()); - ASSERT_NE(entry, nullptr); - entry->SetAuthInfo(account_info.gaia, base::UTF8ToUTF16(email), - /*is_consented_primary_account=*/false); - - // The interception is not shown even at first attempt. - MaybeIntercept(account_info.account_id); - EXPECT_EQ(interceptor()->is_interception_in_progress(), false); - histogram_tester.ExpectBucketCount( - "Signin.Intercept.HeuristicOutcome", - SigninInterceptionHeuristicOutcome::kAbortUserDeclinedProfileForAccount, - 1); -} - TEST_F(DiceWebSigninInterceptorTest, PersistentHash) { // The hash is persistent (the value should never change). EXPECT_EQ("email_174",
diff --git a/chrome/browser/signin/signin_features.cc b/chrome/browser/signin/signin_features.cc index f31e4ae..f1be00be 100644 --- a/chrome/browser/signin/signin_features.cc +++ b/chrome/browser/signin/signin_features.cc
@@ -4,11 +4,6 @@ #include "chrome/browser/signin/signin_features.h" -#if BUILDFLAG(ENABLE_DICE_SUPPORT) -const base::Feature kDiceWebSigninInterceptionFeature{ - "DiceWebSigninInterception", base::FEATURE_ENABLED_BY_DEFAULT}; -#endif // ENABLE_DICE_SUPPORT - // Enables the client-side processing of the HTTP response header // Google-Accounts-RemoveLocalAccount. const base::Feature kProcessGaiaRemoveLocalAccountHeader{
diff --git a/chrome/browser/signin/signin_features.h b/chrome/browser/signin/signin_features.h index b27cf7d..311e4040 100644 --- a/chrome/browser/signin/signin_features.h +++ b/chrome/browser/signin/signin_features.h
@@ -6,11 +6,6 @@ #define CHROME_BROWSER_SIGNIN_SIGNIN_FEATURES_H_ #include "base/feature_list.h" -#include "components/signin/public/base/signin_buildflags.h" - -#if BUILDFLAG(ENABLE_DICE_SUPPORT) -extern const base::Feature kDiceWebSigninInterceptionFeature; -#endif // ENABLE_DICE_SUPPORT extern const base::Feature kProcessGaiaRemoveLocalAccountHeader;
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_manager.cc b/chrome/browser/ui/exclusive_access/exclusive_access_manager.cc index b47f2aff..545205e7 100644 --- a/chrome/browser/ui/exclusive_access/exclusive_access_manager.cc +++ b/chrome/browser/ui/exclusive_access/exclusive_access_manager.cc
@@ -77,7 +77,6 @@ bool force_update) { GURL url = GetExclusiveAccessBubbleURL(); ExclusiveAccessBubbleType bubble_type = GetExclusiveAccessExitBubbleType(); - exclusive_access_context_->UpdateExclusiveAccessExitBubbleContent( url, bubble_type, std::move(bubble_first_hide_callback), force_update); }
diff --git a/chrome/browser/ui/exclusive_access/mouse_lock_controller.cc b/chrome/browser/ui/exclusive_access/mouse_lock_controller.cc index 6610453..ace9c11 100644 --- a/chrome/browser/ui/exclusive_access/mouse_lock_controller.cc +++ b/chrome/browser/ui/exclusive_access/mouse_lock_controller.cc
@@ -97,9 +97,11 @@ mouse_lock_state_ = MOUSELOCK_UNLOCKED; } - exclusive_access_manager()->UpdateExclusiveAccessExitBubbleContent( - base::BindOnce(&MouseLockController::OnBubbleHidden, - weak_ptr_factory_.GetWeakPtr(), web_contents)); + if (!ShouldSuppressBubbleReshowForStateChange()) { + exclusive_access_manager()->UpdateExclusiveAccessExitBubbleContent( + base::BindOnce(&MouseLockController::OnBubbleHidden, + weak_ptr_factory_.GetWeakPtr(), web_contents)); + } } void MouseLockController::ExitExclusiveAccessIfNecessary() { @@ -144,8 +146,11 @@ RecordExitingUMA(); mouse_lock_state_ = MOUSELOCK_UNLOCKED; SetTabWithExclusiveAccess(nullptr); - exclusive_access_manager()->UpdateExclusiveAccessExitBubbleContent( - ExclusiveAccessBubbleHideCallback()); + + if (!ShouldSuppressBubbleReshowForStateChange()) { + exclusive_access_manager()->UpdateExclusiveAccessExitBubbleContent( + ExclusiveAccessBubbleHideCallback()); + } } void MouseLockController::UnlockMouse() { @@ -175,3 +180,14 @@ if (reason == ExclusiveAccessBubbleHideReason::kTimeout) web_contents_granted_silent_mouse_lock_permission_ = web_contents; } + +bool MouseLockController::ShouldSuppressBubbleReshowForStateChange() { + ExclusiveAccessBubbleType bubble_type = + exclusive_access_manager()->GetExclusiveAccessExitBubbleType(); + return (mouse_lock_state_ == MOUSELOCK_LOCKED && + bubble_type == + EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_MOUSELOCK_EXIT_INSTRUCTION) || + (mouse_lock_state_ == MOUSELOCK_UNLOCKED && + bubble_type == + EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_EXIT_INSTRUCTION); +}
diff --git a/chrome/browser/ui/exclusive_access/mouse_lock_controller.h b/chrome/browser/ui/exclusive_access/mouse_lock_controller.h index 35ae92e..ca591edd 100644 --- a/chrome/browser/ui/exclusive_access/mouse_lock_controller.h +++ b/chrome/browser/ui/exclusive_access/mouse_lock_controller.h
@@ -66,6 +66,8 @@ void OnBubbleHidden(content::WebContents*, ExclusiveAccessBubbleHideReason); + bool ShouldSuppressBubbleReshowForStateChange(); + MouseLockState mouse_lock_state_; // Optionally a WebContents instance that is granted permission to silently
diff --git a/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc b/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc index 7eb12715..7b875e9 100644 --- a/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc +++ b/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc
@@ -117,7 +117,14 @@ std::u16string ChromePageInfoUiDelegate::GetPermissionDetail( ContentSettingsType type) { - return content_settings::GetPermissionDetailString(profile_, type, site_url_); + switch (type) { + // TODO(crbug.com/1228243): Reconcile with SiteDetailsPermissionElement. + case ContentSettingsType::ADS: + return l10n_util::GetStringUTF16(IDS_PAGE_INFO_PERMISSION_ADS_SUBTITLE); + default: + return content_settings::GetPermissionDetailString(profile_, type, + site_url_); + } } bool ChromePageInfoUiDelegate::IsBlockAutoPlayEnabled() {
diff --git a/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop.cc b/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop.cc index d225d2f..0e8774ac 100644 --- a/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop.cc +++ b/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop.cc
@@ -95,13 +95,13 @@ // Collect the data that needs to be scanned. if (!drop_data.url_title.empty()) - data.text.push_back(drop_data.url_title); + data.text.push_back(base::UTF16ToUTF8(drop_data.url_title)); if (drop_data.text) - data.text.push_back(*drop_data.text); + data.text.push_back(base::UTF16ToUTF8(*drop_data.text)); if (drop_data.html) - data.text.push_back(*drop_data.html); + data.text.push_back(base::UTF16ToUTF8(*drop_data.html)); if (!drop_data.file_contents.empty()) - data.text.push_back(base::UTF8ToUTF16(drop_data.file_contents)); + data.text.push_back(drop_data.file_contents); if (drop_data.filenames.empty()) { ScanData(web_contents, std::move(callback), std::move(data));
diff --git a/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.cc b/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.cc index a35867d..495aeaf 100644 --- a/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.cc +++ b/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.cc
@@ -60,9 +60,9 @@ class SwitchToTabButton : public TabSharingInfoBarDelegateButton { public: SwitchToTabButton(const TabSharingInfoBarDelegate::FocusTarget& focus_target, - bool focus_target_is_captured) + bool focus_target_is_capturer) : focus_target_(focus_target), - focus_target_is_captured_(focus_target_is_captured) {} + focus_target_is_capturer_(focus_target_is_capturer) {} ~SwitchToTabButton() override = default; void Click(infobars::InfoBar* infobar) override { @@ -102,13 +102,13 @@ private: std::u16string GetDefaultLabel() const { return l10n_util::GetStringUTF16( - focus_target_is_captured_ - ? IDS_TAB_SHARING_INFOBAR_SWITCH_TO_CAPTURED_BUTTON - : IDS_TAB_SHARING_INFOBAR_SWITCH_TO_CAPTURER_BUTTON); + focus_target_is_capturer_ + ? IDS_TAB_SHARING_INFOBAR_SWITCH_TO_CAPTURER_BUTTON + : IDS_TAB_SHARING_INFOBAR_SWITCH_TO_CAPTURED_BUTTON); } const TabSharingInfoBarDelegate::FocusTarget focus_target_; - const bool focus_target_is_captured_; + const bool focus_target_is_capturer_; }; } // namespace
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc index eafc260..24ee0c1 100644 --- a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc +++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc
@@ -130,6 +130,7 @@ ChromeLayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_VERTICAL))); + set_close_on_deactivate(false); set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_BUBBLE_PREFERRED_WIDTH)); @@ -235,18 +236,13 @@ void PermissionPromptBubbleView::SetPromptStyle( PermissionPromptStyle prompt_style) { prompt_style_ = prompt_style; - // If bubble hanging off the padlock icon, with no chip showing, it shouldn't - // close on deactivate and it should stick until user makes a decision. - // Otherwise, the chip is indicating the pending permission request and so the - // bubble can be opened and closed repeatedly. + // If bubble hanging off the padlock icon, with no chip showing, closing the + // dialog should dismiss the pending request because there's no way to bring + // the bubble back. if (prompt_style == PermissionPromptStyle::kBubbleOnly) { - set_close_on_deactivate(false); DialogDelegate::SetCloseCallback( base::BindOnce(&PermissionPromptBubbleView::ClosingPermission, base::Unretained(this))); - } else { - set_close_on_deactivate(true); - DialogDelegate::SetCloseCallback(base::OnceClosure()); } }
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view_browsertest.cc b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view_browsertest.cc index 0db4616e..8fdf20b1 100644 --- a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view_browsertest.cc
@@ -119,16 +119,6 @@ } } - bool VerifyUi() override { - const bool should_close_on_deactivate = GetChip(); - views::Widget* prompt_widget = test_api_->GetPromptWindow(); - views::BubbleDialogDelegate* bubble_dialog = - prompt_widget->widget_delegate()->AsBubbleDialogDelegate(); - EXPECT_EQ(bubble_dialog->close_on_deactivate(), should_close_on_deactivate); - - return DialogBrowserTest::VerifyUi(); - } - GURL GetTestUrl() { return GURL("https://example.com"); } content::RenderFrameHost* GetActiveMainFrame() {
diff --git a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc index df5722a..236e14a 100644 --- a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc +++ b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc
@@ -96,8 +96,7 @@ } // Helper method to create zippy data. -base::Value CreateZippyData(const SettingZippyList& zippy_list, - bool is_minor_mode) { +base::Value CreateZippyData(const SettingZippyList& zippy_list) { base::Value zippy_data(base::Value::Type::LIST); for (auto& setting_zippy : zippy_list) { base::Value data(base::Value::Type::DICTIONARY); @@ -113,7 +112,6 @@ data.SetKey("iconUri", base::Value(setting_zippy.icon_uri())); data.SetKey("popupLink", base::Value(l10n_util::GetStringUTF16( IDS_ASSISTANT_ACTIVITY_CONTROL_POPUP_LINK))); - data.SetKey("isMinorMode", base::Value(is_minor_mode)); zippy_data.Append(std::move(data)); } return zippy_data; @@ -180,8 +178,7 @@ // Get string constants for settings ui. base::Value GetSettingsUiStrings(const assistant::SettingsUi& settings_ui, - bool activity_control_needed, - bool equal_weight_buttons) { + bool activity_control_needed) { auto consent_ui = settings_ui.consent_flow_ui().consent_ui(); auto activity_control_ui = consent_ui.activity_control_ui(); auto third_party_disclosure_ui = consent_ui.third_party_disclosure_ui(); @@ -189,7 +186,6 @@ dictionary.SetKey("activityControlNeeded", base::Value(activity_control_needed)); - dictionary.SetKey("equalWeightButtons", base::Value(equal_weight_buttons)); // Add activity control string constants. if (activity_control_needed) {
diff --git a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h index a80687b..ad7cb77 100644 --- a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h +++ b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h
@@ -59,8 +59,7 @@ using SettingZippyList = google::protobuf::RepeatedPtrField< assistant::ClassicActivityControlUiTexts::SettingZippy>; // Helper method to create zippy data. -base::Value CreateZippyData(const SettingZippyList& zippy_list, - bool is_minor_mode); +base::Value CreateZippyData(const SettingZippyList& zippy_list); // Helper method to create disclosure data. base::Value CreateDisclosureData(const SettingZippyList& disclosure_list); @@ -72,8 +71,7 @@ // Get string constants for settings ui. base::Value GetSettingsUiStrings(const assistant::SettingsUi& settings_ui, - bool activity_control_needed, - bool equal_weight_buttons); + bool activity_control_needed); void RecordActivityControlConsent(Profile* profile, std::string ui_audit_key,
diff --git a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc index cdd79561..c995db8 100644 --- a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc
@@ -22,7 +22,6 @@ #include "chromeos/services/assistant/public/cpp/assistant_prefs.h" #include "chromeos/services/assistant/public/cpp/assistant_service.h" #include "chromeos/services/assistant/public/cpp/features.h" -#include "chromeos/services/assistant/public/proto/get_settings_ui.pb.h" #include "chromeos/services/assistant/public/proto/settings_ui.pb.h" #include "components/login/localized_values_builder.h" #include "components/prefs/pref_service.h" @@ -170,6 +169,9 @@ chromeos::assistant::features::IsVoiceMatchDisabled()); dict->SetBoolean("betterAssistantEnabled", chromeos::assistant::features::IsBetterAssistantEnabled()); + // TODO(https://crbug.com/1224850): read actual minor mode signal from account + // capability or get this info from consent server. + dict->SetBoolean("isMinorMode", features::IsMinorModeRestrictionEnabled()); BaseScreenHandler::GetAdditionalParameters(dict); } @@ -348,7 +350,7 @@ } assistant::SettingsUiSelector selector = GetSettingsUiSelector(); - assistant::AssistantSettings::Get()->GetSettingsWithHeader( + assistant::AssistantSettings::Get()->GetSettings( selector.SerializeAsString(), base::BindOnce(&AssistantOptInFlowScreenHandler::OnGetSettingsResponse, weak_factory_.GetWeakPtr())); @@ -375,7 +377,7 @@ } void AssistantOptInFlowScreenHandler::OnGetSettingsResponse( - const std::string& response) { + const std::string& settings) { const base::TimeDelta time_since_request_sent = base::TimeTicks::Now() - send_request_time_; UMA_HISTOGRAM_TIMES("Assistant.OptInFlow.GetSettingsRequestTime", @@ -389,21 +391,13 @@ return; } - assistant::GetSettingsUiResponse settings_ui_response; - if (!settings_ui_response.ParseFromString(response)) { + assistant::SettingsUi settings_ui; + if (!settings_ui.ParseFromString(settings)) { LOG(ERROR) << "Failed to parse get settings response."; HandleFlowFinished(); return; } - auto settings_ui = settings_ui_response.settings(); - auto header = settings_ui_response.header(); - - bool equal_weight_buttons = - features::IsMinorModeRestrictionEnabled() && - header.footer_button_layout() == - assistant::SettingsResponseHeader_AcceptRejectLayout_EQUAL_WEIGHT; - if (settings_ui.has_gaia_user_context_ui()) { auto gaia_user_context_ui = settings_ui.gaia_user_context_ui(); if (gaia_user_context_ui.assistant_disabled_by_dasher_domain()) { @@ -433,8 +427,6 @@ base::Value zippy_data(base::Value::Type::LIST); bool skip_activity_control = true; pending_consent_data_.clear(); - // We read from `multi_consent_ui` field if it is populated and we assume user - // is a minor user; otherwise, we read from `consent_ui` field. if (features::IsMinorModeRestrictionEnabled() && settings_ui.consent_flow_ui().multi_consent_ui().size()) { auto multi_consent_ui = settings_ui.consent_flow_ui().multi_consent_ui(); @@ -446,8 +438,7 @@ data.consent_token = activity_control_ui.consent_token(); data.ui_audit_key = activity_control_ui.ui_audit_key(); pending_consent_data_.push_back(data); - zippy_data.Append(CreateZippyData(activity_control_ui.setting_zippy(), - /*is_minor_mode=*/true)); + zippy_data.Append(CreateZippyData(activity_control_ui.setting_zippy())); } } } else { @@ -458,8 +449,7 @@ data.consent_token = activity_control_ui.consent_token(); data.ui_audit_key = activity_control_ui.ui_audit_key(); pending_consent_data_.push_back(data); - zippy_data.Append(CreateZippyData(activity_control_ui.setting_zippy(), - /*is_minor_mode=*/false)); + zippy_data.Append(CreateZippyData(activity_control_ui.setting_zippy())); } } @@ -515,8 +505,7 @@ } // Pass string constants dictionary. - auto dictionary = GetSettingsUiStrings(settings_ui, activity_control_needed_, - equal_weight_buttons); + auto dictionary = GetSettingsUiStrings(settings_ui, activity_control_needed_); PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs(); dictionary.SetKey("voiceMatchEnforcedOff", base::Value(IsVoiceMatchEnforcedOff(prefs)));
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc index 42f7beb..69018a90 100644 --- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
@@ -171,6 +171,17 @@ return authpolicy::KerberosEncryptionTypes::ENC_TYPES_STRONG; } +std::string GetFlowString(EnrollmentScreenView::FlowType type) { + switch (type) { + case EnrollmentScreenView::FlowType::kEnterprise: + return "enterprise"; + case EnrollmentScreenView::FlowType::kCFM: + return "cfm"; + case EnrollmentScreenView::FlowType::kEnterpriseLicense: + return "enterpriseLicense"; + } +} + } // namespace // EnrollmentScreenHandler, public ------------------------------ @@ -204,6 +215,8 @@ &EnrollmentScreenHandler::HandleAdCompleteLogin); AddCallback("oauthEnrollAdUnlockConfiguration", &EnrollmentScreenHandler::HandleAdUnlockConfiguration); + AddCallback("enterpriseIdentifierEntered", + &EnrollmentScreenHandler::HandleIdentifierEntered); AddCallback("oauthEnrollRetry", &EnrollmentScreenHandler::HandleRetry); AddCallback("frameLoadingCompleted", &EnrollmentScreenHandler::HandleFrameLoadingCompleted); @@ -217,13 +230,15 @@ // EnrollmentScreenActor implementation ----------------------------------- void EnrollmentScreenHandler::SetEnrollmentConfig( - Controller* controller, const policy::EnrollmentConfig& config) { CHECK(config.should_enroll()); - controller_ = controller; config_ = config; } +void EnrollmentScreenHandler::SetEnrollmentController(Controller* controller) { + controller_ = controller; +} + void EnrollmentScreenHandler::Show() { if (!page_is_ready()) show_on_init_ = true; @@ -238,6 +253,29 @@ ShowStep(kEnrollmentStepSignin); } +void EnrollmentScreenHandler::ShowUserError(UserErrorType error_type, + const std::string& email) { + // Reset the state of the GAIA so after error user would retry enrollment and + // start from enter your account view. + CallJS("login.OAuthEnrollmentScreen.doReload"); + switch (error_type) { + case UserErrorType::kConsumerDomain: { + ShowError( + IDS_ENTERPRISE_ENROLLMENT_CONSUMER_ACCOUNT_WITH_PACKAGED_LICENSE, + true); + break; + } + case UserErrorType::kBusinessDomain: { + ShowErrorMessage( + l10n_util::GetStringFUTF8( + IDS_ENTERPRISE_ENROLLMENT_CONSUMER_ACCOUNT_BUSINESS_DOMAIN_WITH_PACKAGED_LICENSE, + base::ASCIIToUTF16(gaia::ExtractDomainName(email))), + true); + break; + } + } +} + void EnrollmentScreenHandler::ShowActiveDirectoryScreen( const std::string& domain_join_config, const std::string& machine_name, @@ -350,6 +388,10 @@ device_type); } +void EnrollmentScreenHandler::SetFlowType(FlowType flow_type) { + flow_type_ = flow_type; +} + void EnrollmentScreenHandler::ShowEnrollmentSuccessScreen() { ShowStep(kEnrollmentStepSuccess); } @@ -566,6 +608,8 @@ ::login::LocalizedValuesBuilder* builder) { builder->Add("oauthEnrollScreenTitle", IDS_ENTERPRISE_ENROLLMENT_SCREEN_TITLE); + builder->Add("enrollmentAccountCheckTitle", + IDS_ENTERPRISE_ACCOUNT_CHECK_TITLE); builder->Add("oauthEnrollNextBtn", IDS_OFFLINE_LOGIN_NEXT_BUTTON_TEXT); builder->Add("oauthEnrollSkip", IDS_ENTERPRISE_ENROLLMENT_SKIP); if (policy::EnrollmentRequisitionManager::IsRemoraRequisition()) { @@ -902,6 +946,12 @@ weak_ptr_factory_.GetWeakPtr())); } +void EnrollmentScreenHandler::HandleIdentifierEntered( + const std::string& email) { + DCHECK(controller_); + controller_->OnIdentifierEntered(email); +} + void EnrollmentScreenHandler::HandleRetry() { DCHECK(controller_); controller_->OnRetry(); @@ -978,14 +1028,11 @@ screen_data.SetBoolean("is_enrollment_enforced", config_.is_forced()); screen_data.SetBoolean("attestationBased", config_.is_mode_attestation()); screen_data.SetString("management_domain", config_.management_domain); - + screen_data.SetString("flow", GetFlowString(flow_type_)); const std::string app_locale = g_browser_process->GetApplicationLocale(); if (!app_locale.empty()) screen_data.SetString("hl", app_locale); - const bool cfm = policy::EnrollmentRequisitionManager::IsRemoraRequisition(); - screen_data.SetString("flow", cfm ? "cfm" : "enterprise"); - ShowScreenWithData(EnrollmentScreenView::kScreenId, &screen_data); if (first_show_) { first_show_ = false;
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h index e828a95..52c30aa1 100644 --- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
@@ -68,14 +68,17 @@ void RegisterMessages() override; // Implements EnrollmentScreenView: - void SetEnrollmentConfig(Controller* controller, - const policy::EnrollmentConfig& config) override; + void SetEnrollmentConfig(const policy::EnrollmentConfig& config) override; + void SetEnrollmentController(Controller* controller) override; void SetEnterpriseDomainInfo(const std::string& manager, const std::u16string& device_type) override; + void SetFlowType(FlowType flow_type) override; void Show() override; void Hide() override; void ShowSigninScreen() override; + void ShowUserError(UserErrorType error_type, + const std::string& email) override; void ShowActiveDirectoryScreen(const std::string& domain_join_config, const std::string& machine_name, const std::string& username, @@ -117,6 +120,7 @@ const std::string& user_name, const std::string& password); void HandleAdUnlockConfiguration(const std::string& password); + void HandleIdentifierEntered(const std::string& email); void HandleRetry(); void HandleFrameLoadingCompleted(); void HandleDeviceAttributesProvided(const std::string& asset_id, @@ -168,6 +172,9 @@ // The enrollment configuration. policy::EnrollmentConfig config_; + // GAIA flow type parameter that is set to authenticator. + FlowType flow_type_; + // Active Directory configuration in the form of encrypted binary data. std::string active_directory_domain_join_config_;
diff --git a/chrome/browser/ui/webui/signin/dice_web_signin_intercept_handler.cc b/chrome/browser/ui/webui/signin/dice_web_signin_intercept_handler.cc index b0811a5..0d7d8eb 100644 --- a/chrome/browser/ui/webui/signin/dice_web_signin_intercept_handler.cc +++ b/chrome/browser/ui/webui/signin/dice_web_signin_intercept_handler.cc
@@ -15,7 +15,6 @@ #include "chrome/browser/profiles/profile_avatar_icon_util.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/signin/identity_manager_factory.h" -#include "chrome/browser/signin/signin_features.h" #include "chrome/browser/ui/signin/profile_colors_util.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" @@ -228,33 +227,8 @@ return l10n_util::GetStringUTF8( IDS_SIGNIN_DICE_WEB_INTERCEPT_SWITCH_BUBBLE_TITLE); } - - // For profile creations, the title is controlled by an experiment. Expected - // values for the parameter are 1, 2 or 3. - // The version 3 is specific to the "consumer" bubble and is not supported by - // the enterprise bubble (which defaults to version 1 in that case). - int string_version = base::GetFieldTrialParamByFeatureAsInt( - kDiceWebSigninInterceptionFeature, "title_version", - /*default_value=*/1); - - int string_id = IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V1; - switch (string_version) { - case 2: - string_id = IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V2; - break; - case 3: - // Only use version 3 for consumer bubble. - if (bubble_parameters_.interception_type == - DiceWebSigninInterceptor::SigninInterceptionType::kMultiUser) { - string_id = IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE_V3; - } - break; - default: - // For default or invalid parameters, there is nothing to do. - break; - } - - return l10n_util::GetStringUTF8(string_id); + return l10n_util::GetStringUTF8( + IDS_SIGNIN_DICE_WEB_INTERCEPT_CREATE_BUBBLE_TITLE); } std::string DiceWebSigninInterceptHandler::GetBodyText() {
diff --git a/chrome/services/keymaster/public/mojom/cert_store.mojom b/chrome/services/keymaster/public/mojom/cert_store.mojom index 15c2f4d..6339c7b7 100644 --- a/chrome/services/keymaster/public/mojom/cert_store.mojom +++ b/chrome/services/keymaster/public/mojom/cert_store.mojom
@@ -33,25 +33,10 @@ kUnsupportedAlgorithm, }; -// The possible chaps slots relevant for arc-keymaster. Note this does NOT map -// to the PKCS#11 CK_SLOT_ID, but rather to an abstract representation of the -// value. The corresponding CK_SLOT_ID must be queried from cryptohome. -[Extensible] -enum ChapsSlot { - // The key is stored in the user slot. - [Default] kUser, - // The key is stored in the system slot. - kSystem, -}; - -// Metadata to uniquely identify a chaps key. +// Metadata to uniquely identify a Chaps key. struct ChapsKeyData { - // Maps to the CKA_LABEL of the CKO_PRIVATE_KEY in PKCS#11. string label; - // Maps to the CKA_ID of the CKO_PRIVATE_KEY in PKCS#11. string id; - // The slot where this key is stored. Does NOT map to the PKCS#11 CK_SLOT_ID. - [MinVersion=1] ChapsSlot slot; }; // Union of Chrome OS keys from different sources.
diff --git a/chrome/test/chromedriver/capabilities.cc b/chrome/test/chromedriver/capabilities.cc index be1ccfd..90bebbf 100644 --- a/chrome/test/chromedriver/capabilities.cc +++ b/chrome/test/chromedriver/capabilities.cc
@@ -159,7 +159,6 @@ int width = 0; int height = 0; - double device_scale_factor = 0; bool touch = true; bool mobile = true; @@ -169,8 +168,10 @@ if (metrics->FindKey("height") && !metrics->GetInteger("height", &height)) return Status(kInvalidArgument, "'height' must be an integer"); + absl::optional<double> maybe_device_scale_factor = + metrics->FindDoubleKey("pixelRatio"); if (metrics->FindKey("pixelRatio") && - !metrics->GetDouble("pixelRatio", &device_scale_factor)) + !maybe_device_scale_factor.has_value()) return Status(kInvalidArgument, "'pixelRatio' must be a double"); if (metrics->FindKey("touch") && !metrics->GetBoolean("touch", &touch)) @@ -179,8 +180,8 @@ if (metrics->FindKey("mobile") && !metrics->GetBoolean("mobile", &mobile)) return Status(kInvalidArgument, "'mobile' must be a boolean"); - DeviceMetrics* device_metrics = - new DeviceMetrics(width, height, device_scale_factor, touch, mobile); + DeviceMetrics* device_metrics = new DeviceMetrics( + width, height, maybe_device_scale_factor.value_or(0), touch, mobile); capabilities->device_metrics = std::unique_ptr<DeviceMetrics>(device_metrics); }
diff --git a/chrome/test/chromedriver/chrome/geolocation_override_manager_unittest.cc b/chrome/test/chromedriver/chrome/geolocation_override_manager_unittest.cc index 574d861a..aa07c3d 100644 --- a/chrome/test/chromedriver/chrome/geolocation_override_manager_unittest.cc +++ b/chrome/test/chromedriver/chrome/geolocation_override_manager_unittest.cc
@@ -14,13 +14,13 @@ void AssertGeolocationCommand(const Command& command, const Geoposition& geoposition) { ASSERT_EQ("Page.setGeolocationOverride", command.method); - double latitude, longitude, accuracy; - ASSERT_TRUE(command.params.GetDouble("latitude", &latitude)); - ASSERT_TRUE(command.params.GetDouble("longitude", &longitude)); - ASSERT_TRUE(command.params.GetDouble("accuracy", &accuracy)); - ASSERT_EQ(geoposition.latitude, latitude); - ASSERT_EQ(geoposition.longitude, longitude); - ASSERT_EQ(geoposition.accuracy, accuracy); + + ASSERT_EQ(geoposition.latitude, + command.params.FindDoubleKey("latitude").value()); + ASSERT_EQ(geoposition.longitude, + command.params.FindDoubleKey("longitude").value()); + ASSERT_EQ(geoposition.accuracy, + command.params.FindDoubleKey("accuracy").value()); } } // namespace
diff --git a/chrome/test/chromedriver/chrome/mobile_device.cc b/chrome/test/chromedriver/chrome/mobile_device.cc index 1144adf..7e014b7 100644 --- a/chrome/test/chromedriver/chrome/mobile_device.cc +++ b/chrome/test/chromedriver/chrome/mobile_device.cc
@@ -42,7 +42,6 @@ } int width = 0; int height = 0; - double device_scale_factor = 0.0; bool touch = true; bool mobile = true; if (!device->GetInteger("width", &width)) { @@ -53,7 +52,10 @@ return Status(kUnknownError, "malformed device height: should be an integer"); } - if (!device->GetDouble("deviceScaleFactor", &device_scale_factor)) { + + absl::optional<double> maybe_device_scale_factor = + device->FindDoubleKey("deviceScaleFactor"); + if (!maybe_device_scale_factor.has_value()) { return Status(kUnknownError, "malformed device scale factor: should be a double"); } @@ -66,7 +68,7 @@ "malformed mobile: should be a bool"); } tmp_mobile_device->device_metrics = std::make_unique<DeviceMetrics>( - width, height, device_scale_factor, touch, mobile); + width, height, maybe_device_scale_factor.value(), touch, mobile); *mobile_device = std::move(tmp_mobile_device); return Status(kOk);
diff --git a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc index e980205..7852bcd 100644 --- a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc +++ b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc
@@ -15,23 +15,21 @@ const DeviceMetrics& device_metrics) { ASSERT_EQ("Page.setDeviceMetricsOverride", command.method); int width, height; - double device_scale_factor, font_scale_factor; bool mobile, fit_window, text_autosizing; ASSERT_TRUE(command.params.GetInteger("width", &width)); ASSERT_TRUE(command.params.GetInteger("height", &height)); - ASSERT_TRUE(command.params.GetDouble("deviceScaleFactor", - &device_scale_factor)); ASSERT_TRUE(command.params.GetBoolean("mobile", &mobile)); ASSERT_TRUE(command.params.GetBoolean("fitWindow", &fit_window)); ASSERT_TRUE(command.params.GetBoolean("textAutosizing", &text_autosizing)); - ASSERT_TRUE(command.params.GetDouble("fontScaleFactor", &font_scale_factor)); ASSERT_EQ(device_metrics.width, width); ASSERT_EQ(device_metrics.height, height); - ASSERT_EQ(device_metrics.device_scale_factor, device_scale_factor); + ASSERT_EQ(device_metrics.device_scale_factor, + command.params.FindDoubleKey("deviceScaleFactor").value()); ASSERT_EQ(device_metrics.mobile, mobile); ASSERT_EQ(device_metrics.fit_window, fit_window); ASSERT_EQ(device_metrics.text_autosizing, text_autosizing); - ASSERT_EQ(device_metrics.font_scale_factor, font_scale_factor); + ASSERT_EQ(device_metrics.font_scale_factor, + command.params.FindDoubleKey("fontScaleFactor").value()); } } // namespace
diff --git a/chrome/test/chromedriver/chrome/network_conditions.cc b/chrome/test/chromedriver/chrome/network_conditions.cc index c1aebc8b..ca1ebc8 100644 --- a/chrome/test/chromedriver/chrome/network_conditions.cc +++ b/chrome/test/chromedriver/chrome/network_conditions.cc
@@ -52,25 +52,27 @@ if (title != network_name) continue; - if (!network->GetDouble("latency", &network_conditions->latency)) { + absl::optional<double> maybe_latency = network->FindDoubleKey("latency"); + absl::optional<double> maybe_throughput = + network->FindDoubleKey("throughput"); + + if (!maybe_latency.has_value()) { return Status(kUnknownError, "malformed network latency: should be a double"); } // Preset list maintains a single "throughput" attribute for each network, // so we use that value for both |download_throughput| and // |upload_throughput| in the NetworkConditions (as does Chrome). - if (!network->GetDouble("throughput", - &network_conditions->download_throughput) || - !network->GetDouble("throughput", - &network_conditions->upload_throughput)) { + if (!maybe_throughput.has_value()) { return Status(kUnknownError, "malformed network throughput: should be a double"); } - // The throughputs of the network presets are listed in kbps, but must be - // supplied to the OverrideNetworkConditions command as bps. - network_conditions->download_throughput *= 1024; - network_conditions->upload_throughput *= 1024; + network_conditions->latency = maybe_latency.value(); + // The throughputs of the network presets are listed in kbps, but + // must be supplied to the OverrideNetworkConditions command as bps. + network_conditions->download_throughput = maybe_throughput.value() * 1024; + network_conditions->upload_throughput = maybe_throughput.value() * 1024; // |offline| is always false for now. network_conditions->offline = false;
diff --git a/chrome/test/chromedriver/chrome/network_conditions_override_manager_unittest.cc b/chrome/test/chromedriver/chrome/network_conditions_override_manager_unittest.cc index 85171b0..5c045b7 100644 --- a/chrome/test/chromedriver/chrome/network_conditions_override_manager_unittest.cc +++ b/chrome/test/chromedriver/chrome/network_conditions_override_manager_unittest.cc
@@ -16,17 +16,15 @@ const NetworkConditions& network_conditions) { ASSERT_EQ("Network.emulateNetworkConditions", command.method); bool offline; - double latency, download_throughput, upload_throughput; ASSERT_TRUE(command.params.GetBoolean("offline", &offline)); - ASSERT_TRUE(command.params.GetDouble("latency", &latency)); - ASSERT_TRUE(command.params.GetDouble("downloadThroughput", - &download_throughput)); - ASSERT_TRUE(command.params.GetDouble("uploadThroughput", - &upload_throughput)); ASSERT_EQ(network_conditions.offline, offline); - ASSERT_EQ(network_conditions.latency, latency); - ASSERT_EQ(network_conditions.download_throughput, download_throughput); - ASSERT_EQ(network_conditions.upload_throughput, upload_throughput); + + ASSERT_EQ(network_conditions.latency, + command.params.FindDoubleKey("latency").value()); + ASSERT_EQ(network_conditions.download_throughput, + command.params.FindDoubleKey("downloadThroughput").value()); + ASSERT_EQ(network_conditions.upload_throughput, + command.params.FindDoubleKey("uploadThroughput").value()); } } // namespace
diff --git a/chrome/test/chromedriver/element_commands.cc b/chrome/test/chromedriver/element_commands.cc index 5916e40..188f274a 100644 --- a/chrome/test/chromedriver/element_commands.cc +++ b/chrome/test/chromedriver/element_commands.cc
@@ -914,24 +914,27 @@ return Status(kUnknownError, "could not convert to DictionaryValue"); // grab values - double x, y, width, height; - if (!location_dict->GetDouble("x", &x)) + absl::optional<double> maybe_x = location_dict->FindDoubleKey("x"); + if (!maybe_x.has_value()) return Status(kUnknownError, "x coordinate is missing in element location"); - if (!location_dict->GetDouble("y", &y)) + absl::optional<double> maybe_y = location_dict->FindDoubleKey("y"); + if (!maybe_y.has_value()) return Status(kUnknownError, "y coordinate is missing in element location"); - if (!size_dict->GetDouble("height", &height)) + absl::optional<double> maybe_height = size_dict->FindDoubleKey("height"); + if (!maybe_height.has_value()) return Status(kUnknownError, "height is missing in element size"); - if (!size_dict->GetDouble("width", &width)) + absl::optional<double> maybe_width = size_dict->FindDoubleKey("width"); + if (!maybe_width.has_value()) return Status(kUnknownError, "width is missing in element size"); base::DictionaryValue ret; - ret.SetDouble("x", x); - ret.SetDouble("y", y); - ret.SetDouble("width", width); - ret.SetDouble("height", height); + ret.SetDouble("x", maybe_x.value()); + ret.SetDouble("y", maybe_y.value()); + ret.SetDouble("width", maybe_width.value()); + ret.SetDouble("height", maybe_height.value()); value->reset(ret.DeepCopy()); return Status(kOk); }
diff --git a/chrome/test/chromedriver/logging_unittest.cc b/chrome/test/chromedriver/logging_unittest.cc index 8809022..4b0a4e3 100644 --- a/chrome/test/chromedriver/logging_unittest.cc +++ b/chrome/test/chromedriver/logging_unittest.cc
@@ -64,9 +64,7 @@ std::string message; ASSERT_TRUE(entry->GetString("message", &message)); EXPECT_EQ(expected_message, message); - double timestamp = 0; - EXPECT_TRUE(entry->GetDouble("timestamp", ×tamp)); - EXPECT_LT(0, timestamp); + EXPECT_LT(0, entry->FindDoubleKey("timestamp").value()); } } // namespace
diff --git a/chrome/test/chromedriver/performance_logger.cc b/chrome/test/chromedriver/performance_logger.cc index 61bf0df..c5ad104d 100644 --- a/chrome/test/chromedriver/performance_logger.cc +++ b/chrome/test/chromedriver/performance_logger.cc
@@ -228,14 +228,15 @@ } else if (method == "Tracing.bufferUsage") { // 'value' will be between 0-1 and represents how full the DevTools trace // buffer is. If the buffer is full, warn the user. - double buffer_usage = 0; - if (!params.GetDouble("percentFull", &buffer_usage)) { + absl::optional<double> maybe_buffer_usage = + params.FindDoubleKey("percentFull"); + if (!maybe_buffer_usage.has_value()) { // Tracing.bufferUsage event will occur once per second, and it really // only serves as a warning, so if we can't reliably tell whether the // buffer is full, just fail silently instead of spamming the logs. return Status(kOk); } - if (buffer_usage >= 0.99999) { + if (maybe_buffer_usage.value() >= 0.99999) { base::DictionaryValue params; std::string err("Chrome's trace buffer filled while collecting events, " "so some trace events may have been lost");
diff --git a/chrome/test/chromedriver/session_commands.cc b/chrome/test/chromedriver/session_commands.cc index effa435..92d4ea92 100644 --- a/chrome/test/chromedriver/session_commands.cc +++ b/chrome/test/chromedriver/session_commands.cc
@@ -868,15 +868,16 @@ Status ExecuteSetTimeoutLegacy(Session* session, const base::DictionaryValue& params, std::unique_ptr<base::Value>* value) { - double ms_double; - if (!params.GetDouble("ms", &ms_double)) + absl::optional<double> maybe_ms = params.FindDoubleKey("ms"); + if (!maybe_ms.has_value()) return Status(kInvalidArgument, "'ms' must be a double"); + std::string type; if (!params.GetString("type", &type)) return Status(kInvalidArgument, "'type' must be a string"); base::TimeDelta timeout = - base::TimeDelta::FromMilliseconds(static_cast<int>(ms_double)); + base::TimeDelta::FromMilliseconds(static_cast<int>(maybe_ms.value())); if (type == "implicit") { session->implicit_wait = timeout; } else if (type == "script") { @@ -955,22 +956,22 @@ Status ExecuteSetScriptTimeout(Session* session, const base::DictionaryValue& params, std::unique_ptr<base::Value>* value) { - double ms; - if (!params.GetDouble("ms", &ms) || ms < 0) + absl::optional<double> maybe_ms = params.FindDoubleKey("ms"); + if (!maybe_ms.has_value() || maybe_ms.value() < 0) return Status(kInvalidArgument, "'ms' must be a non-negative number"); session->script_timeout = - base::TimeDelta::FromMilliseconds(static_cast<int>(ms)); + base::TimeDelta::FromMilliseconds(static_cast<int>(maybe_ms.value())); return Status(kOk); } Status ExecuteImplicitlyWait(Session* session, const base::DictionaryValue& params, std::unique_ptr<base::Value>* value) { - double ms; - if (!params.GetDouble("ms", &ms) || ms < 0) + absl::optional<double> maybe_ms = params.FindDoubleKey("ms"); + if (!maybe_ms.has_value() || maybe_ms.value() < 0) return Status(kInvalidArgument, "'ms' must be a non-negative number"); session->implicit_wait = - base::TimeDelta::FromMilliseconds(static_cast<int>(ms)); + base::TimeDelta::FromMilliseconds(static_cast<int>(maybe_ms.value())); return Status(kOk); } @@ -1141,14 +1142,15 @@ Status ExecuteSetWindowPosition(Session* session, const base::DictionaryValue& params, std::unique_ptr<base::Value>* value) { - double x = 0; - double y = 0; - if (!params.GetDouble("x", &x) || !params.GetDouble("y", &y)) + absl::optional<double> maybe_x = params.FindDoubleKey("x"); + absl::optional<double> maybe_y = params.FindDoubleKey("y"); + + if (!maybe_x.has_value() || !maybe_y.has_value()) return Status(kInvalidArgument, "missing or invalid 'x' or 'y'"); base::DictionaryValue rect_params; - rect_params.SetInteger("x", static_cast<int>(x)); - rect_params.SetInteger("y", static_cast<int>(y)); + rect_params.SetInteger("x", static_cast<int>(maybe_x.value())); + rect_params.SetInteger("y", static_cast<int>(maybe_y.value())); return session->chrome->SetWindowRect(session->window, rect_params); } @@ -1171,15 +1173,15 @@ Status ExecuteSetWindowSize(Session* session, const base::DictionaryValue& params, std::unique_ptr<base::Value>* value) { - double width = 0; - double height = 0; - if (!params.GetDouble("width", &width) || - !params.GetDouble("height", &height)) + absl::optional<double> maybe_width = params.FindDoubleKey("width"); + absl::optional<double> maybe_height = params.FindDoubleKey("height"); + + if (!maybe_width.has_value() || !maybe_height.has_value()) return Status(kInvalidArgument, "missing or invalid 'width' or 'height'"); base::DictionaryValue rect_params; - rect_params.SetInteger("width", static_cast<int>(width)); - rect_params.SetInteger("height", static_cast<int>(height)); + rect_params.SetInteger("width", static_cast<int>(maybe_width.value())); + rect_params.SetInteger("height", static_cast<int>(maybe_height.value())); return session->chrome->SetWindowRect(session->window, rect_params); }
diff --git a/chrome/test/chromedriver/util.cc b/chrome/test/chromedriver/util.cc index 3151e11c..dc6d375 100644 --- a/chrome/test/chromedriver/util.cc +++ b/chrome/test/chromedriver/util.cc
@@ -509,11 +509,12 @@ return true; } // See if we have a double that contains an int value. - double d; - if (!dict->GetDouble(path, &d)) + absl::optional<double> maybe_decimal = dict->FindDoublePath(path); + if (!maybe_decimal.has_value()) return false; - int i = static_cast<int>(d); - if (i == d) { + + int i = static_cast<int>(maybe_decimal.value()); + if (i == maybe_decimal.value()) { *out_value = i; if (has_value != nullptr) *has_value = true; @@ -526,9 +527,8 @@ base::StringPiece path, double* out_value, bool* has_value) { - // base::Value::GetAsDouble already converts int to double if needed. - return GetOptionalValueDeprecated(dict, path, out_value, has_value, - &base::Value::GetAsDouble); + return GetOptionalValue(dict, path, out_value, has_value, + &base::Value::GetIfDouble); } bool GetOptionalString(const base::DictionaryValue* dict, @@ -572,13 +572,13 @@ } // Check if we have a double, which may or may not contain a safe int value. - double temp_double; - if (!dict->GetDouble(path, &temp_double)) + absl::optional<double> maybe_decimal = dict->FindDoublePath(path); + if (!maybe_decimal.has_value()) return false; // Verify that the value is an integer. - int64_t temp_int64 = static_cast<int64_t>(temp_double); - if (temp_int64 != temp_double) + int64_t temp_int64 = static_cast<int64_t>(maybe_decimal.value()); + if (temp_int64 != maybe_decimal.value()) return false; // Verify that the value is in the range for safe integer.
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc index ef53759..a6b222b7 100644 --- a/chrome/test/chromedriver/window_commands.cc +++ b/chrome/test/chromedriver/window_commands.cc
@@ -288,14 +288,11 @@ cookie_dict->GetString("path", &path); std::string samesite; GetOptionalString(cookie_dict, "sameSite", &samesite); - int64_t expiry = 0; - double temp_double; - if (cookie_dict->GetDouble("expires", &temp_double)) { - // Truncate & convert the value to an integer as required by W3C spec. - int64_t temp_int64 = static_cast<int64_t>(temp_double); - if (!(temp_int64 >= (1ll << 53) || temp_int64 <= -(1ll << 53))) - expiry = temp_int64; - } + int64_t expiry = + static_cast<int64_t>(cookie_dict->FindDoubleKey("expires").value_or(0)); + // Truncate & convert the value to an integer as required by W3C spec. + if (expiry >= (1ll << 53) || expiry <= -(1ll << 53)) + expiry = 0; bool http_only = false; cookie_dict->GetBoolean("httpOnly", &http_only); bool session = false; @@ -626,6 +623,37 @@ *pageRanges = base::JoinString(ranges, ","); return Status(kOk); } + +// Returns: +// 1. Optional with the default value, if there is no such a key in the +// dictionary. +// 2. Empty optional, if the key is in the dictionary, but value has +// unexpected type. +// 3. Optional with value from dictionary. +template <typename T> +absl::optional<T> ParseIfInDictionary( + const base::DictionaryValue* dict, + base::StringPiece key, + T default_value, + absl::optional<T> (base::Value::*getterIfType)() const) { + if (!dict->HasKey(key)) + return absl::make_optional(default_value); + return (dict->FindKey(key)->*getterIfType)(); +} + +absl::optional<double> ParseDoubleIfInDictionary( + const base::DictionaryValue* dict, + base::StringPiece key, + double default_value) { + return ParseIfInDictionary(dict, key, default_value, + &base::Value::GetIfDouble); +} + +absl::optional<int> ParseIntIfInDictionary(const base::DictionaryValue* dict, + base::StringPiece key, + int default_value) { + return ParseIfInDictionary(dict, key, default_value, &base::Value::GetIfInt); +} } // namespace Status ExecuteWindowCommand(const WindowCommand& command, @@ -1468,62 +1496,59 @@ } // Process Pointer Event's properties. - double width = 1; - if (action_item->FindKey("width") && - (!action_item->GetDouble("width", &width) || width < 0)) { + absl::optional<double> maybe_double_value; + absl::optional<int> maybe_int_value; + + maybe_double_value = ParseDoubleIfInDictionary(action_item, "width", 1); + if (!maybe_double_value.has_value() || maybe_double_value.value() < 0) return Status(kInvalidArgument, "'width' must be a non-negative number"); - } - action->SetDouble("width", width); - double height = 1; - if (action_item->FindKey("height") && - (!action_item->GetDouble("height", &height) || height < 0)) { + action->SetDouble("width", maybe_double_value.value()); + + maybe_double_value = ParseDoubleIfInDictionary(action_item, "height", 1); + if (!maybe_double_value.has_value() || maybe_double_value.value() < 0) return Status(kInvalidArgument, "'height' must be a non-negative number"); - } - action->SetDouble("height", height); - double pressure = 0.5; - if (action_item->FindKey("pressure") && - (!action_item->GetDouble("pressure", &pressure) || pressure < 0 || - pressure > 1)) { + action->SetDouble("height", maybe_double_value.value()); + + maybe_double_value = + ParseDoubleIfInDictionary(action_item, "pressure", 0.5); + if (!maybe_double_value.has_value() || maybe_double_value.value() < 0 || + maybe_double_value.value() > 1) return Status( kInvalidArgument, "'pressure' must be a non-negative number in the range of [0,1]"); - } - action->SetDouble("pressure", pressure); - double tangentialPressure = 0; - if (action_item->FindKey("tangentialPressure") && - (!action_item->GetDouble("tangentialPressure", &tangentialPressure) || - tangentialPressure < -1 || tangentialPressure > 1)) { + action->SetDouble("pressure", maybe_double_value.value()); + + maybe_double_value = + ParseDoubleIfInDictionary(action_item, "tangentialPressure", 0); + if (!maybe_double_value.has_value() || maybe_double_value.value() < -1 || + maybe_double_value.value() > 1) return Status( kInvalidArgument, "'tangentialPressure' must be a number in the range of [-1,1]"); - } - action->SetDouble("tangentialPressure", tangentialPressure); - int tiltX = 0; - if (action_item->FindKey("tiltX") && - (!action_item->GetInteger("tiltX", &tiltX) || tiltX < -90 || - tiltX > 90)) { + action->SetDouble("tangentialPressure", maybe_double_value.value()); + + maybe_int_value = ParseIntIfInDictionary(action_item, "tiltX", 0); + if (!maybe_int_value.has_value() || maybe_int_value.value() < -90 || + maybe_int_value.value() > 90) return Status(kInvalidArgument, "'tiltX' must be an integer in the range of [-90,90]"); - } - action->SetInteger("tiltX", tiltX); - int tiltY = 0; - if (action_item->FindKey("tiltY") && - (!action_item->GetInteger("tiltY", &tiltY) || tiltY < -90 || - tiltY > 90)) { + action->SetInteger("tiltX", maybe_int_value.value()); + + maybe_int_value = ParseIntIfInDictionary(action_item, "tiltY", 0); + if (!maybe_int_value.has_value() || maybe_int_value.value() < -90 || + maybe_int_value.value() > 90) return Status(kInvalidArgument, "'tiltY' must be an integer in the range of [-90,90]"); - } - action->SetInteger("tiltY", tiltY); - int twist = 0; - if (action_item->FindKey("twist") && - (!action_item->GetInteger("twist", &twist) || twist < 0 || - twist > 359)) { + action->SetInteger("tiltY", maybe_int_value.value()); + + maybe_int_value = ParseIntIfInDictionary(action_item, "twist", 0); + if (!maybe_int_value.has_value() || maybe_int_value.value() < 0 || + maybe_int_value.value() > 359) return Status(kInvalidArgument, "'twist' must be an integer in the range of [0,359]"); - } - action->SetInteger("twist", twist); + action->SetInteger("twist", maybe_int_value.value()); } action_list->push_back(std::move(action)); } @@ -1684,12 +1709,11 @@ } } } else if (type == "pointer" || type == "wheel") { - double x = 0, y = 0; OriginType origin = kViewPort; std::string element_id; if (action_type == "pointerMove" || action_type == "scroll") { - action->GetDouble("x", &x); - action->GetDouble("y", &y); + double x = action->FindDoubleKey("x").value_or(0); + double y = action->FindDoubleKey("y").value_or(0); const base::DictionaryValue* origin_dict; if (action->FindKey("origin")) { if (action->GetDictionary("origin", &origin_dict)) { @@ -1748,16 +1772,14 @@ } } - double width = 1, height = 1; - action->GetDouble("width", &width); - action->GetDouble("height", &height); - double pressure = 0.5, tangential_pressure = 0; - action->GetDouble("pressure", &pressure); - action->GetDouble("tangentialPressure", &tangential_pressure); - int tilt_x = 0, tilt_y = 0, twist = 0; - action->GetInteger("tiltX", &tilt_x); - action->GetInteger("tiltY", &tilt_y); - action->GetInteger("twist", &twist); + double width = action->FindDoubleKey("width").value_or(1); + double height = action->FindDoubleKey("height").value_or(1); + double pressure = action->FindDoubleKey("pressure").value_or(0.5); + double tangential_pressure = + action->FindDoubleKey("tangentialPressure").value_or(0); + int tilt_x = action->FindIntKey("tiltX").value_or(0); + int tilt_y = action->FindIntKey("tiltY").value_or(0); + int twist = action->FindIntKey("twist").value_or(0); std::string pointer_type; action->GetString("pointerType", &pointer_type); @@ -2456,18 +2478,26 @@ Timeout* timeout) { const base::DictionaryValue* location = NULL; Geoposition geoposition; - if (!params.GetDictionary("location", &location) || - !location->GetDouble("latitude", &geoposition.latitude) || - !location->GetDouble("longitude", &geoposition.longitude)) + if (!params.GetDictionary("location", &location)) return Status(kInvalidArgument, "missing or invalid 'location'"); - if (location->FindKey("accuracy") && - !location->GetDouble("accuracy", &geoposition.accuracy)) { + + absl::optional<double> maybe_latitude = location->FindDoubleKey("latitude"); + if (!maybe_latitude.has_value()) + return Status(kInvalidArgument, "missing or invalid 'location.latitude'"); + geoposition.latitude = maybe_latitude.value(); + + absl::optional<double> maybe_longitude = location->FindDoubleKey("longitude"); + if (!maybe_longitude.has_value()) + return Status(kInvalidArgument, "missing or invalid 'location.longitude'"); + geoposition.longitude = maybe_longitude.value(); + + // |accuracy| is not part of the WebDriver spec yet, so if it is not given + // default to 100 meters accuracy. + absl::optional<double> maybe_accuracy = + ParseDoubleIfInDictionary(location, "accuracy", 100); + if (!maybe_accuracy.has_value()) return Status(kInvalidArgument, "invalid 'accuracy'"); - } else { - // |accuracy| is not part of the WebDriver spec yet, so if it is not given - // default to 100 meters accuracy. - geoposition.accuracy = 100; - } + geoposition.accuracy = maybe_accuracy.value(); Status status = web_view->OverrideGeolocation(geoposition); if (status.IsOk()) { @@ -2493,26 +2523,35 @@ return status; } else if (params.GetDictionary("network_conditions", &conditions)) { // |latency| is required. - if (!conditions->GetDouble("latency", &network_conditions->latency)) + absl::optional<double> maybe_latency = conditions->FindDoubleKey("latency"); + if (!maybe_latency.has_value()) return Status(kInvalidArgument, "invalid 'network_conditions' is missing 'latency'"); + network_conditions->latency = maybe_latency.value(); // Either |throughput| or the pair |download_throughput| and // |upload_throughput| is required. - if (conditions->FindKey("throughput")) { - if (!conditions->GetDouble("throughput", - &network_conditions->download_throughput)) + if (conditions->HasKey("throughput")) { + absl::optional<double> maybe_throughput = + conditions->FindDoubleKey("throughput"); + if (!maybe_throughput.has_value()) return Status(kInvalidArgument, "invalid 'throughput'"); - conditions->GetDouble("throughput", - &network_conditions->upload_throughput); - } else if (conditions->FindKey("download_throughput") && - conditions->FindKey("upload_throughput")) { - if (!conditions->GetDouble("download_throughput", - &network_conditions->download_throughput) || - !conditions->GetDouble("upload_throughput", - &network_conditions->upload_throughput)) + network_conditions->upload_throughput = maybe_throughput.value(); + network_conditions->download_throughput = maybe_throughput.value(); + } else if (conditions->HasKey("download_throughput") && + conditions->HasKey("upload_throughput")) { + absl::optional<double> maybe_download_throughput = + conditions->FindDoubleKey("download_throughput"); + absl::optional<double> maybe_upload_throughput = + conditions->FindDoubleKey("upload_throughput"); + + if (!maybe_download_throughput.has_value() || + !maybe_upload_throughput.has_value()) return Status(kInvalidArgument, "invalid 'download_throughput' or 'upload_throughput'"); + network_conditions->download_throughput = + maybe_download_throughput.value(); + network_conditions->upload_throughput = maybe_upload_throughput.value(); } else { return Status(kInvalidArgument, "invalid 'network_conditions' is missing 'throughput' or "
diff --git a/chrome/test/data/extensions/context_menus/persistent/event_page.crx b/chrome/test/data/extensions/context_menus/persistent/event_page.crx deleted file mode 100644 index 10d86f7..0000000 --- a/chrome/test/data/extensions/context_menus/persistent/event_page.crx +++ /dev/null Binary files differ
diff --git a/chrome/test/data/extensions/context_menus/persistent/event_page/manifest.json b/chrome/test/data/extensions/context_menus/persistent/event_page/manifest.json deleted file mode 100644 index f04d0f4..0000000 --- a/chrome/test/data/extensions/context_menus/persistent/event_page/manifest.json +++ /dev/null
@@ -1,7 +0,0 @@ -{ - "name" : "Context Menus Test Extension", - "version" : "0.1", - "manifest_version": 2, - "permissions": [ "contextMenus", "tabs" ], - "background": { "persistent": false, "scripts": ["test.js"] } -}
diff --git a/chrome/test/data/extensions/context_menus/persistent/manifest.json b/chrome/test/data/extensions/context_menus/persistent/manifest.json new file mode 100644 index 0000000..00ea5761 --- /dev/null +++ b/chrome/test/data/extensions/context_menus/persistent/manifest.json
@@ -0,0 +1,9 @@ +{ + "name" : "Context Menus Test Extension", + // Extension ID: knldjmfmopnpolahpmmgbagdohdnhkik + "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcBHwzDvyBQ6bDppkIs9MP4ksKqCMyXQ/A52JivHZKh4YO/9vJsT3oaYhSpDCE9RPocOEQvwsHsFReW2nUEc6OLLyoCFFxIb7KkLGsmfakkut/fFdNJYh0xOTbSN8YvLWcqph09XAY2Y/f0AL7vfO1cuCqtkMt8hFrBGWxDdf9CQIDAQAB", + "version" : "0.1", + "manifest_version": 2, + "permissions": [ "contextMenus", "tabs" ], + "background": { "persistent": false, "scripts": ["test.js"] } +}
diff --git a/chrome/test/data/extensions/context_menus/persistent/persistent.pem b/chrome/test/data/extensions/context_menus/persistent/persistent.pem deleted file mode 100644 index 0abec696..0000000 --- a/chrome/test/data/extensions/context_menus/persistent/persistent.pem +++ /dev/null
@@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC8PhT/gPpbk9uL -/xUvylB0QyIlr/zU9+UtYCDsiT0KqouuusP8FtOex4pyt+be6/xljjtcw5j/WRmk -zK+UOT2HfpKTqiFnPkHAmMycEPzaYeJWskiGSY/8pHiD2x4hQBqgZTg7q+4iUNMo -psH7uKVrXJqvbzqqYM0aZPL9mj+wTrnR9jcoknaRUil/liFBPm5+lhok9LwRtyzg -Qd3zUnhegYDJ5tv4P3Wl76uSGDWXXTKjg8BMyoCCFH9/QJmFAXvsrrynwaE/PDAJ -ieGR1qcMOy3kHBGQjaEebmTNaxjBcKc8iuP/mCYANQ4ktWwdn8ikTJdrogsL2lIv -v9FUIx/7AgMBAAECggEAF1qxGo/4alMvn7ClLW7cHh3UHI6Mf37v689rgPJ35HJg -mRbVHi9WJZ1brmblhE5ihoD9GWxaTNfTktAi5RtYPblfhbrLoSD8DGEzWsDQILyY -gFQRzmNNs1+pD1wojUyENoEdrGg6HP91FdaL5jyJfVvvBF6i4yTWXXTHzDHjvpjs -rrW143b4LbcpstBatgNHefBPvJL9bBdqvBpceREWE4HIXtj1B3Ac8vhnvNcH3eZF -909/VO4Xugp+8MHm+m2onFTvRkDkl/JWSPmJHmftuwMxBP2JcarZfcaJ0V568jrZ -Op1IA/y+PasowN3zHX2lAFnkkpvtza1JGm1qWjpllQKBgQDb1rMFd3Tge4oA+/YL -UGEZMf2PfgZkSLIt1Q0PxvvRO4ybau/MTeNkEp7wig0mE+WIP7s3ebdhlY+jBoNg -qDvS3LWzKkL1jNsy1jqGqwYxuEmq1c9QO3GlfBV1+b96s2JWm8fdoiWoMTkBU7i0 -cimuYMMCOQa5aKM7sJHUcSo2/wKBgQDbNOIw0gxWowYSNoRF6Z+R/t8BRT8k7dNN -cj5SbF8+agnlKC5jvpQ/MdjsXF9werR2V6BBXGOHXcDbTHiHrMYnBic887CXAXIC -jF8GxnpE0l0d0Kkmd3SedJKILYkBX40QkUas+GynfgjIchcIyFCCeBbhOT6pOcox -cPqx7+TzBQKBgQC1sFf8qKG79d40ugi7iQ72184MDcgSkdJQ9sf4xifQ4TpwKI1P -eP/58TnS6wW69q65UJLWYo4g5I712agy9lebCjZRgRgeAPAYr91m92oDJaAcxOC2 -GqrubgL+og6Sxjb8BXvFvQEKZMQMSLlayQ+Rwv7ok2DvU3+1EVU1EuIk2QKBgBQG -cb9qAOyNOgnB5zWH0ScCNJcmH02dWFdT33OiKNVH1J2VnR9JkrtvL1TwX1ukKgZB -nQc7jHAaVXrzMnOaigOYoU8FKBWzcRngfvHcgeD1osINhNZZxVKQba55EnIIq5de -3ikBDNQERIMjQQ1xV0GD/PsYQqws9lar7osA0laNAoGANs4auFpqjoaRNypgO2G2 -GqQV/Y4GAqZRxjsceZNdJ0wa+h5fkYpCEadIDQtL76hpX84opbhTuoBGNpkMeRAH -y+zRRRUqBB/dG/95C5gboEDfDYbTYvJLHFPIJ/uYyh77QoKIZdHmCKGO2VR/xur/ -psX82yq4i8lQnwaFyiZM0Cw= ------END PRIVATE KEY-----
diff --git a/chrome/test/data/extensions/context_menus/persistent/service_worker.crx b/chrome/test/data/extensions/context_menus/persistent/service_worker.crx deleted file mode 100644 index c6ee85fe..0000000 --- a/chrome/test/data/extensions/context_menus/persistent/service_worker.crx +++ /dev/null Binary files differ
diff --git a/chrome/test/data/extensions/context_menus/persistent/service_worker/manifest.json b/chrome/test/data/extensions/context_menus/persistent/service_worker/manifest.json deleted file mode 100644 index cd5e0b4..0000000 --- a/chrome/test/data/extensions/context_menus/persistent/service_worker/manifest.json +++ /dev/null
@@ -1,7 +0,0 @@ -{ - "name" : "Context Menus Test Extension", - "version" : "0.1", - "manifest_version": 2, - "permissions": [ "contextMenus", "tabs" ], - "background": { "service_worker": "test.js" } -}
diff --git a/chrome/test/data/extensions/context_menus/persistent/service_worker/test.js b/chrome/test/data/extensions/context_menus/persistent/service_worker/test.js deleted file mode 100644 index aa9ca5c..0000000 --- a/chrome/test/data/extensions/context_menus/persistent/service_worker/test.js +++ /dev/null
@@ -1,37 +0,0 @@ -// 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. - -var menuId = 'my_id' - -chrome.runtime.onInstalled.addListener(function(details) { - if (details.reason == 'install') { - chrome.contextMenus.create( - {title: 'Extension Item', id: menuId}, - function() { - if (!chrome.runtime.lastError) { - chrome.test.notifyPass(); - } else { - chrome.test.notifyFail(chrome.runtime.lastError.message); - } - } - ); - } -}); - -chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { - // The C++ test creates a tab at chrome://version as a signal to the - // extension to update the menu item. - if (tab.url != 'chrome://version/') - return; - chrome.contextMenus.update( - menuId, {title: 'Extension Item Updated'}, - function() { - if (!chrome.runtime.lastError) { - chrome.test.notifyPass(); - } else { - chrome.test.notifyFail(chrome.runtime.lastError.message); - } - } - ); -});
diff --git a/chrome/test/data/extensions/context_menus/persistent/event_page/test.js b/chrome/test/data/extensions/context_menus/persistent/test.js similarity index 100% rename from chrome/test/data/extensions/context_menus/persistent/event_page/test.js rename to chrome/test/data/extensions/context_menus/persistent/test.js
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 4c06513..c2aa0e63 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -8753,5 +8753,8 @@ "prefs": { "https_only_mode_enabled": { "default_value": false } } } ] + }, + "RestrictedManagedGuestSessionEnabled": { + "reason_for_missing_test": "Maps into CrosSettings" } }
diff --git a/chrome/test/data/webui/settings/advanced_page_test.js b/chrome/test/data/webui/settings/advanced_page_test.js index 8c0f7758..9957507 100644 --- a/chrome/test/data/webui/settings/advanced_page_test.js +++ b/chrome/test/data/webui/settings/advanced_page_test.js
@@ -50,7 +50,10 @@ return; } - const children = pages.getContentChildren(); + const children = pages.shadowRoot.querySelector('slot') + .assignedNodes({flatten: true}) + .filter(n => n.nodeType === Node.ELEMENT_NODE); + const stampedChildren = children.filter(function(element) { return element.tagName !== 'TEMPLATE'; });
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_ui_test.js b/chrome/test/data/webui/settings/chromeos/os_settings_ui_test.js index 749a701..2c2812ae 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_ui_test.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_ui_test.js
@@ -59,7 +59,9 @@ return; } - const children = pages.getContentChildren(); + const children = pages.shadowRoot.querySelector('slot') + .assignedNodes({flatten: true}) + .filter(n => n.nodeType === Node.ELEMENT_NODE); const stampedChildren = children.filter(function(element) { return element.tagName !== 'TEMPLATE'; });
diff --git a/chrome/test/data/webui/settings/settings_page_test_util.js b/chrome/test/data/webui/settings/settings_page_test_util.js index b0dc62d..10d42e8 100644 --- a/chrome/test/data/webui/settings/settings_page_test_util.js +++ b/chrome/test/data/webui/settings/settings_page_test_util.js
@@ -16,11 +16,12 @@ export function getPage(type) { const settingsUi = document.querySelector('settings-ui'); assertTrue(!!settingsUi); - const settingsMain = settingsUi.$$('settings-main'); + const settingsMain = settingsUi.shadowRoot.querySelector('settings-main'); assertTrue(!!settingsMain); - const page = settingsMain.$$(`settings-${type}-page`); + const page = settingsMain.shadowRoot.querySelector(`settings-${type}-page`); - const idleRender = page && page.$$('settings-idle-load'); + const idleRender = + page && page.shadowRoot.querySelector('settings-idle-load'); if (!idleRender) { return Promise.resolve(page); }
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn index 316bbd5..f6034bf 100644 --- a/chromecast/BUILD.gn +++ b/chromecast/BUILD.gn
@@ -678,7 +678,7 @@ android_manifest = "$root_gen_dir/cast_shell_manifest/AndroidManifest.xml" android_manifest_dep = "//chromecast/browser/android:cast_shell_manifest" - min_sdk_version = 21 + min_sdk_version = 23 target_sdk_version = 31 shared_libraries = [ "//chromecast/android:libcast_shell_android" ]
diff --git a/chromecast/base/BUILD.gn b/chromecast/base/BUILD.gn index 5820ec3..325c6c8 100644 --- a/chromecast/base/BUILD.gn +++ b/chromecast/base/BUILD.gn
@@ -66,8 +66,6 @@ "pref_names.h", "process_utils.cc", "process_utils.h", - "serializers.cc", - "serializers.h", "statistics/weighted_mean.cc", "statistics/weighted_mean.h", "statistics/weighted_moving_average.cc", @@ -171,7 +169,6 @@ "observer_unittest.cc", "path_utils_unittest.cc", "process_utils_unittest.cc", - "serializers_unittest.cc", "statistics/weighted_moving_average_unittest.cc", "statistics/weighted_moving_linear_regression_unittest.cc", "system_time_change_notifier_unittest.cc",
diff --git a/chromecast/base/serializers.cc b/chromecast/base/serializers.cc deleted file mode 100644 index cb4fcd3..0000000 --- a/chromecast/base/serializers.cc +++ /dev/null
@@ -1,53 +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 "chromecast/base/serializers.h" - -#include "base/json/json_file_value_serializer.h" -#include "base/json/json_string_value_serializer.h" -#include "base/logging.h" - -namespace chromecast { - -std::unique_ptr<base::Value> DeserializeFromJson(const std::string& text) { - JSONStringValueDeserializer deserializer(text); - - int error_code = -1; - std::string error_msg; - std::unique_ptr<base::Value> value = - deserializer.Deserialize(&error_code, &error_msg); - DLOG_IF(ERROR, !value) << "JSON error " << error_code << ":" << error_msg; - - // Value will hold the nullptr in case of an error. - return value; -} - -absl::optional<std::string> SerializeToJson(const base::Value& value) { - std::string json_str; - JSONStringValueSerializer serializer(&json_str); - if (serializer.Serialize(value)) - return json_str; - return absl::nullopt; -} - -std::unique_ptr<base::Value> DeserializeJsonFromFile( - const base::FilePath& path) { - JSONFileValueDeserializer deserializer(path); - - int error_code = -1; - std::string error_msg; - std::unique_ptr<base::Value> value = - deserializer.Deserialize(&error_code, &error_msg); - DLOG_IF(ERROR, !value) << "JSON error " << error_code << ":" << error_msg; - - // Value will hold the nullptr in case of an error. - return value; -} - -bool SerializeJsonToFile(const base::FilePath& path, const base::Value& value) { - JSONFileValueSerializer serializer(path); - return serializer.Serialize(value); -} - -} // namespace chromecast
diff --git a/chromecast/base/serializers.h b/chromecast/base/serializers.h deleted file mode 100644 index 27ca8ae..0000000 --- a/chromecast/base/serializers.h +++ /dev/null
@@ -1,45 +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. - -#ifndef CHROMECAST_BASE_SERIALIZERS_H_ -#define CHROMECAST_BASE_SERIALIZERS_H_ - -#include <memory> -#include <string> - -#include "third_party/abseil-cpp/absl/types/optional.h" - -namespace base { -class Value; -class FilePath; -} - -namespace chromecast { - -// Deprecated: use base::JSONReader::Read instead. -// Helper function which deserializes JSON |text| into a base::Value. If |text| -// is empty, is not valid JSON, or if some other deserialization error occurs, -// the return value will hold the NULL pointer. -std::unique_ptr<base::Value> DeserializeFromJson(const std::string& text); - -// Deprecated: use base::JSONWriter::Write instead. -// Helper function which serializes |value| into a JSON string. If a -// serialization error occurs,the return value will be absl::nullopt. -// Dereferencing the result is equivalent to DCHECK()-ing that serialization -// succeeded and retrieving the serialized string. -absl::optional<std::string> SerializeToJson(const base::Value& value); - -// Helper function which deserializes JSON file at |path| into a base::Value. -// If file in |path| is empty, is not valid JSON, or if some other -// deserialization error occurs, the return value will hold the NULL pointer. -std::unique_ptr<base::Value> DeserializeJsonFromFile( - const base::FilePath& path); - -// Helper function which serializes |value| into the file at |path|. The -// function returns true on success, false otherwise. -bool SerializeJsonToFile(const base::FilePath& path, const base::Value& value); - -} // namespace chromecast - -#endif // CHROMECAST_BASE_SERIALIZERS_H_
diff --git a/chromecast/base/serializers_unittest.cc b/chromecast/base/serializers_unittest.cc deleted file mode 100644 index 7ad2e8b..0000000 --- a/chromecast/base/serializers_unittest.cc +++ /dev/null
@@ -1,151 +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 <vector> - -#include "base/files/file_util.h" -#include "base/values.h" -#include "chromecast/base/scoped_temp_file.h" -#include "chromecast/base/serializers.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace chromecast { -namespace { -const char kEmptyJsonString[] = "{}"; -const char kEmptyJsonFileString[] = "{\n\n}\n"; -const char kProperJsonString[] = - "{\n" - " \"compound\": {\n" - " \"a\": 1,\n" - " \"b\": 2\n" - " },\n" - " \"some_String\": \"1337\",\n" - " \"some_int\": 42,\n" - " \"the_list\": [ \"val1\", \"val2\" ]\n" - "}\n"; -const char kPoorlyFormedJsonString[] = "{\"key\":"; -const char kTestKey[] = "test_key"; -const char kTestValue[] = "test_value"; - -} // namespace - -TEST(DeserializeFromJson, EmptyString) { - std::string str; - std::unique_ptr<base::Value> value = DeserializeFromJson(str); - EXPECT_EQ(nullptr, value.get()); -} - -TEST(DeserializeFromJson, EmptyJsonObject) { - std::string str = kEmptyJsonString; - std::unique_ptr<base::Value> value = DeserializeFromJson(str); - EXPECT_NE(nullptr, value.get()); -} - -TEST(DeserializeFromJson, ProperJsonObject) { - std::string str = kProperJsonString; - std::unique_ptr<base::Value> value = DeserializeFromJson(str); - EXPECT_NE(nullptr, value.get()); -} - -TEST(DeserializeFromJson, PoorlyFormedJsonObject) { - std::string str = kPoorlyFormedJsonString; - std::unique_ptr<base::Value> value = DeserializeFromJson(str); - EXPECT_EQ(nullptr, value.get()); -} - -TEST(SerializeToJson, BadValue) { - base::Value value(std::vector<char>(12)); - absl::optional<std::string> str = SerializeToJson(value); - EXPECT_FALSE(str.has_value()); -} - -TEST(SerializeToJson, EmptyValue) { - base::DictionaryValue value; - absl::optional<std::string> str = SerializeToJson(value); - ASSERT_TRUE(str.has_value()); - EXPECT_EQ(kEmptyJsonString, *str); -} - -TEST(SerializeToJson, PopulatedValue) { - base::DictionaryValue orig_value; - orig_value.SetString(kTestKey, kTestValue); - absl::optional<std::string> str = SerializeToJson(orig_value); - ASSERT_TRUE(str.has_value()); - - std::unique_ptr<base::Value> new_value = DeserializeFromJson(*str); - ASSERT_NE(nullptr, new_value.get()); - EXPECT_TRUE(new_value->Equals(&orig_value)); -} - -TEST(DeserializeJsonFromFile, NoFile) { - std::unique_ptr<base::Value> value = - DeserializeJsonFromFile(base::FilePath("/file/does/not/exist.json")); - EXPECT_EQ(nullptr, value.get()); -} - -TEST(DeserializeJsonFromFile, EmptyString) { - ScopedTempFile temp; - EXPECT_EQ(static_cast<int>(strlen("")), temp.Write("")); - std::unique_ptr<base::Value> value = DeserializeJsonFromFile(temp.path()); - EXPECT_EQ(nullptr, value.get()); -} - -TEST(DeserializeJsonFromFile, EmptyJsonObject) { - ScopedTempFile temp; - EXPECT_EQ(static_cast<int>(strlen(kEmptyJsonString)), - temp.Write(kEmptyJsonString)); - std::unique_ptr<base::Value> value = DeserializeJsonFromFile(temp.path()); - EXPECT_NE(nullptr, value.get()); -} - -TEST(DeserializeJsonFromFile, ProperJsonObject) { - ScopedTempFile temp; - EXPECT_EQ(static_cast<int>(strlen(kProperJsonString)), - temp.Write(kProperJsonString)); - std::unique_ptr<base::Value> value = DeserializeJsonFromFile(temp.path()); - EXPECT_NE(nullptr, value.get()); -} - -TEST(DeserializeJsonFromFile, PoorlyFormedJsonObject) { - ScopedTempFile temp; - EXPECT_EQ(static_cast<int>(strlen(kPoorlyFormedJsonString)), - temp.Write(kPoorlyFormedJsonString)); - std::unique_ptr<base::Value> value = DeserializeJsonFromFile(temp.path()); - EXPECT_EQ(nullptr, value.get()); -} - -TEST(SerializeJsonToFile, BadValue) { - ScopedTempFile temp; - - base::Value value(std::vector<char>(12)); - ASSERT_FALSE(SerializeJsonToFile(temp.path(), value)); - std::string str(temp.Read()); - EXPECT_TRUE(str.empty()); -} - -TEST(SerializeJsonToFile, EmptyValue) { - ScopedTempFile temp; - - base::DictionaryValue value; - ASSERT_TRUE(SerializeJsonToFile(temp.path(), value)); - std::string str(temp.Read()); - ASSERT_FALSE(str.empty()); - EXPECT_EQ(kEmptyJsonFileString, str); -} - -TEST(SerializeJsonToFile, PopulatedValue) { - ScopedTempFile temp; - - base::DictionaryValue orig_value; - orig_value.SetString(kTestKey, kTestValue); - ASSERT_TRUE(SerializeJsonToFile(temp.path(), orig_value)); - std::string str(temp.Read()); - ASSERT_FALSE(str.empty()); - - std::unique_ptr<base::Value> new_value = DeserializeJsonFromFile(temp.path()); - ASSERT_NE(nullptr, new_value.get()); - EXPECT_TRUE(new_value->Equals(&orig_value)); -} - -} // namespace chromecast
diff --git a/chromecast/browser/android/apk/AndroidManifest.xml.jinja2 b/chromecast/browser/android/apk/AndroidManifest.xml.jinja2 index fb840b6..51585928 100644 --- a/chromecast/browser/android/apk/AndroidManifest.xml.jinja2 +++ b/chromecast/browser/android/apk/AndroidManifest.xml.jinja2
@@ -8,7 +8,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.chromium.chromecast.shell"> - <uses-sdk android:minSdkVersion="21"/> + <uses-sdk android:minSdkVersion="23"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.INTERNET"/>
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioFocusRequest.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioFocusRequest.java index 2e293577..b624bbd5 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioFocusRequest.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioFocusRequest.java
@@ -44,20 +44,18 @@ } private int getStreamType() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - if (mAudioAttributes != null) { - switch (mAudioAttributes.getContentType()) { - case AudioAttributes.CONTENT_TYPE_MOVIE: - case AudioAttributes.CONTENT_TYPE_MUSIC: - return AudioManager.STREAM_MUSIC; - case AudioAttributes.CONTENT_TYPE_SONIFICATION: - return AudioManager.STREAM_ALARM; - case AudioAttributes.CONTENT_TYPE_SPEECH: - return AudioManager.STREAM_VOICE_CALL; - case AudioAttributes.CONTENT_TYPE_UNKNOWN: - default: - return AudioManager.STREAM_SYSTEM; - } + if (mAudioAttributes != null) { + switch (mAudioAttributes.getContentType()) { + case AudioAttributes.CONTENT_TYPE_MOVIE: + case AudioAttributes.CONTENT_TYPE_MUSIC: + return AudioManager.STREAM_MUSIC; + case AudioAttributes.CONTENT_TYPE_SONIFICATION: + return AudioManager.STREAM_ALARM; + case AudioAttributes.CONTENT_TYPE_SPEECH: + return AudioManager.STREAM_VOICE_CALL; + case AudioAttributes.CONTENT_TYPE_UNKNOWN: + default: + return AudioManager.STREAM_SYSTEM; } } return 0;
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioManager.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioManager.java index 22b77a6..3deb001 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioManager.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioManager.java
@@ -9,7 +9,6 @@ import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.media.audiopolicy.AudioPolicy; -import android.os.Build; import android.os.Build.VERSION_CODES; import androidx.annotation.Nullable; @@ -88,35 +87,6 @@ return audioFocusLossState; } - // Only called on Lollipop and below, in an Activity's onPause() event. - // On Lollipop and below, setStreamMute() calls are cumulative and per-application, and if - // Activities don't unmute the streams that they mute, the stream remains muted to other - // applications, which are unable to unmute the stream themselves. Therefore, when an Activity - // is paused, it must unmute any streams it had muted. - // More context in b/19964892 and b/22204758. - @SuppressWarnings("deprecation") - public void releaseStreamMuteIfNecessary(int streamType) { - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) { - // On L, if we try to unmute a stream that is not muted, a warning Toast appears. - // Check the stream mute state to determine whether to unmute. - boolean isMuted = false; - try { - // isStreamMute() was only made public in M, but it can be accessed through - // reflection in L. - isMuted = (Boolean) mInternal.getClass() - .getMethod("isStreamMute", int.class) - .invoke(mInternal, streamType); - } catch (Exception e) { - Log.e(TAG, "Can not call AudioManager.isStreamMute().", e); - } - - if (isMuted) { - // Note: this is a no-op on fixed-volume devices. - mInternal.setStreamMute(streamType, false); - } - } - } - public int getStreamMaxVolume(int streamType) { return mInternal.getStreamMaxVolume(streamType); }
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java index 536a0d7..c361561 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
@@ -144,13 +144,6 @@ mAudioManagerState.set(CastAudioManager.getAudioManager(this)); })); - // Clean up stream mute state on pause events. - mAudioManagerState.andThen(Observable.not(mResumedState)) - .map(Both::getFirst) - .subscribe(Observers.onEnter((CastAudioManager audioManager) -> { - audioManager.releaseStreamMuteIfNecessary(AudioManager.STREAM_MUSIC); - })); - // Handle each new Intent. Controller<CastWebContentsSurfaceHelper.StartParams> startParamsState = new Controller<>(); mGotIntentState.and(Observable.not(mIsFinishingState))
diff --git a/chromecast/browser/android/junit/src/org/chromium/chromecast/shell/CastAudioManagerTest.java b/chromecast/browser/android/junit/src/org/chromium/chromecast/shell/CastAudioManagerTest.java index acbcd80..4497e52 100644 --- a/chromecast/browser/android/junit/src/org/chromium/chromecast/shell/CastAudioManagerTest.java +++ b/chromecast/browser/android/junit/src/org/chromium/chromecast/shell/CastAudioManagerTest.java
@@ -4,13 +4,9 @@ package org.chromium.chromecast.shell; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - import android.media.AudioAttributes; import android.media.AudioManager; import android.os.Build; -import android.util.SparseIntArray; import org.junit.Test; import org.junit.runner.RunWith; @@ -184,65 +180,4 @@ .closed(CastAudioManager.AudioFocusLoss.TRANSIENT_CAN_DUCK) .end(); } - - // Simulate the AudioManager mute behavior on Android L. The isStreamMute() method is present, - // but can only be used through reflection. Mute requests are cumulative, so a stream only - // unmutes once a equal number of setStreamMute(t, true) setStreamMute(t, false) requests have - // been received. - private static class LollipopAudioManager extends AudioManager { - // Stores the number of total standing mute requests per stream. - private final SparseIntArray mMuteState = new SparseIntArray(); - private boolean mCanCallStreamMute = true; - - public void setCanCallStreamMute(boolean able) { - mCanCallStreamMute = able; - } - - @Override - public boolean isStreamMute(int streamType) { - if (!mCanCallStreamMute) { - throw new RuntimeException("isStreamMute() disabled for testing"); - } - return mMuteState.get(streamType, 0) > 0; - } - - @Override - public void setStreamMute(int streamType, boolean muteState) { - int delta = muteState ? 1 : -1; - int currentMuteCount = mMuteState.get(streamType, 0); - int newMuteCount = currentMuteCount + delta; - assert newMuteCount >= 0; - mMuteState.put(streamType, newMuteCount); - } - } - - @Test - @Config(sdk = Build.VERSION_CODES.LOLLIPOP) - public void testReleaseStreamMuteWithNoMute() { - AudioManager fakeAudioManager = new LollipopAudioManager(); - CastAudioManager audioManager = new CastAudioManager(fakeAudioManager); - audioManager.releaseStreamMuteIfNecessary(AudioManager.STREAM_MUSIC); - assertFalse(fakeAudioManager.isStreamMute(AudioManager.STREAM_MUSIC)); - } - - @Test - @Config(sdk = Build.VERSION_CODES.LOLLIPOP) - public void testReleaseStreamMuteWithMute() { - AudioManager fakeAudioManager = new LollipopAudioManager(); - CastAudioManager audioManager = new CastAudioManager(fakeAudioManager); - fakeAudioManager.setStreamMute(AudioManager.STREAM_MUSIC, true); - assertTrue(fakeAudioManager.isStreamMute(AudioManager.STREAM_MUSIC)); - audioManager.releaseStreamMuteIfNecessary(AudioManager.STREAM_MUSIC); - assertFalse(fakeAudioManager.isStreamMute(AudioManager.STREAM_MUSIC)); - } - - @Test - @Config(sdk = Build.VERSION_CODES.LOLLIPOP) - public void testHandleExceptionFromIsStreamMute() { - LollipopAudioManager fakeAudioManager = new LollipopAudioManager(); - fakeAudioManager.setCanCallStreamMute(false); - CastAudioManager audioManager = new CastAudioManager(fakeAudioManager); - // This should not crash even if isStreamMute() throws an exception. - audioManager.releaseStreamMuteIfNecessary(AudioManager.STREAM_MUSIC); - } }
diff --git a/chromecast/browser/android/junit/src/org/chromium/chromecast/shell/CastWebContentsActivityTest.java b/chromecast/browser/android/junit/src/org/chromium/chromecast/shell/CastWebContentsActivityTest.java index 3ea5cef..f211c3a 100644 --- a/chromecast/browser/android/junit/src/org/chromium/chromecast/shell/CastWebContentsActivityTest.java +++ b/chromecast/browser/android/junit/src/org/chromium/chromecast/shell/CastWebContentsActivityTest.java
@@ -11,7 +11,6 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import android.app.Activity; import android.content.Intent; @@ -36,7 +35,6 @@ import org.robolectric.shadow.api.Shadow; import org.robolectric.shadows.ShadowActivity; -import org.chromium.chromecast.base.Observable; import org.chromium.content_public.browser.WebContents; import org.chromium.testing.local.LocalRobolectricTestRunner; @@ -48,6 +46,9 @@ @RunWith(LocalRobolectricTestRunner.class) @Config(manifest = Config.NONE) public class CastWebContentsActivityTest { + /** + * ShadowActivity that allows us to intercept calls to setTurnScreenOn. + */ @Implements(Activity.class) public static class ExtendedShadowActivity extends ShadowActivity { private boolean mTurnScreenOn; @@ -109,17 +110,6 @@ } @Test - public void testReleasesStreamMuteIfNecessaryOnPause() { - CastAudioManager mockAudioManager = mock(CastAudioManager.class); - when(mockAudioManager.requestAudioFocusWhen(anyObject())) - .thenReturn(mock(Observable.class)); - mActivity.setAudioManagerForTesting(mockAudioManager); - mActivityLifecycle.create().start().resume(); - mActivityLifecycle.pause(); - verify(mockAudioManager).releaseStreamMuteIfNecessary(AudioManager.STREAM_MUSIC); - } - - @Test public void testDropsIntentWithoutUri() { CastWebContentsSurfaceHelper surfaceHelper = mock(CastWebContentsSurfaceHelper.class); WebContents newWebContents = mock(WebContents.class);
diff --git a/chromeos/dbus/userdataauth/fake_userdataauth_client.cc b/chromeos/dbus/userdataauth/fake_userdataauth_client.cc index 24e7acf5..152ad6d 100644 --- a/chromeos/dbus/userdataauth/fake_userdataauth_client.cc +++ b/chromeos/dbus/userdataauth/fake_userdataauth_client.cc
@@ -266,6 +266,21 @@ ReturnProtobufMethodCallback(reply, std::move(callback)); } +void FakeUserDataAuthClient::AddCredentials( + const ::user_data_auth::AddCredentialsRequest& request, + AddCredentialsCallback callback) { + ::user_data_auth::AddCredentialsReply 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); + } + ReturnProtobufMethodCallback(reply, std::move(callback)); +} + void FakeUserDataAuthClient::WaitForServiceToBeAvailable( chromeos::WaitForServiceToBeAvailableCallback callback) { if (service_is_available_ || service_reported_not_available_) {
diff --git a/chromeos/dbus/userdataauth/fake_userdataauth_client.h b/chromeos/dbus/userdataauth/fake_userdataauth_client.h index 5f71225..2760138a 100644 --- a/chromeos/dbus/userdataauth/fake_userdataauth_client.h +++ b/chromeos/dbus/userdataauth/fake_userdataauth_client.h
@@ -94,6 +94,8 @@ void AuthenticateAuthSession( const ::user_data_auth::AuthenticateAuthSessionRequest& request, AuthenticateAuthSessionCallback callback) override; + void AddCredentials(const ::user_data_auth::AddCredentialsRequest& request, + AddCredentialsCallback callback) override; // Mount() related setter/getters.
diff --git a/chromeos/dbus/userdataauth/userdataauth_client.cc b/chromeos/dbus/userdataauth/userdataauth_client.cc index 4a6476c..0c73c59 100644 --- a/chromeos/dbus/userdataauth/userdataauth_client.cc +++ b/chromeos/dbus/userdataauth/userdataauth_client.cc
@@ -235,6 +235,15 @@ std::move(callback)); } + void AddCredentials(const ::user_data_auth::AddCredentialsRequest& request, + AddCredentialsCallback callback) override { + // TODO (crbug.com/1179246): add similar constant in user_data_auth + // namespace. + CallProtoMethod(::cryptohome::kCryptohomeAddCredentials, + ::user_data_auth::kUserDataAuthInterface, request, + std::move(callback)); + } + private: // Calls cryptohomed's |method_name| method in |interface_name| interface, // passing in |request| as input with |timeout_ms|. Once the (asynchronous)
diff --git a/chromeos/dbus/userdataauth/userdataauth_client.h b/chromeos/dbus/userdataauth/userdataauth_client.h index 4808f63f..5eaff14 100644 --- a/chromeos/dbus/userdataauth/userdataauth_client.h +++ b/chromeos/dbus/userdataauth/userdataauth_client.h
@@ -68,6 +68,8 @@ DBusMethodCallback<::user_data_auth::StartAuthSessionReply>; using AuthenticateAuthSessionCallback = DBusMethodCallback<::user_data_auth::AuthenticateAuthSessionReply>; + using AddCredentialsCallback = + DBusMethodCallback<::user_data_auth::AddCredentialsReply>; // Not copyable or movable. UserDataAuthClient(const UserDataAuthClient&) = delete; @@ -187,6 +189,12 @@ const ::user_data_auth::AuthenticateAuthSessionRequest& request, AuthenticateAuthSessionCallback callback) = 0; + // Attempts to add credentials to the vault identified/authorized by auth + // session. + virtual void AddCredentials( + const ::user_data_auth::AddCredentialsRequest& request, + AddCredentialsCallback callback) = 0; + protected: // Initialize/Shutdown should be used instead. UserDataAuthClient();
diff --git a/chromeos/services/assistant/assistant_settings_impl.cc b/chromeos/services/assistant/assistant_settings_impl.cc index 5d33793..249cc62 100644 --- a/chromeos/services/assistant/assistant_settings_impl.cc +++ b/chromeos/services/assistant/assistant_settings_impl.cc
@@ -35,15 +35,7 @@ void AssistantSettingsImpl::GetSettings(const std::string& selector, GetSettingsCallback callback) { - settings_controller().GetSettings(selector, /*include_header=*/false, - std::move(callback)); -} - -void AssistantSettingsImpl::GetSettingsWithHeader( - const std::string& selector, - GetSettingsCallback callback) { - settings_controller().GetSettings(selector, /*include_header=*/true, - std::move(callback)); + settings_controller().GetSettings(selector, std::move(callback)); } void AssistantSettingsImpl::UpdateSettings(const std::string& update,
diff --git a/chromeos/services/assistant/assistant_settings_impl.h b/chromeos/services/assistant/assistant_settings_impl.h index 6db5892..c01839a 100644 --- a/chromeos/services/assistant/assistant_settings_impl.h +++ b/chromeos/services/assistant/assistant_settings_impl.h
@@ -40,8 +40,6 @@ // AssistantSettings overrides: void GetSettings(const std::string& selector, GetSettingsCallback callback) override; - void GetSettingsWithHeader(const std::string& selector, - GetSettingsCallback callback) override; void UpdateSettings(const std::string& update, UpdateSettingsCallback callback) override; void StartSpeakerIdEnrollment(
diff --git a/chromeos/services/assistant/public/cpp/assistant_settings.h b/chromeos/services/assistant/public/cpp/assistant_settings.h index 382ecb72..38a7fbb0 100644 --- a/chromeos/services/assistant/public/cpp/assistant_settings.h +++ b/chromeos/services/assistant/public/cpp/assistant_settings.h
@@ -41,17 +41,12 @@ // |selector| is a serialized proto of SettingsUiSelector, indicating which // settings sub-pages should be requested to the server. - // For `GetSettings`, a serialized proto of SettingsUi containing the settings - // sub-pages requested is paased to `GetSettingsCallback`. - // For `GetSettingsWithHeader`, a serialized proto of GetSettingsUiResponse - // containing the settings and the header information is passed to - // `GetSettingsCallback`. + // Return value is a serialized proto of SettingsUi, containing the settings + // sub-pages requested. // Send a request for the settings ui sub-pages indicated by the |selector|. using GetSettingsCallback = base::OnceCallback<void(const std::string&)>; virtual void GetSettings(const std::string& selector, GetSettingsCallback callback) = 0; - virtual void GetSettingsWithHeader(const std::string& selector, - GetSettingsCallback callback) = 0; // |update| is a serialized proto of SettingsUiUpdate, indicating what kind // of updates should be applied to the settings.
diff --git a/chromeos/services/assistant/public/proto/BUILD.gn b/chromeos/services/assistant/public/proto/BUILD.gn index ca25ea7..d09e1e8 100644 --- a/chromeos/services/assistant/public/proto/BUILD.gn +++ b/chromeos/services/assistant/public/proto/BUILD.gn
@@ -14,7 +14,6 @@ "email_opt_in_ui.proto", "gaia_user_context_ui.proto", "get_settings_ui.proto", - "header.proto", "settings_ui.proto", ] }
diff --git a/chromeos/services/assistant/public/proto/get_settings_ui.proto b/chromeos/services/assistant/public/proto/get_settings_ui.proto index 156dacf..9d5890af 100644 --- a/chromeos/services/assistant/public/proto/get_settings_ui.proto +++ b/chromeos/services/assistant/public/proto/get_settings_ui.proto
@@ -8,7 +8,6 @@ package chromeos.assistant; -import "header.proto"; import "settings_ui.proto"; // GetSettingsUi. @@ -17,9 +16,3 @@ // Required. optional SettingsUiSelector selector = 4; } - -message GetSettingsUiResponse { - optional SettingsUi settings = 1; - - optional SettingsResponseHeader header = 2; -}
diff --git a/chromeos/services/assistant/public/proto/header.proto b/chromeos/services/assistant/public/proto/header.proto deleted file mode 100644 index 0996b1d..0000000 --- a/chromeos/services/assistant/public/proto/header.proto +++ /dev/null
@@ -1,21 +0,0 @@ -// 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. - -syntax = "proto2"; - -option optimize_for = LITE_RUNTIME; - -package chromeos.assistant; - -// Metadata for the response back to the user. -message SettingsResponseHeader { - enum AcceptRejectLayout { - // Unspecified layout for buttons. - UNSPECIFIED = 0; - // Accept is filled on RHS, Reject is filled on LHS. - EQUAL_WEIGHT = 1; - } - // Controls the way the accept and reject buttons are rendered. - optional AcceptRejectLayout footer_button_layout = 2; -}
diff --git a/chromeos/services/assistant/test_support/fake_assistant_settings_impl.cc b/chromeos/services/assistant/test_support/fake_assistant_settings_impl.cc index 5526984..2b15d77b 100644 --- a/chromeos/services/assistant/test_support/fake_assistant_settings_impl.cc +++ b/chromeos/services/assistant/test_support/fake_assistant_settings_impl.cc
@@ -7,7 +7,6 @@ #include <utility> #include "base/callback.h" -#include "chromeos/services/assistant/public/proto/get_settings_ui.pb.h" #include "chromeos/services/assistant/public/proto/settings_ui.pb.h" namespace chromeos { @@ -26,16 +25,6 @@ std::move(callback).Run(settings_ui.SerializeAsString()); } -void FakeAssistantSettingsImpl::GetSettingsWithHeader( - const std::string& selector, - GetSettingsCallback callback) { - // Create a fake response - assistant::GetSettingsUiResponse response; - response.mutable_settings()->mutable_consent_flow_ui()->set_consent_status( - ConsentFlowUi_ConsentStatus_ALREADY_CONSENTED); - std::move(callback).Run(response.SerializeAsString()); -} - void FakeAssistantSettingsImpl::UpdateSettings( const std::string& update, UpdateSettingsCallback callback) {
diff --git a/chromeos/services/assistant/test_support/fake_assistant_settings_impl.h b/chromeos/services/assistant/test_support/fake_assistant_settings_impl.h index d7e058a..7c1d0dc9 100644 --- a/chromeos/services/assistant/test_support/fake_assistant_settings_impl.h +++ b/chromeos/services/assistant/test_support/fake_assistant_settings_impl.h
@@ -22,8 +22,6 @@ // AssistantSettings overrides: void GetSettings(const std::string& selector, GetSettingsCallback callback) override; - void GetSettingsWithHeader(const std::string& selector, - GetSettingsCallback callback) override; void UpdateSettings(const std::string& update, UpdateSettingsCallback callback) override; void StartSpeakerIdEnrollment(
diff --git a/chromeos/services/assistant/test_support/fake_service_controller.cc b/chromeos/services/assistant/test_support/fake_service_controller.cc index 465b463..0c7991f 100644 --- a/chromeos/services/assistant/test_support/fake_service_controller.cc +++ b/chromeos/services/assistant/test_support/fake_service_controller.cc
@@ -122,7 +122,6 @@ } void FakeServiceController::GetSettings(const std::string& selector, - bool include_header, GetSettingsCallback callback) { // Callback must be called to satisfy the mojom contract. std::move(callback).Run(std::string());
diff --git a/chromeos/services/assistant/test_support/fake_service_controller.h b/chromeos/services/assistant/test_support/fake_service_controller.h index 9b42ab12f..aafa4e2c 100644 --- a/chromeos/services/assistant/test_support/fake_service_controller.h +++ b/chromeos/services/assistant/test_support/fake_service_controller.h
@@ -98,7 +98,6 @@ void UpdateSettings(const std::string& settings, UpdateSettingsCallback callback) override; void GetSettings(const std::string& selector, - bool include_header, GetSettingsCallback callback) override; void SetHotwordEnabled(bool value) override {}
diff --git a/chromeos/services/libassistant/public/mojom/settings_controller.mojom b/chromeos/services/libassistant/public/mojom/settings_controller.mojom index 9e77b7d..16e43b6 100644 --- a/chromeos/services/libassistant/public/mojom/settings_controller.mojom +++ b/chromeos/services/libassistant/public/mojom/settings_controller.mojom
@@ -31,12 +31,10 @@ // Retrieve settings. |selector| is a serialized proto of // |SettingsUiSelector|, indicating which settings sub-pages should be // requested to the server. - // On success, the return value is a serialized proto of - // |GetSettingsUiResponse| when `include_header` is true; otherwisse, the - // return value is a serialized proto of |SettingsUi|, containing the - // requested sub-pages. + // On success, the return value is a serialized proto of |SettingsUi|, + // containing the requested sub-pages. // On failure, the return value is the empty string. - GetSettings(string selector, bool include_header) => (string result); + GetSettings(string selector) => (string result); // Update settings. |update| is a serialized proto of |SettingsUiUpdate|, // indicating the newly updated values. @@ -51,3 +49,4 @@ string gaia_id; string access_token; }; +
diff --git a/chromeos/services/libassistant/service_controller_unittest.cc b/chromeos/services/libassistant/service_controller_unittest.cc index 684aa45..b5397f7 100644 --- a/chromeos/services/libassistant/service_controller_unittest.cc +++ b/chromeos/services/libassistant/service_controller_unittest.cc
@@ -112,9 +112,7 @@ MOCK_METHOD(void, SetHotwordEnabled, (bool value)); MOCK_METHOD(void, GetSettings, - (const std::string& selector, - bool include_header, - GetSettingsCallback callback)); + (const std::string& selector, GetSettingsCallback callback)); MOCK_METHOD(void, UpdateSettings, (const std::string& settings, UpdateSettingsCallback callback));
diff --git a/chromeos/services/libassistant/settings_controller.cc b/chromeos/services/libassistant/settings_controller.cc index aff4b7a..865d25f3 100644 --- a/chromeos/services/libassistant/settings_controller.cc +++ b/chromeos/services/libassistant/settings_controller.cc
@@ -117,9 +117,9 @@ // running or stopped. class GetSettingsResponseWaiter : public AbortableTask { public: - GetSettingsResponseWaiter(SettingsController::GetSettingsCallback callback, - bool include_header) - : callback_(std::move(callback)), include_header_(include_header) {} + explicit GetSettingsResponseWaiter( + SettingsController::GetSettingsCallback callback) + : callback_(std::move(callback)) {} GetSettingsResponseWaiter(const GetSettingsResponseWaiter&) = delete; GetSettingsResponseWaiter& operator=(const GetSettingsResponseWaiter&) = @@ -154,16 +154,11 @@ private: void OnResponse(const assistant_client::VoicelessResponse& response) { - std::string result = - assistant::UnwrapGetSettingsUiResponse(response, include_header_); + std::string result = assistant::UnwrapGetSettingsUiResponse(response); std::move(callback_).Run(result); } SettingsController::GetSettingsCallback callback_; - // Whether to include header in response. If this is true, a serialized proto - // of GetSettingsUiResponse is passed to the callback; otherwise, a serialized - // proto of SettingsUi is passed to the callback. - bool include_header_; base::WeakPtrFactory<GetSettingsResponseWaiter> weak_factory_{this}; }; @@ -252,11 +247,9 @@ } void SettingsController::GetSettings(const std::string& selector, - bool include_header, GetSettingsCallback callback) { - auto* waiter = - pending_response_waiters_.Add(std::make_unique<GetSettingsResponseWaiter>( - std::move(callback), include_header)); + auto* waiter = pending_response_waiters_.Add( + std::make_unique<GetSettingsResponseWaiter>(std::move(callback))); waiter->SendRequest(assistant_manager_internal_, selector); }
diff --git a/chromeos/services/libassistant/settings_controller.h b/chromeos/services/libassistant/settings_controller.h index 730b237..7fe0ec6 100644 --- a/chromeos/services/libassistant/settings_controller.h +++ b/chromeos/services/libassistant/settings_controller.h
@@ -40,7 +40,6 @@ void SetSpokenFeedbackEnabled(bool value) override; void SetHotwordEnabled(bool value) override; void GetSettings(const std::string& selector, - bool include_header, GetSettingsCallback callback) override; void UpdateSettings(const std::string& settings, UpdateSettingsCallback callback) override;
diff --git a/chromeos/settings/cros_settings_names.cc b/chromeos/settings/cros_settings_names.cc index e8e9cd0..566a89f 100644 --- a/chromeos/settings/cros_settings_names.cc +++ b/chromeos/settings/cros_settings_names.cc
@@ -512,4 +512,10 @@ // A dictionary pref specifying the recurring schedule for device reboot. const char kDeviceScheduledReboot[] = "cros.device.device_scheduled_reboot"; + +// A boolean specifying whether Chrome should operate in restricted managed +// guest session mode (block features that generate sensitive data and are not +// taken care of via clean-up mechanism in the managed guest session). +const char kRestrictedManagedGuestSessionEnabled[] = + "cros.device.restricted_managed_guest_session_enabled"; } // namespace chromeos
diff --git a/chromeos/settings/cros_settings_names.h b/chromeos/settings/cros_settings_names.h index 4b199983..425e772a 100644 --- a/chromeos/settings/cros_settings_names.h +++ b/chromeos/settings/cros_settings_names.h
@@ -296,6 +296,9 @@ COMPONENT_EXPORT(CHROMEOS_SETTINGS) extern const char kDeviceScheduledReboot[]; + +COMPONENT_EXPORT(CHROMEOS_SETTINGS) +extern const char kRestrictedManagedGuestSessionEnabled[]; } // namespace chromeos // TODO(https://crbug.com/1164001): remove when migrated to ash/components/. @@ -404,6 +407,7 @@ using ::chromeos::kReportOsUpdateStatus; using ::chromeos::kReportRunningKioskApp; using ::chromeos::kReportUploadFrequency; +using ::chromeos::kRestrictedManagedGuestSessionEnabled; using ::chromeos::kSamlLoginAuthenticationType; using ::chromeos::kServiceAccountIdentity; using ::chromeos::kSignedDataRoamingEnabled;
diff --git a/components/autofill/content/browser/content_autofill_driver_factory.cc b/components/autofill/content/browser/content_autofill_driver_factory.cc index e1d18acd..7f4d6ce3 100644 --- a/components/autofill/content/browser/content_autofill_driver_factory.cc +++ b/components/autofill/content/browser/content_autofill_driver_factory.cc
@@ -102,8 +102,7 @@ if (!factory) return; - ContentAutofillDriver* driver = - factory->GetOrCreateDriverForFrame(render_frame_host); + ContentAutofillDriver* driver = factory->DriverForFrame(render_frame_host); if (driver) driver->BindPendingReceiver(std::move(pending_receiver)); } @@ -126,15 +125,6 @@ ContentAutofillDriver* ContentAutofillDriverFactory::DriverForFrame( content::RenderFrameHost* render_frame_host) { AutofillDriver* driver = DriverForKey(render_frame_host); - // This cast is safe because AutofillDriverFactory::AddForKey is protected - // and always called with ContentAutofillDriver instances within - // ContentAutofillDriverFactory. - return static_cast<ContentAutofillDriver*>(driver); -} - -ContentAutofillDriver* ContentAutofillDriverFactory::GetOrCreateDriverForFrame( - content::RenderFrameHost* render_frame_host) { - AutofillDriver* driver = DriverForKey(render_frame_host); // ContentAutofillDriver are created on demand here. if (!driver) { @@ -152,12 +142,6 @@ return static_cast<ContentAutofillDriver*>(driver); } -void ContentAutofillDriverFactory::RenderFrameCreated( - content::RenderFrameHost* render_frame_host) { - // Create the driver at the earliest possible opportunity. - GetOrCreateDriverForFrame(render_frame_host); -} - void ContentAutofillDriverFactory::RenderFrameDeleted( content::RenderFrameHost* render_frame_host) { ContentAutofillDriver* driver = @@ -197,7 +181,7 @@ content::RenderFrameHost* render_frame_host = content::RenderFrameHost::FromID(id); if (render_frame_host) { - GetOrCreateDriverForFrame(render_frame_host)->ProbablyFormSubmitted(); + DriverForFrame(render_frame_host)->ProbablyFormSubmitted(); } } } @@ -208,7 +192,7 @@ (navigation_handle->IsInMainFrame() || navigation_handle->HasSubframeNavigationEntryCommitted())) { ContentAutofillDriver* driver = - GetOrCreateDriverForFrame(navigation_handle->GetRenderFrameHost()); + DriverForFrame(navigation_handle->GetRenderFrameHost()); if (!navigation_handle->IsSameDocument() && !navigation_handle->IsServedFromBackForwardCache()) { if (navigation_handle->IsInMainFrame()) { @@ -245,7 +229,7 @@ navigation_handle->GetPreviousRenderFrameHostId()) { return; } - AutofillDriver* driver = GetOrCreateDriverForFrame(render_frame_host); + AutofillDriver* driver = DriverForFrame(render_frame_host); if (!driver) return; static_cast<ContentAutofillDriver*>(driver)
diff --git a/components/autofill/content/browser/content_autofill_driver_factory.h b/components/autofill/content/browser/content_autofill_driver_factory.h index 374788c..e4a1303 100644 --- a/components/autofill/content/browser/content_autofill_driver_factory.h +++ b/components/autofill/content/browser/content_autofill_driver_factory.h
@@ -75,7 +75,6 @@ content::RenderFrameHost* render_frame_host); // content::WebContentsObserver: - void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override; void DidStartNavigation( content::NavigationHandle* navigation_handle) override; @@ -86,12 +85,6 @@ content::NavigationHandle* navigation_handle) override; private: - // The creation of a driver is private to ensure that we don't accidentally - // register drivers while a frame is already deleted. Such a driver would not - // be unregistered properly. - ContentAutofillDriver* GetOrCreateDriverForFrame( - content::RenderFrameHost* render_frame_host); - std::string app_locale_; BrowserAutofillManager::AutofillDownloadManagerState enable_download_manager_; AutofillManager::AutofillManagerFactoryCallback
diff --git a/components/autofill/core/browser/autofill_download_manager.cc b/components/autofill/core/browser/autofill_download_manager.cc index bc00934f..0780018 100644 --- a/components/autofill/core/browser/autofill_download_manager.cc +++ b/components/autofill/core/browser/autofill_download_manager.cc
@@ -746,10 +746,12 @@ request_data.payload = std::move(payload); DVLOG(1) << "Sending Autofill Upload Request:\n" << upload; - SafeLog(log_manager_) << LoggingScope::kAutofillServer + if (log_manager_) { + log_manager_->Log() << LoggingScope::kAutofillServer << LogMessage::kSendAutofillUpload << Br{} << "Allow upload?: " << allow_upload << Br{} << "Data: " << Br{} << upload; + } if (!allow_upload) return false;
diff --git a/components/autofill/core/browser/autofill_experiments.cc b/components/autofill/core/browser/autofill_experiments.cc index c4c7fa3..419c126 100644 --- a/components/autofill/core/browser/autofill_experiments.cc +++ b/components/autofill/core/browser/autofill_experiments.cc
@@ -38,14 +38,18 @@ namespace autofill { namespace { void LogCardUploadDisabled(LogManager* log_manager, std::string context) { - SafeLog(log_manager) << LoggingScope::kCreditCardUploadStatus + if (log_manager) { + log_manager->Log() << LoggingScope::kCreditCardUploadStatus << LogMessage::kCreditCardUploadDisabled << context << CTag{}; + } } void LogCardUploadEnabled(LogManager* log_manager) { - SafeLog(log_manager) << LoggingScope::kCreditCardUploadStatus + if (log_manager) { + log_manager->Log() << LoggingScope::kCreditCardUploadStatus << LogMessage::kCreditCardUploadEnabled << CTag{}; + } } } // namespace
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index 94888beb5..ccdc323 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -406,8 +406,10 @@ FormStructure* AutofillManager::ParseForm(const FormData& form, const FormStructure* cached_form) { if (form_structures_.size() >= kAutofillManagerMaxFormCacheSize) { - SafeLog(log_manager_) << LoggingScope::kAbortParsing + if (log_manager_) { + log_manager_->Log() << LoggingScope::kAbortParsing << LogMessage::kAbortParsingTooManyForms << form; + } return nullptr; }
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc index a5e36bb3..f224c6d 100644 --- a/components/autofill/core/browser/browser_autofill_manager.cc +++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -379,9 +379,11 @@ // Logs the reason for suppressing autofill suggestions to // chrome://autofill-internals. void LogSuppressReason(LogManager* log_manager, const std::string& reason) { - SafeLog(log_manager) << LoggingScope::kFilling - << LogMessage::kSuggestionSuppressed - << " Reason: " << reason; + if (!log_manager) + return; + log_manager->Log() << LoggingScope::kFilling + << LogMessage::kSuggestionSuppressed + << " Reason: " << reason; } } // namespace @@ -656,11 +658,13 @@ SubmissionSource source) { base::UmaHistogramEnumeration("Autofill.FormSubmission.PerProfileType", client()->GetProfileType()); - SafeLog(log_manager()) << LoggingScope::kSubmission + if (log_manager()) { + log_manager()->Log() << LoggingScope::kSubmission << LogMessage::kFormSubmissionDetected << Br{} << "known_success: " << known_success << Br{} << "source: " << SubmissionSourceToString(source) << Br{} << form; + } // Always upload page language metrics. LogLanguageMetrics(client()->GetLanguageState()); @@ -1677,7 +1681,6 @@ DCHECK(autofill_field); LogBuffer buffer; - buffer.set_active(log_manager() && log_manager()->IsLoggingActive()); buffer << "is credit card section: " << is_credit_card << Br{}; buffer << "is refill: " << is_refill << Br{}; buffer << *form_structure << Br{}; @@ -1865,9 +1868,11 @@ if (action == AutofillDriver::FORM_DATA_ACTION_FILL && !is_refill) personal_data_->RecordUseOf(profile_or_credit_card); - SafeLog(log_manager()) << LoggingScope::kFilling + if (log_manager()) { + log_manager()->Log() << LoggingScope::kFilling << LogMessage::kSendFillingData << Br{} << std::move(buffer); + } driver()->SendFormDataToRenderer(query_id, action, result, field.origin, field_type_map); }
diff --git a/components/autofill/core/browser/form_data_importer.cc b/components/autofill/core/browser/form_data_importer.cc index f14d00ff4..665d60e 100644 --- a/components/autofill/core/browser/form_data_importer.cc +++ b/components/autofill/core/browser/form_data_importer.cc
@@ -55,7 +55,7 @@ bool IsValidFieldTypeAndValue(const ServerFieldTypeSet types_seen, ServerFieldType field_type, const std::u16string& value, - LogBuffer& import_log_buffer) { + LogBuffer* import_log_buffer) { // Abandon the import if two fields of the same type are encountered. // This indicates ambiguous data or miscategorization of types. // Make an exception for: @@ -74,19 +74,23 @@ ? field_type_group != FieldTypeGroup::kPhoneBilling && field_type_group != FieldTypeGroup::kPhoneHome : field_type != PHONE_HOME_NUMBER)) { - import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Multiple fields of type " - << AutofillType::ServerFieldTypeToString(field_type) - << "." << CTag{}; + if (import_log_buffer) { + *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Multiple fields of type " + << AutofillType::ServerFieldTypeToString(field_type) + << "." << CTag{}; + } return false; } // Abandon the import if an email address value shows up in a field that is // not an email address. if (field_type != EMAIL_ADDRESS && IsValidEmailAddress(value)) { - import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Email address found in field of different type: " - << AutofillType::ServerFieldTypeToString(field_type) - << CTag{}; + if (import_log_buffer) { + *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Email address found in field of different type: " + << AutofillType::ServerFieldTypeToString(field_type) + << CTag{}; + } return false; } @@ -101,21 +105,21 @@ bool IsMinimumAddress(const AutofillProfile& profile, const std::string& variation_country_code, const std::string& app_locale, - LogBuffer& import_log_buffer) { + LogBuffer* import_log_buffer) { // Try to acquire the country code form the filled form. std::string country_code = base::UTF16ToASCII(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)); - if (!country_code.empty()) { - import_log_buffer << LogMessage::kImportAddressProfileFromFormCountrySource - << "Country entry in form." << CTag{}; + if (import_log_buffer && !country_code.empty()) { + *import_log_buffer << LogMessage::kImportAddressProfileFromFormCountrySource + << "Country entry in form." << CTag{}; } // As a fallback, use the finch state to get a country code. if (country_code.empty() && !variation_country_code.empty()) { country_code = variation_country_code; - if (!country_code.empty()) { - import_log_buffer + if (import_log_buffer && !country_code.empty()) { + *import_log_buffer << LogMessage::kImportAddressProfileFromFormCountrySource << "Variations service." << CTag{}; } @@ -124,8 +128,8 @@ // As the last resort, derive the country code from the app_locale. if (country_code.empty()) { country_code = AutofillCountry::CountryCodeForLocale(app_locale); - if (!country_code.empty()) { - import_log_buffer + if (import_log_buffer && !country_code.empty()) { + *import_log_buffer << LogMessage::kImportAddressProfileFromFormCountrySource << "App locale." << CTag{}; } @@ -134,15 +138,18 @@ AutofillCountry country(country_code, app_locale); // Include the details of the country to the log. - import_log_buffer << country; + if (import_log_buffer) + *import_log_buffer << country; // Check the |ADDRESS_HOME_LINE1| requirement. bool is_line1_missing = false; if (country.requires_line1() && profile.GetRawInfo(ADDRESS_HOME_LINE1).empty() && profile.GetRawInfo(ADDRESS_HOME_STREET_NAME).empty()) { - import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Missing required ADDRESS_HOME_LINE1." << CTag{}; + if (import_log_buffer) { + *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Missing required ADDRESS_HOME_LINE1." << CTag{}; + } is_line1_missing = true; } @@ -150,8 +157,10 @@ bool is_city_missing = false; if (country.requires_city() && profile.GetRawInfo(ADDRESS_HOME_CITY).empty()) { - import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Missing required ADDRESS_HOME_CITY." << CTag{}; + if (import_log_buffer) { + *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Missing required ADDRESS_HOME_CITY." << CTag{}; + } is_city_missing = true; } @@ -159,16 +168,20 @@ bool is_state_missing = false; if (country.requires_state() && profile.GetRawInfo(ADDRESS_HOME_STATE).empty()) { - import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Missing required ADDRESS_HOME_STATE." << CTag{}; + if (import_log_buffer) { + *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Missing required ADDRESS_HOME_STATE." << CTag{}; + } is_state_missing = true; } // Check the |ADDRESS_HOME_ZIP| requirement. bool is_zip_missing = false; if (country.requires_zip() && profile.GetRawInfo(ADDRESS_HOME_ZIP).empty()) { - import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Missing required ADDRESS_HOME_ZIP." << CTag{}; + if (import_log_buffer) { + *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Missing required ADDRESS_HOME_ZIP." << CTag{}; + } is_zip_missing = true; } @@ -176,9 +189,12 @@ if (country.requires_zip_or_state() && profile.GetRawInfo(ADDRESS_HOME_ZIP).empty() && profile.GetRawInfo(ADDRESS_HOME_STATE).empty()) { - import_log_buffer - << LogMessage::kImportAddressProfileFromFormFailed - << "Missing required ADDRESS_HOME_ZIP or ADDRESS_HOME_STATE." << CTag{}; + if (import_log_buffer) { + *import_log_buffer + << LogMessage::kImportAddressProfileFromFormFailed + << "Missing required ADDRESS_HOME_ZIP or ADDRESS_HOME_STATE." + << CTag{}; + } is_zip_or_state_requirement_violated = true; } @@ -340,7 +356,7 @@ const AutofillProfile& profile, const std::string& variation_country_code, const std::string& app_locale, - LogBuffer& import_log_buffer) { + LogBuffer* import_log_buffer) { // Check if the imported address qualifies as a minimum address. bool is_not_minimum_address = false; if (!IsMinimumAddress(profile, variation_country_code, app_locale, @@ -352,28 +368,32 @@ bool is_email_invalid = false; std::u16string email = profile.GetRawInfo(EMAIL_ADDRESS); if (!email.empty() && !IsValidEmailAddress(email)) { - import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Invalid email address." << CTag{}; + if (import_log_buffer) { + *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Invalid email address." << CTag{}; + } is_email_invalid = true; } // Reject profiles with an invalid |HOME_ADDRESS_STATE| entry. bool is_state_invalid = false; if (profile.IsPresentButInvalid(ADDRESS_HOME_STATE)) { - import_log_buffer - << LogMessage::kImportAddressProfileFromFormFailed - << "Invalid state as of AutofillProfile::IsPresentButInvalid()." - << CTag{}; + if (import_log_buffer) + *import_log_buffer + << LogMessage::kImportAddressProfileFromFormFailed + << "Invalid state as of AutofillProfile::IsPresentButInvalid()." + << CTag{}; is_state_invalid = true; } // Reject profiles with an invalid |HOME_ADDRESS_ZIP| entry. bool is_zip_invalid = false; if (profile.IsPresentButInvalid(ADDRESS_HOME_ZIP)) { - import_log_buffer - << LogMessage::kImportAddressProfileFromFormFailed - << "Invalid ZIP as of AutofillProfile::IsPresentButInvalid()." - << CTag{}; + if (import_log_buffer) + *import_log_buffer + << LogMessage::kImportAddressProfileFromFormFailed + << "Invalid ZIP as of AutofillProfile::IsPresentButInvalid()." + << CTag{}; is_zip_invalid = true; } @@ -443,8 +463,6 @@ bool FormDataImporter::ImportAddressProfiles(const FormStructure& form) { // Create a buffer to collect logging output for the autofill-internals. LogBuffer import_log_buffer; - LogManager* log_manager = client_->GetLogManager(); - import_log_buffer.set_active(log_manager && log_manager->IsLoggingActive()); import_log_buffer << LoggingScope::kAddressProfileFormImport; // Print the full form into the logging scope. import_log_buffer << LogMessage::kImportAddressProfileFromForm << form @@ -475,7 +493,7 @@ import_log_buffer << LogMessage::kImportAddressProfileFromFormSection << section << CTag{}; // Try to import an address profile from the form fields of this section. - if (ImportAddressProfileForSection(form, section, import_log_buffer)) + if (ImportAddressProfileForSection(form, section, &import_log_buffer)) num_complete_profiles++; // And close the div of the section import log. import_log_buffer << CTag{"div"}; @@ -487,7 +505,7 @@ AutofillMetrics::AddressProfileImportStatusMetric::REGULAR_IMPORT); } else if (sections.size() > 1) { // Try to import by combining all sections. - if (ImportAddressProfileForSection(form, "", import_log_buffer)) { + if (ImportAddressProfileForSection(form, "", &import_log_buffer)) { num_complete_profiles++; AutofillMetrics::LogAddressFormImportStatustMetric( AutofillMetrics::AddressProfileImportStatusMetric:: @@ -503,7 +521,9 @@ << num_complete_profiles << CTag{}; // Write log buffer to autofill-internals. - SafeLog(log_manager) << std::move(import_log_buffer); + LogManager* log_manager = client_->GetLogManager(); + if (log_manager) + log_manager->Log() << std::move(import_log_buffer); return num_complete_profiles > 0; } @@ -511,7 +531,7 @@ bool FormDataImporter::ImportAddressProfileForSection( const FormStructure& form, const std::string& section, - LogBuffer& import_log_buffer) { + LogBuffer* import_log_buffer) { // The candidate for profile import. There are many ways for the candidate to // be rejected (see everywhere this function returns false). AutofillProfile candidate_profile; @@ -590,9 +610,11 @@ if (server_field_type == EMAIL_ADDRESS && types_seen.count(server_field_type) && candidate_profile.GetRawInfo(EMAIL_ADDRESS) != value) { - import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Multiple different email addresses present." - << CTag{}; + if (import_log_buffer) { + *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Multiple different email addresses present." + << CTag{}; + } has_multiple_distinct_email_addresses = true; } @@ -652,8 +674,10 @@ } // Check if the country code was still not determined correctly. if (candidate_profile.GetRawInfo(ADDRESS_HOME_COUNTRY).empty()) { - import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Missing country." << CTag{}; + if (import_log_buffer) { + *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Missing country." << CTag{}; + } has_invalid_country = true; } } @@ -668,8 +692,10 @@ !candidate_profile.SetInfoWithVerificationStatus( AutofillType(PHONE_HOME_WHOLE_NUMBER), constructed_number, app_locale_, VerificationStatus::kObserved)) { - import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed - << "Invalid phone number." << CTag{}; + if (import_log_buffer) { + *import_log_buffer << LogMessage::kImportAddressProfileFromFormFailed + << "Invalid phone number." << CTag{}; + } has_invalid_phone_number = true; } }
diff --git a/components/autofill/core/browser/form_data_importer.h b/components/autofill/core/browser/form_data_importer.h index f1c997c..ddba86c 100644 --- a/components/autofill/core/browser/form_data_importer.h +++ b/components/autofill/core/browser/form_data_importer.h
@@ -67,7 +67,7 @@ static bool IsValidLearnableProfile(const AutofillProfile& profile, const std::string& finch_country_code, const std::string& app_locale, - LogBuffer& import_log_buffer); + LogBuffer* import_log_buffer); // Cache the last four of the fetched virtual card so we don't offer saving // them. @@ -126,7 +126,7 @@ // performed on the union of all sections. bool ImportAddressProfileForSection(const FormStructure& form, const std::string& section, - LogBuffer& import_log_buffer); + LogBuffer* import_log_buffer); // Go through the |form| fields and attempt to extract a new credit card in // |imported_credit_card|, or update an existing card.
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index b8cbcac..469e68d 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -539,17 +539,13 @@ } LogBufferSubmitter LogRationalization(LogManager* log_manager) { - LogBufferSubmitter submitter = SafeLog(log_manager); + if (!log_manager) + return LogManager::DevNull(); + LogBufferSubmitter submitter = log_manager->Log(); submitter << LoggingScope::kRationalization << LogMessage::kRationalization; return submitter; } -LogBufferSubmitter LogAbortParsing(LogManager* log_manager) { - LogBufferSubmitter submitter = SafeLog(log_manager); - submitter << LoggingScope::kAbortParsing; - return submitter; -} - } // namespace class FormStructure::SectionedFieldsIndexes { @@ -1018,8 +1014,10 @@ bool FormStructure::ShouldBeParsed(LogManager* log_manager) const { // Exclude URLs not on the web via HTTP(S). if (!HasAllowedScheme(source_url_)) { - LogAbortParsing(log_manager) - << LogMessage::kAbortParsingNotAllowedScheme << *this; + if (log_manager) { + log_manager->Log() << LoggingScope::kAbortParsing + << LogMessage::kAbortParsingNotAllowedScheme << *this; + } return false; } @@ -1030,16 +1028,22 @@ (!all_fields_are_passwords() || active_field_count() < kRequiredFieldsForFormsWithOnlyPasswordFields) && !has_author_specified_types_) { - LogAbortParsing(log_manager) << LogMessage::kAbortParsingNotEnoughFields - << active_field_count() << *this; + if (log_manager) { + log_manager->Log() << LoggingScope::kAbortParsing + << LogMessage::kAbortParsingNotEnoughFields + << active_field_count() << *this; + } return false; } // Rule out search forms. if (MatchesPattern(base::UTF8ToUTF16(target_url_.path_piece()), kUrlSearchActionRe)) { - LogAbortParsing(log_manager) - << LogMessage::kAbortParsingUrlMatchesSearchRegex << *this; + if (log_manager) { + log_manager->Log() << LoggingScope::kAbortParsing + << LogMessage::kAbortParsingUrlMatchesSearchRegex + << *this; + } return false; } @@ -1049,8 +1053,8 @@ } if (!has_text_field && log_manager) { - LogAbortParsing(log_manager) - << LogMessage::kAbortParsingFormHasNoTextfield << *this; + log_manager->Log() << LoggingScope::kAbortParsing + << LogMessage::kAbortParsingFormHasNoTextfield << *this; } return has_text_field; @@ -2614,8 +2618,6 @@ } LogBuffer& operator<<(LogBuffer& buffer, const FormStructure& form) { - if (!buffer.active()) - return buffer; buffer << Tag{"div"} << Attrib{"class", "form"}; buffer << Tag{"table"}; buffer << Tr{} << "Form signature:"
diff --git a/components/autofill/core/browser/geo/autofill_country.cc b/components/autofill/core/browser/geo/autofill_country.cc index e034ba5..2dc8e979 100644 --- a/components/autofill/core/browser/geo/autofill_country.cc +++ b/components/autofill/core/browser/geo/autofill_country.cc
@@ -82,8 +82,6 @@ // Prints a formatted log of a |AutofillCountry| to a |LogBuffer|. LogBuffer& operator<<(LogBuffer& buffer, const AutofillCountry& country) { - if (!buffer.active()) - return buffer; buffer << LogMessage::kImportAddressProfileFromFormAddressRequirements; buffer << Tag{"div"} << Attrib{"class", "country_data"}; buffer << Tag{"table"};
diff --git a/components/autofill/core/browser/logging/log_manager.cc b/components/autofill/core/browser/logging/log_manager.cc index 6664ed9..41fe08d 100644 --- a/components/autofill/core/browser/logging/log_manager.cc +++ b/components/autofill/core/browser/logging/log_manager.cc
@@ -111,8 +111,4 @@ return LogBufferSubmitter(nullptr, false); } -LogBufferSubmitter SafeLog(LogManager* log_manager) { - return log_manager ? log_manager->Log() : LogManager::DevNull(); -} - } // namespace autofill
diff --git a/components/autofill/core/browser/logging/log_manager.h b/components/autofill/core/browser/logging/log_manager.h index 7bd12bb..1794f6a 100644 --- a/components/autofill/core/browser/logging/log_manager.h +++ b/components/autofill/core/browser/logging/log_manager.h
@@ -56,30 +56,12 @@ base::RepeatingClosure notification_callback); // This is the preferred way to submitting log entries. - // - // In case you often find yourself writing the following code: - // if (log_manager) { - // log_manager->Log() << ...; - // } - // You can use - // SafeLog(log_manager) << ...; - // - // If you want to prefix all log messages, you can write the following: - // LogBufferSubmitter LogWithScope(LogManager* log_manager) { - // LogBufferSubmitter submitter = SafeLog(log_manager); - // submitter << LoggingScope::kMyLoggingScope; - // return submitter; - // } virtual LogBufferSubmitter Log() = 0; // Returns a LogBufferSubmitter that ignores all input. static LogBufferSubmitter DevNull(); }; -// Returns a LogBufferSubmitter for |log_buffer| if it is not null, otherwise -// LogManager::DevNull(); -LogBufferSubmitter SafeLog(LogManager* log_manager); - } // namespace autofill #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_LOGGING_LOG_MANAGER_H_
diff --git a/components/autofill/core/browser/metrics/form_event_logger_base.cc b/components/autofill/core/browser/metrics/form_event_logger_base.cc index a099968..e7672cc 100644 --- a/components/autofill/core/browser/metrics/form_event_logger_base.cc +++ b/components/autofill/core/browser/metrics/form_event_logger_base.cc
@@ -258,8 +258,6 @@ void FormEventLoggerBase::RecordFunnelAndKeyMetrics() { LogBuffer funnel_rows; LogBuffer key_metrics_rows; - for (LogBuffer* buffer : {&funnel_rows, &key_metrics_rows}) - buffer->set_active(log_manager_ && log_manager_->IsLoggingActive()); funnel_rows << Tr{} << "Form Type: " << form_type_name_; key_metrics_rows << Tr{} << "Form Type: " << form_type_name_; @@ -353,12 +351,14 @@ << has_logged_will_submit_; } - SafeLog(log_manager_) << LoggingScope::kMetrics << LogMessage::kFunnelMetrics + if (log_manager_) { + log_manager_->Log() << LoggingScope::kMetrics << LogMessage::kFunnelMetrics << Tag{"table"} << std::move(funnel_rows) << CTag{"table"}; - SafeLog(log_manager_) << LoggingScope::kMetrics << LogMessage::kKeyMetrics + log_manager_->Log() << LoggingScope::kMetrics << LogMessage::kKeyMetrics << Tag{"table"} << std::move(key_metrics_rows) << CTag{"table"}; + } } void FormEventLoggerBase::RecordAblationMetrics() {
diff --git a/components/autofill/core/common/form_data.cc b/components/autofill/core/common/form_data.cc index 8597717..a80491b 100644 --- a/components/autofill/core/common/form_data.cc +++ b/components/autofill/core/common/form_data.cc
@@ -268,8 +268,6 @@ } LogBuffer& operator<<(LogBuffer& buffer, const FormData& form) { - if (!buffer.active()) - return buffer; buffer << Tag{"div"} << Attrib{"class", "form"}; buffer << Tag{"table"}; buffer << Tr{} << "Form name:" << form.name;
diff --git a/components/autofill/core/common/form_field_data.cc b/components/autofill/core/common/form_field_data.cc index 38c8a75d..bdf2d18 100644 --- a/components/autofill/core/common/form_field_data.cc +++ b/components/autofill/core/common/form_field_data.cc
@@ -484,8 +484,6 @@ } LogBuffer& operator<<(LogBuffer& buffer, const FormFieldData& field) { - if (!buffer.active()) - return buffer; buffer << Tag{"table"}; buffer << Tr{} << "Name:" << field.name; buffer << Tr{} << "Unique id:" << field.global_id();
diff --git a/components/autofill/core/common/logging/log_buffer.h b/components/autofill/core/common/logging/log_buffer.h index 5be9c65..baf86250 100644 --- a/components/autofill/core/common/logging/log_buffer.h +++ b/components/autofill/core/common/logging/log_buffer.h
@@ -46,14 +46,6 @@ // LogBuffer buffer; // for (...) { buffer << something; } // LogBuffer() << std::move(buffer); -// -// You can override the streaming operator for your own class as follows: -// LogBuffer& operator<<(LogBuffer& buffer, const YourClass& obj) { -// if (!buffer.active()) -// return buf; -// buffer << obj.something; -// return buffer; -// } namespace autofill {
diff --git a/components/cast_channel/enum_table.h b/components/cast_channel/enum_table.h index cca3a665..a63ae86 100644 --- a/components/cast_channel/enum_table.h +++ b/components/cast_channel/enum_table.h
@@ -7,6 +7,7 @@ #include <cstdint> #include <cstring> +#include <ostream> #include "base/check_op.h" #include "base/macros.h"
diff --git a/components/client_hints/README.md b/components/client_hints/README.md index 02d2615e..d9266f0 100644 --- a/components/client_hints/README.md +++ b/components/client_hints/README.md
@@ -64,7 +64,7 @@ ### Client Hints Infrastructure -The client hints set is passed into the document on commit from [NavigationRequest::CommitNavigation](/content/browser/renderer_host/navigation_request.cc) to the document and is used in [FrameFetchContext::AddClientHintsIfNecessary](/third_party/blink/renderer/core/loader/frame_fetch_context.cc), where all of the relevant client hint information filled into the headers to be sent. +The client hints set is passed into the document on commit from [NavigationRequest::CommitNavigation](/content/browser/renderer_host/navigation_request.cc) to the document and is used in [FrameFetchContext::AddClientHintsIfNecessary](/third_party/blink/renderer/core/loader/frame_fetch_context.cc), where all of the relevant client hint information gets filled into the headers to be sent. ### Critical-CH response header
diff --git a/components/domain_reliability/beacon.cc b/components/domain_reliability/beacon.cc index df7581c4..a60326f 100644 --- a/components/domain_reliability/beacon.cc +++ b/components/domain_reliability/beacon.cc
@@ -14,9 +14,6 @@ namespace domain_reliability { -using base::Value; -using base::DictionaryValue; - DomainReliabilityBeacon::DomainReliabilityBeacon() = default; DomainReliabilityBeacon::DomainReliabilityBeacon( @@ -29,40 +26,41 @@ } } -std::unique_ptr<Value> DomainReliabilityBeacon::ToValue( +base::Value DomainReliabilityBeacon::ToValue( base::TimeTicks upload_time, base::TimeTicks last_network_change_time, const GURL& collector_url, const std::vector<std::unique_ptr<std::string>>& path_prefixes) const { - auto beacon_value = std::make_unique<DictionaryValue>(); + base::Value beacon_value(base::Value::Type::DICTIONARY); DCHECK(url.is_valid()); GURL sanitized_url = SanitizeURLForReport(url, collector_url, path_prefixes); - beacon_value->SetString("url", sanitized_url.spec()); - beacon_value->SetString("status", status); + beacon_value.SetStringKey("url", sanitized_url.spec()); + beacon_value.SetStringKey("status", status); if (!quic_error.empty()) - beacon_value->SetString("quic_error", quic_error); + beacon_value.SetStringKey("quic_error", quic_error); if (chrome_error != net::OK) { - DictionaryValue failure_value; - failure_value.SetString("custom_error", net::ErrorToString(chrome_error)); - beacon_value->SetKey("failure_data", std::move(failure_value)); + base::Value failure_value(base::Value::Type::DICTIONARY); + failure_value.SetStringKey("custom_error", + net::ErrorToString(chrome_error)); + beacon_value.SetKey("failure_data", std::move(failure_value)); } - beacon_value->SetString("server_ip", server_ip); - beacon_value->SetBoolean("was_proxied", was_proxied); - beacon_value->SetString("protocol", protocol); + beacon_value.SetStringKey("server_ip", server_ip); + beacon_value.SetBoolKey("was_proxied", was_proxied); + beacon_value.SetStringKey("protocol", protocol); if (details.quic_broken) - beacon_value->SetBoolean("quic_broken", details.quic_broken); + beacon_value.SetBoolKey("quic_broken", details.quic_broken); if (details.quic_port_migration_detected) - beacon_value->SetBoolean("quic_port_migration_detected", - details.quic_port_migration_detected); + beacon_value.SetBoolKey("quic_port_migration_detected", + details.quic_port_migration_detected); if (http_response_code >= 0) - beacon_value->SetInteger("http_response_code", http_response_code); - beacon_value->SetInteger("request_elapsed_ms", elapsed.InMilliseconds()); + beacon_value.SetIntKey("http_response_code", http_response_code); + beacon_value.SetIntKey("request_elapsed_ms", elapsed.InMilliseconds()); base::TimeDelta request_age = upload_time - start_time; - beacon_value->SetInteger("request_age_ms", request_age.InMilliseconds()); + beacon_value.SetIntKey("request_age_ms", request_age.InMilliseconds()); bool network_changed = last_network_change_time > start_time; - beacon_value->SetBoolean("network_changed", network_changed); - beacon_value->SetDouble("sample_rate", sample_rate); - return std::move(beacon_value); + beacon_value.SetBoolKey("network_changed", network_changed); + beacon_value.SetDoubleKey("sample_rate", sample_rate); + return beacon_value; } } // namespace domain_reliability
diff --git a/components/domain_reliability/beacon.h b/components/domain_reliability/beacon.h index 3870125..bc0c5937 100644 --- a/components/domain_reliability/beacon.h +++ b/components/domain_reliability/beacon.h
@@ -56,7 +56,7 @@ // are being uploaded to a same-origin collector. // |path_prefixes| are used to include only a known-safe (not PII) prefix of // URLs when uploading to a non-same-origin collector. - std::unique_ptr<base::Value> ToValue( + base::Value ToValue( base::TimeTicks upload_time, base::TimeTicks last_network_change_time, const GURL& collector_url,
diff --git a/components/domain_reliability/context.cc b/components/domain_reliability/context.cc index 35b9225..e6d15d61 100644 --- a/components/domain_reliability/context.cc +++ b/components/domain_reliability/context.cc
@@ -20,10 +20,6 @@ #include "components/domain_reliability/util.h" #include "net/base/net_errors.h" -using base::DictionaryValue; -using base::ListValue; -using base::Value; - namespace domain_reliability { // static @@ -89,17 +85,16 @@ uploading_beacons_size_ = 0; } -std::unique_ptr<Value> DomainReliabilityContext::GetWebUIData() const { - DictionaryValue* context_value = new DictionaryValue(); +base::Value DomainReliabilityContext::GetWebUIData() const { + base::Value context_value(base::Value::Type::DICTIONARY); - context_value->SetString("origin", config().origin.spec()); - context_value->SetInteger("beacon_count", static_cast<int>(beacons_.size())); - context_value->SetInteger("uploading_beacon_count", - static_cast<int>(uploading_beacons_size_)); - context_value->SetKey( - "scheduler", base::Value::FromUniquePtrValue(scheduler_.GetWebUIData())); + context_value.SetStringKey("origin", config().origin.spec()); + context_value.SetIntKey("beacon_count", static_cast<int>(beacons_.size())); + context_value.SetIntKey("uploading_beacon_count", + static_cast<int>(uploading_beacons_size_)); + context_value.SetKey("scheduler", scheduler_.GetWebUIData()); - return std::unique_ptr<Value>(context_value); + return context_value; } void DomainReliabilityContext::GetQueuedBeaconsForTesting( @@ -162,10 +157,8 @@ std::string report_json = "{}"; int max_upload_depth = -1; bool wrote = base::JSONWriter::Write( - *CreateReport(upload_time_, - collector_url, - &max_upload_depth), - &report_json); + CreateReport(upload_time_, collector_url, &max_upload_depth), + &report_json); DCHECK(wrote); DCHECK_NE(-1, max_upload_depth); @@ -194,16 +187,15 @@ scheduler_.OnBeaconAdded(); } -std::unique_ptr<const Value> DomainReliabilityContext::CreateReport( - base::TimeTicks upload_time, - const GURL& collector_url, - int* max_upload_depth_out) { +base::Value DomainReliabilityContext::CreateReport(base::TimeTicks upload_time, + const GURL& collector_url, + int* max_upload_depth_out) { DCHECK_GT(beacons_.size(), 0u); DCHECK_EQ(0u, uploading_beacons_size_); int max_upload_depth = 0; - ListValue beacons_value; + base::Value beacons_value(base::Value::Type::LIST); for (const auto& beacon : beacons_) { // Only include beacons with a matching NetworkIsolationKey in the report. if (beacon->network_isolation_key != @@ -221,12 +213,12 @@ DCHECK_GT(uploading_beacons_size_, 0u); - std::unique_ptr<DictionaryValue> report_value(new DictionaryValue()); - report_value->SetString("reporter", upload_reporter_string_); - report_value->SetKey("entries", std::move(beacons_value)); + base::Value report_value(base::Value::Type::DICTIONARY); + report_value.SetStringKey("reporter", upload_reporter_string_); + report_value.SetKey("entries", std::move(beacons_value)); *max_upload_depth_out = max_upload_depth; - return std::move(report_value); + return report_value; } void DomainReliabilityContext::CommitUpload() {
diff --git a/components/domain_reliability/context.h b/components/domain_reliability/context.h index 5f10fbf..fc14143 100644 --- a/components/domain_reliability/context.h +++ b/components/domain_reliability/context.h
@@ -67,7 +67,7 @@ // Gets a Value containing data that can be formatted into a web page for // debugging purposes. - std::unique_ptr<base::Value> GetWebUIData() const; + base::Value GetWebUIData() const; // Gets the beacons queued for upload in this context. `*beacons_out` will be // cleared and filled with pointers to the beacons; the pointers remain valid @@ -91,9 +91,9 @@ // Creates a report from all beacons associated with // `uploading_beacons_network_isolation_key_`. Updates // `uploading_beacons_size_`. - std::unique_ptr<const base::Value> CreateReport(base::TimeTicks upload_time, - const GURL& collector_url, - int* max_beacon_depth_out); + base::Value CreateReport(base::TimeTicks upload_time, + const GURL& collector_url, + int* max_beacon_depth_out); // Uses the state remembered by `MarkUpload` to remove successfully uploaded // data but keep beacons and request counts added after the upload started.
diff --git a/components/domain_reliability/context_manager.cc b/components/domain_reliability/context_manager.cc index 4dd1b50..ee608e5 100644 --- a/components/domain_reliability/context_manager.cc +++ b/components/domain_reliability/context_manager.cc
@@ -100,12 +100,11 @@ } } -std::unique_ptr<base::Value> DomainReliabilityContextManager::GetWebUIData() - const { - std::unique_ptr<base::ListValue> contexts_value(new base::ListValue()); +base::Value DomainReliabilityContextManager::GetWebUIData() const { + base::Value contexts_value(base::Value::Type::LIST); for (const auto& context_entry : contexts_) - contexts_value->Append(context_entry.second->GetWebUIData()); - return std::move(contexts_value); + contexts_value.Append(context_entry.second->GetWebUIData()); + return contexts_value; } DomainReliabilityContext* DomainReliabilityContextManager::GetContext(
diff --git a/components/domain_reliability/context_manager.h b/components/domain_reliability/context_manager.h index e320414..c4675c3f 100644 --- a/components/domain_reliability/context_manager.h +++ b/components/domain_reliability/context_manager.h
@@ -75,7 +75,7 @@ // |uploader_| needs to be set before any contexts are created. void SetUploader(DomainReliabilityUploader* uploader); - std::unique_ptr<base::Value> GetWebUIData() const; + base::Value GetWebUIData() const; size_t contexts_size_for_testing() const { return contexts_.size(); }
diff --git a/components/domain_reliability/context_unittest.cc b/components/domain_reliability/context_unittest.cc index 185ad89..8333b1d6 100644 --- a/components/domain_reliability/context_unittest.cc +++ b/components/domain_reliability/context_unittest.cc
@@ -28,8 +28,6 @@ namespace domain_reliability { namespace { -using base::DictionaryValue; -using base::ListValue; using base::Value; typedef std::vector<const DomainReliabilityBeacon*> BeaconVector; @@ -85,36 +83,39 @@ return base::StringPrintf("status%i.test", i); } -template <typename ValueType, - bool (DictionaryValue::*GetValueType)(base::StringPiece, ValueType*) - const> +template <typename ValueTypeFindResult, + typename ValueType, + ValueTypeFindResult (Value::*FindValueType)(base::StringPiece) const> struct HasValue { - bool operator()(const DictionaryValue& dict, + bool operator()(const Value& dict, const std::string& key, ValueType expected_value) { - ValueType actual_value; - bool got_value = (dict.*GetValueType)(key, &actual_value); - if (got_value) - EXPECT_EQ(expected_value, actual_value); - return got_value && (expected_value == actual_value); + ValueTypeFindResult actual_value = (dict.*FindValueType)(key); + if (actual_value) + EXPECT_EQ(expected_value, *actual_value); + return actual_value && (expected_value == *actual_value); } }; -HasValue<bool, &DictionaryValue::GetBoolean> HasBooleanValue; -HasValue<double, &DictionaryValue::GetDouble> HasDoubleValue; -HasValue<int, &DictionaryValue::GetInteger> HasIntegerValue; -HasValue<std::string, &DictionaryValue::GetString> HasStringValue; +HasValue<absl::optional<bool>, bool, &Value::FindBoolPath> HasBooleanValue; +HasValue<absl::optional<double>, double, &Value::FindDoublePath> HasDoubleValue; +HasValue<absl::optional<int>, int, &Value::FindIntPath> HasIntegerValue; +HasValue<const std::string*, std::string, &Value::FindStringPath> + HasStringValue; bool GetEntryFromReport(const Value* report, size_t index, - const DictionaryValue** entry_out) { - const DictionaryValue* report_dict; - const ListValue* entries; - - return report && - report->GetAsDictionary(&report_dict) && - report_dict->GetList("entries", &entries) && - entries->GetDictionary(index, entry_out); + const Value** entry_out) { + if (!report || !report->is_dict()) + return false; + const Value* entries = report->FindListKey("entries"); + if (!entries) + return false; + const Value& entry = entries->GetList()[index]; + if (!entry.is_dict()) + return false; + *entry_out = &entry; + return true; } class DomainReliabilityContextTest : public testing::Test { @@ -363,7 +364,7 @@ std::unique_ptr<Value> value = base::JSONReader::ReadDeprecated(upload_report()); - const DictionaryValue* entry; + const Value* entry; ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry)); EXPECT_TRUE(HasStringValue(*entry, "failure_data.custom_error", "net::ERR_CONNECTION_RESET")); @@ -688,7 +689,7 @@ std::unique_ptr<Value> value = base::JSONReader::ReadDeprecated(upload_report()); - const DictionaryValue* entry; + const Value* entry; ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry)); EXPECT_TRUE(HasBooleanValue(*entry, "network_changed", true)); @@ -719,7 +720,7 @@ std::unique_ptr<Value> value = base::JSONReader::ReadDeprecated(upload_report()); - const DictionaryValue* entry; + const Value* entry; ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry)); EXPECT_TRUE(HasBooleanValue(*entry, "quic_broken", true)); @@ -753,7 +754,7 @@ std::unique_ptr<Value> value = base::JSONReader::ReadDeprecated(upload_report()); - const DictionaryValue* entry; + const Value* entry; ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry)); EXPECT_TRUE(HasStringValue(*entry, "status", "tcp.connection_reset")); @@ -788,7 +789,7 @@ std::unique_ptr<Value> value = base::JSONReader::ReadDeprecated(upload_report()); - const DictionaryValue* entry; + const Value* entry; ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry)); EXPECT_TRUE(HasBooleanValue(*entry, "quic_broken", true)); EXPECT_TRUE(HasStringValue(*entry, "status", "tcp.connection_reset")); @@ -834,7 +835,7 @@ std::unique_ptr<Value> value = base::JSONReader::ReadDeprecated(upload_report()); - const DictionaryValue* entry; + const Value* entry; ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry)); EXPECT_TRUE(HasDoubleValue(*entry, "sample_rate", 0.5));
diff --git a/components/domain_reliability/monitor.cc b/components/domain_reliability/monitor.cc index b903dc8..38e1c12 100644 --- a/components/domain_reliability/monitor.cc +++ b/components/domain_reliability/monitor.cc
@@ -156,12 +156,10 @@ } } -std::unique_ptr<base::Value> DomainReliabilityMonitor::GetWebUIData() const { - std::unique_ptr<base::DictionaryValue> data_value( - new base::DictionaryValue()); - data_value->SetKey("contexts", base::Value::FromUniquePtrValue( - context_manager_.GetWebUIData())); - return std::move(data_value); +base::Value DomainReliabilityMonitor::GetWebUIData() const { + base::Value data_value(base::Value::Type::DICTIONARY); + data_value.SetKey("contexts", context_manager_.GetWebUIData()); + return data_value; } const DomainReliabilityContext* DomainReliabilityMonitor::AddContextForTesting(
diff --git a/components/domain_reliability/monitor.h b/components/domain_reliability/monitor.h index 972274c..5a96a529 100644 --- a/components/domain_reliability/monitor.h +++ b/components/domain_reliability/monitor.h
@@ -125,7 +125,7 @@ // Gets a Value containing data that can be formatted into a web page for // debugging purposes. - std::unique_ptr<base::Value> GetWebUIData() const; + base::Value GetWebUIData() const; // Returns pointer to the added context. const DomainReliabilityContext* AddContextForTesting(
diff --git a/components/domain_reliability/scheduler.cc b/components/domain_reliability/scheduler.cc index 710497e6..919cc4e7 100644 --- a/components/domain_reliability/scheduler.cc +++ b/components/domain_reliability/scheduler.cc
@@ -159,41 +159,41 @@ MaybeScheduleUpload(); } -std::unique_ptr<base::Value> DomainReliabilityScheduler::GetWebUIData() const { +base::Value DomainReliabilityScheduler::GetWebUIData() const { base::TimeTicks now = time_->NowTicks(); - std::unique_ptr<base::DictionaryValue> data(new base::DictionaryValue()); + base::Value data(base::Value::Type::DICTIONARY); - data->SetBoolean("upload_pending", upload_pending_); - data->SetBoolean("upload_scheduled", upload_scheduled_); - data->SetBoolean("upload_running", upload_running_); + data.SetBoolKey("upload_pending", upload_pending_); + data.SetBoolKey("upload_scheduled", upload_scheduled_); + data.SetBoolKey("upload_running", upload_running_); - data->SetInteger("scheduled_min", (scheduled_min_time_ - now).InSeconds()); - data->SetInteger("scheduled_max", (scheduled_max_time_ - now).InSeconds()); + data.SetIntKey("scheduled_min", (scheduled_min_time_ - now).InSeconds()); + data.SetIntKey("scheduled_max", (scheduled_max_time_ - now).InSeconds()); - data->SetInteger("collector_index", static_cast<int>(collector_index_)); + data.SetIntKey("collector_index", static_cast<int>(collector_index_)); if (last_upload_finished_) { - base::DictionaryValue last; - last.SetInteger("start_time", (now - last_upload_start_time_).InSeconds()); - last.SetInteger("end_time", (now - last_upload_end_time_).InSeconds()); - last.SetInteger("collector_index", - static_cast<int>(last_upload_collector_index_)); - last.SetBoolean("success", last_upload_success_); - data->SetKey("last_upload", std::move(last)); + base::Value last(base::Value::Type::DICTIONARY); + last.SetIntKey("start_time", (now - last_upload_start_time_).InSeconds()); + last.SetIntKey("end_time", (now - last_upload_end_time_).InSeconds()); + last.SetIntKey("collector_index", + static_cast<int>(last_upload_collector_index_)); + last.SetBoolKey("success", last_upload_success_); + data.SetKey("last_upload", std::move(last)); } - base::ListValue collectors_value; + base::Value collectors_value(base::Value::Type::LIST); for (const auto& collector : collectors_) { - std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue()); - value->SetInteger("failures", collector->failure_count()); - value->SetInteger("next_upload", - (collector->GetReleaseTime() - now).InSeconds()); + base::Value value(base::Value::Type::DICTIONARY); + value.SetIntKey("failures", collector->failure_count()); + value.SetIntKey("next_upload", + (collector->GetReleaseTime() - now).InSeconds()); collectors_value.Append(std::move(value)); } - data->SetKey("collectors", std::move(collectors_value)); + data.SetKey("collectors", std::move(collectors_value)); - return std::move(data); + return data; } void DomainReliabilityScheduler::MakeDeterministicForTesting() {
diff --git a/components/domain_reliability/scheduler.h b/components/domain_reliability/scheduler.h index 6470741..41d198e9 100644 --- a/components/domain_reliability/scheduler.h +++ b/components/domain_reliability/scheduler.h
@@ -73,7 +73,7 @@ // passed to the upload callback by the Uploader. void OnUploadComplete(const DomainReliabilityUploader::UploadResult& result); - std::unique_ptr<base::Value> GetWebUIData() const; + base::Value GetWebUIData() const; // Disables jitter in BackoffEntries to make scheduling deterministic for // unit tests.
diff --git a/components/media_router/common/media_route_provider_helper.cc b/components/media_router/common/media_route_provider_helper.cc index 6e17493..fb86dce 100644 --- a/components/media_router/common/media_route_provider_helper.cc +++ b/components/media_router/common/media_route_provider_helper.cc
@@ -4,6 +4,8 @@ #include "components/media_router/common/media_route_provider_helper.h" +#include <ostream> + #include "base/notreached.h" #include "base/strings/string_piece.h"
diff --git a/components/omnibox/browser/shortcuts_backend.cc b/components/omnibox/browser/shortcuts_backend.cc index 099f5b09..4196f26 100644 --- a/components/omnibox/browser/shortcuts_backend.cc +++ b/components/omnibox/browser/shortcuts_backend.cc
@@ -14,7 +14,7 @@ #include <vector> #include "base/bind.h" -#include "base/callback_helpers.h" +#include "base/feature_list.h" #include "base/guid.h" #include "base/i18n/case_conversion.h" #include "base/metrics/histogram_macros.h" @@ -27,8 +27,8 @@ #include "components/omnibox/browser/autocomplete_match_type.h" #include "components/omnibox/browser/autocomplete_result.h" #include "components/omnibox/browser/base_search_provider.h" -#include "components/omnibox/browser/omnibox_log.h" #include "components/omnibox/browser/shortcuts_database.h" +#include "components/omnibox/common/omnibox_features.h" namespace { @@ -36,9 +36,9 @@ // compacting repetitions if necessary. std::string StripMatchMarkers(const ACMatchClassifications& matches) { ACMatchClassifications unmatched; - for (auto i(matches.begin()); i != matches.end(); ++i) { + for (const auto& match : matches) { AutocompleteMatch::AddLastClassificationIfNecessary( - &unmatched, i->offset, i->style & ~ACMatchClassification::MATCH); + &unmatched, match.offset, match.style & ~ACMatchClassification::MATCH); } return AutocompleteMatch::ClassificationsToString(unmatched); } @@ -125,20 +125,43 @@ #endif // DCHECK_IS_ON() const std::u16string text_lowercase(base::i18n::ToLower(text)); const base::Time now(base::Time::Now()); + + // Look for an existing shortcut to `match` prefixed by `text`. If there is + // one, it'll be updated. This avoids creating duplicating equivalent + // shortcuts (e.g. 'g', 'go', & 'goo') with distributed `number_of_hits`s and + // outdated `last_access_time`s. There could be multiple relevant shortcuts; + // e.g., the `text` 'wi' could match both shortcuts 'wiki' and 'wild' to + // 'wiki.org/wild_west'. We only update the 1st shortcut; this is slightly + // arbitrary but seems to be fine. Deduping these shortcuts would stop the + // input 'wil' from finding the 2nd shortcut. for (ShortcutMap::const_iterator it( shortcuts_map_.lower_bound(text_lowercase)); it != shortcuts_map_.end() && - base::StartsWith(it->first, text_lowercase, - base::CompareCase::SENSITIVE); + base::StartsWith(it->first, text_lowercase, + base::CompareCase::SENSITIVE); ++it) { if (match.destination_url == it->second.match_core.destination_url) { + // By default, when a user navigates to a shortcut after typing a prefix + // of the shortcut, the shortcut text is replaced with the shorter user + // input. If `kPreserveLongerShortcutsText` is enabled, the + // shortcut keeps 3 additional chars to avoid unstable shortcuts. E.g. if + // the user creates a shortcut with text 'google.com', then navigates + // typing 'go', the shortcut should be suggested even if they type 'goo' + // next time. + auto long_text = + base::FeatureList::IsEnabled(omnibox::kPreserveLongerShortcutsText) + ? it->second.text.substr(0, text.length() + 3) + : text; UpdateShortcut(ShortcutsDatabase::Shortcut( - it->second.id, text, MatchToMatchCore(match, template_url_service_, - search_terms_data_.get()), + it->second.id, long_text, + MatchToMatchCore(match, template_url_service_, + search_terms_data_.get()), now, it->second.number_of_hits + 1)); return; } } + + // If no shortcuts to `match` prefixed by `text` were found, create one. AddShortcut(ShortcutsDatabase::Shortcut( base::GenerateGUID(), text, MatchToMatchCore(match, template_url_service_, search_terms_data_.get()), @@ -284,8 +307,8 @@ const ShortcutsDatabase::ShortcutIDs& shortcut_ids) { if (!initialized()) return false; - for (size_t i = 0; i < shortcut_ids.size(); ++i) { - auto it(guid_map_.find(shortcut_ids[i])); + for (const auto& shortcut_id : shortcut_ids) { + auto it(guid_map_.find(shortcut_id)); if (it != guid_map_.end()) { shortcuts_map_.erase(it->second); guid_map_.erase(it);
diff --git a/components/omnibox/browser/shortcuts_backend_unittest.cc b/components/omnibox/browser/shortcuts_backend_unittest.cc index ef50131f..f4c08f8 100644 --- a/components/omnibox/browser/shortcuts_backend_unittest.cc +++ b/components/omnibox/browser/shortcuts_backend_unittest.cc
@@ -12,11 +12,13 @@ #include "base/files/scoped_temp_dir.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "components/history/core/browser/history_service.h" #include "components/history/core/test/history_service_test_util.h" #include "components/omnibox/browser/shortcuts_constants.h" #include "components/omnibox/browser/shortcuts_database.h" +#include "components/omnibox/common/omnibox_features.h" #include "components/search_engines/search_terms_data.h" #include "components/search_engines/template_url_service.h" #include "testing/gtest/include/gtest/gtest.h" @@ -57,9 +59,12 @@ bool DeleteShortcutsWithURL(const GURL& url); bool DeleteShortcutsWithIDs( const ShortcutsDatabase::ShortcutIDs& deleted_ids); + bool ShortcutExists(const std::u16string& terms); TemplateURLService* GetTemplateURLService(); + ShortcutsBackend* backend() { return backend_.get(); } + private: base::ScopedTempDir profile_dir_; base::test::TaskEnvironment task_environment_; @@ -174,6 +179,10 @@ return backend_->DeleteShortcutsWithIDs(deleted_ids); } +bool ShortcutsBackendTest::ShortcutExists(const std::u16string& terms) { + return shortcuts_map().find(terms) != shortcuts_map().end(); +} + TemplateURLService* ShortcutsBackendTest::GetTemplateURLService() { return template_url_service_.get(); } @@ -367,3 +376,91 @@ ASSERT_EQ(0U, shortcuts_map().size()); } + +TEST_F(ShortcutsBackendTest, AddOrUpdateShortcut) { + InitBackend(); + + AutocompleteMatch match; + match.destination_url = GURL("https://www.google.com"); + + // Should not have a shortcut initially. + EXPECT_EQ(shortcuts_map().size(), 0u); + EXPECT_FALSE(ShortcutExists(u"google")); + + // Should have shortcut after shortcut is added to a match. + backend()->AddOrUpdateShortcut(u"google", match); + EXPECT_EQ(shortcuts_map().size(), 1u); + EXPECT_TRUE(ShortcutExists(u"google")); + + // Should shorten shortcut when a shorter input is used for the match. + backend()->AddOrUpdateShortcut(u"goo", match); + EXPECT_EQ(shortcuts_map().size(), 1u); + EXPECT_TRUE(ShortcutExists(u"goo")); + EXPECT_FALSE(ShortcutExists(u"google")); + + // Should add new shortcut when a longer input is used for the match. + backend()->AddOrUpdateShortcut(u"google", match); + EXPECT_EQ(shortcuts_map().size(), 2u); + EXPECT_TRUE(ShortcutExists(u"goo")); + EXPECT_TRUE(ShortcutExists(u"google")); + + // Should shorten shortcut when a shorter input is used for the match. The + // shorter shortcut to the same match should remain. + backend()->AddOrUpdateShortcut(u"goog", match); + EXPECT_EQ(shortcuts_map().size(), 2u); + EXPECT_TRUE(ShortcutExists(u"goo")); + EXPECT_TRUE(ShortcutExists(u"goog")); + EXPECT_FALSE(ShortcutExists(u"google")); + + // Should only touch the shortest shortcut. The longer shortcut to the same + // match should remain. + backend()->AddOrUpdateShortcut(u"goo", match); + EXPECT_EQ(shortcuts_map().size(), 2u); + EXPECT_TRUE(ShortcutExists(u"goo")); + EXPECT_TRUE(ShortcutExists(u"goog")); + EXPECT_FALSE(ShortcutExists(u"google")); + + // Like above, should only touch the shortest shortcut. The longer shortcut + // to the same match should remain. + backend()->AddOrUpdateShortcut(u"go", match); + EXPECT_EQ(shortcuts_map().size(), 2u); + EXPECT_TRUE(ShortcutExists(u"go")); + EXPECT_FALSE(ShortcutExists(u"goo")); + EXPECT_TRUE(ShortcutExists(u"goog")); + EXPECT_FALSE(ShortcutExists(u"google")); +} + +TEST_F(ShortcutsBackendTest, AddOrUpdateShortcut_LongTextFeature) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + omnibox::kPreserveLongerShortcutsText); + + InitBackend(); + + AutocompleteMatch match; + match.destination_url = GURL("https://www.google.com"); + + // Should not have a shortcut initially. + EXPECT_EQ(shortcuts_map().size(), 0u); + EXPECT_FALSE(ShortcutExists(u"google")); + + // Should have shortcut after shortcut is added to a match. + backend()->AddOrUpdateShortcut(u"google", match); + EXPECT_EQ(shortcuts_map().size(), 1u); + EXPECT_TRUE(ShortcutExists(u"google")); + + // Should not shorten shortcut when a shorter input is used shorter than the + // previous shortcut by no more than 3 chars. + backend()->AddOrUpdateShortcut(u"goo", match); + EXPECT_EQ(shortcuts_map().size(), 1u); + EXPECT_FALSE(ShortcutExists(u"goo")); + EXPECT_TRUE(ShortcutExists(u"google")); + + // Should shorten shortcut when a shorter input is used shorter than the + // previous shortcut by more than 3 chars. + backend()->AddOrUpdateShortcut(u"go", match); + EXPECT_EQ(shortcuts_map().size(), 1u); + EXPECT_FALSE(ShortcutExists(u"go")); + EXPECT_TRUE(ShortcutExists(u"googl")); + EXPECT_FALSE(ShortcutExists(u"google")); +}
diff --git a/components/omnibox/browser/shortcuts_provider.cc b/components/omnibox/browser/shortcuts_provider.cc index 18cc574..55cf703f 100644 --- a/components/omnibox/browser/shortcuts_provider.cc +++ b/components/omnibox/browser/shortcuts_provider.cc
@@ -14,11 +14,11 @@ #include "base/check_op.h" #include "base/containers/cxx20_erase.h" +#include "base/feature_list.h" #include "base/i18n/case_conversion.h" #include "base/metrics/histogram.h" #include "base/numerics/safe_conversions.h" #include "base/strings/strcat.h" -#include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" @@ -28,17 +28,15 @@ #include "components/omnibox/browser/autocomplete_input.h" #include "components/omnibox/browser/autocomplete_match.h" #include "components/omnibox/browser/autocomplete_provider_client.h" -#include "components/omnibox/browser/autocomplete_result.h" -#include "components/omnibox/browser/history_provider.h" #include "components/omnibox/browser/match_compare.h" #include "components/omnibox/browser/omnibox_field_trial.h" #include "components/omnibox/browser/url_prefix.h" +#include "components/omnibox/common/omnibox_features.h" #include "components/prefs/pref_service.h" #include "components/search_engines/omnibox_focus_type.h" #include "components/search_engines/template_url_service.h" #include "components/url_formatter/url_fixer.h" #include "third_party/metrics_proto/omnibox_input_type.pb.h" -#include "url/third_party/mozilla/url_parse.h" namespace { @@ -363,13 +361,22 @@ DCHECK_LE(terms.length(), shortcut.text.length()); // The initial score is based on how much of the shortcut the user has typed. + // If `kPreserveLongerShortcutsText` is enabled, `shortcut.text` may be up to + // 3 chars longer than previous inputs navigating to the shortcut. + size_t adjusted_text_length = shortcut.text.length(); + if (base::FeatureList::IsEnabled(omnibox::kPreserveLongerShortcutsText)) { + adjusted_text_length = + std::max(adjusted_text_length, terms.length() + 3) - 3; + } + double typed_fraction = + static_cast<double>(terms.length()) / adjusted_text_length; + // Using the square root of the typed fraction boosts the base score rapidly // as characters are typed, compared with simply using the typed fraction // directly. This makes sense since the first characters typed are much more // important for determining how likely it is a user wants a particular // shortcut than are the remaining continued characters. - double base_score = max_relevance * sqrt(static_cast<double>(terms.length()) / - shortcut.text.length()); + double base_score = max_relevance * sqrt(typed_fraction); // Then we decay this by half each week. const double kLn2 = 0.6931471805599453;
diff --git a/components/omnibox/browser/shortcuts_provider.h b/components/omnibox/browser/shortcuts_provider.h index 64ba9567..75745eaab 100644 --- a/components/omnibox/browser/shortcuts_provider.h +++ b/components/omnibox/browser/shortcuts_provider.h
@@ -34,7 +34,6 @@ friend class ClassifyTest; friend class ShortcutsProviderExtensionTest; friend class ShortcutsProviderTest; - FRIEND_TEST_ALL_PREFIXES(ShortcutsProviderTest, CalculateScore); ~ShortcutsProvider() override;
diff --git a/components/omnibox/browser/shortcuts_provider_unittest.cc b/components/omnibox/browser/shortcuts_provider_unittest.cc index 1235ac8..54c311d40 100644 --- a/components/omnibox/browser/shortcuts_provider_unittest.cc +++ b/components/omnibox/browser/shortcuts_provider_unittest.cc
@@ -19,6 +19,7 @@ #include "base/memory/ref_counted.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "components/history/core/browser/url_database.h" #include "components/omnibox/browser/autocomplete_input.h" @@ -29,6 +30,7 @@ #include "components/omnibox/browser/in_memory_url_index.h" #include "components/omnibox/browser/shortcuts_backend.h" #include "components/omnibox/browser/shortcuts_provider_test_util.h" +#include "components/omnibox/common/omnibox_features.h" #include "components/search_engines/omnibox_focus_type.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/metrics_proto/omnibox_event.pb.h" @@ -183,6 +185,16 @@ AutocompleteMatchType::HISTORY_URL, "", 1, 100}, }; +ShortcutsDatabase::Shortcut MakeShortcutWithText(std::u16string text) { + return {std::string(), text, + ShortcutsDatabase::Shortcut::MatchCore( + u"www.test.com", GURL("http://www.test.com"), + AutocompleteMatch::DocumentType::NONE, u"www.test.com", + "0,1,4,3,8,1", u"A test", "0,0,2,2", ui::PAGE_TRANSITION_TYPED, + AutocompleteMatchType::HISTORY_URL, std::u16string()), + base::Time::Now(), 1}; +} + } // namespace // ShortcutsProviderTest ------------------------------------------------------ @@ -197,8 +209,7 @@ // Passthrough to the private function in provider_. int CalculateScore(const std::string& terms, - const ShortcutsDatabase::Shortcut& shortcut, - int max_relevance); + const ShortcutsDatabase::Shortcut& shortcut); base::test::TaskEnvironment task_environment_; std::unique_ptr<FakeAutocompleteProviderClient> client_; @@ -225,8 +236,9 @@ int ShortcutsProviderTest::CalculateScore( const std::string& terms, - const ShortcutsDatabase::Shortcut& shortcut, - int max_relevance) { + const ShortcutsDatabase::Shortcut& shortcut) { + const int max_relevance = + ShortcutsProvider::kShortcutsProviderDefaultMaxRelevance; return provider_->CalculateScore(ASCIIToUTF16(terms), shortcut, max_relevance); } @@ -455,43 +467,33 @@ } TEST_F(ShortcutsProviderTest, CalculateScore) { - ShortcutsDatabase::Shortcut shortcut( - std::string(), u"test", - ShortcutsDatabase::Shortcut::MatchCore( - u"www.test.com", GURL("http://www.test.com"), - AutocompleteMatch::DocumentType::NONE, u"www.test.com", "0,1,4,3,8,1", - u"A test", "0,0,2,2", ui::PAGE_TRANSITION_TYPED, - AutocompleteMatchType::HISTORY_URL, std::u16string()), - base::Time::Now(), 1); + auto shortcut = MakeShortcutWithText(u"test"); // Maximal score. - const int max_relevance = - ShortcutsProvider::kShortcutsProviderDefaultMaxRelevance; - const int kMaxScore = CalculateScore("test", shortcut, max_relevance); + const int kMaxScore = CalculateScore("test", shortcut); // Score decreases as percent of the match is decreased. - int score_three_quarters = CalculateScore("tes", shortcut, max_relevance); + int score_three_quarters = CalculateScore("tes", shortcut); EXPECT_LT(score_three_quarters, kMaxScore); - int score_one_half = CalculateScore("te", shortcut, max_relevance); + int score_one_half = CalculateScore("te", shortcut); EXPECT_LT(score_one_half, score_three_quarters); - int score_one_quarter = CalculateScore("t", shortcut, max_relevance); + int score_one_quarter = CalculateScore("t", shortcut); EXPECT_LT(score_one_quarter, score_one_half); // Should decay with time - one week. shortcut.last_access_time = base::Time::Now() - base::TimeDelta::FromDays(7); - int score_week_old = CalculateScore("test", shortcut, max_relevance); + int score_week_old = CalculateScore("test", shortcut); EXPECT_LT(score_week_old, kMaxScore); // Should decay more in two weeks. shortcut.last_access_time = base::Time::Now() - base::TimeDelta::FromDays(14); - int score_two_weeks_old = CalculateScore("test", shortcut, max_relevance); + int score_two_weeks_old = CalculateScore("test", shortcut); EXPECT_LT(score_two_weeks_old, score_week_old); - // But not if it was activly clicked on. 2 hits slow decaying power. + // But not if it was actively clicked on. 2 hits slow decaying power. shortcut.number_of_hits = 2; shortcut.last_access_time = base::Time::Now() - base::TimeDelta::FromDays(14); - int score_popular_two_weeks_old = - CalculateScore("test", shortcut, max_relevance); + int score_popular_two_weeks_old = CalculateScore("test", shortcut); EXPECT_LT(score_two_weeks_old, score_popular_two_weeks_old); // But still decayed. EXPECT_LT(score_popular_two_weeks_old, kMaxScore); @@ -499,14 +501,33 @@ // 3 hits slow decaying power even more. shortcut.number_of_hits = 3; shortcut.last_access_time = base::Time::Now() - base::TimeDelta::FromDays(14); - int score_more_popular_two_weeks_old = - CalculateScore("test", shortcut, max_relevance); + int score_more_popular_two_weeks_old = CalculateScore("test", shortcut); EXPECT_LT(score_two_weeks_old, score_more_popular_two_weeks_old); EXPECT_LT(score_popular_two_weeks_old, score_more_popular_two_weeks_old); // But still decayed. EXPECT_LT(score_more_popular_two_weeks_old, kMaxScore); } +TEST_F(ShortcutsProviderTest, CalculateScore_LongTextFeature) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + omnibox::kPreserveLongerShortcutsText); + + auto long_shortcut = MakeShortcutWithText(u"test Yerevan"); + // Maximal score. + const int kMaxScore = CalculateScore("test Yerevan", long_shortcut); + // Score does not decrease when up to 3 chars are missing. + EXPECT_EQ(CalculateScore("test Yere", long_shortcut), kMaxScore); + // Score decreases if more than 3 chars are missing. + EXPECT_LT(CalculateScore("test Yer", long_shortcut), kMaxScore); + + auto short_shortcut = MakeShortcutWithText(u"ab"); + // Make sure there's no negative or weird scores when the shortcut text is + // shorter than the 3 char adjustment. + EXPECT_EQ(CalculateScore("ab", short_shortcut), kMaxScore); + EXPECT_EQ(CalculateScore("a", short_shortcut), kMaxScore); +} + TEST_F(ShortcutsProviderTest, DeleteMatch) { TestShortcutData shortcuts_to_test_delete[] = { {"BD85DBA2-8C29-49F9-84AE-48E1E90881F1", "delete", "www.deletetest.com/1",
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc index ffbb8cb8..43b84b0 100644 --- a/components/omnibox/common/omnibox_features.cc +++ b/components/omnibox/common/omnibox_features.cc
@@ -202,6 +202,12 @@ "OmniboxShortBookmarkSuggestionsByTotalInputLength", base::FEATURE_DISABLED_BY_DEFAULT}; +// If disabled, updating shortcuts truncates their text to the user input. If +// enabled, they preserve up to 3 additional chars. See `GetShortcutText()` in +// shortcuts_backend.cc for details. +const base::Feature kPreserveLongerShortcutsText{ + "OmniboxPreserveLongerShortcutsText", base::FEATURE_DISABLED_BY_DEFAULT}; + // If enabled, inputs may match bookmark paths. These path matches won't // contribute to scoring. E.g. 'planets jupiter' can suggest a bookmark titled // 'Jupiter' with URL 'en.wikipedia.org/wiki/Jupiter' located in a path
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h index 518f34f..1f425fd5 100644 --- a/components/omnibox/common/omnibox_features.h +++ b/components/omnibox/common/omnibox_features.h
@@ -54,6 +54,7 @@ extern const base::Feature kDisableCGIParamMatching; extern const base::Feature kShortBookmarkSuggestions; extern const base::Feature kShortBookmarkSuggestionsByTotalInputLength; +extern const base::Feature kPreserveLongerShortcutsText; extern const base::Feature kBookmarkPaths; // Document provider
diff --git a/components/page_load_metrics/browser/page_load_tracker.cc b/components/page_load_metrics/browser/page_load_tracker.cc index 6161efc..5070e18 100644 --- a/components/page_load_metrics/browser/page_load_tracker.cc +++ b/components/page_load_metrics/browser/page_load_tracker.cc
@@ -28,7 +28,6 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" #include "services/metrics/public/cpp/ukm_source_id.h" -#include "ui/base/page_transition_types.h" // This macro invokes the specified method on each observer, passing the // variable length arguments as the method's arguments, and removes the observer @@ -238,7 +237,6 @@ page_end_user_initiated_info_(UserInitiatedInfo::NotUserInitiated()), started_in_foreground_(in_foreground), last_dispatched_merged_page_timing_(CreatePageLoadTiming()), - page_transition_(navigation_handle->GetPageTransition()), user_initiated_info_(user_initiated_info), aborted_chain_size_(aborted_chain_size), aborted_chain_size_same_url_(aborted_chain_size_same_url), @@ -439,7 +437,6 @@ did_commit_ = true; url_ = navigation_handle->GetURL(); // Some transitions (like CLIENT_REDIRECT) are only known at commit time. - page_transition_ = navigation_handle->GetPageTransition(); user_initiated_info_.user_gesture = navigation_handle->HasUserGesture(); if (navigation_handle->IsInMainFrame()) {
diff --git a/components/page_load_metrics/browser/page_load_tracker.h b/components/page_load_metrics/browser/page_load_tracker.h index 240d2fa..27be5e66 100644 --- a/components/page_load_metrics/browser/page_load_tracker.h +++ b/components/page_load_metrics/browser/page_load_tracker.h
@@ -23,7 +23,6 @@ #include "net/cookies/canonical_cookie.h" #include "services/metrics/public/cpp/ukm_source.h" #include "third_party/abseil-cpp/absl/types/optional.h" -#include "ui/base/page_transition_types.h" #include "ui/base/scoped_visibility_tracker.h" #include "ui/gfx/geometry/size.h" @@ -356,8 +355,6 @@ base::TimeTicks navigation_start() const { return navigation_start_; } - ui::PageTransition page_transition() const { return page_transition_; } - UserInitiatedInfo user_initiated_info() const { return user_initiated_info_; } PageLoadMetricsUpdateDispatcher* metrics_update_dispatcher() { @@ -469,8 +466,6 @@ mojom::PageLoadTimingPtr last_dispatched_merged_page_timing_; blink::MobileFriendliness latest_mobile_friendliness_; - ui::PageTransition page_transition_; - absl::optional<content::GlobalRequestID> navigation_request_id_; // Whether this page load was user initiated.
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index 0e8755e..85e1f7f 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn
@@ -675,7 +675,6 @@ "password_reuse_manager_impl_unittest.cc", "password_save_manager_impl_unittest.cc", "password_store_impl_unittest.cc", - "password_store_origin_unittest.h", "password_store_unittest.cc", "password_sync_util_unittest.cc", "password_ui_utils_unittest.cc",
diff --git a/components/password_manager/core/browser/mock_password_store.h b/components/password_manager/core/browser/mock_password_store.h index 92ae4927..1c81c289 100644 --- a/components/password_manager/core/browser/mock_password_store.h +++ b/components/password_manager/core/browser/mock_password_store.h
@@ -28,6 +28,14 @@ MOCK_METHOD(void, RemoveLogin, (const PasswordForm&), (override)); MOCK_METHOD(void, + RemoveLoginsByURLAndTime, + (const base::RepeatingCallback<bool(const GURL&)>&, + base::Time, + base::Time, + base::OnceClosure, + base::OnceCallback<void(bool)>), + (override)); + MOCK_METHOD(void, Unblocklist, (const PasswordFormDigest&, base::OnceClosure), (override)); @@ -90,10 +98,20 @@ (const std::u16string&), (override)); MOCK_METHOD(DatabaseCleanupResult, DeleteUndecryptableLogins, (), (override)); + void SetUnsyncedCredentialsDeletionNotifier( + std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier) + override { + NOTIMPLEMENTED(); + } MOCK_METHOD(void, NotifyLoginsChanged, (const PasswordStoreChangeList&), (override)); + void NotifyDeletionsHaveSynced(bool) override { NOTIMPLEMENTED(); } + void NotifyUnsyncedCredentialsWillBeDeleted( + std::vector<PasswordForm>) override { + NOTIMPLEMENTED(); + } MOCK_METHOD(std::vector<InteractionsStats>, GetSiteStatsImpl, (const GURL& origin_domain),
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc index 6b268fd..8198fb11 100644 --- a/components/password_manager/core/browser/password_store.cc +++ b/components/password_manager/core/browser/password_store.cc
@@ -130,10 +130,12 @@ base::OnceClosure completion, base::OnceCallback<void(bool)> sync_completion) { DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); - ScheduleTask(base::BindOnce(&PasswordStore::RemoveLoginsByURLAndTimeInternal, - this, url_filter, delete_begin, delete_end, - std::move(completion), - std::move(sync_completion))); + // TODO(crbug.com/1226042): Pass NotifyLoginsChanged as a callback since + // PasswordStoreImpl won't call PasswordStore::NotifyLoginsChanged directly + // after it inherits PasswordStoreSync. + backend_->RemoveLoginsByURLAndTimeAsync( + base::NullCallback(), url_filter, delete_begin, delete_end, + std::move(completion), std::move(sync_completion)); } void PasswordStore::RemoveLoginsCreatedBetween(base::Time delete_begin, @@ -395,18 +397,6 @@ base::Unretained(this))); } -void PasswordStore::SetUnsyncedCredentialsDeletionNotifier( - std::unique_ptr<PasswordStore::UnsyncedCredentialsDeletionNotifier> - notifier) { - DCHECK(!deletion_notifier_); - DCHECK(notifier); - deletion_notifier_ = std::move(notifier); -} - -void PasswordStore::SetSyncTaskTimeoutForTest(base::TimeDelta timeout) { - sync_task_timeout_ = timeout; -} - PasswordStore::~PasswordStore() { DCHECK(shutdown_called_); } @@ -426,45 +416,12 @@ } } -void PasswordStore::NotifyDeletionsHaveSynced(bool success) { - DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); - // Either all deletions have been committed to the Sync server, or Sync is - // telling us that it won't commit them (because Sync was turned off - // permanently). In either case, run the corresponding callbacks now (on the - // main task runner). - DCHECK(!success || !GetMetadataStore()->HasUnsyncedDeletions()); - if (!deletions_have_synced_callbacks_.empty()) { - base::UmaHistogramBoolean( - "PasswordManager.PasswordStoreDeletionsHaveSynced", success); - } - for (auto& callback : deletions_have_synced_callbacks_) { - main_task_runner_->PostTask(FROM_HERE, - base::BindOnce(std::move(callback), success)); - } - deletions_have_synced_timeout_.Cancel(); - deletions_have_synced_callbacks_.clear(); -} - void PasswordStore::InvokeAndNotifyAboutInsecureCredentialsChange( base::OnceCallback<PasswordStoreChangeList()> callback) { DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); NotifyLoginsChanged(std::move(callback).Run()); } -void PasswordStore::NotifyUnsyncedCredentialsWillBeDeleted( - std::vector<PasswordForm> unsynced_credentials) { - DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); - DCHECK(IsAccountStore()); - // |deletion_notifier_| only gets set for desktop. - if (deletion_notifier_) { - main_task_runner_->PostTask( - FROM_HERE, - base::BindOnce( - &PasswordStore::UnsyncedCredentialsDeletionNotifier::Notify, - deletion_notifier_->GetWeakPtr(), std::move(unsynced_credentials))); - } -} - void PasswordStore::OnInitCompleted(bool success) { DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); init_status_ = success ? InitStatus::kSuccess : InitStatus::kFailure; @@ -571,43 +528,6 @@ CommitTransaction(); } -void PasswordStore::RemoveLoginsByURLAndTimeInternal( - const base::RepeatingCallback<bool(const GURL&)>& url_filter, - base::Time delete_begin, - base::Time delete_end, - base::OnceClosure completion, - base::OnceCallback<void(bool)> sync_completion) { - DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); - TRACE_EVENT0("passwords", "PasswordStore::RemoveLoginsByURLAndTimeInternal"); - BeginTransaction(); - PasswordStoreChangeList changes = - RemoveLoginsByURLAndTimeImpl(url_filter, delete_begin, delete_end); - NotifyLoginsChanged(changes); - // Sync metadata get updated in NotifyLoginsChanged(). Therefore, - // CommitTransaction() must be called after NotifyLoginsChanged(), because - // sync codebase needs to update metadata atomically together with the login - // data. - CommitTransaction(); - - if (completion) - main_task_runner_->PostTask(FROM_HERE, std::move(completion)); - - if (sync_completion) { - deletions_have_synced_callbacks_.push_back(std::move(sync_completion)); - // Start a timeout for sync, or restart it if it was already running. - deletions_have_synced_timeout_.Reset(base::BindOnce( - &PasswordStore::NotifyDeletionsHaveSynced, this, /*success=*/false)); - background_task_runner_->PostDelayedTask( - FROM_HERE, deletions_have_synced_timeout_.callback(), - sync_task_timeout_); - - // Do an immediate check for the case where there are already no unsynced - // deletions. - if (!GetMetadataStore()->HasUnsyncedDeletions()) - NotifyDeletionsHaveSynced(/*success=*/true); - } -} - void PasswordStore::RemoveLoginsCreatedBetweenInternal( base::Time delete_begin, base::Time delete_end,
diff --git a/components/password_manager/core/browser/password_store.h b/components/password_manager/core/browser/password_store.h index 98c5c01..9fbeb4a1 100644 --- a/components/password_manager/core/browser/password_store.h +++ b/components/password_manager/core/browser/password_store.h
@@ -197,10 +197,9 @@ CreateSyncControllerDelegate(); // Sets |deletion_notifier_|. Must not pass a nullptr. - void SetUnsyncedCredentialsDeletionNotifier( - std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier); - - void SetSyncTaskTimeoutForTest(base::TimeDelta timeout); + virtual void SetUnsyncedCredentialsDeletionNotifier( + std::unique_ptr<UnsyncedCredentialsDeletionNotifier> + deletion_notifier) = 0; protected: using LoginsTask = base::OnceCallback<LoginsResult()>; @@ -322,11 +321,6 @@ // been changed. void NotifyLoginsChanged(const PasswordStoreChangeList& changes) override; - void NotifyDeletionsHaveSynced(bool success) override; - - void NotifyUnsyncedCredentialsWillBeDeleted( - std::vector<PasswordForm> unsynced_credentials) override; - // Invokes callback and notifies observers if there was a change to the list // of insecure passwords. It also informs Sync about the updated password // forms to sync up the changes about insecure credentials. @@ -396,12 +390,6 @@ void RemoveLoginInternal(const PasswordForm& form); void UpdateLoginWithPrimaryKeyInternal(const PasswordForm& new_form, const PasswordForm& old_primary_key); - void RemoveLoginsByURLAndTimeInternal( - const base::RepeatingCallback<bool(const GURL&)>& url_filter, - base::Time delete_begin, - base::Time delete_end, - base::OnceClosure completion, - base::OnceCallback<void(bool)> sync_completion); void RemoveLoginsCreatedBetweenInternal(base::Time delete_begin, base::Time delete_end, base::OnceClosure completion); @@ -504,22 +492,10 @@ PrefService* prefs_ = nullptr; - std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier_; - - // A list of callbacks that should be run once all pending deletions have been - // sent to the Sync server. Note that the vector itself lives on the - // background thread, but the callbacks must be run on the main thread! - std::vector<base::OnceCallback<void(bool)>> deletions_have_synced_callbacks_; - // Timeout closure that runs if sync takes too long to propagate deletions. - base::CancelableOnceClosure deletions_have_synced_timeout_; - bool shutdown_called_ = false; InitStatus init_status_ = InitStatus::kUnknown; - // This is usually constant, only changed in tests. - base::TimeDelta sync_task_timeout_ = base::TimeDelta::FromSeconds(30); - DISALLOW_COPY_AND_ASSIGN(PasswordStore); };
diff --git a/components/password_manager/core/browser/password_store_backend.h b/components/password_manager/core/browser/password_store_backend.h index 1e42c73..2a41ddbb 100644 --- a/components/password_manager/core/browser/password_store_backend.h +++ b/components/password_manager/core/browser/password_store_backend.h
@@ -68,16 +68,18 @@ // PasswordStore and the async method on backend_ instead. virtual void AddLoginAsync(OptionalStoreChangeListReply callback, - const PasswordForm& form) {} + const PasswordForm& form) = 0; virtual void UpdateLoginAsync(OptionalStoreChangeListReply callback, - const PasswordForm& form) {} + const PasswordForm& form) = 0; virtual void RemoveLoginAsync(OptionalStoreChangeListReply callback, - const PasswordForm& form) {} + const PasswordForm& form) = 0; virtual void RemoveLoginsByURLAndTimeAsync( OptionalStoreChangeListReply callback, const base::RepeatingCallback<bool(const GURL&)>& url_filter, base::Time delete_begin, - base::Time delete_end) {} + base::Time delete_end, + base::OnceClosure completion, + base::OnceCallback<void(bool)> sync_completion) = 0; virtual void RemoveLoginsCreatedBetweenAsync( OptionalStoreChangeListReply callback, base::Time delete_begin,
diff --git a/components/password_manager/core/browser/password_store_impl.cc b/components/password_manager/core/browser/password_store_impl.cc index 8ec2b8d..0365f44 100644 --- a/components/password_manager/core/browser/password_store_impl.cc +++ b/components/password_manager/core/browser/password_store_impl.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/logging.h" +#include "base/metrics/histogram_functions.h" #include "components/password_manager/core/browser/password_store_change.h" #include "components/password_manager/core/browser/sync/password_sync_bridge.h" #include "components/prefs/pref_service.h" @@ -19,6 +20,8 @@ namespace { +constexpr base::TimeDelta kSyncTaskTimeout = base::TimeDelta::FromSeconds(30); + // Generates PasswordStoreChangeList for affected forms during // InsecureCredentials update. PasswordStoreChangeList BuildPasswordChangeListForInsecureCredentialsUpdate( @@ -47,6 +50,14 @@ base::BindOnce(&PasswordStoreImpl::DestroyOnBackgroundSequence, this)); } +void PasswordStoreImpl::SetUnsyncedCredentialsDeletionNotifier( + std::unique_ptr<PasswordStore::UnsyncedCredentialsDeletionNotifier> + notifier) { + DCHECK(!deletion_notifier_); + DCHECK(notifier); + deletion_notifier_ = std::move(notifier); +} + void PasswordStoreImpl::ReportMetricsImpl(const std::string& sync_username, bool custom_passphrase_sync_enabled, BulkCheckDone bulk_check_done) { @@ -343,6 +354,39 @@ sync_bridge_->ActOnPasswordStoreChanges(changes); } +void PasswordStoreImpl::NotifyDeletionsHaveSynced(bool success) { + DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); + // Either all deletions have been committed to the Sync server, or Sync is + // telling us that it won't commit them (because Sync was turned off + // permanently). In either case, run the corresponding callbacks now (on the + // main task runner). + DCHECK(!success || !GetMetadataStore()->HasUnsyncedDeletions()); + if (!deletions_have_synced_callbacks_.empty()) { + base::UmaHistogramBoolean( + "PasswordManager.PasswordStoreDeletionsHaveSynced", success); + } + for (auto& callback : deletions_have_synced_callbacks_) { + main_task_runner()->PostTask(FROM_HERE, + base::BindOnce(std::move(callback), success)); + } + deletions_have_synced_timeout_.Cancel(); + deletions_have_synced_callbacks_.clear(); +} + +void PasswordStoreImpl::NotifyUnsyncedCredentialsWillBeDeleted( + std::vector<PasswordForm> unsynced_credentials) { + DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); + DCHECK(IsAccountStore()); + // |deletion_notifier_| only gets set for desktop. + if (deletion_notifier_) { + main_task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + &PasswordStoreImpl::UnsyncedCredentialsDeletionNotifier::Notify, + deletion_notifier_->GetWeakPtr(), std::move(unsynced_credentials))); + } +} + bool PasswordStoreImpl::BeginTransaction() { if (login_db_) return login_db_->BeginTransaction(); @@ -435,6 +479,47 @@ std::move(callback)); } +void PasswordStoreImpl::AddLoginAsync(OptionalStoreChangeListReply callback, + const PasswordForm& form) { + background_task_runner()->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&PasswordStoreImpl::AddLoginInternal, this, form), + std::move(callback)); +} + +void PasswordStoreImpl::UpdateLoginAsync(OptionalStoreChangeListReply callback, + const PasswordForm& form) { + background_task_runner()->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&PasswordStoreImpl::UpdateLoginInternal, this, form), + std::move(callback)); +} + +void PasswordStoreImpl::RemoveLoginAsync(OptionalStoreChangeListReply callback, + const PasswordForm& form) { + background_task_runner()->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&PasswordStoreImpl::RemoveLoginInternal, this, form), + std::move(callback)); +} + +void PasswordStoreImpl::RemoveLoginsByURLAndTimeAsync( + OptionalStoreChangeListReply callback, + const base::RepeatingCallback<bool(const GURL&)>& url_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion, + base::OnceCallback<void(bool)> sync_completion) { + // TODO(crbug.com/1226042): Use PostTaskAndReplyWithResult instead of + // PostTask. + background_task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + IgnoreResult(&PasswordStoreImpl::RemoveLoginsByURLAndTimeInternal), + this, url_filter, delete_begin, delete_end, std::move(completion), + std::move(sync_completion))); +} + bool PasswordStoreImpl::InitOnBackgroundSequence( base::RepeatingClosure sync_enabled_or_disabled_cb) { DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); @@ -507,4 +592,82 @@ return results; } +PasswordStoreChangeList PasswordStoreImpl::AddLoginInternal( + const PasswordForm& form) { + DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); + BeginTransaction(); + PasswordStoreChangeList changes = AddLoginSync(form, /*error=*/nullptr); + NotifyLoginsChanged(changes); + // Sync metadata get updated in NotifyLoginsChanged(). Therefore, + // CommitTransaction() must be called after NotifyLoginsChanged(), because + // sync codebase needs to update metadata atomically together with the login + // data. + CommitTransaction(); + return changes; +} + +PasswordStoreChangeList PasswordStoreImpl::UpdateLoginInternal( + const PasswordForm& form) { + DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); + BeginTransaction(); + PasswordStoreChangeList changes = UpdateLoginSync(form, /*error=*/nullptr); + NotifyLoginsChanged(changes); + // Sync metadata get updated in NotifyLoginsChanged(). Therefore, + // CommitTransaction() must be called after NotifyLoginsChanged(), because + // sync codebase needs to update metadata atomically together with the login + // data. + CommitTransaction(); + return changes; +} + +PasswordStoreChangeList PasswordStoreImpl::RemoveLoginInternal( + const PasswordForm& form) { + DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); + BeginTransaction(); + PasswordStoreChangeList changes = RemoveLoginSync(form); + NotifyLoginsChanged(changes); + // Sync metadata get updated in NotifyLoginsChanged(). Therefore, + // CommitTransaction() must be called after NotifyLoginsChanged(), because + // sync codebase needs to update metadata atomically together with the login + // data. + CommitTransaction(); + return changes; +} + +PasswordStoreChangeList PasswordStoreImpl::RemoveLoginsByURLAndTimeInternal( + const base::RepeatingCallback<bool(const GURL&)>& url_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion, + base::OnceCallback<void(bool)> sync_completion) { + BeginTransaction(); + PasswordStoreChangeList changes = + RemoveLoginsByURLAndTimeImpl(url_filter, delete_begin, delete_end); + NotifyLoginsChanged(changes); + // Sync metadata get updated in NotifyLoginsChanged(). Therefore, + // CommitTransaction() must be called after NotifyLoginsChanged(), because + // sync codebase needs to update metadata atomically together with the login + // data. + CommitTransaction(); + + if (completion) + main_task_runner()->PostTask(FROM_HERE, std::move(completion)); + + if (sync_completion) { + deletions_have_synced_callbacks_.push_back(std::move(sync_completion)); + // Start a timeout for sync, or restart it if it was already running. + deletions_have_synced_timeout_.Reset( + base::BindOnce(&PasswordStoreImpl::NotifyDeletionsHaveSynced, this, + /*success=*/false)); + background_task_runner()->PostDelayedTask( + FROM_HERE, deletions_have_synced_timeout_.callback(), kSyncTaskTimeout); + + // Do an immediate check for the case where there are already no unsynced + // deletions. + if (!GetMetadataStore()->HasUnsyncedDeletions()) + NotifyDeletionsHaveSynced(/*success=*/true); + } + return changes; +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_impl.h b/components/password_manager/core/browser/password_store_impl.h index c894d1c..4d52f00 100644 --- a/components/password_manager/core/browser/password_store_impl.h +++ b/components/password_manager/core/browser/password_store_impl.h
@@ -37,6 +37,9 @@ ~PasswordStoreImpl() override; // Implements PasswordStore interface. + void SetUnsyncedCredentialsDeletionNotifier( + std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier) + override; void ReportMetricsImpl(const std::string& sync_username, bool custom_passphrase_sync_enabled, BulkCheckDone bulk_check_done) override; @@ -98,6 +101,9 @@ base::span<const InsecureCredential> credentials) override; PasswordStoreChangeList RemoveLoginSync(const PasswordForm& form) override; void NotifyLoginsChanged(const PasswordStoreChangeList& changes) override; + void NotifyDeletionsHaveSynced(bool success) override; + void NotifyUnsyncedCredentialsWillBeDeleted( + std::vector<PasswordForm> unsynced_credentials) override; bool BeginTransaction() override; void RollbackTransaction() override; bool CommitTransaction() override; @@ -125,6 +131,19 @@ void FillMatchingLoginsAsync( LoginsReply callback, const std::vector<PasswordFormDigest>& forms) override; + void AddLoginAsync(OptionalStoreChangeListReply callback, + const PasswordForm& form) override; + void UpdateLoginAsync(OptionalStoreChangeListReply callback, + const PasswordForm& form) override; + void RemoveLoginAsync(OptionalStoreChangeListReply callback, + const PasswordForm& form) override; + void RemoveLoginsByURLAndTimeAsync( + OptionalStoreChangeListReply callback, + const base::RepeatingCallback<bool(const GURL&)>& url_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion, + base::OnceCallback<void(bool)> sync_completion) override; // Opens |login_db_| and creates |sync_bridge_| on the background sequence. bool InitOnBackgroundSequence( @@ -143,6 +162,16 @@ LoginsResult FillMatchingLoginsInternal( const std::vector<PasswordFormDigest>& forms); + PasswordStoreChangeList AddLoginInternal(const PasswordForm& form); + PasswordStoreChangeList UpdateLoginInternal(const PasswordForm& form); + PasswordStoreChangeList RemoveLoginInternal(const PasswordForm& form); + PasswordStoreChangeList RemoveLoginsByURLAndTimeInternal( + const base::RepeatingCallback<bool(const GURL&)>& url_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion, + base::OnceCallback<void(bool)> sync_completion); + // The login SQL database. The LoginDatabase instance is received via the // in an uninitialized state, so as to allow injecting mocks, then Init() is // called on the background sequence in a deferred manner. If opening the DB @@ -151,6 +180,15 @@ std::unique_ptr<PasswordSyncBridge> sync_bridge_; + std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier_; + + // A list of callbacks that should be run once all pending deletions have been + // sent to the Sync server. Note that the vector itself lives on the + // background thread, but the callbacks must be run on the main thread! + std::vector<base::OnceCallback<void(bool)>> deletions_have_synced_callbacks_; + // Timeout closure that runs if sync takes too long to propagate deletions. + base::CancelableOnceClosure deletions_have_synced_timeout_; + DISALLOW_COPY_AND_ASSIGN(PasswordStoreImpl); };
diff --git a/components/password_manager/core/browser/password_store_impl_unittest.cc b/components/password_manager/core/browser/password_store_impl_unittest.cc index bb53069..97e1242 100644 --- a/components/password_manager/core/browser/password_store_impl_unittest.cc +++ b/components/password_manager/core/browser/password_store_impl_unittest.cc
@@ -20,7 +20,6 @@ #include "components/password_manager/core/browser/password_manager_test_utils.h" #include "components/password_manager/core/browser/password_store_change.h" #include "components/password_manager/core/browser/password_store_consumer.h" -#include "components/password_manager/core/browser/password_store_origin_unittest.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -33,15 +32,20 @@ namespace { -class MockPasswordStoreConsumer : public PasswordStoreConsumer { +class MockPasswordStoreBackendTester { public: - MOCK_METHOD1(OnGetPasswordStoreResultsConstRef, - void(const std::vector<std::unique_ptr<PasswordForm>>&)); + MOCK_METHOD(void, ChangeReceived, (PasswordStoreChangeList)); + MOCK_METHOD(void, + LoginsReceivedConstRef, + (const std::vector<std::unique_ptr<PasswordForm>>&)); - // GMock cannot mock methods with move-only args. - void OnGetPasswordStoreResults( - std::vector<std::unique_ptr<PasswordForm>> results) override { - OnGetPasswordStoreResultsConstRef(results); + void HandleChanges(absl::optional<PasswordStoreChangeList> changes) { + ASSERT_TRUE(changes.has_value()); + ChangeReceived(changes.value()); + } + + void HandleLogins(std::vector<std::unique_ptr<PasswordForm>> results) { + LoginsReceivedConstRef(results); } }; @@ -72,30 +76,49 @@ return data; } -class PasswordStoreImplTestDelegate { +} // anonymous namespace + +class PasswordStoreImplTest : public testing::Test { public: - PasswordStoreImplTestDelegate(); - explicit PasswordStoreImplTestDelegate( - std::unique_ptr<LoginDatabase> database); - ~PasswordStoreImplTestDelegate(); + PasswordStoreImplTest() = default; - PasswordStoreImplTestDelegate(const PasswordStoreImplTestDelegate&) = delete; - PasswordStoreImplTestDelegate operator=( - const PasswordStoreImplTestDelegate&) = delete; + PasswordStoreBackend* Initialize() { + store_ = + base::MakeRefCounted<PasswordStoreImpl>(std::make_unique<LoginDatabase>( + test_login_db_file_path(), IsAccountStore(false))); + store_->Init(/*prefs=*/nullptr); + return store_.get(); + } - PasswordStoreImpl* store() { return store_.get(); } + PasswordStoreBackend* InitializeWithDatabase( + std::unique_ptr<LoginDatabase> database) { + store_ = base::MakeRefCounted<PasswordStoreImpl>(std::move(database)); + store_->Init(/*prefs=*/nullptr); + return store_.get(); + } - void FinishAsyncProcessing(); + void SetUp() override { + OSCryptMocker::SetUp(); + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + } + + void TearDown() override { + store_->ShutdownOnUIThread(); + RunUntilIdle(); + OSCryptMocker::TearDown(); + ASSERT_TRUE(temp_dir_.Delete()); + } + + void RunUntilIdle() { task_environment_.RunUntilIdle(); } private: void SetupTempDir(); void ClosePasswordStore(); - scoped_refptr<PasswordStoreImpl> CreateInitializedStore( - std::unique_ptr<LoginDatabase> database); - - base::FilePath test_login_db_file_path() const; + base::FilePath test_login_db_file_path() const { + return temp_dir_.GetPath().Append(FILE_PATH_LITERAL("login_test")); + } base::test::TaskEnvironment task_environment_{ base::test::TaskEnvironment::MainThreadType::UI}; @@ -103,148 +126,105 @@ scoped_refptr<PasswordStoreImpl> store_; }; -PasswordStoreImplTestDelegate::PasswordStoreImplTestDelegate() { - OSCryptMocker::SetUp(); - SetupTempDir(); - store_ = CreateInitializedStore(std::make_unique<LoginDatabase>( - test_login_db_file_path(), IsAccountStore(false))); -} - -PasswordStoreImplTestDelegate::PasswordStoreImplTestDelegate( - std::unique_ptr<LoginDatabase> database) { - OSCryptMocker::SetUp(); - SetupTempDir(); - store_ = CreateInitializedStore(std::move(database)); -} - -PasswordStoreImplTestDelegate::~PasswordStoreImplTestDelegate() { - ClosePasswordStore(); - OSCryptMocker::TearDown(); -} - -void PasswordStoreImplTestDelegate::FinishAsyncProcessing() { - task_environment_.RunUntilIdle(); -} - -void PasswordStoreImplTestDelegate::SetupTempDir() { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); -} - -void PasswordStoreImplTestDelegate::ClosePasswordStore() { - store_->ShutdownOnUIThread(); - FinishAsyncProcessing(); - ASSERT_TRUE(temp_dir_.Delete()); -} - -scoped_refptr<PasswordStoreImpl> -PasswordStoreImplTestDelegate::CreateInitializedStore( - std::unique_ptr<LoginDatabase> database) { - scoped_refptr<PasswordStoreImpl> store( - new PasswordStoreImpl(std::move(database))); - store->Init(/*prefs=*/nullptr); - - return store; -} - -base::FilePath PasswordStoreImplTestDelegate::test_login_db_file_path() const { - return temp_dir_.GetPath().Append(FILE_PATH_LITERAL("login_test")); -} - -} // anonymous namespace - -INSTANTIATE_TYPED_TEST_SUITE_P(Default, - PasswordStoreOriginTest, - PasswordStoreImplTestDelegate); - -TEST(PasswordStoreImplTest, NonASCIIData) { - PasswordStoreImplTestDelegate delegate; - PasswordStoreImpl* store = delegate.store(); +TEST_F(PasswordStoreImplTest, NonASCIIData) { + PasswordStoreBackend* backend = Initialize(); // Some non-ASCII password form data. - static const PasswordFormData form_data[] = { - {PasswordForm::Scheme::kHtml, "http://foo.example.com", - "http://foo.example.com/origin", "http://foo.example.com/action", - u"มีสีสัน", u"お元気ですか?", u"盆栽", u"أحب كرة", u"£éä국수çà", true, 1}, - }; + static const PasswordFormData form_data = {PasswordForm::Scheme::kHtml, + "http://foo.example.com", + "http://foo.example.com/origin", + "http://foo.example.com/action", + u"มีสีสัน", + u"お元気ですか?", + u"盆栽", + u"أحب كرة", + u"£éä국수çà", + true, + 1}; // Build the expected forms vector and add the forms to the store. std::vector<std::unique_ptr<PasswordForm>> expected_forms; - for (const auto& data : form_data) { - expected_forms.push_back(FillPasswordFormWithData(data)); - store->AddLogin(*expected_forms.back()); - } - - MockPasswordStoreConsumer consumer; + expected_forms.push_back(FillPasswordFormWithData(form_data)); + backend->AddLoginAsync(base::DoNothing(), *expected_forms.back()); + testing::StrictMock<MockPasswordStoreBackendTester> tester; // We expect to get the same data back, even though it's not all ASCII. EXPECT_CALL( - consumer, - OnGetPasswordStoreResultsConstRef( + tester, + LoginsReceivedConstRef( password_manager::UnorderedPasswordFormElementsAre(&expected_forms))); - store->GetAutofillableLogins(&consumer); - delegate.FinishAsyncProcessing(); + backend->GetAutofillableLoginsAsync( + base::BindOnce(&MockPasswordStoreBackendTester::HandleLogins, + base::Unretained(&tester))); + + RunUntilIdle(); } -TEST(PasswordStoreImplTest, Notifications) { - PasswordStoreImplTestDelegate delegate; - PasswordStoreImpl* store = delegate.store(); +TEST_F(PasswordStoreImplTest, TestAddLoginAsync) { + PasswordStoreBackend* backend = Initialize(); + PasswordForm form = *FillPasswordFormWithData(CreateTestPasswordFormData()); - std::unique_ptr<PasswordForm> form = - FillPasswordFormWithData(CreateTestPasswordFormData()); + const PasswordStoreChange add_change = + PasswordStoreChange(PasswordStoreChange::ADD, form); - MockPasswordStoreObserver observer; - store->AddObserver(&observer); + testing::StrictMock<MockPasswordStoreBackendTester> tester; + EXPECT_CALL(tester, ChangeReceived(ElementsAre(add_change))); + backend->AddLoginAsync( + base::BindOnce(&MockPasswordStoreBackendTester::HandleChanges, + base::Unretained(&tester)), + form); + RunUntilIdle(); +} - const PasswordStoreChange expected_add_changes[] = { - PasswordStoreChange(PasswordStoreChange::ADD, *form), - }; +TEST_F(PasswordStoreImplTest, TestUpdateLoginAsync) { + PasswordStoreBackend* backend = Initialize(); + PasswordForm form = *FillPasswordFormWithData(CreateTestPasswordFormData()); - EXPECT_CALL(observer, - OnLoginsChanged(_, ElementsAreArray(expected_add_changes))); + backend->AddLoginAsync(base::DoNothing(), form); + RunUntilIdle(); - // Adding a login should trigger a notification. - store->AddLogin(*form); + form.password_value = u"a different password"; + const PasswordStoreChange update_change = + PasswordStoreChange(PasswordStoreChange::UPDATE, form); - // Change the password. - form->password_value = u"a different password"; + testing::StrictMock<MockPasswordStoreBackendTester> tester; + EXPECT_CALL(tester, ChangeReceived(ElementsAre(update_change))); + backend->UpdateLoginAsync( + base::BindOnce(&MockPasswordStoreBackendTester::HandleChanges, + base::Unretained(&tester)), + form); + RunUntilIdle(); +} - const PasswordStoreChange expected_update_changes[] = { - PasswordStoreChange(PasswordStoreChange::UPDATE, *form), - }; +TEST_F(PasswordStoreImplTest, TestRemoveLoginAsync) { + PasswordStoreBackend* backend = Initialize(); + PasswordForm form = *FillPasswordFormWithData(CreateTestPasswordFormData()); - EXPECT_CALL(observer, - OnLoginsChanged(_, ElementsAreArray(expected_update_changes))); + backend->AddLoginAsync(base::DoNothing(), form); + RunUntilIdle(); - // Updating the login with the new password should trigger a notification. - store->UpdateLogin(*form); + PasswordStoreChange remove_change = + PasswordStoreChange(PasswordStoreChange::REMOVE, form); - const PasswordStoreChange expected_delete_changes[] = { - PasswordStoreChange(PasswordStoreChange::REMOVE, *form), - }; - - EXPECT_CALL(observer, - OnLoginsChanged(_, ElementsAreArray(expected_delete_changes))); - - // Deleting the login should trigger a notification. - store->RemoveLogin(*form); - // Run the tasks to allow all the above expected calls to take place. - delegate.FinishAsyncProcessing(); - - store->RemoveObserver(&observer); + testing::StrictMock<MockPasswordStoreBackendTester> tester; + EXPECT_CALL(tester, ChangeReceived(ElementsAre(remove_change))); + backend->RemoveLoginAsync( + base::BindOnce(&MockPasswordStoreBackendTester::HandleChanges, + base::Unretained(&tester)), + form); + RunUntilIdle(); } // Verify that operations on a PasswordStore with a bad database cause no // explosions, but fail without side effect, return no data and trigger no // notifications. -TEST(PasswordStoreImplTest, OperationsOnABadDatabaseSilentlyFail) { - PasswordStoreImplTestDelegate delegate(std::make_unique<BadLoginDatabase>()); - PasswordStoreImpl* bad_store = delegate.store(); - delegate.FinishAsyncProcessing(); - ASSERT_EQ(nullptr, bad_store->login_db()); +TEST_F(PasswordStoreImplTest, OperationsOnABadDatabaseSilentlyFail) { + PasswordStoreBackend* bad_backend = + InitializeWithDatabase(std::make_unique<BadLoginDatabase>()); + RunUntilIdle(); - testing::StrictMock<MockPasswordStoreObserver> mock_observer; - bad_store->AddObserver(&mock_observer); + testing::StrictMock<MockPasswordStoreBackendTester> tester; // Add a new autofillable login + a blocked login. std::unique_ptr<PasswordForm> form = @@ -254,45 +234,45 @@ blocked_form->url = GURL("http://foo.example.com/origin"); blocked_form->action = GURL("http://foo.example.com/action"); blocked_form->blocked_by_user = true; - bad_store->AddLogin(*form); - bad_store->AddLogin(*blocked_form); - delegate.FinishAsyncProcessing(); + + base::RepeatingCallback<void(absl::optional<PasswordStoreChangeList>)> + handle_changes = + base::BindRepeating(&MockPasswordStoreBackendTester::HandleChanges, + base::Unretained(&tester)); + base::RepeatingCallback<void(LoginsResult)> handle_logins = + base::BindRepeating(&MockPasswordStoreBackendTester::HandleLogins, + base::Unretained(&tester)); + + EXPECT_CALL(tester, ChangeReceived(IsEmpty())); + bad_backend->AddLoginAsync(handle_changes, *form); + RunUntilIdle(); + testing::Mock::VerifyAndClearExpectations(&tester); + + EXPECT_CALL(tester, ChangeReceived(IsEmpty())); + bad_backend->AddLoginAsync(handle_changes, *blocked_form); + RunUntilIdle(); + testing::Mock::VerifyAndClearExpectations(&tester); // Get all logins; autofillable logins; blocked logins. - testing::StrictMock<MockPasswordStoreConsumer> mock_consumer; - EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())); - bad_store->GetLogins(PasswordFormDigest(*form), &mock_consumer); - delegate.FinishAsyncProcessing(); - testing::Mock::VerifyAndClearExpectations(&mock_consumer); - EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())); - bad_store->GetAutofillableLogins(&mock_consumer); - delegate.FinishAsyncProcessing(); - testing::Mock::VerifyAndClearExpectations(&mock_consumer); - EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())); - bad_store->GetAllLogins(&mock_consumer); - delegate.FinishAsyncProcessing(); - testing::Mock::VerifyAndClearExpectations(&mock_consumer); + EXPECT_CALL(tester, LoginsReceivedConstRef(IsEmpty())); + bad_backend->FillMatchingLoginsAsync(handle_logins, + {PasswordFormDigest(*form)}); + RunUntilIdle(); + testing::Mock::VerifyAndClearExpectations(&tester); - // Report metrics. - bad_store->ReportMetrics("Test Username", true, false); - delegate.FinishAsyncProcessing(); + EXPECT_CALL(tester, LoginsReceivedConstRef(IsEmpty())); + bad_backend->GetAutofillableLoginsAsync(handle_logins); + RunUntilIdle(); + testing::Mock::VerifyAndClearExpectations(&tester); - // Change the login. - form->password_value = u"a different password"; - bad_store->UpdateLogin(*form); - delegate.FinishAsyncProcessing(); + EXPECT_CALL(tester, LoginsReceivedConstRef(IsEmpty())); + bad_backend->GetAllLoginsAsync(handle_logins); + RunUntilIdle(); + testing::Mock::VerifyAndClearExpectations(&tester); - // Delete one login; a range of logins. - bad_store->RemoveLogin(*form); - delegate.FinishAsyncProcessing(); - base::RunLoop run_loop; - bad_store->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max(), - run_loop.QuitClosure()); - run_loop.Run(); - delegate.FinishAsyncProcessing(); - - // Ensure no notifications and no explosions during shutdown either. - bad_store->RemoveObserver(&mock_observer); + EXPECT_CALL(tester, ChangeReceived(IsEmpty())); + bad_backend->RemoveLoginAsync(handle_changes, *form); + RunUntilIdle(); } } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_origin_unittest.h b/components/password_manager/core/browser/password_store_origin_unittest.h deleted file mode 100644 index 234728d..0000000 --- a/components/password_manager/core/browser/password_store_origin_unittest.h +++ /dev/null
@@ -1,177 +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. - -#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_ORIGIN_UNITTEST_H_ -#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_ORIGIN_UNITTEST_H_ - -#include <memory> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/run_loop.h" -#include "base/time/time.h" -#include "components/password_manager/core/browser/password_manager_test_utils.h" -#include "components/password_manager/core/browser/password_store.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" -#include "url/origin.h" - -using password_manager::PasswordStore; -using testing::_; -using testing::ElementsAre; - -bool matchesOrigin(const url::Origin& origin, const GURL& url) { - return origin.IsSameOriginWith(url::Origin::Create(url)); -} - -namespace password_manager { - -PasswordFormData CreateTestPasswordFormDataByOrigin(const char* origin_url) { - PasswordFormData data = {PasswordForm::Scheme::kHtml, - origin_url, - origin_url, - "login_element", - u"submit_element", - u"username_element", - u"password_element", - u"username_value", - u"password_value", - true, - 1}; - return data; -} - -// Collection of origin-related testcases common to all platform-specific -// stores. -// The template type T represents a test delegate that must implement the -// following methods: -// // Returns a pointer to a fully initialized store for polymorphic usage. -// PasswordStore* store(); -// -// // Finishes all asnychronous processing on the store. -// void FinishAsyncProcessing(); -template <typename T> -class PasswordStoreOriginTest : public testing::Test { - protected: - T delegate_; -}; - -TYPED_TEST_SUITE_P(PasswordStoreOriginTest); - -TYPED_TEST_P(PasswordStoreOriginTest, - RemoveLoginsByURLAndTimeImpl_AllFittingOriginAndTime) { - const char origin_url[] = "http://foo.example.com/"; - std::unique_ptr<PasswordForm> form = - FillPasswordFormWithData(CreateTestPasswordFormDataByOrigin(origin_url)); - this->delegate_.store()->AddLogin(*form); - this->delegate_.FinishAsyncProcessing(); - - MockPasswordStoreObserver observer; - this->delegate_.store()->AddObserver(&observer); - - const url::Origin origin = url::Origin::Create((GURL(origin_url))); - base::RepeatingCallback<bool(const GURL&)> filter = - base::BindRepeating(&matchesOrigin, origin); - base::RunLoop run_loop; - EXPECT_CALL(observer, - OnLoginsChanged(_, ElementsAre(PasswordStoreChange( - PasswordStoreChange::REMOVE, *form)))); - this->delegate_.store()->RemoveLoginsByURLAndTime( - filter, base::Time(), base::Time::Max(), run_loop.QuitClosure()); - run_loop.Run(); - - this->delegate_.store()->RemoveObserver(&observer); -} - -TYPED_TEST_P(PasswordStoreOriginTest, - RemoveLoginsByURLAndTimeImpl_SomeFittingOriginAndTime) { - const char fitting_url[] = "http://foo.example.com/"; - std::unique_ptr<PasswordForm> form = - FillPasswordFormWithData(CreateTestPasswordFormDataByOrigin(fitting_url)); - this->delegate_.store()->AddLogin(*form); - - const char nonfitting_url[] = "http://bar.example.com/"; - this->delegate_.store()->AddLogin(*FillPasswordFormWithData( - CreateTestPasswordFormDataByOrigin(nonfitting_url))); - - this->delegate_.FinishAsyncProcessing(); - - MockPasswordStoreObserver observer; - this->delegate_.store()->AddObserver(&observer); - - const url::Origin fitting_origin = url::Origin::Create((GURL(fitting_url))); - base::RepeatingCallback<bool(const GURL&)> filter = - base::BindRepeating(&matchesOrigin, fitting_origin); - base::RunLoop run_loop; - EXPECT_CALL(observer, - OnLoginsChanged(_, ElementsAre(PasswordStoreChange( - PasswordStoreChange::REMOVE, *form)))); - this->delegate_.store()->RemoveLoginsByURLAndTime( - filter, base::Time(), base::Time::Max(), run_loop.QuitClosure()); - run_loop.Run(); - - this->delegate_.store()->RemoveObserver(&observer); -} - -TYPED_TEST_P(PasswordStoreOriginTest, - RemoveLoginsByURLAndTimeImpl_NonMatchingOrigin) { - const char origin_url[] = "http://foo.example.com/"; - std::unique_ptr<PasswordForm> form = - FillPasswordFormWithData(CreateTestPasswordFormDataByOrigin(origin_url)); - this->delegate_.store()->AddLogin(*form); - this->delegate_.FinishAsyncProcessing(); - - MockPasswordStoreObserver observer; - this->delegate_.store()->AddObserver(&observer); - - const url::Origin other_origin = - url::Origin::Create(GURL("http://bar.example.com/")); - base::RepeatingCallback<bool(const GURL&)> filter = - base::BindRepeating(&matchesOrigin, other_origin); - base::RunLoop run_loop; - EXPECT_CALL(observer, OnLoginsChanged).Times(0); - this->delegate_.store()->RemoveLoginsByURLAndTime( - filter, base::Time(), base::Time::Max(), run_loop.QuitClosure()); - run_loop.Run(); - - this->delegate_.store()->RemoveObserver(&observer); -} - -TYPED_TEST_P(PasswordStoreOriginTest, - RemoveLoginsByURLAndTimeImpl_NotWithinTimeInterval) { - const char origin_url[] = "http://foo.example.com/"; - std::unique_ptr<PasswordForm> form = - FillPasswordFormWithData(CreateTestPasswordFormDataByOrigin(origin_url)); - this->delegate_.store()->AddLogin(*form); - this->delegate_.FinishAsyncProcessing(); - - MockPasswordStoreObserver observer; - this->delegate_.store()->AddObserver(&observer); - - const url::Origin origin = url::Origin::Create((GURL(origin_url))); - base::RepeatingCallback<bool(const GURL&)> filter = - base::BindRepeating(&matchesOrigin, origin); - base::Time time_after_creation_date = - form->date_created + base::TimeDelta::FromDays(1); - base::RunLoop run_loop; - EXPECT_CALL(observer, OnLoginsChanged).Times(0); - this->delegate_.store()->RemoveLoginsByURLAndTime( - filter, time_after_creation_date, base::Time::Max(), - run_loop.QuitClosure()); - run_loop.Run(); - - this->delegate_.store()->RemoveObserver(&observer); -} - -REGISTER_TYPED_TEST_SUITE_P( - PasswordStoreOriginTest, - RemoveLoginsByURLAndTimeImpl_AllFittingOriginAndTime, - RemoveLoginsByURLAndTimeImpl_SomeFittingOriginAndTime, - RemoveLoginsByURLAndTimeImpl_NonMatchingOrigin, - RemoveLoginsByURLAndTimeImpl_NotWithinTimeInterval); - -} // namespace password_manager - -#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_ORIGIN_UNITTEST_H_
diff --git a/components/password_manager/core/browser/password_store_unittest.cc b/components/password_manager/core/browser/password_store_unittest.cc index b27377af..1428129 100644 --- a/components/password_manager/core/browser/password_store_unittest.cc +++ b/components/password_manager/core/browser/password_store_unittest.cc
@@ -183,6 +183,25 @@ return form; } +bool MatchesOrigin(const GURL& origin, const GURL& url) { + return origin.GetOrigin() == url.GetOrigin(); +} + +PasswordFormData CreateTestPasswordFormDataByOrigin(const char* origin_url) { + PasswordFormData data = {PasswordForm::Scheme::kHtml, + origin_url, + origin_url, + "login_element", + u"submit_element", + u"username_element", + u"password_element", + u"username_value", + u"password_value", + true, + 1}; + return data; +} + } // namespace class PasswordStoreTest : public testing::Test { @@ -1526,4 +1545,128 @@ store->ShutdownOnUIThread(); } +// Collection of origin-related testcases common to all platform-specific +// stores. +class PasswordStoreOriginTest : public PasswordStoreTest { + public: + void SetUp() override { + PasswordStoreTest::SetUp(); + store_ = CreatePasswordStore(); + store_->Init(nullptr); + } + + void TearDown() override { + PasswordStoreTest::TearDown(); + store_->ShutdownOnUIThread(); + } + + PasswordStore* store() { return store_.get(); } + + private: + scoped_refptr<PasswordStoreImpl> store_; +}; + +TEST_F(PasswordStoreOriginTest, + RemoveLoginsByURLAndTimeImpl_AllFittingOriginAndTime) { + constexpr char origin_url[] = "http://foo.example.com/"; + std::unique_ptr<PasswordForm> form = + FillPasswordFormWithData(CreateTestPasswordFormDataByOrigin(origin_url)); + store()->AddLogin(*form); + WaitForPasswordStore(); + + MockPasswordStoreObserver observer; + store()->AddObserver(&observer); + + const GURL origin = GURL(origin_url); + base::RepeatingCallback<bool(const GURL&)> filter = + base::BindRepeating(&MatchesOrigin, origin); + base::RunLoop run_loop; + EXPECT_CALL(observer, + OnLoginsChanged(_, ElementsAre(PasswordStoreChange( + PasswordStoreChange::REMOVE, *form)))); + store()->RemoveLoginsByURLAndTime(filter, base::Time(), base::Time::Max(), + run_loop.QuitClosure()); + run_loop.Run(); + + store()->RemoveObserver(&observer); +} + +TEST_F(PasswordStoreOriginTest, + RemoveLoginsByURLAndTimeImpl_SomeFittingOriginAndTime) { + constexpr char fitting_url[] = "http://foo.example.com/"; + std::unique_ptr<PasswordForm> form = + FillPasswordFormWithData(CreateTestPasswordFormDataByOrigin(fitting_url)); + store()->AddLogin(*form); + + const char nonfitting_url[] = "http://bar.example.com/"; + store()->AddLogin(*FillPasswordFormWithData( + CreateTestPasswordFormDataByOrigin(nonfitting_url))); + + WaitForPasswordStore(); + + MockPasswordStoreObserver observer; + store()->AddObserver(&observer); + + const GURL fitting_origin = GURL(fitting_url); + base::RepeatingCallback<bool(const GURL&)> filter = + base::BindRepeating(&MatchesOrigin, fitting_origin); + base::RunLoop run_loop; + EXPECT_CALL(observer, + OnLoginsChanged(_, ElementsAre(PasswordStoreChange( + PasswordStoreChange::REMOVE, *form)))); + store()->RemoveLoginsByURLAndTime(filter, base::Time(), base::Time::Max(), + run_loop.QuitClosure()); + run_loop.Run(); + + store()->RemoveObserver(&observer); +} + +TEST_F(PasswordStoreOriginTest, + RemoveLoginsByURLAndTimeImpl_NonMatchingOrigin) { + constexpr char origin_url[] = "http://foo.example.com/"; + std::unique_ptr<PasswordForm> form = + FillPasswordFormWithData(CreateTestPasswordFormDataByOrigin(origin_url)); + store()->AddLogin(*form); + WaitForPasswordStore(); + + MockPasswordStoreObserver observer; + store()->AddObserver(&observer); + + const GURL other_origin = GURL("http://bar.example.com/"); + base::RepeatingCallback<bool(const GURL&)> filter = + base::BindRepeating(&MatchesOrigin, other_origin); + base::RunLoop run_loop; + EXPECT_CALL(observer, OnLoginsChanged).Times(0); + store()->RemoveLoginsByURLAndTime(filter, base::Time(), base::Time::Max(), + run_loop.QuitClosure()); + run_loop.Run(); + + store()->RemoveObserver(&observer); +} + +TEST_F(PasswordStoreOriginTest, + RemoveLoginsByURLAndTimeImpl_NotWithinTimeInterval) { + constexpr char origin_url[] = "http://foo.example.com/"; + std::unique_ptr<PasswordForm> form = + FillPasswordFormWithData(CreateTestPasswordFormDataByOrigin(origin_url)); + store()->AddLogin(*form); + WaitForPasswordStore(); + + MockPasswordStoreObserver observer; + store()->AddObserver(&observer); + + const GURL origin = GURL(origin_url); + base::RepeatingCallback<bool(const GURL&)> filter = + base::BindRepeating(&MatchesOrigin, origin); + base::Time time_after_creation_date = + form->date_created + base::TimeDelta::FromDays(1); + base::RunLoop run_loop; + EXPECT_CALL(observer, OnLoginsChanged).Times(0); + store()->RemoveLoginsByURLAndTime(filter, time_after_creation_date, + base::Time::Max(), run_loop.QuitClosure()); + run_loop.Run(); + + store()->RemoveObserver(&observer); +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/test_password_store.cc b/components/password_manager/core/browser/test_password_store.cc index 7c7a63d..22ec549 100644 --- a/components/password_manager/core/browser/test_password_store.cc +++ b/components/password_manager/core/browser/test_password_store.cc
@@ -183,6 +183,43 @@ std::move(callback)); } +void TestPasswordStore::AddLoginAsync(OptionalStoreChangeListReply callback, + const PasswordForm& form) { + background_task_runner()->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&TestPasswordStore::AddLoginImpl, base::Unretained(this), + form, /*error=*/nullptr), + std::move(callback)); +} + +void TestPasswordStore::UpdateLoginAsync(OptionalStoreChangeListReply callback, + const PasswordForm& form) { + background_task_runner()->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&TestPasswordStore::UpdateLoginImpl, + base::Unretained(this), form, /*error=*/nullptr), + std::move(callback)); +} + +void TestPasswordStore::RemoveLoginAsync(OptionalStoreChangeListReply callback, + const PasswordForm& form) { + background_task_runner()->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&TestPasswordStore::RemoveLoginImpl, + base::Unretained(this), form), + std::move(callback)); +} + +void TestPasswordStore::RemoveLoginsByURLAndTimeAsync( + OptionalStoreChangeListReply callback, + const base::RepeatingCallback<bool(const GURL&)>& url_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion, + base::OnceCallback<void(bool)> sync_completion) { + NOTIMPLEMENTED(); +} + PasswordStoreChangeList TestPasswordStore::AddLoginImpl( const PasswordForm& form, AddLoginError* error) { @@ -420,6 +457,11 @@ NOTIMPLEMENTED(); } +void TestPasswordStore::SetUnsyncedCredentialsDeletionNotifier( + std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier) { + NOTIMPLEMENTED(); +} + PasswordStoreChangeList TestPasswordStore::AddLoginSync( const PasswordForm& form, AddLoginError* error) { @@ -453,6 +495,15 @@ return {}; } +void TestPasswordStore::NotifyDeletionsHaveSynced(bool success) { + NOTIMPLEMENTED(); +} + +void TestPasswordStore::NotifyUnsyncedCredentialsWillBeDeleted( + std::vector<PasswordForm> unsynced_credentials) { + NOTIMPLEMENTED(); +} + bool TestPasswordStore::BeginTransaction() { return true; }
diff --git a/components/password_manager/core/browser/test_password_store.h b/components/password_manager/core/browser/test_password_store.h index 7e48ea7c..2b73922 100644 --- a/components/password_manager/core/browser/test_password_store.h +++ b/components/password_manager/core/browser/test_password_store.h
@@ -90,7 +90,19 @@ void FillMatchingLoginsAsync( LoginsReply callback, const std::vector<PasswordFormDigest>& forms) override; - + void AddLoginAsync(OptionalStoreChangeListReply callback, + const PasswordForm& form) override; + void UpdateLoginAsync(OptionalStoreChangeListReply callback, + const PasswordForm& form) override; + void RemoveLoginAsync(OptionalStoreChangeListReply callback, + const PasswordForm& form) override; + void RemoveLoginsByURLAndTimeAsync( + OptionalStoreChangeListReply callback, + const base::RepeatingCallback<bool(const GURL&)>& url_filter, + base::Time delete_begin, + base::Time delete_end, + base::OnceClosure completion, + base::OnceCallback<void(bool)> sync_completion) override; // PasswordStore interface PasswordStoreChangeList AddLoginImpl(const PasswordForm& form, AddLoginError* error) override; @@ -137,7 +149,9 @@ std::vector<FieldInfo> GetAllFieldInfoImpl() override; void RemoveFieldInfoByTimeImpl(base::Time remove_begin, base::Time remove_end) override; - + void SetUnsyncedCredentialsDeletionNotifier( + std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier) + override; // PasswordStoreSync interface. // TODO(crbug.bom/1226042): Remove this after PasswordStore no longer // inherits PasswordStoreSync. @@ -151,6 +165,9 @@ const PasswordForm& form, base::span<const InsecureCredential> credentials) override; PasswordStoreChangeList RemoveLoginSync(const PasswordForm& form) override; + void NotifyDeletionsHaveSynced(bool success) override; + void NotifyUnsyncedCredentialsWillBeDeleted( + std::vector<PasswordForm> unsynced_credentials) override; bool BeginTransaction() override; void RollbackTransaction() override; bool CommitTransaction() override;
diff --git a/components/payments/content/payment_method_manifest_table.cc b/components/payments/content/payment_method_manifest_table.cc index 0957f644..190c41fd 100644 --- a/components/payments/content/payment_method_manifest_table.cc +++ b/components/payments/content/payment_method_manifest_table.cc
@@ -154,12 +154,8 @@ "WHERE credential_id=? " "AND relying_party_id<>?")); int index = 0; - if (!s0.BindBlob(index++, instrument.credential_id)) - return false; - - if (!s0.BindString(index++, instrument.relying_party_id)) - return false; - + s0.BindBlob(index++, instrument.credential_id); + s0.BindString(index++, instrument.relying_party_id); if (s0.Step()) return false; } @@ -168,8 +164,7 @@ sql::Statement s1(db_->GetUniqueStatement( "DELETE FROM secure_payment_confirmation_instrument " "WHERE credential_id=?")); - if (!s1.BindBlob(0, instrument.credential_id)) - return false; + s1.BindBlob(0, instrument.credential_id); if (!s1.Run()) return false; @@ -181,17 +176,10 @@ "(credential_id, relying_party_id, label, icon) " "VALUES (?, ?, ?, ?)")); int index = 0; - if (!s2.BindBlob(index++, instrument.credential_id)) - return false; - - if (!s2.BindString(index++, instrument.relying_party_id)) - return false; - - if (!s2.BindString16(index++, instrument.label)) - return false; - - if (!s2.BindBlob(index++, instrument.icon)) - return false; + s2.BindBlob(index++, instrument.credential_id); + s2.BindString(index++, instrument.relying_party_id); + s2.BindString16(index++, instrument.label); + s2.BindBlob(index++, instrument.icon); if (!s2.Run()) return false; @@ -218,8 +206,7 @@ if (credential_id.empty()) continue; - if (!s.BindBlob(0, credential_id)) - continue; + s.BindBlob(0, credential_id); if (!s.Step()) continue;
diff --git a/components/performance_manager/features.cc b/components/performance_manager/features.cc index da8ac4a..eda3148 100644 --- a/components/performance_manager/features.cc +++ b/components/performance_manager/features.cc
@@ -86,5 +86,27 @@ base::FEATURE_DISABLED_BY_DEFAULT}; #endif +const base::Feature kBFCachePerformanceManagerPolicy{ + "BFCachePerformanceManagerPolicy", base::FEATURE_DISABLED_BY_DEFAULT}; + +BFCachePerformanceManagerPolicyParams::BFCachePerformanceManagerPolicyParams() = + default; +BFCachePerformanceManagerPolicyParams::BFCachePerformanceManagerPolicyParams( + const BFCachePerformanceManagerPolicyParams& rhs) = default; +BFCachePerformanceManagerPolicyParams:: + ~BFCachePerformanceManagerPolicyParams() = default; + +constexpr base::FeatureParam<bool> + BFCachePerformanceManagerPolicyParams::kFlushOnModeratePressure; + +// static +BFCachePerformanceManagerPolicyParams +BFCachePerformanceManagerPolicyParams::GetParams() { + BFCachePerformanceManagerPolicyParams params = {}; + params.flush_on_moderate_pressure_ = + BFCachePerformanceManagerPolicyParams::kFlushOnModeratePressure.Get(); + return params; +} + } // namespace features } // namespace performance_manager
diff --git a/components/performance_manager/graph/policies/bfcache_policy.cc b/components/performance_manager/graph/policies/bfcache_policy.cc index d306d6c..ffaa43f 100644 --- a/components/performance_manager/graph/policies/bfcache_policy.cc +++ b/components/performance_manager/graph/policies/bfcache_policy.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/memory/memory_pressure_listener.h" #include "base/task/task_traits.h" +#include "components/performance_manager/public/features.h" #include "components/performance_manager/public/graph/frame_node.h" #include "components/performance_manager/public/graph/page_node.h" #include "components/performance_manager/public/web_contents_proxy.h" @@ -97,6 +98,14 @@ return; } + if (new_level == base::MemoryPressureListener::MemoryPressureLevel:: + MEMORY_PRESSURE_LEVEL_NONE && + !performance_manager::features::BFCachePerformanceManagerPolicyParams:: + GetParams() + .flush_on_moderate_pressure()) { + return; + } + // Flush the cache of all visible pages, the bfcache of background pages // should already be empty. for (auto* page_node : graph_->GetAllPageNodes()) {
diff --git a/components/performance_manager/public/features.h b/components/performance_manager/public/features.h index ca66e1a..ab5cbfa53 100644 --- a/components/performance_manager/public/features.h +++ b/components/performance_manager/public/features.h
@@ -85,6 +85,37 @@ extern const base::Feature kBackgroundTabLoadingFromPerformanceManager; #endif +// Policy that evicts the BFCache of pages that become non visible or the +// BFCache of all pages when the system is under memory pressure. +extern const base::Feature kBFCachePerformanceManagerPolicy; + +// Parameters allowing to control some aspects of the +// |kBFCachePerformanceManagerPolicy|. +class BFCachePerformanceManagerPolicyParams { + public: + ~BFCachePerformanceManagerPolicyParams(); + + static BFCachePerformanceManagerPolicyParams GetParams(); + + // Whether or not the BFCache of all pages should be flushed when the system + // is under *moderate* memory pressure. The policy always flushes the bfcache + // under critical pressure. + bool flush_on_moderate_pressure() const { + return flush_on_moderate_pressure_; + } + + static constexpr base::FeatureParam<bool> kFlushOnModeratePressure{ + &features::kBFCachePerformanceManagerPolicy, "flush_on_moderate_pressure", + true}; + + private: + BFCachePerformanceManagerPolicyParams(); + BFCachePerformanceManagerPolicyParams( + const BFCachePerformanceManagerPolicyParams& rhs); + + bool flush_on_moderate_pressure_ = true; +}; + } // namespace features } // namespace performance_manager
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto index 064f10cf..eddb0c2 100644 --- a/components/policy/proto/chrome_device_policy.proto +++ b/components/policy/proto/chrome_device_policy.proto
@@ -1796,6 +1796,15 @@ optional string device_scheduled_reboot_settings = 1; } +// Setting that controls whether restricted managed guest session is enabled on +// the device. +message DeviceRestrictedManagedGuestSessionEnabledProto { + // If this policy is set to true, it will forcefully override certain + // policies. If it's set to false or not set, then no policies will be + // overridden. + optional bool enabled = 1 [default = false]; +} + message ChromeDeviceSettingsProto { reserved 61, 90; optional DevicePolicyRefreshRateProto device_policy_refresh_rate = 1; @@ -1956,4 +1965,6 @@ optional DeviceScheduledRebootProto device_scheduled_reboot = 122; optional DevicePciPeripheralDataAccessEnabledProtoV2 device_pci_peripheral_data_access_enabled_v2 = 123; + optional DeviceRestrictedManagedGuestSessionEnabledProto + device_restricted_managed_guest_session_enabled = 124; }
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index a4e82ff..6f53c3bf 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -26429,6 +26429,35 @@ Setting the policy to False removes the sharing icon from the omnibox and the entry from the 3-dot menu.''', }, + { + 'name': 'RestrictedManagedGuestSessionEnabled', + 'owners': ['mpetrisor@chromium.org', 'hendrich@chromium.org'], + 'type': 'main', + 'schema': { 'type': 'boolean' }, + 'supported_on': ['chrome_os:93-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': False, + }, + 'items': [ + { + 'value': True, + 'caption': 'Enable restricted managed guest session.', + }, + { + 'value': False, + 'caption': 'Disable restricted managed guest session.', + }, + ], + 'default': False, + 'example_value': True, + 'id': 872, + 'caption': '''Restricted managed guest sessions''', + 'tags': [], + 'desc': '''The policy only applies to managed guest sessions. It has to be enabled for Imprivata's shared workstation mode to allow in-session user switches. + Setting the policy to True will forcefully override certain policies for features, which persist sensitive user data and are not handled by the clean-up mechanism used for in-session user switches with Imprivata shared workstation mode. + Setting the policy to False or leaving it unset will not override any policies.''', + }, ], 'messages': { # Messages that are not associated to any policies. @@ -27363,6 +27392,6 @@ 'placeholders': [], 'deleted_policy_ids': [114, 115, 204, 205, 206, 412, 476, 544, 546, 562, 569, 578, 583, 585, 586, 587, 588, 589, 590, 591, 600, 668, 669], 'deleted_atomic_policy_group_ids': [19], - 'highest_id_currently_used': 871, + 'highest_id_currently_used': 872, 'highest_atomic_group_id_currently_used': 40 }
diff --git a/components/query_parser/query_parser.cc b/components/query_parser/query_parser.cc index 5be2cd74..ed485f4 100644 --- a/components/query_parser/query_parser.cc +++ b/components/query_parser/query_parser.cc
@@ -6,6 +6,7 @@ #include <algorithm> #include <memory> +#include <ostream> #include "base/check.h" #include "base/compiler_specific.h"
diff --git a/components/sync/driver/sync_service_crypto.cc b/components/sync/driver/sync_service_crypto.cc index 671fd9b..019ec0fa 100644 --- a/components/sync/driver/sync_service_crypto.cc +++ b/components/sync/driver/sync_service_crypto.cc
@@ -262,7 +262,7 @@ bool SyncServiceCrypto::IsEncryptEverythingEnabled() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(state_.engine); - return state_.encrypt_everything || state_.encryption_pending; + return state_.encrypt_everything; } void SyncServiceCrypto::SetEncryptionPassphrase(const std::string& passphrase) {
diff --git a/components/sync/driver/sync_service_crypto.h b/components/sync/driver/sync_service_crypto.h index 4b19dc2..0e65140 100644 --- a/components/sync/driver/sync_service_crypto.h +++ b/components/sync/driver/sync_service_crypto.h
@@ -95,8 +95,6 @@ void OnTrustedVaultKeysChanged() override; void OnTrustedVaultRecoverabilityChanged() override; - bool encryption_pending() const { return state_.encryption_pending; } - private: enum class RequiredUserAction { kUnknownDuringInitialization, @@ -174,11 +172,6 @@ // Whether we want to encrypt everything. bool encrypt_everything = false; - // Whether we're waiting for an attempt to encryption all sync data to - // complete. We track this at this layer in order to allow the user to - // cancel if they e.g. don't remember their explicit passphrase. - bool encryption_pending = false; - // We cache the cryptographer's pending keys whenever // NotifyPassphraseRequired is called. This way, before the UI calls // SetDecryptionPassphrase on the syncer, it can avoid the overhead of an
diff --git a/components/sync/driver/sync_user_settings_impl.cc b/components/sync/driver/sync_user_settings_impl.cc index 6301966..f31068e 100644 --- a/components/sync/driver/sync_user_settings_impl.cc +++ b/components/sync/driver/sync_user_settings_impl.cc
@@ -265,8 +265,6 @@ } bool SyncUserSettingsImpl::IsEncryptedDatatypeEnabled() const { - if (crypto_->encryption_pending()) - return true; const ModelTypeSet preferred_types = GetPreferredDataTypes(); const ModelTypeSet encrypted_types = GetEncryptedDataTypes(); DCHECK(encrypted_types.HasAll(AlwaysEncryptedUserTypes()));
diff --git a/components/sync/trusted_vault/trusted_vault_request.cc b/components/sync/trusted_vault/trusted_vault_request.cc index 7ca40c8..5a47cfa 100644 --- a/components/sync/trusted_vault/trusted_vault_request.cc +++ b/components/sync/trusted_vault/trusted_vault_request.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "base/metrics/histogram_functions.h" #include "base/strings/stringprintf.h" #include "components/signin/public/identity_manager/access_token_info.h" #include "components/sync/trusted_vault/trusted_vault_access_token_fetcher.h" @@ -117,10 +118,20 @@ void TrustedVaultRequest::OnURLLoadComplete( std::unique_ptr<std::string> response_body) { + const int net_error = url_loader_->NetError(); int http_response_code = 0; + if (url_loader_->ResponseInfo() && url_loader_->ResponseInfo()->headers) { http_response_code = url_loader_->ResponseInfo()->headers->response_code(); } + + DCHECK_LE(net_error, 0); + DCHECK_GE(http_response_code, 0); + + base::UmaHistogramSparse( + "Sync.TrustedVaultURLFetchResponse", + http_response_code == 0 ? net_error : http_response_code); + if (http_response_code == net::HTTP_NOT_FOUND) { RunCompletionCallbackAndMaybeDestroySelf(HttpStatus::kNotFound, std::string());
diff --git a/components/ukm/ios/BUILD.gn b/components/ukm/ios/BUILD.gn index b19dfd6..65d1cd47 100644 --- a/components/ukm/ios/BUILD.gn +++ b/components/ukm/ios/BUILD.gn
@@ -5,18 +5,7 @@ assert(target_os == "ios") group("ios") { - public_deps = [ - ":features", - ":ukm_url_recorder", - ] -} - -source_set("features") { - sources = [ - "features.cc", - "features.h", - ] - deps = [ "//base" ] + public_deps = [ ":ukm_url_recorder" ] } source_set("ukm_url_recorder") {
diff --git a/components/ukm/ios/features.cc b/components/ukm/ios/features.cc deleted file mode 100644 index 8e6d8746..0000000 --- a/components/ukm/ios/features.cc +++ /dev/null
@@ -1,8 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "components/ukm/ios/features.h" - -const base::Feature kUmaCellular{"UmaCellular", - base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/components/ukm/ios/features.h b/components/ukm/ios/features.h deleted file mode 100644 index b18cd370..0000000 --- a/components/ukm/ios/features.h +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_UKM_IOS_FEATURES_H_ -#define COMPONENTS_UKM_IOS_FEATURES_H_ - -#include "base/feature_list.h" - -// Used to send UMA data over cellular. -extern const base::Feature kUmaCellular; - -#endif // COMPONENTS_UKM_IOS_FEATURES_H_
diff --git a/components/url_formatter/spoof_checks/skeleton_generator.cc b/components/url_formatter/spoof_checks/skeleton_generator.cc index ed242a7..3cc1d4b 100644 --- a/components/url_formatter/spoof_checks/skeleton_generator.cc +++ b/components/url_formatter/spoof_checks/skeleton_generator.cc
@@ -4,6 +4,8 @@ #include "components/url_formatter/spoof_checks/skeleton_generator.h" +#include <ostream> + #include "base/memory/ptr_util.h" #include "base/strings/string_piece.h" #include "third_party/icu/source/i18n/unicode/regex.h"
diff --git a/components/visitedlink/common/visitedlink_common.cc b/components/visitedlink/common/visitedlink_common.cc index e06f588..5cd8eed 100644 --- a/components/visitedlink/common/visitedlink_common.cc +++ b/components/visitedlink/common/visitedlink_common.cc
@@ -6,6 +6,8 @@ #include <string.h> // for memset() +#include <ostream> + #include "base/bit_cast.h" #include "base/check.h" #include "base/hash/md5.h"
diff --git a/components/viz/common/surfaces/frame_sink_id.cc b/components/viz/common/surfaces/frame_sink_id.cc index 553d3e6..62c830de 100644 --- a/components/viz/common/surfaces/frame_sink_id.cc +++ b/components/viz/common/surfaces/frame_sink_id.cc
@@ -4,6 +4,8 @@ #include "components/viz/common/surfaces/frame_sink_id.h" +#include <ostream> + #include "base/strings/string_piece.h" #include "base/strings/stringprintf.h"
diff --git a/components/viz/common/surfaces/surface_id.cc b/components/viz/common/surfaces/surface_id.cc index ce26752..be76e1ac 100644 --- a/components/viz/common/surfaces/surface_id.cc +++ b/components/viz/common/surfaces/surface_id.cc
@@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <algorithm> - #include "components/viz/common/surfaces/surface_id.h" -#include "components/viz/common/surfaces/surface_range.h" + +#include <algorithm> +#include <ostream> #include "base/strings/stringprintf.h" +#include "components/viz/common/surfaces/surface_range.h" namespace viz {
diff --git a/components/viz/common/surfaces/surface_range.cc b/components/viz/common/surfaces/surface_range.cc index d3b96347..609f612 100644 --- a/components/viz/common/surfaces/surface_range.cc +++ b/components/viz/common/surfaces/surface_range.cc
@@ -4,6 +4,7 @@ #include "components/viz/common/surfaces/surface_range.h" +#include <ostream> #include <string> #include "base/strings/stringprintf.h"
diff --git a/components/viz/service/surfaces/surface_reference.cc b/components/viz/service/surfaces/surface_reference.cc index 721d9d3..39bae88 100644 --- a/components/viz/service/surfaces/surface_reference.cc +++ b/components/viz/service/surfaces/surface_reference.cc
@@ -4,6 +4,8 @@ #include "components/viz/service/surfaces/surface_reference.h" +#include <ostream> + #include "base/strings/stringprintf.h" namespace viz {
diff --git a/components/web_package/test_support/web_bundle_builder.cc b/components/web_package/test_support/web_bundle_builder.cc index 4913f24..6555a52b 100644 --- a/components/web_package/test_support/web_bundle_builder.cc +++ b/components/web_package/test_support/web_bundle_builder.cc
@@ -4,6 +4,8 @@ #include "components/web_package/test_support/web_bundle_builder.h" +#include <ostream> + namespace web_package { namespace test {
diff --git a/components/webapk/webapk.proto b/components/webapk/webapk.proto index 7685ebbc..77a790b 100644 --- a/components/webapk/webapk.proto +++ b/components/webapk/webapk.proto
@@ -84,6 +84,9 @@ // The Android OS version (e.g '11'). optional string android_version = 12; + // Whether this builds supports app identity updates via dialog. + optional bool app_identity_update_supported = 13; + reserved 4, 10; }
diff --git a/components/webapps/browser/android/webapk/webapk_proto_builder.cc b/components/webapps/browser/android/webapk/webapk_proto_builder.cc index 451966b0..33191ac5d 100644 --- a/components/webapps/browser/android/webapk/webapk_proto_builder.cc +++ b/components/webapps/browser/android/webapk/webapk_proto_builder.cc
@@ -104,6 +104,7 @@ const std::string& version, std::map<std::string, WebApkIconHasher::Icon> icon_url_to_murmur2_hash, bool is_manifest_stale, + bool is_app_identity_update_supported, std::vector<WebApkUpdateReason> update_reasons) { std::unique_ptr<webapk::WebApk> webapk(new webapk::WebApk); webapk->set_manifest_url(shortcut_info.manifest_url.spec()); @@ -114,6 +115,7 @@ webapk->set_package_name(package_name); webapk->set_version(version); webapk->set_stale_manifest(is_manifest_stale); + webapk->set_app_identity_update_supported(is_app_identity_update_supported); webapk->set_android_version(base::SysInfo::OperatingSystemVersion()); for (auto update_reason : update_reasons) @@ -272,6 +274,7 @@ const std::string& version, std::map<std::string, WebApkIconHasher::Icon> icon_url_to_murmur2_hash, bool is_manifest_stale, + bool is_app_identity_update_supported, std::vector<WebApkUpdateReason> update_reasons) { base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, base::BlockingType::MAY_BLOCK); @@ -279,7 +282,8 @@ std::unique_ptr<std::string> proto = BuildProtoInBackground( shortcut_info, primary_icon, is_primary_icon_maskable, splash_icon, package_name, version, std::move(icon_url_to_murmur2_hash), - is_manifest_stale, std::move(update_reasons)); + is_manifest_stale, is_app_identity_update_supported, + std::move(update_reasons)); // Create directory if it does not exist. base::CreateDirectory(update_request_path.DirName());
diff --git a/components/webapps/browser/android/webapk/webapk_proto_builder.h b/components/webapps/browser/android/webapk/webapk_proto_builder.h index 34ad27b0..b30d8aa 100644 --- a/components/webapps/browser/android/webapk/webapk_proto_builder.h +++ b/components/webapps/browser/android/webapk/webapk_proto_builder.h
@@ -32,6 +32,7 @@ const std::string& version, std::map<std::string, WebApkIconHasher::Icon> icon_url_to_murmur2_hash, bool is_manifest_stale, + bool is_app_identity_update_supported, std::vector<WebApkUpdateReason> update_reasons); // Builds the WebAPK proto for an update request and stores it to @@ -47,6 +48,7 @@ const std::string& version, std::map<std::string, WebApkIconHasher::Icon> icon_url_to_murmur2_hash, bool is_manifest_stale, + bool is_app_identity_update_supported, std::vector<WebApkUpdateReason> update_reasons); } // namespace webapps
diff --git a/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm b/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm index 837ab67..c562e7de 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm +++ b/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm
@@ -252,6 +252,21 @@ } IN_PROC_BROWSER_TEST_F(AccessibilityTreeFormatterMacBrowserTest, + ParameterizedAttributes_TextMarkerArray) { + TestAndCheck( + R"~~(data:text/html, + <textbox id="textbox">Text</textbox>)~~", + {{"text_range:= textbox.AXTextMarkerRangeForUIElement(textbox)", SCRIPT}, + {"textbox.AXTextMarkerRangeForUnorderedTextMarkers([text_range." + "anchor, text_range.focus])", + SCRIPT}}, + {{"*", "*"}}, + R"~~(text_range={anchor: {:3, 0, down}, focus: {:3, 4, down}} + textbox.AXTextMarkerRangeForUnorderedTextMarkers([text_range.anchor, text_range.focus])={anchor: {:3, 0, down}, focus: {:3, 4, down}} +)~~"); +} + +IN_PROC_BROWSER_TEST_F(AccessibilityTreeFormatterMacBrowserTest, ParameterizedAttributes_NSRange_WrongParameters) { TestWrongParameters(R"~~(data:text/html, <p contentEditable='true'>Text</p>)~~",
diff --git a/content/browser/accessibility/accessibility_tree_formatter_utils_mac.h b/content/browser/accessibility/accessibility_tree_formatter_utils_mac.h index 3742f24..65c0c2a 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_utils_mac.h +++ b/content/browser/accessibility/accessibility_tree_formatter_utils_mac.h
@@ -117,6 +117,7 @@ NSNumber* PropertyNodeToInt(const ui::AXPropertyNode&) const; NSString* PropertyNodeToString(const ui::AXPropertyNode&) const; NSArray* PropertyNodeToIntArray(const ui::AXPropertyNode&) const; + NSArray* PropertyNodeToTextMarkerArray(const ui::AXPropertyNode&) const; NSValue* PropertyNodeToRange(const ui::AXPropertyNode&) const; gfx::NativeViewAccessible PropertyNodeToUIElement( const ui::AXPropertyNode&) const;
diff --git a/content/browser/accessibility/accessibility_tree_formatter_utils_mac.mm b/content/browser/accessibility/accessibility_tree_formatter_utils_mac.mm index 42800aa8..53bd0ba 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_utils_mac.mm +++ b/content/browser/accessibility/accessibility_tree_formatter_utils_mac.mm
@@ -296,6 +296,11 @@ if (property_name == "AXCellForColumnAndRow") { // IntArray return OptionalNSObject::NotNilOrError(PropertyNodeToIntArray(arg_node)); } + if (property_name == + "AXTextMarkerRangeForUnorderedTextMarkers") { // TextMarkerArray + return OptionalNSObject::NotNilOrError( + PropertyNodeToTextMarkerArray(arg_node)); + } if (property_name == "AXStringForRange") { // NSRange return OptionalNSObject::NotNilOrError(PropertyNodeToRange(arg_node)); } @@ -352,6 +357,26 @@ return array; } +// NSArray of AXTextMarker objects. +NSArray* AttributeInvoker::PropertyNodeToTextMarkerArray( + const AXPropertyNode& arraynode) const { + if (!arraynode.IsArray()) { + INTARRAY_FAIL(arraynode, "not array") + } + + NSMutableArray* array = + [[NSMutableArray alloc] initWithCapacity:arraynode.arguments.size()]; + for (const auto& paramnode : arraynode.arguments) { + OptionalNSObject text_marker = Invoke(paramnode); + if (!text_marker.IsNotNil()) { + INTARRAY_FAIL(arraynode, + paramnode.ToFlatString() + "is not a text marker") + } + [array addObject:(*text_marker)]; + } + return array; +} + // NSRange. Format: {loc: integer, len: integer}. NSValue* AttributeInvoker::PropertyNodeToRange( const AXPropertyNode& dictnode) const {
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index 7698335..1db779d 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -5318,7 +5318,7 @@ // If there is no response or no headers in the response, there are // definitely no trial token headers. response_head_ && response_head_->headers && - blink::TrialTokenValidator().RequestEnablesFeature( + blink::TrialTokenValidator().RequestEnablesDeprecatedFeature( common_params_->url, response_head_->headers.get(), "PrivateNetworkAccessNonSecureContextsAllowed", base::Time::Now())) { // TODO(https://crbug.com/1225977): Record that we need to increment a
diff --git a/content/browser/renderer_host/private_network_access_browsertest.cc b/content/browser/renderer_host/private_network_access_browsertest.cc index 8b97071..612d41b 100644 --- a/content/browser/renderer_host/private_network_access_browsertest.cc +++ b/content/browser/renderer_host/private_network_access_browsertest.cc
@@ -2376,10 +2376,8 @@ root_frame_host()->BuildClientSecurityState(); ASSERT_FALSE(security_state.is_null()); - // TODO(https://crbug.com/1225977): Expect `kAllow` once support for trials - // on insecure origins is fixed in `blink::TrialTokenValidator`. EXPECT_EQ(security_state->private_network_request_policy, - network::mojom::PrivateNetworkRequestPolicy::kBlock); + network::mojom::PrivateNetworkRequestPolicy::kAllow); } IN_PROC_BROWSER_TEST_F(PrivateNetworkAccessBrowserTest, OriginDisabled) {
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 86c2df1..0b14bf1 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -853,19 +853,6 @@ if (renderer_side_origin.opaque() && browser_side_origin.opaque()) return; -#if defined(OS_WIN) - // TODO(https://crbug.com/1214098): Navigating to a test-crafted - // (GURL::ReplaceComponents-crafted) file://localhost/C:/dir/file.txt URL will - // fail to round-trip the URL causing `browser_side_origin` and - // `renderer_side_origin` to be different (file://localhost/ vs file:///). In - // particular, without the following "if" statement the test - // ContentSecurityPolicyBrowserTest.FileURLs fails. - if (browser_side_origin.scheme() == url::kFileScheme && - renderer_side_origin.scheme() == url::kFileScheme) { - return; - } -#endif - DCHECK_EQ(browser_side_origin, renderer_side_origin) << "; navigation_request->GetURL() = " << navigation_request->GetURL(); }
diff --git a/content/browser/tracing/startup_tracing_browsertest.cc b/content/browser/tracing/startup_tracing_browsertest.cc index b591a61..9c45662f 100644 --- a/content/browser/tracing/startup_tracing_browsertest.cc +++ b/content/browser/tracing/startup_tracing_browsertest.cc
@@ -192,7 +192,14 @@ StartupTracingTest() = default; void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitch(switches::kTraceStartup); + // TODO(crbug/1220772): Ideally we shouldn't remove any categories and all + // should be well formed, however gpu.angle.* events don't correctly end + // their trace events causing stack depths to explode, this triggers a + // DCHECK failure on debug builds causing test failures. So remove them + // until https://bugs.chromium.org/p/angleproject/issues/detail?id=6158 is + // fixed. + command_line->AppendSwitchASCII(switches::kTraceStartup, + "-gpu.angle,-gpu.angle.gpu"); if (GetFinishType() == FinishType::kWaitForTimeout) { command_line->AppendSwitchASCII(switches::kTraceStartupDuration, "3"); } else { @@ -316,14 +323,7 @@ OutputLocation::kDirectoryWithDefaultBasename, OutputLocation::kDirectoryWithBasenameUpdatedBeforeStop))); -// TODO(crbug.com/1197278): Failing on Windows 7 debug builds. -// TODO(crbug.com/1224903): Failing on Linux dbg tests. -#if (defined(OS_WIN) || defined(OS_LINUX)) && DCHECK_IS_ON() -#define MAYBE_TestEnableTracing DISABLED_TestEnableTracing -#else -#define MAYBE_TestEnableTracing TestEnableTracing -#endif -IN_PROC_BROWSER_TEST_P(StartupTracingTest, MAYBE_TestEnableTracing) { +IN_PROC_BROWSER_TEST_P(StartupTracingTest, TestEnableTracing) { EXPECT_TRUE(NavigateToURL(shell(), GetTestUrl("", "title1.html"))); if (GetOutputLocation() == @@ -355,28 +355,14 @@ testing::Values(OutputType::kJSON, OutputType::kProto), testing::Values(OutputLocation::kDirectoryWithDefaultBasename))); -// TODO(crbug.com/1197278): Failing on Windows 7 debug builds. -// TODO(crbug.com/1224903): Failing on Linux dbg tests. -#if (defined(OS_WIN) || defined(OS_LINUX)) && DCHECK_IS_ON() -#define MAYBE_StopOnUIThread DISABLED_StopOnUIThread -#else -#define MAYBE_StopOnUIThread StopOnUIThread -#endif -IN_PROC_BROWSER_TEST_P(EmergencyStopTracingTest, MAYBE_StopOnUIThread) { +IN_PROC_BROWSER_TEST_P(EmergencyStopTracingTest, StopOnUIThread) { EXPECT_TRUE(NavigateToURL(shell(), GetTestUrl("", "title1.html"))); StartupTracingController::EmergencyStop(); CheckOutput(GetExpectedPath(), GetOutputType()); } -// TODO(crbug.com/1197278): Failing on Windows 7 debug builds. -// TODO(crbug.com/1224903): Failing on Linux dbg tests. -#if (defined(OS_WIN) || defined(OS_LINUX)) && DCHECK_IS_ON() -#define MAYBE_StopOnThreadPool DISABLED_StopOnThreadPool -#else -#define MAYBE_StopOnThreadPool StopOnThreadPool -#endif -IN_PROC_BROWSER_TEST_P(EmergencyStopTracingTest, MAYBE_StopOnThreadPool) { +IN_PROC_BROWSER_TEST_P(EmergencyStopTracingTest, StopOnThreadPool) { EXPECT_TRUE(NavigateToURL(shell(), GetTestUrl("", "title1.html"))); auto expected_path = GetExpectedPath(); @@ -393,14 +379,7 @@ run_loop.Run(); } -// TODO(crbug.com/1197278): Failing on Windows 7 debug builds. -// TODO(crbug.com/1224903): Failing on Linux dbg tests. -#if (defined(OS_WIN) || defined(OS_LINUX)) && DCHECK_IS_ON() -#define MAYBE_StopOnThreadPoolTwice DISABLED_StopOnThreadPoolTwice -#else -#define MAYBE_StopOnThreadPoolTwice StopOnThreadPoolTwice -#endif -IN_PROC_BROWSER_TEST_P(EmergencyStopTracingTest, MAYBE_StopOnThreadPoolTwice) { +IN_PROC_BROWSER_TEST_P(EmergencyStopTracingTest, StopOnThreadPoolTwice) { EXPECT_TRUE(NavigateToURL(shell(), GetTestUrl("", "title1.html"))); auto expected_path = GetExpectedPath();
diff --git a/content/browser/web_exposed_isolation_info.cc b/content/browser/web_exposed_isolation_info.cc index 98c3d2a..5cecf227 100644 --- a/content/browser/web_exposed_isolation_info.cc +++ b/content/browser/web_exposed_isolation_info.cc
@@ -4,6 +4,8 @@ #include "content/browser/web_exposed_isolation_info.h" +#include <ostream> + namespace content { // static
diff --git a/device/bluetooth/public/cpp/bluetooth_uuid.cc b/device/bluetooth/public/cpp/bluetooth_uuid.cc index 0831078..019e843 100644 --- a/device/bluetooth/public/cpp/bluetooth_uuid.cc +++ b/device/bluetooth/public/cpp/bluetooth_uuid.cc
@@ -6,6 +6,7 @@ #include <stddef.h> +#include <ostream> #include <string> #include "base/check_op.h"
diff --git a/device/fido/mac/credential_metadata.cc b/device/fido/mac/credential_metadata.cc index e28764b9..16526d1 100644 --- a/device/fido/mac/credential_metadata.cc +++ b/device/fido/mac/credential_metadata.cc
@@ -4,6 +4,8 @@ #include "device/fido/mac/credential_metadata.h" +#include <ostream> + #include "base/check.h" #include "base/notreached.h" #include "base/strings/string_number_conversions.h"
diff --git a/extensions/common/error_utils.cc b/extensions/common/error_utils.cc index fd5aef4..c75e4ce3 100644 --- a/extensions/common/error_utils.cc +++ b/extensions/common/error_utils.cc
@@ -5,6 +5,7 @@ #include "extensions/common/error_utils.h" #include <initializer_list> +#include <ostream> #include "base/check_op.h" #include "base/strings/string_piece.h"
diff --git a/extensions/common/extension_icon_set.cc b/extensions/common/extension_icon_set.cc index d8b7d77b..5099247 100644 --- a/extensions/common/extension_icon_set.cc +++ b/extensions/common/extension_icon_set.cc
@@ -4,6 +4,8 @@ #include "extensions/common/extension_icon_set.h" +#include <ostream> + #include "base/check_op.h" #include "base/files/file_path.h" #include "base/strings/string_util.h"
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn index 1322b97..076bf1e 100644 --- a/ios/chrome/app/BUILD.gn +++ b/ios/chrome/app/BUILD.gn
@@ -297,7 +297,6 @@ "//components/proxy_config", "//components/suggestions", "//components/sync", - "//components/ukm/ios:features", "//components/web_resource", "//ios/chrome/app/application_delegate", "//ios/chrome/app/application_delegate:application_delegate_internal",
diff --git a/ios/chrome/app/application_delegate/BUILD.gn b/ios/chrome/app/application_delegate/BUILD.gn index da405b23..6d3bb1b 100644 --- a/ios/chrome/app/application_delegate/BUILD.gn +++ b/ios/chrome/app/application_delegate/BUILD.gn
@@ -202,7 +202,6 @@ "//components/prefs", "//components/previous_session_info", "//components/search_engines", - "//components/ukm/ios:features", "//components/ukm/ios:ukm_reporting_ios_util", "//ios/chrome/app", "//ios/chrome/app:mode",
diff --git a/ios/chrome/app/application_delegate/metric_kit_subscriber.h b/ios/chrome/app/application_delegate/metric_kit_subscriber.h index feb97c54..9cb08a4 100644 --- a/ios/chrome/app/application_delegate/metric_kit_subscriber.h +++ b/ios/chrome/app/application_delegate/metric_kit_subscriber.h
@@ -12,7 +12,6 @@ // A subscriber that save MetricKit reports to the application document // directory. -API_AVAILABLE(ios(13.0)) @interface MetricKitSubscriber : NSObject <MXMetricManagerSubscriber> + (instancetype)sharedInstance;
diff --git a/ios/chrome/app/application_delegate/metric_kit_subscriber.mm b/ios/chrome/app/application_delegate/metric_kit_subscriber.mm index d31fb69..f3d2001d 100644 --- a/ios/chrome/app/application_delegate/metric_kit_subscriber.mm +++ b/ios/chrome/app/application_delegate/metric_kit_subscriber.mm
@@ -61,8 +61,8 @@ } #endif -void ReportLongDuration(const char* histogram_name, NSMeasurement* measurement) - API_AVAILABLE(ios(13.0)) { +void ReportLongDuration(const char* histogram_name, + NSMeasurement* measurement) { if (!measurement) { return; } @@ -75,8 +75,7 @@ base::TimeDelta::FromSeconds(86400 /* secs per day */), 50); } -void ReportMemory(const char* histogram_name, NSMeasurement* measurement) - API_AVAILABLE(ios(13.0)) { +void ReportMemory(const char* histogram_name, NSMeasurement* measurement) { if (!measurement) { return; } @@ -87,8 +86,7 @@ base::UmaHistogramMemoryLargeMB(histogram_name, value); } -void WriteMetricPayloads(NSArray<MXMetricPayload*>* payloads) - API_AVAILABLE(ios(13.0)) { +void WriteMetricPayloads(NSArray<MXMetricPayload*>* payloads) { NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString* documents_directory = [paths objectAtIndex:0]; @@ -229,8 +227,7 @@ } } -- (void)didReceiveMetricPayloads:(NSArray<MXMetricPayload*>*)payloads - API_AVAILABLE(ios(13.0)) { +- (void)didReceiveMetricPayloads:(NSArray<MXMetricPayload*>*)payloads { NSUserDefaults* standard_defaults = [NSUserDefaults standardUserDefaults]; if ([standard_defaults boolForKey:kEnableMetricKit]) { base::ThreadPool::PostTask( @@ -246,8 +243,7 @@ } - (void)logStartupDurationMXHistogram:(MXHistogram*)histogram - toUMAHistogram:(const char*)histogramUMAName - API_AVAILABLE(ios(13.0)) { + toUMAHistogram:(const char*)histogramUMAName { if (!histogram || !histogram.totalBucketCount) { return; } @@ -335,7 +331,7 @@ } #endif -- (void)processPayload:(MXMetricPayload*)payload API_AVAILABLE(ios(13.0)) { +- (void)processPayload:(MXMetricPayload*)payload { // TODO(crbug.com/1140474): See related bug for why |bundleVersion| comes from // mainBundle instead of from version_info::GetVersionNumber(). Remove once // iOS 14.2 reaches mass adoption.
diff --git a/ios/chrome/app/application_delegate/metrics_mediator.mm b/ios/chrome/app/application_delegate/metrics_mediator.mm index ce2ad68f..1f641ad9 100644 --- a/ios/chrome/app/application_delegate/metrics_mediator.mm +++ b/ios/chrome/app/application_delegate/metrics_mediator.mm
@@ -18,7 +18,6 @@ #include "components/metrics/metrics_service.h" #include "components/prefs/pref_service.h" #import "components/previous_session_info/previous_session_info.h" -#include "components/ukm/ios/features.h" #include "components/ukm/ios/ukm_reporting_ios_util.h" #import "ios/chrome/app/application_delegate/metric_kit_subscriber.h" #import "ios/chrome/app/application_delegate/startup_information.h" @@ -294,12 +293,6 @@ - (void)updateMetricsStateBasedOnPrefsUserTriggered:(BOOL)isUserTriggered { BOOL optIn = [self areMetricsEnabled]; BOOL allowUploading = [self isUploadingEnabled]; - if (!base::FeatureList::IsEnabled(kUmaCellular)) { - BOOL wifiOnly = GetApplicationContext()->GetLocalState()->GetBoolean( - prefs::kMetricsReportingWifiOnly); - optIn = optIn && wifiOnly; - } - if (isUserTriggered) [self updateMetricsPrefsOnPermissionChange:optIn]; [self setMetricsEnabled:optIn withUploading:allowUploading]; @@ -326,19 +319,7 @@ } - (BOOL)isUploadingEnabled { - BOOL optIn = [self areMetricsEnabled]; - if (base::FeatureList::IsEnabled(kUmaCellular)) { - return optIn; - } - BOOL wifiOnly = GetApplicationContext()->GetLocalState()->GetBoolean( - prefs::kMetricsReportingWifiOnly); - BOOL allowUploading = optIn; - if (optIn && wifiOnly) { - BOOL usingWWAN = net::NetworkChangeNotifier::IsConnectionCellular( - net::NetworkChangeNotifier::GetConnectionType()); - allowUploading = !usingWWAN; - } - return allowUploading; + return [self areMetricsEnabled]; } #pragma mark - Internal methods. @@ -528,13 +509,8 @@ } - (BOOL)isMetricsReportingEnabledWifiOnly { - BOOL optIn = GetApplicationContext()->GetLocalState()->GetBoolean( + return GetApplicationContext()->GetLocalState()->GetBoolean( metrics::prefs::kMetricsReportingEnabled); - if (base::FeatureList::IsEnabled(kUmaCellular)) { - return optIn; - } - return optIn && GetApplicationContext()->GetLocalState()->GetBoolean( - prefs::kMetricsReportingWifiOnly); } @end
diff --git a/ios/chrome/app/application_delegate/mock_metrickit_metric_payload.h b/ios/chrome/app/application_delegate/mock_metrickit_metric_payload.h index 5be49c9..887a6fbc 100644 --- a/ios/chrome/app/application_delegate/mock_metrickit_metric_payload.h +++ b/ios/chrome/app/application_delegate/mock_metrickit_metric_payload.h
@@ -16,6 +16,6 @@ // @"histogrammedTimeToFirstDrawKey" : @{@5 : @2, @15 : @4} // will report 2 startup in bucket [0,10] and 4 in bucket [10,20]. // Only the values currently reported in Chrome are mocked. -id MockMetricPayload(NSDictionary* dictionary) API_AVAILABLE(ios(13.0)); +id MockMetricPayload(NSDictionary* dictionary); #endif // IOS_CHROME_APP_APPLICATION_DELEGATE_MOCK_METRICKIT_METRIC_PAYLOAD_H_
diff --git a/ios/chrome/app/application_delegate/mock_metrickit_metric_payload.mm b/ios/chrome/app/application_delegate/mock_metrickit_metric_payload.mm index 8821b07..28856de 100644 --- a/ios/chrome/app/application_delegate/mock_metrickit_metric_payload.mm +++ b/ios/chrome/app/application_delegate/mock_metrickit_metric_payload.mm
@@ -16,7 +16,7 @@ #error "This file requires ARC support." #endif -id MockMXMetadata() API_AVAILABLE(ios(13.0)) { +id MockMXMetadata() { // TODO(crbug.com/1140474): See related bug for why |bundleVersion| comes from // mainBundle instead of from version_info::GetVersionNumber(). Remove once // iOS 14.2 reaches mass adoption. @@ -36,7 +36,7 @@ return mock_measurement; } -id MockMXMemoryMetric(NSDictionary* dictionary) API_AVAILABLE(ios(13.0)) { +id MockMXMemoryMetric(NSDictionary* dictionary) { id memory_metric = OCMClassMock([MXMemoryMetric class]); NSNumber* suspended_memory = [dictionary objectForKey:@"averageSuspendedMemory"]; @@ -61,7 +61,7 @@ return memory_metric; } -id MockMXAppRunTimeMetric(NSDictionary* dictionary) API_AVAILABLE(ios(13.0)) { +id MockMXAppRunTimeMetric(NSDictionary* dictionary) { id app_run_time = OCMClassMock([MXAppRunTimeMetric class]); NSNumber* cumulative_foreground = [dictionary objectForKey:@"cumulativeForegroundTime"]; @@ -85,8 +85,7 @@ return app_run_time; } -id MockMXHistogram(NSDictionary* dictionary, int delta) - API_AVAILABLE(ios(13.0)) { +id MockMXHistogram(NSDictionary* dictionary, int delta) { id histogram = OCMClassMock([MXHistogram class]); OCMStub([histogram totalBucketCount]).andReturn(dictionary.count); NSMutableArray* buckets = [[NSMutableArray alloc] init]; @@ -104,7 +103,7 @@ return histogram; } -id MockMXAppLaunchMetric(NSDictionary* dictionary) API_AVAILABLE(ios(13.0)) { +id MockMXAppLaunchMetric(NSDictionary* dictionary) { id app_launch = OCMClassMock([MXAppLaunchMetric class]); NSDictionary* first_draw = [dictionary objectForKey:@"histogrammedTimeToFirstDrawKey"]; @@ -125,8 +124,7 @@ return app_launch; } -id MockMXAppResponsivenessMetric(NSDictionary* dictionary) - API_AVAILABLE(ios(13.0)) { +id MockMXAppResponsivenessMetric(NSDictionary* dictionary) { id responsiveness = OCMClassMock([MXAppResponsivenessMetric class]); NSDictionary* hang_time = [dictionary objectForKey:@"histogrammedAppHangTime"]; @@ -202,7 +200,7 @@ } #endif -id MockMetricPayload(NSDictionary* dictionary) API_AVAILABLE(ios(13.0)) { +id MockMetricPayload(NSDictionary* dictionary) { id mock_report = OCMClassMock([MXMetricPayload class]); NSDictionary* application_time_metrics_dict = [dictionary objectForKey:@"applicationTimeMetrics"];
diff --git a/ios/chrome/app/blocking_scene_commands.h b/ios/chrome/app/blocking_scene_commands.h index 54d08fb..3072cfa 100644 --- a/ios/chrome/app/blocking_scene_commands.h +++ b/ios/chrome/app/blocking_scene_commands.h
@@ -11,8 +11,7 @@ @protocol BlockingSceneCommands // Activates the scene that currently shows blocking UI. -- (void)activateBlockingScene:(UIScene*)requestingScene - API_AVAILABLE(ios(13.0)); +- (void)activateBlockingScene:(UIScene*)requestingScene; @end
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index a38da5e9..35d55dd 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -29,7 +29,6 @@ #include "components/prefs/ios/pref_observer_bridge.h" #include "components/prefs/pref_change_registrar.h" #import "components/previous_session_info/previous_session_info.h" -#include "components/ukm/ios/features.h" #include "components/web_resource/web_resource_pref_names.h" #include "ios/chrome/app/app_metrics_app_state_agent.h" #import "ios/chrome/app/application_delegate/metrics_mediator.h" @@ -798,16 +797,11 @@ _localStatePrefObserverBridge->ObserveChangesForPreference( metrics::prefs::kMetricsReportingEnabled, &_localStatePrefChangeRegistrar); - if (!base::FeatureList::IsEnabled(kUmaCellular)) { - _localStatePrefObserverBridge->ObserveChangesForPreference( - prefs::kMetricsReportingWifiOnly, &_localStatePrefChangeRegistrar); - } // Calls the onPreferenceChanged function in case there was // a change to the observed preferences before the observer // bridge was set up. [self onPreferenceChanged:metrics::prefs::kMetricsReportingEnabled]; - [self onPreferenceChanged:prefs::kMetricsReportingWifiOnly]; // Track changes to default search engine. TemplateURLService* service = @@ -1121,8 +1115,7 @@ - (void)onPreferenceChanged:(const std::string&)preferenceName { // Turn on or off metrics & crash reporting when either preference changes. - if (preferenceName == metrics::prefs::kMetricsReportingEnabled || - preferenceName == prefs::kMetricsReportingWifiOnly) { + if (preferenceName == metrics::prefs::kMetricsReportingEnabled) { [_metricsMediator updateMetricsStateBasedOnPrefsUserTriggered:YES]; } }
diff --git a/ios/chrome/app/multitasking_test_scene_delegate.mm b/ios/chrome/app/multitasking_test_scene_delegate.mm index 9824cf3..1594bea 100644 --- a/ios/chrome/app/multitasking_test_scene_delegate.mm +++ b/ios/chrome/app/multitasking_test_scene_delegate.mm
@@ -4,6 +4,8 @@ #import "ios/chrome/app/multitasking_test_scene_delegate.h" +#include <ostream> + #include "base/notreached.h" #import "ios/chrome/app/application_delegate/app_state.h" #import "ios/chrome/app/chrome_overlay_window.h"
diff --git a/ios/chrome/app/startup/register_experimental_settings.mm b/ios/chrome/app/startup/register_experimental_settings.mm index 021e77e3..6a70452 100644 --- a/ios/chrome/app/startup/register_experimental_settings.mm +++ b/ios/chrome/app/startup/register_experimental_settings.mm
@@ -4,6 +4,8 @@ #include "ios/chrome/app/startup/register_experimental_settings.h" +#include <ostream> + #include "base/check.h" #include "base/mac/bundle_locations.h" #include "base/notreached.h"
diff --git a/ios/chrome/app/startup/setup_debugging.mm b/ios/chrome/app/startup/setup_debugging.mm index 178f837..d3fcdf6 100644 --- a/ios/chrome/app/startup/setup_debugging.mm +++ b/ios/chrome/app/startup/setup_debugging.mm
@@ -6,6 +6,8 @@ #include <objc/runtime.h> +#include <ostream> + #include "base/check.h" #include "base/strings/sys_string_conversions.h" #include "components/crash/core/common/objc_zombie.h"
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn index e1a747b..bfe76c0 100644 --- a/ios/chrome/browser/BUILD.gn +++ b/ios/chrome/browser/BUILD.gn
@@ -86,7 +86,6 @@ "//components/strings", "//components/sync", "//components/translate/core/browser", - "//components/ukm/ios:features", "//components/unified_consent", "//components/url_formatter", "//components/variations/net", @@ -211,7 +210,6 @@ "//components/sessions", "//components/translate/core/browser", "//components/ukm", - "//components/ukm/ios:features", "//components/update_client", "//components/variations", "//components/variations/field_trial_config",
diff --git a/ios/chrome/browser/flags/BUILD.gn b/ios/chrome/browser/flags/BUILD.gn index 8c3b744..d8b1614 100644 --- a/ios/chrome/browser/flags/BUILD.gn +++ b/ios/chrome/browser/flags/BUILD.gn
@@ -43,7 +43,6 @@ "//components/strings:components_strings", "//components/sync/driver", "//components/translate/core/browser", - "//components/ukm/ios:features", "//components/unified_consent", "//components/variations", "//ios/chrome/app/strings:ios_strings",
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 143ec3d..59fb8d4b 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -55,7 +55,6 @@ #include "components/sync/base/sync_base_switches.h" #include "components/sync/driver/sync_driver_switches.h" #include "components/translate/core/browser/translate_prefs.h" -#include "components/ukm/ios/features.h" #include "ios/chrome/browser/browsing_data/browsing_data_features.h" #include "ios/chrome/browser/chrome_switches.h" #include "ios/chrome/browser/crash_report/features.h" @@ -469,9 +468,6 @@ {"settings-refresh", flag_descriptions::kSettingsRefreshName, flag_descriptions::kSettingsRefreshDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kSettingsRefresh)}, - {"send-uma-cellular", flag_descriptions::kSendUmaOverAnyNetwork, - flag_descriptions::kSendUmaOverAnyNetworkDescription, flags_ui::kOsIos, - FEATURE_VALUE_TYPE(kUmaCellular)}, {"autofill-use-mobile-label-disambiguation", flag_descriptions::kAutofillUseMobileLabelDisambiguationName, flag_descriptions::kAutofillUseMobileLabelDisambiguationDescription,
diff --git a/ios/chrome/browser/ios_chrome_main_parts.mm b/ios/chrome/browser/ios_chrome_main_parts.mm index cb75d999..d1223f41 100644 --- a/ios/chrome/browser/ios_chrome_main_parts.mm +++ b/ios/chrome/browser/ios_chrome_main_parts.mm
@@ -34,7 +34,6 @@ #include "components/prefs/json_pref_store.h" #include "components/prefs/pref_service.h" #include "components/translate/core/browser/translate_download_manager.h" -#include "components/ukm/ios/features.h" #include "components/variations/field_trial_config/field_trial_util.h" #include "components/variations/service/variations_service.h" #include "components/variations/synthetic_trials_active_group_id_provider.h" @@ -106,12 +105,6 @@ } #endif -// If enabled, always pass |true| to MetricsServicesManager -// UpdateUploadPermissions. Once impact of the UmaCellular logic to check -// cellular is determined, this flag and the incorrect logic can be removed. -const base::Feature kFixUmaCellularMetricsRecording{ - "FixUmaCellularMetricsRecording", base::FEATURE_DISABLED_BY_DEFAULT}; - } // namespace IOSChromeMainParts::IOSChromeMainParts( @@ -381,25 +374,6 @@ } void IOSChromeMainParts::StartMetricsRecording() { - bool isConnectionCellular = net::NetworkChangeNotifier::IsConnectionCellular( - net::NetworkChangeNotifier::GetConnectionType()); - bool mayUpload = false; - if (base::FeatureList::IsEnabled(kUmaCellular)) { - if (base::FeatureList::IsEnabled(kFixUmaCellularMetricsRecording)) { - mayUpload = true; - } else { - // This is wrong and should be removed, but the fix is gated by the - // feature flag above to measure impact. - mayUpload = !isConnectionCellular; - } - } else { - // TODO(crbug.com/1179809): Now that kUmaCellular is default, all references - // to kUmaCellular and kMetricsReportingWifiOnly should be removed, but only - // after a study of kFixUmaCellularMetricsRecording is completed. - bool wifiOnly = local_state_->GetBoolean(prefs::kMetricsReportingWifiOnly); - mayUpload = !wifiOnly || !isConnectionCellular; - } - application_context_->GetMetricsServicesManager()->UpdateUploadPermissions( - mayUpload); + true); }
diff --git a/ios/chrome/browser/metrics/user_interface_style_recorder.h b/ios/chrome/browser/metrics/user_interface_style_recorder.h index 1accf692..039626d 100644 --- a/ios/chrome/browser/metrics/user_interface_style_recorder.h +++ b/ios/chrome/browser/metrics/user_interface_style_recorder.h
@@ -8,7 +8,6 @@ #import <UIKit/UIKit.h> // Reports metrics for the user interface style on iOS 13+. -API_AVAILABLE(ios(13.0)) @interface UserInterfaceStyleRecorder : NSObject - (instancetype)initWithUserInterfaceStyle:(UIUserInterfaceStyle)style
diff --git a/ios/chrome/browser/omaha/omaha_service.mm b/ios/chrome/browser/omaha/omaha_service.mm index 0840fde2..3152e20 100644 --- a/ios/chrome/browser/omaha/omaha_service.mm +++ b/ios/chrome/browser/omaha/omaha_service.mm
@@ -552,6 +552,7 @@ xml_wrapper.WriteAttribute("version", versionName.c_str()); xml_wrapper.WriteAttribute("nextversion", ""); } + xml_wrapper.WriteAttribute("ap", channelName.c_str()); xml_wrapper.WriteAttribute("lang", locale_lang_.c_str()); xml_wrapper.WriteAttribute("brand", provider->GetBrandCode().c_str()); xml_wrapper.WriteAttribute("client", ""); @@ -584,7 +585,6 @@ } else { // Set up <updatecheck/> xml_wrapper.StartElement("updatecheck"); - xml_wrapper.WriteAttribute("tag", channelName.c_str()); xml_wrapper.EndElement(); // Set up <ping active=1/>
diff --git a/ios/chrome/browser/omaha/omaha_service_unittest.mm b/ios/chrome/browser/omaha/omaha_service_unittest.mm index 7a22d104..97e5cdb 100644 --- a/ios/chrome/browser/omaha/omaha_service_unittest.mm +++ b/ios/chrome/browser/omaha/omaha_service_unittest.mm
@@ -138,10 +138,10 @@ " sessionid=\"sessionId\" hardware_class=\"[^\"]*\">" "<os platform=\"ios\" version=\"[0-9][0-9]*\\(\\.[0-9][0-9]*\\)*\"" " arch=\"[^\"]*\"/>" - "<app version=\"[^\"]*\" nextversion=\"\" lang=\"[^\"]*\"" + "<app version=\"[^\"]*\" nextversion=\"\" ap=\"[^\"]*\" lang=\"[^\"]*\"" " brand=\"[A-Z][A-Z][A-Z][A-Z]\" client=\"\" appid=\"{[^}]*}\"" " installage=\"0\">" - "<updatecheck tag=\"[^\"]*\"/>" + "<updatecheck/>" "<ping active=\"1\" ad=\"-2\" rd=\"-2\"/></app></request>"; OmahaService service(false); @@ -167,9 +167,9 @@ " sessionid=\"sessionId\" hardware_class=\"[^\"]*\">" "<os platform=\"ios\" version=\"[0-9][0-9]*\\(\\.[0-9][0-9]*\\)*\"" " arch=\"[^\"]*\"/>" - "<app version=\"[^\"]*\" nextversion=\"\" lang=\"[^\"]*\"" + "<app version=\"[^\"]*\" nextversion=\"\" ap=\"[^\"]*\" lang=\"[^\"]*\"" " brand=\"[A-Z][A-Z][A-Z][A-Z]\" client=\"\" appid=\"{[^}]*}\">" - "<updatecheck tag=\"[^\"]*\"/>" + "<updatecheck/>" "<ping active=\"1\" ad=\"-2\" rd=\"-2\"/></app></request>"; OmahaService service(false); @@ -197,7 +197,7 @@ " sessionid=\"sessionId\" hardware_class=\"[^\"]*\">" "<os platform=\"ios\" version=\"[0-9][0-9]*(\\.[0-9][0-9]*)*\"" " arch=\"[^\"]*\"/>" - "<app version=\"%s\" nextversion=\"[^\"]*\" lang=\"[^\"]*\"" + "<app version=\"%s\" nextversion=\"[^\"]*\" ap=\"[^\"]*\" lang=\"[^\"]*\"" " brand=\"[A-Z][A-Z][A-Z][A-Z]\" client=\"\" appid=\"{[^}]*}\"" " installage=\"%d\">" "<event eventtype=\"%d\" eventresult=\"1\"/>" @@ -546,9 +546,9 @@ " sessionid=\"sessionId\" hardware_class=\"[^\"]*\">" "<os platform=\"ios\" version=\"[0-9][0-9]*\\(\\.[0-9][0-9]*\\)*\"" " arch=\"[^\"]*\"/>" - "<app version=\"[^\"]*\" nextversion=\"\" lang=\"[^\"]*\"" + "<app version=\"[^\"]*\" nextversion=\"\" ap=\"[^\"]*\" lang=\"[^\"]*\"" " brand=\"[A-Z][A-Z][A-Z][A-Z]\" client=\"\" appid=\"{[^}]*}\">" - "<updatecheck tag=\"[^\"]*\"/>" + "<updatecheck/>" "<ping active=\"1\" ad=\"4088\" rd=\"4088\"/></app></request>"; std::string content = service.GetPingContent(
diff --git a/ios/chrome/browser/pref_names.cc b/ios/chrome/browser/pref_names.cc index c815c6e..fe39cfd 100644 --- a/ios/chrome/browser/pref_names.cc +++ b/ios/chrome/browser/pref_names.cc
@@ -106,11 +106,6 @@ const char kNTPContentSuggestionsEnabled[] = "ios.ntp.content_suggestions_enabled"; -// Preference that hold a boolean indicating whether metrics reporting should -// be limited to wifi (when enabled). -const char kMetricsReportingWifiOnly[] = - "ios.user_experience_metrics.wifi_only"; - // Boolean that is true when Suggest support is enabled. const char kSearchSuggestEnabled[] = "search.suggest_enabled";
diff --git a/ios/chrome/browser/pref_names.h b/ios/chrome/browser/pref_names.h index 9172635..73b3cea 100644 --- a/ios/chrome/browser/pref_names.h +++ b/ios/chrome/browser/pref_names.h
@@ -31,7 +31,6 @@ extern const char kIosSettingsSigninPromoDisplayedCount[]; extern const char kLastSessionExitedCleanly[]; extern const char kNTPContentSuggestionsEnabled[]; -extern const char kMetricsReportingWifiOnly[]; extern const char kPrintingEnabled[]; extern const char kSearchSuggestEnabled[];
diff --git a/ios/chrome/browser/prefs/BUILD.gn b/ios/chrome/browser/prefs/BUILD.gn index d86bdaa9..89efb1f 100644 --- a/ios/chrome/browser/prefs/BUILD.gn +++ b/ios/chrome/browser/prefs/BUILD.gn
@@ -66,7 +66,6 @@ "//components/sync_sessions", "//components/translate/core/browser", "//components/translate/core/common", - "//components/ukm/ios:features", "//components/unified_consent", "//components/update_client", "//components/variations/service",
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm index d2a5d8b..b74ff8d5 100644 --- a/ios/chrome/browser/prefs/browser_prefs.mm +++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -49,7 +49,6 @@ #include "components/sync_sessions/session_sync_prefs.h" #include "components/translate/core/browser/translate_pref_names.h" #include "components/translate/core/browser/translate_prefs.h" -#include "components/ukm/ios/features.h" #include "components/unified_consent/unified_consent_service.h" #include "components/update_client/update_client.h" #include "components/variations/service/variations_service.h" @@ -102,19 +101,23 @@ // Deprecated 9/2020 const char kPasswordManagerOnboardingState[] = "profile.password_manager_onboarding_state"; - const char kWasOnboardingFeatureCheckedBefore[] = "profile.was_pwm_onboarding_feature_checked_before"; +// Deprecated 12/2020 +const char kDomainsWithCookiePref[] = "signin.domains_with_cookie"; + // Deprecated 03/2021 const char kOmniboxGeolocationAuthorizationState[] = "ios.omnibox.geolocation_authorization_state"; const char kOmniboxGeolocationLastAuthorizationAlertVersion[] = "ios.omnibox.geolocation_last_authorization_alert_version"; -} -// Deprecated 12/2020 -const char kDomainsWithCookiePref[] = "signin.domains_with_cookie"; +// Deprecated 07/2021 +const char kMetricsReportingWifiOnly[] = + "ios.user_experience_metrics.wifi_only"; + +} void RegisterLocalStatePrefs(PrefRegistrySimple* registry) { BrowserStateInfoCache::RegisterPrefs(registry); @@ -152,10 +155,7 @@ registry->RegisterBooleanPref(metrics::prefs::kMetricsReportingEnabled, false); registry->RegisterBooleanPref(prefs::kLastSessionExitedCleanly, true); - if (!base::FeatureList::IsEnabled(kUmaCellular)) { - registry->RegisterBooleanPref(prefs::kMetricsReportingWifiOnly, true); - } - + registry->RegisterBooleanPref(kMetricsReportingWifiOnly, true); registry->RegisterBooleanPref(kGCMChannelStatus, true); registry->RegisterIntegerPref(kGCMChannelPollIntervalSeconds, 0); registry->RegisterInt64Pref(kGCMChannelLastCheckTime, 0); @@ -281,6 +281,9 @@ // Added 2021/03. prefs->ClearPref(kOmniboxGeolocationAuthorizationState); prefs->ClearPref(kOmniboxGeolocationLastAuthorizationAlertVersion); + + // Added 7/2021 + prefs->ClearPref(kMetricsReportingWifiOnly); } // This method should be periodically pruned of year+ old migrations.
diff --git a/ios/chrome/browser/signin/gaia_auth_fetcher_ios_ns_url_session_bridge_unittests.mm b/ios/chrome/browser/signin/gaia_auth_fetcher_ios_ns_url_session_bridge_unittests.mm index edf5087d..0260fe1 100644 --- a/ios/chrome/browser/signin/gaia_auth_fetcher_ios_ns_url_session_bridge_unittests.mm +++ b/ios/chrome/browser/signin/gaia_auth_fetcher_ios_ns_url_session_bridge_unittests.mm
@@ -376,11 +376,6 @@ // Tests to send a request with no cookies set in the cookie store and receive // multiples cookies from the request. TEST_F(GaiaAuthFetcherIOSNSURLSessionBridgeTest, FetchWithEmptyCookieStore) { - // TODO(crbug.com/1106030): expected_cookies_set is failing on iOS12. - if (!base::ios::IsRunningOnIOS13OrLater()) { - return; - } - ASSERT_FALSE(url_session_configuration_.HTTPCookieStorage.cookies.count); ASSERT_TRUE(FetchURL(GetFetchGURL())); ASSERT_TRUE(completion_handler_); @@ -400,11 +395,6 @@ // Tests to send a request with one cookie set in the cookie store and receive // another cookies from the request. TEST_F(GaiaAuthFetcherIOSNSURLSessionBridgeTest, FetchWithCookieStore) { - // TODO(crbug.com/1106030): expected_cookies_set is failing on iOS12. - if (!base::ios::IsRunningOnIOS13OrLater()) { - return; - } - NSArray* cookies_to_send = @[ GetCookie1() ]; ASSERT_TRUE(SetCookiesInCookieManager(cookies_to_send)); @@ -427,11 +417,6 @@ // Tests to a request with a redirect. One cookie is received by the first // request, and a second one by the redirected request. TEST_F(GaiaAuthFetcherIOSNSURLSessionBridgeTest, FetchWithRedirect) { - // TODO(crbug.com/1106030): expected_cookies_set is failing on iOS12. - if (!base::ios::IsRunningOnIOS13OrLater()) { - return; - } - ASSERT_TRUE(FetchURL(GetFetchGURL())); ASSERT_FALSE(url_session_configuration_.HTTPCookieStorage.cookies.count); ASSERT_TRUE(completion_handler_);
diff --git a/ios/chrome/browser/ui/activity_services/activity_service_controller_egtest.mm b/ios/chrome/browser/ui/activity_services/activity_service_controller_egtest.mm index 6b6c97e..b36d202a 100644 --- a/ios/chrome/browser/ui/activity_services/activity_service_controller_egtest.mm +++ b/ios/chrome/browser/ui/activity_services/activity_service_controller_egtest.mm
@@ -54,26 +54,7 @@ @implementation ActivityServiceControllerTestCase -- (void)testActivityServiceControllerIsDisabled { - // TODO(crbug.com/996541) Starting in Xcode 11 beta 6, the share button does - // not appear (even with a delay) flakily. - if (@available(iOS 13, *)) - EARL_GREY_TEST_DISABLED(@"Test disabled on iOS13."); - - // Open an un-shareable page. - GURL kURL("chrome://version"); - [ChromeEarlGrey loadURL:kURL]; - // Verify that the share button is disabled. - id<GREYMatcher> share_button = chrome_test_util::TabShareButton(); - [[EarlGrey selectElementWithMatcher:share_button] - assertWithMatcher:grey_accessibilityTrait( - UIAccessibilityTraitNotEnabled)]; -} - - (void)testOpenActivityServiceControllerAndCopy { - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Test disabled on iOS12."); - } // Set up mock http server. std::map<GURL, std::string> responses; GURL url = web::test::HttpServer::MakeUrl("http://potato");
diff --git a/ios/chrome/browser/ui/activity_services/data/chrome_activity_image_source.mm b/ios/chrome/browser/ui/activity_services/data/chrome_activity_image_source.mm index 6baf01c..486fdb8 100644 --- a/ios/chrome/browser/ui/activity_services/data/chrome_activity_image_source.mm +++ b/ios/chrome/browser/ui/activity_services/data/chrome_activity_image_source.mm
@@ -60,7 +60,7 @@ } - (LPLinkMetadata*)activityViewControllerLinkMetadata: - (UIActivityViewController*)activityViewController API_AVAILABLE(ios(13.0)) { + (UIActivityViewController*)activityViewController { NSItemProvider* imageProvider = [[NSItemProvider alloc] initWithObject:self.image];
diff --git a/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_egtest.mm b/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_egtest.mm index 980d7e2..a2721d0 100644 --- a/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_egtest.mm +++ b/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_egtest.mm
@@ -221,9 +221,6 @@ // Verifies that advanced sign-in shows an alert dialog when being swiped to // dismiss. - (void)testSwipeDownToCancelAdvancedSignin { - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower."); - } FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1]; [SigninEarlGrey addFakeIdentity:fakeIdentity];
diff --git a/ios/chrome/browser/ui/authentication/signin/signin_coordinator.mm b/ios/chrome/browser/ui/authentication/signin/signin_coordinator.mm index 286f166..6b7d569a 100644 --- a/ios/chrome/browser/ui/authentication/signin/signin_coordinator.mm +++ b/ios/chrome/browser/ui/authentication/signin/signin_coordinator.mm
@@ -191,6 +191,11 @@ } - (void)stop { + // If you are an user of a SigninCoordinator subclass: + // The sign-in view is still presented. You should not call |stop|, if you + // need to close the view. You need to call -[SigninCoordinator + // interruptWithAction:completion:]. + // If you work on a SigninCoordinator subclass: // -[SigninCoordinator runCompletionCallbackWithSigninResult:completionInfo:] // has to be called by the subclass before // -[SigninCoordinator stop] is called.
diff --git a/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm b/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm index 044b795c..b48ccb4 100644 --- a/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm +++ b/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm
@@ -394,9 +394,6 @@ // Verifies that advanced sign-in shows an alert dialog when being swiped to // dismiss. - (void)testSwipeDownToCancelAdvancedSignin { - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower."); - } FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1]; [SigninEarlGrey addFakeIdentity:fakeIdentity]; [self openSigninFromView:OpenSigninMethodFromSettings tapSettingsLink:YES];
diff --git a/ios/chrome/browser/ui/authentication/signin/signin_coordinator_mice_egtest.mm b/ios/chrome/browser/ui/authentication/signin/signin_coordinator_mice_egtest.mm index 7667d82..6f5b364d 100644 --- a/ios/chrome/browser/ui/authentication/signin/signin_coordinator_mice_egtest.mm +++ b/ios/chrome/browser/ui/authentication/signin/signin_coordinator_mice_egtest.mm
@@ -102,8 +102,7 @@ // Tests that opening the sign-in screen from the Sync Off tab and signin in // will turn Sync On. -// TODO(crbug.com/1227847) - fix and re-enable -- (void)DISABLED_testSignInFromSyncOffLink { +- (void)testSignInFromSyncOffLink { FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1]; [SigninEarlGrey addFakeIdentity:fakeIdentity]; @@ -120,12 +119,7 @@ kSettingsGoogleSyncAndServicesCellId), nil)] performAction:grey_tap()]; - // If the consent screen was previously scrolled it will not need to be - // scrolled again. - [[EarlGrey - selectElementWithMatcher:ButtonWithAccessibilityLabelId( - IDS_IOS_ACCOUNT_UNIFIED_CONSENT_OK_BUTTON)] - performAction:grey_tap()]; + [SigninEarlGreyUI tapSigninConfirmationDialog]; // Check Sync On label is visible and user is signed in. [SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity];
diff --git a/ios/chrome/browser/ui/authentication/signin_earl_grey_ui.h b/ios/chrome/browser/ui/authentication/signin_earl_grey_ui.h index f54caef..7104712d 100644 --- a/ios/chrome/browser/ui/authentication/signin_earl_grey_ui.h +++ b/ios/chrome/browser/ui/authentication/signin_earl_grey_ui.h
@@ -74,6 +74,9 @@ + (void)openRemoveAccountConfirmationDialogWithFakeIdentity: (FakeChromeIdentity*)fakeIdentity; +// Opens MyGoogle UI from the account list settings. ++ (void)openMyGoogleDialogWithFakeIdentity:(FakeChromeIdentity*)fakeIdentity; + // Taps "Remove account from this device" button and follow-up confirmation. // Assumes the user is on the Settings screen. + (void)tapRemoveAccountFromDeviceWithFakeIdentity:
diff --git a/ios/chrome/browser/ui/authentication/signin_earl_grey_ui.mm b/ios/chrome/browser/ui/authentication/signin_earl_grey_ui.mm index 491b689..ca05808 100644 --- a/ios/chrome/browser/ui/authentication/signin_earl_grey_ui.mm +++ b/ios/chrome/browser/ui/authentication/signin_earl_grey_ui.mm
@@ -253,6 +253,17 @@ performAction:grey_tap()]; } ++ (void)openMyGoogleDialogWithFakeIdentity:(FakeChromeIdentity*)fakeIdentity { + [[EarlGrey selectElementWithMatcher:ButtonWithAccessibilityLabel( + fakeIdentity.userEmail)] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher: + ButtonWithAccessibilityLabel(l10n_util::GetNSString( + IDS_IOS_MANAGE_YOUR_GOOGLE_ACCOUNT_TITLE))] + performAction:grey_tap()]; + [ChromeEarlGreyUI waitForAppToIdle]; +} + + (void)tapRemoveAccountFromDeviceWithFakeIdentity: (FakeChromeIdentity*)fakeIdentity { [self openRemoveAccountConfirmationDialogWithFakeIdentity:fakeIdentity];
diff --git a/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator.mm b/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator.mm index e220d01..5f05c13 100644 --- a/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator.mm +++ b/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator.mm
@@ -139,15 +139,15 @@ [self.actionSheetCoordinator addItemWithTitle:l10n_util::GetNSString(IDS_CANCEL) action:^{ - if (weakSelf) { + if (weakSelf) weakSelf.completion(NO); - } } style:UIAlertActionStyleCancel]; [self.actionSheetCoordinator start]; } - (void)stop { + [self.actionSheetCoordinator stop]; self.actionSheetCoordinator = nil; }
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm index a8b86d63..f4541ce 100644 --- a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm
@@ -4,6 +4,8 @@ #import "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.h" +#include <ostream> + #include "base/check_op.h" #include "base/ios/ns_range.h" #include "components/google/core/common/google_util.h"
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.mm b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.mm index 6a7e81cd..708bacd 100644 --- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.mm +++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.mm
@@ -220,7 +220,7 @@ // On iOS 13, beta 3, the popover is not dismissed when the keyboard hides. // This explicitly dismiss any popover. // TODO(crbug.com/1116037): Verify if this workaround is still needed. - if (base::ios::IsRunningOnIOS13OrLater() && IsIPadIdiom()) { + if (IsIPadIdiom()) { [self reset]; } }
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_ui.mm b/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_ui.mm index 724621b..c501f5c 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_ui.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_ui.mm
@@ -61,7 +61,7 @@ // Making sure the edit button we're selecting is not on the bottom bar via // exclusion by accessibility ID and ancestry. return grey_allOf( - EditButton([ChromeEarlGrey isNativeContextMenusEnabled]), + EditButton(), grey_not(grey_accessibilityID(kBookmarkHomeTrailingButtonIdentifier)), grey_not(grey_ancestor( grey_accessibilityID(kBookmarkHomeTrailingButtonIdentifier))), @@ -260,63 +260,43 @@ } - (void)verifyContextMenuForSingleURLWithEditEnabled:(BOOL)editEnabled { - if ([ChromeEarlGrey isNativeContextMenusEnabled]) { - [[EarlGrey selectElementWithMatcher:OpenLinkInNewTabButton()] - assertWithMatcher:grey_sufficientlyVisible()]; - [[EarlGrey selectElementWithMatcher:OpenLinkInIncognitoButton(YES)] - assertWithMatcher:grey_sufficientlyVisible()]; - [[EarlGrey selectElementWithMatcher:CopyLinkButton(YES)] - assertWithMatcher:grey_sufficientlyVisible()]; - [[EarlGrey selectElementWithMatcher:ShareButton()] - assertWithMatcher:grey_sufficientlyVisible()]; + [[EarlGrey selectElementWithMatcher:OpenLinkInNewTabButton()] + assertWithMatcher:grey_sufficientlyVisible()]; + [[EarlGrey selectElementWithMatcher:OpenLinkInIncognitoButton()] + assertWithMatcher:grey_sufficientlyVisible()]; + [[EarlGrey selectElementWithMatcher:CopyLinkButton()] + assertWithMatcher:grey_sufficientlyVisible()]; + [[EarlGrey selectElementWithMatcher:ShareButton()] + assertWithMatcher:grey_sufficientlyVisible()]; - // Some actions need to be disabled when users cannot edit a given bookmark. - id<GREYMatcher> matcher = - editEnabled ? grey_sufficientlyVisible() - : grey_accessibilityTrait(UIAccessibilityTraitNotEnabled); - [[EarlGrey selectElementWithMatcher:chrome_test_util:: - BookmarksContextMenuEditButton()] - assertWithMatcher:matcher]; - [[EarlGrey selectElementWithMatcher:DeleteButton()] - assertWithMatcher:matcher]; - - return; - } - - // Action Sheets are used as context menus on iOS 12. - [self verifyActionSheetsForSingleURLWithEditEnabled:editEnabled]; + // Some actions need to be disabled when users cannot edit a given bookmark. + id<GREYMatcher> matcher = + editEnabled ? grey_sufficientlyVisible() + : grey_accessibilityTrait(UIAccessibilityTraitNotEnabled); + [[EarlGrey selectElementWithMatcher:chrome_test_util:: + BookmarksContextMenuEditButton()] + assertWithMatcher:matcher]; + [[EarlGrey selectElementWithMatcher:DeleteButton()] + assertWithMatcher:matcher]; } - (void)verifyContextMenuForSingleFolderWithEditEnabled:(BOOL)editEnabled { - if ([ChromeEarlGrey isNativeContextMenusEnabled]) { - // Edit and Move need to be disabled when users cannot edit a given - // bookmark. - id<GREYMatcher> matcher = - editEnabled ? grey_sufficientlyVisible() - : grey_accessibilityTrait(UIAccessibilityTraitNotEnabled); - [[EarlGrey selectElementWithMatcher:chrome_test_util:: - BookmarksContextMenuEditButton()] - assertWithMatcher:matcher]; - [[EarlGrey selectElementWithMatcher:MoveButton()] - assertWithMatcher:matcher]; - return; - } - - // Action Sheets are used as context menus on iOS 12. - [self verifyActionSheetsForSingleFolderWithEditEnabled:editEnabled]; + // Edit and Move need to be disabled when users cannot edit a given + // bookmark. + id<GREYMatcher> matcher = + editEnabled ? grey_sufficientlyVisible() + : grey_accessibilityTrait(UIAccessibilityTraitNotEnabled); + [[EarlGrey selectElementWithMatcher:chrome_test_util:: + BookmarksContextMenuEditButton()] + assertWithMatcher:matcher]; + [[EarlGrey selectElementWithMatcher:MoveButton()] assertWithMatcher:matcher]; } - (void)dismissContextMenu { - if ([ChromeEarlGrey isNativeContextMenusEnabled]) { - // Since there are is no cancel action on the iOS 13 context menus, dismiss - // by tapping elsewhere (on the key window). - [[EarlGrey selectElementWithMatcher:grey_keyWindow()] - performAction:grey_tap()]; - return; - } - - // Action Sheets are used as context menus on iOS 12. - [self dismissActionSheets]; + // Since there are is no cancel action on the iOS 13 context menus, dismiss + // by tapping elsewhere (on the key window). + [[EarlGrey selectElementWithMatcher:grey_keyWindow()] + performAction:grey_tap()]; } - (void)verifyActionSheetsForSingleURLWithEditEnabled:(BOOL)editEnabled {
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm index 0a0624b8..7e54456a 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
@@ -69,7 +69,6 @@ #import "ios/chrome/browser/ui/table_view/table_view_utils.h" #import "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" -#import "ios/chrome/browser/ui/util/menu_util.h" #import "ios/chrome/browser/ui/util/rtl_geometry.h" #import "ios/chrome/browser/ui/util/ui_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" @@ -525,16 +524,6 @@ self.tableView.sectionFooterHeight = 1; self.sharedState.tableView.allowsMultipleSelectionDuringEditing = YES; - if (!IsNativeContextMenuEnabled()) { - UILongPressGestureRecognizer* longPressRecognizer = - [[UILongPressGestureRecognizer alloc] - initWithTarget:self - action:@selector(handleLongPress:)]; - longPressRecognizer.numberOfTouchesRequired = 1; - longPressRecognizer.delegate = self; - [self.sharedState.tableView addGestureRecognizer:longPressRecognizer]; - } - // Create the mediator and hook up the table view. self.mediator = [[BookmarkHomeMediator alloc] initWithSharedState:self.sharedState @@ -2313,14 +2302,7 @@ - (UIContextMenuConfiguration*)tableView:(UITableView*)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath*)indexPath - point:(CGPoint)point - API_AVAILABLE(ios(13.0)) { - if (!IsNativeContextMenuEnabled()) { - // Returning nil will allow the gesture to be captured and show the old - // context menus. - return nil; - } - + point:(CGPoint)point { if (self.sharedState.currentlyInEditMode) { // Don't show the context menu when currently in editing mode. return nil;
diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_accessibility_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_accessibility_egtest.mm index 7e4f8d51..7ca00e7 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmarks_accessibility_egtest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmarks_accessibility_egtest.mm
@@ -78,10 +78,7 @@ performAction:grey_longPress()]; id<GREYMatcher> editFolderMatcher = - [ChromeEarlGrey isNativeContextMenusEnabled] - ? chrome_test_util::BookmarksContextMenuEditButton() - : ButtonWithAccessibilityLabelId( - IDS_IOS_BOOKMARK_CONTEXT_MENU_EDIT_FOLDER); + chrome_test_util::BookmarksContextMenuEditButton(); [[EarlGrey selectElementWithMatcher:editFolderMatcher] performAction:grey_tap()];
diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm index 124d5497..e1a5f2c9 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm
@@ -785,9 +785,6 @@ } - (void)testSwipeDownToDismiss { - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower."); - } if (!IsCollectionsCardPresentationStyleEnabled()) { EARL_GREY_TEST_SKIPPED(@"Test disabled on when feature flag is off."); }
diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_entries_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_entries_egtest.mm index d8f7841..f075765 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmarks_entries_egtest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmarks_entries_egtest.mm
@@ -207,11 +207,6 @@ // Verify Edit Text functionality on single URL selection. - (void)testEditTextOnSingleURL { - // TODO(crbug.com/1049972): Re-enable on iOS 12. - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"EG1 Fails on iOS 12."); - } - [BookmarkEarlGrey setupStandardBookmarks]; [BookmarkEarlGreyUI openBookmarks]; [BookmarkEarlGreyUI openMobileBookmarks]; @@ -557,11 +552,9 @@ // Open a bookmark in an incognito tab from a normal session (through a long // press). - BOOL newMenusEnabled = [ChromeEarlGrey isNativeContextMenusEnabled]; [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"French URL")] performAction:grey_longPress()]; - [[EarlGrey - selectElementWithMatcher:OpenLinkInIncognitoButton(newMenusEnabled)] + [[EarlGrey selectElementWithMatcher:OpenLinkInIncognitoButton()] performAction:grey_tap()]; // Verify there is 1 incognito tab created and no new normal tab created. @@ -603,8 +596,7 @@ // long press). [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Second URL")] performAction:grey_longPress()]; - [[EarlGrey - selectElementWithMatcher:OpenLinkInIncognitoButton(newMenusEnabled)] + [[EarlGrey selectElementWithMatcher:OpenLinkInIncognitoButton()] performAction:grey_tap()]; // Verify a new incognito tab is created. @@ -1042,9 +1034,6 @@ } - (void)testSwipeDownToDismissFromPushedVC { - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower."); - } if (!IsCollectionsCardPresentationStyleEnabled()) { EARL_GREY_TEST_SKIPPED(@"Test disabled on when feature flag is off."); }
diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_folders_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_folders_egtest.mm index 4588f9d4..507c7372c 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmarks_folders_egtest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmarks_folders_egtest.mm
@@ -266,9 +266,6 @@ } - (void)testSwipeDownToDismissFromEditFolder { - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower."); - } if (!IsCollectionsCardPresentationStyleEnabled()) { EARL_GREY_TEST_SKIPPED(@"Test disabled on when feature flag is off."); } @@ -383,19 +380,11 @@ @"Mobile Bookmarks")] performAction:grey_longPress()]; - // Verify it doesn't show the context menu. (long press is disabled on - // permanent node.) - if ([ChromeEarlGrey isNativeContextMenusEnabled]) { - // We cannot locate new context menus any way, therefore we'll use the - // 'Edit' action presence as proxy. - [[EarlGrey selectElementWithMatcher:chrome_test_util:: - BookmarksContextMenuEditButton()] - assertWithMatcher:grey_nil()]; - } else { - [[EarlGrey selectElementWithMatcher:grey_accessibilityID( - kBookmarkHomeContextMenuIdentifier)] - assertWithMatcher:grey_nil()]; - } + // We cannot locate new context menus any way, therefore we'll use the + // 'Edit' action presence as proxy. + [[EarlGrey selectElementWithMatcher:chrome_test_util:: + BookmarksContextMenuEditButton()] + assertWithMatcher:grey_nil()]; } // Verify Edit functionality for single folder selection. @@ -412,10 +401,7 @@ performAction:grey_longPress()]; id<GREYMatcher> editFolderMatcher = - [ChromeEarlGrey isNativeContextMenusEnabled] - ? chrome_test_util::BookmarksContextMenuEditButton() - : ButtonWithAccessibilityLabelId( - IDS_IOS_BOOKMARK_CONTEXT_MENU_EDIT_FOLDER); + chrome_test_util::BookmarksContextMenuEditButton(); [[EarlGrey selectElementWithMatcher:editFolderMatcher] performAction:grey_tap()];
diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_search_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_search_egtest.mm index 2dd949f..92cdb9a 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmarks_search_egtest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmarks_search_egtest.mm
@@ -388,10 +388,7 @@ performAction:grey_longPress()]; id<GREYMatcher> editFolderAction = - [ChromeEarlGrey isNativeContextMenusEnabled] - ? chrome_test_util::BookmarksContextMenuEditButton() - : ButtonWithAccessibilityLabelId( - IDS_IOS_BOOKMARK_CONTEXT_MENU_EDIT_FOLDER); + chrome_test_util::BookmarksContextMenuEditButton(); [[EarlGrey selectElementWithMatcher:editFolderAction] performAction:grey_tap()];
diff --git a/ios/chrome/browser/ui/bookmarks/managed_bookmarks_egtest.mm b/ios/chrome/browser/ui/bookmarks/managed_bookmarks_egtest.mm index 66ace934..1b3c880a 100644 --- a/ios/chrome/browser/ui/bookmarks/managed_bookmarks_egtest.mm +++ b/ios/chrome/browser/ui/bookmarks/managed_bookmarks_egtest.mm
@@ -323,11 +323,6 @@ // Tests that swipe is disabled in managed bookmarks top-level folder and // sub-folder. - (void)testSwipeDisabled { - // TODO(crbug.com/1070676): Earl grey swipe fails on iOS 12. - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Fails on iOS 12."); - } - [BookmarkEarlGreyUI openBookmarks]; [self openCustomManagedBookmarksFolder]; @@ -353,11 +348,6 @@ // Tests that swiping is disabled on managed bookmark items on search results. - (void)testSwipeDisabledOnSearchResults { - // TODO(crbug.com/1070676): Earl grey swipe fails on iOS 12. - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Fails on iOS 12."); - } - [BookmarkEarlGreyUI openBookmarks]; SearchBookmarksForText(@"URL\n");
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm index e0809c7..6f5bc90 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -3763,9 +3763,8 @@ contextMenuConfigurationForParams:(const web::ContextMenuParams&)params previewProvider: (UIContextMenuContentPreviewProvider)previewProvider - completionHandler: - (void (^)(UIContextMenuConfiguration*))completionHandler - API_AVAILABLE(ios(13.0)) { + completionHandler:(void (^)(UIContextMenuConfiguration*)) + completionHandler { // Prevent context menu from displaying for a tab which is no longer the // current one. if (webState != self.currentWebState) {
diff --git a/ios/chrome/browser/ui/commands/command_dispatcher.mm b/ios/chrome/browser/ui/commands/command_dispatcher.mm index df679270..a5776ea 100644 --- a/ios/chrome/browser/ui/commands/command_dispatcher.mm +++ b/ios/chrome/browser/ui/commands/command_dispatcher.mm
@@ -5,6 +5,8 @@ #import "ios/chrome/browser/ui/commands/command_dispatcher.h" #include <objc/runtime.h> + +#include <ostream> #include <unordered_map> #include <vector>
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 b5be214f..41a6b30 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
@@ -684,8 +684,7 @@ - (UIContextMenuConfiguration*)contextMenuConfigurationForItem: (ContentSuggestionsMostVisitedItem*)item - fromView:(UIView*)view - API_AVAILABLE(ios(13.0)) { + fromView:(UIView*)view { __weak __typeof(self) weakSelf = self; UIContextMenuActionProvider actionProvider =
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm index 7d13011..c510a33 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm
@@ -316,9 +316,7 @@ // Open in new incognito tab. [[EarlGrey - selectElementWithMatcher:chrome_test_util::OpenLinkInIncognitoButton( - [ChromeEarlGrey - isNativeContextMenusEnabled])] + selectElementWithMatcher:chrome_test_util::OpenLinkInIncognitoButton()] performAction:grey_tap()]; [ChromeEarlGrey waitForMainTabCount:1]; @@ -400,16 +398,6 @@ selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( IDS_IOS_CONTENT_CONTEXT_ADDTOREADINGLIST)] assertWithMatcher:grey_nil()]; - - if ([ChromeEarlGrey isNativeContextMenusEnabled]) { - // iOS 13 Context Menus don't have a Cancel action. - return; - } - if (![ChromeEarlGrey isRegularXRegularSizeClass]) { - [[EarlGrey selectElementWithMatcher: - chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_APP_CANCEL)] assertWithMatcher:grey_interactable()]; - } } #pragma mark - Test utils
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_menu_provider.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_menu_provider.h index fa610d9..42396094 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_menu_provider.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_menu_provider.h
@@ -15,8 +15,7 @@ // represented on the UI by |view|. - (UIContextMenuConfiguration*)contextMenuConfigurationForItem: (ContentSuggestionsMostVisitedItem*)item - fromView:(UIView*)view - API_AVAILABLE(ios(13.0)); + fromView:(UIView*)view; @end
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h index f71fc9c..3eb7fcf 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h
@@ -83,8 +83,7 @@ // Delegate for handling actions relating to content suggestions. @property(nonatomic, weak) id<ContentSuggestionsActionHandler> handler; // Provider of menu configurations for the contentSuggestions component. -@property(nonatomic, weak) id<ContentSuggestionsMenuProvider> menuProvider - API_AVAILABLE(ios(13.0)); +@property(nonatomic, weak) id<ContentSuggestionsMenuProvider> menuProvider; // Discover Feed metrics recorder. @property(nonatomic, strong) DiscoverFeedMetricsRecorder* discoverFeedMetricsRecorder;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm index a04b8f37..7e266af 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -41,7 +41,6 @@ #import "ios/chrome/browser/ui/start_surface/start_surface_features.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_utils.h" #import "ios/chrome/browser/ui/ui_feature_flags.h" -#import "ios/chrome/browser/ui/util/menu_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" @@ -527,14 +526,7 @@ - (UIContextMenuConfiguration*)collectionView:(UICollectionView*)collectionView contextMenuConfigurationForItemAtIndexPath:(NSIndexPath*)indexPath - point:(CGPoint)point - API_AVAILABLE(ios(13.0)) { - if (!IsNativeContextMenuEnabled()) { - // Returning nil will allow the gesture to be captured and show the old - // context menus. - return nil; - } - + point:(CGPoint)point { CollectionViewItem* item = [self.collectionViewModel itemAtIndexPath:indexPath]; @@ -973,12 +965,6 @@ readLaterAction:NO]; break; case ContentSuggestionTypeMostVisited: - if (!IsNativeContextMenuEnabled()) { - [self.suggestionCommandHandler - displayContextMenuForMostVisitedItem:touchedItem - atPoint:touchLocation - atIndexPath:touchedItemIndexPath]; - } break; default: break;
diff --git a/ios/chrome/browser/ui/first_run/welcome_to_chrome_view.mm b/ios/chrome/browser/ui/first_run/welcome_to_chrome_view.mm index d4eb60d..ff6af27 100644 --- a/ios/chrome/browser/ui/first_run/welcome_to_chrome_view.mm +++ b/ios/chrome/browser/ui/first_run/welcome_to_chrome_view.mm
@@ -6,6 +6,8 @@ #import <MaterialComponents/MaterialTypography.h> +#include <ostream> + #include "base/check_op.h" #include "base/i18n/rtl.h" #include "base/ios/ns_range.h"
diff --git a/ios/chrome/browser/ui/history/history_coordinator.mm b/ios/chrome/browser/ui/history/history_coordinator.mm index b7a2a3e..9bd8edc 100644 --- a/ios/chrome/browser/ui/history/history_coordinator.mm +++ b/ios/chrome/browser/ui/history/history_coordinator.mm
@@ -194,8 +194,7 @@ - (UIContextMenuConfiguration*)contextMenuConfigurationForItem: (HistoryEntryItem*)item - withView:(UIView*)view - API_AVAILABLE(ios(13.0)) { + withView:(UIView*)view { __weak id<HistoryEntryItemDelegate> historyItemDelegate = self.historyTableViewController; __weak __typeof(self) weakSelf = self;
diff --git a/ios/chrome/browser/ui/history/history_menu_provider.h b/ios/chrome/browser/ui/history/history_menu_provider.h index b9740e8c..2c9a0b0 100644 --- a/ios/chrome/browser/ui/history/history_menu_provider.h +++ b/ios/chrome/browser/ui/history/history_menu_provider.h
@@ -14,8 +14,7 @@ // represented on the UI by |view|. - (UIContextMenuConfiguration*)contextMenuConfigurationForItem: (HistoryEntryItem*)item - withView:(UIView*)view - API_AVAILABLE(ios(13.0)); + withView:(UIView*)view; @end
diff --git a/ios/chrome/browser/ui/history/history_table_view_controller.mm b/ios/chrome/browser/ui/history/history_table_view_controller.mm index b2a3bcc..eab65fd5 100644 --- a/ios/chrome/browser/ui/history/history_table_view_controller.mm +++ b/ios/chrome/browser/ui/history/history_table_view_controller.mm
@@ -44,7 +44,6 @@ #import "ios/chrome/browser/ui/table_view/table_view_navigation_controller_constants.h" #import "ios/chrome/browser/ui/table_view/table_view_utils.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" -#import "ios/chrome/browser/ui/util/menu_util.h" #import "ios/chrome/browser/ui/util/pasteboard_util.h" #import "ios/chrome/browser/url_loading/url_loading_browser_agent.h" #import "ios/chrome/browser/url_loading/url_loading_params.h" @@ -187,16 +186,6 @@ // history content. self.tableView.tableFooterView = [[UIView alloc] init]; - if (!IsNativeContextMenuEnabled()) { - // Long-press gesture recognizer. - UILongPressGestureRecognizer* longPressRecognizer = - [[UILongPressGestureRecognizer alloc] - initWithTarget:self - action:@selector - (displayContextMenuInvokedByGestureRecognizer:)]; - [self.tableView addGestureRecognizer:longPressRecognizer]; - } - self.dragDropHandler = [[TableViewURLDragDropHandler alloc] init]; self.dragDropHandler.origin = WindowActivityHistoryOrigin; self.dragDropHandler.dragDataSource = self; @@ -639,14 +628,7 @@ - (UIContextMenuConfiguration*)tableView:(UITableView*)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath*)indexPath - point:(CGPoint)point - API_AVAILABLE(ios(13.0)) { - if (!IsNativeContextMenuEnabled()) { - // Returning nil will allow the gesture to be captured and show the old - // context menus. - return nil; - } - + point:(CGPoint)point { if (self.isEditing) { // Don't show the context menu when currently in editing mode. return nil;
diff --git a/ios/chrome/browser/ui/history/history_ui_egtest.mm b/ios/chrome/browser/ui/history/history_ui_egtest.mm index 8f0977c..3efa504e 100644 --- a/ios/chrome/browser/ui/history/history_ui_egtest.mm +++ b/ios/chrome/browser/ui/history/history_ui_egtest.mm
@@ -341,9 +341,6 @@ // Tests clear browsing history. - (void)testClearBrowsingHistorySwipeDownDismiss { - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower."); - } if (!IsCollectionsCardPresentationStyleEnabled()) { EARL_GREY_TEST_SKIPPED(@"Test disabled on when feature flag is off."); } @@ -421,10 +418,7 @@ // Select "Open in New Incognito Tab" and confirm that new tab is opened in // incognito with the selected URL. - [ChromeEarlGrey - verifyOpenInIncognitoActionWithURL:_URL1.GetContent() - useNewString:[ChromeEarlGrey - isNativeContextMenusEnabled]]; + [ChromeEarlGrey verifyOpenInIncognitoActionWithURL:_URL1.GetContent()]; } // Tests display and selection of 'Copy URL' in a context menu on a history @@ -440,20 +434,14 @@ // Tap "Copy URL" and wait for the URL to be copied to the pasteboard. [ChromeEarlGrey - verifyCopyLinkActionWithText:[NSString stringWithUTF8String:_URL1.spec() - .c_str()] - useNewString:[ChromeEarlGrey - isNativeContextMenusEnabled]]; + verifyCopyLinkActionWithText:[NSString + stringWithUTF8String:_URL1.spec() + .c_str()]]; } // Tests display and selection of "Share" in the context menu for a history // entry. - (void)testContextMenuShare { - if (![ChromeEarlGrey isNativeContextMenusEnabled]) { - EARL_GREY_TEST_SKIPPED( - @"Test disabled when Native Context Menus feature flag is off."); - } - [self loadTestURLs]; [self openHistoryPanel]; @@ -469,11 +457,6 @@ // Tests the Delete context menu action for a History entry. - (void)testContextMenuDelete { - if (![ChromeEarlGrey isNativeContextMenusEnabled]) { - EARL_GREY_TEST_SKIPPED( - @"Test disabled when Native Context Menus feature flag is off."); - } - [self loadTestURLs]; [self openHistoryPanel]; @@ -504,9 +487,6 @@ // Tests that the VC can be dismissed by swiping down. - (void)testSwipeDownDismiss { - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower."); - } if (!IsCollectionsCardPresentationStyleEnabled()) { EARL_GREY_TEST_SKIPPED(@"Test disabled on when feature flag is off."); } @@ -533,14 +513,11 @@ - (void)testSwipeDownDismissWhileSearching { // TODO(crbug.com/1078165): Test fails on iOS 13+ iPad devices. #if !TARGET_IPHONE_SIMULATOR - if ([ChromeEarlGrey isIPadIdiom] && base::ios::IsRunningOnIOS13OrLater()) { + if ([ChromeEarlGrey isIPadIdiom]) { EARL_GREY_TEST_DISABLED(@"This test fails on iOS 13+ iPad device."); } #endif - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower."); - } if (!IsCollectionsCardPresentationStyleEnabled()) { EARL_GREY_TEST_SKIPPED(@"Test disabled on when feature flag is off."); }
diff --git a/ios/chrome/browser/ui/link_to_text/link_to_text_egtest.mm b/ios/chrome/browser/ui/link_to_text/link_to_text_egtest.mm index 175cdbc..4618636 100644 --- a/ios/chrome/browser/ui/link_to_text/link_to_text_egtest.mm +++ b/ios/chrome/browser/ui/link_to_text/link_to_text_egtest.mm
@@ -204,12 +204,6 @@ // Tests that a link can be generated for a simple text selection. - (void)testGenerateLinkForSimpleText { - if (!base::ios::IsRunningOnIOS13OrLater()) { - // Skip test on iOS 12 as the Activity View on that version is not - // accessible by Earl Grey. - EARL_GREY_TEST_SKIPPED(@"Test skipped on iOS 12."); - } - // TODO(crbug.com/1149603): Re-enable this test on iPad once presenting // popovers work. if ([ChromeEarlGrey isIPadIdiom]) { @@ -280,11 +274,6 @@ } - (void)testBadSelectionDisablesGenerateLink { - if (!base::ios::IsRunningOnIOS13OrLater()) { - // The TextInput implementation is incomplete on iOS 13, so this condition - // isn't enforced on older versions. - EARL_GREY_TEST_SKIPPED(@"Test skipped on iOS 13."); - } if (@available(iOS 14, *)) { [ChromeEarlGrey loadURL:self.testServer->GetURL(kNoTextTestURL)]; [ChromeEarlGrey waitForWebStateContainingText:kNoTextTestPageTextSample];
diff --git a/ios/chrome/browser/ui/menu/action_factory.h b/ios/chrome/browser/ui/menu/action_factory.h index 193fb4f..dab75174 100644 --- a/ios/chrome/browser/ui/menu/action_factory.h +++ b/ios/chrome/browser/ui/menu/action_factory.h
@@ -17,7 +17,6 @@ // Factory providing methods to create UIActions with consistent titles, images // and metrics structure. -API_AVAILABLE(ios(13.0)) @interface ActionFactory : NSObject // Initializes a factory instance for the current |browser| to create action
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm b/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm index 083a762..2eb4ea9 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm
@@ -298,13 +298,6 @@ } - (void)testFocusingOmniboxDismissesEditMenu { -// TODO(crbug.com/1129095): Re-enable test for iOS 12 device. -#if !TARGET_IPHONE_SIMULATOR - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Fails on iOS 12 devices."); - } -#endif - [self openPage1]; // Long pressing should open edit menu.
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h index b34107d..86d8fd7f 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h +++ b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h
@@ -230,10 +230,6 @@ // popup, and then remove this hack. b/5877366. BOOL ignore_popup_updates_; - // iOS 10.3 fails to apply the strikethrough style unless an extra style is - // also applied. See https://crbug.com/699702 for discussion. - BOOL use_strikethrough_workaround_; - // Temporary pointer to the attributed display string, stored as color and // other emphasis attributes are applied by the superclass. NSMutableAttributedString* attributing_display_string_;
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm index afe71be..61d26b965 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm
@@ -94,9 +94,6 @@ paste_delegate_ = [[OmniboxTextFieldPasteDelegate alloc] init]; [field_ setPasteDelegate:paste_delegate_]; - - use_strikethrough_workaround_ = base::ios::IsRunningOnOrLater(10, 3, 0) && - !base::ios::IsRunningOnOrLater(11, 2, 0); } OmniboxViewIOS::~OmniboxViewIOS() = default;
diff --git a/ios/chrome/browser/ui/open_in/open_in_controller_egtest.mm b/ios/chrome/browser/ui/open_in/open_in_controller_egtest.mm index 9998c48..05a5606 100644 --- a/ios/chrome/browser/ui/open_in/open_in_controller_egtest.mm +++ b/ios/chrome/browser/ui/open_in/open_in_controller_egtest.mm
@@ -72,11 +72,6 @@ if ([ChromeEarlGrey isIPadIdiom]) EARL_GREY_TEST_SKIPPED(@"Test skipped on iPad."); - // UIActivityViewController doesn't display the filename on iOS 12. - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower."); - } - // Open the activity menu. [ChromeEarlGrey loadURL:self.testServer->GetURL(kPDFPath)]; [[EarlGrey selectElementWithMatcher:chrome_test_util::OpenInButton()] @@ -113,11 +108,6 @@ if ([ChromeEarlGrey isIPadIdiom]) EARL_GREY_TEST_SKIPPED(@"Test skipped on iPad."); - // UIActivityViewController doesn't display the filename on iOS 12. - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower."); - } - // Open the activity menu. [ChromeEarlGrey loadURL:self.testServer->GetURL(kPNGPath)]; [[EarlGrey selectElementWithMatcher:chrome_test_util::OpenInButton()]
diff --git a/ios/chrome/browser/ui/overlays/overlay_presentation_context_impl_unittest.mm b/ios/chrome/browser/ui/overlays/overlay_presentation_context_impl_unittest.mm index adb0394d6..db0243ca 100644 --- a/ios/chrome/browser/ui/overlays/overlay_presentation_context_impl_unittest.mm +++ b/ios/chrome/browser/ui/overlays/overlay_presentation_context_impl_unittest.mm
@@ -289,13 +289,6 @@ // Tests the presentation flow for contained overlay UI. TEST_F(OverlayPresentationContextImplTest, ContainedOverlayUI) { -#if !TARGET_OS_SIMULATOR - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - // TODO(crbug.com/1099287): Test is failing on iOS 12.4 device. - return; - } -#endif // TARGET_OS_SIMULATOR - std::unique_ptr<OverlayRequest> request = OverlayRequest::CreateWithConfig<TestContainedOverlay>(); context_.PrepareToShowOverlayUI(request.get());
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm index 55e33285..62d221ee 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm
@@ -460,8 +460,7 @@ - (UIContextMenuConfiguration*)contextMenuConfigurationForItem: (id<ReadingListListItem>)item - withView:(UIView*)view - API_AVAILABLE(ios(13.0)) { + withView:(UIView*)view { __weak id<ReadingListListItemAccessibilityDelegate> accessibilityDelegate = self.tableViewController; __weak __typeof(self) weakSelf = self;
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm b/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm index aa5d77a..c994bf2 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm
@@ -578,10 +578,7 @@ // Long press the entry, and open it offline. LongPressEntry(kDistillableTitle); - int offlineStringId = IDS_IOS_READING_LIST_CONTENT_CONTEXT_OFFLINE; - if ([ChromeEarlGrey isNativeContextMenusEnabled]) { - offlineStringId = IDS_IOS_READING_LIST_OPEN_OFFLINE_BUTTON; - } + int offlineStringId = IDS_IOS_READING_LIST_OPEN_OFFLINE_BUTTON; TapContextMenuButtonWithA11yLabelID(offlineStringId); [ChromeEarlGrey waitForPageToFinishLoading]; @@ -637,10 +634,7 @@ // Long press the entry, and open it offline. LongPressEntry(kDistillableTitle); - int offlineStringId = IDS_IOS_READING_LIST_CONTENT_CONTEXT_OFFLINE; - if ([ChromeEarlGrey isNativeContextMenusEnabled]) { - offlineStringId = IDS_IOS_READING_LIST_OPEN_OFFLINE_BUTTON; - } + int offlineStringId = IDS_IOS_READING_LIST_OPEN_OFFLINE_BUTTON; TapContextMenuButtonWithA11yLabelID(offlineStringId); [ChromeEarlGrey waitForPageToFinishLoading]; @@ -687,10 +681,7 @@ // Long press the entry, and open it offline. LongPressEntry(kDistillableTitle); - int offlineStringId = IDS_IOS_READING_LIST_CONTENT_CONTEXT_OFFLINE; - if ([ChromeEarlGrey isNativeContextMenusEnabled]) { - offlineStringId = IDS_IOS_READING_LIST_OPEN_OFFLINE_BUTTON; - } + int offlineStringId = IDS_IOS_READING_LIST_OPEN_OFFLINE_BUTTON; TapContextMenuButtonWithA11yLabelID(offlineStringId); [ChromeEarlGrey waitForPageToFinishLoading]; @@ -1161,9 +1152,6 @@ if (base::ios::IsRunningOnIOS14OrLater() && ![ChromeEarlGrey isIPadIdiom]) { EARL_GREY_TEST_DISABLED(@"Fails on iOS14 iPhones."); } - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower."); - } if (![ChromeEarlGreyAppInterface isCollectionsCardPresentationStyleEnabled]) { EARL_GREY_TEST_SKIPPED(@"Test disabled on when feature flag is off."); } @@ -1194,10 +1182,7 @@ LongPressEntry(kReadTitle); // Tap "Copy URL" and wait for the URL to be copied to the pasteboard. - [ChromeEarlGrey - verifyCopyLinkActionWithText:kReadURL - useNewString:[ChromeEarlGrey - isNativeContextMenusEnabled]]; + [ChromeEarlGrey verifyCopyLinkActionWithText:kReadURL]; } // Tests the Open in New Tab context menu action for a reading list entry. @@ -1222,18 +1207,11 @@ // Select "Open in Incognito" and confirm that new tab is opened with selected // URL. [ChromeEarlGrey - verifyOpenInIncognitoActionWithURL:distillablePageURL.GetContent() - useNewString:[ChromeEarlGrey - isNativeContextMenusEnabled]]; + verifyOpenInIncognitoActionWithURL:distillablePageURL.GetContent()]; } // Tests the Mark as Read/Unread context menu action for a reading list entry. - (void)testContextMenuMarkAsReadAndBack { - if (![ChromeEarlGrey isNativeContextMenusEnabled]) { - EARL_GREY_TEST_SKIPPED( - @"Test disabled when Native Context Menus feature flag is off."); - } - AddEntriesAndOpenReadingList(); AssertAllEntriesVisible(); @@ -1269,11 +1247,6 @@ // Tests the Share context menu action for a reading list entry. - (void)testContextMenuShare { - if (![ChromeEarlGrey isNativeContextMenusEnabled]) { - EARL_GREY_TEST_SKIPPED( - @"Test disabled when Native Context Menus feature flag is off."); - } - GURL distillablePageURL(self.testServer->GetURL(kDistillableURL)); [self addURLToReadingList:distillablePageURL]; LongPressEntry(kDistillableTitle); @@ -1284,11 +1257,6 @@ // Tests the Delete context menu action for a reading list entry. - (void)testContextMenuDelete { - if (![ChromeEarlGrey isNativeContextMenusEnabled]) { - EARL_GREY_TEST_SKIPPED( - @"Test disabled when Native Context Menus feature flag is off."); - } - GURL distillablePageURL(self.testServer->GetURL(kDistillableURL)); [self addURLToReadingList:distillablePageURL]; LongPressEntry(kDistillableTitle);
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_menu_provider.h b/ios/chrome/browser/ui/reading_list/reading_list_menu_provider.h index d9c3016e..cdad8ce9 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_menu_provider.h +++ b/ios/chrome/browser/ui/reading_list/reading_list_menu_provider.h
@@ -14,8 +14,7 @@ // corresponding |view|. - (UIContextMenuConfiguration*)contextMenuConfigurationForItem: (id<ReadingListListItem>)item - withView:(UIView*)view - API_AVAILABLE(ios(13.0)); + withView:(UIView*)view; @end
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.h b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.h index 257c0ed..5068e854d 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.h +++ b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.h
@@ -30,8 +30,7 @@ // The browser. @property(nonatomic, assign) Browser* browser; // Provider of menu configurations for the readingList component. -@property(nonatomic, weak) id<ReadingListMenuProvider> menuProvider - API_AVAILABLE(ios(13.0)); +@property(nonatomic, weak) id<ReadingListMenuProvider> menuProvider; // Initializers. - (instancetype)init NS_DESIGNATED_INITIALIZER;
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm index 7185085..e21773c 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm
@@ -36,7 +36,6 @@ #import "ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h" #import "ios/chrome/browser/ui/table_view/table_view_utils.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" -#import "ios/chrome/browser/ui/util/menu_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #include "ios/chrome/grit/ios_strings.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -226,23 +225,11 @@ self.tableView.estimatedSectionHeaderHeight = 56; self.tableView.allowsMultipleSelectionDuringEditing = YES; self.tableView.allowsMultipleSelection = YES; - // Add a tableFooterView in order to disable separators at the bottom of the - // tableView. - - // Add gesture recognizer for the context menu. - if (!IsNativeContextMenuEnabled()) { - UILongPressGestureRecognizer* longPressRecognizer = - [[UILongPressGestureRecognizer alloc] - initWithTarget:self - action:@selector(handleLongPress:)]; - [self.tableView addGestureRecognizer:longPressRecognizer]; - } - - self.dragDropHandler = [[TableViewURLDragDropHandler alloc] init]; - self.dragDropHandler.origin = WindowActivityReadingListOrigin; - self.dragDropHandler.dragDataSource = self; - self.tableView.dragDelegate = self.dragDropHandler; - self.tableView.dragInteractionEnabled = true; + self.dragDropHandler = [[TableViewURLDragDropHandler alloc] init]; + self.dragDropHandler.origin = WindowActivityReadingListOrigin; + self.dragDropHandler.dragDataSource = self; + self.tableView.dragDelegate = self.dragDropHandler; + self.tableView.dragInteractionEnabled = true; } - (void)viewWillTransitionToSize:(CGSize)size @@ -356,14 +343,7 @@ - (UIContextMenuConfiguration*)tableView:(UITableView*)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath*)indexPath - point:(CGPoint)point - API_AVAILABLE(ios(13.0)) { - if (!IsNativeContextMenuEnabled()) { - // Returning nil will allow the gesture to be captured and show the old - // context menus. - return nil; - } - + point:(CGPoint)point { if (self.isEditing) { // Don't show the context menu when currently in editing mode. return nil;
diff --git a/ios/chrome/browser/ui/recent_tabs/BUILD.gn b/ios/chrome/browser/ui/recent_tabs/BUILD.gn index cb1ff5aa..0e9b66b 100644 --- a/ios/chrome/browser/ui/recent_tabs/BUILD.gn +++ b/ios/chrome/browser/ui/recent_tabs/BUILD.gn
@@ -107,7 +107,7 @@ "//ios/chrome/common/ui/colors", "//ios/chrome/common/ui/favicon", "//ios/public/provider/chrome/browser", - "//ios/public/provider/chrome/browser/modals", + "//ios/public/provider/chrome/browser/modals:modals_api", "//ios/public/provider/chrome/browser/signin", "//ui/base", ]
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_egtest.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_egtest.mm index 578dd9ab..948efdc5 100644 --- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_egtest.mm +++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_egtest.mm
@@ -238,9 +238,6 @@ if (base::ios::IsRunningOnIOS14OrLater() && ![ChromeEarlGrey isIPadIdiom]) { EARL_GREY_TEST_DISABLED(@"Fails on iOS14 iPhones."); } - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower."); - } if (!IsCollectionsCardPresentationStyleEnabled()) { EARL_GREY_TEST_SKIPPED(@"Test disabled on when feature flag is off."); } @@ -312,29 +309,19 @@ // Tests the Copy Link action on a recent tab's context menu. - (void)testContextMenuCopyLink { - if (![ChromeEarlGrey isNativeContextMenusEnabled]) { - EARL_GREY_TEST_SKIPPED( - @"Test disabled when Native Context Menus feature flag is off."); - } - [self loadTestURL]; OpenRecentTabsPanel(); [self longPressTestURLTab]; GURL testURL = TestPageURL(); [ChromeEarlGrey - verifyCopyLinkActionWithText:[NSString stringWithUTF8String:testURL.spec() - .c_str()] - useNewString:YES]; + verifyCopyLinkActionWithText:[NSString + stringWithUTF8String:testURL.spec() + .c_str()]]; } // Tests the Open in New Tab action on a recent tab's context menu. - (void)testContextMenuOpenInNewTab { - if (![ChromeEarlGrey isNativeContextMenusEnabled]) { - EARL_GREY_TEST_SKIPPED( - @"Test disabled when Native Context Menus feature flag is off."); - } - [self loadTestURL]; OpenRecentTabsPanel(); [self longPressTestURLTab]; @@ -352,11 +339,6 @@ EARL_GREY_TEST_DISABLED(@"Multiple windows can't be opened."); } - if (![ChromeEarlGrey isNativeContextMenusEnabled]) { - EARL_GREY_TEST_SKIPPED( - @"Test disabled when Native Context Menus feature flag is off."); - } - [self loadTestURL]; OpenRecentTabsPanel(); @@ -375,11 +357,6 @@ // Tests the Share action on a recent tab's context menu. - (void)testContextMenuShare { - if (![ChromeEarlGrey isNativeContextMenusEnabled]) { - EARL_GREY_TEST_SKIPPED( - @"Test disabled when Native Context Menus feature flag is off."); - } - [self loadTestURL]; OpenRecentTabsPanel(); [self longPressTestURLTab];
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_menu_helper.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_menu_helper.mm index 013f1be..275f3e8 100644 --- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_menu_helper.mm +++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_menu_helper.mm
@@ -51,8 +51,7 @@ - (UIContextMenuConfiguration*)contextMenuConfigurationForItem: (TableViewURLItem*)item - fromView:(UIView*)view - API_AVAILABLE(ios(13.0)) { + fromView:(UIView*)view { __weak __typeof(self) weakSelf = self; UIContextMenuActionProvider actionProvider = ^( @@ -112,7 +111,7 @@ - (UIContextMenuConfiguration*) contextMenuConfigurationForHeaderWithSectionIdentifier: - (NSInteger)sectionIdentifier API_AVAILABLE(ios(13.0)) { + (NSInteger)sectionIdentifier { __weak __typeof(self) weakSelf = self; UIContextMenuActionProvider actionProvider =
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_menu_provider.h b/ios/chrome/browser/ui/recent_tabs/recent_tabs_menu_provider.h index 4020cedc..ab20e63c 100644 --- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_menu_provider.h +++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_menu_provider.h
@@ -16,14 +16,13 @@ // associated |view|. - (UIContextMenuConfiguration*)contextMenuConfigurationForItem: (TableViewURLItem*)item - fromView:(UIView*)view - API_AVAILABLE(ios(13.0)); + fromView:(UIView*)view; // Creates a context menu configuration instance for the header of the given // |sectionIdentifier|. - (UIContextMenuConfiguration*) contextMenuConfigurationForHeaderWithSectionIdentifier: - (NSInteger)sectionIdentifier API_AVAILABLE(ios(13.0)); + (NSInteger)sectionIdentifier; @end
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.h b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.h index 1ff622a..d1fb7d55 100644 --- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.h +++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.h
@@ -48,11 +48,10 @@ @property(nonatomic, weak) id<TableViewFaviconDataSource> imageDataSource; // Provider of menu configurations for the recentTabs component. -@property(nonatomic, weak) id<RecentTabsMenuProvider> menuProvider - API_AVAILABLE(ios(13.0)); +@property(nonatomic, weak) id<RecentTabsMenuProvider> menuProvider; // Multi-window session for this vc's recent tabs. -@property(nonatomic, assign) UISceneSession* session API_AVAILABLE(ios(13.0)); +@property(nonatomic, assign) UISceneSession* session; // Initializers. - (instancetype)init NS_DESIGNATED_INITIALIZER;
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm index 03ce1d5..63c3917c 100644 --- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm +++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -57,7 +57,6 @@ #import "ios/chrome/browser/ui/table_view/table_view_favicon_data_source.h" #import "ios/chrome/browser/ui/table_view/table_view_utils.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" -#import "ios/chrome/browser/ui/util/menu_util.h" #include "ios/chrome/browser/ui/util/ui_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/browser/url_loading/url_loading_browser_agent.h" @@ -70,8 +69,7 @@ #import "ios/chrome/common/ui/favicon/favicon_view.h" #include "ios/chrome/grit/ios_chromium_strings.h" #include "ios/chrome/grit/ios_strings.h" -#include "ios/public/provider/chrome/browser/chrome_browser_provider.h" -#import "ios/public/provider/chrome/browser/modals/modals_provider.h" +#import "ios/public/provider/chrome/browser/modals/modals_api.h" #import "ios/public/provider/chrome/browser/signin/signin_presenter.h" #import "ios/web/public/web_state.h" #include "ui/base/l10n/l10n_util.h" @@ -120,7 +118,6 @@ } // namespace -API_AVAILABLE(ios(13.0)) @interface ListModelCollapsedSceneSessionMediator : ListModelCollapsedMediator // Creates a collapsed section mediator that stores data in the session's // userInfo instead of NSUserDefaults, which allows different states per window. @@ -769,10 +766,7 @@ - (void)dismissModals { [self.contextMenuCoordinator stop]; - - ios::GetChromeBrowserProvider() - .GetModalsProvider() - ->DismissModalsForTableView(self.tableView); + ios::provider::DismissModalsForTableView(self.tableView); } #pragma mark - UITableViewDelegate @@ -891,16 +885,9 @@ } // Gesture recognizer for long press context menu. - if (!IsNativeContextMenuEnabled()) { - UILongPressGestureRecognizer* longPress = - [[UILongPressGestureRecognizer alloc] - initWithTarget:self - action:@selector(handleLongPress:)]; - [header addGestureRecognizer:longPress]; - } else if (@available(iOS 13, *)) { - [header addInteraction:[[UIContextMenuInteraction alloc] - initWithDelegate:self]]; - } + [header + addInteraction:[[UIContextMenuInteraction alloc] initWithDelegate:self]]; + // Gesture recognizer for header collapsing/expanding. UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self @@ -911,14 +898,7 @@ - (UIContextMenuConfiguration*)tableView:(UITableView*)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath*)indexPath - point:(CGPoint)point - API_AVAILABLE(ios(13.0)) { - if (!IsNativeContextMenuEnabled()) { - // Returning nil will allow the gesture to be captured and show the old - // context menus. - return nil; - } - + point:(CGPoint)point { NSInteger itemType = [self.tableViewModel itemTypeForIndexPath:indexPath]; if (itemType != ItemTypeRecentlyClosed && itemType != ItemTypeSessionTabData) return nil; @@ -936,8 +916,7 @@ - (UIContextMenuConfiguration*)contextMenuInteraction: (UIContextMenuInteraction*)interaction - configurationForMenuAtLocation:(CGPoint)location - API_AVAILABLE(ios(13.0)) { + configurationForMenuAtLocation:(CGPoint)location { UIView* header = [interaction view]; NSInteger tappedHeaderSectionIdentifier = header.tag;
diff --git a/ios/chrome/browser/ui/settings/cells/settings_check_cell.mm b/ios/chrome/browser/ui/settings/cells/settings_check_cell.mm index 77f95fea..d4d666d63 100644 --- a/ios/chrome/browser/ui/settings/cells/settings_check_cell.mm +++ b/ios/chrome/browser/ui/settings/cells/settings_check_cell.mm
@@ -92,14 +92,8 @@ _trailingImageView.hidden = YES; [contentView addSubview:_trailingImageView]; // |activityIndictor| attributes. - if (base::ios::IsRunningOnIOS13OrLater()) { - // Creates default activity indicator. Color depends on appearance. - _activityIndicator = [[UIActivityIndicatorView alloc] init]; - } else { - // For iOS 12 and lower the color should be always gray otherwise - // indicator is not visible. - _activityIndicator = GetMediumUIActivityIndicatorView(); - } + // Creates default activity indicator. Color depends on appearance. + _activityIndicator = [[UIActivityIndicatorView alloc] init]; _activityIndicator.translatesAutoresizingMaskIntoConstraints = NO; _activityIndicator.hidden = YES; [contentView addSubview:_activityIndicator];
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_egtest.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_egtest.mm index 98a073b..5552154d 100644 --- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_egtest.mm +++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_egtest.mm
@@ -103,9 +103,6 @@ // Verifies that the CBD screen can be swiped down to dismiss. - (void)testClearBrowsingDataSwipeDown { - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower."); - } [self openClearBrowsingDataDialog]; // Check that CBD is presented. @@ -255,10 +252,6 @@ // Tests that tapping the "Learn more" link opens the help center. - (void)testTapLearnMore { - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Fails on iOS 12."); - } - [self openClearBrowsingDataDialog]; [[EarlGrey @@ -281,10 +274,6 @@ // Tests that opening the Clear Browsing interface from the History and tapping // the "Learn more" link opens the help center. - (void)testTapLearnMoreFromHistory { - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Fails on iOS 12."); - } - [ChromeEarlGreyUI openToolsMenu]; [ChromeEarlGreyUI tapToolsMenuButton:HistoryButton()]; [[EarlGrey selectElementWithMatcher:chrome_test_util::
diff --git a/ios/chrome/browser/ui/settings/google_services/BUILD.gn b/ios/chrome/browser/ui/settings/google_services/BUILD.gn index 990911ff..a8f11d6 100644 --- a/ios/chrome/browser/ui/settings/google_services/BUILD.gn +++ b/ios/chrome/browser/ui/settings/google_services/BUILD.gn
@@ -49,7 +49,6 @@ "//components/signin/public/identity_manager/objc", "//components/strings", "//components/sync", - "//components/ukm/ios:features", "//components/unified_consent", "//ios/chrome/app/strings", "//ios/chrome/browser",
diff --git a/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm b/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm index d2e8985..f5fa2cd0 100644 --- a/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm +++ b/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm
@@ -139,6 +139,29 @@ performAction:grey_tap()]; } +// Opens the MyGoogleUI for the primary account, and then the primary account +// is removed while MyGoogle UI is still opened. +- (void)testRemoveAccountWithMyGoogleUIOpened { + FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1]; + + // Sign In |fakeIdentity|, then open the Account Settings. + [SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity]; + [ChromeEarlGreyUI openSettingsMenu]; + [ChromeEarlGreyUI tapSettingsMenuButton:SettingsAccountButton()]; + + // Open MyGoogleUI. + [SigninEarlGreyUI openMyGoogleDialogWithFakeIdentity:fakeIdentity]; + + // Forget Identity. + [SigninEarlGrey forgetFakeIdentity:fakeIdentity]; + [ChromeEarlGreyUI waitForAppToIdle]; + [SigninEarlGrey verifySignedOut]; + + // Close settings. + [[EarlGrey selectElementWithMatcher:SettingsDoneButton()] + performAction:grey_tap()]; +} + // Tests opening the remove identity confirmation dialog once, and cancel the // dialog. Then we open the remove identity confirmation dialog to remove the // identity. And finally the remove identity confirmation dialog is opened a
diff --git a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm index e4c57f5..d432726 100644 --- a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm
@@ -18,6 +18,8 @@ #include "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/signin/authentication_service.h" #include "ios/chrome/browser/signin/authentication_service_factory.h" +#import "ios/chrome/browser/signin/chrome_account_manager_service.h" +#import "ios/chrome/browser/signin/chrome_account_manager_service_factory.h" #import "ios/chrome/browser/signin/chrome_identity_service_observer_bridge.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" #include "ios/chrome/browser/sync/sync_setup_service.h" @@ -239,12 +241,14 @@ signin::IdentityManager* identityManager = IdentityManagerFactory::GetForBrowserState(_browser->GetBrowserState()); + ChromeAccountManagerService* accountManagerService = + ChromeAccountManagerServiceFactory::GetForBrowserState( + _browser->GetBrowserState()); + NSString* authenticatedEmail = [authenticatedIdentity userEmail]; for (const auto& account : identityManager->GetAccountsWithRefreshTokens()) { - ios::ChromeIdentityService* identityService = - ios::GetChromeBrowserProvider().GetChromeIdentityService(); ChromeIdentity* identity = - identityService->GetIdentityWithGaiaID(account.gaia); + accountManagerService->GetIdentityWithGaiaID(account.gaia); if (!identity) { // Ignore the case in which the identity is invalid at lookup time. This // may be due to inconsistencies between the identity service and @@ -458,11 +462,6 @@ "-stopBrowserStateServiceObservers"; [self reloadData]; - if (![self authService]->HasPrimaryIdentity(signin::ConsentLevel::kSignin) && - self.dismissAccountDetailsViewControllerBlock) { - self.dismissAccountDetailsViewControllerBlock(/*animated=*/YES); - self.dismissAccountDetailsViewControllerBlock = nil; - } // Only attempt to pop the top-most view controller once the account list // has been dismissed. [self popViewIfSignedOut]; @@ -602,11 +601,11 @@ view:itemView]; __weak AccountsTableViewController* weakSelf = self; self.signoutCoordinator.completion = ^(BOOL success) { + [weakSelf.signoutCoordinator stop]; + weakSelf.signoutCoordinator = nil; if (success) { [weakSelf handleAuthenticationOperationDidFinish]; } - [weakSelf.signoutCoordinator stop]; - weakSelf.signoutCoordinator = nil; }; self.signoutCoordinator.delegate = self; [self.signoutCoordinator start]; @@ -737,23 +736,44 @@ return; } _isBeingDismissed = YES; + __weak __typeof(self) weakSelf = self; void (^popAccountsTableViewController)() = ^() { [base::mac::ObjCCastStrict<SettingsNavigationController>( - self.navigationController) + weakSelf.navigationController) popViewControllerOrCloseSettingsAnimated:YES]; }; - if (self.presentedViewController) { + if (self.dismissAccountDetailsViewControllerBlock) { + DCHECK(self.presentedViewController); + DCHECK(!self.alertCoordinator); + DCHECK(!self.removeAccountCoordinator); + DCHECK(!self.signoutCoordinator); + // TODO(crbug.com/1221066): Need to add a completion block in + // |dismissAccountDetailsViewControllerBlock| callback, to trigger + // |popAccountsTableViewController()|. + // Once we have a completion block, we can set |animated| to YES. + self.dismissAccountDetailsViewControllerBlock(/*animated=*/NO); + self.dismissAccountDetailsViewControllerBlock = nil; + popAccountsTableViewController(); + } else if (self.alertCoordinator || self.removeAccountCoordinator || + self.signoutCoordinator) { + DCHECK(self.presentedViewController); // If |self| is presenting a view controller (like |self.alertCoordinator|, - // |_removeAccountCoordinator| or the account detail view controller, it - // has to be dismissed before |self| can be poped from the navigation - // controller. + // |self.removeAccountCoordinator|, it has to be dismissed before |self| can + // be poped from the navigation controller. // This issue can be easily reproduced with EG tests, but not with Chrome // app itself. [self dismissViewControllerAnimated:NO completion:^{ + [weakSelf.alertCoordinator stop]; + weakSelf.alertCoordinator = nil; + [weakSelf.removeAccountCoordinator stop]; + weakSelf.removeAccountCoordinator = nil; + [weakSelf.signoutCoordinator stop]; + weakSelf.signoutCoordinator = nil; popAccountsTableViewController(); }]; } else { + DCHECK(!self.presentedViewController); // Pops |self|. popAccountsTableViewController(); }
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm index fdcd6eadf..7229e5c 100644 --- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm +++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm
@@ -16,7 +16,6 @@ #include "components/signin/public/base/signin_pref_names.h" #import "components/signin/public/identity_manager/objc/identity_manager_observer_bridge.h" #include "components/sync/driver/sync_service.h" -#include "components/ukm/ios/features.h" #include "components/unified_consent/pref_names.h" #include "ios/chrome/browser/pref_names.h" #import "ios/chrome/browser/signin/authentication_service.h" @@ -227,13 +226,6 @@ initWithPrefService:localPrefService prefName:metrics::prefs::kMetricsReportingEnabled]; _sendDataUsagePreference.observer = self; - if (!base::FeatureList::IsEnabled(kUmaCellular)) { - // When flag is not, kMetricsReportingWifiOnly pref has not been - // initialized, so don't create a PrefBackedBoolean for it. - _sendDataUsageWifiOnlyPreference = [[PrefBackedBoolean alloc] - initWithPrefService:localPrefService - prefName:prefs::kMetricsReportingWifiOnly]; - } _passwordLeakCheckEnabled = [[PrefBackedBoolean alloc] initWithPrefService:userPrefService prefName:password_manager::prefs::
diff --git a/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm b/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm index b61167d..2a77c87 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm
@@ -1212,18 +1212,8 @@ // Wait until the alerts are dismissed. [ChromeEarlGreyUI waitForAppToIdle]; - // On iOS 13+ phone when building with the iOS 12 SDK, the share sheet is - // presented fullscreen, so the export button is removed from the view - // hierarchy. Check that either the button is not present, or that it remains - // visible but is disabled. id<GREYMatcher> exportButtonStatusMatcher = grey_accessibilityTrait(UIAccessibilityTraitNotEnabled); -#if !defined(__IPHONE_13_0) || (__IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_13_0) - if (base::ios::IsRunningOnIOS13OrLater()) { - exportButtonStatusMatcher = - grey_anyOf(grey_nil(), exportButtonStatusMatcher, nil); - } -#endif [[EarlGrey selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( @@ -1239,8 +1229,7 @@ } else { // Tap on the "Cancel" or "X" button accompanying the activity view to // dismiss it. - NSString* dismissLabel = - base::ios::IsRunningOnIOS13OrLater() ? @"Close" : @"Cancel"; + NSString* dismissLabel = @"Close"; [[EarlGrey selectElementWithMatcher:grey_allOf( ButtonWithAccessibilityLabel(dismissLabel),
diff --git a/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm b/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm index 55da5f6..0618f8b 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm
@@ -1224,7 +1224,7 @@ // Starting with iOS13, alerts of style UIAlertControllerStyleActionSheet // need a sourceView or sourceRect, or this crashes. - if (base::ios::IsRunningOnIOS13OrLater() && IsIPadIdiom()) { + if (IsIPadIdiom()) { exportConfirmation.popoverPresentationController.sourceView = self.tableView; }
diff --git a/ios/chrome/browser/ui/settings/settings_accessibility_egtest.mm b/ios/chrome/browser/ui/settings/settings_accessibility_egtest.mm index 070a00803..741f61b7 100644 --- a/ios/chrome/browser/ui/settings/settings_accessibility_egtest.mm +++ b/ios/chrome/browser/ui/settings/settings_accessibility_egtest.mm
@@ -119,10 +119,6 @@ // Verifies that the Settings screen can be swiped down to dismiss, and clean up // is performed allowing a new presentation. - (void)testSettingsSwipeDownDismiss { - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower."); - } - [ChromeEarlGreyUI openSettingsMenu]; // Check that Settings is presented.
diff --git a/ios/chrome/browser/ui/settings/settings_app_interface.h b/ios/chrome/browser/ui/settings/settings_app_interface.h index 58c2a17..6b6877c 100644 --- a/ios/chrome/browser/ui/settings/settings_app_interface.h +++ b/ios/chrome/browser/ui/settings/settings_app_interface.h
@@ -26,12 +26,6 @@ // Allows turning on and off metrics reporting. + (void)setMetricsReportingEnabled:(BOOL)reportingEnabled; -// Allows turning on and off metrics reporting. |wifiOnly| is appllicable only -// if reporting is enabled. Reporting will not happen on cellular connection if -// |wifiOnly| is YES. -+ (void)setMetricsReportingEnabled:(BOOL)reportingEnabled - wifiOnly:(BOOL)wifiOnly; - // Allows simulating turning the cellular network on/off. + (void)setCellularNetworkEnabled:(BOOL)cellularNetworkEnabled;
diff --git a/ios/chrome/browser/ui/settings/settings_app_interface.mm b/ios/chrome/browser/ui/settings/settings_app_interface.mm index 8e1fefa0..798734e5 100644 --- a/ios/chrome/browser/ui/settings/settings_app_interface.mm +++ b/ios/chrome/browser/ui/settings/settings_app_interface.mm
@@ -75,18 +75,6 @@ chrome_test_util::WaitForBreakpadQueue(); } -// TODO(crbug.com/953862): Remove as part of feature flag cleanup. -+ (void)setMetricsReportingEnabled:(BOOL)reportingEnabled - wifiOnly:(BOOL)wifiOnly { - chrome_test_util::SetBooleanLocalStatePref( - metrics::prefs::kMetricsReportingEnabled, reportingEnabled); - chrome_test_util::SetBooleanLocalStatePref(prefs::kMetricsReportingWifiOnly, - wifiOnly); - // Breakpad uses dispatch_async to update its state. Wait to get to a - // consistent state. - chrome_test_util::WaitForBreakpadQueue(); -} - + (void)setCellularNetworkEnabled:(BOOL)cellularNetworkEnabled { chrome_test_util::SetWWANStateTo(cellularNetworkEnabled); // Breakpad uses dispatch_async to update its state. Wait to get to a
diff --git a/ios/chrome/browser/ui/settings/settings_egtest.mm b/ios/chrome/browser/ui/settings/settings_egtest.mm index 369faee..edcd3df 100644 --- a/ios/chrome/browser/ui/settings/settings_egtest.mm +++ b/ios/chrome/browser/ui/settings/settings_egtest.mm
@@ -250,94 +250,27 @@ } - (void)assertsMetricsPrefsForService:(MetricsServiceType)serviceType { - // Two preferences, each with two values - on or off. Check all four - // combinations: - // kMetricsReportingEnabled OFF and kMetricsReportingWifiOnly OFF + // kMetricsReportingEnabled OFF // - Services do not record data and do not upload data. + [SettingsAppInterface setMetricsReportingEnabled:NO]; - // kMetricsReportingEnabled OFF and kMetricsReportingWifiOnly ON - // - Services do not record data and do not upload data. - // Note that if kMetricsReportingEnabled is OFF, the state of - // kMetricsReportingWifiOnly does not matter. - - // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly ON - // - Services record data and upload data only when the device is using - // a wifi connection. Note: rather than checking for wifi, the code - // checks for a cellular network (wwan). wwan != wifi. So if wwan is - // true, services do not upload any data. - - // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly OFF - // - Services record data and upload data. - - if ([ChromeEarlGrey isUMACellularEnabled]) { - // kMetricsReportingEnabled OFF - [SettingsAppInterface setMetricsReportingEnabled:NO]; - } else { - // kMetricsReportingEnabled OFF and kMetricsReportingWifiOnly OFF - [SettingsAppInterface setMetricsReportingEnabled:NO wifiOnly:NO]; - } // Service should be completely disabled. // I.e. no recording of data, and no uploading of what's been recorded. [self assertMetricsServiceDisabled:serviceType]; - if ([ChromeEarlGrey isUMACellularEnabled]) { - // kMetricsReportingEnabled OFF - [SettingsAppInterface setMetricsReportingEnabled:NO]; - } else { - // kMetricsReportingEnabled OFF and kMetricsReportingWifiOnly ON - [SettingsAppInterface setMetricsReportingEnabled:NO wifiOnly:YES]; - } - // If kMetricsReportingEnabled is OFF, any service should remain completely - // disabled, i.e. no uploading even if kMetricsReportingWifiOnly is ON. - [self assertMetricsServiceDisabled:serviceType]; - -// Split here: Official build vs. Development build. -// Official builds allow recording and uploading of data, honoring the -// metrics prefs. Development builds should never record or upload data. + // kMetricsReportingEnabled ON + // - Services record data and upload data. #if BUILDFLAG(GOOGLE_CHROME_BRANDING) - // Official build. - // The values of the prefs and the wwan vs wifi state should be honored by - // the services, turning on and off according to the rules laid out above. - - if (![ChromeEarlGrey isUMACellularEnabled]) { - // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly ON. - [SettingsAppInterface setMetricsReportingEnabled:YES wifiOnly:YES]; - // Service should be enabled. - [self assertMetricsServiceEnabled:serviceType]; - - // Set the network to use a cellular network, which should disable uploading - // when the wifi-only flag is set. - [SettingsAppInterface setCellularNetworkEnabled:YES]; - [self assertMetricsServiceEnabledButNotUploading:serviceType]; - - // Turn off cellular network usage, which should enable uploading. - [SettingsAppInterface setCellularNetworkEnabled:NO]; - [self assertMetricsServiceEnabled:serviceType]; - - // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly OFF - [SettingsAppInterface setMetricsReportingEnabled:YES wifiOnly:NO]; - [self assertMetricsServiceEnabled:serviceType]; - } - + // Official builds allow recording and uploading of data, honoring the + // metrics prefs. Development builds should never record or upload data. + [SettingsAppInterface setMetricsReportingEnabled:YES]; + // Service should be enabled. + [self assertMetricsServiceEnabled:serviceType]; #else // Development build. Do not allow any recording or uploading of data. - // Specifically, the kMetricsReportingEnabled preference is completely - // disregarded for non-official builds, and checking its value always returns - // false (NO). - // This tests that no matter the state change, pref or network connection, - // services remain disabled. - - if (![ChromeEarlGrey isUMACellularEnabled]) { - // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly ON - [SettingsAppInterface setMetricsReportingEnabled:YES wifiOnly:YES]; - // Service should remain disabled. - [self assertMetricsServiceDisabled:serviceType]; - - // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly OFF - [SettingsAppInterface setMetricsReportingEnabled:YES wifiOnly:NO]; - // Service should remain disabled. - [self assertMetricsServiceDisabled:serviceType]; - } + [SettingsAppInterface setMetricsReportingEnabled:YES]; + // Service should remain disabled. + [self assertMetricsServiceDisabled:serviceType]; #endif } @@ -388,14 +321,13 @@ } // Verifies that metrics reporting works properly under possible settings of the -// preferences kMetricsReportingEnabled and kMetricsReportingWifiOnly. +// preference kMetricsReportingEnabled. - (void)testMetricsReporting { [self assertsMetricsPrefsForService:kMetrics]; } // Verifies that breakpad reporting works properly under possible settings of -// the preferences |kMetricsReportingEnabled| and |kMetricsReportingWifiOnly| -// for non-first-launch runs. +// the preference |kMetricsReportingEnabled|. // NOTE: breakpad only allows uploading for non-first-launch runs. - (void)testBreakpadReporting { [self setTearDownHandler:^{ @@ -408,8 +340,7 @@ } // Verifies that breakpad reporting works properly under possible settings of -// the preferences |kMetricsReportingEnabled| and |kMetricsReportingWifiOnly| -// for first-launch runs. +// the preference |kMetricsReportingEnabled|. // NOTE: breakpad only allows uploading for non-first-launch runs. - (void)testBreakpadReportingFirstLaunch { [self setTearDownHandler:^{
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn index 11934694..4d48d89 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn
@@ -74,8 +74,7 @@ "//ios/chrome/browser/ui/util", "//ios/chrome/common/ui/colors", "//ios/chrome/common/ui/util", - "//ios/public/provider/chrome/browser", - "//ios/public/provider/chrome/browser/modals", + "//ios/public/provider/chrome/browser/modals:modals_api", "//ui/base", ] }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_helper.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_helper.mm index 4dc4cb1..15cfb12 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_helper.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_helper.mm
@@ -48,7 +48,7 @@ } - (UIContextMenuConfiguration*)contextMenuConfigurationForGridCell: - (GridCell*)gridCell API_AVAILABLE(ios(13.0)) { + (GridCell*)gridCell { __weak __typeof(self) weakSelf = self; UIContextMenuActionProvider actionProvider =
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_provider.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_provider.h index ff955d80..f5dbc872 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_provider.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_provider.h
@@ -14,7 +14,7 @@ // Returns a context menu configuration instance for the given |gridCell|. - (UIContextMenuConfiguration*)contextMenuConfigurationForGridCell: - (GridCell*)gridCell API_AVAILABLE(ios(13.0)); + (GridCell*)gridCell; @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h index 7bfabc8..94d11ce 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h
@@ -100,8 +100,7 @@ // biometric authentication. @property(nonatomic, assign) BOOL contentNeedsAuthentication; // Provider of context menu configurations for the tabs in the grid. -@property(nonatomic, weak) id<GridContextMenuProvider> menuProvider - API_AVAILABLE(ios(13.0)); +@property(nonatomic, weak) id<GridContextMenuProvider> menuProvider; // The item IDs of selected items for editing. @property(nonatomic, readonly) NSArray<NSString*>* selectedItemIDsForEditing;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm index 5034ae78..7ca48a0 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
@@ -32,8 +32,7 @@ #import "ios/chrome/browser/ui/util/rtl_geometry.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/ui/util/constraints_ui_util.h" -#include "ios/public/provider/chrome/browser/chrome_browser_provider.h" -#import "ios/public/provider/chrome/browser/modals/modals_provider.h" +#include "ios/public/provider/chrome/browser/modals/modals_api.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -417,8 +416,7 @@ - (UIContextMenuConfiguration*)collectionView:(UICollectionView*)collectionView contextMenuConfigurationForItemAtIndexPath:(NSIndexPath*)indexPath - point:(CGPoint)point - API_AVAILABLE(ios(13.0)) { + point:(CGPoint)point { // Context menu shouldn't appear in the selection mode. if (!IsTabGridContextMenuEnabled() || _mode == TabGridModeSelection) { return nil; @@ -817,9 +815,7 @@ } - (void)dismissModals { - ios::GetChromeBrowserProvider() - .GetModalsProvider() - ->DismissModalsForCollectionView(self.collectionView); + ios::provider::DismissModalsForCollectionView(self.collectionView); } #pragma mark - LayoutSwitcher
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm index 8191bab..6ed91cd 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
@@ -245,27 +245,17 @@ // Tests the Copy Link action on a recent tab's context menu. - (void)testRecentTabsContextMenuCopyLink { - if (![ChromeEarlGrey isNativeContextMenusEnabled]) { - EARL_GREY_TEST_SKIPPED( - @"Test disabled when Native Context Menus feature flag is off."); - } - [self prepareRecentTabWithURL:_URL1 response:kResponse1]; [self longPressTabWithTitle:[NSString stringWithUTF8String:kTitle1]]; [ChromeEarlGrey - verifyCopyLinkActionWithText:[NSString stringWithUTF8String:_URL1.spec() - .c_str()] - useNewString:YES]; + verifyCopyLinkActionWithText:[NSString + stringWithUTF8String:_URL1.spec() + .c_str()]]; } // Tests the Open in New Tab action on a recent tab's context menu. - (void)testRecentTabsContextMenuOpenInNewTab { - if (![ChromeEarlGrey isNativeContextMenusEnabled]) { - EARL_GREY_TEST_SKIPPED( - @"Test disabled when Native Context Menus feature flag is off."); - } - [self prepareRecentTabWithURL:_URL1 response:kResponse1]; [self longPressTabWithTitle:[NSString stringWithUTF8String:kTitle1]]; @@ -282,11 +272,6 @@ EARL_GREY_TEST_DISABLED(@"Multiple windows can't be opened."); } - if (![ChromeEarlGrey isNativeContextMenusEnabled]) { - EARL_GREY_TEST_SKIPPED( - @"Test disabled when Native Context Menus feature flag is off."); - } - [self prepareRecentTabWithURL:_URL1 response:kResponse1]; [self longPressTabWithTitle:[NSString stringWithUTF8String:kTitle1]]; @@ -295,11 +280,6 @@ // Tests the Share action on a recent tab's context menu. - (void)testRecentTabsContextMenuShare { - if (![ChromeEarlGrey isNativeContextMenusEnabled]) { - EARL_GREY_TEST_SKIPPED( - @"Test disabled when Native Context Menus feature flag is off."); - } - [self prepareRecentTabWithURL:_URL1 response:kResponse1]; [self longPressTabWithTitle:[NSString stringWithUTF8String:kTitle1]]; @@ -312,11 +292,6 @@ // Tests the Share action on a tab grid item's context menu. - (void)testTabGridItemContextMenuShare { - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_SKIPPED( - @"Tab Grid context menu only supported on iOS 13 and later."); - } - [ChromeEarlGrey loadURL:_URL1]; [ChromeEarlGrey waitForWebStateContainingText:kResponse1]; @@ -332,11 +307,6 @@ // Tests the Add to Reading list action on a tab grid item's context menu. - (void)testTabGridItemContextMenuAddToReadingList { - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_SKIPPED( - @"Tab Grid context menu only supported on iOS 13 and later."); - } - [ChromeEarlGrey loadURL:_URL1]; [ChromeEarlGrey waitForWebStateContainingText:kResponse1]; @@ -351,11 +321,6 @@ // Tests the Add to Bookmarks action on a tab grid item's context menu. - (void)testTabGridItemContextMenuAddToBookmarks { - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_SKIPPED( - @"Tab Grid context menu only supported on iOS 13 and later."); - } - [ChromeEarlGrey loadURL:_URL1]; [ChromeEarlGrey waitForWebStateContainingText:kResponse1]; @@ -412,11 +377,6 @@ // Tests the Share action on a tab grid item's context menu. - (void)testTabGridItemContextCloseTab { - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_SKIPPED( - @"Tab Grid context menu only supported on iOS 13 and later."); - } - [ChromeEarlGrey loadURL:_URL1]; [ChromeEarlGrey waitForWebStateContainingText:kResponse1];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_thumb_strip_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_thumb_strip_egtest.mm index bc1c0274..89837d2 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_thumb_strip_egtest.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_thumb_strip_egtest.mm
@@ -74,13 +74,9 @@ - (AppLaunchConfiguration)appConfigurationForTestCase { AppLaunchConfiguration config; - // Enabling this feature causes all tests to fail as part of setup. - // See crbug.com/1143299. - if (base::ios::IsRunningOnIOS13OrLater()) { - config.features_enabled.push_back(kExpandedTabStrip); - config.features_disabled.push_back( - fullscreen::features::kSmoothScrollingDefault); - } + config.features_enabled.push_back(kExpandedTabStrip); + config.features_disabled.push_back( + fullscreen::features::kSmoothScrollingDefault); return config; } @@ -105,11 +101,6 @@ EARL_GREY_TEST_SKIPPED(@"Thumb strip is not enabled on iPhone"); } - // See crbug.com/1143299. - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Fails on iOS 12 devices."); - } - [self setUpTestServer]; const GURL URL = self.testServer->GetURL("/querytitle?Tab1"); @@ -194,11 +185,6 @@ EARL_GREY_TEST_SKIPPED(@"Thumb strip is not enabled on iPhone"); } - // See crbug.com/1143299. - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Fails on iOS 12 devices."); - } - [self setUpTestServer]; const GURL URL = self.testServer->GetURL("/querytitle?Tab1"); @@ -258,11 +244,6 @@ EARL_GREY_TEST_SKIPPED(@"Thumb strip is not enabled on iPhone"); } - // See crbug.com/1143299. - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Fails on iOS 12 devices."); - } - [self setUpTestServer]; const GURL URL = self.testServer->GetURL("/querytitle?Tab1"); @@ -335,11 +316,6 @@ EARL_GREY_TEST_SKIPPED(@"Thumb strip is not enabled on iPhone"); } - // See crbug.com/1143299. - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Fails on iOS 12 devices."); - } - [self setUpTestServer]; const GURL URL = self.testServer->GetURL("/querytitle?Tab1"); @@ -386,11 +362,6 @@ EARL_GREY_TEST_SKIPPED(@"Thumb strip is not enabled on iPhone"); } - // See crbug.com/1143299. - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Fails on iOS 12 devices."); - } - [self setUpTestServer]; const GURL URL = self.testServer->GetURL("/querytitle?Tab1");
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h index 7d5806a..43dd869 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h
@@ -128,9 +128,9 @@ // Provides the context menu for the tabs on the grid. @property(nonatomic, weak) id<GridContextMenuProvider> - regularTabsContextMenuProvider API_AVAILABLE(ios(13.0)); + regularTabsContextMenuProvider; @property(nonatomic, weak) id<GridContextMenuProvider> - incognitoTabsContextMenuProvider API_AVAILABLE(ios(13.0)); + incognitoTabsContextMenuProvider; // Init with tab grid view configuration, which decides which sub view // controller should be added.
diff --git a/ios/chrome/browser/ui/tabs/tab_view.mm b/ios/chrome/browser/ui/tabs/tab_view.mm index 2ec3aba7..c7b64274 100644 --- a/ios/chrome/browser/ui/tabs/tab_view.mm +++ b/ios/chrome/browser/ui/tabs/tab_view.mm
@@ -346,10 +346,6 @@ // Updates this tab's style based on the value of |selected| and the current // incognito style. - (void)updateStyleForSelected:(BOOL)selected { - // On iOS 13 there is no need to pick custom incognito assets because - // |overrideUserInterfaceStyle| is set to dark mode when in incognito. - using base::ios::IsRunningOnIOS13OrLater; - // Style the background image first. NSString* state = (selected ? @"foreground" : @"background"); NSString* imageName = [NSString stringWithFormat:@"tabstrip_%@_tab", state];
diff --git a/ios/chrome/browser/ui/thumb_strip/thumb_strip_egtest.mm b/ios/chrome/browser/ui/thumb_strip/thumb_strip_egtest.mm index c063c2a..76c109a1 100644 --- a/ios/chrome/browser/ui/thumb_strip/thumb_strip_egtest.mm +++ b/ios/chrome/browser/ui/thumb_strip/thumb_strip_egtest.mm
@@ -68,13 +68,9 @@ - (AppLaunchConfiguration)appConfigurationForTestCase { AppLaunchConfiguration config; - // Enabling this feature causes all tests to fail as part of setup. - // See crbug.com/1143299. - if (base::ios::IsRunningOnIOS13OrLater()) { - config.features_enabled.push_back(kExpandedTabStrip); - config.features_disabled.push_back( - fullscreen::features::kSmoothScrollingDefault); - } + config.features_enabled.push_back(kExpandedTabStrip); + config.features_disabled.push_back( + fullscreen::features::kSmoothScrollingDefault); return config; } @@ -100,11 +96,6 @@ EARL_GREY_TEST_SKIPPED(@"Thumb strip is not enabled on iPhone"); } - // See crbug.com/1143299. - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Fails on iOS 12 devices."); - } - [self setUpTestServer]; const GURL URL = self.testServer->GetURL("/querytitle?Hello"); @@ -137,11 +128,6 @@ EARL_GREY_TEST_SKIPPED(@"Thumb strip is not enabled on iPhone"); } - // See crbug.com/1143299. - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Fails on iOS 12 devices."); - } - [self setUpTestServer]; const GURL URL = self.testServer->GetURL("/querytitle?Hello"); @@ -194,11 +180,6 @@ EARL_GREY_TEST_SKIPPED(@"Thumb strip is not enabled on iPhone"); } - // See crbug.com/1143299. - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Fails on iOS 12 devices."); - } - [self setUpTestServer]; const GURL URL = self.testServer->GetURL("/querytitle?Hello"); @@ -242,11 +223,6 @@ EARL_GREY_TEST_SKIPPED(@"Thumb strip is not enabled on iPhone"); } - // See crbug.com/1143299. - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Fails on iOS 12 devices."); - } - // Scroll the NTP to reveal the thumb strip. [[EarlGrey selectElementWithMatcher:NTPCollectionView()] performAction:grey_swipeSlowInDirection(kGREYDirectionDown)]; @@ -283,11 +259,6 @@ EARL_GREY_TEST_SKIPPED(@"Thumb strip is not enabled on iPhone"); } - // See crbug.com/1143299. - if (!base::ios::IsRunningOnIOS13OrLater()) { - EARL_GREY_TEST_DISABLED(@"Fails on iOS 12 devices."); - } - [self setUpTestServer]; const GURL URL1 = self.testServer->GetURL("/querytitle?Page1");
diff --git a/ios/chrome/browser/ui/util/BUILD.gn b/ios/chrome/browser/ui/util/BUILD.gn index 550b65099..653dc53 100644 --- a/ios/chrome/browser/ui/util/BUILD.gn +++ b/ios/chrome/browser/ui/util/BUILD.gn
@@ -32,8 +32,6 @@ "layout_guide_names.mm", "manual_text_framer.h", "manual_text_framer.mm", - "menu_util.h", - "menu_util.mm", "named_guide.h", "named_guide.mm", "named_guide_util.h",
diff --git a/ios/chrome/browser/ui/util/label_observer.mm b/ios/chrome/browser/ui/util/label_observer.mm index 2e66e557..3fe4738 100644 --- a/ios/chrome/browser/ui/util/label_observer.mm +++ b/ios/chrome/browser/ui/util/label_observer.mm
@@ -6,6 +6,8 @@ #import <objc/runtime.h> +#include <ostream> + #include "base/notreached.h" #include "base/strings/sys_string_conversions.h"
diff --git a/ios/chrome/browser/ui/util/menu_util.h b/ios/chrome/browser/ui/util/menu_util.h deleted file mode 100644 index c5a7840..0000000 --- a/ios/chrome/browser/ui/util/menu_util.h +++ /dev/null
@@ -1,12 +0,0 @@ -// 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. - -#ifndef IOS_CHROME_BROWSER_UI_UTIL_MENU_UTIL_H_ -#define IOS_CHROME_BROWSER_UI_UTIL_MENU_UTIL_H_ - -// Returns true if the native context menu flag is Enabled and the app is -// currently running on iOS 13 or higher. -bool IsNativeContextMenuEnabled(); - -#endif // IOS_CHROME_BROWSER_UI_UTIL_MENU_UTIL_H_
diff --git a/ios/chrome/browser/ui/util/menu_util.mm b/ios/chrome/browser/ui/util/menu_util.mm deleted file mode 100644 index 994a422..0000000 --- a/ios/chrome/browser/ui/util/menu_util.mm +++ /dev/null
@@ -1,16 +0,0 @@ -// 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. - -#import "ios/chrome/browser/ui/util/menu_util.h" - -#include "base/ios/ios_util.h" -#import "ios/chrome/browser/ui/ui_feature_flags.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -bool IsNativeContextMenuEnabled() { - return base::ios::IsRunningOnIOS13OrLater(); -}
diff --git a/ios/chrome/browser/ui/util/uikit_ui_util_unittest.mm b/ios/chrome/browser/ui/util/uikit_ui_util_unittest.mm index 35d6581..7a9f905 100644 --- a/ios/chrome/browser/ui/util/uikit_ui_util_unittest.mm +++ b/ios/chrome/browser/ui/util/uikit_ui_util_unittest.mm
@@ -19,9 +19,8 @@ using UIKitUIUtilTest = PlatformTest; -// Verify the assumption about UIViewController that on iPad and iOS 13 all -// orientations are supported, and all orientations but Portrait Upside-Down on -// iOS 12 iPhone and iPod Touch. +// Verify the assumption about UIViewController that on iPad and iOS 13+ all +// orientations are supported. TEST_F(UIKitUIUtilTest, UIViewControllerSupportedOrientationsTest) { UIViewController* viewController = [[UIViewController alloc] initWithNibName:nil bundle:nil]; @@ -32,15 +31,6 @@ return; } - // Running on iPhone iOS 12 or earlier. - if (!base::ios::IsRunningOnIOS13OrLater()) { - EXPECT_EQ(UIInterfaceOrientationMaskAllButUpsideDown, - [viewController supportedInterfaceOrientations]); - return; - } - - // Running on iOS 13 iPhone. - // Starting with iOS 13, the default [UIViewController // supportedInterfaceOrientations] returns UIInterfaceOrientationMaskAll. // However, this is only true if the application was built with the Xcode 11
diff --git a/ios/chrome/browser/web/cache_egtest.mm b/ios/chrome/browser/web/cache_egtest.mm index a293403..678c3af 100644 --- a/ios/chrome/browser/web/cache_egtest.mm +++ b/ios/chrome/browser/web/cache_egtest.mm
@@ -128,45 +128,6 @@ return config; } -// Tests caching behavior on navigate back and page reload. Navigate back should -// use the cached page. Page reload should use cache-control in the request -// header and show updated page. -- (void)testCachingBehaviorOnNavigateBackAndPageReload { - // TODO(crbug.com/747436): re-enable this test on iOS 10.3.1 and afterwards - // once the bug is fixed. - if (base::ios::IsRunningOnOrLater(10, 3, 1)) { - EARL_GREY_TEST_DISABLED(@"Disabled on iOS 10.3.1 and afterwards."); - } - - web::test::SetUpHttpServer(std::make_unique<CacheTestResponseProvider>()); - - const GURL cacheTestFirstPageURL = - HttpServer::MakeUrl(kCacheTestFirstPageURL); - - // 1st hit to server. Verify that the server has the correct hit count. - [ChromeEarlGrey loadURL:cacheTestFirstPageURL]; - [ChromeEarlGrey waitForWebStateContainingText:"serverHitCounter: 1"]; - - // Navigate to another page. 2nd hit to server. - [ChromeEarlGrey - tapWebStateElementWithID:[NSString - stringWithUTF8String:kCacheTestLinkID]]; - [ChromeEarlGrey waitForWebStateContainingText:"serverHitCounter: 2"]; - - // Navigate back. This should not hit the server. Verify the page has been - // loaded from cache. The serverHitCounter will remain the same. - [ChromeEarlGrey goBack]; - [ChromeEarlGrey waitForWebStateContainingText:"serverHitCounter: 1"]; - - // Reload page. 3rd hit to server. Verify that page reload causes the - // hitCounter to show updated value. - [ChromeEarlGrey reload]; - [ChromeEarlGrey waitForWebStateContainingText:"serverHitCounter: 3"]; - - // Verify that page reload causes Cache-Control value to be sent with request. - [ChromeEarlGrey waitForWebStateContainingText:"cacheControl: max-age=0"]; -} - // Tests caching behavior when opening new tab. New tab should not use the // cached page. - (void)testCachingBehaviorOnOpenNewTab {
diff --git a/ios/chrome/browser/web/forms_egtest.mm b/ios/chrome/browser/web/forms_egtest.mm index 5189809..9ca44fd 100644 --- a/ios/chrome/browser/web/forms_egtest.mm +++ b/ios/chrome/browser/web/forms_egtest.mm
@@ -530,7 +530,7 @@ // TODO:(crbug.com/1147654): re-enable after figuring out why it is failing. - (void)DISABLE_testPostFormEntryWithKeyboard { // Test fails on iPad Air 2 13.4 crbug.com/1102608. - if ([ChromeEarlGrey isIPadIdiom] && base::ios::IsRunningOnOrLater(13, 0, 0)) { + if ([ChromeEarlGrey isIPadIdiom]) { EARL_GREY_TEST_DISABLED(@"Fails in iOS 13 on iPads."); }
diff --git a/ios/chrome/browser/web/navigation_egtest.mm b/ios/chrome/browser/web/navigation_egtest.mm index 578441ee..34fc844 100644 --- a/ios/chrome/browser/web/navigation_egtest.mm +++ b/ios/chrome/browser/web/navigation_egtest.mm
@@ -564,13 +564,6 @@ // Tests that navigating forward from a WebUI URL works when resuming from // session restore. This is a regression test for https://crbug.com/814790. - (void)testRestoreHistoryToWebUIAndNavigateForward { -#if TARGET_IPHONE_SIMULATOR - if (!base::ios::IsRunningOnIOS13OrLater() && ![ChromeEarlGrey isIPadIdiom]) { - // This test is failing on one bot for that very specific configuration. See - // https://crbug.com/1059496 for more info. - EARL_GREY_TEST_DISABLED(@"Failing on iPhone 12 simulator."); - } -#endif GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); const GURL destinationURL = self.testServer->GetURL(kSimpleFileBasedTestURL); [ChromeEarlGrey loadURL:GURL("chrome://version")]; @@ -597,13 +590,6 @@ EARL_GREY_TEST_DISABLED(@"Test disabled on iOS 13.4 but enabled in iOS 14"); } -#if TARGET_IPHONE_SIMULATOR - if (!base::ios::IsRunningOnIOS13OrLater() && ![ChromeEarlGrey isIPadIdiom]) { - // This test is failing on one bot for that very specific configuration. See - // https://crbug.com/1059496 for more info. - EARL_GREY_TEST_DISABLED(@"Failing on iPhone 12 simulator."); - } -#endif GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); const GURL destinationURL = self.testServer->GetURL(kSimpleFileBasedTestURL); [ChromeEarlGrey loadURL:destinationURL]; @@ -623,13 +609,6 @@ // Tests that restoring a placeholder URL is correctly restored. This is a // regression test from http://crbug.com/1011758. - (void)testRestoreHistoryToPlaceholderURL { -#if TARGET_IPHONE_SIMULATOR - if (!base::ios::IsRunningOnIOS13OrLater() && ![ChromeEarlGrey isIPadIdiom]) { - // This test is failing on one bot for that very specific configuration. See - // https://crbug.com/1059496 for more info. - EARL_GREY_TEST_DISABLED(@"Failing on iPhone 12 simulator."); - } -#endif GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); const GURL destinationURL("chrome://crash"); [ChromeEarlGrey loadURL:destinationURL];
diff --git a/ios/chrome/browser/web/web_share_egtest.mm b/ios/chrome/browser/web/web_share_egtest.mm index 8ae4b49..90d354f 100644 --- a/ios/chrome/browser/web/web_share_egtest.mm +++ b/ios/chrome/browser/web/web_share_egtest.mm
@@ -93,12 +93,6 @@ // Tests that a fully specified url can be shared. - (void)testShareUrl { - if (!base::ios::IsRunningOnIOS13OrLater()) { - // Test is unsupported on iOS 12 because presenting the share sheet in this - // EarlGrey test crashes the app. - EARL_GREY_TEST_SKIPPED(@"Skipped for iOS 12."); - } - const GURL pageURL = self.testServer->GetURL(kWebShareValidLinkUrl); [ChromeEarlGrey loadURL:pageURL]; [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] @@ -112,12 +106,6 @@ // Tests that a relative url can be shared. - (void)testShareRelativeUrl { - if (!base::ios::IsRunningOnIOS13OrLater()) { - // Test is unsupported on iOS 12 because presenting the share sheet in this - // EarlGrey test crashes the app. - EARL_GREY_TEST_SKIPPED(@"Skipped for iOS 12."); - } - const GURL pageURL = self.testServer->GetURL(kWebShareRelativeLinkUrl); [ChromeEarlGrey loadURL:pageURL]; [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] @@ -131,12 +119,6 @@ // Tests that a relative url can be shared when the filename starts with "file". - (void)testShareRelativeFilenameUrl { - if (!base::ios::IsRunningOnIOS13OrLater()) { - // Test is unsupported on iOS 12 because presenting the share sheet in this - // EarlGrey test crashes the app. - EARL_GREY_TEST_SKIPPED(@"Skipped for iOS 12."); - } - const GURL pageURL = self.testServer->GetURL(kWebShareRelativeFilenameFileUrl); [ChromeEarlGrey loadURL:pageURL]; @@ -151,12 +133,6 @@ // Tests that a "file://" url can not be shared. - (void)testShareFileUrl { - if (!base::ios::IsRunningOnIOS13OrLater()) { - // Test is unsupported on iOS 12 because presenting the share sheet in this - // EarlGrey test crashes the app. - EARL_GREY_TEST_SKIPPED(@"Skipped for iOS 12."); - } - const GURL pageURL = self.testServer->GetURL(kWebShareFileUrl); [ChromeEarlGrey loadURL:pageURL]; [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
diff --git a/ios/chrome/common/credential_provider/archivable_credential_store.mm b/ios/chrome/common/credential_provider/archivable_credential_store.mm index e5d84e8c..4a51e85 100644 --- a/ios/chrome/common/credential_provider/archivable_credential_store.mm +++ b/ios/chrome/common/credential_provider/archivable_credential_store.mm
@@ -4,6 +4,8 @@ #import "ios/chrome/common/credential_provider/archivable_credential_store.h" +#include <ostream> + #include "base/check.h" #include "base/notreached.h" #include "base/strings/sys_string_conversions.h"
diff --git a/ios/chrome/test/app/chrome_test_util.mm b/ios/chrome/test/app/chrome_test_util.mm index 9aee991..7e417d03 100644 --- a/ios/chrome/test/app/chrome_test_util.mm +++ b/ios/chrome/test/app/chrome_test_util.mm
@@ -66,7 +66,7 @@ // testing. UIOpenURLContext has no init available, so this can only be // allocated. It uses obscuring properties for URL and options. // TODO(crbug.com/1115018) Explore improving this which can become brittle. -API_AVAILABLE(ios(13.0)) @interface FakeUIOpenURLContext : UIOpenURLContext +@interface FakeUIOpenURLContext : UIOpenURLContext @property(nonatomic, copy) NSURL* URL; @property(nonatomic, strong) UISceneOpenURLOptions* options; @end
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index b1d67fa..7fdc6ce 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -74,7 +74,6 @@ "//components/strings", "//components/sync/base", "//components/translate/core/browser", - "//components/ukm/ios:features", "//components/unified_consent", "//components/variations", "//ios/chrome/app:app_internal",
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.h b/ios/chrome/test/earl_grey/chrome_earl_grey.h index c4ac175..6d93ac0f 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey.h +++ b/ios/chrome/test/earl_grey/chrome_earl_grey.h
@@ -607,9 +607,6 @@ // Returns YES if a variation triggering server-side behavior is enabled. - (BOOL)isTriggerVariationEnabled:(int)variationID; -// Returns YES if UmaCellular feature is enabled. -- (BOOL)isUMACellularEnabled WARN_UNUSED_RESULT; - // Returns YES if UKM feature is enabled. - (BOOL)isUKMEnabled WARN_UNUSED_RESULT; @@ -630,9 +627,6 @@ // Returns whether the mobile version of the websites are requested by default. - (BOOL)isMobileModeByDefault WARN_UNUSED_RESULT; -// Returns whether the native context menus feature is enabled or not. -- (BOOL)isNativeContextMenusEnabled; - // Returns whether the app is configured to, and running in an environment which // can, open multiple windows. - (BOOL)areMultipleWindowsSupported; @@ -694,10 +688,8 @@ #pragma mark - Context Menus Utilities (EG2) // Taps on the Copy Link context menu action and verifies that the |text| has -// been copied to the pasteboard. |useNewString| determines which action string -// to use. -- (void)verifyCopyLinkActionWithText:(NSString*)text - useNewString:(BOOL)useNewString; +// been copied to the pasteboard. +- (void)verifyCopyLinkActionWithText:(NSString*)text; // Taps on the Open in New Tab context menu action and waits for the |URL| to be // present in the omnibox. @@ -708,10 +700,8 @@ - (void)verifyOpenInNewWindowActionWithContent:(const std::string&)content; // Taps on the Open in Incognito context menu action and waits for the |URL| to -// be present in the omnibox. |useNewString| determines which action string -// to use. -- (void)verifyOpenInIncognitoActionWithURL:(const std::string&)URL - useNewString:(BOOL)useNewString; +// be present in the omnibox. +- (void)verifyOpenInIncognitoActionWithURL:(const std::string&)URL; // Taps on the Share context menu action and validates that the ActivityView // was brought up with the correct title in its header. The title starts as the
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.mm b/ios/chrome/test/earl_grey/chrome_earl_grey.mm index 9cfb295..49b6c63e 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
@@ -1155,10 +1155,6 @@ return [ChromeEarlGreyAppInterface isTriggerVariationEnabled:variationID]; } -- (BOOL)isUMACellularEnabled { - return [ChromeEarlGreyAppInterface isUMACellularEnabled]; -} - - (BOOL)isUKMEnabled { return [ChromeEarlGreyAppInterface isUKMEnabled]; } @@ -1184,10 +1180,6 @@ return [ChromeEarlGreyAppInterface isMobileModeByDefault]; } -- (BOOL)isNativeContextMenusEnabled { - return [ChromeEarlGreyAppInterface isNativeContextMenusEnabled]; -} - - (BOOL)areMultipleWindowsSupported { return [ChromeEarlGreyAppInterface areMultipleWindowsSupported]; } @@ -1309,10 +1301,9 @@ #pragma mark - Context Menus Utilities (EG2) -- (void)verifyCopyLinkActionWithText:(NSString*)text - useNewString:(BOOL)useNewString { +- (void)verifyCopyLinkActionWithText:(NSString*)text { [ChromeEarlGreyAppInterface clearPasteboardURLs]; - [[EarlGrey selectElementWithMatcher:CopyLinkButton(useNewString)] + [[EarlGrey selectElementWithMatcher:CopyLinkButton()] performAction:grey_tap()]; [self verifyStringCopied:text]; } @@ -1340,14 +1331,13 @@ [ChromeEarlGrey waitForWebStateContainingText:content inWindowWithNumber:1]; } -- (void)verifyOpenInIncognitoActionWithURL:(const std::string&)URL - useNewString:(BOOL)useNewString { +- (void)verifyOpenInIncognitoActionWithURL:(const std::string&)URL { // Check tab count prior to execution. NSUInteger oldRegularTabCount = [ChromeEarlGreyAppInterface mainTabCount]; NSUInteger oldIncognitoTabCount = [ChromeEarlGreyAppInterface incognitoTabCount]; - [[EarlGrey selectElementWithMatcher:OpenLinkInIncognitoButton(useNewString)] + [[EarlGrey selectElementWithMatcher:OpenLinkInIncognitoButton()] performAction:grey_tap()]; [self waitForIncognitoTabCount:oldIncognitoTabCount + 1];
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h index c19a4e8..78c5835 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h +++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h
@@ -487,9 +487,6 @@ // Returns YES if a variation triggering server-side behavior is enabled. + (BOOL)isTriggerVariationEnabled:(int)variationID; -// Returns YES if UmaCellular feature is enabled. -+ (BOOL)isUMACellularEnabled WARN_UNUSED_RESULT; - // Returns YES if UKM feature is enabled. + (BOOL)isUKMEnabled WARN_UNUSED_RESULT; @@ -513,9 +510,6 @@ // Returns whether the mobile version of the websites are requested by default. + (BOOL)isMobileModeByDefault WARN_UNUSED_RESULT; -// Returns whether the native context menus feature is enabled or not. -+ (BOOL)isNativeContextMenusEnabled; - // Returns whether the app is configured to, and running in an environment which // can, open multiple windows. + (BOOL)areMultipleWindowsSupported;
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm index 42ea377..1786da16 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
@@ -18,7 +18,6 @@ #include "components/metrics/demographics/demographic_metrics_provider.h" #include "components/prefs/pref_service.h" #include "components/sync/base/pref_names.h" -#import "components/ukm/ios/features.h" #include "components/unified_consent/unified_consent_service.h" #include "components/variations/variations_associated_data.h" #include "components/variations/variations_ids_provider.h" @@ -34,7 +33,6 @@ #import "ios/chrome/browser/ui/tab_switcher/tab_grid/features.h" #import "ios/chrome/browser/ui/table_view/feature_flags.h" #import "ios/chrome/browser/ui/ui_feature_flags.h" -#import "ios/chrome/browser/ui/util/menu_util.h" #import "ios/chrome/browser/ui/util/named_guide.h" #import "ios/chrome/browser/ui/util/rtl_geometry.h" #import "ios/chrome/browser/unified_consent/unified_consent_service_factory.h" @@ -994,10 +992,6 @@ return std::find(ids.begin(), ids.end(), variationID) != ids.end(); } -+ (BOOL)isUMACellularEnabled { - return base::FeatureList::IsEnabled(kUmaCellular); -} - + (BOOL)isUKMEnabled { return base::FeatureList::IsEnabled(ukm::kUkmFeature); } @@ -1035,10 +1029,6 @@ return webClientUserAgent == web::UserAgentType::MOBILE; } -+ (BOOL)isNativeContextMenusEnabled { - return IsNativeContextMenuEnabled(); -} - + (BOOL)areMultipleWindowsSupported { return base::ios::IsMultipleScenesSupported(); }
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.h b/ios/chrome/test/earl_grey/chrome_matchers.h index 4da1161f..90d3097 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers.h +++ b/ios/chrome/test/earl_grey/chrome_matchers.h
@@ -165,8 +165,8 @@ id<GREYMatcher> OpenLinkInNewTabButton(); // Matcher for the Open in Incognito option in the context menu when long -// pressing a link. |use_new_string| determines which string to use. -id<GREYMatcher> OpenLinkInIncognitoButton(BOOL use_new_string); +// pressing a link. +id<GREYMatcher> OpenLinkInIncognitoButton(); // Matcher for the Open in New Window option in the context menu when long // pressing a link. @@ -380,12 +380,11 @@ id<GREYMatcher> CopyActivityButton(); // Matcher for the Copy Link option in the updated context menus when long -// pressing on a link. |use_new_string| determines which string to use. -id<GREYMatcher> CopyLinkButton(BOOL use_new_string); +// pressing on a link. +id<GREYMatcher> CopyLinkButton(); -// Matcher for the Edit option on the updated context menus. |use_new_string| -// determines which string to use. -id<GREYMatcher> EditButton(BOOL use_new_string); +// Matcher for the Edit option on the context menus. +id<GREYMatcher> EditButton(); // Matcher for the Move option on the updated context menus. id<GREYMatcher> MoveButton();
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.mm b/ios/chrome/test/earl_grey/chrome_matchers.mm index 42cc08d..08885ac 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers.mm
@@ -220,9 +220,8 @@ return [ChromeMatchersAppInterface openLinkInNewTabButton]; } -id<GREYMatcher> OpenLinkInIncognitoButton(BOOL use_new_string) { - return [ChromeMatchersAppInterface - openLinkInIncognitoButtonWithUseNewString:use_new_string]; +id<GREYMatcher> OpenLinkInIncognitoButton() { + return [ChromeMatchersAppInterface openLinkInIncognitoButton]; } id<GREYMatcher> OpenLinkInNewWindowButton() { @@ -482,13 +481,12 @@ return [ChromeMatchersAppInterface copyActivityButton]; } -id<GREYMatcher> CopyLinkButton(BOOL use_new_string) { - return [ChromeMatchersAppInterface - copyLinkButtonWithUseNewString:use_new_string]; +id<GREYMatcher> CopyLinkButton() { + return [ChromeMatchersAppInterface copyLinkButton]; } -id<GREYMatcher> EditButton(BOOL use_new_string) { - return [ChromeMatchersAppInterface editButtonWithUseNewString:use_new_string]; +id<GREYMatcher> EditButton() { + return [ChromeMatchersAppInterface editButton]; } id<GREYMatcher> MoveButton() {
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h index 0a7563e3..a98d663 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h +++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h
@@ -158,8 +158,8 @@ + (id<GREYMatcher>)openLinkInNewTabButton; // Matcher for the Open in Incognito option in the context menu when long -// pressing a link. |useNewString| determines which string to use. -+ (id<GREYMatcher>)openLinkInIncognitoButtonWithUseNewString:(BOOL)useNewString; +// pressing a link. ++ (id<GREYMatcher>)openLinkInIncognitoButton; // Matcher for the Open in New Window option in the context menu when long // pressing a link. @@ -373,12 +373,11 @@ + (id<GREYMatcher>)copyActivityButton; // Matcher for the Copy Link option in the updated context menus when long -// pressing on a link. |useNewString| determines which string to use. -+ (id<GREYMatcher>)copyLinkButtonWithUseNewString:(BOOL)useNewString; +// pressing on a link. ++ (id<GREYMatcher>)copyLinkButton; -// Matcher for the Edit option on the updated context menus. |useNewString| -// determines which string to use. -+ (id<GREYMatcher>)editButtonWithUseNewString:(BOOL)useNewString; +// Matcher for the Edit option on the context menus. ++ (id<GREYMatcher>)editButton; // Matcher for the Move option on the updated context menus. + (id<GREYMatcher>)moveButton;
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm index 4ca0f1d..e45ca9a 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm
@@ -434,10 +434,8 @@ buttonWithAccessibilityLabelID:(IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB)]; } -+ (id<GREYMatcher>)openLinkInIncognitoButtonWithUseNewString: - (BOOL)useNewString { - int stringId = useNewString ? IDS_IOS_OPEN_IN_INCOGNITO_ACTION_TITLE - : IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB; ++ (id<GREYMatcher>)openLinkInIncognitoButton { + int stringId = IDS_IOS_OPEN_IN_INCOGNITO_ACTION_TITLE; return [ChromeMatchersAppInterface buttonWithAccessibilityLabelID:(stringId)]; } @@ -774,15 +772,13 @@ grey_ancestor(grey_kindOfClassName(@"UIActivityActionGroupCell")), nil); } -+ (id<GREYMatcher>)copyLinkButtonWithUseNewString:(BOOL)useNewString { - int stringId = useNewString ? IDS_IOS_COPY_LINK_ACTION_TITLE - : IDS_IOS_CONTENT_CONTEXT_COPY; ++ (id<GREYMatcher>)copyLinkButton { + int stringId = IDS_IOS_COPY_LINK_ACTION_TITLE; return [ChromeMatchersAppInterface buttonWithAccessibilityLabelID:stringId]; } -+ (id<GREYMatcher>)editButtonWithUseNewString:(BOOL)useNewString { - int stringId = useNewString ? IDS_IOS_EDIT_ACTION_TITLE - : IDS_IOS_BOOKMARK_CONTEXT_MENU_EDIT; ++ (id<GREYMatcher>)editButton { + int stringId = IDS_IOS_EDIT_ACTION_TITLE; return [ChromeMatchersAppInterface buttonWithAccessibilityLabelID:stringId]; }
diff --git a/ios/chrome/test/earl_grey2/smoke_egtest.mm b/ios/chrome/test/earl_grey2/smoke_egtest.mm index faf46dd..771562f 100644 --- a/ios/chrome/test/earl_grey2/smoke_egtest.mm +++ b/ios/chrome/test/earl_grey2/smoke_egtest.mm
@@ -301,10 +301,6 @@ testAppLaunchManagerBackgroundAndForegroundApp #endif - (void)FLAKY_testAppLaunchManagerBackgroundAndForegroundApp { - if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { - EARL_GREY_TEST_DISABLED(@"Test disabled on iOS 12 and lower."); - } - [ChromeEarlGrey openNewTab]; [[AppLaunchManager sharedManager] backgroundAndForegroundApp]; [ChromeEarlGrey waitForMainTabCount:2];
diff --git a/ios/testing/ocmock_complex_type_helper.mm b/ios/testing/ocmock_complex_type_helper.mm index 053f0f0b..37fa305 100644 --- a/ios/testing/ocmock_complex_type_helper.mm +++ b/ios/testing/ocmock_complex_type_helper.mm
@@ -4,6 +4,8 @@ #import "ios/testing/ocmock_complex_type_helper.h" +#include <ostream> + #include "base/check.h" #import "base/strings/sys_string_conversions.h"
diff --git a/ios/web/js_messaging/crw_js_window_id_manager.mm b/ios/web/js_messaging/crw_js_window_id_manager.mm index 63dc312..8b98d6d 100644 --- a/ios/web/js_messaging/crw_js_window_id_manager.mm +++ b/ios/web/js_messaging/crw_js_window_id_manager.mm
@@ -4,6 +4,8 @@ #import "ios/web/js_messaging/crw_js_window_id_manager.h" +#include <ostream> + #include "base/dcheck_is_on.h" #include "base/notreached.h" #include "base/strings/string_number_conversions.h"
diff --git a/ios/web/navigation/crw_error_page_helper.mm b/ios/web/navigation/crw_error_page_helper.mm index a08ac40..6fa9237 100644 --- a/ios/web/navigation/crw_error_page_helper.mm +++ b/ios/web/navigation/crw_error_page_helper.mm
@@ -4,6 +4,8 @@ #import "ios/web/navigation/crw_error_page_helper.h" +#include <ostream> + #include "base/check.h" #include "base/strings/sys_string_conversions.h" #include "net/base/escape.h"
diff --git a/media/base/cdm_key_information.cc b/media/base/cdm_key_information.cc index 73bd18b..38aed14 100644 --- a/media/base/cdm_key_information.cc +++ b/media/base/cdm_key_information.cc
@@ -4,6 +4,8 @@ #include "media/base/cdm_key_information.h" +#include <ostream> + #include "base/notreached.h" #include "base/strings/string_number_conversions.h"
diff --git a/media/base/decrypt_config.cc b/media/base/decrypt_config.cc index ff3ed63f..b874b34 100644 --- a/media/base/decrypt_config.cc +++ b/media/base/decrypt_config.cc
@@ -6,6 +6,8 @@ #include <stddef.h> +#include <ostream> + #include "base/check_op.h" #include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h"
diff --git a/net/base/escape.cc b/net/base/escape.cc index 23f9cda..f2d7eee 100644 --- a/net/base/escape.cc +++ b/net/base/escape.cc
@@ -4,12 +4,15 @@ #include "net/base/escape.h" +#include <ostream> + #include "base/check_op.h" #include "base/cxx17_backports.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversion_utils.h" #include "base/strings/utf_string_conversions.h" #include "base/third_party/icu/icu_utf.h" +#include "build/build_config.h" namespace net {
diff --git a/net/base/hash_value.cc b/net/base/hash_value.cc index ec440bb..4a35bda 100644 --- a/net/base/hash_value.cc +++ b/net/base/hash_value.cc
@@ -5,7 +5,9 @@ #include "net/base/hash_value.h" #include <stdlib.h> + #include <algorithm> +#include <ostream> #include "base/base64.h" #include "base/check_op.h"
diff --git a/net/base/ip_endpoint.cc b/net/base/ip_endpoint.cc index f8da6e4..f4e5abb 100644 --- a/net/base/ip_endpoint.cc +++ b/net/base/ip_endpoint.cc
@@ -4,6 +4,8 @@ #include "net/base/ip_endpoint.h" +#include <ostream> + #include "build/build_config.h" #if defined(OS_WIN)
diff --git a/net/ftp/ftp_network_transaction.cc b/net/ftp/ftp_network_transaction.cc index c028d31..4029a99 100644 --- a/net/ftp/ftp_network_transaction.cc +++ b/net/ftp/ftp_network_transaction.cc
@@ -30,6 +30,7 @@ #include "net/log/net_log_source.h" #include "net/socket/client_socket_factory.h" #include "net/socket/stream_socket.h" +#include "url/scheme_host_port.h" #include "url/url_constants.h" namespace net { @@ -664,7 +665,7 @@ // Using an empty NetworkIsolationKey here, since FTP support is deprecated, // and should go away soon. resolve_request_ = - resolver_->CreateRequest(HostPortPair::FromURL(request_->url), + resolver_->CreateRequest(url::SchemeHostPort(request_->url), NetworkIsolationKey(), net_log_, absl::nullopt); return resolve_request_->Start(base::BindOnce( &FtpNetworkTransaction::OnIOComplete, base::Unretained(this)));
diff --git a/net/ssl/ssl_cipher_suite_names.cc b/net/ssl/ssl_cipher_suite_names.cc index fb852b7d..8a539db 100644 --- a/net/ssl/ssl_cipher_suite_names.cc +++ b/net/ssl/ssl_cipher_suite_names.cc
@@ -4,6 +4,8 @@ #include "net/ssl/ssl_cipher_suite_names.h" +#include <ostream> + #include "base/notreached.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h"
diff --git a/net/websockets/websocket_channel.cc b/net/websockets/websocket_channel.cc index e9e3666a..5107a5a 100644 --- a/net/websockets/websocket_channel.cc +++ b/net/websockets/websocket_channel.cc
@@ -17,7 +17,6 @@ #include "base/cxx17_backports.h" #include "base/location.h" #include "base/memory/weak_ptr.h" -#include "base/metrics/histogram_functions.h" #include "base/numerics/safe_conversions.h" #include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" @@ -134,59 +133,6 @@ scoped_refptr<IOBuffer> buffer_; }; -void LogCloseCodeForUma(uint16_t code) { - // From RFC6455: "The status code is an integer number between 1000 and 4999 - // (inclusive)". In practice, any 16-bit unsigned integer may be sent. For UMA - // purposes, we bucket codes whose meanings are not standardised. This enum is - // emitted to UMA, so don't remove entries or renumber it. It's better not to - // add new entries at all, since it will make older records incompatible with - // newer records. - enum class BucketedCloseCode { - kNormalClosure = 0, // 1000 - kGoingAway = 1, // 1001 - kProtocolError = 2, // 1002 - kUnsupportedData = 3, // 1003 - kReserved = 4, // 1004 - kNoStatusRcvd = 5, // 1005 - kAbnormalClosure = 6, // 1006 - kInvalidFramePayloadData = 7, // 1007 - kPolicyViolation = 8, // 1008 - kMessageTooBig = 9, // 1009 - kMandatoryExt = 10, // 1010 - kInternalError = 11, // 1011 - kServiceRestart = 12, // 1012 - kTryAgainLater = 13, // 1013 - kBadGateway = 14, // 1014 - kTlsHandshake = 15, // 1015 - kOther1000Range = 16, // 1016-1999 - k2000Range = 17, // 2000-2999 - k3000Range = 18, // 3000-3999 - k4000Range = 19, // 4000-4999 - kUnder1000 = 20, // 0-999 - k5000AndOver = 21, // 5000-65535 - kMaxValue = k5000AndOver - }; - - BucketedCloseCode bucketed_code; - if (code >= 1000 && code <= 1015) { - bucketed_code = static_cast<BucketedCloseCode>(code - 1000); - } else if (code < 1000) { - bucketed_code = BucketedCloseCode::kUnder1000; - } else if (code < 2000) { - bucketed_code = BucketedCloseCode::kOther1000Range; - } else if (code < 3000) { - bucketed_code = BucketedCloseCode::k2000Range; - } else if (code < 4000) { - bucketed_code = BucketedCloseCode::k3000Range; - } else if (code < 5000) { - bucketed_code = BucketedCloseCode::k4000Range; - } else { - bucketed_code = BucketedCloseCode::k5000AndOver; - } - - base::UmaHistogramEnumeration("Net.WebSocket.CloseCode", bucketed_code); -} - } // namespace // A class to encapsulate a set of frames and information about the size of @@ -1046,7 +992,6 @@ void WebSocketChannel::DoDropChannel(bool was_clean, uint16_t code, const std::string& reason) { - LogCloseCodeForUma(code); event_interface_->OnDropChannel(was_clean, code, reason); }
diff --git a/remoting/signaling/signaling_address.cc b/remoting/signaling/signaling_address.cc index b33ed1cd..93c4852 100644 --- a/remoting/signaling/signaling_address.cc +++ b/remoting/signaling/signaling_address.cc
@@ -6,6 +6,8 @@ #include <string.h> +#include <ostream> + #include "base/check_op.h" #include "base/notreached.h" #include "base/strings/string_util.h"
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 9d900391..e458ba1 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -1056,8 +1056,7 @@ return; } - std::move(callback).Run( - std::move(*domain_reliability_monitor_->GetWebUIData())); + std::move(callback).Run(domain_reliability_monitor_->GetWebUIData()); } void NetworkContext::CloseAllConnections(CloseAllConnectionsCallback callback) {
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h index d7e5f778..985c4a7d 100644 --- a/skia/config/SkUserConfig.h +++ b/skia/config/SkUserConfig.h
@@ -205,8 +205,6 @@ // Max. verb count for paths rendered by the edge-AA tessellating path renderer. #define GR_AA_TESSELLATOR_MAX_VERB_COUNT 100 -#define SK_SUPPORT_LEGACY_GETBLENDMODE - #define GR_DISABLE_TESSELLATION_ON_ES2 #define SK_SUPPORT_LEGACY_AAA_CHOICE
diff --git a/skia/ext/benchmarking_canvas.cc b/skia/ext/benchmarking_canvas.cc index 3c05446..aee01d4 100644 --- a/skia/ext/benchmarking_canvas.cc +++ b/skia/ext/benchmarking_canvas.cc
@@ -192,9 +192,9 @@ val->SetString("Style", gStyleStrings[paint.getStyle()]); } - if (paint.getBlendMode() != default_paint.getBlendMode()) { - val->SetKey("Xfermode", - base::Value::FromUniquePtrValue(AsValue(paint.getBlendMode()))); + if (paint.asBlendMode() != default_paint.asBlendMode()) { + val->SetKey("Xfermode", base::Value::FromUniquePtrValue(AsValue( + paint.getBlendMode_or(SkBlendMode::kSrcOver)))); } if (paint.isAntiAlias() || paint.isDither()) {
diff --git a/storage/browser/blob/blob_storage_constants.cc b/storage/browser/blob/blob_storage_constants.cc index 96143d9..ba9c728 100644 --- a/storage/browser/blob/blob_storage_constants.cc +++ b/storage/browser/blob/blob_storage_constants.cc
@@ -4,6 +4,8 @@ #include "storage/browser/blob/blob_storage_constants.h" +#include <ostream> + #include "base/check.h" #include "base/command_line.h" #include "base/strings/string_number_conversions.h"
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index d8b22af..e81e1024 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -6100,78 +6100,6 @@ }, { "args": [ - "--shared-prefs-file=//chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json", - "--additional-apk=//third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk", - "--gs-results-bucket=chromium-result-details", - "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" - ], - "merge": { - "args": [ - "--bucket", - "chromium-result-details", - "--test-name", - "chrome_public_test_vr_apk" - ], - "script": "//build/android/pylib/results/presentation/test_results_presentation.py" - }, - "resultdb": { - "enable": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/luci/logdog/butler/${platform}", - "location": "bin", - "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "device_os": null, - "device_type": null, - "machine_type": "e2-standard-4", - "os": "Ubuntu-16.04|Ubuntu-18.04", - "pool": "chromium.tests.avd" - } - ], - "named_caches": [ - { - "name": "avd_generic_androidS", - "path": ".android" - }, - { - "name": "system_images_android_S_google_apis_x64", - "path": ".emulator_sdk" - } - ], - "optional_dimensions": { - "60": [ - { - "caches": "avd_generic_androidS" - } - ] - }, - "output_links": [ - { - "link": [ - "https://luci-logdog.appspot.com/v/?s", - "=android%2Fswarming%2Flogcats%2F", - "${TASK_ID}%2F%2B%2Funified_logcats" - ], - "name": "shard #${SHARD_INDEX} logcats" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 - }, - "test": "chrome_public_test_vr_apk", - "test_id_prefix": "ninja://chrome/android:chrome_public_test_vr_apk/" - }, - { - "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" @@ -9294,75 +9222,6 @@ "--bucket", "chromium-result-details", "--test-name", - "vr_android_unittests" - ], - "script": "//build/android/pylib/results/presentation/test_results_presentation.py" - }, - "resultdb": { - "enable": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/luci/logdog/butler/${platform}", - "location": "bin", - "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "device_os": null, - "device_type": null, - "machine_type": "e2-standard-4", - "os": "Ubuntu-16.04|Ubuntu-18.04", - "pool": "chromium.tests.avd" - } - ], - "named_caches": [ - { - "name": "avd_generic_androidS", - "path": ".android" - }, - { - "name": "system_images_android_S_google_apis_x64", - "path": ".emulator_sdk" - } - ], - "optional_dimensions": { - "60": [ - { - "caches": "avd_generic_androidS" - } - ] - }, - "output_links": [ - { - "link": [ - "https://luci-logdog.appspot.com/v/?s", - "=android%2Fswarming%2Flogcats%2F", - "${TASK_ID}%2F%2B%2Funified_logcats" - ], - "name": "shard #${SHARD_INDEX} logcats" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "vr_android_unittests", - "test_id_prefix": "ninja://chrome/browser/android/vr:vr_android_unittests/" - }, - { - "args": [ - "--gs-results-bucket=chromium-result-details", - "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_androidS.textpb" - ], - "merge": { - "args": [ - "--bucket", - "chromium-result-details", - "--test-name", "weblayer_browsertests" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index aadf44e..eece389 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -995,10 +995,17 @@ 'Lollipop Phone Tester', 'Lollipop Tablet Tester', 'Marshmallow Tablet Tester', + + # Not available for android x86 & x64 platforms since this GN target + # asserts "enable_vr" which is only true for arm & arm64 on android + # platform. See //chrome/android/BUILD.gn and + # //device/vr/buildflags/buildflags.gni 'android-11-x86-fyi-rel', + 'android-12-x64-fyi-rel', 'android-lollipop-arm-rel', 'android-marshmallow-x86-rel-non-cq', 'android-pie-x86-rel', + 'android-pie-arm64-rel', # https://crbug.com/1010211 'ToTAndroid', 'android-asan', # https://crbug.com/964562 @@ -3046,9 +3053,15 @@ 'vr_android_unittests': { 'remove_from': [ 'android-lollipop-arm-rel', + + # Not available for android x86 & x64 platforms since this GN target + # asserts "enable_vr" which is only true for arm & arm64 on android + # platform. See //chrome/browser/android/vr/BUILD.gn and + # //device/vr/buildflags/buildflags.gni 'android-marshmallow-x86-rel-non-cq', 'android-pie-x86-rel', 'android-11-x86-fyi-rel', + 'android-12-x64-fyi-rel', ], }, 'vr_common_unittests': {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index bb04878..acc695f 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -3613,21 +3613,6 @@ ] } ], - "FixUmaCellularMetricsRecording": [ - { - "platforms": [ - "ios" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "FixUmaCellularMetricsRecording" - ] - } - ] - } - ], "FuzzyAppSearch": [ { "platforms": [ @@ -3678,6 +3663,25 @@ ] } ], + "GoogleLensDesktopContextMenuSearch": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LensStandalone" + ] + } + ] + } + ], "GoogleLensSdkIntent": [ { "platforms": [
diff --git a/third_party/blink/common/bluetooth/web_bluetooth_device_id.cc b/third_party/blink/common/bluetooth/web_bluetooth_device_id.cc index 7ba88c0..bca469b 100644 --- a/third_party/blink/common/bluetooth/web_bluetooth_device_id.cc +++ b/third_party/blink/common/bluetooth/web_bluetooth_device_id.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h" +#include <ostream> #include <utility> #include "base/base64.h"
diff --git a/third_party/blink/common/origin_trials/trial_token_validator.cc b/third_party/blink/common/origin_trials/trial_token_validator.cc index 2ed5f823..1bedc49 100644 --- a/third_party/blink/common/origin_trials/trial_token_validator.cc +++ b/third_party/blink/common/origin_trials/trial_token_validator.cc
@@ -15,18 +15,22 @@ #include "third_party/blink/public/common/origin_trials/trial_token.h" #include "third_party/blink/public/common/origin_trials/trial_token_result.h" +namespace blink { namespace { -static base::RepeatingCallback<blink::OriginTrialPolicy*()>& PolicyGetter() { - static base::NoDestructor< - base::RepeatingCallback<blink::OriginTrialPolicy*()>> - policy(base::BindRepeating( - []() -> blink::OriginTrialPolicy* { return nullptr; })); +static base::RepeatingCallback<OriginTrialPolicy*()>& PolicyGetter() { + static base::NoDestructor<base::RepeatingCallback<OriginTrialPolicy*()>> + policy( + base::BindRepeating([]() -> OriginTrialPolicy* { return nullptr; })); return *policy; } -} // namespace -namespace blink { +bool IsDeprecationTrialPossible() { + OriginTrialPolicy* policy = PolicyGetter().Run(); + return policy && policy->IsOriginTrialsSupported(); +} + +} // namespace TrialTokenValidator::TrialTokenValidator() {} @@ -38,8 +42,8 @@ } void TrialTokenValidator::ResetOriginTrialPolicyGetter() { - SetOriginTrialPolicyGetter(base::BindRepeating( - []() -> blink::OriginTrialPolicy* { return nullptr; })); + SetOriginTrialPolicyGetter( + base::BindRepeating([]() -> OriginTrialPolicy* { return nullptr; })); } TrialTokenResult TrialTokenValidator::ValidateToken( @@ -124,13 +128,30 @@ const net::HttpResponseHeaders* response_headers, base::StringPiece feature_name, base::Time current_time) const { - if (!IsTrialPossibleOnOrigin(request_url)) - return false; + return IsTrialPossibleOnOrigin(request_url) && + ResponseBearsValidTokenForFeature(request_url, *response_headers, + feature_name, current_time); +} +bool TrialTokenValidator::RequestEnablesDeprecatedFeature( + const GURL& request_url, + const net::HttpResponseHeaders* response_headers, + base::StringPiece feature_name, + base::Time current_time) const { + return IsDeprecationTrialPossible() && + ResponseBearsValidTokenForFeature(request_url, *response_headers, + feature_name, current_time); +} + +bool TrialTokenValidator::ResponseBearsValidTokenForFeature( + const GURL& request_url, + const net::HttpResponseHeaders& response_headers, + base::StringPiece feature_name, + base::Time current_time) const { url::Origin origin = url::Origin::Create(request_url); size_t iter = 0; std::string token; - while (response_headers->EnumerateHeader(&iter, "Origin-Trial", &token)) { + while (response_headers.EnumerateHeader(&iter, "Origin-Trial", &token)) { TrialTokenResult result = ValidateToken(token, origin, current_time); // TODO(mek): Log the validation errors to histograms? if (result.Status() == OriginTrialTokenStatus::kSuccess)
diff --git a/third_party/blink/common/origin_trials/trial_token_validator_unittest.cc b/third_party/blink/common/origin_trials/trial_token_validator_unittest.cc index e322401..a52e436 100644 --- a/third_party/blink/common/origin_trials/trial_token_validator_unittest.cc +++ b/third_party/blink/common/origin_trials/trial_token_validator_unittest.cc
@@ -443,6 +443,13 @@ Now())); } +TEST_F(TrialTokenValidatorTest, ValidateRequestForDeprecationInsecure) { + response_headers_->AddHeader("Origin-Trial", kInsecureOriginToken); + EXPECT_TRUE(validator_.RequestEnablesDeprecatedFeature( + GURL(kInsecureOrigin), response_headers_.get(), kAppropriateFeatureName, + Now())); +} + TEST_F(TrialTokenValidatorTest, ValidateRequestValidToken) { response_headers_->AddHeader("Origin-Trial", kSampleToken); EXPECT_TRUE(validator_.RequestEnablesFeature(GURL(kAppropriateOrigin), @@ -450,12 +457,25 @@ kAppropriateFeatureName, Now())); } +TEST_F(TrialTokenValidatorTest, ValidateRequestForDeprecationValidToken) { + response_headers_->AddHeader("Origin-Trial", kSampleToken); + EXPECT_TRUE(validator_.RequestEnablesDeprecatedFeature( + GURL(kAppropriateOrigin), response_headers_.get(), + kAppropriateFeatureName, Now())); +} + TEST_F(TrialTokenValidatorTest, ValidateRequestNoTokens) { EXPECT_FALSE(validator_.RequestEnablesFeature( GURL(kAppropriateOrigin), response_headers_.get(), kAppropriateFeatureName, Now())); } +TEST_F(TrialTokenValidatorTest, ValidateRequestForDeprecationNoTokens) { + EXPECT_FALSE(validator_.RequestEnablesDeprecatedFeature( + GURL(kAppropriateOrigin), response_headers_.get(), + kAppropriateFeatureName, Now())); +} + TEST_F(TrialTokenValidatorTest, ValidateRequestMultipleHeaders) { response_headers_->AddHeader("Origin-Trial", kSampleToken); response_headers_->AddHeader("Origin-Trial", kExpiredToken);
diff --git a/third_party/blink/public/common/origin_trials/trial_token_validator.h b/third_party/blink/public/common/origin_trials/trial_token_validator.h index 3d3c220..26a0566 100644 --- a/third_party/blink/public/common/origin_trials/trial_token_validator.h +++ b/third_party/blink/public/common/origin_trials/trial_token_validator.h
@@ -57,15 +57,37 @@ const url::Origin* third_party_origin, base::Time current_time) const; + // |request| must not be nullptr. bool RequestEnablesFeature(const net::URLRequest* request, base::StringPiece feature_name, base::Time current_time) const; + // Returns whether the given response for the given URL enable the named + // Origin or Deprecation Trial at the given time. + // + // |response_headers| must not be nullptr. bool RequestEnablesFeature(const GURL& request_url, const net::HttpResponseHeaders* response_headers, base::StringPiece feature_name, base::Time current_time) const; + // Similar to |RequestEnablesFeature()|, but for Deprecation Trials that may + // be enabled on insecure origins. + // + // For Origin Trials (as opposed to Deprecation Trials) or Deprecation Trials + // that are enabled exclusively on secure origins, use + // |RequestEnablesFeature()| instead. + // + // Functionally, the only difference is that this can return true even if + // |request_url|'s origin is not secure. + // + // |response_headers| must not be nullptr. + bool RequestEnablesDeprecatedFeature( + const GURL& request_url, + const net::HttpResponseHeaders* response_headers, + base::StringPiece feature_name, + base::Time current_time) const; + // Returns all valid tokens in |headers|. std::unique_ptr<FeatureToTokensMap> GetValidTokensFromHeaders( const url::Origin& origin, @@ -84,6 +106,15 @@ static void ResetOriginTrialPolicyGetter(); static bool IsTrialPossibleOnOrigin(const GURL& url); + + private: + // Helper for |RequestEnablesFeature()| and + // |RequestEnablesDeprecatedFeature()|. + bool ResponseBearsValidTokenForFeature( + const GURL& request_url, + const net::HttpResponseHeaders& response_headers, + base::StringPiece feature_name, + base::Time current_time) const; }; // class TrialTokenValidator } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc index 6dc26c3f..9c763e03 100644 --- a/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc
@@ -7,7 +7,6 @@ #include <memory> #include <utility> -#include "base/memory/ptr_util.h" #include "third_party/blink/renderer/core/animation/interpolable_transform_list.h" #include "third_party/blink/renderer/core/animation/length_units_checker.h" #include "third_party/blink/renderer/core/css/css_function_value.h" @@ -24,7 +23,7 @@ namespace { InterpolationValue ConvertTransform(TransformOperations&& transform) { return InterpolationValue( - InterpolableTransformList::Create(std::move(transform))); + std::make_unique<InterpolableTransformList>(std::move(transform))); } InterpolationValue ConvertTransform(const TransformOperations& transform) {
diff --git a/third_party/blink/renderer/core/animation/interpolable_transform_list.cc b/third_party/blink/renderer/core/animation/interpolable_transform_list.cc index 92c9fba..92a6b85d 100644 --- a/third_party/blink/renderer/core/animation/interpolable_transform_list.cc +++ b/third_party/blink/renderer/core/animation/interpolable_transform_list.cc
@@ -10,12 +10,6 @@ namespace blink { // static -std::unique_ptr<InterpolableTransformList> InterpolableTransformList::Create( - TransformOperations&& operations) { - return std::make_unique<InterpolableTransformList>(std::move(operations)); -} - -// static std::unique_ptr<InterpolableTransformList> InterpolableTransformList::ConvertCSSValue(const CSSValue& css_value, const StyleResolverState* state) {
diff --git a/third_party/blink/renderer/core/animation/interpolable_transform_list.h b/third_party/blink/renderer/core/animation/interpolable_transform_list.h index 9275a2e..65f9ca5 100644 --- a/third_party/blink/renderer/core/animation/interpolable_transform_list.h +++ b/third_party/blink/renderer/core/animation/interpolable_transform_list.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLABLE_TRANSFORM_LIST_H_ #include <memory> + #include "third_party/blink/renderer/core/animation/interpolable_value.h" #include "third_party/blink/renderer/platform/transforms/transform_operations.h" #include "third_party/blink/renderer/platform/wtf/casting.h" @@ -22,8 +23,6 @@ InterpolableTransformList(TransformOperations&& operations) : operations_(std::move(operations)) {} - static std::unique_ptr<InterpolableTransformList> Create( - TransformOperations&&); static std::unique_ptr<InterpolableTransformList> ConvertCSSValue( const CSSValue&, const StyleResolverState*);
diff --git a/third_party/blink/renderer/core/animation/interpolable_value.h b/third_party/blink/renderer/core/animation/interpolable_value.h index 0fe3e2eb..54cb5f2 100644 --- a/third_party/blink/renderer/core/animation/interpolable_value.h +++ b/third_party/blink/renderer/core/animation/interpolable_value.h
@@ -8,11 +8,10 @@ #include <memory> #include <utility> -#include "base/memory/ptr_util.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/casting.h" #include "third_party/blink/renderer/platform/wtf/vector.h" +#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" namespace blink { @@ -104,22 +103,15 @@ double value_; }; -class CORE_EXPORT InterpolableList : public InterpolableValue { +class CORE_EXPORT InterpolableList final : public InterpolableValue { public: - // Explicitly delete operator= because MSVC automatically generate - // copy constructors and operator= for dll-exported classes. - // Since InterpolableList is not copyable, automatically generated - // operator= causes MSVC compiler error. - // However, we cannot use DISALLOW_COPY_AND_ASSIGN because InterpolableList - // has its own copy constructor. So just delete operator= here. - InterpolableList& operator=(const InterpolableList&) = delete; - explicit InterpolableList(wtf_size_t size) : values_(size) {} - InterpolableList(const InterpolableList& other) : values_(other.length()) { - for (wtf_size_t i = 0; i < length(); i++) - Set(i, other.values_[i]->Clone()); - } + // Move-only; use Clone() to make a copy. + InterpolableList(const InterpolableList&) = delete; + InterpolableList& operator=(const InterpolableList&) = delete; + InterpolableList(InterpolableList&&) = default; + InterpolableList& operator=(InterpolableList&&) = default; const InterpolableValue* Get(wtf_size_t position) const { return values_[position].get(); @@ -146,7 +138,10 @@ private: InterpolableList* RawClone() const final { - return new InterpolableList(*this); + auto* result = new InterpolableList(length()); + for (wtf_size_t i = 0; i < length(); i++) + result->Set(i, values_[i]->Clone()); + return result; } InterpolableList* RawCloneAndZero() const final;
diff --git a/third_party/blink/renderer/core/css/mathml.css b/third_party/blink/renderer/core/css/mathml.css index 7a26d29..05693cb 100644 --- a/third_party/blink/renderer/core/css/mathml.css +++ b/third_party/blink/renderer/core/css/mathml.css
@@ -35,6 +35,16 @@ /* By default, we only display the MathML formulas without any formatting other than the one specified by the display attribute. */ math { + direction: ltr; + writing-mode: horizontal-tb; + text-indent: 0; + letter-spacing: normal; + line-height: normal; + word-spacing: normal; + /* TODO(1228189): Implement font-family: math */ + font-size: inherited; + font-style: normal; + font-weight: normal; display: inline math; math-shift: normal; math-style: compact; @@ -66,7 +76,7 @@ } merror { - color: red; + border: 1px solid red; background-color: lightYellow; } @@ -124,10 +134,14 @@ munderover[accent="true" i] > :nth-child(3) { font-size: inherit; } - -munder > :nth-child(2), -munderover > :nth-child(2), +msub > :nth-child(2), +msubsup > :nth-child(2), +mmultiscripts > :nth-child(even), +mmultiscripts > mprescripts ~ :nth-child(odd), mover[accent="true" i] > :first-child, munderover[accent="true" i] > :first-child { math-shift: compact; } +mmultiscripts > mprescripts ~ :nth-child(even) { + math-shift: inherit; +}
diff --git a/third_party/blink/renderer/core/layout/layout_inline.cc b/third_party/blink/renderer/core/layout/layout_inline.cc index 601ff3b..be543d9 100644 --- a/third_party/blink/renderer/core/layout/layout_inline.cc +++ b/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -523,6 +523,20 @@ if (!new_child->IsInline() && !new_child->IsFloatingOrOutOfFlowPositioned() && !new_child->IsTablePart()) { + if (UNLIKELY(RuntimeEnabledFeatures::LayoutNGBlockInInlineEnabled())) { + // TODO(crbug.com/716930): This logic is still at the prototype level and + // to be re-written, but landed under the runtime flag to allow us working + // on dependent code in parallel. + DCHECK(!new_child->IsInline()); + auto* anonymous_box = DynamicTo<LayoutBlockFlow>( + before_child ? before_child->PreviousSibling() : LastChild()); + if (!anonymous_box || !anonymous_box->IsAnonymous()) { + anonymous_box = CreateAnonymousContainerForBlockChildren(); + LayoutBoxModelObject::AddChild(anonymous_box, before_child); + } + anonymous_box->AddChild(new_child); + return; + } LayoutBlockFlow* new_box = CreateAnonymousContainerForBlockChildren(); LayoutBoxModelObject* old_continuation = Continuation(); SetContinuation(new_box); @@ -1585,6 +1599,13 @@ void LayoutInline::ChildBecameNonInline(LayoutObject* child) { NOT_DESTROYED(); + if (UNLIKELY(RuntimeEnabledFeatures::LayoutNGBlockInInlineEnabled())) { + DCHECK(!child->IsInline()); + // TODO(crbug.com/716930): Add anonymous blocks as + // |AddChildIgnoringContinuation| does. + NOTIMPLEMENTED(); + return; + } // We have to split the parent flow. LayoutBlockFlow* new_box = CreateAnonymousContainerForBlockChildren(); LayoutBoxModelObject* old_continuation = Continuation();
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.cc index a9cc781..74134a6 100644 --- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.cc
@@ -17,7 +17,7 @@ // Describes the amount to shift the numerator/denominator of the fraction when // a fraction bar is present. Data is populated from the OpenType MATH table. // If the OpenType MATH table is not present fallback values are used. -// https://mathml-refresh.github.io/mathml-core/#fraction-with-nonzero-line-thickness +// https://w3c.github.io/mathml-core/#fraction-with-nonzero-line-thickness struct FractionParameters { LayoutUnit numerator_gap_min; LayoutUnit denominator_gap_min; @@ -72,7 +72,7 @@ // Describes the amount to shift the numerator/denominator of the fraction when // a fraction bar is not present. Data is populated from the OpenType MATH // table. If the OpenType MATH table is not present fallback values are used. -// https://mathml-refresh.github.io/mathml-core/#fraction-with-zero-line-thickness +// https://w3c.github.io/mathml-core/#fraction-with-zero-line-thickness struct FractionStackParameters { LayoutUnit gap_min; LayoutUnit top_shift_up;
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.cc b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.cc index fef9f02..29f63f0 100644 --- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.cc
@@ -90,7 +90,7 @@ } // Valid according to: -// https://mathml-refresh.github.io/mathml-core/#prescripts-and-tensor-indices-mmultiscripts +// https://w3c.github.io/mathml-core/#prescripts-and-tensor-indices-mmultiscripts inline bool IsValidMultiscript(const NGBlockNode& node) { auto child = To<NGBlockNode>(FirstChildInFlow(node)); if (!child || IsPrescriptDelimiter(child)) @@ -185,7 +185,7 @@ MinMaxSizes GetMinMaxSizesForVerticalStretchyOperator( const ComputedStyle& style, UChar character) { - // https://mathml-refresh.github.io/mathml-core/#dfn-preferred-inline-size-of-a-glyph-stretched-along-the-block-axis + // https://w3c.github.io/mathml-core/#dfn-preferred-inline-size-of-a-glyph-stretched-along-the-block-axis const SimpleFontData* font_data = style.GetFont().PrimaryFont(); MinMaxSizes sizes; if (!font_data) @@ -220,7 +220,7 @@ return false; auto base = To<NGBlockNode>(FirstChildInFlow(node)); // TODO(crbug.com/1124298)): - // https://mathml-refresh.github.io/mathml-core/#embellished-operators + // https://w3c.github.io/mathml-core/#embellished-operators if (auto* element = DynamicTo<MathMLOperatorElement>(base.GetDOMNode())) { return element->HasBooleanProperty(MathMLOperatorElement::kMovableLimits); @@ -231,7 +231,7 @@ bool IsOperatorWithSpecialShaping(const NGBlockNode& node) { if (!node.IsBlock() || !node.IsMathML() || !node.FirstChild().IsInline()) return false; - // https://mathml-refresh.github.io/mathml-core/#layout-of-operators + // https://w3c.github.io/mathml-core/#layout-of-operators if (auto* element = DynamicTo<MathMLOperatorElement>(node.GetDOMNode())) { UChar32 base_code_point = element->GetOperatorContent().code_point; if (base_code_point == kNonCharacter ||
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.h b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.h index 61f91bf5..31f31946 100644 --- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.h +++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.h
@@ -39,7 +39,7 @@ bool IsValidMathMLScript(const NGBlockNode&); bool IsValidMathMLRadical(const NGBlockNode&); -// https://mathml-refresh.github.io/mathml-core/#dfn-default-rule-thickness +// https://w3c.github.io/mathml-core/#dfn-default-rule-thickness inline float RuleThicknessFallback(const ComputedStyle& style) { const SimpleFontData* font_data = style.GetFont().PrimaryFont(); if (!font_data) @@ -66,7 +66,7 @@ // Get parameters for horizontal positioning of mroot. // The parameters are defined here: -// https://mathml-refresh.github.io/mathml-core/#layout-constants-mathconstants +// https://w3c.github.io/mathml-core/#layout-constants-mathconstants struct RadicalHorizontalParameters { LayoutUnit kern_before_degree; LayoutUnit kern_after_degree; @@ -76,7 +76,7 @@ // Get parameters for vertical positioning of msqrt/mroot. // The parameters are defined here: -// https://mathml-refresh.github.io/mathml-core/#layout-constants-mathconstants +// https://w3c.github.io/mathml-core/#layout-constants-mathconstants struct RadicalVerticalParameters { LayoutUnit vertical_gap; LayoutUnit rule_thickness; @@ -86,7 +86,7 @@ RadicalVerticalParameters GetRadicalVerticalParameters(const ComputedStyle&, bool has_index); -// https://mathml-refresh.github.io/mathml-core/#dfn-preferred-inline-size-of-a-glyph-stretched-along-the-block-axis +// https://w3c.github.io/mathml-core/#dfn-preferred-inline-size-of-a-glyph-stretched-along-the-block-axis MinMaxSizes GetMinMaxSizesForVerticalStretchyOperator(const ComputedStyle&, UChar character);
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_operator_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_operator_layout_algorithm.cc index d159182..cd7fc84 100644 --- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_operator_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_operator_layout_algorithm.cc
@@ -38,7 +38,7 @@ // properly laid out but the glyph will actually be used to determine a // "large" or "stretched" version, from which we perform measurement and // painting. - // See https://mathml-refresh.github.io/mathml-core/#layout-of-operators + // See https://w3c.github.io/mathml-core/#layout-of-operators NGLayoutInputNode child = Node().FirstChild(); DCHECK(child && child.IsInline()); DCHECK(!child.NextSibling());
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_radical_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_radical_layout_algorithm.cc index 3a5cfd1..d699b6f 100644 --- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_radical_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_radical_layout_algorithm.cc
@@ -93,7 +93,7 @@ } if (index) { // Handle layout of index child. - // (https://mathml-refresh.github.io/mathml-core/#root-with-index). + // (https://w3c.github.io/mathml-core/#root-with-index). NGConstraintSpace constraint_space = CreateConstraintSpaceForMathChild( Node(), ChildAvailableSize(), ConstraintSpace(), index); scoped_refptr<const NGLayoutResult> index_layout_result =
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.cc index 7f360b0..6eafa65 100644 --- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.cc
@@ -29,9 +29,9 @@ // Describes the amount of shift to apply to the sub/sup boxes. // Data is populated from the OpenType MATH table. // If the OpenType MATH table is not present fallback values are used. -// https://mathml-refresh.github.io/mathml-core/#base-with-subscript -// https://mathml-refresh.github.io/mathml-core/#base-with-superscript -// https://mathml-refresh.github.io/mathml-core/#base-with-subscript-and-superscript +// https://w3c.github.io/mathml-core/#base-with-subscript +// https://w3c.github.io/mathml-core/#base-with-superscript +// https://w3c.github.io/mathml-core/#base-with-subscript-and-superscript struct ScriptsVerticalParameters { STACK_ALLOCATED(); @@ -146,7 +146,7 @@ continue; case MathScriptType::kMultiscripts: { // The structure of mmultiscripts is specified here: - // https://mathml-refresh.github.io/mathml-core/#prescripts-and-tensor-indices-mmultiscripts + // https://w3c.github.io/mathml-core/#prescripts-and-tensor-indices-mmultiscripts if (IsPrescriptDelimiter(block_child)) { if (!number_of_scripts_is_even || *prescripts) { NOTREACHED();
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.cc index b75412f5..930daa88 100644 --- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.cc
@@ -19,8 +19,8 @@ // Describes the amount to shift to apply to the under/over boxes. // Data is populated from the OpenType MATH table. // If the OpenType MATH table is not present fallback values are used. -// https://mathml-refresh.github.io/mathml-core/#base-with-underscript -// https://mathml-refresh.github.io/mathml-core/#base-with-overscript +// https://w3c.github.io/mathml-core/#base-with-underscript +// https://w3c.github.io/mathml-core/#base-with-overscript struct UnderOverVerticalParameters { bool use_under_over_bar_fallback; LayoutUnit under_gap_min; @@ -41,7 +41,7 @@ if (!font_data) return parameters; - // https://mathml-refresh.github.io/mathml-core/#dfn-default-fallback-constant + // https://w3c.github.io/mathml-core/#dfn-default-fallback-constant const float default_fallback_constant = 0; if (is_base_large_operator) { @@ -121,7 +121,7 @@ return parameters; } -// https://mathml-refresh.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover +// https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover bool HasAccent(const NGBlockNode& node, bool accent_under) { DCHECK(node); auto* underover = To<MathMLUnderOverElement>(node.GetDOMNode());
diff --git a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h index f19c7d3d..e3f67d9 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h +++ b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
@@ -277,7 +277,7 @@ // Inline/block target stretch size constraints. // See: - // https://mathml-refresh.github.io/mathml-core/#dfn-inline-stretch-size-constraint + // https://w3c.github.io/mathml-core/#dfn-inline-stretch-size-constraint LayoutUnit TargetStretchInlineSize() const { return HasRareData() ? rare_data_->TargetStretchInlineSize() : kIndefiniteSize;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_result.h b/third_party/blink/renderer/core/layout/ng/ng_layout_result.h index 353588fa..1013939 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_result.h +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_result.h
@@ -366,7 +366,7 @@ scoped_refptr<const NGPhysicalFragment> physical_fragment, NGLineBoxFragmentBuilder*); - // See https://mathml-refresh.github.io/mathml-core/#box-model + // See https://w3c.github.io/mathml-core/#box-model struct MathData { LayoutUnit italic_correction_; };
diff --git a/third_party/blink/renderer/core/mathml/mathml_element.h b/third_party/blink/renderer/core/mathml/mathml_element.h index 8d4fcf2..6afe13a 100644 --- a/third_party/blink/renderer/core/mathml/mathml_element.h +++ b/third_party/blink/renderer/core/mathml/mathml_element.h
@@ -50,7 +50,7 @@ void ParseAttribute(const AttributeModificationParams&) override; - // https://mathml-refresh.github.io/mathml-core/#dfn-boolean + // https://w3c.github.io/mathml-core/#dfn-boolean absl::optional<bool> BooleanAttribute(const QualifiedName& name) const; };
diff --git a/third_party/blink/renderer/core/mathml/mathml_fraction_element.cc b/third_party/blink/renderer/core/mathml/mathml_fraction_element.cc index 29147feb..edbf833 100644 --- a/third_party/blink/renderer/core/mathml/mathml_fraction_element.cc +++ b/third_party/blink/renderer/core/mathml/mathml_fraction_element.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/core/mathml/mathml_fraction_element.h" +#include "third_party/blink/renderer/core/css/style_change_reason.h" +#include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { @@ -19,4 +21,20 @@ style.SetMathFractionBarThickness(std::move(*length_or_percentage_value)); } +void MathMLFractionElement::ParseAttribute( + const AttributeModificationParams& param) { + if (GetLayoutObject() && GetLayoutObject()->IsMathML() && + param.name == mathml_names::kLinethicknessAttr && + param.new_value != param.old_value) { + // TODO(crbug.com/1121113): Isn't it enough to set needs style recalc and + // let the style system perform proper layout and paint invalidation? + SetNeedsStyleRecalc( + kLocalStyleChange, + StyleChangeReasonForTracing::Create(style_change_reason::kAttribute)); + GetLayoutObject()->SetNeedsLayoutAndFullPaintInvalidation( + layout_invalidation_reason::kAttributeChanged); + } + MathMLElement::ParseAttribute(param); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/mathml/mathml_fraction_element.h b/third_party/blink/renderer/core/mathml/mathml_fraction_element.h index 65b250c..cf4ae23 100644 --- a/third_party/blink/renderer/core/mathml/mathml_fraction_element.h +++ b/third_party/blink/renderer/core/mathml/mathml_fraction_element.h
@@ -18,6 +18,9 @@ void AddMathFractionBarThicknessIfNeeded(ComputedStyle&, const CSSToLengthConversionData&); + + private: + void ParseAttribute(const AttributeModificationParams&) final; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/mathml/mathml_operator_element.cc b/third_party/blink/renderer/core/mathml/mathml_operator_element.cc index 62f3fa0..f163b140 100644 --- a/third_party/blink/renderer/core/mathml/mathml_operator_element.cc +++ b/third_party/blink/renderer/core/mathml/mathml_operator_element.cc
@@ -34,7 +34,7 @@ return character; } -// https://mathml-refresh.github.io/mathml-core/#operator-dictionary-categories-values +// https://w3c.github.io/mathml-core/#operator-dictionary-categories-values // Leading and trailing spaces are respresented in math units, i.e. 1/18em. struct MathMLOperatorDictionaryProperties { unsigned leading_space_in_math_unit : 3; @@ -145,6 +145,8 @@ param.name == mathml_names::kRspaceAttr) { needs_layout = param.new_value != param.old_value; if (needs_layout && GetLayoutObject()) { + // TODO(crbug.com/1121113): Isn't it enough to set needs style recalc and + // let the style system perform proper layout and paint invalidation? SetNeedsStyleRecalc( kLocalStyleChange, StyleChangeReasonForTracing::Create(style_change_reason::kAttribute)); @@ -158,7 +160,7 @@ MathMLElement::ParseAttribute(param); } -// https://mathml-refresh.github.io/mathml-core/#dfn-algorithm-for-determining-the-properties-of-an-embellished-operator +// https://w3c.github.io/mathml-core/#dfn-algorithm-for-determining-the-properties-of-an-embellished-operator void MathMLOperatorElement::ComputeDictionaryCategory() { if (properties_.dictionary_category != MathMLOperatorDictionaryCategory::kUndefined) @@ -170,7 +172,7 @@ // We first determine the form attribute and use the default spacing and // properties. - // https://mathml-refresh.github.io/mathml-core/#dfn-form + // https://w3c.github.io/mathml-core/#dfn-form const auto& value = FastGetAttribute(mathml_names::kFormAttr); bool explicit_form = true; MathMLOperatorDictionaryForm form; @@ -183,7 +185,7 @@ } else { // TODO(crbug.com/1121113): Implement the remaining rules for determining // form. - // https://mathml-refresh.github.io/mathml-core/#dfn-algorithm-for-determining-the-form-of-an-embellished-operator + // https://w3c.github.io/mathml-core/#dfn-algorithm-for-determining-the-form-of-an-embellished-operator explicit_form = false; if (!previousSibling() && nextSibling()) form = MathMLOperatorDictionaryForm::kPrefix; @@ -195,7 +197,7 @@ // We then try and find an entry in the operator dictionary to override the // default values. - // https://mathml-refresh.github.io/mathml-core/#dfn-algorithm-for-determining-the-properties-of-an-embellished-operator + // https://w3c.github.io/mathml-core/#dfn-algorithm-for-determining-the-properties-of-an-embellished-operator auto category = FindCategory(GetOperatorContent().characters, form); if (category != MathMLOperatorDictionaryCategory::kNone) { // Step 2. @@ -226,7 +228,7 @@ DCHECK(properties_.dirty_flags & flag); const auto& name = OperatorPropertyFlagToAttributeName(flag); if (absl::optional<bool> value = BooleanAttribute(name)) { - // https://mathml-refresh.github.io/mathml-core/#dfn-algorithm-for-determining-the-properties-of-an-embellished-operator + // https://w3c.github.io/mathml-core/#dfn-algorithm-for-determining-the-properties-of-an-embellished-operator // Step 1. if (*value) { properties_.flags |= flag;
diff --git a/third_party/blink/renderer/core/mathml/mathml_padded_element.cc b/third_party/blink/renderer/core/mathml/mathml_padded_element.cc index 6f54654d..d647e10 100644 --- a/third_party/blink/renderer/core/mathml/mathml_padded_element.cc +++ b/third_party/blink/renderer/core/mathml/mathml_padded_element.cc
@@ -48,6 +48,8 @@ const AttributeModificationParams& param) { if (param.name == mathml_names::kLspaceAttr || param.name == mathml_names::kVoffsetAttr) { + // TODO(crbug.com/1121113): Isn't it enough to set needs style recalc and + // let the style system perform proper layout and paint invalidation? SetNeedsStyleRecalc( kLocalStyleChange, StyleChangeReasonForTracing::Create(style_change_reason::kAttribute));
diff --git a/third_party/blink/renderer/core/timing/performance.cc b/third_party/blink/renderer/core/timing/performance.cc index 078d3ae..03554c86 100644 --- a/third_party/blink/renderer/core/timing/performance.cc +++ b/third_party/blink/renderer/core/timing/performance.cc
@@ -768,12 +768,12 @@ const AtomicString& mark_name, PerformanceMarkOptions* mark_options, ExceptionState& exception_state) { - DEFINE_STATIC_LOCAL(const AtomicString, mark_fully_loaded, - ("mark_fully_loaded")); - DEFINE_STATIC_LOCAL(const AtomicString, mark_fully_visible, - ("mark_fully_visible")); - DEFINE_STATIC_LOCAL(const AtomicString, mark_interactive, - ("mark_interactive")); + DEFINE_THREAD_SAFE_STATIC_LOCAL(const AtomicString, mark_fully_loaded, + ("mark_fully_loaded")); + DEFINE_THREAD_SAFE_STATIC_LOCAL(const AtomicString, mark_fully_visible, + ("mark_fully_visible")); + DEFINE_THREAD_SAFE_STATIC_LOCAL(const AtomicString, mark_interactive, + ("mark_interactive")); if (mark_options && (mark_options->hasStartTime() || mark_options->hasDetail())) { UseCounter::Count(GetExecutionContext(), WebFeature::kUserTimingL3);
diff --git a/third_party/blink/renderer/core/timing/profiler.idl b/third_party/blink/renderer/core/timing/profiler.idl index 7a26ff9..649f087 100644 --- a/third_party/blink/renderer/core/timing/profiler.idl +++ b/third_party/blink/renderer/core/timing/profiler.idl
@@ -3,7 +3,7 @@ // found in the LICENSE file. // https://wicg.github.io/js-self-profiling/#the-profiler-interface -[Exposed=(Window,Worker), RuntimeEnabled=ExperimentalJSProfiler] +[Exposed=Window, RuntimeEnabled=ExperimentalJSProfiler] interface Profiler : EventTarget { readonly attribute DOMHighResTimeStamp sampleInterval; readonly attribute boolean stopped;
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn index 26cc3459..9d6ab18 100644 --- a/third_party/blink/renderer/modules/BUILD.gn +++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -256,10 +256,28 @@ ":make_modules_generated_event_target_names", ":make_modules_generated_indexed_db_names", ":make_modules_generated_media_capabilities_names", + "//components/payments/mojom:mojom_blink_headers", + "//components/schema_org/common:mojom_blink_headers", + "//components/services/filesystem/public/mojom:mojom_blink_headers", + "//device/bluetooth/public/mojom:mojom_blink_headers", + "//device/gamepad/public/mojom:mojom_blink_headers", + "//device/vr/public/mojom:vr_service_blink_headers", + "//media/capture/mojom:image_capture_blink_headers", + "//media/midi:mojo_blink_headers", + "//services/device/public/mojom:generic_sensor_headers", + "//services/device/public/mojom:mojom_blink_headers", + "//services/device/public/mojom:usb_blink_headers", + "//services/shape_detection/public/mojom:mojom_blink_headers", + "//third_party/blink/public/mojom:mojom_modules_blink_headers", "//third_party/blink/renderer/bindings/modules/v8:generated", "//third_party/blink/renderer/core:core_event_interfaces", "//third_party/blink/renderer/modules/mediarecorder:buildflags", + "//ui/accessibility:ax_enums_mojo_blink_headers", + "//ui/display/mojom:mojom_blink_headers", ] + if (is_fuchsia) { + public_deps += [ "//media/fuchsia/mojom:mojom_blink_headers" ] + } } # generate_event_interfaces ----------------------------------------------------
diff --git a/third_party/blink/renderer/modules/sanitizer_api/BUILD.gn b/third_party/blink/renderer/modules/sanitizer_api/BUILD.gn index c471a49c..c8413c3 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/BUILD.gn +++ b/third_party/blink/renderer/modules/sanitizer_api/BUILD.gn
@@ -26,12 +26,14 @@ corpus_source_config = [ # These match source files: corpus/*.txt "config1", "config2", + "config3", "default", ] corpus_source_html = [ # These match source files: corpus/*.html "simple1", "simple2", "simple3", + "simple4", "medium1", "medium2", "medium3",
diff --git a/third_party/blink/renderer/modules/sanitizer_api/corpus/config3.txt b/third_party/blink/renderer/modules/sanitizer_api/corpus/config3.txt new file mode 100644 index 0000000..473485c6 --- /dev/null +++ b/third_party/blink/renderer/modules/sanitizer_api/corpus/config3.txt
@@ -0,0 +1,9 @@ +allow_elements: "div" +allow_elements: "p" +allow_elements: "span" +allow_elements: "em" +allow_elements: "b" +allow_elements: "h1" +allow_elements: "h2" +allow_elements: "h3" +allow_comments: true
diff --git a/third_party/blink/renderer/modules/sanitizer_api/corpus/simple4.html b/third_party/blink/renderer/modules/sanitizer_api/corpus/simple4.html new file mode 100644 index 0000000..9f490c7 --- /dev/null +++ b/third_party/blink/renderer/modules/sanitizer_api/corpus/simple4.html
@@ -0,0 +1,4 @@ +<div onclick="alert(1)"> + <!-- a comment --> + <p>Hello <strong>World!</p> +</div>
diff --git a/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.cc b/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.cc index 9bdf112..4b052ba4 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.cc +++ b/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.cc
@@ -8,13 +8,12 @@ namespace blink { -void ElementSanitizer::SetSanitizedHTML(ScriptState* script_state, - Element& element, - const String& markup, - Sanitizer* sanitizer, - ExceptionState& exception_state) { - sanitizer->ElementSetSanitizedHTML(script_state, element, markup, - exception_state); +void ElementSanitizer::SetHTML(ScriptState* script_state, + Element& element, + const String& markup, + Sanitizer* sanitizer, + ExceptionState& exception_state) { + sanitizer->ElementSetHTML(script_state, element, markup, exception_state); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.h b/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.h index dd7ed20..5f5bf03 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.h +++ b/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.h
@@ -17,11 +17,11 @@ class MODULES_EXPORT ElementSanitizer final { public: - static void SetSanitizedHTML(ScriptState*, - Element&, - const String&, - Sanitizer*, - ExceptionState&); + static void SetHTML(ScriptState*, + Element&, + const String&, + Sanitizer*, + ExceptionState&); }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.idl b/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.idl index 1700c3b..38af2f5d 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.idl +++ b/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.idl
@@ -8,8 +8,6 @@ RuntimeEnabled=SanitizerAPI, ImplementedAs=ElementSanitizer ] partial interface Element { - // TODO(vogelheim): This name is likely going to change. Adapt when the - // standards PR changes as well. - [CEReactions, RaisesException, CallWith=ScriptState, MeasureAs=SanitizerAPIElementSetSanitized] void SetSanitizedHTML(DOMString markup, Sanitizer sanitizer); + [CEReactions, RaisesException, CallWith=ScriptState, MeasureAs=SanitizerAPIElementSetSanitized] void SetHTML(DOMString markup, Sanitizer sanitizer); };
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc index 6dfc71c..1c6d7469 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc +++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc
@@ -47,7 +47,8 @@ return !config || (!config->hasDropElements() && !config->hasBlockElements() && !config->hasAllowElements() && !config->hasDropAttributes() && - !config->hasAllowAttributes() && !config->hasAllowCustomElements()); + !config->hasAllowAttributes() && !config->hasAllowCustomElements() && + !config->hasAllowComments()); } SanitizerConfig* SanitizerConfigCopy(const SanitizerConfig* config) { @@ -61,6 +62,9 @@ if (config->hasAllowCustomElements()) { copy->setAllowCustomElements(config->allowCustomElements()); } + if (config->hasAllowComments()) { + copy->setAllowComments(config->allowComments()); + } if (config->hasAllowElements()) { copy->setAllowElements(config->allowElements()); } @@ -140,10 +144,10 @@ return element; } -void Sanitizer::ElementSetSanitizedHTML(ScriptState* script_state, - Element& element, - const String& markup, - ExceptionState& exception_state) { +void Sanitizer::ElementSetHTML(ScriptState* script_state, + Element& element, + const String& markup, + ExceptionState& exception_state) { Element* new_element = sanitizeFor(script_state, element.localName(), markup, exception_state); if (!new_element || exception_state.HadException()) @@ -205,63 +209,83 @@ Node* node = fragment->firstChild(); while (node) { - // Skip non-Element nodes. - if (node->getNodeType() != Node::NodeType::kElementNode) { - node = NodeTraversal::Next(*node, fragment); - continue; - } + switch (node->getNodeType()) { + case Node::NodeType::kElementNode: { + // TODO(crbug.com/1126936): Review the sanitising algorithm for + // non-HTMLs. + // 1. Let |name| be |element|'s tag name. + String name = node->nodeName().UpperASCII(); - // TODO(crbug.com/1126936): Review the sanitising algorithm for non-HTMLs. - // 1. Let |name| be |element|'s tag name. - String name = node->nodeName().UpperASCII(); + // 2. Detect whether current element is a custom element or not. + bool is_custom_element = + CustomElement::IsValidName(AtomicString(name.LowerASCII()), false); - // 2. Detect whether current element is a custom element or not. - bool is_custom_element = - CustomElement::IsValidName(AtomicString(name.LowerASCII()), false); - - // 3. If |kind| is `regular` and if |name| is not contained in the - // default element allow list, then 'drop' - if (baseline_drop_elements_.Contains(name)) { - node = DropElement(node, fragment); - UseCounter::Count(window->GetExecutionContext(), - WebFeature::kSanitizerAPIActionTaken); - } else if (is_custom_element && !config_.allow_custom_elements_) { - // 4. If |kind| is `custom` and if allow_custom_elements_ is unset or set - // to anything other than `true`, then 'drop'. - node = DropElement(node, fragment); - UseCounter::Count(window->GetExecutionContext(), - WebFeature::kSanitizerAPIActionTaken); - } else if (!node->IsHTMLElement()) { - // Presently unspec-ed: If |node| is in a non-HTML namespace: Drop. - node = DropElement(node, fragment); - UseCounter::Count(window->GetExecutionContext(), - WebFeature::kSanitizerAPIActionTaken); - } else if (config_.drop_elements_.Contains(name)) { - // 5. If |name| is in |config|'s [=element drop list=] then 'drop'. - node = DropElement(node, fragment); - UseCounter::Count(window->GetExecutionContext(), - WebFeature::kSanitizerAPIActionTaken); - } else if (config_.block_elements_.Contains(name)) { - // 6. If |name| is in |config|'s [=element block list=] then 'block'. - node = BlockElement(node, fragment, exception_state); - UseCounter::Count(window->GetExecutionContext(), - WebFeature::kSanitizerAPIActionTaken); - } else if (!config_.allow_elements_.Contains(name)) { - // 7. if |name| is not in |config|'s [=element allow list=] then 'block'. - node = BlockElement(node, fragment, exception_state); - UseCounter::Count(window->GetExecutionContext(), - WebFeature::kSanitizerAPIActionTaken); - } else if (IsA<HTMLTemplateElement>(node)) { - // 8. If |element|'s [=element interface=] is {{HTMLTemplateElement}} - // Run the steps of the [=sanitize document fragment=] algorithm on - // |element|'s |content| attribute. - DoSanitizing(To<HTMLTemplateElement>(node)->content(), window, - exception_state); - UseCounter::Count(window->GetExecutionContext(), - WebFeature::kSanitizerAPIActionTaken); - node = KeepElement(node, fragment, name, window); - } else { - node = KeepElement(node, fragment, name, window); + // 3. If |kind| is `regular` and if |name| is not contained in the + // default element allow list, then 'drop' + if (baseline_drop_elements_.Contains(name)) { + node = DropElement(node, fragment); + UseCounter::Count(window->GetExecutionContext(), + WebFeature::kSanitizerAPIActionTaken); + } else if (is_custom_element && !config_.allow_custom_elements_) { + // 4. If |kind| is `custom` and if allow_custom_elements_ is unset or + // set to anything other than `true`, then 'drop'. + node = DropElement(node, fragment); + UseCounter::Count(window->GetExecutionContext(), + WebFeature::kSanitizerAPIActionTaken); + } else if (!node->IsHTMLElement()) { + // Presently unspec-ed: If |node| is in a non-HTML namespace: Drop. + node = DropElement(node, fragment); + UseCounter::Count(window->GetExecutionContext(), + WebFeature::kSanitizerAPIActionTaken); + } else if (config_.drop_elements_.Contains(name)) { + // 5. If |name| is in |config|'s [=element drop list=] then 'drop'. + node = DropElement(node, fragment); + UseCounter::Count(window->GetExecutionContext(), + WebFeature::kSanitizerAPIActionTaken); + } else if (config_.block_elements_.Contains(name)) { + // 6. If |name| is in |config|'s [=element block list=] then 'block'. + node = BlockElement(node, fragment, exception_state); + UseCounter::Count(window->GetExecutionContext(), + WebFeature::kSanitizerAPIActionTaken); + } else if (!config_.allow_elements_.Contains(name)) { + // 7. if |name| is not in |config|'s [=element allow list=] then + // 'block'. + node = BlockElement(node, fragment, exception_state); + UseCounter::Count(window->GetExecutionContext(), + WebFeature::kSanitizerAPIActionTaken); + } else if (IsA<HTMLTemplateElement>(node)) { + // 8. If |element|'s [=element interface=] is {{HTMLTemplateElement}} + // Run the steps of the [=sanitize document fragment=] algorithm on + // |element|'s |content| attribute. + DoSanitizing(To<HTMLTemplateElement>(node)->content(), window, + exception_state); + UseCounter::Count(window->GetExecutionContext(), + WebFeature::kSanitizerAPIActionTaken); + node = KeepElement(node, fragment, name, window); + } else { + node = KeepElement(node, fragment, name, window); + } + break; + } + case Node::NodeType::kTextNode: + // Text node: Keep (by skipping over it). + node = NodeTraversal::Next(*node, fragment); + break; + case Node::NodeType::kCommentNode: + // Comment: Drop (unless allowed by config). + node = config_.allow_comments_ ? NodeTraversal::Next(*node, fragment) + : DropElement(node, fragment); + break; + case Node::NodeType::kDocumentNode: + case Node::NodeType::kDocumentFragmentNode: + // Document & DocumentFragment: Drop (unless it's the root). + node = !node->parentNode() ? NodeTraversal::Next(*node, fragment) + : DropElement(node, fragment); + break; + default: + // Default: Drop anything not explicitly handled. + node = DropElement(node, fragment); + break; } } }
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h index 77ba12f..000541d 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h +++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h
@@ -52,12 +52,12 @@ SanitizerConfig* getConfiguration() const; static SanitizerConfig* getDefaultConfiguration(); - // Implementation of ElementSanitizer::SetSanitizedHTML, so that we have + // Implementation of ElementSanitizer::SetHTML, so that we have // all the sanitizer logic in one place. - void ElementSetSanitizedHTML(ScriptState* script_state, - Element& element, - const String& markup, - ExceptionState& exception_state); + void ElementSetHTML(ScriptState* script_state, + Element& element, + const String& markup, + ExceptionState& exception_state); void Trace(Visitor*) const override;
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc index 06198eb4..68dd6b09 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc +++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc
@@ -7,11 +7,12 @@ // To test out locally: // - Assuming // $OUT is your local build output directory with use_libbfuzzer set. -// $GEN is the suitable 'gen' directory under $OUT. $GEN is -// $OUT/gen/third_party_blink/renderer/modules/sanitizer_api. +// $GEN is the suitable 'gen' directory under $OUT. +// // - Build: // $ ninja -C $OUT sanitizer_api_fuzzer // - Run with: +// $ GEN=$OUT/gen/third_party/blink/renderer/modules/sanitizer_api // $ $OUT/sanitizer_api_fuzzer --dict=$GEN/sanitizer_api.dict \ // $(mktemp -d) $GEN/corpus/ @@ -77,6 +78,7 @@ sanitizer_config->setDropAttributes(drop_attributes); } sanitizer_config->setAllowCustomElements(proto.allow_custom_elements()); + sanitizer_config->setAllowComments(proto.allow_comments()); } void TextProtoFuzzer(const SanitizerConfigProto& proto,
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.idl b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.idl index c5c3c860..d05aebb 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.idl +++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.idl
@@ -11,4 +11,5 @@ record<DOMString, sequence<DOMString>> allowAttributes; record<DOMString, sequence<DOMString>> dropAttributes; boolean allowCustomElements; + boolean allowComments; };
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto index d12277b6..c555303e 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto +++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto
@@ -16,6 +16,7 @@ map<string, Elements> drop_attributes = 6; optional bool allow_custom_elements = 7; + optional bool allow_comments = 8; enum StringContext { TEMPLATE = 0;
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config_impl.cc b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config_impl.cc index e9b186e..de0e422f 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config_impl.cc +++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config_impl.cc
@@ -329,6 +329,7 @@ impl.allow_custom_elements_ = config->hasAllowCustomElements() && config->allowCustomElements(); + impl.allow_comments_ = config->hasAllowComments() && config->allowComments(); // Format dropElements to uppercase. if (config->hasDropElements()) {
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config_impl.h b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config_impl.h index b2d0bff6..4ef86d9 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config_impl.h +++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config_impl.h
@@ -30,6 +30,7 @@ HashMap<String, Vector<String>> allow_attributes_; HashMap<String, Vector<String>> drop_attributes_; bool allow_custom_elements_; + bool allow_comments_; // Create a SantizerConfigImpl from a SanitizerConfig. // Will use the default config if it received nullptr.
diff --git a/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h b/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h index a5d640e1..cb8566c2 100644 --- a/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h +++ b/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h
@@ -30,7 +30,7 @@ bool is_extender; }; - // https://mathml-refresh.github.io/mathml-core/#the-glyphassembly-table + // https://w3c.github.io/mathml-core/#the-glyphassembly-table struct AssemblyParameters { float connector_overlap{0}; unsigned repetition_count{0};
diff --git a/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.cc b/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.cc index fc2dc146..823a1ff20 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.cc
@@ -48,7 +48,7 @@ : HB_DIRECTION_BTT; // Go over the assembly parts and determine parameters used below. - // https://mathml-refresh.github.io/mathml-core/#the-glyphassembly-table + // https://w3c.github.io/mathml-core/#the-glyphassembly-table float min_connector_overlap = HarfBuzzUnitsToFloat( hb_ot_math_get_min_connector_overlap(hb_font, hb_stretch_axis)); float max_connector_overlap = std::numeric_limits<float>::max();
diff --git a/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h b/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h index eb78f22..07d13396 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h +++ b/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h
@@ -22,7 +22,7 @@ // TODO(https://crbug.com/1057589): Add a TextDirection parameter, so that it's // possible to perform glyph-level (rtlm feature) or character-level mirroring // before stretching. -// https://mathml-refresh.github.io/mathml-core/#algorithms-for-glyph-stretching +// https://w3c.github.io/mathml-core/#algorithms-for-glyph-stretching class PLATFORM_EXPORT StretchyOperatorShaper final { DISALLOW_NEW(); @@ -40,8 +40,7 @@ // Shape the stretched operator. The coordinates of the glyph(s) use the same // origin as the rectangle assigned to the optional OUT Metrics parameter. // May be called multiple times; font and direction may vary between calls. - // https://mathml-refresh.github.io/mathml-core/#dfn-shape-a-stretchy-glyph - // https://mathml-refresh.github.io/mathml-core/#dfn-box-metrics-of-a-stretchy-glyph + // https://w3c.github.io/mathml-core/#dfn-shape-a-stretchy-glyph scoped_refptr<ShapeResult> Shape(const Font*, float target_size, Metrics* metrics = nullptr) const;
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource.cc b/third_party/blink/renderer/platform/graphics/canvas_resource.cc index 57ac2e8..f6d0946 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource.cc
@@ -354,7 +354,8 @@ context_provider_wrapper_->ContextProvider() ->GetCapabilities()) : GL_TEXTURE_2D), - use_oop_rasterization_(context_provider_wrapper_->ContextProvider() + use_oop_rasterization_(is_accelerated && + context_provider_wrapper_->ContextProvider() ->GetCapabilities() .supports_oop_raster) { auto* gpu_memory_buffer_manager = @@ -420,13 +421,14 @@ if (use_oop_rasterization_) return; + // For the non-accelerated case, writes are done on the CPU. So we don't need + // a texture for reads or writes. + if (!is_accelerated_) + return; + owning_thread_data().texture_id_for_read_access = raster_interface->CreateAndConsumeForGpuRaster(shared_image_mailbox); - // For the non-accelerated case, writes are done on the CPU. So we don't need - // a texture for writes. - if (!is_accelerated_) - return; if (shared_image_usage_flags & gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE) { owning_thread_data().texture_id_for_write_access =
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc index ea54d7c..44bf691 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -986,7 +986,7 @@ // If we cannot use overlay, we have to remove the scanout flag and the // concurrent read write flag. if (!is_gpu_memory_buffer_image_allowed || - !capabilities.texture_storage_image) { + (is_accelerated && !capabilities.texture_storage_image)) { shared_image_usage_flags &= ~gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE; shared_image_usage_flags &= ~gpu::SHARED_IMAGE_USAGE_SCANOUT; }
diff --git a/third_party/blink/renderer/platform/graphics/logging_canvas.cc b/third_party/blink/renderer/platform/graphics/logging_canvas.cc index ce77220f..2108a4fb 100644 --- a/third_party/blink/renderer/platform/graphics/logging_canvas.cc +++ b/third_party/blink/renderer/platform/graphics/logging_canvas.cc
@@ -340,8 +340,11 @@ paint_item->SetString("strokeCap", StrokeCapName(paint.getStrokeCap())); paint_item->SetString("strokeJoin", StrokeJoinName(paint.getStrokeJoin())); paint_item->SetString("styleName", StyleName(paint.getStyle())); - if (paint.getBlendMode() != SkBlendMode::kSrcOver) - paint_item->SetString("blendMode", SkBlendMode_Name(paint.getBlendMode())); + const auto bm = paint.asBlendMode(); + if (bm != SkBlendMode::kSrcOver) { + paint_item->SetString("blendMode", + bm ? SkBlendMode_Name(bm.value()) : "custom"); + } if (paint.getImageFilter()) paint_item->SetString("imageFilter", "SkImageFilter"); return paint_item;
diff --git a/third_party/blink/renderer/platform/text/character.cc b/third_party/blink/renderer/platform/text/character.cc index 33dcbdfc..4b6da15 100644 --- a/third_party/blink/renderer/platform/text/character.cc +++ b/third_party/blink/renderer/platform/text/character.cc
@@ -276,7 +276,7 @@ hint_char_script != USCRIPT_COMMON; } -// https://mathml-refresh.github.io/mathml-core/#stretchy-operator-axis +// https://w3c.github.io/mathml-core/#stretchy-operator-axis static const UChar stretchy_operator_with_inline_axis[]{ 0x003D, 0x005E, 0x005F, 0x007E, 0x00AF, 0x02C6, 0x02C7, 0x02C9, 0x02CD, 0x02DC, 0x02F7, 0x0302, 0x0332, 0x203E, 0x20D0, 0x20D1, 0x20D6, 0x20D7,
diff --git a/third_party/blink/renderer/platform/text/character_test.cc b/third_party/blink/renderer/platform/text/character_test.cc index d3041b0..cb8e8cf 100644 --- a/third_party/blink/renderer/platform/text/character_test.cc +++ b/third_party/blink/renderer/platform/text/character_test.cc
@@ -412,7 +412,7 @@ } TEST(CharacterTest, IsVerticalMathCharacter) { - // https://mathml-refresh.github.io/mathml-core/#stretchy-operator-axis + // https://w3c.github.io/mathml-core/#stretchy-operator-axis const UChar stretchy_operator_with_inline_axis[]{ 0x003D, 0x005E, 0x005F, 0x007E, 0x00AF, 0x02C6, 0x02C7, 0x02C9, 0x02CD, 0x02DC, 0x02F7, 0x0302, 0x0332, 0x203E, 0x20D0, 0x20D1, 0x20D6, 0x20D7,
diff --git a/third_party/blink/renderer/platform/text/mathml_operator_dictionary.cc b/third_party/blink/renderer/platform/text/mathml_operator_dictionary.cc index 16a1e90..a75cb89 100644 --- a/third_party/blink/renderer/platform/text/mathml_operator_dictionary.cc +++ b/third_party/blink/renderer/platform/text/mathml_operator_dictionary.cc
@@ -10,12 +10,12 @@ namespace { -// https://mathml-refresh.github.io/mathml-core/#operator-dictionary-compact-special-tables +// https://w3c.github.io/mathml-core/#operator-dictionary-compact-special-tables const char* operators_2_ascii_chars[] = { "!!", "!=", "&&", "**", "*=", "++", "+=", "--", "-=", "->", "..", "//", "/=", ":=", "<=", "<>", "==", ">=", "||"}; -// https://mathml-refresh.github.io/mathml-core/#operator-dictionary-categories-hexa-table +// https://w3c.github.io/mathml-core/#operator-dictionary-categories-hexa-table struct EntryRange { uint16_t entry; unsigned range_bounds_delta : 4; @@ -30,7 +30,7 @@ // The following representation is taken from the spec, and reduces storage // requirements by mapping codepoints and category to better make use of the // available bytes. For details see -// https://mathml-refresh.github.io/mathml-core/#operator-dictionary. +// https://w3c.github.io/mathml-core/#operator-dictionary. static const EntryRange compact_dictionary[] = { {0x8025, 0}, {0x802A, 0}, {0x402B, 0}, {0x402D, 0}, {0x802E, 0}, {0x402F, 0}, {0x803F, 1}, {0xC05C, 0}, {0x805E, 1}, {0x807C, 0}, @@ -126,7 +126,7 @@ return MathMLOperatorDictionaryCategory::kNone; // Handle special categories that are not encoded in the compact dictionary. - // https://mathml-refresh.github.io/mathml-core/#operator-dictionary-categories-values + // https://w3c.github.io/mathml-core/#operator-dictionary-categories-values if (form == MathMLOperatorDictionaryForm::kPrefix && ((kDoubleStruckItalicCapitalDCharacter <= key && key <= kDoubleStruckItalicSmallDCharacter) || @@ -169,7 +169,7 @@ return MathMLOperatorDictionaryCategory::kNone; // An entry is found: set the properties according the category. - // https://mathml-refresh.github.io/mathml-core/#operator-dictionary-categories-values + // https://w3c.github.io/mathml-core/#operator-dictionary-categories-values switch (ExtractCategory(*entry_range)) { case 0x0: return MathMLOperatorDictionaryCategory::kA;
diff --git a/third_party/blink/renderer/platform/text/mathml_operator_dictionary.h b/third_party/blink/renderer/platform/text/mathml_operator_dictionary.h index 3e3c2db..bd1cdba 100644 --- a/third_party/blink/renderer/platform/text/mathml_operator_dictionary.h +++ b/third_party/blink/renderer/platform/text/mathml_operator_dictionary.h
@@ -30,7 +30,7 @@ // FindCategory takes a UTF-16 string and form (infix, prefix, postfix) as input // and returns the operator dictionary category for this pair, see: -// https://mathml-refresh.github.io/mathml-core/#operator-dictionary +// https://w3c.github.io/mathml-core/#operator-dictionary // The returned value is never MathMLOperatorDictionaryCategory::kUndefined. PLATFORM_EXPORT MathMLOperatorDictionaryCategory FindCategory(const String& content, MathMLOperatorDictionaryForm);
diff --git a/third_party/blink/renderer/platform/wtf/text/math_transform.cc b/third_party/blink/renderer/platform/wtf/text/math_transform.cc index 1d76435..1d0612f 100644 --- a/third_party/blink/renderer/platform/wtf/text/math_transform.cc +++ b/third_party/blink/renderer/platform/wtf/text/math_transform.cc
@@ -32,7 +32,7 @@ // earlier is added to obtain the final code point. UChar32 transformed_char = base_char + kMathBoldUpperA + (kMathItalicUpperA - kMathBoldUpperA); - // https://mathml-refresh.github.io/mathml-core/#italic-mappings + // https://w3c.github.io/mathml-core/#italic-mappings if (transformed_char == 0x1D455) return 0x210E; return transformed_char;
diff --git a/third_party/blink/renderer/platform/wtf/text/math_transform_test.cc b/third_party/blink/renderer/platform/wtf/text/math_transform_test.cc index 1c56a5c..5b8871c 100644 --- a/third_party/blink/renderer/platform/wtf/text/math_transform_test.cc +++ b/third_party/blink/renderer/platform/wtf/text/math_transform_test.cc
@@ -10,7 +10,7 @@ namespace { -// https://mathml-refresh.github.io/mathml-core/#italic-mappings +// https://w3c.github.io/mathml-core/#italic-mappings TEST(MathTransform, Italics) { static struct ItalicsTestData { UChar32 code_point;
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 63956b5..057db1e 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1102,6 +1102,7 @@ virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-list-item-005.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-list-item-006.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-nested-balancing-004.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-scroll-content.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-006.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-007.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-008.html [ Pass ] @@ -4778,7 +4779,6 @@ crbug.com/1207342 http/tests/devtools/sources/debugger-ui/debugger-expand-scope.js [ Pass Failure ] crbug.com/1207342 http/tests/devtools/sources/debugger-ui/script-formatter-breakpoints-3.js [ Pass Failure ] crbug.com/1207342 http/tests/devtools/sources/debugger-ui/scripts-sorting.js [ Pass Failure ] -crbug.com/1207342 http/tests/devtools/sources/debugger-ui/debugger-inline-values.js [ Pass Failure ] crbug.com/1207342 http/tests/devtools/sources/debugger-ui/switch-file.js [ Pass Failure ] crbug.com/1207342 http/tests/devtools/sources/debugger-ui/watch-expressions-preserve-expansion.js [ Pass Failure ] crbug.com/1207342 http/tests/devtools/sources/debugger-ui/copy-stack-trace.js [ Pass Failure ] @@ -6074,7 +6074,6 @@ crbug.com/1046784 [ Linux ] http/tests/devtools/tracing/timeline-misc/timeline-event-causes.js [ Failure Pass ] # Sheriff 2020-07-23 -crbug.com/1108728 [ Mac ] external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/opener-accessed_openee-coop-ro.https.html [ Failure ] crbug.com/1108786 [ Mac ] http/tests/devtools/tracing/timeline-js/timeline-gc-event.js [ Failure Pass ] crbug.com/1108786 [ Linux ] http/tests/devtools/tracing/timeline-js/timeline-gc-event.js [ Failure Pass ] @@ -7298,5 +7297,5 @@ crbug.com/1227092 [ Win ] virtual/scroll-unification/fast/events/selection-autoscroll-borderbelt.html [ Failure Pass ] # Sheriff 2021-07-12 -crbug.com/1228149 virtual/shared_array_buffer_on_desktop/http/tests/devtools/sources/debugger-ui/debugger-inline-values.js [ Pass Timeout ] -crbug.com/1228149 virtual/shared_array_buffer_on_desktop/http/tests/devtools/sources/debugger-ui/debugger-inline-values-frames.js [ Pass Timeout ] +crbug.com/1228149 http/tests/devtools/sources/debugger-ui/debugger-inline-values.js [ Pass Timeout ] +crbug.com/1228149 http/tests/devtools/sources/debugger-ui/debugger-inline-values-frames.js [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/WebGPUExpectations b/third_party/blink/web_tests/WebGPUExpectations index df6b695..5467a9a 100644 --- a/third_party/blink/web_tests/WebGPUExpectations +++ b/third_party/blink/web_tests/WebGPUExpectations
@@ -289,6 +289,10 @@ crbug.com/1197369 wpt_internal/webgpu/cts.html?q=webgpu:api,validation,queue,copyToTexture,ImageBitmap,* [ Skip ] crbug.com/1197369 wpt_internal/webgpu/cts.html?q=webgpu:web_platform,copyToTexture,ImageBitmap:* [ Skip ] +# Validation rules of index buffer OOB in DrawIndexed are changing, skipped until the CTS are fix to spec. +crbug.com/dawn/808 wpt_internal/webgpu/cts.html?q=webgpu:api,validation,encoding,cmds,index_access:out_of_bounds:* [ Skip ] +crbug.com/dawn/808 wpt_internal/webgpu/cts.html?q=webgpu:api,validation,encoding,cmds,index_access:out_of_bounds_zero_sized_index_buffer:* [ Skip ] + ### ### Mac (Metal) specific ###
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coop-navigate-same-origin-csp-sandbox-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coop-navigate-same-origin-csp-sandbox-expected.txt new file mode 100644 index 0000000..428a7a9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coop-navigate-same-origin-csp-sandbox-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL coop-navigate-same-origin-csp-sandbox assert_equals: expected "Success: no opener" but got "Error: have opener" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coop-navigate-same-origin-csp-sandbox.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coop-navigate-same-origin-csp-sandbox.html new file mode 100644 index 0000000..e6ed947 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coop-navigate-same-origin-csp-sandbox.html
@@ -0,0 +1,64 @@ +<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 src="./resources/common.js"></script> +<script src="./resources/dispatcher.js"></script> +<script> + +const directory = '/html/cross-origin-opener-policy/'; +const executor_path = directory + '/resources/executor.html?pipe='; + +const https_origin = get_host_info().HTTPS_ORIGIN; +const coop_same_origin = + '|header(Cross-Origin-Opener-Policy,same-origin)'; +const csp_sandbox = + '|header(Content-Security-Policy, sandbox allow-scripts)'; + +promise_test(async test => { + const driver_token = token(); + + // 1. Start from a COOP:same-origin document. + const opener_token = token(); + const opener_url = https_origin + executor_path + coop_same_origin + + `&uuid=${opener_token}`; + const w = window.open(opener_url); + add_completion_callback(() => w.close()); + + // 2. It opens a popups, and then navigates the popup toward a same-origin + // COOP:same-origin document with CSP:sandbox + const openee_token = token(); + const openee_url = https_origin + executor_path + coop_same_origin + + csp_sandbox + `&uuid=${openee_token}`; + send(opener_token, ` + openee = window.open("${openee_url}"); + `); + add_completion_callback(() => send(openee_token, "close()")); + + // Because of CSP:sandbox, the popup is not considered same-origin with + // its openee. Check the openee/opener relationship is now closed. + send(openee_token, ` + if (opener) + send("${driver_token}", "Error: have opener"); + else + send("${driver_token}", "Success: no opener"); + `); + assert_equals(await receive(driver_token), "Success: no opener"); + + // Technically, the opener's "openee" WindowProxy should appear as closed at + // this time. The popup loaded a new document, and at least two fetch requests + // were made. This is more than enough. However, in theory, there is nothing + // to guarantee we can observe "openee.close". Wait a bit to ensure this will + // never flake. + await new Promise(r => test.step_timeout(r, 1000)); + + send(opener_token, ` + if (openee.closed) + send("${driver_token}", "Success: openee closed"); + else + send("${driver_token}", "Error: can still access openee"); + `); + assert_equals(await receive(driver_token), "Success: openee closed"); +}); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/direction/direction-expected.txt b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/direction/direction-expected.txt deleted file mode 100644 index ca57d09..0000000 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/direction/direction-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Check direction assert_equals: expected "ltr" but got "rtl" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-002-expected.txt b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-002-expected.txt deleted file mode 100644 index a3382b5..0000000 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-002-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -This is a testharness.js-based test. -PASS Positive -PASS Negative -PASS Percentage -PASS Named space -PASS Calc() expression -FAIL Dynamic linethickness assert_approx_equals: attach expected 400 +/- 2 but got 99.96875 -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/mrow/merror-001-expected.txt b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/mrow/merror-001-expected.txt deleted file mode 100644 index 1848d63..0000000 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/mrow/merror-001-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This is a testharness.js-based test. -FAIL Default CSS properties on merror assert_equals: expected "1px" but got "0px" -FAIL Bounding box is the same as mrow + 1px border assert_equals: expected 202 but got 200 -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/cramped-001-expected.txt b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/cramped-001-expected.txt deleted file mode 100644 index ce7faae..0000000 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/cramped-001-expected.txt +++ /dev/null
@@ -1,18 +0,0 @@ -This is a testharness.js-based test. -PASS child of non-cramped element -PASS child of cramped element -PASS child of msqrt -PASS child of mroot -PASS child of mfrac -FAIL child of msub assert_greater_than: subscript should be cramped expected a number greater than 25 but got 20 -PASS child of msup -FAIL child of msubsup assert_greater_than: subscript should be cramped expected a number greater than 25 but got 20 -FAIL child of munder assert_less_than: underscript should not be cramped expected a number less than 25 but got 49.984375 -PASS child of mover (non-accent overscript) -FAIL child of munderover (non-accent overscript) assert_less_than: underscript should not be cramped expected a number less than 25 but got 49.984375 -PASS accent child of mover (accent overscript) -FAIL accent child of munderover (accent overscript) assert_less_than: underscript should not be cramped expected a number less than 25 but got 49.984375 -FAIL mmultiscripts assert_greater_than: post-subscript should be cramped expected a number greater than 25 but got 20 -PASS element with specified CSS math-style -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/attribute-mapping-001-expected.txt b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/attribute-mapping-001-expected.txt deleted file mode 100644 index 751e02b..0000000 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/attribute-mapping-001-expected.txt +++ /dev/null
@@ -1,164 +0,0 @@ -This is a testharness.js-based test. -Found 160 tests; 159 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS dir on the math element is mapped to CSS direction -PASS mathcolor on the math element is mapped to CSS color -PASS mathbackground on the math element is mapped to CSS background-color -PASS mathsize on the math element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the math element are not mapped to CSS -PASS dir on the annotation element is mapped to CSS direction -PASS mathcolor on the annotation element is mapped to CSS color -PASS mathbackground on the annotation element is mapped to CSS background-color -PASS mathsize on the annotation element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the annotation element are not mapped to CSS -PASS dir on the annotation-xml element is mapped to CSS direction -PASS mathcolor on the annotation-xml element is mapped to CSS color -PASS mathbackground on the annotation-xml element is mapped to CSS background-color -PASS mathsize on the annotation-xml element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the annotation-xml element are not mapped to CSS -PASS dir on the maction element is mapped to CSS direction -PASS mathcolor on the maction element is mapped to CSS color -PASS mathbackground on the maction element is mapped to CSS background-color -PASS mathsize on the maction element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the maction element are not mapped to CSS -PASS dir on the menclose element is mapped to CSS direction -PASS mathcolor on the menclose element is mapped to CSS color -PASS mathbackground on the menclose element is mapped to CSS background-color -PASS mathsize on the menclose element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the menclose element are not mapped to CSS -PASS dir on the merror element is mapped to CSS direction -FAIL mathcolor on the merror element is mapped to CSS color assert_equals: no attribute expected "rgb(0, 0, 255)" but got "rgb(255, 0, 0)" -PASS mathbackground on the merror element is mapped to CSS background-color -PASS mathsize on the merror element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the merror element are not mapped to CSS -PASS dir on the mfrac element is mapped to CSS direction -PASS mathcolor on the mfrac element is mapped to CSS color -PASS mathbackground on the mfrac element is mapped to CSS background-color -PASS mathsize on the mfrac element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mfrac element are not mapped to CSS -PASS dir on the mi element is mapped to CSS direction -PASS mathcolor on the mi element is mapped to CSS color -PASS mathbackground on the mi element is mapped to CSS background-color -PASS mathsize on the mi element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mi element are not mapped to CSS -PASS dir on the mmultiscripts element is mapped to CSS direction -PASS mathcolor on the mmultiscripts element is mapped to CSS color -PASS mathbackground on the mmultiscripts element is mapped to CSS background-color -PASS mathsize on the mmultiscripts element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mmultiscripts element are not mapped to CSS -PASS dir on the mn element is mapped to CSS direction -PASS mathcolor on the mn element is mapped to CSS color -PASS mathbackground on the mn element is mapped to CSS background-color -PASS mathsize on the mn element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mn element are not mapped to CSS -PASS dir on the mo element is mapped to CSS direction -PASS mathcolor on the mo element is mapped to CSS color -PASS mathbackground on the mo element is mapped to CSS background-color -PASS mathsize on the mo element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mo element are not mapped to CSS -PASS dir on the mover element is mapped to CSS direction -PASS mathcolor on the mover element is mapped to CSS color -PASS mathbackground on the mover element is mapped to CSS background-color -PASS mathsize on the mover element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mover element are not mapped to CSS -PASS dir on the mpadded element is mapped to CSS direction -PASS mathcolor on the mpadded element is mapped to CSS color -PASS mathbackground on the mpadded element is mapped to CSS background-color -PASS mathsize on the mpadded element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mpadded element are not mapped to CSS -PASS dir on the mphantom element is mapped to CSS direction -PASS mathcolor on the mphantom element is mapped to CSS color -PASS mathbackground on the mphantom element is mapped to CSS background-color -PASS mathsize on the mphantom element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mphantom element are not mapped to CSS -PASS dir on the mprescripts element is mapped to CSS direction -PASS mathcolor on the mprescripts element is mapped to CSS color -PASS mathbackground on the mprescripts element is mapped to CSS background-color -PASS mathsize on the mprescripts element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mprescripts element are not mapped to CSS -PASS dir on the mroot element is mapped to CSS direction -PASS mathcolor on the mroot element is mapped to CSS color -PASS mathbackground on the mroot element is mapped to CSS background-color -PASS mathsize on the mroot element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mroot element are not mapped to CSS -PASS dir on the mrow element is mapped to CSS direction -PASS mathcolor on the mrow element is mapped to CSS color -PASS mathbackground on the mrow element is mapped to CSS background-color -PASS mathsize on the mrow element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mrow element are not mapped to CSS -PASS dir on the ms element is mapped to CSS direction -PASS mathcolor on the ms element is mapped to CSS color -PASS mathbackground on the ms element is mapped to CSS background-color -PASS mathsize on the ms element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the ms element are not mapped to CSS -PASS dir on the mspace element is mapped to CSS direction -PASS mathcolor on the mspace element is mapped to CSS color -PASS mathbackground on the mspace element is mapped to CSS background-color -PASS mathsize on the mspace element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mspace element are not mapped to CSS -PASS dir on the msqrt element is mapped to CSS direction -PASS mathcolor on the msqrt element is mapped to CSS color -PASS mathbackground on the msqrt element is mapped to CSS background-color -PASS mathsize on the msqrt element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the msqrt element are not mapped to CSS -PASS dir on the mstyle element is mapped to CSS direction -PASS mathcolor on the mstyle element is mapped to CSS color -PASS mathbackground on the mstyle element is mapped to CSS background-color -PASS mathsize on the mstyle element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mstyle element are not mapped to CSS -PASS dir on the msub element is mapped to CSS direction -PASS mathcolor on the msub element is mapped to CSS color -PASS mathbackground on the msub element is mapped to CSS background-color -PASS mathsize on the msub element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the msub element are not mapped to CSS -PASS dir on the msubsup element is mapped to CSS direction -PASS mathcolor on the msubsup element is mapped to CSS color -PASS mathbackground on the msubsup element is mapped to CSS background-color -PASS mathsize on the msubsup element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the msubsup element are not mapped to CSS -PASS dir on the msup element is mapped to CSS direction -PASS mathcolor on the msup element is mapped to CSS color -PASS mathbackground on the msup element is mapped to CSS background-color -PASS mathsize on the msup element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the msup element are not mapped to CSS -PASS dir on the mtable element is mapped to CSS direction -PASS mathcolor on the mtable element is mapped to CSS color -PASS mathbackground on the mtable element is mapped to CSS background-color -PASS mathsize on the mtable element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mtable element are not mapped to CSS -PASS dir on the mtd element is mapped to CSS direction -PASS mathcolor on the mtd element is mapped to CSS color -PASS mathbackground on the mtd element is mapped to CSS background-color -PASS mathsize on the mtd element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mtd element are not mapped to CSS -PASS dir on the mtext element is mapped to CSS direction -PASS mathcolor on the mtext element is mapped to CSS color -PASS mathbackground on the mtext element is mapped to CSS background-color -PASS mathsize on the mtext element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mtext element are not mapped to CSS -PASS dir on the mtr element is mapped to CSS direction -PASS mathcolor on the mtr element is mapped to CSS color -PASS mathbackground on the mtr element is mapped to CSS background-color -PASS mathsize on the mtr element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the mtr element are not mapped to CSS -PASS dir on the munder element is mapped to CSS direction -PASS mathcolor on the munder element is mapped to CSS color -PASS mathbackground on the munder element is mapped to CSS background-color -PASS mathsize on the munder element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the munder element are not mapped to CSS -PASS dir on the munderover element is mapped to CSS direction -PASS mathcolor on the munderover element is mapped to CSS color -PASS mathbackground on the munderover element is mapped to CSS background-color -PASS mathsize on the munderover element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the munderover element are not mapped to CSS -PASS dir on the none element is mapped to CSS direction -PASS mathcolor on the none element is mapped to CSS color -PASS mathbackground on the none element is mapped to CSS background-color -PASS mathsize on the none element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the none element are not mapped to CSS -PASS dir on the semantics element is mapped to CSS direction -PASS mathcolor on the semantics element is mapped to CSS color -PASS mathbackground on the semantics element is mapped to CSS background-color -PASS mathsize on the semantics element is mapped to CSS font-size -PASS deprecated MathML3 attributes on the semantics element are not mapped to CSS -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/default-properties-on-the-math-root-expected.txt b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/default-properties-on-the-math-root-expected.txt deleted file mode 100644 index d0fae2e..0000000 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/default-properties-on-the-math-root-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This is a testharness.js-based test. -FAIL Value of direction on the <math> root assert_equals: when specified from the UA sheet expected "ltr" but got "rtl" -PASS Value of writing-mode on the <math> root -FAIL Value of text-indent on the <math> root assert_equals: when specified from the UA sheet expected "0px" but got "8px" -FAIL Value of letter-spacing on the <math> root assert_equals: when specified from the UA sheet expected "normal" but got "8px" -FAIL Value of line-height on the <math> root assert_equals: when specified from the UA sheet expected "normal" but got "8px" -FAIL Value of word-spacing on the <math> root assert_equals: when specified from the UA sheet expected "0px" but got "8px" -FAIL Value of font-style on the <math> root assert_equals: when specified from the UA sheet expected "normal" but got "italic" -FAIL Value of font-weight on the <math> root assert_equals: when specified from the UA sheet expected "400" but got "700" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/border-002-expected.txt b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/border-002-expected.txt deleted file mode 100644 index 862589b..0000000 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/padding-border-margin/border-002-expected.txt +++ /dev/null
@@ -1,52 +0,0 @@ -This is a testharness.js-based test. -PASS Border properties on maction -PASS Border properties on maction (rtl) -PASS Border properties on menclose -PASS Border properties on menclose (rtl) -FAIL Border properties on merror assert_approx_equals: element width expected 70 +/- 1 but got 72 -FAIL Border properties on merror (rtl) assert_approx_equals: element width expected 70 +/- 1 but got 72 -PASS Border properties on mfrac -PASS Border properties on mfrac (rtl) -PASS Border properties on mi -PASS Border properties on mi (rtl) -PASS Border properties on mmultiscripts -PASS Border properties on mmultiscripts (rtl) -PASS Border properties on mn -PASS Border properties on mn (rtl) -PASS Border properties on mo -PASS Border properties on mo (rtl) -PASS Border properties on mover -PASS Border properties on mover (rtl) -PASS Border properties on mpadded -PASS Border properties on mpadded (rtl) -PASS Border properties on mphantom -PASS Border properties on mphantom (rtl) -PASS Border properties on mroot -PASS Border properties on mroot (rtl) -PASS Border properties on mrow -PASS Border properties on mrow (rtl) -PASS Border properties on ms -PASS Border properties on ms (rtl) -PASS Border properties on mspace -PASS Border properties on msqrt -PASS Border properties on msqrt (rtl) -PASS Border properties on mstyle -PASS Border properties on mstyle (rtl) -PASS Border properties on msub -PASS Border properties on msub (rtl) -PASS Border properties on msubsup -PASS Border properties on msubsup (rtl) -PASS Border properties on msup -PASS Border properties on msup (rtl) -PASS Border properties on mtable -PASS Border properties on mtable (rtl) -PASS Border properties on mtext -PASS Border properties on mtext (rtl) -PASS Border properties on munder -PASS Border properties on munder (rtl) -PASS Border properties on munderover -PASS Border properties on munderover (rtl) -PASS Border properties on semantics -PASS Border properties on semantics (rtl) -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 60eee1d..7b0b4e5 100644 --- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -1227,12 +1227,6 @@ method request method requestAll method revoke -interface Profiler : EventTarget - attribute @@toStringTag - getter sampleInterval - getter stopped - method constructor - method stop interface PromiseRejectionEvent : Event attribute @@toStringTag getter promise
diff --git a/third_party/blink/web_tests/http/tests/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/element-instance-property-listing-expected.txt index cb229082..c941258 100644 --- a/third_party/blink/web_tests/http/tests/webexposed/element-instance-property-listing-expected.txt +++ b/third_party/blink/web_tests/http/tests/webexposed/element-instance-property-listing-expected.txt
@@ -22,7 +22,7 @@ property ENTITY_REFERENCE_NODE property NOTATION_NODE property PROCESSING_INSTRUCTION_NODE - property SetSanitizedHTML + property SetHTML property TEXT_NODE property accessKey property accessibleNode @@ -1243,7 +1243,7 @@ property ENTITY_REFERENCE_NODE property NOTATION_NODE property PROCESSING_INSTRUCTION_NODE - property SetSanitizedHTML + property SetHTML property TEXT_NODE property accessibleNode property addEventListener
diff --git a/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-dedicated-worker-expected.txt index ef414a7..baf48c98 100644 --- a/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -1254,12 +1254,6 @@ [Worker] getter stride [Worker] method constructor [Worker] method readInto -[Worker] interface Profiler : EventTarget -[Worker] attribute @@toStringTag -[Worker] getter sampleInterval -[Worker] getter stopped -[Worker] method constructor -[Worker] method stop [Worker] interface ProgressEvent : Event [Worker] attribute @@toStringTag [Worker] getter lengthComputable
diff --git a/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-expected.txt index a5a32f8..cfe37e2 100644 --- a/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-expected.txt
@@ -2252,7 +2252,7 @@ getter shadowRoot getter slot getter tagName - method SetSanitizedHTML + method SetHTML method after method animate method append
diff --git a/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-shared-worker-expected.txt index 13bbb42..0984d6da 100644 --- a/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -1124,12 +1124,6 @@ [Worker] method request [Worker] method requestAll [Worker] method revoke -[Worker] interface Profiler : EventTarget -[Worker] attribute @@toStringTag -[Worker] getter sampleInterval -[Worker] getter stopped -[Worker] method constructor -[Worker] method stop [Worker] interface ProgressEvent : Event [Worker] attribute @@toStringTag [Worker] getter lengthComputable
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/opener-accessed_openee-coop-ro.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/opener-accessed_openee-coop-ro.https-expected.txt deleted file mode 100644 index 968e4f27..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/opener-accessed_openee-coop-ro.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Openee (COOP-RO+COEP) accesses opener. Report to openee promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'includes' of undefined" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/opener-accessed_openee-coop-ro.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/opener-accessed_openee-coop-ro.https-expected.txt deleted file mode 100644 index 89c49c5..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/opener-accessed_openee-coop-ro.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Openee (COOP-RO+COEP) accesses opener. Report to openee assert_not_equals: Report not received got disallowed value "timeout" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/virtual/anonymous-iframe/http/tests/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/virtual/anonymous-iframe/http/tests/webexposed/element-instance-property-listing-expected.txt index 4cd3c09..1040012 100644 --- a/third_party/blink/web_tests/virtual/anonymous-iframe/http/tests/webexposed/element-instance-property-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/anonymous-iframe/http/tests/webexposed/element-instance-property-listing-expected.txt
@@ -22,7 +22,7 @@ property ENTITY_REFERENCE_NODE property NOTATION_NODE property PROCESSING_INSTRUCTION_NODE - property SetSanitizedHTML + property SetHTML property TEXT_NODE property accessKey property accessibleNode @@ -1244,7 +1244,7 @@ property ENTITY_REFERENCE_NODE property NOTATION_NODE property PROCESSING_INSTRUCTION_NODE - property SetSanitizedHTML + property SetHTML property TEXT_NODE property accessibleNode property addEventListener
diff --git a/third_party/blink/web_tests/virtual/anonymous-iframe/http/tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/anonymous-iframe/http/tests/webexposed/global-interface-listing-expected.txt index 1e8742a4..60578ac3 100644 --- a/third_party/blink/web_tests/virtual/anonymous-iframe/http/tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/anonymous-iframe/http/tests/webexposed/global-interface-listing-expected.txt
@@ -2252,7 +2252,7 @@ getter shadowRoot getter slot getter tagName - method SetSanitizedHTML + method SetHTML method after method animate method append
diff --git a/third_party/blink/web_tests/wpt_internal/sanitizer-api/element-set-sanitized-html.https.tentative.html b/third_party/blink/web_tests/wpt_internal/sanitizer-api/element-set-sanitized-html.https.tentative.html index c773745..ab0f708 100644 --- a/third_party/blink/web_tests/wpt_internal/sanitizer-api/element-set-sanitized-html.https.tentative.html +++ b/third_party/blink/web_tests/wpt_internal/sanitizer-api/element-set-sanitized-html.https.tentative.html
@@ -20,20 +20,20 @@ test(t => { const div = document.createElement("div"); - assert_throws_js(TypeError, _ => div.SetSanitizedHTML()); - assert_throws_js(TypeError, _ => div.SetSanitizedHTML("abc")); - assert_throws_js(TypeError, _ => div.SetSanitizedHTML("abc", null)); - }, "Sanitizer: Element.SetSanitizedHTML throws with insufficient arguments."); + assert_throws_js(TypeError, _ => div.SetHTML()); + assert_throws_js(TypeError, _ => div.SetHTML("abc")); + assert_throws_js(TypeError, _ => div.SetHTML("abc", null)); + }, "Sanitizer: Element.SetHTML throws with insufficient arguments."); for(const context of ["div", "template", "table"]) { const elem1 = document.createElement(context); const elem2 = document.createElement(context); for (const probe of ["<em>Hello</em>", "<td>data</td>"]) { - elem1.SetSanitizedHTML(probe, new Sanitizer()); + elem1.SetHTML(probe, new Sanitizer()); elem2.innerHTML = probe; test(t => { assert_node_equals(elem2, elem1); - }, `Sanitizer: <${context}>.SetSanitizedHTML("${probe}", ...) obeys parse context.`); + }, `Sanitizer: <${context}>.SetHTML("${probe}", ...) obeys parse context.`); } } @@ -41,9 +41,9 @@ const element = document.createElement("template"); test(t => { let s = new Sanitizer(testcase.config_input); - element.SetSanitizedHTML(testcase.value, s); + element.SetHTML(testcase.value, s); assert_node_equals(buildNode(element.localName, testcase.result), element); - }, "Sanitizer: Element.SetSanitizedHTML with config: " + testcase.message); + }, "Sanitizer: Element.SetHTML with config: " + testcase.message); } </script> </body>
diff --git a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.https.tentative-expected.txt b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.https.tentative-expected.txt deleted file mode 100644 index 5c5063df..0000000 --- a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.https.tentative-expected.txt +++ /dev/null
@@ -1,70 +0,0 @@ -This is a testharness.js-based test. -Found 66 tests; 65 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS SanitizerAPI with config with Document: plaintext -PASS SanitizerAPI with config with Document: xmp -PASS SanitizerAPI with config with Document: Template element -PASS SanitizerAPI with config with Document: HTMLAnchorElement with javascript protocal -PASS SanitizerAPI with config with Document: HTMLAnchorElement with javascript protocal start with space -PASS SanitizerAPI with config with Document: HTMLAnchorElement -PASS SanitizerAPI with config with Document: HTMLAreaElement with javascript protocal -PASS SanitizerAPI with config with Document: HTMLAreaElement with javascript protocal start with space -PASS SanitizerAPI with config with Document: HTMLAreaElement -PASS SanitizerAPI with config with Document: HTMLFormElement with javascript action -PASS SanitizerAPI with config with Document: HTMLFormElement with javascript action start with space -PASS SanitizerAPI with config with Document: HTMLFormElement -PASS SanitizerAPI with config with Document: HTMLInputElement with javascript formaction -PASS SanitizerAPI with config with Document: HTMLInputElement with javascript formaction start with space -PASS SanitizerAPI with config with Document: HTMLInputElement -PASS SanitizerAPI with config with Document: HTMLButtonElement with javascript formaction -PASS SanitizerAPI with config with Document: HTMLButtonElement with javascript formaction start with space -PASS SanitizerAPI with config with Document: HTMLButtonElement -FAIL SanitizerAPI with config with Document: malformed HTML assert_equals: expected "<p>Some text</p><!-- 1 --><!-- 2 --><p>Some more text</p>" but got "<p>Some text</p><p>Some more text</p>" -PASS SanitizerAPI with config with Document: Regression test for WICG/sanitizer-api#84. -PASS SanitizerAPI with config with Document: Regression test for WICG/sanitizer-api#85. -PASS SanitizerAPI with config with Document: Regression test for WICG/sanitizer-api#86. -PASS SanitizerAPI with config with DocumentFragment: plaintext -PASS SanitizerAPI with config with DocumentFragment: xmp -PASS SanitizerAPI with config with DocumentFragment: Template element -PASS SanitizerAPI with config with DocumentFragment: HTMLAnchorElement with javascript protocal -PASS SanitizerAPI with config with DocumentFragment: HTMLAnchorElement with javascript protocal start with space -PASS SanitizerAPI with config with DocumentFragment: HTMLAnchorElement -PASS SanitizerAPI with config with DocumentFragment: HTMLAreaElement with javascript protocal -PASS SanitizerAPI with config with DocumentFragment: HTMLAreaElement with javascript protocal start with space -PASS SanitizerAPI with config with DocumentFragment: HTMLAreaElement -PASS SanitizerAPI with config with DocumentFragment: HTMLFormElement with javascript action -PASS SanitizerAPI with config with DocumentFragment: HTMLFormElement with javascript action start with space -PASS SanitizerAPI with config with DocumentFragment: HTMLFormElement -PASS SanitizerAPI with config with DocumentFragment: HTMLInputElement with javascript formaction -PASS SanitizerAPI with config with DocumentFragment: HTMLInputElement with javascript formaction start with space -PASS SanitizerAPI with config with DocumentFragment: HTMLInputElement -PASS SanitizerAPI with config with DocumentFragment: HTMLButtonElement with javascript formaction -PASS SanitizerAPI with config with DocumentFragment: HTMLButtonElement with javascript formaction start with space -PASS SanitizerAPI with config with DocumentFragment: HTMLButtonElement -PASS SanitizerAPI with config with DocumentFragment: malformed HTML -PASS SanitizerAPI with config with DocumentFragment: Regression test for WICG/sanitizer-api#84. -PASS SanitizerAPI with config with DocumentFragment: Regression test for WICG/sanitizer-api#85. -PASS SanitizerAPI with config with DocumentFragment: Regression test for WICG/sanitizer-api#86. -PASS SanitizerAPI with config with Element.SetSanitizedHTML: plaintext -PASS SanitizerAPI with config with Element.SetSanitizedHTML: xmp -PASS SanitizerAPI with config with Element.SetSanitizedHTML: Template element -PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLAnchorElement with javascript protocal -PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLAnchorElement with javascript protocal start with space -PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLAnchorElement -PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLAreaElement with javascript protocal -PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLAreaElement with javascript protocal start with space -PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLAreaElement -PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLFormElement with javascript action -PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLFormElement with javascript action start with space -PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLFormElement -PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLInputElement with javascript formaction -PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLInputElement with javascript formaction start with space -PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLInputElement -PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLButtonElement with javascript formaction -PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLButtonElement with javascript formaction start with space -PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLButtonElement -PASS SanitizerAPI with config with Element.SetSanitizedHTML: malformed HTML -PASS SanitizerAPI with config with Element.SetSanitizedHTML: Regression test for WICG/sanitizer-api#84. -PASS SanitizerAPI with config with Element.SetSanitizedHTML: Regression test for WICG/sanitizer-api#85. -PASS SanitizerAPI with config with Element.SetSanitizedHTML: Regression test for WICG/sanitizer-api#86. -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.https.tentative.html b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.https.tentative.html index 19f3a9b5..bbc0aa8 100644 --- a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.https.tentative.html +++ b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.https.tentative.html
@@ -47,15 +47,15 @@ assert_equals(getString(fragment), c.result); }, "SanitizerAPI with config with DocumentFragment: " + c.message)); - // Let's also test .SetSanitizedHTML. The main test suite factors this out + // Let's also test .SetHTML. The main test suite factors this out // into a seperate file. testcases.forEach(c => test(t => { let result = document.createElement("div"); let probe = document.createElement("div"); result.innerHTML = c.result; - probe.SetSanitizedHTML(c.value, new Sanitizer(c.config_input)); + probe.SetHTML(c.value, new Sanitizer(c.config_input)); assert_equals(result.innerHTML, probe.innerHTML); - }, "SanitizerAPI with config with Element.SetSanitizedHTML: " + c.message)); + }, "SanitizerAPI with config with Element.SetHTML: " + c.message)); </script> </body> </html>
diff --git a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitizeToString.https.tentative-expected.txt b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitizeToString.https.tentative-expected.txt deleted file mode 100644 index c9c582bc..0000000 --- a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitizeToString.https.tentative-expected.txt +++ /dev/null
@@ -1,72 +0,0 @@ -This is a testharness.js-based test. -Found 68 tests; 67 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS SanitizerAPI sanitize function without argument should throw an error. -PASS SanitizerAPI sanitizeToString function for null. -PASS SanitizerAPI config: plaintext, sanitizeToString from string function for plaintext -PASS SanitizerAPI config: xmp, sanitizeToString from string function for xmp -PASS SanitizerAPI config: Template element, sanitizeToString from string function for Template element -PASS SanitizerAPI config: HTMLAnchorElement with javascript protocal, sanitizeToString from string function for HTMLAnchorElement with javascript protocal -PASS SanitizerAPI config: HTMLAnchorElement with javascript protocal start with space, sanitizeToString from string function for HTMLAnchorElement with javascript protocal start with space -PASS SanitizerAPI config: HTMLAnchorElement, sanitizeToString from string function for HTMLAnchorElement -PASS SanitizerAPI config: HTMLAreaElement with javascript protocal, sanitizeToString from string function for HTMLAreaElement with javascript protocal -PASS SanitizerAPI config: HTMLAreaElement with javascript protocal start with space, sanitizeToString from string function for HTMLAreaElement with javascript protocal start with space -PASS SanitizerAPI config: HTMLAreaElement, sanitizeToString from string function for HTMLAreaElement -PASS SanitizerAPI config: HTMLFormElement with javascript action, sanitizeToString from string function for HTMLFormElement with javascript action -PASS SanitizerAPI config: HTMLFormElement with javascript action start with space, sanitizeToString from string function for HTMLFormElement with javascript action start with space -PASS SanitizerAPI config: HTMLFormElement, sanitizeToString from string function for HTMLFormElement -PASS SanitizerAPI config: HTMLInputElement with javascript formaction, sanitizeToString from string function for HTMLInputElement with javascript formaction -PASS SanitizerAPI config: HTMLInputElement with javascript formaction start with space, sanitizeToString from string function for HTMLInputElement with javascript formaction start with space -PASS SanitizerAPI config: HTMLInputElement, sanitizeToString from string function for HTMLInputElement -PASS SanitizerAPI config: HTMLButtonElement with javascript formaction, sanitizeToString from string function for HTMLButtonElement with javascript formaction -PASS SanitizerAPI config: HTMLButtonElement with javascript formaction start with space, sanitizeToString from string function for HTMLButtonElement with javascript formaction start with space -PASS SanitizerAPI config: HTMLButtonElement, sanitizeToString from string function for HTMLButtonElement -PASS SanitizerAPI config: malformed HTML, sanitizeToString from string function for malformed HTML -PASS SanitizerAPI config: Regression test for WICG/sanitizer-api#84., sanitizeToString from string function for Regression test for WICG/sanitizer-api#84. -PASS SanitizerAPI config: Regression test for WICG/sanitizer-api#85., sanitizeToString from string function for Regression test for WICG/sanitizer-api#85. -PASS SanitizerAPI config: Regression test for WICG/sanitizer-api#86., sanitizeToString from string function for Regression test for WICG/sanitizer-api#86. -PASS SanitizerAPI with config: plaintext, sanitizeToString from document function for plaintext -PASS SanitizerAPI with config: xmp, sanitizeToString from document function for xmp -PASS SanitizerAPI with config: Template element, sanitizeToString from document function for Template element -PASS SanitizerAPI with config: HTMLAnchorElement with javascript protocal, sanitizeToString from document function for HTMLAnchorElement with javascript protocal -PASS SanitizerAPI with config: HTMLAnchorElement with javascript protocal start with space, sanitizeToString from document function for HTMLAnchorElement with javascript protocal start with space -PASS SanitizerAPI with config: HTMLAnchorElement, sanitizeToString from document function for HTMLAnchorElement -PASS SanitizerAPI with config: HTMLAreaElement with javascript protocal, sanitizeToString from document function for HTMLAreaElement with javascript protocal -PASS SanitizerAPI with config: HTMLAreaElement with javascript protocal start with space, sanitizeToString from document function for HTMLAreaElement with javascript protocal start with space -PASS SanitizerAPI with config: HTMLAreaElement, sanitizeToString from document function for HTMLAreaElement -PASS SanitizerAPI with config: HTMLFormElement with javascript action, sanitizeToString from document function for HTMLFormElement with javascript action -PASS SanitizerAPI with config: HTMLFormElement with javascript action start with space, sanitizeToString from document function for HTMLFormElement with javascript action start with space -PASS SanitizerAPI with config: HTMLFormElement, sanitizeToString from document function for HTMLFormElement -PASS SanitizerAPI with config: HTMLInputElement with javascript formaction, sanitizeToString from document function for HTMLInputElement with javascript formaction -PASS SanitizerAPI with config: HTMLInputElement with javascript formaction start with space, sanitizeToString from document function for HTMLInputElement with javascript formaction start with space -PASS SanitizerAPI with config: HTMLInputElement, sanitizeToString from document function for HTMLInputElement -PASS SanitizerAPI with config: HTMLButtonElement with javascript formaction, sanitizeToString from document function for HTMLButtonElement with javascript formaction -PASS SanitizerAPI with config: HTMLButtonElement with javascript formaction start with space, sanitizeToString from document function for HTMLButtonElement with javascript formaction start with space -PASS SanitizerAPI with config: HTMLButtonElement, sanitizeToString from document function for HTMLButtonElement -FAIL SanitizerAPI with config: malformed HTML, sanitizeToString from document function for malformed HTML assert_equals: expected "<p>Some text</p><!-- 1 --><!-- 2 --><p>Some more text</p>" but got "<p>Some text</p><p>Some more text</p>" -PASS SanitizerAPI with config: Regression test for WICG/sanitizer-api#84., sanitizeToString from document function for Regression test for WICG/sanitizer-api#84. -PASS SanitizerAPI with config: Regression test for WICG/sanitizer-api#85., sanitizeToString from document function for Regression test for WICG/sanitizer-api#85. -PASS SanitizerAPI with config: Regression test for WICG/sanitizer-api#86., sanitizeToString from document function for Regression test for WICG/sanitizer-api#86. -PASS SanitizerAPI with config: plaintext, sanitizeToString from document fragment function for plaintext -PASS SanitizerAPI with config: xmp, sanitizeToString from document fragment function for xmp -PASS SanitizerAPI with config: Template element, sanitizeToString from document fragment function for Template element -PASS SanitizerAPI with config: HTMLAnchorElement with javascript protocal, sanitizeToString from document fragment function for HTMLAnchorElement with javascript protocal -PASS SanitizerAPI with config: HTMLAnchorElement with javascript protocal start with space, sanitizeToString from document fragment function for HTMLAnchorElement with javascript protocal start with space -PASS SanitizerAPI with config: HTMLAnchorElement, sanitizeToString from document fragment function for HTMLAnchorElement -PASS SanitizerAPI with config: HTMLAreaElement with javascript protocal, sanitizeToString from document fragment function for HTMLAreaElement with javascript protocal -PASS SanitizerAPI with config: HTMLAreaElement with javascript protocal start with space, sanitizeToString from document fragment function for HTMLAreaElement with javascript protocal start with space -PASS SanitizerAPI with config: HTMLAreaElement, sanitizeToString from document fragment function for HTMLAreaElement -PASS SanitizerAPI with config: HTMLFormElement with javascript action, sanitizeToString from document fragment function for HTMLFormElement with javascript action -PASS SanitizerAPI with config: HTMLFormElement with javascript action start with space, sanitizeToString from document fragment function for HTMLFormElement with javascript action start with space -PASS SanitizerAPI with config: HTMLFormElement, sanitizeToString from document fragment function for HTMLFormElement -PASS SanitizerAPI with config: HTMLInputElement with javascript formaction, sanitizeToString from document fragment function for HTMLInputElement with javascript formaction -PASS SanitizerAPI with config: HTMLInputElement with javascript formaction start with space, sanitizeToString from document fragment function for HTMLInputElement with javascript formaction start with space -PASS SanitizerAPI with config: HTMLInputElement, sanitizeToString from document fragment function for HTMLInputElement -PASS SanitizerAPI with config: HTMLButtonElement with javascript formaction, sanitizeToString from document fragment function for HTMLButtonElement with javascript formaction -PASS SanitizerAPI with config: HTMLButtonElement with javascript formaction start with space, sanitizeToString from document fragment function for HTMLButtonElement with javascript formaction start with space -PASS SanitizerAPI with config: HTMLButtonElement, sanitizeToString from document fragment function for HTMLButtonElement -PASS SanitizerAPI with config: malformed HTML, sanitizeToString from document fragment function for malformed HTML -PASS SanitizerAPI with config: Regression test for WICG/sanitizer-api#84., sanitizeToString from document fragment function for Regression test for WICG/sanitizer-api#84. -PASS SanitizerAPI with config: Regression test for WICG/sanitizer-api#85., sanitizeToString from document fragment function for Regression test for WICG/sanitizer-api#85. -PASS SanitizerAPI with config: Regression test for WICG/sanitizer-api#86., sanitizeToString from document fragment function for Regression test for WICG/sanitizer-api#86. -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/wpt_internal/sanitizer-api/support/testcases.sub.js b/third_party/blink/web_tests/wpt_internal/sanitizer-api/support/testcases.sub.js index be70c6f..e084d75 100644 --- a/third_party/blink/web_tests/wpt_internal/sanitizer-api/support/testcases.sub.js +++ b/third_party/blink/web_tests/wpt_internal/sanitizer-api/support/testcases.sub.js
@@ -17,7 +17,13 @@ {config_input: {}, value: "<button formaction='javascript:evil.com'>Click.</button>", result: "<button>Click.</button>", message: "HTMLButtonElement with javascript formaction"}, {config_input: {}, value: "<button formaction=' javascript:evil.com'>Click.</button>", result: "<button>Click.</button>", message: "HTMLButtonElement with javascript formaction start with space"}, {config_input: {}, value: "<button formaction='http:evil.com'>Click.</button>", result: "<button formaction=\"http:evil.com\">Click.</button>", message: "HTMLButtonElement"}, - {config_input: {}, value: "<p>Some text</p></body><!-- 1 --></html><!-- 2 --><p>Some more text</p>", result: "<p>Some text</p><!-- 1 --><!-- 2 --><p>Some more text</p>", message: "malformed HTML"}, + {config_input: {}, value: "<p>Some text</p></body><!-- 1 --></html><!-- 2 --><p>Some more text</p>", result: "<p>Some text</p><p>Some more text</p>", message: "malformed HTML"}, + {config_input: {}, value: "<p>Some text</p><!-- 1 --><!-- 2 --><p>Some more text</p>", result: "<p>Some text</p><p>Some more text</p>", message: "HTML with comments; comments not allowed"}, + {config_input: {allowComments: true}, value: "<p>Some text</p><!-- 1 --><!-- 2 --><p>Some more text</p>", result: "<p>Some text</p><!-- 1 --><!-- 2 --><p>Some more text</p>", message: "HTML with comments; allowComments"}, + {config_input: {allowComments: false}, value: "<p>Some text</p><!-- 1 --><!-- 2 --><p>Some more text</p>", result: "<p>Some text</p><p>Some more text</p>", message: "HTML with comments; !allowComments"}, + {config_input: {}, value: "<p>comment<!-- hello -->in<!-- </p> -->text</p>", result: "<p>commentintext</p>", message: "HTML with comments deeper in the tree"}, + {config_input: {allowComments: true}, value: "<p>comment<!-- hello -->in<!-- </p> -->text</p>", result: "<p>comment<!-- hello -->in<!-- </p> -->text</p>", message: "HTML with comments deeper in the tree, allowComments"}, + {config_input: {allowComments: false}, value: "<p>comment<!-- hello -->in<!-- </p> -->text</p>", result: "<p>commentintext</p>", message: "HTML with comments deeper in the tree, !allowComments"}, // Test cases from issue WICG/sanitizer-api#84 {
diff --git a/third_party/crashpad/crashpad/util/win/get_function.cc b/third_party/crashpad/crashpad/util/win/get_function.cc index 3d00a7a..91a91652a 100644 --- a/third_party/crashpad/crashpad/util/win/get_function.cc +++ b/third_party/crashpad/crashpad/util/win/get_function.cc
@@ -14,6 +14,8 @@ #include "util/win/get_function.h" +#include <ostream> + #include "base/check.h" #include "base/strings/utf_string_conversions.h"
diff --git a/third_party/zlib/google/zip_writer.cc b/third_party/zlib/google/zip_writer.cc index 69949cde..90b56eda 100644 --- a/third_party/zlib/google/zip_writer.cc +++ b/third_party/zlib/google/zip_writer.cc
@@ -8,12 +8,25 @@ #include "base/files/file.h" #include "base/logging.h" +#include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "third_party/zlib/google/zip_internal.h" namespace zip { namespace internal { +class Redact { + public: + explicit Redact(const base::FilePath& path) : path_(path) {} + + friend std::ostream& operator<<(std::ostream& out, const Redact&& r) { + return LOG_IS_ON(INFO) ? out << "'" << r.path_ << "'" : out << "(redacted)"; + } + + private: + const base::FilePath& path_; +}; + bool ZipWriter::ShouldContinue() { if (!progress_callback_) return true; @@ -38,7 +51,7 @@ file.ReadAtCurrentPos(buf, zip::internal::kZipBufSize); if (num_bytes < 0) { - DPLOG(ERROR) << "Cannot read file '" << path << "'"; + PLOG(ERROR) << "Cannot read file " << Redact(path); return false; } @@ -46,7 +59,8 @@ return true; if (zipWriteInFileInZip(zip_file_, buf, num_bytes) != ZIP_OK) { - DLOG(ERROR) << "Cannot write data from file '" << path << "' to ZIP"; + PLOG(ERROR) << "Cannot write data from file " << Redact(path) + << " to ZIP"; return false; } @@ -94,7 +108,7 @@ return false; if (!info.is_directory) { - LOG(ERROR) << "Not a directory: '" << path << "'"; + LOG(ERROR) << "Not a directory: " << Redact(path); return false; } @@ -141,7 +155,7 @@ APPEND_STATUS_CREATE); if (!zip_file) { - DLOG(ERROR) << "Cannot create ZIP file '" << zip_file_path << "'"; + PLOG(ERROR) << "Cannot create ZIP file " << Redact(zip_file_path); return nullptr; } @@ -239,7 +253,7 @@ base::File& file = files[i]; if (!file.IsValid()) { - LOG(ERROR) << "Cannot open '" << relative_path << "'"; + LOG(ERROR) << "Cannot open " << Redact(relative_path); return false; }
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py index 9945e70..b62b6a8 100644 --- a/tools/json_schema_compiler/cc_generator.py +++ b/tools/json_schema_compiler/cc_generator.py
@@ -47,6 +47,7 @@ self._namespace.short_filename)) .Append() .Append('#include <memory>') + .Append('#include <ostream>') .Append('#include <string>') .Append('#include <utility>') .Append('#include <vector>')
diff --git a/tools/json_schema_compiler/util.cc b/tools/json_schema_compiler/util.cc index 776f7e0..4c9a64e 100644 --- a/tools/json_schema_compiler/util.cc +++ b/tools/json_schema_compiler/util.cc
@@ -56,7 +56,13 @@ } bool PopulateItem(const base::Value& from, double* out) { - return from.GetAsDouble(out); + absl::optional<double> maybe_double = from.GetIfDouble(); + if (maybe_double.has_value()) { + if (out) + *out = maybe_double.value(); + return true; + } + return false; } bool PopulateItem(const base::Value& from, double* out, std::u16string* error) {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 5a24f1e0..a059e94 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -17999,7 +17999,6 @@ <int value="10" label="11.1"/> <int value="11" label="12.0"/> <int value="12" label="12.1"/> - <int value="13" label="12.2"/> </enum> <enum name="D3D11InitializeResult"> @@ -18069,6 +18068,7 @@ <int value="2" label="D3D_FEATURE_LEVEL_12_1"/> <int value="3" label="D3D_FEATURE_LEVEL_11_0"/> <int value="4" label="D3D_FEATURE_LEVEL_11_1"/> + <int value="5" label="D3D_FEATURE_LEVEL_12_2"/> </enum> <enum name="D3D9InitializeResult"> @@ -25855,6 +25855,7 @@ <int value="869" label="JavaScriptJitBlockedForSites"/> <int value="870" label="AllowHttpsOnlyMode"/> <int value="871" label="DesktopSharingHubEnabled"/> + <int value="872" label="RestrictedManagedGuestSessionEnabled"/> </enum> <enum name="EnterprisePolicyDeviceIdValidity">
diff --git a/tools/metrics/histograms/histograms_xml/net/histograms.xml b/tools/metrics/histograms/histograms_xml/net/histograms.xml index 0bb07d4b..793b3d8a 100644 --- a/tools/metrics/histograms/histograms_xml/net/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/net/histograms.xml
@@ -5691,6 +5691,9 @@ <histogram name="Net.WebSocket.CloseCode" enum="WebSocketCloseCode" expires_after="2021-07-01"> + <obsolete> + Removed July 2021. + </obsolete> <owner>ricea@chromium.org</owner> <owner>yhirano@chromium.org</owner> <owner>yoichio@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/sync/histograms.xml b/tools/metrics/histograms/histograms_xml/sync/histograms.xml index 446c873..74526d71 100644 --- a/tools/metrics/histograms/histograms_xml/sync/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/sync/histograms.xml
@@ -1437,6 +1437,18 @@ </summary> </histogram> +<histogram name="Sync.TrustedVaultURLFetchResponse" + enum="CombinedHttpResponseAndNetErrorCode" expires_after="2021-11-01"> + <owner>mmoskvitin@google.com</owner> + <owner>mastiz@chromium.org</owner> + <component>Services>Sync</component> + <summary> + Counts of responses (both http code and net error code) for requests to the + Trusted Vault server (aka Security Domain Service). Note that requests that + timed out are not covered by this histogram. + </summary> +</histogram> + <histogram name="Sync.TypedURLDatabaseError" enum="SyncTypedUrlDatabaseError" expires_after="2021-12-20"> <owner>jkrcal@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml b/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml index bea5fbdb..2abbb611 100644 --- a/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml
@@ -3856,9 +3856,8 @@ </histogram> <histogram name="WebRtcEventLogging.Api" enum="WebRtcEventLoggingApiEnum" - expires_after="2021-11-07"> + expires_after="2022-11-07"> <owner>eladalon@chromium.org</owner> - <owner>saeedj@google.com</owner> <owner>manj@google.com</owner> <owner>dmitriyg@google.com</owner> <summary> @@ -3868,9 +3867,8 @@ </histogram> <histogram name="WebRtcEventLogging.NetError" units="units" - expires_after="2021-07-07"> + expires_after="2022-11-07"> <owner>eladalon@chromium.org</owner> - <owner>saeedj@google.com</owner> <owner>manj@google.com</owner> <owner>dmitriyg@google.com</owner> <summary> @@ -3880,9 +3878,8 @@ </histogram> <histogram name="WebRtcEventLogging.Upload" enum="WebRtcEventLoggingUploadEnum" - expires_after="2021-11-14"> + expires_after="2022-11-07"> <owner>eladalon@chromium.org</owner> - <owner>saeedj@google.com</owner> <owner>manj@google.com</owner> <owner>dmitriyg@google.com</owner> <summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 2cda690..8727d1a 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -1,16 +1,16 @@ { "trace_processor_shell": { "win": { - "hash": "b1b2bf383645661b4c6790657863c46cec02121d", - "remote_path": "perfetto_binaries/trace_processor_shell/win/10a3658d9f6b470ba970e2bea95f19b1fd2e9cf2/trace_processor_shell.exe" + "hash": "c1c9368721a4da0f38ec9d5b99ce0cb48c371450", + "remote_path": "perfetto_binaries/trace_processor_shell/win/d04538362330bd3ae3d534c542fb71ead7b8f28a/trace_processor_shell.exe" }, "mac": { - "hash": "430c7a66ec2369760e6bb6a27174d7229b4f9fcf", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/10a3658d9f6b470ba970e2bea95f19b1fd2e9cf2/trace_processor_shell" + "hash": "168375ccbf25eafb4d77339b26ca40e806a44b7e", + "remote_path": "perfetto_binaries/trace_processor_shell/mac/9d04c12dbe18118cc78c8584508f9eac5ff757f9/trace_processor_shell" }, "linux": { - "hash": "d1a365306fac2e7d54fa5e336286811d2d7f6252", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/10a3658d9f6b470ba970e2bea95f19b1fd2e9cf2/trace_processor_shell" + "hash": "a91015a337519c0c1cf82efec48deddc70650e63", + "remote_path": "perfetto_binaries/trace_processor_shell/linux/9d04c12dbe18118cc78c8584508f9eac5ff757f9/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index fc4a66ff..6902e9e 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -278,6 +278,8 @@ crbug.com/892223 [ android-nexus-5 ] rasterize_and_record_micro.top_25/file://static_top_25/yahoogames.html [ Skip ] crbug.com/910207 [ android-nexus-5x ] rasterize_and_record_micro.top_25/file://static_top_25/yahoogames.html [ Skip ] crbug.com/875878 [ android-nexus-6 android-webview ] rasterize_and_record_micro.top_25/file://static_top_25/yahoogames.html [ Skip ] +crbug.com/1228228 [ android-webview ] rasterize_and_record_micro.top_25/file://static_top_25/gmail.html [ Skip ] +crbug.com/1228228 [ mac-10.12 ] rasterize_and_record_micro.top_25/file://static_top_25/gmail.html [ Skip ] # Benchmark: startup.mobile crbug.com/948789 [ android-nexus-5 ] startup.mobile/maps_pwa:with_http_cache [ Skip ]
diff --git a/ui/base/text/bytes_formatting.cc b/ui/base/text/bytes_formatting.cc index 7cceda67..eda25e9 100644 --- a/ui/base/text/bytes_formatting.cc +++ b/ui/base/text/bytes_formatting.cc
@@ -4,6 +4,8 @@ #include "ui/base/text/bytes_formatting.h" +#include <ostream> + #include "base/check.h" #include "base/cxx17_backports.h" #include "base/i18n/number_formatting.h"
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc index 06b218f..988159e7 100644 --- a/ui/gfx/render_text.cc +++ b/ui/gfx/render_text.cc
@@ -1031,7 +1031,7 @@ // Newline segment should be ignored in finding segment index with x // coordinate because it's not drawn. Vector2d newline_offset; - if (line.segments.size() > 1 && IsNewlineSegment(line.segments.front())) + if (line.segments.size() >= 1 && IsNewlineSegment(line.segments.front())) newline_offset.set_x(line.segments.front().width()); float point_offset_relative_segment = 0;
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc index e1399bc..80c27f9 100644 --- a/ui/gfx/render_text_unittest.cc +++ b/ui/gfx/render_text_unittest.cc
@@ -3156,6 +3156,68 @@ SELECTION_CARET, &expected_range); } +TEST_F(RenderTextTest, MoveCursor_UpDown_EmptyLines) { + SetGlyphWidth(5); + RenderText* render_text = GetRenderText(); + render_text->SetText(u"one\n\ntwo three"); + render_text->SetDisplayRect(Rect(45, 1000)); + render_text->SetMultiline(true); + EXPECT_EQ(3U, render_text->GetNumLines()); + + std::vector<Range> expected_range; + + // Test up/down cursor movement at the start of the line. + render_text->SelectRange(Range(0)); + expected_range.push_back(Range(4)); + expected_range.push_back(Range(5)); + expected_range.push_back(Range(14)); + RunMoveCursorTestAndClearExpectations(render_text, CHARACTER_BREAK, + CURSOR_DOWN, SELECTION_NONE, + &expected_range); + + render_text->SelectRange(Range(5)); + expected_range.push_back(Range(4)); + expected_range.push_back(Range(0)); + expected_range.push_back(Range(0)); + RunMoveCursorTestAndClearExpectations(render_text, CHARACTER_BREAK, CURSOR_UP, + SELECTION_NONE, &expected_range); + + // Test up/down movement at the end of the line. + render_text->SelectRange(Range(3)); + expected_range.push_back(Range(4)); + // TODO(crbug.com/1163587): This should actually be |8|, since |9| is the + // beginning of the next line. This assert is left in for now to allow testing + // the next expected position, which correctly ends up at |14|. + expected_range.push_back(Range(9)); + expected_range.push_back(Range(14)); + RunMoveCursorTestAndClearExpectations(render_text, CHARACTER_BREAK, + CURSOR_DOWN, SELECTION_NONE, + &expected_range); + + render_text->SelectRange(Range(14)); + expected_range.push_back(Range(4)); + expected_range.push_back(Range(3)); + expected_range.push_back(Range(0)); + RunMoveCursorTestAndClearExpectations(render_text, CHARACTER_BREAK, CURSOR_UP, + SELECTION_NONE, &expected_range); + + // Test up/down movement somewhere in the middle of the line. + render_text->SelectRange(Range(2)); + expected_range.push_back(Range(4)); + expected_range.push_back(Range(7)); + expected_range.push_back(Range(14)); + RunMoveCursorTestAndClearExpectations(render_text, CHARACTER_BREAK, + CURSOR_DOWN, SELECTION_NONE, + &expected_range); + + render_text->SelectRange(Range(7)); + expected_range.push_back(Range(4)); + expected_range.push_back(Range(2)); + expected_range.push_back(Range(0)); + RunMoveCursorTestAndClearExpectations(render_text, CHARACTER_BREAK, CURSOR_UP, + SELECTION_NONE, &expected_range); +} + TEST_F(RenderTextTest, MoveCursor_UpDown_Cache) { SetGlyphWidth(5); RenderText* render_text = GetRenderText();
diff --git a/url/gurl.cc b/url/gurl.cc index cf50ecc..734aa0b 100644 --- a/url/gurl.cc +++ b/url/gurl.cc
@@ -237,11 +237,8 @@ NULL, &output, &result.parsed_); output.Complete(); - if (result.is_valid_ && result.SchemeIsFileSystem()) { - result.inner_url_ = - std::make_unique<GURL>(result.spec_.data(), result.parsed_.Length(), - *result.parsed_.inner_parsed(), true); - } + + ProcessFileOrFileSystemURLAfterReplaceComponents(result); return result; } @@ -260,14 +257,34 @@ NULL, &output, &result.parsed_); output.Complete(); - if (result.is_valid_ && result.SchemeIsFileSystem()) { - result.inner_url_ = - std::make_unique<GURL>(result.spec_.data(), result.parsed_.Length(), - *result.parsed_.inner_parsed(), true); - } + + ProcessFileOrFileSystemURLAfterReplaceComponents(result); + return result; } +void GURL::ProcessFileOrFileSystemURLAfterReplaceComponents(GURL& url) const { + if (!url.is_valid_) + return; + if (url.SchemeIsFileSystem()) { + url.inner_url_ = + std::make_unique<GURL>(url.spec_.data(), url.parsed_.Length(), + *url.parsed_.inner_parsed(), true); + } +#ifdef WIN32 + if (url.SchemeIsFile()) { + // On Win32, some file URLs created through ReplaceComponents used to lose + // its hostname after getting reparsed (e.g. when it's sent through IPC) due + // to special handling of file URLs with Windows-drive paths in the URL + // parser. To make the behavior for URLs modified through ReplaceComponents + // (instead of getting fully reparsed) the same, immediately reparse the + // URL here to trigger the special handling. + // See https://crbug.com/1214098. + url = GURL(url.spec()); + } +#endif +} + GURL GURL::GetOrigin() const { // This doesn't make sense for invalid or nonstandard URLs, so return // the empty URL.
diff --git a/url/gurl.h b/url/gurl.h index 74c6e746..38ba831 100644 --- a/url/gurl.h +++ b/url/gurl.h
@@ -468,6 +468,8 @@ return base::StringPiece(&spec_[comp.begin], comp.len); } + void ProcessFileOrFileSystemURLAfterReplaceComponents(GURL& url) const; + // The actual text of the URL, in canonical ASCII form. std::string spec_;
diff --git a/url/ipc/url_param_traits_unittest.cc b/url/ipc/url_param_traits_unittest.cc index 7115394..9103f80 100644 --- a/url/ipc/url_param_traits_unittest.cc +++ b/url/ipc/url_param_traits_unittest.cc
@@ -88,49 +88,67 @@ // Test for the GURL testcase based on https://crbug.com/1214098 (which in turn // was based on ContentSecurityPolicyBrowserTest.FileURLs). TEST(IPCMessageTest, SerializeGurl_WindowsDriveInPathReplacement) { - GURL url1("file://hostname/"); - ExpectSerializationRoundtrips(url1); - EXPECT_EQ("/", url1.path()); - EXPECT_EQ("hostname", url1.host()); + { + // #1: Try creating a file URL with a non-empty hostname. + GURL url_without_windows_drive_letter("file://hostname/"); + EXPECT_EQ("/", url_without_windows_drive_letter.path()); + EXPECT_EQ("hostname", url_without_windows_drive_letter.host()); + ExpectSerializationRoundtrips(url_without_windows_drive_letter); + } - // Use GURL::Replacement to create a GURL with 1) a path that starts with a C: - // drive letter and 2) has a non-empty hostname (inherited from `url1` above). - // Without GURL::Replacement we would just get `url2` below, with an empty - // hostname, because of how DoParseUNC resets the hostname on Win32 (for more - // details see https://crbug.com/1214098#c4). - GURL::Replacements repl; - const std::string kNewPath = "/C:/dir/file.txt"; - repl.SetPath(kNewPath.c_str(), url::Component(0, kNewPath.length())); - GURL url1_with_replaced_path = url1.ReplaceComponents(repl); - EXPECT_EQ(kNewPath, url1_with_replaced_path.path()); - EXPECT_EQ("hostname", url1_with_replaced_path.host()); + { + // #2: Use GURL::Replacement to create a GURL with 1) a path that starts + // with a Windows drive letter and 2) has a non-empty hostname (inherited + // from `url_without_windows_drive_letter` above). This used to not go + // through the DoParseUNC path that normally strips the hostname (for more + // details, see https://crbug.com/1214098#c4). + GURL::Replacements repl; + const std::string kNewPath = "/C:/dir/file.txt"; + repl.SetPath(kNewPath.c_str(), url::Component(0, kNewPath.length())); + GURL url_made_with_replace_components = + GURL("file://hostname/").ReplaceComponents(repl); + EXPECT_EQ(kNewPath, url_made_with_replace_components.path()); #ifdef WIN32 - // TODO(https://crbug.com/1214098): All GURLs should round-trip when bounced - // through IPC, but this doesn't work for `url1_with_replaced_path` on - // Windows. - GURL roundtrip = BounceUrl(url1_with_replaced_path); - EXPECT_NE(roundtrip.host(), url1_with_replaced_path.host()); + // Due to the reparsing logic in ReplaceComponents, the hostname is stripped + // for this URL too. + EXPECT_EQ("", url_made_with_replace_components.host()); + EXPECT_EQ("file:///C:/dir/file.txt", + url_made_with_replace_components.spec()); #else - // This is the MAIN VERIFICATION in this test. The fact that this - // verification fails on Windows is the bug tracked in - // https://crbug.com/1214098. - ExpectSerializationRoundtrips(url1_with_replaced_path); + EXPECT_EQ("hostname", url_made_with_replace_components.host()); + EXPECT_EQ("file://hostname/C:/dir/file.txt", + url_made_with_replace_components.spec()); #endif + // This is the MAIN VERIFICATION in this test. This used to fail on Windows, + // see https://crbug.com/1214098. + ExpectSerializationRoundtrips(url_made_with_replace_components); + } - // On Windows, IPC will serialize/deserialze `url1_with_replaced_path` as - // `url2` (i.e. it won't round-trip the URL spec). The test assertions below - // help illustrate why we can't assert ExpectSerializationRoundtrips above (on - // Windows). - EXPECT_EQ("file://hostname/C:/dir/file.txt", url1_with_replaced_path.spec()); - GURL url2(url1_with_replaced_path.spec()); + { + // #3: Try to create a URL with a Windows drive letter and a non-empty + // hostname directly. + GURL url_created_directly("file://hostname/C:/dir/file.txt"); + EXPECT_EQ("/C:/dir/file.txt", url_created_directly.path()); #ifdef WIN32 - EXPECT_NE(url2.spec(), url1_with_replaced_path.spec()); - EXPECT_EQ("", url2.host()); + // On Win32, the hostname will be reset by DoParseUNC. + EXPECT_EQ("", url_created_directly.host()); + EXPECT_EQ("file:///C:/dir/file.txt", url_created_directly.spec()); #else - EXPECT_EQ(url2.spec(), url1_with_replaced_path.spec()); - EXPECT_EQ("hostname", url2.host()); + // On other platforms, the hostname is kept. + EXPECT_EQ("hostname", url_created_directly.host()); + EXPECT_EQ("file://hostname/C:/dir/file.txt", url_created_directly.spec()); #endif - EXPECT_EQ(url2.path(), url1_with_replaced_path.path()); - ExpectSerializationRoundtrips(url2); + ExpectSerializationRoundtrips(url_created_directly); + + // The URL created directly and the URL created through ReplaceComponents + // should be the same. + GURL::Replacements repl; + const std::string kNewPath = "/C:/dir/file.txt"; + repl.SetPath(kNewPath.c_str(), url::Component(0, kNewPath.length())); + GURL url_made_with_replace_components = + GURL("file://hostname/").ReplaceComponents(repl); + EXPECT_EQ(url_created_directly.spec(), + url_made_with_replace_components.spec()); + } }
diff --git a/url/mojom/url_gurl_mojom_traits_unittest.cc b/url/mojom/url_gurl_mojom_traits_unittest.cc index 357a701..886ca37 100644 --- a/url/mojom/url_gurl_mojom_traits_unittest.cc +++ b/url/mojom/url_gurl_mojom_traits_unittest.cc
@@ -99,51 +99,69 @@ // Test for the GURL testcase based on https://crbug.com/1214098 (which in turn // was based on ContentSecurityPolicyBrowserTest.FileURLs). TEST_F(MojoGURLStructTraitsTest, WindowsDriveInPathReplacement) { - GURL url1("file://hostname/"); - ExpectSerializationRoundtrips(url1); - EXPECT_EQ("/", url1.path()); - EXPECT_EQ("hostname", url1.host()); + { + // #1: Try creating a file URL with a non-empty hostname. + GURL url_without_windows_drive_letter("file://hostname/"); + EXPECT_EQ("/", url_without_windows_drive_letter.path()); + EXPECT_EQ("hostname", url_without_windows_drive_letter.host()); + ExpectSerializationRoundtrips(url_without_windows_drive_letter); + } - // Use GURL::Replacement to create a GURL with 1) a path that starts with a C: - // drive letter and 2) has a non-empty hostname (inherited from `url1` above). - // Without GURL::Replacement we would just get `url2` below, with an empty - // hostname, because of how DoParseUNC resets the hostname on Win32 (for more - // details see https://crbug.com/1214098#c4). - GURL::Replacements repl; - const std::string kNewPath = "/C:/dir/file.txt"; - repl.SetPath(kNewPath.c_str(), url::Component(0, kNewPath.length())); - GURL url1_with_replaced_path = url1.ReplaceComponents(repl); - EXPECT_EQ(kNewPath, url1_with_replaced_path.path()); - EXPECT_EQ("hostname", url1_with_replaced_path.host()); + { + // #2: Use GURL::Replacement to create a GURL with 1) a path that starts + // with a Windows drive letter and 2) has a non-empty hostname (inherited + // from `url_without_windows_drive_letter` above). This used to not go + // through the DoParseUNC path that normally strips the hostname (for more + // details, see https://crbug.com/1214098#c4). + GURL::Replacements repl; + const std::string kNewPath = "/C:/dir/file.txt"; + repl.SetPath(kNewPath.c_str(), url::Component(0, kNewPath.length())); + GURL url_made_with_replace_components = + GURL("file://hostname/").ReplaceComponents(repl); + EXPECT_EQ(kNewPath, url_made_with_replace_components.path()); #ifdef WIN32 - // TODO(https://crbug.com/1214098): All GURLs should round-trip when bounced - // through IPC, but this doesn't work for `url1_with_replaced_path` on - // Windows. - GURL roundtrip = BounceUrl(url1_with_replaced_path); - EXPECT_NE(roundtrip.host(), url1_with_replaced_path.host()); + // Due to the reparsing logic in ReplaceComponents, the hostname is stripped + // for this URL too. + EXPECT_EQ("", url_made_with_replace_components.host()); + EXPECT_EQ("file:///C:/dir/file.txt", + url_made_with_replace_components.spec()); #else - // This is the MAIN VERIFICATION in this test. The fact that this - // verification fails on Windows is the bug tracked in - // https://crbug.com/1214098. - ExpectSerializationRoundtrips(url1_with_replaced_path); + EXPECT_EQ("hostname", url_made_with_replace_components.host()); + EXPECT_EQ("file://hostname/C:/dir/file.txt", + url_made_with_replace_components.spec()); #endif + // This is the MAIN VERIFICATION in this test. This used to fail on Windows, + // see https://crbug.com/1214098. + ExpectSerializationRoundtrips(url_made_with_replace_components); + } - // On Windows, IPC will serialize/deserialze `url1_with_replaced_path` as - // `url2` (i.e. it won't round-trip the URL spec). The test assertions below - // help illustrate why we can't assert ExpectSerializationRoundtrips above (on - // Windows). - EXPECT_EQ("file://hostname/C:/dir/file.txt", url1_with_replaced_path.spec()); - GURL url2(url1_with_replaced_path.spec()); + { + // #3: Try to create a URL with a Windows drive letter and a non-empty + // hostname directly. + GURL url_created_directly("file://hostname/C:/dir/file.txt"); + EXPECT_EQ("/C:/dir/file.txt", url_created_directly.path()); #ifdef WIN32 - EXPECT_NE(url2.spec(), url1_with_replaced_path.spec()); - EXPECT_EQ("", url2.host()); + // On Win32, the hostname will be reset by DoParseUNC. + EXPECT_EQ("", url_created_directly.host()); + EXPECT_EQ("file:///C:/dir/file.txt", url_created_directly.spec()); #else - EXPECT_EQ(url2.spec(), url1_with_replaced_path.spec()); - EXPECT_EQ("hostname", url2.host()); + // On other platforms, the hostname is kept. + EXPECT_EQ("hostname", url_created_directly.host()); + EXPECT_EQ("file://hostname/C:/dir/file.txt", url_created_directly.spec()); #endif - EXPECT_EQ(url2.path(), url1_with_replaced_path.path()); - ExpectSerializationRoundtrips(url2); + ExpectSerializationRoundtrips(url_created_directly); + + // The URL created directly and the URL created through ReplaceComponents + // should be the same. + GURL::Replacements repl; + const std::string kNewPath = "/C:/dir/file.txt"; + repl.SetPath(kNewPath.c_str(), url::Component(0, kNewPath.length())); + GURL url_made_with_replace_components = + GURL("file://hostname/").ReplaceComponents(repl); + EXPECT_EQ(url_created_directly.spec(), + url_made_with_replace_components.spec()); + } } // Test of basic Origin serialization.
diff --git a/url/third_party/mozilla/url_parse.cc b/url/third_party/mozilla/url_parse.cc index d882e3f..8a2d9d9d 100644 --- a/url/third_party/mozilla/url_parse.cc +++ b/url/third_party/mozilla/url_parse.cc
@@ -38,6 +38,8 @@ #include <stdlib.h> +#include <ostream> + #include "base/check_op.h" #include "url/url_parse_internal.h" #include "url/url_util.h"
diff --git a/url/url_idna_icu_alternatives_ios.mm b/url/url_idna_icu_alternatives_ios.mm index c5da3593..0fb241b 100644 --- a/url/url_idna_icu_alternatives_ios.mm +++ b/url/url_idna_icu_alternatives_ios.mm
@@ -4,6 +4,7 @@ #include <string.h> +#include <ostream> #include <string> #include "base/strings/string_piece.h" @@ -24,4 +25,4 @@ return false; } -} // namespace url \ No newline at end of file +} // namespace url
diff --git a/url/url_util.cc b/url/url_util.cc index 00da5707..42bb76c 100644 --- a/url/url_util.cc +++ b/url/url_util.cc
@@ -6,7 +6,9 @@ #include <stddef.h> #include <string.h> + #include <atomic> +#include <ostream> #include "base/check_op.h" #include "base/compiler_specific.h"