diff --git a/DEPS b/DEPS index 73dea76..0aa515b2 100644 --- a/DEPS +++ b/DEPS
@@ -319,7 +319,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '48f7cb2ab354e2fbafbde943e05082058585dca0', + 'swiftshader_revision': '6d0e2d57acf9486b869dc06c6f53a12fe5a55636', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -378,7 +378,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '978c34bea3e5d056785891cb3715b8b617d6d8a9', + 'catapult_revision': 'e9d00911512b1412c72eda19785a332ae13cfa69', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -490,7 +490,7 @@ # If you change this, also update the libc++ revision in # //buildtools/deps_revisions.gni. - 'libcxx_revision': 'ebf2d34001903baf5169f4bee0b4823025d36da6', + 'libcxx_revision': '64d36e572d3f9719c5d75011a718f33f11126851', # GN CIPD package version. 'gn_version': 'git_revision:b9c6c19be95a3863e02f00f1fe403b2502e345b6', @@ -818,7 +818,7 @@ 'src/clank': { 'url': 'https://chrome-internal.googlesource.com/clank/internal/apps.git' + '@' + - '6dd3c99a521578ce7bdf8a234d20a4e0cf73e273', + '9ea4f61b3c171f9393aa126d3b9913f7bec2d644', 'condition': 'checkout_android and checkout_src_internal and not checkout_clank_via_src_internal', }, @@ -912,7 +912,7 @@ 'packages': [ { 'package': 'chromium/rts/model/linux-amd64', - 'version': 'hppdaBp4VoTvi0ItuKgaCv9SuQK9Sl4WeAnZ5Fzc-bMC', + 'version': 'XEbOH2L8Z6ubx_LPnXmj_Xdltz9g3D9H8GZK39M3ufIC', }, ], 'dep_type': 'cipd', @@ -923,7 +923,7 @@ 'packages': [ { 'package': 'chromium/rts/model/mac-amd64', - 'version': 'jdJ6El9S2NMDQ2vffy_v-sD5dSaXloWg5ZnhUNfYjuQC', + 'version': 'ekwGtBO0MwF3UiT2Mrd_s8obssggePxHG4yLRniKIO8C', }, ], 'dep_type': 'cipd', @@ -934,7 +934,7 @@ 'packages': [ { 'package': 'chromium/rts/model/windows-amd64', - 'version': 'UZfHWq2RLk2n8VK7n_FZJamXWnrKVr_g5ocWXY9dV1IC', + 'version': 'Kw4UqmzsIh9S81Bme5Nn8PWYRJHQCwkRY244SZR53j8C', }, ], 'dep_type': 'cipd', @@ -1002,7 +1002,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'cHra4lihGuEjjePdvusuSkcTCUXWaEJe0n_RtvAbUfwC', + 'version': 'JAK1JohWSJjm36wDo8wmTCudJ4_FjnqO3PuS7EC2EZoC', }, ], 'condition': 'checkout_android', @@ -1217,7 +1217,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' + '@' + 'c21ecb73b68dadfbf6964ce78ea3a861900a7c6d', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '6c507298cc8d99e4f543d18c4ae4fcc8fcdb8158', 'condition': 'checkout_chromeos', }, @@ -1245,7 +1245,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'ab896c761c0529a9ea0437b967a25aa4368957a1', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '5b5ee2de1b2b405061b92185c129a7016c6d62b4', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1811,7 +1811,7 @@ 'dep_type': 'cipd', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@0386d7db7e5932861207f26aeb225368a31f83ad', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@cc354388a3eba2759a5158896c2ed7a433ab5884', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'ebe84bec02c041d28f902da0214bf442743fc907', @@ -1851,7 +1851,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'eba1a78f3d741241b0dbee728561b61e9587a686', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '77ec9f501593d74b18a032fab999e7d350d15add', + Var('webrtc_git') + '/src.git' + '@' + '2068d0daa78100056dd1e3c1eae7317389079859', # Wuffs' canonical repository is at github.com/google/wuffs, but we use # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file. @@ -1921,7 +1921,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@4d816302525dff8ee8e5c1204d2c84c550d669fd', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@09f5b2382850af3ea498f4b386d8a2696abafca2', 'condition': 'checkout_src_internal', }, @@ -1962,7 +1962,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'MDlzVT6pgCLfZh9mbyIvVkzHWtr_uqgEm_9GHxROZyUC', + 'version': 'feBy3xsR68fgOa4--x06At_7WOjDwg_7v0Oavzlp8cMC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 213b129..d338202 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -2952,6 +2952,7 @@ "system/power/adaptive_charging_notification_controller_unittest.cc", "system/power/adaptive_charging_nudge_controller_unittest.cc", "system/power/backlights_forced_off_setter_unittest.cc", + "system/power/battery_notification_unittest.cc", "system/power/peripheral_battery_listener_unittest.cc", "system/power/peripheral_battery_notifier_listener_integration_test.cc", "system/power/peripheral_battery_notifier_unittest.cc",
diff --git a/ash/app_list/app_list_controller_impl_unittest.cc b/ash/app_list/app_list_controller_impl_unittest.cc index 19e7bfa..e563c95c 100644 --- a/ash/app_list/app_list_controller_impl_unittest.cc +++ b/ash/app_list/app_list_controller_impl_unittest.cc
@@ -1446,16 +1446,11 @@ EXPECT_FALSE(controller->IsVisible()); } -// App list assistant tests, parameterized by ProductivityLauncher. -class AppListControllerWithAssistantTest - : public AppListControllerImplTest, - public testing::WithParamInterface<bool> { +// App list assistant tests. +class AppListControllerWithAssistantTest : public AppListControllerImplTest { public: AppListControllerWithAssistantTest() - : assistant_test_api_(AssistantTestApi::Create()) { - feature_list_.InitWithFeatureState(features::kProductivityLauncher, - GetParam()); - } + : assistant_test_api_(AssistantTestApi::Create()) {} AppListControllerWithAssistantTest( const AppListControllerWithAssistantTest&) = delete; AppListControllerWithAssistantTest& operator=( @@ -1488,13 +1483,9 @@ base::test::ScopedFeatureList feature_list_; }; -INSTANTIATE_TEST_SUITE_P(ProductivityLauncher, - AppListControllerWithAssistantTest, - testing::Bool()); - -// Verifies the scenario that the Assistant shortcut is triggered when the the -// app list close animation is running. -TEST_P(AppListControllerWithAssistantTest, +// Verifies the scenario that the Assistant shortcut is triggered when the app +// list close animation is running. +TEST_F(AppListControllerWithAssistantTest, TriggerAssistantKeyWhenAppListClosing) { // Show the Assistant and verify the app list state. ToggleAssistantUiWithAccelerator(); @@ -1516,17 +1507,11 @@ EXPECT_EQ(AssistantVisibility::kClosing, GetAssistantVisibility()); // Toggle the Assistant ui and wait for app list animation to finish. - if (features::IsProductivityLauncherEnabled()) { - AppListBubbleView* bubble_view = - app_list_controller->bubble_presenter_for_test() - ->bubble_view_for_test(); - ToggleAssistantUiWithAccelerator(); - ui::LayerAnimationStoppedWaiter().Wait(bubble_view->layer()); - } else { - views::WidgetAnimationWaiter waiter(GetAppListView()->GetWidget()); - ToggleAssistantUiWithAccelerator(); - waiter.WaitForAnimation(); - } + AppListBubbleView* bubble_view = + app_list_controller->bubble_presenter_for_test() + ->bubble_view_for_test(); + ToggleAssistantUiWithAccelerator(); + ui::LayerAnimationStoppedWaiter().Wait(bubble_view->layer()); } // Verify that the Assistant ui is visible. In addition, the text in the @@ -1540,17 +1525,16 @@ PressAndReleaseKey(ui::KeyboardCode::VKEY_COMMAND); EXPECT_FALSE(app_list_controller->IsVisible()); - // Toggle the Assistant ui. The text input field should be cleared. + // Toggle the Assistant ui. The text is still the same in the input field. ToggleAssistantUiWithAccelerator(); EXPECT_TRUE(app_list_controller->IsVisible()); - // TODO(jamescook): Decide if we want this behavior for ProductivityLauncher. - if (!features::IsProductivityLauncherEnabled()) - EXPECT_TRUE(assistant_test_api_->input_text_field()->GetText().empty()); + EXPECT_TRUE(assistant_test_api_->IsVisible()); + EXPECT_EQ(u"xyz", assistant_test_api_->input_text_field()->GetText()); } -// Verifies the scenario that the search key is triggered when the the app list +// Verifies the scenario that the search key is triggered when the app list // close animation is running. -TEST_P(AppListControllerWithAssistantTest, TriggerSearchKeyWhenAppListClosing) { +TEST_F(AppListControllerWithAssistantTest, TriggerSearchKeyWhenAppListClosing) { ToggleAssistantUiWithAccelerator(); auto* app_list_controller = Shell::Get()->app_list_controller(); EXPECT_TRUE(app_list_controller->IsVisible()); @@ -1564,17 +1548,10 @@ EXPECT_EQ(AssistantVisibility::kClosing, GetAssistantVisibility()); // Press the search key to reshow the app list. - if (features::IsProductivityLauncherEnabled()) { - AppListBubbleView* bubble_view = - app_list_controller->bubble_presenter_for_test() - ->bubble_view_for_test(); - PressAndReleaseKey(ui::KeyboardCode::VKEY_COMMAND); - ui::LayerAnimationStoppedWaiter().Wait(bubble_view->layer()); - } else { - views::WidgetAnimationWaiter waiter(GetAppListView()->GetWidget()); - PressAndReleaseKey(ui::KeyboardCode::VKEY_COMMAND); - waiter.WaitForAnimation(); - } + AppListBubbleView* bubble_view = + app_list_controller->bubble_presenter_for_test()->bubble_view_for_test(); + PressAndReleaseKey(ui::KeyboardCode::VKEY_COMMAND); + ui::LayerAnimationStoppedWaiter().Wait(bubble_view->layer()); // The Assistant should be closed. EXPECT_EQ(AssistantVisibility::kClosed, GetAssistantVisibility());
diff --git a/ash/app_list/views/assistant/assistant_dialog_plate.cc b/ash/app_list/views/assistant/assistant_dialog_plate.cc index 140b4d72..c65b0bd9 100644 --- a/ash/app_list/views/assistant/assistant_dialog_plate.cc +++ b/ash/app_list/views/assistant/assistant_dialog_plate.cc
@@ -90,13 +90,8 @@ if (features::IsDarkLightModeEnabled()) return cros_tokens::kColorPrimary; - if (features::IsProductivityLauncherEnabled()) { - // Productivity launcher is default dark. - return cros_tokens::kColorPrimaryDark; - } - - // The old behavior is default light. - return cros_tokens::kColorPrimaryLight; + // The dark color is used by default. + return cros_tokens::kColorPrimaryDark; } // Returns the secondary color adjusted for enabled features. @@ -104,13 +99,8 @@ if (features::IsDarkLightModeEnabled()) return cros_tokens::kColorSecondary; - if (features::IsProductivityLauncherEnabled()) { - // Productivity launcher is default dark. - return cros_tokens::kColorSecondaryDark; - } - - // The old behavior is default light. - return cros_tokens::kColorSecondaryLight; + // The dark color is used by default. + return cros_tokens::kColorSecondaryDark; } } // namespace
diff --git a/ash/app_list/views/assistant/assistant_page_view.cc b/ash/app_list/views/assistant/assistant_page_view.cc index 07f77f0d..950efd3 100644 --- a/ash/app_list/views/assistant/assistant_page_view.cc +++ b/ash/app_list/views/assistant/assistant_page_view.cc
@@ -450,30 +450,19 @@ void AssistantPageView::UpdateBackground(bool in_tablet_mode) { // Blur - if (features::IsProductivityLauncherEnabled() || - (in_tablet_mode && features::IsDarkLightModeEnabled() && - features::IsBackgroundBlurEnabled())) { - layer()->SetBackgroundBlur(ColorProvider::kBackgroundBlurSigma); - layer()->SetBackdropFilterQuality(ColorProvider::kBackgroundBlurQuality); - } else { - layer()->SetBackgroundBlur(0.0f); - layer()->SetBackdropFilterQuality(0.0f); - } + layer()->SetBackgroundBlur(ColorProvider::kBackgroundBlurSigma); + layer()->SetBackdropFilterQuality(ColorProvider::kBackgroundBlurQuality); // Color const auto* color_provider = GetWidget() ? GetWidget()->GetColorProvider() : nullptr; + // ColorProvide might be nullptr in tests or this function is triggered before // `this` is added to the view hierarchy. - if (color_provider && features::IsProductivityLauncherEnabled()) { + if (color_provider) layer()->SetColor(color_provider->GetColor(kColorAshShieldAndBase80)); - } else if (color_provider && features::IsDarkLightModeEnabled()) { - layer()->SetColor(color_provider->GetColor( - features::IsBackgroundBlurEnabled() ? kColorAshShieldAndBase80 - : kColorAshShieldAndBase95)); - } else { + else layer()->SetColor(SK_ColorWHITE); - } } // TODO(crbug.com/1359096): Clean up this function and its relative code path.
diff --git a/ash/app_list/views/assistant/assistant_test_api_impl.cc b/ash/app_list/views/assistant/assistant_test_api_impl.cc index a6c22f7..64b9387 100644 --- a/ash/app_list/views/assistant/assistant_test_api_impl.cc +++ b/ash/app_list/views/assistant/assistant_test_api_impl.cc
@@ -55,8 +55,7 @@ } bool AssistantTestApiImpl::IsVisible() { - if (!TabletMode::Get()->InTabletMode() && - features::IsProductivityLauncherEnabled()) { + if (!TabletMode::Get()->InTabletMode()) { return Shell::Get()->app_list_controller()->IsVisible() && GetAppListBubbleView()->assistant_page_->GetVisible(); } @@ -75,8 +74,7 @@ } views::View* AssistantTestApiImpl::page_view() { - if (!TabletMode::Get()->InTabletMode() && - features::IsProductivityLauncherEnabled()) { + if (!TabletMode::Get()->InTabletMode()) { auto* bubble_view = GetAppListBubbleView(); DCHECK(bubble_view) << "App list is not showing. Display the assistant UI first.";
diff --git a/ash/app_list/views/search_result_list_view.cc b/ash/app_list/views/search_result_list_view.cc index 9986e75..1f91a19b 100644 --- a/ash/app_list/views/search_result_list_view.cc +++ b/ash/app_list/views/search_result_list_view.cc
@@ -460,8 +460,11 @@ std::vector<AppListNotifier::Result> notifier_results; for (const auto* result : displayed_results) notifier_results.emplace_back(result->id(), result->metrics_type()); - notifier->NotifyResultsUpdated(SearchResultDisplayType::kList, - notifier_results); + notifier->NotifyResultsUpdated( + list_type_ == SearchResultListType::kAnswerCard + ? SearchResultDisplayType::kAnswerCard + : SearchResultDisplayType::kList, + notifier_results); } return displayed_results.size(); }
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 8fdda184..41eb4cbf 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -1961,11 +1961,6 @@ "UseAuthFactors", base::FEATURE_ENABLED_BY_DEFAULT); -// Enables using the BluetoothSystem Mojo interface for Bluetooth operations. -BASE_FEATURE(kUseBluetoothSystemInAsh, - "UseBluetoothSystemInAsh", - base::FEATURE_DISABLED_BY_DEFAULT); - // When enabled, the login shelf view is placed in its own widget instead of // sharing the shelf widget with other components. BASE_FEATURE(kUseLoginShelfWidget,
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 5238f87..be68720 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -558,8 +558,6 @@ COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kUseAuthsessionAuthentication); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kUseAuthFactors); -// TODO(b/231254441): Remove kUseBluetoothSystemInAsh flag. -COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kUseBluetoothSystemInAsh); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kUseLoginShelfWidget); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kUseMessagesStagingUrl); COMPONENT_EXPORT(ASH_CONSTANTS)
diff --git a/ash/shell.cc b/ash/shell.cc index 65f1e7a7..f3f1abc 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -1089,7 +1089,8 @@ wallpaper_controller_ = WallpaperControllerImpl::Create(local_state_); - if (features::IsRgbKeyboardEnabled()) { + if (features::IsRgbKeyboardEnabled() && + rgb_keyboard_manager_->IsRgbKeyboardSupported()) { // Initialized after |wallpaper_controller_| because we will need to observe // when the extracted wallpaper color changes. keyboard_backlight_color_controller_ =
diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h index bd104a54..17eee901 100644 --- a/ash/shell_delegate.h +++ b/ash/shell_delegate.h
@@ -14,7 +14,6 @@ #include "chromeos/ui/base/window_pin_type.h" #include "components/version_info/channel.h" #include "mojo/public/cpp/bindings/pending_receiver.h" -#include "services/device/public/mojom/bluetooth_system.mojom-forward.h" #include "services/device/public/mojom/fingerprint.mojom-forward.h" #include "services/media_session/public/cpp/media_session_service.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -102,10 +101,6 @@ // dragged out of it. virtual int GetBrowserWebUITabStripHeight() = 0; - // Binds a BluetoothSystemFactory receiver if possible. - virtual void BindBluetoothSystemFactory( - mojo::PendingReceiver<device::mojom::BluetoothSystemFactory> receiver) {} - // Binds a fingerprint receiver in the Device Service if possible. virtual void BindFingerprint( mojo::PendingReceiver<device::mojom::Fingerprint> receiver) {}
diff --git a/ash/system/keyboard_brightness/keyboard_backlight_color_controller.cc b/ash/system/keyboard_brightness/keyboard_backlight_color_controller.cc index 1ff11af5..50d9412 100644 --- a/ash/system/keyboard_brightness/keyboard_backlight_color_controller.cc +++ b/ash/system/keyboard_brightness/keyboard_backlight_color_controller.cc
@@ -73,12 +73,7 @@ if (account_id.empty()) return personalization_app::mojom::BacklightColor::kWallpaper; auto* pref_service = GetUserPrefService(account_id); - if (!pref_service) { - // TODO(b/238463679): Migrate to local state pref. There may be a timing - // issue that results in null pref service. Defaults to |kWallpaper| when - // that happens. - return personalization_app::mojom::BacklightColor::kWallpaper; - } + DCHECK(pref_service); return static_cast<personalization_app::mojom::BacklightColor>( pref_service->GetInteger(prefs::kPersonalizationKeyboardBacklightColor)); }
diff --git a/ash/system/keyboard_brightness/keyboard_backlight_color_controller_unittest.cc b/ash/system/keyboard_brightness/keyboard_backlight_color_controller_unittest.cc index 724448ab..e804c12 100644 --- a/ash/system/keyboard_brightness/keyboard_backlight_color_controller_unittest.cc +++ b/ash/system/keyboard_brightness/keyboard_backlight_color_controller_unittest.cc
@@ -3,6 +3,9 @@ // found in the LICENSE file. #include "ash/system/keyboard_brightness/keyboard_backlight_color_controller.h" + +#include <memory> + #include "ash/constants/ash_features.h" #include "ash/rgb_keyboard/rgb_keyboard_util.h" #include "ash/shell.h" @@ -80,10 +83,15 @@ void SetUp() override { AshTestBase::SetUp(); - controller_ = Shell::Get()->keyboard_backlight_color_controller(); + controller_ = std::make_unique<KeyboardBacklightColorController>(); wallpaper_controller_ = Shell::Get()->wallpaper_controller(); } + void TearDown() override { + controller_.reset(); + AshTestBase::TearDown(); + } + protected: const base::HistogramTester& histogram_tester() const { return histogram_tester_; @@ -97,7 +105,7 @@ controller_->displayed_color_for_testing_ = SK_ColorTRANSPARENT; } - KeyboardBacklightColorController* controller_ = nullptr; + std::unique_ptr<KeyboardBacklightColorController> controller_; WallpaperControllerImpl* wallpaper_controller_ = nullptr; private:
diff --git a/ash/system/keyboard_brightness/keyboard_backlight_color_nudge_controller_unittest.cc b/ash/system/keyboard_brightness/keyboard_backlight_color_nudge_controller_unittest.cc index 7d6fbce..b1f8525c 100644 --- a/ash/system/keyboard_brightness/keyboard_backlight_color_nudge_controller_unittest.cc +++ b/ash/system/keyboard_brightness/keyboard_backlight_color_nudge_controller_unittest.cc
@@ -7,7 +7,6 @@ #include "ash/controls/contextual_tooltip.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" -#include "ash/system/keyboard_brightness/keyboard_backlight_color_controller.h" #include "ash/test/ash_test_base.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" @@ -36,18 +35,7 @@ ~KeyboardBacklightColorNudgeControllerTest() override = default; - // testing::Test: - void SetUp() override { - AshTestBase::SetUp(); - - controller_ = Shell::Get() - ->keyboard_backlight_color_controller() - ->keyboard_backlight_color_nudge_controller(); - } - protected: - KeyboardBacklightColorNudgeController* controller_ = nullptr; - PrefService* pref_service() { return Shell::Get()->session_controller()->GetActivePrefService(); } @@ -58,6 +46,8 @@ contextual_tooltip::TooltipType::kKeyboardBacklightColor, nullptr); } + KeyboardBacklightColorNudgeController controller_; + private: base::test::ScopedFeatureList scoped_feature_list_; }; @@ -69,7 +59,7 @@ SimulateUserLogin(account_id_1); EXPECT_TRUE(can_show_nudge()); - controller_->MaybeShowEducationNudge(&anchor_view); + controller_.MaybeShowEducationNudge(&anchor_view); EXPECT_FALSE(can_show_nudge()); @@ -83,7 +73,7 @@ SimulateUserLogin(account_id_1); EXPECT_TRUE(can_show_nudge()); - controller_->SetUserPerformedAction(); + controller_.SetUserPerformedAction(); EXPECT_FALSE(can_show_nudge());
diff --git a/ash/system/power/battery_notification_unittest.cc b/ash/system/power/battery_notification_unittest.cc new file mode 100644 index 0000000..7f964bb --- /dev/null +++ b/ash/system/power/battery_notification_unittest.cc
@@ -0,0 +1,101 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/system/power/battery_notification.h" + +#include <string> + +#include "ash/strings/grit/ash_strings.h" +#include "ash/system/power/power_notification_controller.h" +#include "ash/system/power/power_status.h" +#include "ash/test/ash_test_base.h" +#include "chromeos/dbus/power_manager/power_supply_properties.pb.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/message_center/message_center.h" +#include "ui/message_center/public/cpp/notification.h" +#include "ui/message_center/public/cpp/notification_types.h" + +namespace ash { + +namespace { +constexpr int kCriticalMinutes = 5; +constexpr int kLowPowerMinutes = 15; +} // namespace + +class BatteryNotificationTest : public AshTestBase { + public: + BatteryNotificationTest() = default; + BatteryNotificationTest(const BatteryNotificationTest&) = delete; + BatteryNotificationTest& operator=(const BatteryNotificationTest&) = delete; + ~BatteryNotificationTest() override = default; + + // AshTestBase: + void SetUp() override { + AshTestBase::SetUp(); + + battery_notification_ = std::make_unique<BatteryNotification>( + message_center::MessageCenter::Get(), + PowerNotificationController::NotificationState::NOTIFICATION_LOW_POWER); + } + + void TearDown() override { + battery_notification_.reset(); + AshTestBase::TearDown(); + } + + message_center::Notification* GetBatteryNotification() { + return message_center::MessageCenter::Get()->FindNotificationById( + BatteryNotification::kNotificationId); + } + + protected: + std::unique_ptr<BatteryNotification> battery_notification_; +}; + +TEST_F(BatteryNotificationTest, LowPowerNotification) { + power_manager::PowerSupplyProperties proto; + // Set the rounded value matches the low power threshold. + proto.set_battery_time_to_empty_sec(kLowPowerMinutes * 60 + 29); + PowerStatus::Get()->SetProtoForTesting(proto); + + battery_notification_->Update( + PowerNotificationController::NotificationState::NOTIFICATION_LOW_POWER); + + auto* notification = GetBatteryNotification(); + ASSERT_TRUE(notification); + + EXPECT_EQ(message_center::SystemNotificationWarningLevel::WARNING, + notification->system_notification_warning_level()); + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_LOW_BATTERY_TITLE), + notification->title()); + EXPECT_EQ(message_center::FullscreenVisibility::OVER_USER, + notification->fullscreen_visibility()); + EXPECT_FALSE(notification->pinned()); +} + +TEST_F(BatteryNotificationTest, CriticalPowerNotification) { + power_manager::PowerSupplyProperties proto; + // Set the rounded value matches the critical power threshold. + proto.set_battery_time_to_empty_sec(kCriticalMinutes * 60 + 29); + PowerStatus::Get()->SetProtoForTesting(proto); + + battery_notification_->Update( + PowerNotificationController::NotificationState::NOTIFICATION_CRITICAL); + + auto* notification = GetBatteryNotification(); + ASSERT_TRUE(notification); + + EXPECT_EQ(message_center::SystemNotificationWarningLevel::CRITICAL_WARNING, + notification->system_notification_warning_level()); + EXPECT_EQ( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CRITICAL_BATTERY_TITLE), + notification->title()); + EXPECT_EQ(message_center::FullscreenVisibility::OVER_USER, + notification->fullscreen_visibility()); + EXPECT_EQ(message_center::NotificationPriority::SYSTEM_PRIORITY, + notification->priority()); + EXPECT_TRUE(notification->pinned()); +} + +} // namespace ash
diff --git a/ash/webui/diagnostics_ui/resources/BUILD.gn b/ash/webui/diagnostics_ui/resources/BUILD.gn index f617065..55f0aba 100644 --- a/ash/webui/diagnostics_ui/resources/BUILD.gn +++ b/ash/webui/diagnostics_ui/resources/BUILD.gn
@@ -17,6 +17,7 @@ "diagnostics_browser_proxy.ts", "diagnostics_types.ts", "diagnostics_utils.ts", + "drawing_provider.ts", "fake_data.ts", "fake_input_data_provider.ts", "fake_network_health_provider.ts",
diff --git a/ash/webui/diagnostics_ui/resources/drawing_provider.ts b/ash/webui/diagnostics_ui/resources/drawing_provider.ts new file mode 100644 index 0000000..04b17e4 --- /dev/null +++ b/ash/webui/diagnostics_ui/resources/drawing_provider.ts
@@ -0,0 +1,113 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {assert} from 'chrome://resources/js/assert_ts.js'; + +export const LINE_CAP = 'round'; +export const LINE_WIDTH = 20; +export const MARK_RADIUS = 10; +export const MARK_COLOR = + 'rgba(var(--cros-icon-color-prominent), var(--cros-second-tone-opacity))'; +export const TRAIL_COLOR = 'var(--google-blue-50)'; +export const SOURCE_OVER = 'source-over'; +export const DESTINATION_OVER = 'destination-over'; + +/** + * DrawingProvider interface provides drawing methods for touchscreen and + * touchpad tester to draw on screen. + */ +interface DrawingProvider { + // For touchscreen tester to draw a trail on screen. + drawTrail(x0: number, y0: number, x1: number, y1: number): void; + + // For touchscreen tester to draw a trial mark on screen. + drawTrailMark(x: number, y: number): void; +} + +/** + * CanvasDrawingProvider implements the DrawingProvider interface using html + * Canvas API. This design makes the drawing mechanism in a replaceable module. + */ +export class CanvasDrawingProvider implements DrawingProvider { + private ctx: CanvasRenderingContext2D; + + constructor(ctx: CanvasRenderingContext2D) { + this.ctx = ctx; + this.setup(); + } + + setup() { + assert(this.ctx); + this.ctx.lineCap = LINE_CAP; + this.ctx.lineWidth = LINE_WIDTH; + } + + /** + * For testing only. + */ + getCtx(): CanvasRenderingContext2D { + return this.ctx; + } + + /** + * For testing only. + */ + getLineCap(): string { + return this.ctx.lineCap; + } + + /** + * For testing only. + */ + getLineWidth(): number { + return this.ctx.lineWidth; + } + + /** + * For testing only. + */ + getStrokeStyle(): string|CanvasGradient|CanvasPattern { + return this.ctx.strokeStyle; + } + + /** + * For testing only. + */ + getFillStyle(): string|CanvasGradient|CanvasPattern { + return this.ctx.fillStyle; + } + + /** + * For testing only. + */ + getGlobalCompositeOperation(): string { + return this.ctx.globalCompositeOperation; + } + + /** + * Draw a line on canvas. + */ + drawTrail(x0: number, y0: number, x1: number, y1: number): void { + assert(this.ctx); + this.ctx.strokeStyle = TRAIL_COLOR; + this.ctx.beginPath(); + this.ctx.moveTo(x0, y0); + this.ctx.lineTo(x1, y1); + this.ctx.stroke(); + } + + /** + * Draw a trail mark on canvas. + */ + drawTrailMark(x: number, y: number): void { + assert(this.ctx); + // Making sure the mark is always on top. + this.ctx.globalCompositeOperation = SOURCE_OVER; + this.ctx.fillStyle = MARK_COLOR; + this.ctx.beginPath(); + this.ctx.arc(x, y, MARK_RADIUS, 0, 2 * Math.PI); + this.ctx.fill(); + this.ctx.globalCompositeOperation = DESTINATION_OVER; + } +} \ No newline at end of file
diff --git a/ash/webui/diagnostics_ui/resources/touchscreen_tester.ts b/ash/webui/diagnostics_ui/resources/touchscreen_tester.ts index 9836b3ef..3687e5c5 100644 --- a/ash/webui/diagnostics_ui/resources/touchscreen_tester.ts +++ b/ash/webui/diagnostics_ui/resources/touchscreen_tester.ts
@@ -9,6 +9,7 @@ import {assert} from 'chrome://resources/js/assert_ts.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {CanvasDrawingProvider} from './drawing_provider.js'; import {getTemplate} from './touchscreen_tester.html.js'; // To ensure the tester works when the user rotates their screen, we @@ -29,6 +30,9 @@ return getTemplate(); } + // Drawing provider. + private drawingProvider: CanvasDrawingProvider; + getDialog(dialogId: string): CrDialogElement { const dialog = this.shadowRoot!.getElementById(dialogId); assert(dialog); @@ -89,6 +93,10 @@ this.getDialog('canvas-dialog')!.shadowRoot!.querySelector( '.top-container') as HTMLElement; topContainer!.style.display = 'none'; + + const ctx = canvas.getContext('2d'); + assert(ctx); + this.drawingProvider = new CanvasDrawingProvider(ctx); } }
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc index 5e10954..2ae4dff 100644 --- a/ash/wm/workspace/workspace_layout_manager_unittest.cc +++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -20,6 +20,7 @@ #include "ash/public/cpp/app_list/app_list_features.h" #include "ash/public/cpp/keyboard/keyboard_switches.h" #include "ash/public/cpp/shelf_config.h" +#include "ash/public/cpp/shelf_types.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/test/shell_test_api.h" #include "ash/public/cpp/window_backdrop.h" @@ -694,23 +695,147 @@ EXPECT_TRUE(window->GetProperty(kWindowStateKey)); } -// Make sure window bounds is correct with session state lock/unlock. +// Make sure window bounds is correct with session state lock/unlock. It tests +// cases with various shelf settings. TEST_F(WorkspaceLayoutManagerTest, WindowBoundsWithSessionState) { TestSessionControllerClient* client = GetSessionControllerClient(); Shelf* shelf = GetPrimaryShelf(); - shelf->SetAlignment(ShelfAlignment::kLeft); - ASSERT_EQ(ShelfAlignment::kLeft, shelf->alignment()); - const gfx::Rect bounds = - WorkAreaInsets::ForWindow(Shell::GetPrimaryRootWindow()) - ->ComputeStableWorkArea(); - std::unique_ptr<aura::Window> window = CreateTestWindow(bounds); - EXPECT_EQ(bounds, window->bounds()); + constexpr ShelfAlignment alignments[] = { + ShelfAlignment::kLeft, ShelfAlignment::kRight, ShelfAlignment::kBottom}; + constexpr ShelfAutoHideBehavior auto_hide_behaviors[] = { + ShelfAutoHideBehavior::kAlways, ShelfAutoHideBehavior::kNever}; - client->SetSessionState(session_manager::SessionState::LOCKED); - EXPECT_EQ(bounds, window->bounds()); - client->SetSessionState(session_manager::SessionState::ACTIVE); - EXPECT_EQ(bounds, window->bounds()); + // Test normal window. + for (auto alignment : alignments) { + for (auto auto_hide_behavior : auto_hide_behaviors) { + SCOPED_TRACE("Primary shelf alignment: " + + base::NumberToString(static_cast<int>(alignment))); + SCOPED_TRACE("Primary shelf auto hide behavior: " + + base::NumberToString(static_cast<int>(auto_hide_behavior))); + + // Update the shelf setting. + shelf->SetAlignment(alignment); + shelf->SetAutoHideBehavior(auto_hide_behavior); + ASSERT_EQ(alignment, shelf->alignment()); + ASSERT_EQ(auto_hide_behavior, shelf->auto_hide_behavior()); + + // Create the test window, and set its bounds to match the entire + // workarea. + std::unique_ptr<aura::Window> window = CreateTestWindow(); + const gfx::Rect bounds = + screen_util::GetDisplayWorkAreaBoundsInParent(window.get()); + window->SetBounds(bounds); + EXPECT_EQ(bounds, window->bounds()); + + // Lock/unlock the session, the test window should remain the same bounds. + client->SetSessionState(session_manager::SessionState::LOCKED); + EXPECT_EQ(bounds, window->bounds()); + client->SetSessionState(session_manager::SessionState::ACTIVE); + EXPECT_EQ(bounds, window->bounds()); + } + } + + // Test maximized window. + for (auto alignment : alignments) { + for (auto auto_hide_behavior : auto_hide_behaviors) { + SCOPED_TRACE("Primary shelf alignment: " + + base::NumberToString(static_cast<int>(alignment))); + SCOPED_TRACE("Primary shelf auto hide behavior: " + + base::NumberToString(static_cast<int>(auto_hide_behavior))); + + // Update the shelf setting. + shelf->SetAlignment(alignment); + shelf->SetAutoHideBehavior(auto_hide_behavior); + ASSERT_EQ(alignment, shelf->alignment()); + ASSERT_EQ(auto_hide_behavior, shelf->auto_hide_behavior()); + + // Create the test window, and maximize it. + std::unique_ptr<aura::Window> window = CreateTestWindow(); + const gfx::Rect bounds = + screen_util::GetDisplayWorkAreaBoundsInParent(window.get()); + WindowState::Get(window.get())->Maximize(); + EXPECT_EQ(bounds, window->bounds()); + + // Lock/unlock the session, the test window should remain the same bounds. + client->SetSessionState(session_manager::SessionState::LOCKED); + EXPECT_EQ(bounds, window->bounds()); + client->SetSessionState(session_manager::SessionState::ACTIVE); + EXPECT_EQ(bounds, window->bounds()); + } + } +} + +// Make sure maximized window bounds is correct with multiple displays. It tests +// cases when disconnecting secondary display in lock session with various shelf +// settings. +TEST_F(WorkspaceLayoutManagerTest, WindowBoundsWithMultiDisplays) { + TestSessionControllerClient* client = GetSessionControllerClient(); + + constexpr ShelfAlignment alignments[] = { + ShelfAlignment::kLeft, ShelfAlignment::kRight, ShelfAlignment::kBottom}; + constexpr ShelfAutoHideBehavior auto_hide_behaviors[] = { + ShelfAutoHideBehavior::kAlways, ShelfAutoHideBehavior::kNever}; + + // Test maximized window. + for (auto primary_alignment : alignments) { + for (auto primary_auto_hide_behavior : auto_hide_behaviors) { + for (auto secondary_alignment : alignments) { + for (auto secondary_auto_hide_behavior : auto_hide_behaviors) { + SCOPED_TRACE( + "Primary shelf alignment: " + + base::NumberToString(static_cast<int>(primary_alignment))); + SCOPED_TRACE("Primary shelf auto hide behavior: " + + base::NumberToString( + static_cast<int>(primary_auto_hide_behavior))); + SCOPED_TRACE( + "Secondary shelf alignment: " + + base::NumberToString(static_cast<int>(secondary_alignment))); + SCOPED_TRACE("Secondary shelf auto hide behavior: " + + base::NumberToString( + static_cast<int>(secondary_auto_hide_behavior))); + + // Update to 2 displays. + UpdateDisplay("800x600,500x400"); + Shelf* primary_shelf = GetPrimaryShelf(); + Shelf* secondary_shelf = + Shell::GetAllRootWindowControllers().back()->shelf(); + + // Update shelf for the primary display. + primary_shelf->SetAlignment(primary_alignment); + primary_shelf->SetAutoHideBehavior(primary_auto_hide_behavior); + ASSERT_EQ(primary_alignment, primary_shelf->alignment()); + ASSERT_EQ(primary_auto_hide_behavior, + primary_shelf->auto_hide_behavior()); + + // Update shelf for the secondary display. + secondary_shelf->SetAlignment(secondary_alignment); + secondary_shelf->SetAutoHideBehavior(secondary_auto_hide_behavior); + ASSERT_EQ(secondary_alignment, secondary_shelf->alignment()); + ASSERT_EQ(secondary_auto_hide_behavior, + secondary_shelf->auto_hide_behavior()); + + // Create a test window, move it to the secondary display, and + // maximize it. + std::unique_ptr<aura::Window> window = CreateTestWindow(); + window_util::MoveWindowToDisplay(window.get(), + GetSecondaryDisplay().id()); + WindowState::Get(window.get())->Maximize(); + EXPECT_EQ(screen_util::GetDisplayWorkAreaBoundsInParent(window.get()), + window->bounds()); + + // Lock the session, disconnect the secondary display, then unlock the + // session. The maximized window should be moved to the primary + // display with correct bounds. + client->SetSessionState(session_manager::SessionState::LOCKED); + UpdateDisplay("800x600"); + client->SetSessionState(session_manager::SessionState::ACTIVE); + EXPECT_EQ(screen_util::GetDisplayWorkAreaBoundsInParent(window.get()), + window->bounds()); + } + } + } + } } // Following "Solo" tests were originally written for BaseLayoutManager.
diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py index 4418a36..94776c0 100755 --- a/base/android/jni_generator/jni_generator.py +++ b/base/android/jni_generator/jni_generator.py
@@ -1553,18 +1553,18 @@ return os.sep.join(script_components[base_index:]) -def _RemoveStaleHeaders(path, output_names): +def _RemoveStaleHeaders(path, output_files): if not os.path.isdir(path): return # Do not remove output files so that timestamps on declared outputs are not # modified unless their contents are changed (avoids reverse deps needing to # be rebuilt). - preserve = set(output_names) + preserve = set(output_files) for root, _, files in os.walk(path): for f in files: - if f not in preserve: - file_path = os.path.join(root, f) - if os.path.isfile(file_path) and file_path.endswith('.h'): + file_path = os.path.join(root, f) + if file_path not in preserve: + if os.path.isfile(file_path) and os.path.splitext(file_path)[1] == '.h': os.remove(file_path) @@ -1596,17 +1596,13 @@ action='append', required=True, dest='input_files', - help='Input filenames, or paths within a .jar if ' + help='Input file names, or paths within a .jar if ' '--jar-file is used.') - parser.add_argument('--output_dir', required=True, help='Output directory.') - # TODO(agrieve): --prev_output_dir used only to make incremental builds work. - # Remove --prev_output_dir at some point after 2022. - parser.add_argument('--prev_output_dir', - help='Delete headers found in this directory.') - parser.add_argument('--output_name', - action='append', - dest='output_names', - help='Output filenames within output directory.') + parser.add_argument( + '--output_file', + action='append', + dest='output_files', + help='Output file names.') parser.add_argument( '--script_name', default=GetScriptName(), @@ -1655,28 +1651,22 @@ parser.add_argument( '--split_name', help='Split name that the Java classes should be loaded from.') - # TODO(agrieve): --stamp used only to make incremental builds work. - # Remove --stamp at some point after 2022. - parser.add_argument('--stamp', - help='Process --prev_output_dir and touch this file.') args = parser.parse_args() input_files = args.input_files - output_names = args.output_names - - if args.prev_output_dir: - _RemoveStaleHeaders(args.prev_output_dir, []) - - if args.stamp: - build_utils.Touch(args.stamp) - sys.exit(0) - - if output_names: + output_files = args.output_files + if output_files: + output_dirs = set(os.path.dirname(f) for f in output_files) + if len(output_dirs) != 1: + parser.error( + 'jni_generator only supports a single output directory per target ' + '(got {})'.format(output_dirs)) + output_dir = output_dirs.pop() # Remove existing headers so that moving .java source files but not updating # the corresponding C++ include will be a compile failure (otherwise # incremental builds will usually not catch this). - _RemoveStaleHeaders(args.output_dir, output_names) + _RemoveStaleHeaders(output_dir, output_files) else: - output_names = [None] * len(input_files) + output_files = [None] * len(input_files) temp_dir = tempfile.mkdtemp() try: if args.jar_file: @@ -1684,11 +1674,7 @@ z.extractall(temp_dir, input_files) input_files = [os.path.join(temp_dir, f) for f in input_files] - for java_path, header_name in zip(input_files, output_names): - if header_name: - header_path = os.path.join(args.output_dir, header_name) - else: - header_path = None + for java_path, header_path in zip(input_files, output_files): GenerateJNIHeader(java_path, header_path, args) finally: shutil.rmtree(temp_dir)
diff --git a/base/memory/raw_ptr_asan_bound_arg_tracker.cc b/base/memory/raw_ptr_asan_bound_arg_tracker.cc index 38336ea0..50b4b82b 100644 --- a/base/memory/raw_ptr_asan_bound_arg_tracker.cc +++ b/base/memory/raw_ptr_asan_bound_arg_tracker.cc
@@ -35,8 +35,7 @@ } RawPtrAsanBoundArgTracker::RawPtrAsanBoundArgTracker() - : enabled_(RawPtrAsanService::GetInstance().mode() == - RawPtrAsanService::Mode::kEnabled) { + : enabled_(RawPtrAsanService::GetInstance().IsEnabled()) { if (enabled_) { prev_protected_args_ = CurrentProtectedArgs().Get(); CurrentProtectedArgs().Set(&protected_args_);
diff --git a/base/memory/raw_ptr_asan_service.h b/base/memory/raw_ptr_asan_service.h index edde678..5cf89de 100644 --- a/base/memory/raw_ptr_asan_service.h +++ b/base/memory/raw_ptr_asan_service.h
@@ -26,12 +26,6 @@ class BASE_EXPORT RawPtrAsanService { public: - enum class Mode { - kUninitialized, - kDisabled, - kEnabled, - }; - enum class ReportType { kDereference, kExtraction, @@ -41,10 +35,11 @@ void Configure(EnableDereferenceCheck, EnableExtractionCheck, EnableInstantiationCheck); - Mode mode() const { return mode_; } bool IsSupportedAllocation(void*) const; + bool IsEnabled() const { return mode_ == Mode::kEnabled; } + NO_SANITIZE("address") ALWAYS_INLINE bool is_dereference_check_enabled() const { return is_dereference_check_enabled_; @@ -68,6 +63,12 @@ static void Log(const char* format, ...); private: + enum class Mode { + kUninitialized, + kDisabled, + kEnabled, + }; + struct PendingReport { ReportType type; uintptr_t allocation_base;
diff --git a/base/memory/raw_ptr_unittest.cc b/base/memory/raw_ptr_unittest.cc index 7917bae..84306bd 100644 --- a/base/memory/raw_ptr_unittest.cc +++ b/base/memory/raw_ptr_unittest.cc
@@ -1855,8 +1855,7 @@ class AsanBackupRefPtrTest : public testing::Test { protected: void SetUp() override { - if (RawPtrAsanService::GetInstance().mode() != - RawPtrAsanService::Mode::kEnabled) { + if (!RawPtrAsanService::GetInstance().IsEnabled()) { base::RawPtrAsanService::GetInstance().Configure( base::EnableDereferenceCheck(true), base::EnableExtractionCheck(true), base::EnableInstantiationCheck(true));
diff --git a/base/memory/raw_ref_unittest.cc b/base/memory/raw_ref_unittest.cc index 2790a48..e34bf86 100644 --- a/base/memory/raw_ref_unittest.cc +++ b/base/memory/raw_ref_unittest.cc
@@ -775,8 +775,7 @@ #if BUILDFLAG(USE_ASAN_BACKUP_REF_PTR) TEST(AsanBackupRefPtrImpl, RawRefGet) { - if (base::RawPtrAsanService::GetInstance().mode() != - base::RawPtrAsanService::Mode::kEnabled) { + if (!base::RawPtrAsanService::GetInstance().IsEnabled()) { base::RawPtrAsanService::GetInstance().Configure( base::EnableDereferenceCheck(true), base::EnableExtractionCheck(true), base::EnableInstantiationCheck(true));
diff --git a/base/power_monitor/battery_level_provider.cc b/base/power_monitor/battery_level_provider.cc index 98146b0..042e959 100644 --- a/base/power_monitor/battery_level_provider.cc +++ b/base/power_monitor/battery_level_provider.cc
@@ -11,6 +11,12 @@ #if !BUILDFLAG(HAS_BATTERY_LEVEL_PROVIDER_IMPL) std::unique_ptr<BatteryLevelProvider> BatteryLevelProvider::Create() { +#if BUILDFLAG(IS_CHROMEOS_ASH) + // TODO(crbug.com/1373560): ChromeOS doesn't define + // `HAS_BATTERY_LEVEL_PROVIDER_IMPL` but still supplies its own + // `BatteryLevelProvider` + NOTREACHED(); +#endif return nullptr; } #endif
diff --git a/base/power_monitor/battery_state_sampler.cc b/base/power_monitor/battery_state_sampler.cc index fefeaa0..3909fe4 100644 --- a/base/power_monitor/battery_state_sampler.cc +++ b/base/power_monitor/battery_state_sampler.cc
@@ -52,7 +52,10 @@ BatteryStateSampler* BatteryStateSampler::Get() { // On a platform with a BatteryLevelProvider implementation, the global // instance must be created before accessing it. -#if BUILDFLAG(HAS_BATTERY_LEVEL_PROVIDER_IMPL) + // TODO(crbug.com/1373560): ChromeOS currently doesn't define + // `HAS_BATTERY_LEVEL_PROVIDER_IMPL` but it should once the locations of the + // providers and sampling sources are consolidated. +#if BUILDFLAG(HAS_BATTERY_LEVEL_PROVIDER_IMPL) || BUILDFLAG(IS_CHROMEOS_ASH) DCHECK(g_battery_state_sampler); #endif return g_battery_state_sampler; @@ -73,6 +76,12 @@ observer_list_.RemoveObserver(observer); } +void BatteryStateSampler::Shutdown() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + sampling_event_source_.reset(); + battery_level_provider_.reset(); +} + // static std::unique_ptr<base::BatteryStateSampler> BatteryStateSampler::CreateInstanceForTesting( @@ -112,6 +121,7 @@ void BatteryStateSampler::OnSamplingEvent() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(battery_level_provider_); battery_level_provider_->GetBatteryState(base::BindOnce( &BatteryStateSampler::OnBatteryStateSampled, base::Unretained(this)));
diff --git a/base/power_monitor/battery_state_sampler.h b/base/power_monitor/battery_state_sampler.h index 6d849ce..8d08fbc 100644 --- a/base/power_monitor/battery_state_sampler.h +++ b/base/power_monitor/battery_state_sampler.h
@@ -51,6 +51,12 @@ void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); + // Shuts down this instance but doesn't destroy it. This allows it to remain + // alive for its observers to deregister as they are destroyed without causing + // use-after-frees, but it won't serve any samples after this is called. + // Invoked in `PostMainMessageLoopRun`. + void Shutdown(); + // Creates, installs, and returns an instance of the sampler for testing. // This is meant to be used in browser tests before browser init to control // the sampler's behavior in the tests.
diff --git a/base/power_monitor/battery_state_sampler_unittest.cc b/base/power_monitor/battery_state_sampler_unittest.cc index eeb306f..16f39ae 100644 --- a/base/power_monitor/battery_state_sampler_unittest.cc +++ b/base/power_monitor/battery_state_sampler_unittest.cc
@@ -123,9 +123,11 @@ } TEST(BatteryStateSamplerTest, GlobalInstance) { -#if BUILDFLAG(HAS_BATTERY_LEVEL_PROVIDER_IMPL) +#if BUILDFLAG(HAS_BATTERY_LEVEL_PROVIDER_IMPL) || BUILDFLAG(IS_CHROMEOS_ASH) // Get() DCHECKs on platforms with a battery level provider if it's called - // without being initialized + // without being initialized. ChromeOS behaves the same because it has a + // `BatteryLevelProvider`, but it doesn't live in base so it doesn't exist in + // this test. EXPECT_DCHECK_DEATH(BatteryStateSampler::Get()); #else // Get() returns null if the sampler doesn't exist on platforms without a @@ -154,7 +156,7 @@ battery_state_sampler.reset(); // The sampler no longer exists. -#if BUILDFLAG(HAS_BATTERY_LEVEL_PROVIDER_IMPL) +#if BUILDFLAG(HAS_BATTERY_LEVEL_PROVIDER_IMPL) || BUILDFLAG(IS_CHROMEOS_ASH) EXPECT_DCHECK_DEATH(BatteryStateSampler::Get()); #else EXPECT_FALSE(BatteryStateSampler::Get());
diff --git a/base/tracing/protos/chrome_track_event.proto b/base/tracing/protos/chrome_track_event.proto index 279226a6..7654b73 100644 --- a/base/tracing/protos/chrome_track_event.proto +++ b/base/tracing/protos/chrome_track_event.proto
@@ -964,9 +964,27 @@ repeated int32 pid = 1; } +message UkmPageLoadTimingUpdate { + // This can be used to uniquely identify a navigation from the point of view + // of UKM. + optional int64 ukm_source_id = 1; + + // The URL of a page can change throughout its lifetime. This is the current + // url when this timing update was dispatched. + optional string latest_url = 2; + + // Latest fully aggregated value of Cumulative Layout Shift. + optional float latest_cumulative_layout_shift = 3; + + // Latest fully aggregated value of Largest Contentful Paint. + optional double latest_largest_contentful_paint_ms = 4; + + optional double first_contentful_paint_ms = 5; +} + message ChromeTrackEvent { // Extension range for Chrome: 1000-1999 - // Next ID: 1044 + // Next ID: 1045 extend TrackEvent { optional ChromeAppState chrome_app_state = 1000; @@ -1060,5 +1078,7 @@ optional ActiveProcesses active_processes = 1042; optional BlinkTaskScope blink_task_scope = 1043; + + optional UkmPageLoadTimingUpdate ukm_page_load_timing_update = 1044; } }
diff --git a/build/config/android/BUILD.gn b/build/config/android/BUILD.gn index d00b883..11a9327 100644 --- a/build/config/android/BUILD.gn +++ b/build/config/android/BUILD.gn
@@ -2,7 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//build/config/android/rules.gni") +import("//build/config/android/config.gni") import("//build/config/c++/c++.gni") import("//build/config/compiler/compiler.gni") import("//build/config/sanitizers/sanitizers.gni") @@ -162,10 +162,6 @@ } } -config("jni_include_dir") { - include_dirs = [ jni_headers_dir ] -} - if (current_toolchain == default_toolchain) { pool("goma_javac_pool") { # Override action_pool when goma is enabled for javac.
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 3552438..69d11b7 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -5,6 +5,7 @@ # Do not add any imports to non-//build directories here. # Some projects (e.g. V8) do not have non-build directories DEPS'ed in. import("//build/config/android/config.gni") +import("//build/config/android/copy_ex.gni") import("//build/config/compiler/compiler.gni") import("//build/config/compute_inputs_for_analyze.gni") import("//build/config/coverage/coverage.gni")
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index be99648..0136b04 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -7,13 +7,12 @@ import("//build/config/android/channel.gni") import("//build/config/android/config.gni") -import("//build/config/android/copy_ex.gni") +import("//build/config/android/internal_rules.gni") import("//build/config/clang/clang.gni") import("//build/config/compiler/compiler.gni") import("//build/config/coverage/coverage.gni") import("//build/config/python.gni") import("//build/config/rts.gni") -import("//build/config/sanitizers/sanitizers.gni") import("//build/config/zip.gni") import("//build/toolchain/toolchain.gni") @@ -23,16 +22,6 @@ enable_jni_tracing = false } -# Use a dedicated include dir so that files can #include headers from other -# toolchains without affecting non-JNI #includes. -if (target_os == "android") { - jni_headers_dir = "$root_build_dir/gen/jni_headers" -} else { - # Chrome OS builds cannot share gen/ directories because is_android=false - # within default_toolchain. - jni_headers_dir = "$root_gen_dir/jni_headers" -} - if (target_cpu == "arm") { _sanitizer_arch = "arm" } else if (target_cpu == "arm64") { @@ -135,13 +124,11 @@ } if (enable_java_templates) { - import("//build/config/android/internal_rules.gni") + import("//build/config/sanitizers/sanitizers.gni") # JNI target implementation. See generate_jni or generate_jar_jni for usage. template("generate_jni_impl") { - _prev_jni_output_dir = "$target_gen_dir/$target_name" - _subdir = rebase_path(target_gen_dir, root_gen_dir) - _jni_output_dir = "$jni_headers_dir/$_subdir/$target_name" + _jni_output_dir = "${target_gen_dir}/${target_name}" if (defined(invoker.jni_generator_include)) { _jni_generator_include = invoker.jni_generator_include _jni_generator_include_deps = [] @@ -173,18 +160,9 @@ public_deps = [] } public_deps += _jni_generator_include_deps - - public_configs = [ "//build/config/android:jni_include_dir" ] inputs = [] args = [ "--ptr_type=long", - - # TODO(agrieve): --prev_output_dir used only to make incremental builds - # work. Remove --prev_output_dir at some point after 2022. - "--prev_output_dir", - rebase_path(_prev_jni_output_dir, root_build_dir), - "--output_dir", - rebase_path(_jni_output_dir, root_build_dir), "--includes", rebase_path(_jni_generator_include, _jni_output_dir), ] @@ -230,16 +208,17 @@ outputs = [] foreach(_name, _input_names) { - _name = get_path_info(_name, "name") + "_jni.h" - outputs += [ "$_jni_output_dir/$_name" ] - - # Avoid passing GN lists because not all webrtc embedders use //build. - args += [ - "--output_name", - _name, - ] + _name_part = get_path_info(_name, "name") + outputs += [ "${_jni_output_dir}/${_name_part}_jni.h" ] } + # Avoid passing GN lists because not all webrtc embedders use //build. + foreach(_output, outputs) { + args += [ + "--output_file", + rebase_path(_output, root_build_dir), + ] + } foreach(_input, _input_args) { args += [ "--input_file=$_input" ] } @@ -250,30 +229,6 @@ if (enable_jni_tracing) { args += [ "--enable_tracing" ] } - if (current_toolchain != default_toolchain && target_os == "android") { - # Rather than regenerating .h files in secondary toolchains, re-use the - # ones from the primary toolchain by depending on it and adding the - # root gen directory to the include paths. - # https://crbug.com/1369398 - inputs = [] - outputs = [] - _stamp = "$target_gen_dir/$target_name.stamp" - outputs = [ _stamp ] - - # Since we used to generate the .h files rather than delegate, the - # script will delete all .h files it finds in --prev_output_dir. - # TODO(agrieve): --prev_output_dir used only to make incremental builds - # work. Convert to group() target at some point after 2022. - args += [ - "--stamp", - rebase_path(_stamp, root_build_dir), - ] - public_deps = [] - public_deps = [ ":$target_name($default_toolchain)" ] - } else if (defined(visibility)) { - # Allow dependency on ourselves from secondary toolchain. - visibility += [ ":$target_name" ] - } } }
diff --git a/build/fuchsia/test/run_test.py b/build/fuchsia/test/run_test.py index 598a3589..2c93753c 100755 --- a/build/fuchsia/test/run_test.py +++ b/build/fuchsia/test/run_test.py
@@ -75,7 +75,9 @@ parser.error('-d is required when --target-id is used') with ExitStack() as stack: - set_ffx_isolate_dir(stack.enter_context(tempfile.TemporaryDirectory())) + if not runner_args.device: + set_ffx_isolate_dir( + stack.enter_context(tempfile.TemporaryDirectory())) stack.enter_context( ScopedFfxConfig('repository.server.listen', '"[::]:0"')) log_manager = stack.enter_context(LogManager(runner_args.logs_dir))
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni index ec6051b5..8e0ad585 100644 --- a/buildtools/deps_revisions.gni +++ b/buildtools/deps_revisions.gni
@@ -5,5 +5,5 @@ declare_args() { # Used to cause full rebuilds on libc++ rolls. This should be kept in sync # with the libcxx_revision vars in //DEPS. - libcxx_revision = "ebf2d34001903baf5169f4bee0b4823025d36da6" + libcxx_revision = "64d36e572d3f9719c5d75011a718f33f11126851" }
diff --git a/cc/base/math_util.cc b/cc/base/math_util.cc index e025ed3..e650c6b2 100644 --- a/cc/base/math_util.cc +++ b/cc/base/math_util.cc
@@ -276,12 +276,6 @@ return src_rect + gfx::ToFlooredVector2d(transform.To2dTranslation()); gfx::RectF mapped_rect = MapClippedRect(transform, gfx::RectF(src_rect)); - - // gfx::ToEnclosingRect crashes if called on a RectF with any NaN coordinate. - if (std::isnan(mapped_rect.x()) || std::isnan(mapped_rect.y()) || - std::isnan(mapped_rect.right()) || std::isnan(mapped_rect.bottom())) - return gfx::Rect(); - return gfx::ToEnclosingRectIgnoringError(mapped_rect, ignore_error); }
diff --git a/cc/base/math_util_unittest.cc b/cc/base/math_util_unittest.cc index 7bfd0b2a..8006369 100644 --- a/cc/base/math_util_unittest.cc +++ b/cc/base/math_util_unittest.cc
@@ -344,33 +344,33 @@ gfx::Transform rotation; rotation.RotateAboutYAxis(170.0); - int max_int = std::numeric_limits<int>::max(); - + // The following code should not crash due to NaNs. The result rects are + // empty because either the geometry was saturated or NaNs were set to 0. output = MathUtil::MapEnclosingClippedRect(large_x_scale, input); - EXPECT_EQ(gfx::Rect(max_int, 2, 0, 200), output); + EXPECT_TRUE(output.IsEmpty()); output = MathUtil::MapEnclosingClippedRect(large_x_scale * rotation, input); - EXPECT_EQ(gfx::Rect(), output); + EXPECT_TRUE(output.IsEmpty()); output = MathUtil::MapEnclosingClippedRect(infinite_x_scale, input); - EXPECT_EQ(gfx::Rect(max_int, 2, 0, 200), output); + EXPECT_TRUE(output.IsEmpty()); output = MathUtil::MapEnclosingClippedRect(infinite_x_scale * rotation, input); - EXPECT_EQ(gfx::Rect(), output); + EXPECT_TRUE(output.IsEmpty()); output = MathUtil::MapEnclosingClippedRect(large_y_scale, input); - EXPECT_EQ(gfx::Rect(1, max_int, 100, 0), output); + EXPECT_TRUE(output.IsEmpty()); output = MathUtil::MapEnclosingClippedRect(large_y_scale * rotation, input); - EXPECT_EQ(gfx::Rect(-100, max_int, 100, 0), output); + EXPECT_TRUE(output.IsEmpty()); output = MathUtil::MapEnclosingClippedRect(infinite_y_scale, input); - EXPECT_EQ(gfx::Rect(1, max_int, 100, 0), output); + EXPECT_TRUE(output.IsEmpty()); output = MathUtil::MapEnclosingClippedRect(infinite_y_scale * rotation, input); - EXPECT_EQ(gfx::Rect(), output); + EXPECT_TRUE(output.IsEmpty()); } TEST(MathUtilTest, MapEnclosingRectIgnoringError) { @@ -412,35 +412,35 @@ gfx::Transform rotation; rotation.RotateAboutYAxis(170.0); - int max_int = std::numeric_limits<int>::max(); - + // The following code should not crash due to NaNs. The result rects are + // empty because either the geometry was saturated or NaNs were set to 0. output = MathUtil::ProjectEnclosingClippedRect(large_x_scale, input); - EXPECT_EQ(gfx::Rect(max_int, 2, 0, 200), output); + EXPECT_TRUE(output.IsEmpty()); output = MathUtil::ProjectEnclosingClippedRect(large_x_scale * rotation, input); - EXPECT_EQ(gfx::Rect(), output); + EXPECT_TRUE(output.IsEmpty()); output = MathUtil::ProjectEnclosingClippedRect(infinite_x_scale, input); - EXPECT_EQ(gfx::Rect(max_int, 2, 0, 200), output); + EXPECT_TRUE(output.IsEmpty()); output = MathUtil::ProjectEnclosingClippedRect(infinite_x_scale * rotation, input); - EXPECT_EQ(gfx::Rect(), output); + EXPECT_TRUE(output.IsEmpty()); output = MathUtil::ProjectEnclosingClippedRect(large_y_scale, input); - EXPECT_EQ(gfx::Rect(1, max_int, 100, 0), output); + EXPECT_TRUE(output.IsEmpty()); output = MathUtil::ProjectEnclosingClippedRect(large_y_scale * rotation, input); - EXPECT_EQ(gfx::Rect(-103, max_int, 102, 0), output); + EXPECT_TRUE(output.IsEmpty()); output = MathUtil::ProjectEnclosingClippedRect(infinite_y_scale, input); - EXPECT_EQ(gfx::Rect(1, max_int, 100, 0), output); + EXPECT_TRUE(output.IsEmpty()); output = MathUtil::ProjectEnclosingClippedRect(infinite_y_scale * rotation, input); - EXPECT_EQ(gfx::Rect(), output); + EXPECT_TRUE(output.IsEmpty()); } TEST(MathUtilTest, RoundUp) {
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 789c28d8..a22b342 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -2754,14 +2754,6 @@ gfx::PointF screen_end = MathUtil::MapPoint(screen_space_transform, layer_end, &clipped); - // MapPoint can produce points with NaN components (even when no inputs are - // NaN). Since consumers of gfx::SelectionBounds may round |edge_start| or - // |edge_end| (and since rounding will crash on NaN), we return an empty - // bound instead. - if (std::isnan(screen_start.x()) || std::isnan(screen_start.y()) || - std::isnan(screen_end.x()) || std::isnan(screen_end.y())) - return gfx::SelectionBound(); - const float inv_scale = 1.f / device_scale_factor; viewport_bound.SetEdgeStart(gfx::ScalePoint(screen_start, inv_scale)); viewport_bound.SetEdgeEnd(gfx::ScalePoint(screen_end, inv_scale));
diff --git a/cc/trees/layer_tree_impl_unittest.cc b/cc/trees/layer_tree_impl_unittest.cc index 720dafa..37382cf 100644 --- a/cc/trees/layer_tree_impl_unittest.cc +++ b/cc/trees/layer_tree_impl_unittest.cc
@@ -2168,10 +2168,18 @@ viz::Selection<gfx::SelectionBound> output; host_impl().active_tree()->GetViewportSelection(&output); - // edge_end and edge_start aren't allowed to have NaNs, so the selection - // should be empty. - EXPECT_EQ(gfx::SelectionBound(), output.start); - EXPECT_EQ(gfx::SelectionBound(), output.end); + auto point_is_valid = [](const gfx::PointF& p) { + return std::isfinite(p.x()) && std::isfinite(p.y()); + }; + auto selection_bound_is_valid = [&](const gfx::SelectionBound& b) { + return point_is_valid(b.edge_start()) && + point_is_valid(b.visible_edge_start()) && + point_is_valid(b.edge_end()) && point_is_valid(b.visible_edge_end()); + }; + // No NaNs or infinities in SelectounBound. + EXPECT_TRUE(selection_bound_is_valid(output.start)) + << output.start.ToString(); + EXPECT_TRUE(selection_bound_is_valid(output.end)) << output.end.ToString(); } TEST_F(LayerTreeImplTest, SelectionBoundsForCaretLayer) {
diff --git a/chrome/android/expectations/lint-suppressions.xml b/chrome/android/expectations/lint-suppressions.xml index e3ae052..1b9d298c 100644 --- a/chrome/android/expectations/lint-suppressions.xml +++ b/chrome/android/expectations/lint-suppressions.xml
@@ -44,6 +44,7 @@ <ignore regexp="components/embedder_support/android/java/res"/> </issue> <issue id="ImpliedQuantity"> + <ignore regexp="chrome/android/features/tab_ui/java_strings_grd"/> <ignore regexp="chrome/browser/ui/android/strings/ui_strings_grd"/> <ignore regexp="components/browser_ui/strings/android/browser_ui_strings_grd"/> </issue>
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetView.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetView.java index 24c81d37..6b92237 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetView.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetView.java
@@ -4,7 +4,7 @@ package org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet; -import static org.chromium.chrome.browser.password_manager.PasswordManagerHelper.usesUnifiedPasswordManagerUI; +import static org.chromium.chrome.browser.password_manager.PasswordManagerHelper.usesUnifiedPasswordManagerBranding; import android.content.Context; import android.view.LayoutInflater; @@ -71,7 +71,7 @@ mSheetItemListView.setLayoutManager(new LinearLayoutManager( mSheetItemListView.getContext(), LinearLayoutManager.VERTICAL, false)); mSheetItemListView.setItemAnimator(null); - if (usesUnifiedPasswordManagerUI()) { + if (usesUnifiedPasswordManagerBranding()) { // TODO(crbug.com/1217070): update the layout xml once feature is rolled out final TextView titleTextView = mContentView.findViewById(R.id.sheet_title); titleTextView.setText(R.string.all_passwords_bottom_sheet_title_gpm); @@ -106,7 +106,7 @@ void setWarning(CharSequence warningMessage) { final TextView warningTextView = mContentView.findViewById(R.id.sheet_warning); warningTextView.setText(warningMessage); - if (usesUnifiedPasswordManagerUI()) { + if (usesUnifiedPasswordManagerBranding()) { // TODO(crbug.com/1217070): remove from the layout xml once feature roll out final TextView warningSecondTextView = mContentView.findViewById(R.id.sheet_warning_second);
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetViewBinder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetViewBinder.java index 913583b..f529f5a 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetViewBinder.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetViewBinder.java
@@ -12,7 +12,7 @@ import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.ORIGIN; import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.SHEET_ITEMS; import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.VISIBLE; -import static org.chromium.chrome.browser.password_manager.PasswordManagerHelper.usesUnifiedPasswordManagerUI; +import static org.chromium.chrome.browser.password_manager.PasswordManagerHelper.usesUnifiedPasswordManagerBranding; import android.content.res.Resources; import android.graphics.drawable.Drawable; @@ -190,7 +190,7 @@ String formattedOrigin = UrlFormatter.formatUrlForSecurityDisplay( new GURL(origin), SchemeDisplay.OMIT_CRYPTOGRAPHIC); return String.format( - resources.getString(usesUnifiedPasswordManagerUI() + resources.getString(usesUnifiedPasswordManagerBranding() ? R.string.all_passwords_bottom_sheet_subtitle : R.string.all_passwords_bottom_sheet_warning_dialog_message_first), formattedOrigin);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorAction.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorAction.java index 408bfb7..35a17f3 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorAction.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorAction.java
@@ -132,6 +132,11 @@ assert buttonType >= ButtonType.TEXT && buttonType < ButtonType.NUM_ENTRIES; assert iconPosition >= IconPosition.START && iconPosition < IconPosition.NUM_ENTRIES; + final String expectedResourceourceTypeName = "plurals"; + boolean titleIsPlural = expectedResourceourceTypeName.equals( + ContextUtils.getApplicationContext().getResources().getResourceTypeName( + titleResourceId)); + mModel = new PropertyModel.Builder(TabSelectionEditorActionProperties.ACTION_KEYS) .with(TabSelectionEditorActionProperties.MENU_ITEM_ID, menuItemId) @@ -139,6 +144,7 @@ .with(TabSelectionEditorActionProperties.BUTTON_TYPE, buttonType) .with(TabSelectionEditorActionProperties.ICON_POSITION, iconPosition) .with(TabSelectionEditorActionProperties.TITLE_RESOURCE_ID, titleResourceId) + .with(TabSelectionEditorActionProperties.TITLE_IS_PLURAL, titleIsPlural) .with(TabSelectionEditorActionProperties.CONTENT_DESCRIPTION_RESOURCE_ID, contentDescriptionResourceId) .with(TabSelectionEditorActionProperties.ICON, icon) @@ -156,7 +162,6 @@ if (contentDescriptionResourceId == null) return; - final String expectedResourceourceTypeName = "plurals"; assert expectedResourceourceTypeName.equals( ContextUtils.getApplicationContext().getResources().getResourceTypeName( contentDescriptionResourceId))
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProperties.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProperties.java index cb6f571..ca42ee5 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProperties.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorActionProperties.java
@@ -26,8 +26,11 @@ public static final ReadableIntPropertyKey ICON_POSITION = new ReadableIntPropertyKey(); public static final WritableIntPropertyKey TITLE_RESOURCE_ID = new WritableIntPropertyKey(); + public static final WritableBooleanPropertyKey TITLE_IS_PLURAL = + new WritableBooleanPropertyKey(); public static final WritableObjectPropertyKey<Integer> CONTENT_DESCRIPTION_RESOURCE_ID = new WritableObjectPropertyKey(); + public static final WritableObjectPropertyKey<String> TITLE = new WritableObjectPropertyKey(); public static final WritableObjectPropertyKey<String> CONTENT_DESCRIPTION = new WritableObjectPropertyKey<>(); public static final WritableObjectPropertyKey<Drawable> ICON = @@ -59,13 +62,13 @@ * Keys for the {@link TabSelectionEditorAction}. */ public static final PropertyKey[] ACTION_KEYS = {MENU_ITEM_ID, SHOW_MODE, BUTTON_TYPE, - ICON_POSITION, TITLE_RESOURCE_ID, CONTENT_DESCRIPTION_RESOURCE_ID, ICON, ENABLED, - ITEM_COUNT, TEXT_TINT, ICON_TINT, SKIP_ICON_TINT, ON_CLICK_LISTENER, + ICON_POSITION, TITLE_RESOURCE_ID, TITLE_IS_PLURAL, CONTENT_DESCRIPTION_RESOURCE_ID, + ICON, ENABLED, ITEM_COUNT, TEXT_TINT, ICON_TINT, SKIP_ICON_TINT, ON_CLICK_LISTENER, ON_SELECTION_STATE_CHANGE}; /** * Keys for the {@link TabSelectionEditorMenuItem}. */ public static final PropertyKey[] MENU_ITEM_KEYS = { - MENU_ITEM_ID, TITLE_RESOURCE_ID, CONTENT_DESCRIPTION, ICON, ENABLED}; + MENU_ITEM_ID, TITLE, CONTENT_DESCRIPTION, ICON, ENABLED, ITEM_COUNT}; }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCloseAction.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCloseAction.java index f57cc98..f819d40 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCloseAction.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCloseAction.java
@@ -35,7 +35,7 @@ private TabSelectionEditorCloseAction(@ShowMode int showMode, @ButtonType int buttonType, @IconPosition int iconPosition, Drawable drawable) { super(R.id.tab_selection_editor_close_menu_item, showMode, buttonType, iconPosition, - R.string.tab_selection_editor_close_tabs, + R.plurals.tab_selection_editor_close_tabs, R.plurals.accessibility_tab_selection_editor_close_tabs, drawable); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorGroupAction.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorGroupAction.java index 8869ef9..e551b5d1 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorGroupAction.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorGroupAction.java
@@ -38,7 +38,7 @@ private TabSelectionEditorGroupAction(@ShowMode int showMode, @ButtonType int buttonType, @IconPosition int iconPosition, Drawable drawable) { super(R.id.tab_selection_editor_group_menu_item, showMode, buttonType, iconPosition, - R.string.tab_selection_editor_group_tabs, + R.plurals.tab_selection_editor_group_tabs, R.plurals.accessibility_tab_selection_editor_group_tabs, drawable); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuAdapter.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuAdapter.java index e39a1a1..7175171 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuAdapter.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuAdapter.java
@@ -83,14 +83,14 @@ private void bindMenuItemProperty( PropertyModel actionModel, TabSelectionEditorMenuItem menuItem, PropertyKey key) { if (key == TabSelectionEditorActionProperties.TITLE_RESOURCE_ID) { - menuItem.setTitleResourceId( - actionModel.get(TabSelectionEditorActionProperties.TITLE_RESOURCE_ID)); - } else if (key == TabSelectionEditorActionProperties.CONTENT_DESCRIPTION_RESOURCE_ID - || key == TabSelectionEditorActionProperties.ITEM_COUNT) { - menuItem.setContentDescription( - actionModel.get( - TabSelectionEditorActionProperties.CONTENT_DESCRIPTION_RESOURCE_ID), - actionModel.get(TabSelectionEditorActionProperties.ITEM_COUNT)); + updateTitle(actionModel, menuItem); + } else if (key == TabSelectionEditorActionProperties.CONTENT_DESCRIPTION_RESOURCE_ID) { + updateContentDescription(actionModel, menuItem); + } else if (key == TabSelectionEditorActionProperties.ITEM_COUNT) { + if (actionModel.get(TabSelectionEditorActionProperties.TITLE_IS_PLURAL)) { + updateTitle(actionModel, menuItem); + } + updateContentDescription(actionModel, menuItem); } else if (key == TabSelectionEditorActionProperties.ICON_POSITION || key == TabSelectionEditorActionProperties.ICON) { menuItem.setIcon(actionModel.get(TabSelectionEditorActionProperties.ICON_POSITION), @@ -110,12 +110,27 @@ } } + private void updateTitle(PropertyModel actionModel, TabSelectionEditorMenuItem menuItem) { + int itemCount = actionModel.get(TabSelectionEditorActionProperties.TITLE_IS_PLURAL) + ? actionModel.get(TabSelectionEditorActionProperties.ITEM_COUNT) + : -1; + menuItem.setTitle( + actionModel.get(TabSelectionEditorActionProperties.TITLE_RESOURCE_ID), itemCount); + } + + private void updateContentDescription( + PropertyModel actionModel, TabSelectionEditorMenuItem menuItem) { + menuItem.setContentDescription( + actionModel.get(TabSelectionEditorActionProperties.CONTENT_DESCRIPTION_RESOURCE_ID), + actionModel.get(TabSelectionEditorActionProperties.ITEM_COUNT)); + } + public static void bindMenuItem(PropertyModel model, View view, PropertyKey propertyKey) { TextView textView = view.findViewById(R.id.menu_item_text); ImageView startIcon = view.findViewById(R.id.menu_item_icon); ImageView endIcon = view.findViewById(R.id.menu_item_end_icon); - if (propertyKey == TabSelectionEditorActionProperties.TITLE_RESOURCE_ID) { - textView.setText(model.get(TabSelectionEditorActionProperties.TITLE_RESOURCE_ID)); + if (propertyKey == TabSelectionEditorActionProperties.TITLE) { + textView.setText(model.get(TabSelectionEditorActionProperties.TITLE)); } else if (propertyKey == TabSelectionEditorActionProperties.CONTENT_DESCRIPTION) { textView.setContentDescription( model.get(TabSelectionEditorActionProperties.CONTENT_DESCRIPTION));
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuItem.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuItem.java index 1dc5e28..fd846e8 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuItem.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuItem.java
@@ -78,11 +78,23 @@ return mListItem; } - public void setTitleResourceId(int titleResourceId) { - mListItem.model.set(TabSelectionEditorActionProperties.TITLE_RESOURCE_ID, titleResourceId); + /** + * Set the title in the menu and ActionView. + * @param titleResourceId Resource ID of the title. + * @param itemCount current item count. -1 means the title is not plural. + */ + public void setTitle(int titleResourceId, int itemCount) { + String title; + if (itemCount >= 0) { + title = mContext.getResources().getQuantityString( + titleResourceId, itemCount, itemCount); + } else { + title = mContext.getResources().getString(titleResourceId); + } + mListItem.model.set(TabSelectionEditorActionProperties.TITLE, title); if (mActionView != null) { if (mShowText) { - mActionView.setText(titleResourceId); + mActionView.setText(title); } else { mActionView.setText(""); mActionView.setMinWidth(0);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorShareAction.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorShareAction.java index de98706..7e91dd2 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorShareAction.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorShareAction.java
@@ -48,7 +48,7 @@ @IconPosition int iconPosition, Supplier<ShareDelegate> shareDelegateSupplier, Drawable drawable) { super(R.id.tab_selection_editor_share_menu_item, showMode, buttonType, iconPosition, - R.string.tab_selection_editor_share_tabs_action_button, + R.plurals.tab_selection_editor_share_tabs_action_button, R.plurals.accessibility_tab_selection_editor_share_tabs_action_button, drawable); mShareDelegateSupplier = shareDelegateSupplier; }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorUngroupAction.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorUngroupAction.java index 97ede2896..80bfb4a 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorUngroupAction.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorUngroupAction.java
@@ -36,7 +36,7 @@ private TabSelectionEditorUngroupAction(@ShowMode int showMode, @ButtonType int buttonType, @IconPosition int iconPosition, Drawable drawable) { super(R.id.tab_selection_editor_ungroup_menu_item, showMode, buttonType, iconPosition, - R.string.tab_selection_editor_ungroup_tabs, + R.plurals.tab_selection_editor_ungroup_tabs, R.plurals.accessibility_tab_selection_editor_ungroup_tabs, drawable); }
diff --git a/chrome/android/features/tab_ui/java/strings/android_chrome_tab_ui_strings.grd b/chrome/android/features/tab_ui/java/strings/android_chrome_tab_ui_strings.grd index ad559d1..74f7780 100644 --- a/chrome/android/features/tab_ui/java/strings/android_chrome_tab_ui_strings.grd +++ b/chrome/android/features/tab_ui/java/strings/android_chrome_tab_ui_strings.grd
@@ -255,7 +255,10 @@ Deselect all </message> <message name="IDS_TAB_SELECTION_EDITOR_SHARE_TABS_ACTION_BUTTON" desc="This text button is shown in the Tab Selection Editor Toolbar. When the user taps the button, Chrome shares all currently selected tabs shown in the editor. [CHAR_LIMIT=27]"> - Share tabs + {TABS_COUNT, plural, + =1 {Share tab} + other {Share tabs} + } </message> <message name="IDS_ACCESSIBILITY_TAB_SELECTION_EDITOR_SHARE_TABS_ACTION_BUTTON" desc="The accessibility string for the share button in the Tab Selection Editor Toolbar. Tap this button to share all selected tabs."> {TABS_COUNT, plural, @@ -270,7 +273,10 @@ } </message> <message name="IDS_TAB_SELECTION_EDITOR_GROUP_TABS" desc="This text menu item is shown in the Tab Selection Editor menu. 'Group' is a verb. When the user taps the menu item, Chrome creates a new group that contains the selected tabs. [CHAR_LIMIT=27]"> - Group tabs + {TABS_COUNT, plural, + =1 {Group tab} + other {Group tabs} + } </message> <message name="IDS_ACCESSIBILITY_TAB_SELECTION_EDITOR_GROUP_TABS" desc="The accessibility text to read when the 'Group tabs' menu item in the selection mode menu is focused. When this menu item is tapped, all the selected tabs will be grouped together."> {TABS_COUNT, plural, @@ -279,7 +285,10 @@ } </message> <message name="IDS_TAB_SELECTION_EDITOR_UNGROUP_TABS" desc="This text menu item is shown in the Tab Selection Editor menu. 'Ungroup' is a verb. When the user taps the menu item, Chrome removes the selected tabs from the group. [CHAR_LIMIT=27]"> - Ungroup tabs + {TABS_COUNT, plural, + =1 {Ungroup tab} + other {Ungroup tabs} + } </message> <message name="IDS_ACCESSIBILITY_TAB_SELECTION_EDITOR_UNGROUP_TABS" desc="The accessibility text to read when the 'Ungroup tabs' menu item in the selection mode menu is focused. When this menu item is tapped, all the selected tabs will be ungroup."> {TABS_COUNT, plural, @@ -288,7 +297,10 @@ } </message> <message name="IDS_TAB_SELECTION_EDITOR_CLOSE_TABS" desc="This text menu item is shown in the Tab Selection Editor menu. 'Close' is a verb. When the user taps the menu item, Chrome closes the selected tabs. [CHAR_LIMIT=27]"> - Close tabs + {TABS_COUNT, plural, + =1 {Close tab} + other {Close tabs} + } </message> <message name="IDS_ACCESSIBILITY_TAB_SELECTION_EDITOR_CLOSE_TABS" desc="The accessibility text to read when the 'Close tabs' menu item in the selection mode menu is focused. When this menu item is tapped, all the selected tabs will be closed."> {TABS_COUNT, plural,
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuTest.java index 64e5ab6d..5541a84 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuTest.java
@@ -89,8 +89,8 @@ public RenderTestRule mRenderTestRule = RenderTestRule.Builder.withPublicCorpus() .setBugComponent(Component.UI_BROWSER_MOBILE_TAB_SWITCHER_GRID) - .setRevision(2) - .setDescription("TabSelectionEditorV2 Menu Refactor") + .setRevision(3) + .setDescription("Pluralize strings") .build(); static class FakeTabSelectionEditorAction extends TabSelectionEditorAction { @@ -233,7 +233,7 @@ actions.add(new FakeTabSelectionEditorAction(getActivity(), R.id.tab_selection_editor_close_menu_item, ShowMode.IF_ROOM, ButtonType.ICON_AND_TEXT, IconPosition.END, - R.string.tab_selection_editor_close_tabs, R.drawable.ic_close_tabs_24dp)); + R.plurals.tab_selection_editor_close_tabs, R.drawable.ic_close_tabs_24dp)); configureMenuWithActions(actions); }); @@ -252,7 +252,7 @@ actions.add(new FakeTabSelectionEditorAction(getActivity(), R.id.tab_selection_editor_close_menu_item, ShowMode.IF_ROOM, ButtonType.ICON_AND_TEXT, IconPosition.END, - R.string.tab_selection_editor_close_tabs, R.drawable.ic_close_tabs_24dp)); + R.plurals.tab_selection_editor_close_tabs, R.drawable.ic_close_tabs_24dp)); configureMenuWithActions(actions); }); @@ -272,7 +272,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { actions.add(new FakeTabSelectionEditorAction(getActivity(), R.id.tab_selection_editor_close_menu_item, ShowMode.IF_ROOM, ButtonType.ICON, - IconPosition.END, R.string.tab_selection_editor_close_tabs, + IconPosition.END, R.plurals.tab_selection_editor_close_tabs, R.drawable.ic_close_tabs_24dp)); configureMenuWithActions(actions); }); @@ -293,7 +293,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { actions.add(new FakeTabSelectionEditorAction(getActivity(), R.id.tab_selection_editor_close_menu_item, ShowMode.IF_ROOM, ButtonType.TEXT, - IconPosition.END, R.string.tab_selection_editor_close_tabs, + IconPosition.END, R.plurals.tab_selection_editor_close_tabs, R.drawable.ic_close_tabs_24dp)); configureMenuWithActions(actions); }); @@ -330,14 +330,14 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { actions.add(new FakeTabSelectionEditorAction(getActivity(), R.id.tab_selection_editor_close_menu_item, ShowMode.MENU_ONLY, ButtonType.TEXT, - IconPosition.START, R.string.tab_selection_editor_close_tabs, + IconPosition.START, R.plurals.tab_selection_editor_close_tabs, R.drawable.ic_close_tabs_24dp)); configureMenuWithActions(actions); }); TestThreadUtils.runOnUiThreadBlocking( () -> { actions.get(0).setShouldEnableAction(false); }); - setSelectedItems(new HashSet<Integer>(Arrays.asList(new Integer[] {TAB_ID_0}))); + setSelectedItems(new HashSet<Integer>(Arrays.asList(new Integer[] {TAB_ID_0, TAB_ID_1}))); PopupListener listener = new PopupListener(); openMenu(listener); @@ -356,7 +356,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { actions.add(new FakeTabSelectionEditorAction(getActivity(), R.id.tab_selection_editor_close_menu_item, ShowMode.MENU_ONLY, ButtonType.TEXT, - IconPosition.START, R.string.tab_selection_editor_close_tabs, + IconPosition.START, R.plurals.tab_selection_editor_close_tabs, R.drawable.ic_close_tabs_24dp)); configureMenuWithActions(actions); }); @@ -378,8 +378,8 @@ PopupListener listener = new PopupListener(); openMenu(listener); - assertMenuItem("Close tabs", true); - clickMenuItem("Close tabs"); + assertMenuItem("Close tab", true); + clickMenuItem("Close tab"); helper.waitForCallback(0); mRenderTestRule.render(mToolbar, "singleMenuItemEnabled_Toolbar"); @@ -399,11 +399,11 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { actions.add(new FakeTabSelectionEditorAction(getActivity(), R.id.tab_selection_editor_close_menu_item, ShowMode.IF_ROOM, ButtonType.ICON, - IconPosition.START, R.string.tab_selection_editor_close_tabs, + IconPosition.START, R.plurals.tab_selection_editor_close_tabs, R.drawable.ic_close_tabs_24dp)); actions.add(new FakeTabSelectionEditorAction(getActivity(), R.id.tab_selection_editor_group_menu_item, ShowMode.IF_ROOM, ButtonType.ICON, - IconPosition.END, R.string.tab_selection_editor_group_tabs, + IconPosition.END, R.plurals.tab_selection_editor_group_tabs, R.drawable.ic_widgets)); configureMenuWithActions(actions); }); @@ -425,11 +425,11 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { actions.add(new FakeTabSelectionEditorAction(getActivity(), R.id.tab_selection_editor_close_menu_item, ShowMode.MENU_ONLY, ButtonType.TEXT, - IconPosition.START, R.string.tab_selection_editor_close_tabs, + IconPosition.START, R.plurals.tab_selection_editor_close_tabs, R.drawable.ic_close_tabs_24dp)); actions.add(new FakeTabSelectionEditorAction(getActivity(), R.id.tab_selection_editor_group_menu_item, ShowMode.IF_ROOM, ButtonType.ICON, - IconPosition.START, R.string.tab_selection_editor_group_tabs, + IconPosition.START, R.plurals.tab_selection_editor_group_tabs, R.drawable.ic_widgets)); configureMenuWithActions(actions); }); @@ -440,7 +440,7 @@ PopupListener listener = new PopupListener(); openMenu(listener); - assertMenuItem("Close tabs", true); + assertMenuItem("Close tab", true); mRenderTestRule.render(mToolbar, "oneActionToolbarOneMenuItemEnabled_Toobar"); mRenderTestRule.render(mTabSelectionEditorMenu.getContentView(), "oneActionToolbarOneMenuItemEnabled_Menu"); @@ -455,11 +455,11 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { actions.add(new FakeTabSelectionEditorAction(getActivity(), R.id.tab_selection_editor_close_menu_item, ShowMode.MENU_ONLY, ButtonType.TEXT, - IconPosition.END, R.string.tab_selection_editor_close_tabs, + IconPosition.END, R.plurals.tab_selection_editor_close_tabs, R.drawable.ic_close_tabs_24dp)); actions.add(new FakeTabSelectionEditorAction(getActivity(), R.id.tab_selection_editor_group_menu_item, ShowMode.MENU_ONLY, ButtonType.ICON, - IconPosition.START, R.string.tab_selection_editor_group_tabs, + IconPosition.START, R.plurals.tab_selection_editor_group_tabs, R.drawable.ic_widgets)); configureMenuWithActions(actions); }); @@ -470,8 +470,8 @@ PopupListener listener = new PopupListener(); openMenu(listener); - assertMenuItem("Close tabs", true); - assertMenuItem("Group tabs", false); + assertMenuItem("Close tab", true); + assertMenuItem("Group tab", false); mRenderTestRule.render( mTabSelectionEditorMenu.getContentView(), "twoMenuItemsPartlyDisabled_Menu"); closeMenu(listener);
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java index b2fb4a8..d0ff9f0 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java
@@ -596,7 +596,7 @@ mRobot.actionRobot.clickItemAtAdapterPosition(0) .clickToolbarMenuButton() - .clickToolbarMenuItem("Close tabs"); + .clickToolbarMenuItem("Close tab"); assertEquals(1, getTabsInCurrentTabModel().size()); }
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCloseActionUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCloseActionUnitTest.java index ae785c9..fac8245 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCloseActionUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCloseActionUnitTest.java
@@ -82,9 +82,11 @@ public void testInherentActionProperties() { Assert.assertEquals(R.id.tab_selection_editor_close_menu_item, mAction.getPropertyModel().get(TabSelectionEditorActionProperties.MENU_ITEM_ID)); - Assert.assertEquals(R.string.tab_selection_editor_close_tabs, + Assert.assertEquals(R.plurals.tab_selection_editor_close_tabs, mAction.getPropertyModel().get( TabSelectionEditorActionProperties.TITLE_RESOURCE_ID)); + Assert.assertEquals(true, + mAction.getPropertyModel().get(TabSelectionEditorActionProperties.TITLE_IS_PLURAL)); Assert.assertEquals(R.plurals.accessibility_tab_selection_editor_close_tabs, mAction.getPropertyModel() .get(TabSelectionEditorActionProperties.CONTENT_DESCRIPTION_RESOURCE_ID)
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorGroupActionUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorGroupActionUnitTest.java index 27144ddc..f14c768 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorGroupActionUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorGroupActionUnitTest.java
@@ -81,9 +81,11 @@ public void testInherentActionProperties() { Assert.assertEquals(R.id.tab_selection_editor_group_menu_item, mAction.getPropertyModel().get(TabSelectionEditorActionProperties.MENU_ITEM_ID)); - Assert.assertEquals(R.string.tab_selection_editor_group_tabs, + Assert.assertEquals(R.plurals.tab_selection_editor_group_tabs, mAction.getPropertyModel().get( TabSelectionEditorActionProperties.TITLE_RESOURCE_ID)); + Assert.assertEquals(true, + mAction.getPropertyModel().get(TabSelectionEditorActionProperties.TITLE_IS_PLURAL)); Assert.assertEquals(R.plurals.accessibility_tab_selection_editor_group_tabs, mAction.getPropertyModel() .get(TabSelectionEditorActionProperties.CONTENT_DESCRIPTION_RESOURCE_ID)
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorSelectionActionUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorSelectionActionUnitTest.java index 8e8300b7..9686777 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorSelectionActionUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorSelectionActionUnitTest.java
@@ -73,6 +73,8 @@ Assert.assertEquals(R.string.tab_selection_editor_select_all, mAction.getPropertyModel().get( TabSelectionEditorActionProperties.TITLE_RESOURCE_ID)); + Assert.assertEquals(false, + mAction.getPropertyModel().get(TabSelectionEditorActionProperties.TITLE_IS_PLURAL)); Assert.assertEquals(null, mAction.getPropertyModel().get( TabSelectionEditorActionProperties.CONTENT_DESCRIPTION_RESOURCE_ID));
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorShareActionUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorShareActionUnitTest.java index c13e868..4e3eb3f7 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorShareActionUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorShareActionUnitTest.java
@@ -95,9 +95,11 @@ Assert.assertEquals(R.id.tab_selection_editor_share_menu_item, mAction.getPropertyModel().get(TabSelectionEditorActionProperties.MENU_ITEM_ID)); - Assert.assertEquals(R.string.tab_selection_editor_share_tabs_action_button, + Assert.assertEquals(R.plurals.tab_selection_editor_share_tabs_action_button, mAction.getPropertyModel().get( TabSelectionEditorActionProperties.TITLE_RESOURCE_ID)); + Assert.assertEquals(true, + mAction.getPropertyModel().get(TabSelectionEditorActionProperties.TITLE_IS_PLURAL)); Assert.assertEquals(R.plurals.accessibility_tab_selection_editor_share_tabs_action_button, mAction.getPropertyModel() .get(TabSelectionEditorActionProperties.CONTENT_DESCRIPTION_RESOURCE_ID)
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorUngroupActionUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorUngroupActionUnitTest.java index cdab4af..da216be 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorUngroupActionUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorUngroupActionUnitTest.java
@@ -76,9 +76,11 @@ public void testInherentActionProperties() { Assert.assertEquals(R.id.tab_selection_editor_ungroup_menu_item, mAction.getPropertyModel().get(TabSelectionEditorActionProperties.MENU_ITEM_ID)); - Assert.assertEquals(R.string.tab_selection_editor_ungroup_tabs, + Assert.assertEquals(R.plurals.tab_selection_editor_ungroup_tabs, mAction.getPropertyModel().get( TabSelectionEditorActionProperties.TITLE_RESOURCE_ID)); + Assert.assertEquals(true, + mAction.getPropertyModel().get(TabSelectionEditorActionProperties.TITLE_IS_PLURAL)); Assert.assertEquals(R.plurals.accessibility_tab_selection_editor_ungroup_tabs, mAction.getPropertyModel() .get(TabSelectionEditorActionProperties.CONTENT_DESCRIPTION_RESOURCE_ID)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java index ae53a0e2..e722010f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -97,6 +97,7 @@ add(ChromeFeatureList.sCreateSafebrowsingOnStartup); add(ChromeFeatureList.sCriticalPersistedTabData); add(ChromeFeatureList.sDiscoverMultiColumn); + add(ChromeFeatureList.sTabStripRedesign); add(ChromeFeatureList.sDiscardOccludedBitmaps); add(ChromeFeatureList.sDownloadsAutoResumptionNative); add(ChromeFeatureList.sEarlyLibraryLoad);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/CredentialLeakDialogBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/CredentialLeakDialogBridge.java index 8275b679..9d1f5d1c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/CredentialLeakDialogBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/CredentialLeakDialogBridge.java
@@ -54,7 +54,7 @@ if (isChangeAutomaticallyAvailable) { headerDrawableId = R.drawable.password_checkup_change_automatically; } else { - headerDrawableId = PasswordManagerHelper.usesUnifiedPasswordManagerUI() + headerDrawableId = PasswordManagerHelper.usesUnifiedPasswordManagerBranding() ? R.drawable.password_check_header_red : R.drawable.password_checkup_warning; };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogMediator.java index 3d4faa93..7a1d15a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogMediator.java
@@ -59,7 +59,7 @@ R.string.password_generation_dialog_use_password_button) .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, R.string.password_generation_dialog_cancel_button); - if (PasswordManagerHelper.usesUnifiedPasswordManagerUI()) { + if (PasswordManagerHelper.usesUnifiedPasswordManagerBranding()) { builder = builder.with(ModalDialogProperties.TITLE_ICON, customView.getContext(), new PasswordManagerResourceProviderImpl() .getPasswordManagerIcon())
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerDialogViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerDialogViewBinder.java index eab7f4a6..b3fb6e4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerDialogViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerDialogViewBinder.java
@@ -31,7 +31,7 @@ // TODO(crbug.com/1271552): Cropping was needed for previous image version. // Depending on feature status, remove this or inline the cropping into // password_manager_dialog_with_help_button.xml. - if (!PasswordManagerHelper.usesUnifiedPasswordManagerUI()) { + if (!PasswordManagerHelper.usesUnifiedPasswordManagerBranding()) { dialogView.cropImageToText(); } } else if (TITLE == propertyKey) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java index 4bb447a..c72bed9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.settings; import static org.chromium.chrome.browser.password_manager.PasswordManagerHelper.hasChosenToSyncPasswords; +import static org.chromium.chrome.browser.password_manager.PasswordManagerHelper.usesUnifiedPasswordManagerBranding; import static org.chromium.chrome.browser.password_manager.PasswordManagerHelper.usesUnifiedPasswordManagerUI; import android.content.Context; @@ -340,7 +341,7 @@ private void updatePasswordsPreference() { Preference passwordsPreference = findPreference(PREF_PASSWORDS); - if (usesUnifiedPasswordManagerUI()) { + if (usesUnifiedPasswordManagerBranding()) { // TODO(crbug.com/1217070): Move this to the layout xml once the feature is rolled out passwordsPreference.setTitle(getPasswordsPreferenceElementTitle()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java index 2920ce26..661b500 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java
@@ -283,7 +283,7 @@ ContextUtils.getApplicationContext().getPackageManager(), profile), printCallback, new LargeIconBridge(profile), isIncognito, AppHooks.get().getImageEditorModuleProvider(), - TrackerFactory.getTrackerForProfile(profile), profileSupplier); + TrackerFactory.getTrackerForProfile(profile), profile); coordinator.showInitialShareSheet(params, chromeShareExtras, shareStartTime); } else { RecordHistogram.recordEnumeratedHistogram(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/ExpandablePaymentHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/ExpandablePaymentHandlerTest.java index 75ceb96..26b5fc9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/ExpandablePaymentHandlerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/ExpandablePaymentHandlerTest.java
@@ -34,7 +34,6 @@ import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason; @@ -207,7 +206,7 @@ @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1191988") + @DisabledTest(message = "https://crbug.com/1191988") @Feature({"Payments"}) public void testSwipeDownCloseUI() throws Throwable { startDefaultServer(); @@ -399,7 +398,7 @@ @SmallTest @Feature({"Payments"}) @ParameterAnnotations.UseMethodParameter(BadCertParams.class) - @FlakyTest(message = "https://crbug.com/1288003") + @DisabledTest(message = "https://crbug.com/1288003") public void testInsecureConnectionNotShowUi(int badCertificate) throws Throwable { startServer(badCertificate); PaymentHandlerCoordinator paymentHandler = createPaymentHandlerAndShow(mDefaultIsIncognito);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java index 6c8c1fe..a2877da 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java
@@ -13,8 +13,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.payments.PaymentRequestTestRule.AppPresence; @@ -51,7 +51,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) @CommandLineFlags.Add({"disable-features=PaymentRequestBasicCard"}) public void testCannotMakePayment_UserAbort() throws TimeoutException { @@ -93,7 +93,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) @CommandLineFlags.Add({"disable-features=PaymentRequestBasicCard"}) public void testCannotMakePayment_Complete() throws TimeoutException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentQueryNoCardTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentQueryNoCardTest.java index 4d521439..fca5ffc 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentQueryNoCardTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentQueryNoCardTest.java
@@ -11,8 +11,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard; @@ -49,7 +49,7 @@ @Test @MediumTest @Feature({"Payments"}) - @FlakyTest(message = "https://crbug.com/1182384") + @DisabledTest(message = "https://crbug.com/1182384") public void testNoAppInFastBobPayInFactory() throws TimeoutException { mPaymentRequestTestRule.addPaymentAppFactory( AppPresence.NO_APPS, FactorySpeed.FAST_FACTORY);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsAndFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsAndFreeShippingTest.java index 62aa3745..f333b72 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsAndFreeShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsAndFreeShippingTest.java
@@ -13,8 +13,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -58,7 +58,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -82,7 +82,7 @@ @Test @MediumTest @Feature({"Payments"}) - @FlakyTest(message = "https://crbug.com/1182589") + @DisabledTest(message = "https://crbug.com/1182589") public void testPaymentRequestEventsMetric() throws TimeoutException { // Start and complete the Payment Request. mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsTest.java index ab0fae005..6e59d06 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsTest.java
@@ -13,8 +13,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -73,7 +73,7 @@ /** Provide the existing valid payer name, phone number and email address to the merchant. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -86,7 +86,7 @@ /** Attempt to add invalid contact information and cancel the transaction. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddInvalidContactAndCancel() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -109,7 +109,7 @@ /** Add new payer name, phone number and email address and provide that to the merchant. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddContactAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -133,7 +133,7 @@ @Test @MediumTest @Feature({"Payments"}) - @FlakyTest(message = "https://crbug.com/1182528") + @DisabledTest(message = "https://crbug.com/1182528") public void testQuickAddContactAndCloseShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); mPaymentRequestTestRule.clickInContactInfoAndWait( @@ -164,7 +164,7 @@ /** Quickly pressing on [X] and then "add contact info" should not crash. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testQuickCloseAndAddContactShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -192,7 +192,7 @@ /** Test that going into the editor and cancelling will leave the row checked. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testEditContactAndCancelEditorShouldKeepContactSelected() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -213,7 +213,7 @@ /** Test that going into the "add" flow and cancelling will leave existing row checked. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddContactAndCancelEditorShouldKeepContactSelected() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -234,7 +234,7 @@ /** Quickly pressing on "add contact info" and then "cancel" should not crash. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testQuickAddContactAndCancelShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -266,7 +266,7 @@ /** Quickly pressing on "cancel" and then "add contact info" should not crash. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testQuickCancelAndAddContactShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -297,7 +297,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testSuggestionsDeduped() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -312,7 +312,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPaymentRequestEventsMetric() throws TimeoutException { // Start and complete the Payment Request.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingMultipleAddressesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingMultipleAddressesTest.java index 36935c9..dc2db966 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingMultipleAddressesTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingMultipleAddressesTest.java
@@ -13,8 +13,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -115,7 +115,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testShippingAddressSuggestionOrdering() throws TimeoutException { // Create two complete and two incomplete profiles. Values are set so that complete profiles @@ -154,7 +154,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testEquallyIncompleteSuggestionsOrdering() throws TimeoutException { // Create two profiles both with missing phone numbers. @@ -179,7 +179,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testShippingAddressSuggestionLimit() throws TimeoutException { // Create five profiles that can be suggested to the user. @@ -220,7 +220,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testShippingAddressSuggestion_OnlyIncludeProfilesWithStreetAddress() throws TimeoutException { @@ -253,7 +253,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testShippingAddresNotAcceptedByMerchant() throws TimeoutException { // Add a profile that is not accepted by the website. @@ -282,7 +282,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testShippingAddressEditRequiredMessage() throws TimeoutException { // Create four incomplete profiles with different missing information. Profiles will be @@ -321,7 +321,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testMissingShippingAddressFieldRecorded() throws TimeoutException { // Add a profile with invalid shipping address, and another one with both missing name and @@ -348,7 +348,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testMissingNameFieldRecorded() throws TimeoutException { // Add a profile with invalid shipping address, and another one with missing name. @@ -373,7 +373,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAllMissingFieldsRecorded() throws TimeoutException { // Don't add any profiles
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingSingleAddressTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingSingleAddressTest.java index da082d3..4bc09888 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingSingleAddressTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingSingleAddressTest.java
@@ -12,8 +12,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -53,7 +53,7 @@ /** The shipping address should not be selected in UI by default. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddressNotSelected() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -64,7 +64,7 @@ /** Expand the shipping address section, select an address, and click "Pay." */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testSelectValidAddressAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -89,7 +89,7 @@ /** Expand the shipping address section, select an address, edit it and click "Pay." */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testSelectValidAddressEditItAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -123,7 +123,7 @@ /** Expand the shipping address section, select address, edit but cancel editing, and "Pay". */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testSelectValidAddressEditItAndCancelAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -158,7 +158,7 @@ /** Attempt to add an invalid address and cancel the transaction. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddInvalidAddressAndCancel() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -186,7 +186,7 @@ * @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) // crbug.com/626289 */ @Test - @FlakyTest(message = "crbug.com/626289") + @DisabledTest(message = "crbug.com/626289") @Feature({"Payments"}) public void testAddAddressAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -213,7 +213,7 @@ /** Quickly pressing "add address" and then [X] should not crash. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testQuickAddAddressAndCloseShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -245,7 +245,7 @@ /** Quickly pressing [X] and then "add address" should not crash. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testQuickCloseAndAddAddressShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -273,7 +273,7 @@ /** Quickly pressing "add address" and then "cancel" should not crash. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testQuickAddAddressAndCancelShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -305,7 +305,7 @@ /** Quickly pressing on "cancel" and then "add address" should not crash. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testQuickCancelAndAddAddressShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndFreeShippingTest.java index 9d22dd7..1237220 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndFreeShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndFreeShippingTest.java
@@ -13,8 +13,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -54,7 +54,7 @@ /** Submit the email and the shipping address to the merchant when the user clicks "Pay." */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -75,7 +75,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPaymentRequestEventsMetric() throws TimeoutException { // Start and cancel the Payment Request. @@ -100,7 +100,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddAddressNoCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndPhoneTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndPhoneTest.java index 6571edf8..73f1d2d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndPhoneTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndPhoneTest.java
@@ -13,8 +13,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -72,7 +72,7 @@ /** Provide the existing valid email address and phone number to the merchant. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -85,7 +85,7 @@ /** Attempt to add an invalid email address and phone number and cancel the transaction. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddInvalidEmailAndCancel() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -108,7 +108,7 @@ /** Add a new email address and phone number and provide that to the merchant. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddEmailAndPhoneAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -133,7 +133,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testSuggestionsDeduped() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -148,7 +148,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPaymentRequestEventsMetric() throws TimeoutException { // Start and cancel the Payment Request.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailTest.java index d792e464..1a2dd2a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailTest.java
@@ -13,8 +13,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -72,7 +72,7 @@ /** Provide the existing valid email address to the merchant. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -84,7 +84,7 @@ /** Attempt to add an invalid email address and cancel the transaction. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddInvalidEmailAndCancel() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -107,7 +107,7 @@ /** Add a new email address and provide that to the merchant. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddEmailAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -131,7 +131,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testSuggestionsDeduped() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -146,7 +146,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPaymentRequestEventsMetric() throws TimeoutException { // Start and complete the Payment Request.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmptyUpdateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmptyUpdateTest.java index 39d8b95..91671990 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmptyUpdateTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmptyUpdateTest.java
@@ -11,8 +11,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -49,7 +49,7 @@ /** Expand the shipping address section and select a valid address. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testSelectValidAddress() throws Throwable { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExtraShippingOptionsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExtraShippingOptionsTest.java index b475cdc..981b3544 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExtraShippingOptionsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExtraShippingOptionsTest.java
@@ -11,8 +11,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -52,7 +52,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java index 34d1980..f8d0f64 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java
@@ -18,8 +18,8 @@ import org.chromium.base.test.params.ParameterAnnotations; import org.chromium.base.test.params.ParameterizedRunner; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -95,7 +95,7 @@ /** Submit the shipping address to the merchant when the user clicks "Pay." */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments", "RenderTest"}) @ParameterAnnotations.UseMethodParameter(NightModeTestUtils.NightModeParams.class) public void testPayWithRender(boolean nightModeEnabled) throws Throwable { @@ -116,7 +116,7 @@ /** Attempt to add an invalid address and cancel the transaction. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/673371") + @DisabledTest(message = "crbug.com/673371") @Feature({"Payments"}) public void testAddInvalidAddressAndCancel() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -137,7 +137,7 @@ /** Add a valid address and complete the transaction. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddAddressAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -164,7 +164,7 @@ /** Change the country in the spinner, add a valid address, and complete the transaction. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testChangeCountryAddAddressAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -193,7 +193,7 @@ /** Quickly pressing on "add address" and then [X] should not crash. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testQuickAddAddressAndCloseShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -225,7 +225,7 @@ /** Quickly pressing on [X] and then "add address" should not crash. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testQuickCloseAndAddAddressShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -253,7 +253,7 @@ /** Quickly pressing on "add address" and then "cancel" should not crash. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/673371") + @DisabledTest(message = "crbug.com/673371") @Feature({"Payments"}) public void testQuickAddAddressAndCancelShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -285,7 +285,7 @@ /** Quickly pressing on "cancel" and then "add address" should not crash. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testQuickCancelAndAddAddressShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -316,7 +316,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPaymentRequestEventsMetric() throws TimeoutException { // Start and abort the Payment Request.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteContactDetailsAndFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteContactDetailsAndFreeShippingTest.java index 1d8e487..5da04cc 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteContactDetailsAndFreeShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteContactDetailsAndFreeShippingTest.java
@@ -12,8 +12,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -55,7 +55,7 @@ /** Update the shipping address with valid data and see that the contacts section is updated. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testEditIncompleteShippingAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -93,7 +93,7 @@ /** Add a shipping address with valid data and see that the contacts section is updated. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testEditIncompleteShippingAndContactAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteContactDetailsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteContactDetailsTest.java index d1312fc..9d45215e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteContactDetailsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteContactDetailsTest.java
@@ -12,8 +12,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -53,7 +53,7 @@ /** Attempt to update the contact information with invalid data and cancel the transaction. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testEditIncompleteContactAndCancel() throws TimeoutException { // Not ready to pay since Contact email is invalid. @@ -86,7 +86,7 @@ /** Attempt to add invalid contact info alongside the already invalid info, and cancel. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddIncompleteContactAndCancel() throws TimeoutException { // Not ready to pay since Contact email is invalid. @@ -119,7 +119,7 @@ /** Update the contact information with valid data and provide that to the merchant. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testEditIncompleteContactAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteEmailTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteEmailTest.java index b5b6263..56c2189 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteEmailTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteEmailTest.java
@@ -12,8 +12,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -53,7 +53,7 @@ /** Attempt to update the email with invalid data and cancel the transaction. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testEditIncompleteEmailAndCancel() throws TimeoutException { // Not ready to pay since Contact email is invalid. @@ -85,7 +85,7 @@ /** Attempt to add an invalid email alongside the already invalid data and cancel. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddIncompleteEmailAndCancel() throws TimeoutException { // Not ready to pay since Contact email is invalid. @@ -118,7 +118,7 @@ /** Update the email with valid data and provide that to the merchant. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testEditIncompleteEmailAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompletePhoneTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompletePhoneTest.java index 402afd29..de7c9cec 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompletePhoneTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompletePhoneTest.java
@@ -12,8 +12,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -53,7 +53,7 @@ @Test @MediumTest @Feature({"Payments"}) - @FlakyTest(message = "https://crbug.com/1197578") + @DisabledTest(message = "https://crbug.com/1197578") public void testEditIncompletePhoneAndCancel() throws TimeoutException { // Not ready to pay since Contact phone is invalid. mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -84,7 +84,7 @@ /** Attempt to add an invalid phone alongside the already invalid data and cancel. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddIncompletePhoneAndCancel() throws TimeoutException { // Not ready to pay since Contact phone is invalid. @@ -117,7 +117,7 @@ /** Update the phone with valid data and provide that to the merchant. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testEditIncompletePhoneAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java index a108d63..e25ba6f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java
@@ -13,8 +13,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -58,7 +58,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testNumberOfSuggestionsShown_ShippingAddress_Completed() throws TimeoutException { createTestData(); @@ -83,7 +83,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testNumberOfSuggestionsShown_ShippingAddress_AbortedByUser() throws InterruptedException, TimeoutException { @@ -197,7 +197,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testNumberOfSuggestionsShown_ContactInfo_Completed() throws TimeoutException { createTestData(); @@ -224,7 +224,7 @@ @Test @MediumTest @Feature({"Payments"}) - @FlakyTest(message = "https://crbug.com/1197578") + @DisabledTest(message = "https://crbug.com/1197578") public void testNumberOfSuggestionsShown_ContactInfo_AbortedByUser() throws InterruptedException, TimeoutException { createTestData(); @@ -250,7 +250,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testUserHadCompleteSuggestions_ShippingAndPayment() throws TimeoutException { // Add two addresses and two cards. @@ -278,7 +278,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testUserDidNotHaveCompleteSuggestions_ShippingAndPayment_IncompleteShipping() throws TimeoutException { @@ -313,7 +313,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testUserDidNotHaveCompleteSuggestions_ShippingAndPayment_IncompleteCard() throws TimeoutException { @@ -346,7 +346,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testUserDidNotHaveCompleteSuggestions_ShippingAndPayment_OnlyPaymentApp() throws TimeoutException { @@ -413,7 +413,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testUserHadCompleteSuggestions_ShippingAndPaymentApp_HasInvalidShipping() throws TimeoutException { @@ -447,7 +447,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testNoContactInfoHistogram() throws TimeoutException { createTestData();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMultipleContactDetailsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMultipleContactDetailsTest.java index 6db921b..52f53c4b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMultipleContactDetailsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMultipleContactDetailsTest.java
@@ -13,8 +13,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -141,7 +141,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testContactDetailsSuggestionOrdering() throws TimeoutException { // Set the use stats so that profile[0] has the highest frecency score, profile[1] the @@ -178,7 +178,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testContactDetailsEditRequiredMessage() throws TimeoutException { mProfilesToAdd = new AutofillProfile[] {AUTOFILL_PROFILES[0], AUTOFILL_PROFILES[1], @@ -211,7 +211,7 @@ @Test @MediumTest @Feature({"Payments"}) - @FlakyTest(message = "https://crbug.com/1182590") + @DisabledTest(message = "https://crbug.com/1182590") public void testContactDetailsDedupe_EmptyFields() throws TimeoutException { // Add the original profile and a bunch of similar profiles with missing fields. // Make sure the original profile is suggested last, to test that the suggestions are @@ -242,7 +242,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testContactDetailsDedupe_Capitalization() throws TimeoutException { // Add the original profile and the one where the the name is not capitalized. @@ -265,7 +265,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testContactDetailsDontDedupe_FieldSubset() throws TimeoutException { // Add the original profile and the one where the email is a superset of the original. @@ -291,7 +291,7 @@ @Test @MediumTest @Feature({"Payments"}) - @FlakyTest(message = "https://crbug.com/1182644") + @DisabledTest(message = "https://crbug.com/1182644") public void testContactDetailsAllMissingFieldsRecorded() throws TimeoutException { // Don't add any profiles. mProfilesToAdd = new AutofillProfile[] {};
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameAndFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameAndFreeShippingTest.java index 5ef0b5f..8631b196 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameAndFreeShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameAndFreeShippingTest.java
@@ -13,8 +13,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -53,7 +53,7 @@ /** Submit the payer name and shipping address to the merchant when the user clicks "Pay." */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -74,7 +74,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPaymentRequestEventsMetric() throws TimeoutException { // Start and cancel the Payment Request.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameTest.java index f3a835ae..a743f83 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameTest.java
@@ -13,8 +13,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -73,7 +73,7 @@ /** Provide the existing valid payer name to the merchant. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -89,7 +89,7 @@ /** Attempt to add an invalid payer name and cancel the transaction. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddInvalidNameAndCancel() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -112,7 +112,7 @@ /** Add a new payer name and provide that to the merchant. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddNameAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -139,7 +139,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testSuggestionsDeduped() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -154,7 +154,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPaymentRequestEventsMetric() throws TimeoutException { // Start and complete the Payment Request.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingOptionsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingOptionsTest.java index faa619f..cb12772 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingOptionsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingOptionsTest.java
@@ -12,8 +12,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -62,7 +62,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAllShippingAddressesInvalid() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java index 8e84c588..68a63b8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java
@@ -13,8 +13,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -53,7 +53,7 @@ /** Click [X] to cancel payment. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testCloseDialog() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -66,7 +66,7 @@ /** Click [EDIT] to expand the dialog, then click [X] to cancel payment. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testEditAndCloseDialog() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -81,7 +81,7 @@ /** Click [EDIT] to expand the dialog, then click [CANCEL] to cancel payment. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testEditAndCancelDialog() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -96,7 +96,7 @@ /** Click [PAY] and dismiss the card unmask dialog. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -113,7 +113,7 @@ /** Click [PAY], type in "123" into the CVC dialog, then submit the payment. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testCancelUnmaskAndRetry() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -134,7 +134,7 @@ /** Quickly pressing on [X] and then "add card" should not crash. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testQuickCloseAndAddCardShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -162,7 +162,7 @@ /** Quickly pressing on "cancel" and then "add card" should not crash. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testQuickCancelAndAddCardShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -193,7 +193,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testQuickDismissAndPayShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -219,7 +219,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testQuickDismissAndCloseShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -245,7 +245,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testQuickCloseAndDismissShouldNotCrash() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -272,7 +272,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPaymentRequestEventsMetric() throws TimeoutException { // Start and cancel the Payment Request.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoUpdateWithTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoUpdateWithTest.java index 624a21c..8c5a3660 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoUpdateWithTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoUpdateWithTest.java
@@ -12,8 +12,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -58,7 +58,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testNoEventListener() throws Throwable { mRule.triggerUIAndWait("buyWithoutListeners", mRule.getReadyForInput()); @@ -78,7 +78,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testNoUpdateWith() throws Throwable { mRule.triggerUIAndWait("buyWithoutCallingUpdateWith", mRule.getReadyForInput()); @@ -95,7 +95,7 @@ /** A merchant that calls updateWith() without using promises will not cause timeouts in UI. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testNoPromises() throws Throwable { mRule.triggerUIAndWait("buyWithoutPromises", mRule.getReadyForInput());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppTest.java index a719e6bc..3227efe 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppTest.java
@@ -11,8 +11,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.payments.PaymentRequestTestRule.AppPresence; import org.chromium.chrome.browser.payments.PaymentRequestTestRule.AppSpeed; @@ -66,7 +66,7 @@ @Test @MediumTest @Feature({"Payments"}) - @FlakyTest(message = "https://crbug.com/1182387") + @DisabledTest(message = "https://crbug.com/1182387") public void testNoAppsInSlowBobPayFactory() throws TimeoutException { mPaymentRequestTestRule.addPaymentAppFactory( AppPresence.NO_APPS, FactorySpeed.SLOW_FACTORY); @@ -79,7 +79,7 @@ @Test @MediumTest @Feature({"Payments"}) - @FlakyTest(message = "https://crbug.com/1182385") + @DisabledTest(message = "https://crbug.com/1182385") public void testAppsCreatedAfterDismissShouldNotCrash() throws TimeoutException { TestFactory factory = mPaymentRequestTestRule.addPaymentAppFactory( AppPresence.HAVE_APPS, FactorySpeed.FAST_FACTORY); @@ -98,7 +98,7 @@ @Test @MediumTest @Feature({"Payments"}) - @FlakyTest(message = "https://crbug.com/1189547") + @DisabledTest(message = "https://crbug.com/1189547") public void testFactoryActivityAfterDismissShouldNotCrash() throws TimeoutException { TestFactory factory = mPaymentRequestTestRule.addPaymentAppFactory( AppPresence.HAVE_APPS, FactorySpeed.FAST_FACTORY); @@ -148,7 +148,7 @@ @Test @MediumTest @Feature({"Payments"}) - @FlakyTest(message = "https://crbug.com/1182588") + @DisabledTest(message = "https://crbug.com/1182588") public void testPayViaDelayedFastBobPay() throws TimeoutException { mPaymentRequestTestRule.addPaymentAppFactory("https://bobpay.com", AppPresence.HAVE_APPS, FactorySpeed.FAST_FACTORY, AppSpeed.FAST_APP);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneAndFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneAndFreeShippingTest.java index 123e98a..9e72123 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneAndFreeShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneAndFreeShippingTest.java
@@ -13,8 +13,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -53,7 +53,7 @@ /** Submit the phone number and shipping address to the merchant when the user clicks "Pay." */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -74,7 +74,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPaymentRequestEventsMetric() throws TimeoutException { // Start and complete the Payment Request.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneTest.java index 57d5850..70cfb29a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneTest.java
@@ -13,8 +13,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -72,7 +72,7 @@ /** Provide the existing valid phone number to the merchant. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -84,7 +84,7 @@ /** Attempt to add an invalid phone number and cancel the transaction. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddInvalidPhoneAndCancel() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -107,7 +107,7 @@ /** Add a new phone number and provide that to the merchant. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddPhoneAndPay() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -131,7 +131,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testSuggestionsDeduped() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -146,7 +146,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testPaymentRequestEventsMetric() throws TimeoutException { // Start and abort the Payment Request.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRetryTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRetryTest.java index 399d531..fe2d3092 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRetryTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRetryTest.java
@@ -12,8 +12,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -86,7 +86,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testRetryWithDefaultError() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -110,7 +110,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testRetryWithCustomError() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -135,7 +135,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments", "RenderTest"}) public void testRetryWithShippingAddressErrors() throws Throwable { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -186,7 +186,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments", "RenderTest"}) public void testRetryWithPayerErrors() throws Throwable { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -229,7 +229,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testRetryWithShippingAddressErrorsAndPayerErrors() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -272,7 +272,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testRetryAndPayerDetailChangeEvent() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput()); @@ -312,7 +312,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testRetryAndReselectContactDetail() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressAndOptionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressAndOptionTest.java index 2771f02..1a06617 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressAndOptionTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressAndOptionTest.java
@@ -12,8 +12,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -58,7 +58,7 @@ /** Verifies that the shipping address format in bottomsheet mode is as expected. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testShippingAddressFormat_BottomSheet() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -80,7 +80,7 @@ /** Verifies that the shipping address format in fullsheet mode is as expected. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testShippingAddressFormat_FullSheet() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -104,7 +104,7 @@ /** Verifies that the shipping address format in fullsheet mode is as expected. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testShippingAddressFormat_Expanded() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -135,7 +135,7 @@ /** Verifies that the shipping address format of a new address is as expected. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testShippingAddressFormat_NewAddress() throws TimeoutException { mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay()); @@ -165,7 +165,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testEditShippingAddressAndCancelEditorShouldKeepAddressSelected() throws TimeoutException { @@ -190,7 +190,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testEditShippingAddressAndClickAndroidBackButtonShouldKeepAddressSelected() throws TimeoutException { @@ -215,7 +215,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddShippingAddressAndCancelEditorShouldKeepAddressSelected() throws TimeoutException { @@ -240,7 +240,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddShippingAddressAndClickAndroidBackButtonShouldKeepAddressSelected() throws TimeoutException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressChangeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressChangeTest.java index 6890bf3..8320b58 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressChangeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressChangeTest.java
@@ -11,8 +11,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -51,7 +51,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testAddressRedactionInShippingAddressChange() throws TimeoutException { // Select a shipping address and cancel out.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowPromiseSingleOptionShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowPromiseSingleOptionShippingTest.java index 460c14f..7d4ad17 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowPromiseSingleOptionShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowPromiseSingleOptionShippingTest.java
@@ -12,8 +12,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -51,7 +51,7 @@ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testFastApp() throws TimeoutException { mRule.addPaymentAppFactory("basic-card", AppPresence.HAVE_APPS, FactorySpeed.FAST_FACTORY); @@ -66,7 +66,7 @@ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testSlowApp() throws TimeoutException { mRule.addPaymentAppFactory(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowPromiseSingleOptionShippingWithUpdateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowPromiseSingleOptionShippingWithUpdateTest.java index 12b8da65..81f22b6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowPromiseSingleOptionShippingWithUpdateTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowPromiseSingleOptionShippingWithUpdateTest.java
@@ -12,8 +12,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -51,7 +51,7 @@ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testFastApp() throws TimeoutException { mRule.addPaymentAppFactory("basic-card", AppPresence.HAVE_APPS, FactorySpeed.FAST_FACTORY); @@ -66,7 +66,7 @@ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testSlowApp() throws TimeoutException { mRule.addPaymentAppFactory(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowPromiseUSOnlyShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowPromiseUSOnlyShippingTest.java index 4e447f4..accbfea 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowPromiseUSOnlyShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowPromiseUSOnlyShippingTest.java
@@ -12,8 +12,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -41,7 +41,7 @@ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testCannotShipWithFastApp() throws TimeoutException { mRule.addPaymentAppFactory("basic-card", AppPresence.HAVE_APPS, FactorySpeed.FAST_FACTORY); @@ -50,7 +50,7 @@ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testCannotShipWithSlowApp() throws TimeoutException { mRule.addPaymentAppFactory( @@ -77,7 +77,7 @@ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testCanShipWithFastApp() throws TimeoutException { mRule.addPaymentAppFactory("basic-card", AppPresence.HAVE_APPS, FactorySpeed.FAST_FACTORY); @@ -86,7 +86,7 @@ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testCanShipWithSlowApp() throws TimeoutException { mRule.addPaymentAppFactory(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestUpdateWithTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestUpdateWithTest.java index 489ac02..c0b2797 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestUpdateWithTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestUpdateWithTest.java
@@ -12,8 +12,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -55,7 +55,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testUpdateWithEmpty() throws Throwable { mRule.triggerUIAndWait("updateWithEmpty", mRule.getReadyToPay()); @@ -79,7 +79,7 @@ /** A merchant that calls updateWith() with total will not cause timeouts in UI. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testUpdateWithTotal() throws Throwable { mRule.triggerUIAndWait("updateWithTotal", mRule.getReadyToPay()); @@ -106,7 +106,7 @@ /** A merchant that calls updateWith() with displayItems will not cause timeouts in UI. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testUpdateWithDisplayItems() throws Throwable { mRule.triggerUIAndWait("updateWithDisplayItems", mRule.getReadyToPay()); @@ -133,7 +133,7 @@ /** A merchant that calls updateWith() with shipping options will not cause timeouts in UI. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testUpdateWithShippingOptions() throws Throwable { mRule.triggerUIAndWait("updateWithShippingOptions", mRule.getReadyToPay()); @@ -160,7 +160,7 @@ /** A merchant that calls updateWith() with modifiers will not cause timeouts in UI. */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testUpdateWithModifiers() throws Throwable { mRule.triggerUIAndWait("updateWithModifiers", mRule.getReadyToPay()); @@ -190,7 +190,7 @@ */ @Test @MediumTest - @FlakyTest(message = "crbug.com/1182234") + @DisabledTest(message = "crbug.com/1182234") @Feature({"Payments"}) public void testUpdateWithError() throws Throwable { mRule.triggerUIAndWait("updateWithError", mRule.getReadyToPay());
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 139f39be..59d094ce 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -7152,6 +7152,9 @@ <message name="IDS_ACCNAME_SIDE_PANEL_RESIZE" is_accessibility_with_no_ui="true" desc="Screen reader announcement when the side panel resize handle is focused."> Side Panel Resize Handle </message> + <message name="IDS_ACCNAME_SIDE_PANEL_SELECTOR" is_accessibility_with_no_ui="true" desc="Screen reader announcement when the side panel header combobox is focused."> + Side Panel Selector + </message> <message name="IDS_SIDE_PANEL_CUSTOMIZE_CHROME_TITLE" desc="The name of the Customize Chrome feature in the side panel combo box."> Customize Chrome </message> @@ -7305,9 +7308,18 @@ <message name="IDS_LENS_SEARCH_UPLOAD_DIALOG_DRAG_DROP_TITLE" desc="Message to user when they are dragging an image over the image drop zone."> Drop an image here </message> - <message name="IDS_LENS_SEARCH_UPLOAD_DIALOG_LOADING_TEXT" desc="Message to user when their is uploading."> + <message name="IDS_LENS_SEARCH_UPLOAD_DIALOG_LOADING_TEXT" desc="Message to user when their image is uploading."> Uploading... </message> + <message name="IDS_LENS_SEARCH_UPLOAD_DIALOG_OFFLINE_TEXT" desc="Message to user when they are offline."> + No network connection + </message> + <message name="IDS_LENS_SEARCH_UPLOAD_DIALOG_OFFLINE_SUBTITLE_TEXT" desc="Instructions to user when they are offline."> + please check your internet connection and try again + </message> + <message name="IDS_LENS_SEARCH_UPLOAD_DIALOG_OFFLINE_BUTTON_LABEL" desc="Label for button which allows the user to retry connection."> + Try again + </message> <message name="IDS_TOOLTIP_SAVE_CREDIT_CARD" desc="The tooltip for the icon that shows the save credit card bubble"> Save card </message>
diff --git a/chrome/app/generated_resources_grd/IDS_LENS_SEARCH_UPLOAD_DIALOG_OFFLINE_BUTTON_LABEL.png.sha1 b/chrome/app/generated_resources_grd/IDS_LENS_SEARCH_UPLOAD_DIALOG_OFFLINE_BUTTON_LABEL.png.sha1 new file mode 100644 index 0000000..707322d --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_LENS_SEARCH_UPLOAD_DIALOG_OFFLINE_BUTTON_LABEL.png.sha1
@@ -0,0 +1 @@ +cc9df7912c5fd764d78bc5aa5fdc8b362d341d11 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_LENS_SEARCH_UPLOAD_DIALOG_OFFLINE_SUBTITLE_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_LENS_SEARCH_UPLOAD_DIALOG_OFFLINE_SUBTITLE_TEXT.png.sha1 new file mode 100644 index 0000000..6f424ec8 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_LENS_SEARCH_UPLOAD_DIALOG_OFFLINE_SUBTITLE_TEXT.png.sha1
@@ -0,0 +1 @@ +d48de8036bb5a667b4f261da7fd0454f943ee656 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_LENS_SEARCH_UPLOAD_DIALOG_OFFLINE_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_LENS_SEARCH_UPLOAD_DIALOG_OFFLINE_TEXT.png.sha1 new file mode 100644 index 0000000..28ce397 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_LENS_SEARCH_UPLOAD_DIALOG_OFFLINE_TEXT.png.sha1
@@ -0,0 +1 @@ +8e2ac711c76e0ecc314dfe71a217639769423bfe \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 40795697..58e3d460 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -609,6 +609,12 @@ <message name="IDS_SETTINGS_INPUT_METHOD_OPTIONS_JAPANESE_NUMBER_OF_SUGGESTIONS" desc="The label for the setting to set the number of suggestions the Japanese input method should show."> Number of suggestions </message> + <message name="IDS_SETTINGS_INPUT_METHOD_OPTIONS_JAPANESE_DISABLE_PERSONALIZED_SUGGESTIONS" desc="The label for the setting toggle to enable or disable the personalized conversions and custom user dictionaries for Japanese. The original string in Japanese is '学習機能、入力履歴からのサジェスト機能、ユーザ辞書機能を無効にする'."> + Disable personalized conversions and suggestions as well as user dictionary + </message> + <message name="IDS_SETTINGS_INPUT_METHOD_OPTIONS_JAPANESE_SEND_STATISTICS_TO_GOOGLE" desc="The label for the setting toggle to enable or disable sending all usage statistics and crash reports to Google. The original string in Japanese is '使用統計データや障害レポートを Google に自動送信する'."> + Automatically send usage statistics and crash reports to Google + </message> <message name="IDS_SETTINGS_INPUT_METHOD_OPTIONS_ENABLE_DOUBLE_SPACE_PERIOD" desc="The label for the input method option to enable double-space to type period (when an user types two consecutive space, it outputs a period)."> Double-space to type period </message>
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INPUT_METHOD_OPTIONS_JAPANESE_DISABLE_PERSONALIZED_SUGGESTIONS.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INPUT_METHOD_OPTIONS_JAPANESE_DISABLE_PERSONALIZED_SUGGESTIONS.png.sha1 new file mode 100644 index 0000000..46208d1 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INPUT_METHOD_OPTIONS_JAPANESE_DISABLE_PERSONALIZED_SUGGESTIONS.png.sha1
@@ -0,0 +1 @@ +9d94b62e05af49990c877ef12acac6e90ed83f68
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INPUT_METHOD_OPTIONS_JAPANESE_SEND_STATISTICS_TO_GOOGLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INPUT_METHOD_OPTIONS_JAPANESE_SEND_STATISTICS_TO_GOOGLE.png.sha1 new file mode 100644 index 0000000..46208d1 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INPUT_METHOD_OPTIONS_JAPANESE_SEND_STATISTICS_TO_GOOGLE.png.sha1
@@ -0,0 +1 @@ +9d94b62e05af49990c877ef12acac6e90ed83f68
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 59f9bdbd..5f1e730 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -3068,11 +3068,11 @@ <message name="IDS_SETTINGS_COOKIES_BLOCK_ALL_BULLET_THREE" desc="Description for the third bullet of block all cookies radio toggle"> Features on many sites may not work </message> - <message name="IDS_SETTINGS_COOKIES_FIRST_PARTY_SETS_TOGGLE_LABEL" desc="Label for the toggle that allows the user to control First Party sets enabled sharing between related sites" translateable="false"> - Allow related sites to remember you across sites + <message name="IDS_SETTINGS_COOKIES_FIRST_PARTY_SETS_TOGGLE_LABEL" desc="Label for the toggle that allows the user to control first-party sets enabled sharing between related sites"> + Allow related sites to see your activity in the group </message> - <message name="IDS_SETTINGS_COOKIES_FIRST_PARTY_SETS_TOGGLE_SUB_LABEL" desc="Sub-label for the toggle that allows the user to control First Party sets enabled sharing between related sites" translateable="false"> - Related sites use cookies to help with things like keeping you signed in + <message name="IDS_SETTINGS_COOKIES_FIRST_PARTY_SETS_TOGGLE_SUB_LABEL" desc="Sub-label for the toggle that allows the user to control first-party sets enabled sharing between related sites"> + A company can define a group of sites that can use cookies to share your activity in the group. This is off in Incognito. </message> <message name="IDS_SETTINGS_COOKIES_CLEAR_ON_EXIT" desc="Label for the toggle that allows the user to automatically delete their cookies and site data when they close all browser windows."> Clear cookies and site data when you close all windows @@ -3389,8 +3389,8 @@ <message name="IDS_SETTINGS_SITE_SETTINGS_CLEAR_DISPLAYED_STORAGE_DIALOG_TITLE" desc="Title of the dialog that warns about deleting displayed site data."> Clear displayed data? </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE" translateable="false" desc="Placeholder string for first party sets informational learn more link shown when sites are filtered by first party set owner"> - These sites are in <ph name="FPS_OWNER">$1<ex>google.com</ex></ph>'s group of sites that can see your activity in the group. <ph name="LINK_BEGIN"><a></ph>Learn more<ph name="LINK_END"></a></ph> + <message name="IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE" desc="Label for first-party sets explainer with a learn more link shown when sites are filtered by first-party set owner"> + These sites are in a group defined by <ph name="FPS_OWNER">$1<ex>google.com</ex></ph>. Sites in a group can see your activity in the group. <ph name="LINK_BEGIN"><a></ph>Learn more<ph name="LINK_END"></a></ph> </message> <message name="IDS_SETTINGS_SITE_SETTINGS_CLEAR_ALL_STORAGE_DESCRIPTION" desc="Label describing how much total disk space chrome is using, next to the clear all button"> Total storage used by sites: <ph name="TOTAL_USAGE">$1<ex>8 GB</ex></ph> @@ -3403,15 +3403,15 @@ </message> <message name="IDS_SETTINGS_SITE_SETTINGS_CLEAR_DISPLAYED_STORAGE_LABEL" desc="Label for button to clear displayed site data"> Clear displayed data - </message> <message name="IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_MEMBERSHIP_LABEL" translateable="false" desc="Placeholder string for first party sets member count shown on site details and site entry"> + </message> <message name="IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_MEMBERSHIP_LABEL" desc="Label displaying how many members are in a first-party set for a specific site. This is displayed on site entries in all sites page and site details page."> {MEMBERS, plural, - =1 {Allowed for 1 <ph name="FPS_OWNER">$1<ex>google.com</ex></ph> site} - other {Allowed for {MEMBERS} <ph name="FPS_OWNER">{FPS_OWNER}<ex>google.com</ex></ph> sites}} + =1 {1 site in <ph name="FPS_OWNER">{FPS_OWNER}<ex>google.com</ex></ph>'s group} + other {{MEMBERS} sites in <ph name="FPS_OWNER">{FPS_OWNER}<ex>google.com</ex></ph>'s group}} </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_SHOW_RELATED_SITES_BUTTON" translateable="false" desc="Placeholder string for first party sets show related sites button"> - Show related sites + <message name="IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_SHOW_RELATED_SITES_BUTTON" desc="Label for the button on the first-party sets more actions menu to allow users to filter sites by the first-party set owner."> + Show sites in same group </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_SITE_CLEAR_STORAGE_BUTTON" translateable="false" desc="Placeholder string for first party sets clear data and permissions for site button"> + <message name="IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_SITE_CLEAR_STORAGE_BUTTON" desc="Label for the button on the first-party sets more actions menu to allow users to clear data and permissions for a specific site entry."> Clear data and permissions </message> <message name="IDS_SETTINGS_SITE_SETTINGS_CLEAR_ALL_STORAGE_CONFIRMATION" desc="Text for the dialog that warns about clearing storage used by all sites.">
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_COOKIES_FIRST_PARTY_SETS_TOGGLE_LABEL.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_COOKIES_FIRST_PARTY_SETS_TOGGLE_LABEL.png.sha1 new file mode 100644 index 0000000..df46ee4 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_COOKIES_FIRST_PARTY_SETS_TOGGLE_LABEL.png.sha1
@@ -0,0 +1 @@ +8d7cd0882efe2f55e2a07c6edb1e2b55475f1740 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_COOKIES_FIRST_PARTY_SETS_TOGGLE_SUB_LABEL.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_COOKIES_FIRST_PARTY_SETS_TOGGLE_SUB_LABEL.png.sha1 new file mode 100644 index 0000000..df46ee4 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_COOKIES_FIRST_PARTY_SETS_TOGGLE_SUB_LABEL.png.sha1
@@ -0,0 +1 @@ +8d7cd0882efe2f55e2a07c6edb1e2b55475f1740 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE.png.sha1 new file mode 100644 index 0000000..4e62f38 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_LEARN_MORE.png.sha1
@@ -0,0 +1 @@ +07c465bd8442b033868d2a8a648c7ee1fedb4d91 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_MEMBERSHIP_LABEL.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_MEMBERSHIP_LABEL.png.sha1 new file mode 100644 index 0000000..b07080d --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_MEMBERSHIP_LABEL.png.sha1
@@ -0,0 +1 @@ +d0e7b47bf335dbae478052242c19a8ebade1e988 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_SHOW_RELATED_SITES_BUTTON.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_SHOW_RELATED_SITES_BUTTON.png.sha1 new file mode 100644 index 0000000..3cdbd90c --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_SHOW_RELATED_SITES_BUTTON.png.sha1
@@ -0,0 +1 @@ +06ac5a8264fd33de8b1d4c64327cb77c5b62b0c3 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_SITE_CLEAR_STORAGE_BUTTON.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_SITE_CLEAR_STORAGE_BUTTON.png.sha1 new file mode 100644 index 0000000..3cdbd90c --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_SITE_CLEAR_STORAGE_BUTTON.png.sha1
@@ -0,0 +1 @@ +06ac5a8264fd33de8b1d4c64327cb77c5b62b0c3 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 42d640b8..8d4f7ff 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1093,6 +1093,8 @@ "performance_manager/decorators/helpers/page_live_state_decorator_helper.h", "performance_manager/decorators/page_aggregator.cc", "performance_manager/decorators/page_aggregator.h", + "performance_manager/decorators/page_live_state_decorator_delegate_impl.cc", + "performance_manager/decorators/page_live_state_decorator_delegate_impl.h", "performance_manager/decorators/process_priority_aggregator.cc", "performance_manager/decorators/process_priority_aggregator.h", "performance_manager/mechanisms/page_freezer.cc", @@ -5660,12 +5662,12 @@ "policy/status_provider/user_policy_status_provider_lacros.h", "signin/signin_ui_delegate_impl_lacros.cc", "signin/signin_ui_delegate_impl_lacros.h", - "speech/tts_external_platform_delegate_impl_lacros.cc", - "speech/tts_external_platform_delegate_impl_lacros.h", "speech/tts_client_factory_lacros.cc", "speech/tts_client_factory_lacros.h", "speech/tts_client_lacros.cc", "speech/tts_client_lacros.h", + "speech/tts_external_platform_delegate_impl_lacros.cc", + "speech/tts_external_platform_delegate_impl_lacros.h", "speech/tts_lacros.cc", "speech/tts_lacros.h", "task_manager/providers/crosapi/task_manager_controller_lacros.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index aa1e7347..38a0dd9e 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -6101,6 +6101,11 @@ FEATURE_WITH_PARAMS_VALUE_TYPE(ntp_features::kNtpSafeBrowsingModule, kNtpSafeBrowsingModuleVariations, "DesktopNtpModules")}, + + {"ntp-desktop-lens", flag_descriptions::kNtpDesktopLensName, + flag_descriptions::kNtpDesktopLensDescription, kOsDesktop, + FEATURE_VALUE_TYPE(ntp_features::kNtpRealboxLensSearch)}, + #endif // !BUILDFLAG(IS_ANDROID) #if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION) @@ -6393,6 +6398,11 @@ flag_descriptions::kDiscoverFeedMultiColumnAndroidDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kDiscoverFeedMultiColumn)}, + {"enable-tab-strip-redesign", + flag_descriptions::kTabStripRedesignAndroidName, + flag_descriptions::kTabStripRedesignAndroidDescription, kOsAndroid, + FEATURE_VALUE_TYPE(chrome::android::kTabStripRedesign)}, + {"enable-conditional-tabstrip", flag_descriptions::kConditionalTabStripAndroidName, flag_descriptions::kConditionalTabStripAndroidDescription, kOsAndroid, @@ -7741,10 +7751,10 @@ flag_descriptions::kAttributionReportingDebugModeDescription, kOsAll, SINGLE_VALUE_TYPE(switches::kAttributionReportingDebugMode)}, - {"private-aggregation-debug-mode", - flag_descriptions::kPrivateAggregationDebugModeName, - flag_descriptions::kPrivateAggregationDebugModeDescription, kOsAll, - SINGLE_VALUE_TYPE(switches::kPrivateAggregationDebugMode)}, + {"private-aggregation-developer-mode", + flag_descriptions::kPrivateAggregationDeveloperModeName, + flag_descriptions::kPrivateAggregationDeveloperModeDescription, kOsAll, + SINGLE_VALUE_TYPE(switches::kPrivateAggregationDeveloperMode)}, {"client-storage-access-context-auditing", flag_descriptions::kClientStorageAccessContextAuditingName,
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc index 7fe133a..882d287 100644 --- a/chrome/browser/apps/guest_view/web_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -5523,6 +5523,13 @@ entry->metrics.begin()->second); } +IN_PROC_BROWSER_TEST_P(WebViewTest, InsertIntoDetachedIframe) { + TestHelper("testInsertIntoDetachedIframe", "web_view/shim", + NEEDS_TEST_SERVER); + // Round-trip to ensure the embedder did not crash. + EXPECT_EQ(true, content::EvalJs(GetFirstAppWindowWebContents(), "true")); +} + #if BUILDFLAG(ENABLE_PPAPI) class WebViewPPAPITest : public WebViewTest { protected:
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl.cc index 7fd2f2b..0471da7 100644 --- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl.cc +++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl.cc
@@ -24,15 +24,6 @@ namespace ash::personalization_app { -namespace { -KeyboardBacklightColorController* GetKeyboardBacklightColorController() { - auto* keyboard_backlight_color_controller = - ash::Shell::Get()->keyboard_backlight_color_controller(); - DCHECK(keyboard_backlight_color_controller); - return keyboard_backlight_color_controller; -} -} // namespace - PersonalizationAppKeyboardBacklightProviderImpl:: PersonalizationAppKeyboardBacklightProviderImpl(content::WebUI* web_ui) : profile_(Profile::FromWebUI(web_ui)) {} @@ -101,6 +92,23 @@ } void PersonalizationAppKeyboardBacklightProviderImpl:: + SetKeyboardBacklightColorControllerForTesting( + KeyboardBacklightColorController* controller) { + keyboard_backlight_color_controller_for_testing_ = controller; +} + +KeyboardBacklightColorController* +PersonalizationAppKeyboardBacklightProviderImpl:: + GetKeyboardBacklightColorController() { + if (keyboard_backlight_color_controller_for_testing_) + return keyboard_backlight_color_controller_for_testing_; + auto* keyboard_backlight_color_controller = + ash::Shell::Get()->keyboard_backlight_color_controller(); + DCHECK(keyboard_backlight_color_controller); + return keyboard_backlight_color_controller; +} + +void PersonalizationAppKeyboardBacklightProviderImpl:: NotifyBacklightColorChanged() { DCHECK(keyboard_backlight_observer_remote_.is_bound()); keyboard_backlight_observer_remote_->OnBacklightColorChanged(
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl.h b/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl.h index 05db719..fd047ac 100644 --- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl.h +++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl.h
@@ -7,6 +7,7 @@ #include "ash/public/cpp/wallpaper/wallpaper_controller.h" #include "ash/public/cpp/wallpaper/wallpaper_controller_observer.h" +#include "ash/system/keyboard_brightness/keyboard_backlight_color_controller.h" #include "ash/webui/personalization_app/mojom/personalization_app.mojom.h" #include "ash/webui/personalization_app/personalization_app_keyboard_backlight_provider.h" #include "base/scoped_observation.h" @@ -52,13 +53,23 @@ // WallpaperControllerObserver: void OnWallpaperColorsChanged() override; + // Tests can provide the controller in case it is not initialized in + // ash::Shell. + void SetKeyboardBacklightColorControllerForTesting( + KeyboardBacklightColorController* controller); + private: + KeyboardBacklightColorController* GetKeyboardBacklightColorController(); + // Notify webUI the current state of backlight color. void NotifyBacklightColorChanged(); // Pointer to profile of user that opened personalization SWA. Not owned. raw_ptr<Profile> const profile_ = nullptr; + raw_ptr<KeyboardBacklightColorController> + keyboard_backlight_color_controller_for_testing_; + mojo::Receiver<mojom::KeyboardBacklightProvider> keyboard_backlight_receiver_{ this};
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl_unittest.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl_unittest.cc index 6100e52..619d192 100644 --- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl_unittest.cc +++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl_unittest.cc
@@ -4,7 +4,10 @@ #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl.h" +#include <memory> + #include "ash/constants/ash_features.h" +#include "ash/system/keyboard_brightness/keyboard_backlight_color_controller.h" #include "ash/webui/personalization_app/mojom/personalization_app.mojom.h" #include "base/test/metrics/histogram_tester.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" @@ -101,11 +104,16 @@ keyboard_backlight_provider_ = std::make_unique<PersonalizationAppKeyboardBacklightProviderImpl>( &web_ui_); + keyboard_backlight_color_controller_ = + std::make_unique<KeyboardBacklightColorController>(); + keyboard_backlight_provider_->SetKeyboardBacklightColorControllerForTesting( + keyboard_backlight_color_controller_.get()); keyboard_backlight_provider_->BindInterface( keyboard_backlight_provider_remote_.BindNewPipeAndPassReceiver()); } void TearDown() override { + keyboard_backlight_color_controller_.reset(); keyboard_backlight_provider_.reset(); ChromeAshTestBase::TearDown(); } @@ -148,6 +156,8 @@ content::TestWebUI web_ui_; std::unique_ptr<content::WebContents> web_contents_; TestingProfile* profile_; + std::unique_ptr<KeyboardBacklightColorController> + keyboard_backlight_color_controller_; mojo::Remote<ash::personalization_app::mojom::KeyboardBacklightProvider> keyboard_backlight_provider_remote_; std::unique_ptr<PersonalizationAppKeyboardBacklightProviderImpl>
diff --git a/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java b/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java index 0b72f48..6fca794 100644 --- a/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java +++ b/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
@@ -1063,7 +1063,7 @@ TestThreadUtils.runOnUiThreadBlocking( () -> { backgroundTab.loadUrl(new LoadUrlParams(url)); }); - waitForAppBannerPipelineStatus(backgroundTab, /* PENDING_PROMPT */ 8); + waitForAppBannerPipelineStatus(backgroundTab, /* PENDING_PROMPT */ 9); ThreadUtils.runOnUiThreadBlocking(() -> { Assert.assertEquals(BottomSheetController.SheetState.HIDDEN, @@ -1182,7 +1182,7 @@ TestThreadUtils.runOnUiThreadBlocking( () -> { backgroundTab.loadUrl(new LoadUrlParams(url)); }); - waitForAppBannerPipelineStatus(backgroundTab, /* PENDING_PROMPT */ 8); + waitForAppBannerPipelineStatus(backgroundTab, /* PENDING_PROMPT */ 9); assertNoHelpBubble(withText(R.string.iph_pwa_install_available_text)); }
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc index 790404b..eb54136 100644 --- a/chrome/browser/banners/app_banner_manager_browsertest.cc +++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -157,6 +157,12 @@ return params; } + InstallableParams ParamsToPerformWorkerCheck() override { + InstallableParams params = AppBannerManager::ParamsToPerformWorkerCheck(); + params.wait_for_worker = wait_for_worker_; + return params; + } + void OnBannerPromptReply( mojo::Remote<blink::mojom::AppBannerController> controller, blink::mojom::AppBannerPromptReply reply) override { @@ -189,9 +195,9 @@ bool IsWebAppConsideredInstalled() const override { return false; } - private: base::OnceClosure on_done_; + private: // If non-null, |on_banner_prompt_reply_| will be invoked from // OnBannerPromptReply. base::OnceClosure on_banner_prompt_reply_; @@ -258,6 +264,7 @@ // cases navigate the page, causing the state to go back to INACTIVE. EXPECT_TRUE(manager->state() == State::COMPLETE || manager->state() == State::PENDING_PROMPT || + manager->state() == State::PENDING_WORKER || manager->state() == State::INACTIVE); // If in incognito, ensure that nothing is recorded. @@ -1115,6 +1122,8 @@ embedded_test_server()->GetURL("/banners/manifest_test_page.html"), absl::nullopt); EXPECT_EQ(manager->state(), AppBannerManager::State::PENDING_PROMPT); + EXPECT_EQ(manager->GetInstallableWebAppCheckResultForTesting(), + AppBannerManager::InstallableWebAppCheckResult::kYes_Promotable); } IN_PROC_BROWSER_TEST_P(AppBannerServiceWorkerCriteriaTest, NoServiceWorker) { @@ -1123,25 +1132,20 @@ // Set not wait for service worker so it will not timeout. manager->SetWaitForServiceWorker(false); - absl::optional<InstallableStatusCode> expected_code; - switch (GetParam()) { - case ServiceWorkerCriteriaType::kDisabled: - expected_code = NO_MATCHING_SERVICE_WORKER; - break; - case ServiceWorkerCriteriaType::kSkipForInstalls: - expected_code = SERVICE_WORKER_NOT_REQUIRED; - break; - } - RunBannerTest(browser(), manager.get(), embedded_test_server()->GetURL( "/banners/manifest_no_service_worker.html"), - expected_code); + NO_MATCHING_SERVICE_WORKER); - if (expected_code) { - EXPECT_EQ(manager->state(), AppBannerManager::State::COMPLETE); + EXPECT_EQ(manager->state(), AppBannerManager::State::COMPLETE); + + if (GetParam() == ServiceWorkerCriteriaType::kDisabled) { + EXPECT_EQ(manager->GetInstallableWebAppCheckResultForTesting(), + AppBannerManager::InstallableWebAppCheckResult::kNo); } else { - EXPECT_EQ(manager->state(), AppBannerManager::State::PENDING_PROMPT); + EXPECT_EQ( + manager->GetInstallableWebAppCheckResultForTesting(), + AppBannerManager::InstallableWebAppCheckResult::kYes_ByUserRequest); } } @@ -1149,28 +1153,69 @@ std::unique_ptr<AppBannerManagerTest> manager( CreateAppBannerManager(browser())); - absl::optional<InstallableStatusCode> expected_code; - switch (GetParam()) { - case ServiceWorkerCriteriaType::kDisabled: - expected_code = NOT_OFFLINE_CAPABLE; - break; - case ServiceWorkerCriteriaType::kSkipForInstalls: - expected_code = SERVICE_WORKER_NOT_REQUIRED; - break; - } - RunBannerTest(browser(), manager.get(), embedded_test_server()->GetURL( "/banners/no_sw_fetch_handler_test_page.html"), - expected_code); + NOT_OFFLINE_CAPABLE); - if (expected_code) { - EXPECT_EQ(manager->state(), AppBannerManager::State::COMPLETE); + EXPECT_EQ(manager->state(), AppBannerManager::State::COMPLETE); + + if (GetParam() == ServiceWorkerCriteriaType::kDisabled) { + EXPECT_EQ(manager->GetInstallableWebAppCheckResultForTesting(), + AppBannerManager::InstallableWebAppCheckResult::kNo); } else { - EXPECT_EQ(manager->state(), AppBannerManager::State::PENDING_PROMPT); + EXPECT_EQ( + manager->GetInstallableWebAppCheckResultForTesting(), + AppBannerManager::InstallableWebAppCheckResult::kYes_ByUserRequest); } } +class PendingWorkerAppBannerManager : public AppBannerManagerTest { + public: + explicit PendingWorkerAppBannerManager(content::WebContents* web_contents) + : AppBannerManagerTest(web_contents) {} + + PendingWorkerAppBannerManager(const PendingWorkerAppBannerManager&) = delete; + PendingWorkerAppBannerManager& operator=( + const PendingWorkerAppBannerManager&) = delete; + + ~PendingWorkerAppBannerManager() override = default; + + protected: + void UpdateState(AppBannerManager::State state) override { + AppBannerManagerTest::UpdateState(state); + if (state == AppBannerManager::State::PENDING_WORKER) { + if (on_done_) + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + std::move(on_done_)); + } + } +}; + +IN_PROC_BROWSER_TEST_P(AppBannerServiceWorkerCriteriaTest, + PendingServiceWorker) { + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + std::unique_ptr<PendingWorkerAppBannerManager> manager = + std::make_unique<PendingWorkerAppBannerManager>(web_contents); + + RunBannerTest(browser(), manager.get(), + embedded_test_server()->GetURL( + "/banners/manifest_no_service_worker.html"), + absl::nullopt); + + EXPECT_EQ(manager->state(), AppBannerManager::State::PENDING_WORKER); + if (GetParam() == ServiceWorkerCriteriaType::kDisabled) { + EXPECT_EQ(manager->GetInstallableWebAppCheckResultForTesting(), + AppBannerManager::InstallableWebAppCheckResult::kUnknown); + } else { + EXPECT_EQ( + manager->GetInstallableWebAppCheckResultForTesting(), + AppBannerManager::InstallableWebAppCheckResult::kYes_ByUserRequest); + } + EXPECT_EQ(manager->GetAppName(), u"Manifest test app"); +} + INSTANTIATE_TEST_SUITE_P( All, AppBannerServiceWorkerCriteriaTest,
diff --git a/chrome/browser/banners/test_app_banner_manager_desktop.cc b/chrome/browser/banners/test_app_banner_manager_desktop.cc index 031a929..607c9b2 100644 --- a/chrome/browser/banners/test_app_banner_manager_desktop.cc +++ b/chrome/browser/banners/test_app_banner_manager_desktop.cc
@@ -59,7 +59,13 @@ installable_quit_closure_ = run_loop.QuitClosure(); run_loop.Run(); } - return *installable_; + // Only wait for worker check if it has started after the installable check. + if (waiting_for_worker_) { + base::RunLoop run_loop; + promotable_quit_closure_ = run_loop.QuitClosure(); + run_loop.Run(); + } + return *installable_ && promotable_; } void TestAppBannerManagerDesktop::PrepareDone(base::OnceClosure on_done) { @@ -92,9 +98,22 @@ SetInstallable(result.NoBlockingErrors()); } +void TestAppBannerManagerDesktop::PerformServiceWorkerCheck() { + waiting_for_worker_ = true; + AppBannerManagerDesktop::PerformServiceWorkerCheck(); +} + +void TestAppBannerManagerDesktop::OnDidPerformWorkerCheck( + const InstallableData& result) { + AppBannerManagerDesktop::OnDidPerformWorkerCheck(result); + SetPromotable(result.NoBlockingErrors()); +} + void TestAppBannerManagerDesktop::ResetCurrentPageData() { AppBannerManagerDesktop::ResetCurrentPageData(); installable_.reset(); + promotable_ = false; + waiting_for_worker_ = false; if (tear_down_quit_closure_) std::move(tear_down_quit_closure_).Run(); } @@ -145,6 +164,14 @@ std::move(installable_quit_closure_).Run(); } +void TestAppBannerManagerDesktop::SetPromotable(bool promotable) { + DCHECK(waiting_for_worker_); + waiting_for_worker_ = false; + promotable_ = promotable; + if (promotable_quit_closure_) + std::move(promotable_quit_closure_).Run(); +} + void TestAppBannerManagerDesktop::OnFinished() { if (on_done_) { base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
diff --git a/chrome/browser/banners/test_app_banner_manager_desktop.h b/chrome/browser/banners/test_app_banner_manager_desktop.h index 90f3c37..b109aba 100644 --- a/chrome/browser/banners/test_app_banner_manager_desktop.h +++ b/chrome/browser/banners/test_app_banner_manager_desktop.h
@@ -38,7 +38,7 @@ // Blocks until the existing installability check has been cleared. void WaitForInstallableCheckTearDown(); - // Returns whether the installable check passed. + // Returns whether both the installable and promotable check passed. bool WaitForInstallableCheck(); // Configures a callback to be invoked when the app banner flow finishes. @@ -54,6 +54,8 @@ void OnDidGetManifest(const InstallableData& result) override; void OnDidPerformInstallableWebAppCheck( const InstallableData& result) override; + void PerformServiceWorkerCheck() override; + void OnDidPerformWorkerCheck(const InstallableData& result) override; void ResetCurrentPageData() override; // AppBannerManagerDesktop: @@ -71,11 +73,15 @@ private: void SetInstallable(bool installable); + void SetPromotable(bool promotable); void OnFinished(); absl::optional<bool> installable_; + bool waiting_for_worker_; + bool promotable_; base::OnceClosure tear_down_quit_closure_; base::OnceClosure installable_quit_closure_; + base::OnceClosure promotable_quit_closure_; base::OnceClosure on_done_; base::OnceClosure on_install_; };
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index a21d8ff..6ee1cb7 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1464,8 +1464,6 @@ prefs::kSharedArrayBufferUnrestrictedAccessAllowed, false); #endif registry->RegisterBooleanPref(prefs::kSandboxExternalProtocolBlocked, true); - registry->RegisterBooleanPref(prefs::kDisplayCapturePermissionsPolicyEnabled, - true); registry->RegisterBooleanPref(prefs::kSSLErrorOverrideAllowed, true); registry->RegisterListPref(prefs::kSSLErrorOverrideAllowedForOrigins); registry->RegisterBooleanPref( @@ -2550,11 +2548,6 @@ if (!prefs->GetBoolean(prefs::kSandboxExternalProtocolBlocked)) command_line->AppendSwitch(kDisableSandboxExternalProtocolSwitch); - if (prefs->GetBoolean(prefs::kDisplayCapturePermissionsPolicyEnabled)) { - command_line->AppendSwitch( - switches::kDisplayCapturePermissionsPolicyAllowed); - } - if (prefs->HasPrefPath(prefs::kAllowDinosaurEasterEgg) && !prefs->GetBoolean(prefs::kAllowDinosaurEasterEgg)) { command_line->AppendSwitch( @@ -5845,6 +5838,12 @@ return bluetooth_delegate_.get(); } +content::UsbDelegate* ChromeContentBrowserClient::GetUsbDelegate() { + if (!usb_delegate_) + usb_delegate_ = std::make_unique<ChromeUsbDelegate>(); + return usb_delegate_.get(); +} + #if !BUILDFLAG(IS_ANDROID) void ChromeContentBrowserClient::CreateDeviceInfoService( content::RenderFrameHost* render_frame_host, @@ -5873,12 +5872,6 @@ return hid_delegate_.get(); } -content::UsbDelegate* ChromeContentBrowserClient::GetUsbDelegate() { - if (!usb_delegate_) - usb_delegate_ = std::make_unique<ChromeUsbDelegate>(); - return usb_delegate_.get(); -} - content::DirectSocketsDelegate* ChromeContentBrowserClient::GetDirectSocketsDelegate() { if (!direct_sockets_delegate_) {
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index acea3e0..10b5cf0 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -605,6 +605,7 @@ bool ShouldForceDownloadResource(const GURL& url, const std::string& mime_type) override; content::BluetoothDelegate* GetBluetoothDelegate() override; + content::UsbDelegate* GetUsbDelegate() override; #if !BUILDFLAG(IS_ANDROID) void CreateDeviceInfoService( content::RenderFrameHost* render_frame_host, @@ -615,7 +616,6 @@ override; content::SerialDelegate* GetSerialDelegate() override; content::HidDelegate* GetHidDelegate() override; - content::UsbDelegate* GetUsbDelegate() override; content::DirectSocketsDelegate* GetDirectSocketsDelegate() override; content::WebAuthenticationDelegate* GetWebAuthenticationDelegate() override; std::unique_ptr<content::AuthenticatorRequestClientDelegate>
diff --git a/chrome/browser/commerce/coupons/coupon_service_unittest.cc b/chrome/browser/commerce/coupons/coupon_service_unittest.cc index 6cf8c28e..b504723 100644 --- a/chrome/browser/commerce/coupons/coupon_service_unittest.cc +++ b/chrome/browser/commerce/coupons/coupon_service_unittest.cc
@@ -213,20 +213,8 @@ TestingProfile profile_; raw_ptr<CouponService> service_; raw_ptr<CouponDB> coupon_db_; - // TODO(crbug/1313126): These are only initialized here because - // AutofillOfferData does not have a default ctor, and are overwritten in - // tests. Change these to local-only or to pointers so that this throwaway - // initialization isn't necessary. - autofill::AutofillOfferData coupon_data_a_ = - BuildCouponOfferData(kMockCouponIdA, - kMockMerchantA, - kMockCouponDescriptionA, - kMockCouponCodeA); - autofill::AutofillOfferData coupon_data_b_ = - BuildCouponOfferData(kMockCouponIdB, - kMockMerchantB, - kMockCouponDescriptionB, - kMockCouponCodeB); + autofill::AutofillOfferData coupon_data_a_; + autofill::AutofillOfferData coupon_data_b_; }; TEST_F(CouponServiceTest, TestGetCouponForUrl) {
diff --git a/chrome/browser/download/bubble/download_bubble_controller.cc b/chrome/browser/download/bubble/download_bubble_controller.cc index f1d5464..c3a51e1 100644 --- a/chrome/browser/download/bubble/download_bubble_controller.cc +++ b/chrome/browser/download/bubble/download_bubble_controller.cc
@@ -394,6 +394,8 @@ DownloadUIModel* model, DownloadCommands::Command command) { DownloadCommands commands(model->GetWeakPtr()); + base::UmaHistogramExactLinear("Download.Bubble.ProcessedCommand", command, + DownloadCommands::MAX + 1); switch (command) { case DownloadCommands::KEEP: case DownloadCommands::DISCARD:
diff --git a/chrome/browser/download/download_item_model.cc b/chrome/browser/download/download_item_model.cc index 1101d9c7..3c46941 100644 --- a/chrome/browser/download/download_item_model.cc +++ b/chrome/browser/download/download_item_model.cc
@@ -174,6 +174,19 @@ } #endif +// Enum representing reasons why a download is not preferred to be opened in +// browser. +enum class NotOpenedInBrowserReason { + // The total number of checks. This value should be used as the denominator + // when calculating the percentage of a specific reason below. + TOTAL_DOWNLOAD_CHECKED = 0, + DOWNLOAD_PATH_EMPTY = 1, + NOT_PREFERRED_IN_DELEGATE = 2, + CANNOT_BE_HANDLED_SAFELY = 3, + + kMaxValue = CANNOT_BE_HANDLED_SAFELY +}; + } // namespace // ----------------------------------------------------------------------------- @@ -783,6 +796,7 @@ case DownloadCommands::ALWAYS_OPEN_TYPE: { bool is_checked = IsCommandChecked(download_commands, DownloadCommands::ALWAYS_OPEN_TYPE); + base::UmaHistogramBoolean("Download.SetAlwaysOpenTo", !is_checked); DownloadPrefs* prefs = DownloadPrefs::FromBrowserContext(profile()); #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \ BUILDFLAG(IS_MAC) @@ -1178,6 +1192,24 @@ if (!delegate) return; + // TODO(crbug.com/1372476): Remove this histogram and the associated enum + // after debugging. + base::UmaHistogramEnumeration( + "Download.NotPreferredOpeningInBrowserReasons", + NotOpenedInBrowserReason::TOTAL_DOWNLOAD_CHECKED); + if (target_path.empty()) { + base::UmaHistogramEnumeration( + "Download.NotPreferredOpeningInBrowserReasons", + NotOpenedInBrowserReason::DOWNLOAD_PATH_EMPTY); + } else if (!delegate->IsOpenInBrowserPreferreredForFile(target_path)) { + base::UmaHistogramEnumeration( + "Download.NotPreferredOpeningInBrowserReasons", + NotOpenedInBrowserReason::NOT_PREFERRED_IN_DELEGATE); + } else if (!is_filetype_handled_safely) { + base::UmaHistogramEnumeration( + "Download.NotPreferredOpeningInBrowserReasons", + NotOpenedInBrowserReason::CANNOT_BE_HANDLED_SAFELY); + } if (!target_path.empty() && delegate->IsOpenInBrowserPreferreredForFile(target_path) && is_filetype_handled_safely) {
diff --git a/chrome/browser/download/download_stats.cc b/chrome/browser/download/download_stats.cc index 1351788..330c4862 100644 --- a/chrome/browser/download/download_stats.cc +++ b/chrome/browser/download/download_stats.cc
@@ -8,6 +8,7 @@ #include "base/metrics/user_metrics.h" #include "base/notreached.h" #include "build/build_config.h" +#include "components/download/public/common/download_content.h" #include "components/profile_metrics/browser_profile_type.h" #include "components/safe_browsing/content/browser/download/download_stats.h" @@ -47,10 +48,26 @@ download::DownloadContent download_content = download::DownloadContentFromMimeType( mime_type_string, /*record_content_subcategory=*/false); + if (download_content == download::DownloadContent::DOCUMENT || + download_content == download::DownloadContent::PDF || + download_content == download::DownloadContent::SPREADSHEET || + download_content == download::DownloadContent::TEXT || + download_content == download::DownloadContent::UNRECOGNIZED) { + // TODO(crbug.com/1372476): Remove this histogram after debugging. + base::UmaHistogramEnumeration( + "Download.OpenMethod." + + download::GetDownloadContentString(download_content), + open_method, DOWNLOAD_OPEN_METHOD_LAST_ENTRY); + } base::UmaHistogramEnumeration("Download.Open.ContentType", download_content, download::DownloadContent::MAX); } +void RecordDownloadOpenButtonPressed(bool is_download_completed) { + base::UmaHistogramBoolean("Download.OpenButtonPressed.IsDownloadCompleted", + is_download_completed); +} + void RecordDatabaseAvailability(bool is_available) { base::UmaHistogramBoolean("Download.Database.IsAvailable", is_available); }
diff --git a/chrome/browser/download/download_stats.h b/chrome/browser/download/download_stats.h index c502f00..77feec3 100644 --- a/chrome/browser/download/download_stats.h +++ b/chrome/browser/download/download_stats.h
@@ -136,6 +136,11 @@ void RecordDownloadOpen(ChromeDownloadOpenMethod open_method, const std::string& mime_type_string); +// TODO(crbug.com/1372476): Remove this function after debugging. +// Record that a download open button was pressed, either on download shelf or +// download bubble. +void RecordDownloadOpenButtonPressed(bool is_download_completed); + // Record if the database is available to provide the next download id before // starting all downloads. void RecordDatabaseAvailability(bool is_available);
diff --git a/chrome/browser/download/download_stats_unittest.cc b/chrome/browser/download/download_stats_unittest.cc index 41973e4..8852b73 100644 --- a/chrome/browser/download/download_stats_unittest.cc +++ b/chrome/browser/download/download_stats_unittest.cc
@@ -5,8 +5,10 @@ #include "chrome/browser/download/download_stats.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/metrics/user_action_tester.h" #include "build/build_config.h" #include "chrome/browser/download/download_prompt_status.h" +#include "components/download/public/common/download_content.h" #include "testing/gtest/include/gtest/gtest.h" namespace { @@ -41,4 +43,23 @@ histogram_tester.ExpectTotalCount(kDownloadCancelReasonHistogram, 1); } +TEST(DownloadStatsTest, RecordDownloadOpen) { + base::HistogramTester histogram_tester; + base::UserActionTester user_action_tester; + RecordDownloadOpen(DOWNLOAD_OPEN_METHOD_DEFAULT_BROWSER, "application/pdf"); + + EXPECT_EQ(1, user_action_tester.GetActionCount("Download.Open")); + histogram_tester.ExpectUniqueSample( + "Download.OpenMethod", + /*sample=*/DOWNLOAD_OPEN_METHOD_DEFAULT_BROWSER, + /*expected_bucket_count=*/1); + histogram_tester.ExpectUniqueSample( + "Download.OpenMethod.PDF", + /*sample=*/DOWNLOAD_OPEN_METHOD_DEFAULT_BROWSER, + /*expected_bucket_count=*/1); + histogram_tester.ExpectUniqueSample("Download.Open.ContentType", + /*sample=*/download::DownloadContent::PDF, + /*expected_bucket_count=*/1); +} + } // namespace
diff --git a/chrome/browser/extensions/test_resources_browsertest.cc b/chrome/browser/extensions/test_resources_browsertest.cc index bad1c01f..dd0e363 100644 --- a/chrome/browser/extensions/test_resources_browsertest.cc +++ b/chrome/browser/extensions/test_resources_browsertest.cc
@@ -13,6 +13,9 @@ #include "content/public/test/browser_test_utils.h" #include "extensions/common/extension.h" #include "extensions/common/manifest.h" +#include "extensions/common/manifest_constants.h" +#include "extensions/common/manifest_handlers/externally_connectable.h" +#include "extensions/common/url_pattern.h" #include "extensions/test/test_extension_dir.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -20,6 +23,12 @@ namespace { +constexpr char kComponentExtensionKey[] = + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+uU63MD6T82Ldq5wjrDFn5mGmPnnnj" + "WZBWxYXfpG4kVf0s+p24VkXwTXsxeI12bRm8/ft9sOq0XiLfgQEh5JrVUZqvFlaZYoS+g" + "iZfUqzKFGMLa4uiSMDnvv+byxrqAepKz5G8XX/q5Wm5cvpdjwgiu9z9iM768xJy+Ca/G5" + "qQwIDAQAB"; + // The value set by the script // in chrome/test/data/extensions/test_resources_test/script.js. constexpr int kSentinelValue = 42; @@ -97,11 +106,6 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TestResourcesLoadInComponentExtension) { TestExtensionDir test_dir; - constexpr char kKey[] = - "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+uU63MD6T82Ldq5wjrDFn5mGmPnnnj" - "WZBWxYXfpG4kVf0s+p24VkXwTXsxeI12bRm8/ft9sOq0XiLfgQEh5JrVUZqvFlaZYoS+g" - "iZfUqzKFGMLa4uiSMDnvv+byxrqAepKz5G8XX/q5Wm5cvpdjwgiu9z9iM768xJy+Ca/G5" - "qQwIDAQAB"; constexpr char kManifestTemplate[] = R"({ "name": "Test Extension", @@ -109,7 +113,8 @@ "manifest_version": 2, "key": "%s" })"; - test_dir.WriteManifest(base::StringPrintf(kManifestTemplate, kKey)); + test_dir.WriteManifest( + base::StringPrintf(kManifestTemplate, kComponentExtensionKey)); constexpr char kPageHtml[] = R"(<html> @@ -131,6 +136,60 @@ EXPECT_EQ(kSentinelValue, *sentinel); } +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, + LoadComponentExtensionUpdateWithManifestChanges) { + TestExtensionDir test_dir; + + static constexpr char test_domain1[] = "http://*.domain1.com/*"; + static constexpr char test_domain2[] = "http://*.domain2.com/*"; + + static constexpr char kManifestTemplate[] = + R"({ + "name": "Test Component Extension", + "version": "1", + "description": "", + "manifest_version": 3, + "key": "%s", + "externally_connectable": { + "matches": [ + "%s" + ] + } + })"; + + test_dir.WriteManifest(base::StringPrintf( + kManifestTemplate, kComponentExtensionKey, test_domain1)); + + const Extension* extension1 = + LoadExtensionAsComponent(test_dir.UnpackedPath()); + ASSERT_TRUE(extension1); + EXPECT_EQ(mojom::ManifestLocation::kComponent, extension1->location()); + + ExternallyConnectableInfo* info1 = static_cast<ExternallyConnectableInfo*>( + extension1->GetManifestData(manifest_keys::kExternallyConnectable)); + ASSERT_TRUE(info1); + EXPECT_EQ(1ul, info1->matches.size()); + + EXPECT_EQ(URLPattern(URLPattern::SCHEME_ALL, test_domain1), + *info1->matches.begin()); + + // Update the manifest and load the extension again. + test_dir.WriteManifest(base::StringPrintf( + kManifestTemplate, kComponentExtensionKey, test_domain2)); + const Extension* extension2 = + LoadExtensionAsComponent(test_dir.UnpackedPath()); + ASSERT_TRUE(extension2); + EXPECT_EQ(mojom::ManifestLocation::kComponent, extension2->location()); + + ExternallyConnectableInfo* info2 = static_cast<ExternallyConnectableInfo*>( + extension2->GetManifestData(manifest_keys::kExternallyConnectable)); + ASSERT_TRUE(info2); + EXPECT_EQ(1ul, info2->matches.size()); + + EXPECT_EQ(URLPattern(URLPattern::SCHEME_ALL, test_domain2), + *info2->matches.begin()); +} + // Tests that resources from _test_resources can be loaded from different // directories. Though the default is chrome/test/data/extensions, a test class // can specify its own.
diff --git a/chrome/browser/feed/android/BUILD.gn b/chrome/browser/feed/android/BUILD.gn index 80534798..0e96b84 100644 --- a/chrome/browser/feed/android/BUILD.gn +++ b/chrome/browser/feed/android/BUILD.gn
@@ -94,7 +94,6 @@ "//build/android:build_java", "//chrome/android:base_module_java", "//chrome/browser/browser_controls/android:java", - "//chrome/browser/creator/android:java", "//chrome/browser/feature_engagement:java", "//chrome/browser/feedback/android:java", "//chrome/browser/flags:java", @@ -312,7 +311,6 @@ "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support", - "//chrome/browser/creator/android:java", "//chrome/browser/feature_engagement:java", "//chrome/browser/feedback/android:java", "//chrome/browser/flags:java",
diff --git a/chrome/browser/first_party_sets/first_party_sets_policy_service_unittest.cc b/chrome/browser/first_party_sets/first_party_sets_policy_service_unittest.cc index 0b3d4fbc..a440b59 100644 --- a/chrome/browser/first_party_sets/first_party_sets_policy_service_unittest.cc +++ b/chrome/browser/first_party_sets/first_party_sets_policy_service_unittest.cc
@@ -75,18 +75,13 @@ FirstPartySetsPolicyServiceFactory::GetForBrowserContext(&profile); service->AddRemoteAccessDelegate(std::move(mock_delegate_remote_)); - // Ensure NotifyReady is called with the empty config. - base::RunLoop loop; - network::mojom::FirstPartySetsReadyEventPtr actual; - EXPECT_CALL(mock_delegate, NotifyReady(_)) - .WillOnce([&](network::mojom::FirstPartySetsReadyEventPtr ptr) { - actual = std::move(ptr); - loop.Quit(); - }); - loop.Run(); + net::FirstPartySetsContextConfig config; - EXPECT_FALSE(actual.is_null()); - EXPECT_EQ(actual->config, net::FirstPartySetsContextConfig()); + // Ensure NotifyReady is called with the empty config. + EXPECT_CALL(mock_delegate, NotifyReady(CarryingConfig(std::ref(config)))) + .Times(1); + + env().RunUntilIdle(); } TEST_F(DefaultFirstPartySetsPolicyServiceTest, GuestProfiles) { @@ -100,18 +95,13 @@ FirstPartySetsPolicyServiceFactory::GetForBrowserContext(profile.get()); service->AddRemoteAccessDelegate(std::move(mock_delegate_remote_)); - // Ensure NotifyReady is called with the empty config. - base::RunLoop loop; - network::mojom::FirstPartySetsReadyEventPtr actual; - EXPECT_CALL(mock_delegate, NotifyReady(_)) - .WillOnce([&](network::mojom::FirstPartySetsReadyEventPtr ptr) { - actual = std::move(ptr); - loop.Quit(); - }); - loop.Run(); + net::FirstPartySetsContextConfig config; - EXPECT_FALSE(actual.is_null()); - EXPECT_EQ(actual->config, net::FirstPartySetsContextConfig()); + // Ensure NotifyReady is called with the empty config. + EXPECT_CALL(mock_delegate, NotifyReady(CarryingConfig(std::ref(config)))) + .Times(1); + + env().RunUntilIdle(); } TEST_F(DefaultFirstPartySetsPolicyServiceTest, EnabledForLegitProfile) { @@ -122,18 +112,13 @@ FirstPartySetsPolicyServiceFactory::GetForBrowserContext(&profile); service->AddRemoteAccessDelegate(std::move(mock_delegate_remote_)); - // Ensure NotifyReady is called with the empty config. - base::RunLoop loop; - network::mojom::FirstPartySetsReadyEventPtr actual; - EXPECT_CALL(mock_delegate, NotifyReady(_)) - .WillOnce([&](network::mojom::FirstPartySetsReadyEventPtr ptr) { - actual = std::move(ptr); - loop.Quit(); - }); - loop.Run(); + net::FirstPartySetsContextConfig config; - EXPECT_FALSE(actual.is_null()); - EXPECT_EQ(actual->config, net::FirstPartySetsContextConfig()); + // Ensure NotifyReady is called with the empty config. + EXPECT_CALL(mock_delegate, NotifyReady(CarryingConfig(std::ref(config)))) + .Times(1); + + env().RunUntilIdle(); } class FirstPartySetsPolicyServiceTest
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index e2e2368..1b29593 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -3088,6 +3088,11 @@ "expiry_milestone": 114 }, { + "name": "enable-tab-strip-redesign", + "owners": [ "zheliooo", "skavuluru", "nemco", "clank-app-team@google.com" ], + "expiry_milestone": 120 + }, + { "name": "enable-tab-switcher-on-return", "owners": [ "memex-team@google.com" ], "expiry_milestone": 115 @@ -4802,6 +4807,11 @@ "expiry_milestone": 108 }, { + "name": "ntp-desktop-lens", + "owners": [ "yowakita", "tiborg" ], + "expiry_milestone": 112 + }, + { "name": "ntp-drive-module", "owners": [ "mahmadi", "tiborg" ], "expiry_milestone": 108 @@ -5579,7 +5589,7 @@ "expiry_milestone": 108 }, { - "name": "private-aggregation-debug-mode", + "name": "private-aggregation-developer-mode", "owners": [ "//content/browser/private_aggregation/OWNERS" ],
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index ce58765b..9531085 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -2480,12 +2480,12 @@ "Fenced Frames, Shared Storage, Private Aggregation, and their associated " "features."; -const char kPrivateAggregationDebugModeName[] = - "Private Aggregation debug mode"; -const char kPrivateAggregationDebugModeDescription[] = - "Enables debug mode for the Private Aggregation API. This removes all " - "reporting delays. Only works if the Private Aggregation API is already " - "enabled."; +const char kPrivateAggregationDeveloperModeName[] = + "Private Aggregation developer mode"; +const char kPrivateAggregationDeveloperModeDescription[] = + "Enables the developer mode for the Private Aggregation API. This removes " + "all reporting delays. Only works if the Private Aggregation API is " + "already enabled."; const char kProminentDarkModeActiveTabTitleName[] = "Prominent Dark Mode Active Tab Titles"; @@ -4185,6 +4185,11 @@ "Enabled single or multi-column Discover feed based on screen width on " "Android."; +const char kTabStripRedesignAndroidName[] = "Tab Strip Redesign Android."; +const char kTabStripRedesignAndroidDescription[] = + "Enabled Tab Strip Redesign on Android - A visual redesign of Clank Tab " + "Strip that is consistent with GM3."; + const char kTouchDragAndContextMenuName[] = "Simultaneous touch drag and context menu"; const char kTouchDragAndContextMenuDescription[] = @@ -4377,6 +4382,10 @@ const char kNtpChromeCartModuleDescription[] = "Shows the chrome cart module on the New Tab Page."; +const char kNtpDesktopLensName[] = "NTP Desktop Lens Entrypoint"; +const char kNtpDesktopLensDescription[] = + "Shows a Lens entrypoint and upload dialog in desktop NTP when enabled."; + const char kNtpDriveModuleName[] = "NTP Drive Module"; const char kNtpDriveModuleDescription[] = "Shows the Google Drive module on the New Tab Page";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index fe060a6..ed09cb1 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1385,8 +1385,8 @@ extern const char kPrivacySandboxAdsAPIsOverrideName[]; extern const char kPrivacySandboxAdsAPIsOverrideDescription[]; -extern const char kPrivateAggregationDebugModeName[]; -extern const char kPrivateAggregationDebugModeDescription[]; +extern const char kPrivateAggregationDeveloperModeName[]; +extern const char kPrivateAggregationDeveloperModeDescription[]; extern const char kProminentDarkModeActiveTabTitleName[]; extern const char kProminentDarkModeActiveTabTitleDescription[]; @@ -1656,6 +1656,9 @@ extern const char kDiscoverFeedMultiColumnAndroidName[]; extern const char kDiscoverFeedMultiColumnAndroidDescription[]; +extern const char kTabStripRedesignAndroidName[]; +extern const char kTabStripRedesignAndroidDescription[]; + extern const char kTailoredSecurityDesktopNoticeName[]; extern const char kTailoredSecurityDesktopNoticeDescription[]; @@ -2490,6 +2493,9 @@ extern const char kNtpChromeCartModuleName[]; extern const char kNtpChromeCartModuleDescription[]; +extern const char kNtpDesktopLensName[]; +extern const char kNtpDesktopLensDescription[]; + extern const char kNtpDriveModuleName[]; extern const char kNtpDriveModuleDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index e2cf8d4..28445c7 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -305,6 +305,7 @@ &kTabGroupsUiImprovementsAndroid, &kTabGroupsForTablets, &kDiscoverFeedMultiColumn, + &kTabStripRedesign, &kTabGridLayoutAndroid, &kTabReparenting, &kTabSelectionEditorV2, @@ -387,6 +388,7 @@ &password_manager::features::kTouchToFillPasswordSubmission, &password_manager::features::kUnifiedCredentialManagerDryRun, &password_manager::features::kUnifiedPasswordManagerAndroid, + &password_manager::features::kUnifiedPasswordManagerAndroidBranding, &password_manager::features::kUnifiedPasswordManagerErrorMessages, &password_manager::features::kPasswordEditDialogWithDetails, &privacy_sandbox::kPrivacySandboxFirstPartySetsUI, @@ -1023,6 +1025,10 @@ "DiscoverFeedMultiColumn", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kTabStripRedesign, + "TabStripRedesign", + base::FEATURE_DISABLED_BY_DEFAULT); + BASE_FEATURE(kTabSwitcherOnReturn, "TabSwitcherOnReturn", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index e952cd1..402124ba 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -166,6 +166,7 @@ BASE_DECLARE_FEATURE(kTabSelectionEditorV2); BASE_DECLARE_FEATURE(kTabStripImprovements); BASE_DECLARE_FEATURE(kDiscoverFeedMultiColumn); +BASE_DECLARE_FEATURE(kTabStripRedesign); BASE_DECLARE_FEATURE(kTabSwitcherOnReturn); BASE_DECLARE_FEATURE(kTabToGTSAnimation); BASE_DECLARE_FEATURE(kTestDefaultDisabled);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 15f1c95..8a00aea 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -555,6 +555,7 @@ "SplitCacheByNetworkIsolationKey"; public static final String START_SURFACE_ANDROID = "StartSurfaceAndroid"; public static final String FEED_MULTI_COLUMN = "DiscoverFeedMultiColumn"; + public static final String TAB_STRIP_REDESIGN = "TabStripRedesign"; public static final String FEED_POSITION_ANDROID = "FeedPositionAndroid"; public static final String SEARCH_RESUMPTION_MODULE_ANDROID = "SearchResumptionModuleAndroid"; public static final String START_SURFACE_RETURN_TIME = "StartSurfaceReturnTime"; @@ -602,6 +603,8 @@ public static final String UNIFIED_CREDENTIAL_MANAGER_DRY_RUN = "UnifiedCredentialManagerDryRun"; public static final String UNIFIED_PASSWORD_MANAGER_ANDROID = "UnifiedPasswordManagerAndroid"; + public static final String UNIFIED_PASSWORD_MANAGER_ANDROID_BRANDING = + "UnifiedPasswordManagerAndroidBranding"; public static final String UNIFIED_PASSWORD_MANAGER_ERROR_MESSAGES = "UnifiedPasswordManagerErrorMessages"; public static final String UPCOMING_SHARING_FEATURES = "UpcomingSharingFeatures"; @@ -738,6 +741,7 @@ new CachedFlag(TAB_STRIP_IMPROVEMENTS, true); public static final CachedFlag sTabToGTSAnimation = new CachedFlag(TAB_TO_GTS_ANIMATION, true); public static final CachedFlag sDiscoverMultiColumn = new CachedFlag(FEED_MULTI_COLUMN, false); + public static final CachedFlag sTabStripRedesign = new CachedFlag(TAB_STRIP_REDESIGN, false); public static final CachedFlag sTestDefaultDisabled = new CachedFlag(TEST_DEFAULT_DISABLED, false); public static final CachedFlag sTestDefaultEnabled = new CachedFlag(TEST_DEFAULT_ENABLED, true);
diff --git a/chrome/browser/media/cast_mirroring_service_host.cc b/chrome/browser/media/cast_mirroring_service_host.cc index b3ee46f..9e9a235 100644 --- a/chrome/browser/media/cast_mirroring_service_host.cc +++ b/chrome/browser/media/cast_mirroring_service_host.cc
@@ -148,27 +148,6 @@ // static void CastMirroringServiceHost::GetForDesktop( - content::WebContents* initiator_contents, - const std::string& desktop_stream_id, - mojo::PendingReceiver<mojom::MirroringServiceHost> receiver) { - DCHECK(!desktop_stream_id.empty()); - if (initiator_contents) { - std::string original_extension_name; - const content::DesktopMediaID media_id = - content::DesktopStreamsRegistry::GetInstance()->RequestMediaForStreamId( - desktop_stream_id, - initiator_contents->GetPrimaryMainFrame()->GetProcess()->GetID(), - initiator_contents->GetPrimaryMainFrame()->GetRoutingID(), - url::Origin::Create(initiator_contents->GetVisibleURL()), - &original_extension_name, content::kRegistryStreamTypeDesktop); - mojo::MakeSelfOwnedReceiver( - std::make_unique<CastMirroringServiceHost>(media_id), - std::move(receiver)); - } -} - -// static -void CastMirroringServiceHost::GetForDesktop( const content::DesktopMediaID& media_id, mojo::PendingReceiver<mojom::MirroringServiceHost> receiver) { mojo::MakeSelfOwnedReceiver(
diff --git a/chrome/browser/media/cast_mirroring_service_host.h b/chrome/browser/media/cast_mirroring_service_host.h index 80e46ef..af4ccb01 100644 --- a/chrome/browser/media/cast_mirroring_service_host.h +++ b/chrome/browser/media/cast_mirroring_service_host.h
@@ -53,13 +53,6 @@ content::WebContents* target_contents, mojo::PendingReceiver<mojom::MirroringServiceHost> receiver); - // TODO(crbug.com/809249): Remove when the extension-based implementation of - // the Cast MRP is removed. - static void GetForDesktop( - content::WebContents* initiator_contents, - const std::string& desktop_stream_id, - mojo::PendingReceiver<mojom::MirroringServiceHost> receiver); - static void GetForDesktop( const content::DesktopMediaID& media_id, mojo::PendingReceiver<mojom::MirroringServiceHost> receiver);
diff --git a/chrome/browser/media/webrtc/display_media_access_handler.cc b/chrome/browser/media/webrtc/display_media_access_handler.cc index 4657aa82..9cb34fd8 100644 --- a/chrome/browser/media/webrtc/display_media_access_handler.cc +++ b/chrome/browser/media/webrtc/display_media_access_handler.cc
@@ -179,25 +179,18 @@ return; } - Profile* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); - // The kDisplayCapturePermissionsPolicyEnabled preference controls whether - // the display-capture permissions-policy is applied or skipped. - if (profile->GetPrefs()->GetBoolean( - prefs::kDisplayCapturePermissionsPolicyEnabled)) { - // If the display-capture permissions-policy disallows capture, the render - // process was not supposed to send this message. - if (!rfh->IsFeatureEnabled( - blink::mojom::PermissionsPolicyFeature::kDisplayCapture)) { - bad_message::ReceivedBadMessage( - rfh->GetProcess(), bad_message::BadMessageReason:: - RFH_DISPLAY_CAPTURE_PERMISSION_MISSING); - std::move(callback).Run( - blink::mojom::StreamDevicesSet(), - blink::mojom::MediaStreamRequestResult::PERMISSION_DENIED, - /*ui=*/nullptr); - return; - } + // If the display-capture permissions-policy disallows capture, the render + // process was not supposed to send this message. + if (!rfh->IsFeatureEnabled( + blink::mojom::PermissionsPolicyFeature::kDisplayCapture)) { + bad_message::ReceivedBadMessage( + rfh->GetProcess(), bad_message::BadMessageReason:: + RFH_DISPLAY_CAPTURE_PERMISSION_MISSING); + std::move(callback).Run( + blink::mojom::StreamDevicesSet(), + blink::mojom::MediaStreamRequestResult::PERMISSION_DENIED, + /*ui=*/nullptr); + return; } }
diff --git a/chrome/browser/metrics/power/power_metrics_reporter.h b/chrome/browser/metrics/power/power_metrics_reporter.h index 16c242a..973e4bcf 100644 --- a/chrome/browser/metrics/power/power_metrics_reporter.h +++ b/chrome/browser/metrics/power/power_metrics_reporter.h
@@ -17,6 +17,7 @@ #include "chrome/browser/metrics/power/usage_scenario.h" #include "chrome/browser/metrics/usage_scenario/usage_scenario_data_store.h" #include "chrome/browser/metrics/usage_scenario/usage_scenario_tracker.h" +#include "components/performance_manager/public/power/battery_level_provider_creator.h" #include "third_party/abseil-cpp/absl/types/optional.h" #if BUILDFLAG(IS_MAC) @@ -56,7 +57,7 @@ UsageScenarioDataStore* short_usage_scenario_data_store = nullptr, UsageScenarioDataStore* long_usage_scenario_data_store = nullptr, std::unique_ptr<base::BatteryLevelProvider> battery_level_provider = - base::BatteryLevelProvider::Create() + performance_manager::power::CreateBatteryLevelProvider() #if BUILDFLAG(IS_MAC) , std::unique_ptr<CoalitionResourceUsageProvider>
diff --git a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc index 3472441..92560ce 100644 --- a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc +++ b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
@@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/command_line.h" -#include "chrome/browser/page_load_metrics/integration_tests/metric_integration_test.h" +#include <algorithm> +#include <memory> +#include "base/command_line.h" #include "base/feature_list.h" #include "base/json/json_string_value_serializer.h" #include "base/strings/strcat.h" @@ -12,6 +13,7 @@ #include "base/test/trace_event_analyzer.h" #include "build/build_config.h" #include "cc/base/switches.h" +#include "chrome/browser/page_load_metrics/integration_tests/metric_integration_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/page_load_metrics/browser/page_load_metrics_test_waiter.h" #include "components/paint_preview/buildflags/buildflags.h" @@ -40,7 +42,8 @@ namespace { -void ValidateCandidate(int expected_size, const TraceEvent& event) { +void ValidateTraceEventHasCorrectCandidateSize(int expected_size, + const TraceEvent& event) { ASSERT_TRUE(event.HasDictArg("data")); base::Value::Dict data = event.GetKnownArgAsDict("data"); @@ -66,21 +69,6 @@ return GetCandidateIndex(*lhs) < GetCandidateIndex(*rhs); } -void ValidateTraceEvents(std::unique_ptr<TraceAnalyzer> analyzer) { - TraceEventVector events; - analyzer->FindEvents(Query::EventNameIs("largestContentfulPaint::Candidate"), - &events); - EXPECT_EQ(3ul, events.size()); - std::sort(events.begin(), events.end(), compare_candidate_index); - - // LCP_0 uses green-16x16.png, of size 16 x 16. - ValidateCandidate(16 * 16, *events[0]); - // LCP_1 uses blue96x96.png, of size 96 x 96. - ValidateCandidate(96 * 96, *events[1]); - // LCP_2 uses green-256x256.png, of size 16 x 16. - ValidateCandidate(256 * 256, *events[2]); -} - } // namespace IN_PROC_BROWSER_TEST_F(MetricIntegrationTest, LargestContentfulPaint) { @@ -138,7 +126,25 @@ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("about:blank"))); // Check Trace Events. - ValidateTraceEvents(StopTracingAndAnalyze()); + std::unique_ptr<TraceAnalyzer> trace_analyzer = StopTracingAndAnalyze(); + TraceEventVector candidate_events; + trace_analyzer->FindEvents( + Query::EventNameIs("largestContentfulPaint::Candidate"), + &candidate_events); + EXPECT_EQ(3ul, candidate_events.size()); + std::sort(candidate_events.begin(), candidate_events.end(), + compare_candidate_index); + + // LCP_0 uses green-16x16.png, of size 16 x 16. + ValidateTraceEventHasCorrectCandidateSize(16 * 16, *candidate_events[0]); + // LCP_1 uses blue96x96.png, of size 96 x 96. + ValidateTraceEventHasCorrectCandidateSize(96 * 96, *candidate_events[1]); + // LCP_2 uses green-256x256.png, of size 16 x 16. + ValidateTraceEventHasCorrectCandidateSize(256 * 256, *candidate_events[2]); + + ExpectMetricInLastUKMUpdateTraceEventNear( + *trace_analyzer, "latest_largest_contentful_paint_ms", + lcp_timestamps[2].value(), 1.2); // Check UKM. // Since UKM rounds to an integer while the JS API returns a coarsened double, @@ -181,7 +187,6 @@ IN_PROC_BROWSER_TEST_F(MetricIntegrationTest, LargestContentfulPaintPaintPreview) { Start(); - StartTracing({"loading"}); Load("/largest_contentful_paint_paint_preview.html"); content::EvalJsResult lcp_before_paint_preview = @@ -252,6 +257,8 @@ // Navigate away to force metrics recording. ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("about:blank"))); + std::unique_ptr<TraceAnalyzer> trace_analyzer = StopTracingAndAnalyze(); + // |lcpTime| is computed from 3 different JS timestamps, so use an epsilon of // 2 to account for coarsening and UKM integer rounding. ExpectUKMPageLoadMetricNear( @@ -259,6 +266,9 @@ 2.0); ExpectUniqueUMAPageLoadMetricNear( "PageLoad.PaintTiming.NavigationToLargestContentfulPaint2", lcpTime); + + ExpectMetricInLastUKMUpdateTraceEventNear( + *trace_analyzer, "latest_largest_contentful_paint_ms", lcpTime, 2.0); } class IsAnimatedLCPTest : public MetricIntegrationTest {
diff --git a/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.cc b/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.cc index 7a68ce36..9566f96 100644 --- a/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.cc +++ b/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.cc
@@ -27,7 +27,10 @@ using net::test_server::BasicHttpResponse; using net::test_server::HttpRequest; using net::test_server::HttpResponse; +using trace_analyzer::Query; using trace_analyzer::TraceAnalyzer; +using trace_analyzer::TraceEvent; +using trace_analyzer::TraceEventVector; using ukm::TestUkmRecorder; using ukm::builders::PageLoad; using ukm::mojom::UkmEntry; @@ -194,3 +197,23 @@ << "The sample for " << metric_name.data() << " is not near the expected value!"; } + +void MetricIntegrationTest::ExpectMetricInLastUKMUpdateTraceEventNear( + TraceAnalyzer& trace_analyzer, + base::StringPiece metric_name, + double expected_value, + double epsilon) { + TraceEventVector ukm_update_events; + trace_analyzer.FindEvents(Query::EventNameIs("UkmPageLoadTimingUpdate"), + &ukm_update_events); + ASSERT_GT(ukm_update_events.size(), 0ul); + + const TraceEvent* last_update_event = ukm_update_events.back(); + + base::Value::Dict arg_dict; + last_update_event->GetArgAsDict("ukm_page_load_timing_update", &arg_dict); + absl::optional<double> metric_value = arg_dict.FindDouble(metric_name); + ASSERT_TRUE(metric_value.has_value()); + + EXPECT_NEAR(expected_value, *metric_value, epsilon); +}
diff --git a/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.h b/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.h index ad3c421b..e5be5b8 100644 --- a/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.h +++ b/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.h
@@ -107,6 +107,15 @@ void ExpectUniqueUMAPageLoadMetricNear(base::StringPiece metric_name, double expected_value); + // Checks that the value of |metric_name| in the latest timing update trace + // event emitted by UkmPageLoadMetricsObserver is within |epsilon| of + // |expected_value|. + void ExpectMetricInLastUKMUpdateTraceEventNear( + trace_analyzer::TraceAnalyzer& trace_analyzer, + base::StringPiece metric_name, + double expected_value, + double epsilon); + private: static std::unique_ptr<net::test_server::HttpResponse> HandleRequest( const std::string& relative_url,
diff --git a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc index 0a520ae..d6c6a906 100644 --- a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc
@@ -14,6 +14,7 @@ #include "base/metrics/histogram_macros.h" #include "base/trace_event/common/trace_event_common.h" #include "base/trace_event/trace_event.h" +#include "base/trace_event/typed_macros.h" #include "cc/metrics/ukm_smoothness_data.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/content_settings/cookie_settings_factory.h" @@ -596,6 +597,7 @@ return; DCHECK(timing.paint_timing->first_contentful_paint.has_value()); + first_contentful_paint_ = timing.paint_timing->first_contentful_paint.value(); ukm::builders::PageLoad builder(GetDelegate().GetPageUkmSourceId()); builder.SetPaintTiming_NavigationToFirstContentfulPaint( @@ -615,6 +617,13 @@ builder.Record(ukm::UkmRecorder::Get()); } +const page_load_metrics::ContentfulPaintTimingInfo& +UkmPageLoadMetricsObserver::GetCoreWebVitalsLcpTimingInfo() { + return GetDelegate() + .GetLargestContentfulPaintHandler() + .MergeMainFrameAndSubframes(); +} + void UkmPageLoadMetricsObserver::RecordTimingMetrics( const page_load_metrics::mojom::PageLoadTiming& timing) { ukm::builders::PageLoad builder(GetDelegate().GetPageUkmSourceId()); @@ -664,27 +673,25 @@ builder.SetPaintTiming_NavigationToLargestContentfulPaint2_MainFrame( main_frame_largest_contentful_paint.Time().value().InMilliseconds()); } - const page_load_metrics::ContentfulPaintTimingInfo& - all_frames_largest_contentful_paint = - GetDelegate() - .GetLargestContentfulPaintHandler() - .MergeMainFrameAndSubframes(); - if (all_frames_largest_contentful_paint.ContainsValidTime() && + + const page_load_metrics::ContentfulPaintTimingInfo& cwv_lcp_timing_info = + GetCoreWebVitalsLcpTimingInfo(); + if (cwv_lcp_timing_info.ContainsValidTime() && WasStartedInForegroundOptionalEventInForeground( - all_frames_largest_contentful_paint.Time(), GetDelegate())) { + cwv_lcp_timing_info.Time(), GetDelegate())) { builder.SetPaintTiming_NavigationToLargestContentfulPaint2( - all_frames_largest_contentful_paint.Time().value().InMilliseconds()); + cwv_lcp_timing_info.Time().value().InMilliseconds()); builder.SetPaintTiming_LargestContentfulPaintType( - LargestContentfulPaintTypeToUKMFlags( - all_frames_largest_contentful_paint.Type())); - if (all_frames_largest_contentful_paint.TextOrImage() == + LargestContentfulPaintTypeToUKMFlags(cwv_lcp_timing_info.Type())); + if (cwv_lcp_timing_info.TextOrImage() == page_load_metrics::ContentfulPaintTimingInfo:: LargestContentTextOrImage::kImage) { builder.SetPaintTiming_LargestContentfulPaintBPP( - CalculateLCPEntropyBucket( - all_frames_largest_contentful_paint.ImageBPP())); + CalculateLCPEntropyBucket(cwv_lcp_timing_info.ImageBPP())); } } + RecordInternalTimingMetrics(cwv_lcp_timing_info); + const page_load_metrics::ContentfulPaintTimingInfo& cross_site_sub_frame_largest_contentful_paint = GetDelegate() @@ -700,7 +707,6 @@ .value() .InMilliseconds()); } - RecordInternalTimingMetrics(all_frames_largest_contentful_paint); if (timing.interactive_timing->first_input_delay && WasStartedInForegroundOptionalEventInForeground( timing.interactive_timing->first_input_timestamp, GetDelegate())) { @@ -994,6 +1000,17 @@ } } +absl::optional<float> UkmPageLoadMetricsObserver::GetCoreWebVitalsCLS() { + const page_load_metrics::NormalizedCLSData& normalized_cls_data = + GetDelegate().GetNormalizedCLSData( + page_load_metrics::PageLoadMetricsObserverDelegate::BfcacheStrategy:: + ACCUMULATE); + if (!normalized_cls_data.data_tainted) { + return normalized_cls_data.session_windows_gap1000ms_max5000ms_max_cls; + } + return absl::nullopt; +} + void UkmPageLoadMetricsObserver::ReportLayoutStability() { // Don't report CLS if we were never in the foreground. if (last_time_shown_.is_null()) @@ -1017,25 +1034,21 @@ GetDelegate() .GetMainFrameRenderData() .layout_shift_score_before_input_or_scroll)); - // Record CLS normalization UKM. - const page_load_metrics::NormalizedCLSData& normalized_cls_data = - GetDelegate().GetNormalizedCLSData( - page_load_metrics::PageLoadMetricsObserverDelegate::BfcacheStrategy:: - ACCUMULATE); - if (!normalized_cls_data.data_tainted) { - const float max_cls = - normalized_cls_data.session_windows_gap1000ms_max5000ms_max_cls; + + const absl::optional<float> cwv_cls_value = GetCoreWebVitalsCLS(); + if (cwv_cls_value.has_value()) { builder .SetLayoutInstability_MaxCumulativeShiftScore_SessionWindow_Gap1000ms_Max5000ms( - page_load_metrics::LayoutShiftUkmValue(max_cls)); + page_load_metrics::LayoutShiftUkmValue(*cwv_cls_value)); base::UmaHistogramCounts100( "PageLoad.LayoutInstability.MaxCumulativeShiftScore.SessionWindow." "Gap1000ms.Max5000ms", - page_load_metrics::LayoutShiftUmaValue(max_cls)); + page_load_metrics::LayoutShiftUmaValue(*cwv_cls_value)); base::UmaHistogramCustomCounts( "PageLoad.LayoutInstability.MaxCumulativeShiftScore.SessionWindow." "Gap1000ms.Max5000ms2", - page_load_metrics::LayoutShiftUmaValue10000(max_cls), 1, 24000, 50); + page_load_metrics::LayoutShiftUmaValue10000(*cwv_cls_value), 1, 24000, + 50); // The pseudo metric of PageLoad.LayoutInstability.MaxCumulativeShiftScore. // SessionWindow.Gap1000ms.Max5000ms2. // Only used to assess field trial data quality. @@ -1043,7 +1056,7 @@ "UMA.Pseudo.PageLoad.LayoutInstability.MaxCumulativeShiftScore." "SessionWindow.Gap1000ms.Max5000ms2", page_load_metrics::LayoutShiftUmaValue10000( - metrics::GetPseudoMetricsSample(max_cls)), + metrics::GetPseudoMetricsSample(*cwv_cls_value)), 1, 24000, 50); } builder.Record(ukm::UkmRecorder::Get()); @@ -1439,6 +1452,39 @@ TRACE_EVENT_CATEGORY_GROUP_ENABLED("loading", &loading_enabled); if (!loading_enabled) return; + + TRACE_EVENT_INSTANT( + "loading", "UkmPageLoadTimingUpdate", [&](perfetto::EventContext ctx) { + auto* event = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>(); + auto* data = event->set_ukm_page_load_timing_update(); + if (first_contentful_paint_.has_value()) { + data->set_first_contentful_paint_ms( + first_contentful_paint_.value().InMillisecondsF()); + } + data->set_ukm_source_id( + static_cast<int64_t>(GetDelegate().GetPageUkmSourceId())); + data->set_latest_url(GetDelegate().GetUrl().spec()); + + const absl::optional<float> cwv_cls_value = GetCoreWebVitalsCLS(); + if (cwv_cls_value.has_value()) { + data->set_latest_cumulative_layout_shift(*cwv_cls_value); + } + const page_load_metrics::ContentfulPaintTimingInfo& + cwv_lcp_timing_info = GetCoreWebVitalsLcpTimingInfo(); + if (cwv_lcp_timing_info.ContainsValidTime() && + WasStartedInForegroundOptionalEventInForeground( + cwv_lcp_timing_info.Time(), GetDelegate())) { + data->set_latest_largest_contentful_paint_ms( + cwv_lcp_timing_info.Time().value().InMillisecondsF()); + } + }); + + // The ones below are old trace events which should not be necessary given the + // UkmPageLoadTimingUpdate event above, but they may be used in + // devtools/lighthouse in addition to the old catapult loadingMetric. They can + // be removed once we verify that the consumers of these trace events have + // been updated. + const page_load_metrics::ContentfulPaintTimingInfo& paint = GetDelegate() .GetLargestContentfulPaintHandler()
diff --git a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.h index 80cccb0..eb3a33ae 100644 --- a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.h
@@ -139,6 +139,16 @@ void ReportLayoutStability(); + // Returns the current Core Web Vital definition of Cumulative Layout Shift. + // Returns nullopt if current value should not be reported to UKM. + absl::optional<float> GetCoreWebVitalsCLS(); + + // Returns the current Core Web Vital definition of Largest Contentful Paint. + // The caller needs to check whether the value should be reported to UKM based + // on when the page was backgrounded and other validations. + const page_load_metrics::ContentfulPaintTimingInfo& + GetCoreWebVitalsLcpTimingInfo(); + void RecordAbortMetrics( const page_load_metrics::mojom::PageLoadTiming& timing, base::TimeTicks page_end_time, @@ -250,6 +260,9 @@ content::NavigationHandleTiming navigation_handle_timing_; absl::optional<net::LoadTimingInfo> main_frame_timing_; + // First contentful paint as reported in OnFirstContentfulPaintInPage. + absl::optional<base::TimeDelta> first_contentful_paint_; + // How the SiteInstance for the committed page was assigned a renderer. absl::optional<content::SiteInstanceProcessAssignment> render_process_assignment_;
diff --git a/chrome/browser/password_manager/android/generated_password_saved_message_delegate.cc b/chrome/browser/password_manager/android/generated_password_saved_message_delegate.cc index 95e328f..05c8856 100644 --- a/chrome/browser/password_manager/android/generated_password_saved_message_delegate.cc +++ b/chrome/browser/password_manager/android/generated_password_saved_message_delegate.cc
@@ -35,7 +35,7 @@ void GeneratedPasswordSavedMessageDelegate::ShowPrompt( content::WebContents* web_contents, std::unique_ptr<password_manager::PasswordFormManagerForUI> saved_form) { - using password_manager::features::UsesUnifiedPasswordManagerUi; + using password_manager::features::UsesUnifiedPasswordManagerBranding; message_ = std::make_unique<messages::MessageWrapper>( messages::MessageIdentifier::GENERATED_PASSWORD_SAVED, @@ -48,7 +48,7 @@ l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_CONFIRM_SAVED_TITLE)); std::u16string description; - if (UsesUnifiedPasswordManagerUi()) { + if (UsesUnifiedPasswordManagerBranding()) { description = l10n_util::GetStringUTF16( IDS_PASSWORD_MANAGER_GENERATED_PASSWORD_SAVED_MESSAGE_DESCRIPTION); } else { @@ -63,7 +63,7 @@ message_->SetDescription(description); message_->SetPrimaryButtonText(l10n_util::GetStringUTF16(IDS_OK)); - if (UsesUnifiedPasswordManagerUi()) { + if (UsesUnifiedPasswordManagerBranding()) { message_->SetIconResourceId(ResourceMapper::MapToJavaDrawableId( IDR_ANDROID_PASSWORD_MANAGER_LOGO_24DP)); message_->DisableIconTint();
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerHelper.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerHelper.java index 98a97aa..f1c3b48 100644 --- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerHelper.java +++ b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerHelper.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.password_manager; import static org.chromium.chrome.browser.flags.ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID; +import static org.chromium.chrome.browser.flags.ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID_BRANDING; import android.app.PendingIntent; import android.app.PendingIntent.CanceledException; @@ -343,6 +344,11 @@ return false; } + public static boolean usesUnifiedPasswordManagerBranding() { + return usesUnifiedPasswordManagerUI() + || ChromeFeatureList.isEnabled(UNIFIED_PASSWORD_MANAGER_ANDROID_BRANDING); + } + // TODO(http://crbug.com/1371422): Remove method and manage eviction from native code // as this is covered by chrome://password-manager-internals page. public static void resetUpmUnenrollment() {
diff --git a/chrome/browser/password_manager/android/save_update_password_message_delegate.cc b/chrome/browser/password_manager/android/save_update_password_message_delegate.cc index aa95e594..b1f36e75 100644 --- a/chrome/browser/password_manager/android/save_update_password_message_delegate.cc +++ b/chrome/browser/password_manager/android/save_update_password_message_delegate.cc
@@ -191,7 +191,7 @@ std::u16string description = GetMessageDescription( pending_credentials, update_password, - password_manager::features::UsesUnifiedPasswordManagerUi()); + password_manager::features::UsesUnifiedPasswordManagerBranding()); message_->SetDescription(description); update_password_ = update_password; @@ -200,7 +200,7 @@ message_->SetPrimaryButtonText(l10n_util::GetStringUTF16( GetPrimaryButtonTextId(update_password, use_followup_button_text))); - if (password_manager::features::UsesUnifiedPasswordManagerUi()) { + if (password_manager::features::UsesUnifiedPasswordManagerBranding()) { message_->SetIconResourceId(ResourceMapper::MapToJavaDrawableId( IDR_ANDROID_PASSWORD_MANAGER_LOGO_24DP)); message_->DisableIconTint(); @@ -224,7 +224,7 @@ message->SetSecondaryIconResourceId( ResourceMapper::MapToJavaDrawableId(IDR_ANDROID_MESSAGE_SETTINGS)); message->SetSecondaryButtonMenuText(l10n_util::GetStringUTF16( - password_manager::features::UsesUnifiedPasswordManagerUi() + password_manager::features::UsesUnifiedPasswordManagerBranding() ? IDS_PASSWORD_MESSAGE_NEVER_SAVE_MENU_ITEM : IDS_PASSWORD_MANAGER_BLOCKLIST_BUTTON)); message->SetSecondaryActionCallback(base::BindRepeating(
diff --git a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc index 37fd291..a6bdfd1 100644 --- a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc +++ b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/performance_manager/decorators/frozen_frame_aggregator.h" #include "chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper.h" #include "chrome/browser/performance_manager/decorators/page_aggregator.h" +#include "chrome/browser/performance_manager/decorators/page_live_state_decorator_delegate_impl.h" #include "chrome/browser/performance_manager/metrics/memory_pressure_metrics.h" #include "chrome/browser/performance_manager/metrics/metrics_provider.h" #include "chrome/browser/performance_manager/metrics/page_timeline_monitor.h" @@ -31,6 +32,7 @@ #include "components/performance_manager/embedder/performance_manager_lifetime.h" #include "components/performance_manager/embedder/performance_manager_registry.h" #include "components/performance_manager/performance_manager_feature_observer_client.h" +#include "components/performance_manager/public/decorators/page_live_state_decorator.h" #include "components/performance_manager/public/decorators/page_load_tracker_decorator_helper.h" #include "components/performance_manager/public/decorators/process_metrics_decorator.h" #include "components/performance_manager/public/features.h" @@ -40,6 +42,10 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "base/allocator/buildflags.h" +#include "chromeos/dbus/power/power_manager_client.h" +#include "components/performance_manager/power/battery_level_provider_chromeos.h" +#include "components/performance_manager/power/dbus_power_manager_sampling_event_source.h" + #if defined(ARCH_CPU_X86_64) #include "chrome/browser/performance_manager/policies/userspace_swap_policy_chromeos.h" #endif // defined(ARCH_CPU_X86_64) @@ -100,6 +106,9 @@ std::make_unique<performance_manager::FrozenFrameAggregator>()); graph->PassToGraph( std::make_unique<performance_manager::ProcessMetricsDecorator>()); + graph->PassToGraph( + std::make_unique<performance_manager::PageLiveStateDecorator>( + performance_manager::PageLiveStateDelegateImpl::Create())); if (performance_manager::policies::WorkingSetTrimmerPolicy:: PlatformSupportsWorkingSetTrim()) { @@ -248,12 +257,27 @@ std::make_unique<performance_manager::ExtensionWatcher>(); #endif -#if BUILDFLAG(HAS_BATTERY_LEVEL_PROVIDER_IMPL) // Some browser tests need to control how the battery state behaves, so they // install a test `BatteryStateSampler` before browser setup. - if (!base::BatteryStateSampler::HasTestingInstance()) + if (!base::BatteryStateSampler::HasTestingInstance()) { + // The ChromeOS `BatteryLevelProvider` and `SamplingEventSource` + // implementations are in `components` for dependency reasons, so they need + // to be created here and passed in explicitly to `BatteryStateSampler`. + // TODO(crbug.com/1373560): All of the battery level machinery should be in + // the same location, and the ifdefs should be contained to the + // `BatteryLevelProvider` and SamplingEventSource` instantiation functions. +#if BUILDFLAG(IS_CHROMEOS_ASH) + battery_state_sampler_ = std::make_unique<base::BatteryStateSampler>( + std::make_unique< + performance_manager::power::DbusPowerManagerSamplingEventSource>( + chromeos::PowerManagerClient::Get()), + std::make_unique< + performance_manager::power::BatteryLevelProviderChromeOS>( + chromeos::PowerManagerClient::Get())); +#elif BUILDFLAG(HAS_BATTERY_LEVEL_PROVIDER_IMPL) battery_state_sampler_ = std::make_unique<base::BatteryStateSampler>(); #endif + } } void ChromeBrowserMainExtraPartsPerformanceManager::PreMainMessageLoopRun() { @@ -295,6 +319,9 @@ #if !BUILDFLAG(IS_ANDROID) user_performance_tuning_manager_.reset(); profile_discard_opt_out_list_helper_.reset(); + + if (battery_state_sampler_) + battery_state_sampler_->Shutdown(); #endif // Releasing `performance_manager_lifetime_` will tear down the registry and
diff --git a/chrome/browser/performance_manager/decorators/page_live_state_decorator_delegate_impl.cc b/chrome/browser/performance_manager/decorators/page_live_state_decorator_delegate_impl.cc new file mode 100644 index 0000000..d363eade --- /dev/null +++ b/chrome/browser/performance_manager/decorators/page_live_state_decorator_delegate_impl.cc
@@ -0,0 +1,42 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/performance_manager/decorators/page_live_state_decorator_delegate_impl.h" + +#include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/permissions/permissions_client.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/web_contents.h" + +namespace performance_manager { + +PageLiveStateDelegateImpl::~PageLiveStateDelegateImpl() = default; + +// static +base::SequenceBound<PageLiveStateDecorator::Delegate> +PageLiveStateDelegateImpl::Create() { + return base::SequenceBound<PageLiveStateDelegateImpl>( + content::GetUIThreadTaskRunner({})); +} + +std::map<ContentSettingsType, ContentSetting> +PageLiveStateDelegateImpl::GetContentSettingsForUrl( + WebContentsProxy web_contents_proxy, + const GURL& url) { + content::WebContents* web_contents = web_contents_proxy.Get(); + if (!web_contents) + return {}; + + ContentSetting setting = + permissions::PermissionsClient::Get() + ->GetSettingsMap(web_contents->GetBrowserContext()) + ->GetContentSetting(url, url, ContentSettingsType::NOTIFICATIONS); + + return { + {ContentSettingsType::NOTIFICATIONS, setting}, + }; +} + +} // namespace performance_manager
diff --git a/chrome/browser/performance_manager/decorators/page_live_state_decorator_delegate_impl.h b/chrome/browser/performance_manager/decorators/page_live_state_decorator_delegate_impl.h new file mode 100644 index 0000000..a78af498 --- /dev/null +++ b/chrome/browser/performance_manager/decorators/page_live_state_decorator_delegate_impl.h
@@ -0,0 +1,34 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/threading/sequence_bound.h" +#include "components/content_settings/core/common/content_settings.h" +#include "components/content_settings/core/common/content_settings_types.h" +#include "components/performance_manager/public/decorators/page_live_state_decorator.h" + +#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_DECORATORS_PAGE_LIVE_STATE_DECORATOR_DELEGATE_IMPL_H_ +#define CHROME_BROWSER_PERFORMANCE_MANAGER_DECORATORS_PAGE_LIVE_STATE_DECORATOR_DELEGATE_IMPL_H_ + +namespace performance_manager { + +// Concrete implementation of PageLiveStateDecorator::Delegate that is used in +// non-test code. This obtains the relevant content settings through +// `PermissionsClient` and currently only handles the `NOTIFICATIONS` setting. +class PageLiveStateDelegateImpl + : public performance_manager::PageLiveStateDecorator::Delegate { + public: + ~PageLiveStateDelegateImpl() override; + + static base::SequenceBound<PageLiveStateDecorator::Delegate> Create(); + + // Gets the content settings for `url` in the profile of `web_contents_proxy`. + // Currently only handles the `NOTIFICATIONS` setting. + std::map<ContentSettingsType, ContentSetting> GetContentSettingsForUrl( + WebContentsProxy web_contents_proxy, + const GURL& url) override; +}; + +} // namespace performance_manager + +#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_DECORATORS_PAGE_LIVE_STATE_DECORATOR_DELEGATE_IMPL_H_
diff --git a/chrome/browser/performance_manager/mechanisms/page_discarder_browsertest.cc b/chrome/browser/performance_manager/mechanisms/page_discarder_browsertest.cc index 0e7d887f..3ca1f81 100644 --- a/chrome/browser/performance_manager/mechanisms/page_discarder_browsertest.cc +++ b/chrome/browser/performance_manager/mechanisms/page_discarder_browsertest.cc
@@ -77,7 +77,7 @@ performance_manager::user_tuning::UserPerformanceTuningManager:: PreDiscardResourceUsage::FromWebContents(new_contents); EXPECT_TRUE(pre_discard_resource_usage); - EXPECT_EQ(total, pre_discard_resource_usage->resident_set_size_estimate()); + EXPECT_EQ(total, pre_discard_resource_usage->resident_set_size_estimate_kb()); } } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/policies/page_discarding_helper.cc b/chrome/browser/performance_manager/policies/page_discarding_helper.cc index 5bb85a51..4307c58a 100644 --- a/chrome/browser/performance_manager/policies/page_discarding_helper.cc +++ b/chrome/browser/performance_manager/policies/page_discarding_helper.cc
@@ -352,6 +352,12 @@ return CanUrgentlyDiscardResult::kProtected; if (live_state_data->IsConnectedToUSBDevice()) return CanUrgentlyDiscardResult::kProtected; + if (live_state_data->IsActiveTab()) + return CanUrgentlyDiscardResult::kProtected; + if (live_state_data->IsContentSettingTypeAllowed( + ContentSettingsType::NOTIFICATIONS)) { + return CanUrgentlyDiscardResult::kProtected; + } #if !BUILDFLAG(IS_CHROMEOS) // TODO(sebmarchand): Skip this check if the Entreprise memory limit is set. if (live_state_data->WasDiscarded()) @@ -369,12 +375,6 @@ // TODO(sebmarchand): Do not discard crashed tabs. - // TODO(sebmarchand): Do not discard tabs that are the active ones in a tab - // strip. - - // TODO(sebmarchand): Do not try to discard PageNode not attached to a tab - // strip. - return CanUrgentlyDiscardResult::kEligible; }
diff --git a/chrome/browser/performance_manager/policies/page_discarding_helper_unittest.cc b/chrome/browser/performance_manager/policies/page_discarding_helper_unittest.cc index 43558a8..b7630a8a2 100644 --- a/chrome/browser/performance_manager/policies/page_discarding_helper_unittest.cc +++ b/chrome/browser/performance_manager/policies/page_discarding_helper_unittest.cc
@@ -206,6 +206,44 @@ page_node())); } +TEST_F(PageDiscardingHelperTest, TestCannotDiscardIsActiveTab) { + PageLiveStateDecorator::Data::GetOrCreateForPageNode(page_node()) + ->SetIsActiveTabForTesting(true); + EXPECT_FALSE( + PageDiscardingHelper::GetFromGraph(graph())->CanUrgentlyDiscardForTesting( + page_node())); +} + +TEST_F(PageDiscardingHelperTest, TestCannotDiscardWithNotificationPermission) { + // The page is discardable if notifications are blocked. + PageLiveStateDecorator::Data::GetOrCreateForPageNode(page_node()) + ->SetContentSettingsForTesting({ + {ContentSettingsType::NOTIFICATIONS, CONTENT_SETTING_BLOCK}, + }); + EXPECT_TRUE( + PageDiscardingHelper::GetFromGraph(graph())->CanUrgentlyDiscardForTesting( + page_node())); + + // The page is discardable if notifications aren't found in its permissions + // list. + PageLiveStateDecorator::Data::GetOrCreateForPageNode(page_node()) + ->SetContentSettingsForTesting({ + {ContentSettingsType::AUTO_SELECT_CERTIFICATE, CONTENT_SETTING_ALLOW}, + }); + EXPECT_TRUE( + PageDiscardingHelper::GetFromGraph(graph())->CanUrgentlyDiscardForTesting( + page_node())); + + // The page is not discardable if it can send notifications. + PageLiveStateDecorator::Data::GetOrCreateForPageNode(page_node()) + ->SetContentSettingsForTesting({ + {ContentSettingsType::NOTIFICATIONS, CONTENT_SETTING_ALLOW}, + }); + EXPECT_FALSE( + PageDiscardingHelper::GetFromGraph(graph())->CanUrgentlyDiscardForTesting( + page_node())); +} + TEST_F(PageDiscardingHelperTest, TestCannotDiscardPageOnNoDiscardList) { base::test::ScopedFeatureList feature_list; feature_list.InitWithFeatures({features::kHighEfficiencyModeAvailable,
diff --git a/chrome/browser/performance_manager/policies/page_freezing_policy.h b/chrome/browser/performance_manager/policies/page_freezing_policy.h index 17b693e..af4b9b3 100644 --- a/chrome/browser/performance_manager/policies/page_freezing_policy.h +++ b/chrome/browser/performance_manager/policies/page_freezing_policy.h
@@ -119,6 +119,7 @@ void OnIsAutoDiscardableChanged(const PageNode* page_node) override {} void OnWasDiscardedChanged(const PageNode* page_node) override {} void OnIsActiveTabChanged(const PageNode* page_node) override {} + void OnContentSettingsChanged(const PageNode* page_node) override {} // Helper function that either calls SubmitNegativeVote() or // InvalidateNegativeVote() when the value of a property changes.
diff --git a/chrome/browser/performance_manager/policies/page_freezing_policy_unittest.cc b/chrome/browser/performance_manager/policies/page_freezing_policy_unittest.cc index e1eeeb7..77769c3 100644 --- a/chrome/browser/performance_manager/policies/page_freezing_policy_unittest.cc +++ b/chrome/browser/performance_manager/policies/page_freezing_policy_unittest.cc
@@ -8,6 +8,7 @@ #include "base/memory/raw_ptr.h" #include "base/time/time.h" +#include "chrome/browser/performance_manager/decorators/page_live_state_decorator_delegate_impl.h" #include "chrome/browser/performance_manager/mechanisms/page_freezer.h" #include "components/performance_manager/decorators/freezing_vote_decorator.h" #include "components/performance_manager/freezing/freezing_vote_aggregator.h" @@ -74,8 +75,9 @@ PageFreezingPolicyTest& operator=(const PageFreezingPolicyTest&) = delete; void OnGraphCreated(GraphImpl* graph) override { - // The freezing logic relies on the existance of the page live state data. - graph->PassToGraph(std::make_unique<PageLiveStateDecorator>()); + // The freezing logic relies on the existence of the page live state data. + graph->PassToGraph(std::make_unique<PageLiveStateDecorator>( + PageLiveStateDelegateImpl::Create())); graph->PassToGraph(std::make_unique<FreezingVoteDecorator>()); // Create the policy and pass it to the graph. auto policy = std::make_unique<policies::PageFreezingPolicy>();
diff --git a/chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h b/chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h index 9a42f48..4945450 100644 --- a/chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h +++ b/chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h
@@ -101,7 +101,8 @@ uint64_t resident_set_size_estimate); ~PreDiscardResourceUsage() override; - uint64_t resident_set_size_estimate() const { + // Returns the resource usage estimate in kilobytes. + uint64_t resident_set_size_estimate_kb() const { return resident_set_size_estimate_; } @@ -190,6 +191,7 @@ high_efficiency_mode_toggle_delegate_; bool has_battery_ = false; + bool force_has_battery_ = false; bool on_battery_power_ = false; bool is_below_low_battery_threshold_ = false; @@ -198,6 +200,9 @@ battery_state_sampler_obs_{this}; PrefChangeRegistrar pref_change_registrar_; base::ObserverList<Observer> observers_; + + // Command line switch for overriding the device has battery flag. + static const char kForceDeviceHasBattery[]; }; } // namespace performance_manager::user_tuning
diff --git a/chrome/browser/performance_manager/test_support/page_discarding_utils.cc b/chrome/browser/performance_manager/test_support/page_discarding_utils.cc index 270ad61..91f51d0e 100644 --- a/chrome/browser/performance_manager/test_support/page_discarding_utils.cc +++ b/chrome/browser/performance_manager/test_support/page_discarding_utils.cc
@@ -6,6 +6,7 @@ #include "base/time/time.h" #include "chrome/browser/performance_manager/decorators/page_aggregator.h" +#include "chrome/browser/performance_manager/decorators/page_live_state_decorator_delegate_impl.h" #include "chrome/browser/performance_manager/policies/page_discarding_helper.h" #include "components/performance_manager/decorators/freezing_vote_decorator.h" #include "components/performance_manager/freezing/freezing_vote_aggregator.h" @@ -48,8 +49,9 @@ auto mock_discarder = std::make_unique<MockPageDiscarder>(); mock_discarder_ = mock_discarder.get(); - // The discarding logic relies on the existance of the page live state data. - graph()->PassToGraph(std::make_unique<PageLiveStateDecorator>()); + // The discarding logic relies on the existence of the page live state data. + graph()->PassToGraph(std::make_unique<PageLiveStateDecorator>( + PageLiveStateDelegateImpl::Create())); // Create the helper and pass it to the graph. auto page_discarding_helper =
diff --git a/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager.cc b/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager.cc index 2f3e5ec..50e432e 100644 --- a/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager.cc +++ b/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h" +#include "base/command_line.h" #include "base/feature_list.h" #include "base/power_monitor/power_monitor.h" #include "base/values.h" @@ -57,6 +58,9 @@ const uint64_t UserPerformanceTuningManager::kLowBatteryThresholdPercent = 20; +const char UserPerformanceTuningManager::kForceDeviceHasBattery[] = + "force-device-has-battery"; + WEB_CONTENTS_USER_DATA_KEY_IMPL( UserPerformanceTuningManager::PreDiscardResourceUsage); @@ -196,6 +200,12 @@ if (base::FeatureList::IsEnabled( performance_manager::features::kBatterySaverModeAvailable)) { + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(kForceDeviceHasBattery)) { + force_has_battery_ = true; + has_battery_ = true; + } + pref_change_registrar_.Add( performance_manager::user_tuning::prefs::kBatterySaverModeState, base::BindRepeating( @@ -307,7 +317,8 @@ return; bool had_battery = has_battery_; - has_battery_ = battery_state->battery_count > 0; + has_battery_ = force_has_battery_ || battery_state->battery_count > 0; + // If the "has battery" state changed, notify observers. if (had_battery != has_battery_) { for (auto& obs : observers_) {
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index b0aa4b2..072a7e3 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -409,9 +409,6 @@ { key::kDisableScreenshots, prefs::kDisableScreenshots, base::Value::Type::BOOLEAN }, - { key::kDisplayCapturePermissionsPolicyEnabled, - prefs::kDisplayCapturePermissionsPolicyEnabled, - base::Value::Type::BOOLEAN }, { key::kDownloadBubbleEnabled, prefs::kDownloadBubbleEnabled, base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/portal/portal_browsertest.cc b/chrome/browser/portal/portal_browsertest.cc index 2524e74..411f6bd 100644 --- a/chrome/browser/portal/portal_browsertest.cc +++ b/chrome/browser/portal/portal_browsertest.cc
@@ -364,7 +364,10 @@ "document.documentElement.hasAttribute('subframe');")); } -IN_PROC_BROWSER_TEST_F(PortalBrowserTest, BrowserHistoryUpdatesOnActivation) { +// TODO(crbug.com/1372129): This test is flaking on all platforms. The renderer +// seems to be terinated occasionally preventing the ASSERT_EQ from succeeding. +IN_PROC_BROWSER_TEST_F(PortalBrowserTest, + DISABLED_BrowserHistoryUpdatesOnActivation) { ASSERT_TRUE(embedded_test_server()->Start()); Profile* profile = browser()->profile();
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java index 5a1bbd1..535b2789 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -625,6 +625,13 @@ "Chrome.OfflineMeasurements.SystemStateList"; /** + * Serialized GroupsInfo data used by Omnibox Suggestions to present suggestions before + * natives are ready. + */ + public static final String OMNIBOX_CACHED_ZERO_SUGGEST_GROUPS_INFO = + "Chrome.Omnibox.CachedZeroSuggestGroupsInfo"; + + /** * Prefix of the preferences to persist pushed notifications when native is not initialized. * Each suffix pertains to a specific OptimizationType. All entries are cleared when native is * initialized. @@ -1022,13 +1029,6 @@ new KeyPrefix("zero_suggest_post_content_type*"); public static final KeyPrefix KEY_ZERO_SUGGEST_POST_CONTENT_DATA_PREFIX = new KeyPrefix("zero_suggest_post_content_data*"); - public static final String KEY_ZERO_SUGGEST_HEADER_LIST_SIZE = "zero_suggest_header_list_size"; - public static final KeyPrefix KEY_ZERO_SUGGEST_HEADER_GROUP_ID_PREFIX = - new KeyPrefix("zero_suggest_header_group_id*"); - public static final KeyPrefix KEY_ZERO_SUGGEST_HEADER_GROUP_TITLE_PREFIX = - new KeyPrefix("zero_suggest_header_group_title*"); - public static final KeyPrefix KEY_ZERO_SUGGEST_HEADER_GROUP_COLLAPSED_BY_DEFAULT_PREFIX = - new KeyPrefix("zero_suggest_header_group_collapsed_by_default*"); public static final String BLUETOOTH_NOTIFICATION_IDS = "Chrome.Bluetooth.NotificationIds"; public static final String USB_NOTIFICATION_IDS = "Chrome.USB.NotificationIds"; @@ -1141,6 +1141,7 @@ OFFLINE_MEASUREMENTS_LAST_CHECK_MILLIS, OFFLINE_MEASUREMENTS_SYSTEM_STATE_LIST, OFFLINE_MEASUREMENTS_USER_AGENT_STRING, + OMNIBOX_CACHED_ZERO_SUGGEST_GROUPS_INFO, OPEN_HISTORY_COUNT, OPEN_NEW_TAB_PAGE_COUNT, OPEN_RECENT_TABS_COUNT,
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java index b78224ba..94c52d2 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java
@@ -146,8 +146,7 @@ ChromePreferenceKeys.VR_FEEDBACK_OPT_OUT, ChromePreferenceKeys.VR_SHOULD_REGISTER_ASSETS_COMPONENT_ON_STARTUP, ChromePreferenceKeys.WEBAPK_UNINSTALLED_PACKAGES, - ChromePreferenceKeys.KEY_ZERO_SUGGEST_LIST_SIZE, - ChromePreferenceKeys.KEY_ZERO_SUGGEST_HEADER_LIST_SIZE + ChromePreferenceKeys.KEY_ZERO_SUGGEST_LIST_SIZE ); // clang-format on } @@ -169,10 +168,7 @@ ChromePreferenceKeys.KEY_ZERO_SUGGEST_IS_DELETABLE_PREFIX, ChromePreferenceKeys.KEY_ZERO_SUGGEST_IS_STARRED_PREFIX, ChromePreferenceKeys.KEY_ZERO_SUGGEST_POST_CONTENT_TYPE_PREFIX, - ChromePreferenceKeys.KEY_ZERO_SUGGEST_POST_CONTENT_DATA_PREFIX, - ChromePreferenceKeys.KEY_ZERO_SUGGEST_HEADER_GROUP_ID_PREFIX, - ChromePreferenceKeys.KEY_ZERO_SUGGEST_HEADER_GROUP_TITLE_PREFIX, - ChromePreferenceKeys.KEY_ZERO_SUGGEST_HEADER_GROUP_COLLAPSED_BY_DEFAULT_PREFIX + ChromePreferenceKeys.KEY_ZERO_SUGGEST_POST_CONTENT_DATA_PREFIX ); // clang-format on }
diff --git a/chrome/browser/resources/chromeos/login/BUILD.gn b/chrome/browser/resources/chromeos/login/BUILD.gn index ab19b922..5d4a9f4a 100644 --- a/chrome/browser/resources/chromeos/login/BUILD.gn +++ b/chrome/browser/resources/chromeos/login/BUILD.gn
@@ -220,7 +220,6 @@ "components/display_manager_types.m.js", "components/gaia_dialog.m.js", "components/gaia_header.m.js", - "components/gaia_button.m.js", "components/gaia_input_form.m.js", "components/hd_iron_icon.m.js", "components/long_touch_detector.m.js", @@ -271,6 +270,7 @@ out_manifest = "$target_gen_dir/$web_components_manifest" in_files = [ + "components/gaia_button.js", "components/notification_card.js", "components/security_token_pin.js", "screens/common/adb_sideloading.js",
diff --git a/chrome/browser/resources/chromeos/login/components/BUILD.gn b/chrome/browser/resources/chromeos/login/components/BUILD.gn index a2126b3..71dc3b9 100644 --- a/chrome/browser/resources/chromeos/login/components/BUILD.gn +++ b/chrome/browser/resources/chromeos/login/components/BUILD.gn
@@ -20,7 +20,7 @@ # Local targets ":display_manager_types.m", - ":gaia_button.m", + ":gaia_button", ":gaia_dialog.m", ":gaia_header.m", ":gaia_input_form.m", @@ -58,7 +58,6 @@ "progress_list_item:polymer3_elements", # Local targets - ":gaia_button_module", ":gaia_dialog_module", ":gaia_header_module", ":gaia_input_form_module", @@ -87,14 +86,14 @@ extra_deps = [ ":modulize" ] } -js_library("gaia_button.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/components/gaia_button.m.js" ] +js_library("gaia_button") { + sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/components/gaia_button.js" ] deps = [ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] externs_list = [ "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js" ] - extra_deps = [ ":gaia_button_module" ] + extra_deps = [ ":web_components" ] } js_library("gaia_dialog.m") { @@ -273,15 +272,6 @@ extra_deps = [ ":modulize" ] } -polymer_modulizer("gaia_button") { - js_file = "gaia_button.js" - html_file = "gaia_button.html" - html_type = "dom-module" - auto_imports = oobe_auto_imports - migrated_imports = oobe_migrated_imports - namespace_rewrites = oobe_namespace_rewrites -} - polymer_modulizer("gaia_dialog") { js_file = "gaia_dialog.js" html_file = "gaia_dialog.html" @@ -417,7 +407,8 @@ html_to_js("web_components") { js_files = [ - "security_token_pin.js", + "gaia_button.js", "notification_card.js", + "security_token_pin.js", ] }
diff --git a/chrome/browser/resources/chromeos/login/components/gaia_button.html b/chrome/browser/resources/chromeos/login/components/gaia_button.html index 170f06f..fb62ba9 100644 --- a/chrome/browser/resources/chromeos/login/components/gaia_button.html +++ b/chrome/browser/resources/chromeos/login/components/gaia_button.html
@@ -4,11 +4,6 @@ found in the LICENSE file. --> -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> - <!-- Material design buttons that mimic GAIA's buttons. @@ -20,40 +15,36 @@ that looks more like a link. 'disabled' - button is disabled when the attribute is set. --> -<dom-module id="gaia-button"> - <template> - <style> - :host { - display: inline-block; - } +<style> + :host { + display: inline-block; + } - :host([link]) cr-button { - background-color: transparent; - border: none; - border-radius: 0; - box-shadow: none; - color: var(--cros-link-color); - font-weight: 400; - margin: 0 -0.57em; - min-width: 0; - } + :host([link]) cr-button { + background-color: transparent; + border: none; + border-radius: 0; + box-shadow: none; + color: var(--cros-link-color); + font-weight: 400; + margin: 0 -0.57em; + min-width: 0; + } - :host([link]) cr-button:focus { - background-color: var(--cros-button-active-shadow-color-ambient-primary); - } + :host([link]) cr-button:focus { + background-color: var(--cros-button-active-shadow-color-ambient-primary); + } - :host-context(.focus-outline-visible):host([link]) cr-button:focus { - font-weight: 500; - } + :host-context(.focus-outline-visible):host([link]) cr-button:focus { + font-weight: 500; + } - :host([link]) cr-button[disabled] { - color: var(--cros-color-disabled); - } - </style> - <cr-button id="button" disabled="[[disabled]]" on-click="onClick_" - noink$="[[link]]"> - <slot></slot> - </cr-button> - </template> - <script src="gaia_button.js"></script> -</dom-module> + :host([link]) cr-button[disabled] { + color: var(--cros-color-disabled); + } +</style> +<cr-button id="button" disabled="[[disabled]]" on-click="onClick_" + noink$="[[link]]"> + <slot></slot> +</cr-button> +
diff --git a/chrome/browser/resources/chromeos/login/components/gaia_button.js b/chrome/browser/resources/chromeos/login/components/gaia_button.js index 3a1e3b7..d791a47 100644 --- a/chrome/browser/resources/chromeos/login/components/gaia_button.js +++ b/chrome/browser/resources/chromeos/login/components/gaia_button.js
@@ -6,13 +6,17 @@ * @fileoverview Polymer element wrapping gaia styled button for login/oobe. */ -/* #js_imports_placeholder */ +import '//resources/cr_elements/cr_button/cr_button.js'; +import '//resources/polymer/v3_0/paper-styles/color.js'; + +import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + /** * @constructor * @extends {PolymerElement} */ -const GaiaButtonBase = Polymer.mixinBehaviors([], Polymer.Element); +const GaiaButtonBase = mixinBehaviors([], PolymerElement); /** * @typedef {{ @@ -21,12 +25,15 @@ */ GaiaButtonBase.$; +/** @polymer */ class GaiaButton extends GaiaButtonBase { static get is() { return 'gaia-button'; } - /* #html_template_placeholder */ + static get template() { + return html`{__html_template__}`; + } static get properties() { return { @@ -45,10 +52,6 @@ }; } - constructor() { - super(); - } - focus() { this.$.button.focus(); }
diff --git a/chrome/browser/resources/chromeos/login/debug/debug.js b/chrome/browser/resources/chromeos/login/debug/debug.js index c4d6b71..422e7bd6 100644 --- a/chrome/browser/resources/chromeos/login/debug/debug.js +++ b/chrome/browser/resources/chromeos/login/debug/debug.js
@@ -418,6 +418,15 @@ id: 'creds', trigger: (screen) => { screen.setUIStep('creds'); + screen.isDomainJoin = false; + }, + data: {}, + }, + { + id: 'creds(isDomainJoin)', + trigger: (screen) => { + screen.setUIStep('creds'); + screen.isDomainJoin = true; }, data: {}, },
diff --git a/chrome/browser/resources/chromeos/login/oobe_auto_imports.gni b/chrome/browser/resources/chromeos/login/oobe_auto_imports.gni index 68d00afd..199ca20 100644 --- a/chrome/browser/resources/chromeos/login/oobe_auto_imports.gni +++ b/chrome/browser/resources/chromeos/login/oobe_auto_imports.gni
@@ -109,6 +109,7 @@ "ash/webui/common/resources/network/network_list_types.html", "ash/webui/common/resources/network/network_select.html", "ash/webui/common/resources/network/onc_mojo.html", + "chrome/browser/resources/chromeos/login/components/gaia_button.html", "chrome/browser/resources/chromeos/login/components/notification_card.html", "chrome/browser/resources/chromeos/login/components/security_token_pin.html", "chrome/browser/resources/chromeos/login/screens/common/offline_ad_login.html",
diff --git a/chrome/browser/resources/chromeos/login/screens/login/offline_login.js b/chrome/browser/resources/chromeos/login/screens/login/offline_login.js index 4eede98..d70b435 100644 --- a/chrome/browser/resources/chromeos/login/screens/login/offline_login.js +++ b/chrome/browser/resources/chromeos/login/screens/login/offline_login.js
@@ -12,7 +12,7 @@ import '//resources/cr_elements/cr_input/cr_input.js'; import '../../components/gaia_header.m.js'; import '../../components/gaia_input_form.m.js'; -import '../../components/gaia_button.m.js'; +import '../../components/gaia_button.js'; import '../../components/common_styles/oobe_dialog_host_styles.m.js'; import '../../components/dialogs/oobe_content_dialog.m.js'; import '../../components/buttons/oobe_back_button.m.js';
diff --git a/chrome/browser/resources/new_tab_page/icons/BUILD.gn b/chrome/browser/resources/new_tab_page/icons/BUILD.gn index f2da3b9..b48fa872 100644 --- a/chrome/browser/resources/new_tab_page/icons/BUILD.gn +++ b/chrome/browser/resources/new_tab_page/icons/BUILD.gn
@@ -29,6 +29,7 @@ "link.svg", "mail.svg", "mic.svg", + "offline_dialog.svg", "shortcut_circles.svg", "twitter.svg", "upload.svg",
diff --git a/chrome/browser/resources/new_tab_page/icons/offline_dialog.svg b/chrome/browser/resources/new_tab_page/icons/offline_dialog.svg new file mode 100644 index 0000000..5b52c9a1 --- /dev/null +++ b/chrome/browser/resources/new_tab_page/icons/offline_dialog.svg
@@ -0,0 +1 @@ +<svg width="55" height="51" viewBox="0 0 55 51" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="m23.184 11.959-5.922-6.155C30.291 2.11 44.846 5.452 55 16.179l-4.908 5.1c-7.446-7.562-17.43-10.727-26.907-9.32Zm21.831 14.596c-4.23-4.396-9.477-6.858-15.061-7.386l11 11.431 4.061-4.045ZM4.57 0 1.015 3.693 7.277 10.2C4.738 11.783 2.2 13.717 0 16.004l4.908 5.1c2.2-2.287 4.738-4.221 7.446-5.628l5.246 5.452c-2.877 1.23-5.415 2.99-7.785 5.275l4.908 5.1c2.37-2.462 5.246-4.044 8.292-4.748l6.939 7.21c-3.554-1.054-7.446 0-10.154 2.814l7.446 7.738 6.43-6.682L46.539 51l3.554-3.693L4.57 0Z" fill="#BDC1C6"/></svg> \ No newline at end of file
diff --git a/chrome/browser/resources/new_tab_page/lens_upload_dialog.html b/chrome/browser/resources/new_tab_page/lens_upload_dialog.html index 81a9893..01256762 100644 --- a/chrome/browser/resources/new_tab_page/lens_upload_dialog.html +++ b/chrome/browser/resources/new_tab_page/lens_upload_dialog.html
@@ -210,7 +210,8 @@ --upload-dialog-input-submit-color: var(--google-blue-600); } - #loadingContainer { + #loadingContainer, + #offlineContainer { align-items: center; display: flex; flex-direction: column; @@ -222,6 +223,27 @@ display: block; margin-bottom: 12px; } + + #offlineTitle { + color: var(--upload-dialog-title-color); + } + + #offlineImage { + background: url(icons/offline_dialog.svg) no-repeat center; + height: 51px; + margin-bottom: 24px; + width: 55px; + } + + #offlineSubtitle { + color: var(--upload-dialog-drag-drop-title-color); + font-size: 16px; + margin-top: 6px; + } + + #offlineRetryButton { + margin-top: 21px; + } </style> <div id="dialog" hidden$="{{isHidden_}}" tabindex="-1" lang="$i18n{language}"> @@ -279,6 +301,22 @@ </div> </div> </template> + <!-- Offline state --> + <template is="dom-if" if="{{isOffline_}}"> + <div id="offlineContainer"> + <div id="offlineImage"></div> + <div id="offlineTitle" class="drag-drop-title"> + $i18n{lensSearchUploadDialogOfflineText} + </div> + <div id="offlineSubtitle"> + $i18n{lensSearchUploadDialogOfflineSubtitleText} + </div> + <cr-button id="offlineRetryButton" class="action-button" + on-click="onOfflineRetryButtonClick_"> + $i18n{lensSearchUploadDialogOfflineButtonLabel} + </cr-button> + </div> + </template> </div> - </div> + </div> </div> \ No newline at end of file
diff --git a/chrome/browser/resources/new_tab_page/lens_upload_dialog.ts b/chrome/browser/resources/new_tab_page/lens_upload_dialog.ts index e6b5da51..6917ccf 100644 --- a/chrome/browser/resources/new_tab_page/lens_upload_dialog.ts +++ b/chrome/browser/resources/new_tab_page/lens_upload_dialog.ts
@@ -9,18 +9,21 @@ import {afterNextRender, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './lens_upload_dialog.html.js'; +import {WindowProxy} from './window_proxy.js'; enum DialogState { // Dialog is currently hidden from the user. HIDDEN, // Dialog is open and awaiting user input. NORMAL, - // User is dragging a file over the UI + // User is dragging a file over the UI. DRAGGING, - // User dropped a file and a request to Lens is started + // User dropped a file and a request to Lens is started. LOADING, - // User selected a file that resulted in an error + // User selected a file that resulted in an error. ERROR, + // User is offline. + OFFLINE, } export interface LensUploadDialogElement { @@ -63,6 +66,11 @@ computed: `computeIsLoading_(dialogState_)`, reflectToAttribute: true, }, + isOffline_: { + type: Boolean, + computed: `computeIsOffline_(dialogState_)`, + reflectToAttribute: true, + }, }; } @@ -86,6 +94,10 @@ return dialogState === DialogState.LOADING; } + private computeIsOffline_(dialogState: DialogState): boolean { + return dialogState === DialogState.OFFLINE; + } + constructor() { super(); this.outsideClickHandler_ = (event: MouseEvent) => { @@ -106,7 +118,7 @@ } openDialog() { - this.dialogState_ = DialogState.NORMAL; + this.setOnlineState_(); // Click handler needs to be attached outside of the initial event handler, // otherwise the click of the icon which initially opened the dialog would // also be registered in the outside click handler, causing the dialog to @@ -120,6 +132,15 @@ this.dispatchEvent(new Event('close-lens-search')); } + /** + * Checks to see if the user is online or offline and sets the dialog state + * accordingly. + */ + private setOnlineState_() { + this.dialogState_ = WindowProxy.getInstance().onLine ? DialogState.NORMAL : + DialogState.OFFLINE; + } + private attachOutsideClickHandler_() { if (!this.outsideClickHandlerAttached_) { document.addEventListener('click', this.outsideClickHandler_); @@ -137,6 +158,10 @@ private onCloseButtonClick_() { this.closeDialog(); } + + private onOfflineRetryButtonClick_() { + this.setOnlineState_(); + } } declare global { interface HTMLElementTagNameMap {
diff --git a/chrome/browser/resources/new_tab_page/window_proxy.ts b/chrome/browser/resources/new_tab_page/window_proxy.ts index 9e32001..82678f1 100644 --- a/chrome/browser/resources/new_tab_page/window_proxy.ts +++ b/chrome/browser/resources/new_tab_page/window_proxy.ts
@@ -70,4 +70,8 @@ get url(): URL { return new URL(window.location.href); } + + get onLine(): boolean { + return window.navigator.onLine; + } }
diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn index bc95df1e..c5f643c 100644 --- a/chrome/browser/resources/settings/BUILD.gn +++ b/chrome/browser/resources/settings/BUILD.gn
@@ -339,6 +339,7 @@ "people_page/sync_browser_proxy.ts", "people_page/profile_info_browser_proxy.ts", "performance_page/performance_browser_proxy.ts", + "performance_page/performance_metrics_proxy.ts", "prefs/prefs_mixin.ts", "prefs/prefs.ts", "prefs/prefs_types.ts",
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_options_page.js b/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_options_page.js index 9c8cad4..9ecfb77a 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_options_page.js +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_options_page.js
@@ -11,6 +11,7 @@ import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js'; import '../../settings_shared.css.js'; import './os_japanese_clear_ime_data_dialog.js'; +import './os_japanese_manage_user_dictionary_page.js'; import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/cr_elements/i18n_behavior.js'; import {assert, assertNotReached} from 'chrome://resources/js/assert.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_util.js b/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_util.js index 554e041..48d820a 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_util.js +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_util.js
@@ -83,6 +83,9 @@ JAPANESE_KEYMAP_STYLE: 'JapaneseKeymapStyle', JAPANESE_MANAGE_USER_DICTIONARY: 'JapaneseManageUserDictionary', JAPANESE_CLEAR_PERSONALIZATION_DATA: 'JapaneseClearPersonalizationData', + JAPANESE_DISABLE_PERSONALIZED_SUGGESTIONS: 'JapaneseDisableSuggestions', + JAPANESE_AUTOMATICALLY_SEND_STATISTICS_TO_GOOGLE: + 'AutomaticallySendStatisticsToGoogle', // Options for Korean input method. KOREAN_ENABLE_SYLLABLE_INPUT: 'koreanEnableSyllableInput', KOREAN_KEYBOARD_LAYOUT: 'koreanKeyboardLayout', @@ -150,6 +153,9 @@ [OptionType.JAPANESE_SECTION_SHORTCUT]: JAPANESE_SECTION_SHORTCUT.DIGITS_123456789, [OptionType.JAPANESE_KEYMAP_STYLE]: JAPANESE_KEYMAP_STYLE.CUSTOM, + [OptionType.JAPANESE_DISABLE_PERSONALIZED_SUGGESTIONS]: true, + [OptionType.JAPANESE_AUTOMATICALLY_SEND_STATISTICS_TO_GOOGLE]: true, + // Options for Korean input method. [OptionType.KOREAN_ENABLE_SYLLABLE_INPUT]: true, [OptionType.KOREAN_KEYBOARD_LAYOUT]: KeyboardLayout.SET2, @@ -283,15 +289,12 @@ }], }, { - // TODO(b/234790486): Customize privacy with the correct values. The - // correct values are the ones from the legacy settings page that used to - // be found in - // chrome-extension://jkghodnilhceideoidjikpgommlajknk/mozc_option.html. - // This is still missing 2 settings, but will do that separately. title: SettingsHeaders.PRIVACY, - optionNames: [{ - name: OptionType.JAPANESE_CLEAR_PERSONALIZATION_DATA, - }], + optionNames: [ + {name: OptionType.JAPANESE_CLEAR_PERSONALIZATION_DATA}, + {name: OptionType.JAPANESE_DISABLE_PERSONALIZED_SUGGESTIONS}, + {name: OptionType.JAPANESE_AUTOMATICALLY_SEND_STATISTICS_TO_GOOGLE}, + ], }, ], [SettingsType.ZHUYIN_SETTINGS]: [{ @@ -456,6 +459,8 @@ case OptionType.JAPANESE_AUTOMATICALLY_SWITCH_TO_HALFWIDTH: case OptionType.JAPANESE_USE_SYSTEM_DICTIONARY: case OptionType.JAPANESE_USE_INPUT_HISTORY: + case OptionType.JAPANESE_DISABLE_PERSONALIZED_SUGGESTIONS: + case OptionType.JAPANESE_AUTOMATICALLY_SEND_STATISTICS_TO_GOOGLE: case OptionType.PHYSICAL_KEYBOARD_ENABLE_CAPITALIZATION: case OptionType.PHYSICAL_KEYBOARD_ENABLE_PREDICTIVE_WRITING: case OptionType.PHYSICAL_KEYBOARD_ENABLE_DIACRITICS_ON_LONGPRESS: @@ -593,6 +598,10 @@ return 'inputMethodOptionsJapaneseManageUserDictionary'; case OptionType.JAPANESE_CLEAR_PERSONALIZATION_DATA: return 'inputMethodOptionsJapaneseClearPersonalizationData'; + case OptionType.JAPANESE_DISABLE_PERSONALIZED_SUGGESTIONS: + return 'inputMethodOptionsJapaneseDisablePersonalizedSuggestions'; + case OptionType.JAPANESE_AUTOMATICALLY_SEND_STATISTICS_TO_GOOGLE: + return 'inputMethodOptionsJapaneseAutomaticallySendStatisticsToGoogle'; case OptionType.XKB_LAYOUT: return 'inputMethodOptionsXkbLayout'; case OptionType.EDIT_USER_DICT:
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/lock_screen.html b/chrome/browser/resources/settings/chromeos/os_people_page/lock_screen.html index 146a5c9b..244c4a90 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/lock_screen.html +++ b/chrome/browser/resources/settings/chromeos/os_people_page/lock_screen.html
@@ -72,10 +72,10 @@ aria-labelledby="lockScreenOptionsTitle" deep-link-focus-id$="[[Setting.kChangeAuthPinV2]]"> <cr-radio-button name="password" class="list-item underbar" - label=$i18n{lockScreenPasswordOnly}> + label="$i18n{lockScreenPasswordOnly}"> </cr-radio-button> <cr-radio-button name="pin+password" class="list-item-start" - label=$i18n{lockScreenPinOrPassword}> + label="$i18n{lockScreenPinOrPassword}"> </cr-radio-button> <template is="dom-if" if="[[showConfigurePinButton_(selectedUnlockType)]]">
diff --git a/chrome/browser/resources/settings/performance_page/battery_page.html b/chrome/browser/resources/settings/performance_page/battery_page.html index f32a52138..5888fc8 100644 --- a/chrome/browser/resources/settings/performance_page/battery_page.html +++ b/chrome/browser/resources/settings/performance_page/battery_page.html
@@ -3,7 +3,7 @@ padding-block-end: var(--cr-section-vertical-padding); } </style> -<settings-toggle-button id="toggleButton" +<settings-toggle-button id="toggleButton" on-change="onChange_" pref="{{prefs.performance_tuning.battery_saver_mode.state}}" label="$i18n{batterySaverModeLabel}" sub-label-with-link="$i18n{batterySaverModeDescription}" @@ -16,7 +16,7 @@ opened="[[isBatterySaverModeEnabled_( prefs.performance_tuning.battery_saver_mode.state.value)]]"> <div class="cr-row continuation battery-saver-radio-group"> - <settings-radio-group id="radioGroup" + <settings-radio-group id="radioGroup" on-change="onChange_" pref="{{prefs.performance_tuning.battery_saver_mode.state}}" group-aria-label="$i18n{batterySaverModeLabel}"> <controlled-radio-button @@ -24,7 +24,7 @@ name="[[batterySaverModeStatePrefValues.enabledBelowThreshold]]" pref="[[prefs.performance_tuning.battery_saver_mode.state]]"> </controlled-radio-button> - <controlled-radio-button + <controlled-radio-button id="enabledOnBatteryButton" label="$i18n{batterySaverModeEnabledOnBatteryLabel}" name="[[batterySaverModeStatePrefValues.enabledOnBattery]]" pref="[[prefs.performance_tuning.battery_saver_mode.state]]">
diff --git a/chrome/browser/resources/settings/performance_page/battery_page.ts b/chrome/browser/resources/settings/performance_page/battery_page.ts index 26efc82..255f7c0 100644 --- a/chrome/browser/resources/settings/performance_page/battery_page.ts +++ b/chrome/browser/resources/settings/performance_page/battery_page.ts
@@ -1,10 +1,10 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. +// Copyright 2022 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off import 'chrome://resources/cr_elements/cr_shared_style.css.js'; import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js'; +import '../controls/controlled_radio_button.js'; import '../controls/settings_radio_group.js'; import '../controls/settings_toggle_button.js'; import '../settings_shared.css.js'; @@ -12,24 +12,32 @@ import {IronCollapseElement} from 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {ControlledRadioButtonElement} from '../controls/controlled_radio_button.js'; import {SettingsRadioGroupElement} from '../controls/settings_radio_group.js'; import {SettingsToggleButtonElement} from '../controls/settings_toggle_button.js'; import {loadTimeData} from '../i18n_setup.js'; import {OpenWindowProxyImpl} from '../open_window_proxy.js'; +import {PrefsMixin} from '../prefs/prefs_mixin.js'; import {getTemplate} from './battery_page.html.js'; import {PerformanceBrowserProxy, PerformanceBrowserProxyImpl} from './performance_browser_proxy.js'; -// clang-format on +import {BatterySaverModeState, PerformanceMetricsProxy, PerformanceMetricsProxyImpl} from './performance_metrics_proxy.js'; + +export const BATTERY_SAVER_MODE_PREF = + 'performance_tuning.battery_saver_mode.state'; export interface SettingsBatteryPageElement { $: { + enabledOnBatteryButton: ControlledRadioButtonElement, radioGroup: SettingsRadioGroupElement, radioGroupCollapse: IronCollapseElement, toggleButton: SettingsToggleButtonElement, }; } -export class SettingsBatteryPageElement extends PolymerElement { +const SettingsBatteryPageElementBase = PrefsMixin(PolymerElement); + +export class SettingsBatteryPageElement extends SettingsBatteryPageElementBase { static get is() { return 'settings-battery-page'; } @@ -40,11 +48,6 @@ static get properties() { return { - prefs: { - type: Object, - notify: true, - }, - /** * Possible values for the * 'prefs.performance_tuning.battery_saver_mode.state' preference. These @@ -56,10 +59,10 @@ readOnly: true, type: Object, value: { - disabled: 0, - enabledBelowThreshold: 1, - enabledOnBattery: 2, - enabled: 3, + disabled: BatterySaverModeState.DISABLED, + enabledBelowThreshold: BatterySaverModeState.ENABLED_BELOW_THRESHOLD, + enabledOnBattery: BatterySaverModeState.ENABLED_ON_BATTERY, + enabled: BatterySaverModeState.ENABLED, }, }, }; @@ -74,6 +77,8 @@ private browserProxy_: PerformanceBrowserProxy = PerformanceBrowserProxyImpl.getInstance(); + private metricsProxy_: PerformanceMetricsProxy = + PerformanceMetricsProxyImpl.getInstance(); private isBatterySaverModeEnabled_(value: number): boolean { return value !== this.batterySaverModeStatePrefValues.disabled; @@ -90,6 +95,11 @@ break; } } + + private onChange_() { + this.metricsProxy_.recordBatterySaverModeChanged( + this.getPref(BATTERY_SAVER_MODE_PREF).value); + } } declare global {
diff --git a/chrome/browser/resources/settings/performance_page/performance_metrics_proxy.ts b/chrome/browser/resources/settings/performance_page/performance_metrics_proxy.ts new file mode 100644 index 0000000..acd97bc --- /dev/null +++ b/chrome/browser/resources/settings/performance_page/performance_metrics_proxy.ts
@@ -0,0 +1,63 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +// This must be kept in sync with BatterySaverModeState in +// components/performance_manager/public/user_tuning/prefs.h +export enum BatterySaverModeState { + DISABLED = 0, + ENABLED_BELOW_THRESHOLD = 1, + ENABLED_ON_BATTERY = 2, + ENABLED = 3, +} + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +export enum HighEfficiencyModeExceptionListAction { + ADD = 0, + EDIT = 1, + REMOVE = 2, +} + +function getNumericEnumLength(e: Object) { + // numeric enums have reverse mapping when compiled to js, so must divide by 2 + return Object.keys(e).length / 2; +} + +export interface PerformanceMetricsProxy { + recordBatterySaverModeChanged(state: BatterySaverModeState): void; + recordHighEfficiencyModeChanged(enabled: boolean): void; + recordExceptionListAction(action: HighEfficiencyModeExceptionListAction): + void; +} + +export class PerformanceMetricsProxyImpl implements PerformanceMetricsProxy { + recordBatterySaverModeChanged(state: BatterySaverModeState) { + chrome.metricsPrivate.recordEnumerationValue( + 'PerformanceControls.BatterySaver.SettingsChangeMode', state, + getNumericEnumLength(BatterySaverModeState)); + } + + recordHighEfficiencyModeChanged(enabled: boolean): void { + chrome.metricsPrivate.recordBoolean( + 'PerformanceControls.HighEfficiency.SettingsChangeMode', enabled); + } + + recordExceptionListAction(action: HighEfficiencyModeExceptionListAction) { + chrome.metricsPrivate.recordEnumerationValue( + 'PerformanceControls.HighEfficiency.SettingsChangeExceptionList', + action, getNumericEnumLength(HighEfficiencyModeExceptionListAction)); + } + + static getInstance(): PerformanceMetricsProxy { + return instance || (instance = new PerformanceMetricsProxyImpl()); + } + + static setInstance(obj: PerformanceMetricsProxy) { + instance = obj; + } +} + +let instance: PerformanceMetricsProxy|null = null;
diff --git a/chrome/browser/resources/settings/performance_page/performance_page.html b/chrome/browser/resources/settings/performance_page/performance_page.html index d4762eb..5ff18d2 100644 --- a/chrome/browser/resources/settings/performance_page/performance_page.html +++ b/chrome/browser/resources/settings/performance_page/performance_page.html
@@ -1,4 +1,4 @@ -<settings-toggle-button id="toggleButton" +<settings-toggle-button id="toggleButton" on-change="onChange_" pref="{{prefs.performance_tuning.high_efficiency_mode.enabled}}" label="$i18n{highEfficiencyModeLabel}" sub-label-with-link="$i18n{highEfficiencyModeDescription}"
diff --git a/chrome/browser/resources/settings/performance_page/performance_page.ts b/chrome/browser/resources/settings/performance_page/performance_page.ts index ebc67cc..f1a2191 100644 --- a/chrome/browser/resources/settings/performance_page/performance_page.ts +++ b/chrome/browser/resources/settings/performance_page/performance_page.ts
@@ -1,8 +1,7 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. +// Copyright 2022 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off import '../controls/settings_toggle_button.js'; import './tab_discard_exception_list.js'; @@ -11,11 +10,17 @@ import {SettingsToggleButtonElement} from '../controls/settings_toggle_button.js'; import {loadTimeData} from '../i18n_setup.js'; import {OpenWindowProxyImpl} from '../open_window_proxy.js'; +import {PrefsMixin} from '../prefs/prefs_mixin.js'; import {PerformanceBrowserProxy, PerformanceBrowserProxyImpl} from './performance_browser_proxy.js'; +import {PerformanceMetricsProxy, PerformanceMetricsProxyImpl} from './performance_metrics_proxy.js'; import {getTemplate} from './performance_page.html.js'; import {TabDiscardExceptionListElement} from './tab_discard_exception_list.js'; -// clang-format on + +export const HIGH_EFFICIENCY_MODE_PREF = + 'performance_tuning.high_efficiency_mode.enabled'; + +const SettingsPerformancePageElementBase = PrefsMixin(PolymerElement); export interface SettingsPerformancePageElement { $: { @@ -24,7 +29,8 @@ }; } -export class SettingsPerformancePageElement extends PolymerElement { +export class SettingsPerformancePageElement extends + SettingsPerformancePageElementBase { static get is() { return 'settings-performance-page'; } @@ -33,17 +39,10 @@ return getTemplate(); } - static get properties() { - return { - prefs: { - type: Object, - notify: true, - }, - }; - } - private browserProxy_: PerformanceBrowserProxy = PerformanceBrowserProxyImpl.getInstance(); + private metricsProxy_: PerformanceMetricsProxy = + PerformanceMetricsProxyImpl.getInstance(); private onLearnMoreOrSendFeedbackClick_(e: CustomEvent<string>) { switch (e.detail) { @@ -56,6 +55,11 @@ break; } } + + private onChange_() { + this.metricsProxy_.recordHighEfficiencyModeChanged( + this.getPref(HIGH_EFFICIENCY_MODE_PREF).value); + } } declare global {
diff --git a/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.html b/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.html index 991e02e9..43aaa53 100644 --- a/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.html +++ b/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.html
@@ -21,7 +21,7 @@ <div id="outer" class="layout vertical list-frame"> <div id="container" class="scroll-container" scrollable> <iron-list id="list" items="[[siteList_]]" scroll-target="container" - preserve-focus risk-selection> + preserve-focus risk-selection class="cr-separators"> <template> <tab-discard-exception-entry site="[[item]]" first$="[[!index]]" tabindex$="[[tabIndex]]" iron-list-tab-index="[[tabIndex]]"
diff --git a/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.ts b/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.ts index dd35e12..9847ede1 100644 --- a/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.ts +++ b/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.ts
@@ -22,6 +22,7 @@ import {PrefsMixin} from '../prefs/prefs_mixin.js'; +import {HighEfficiencyModeExceptionListAction, PerformanceMetricsProxy, PerformanceMetricsProxyImpl} from './performance_metrics_proxy.js'; import {getTemplate} from './tab_discard_exception_list.html.js'; export interface TabDiscardExceptionListElement { @@ -36,7 +37,7 @@ const TabDiscardExceptionListElementBase = CrScrollableMixin(ListPropertyUpdateMixin(PrefsMixin(PolymerElement))); -const TAB_DISCARD_EXCEPTIONS_PREF = +export const TAB_DISCARD_EXCEPTIONS_PREF = 'performance_tuning.tab_discarding.exceptions'; export class TabDiscardExceptionListElement extends @@ -89,6 +90,9 @@ private selectedRule_: string; private showDialog_: boolean; + private metricsProxy_: PerformanceMetricsProxy = + PerformanceMetricsProxyImpl.getInstance(); + private hasSites_(): boolean { return this.siteList_.length > 0; } @@ -127,14 +131,20 @@ TAB_DISCARD_EXCEPTIONS_PREF, this.selectedRule_, newRule); } } + this.metricsProxy_.recordExceptionListAction( + HighEfficiencyModeExceptionListAction.EDIT); return; } // add dialog this.appendPrefListItem(TAB_DISCARD_EXCEPTIONS_PREF, newRule); + this.metricsProxy_.recordExceptionListAction( + HighEfficiencyModeExceptionListAction.ADD); } private onDeleteClick_() { this.deletePrefListItem(TAB_DISCARD_EXCEPTIONS_PREF, this.selectedRule_); + this.metricsProxy_.recordExceptionListAction( + HighEfficiencyModeExceptionListAction.REMOVE); this.$.menu.get().close(); }
diff --git a/chrome/browser/resources/settings/settings.ts b/chrome/browser/resources/settings/settings.ts index 464cc06..82c156f 100644 --- a/chrome/browser/resources/settings/settings.ts +++ b/chrome/browser/resources/settings/settings.ts
@@ -56,12 +56,13 @@ export {ProfileInfo, ProfileInfoBrowserProxy, ProfileInfoBrowserProxyImpl} from './people_page/profile_info_browser_proxy.js'; export {MAX_SIGNIN_PROMO_IMPRESSION, SettingsSyncAccountControlElement} from './people_page/sync_account_control.js'; export {PageStatus, StatusAction, StoredAccount, SyncBrowserProxy, SyncBrowserProxyImpl, SyncPrefs, syncPrefsIndividualDataTypes, SyncStatus, TrustedVaultBannerState} from './people_page/sync_browser_proxy.js'; -export {SettingsBatteryPageElement} from './performance_page/battery_page.js'; +export {BATTERY_SAVER_MODE_PREF, SettingsBatteryPageElement} from './performance_page/battery_page.js'; export {PerformanceBrowserProxy, PerformanceBrowserProxyImpl} from './performance_page/performance_browser_proxy.js'; -export {SettingsPerformancePageElement} from './performance_page/performance_page.js'; +export {BatterySaverModeState, HighEfficiencyModeExceptionListAction, PerformanceMetricsProxy, PerformanceMetricsProxyImpl} from './performance_page/performance_metrics_proxy.js'; +export {HIGH_EFFICIENCY_MODE_PREF, SettingsPerformancePageElement} from './performance_page/performance_page.js'; export {MAX_TAB_DISCARD_EXCEPTION_RULE_LENGTH, SUBMIT_EVENT, TabDiscardExceptionDialogElement} from './performance_page/tab_discard_exception_dialog.js'; export {TabDiscardExceptionEntryElement} from './performance_page/tab_discard_exception_entry.js'; -export {TabDiscardExceptionListElement} from './performance_page/tab_discard_exception_list.js'; +export {TAB_DISCARD_EXCEPTIONS_PREF, TabDiscardExceptionListElement} from './performance_page/tab_discard_exception_list.js'; export {prefToString, stringToPrefValue} from './prefs/pref_util.js'; export {SettingsPrefsElement} from './prefs/prefs.js'; export {PrefsMixin, PrefsMixinInterface} from './prefs/prefs_mixin.js';
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java index bfd963c..c1347f7 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
@@ -82,7 +82,7 @@ private final Tracker mFeatureEngagementTracker; private final @LinkGeneration int mLinkGenerationStatusForMetrics; private final LinkToggleMetricsDetails mLinkToggleMetricsDetails; - private final Supplier<Profile> mProfileSupplier; + private final Profile mProfile; /** * Constructs a new {@link ChromeProvidedSharingOptionsProvider}. @@ -106,7 +106,7 @@ * generation, sharing text from successful link-to-text generation, or sharing link-to-text. * @param linkToggleMetricsDetails {@link LinkToggleMetricsDetails} for recording the final * toggle state. - * * @param profileSupplier A profile supplier to pull the current profile of the User. + * * @param profile The current profile of the User. */ ChromeProvidedSharingOptionsProvider(Activity activity, WindowAndroid windowAndroid, Supplier<Tab> tabProvider, BottomSheetController bottomSheetController, @@ -115,7 +115,7 @@ ChromeOptionShareCallback chromeOptionShareCallback, ImageEditorModuleProvider imageEditorModuleProvider, Tracker featureEngagementTracker, String url, @LinkGeneration int linkGenerationStatusForMetrics, - LinkToggleMetricsDetails linkToggleMetricsDetails, Supplier<Profile> profileSupplier) { + LinkToggleMetricsDetails linkToggleMetricsDetails, Profile profile) { mActivity = activity; mWindowAndroid = windowAndroid; mTabProvider = tabProvider; @@ -131,7 +131,7 @@ mUrl = url; mLinkGenerationStatusForMetrics = linkGenerationStatusForMetrics; mLinkToggleMetricsDetails = linkToggleMetricsDetails; - mProfileSupplier = profileSupplier; + mProfile = profile; mOrderedFirstPartyOptions = new ArrayList<>(); initializeFirstPartyOptionsInOrder(); } @@ -242,7 +242,7 @@ mIconContentDescription, (view) -> { ShareSheetCoordinator.recordShareMetrics(mFeatureNameForMetrics, mLinkGenerationStatusForMetrics, mLinkToggleMetricsDetails, - mShareStartTime, mProfileSupplier.get()); + mShareStartTime, mProfile); if (mHideBottomSheetContentOnTap) { mBottomSheetController.hideContent(mBottomSheetContent, true); } @@ -285,7 +285,6 @@ * mOrderedFirstPartyOptions} in the order they should appear. */ private void initializeFirstPartyOptionsInOrder() { - Profile profile = mProfileSupplier.get(); boolean enableAllUpcomingSharingFeatures = ChromeFeatureList.isEnabled(ChromeFeatureList.UPCOMING_SHARING_FEATURES); if (ChromeFeatureList.isEnabled(ChromeFeatureList.WEBNOTES_STYLIZE)) { @@ -307,7 +306,7 @@ mOrderedFirstPartyOptions.add(createCopyFirstPartyOption()); mOrderedFirstPartyOptions.add(createCopyTextFirstPartyOption()); Optional<Integer> sendTabToSelfDisplayReason = - SendTabToSelfAndroidBridge.getEntryPointDisplayReason(profile, mUrl); + SendTabToSelfAndroidBridge.getEntryPointDisplayReason(mProfile, mUrl); if (sendTabToSelfDisplayReason.isPresent() || !ChromeFeatureList.isEnabled(ChromeFeatureList.SEND_TAB_TO_SELF_SIGNIN_PROMO)) { mOrderedFirstPartyOptions.add(createSendTabToSelfFirstPartyOption()); @@ -315,7 +314,7 @@ if (!mIsIncognito) { mOrderedFirstPartyOptions.add(createQrCodeFirstPartyOption()); } - if (mTabProvider.hasValue() && UserPrefs.get(profile).getBoolean(Pref.PRINTING_ENABLED)) { + if (mTabProvider.hasValue() && UserPrefs.get(mProfile).getBoolean(Pref.PRINTING_ENABLED)) { mOrderedFirstPartyOptions.add(createPrintingFirstPartyOption()); } mOrderedFirstPartyOptions.add(createSaveImageFirstPartyOption()); @@ -449,9 +448,9 @@ .setIcon(R.drawable.send_tab, R.string.send_tab_to_self_share_activity_title) .setFeatureNameForMetrics("SharingHubAndroid.SendTabToSelfSelected") .setOnClickCallback((view) -> { - SendTabToSelfCoordinator sttsCoordinator = new SendTabToSelfCoordinator( - mActivity, mWindowAndroid, mUrl, mShareParams.getTitle(), - mBottomSheetController, mProfileSupplier.get()); + SendTabToSelfCoordinator sttsCoordinator = + new SendTabToSelfCoordinator(mActivity, mWindowAndroid, mUrl, + mShareParams.getTitle(), mBottomSheetController, mProfile); sttsCoordinator.show(); }) .build();
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinator.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinator.java index 6c60c119..b95695bf 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinator.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinator.java
@@ -69,7 +69,7 @@ private final BottomSheetObserver mBottomSheetObserver; private final LargeIconBridge mIconBridge; private final Tracker mFeatureEngagementTracker; - private final Supplier<Profile> mProfileSupplier; + private final Profile mProfile; private long mShareStartTime; private boolean mExcludeFirstParty; @@ -99,7 +99,7 @@ * @param modelBuilder The {@link ShareSheetPropertyModelBuilder} for the share sheet. * @param isIncognito Whether the share sheet was opened in incognito mode or not. * @param imageEditorModuleProvider Image Editor module entry point if present in the APK. - * @param profileSupplier A profile supplier to pull the current profile of the User. + * @param profile The current profile of the User. */ // TODO(crbug/1022172): Should be package-protected once modularization is complete. public ShareSheetCoordinator(BottomSheetController controller, @@ -107,7 +107,7 @@ ShareSheetPropertyModelBuilder modelBuilder, Callback<Tab> printTab, LargeIconBridge iconBridge, boolean isIncognito, ImageEditorModuleProvider imageEditorModuleProvider, Tracker featureEngagementTracker, - Supplier<Profile> profileSupplier) { + Profile profile) { mBottomSheetController = controller; mLifecycleDispatcher = lifecycleDispatcher; mLifecycleDispatcher.register(this); @@ -144,10 +144,10 @@ mBottomSheetController.addObserver(mBottomSheetObserver); mIconBridge = iconBridge; mFeatureEngagementTracker = featureEngagementTracker; - mProfileSupplier = profileSupplier; + mProfile = profile; mShareSheetUsageRankingHelper = new ShareSheetUsageRankingHelper(mBottomSheetController, mBottomSheet, mShareStartTime, mLinkGenerationStatusForMetrics, - mLinkToggleMetricsDetails, mPropertyModelBuilder, mProfileSupplier); + mLinkToggleMetricsDetails, mPropertyModelBuilder, mProfile); } protected void destroy() { @@ -298,7 +298,7 @@ mWindowAndroid, mTabProvider, mBottomSheetController, mBottomSheet, shareParams, mPrintTabCallback, mIsIncognito, mShareStartTime, this, mImageEditorModuleProvider, mFeatureEngagementTracker, getUrlToShare(shareParams, chromeShareExtras), - mLinkGenerationStatusForMetrics, mLinkToggleMetricsDetails, mProfileSupplier); + mLinkGenerationStatusForMetrics, mLinkToggleMetricsDetails, mProfile); mIsMultiWindow = ApiCompatibilityUtils.isInMultiWindowMode(activity); return mChromeProvidedSharingOptionsProvider.getPropertyModels(
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetUsageRankingHelper.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetUsageRankingHelper.java index 84ca37d..d8e387f 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetUsageRankingHelper.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetUsageRankingHelper.java
@@ -13,7 +13,6 @@ import org.chromium.base.Callback; import org.chromium.base.ContextUtils; -import org.chromium.base.supplier.Supplier; import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.profiles.Profile; @@ -67,7 +66,7 @@ private final BottomSheetController mBottomSheetController; private final ShareSheetPropertyModelBuilder mPropertyModelBuilder; - private final Supplier<Profile> mProfileSupplier; + private final Profile mProfile; private ShareSheetBottomSheetContent mBottomSheet; private long mShareStartTime; @@ -90,16 +89,15 @@ * @param linkToggleMetricsDetails {@link LinkToggleMetricsDetails} to record link toggle * metrics, and contains the {@link LinkToggleState} to update to. * @param propertyModelBuilder The {@link ShareSheetPropertyModelBuilder} for the share sheet. - * @param profileSupplier A profile supplier to pull the current profile of the User. + * @param profile The current profile of the User. */ ShareSheetUsageRankingHelper(BottomSheetController bottomSheetController, ShareSheetBottomSheetContent bottomSheet, long shareStartTime, int linkGenerationStatusForMetrics, LinkToggleMetricsDetails linkToggleMetricsDetails, - ShareSheetPropertyModelBuilder propertyModelBuilder, - Supplier<Profile> profileSupplier) { + ShareSheetPropertyModelBuilder propertyModelBuilder, Profile profile) { mBottomSheetController = bottomSheetController; mPropertyModelBuilder = propertyModelBuilder; - mProfileSupplier = profileSupplier; + mProfile = profile; mBottomSheet = bottomSheet; mShareStartTime = shareStartTime; mLinkGenerationStatusForMetrics = linkGenerationStatusForMetrics; @@ -115,9 +113,6 @@ void createThirdPartyPropertyModelsFromUsageRanking(Activity activity, ShareParams params, Set<Integer> contentTypes, boolean saveLastUsed, Callback<List<PropertyModel>> callback) { - Profile profile = mProfileSupplier.get(); - assert profile != null; - String type = contentTypesToTypeForRanking(contentTypes); PackageManager pm = ContextUtils.getApplicationContext().getPackageManager(); @@ -165,10 +160,10 @@ // TODO(ellyjones): Does !saveLastUsed always imply that we shouldn't incorporate the share // into our ranking? - boolean persist = !profile.isOffTheRecord() && saveLastUsed; + boolean persist = !mProfile.isOffTheRecord() && saveLastUsed; ShareRankingBridge.rank( - profile, type, availableActivities, fold, length, persist, ranking -> { + mProfile, type, availableActivities, fold, length, persist, ranking -> { onThirdPartyShareTargetsReceived( callback, resolveInfos, activity, params, saveLastUsed, ranking); }); @@ -258,12 +253,11 @@ /*accessibilityDescription=*/null, (shareParams) -> { - Profile profile = mProfileSupplier.get(); ShareSheetCoordinator.recordShareMetrics("SharingHubAndroid.MoreSelected", mLinkGenerationStatusForMetrics, mLinkToggleMetricsDetails, - mShareStartTime, profile); + mShareStartTime, mProfile); mBottomSheetController.hideContent(mBottomSheet, true); - ShareHelper.showDefaultShareUi(params, profile, saveLastUsed); + ShareHelper.showDefaultShareUi(params, mProfile, saveLastUsed); // Reset callback to prevent cancel() being called when the custom sheet is // closed. The callback will be called by ShareHelper on actions from the // default share UI.
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java index 442dfda..5b058efe 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java
@@ -13,7 +13,6 @@ import android.app.Activity; import android.os.Build; -import android.os.Looper; import android.support.test.runner.lifecycle.Stage; import android.view.View; @@ -33,10 +32,10 @@ import org.mockito.MockitoAnnotations; import org.chromium.base.metrics.RecordHistogram; -import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.supplier.Supplier; import org.chromium.base.test.BaseActivityTestRule; import org.chromium.base.test.util.ApplicationTestUtils; +import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.JniMocker; import org.chromium.base.test.util.UserActionTester; @@ -75,6 +74,7 @@ /** * Unit tests {@link ChromeProvidedSharingOptionsProvider}. */ +@Batch(Batch.UNIT_TESTS) @RunWith(ChromeJUnit4ClassRunner.class) @EnableFeatures( {ChromeFeatureList.CHROME_SHARE_LONG_SCREENSHOT, ChromeFeatureList.WEBNOTES_STYLIZE}) @@ -122,11 +122,9 @@ private Activity mActivity; private ChromeProvidedSharingOptionsProvider mChromeProvidedSharingOptionsProvider; private UserActionTester mActionTester; - private ObservableSupplierImpl<Profile> mProfileSupplier; @Before public void setUp() { - Looper.prepare(); NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess(); MockitoAnnotations.initMocks(this); mJniMocker.mock(UserPrefsJni.TEST_HOOKS, mUserPrefsNatives); @@ -143,8 +141,6 @@ Mockito.doNothing().when(mBottomSheetController).hideContent(any(), anyBoolean()); TrackerFactory.setTrackerForTests(mTracker); - mProfileSupplier = new ObservableSupplierImpl<>(); - mProfileSupplier.set(mProfile); mActivityTestRule.launchActivity(null); ApplicationTestUtils.waitForActivityState(mActivityTestRule.getActivity(), Stage.RESUMED); mActivity = mActivityTestRule.getActivity(); @@ -489,7 +485,7 @@ /*imageEditorModuleProvider*/ null, mTracker, URL, linkGenerationStatus, new LinkToggleMetricsDetails( LinkToggleState.COUNT, DetailedContentType.NOT_SPECIFIED), - mProfileSupplier); + mProfile); } private boolean propertyModelsContain(List<PropertyModel> propertyModels, int labelId) { @@ -514,7 +510,6 @@ private void assertCorrectLinkGenerationMetrics( List<PropertyModel> propertyModels, @LinkGeneration int linkGenerationStatus) { - Looper.prepare(); mActionTester = new UserActionTester(); View view = Mockito.mock(View.class); for (PropertyModel propertyModel : propertyModels) {
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinatorTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinatorTest.java index 77733e7..eaf33771 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinatorTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinatorTest.java
@@ -27,7 +27,6 @@ import org.robolectric.Robolectric; import org.robolectric.annotation.LooperMode; -import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.supplier.Supplier; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.JniMocker; @@ -87,7 +86,6 @@ private Activity mActivity; private ShareParams mParams; private ShareSheetCoordinator mShareSheetCoordinator; - private ObservableSupplierImpl<Profile> mProfileSupplier; @Before public void setUp() { @@ -115,15 +113,12 @@ when(mDistillerUrlUtilsJniMock.getOriginalUrlFromDistillerUrl(anyString())) .thenReturn(JUnitTestGURLs.getGURL(MOCK_URL)); TrackerFactory.setTrackerForTests(mTracker); - mProfileSupplier = new ObservableSupplierImpl<>(); - mProfileSupplier.set(mProfile); mParams = new ShareParams.Builder(mWindow, "title", MOCK_URL) .setCallback(mTargetChosenCallback) .build(); - mShareSheetCoordinator = - new ShareSheetCoordinator(mController, mLifecycleDispatcher, mTabProvider, - mPropertyModelBuilder, null, null, false, null, null, mProfileSupplier); + mShareSheetCoordinator = new ShareSheetCoordinator(mController, mLifecycleDispatcher, + mTabProvider, mPropertyModelBuilder, null, null, false, null, null, mProfile); } @Test
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetUsageRankingHelperTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetUsageRankingHelperTest.java index ad6ecf6..74f5c1a 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetUsageRankingHelperTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetUsageRankingHelperTest.java
@@ -27,7 +27,6 @@ import org.robolectric.Robolectric; import org.robolectric.annotation.LooperMode; -import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.JniMocker; @@ -89,8 +88,6 @@ private Activity mActivity; private ShareParams mParams; private ShareSheetUsageRankingHelper mShareSheetUsageRankingHelper; - private ObservableSupplierImpl<Profile> mProfileSupplier; - private long mShareStartTime; private @LinkGeneration int mLinkGenerationStatusForMetrics = LinkGeneration.MAX; private LinkToggleMetricsDetails mLinkToggleMetricsDetails = new LinkToggleMetricsDetails(LinkToggleState.COUNT, DetailedContentType.NOT_SPECIFIED); @@ -107,16 +104,13 @@ when(mContentTypes.contains(ShareSheetPropertyModelBuilder.ContentType.IMAGE)) .thenReturn(true); - mProfileSupplier = new ObservableSupplierImpl<>(); - mProfileSupplier.set(mProfile); - mParams = new ShareParams.Builder(mWindow, "title", MOCK_URL) .setCallback(mTargetChosenCallback) .build(); mShareSheetUsageRankingHelper = new ShareSheetUsageRankingHelper(mBottomSheetController, - mBottomSheet, mShareStartTime, mLinkGenerationStatusForMetrics, - mLinkToggleMetricsDetails, mPropertyModelBuilder, mProfileSupplier); + mBottomSheet, /* shareStartTime=*/1234, mLinkGenerationStatusForMetrics, + mLinkToggleMetricsDetails, mPropertyModelBuilder, mProfile); } @Test
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillCoordinator.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillCoordinator.java index 4adb7a9..4129c72 100644 --- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillCoordinator.java +++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillCoordinator.java
@@ -4,7 +4,7 @@ package org.chromium.chrome.browser.touch_to_fill; -import static org.chromium.chrome.browser.password_manager.PasswordManagerHelper.usesUnifiedPasswordManagerUI; +import static org.chromium.chrome.browser.password_manager.PasswordManagerHelper.usesUnifiedPasswordManagerBranding; import android.content.Context; @@ -35,7 +35,7 @@ TouchToFillComponent.Delegate delegate) { mMediator.initialize(context, delegate, mModel, new LargeIconBridge(Profile.getLastUsedRegularProfile()), - context.getResources().getDimensionPixelSize(usesUnifiedPasswordManagerUI() + context.getResources().getDimensionPixelSize(usesUnifiedPasswordManagerBranding() ? R.dimen.touch_to_fill_favicon_size_modern : R.dimen.touch_to_fill_favicon_size)); setUpModelChangeProcessors(mModel, new TouchToFillView(context, sheetController));
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java index 93ea8f1..43a7aa5 100644 --- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java +++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java
@@ -4,7 +4,7 @@ package org.chromium.chrome.browser.touch_to_fill; -import static org.chromium.chrome.browser.password_manager.PasswordManagerHelper.usesUnifiedPasswordManagerUI; +import static org.chromium.chrome.browser.password_manager.PasswordManagerHelper.usesUnifiedPasswordManagerBranding; import android.content.Context; import android.graphics.Canvas; @@ -77,7 +77,7 @@ */ private int selectBackgroundDrawable( int position, boolean containsFillButton, int itemCount) { - if (!usesUnifiedPasswordManagerUI()) { + if (!usesUnifiedPasswordManagerBranding()) { return R.drawable.touch_to_fill_credential_background; } if (containsFillButton) { // Round all the corners of the only item. @@ -167,7 +167,7 @@ : View.LAYOUT_DIRECTION_LTR; mContentView.setLayoutDirection(layoutDirection); - if (usesUnifiedPasswordManagerUI()) { + if (usesUnifiedPasswordManagerBranding()) { mSheetItemListView.addItemDecoration(new HorizontalDividerItemDecoration( mContentView.getResources().getDimensionPixelSize( R.dimen.touch_to_fill_sheet_items_spacing), @@ -371,10 +371,10 @@ totalHeight += getHeightWithMargins(child, false); } // Since the last element is fully visible, add the conclusive margin. - totalHeight += - getContentView().getResources().getDimensionPixelSize(usesUnifiedPasswordManagerUI() - ? R.dimen.touch_to_fill_sheet_bottom_padding_button_modern - : R.dimen.touch_to_fill_sheet_bottom_padding_button); + totalHeight += getContentView().getResources().getDimensionPixelSize( + usesUnifiedPasswordManagerBranding() + ? R.dimen.touch_to_fill_sheet_bottom_padding_button_modern + : R.dimen.touch_to_fill_sheet_bottom_padding_button); return totalHeight; } @@ -425,7 +425,8 @@ private @Px int getInsetDisplayWidth() { return mContentView.getContext().getResources().getDisplayMetrics().widthPixels - 2 - * mContentView.getResources().getDimensionPixelSize(usesUnifiedPasswordManagerUI() + * mContentView.getResources().getDimensionPixelSize( + usesUnifiedPasswordManagerBranding() ? R.dimen.touch_to_fill_sheet_margin_modern : R.dimen.touch_to_fill_sheet_margin); }
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java index 474ffb4..5770f64 100644 --- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java +++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java
@@ -4,7 +4,7 @@ package org.chromium.chrome.browser.touch_to_fill; -import static org.chromium.chrome.browser.password_manager.PasswordManagerHelper.usesUnifiedPasswordManagerUI; +import static org.chromium.chrome.browser.password_manager.PasswordManagerHelper.usesUnifiedPasswordManagerBranding; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.CREDENTIAL; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.FAVICON_OR_FALLBACK; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.FORMATTED_ORIGIN; @@ -95,25 +95,27 @@ switch (itemType) { case ItemType.HEADER: return new TouchToFillViewHolder(parent, - usesUnifiedPasswordManagerUI() ? R.layout.touch_to_fill_header_item_modern - : R.layout.touch_to_fill_header_item, + usesUnifiedPasswordManagerBranding() + ? R.layout.touch_to_fill_header_item_modern + : R.layout.touch_to_fill_header_item, TouchToFillViewBinder::bindHeaderView); case ItemType.CREDENTIAL: return new TouchToFillViewHolder(parent, - usesUnifiedPasswordManagerUI() + usesUnifiedPasswordManagerBranding() ? R.layout.touch_to_fill_credential_item_modern : R.layout.touch_to_fill_credential_item, TouchToFillViewBinder::bindCredentialView); case ItemType.WEBAUTHN_CREDENTIAL: return new TouchToFillViewHolder(parent, - usesUnifiedPasswordManagerUI() + usesUnifiedPasswordManagerBranding() ? R.layout.touch_to_fill_webauthn_credential_item_modern : R.layout.touch_to_fill_webauthn_credential_item, TouchToFillViewBinder::bindWebAuthnCredentialView); case ItemType.FILL_BUTTON: return new TouchToFillViewHolder(parent, - usesUnifiedPasswordManagerUI() ? R.layout.touch_to_fill_fill_button_modern - : R.layout.touch_to_fill_fill_button, + usesUnifiedPasswordManagerBranding() + ? R.layout.touch_to_fill_fill_button_modern + : R.layout.touch_to_fill_fill_button, TouchToFillViewBinder::bindFillButtonView); } assert false : "Cannot create view for ItemType: " + itemType; @@ -291,9 +293,10 @@ ImageView sheetHeaderImage = view.findViewById(R.id.touch_to_fill_sheet_header_image); sheetHeaderImage.setImageDrawable(AppCompatResources.getDrawable(view.getContext(), - usesUnifiedPasswordManagerUI() ? PasswordManagerResourceProviderFactory.create() - .getPasswordManagerIcon() - : model.get(IMAGE_DRAWABLE_ID))); + usesUnifiedPasswordManagerBranding() + ? PasswordManagerResourceProviderFactory.create() + .getPasswordManagerIcon() + : model.get(IMAGE_DRAWABLE_ID))); } else { assert false : "Unhandled update to property:" + key; }
diff --git a/chrome/browser/ui/android/omnibox/BUILD.gn b/chrome/browser/ui/android/omnibox/BUILD.gn index b51643d..03ef64a 100644 --- a/chrome/browser/ui/android/omnibox/BUILD.gn +++ b/chrome/browser/ui/android/omnibox/BUILD.gn
@@ -200,6 +200,7 @@ "//content/public/android:content_java", "//third_party/android_deps:guava_android_java", "//third_party/android_deps:material_design_java", + "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_appcompat_appcompat_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java",
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/CachedZeroSuggestionsManager.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/CachedZeroSuggestionsManager.java index 356c618..125c995 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/CachedZeroSuggestionsManager.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/CachedZeroSuggestionsManager.java
@@ -8,9 +8,6 @@ import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.KEY_ZERO_SUGGEST_DESCRIPTION_PREFIX; import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.KEY_ZERO_SUGGEST_DISPLAY_TEXT_PREFIX; import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.KEY_ZERO_SUGGEST_GROUP_ID_PREFIX; -import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.KEY_ZERO_SUGGEST_HEADER_GROUP_COLLAPSED_BY_DEFAULT_PREFIX; -import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.KEY_ZERO_SUGGEST_HEADER_GROUP_ID_PREFIX; -import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.KEY_ZERO_SUGGEST_HEADER_GROUP_TITLE_PREFIX; import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.KEY_ZERO_SUGGEST_IS_DELETABLE_PREFIX; import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.KEY_ZERO_SUGGEST_IS_SEARCH_TYPE_PREFIX; import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.KEY_ZERO_SUGGEST_NATIVE_SUBTYPES_PREFIX; @@ -26,6 +23,8 @@ import androidx.annotation.VisibleForTesting; import androidx.collection.ArraySet; +import com.google.protobuf.InvalidProtocolBufferException; + import org.chromium.base.Function; import org.chromium.chrome.browser.omnibox.MatchClassificationStyle; import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType; @@ -197,23 +196,8 @@ */ private static void cacheGroupsDetails( SharedPreferencesManager prefs, GroupsInfo groupsDetails) { - final var groupConfigs = groupsDetails.getGroupConfigsMap(); - final int size = groupConfigs.size(); - prefs.writeInt(ChromePreferenceKeys.KEY_ZERO_SUGGEST_HEADER_LIST_SIZE, size); - - int i = 0; - for (var entry : groupConfigs.entrySet()) { - final GroupConfig details = entry.getValue(); - String title = details.getHeaderText(); - boolean collapsedByDefault = details.getVisibility() == GroupConfig.Visibility.HIDDEN; - - prefs.writeInt(KEY_ZERO_SUGGEST_HEADER_GROUP_ID_PREFIX.createKey(i), entry.getKey()); - prefs.writeString(KEY_ZERO_SUGGEST_HEADER_GROUP_TITLE_PREFIX.createKey(i), title); - prefs.writeBoolean( - KEY_ZERO_SUGGEST_HEADER_GROUP_COLLAPSED_BY_DEFAULT_PREFIX.createKey(i), - collapsedByDefault); - i++; - } + prefs.writeString(ChromePreferenceKeys.OMNIBOX_CACHED_ZERO_SUGGEST_GROUPS_INFO, + Base64.encodeToString(groupsDetails.toByteArray(), Base64.DEFAULT)); } /** @@ -225,32 +209,22 @@ @NonNull @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) static GroupsInfo readCachedGroupsDetails(SharedPreferencesManager prefs) { - final int size = prefs.readInt(ChromePreferenceKeys.KEY_ZERO_SUGGEST_HEADER_LIST_SIZE, 0); - final var builder = GroupsInfo.newBuilder(); + var encoded = prefs.readString( + ChromePreferenceKeys.OMNIBOX_CACHED_ZERO_SUGGEST_GROUPS_INFO, null); - for (int i = 0; i < size; i++) { - int groupId = prefs.readInt(KEY_ZERO_SUGGEST_HEADER_GROUP_ID_PREFIX.createKey(i), - AutocompleteMatch.INVALID_GROUP); - String groupTitle = - prefs.readString(KEY_ZERO_SUGGEST_HEADER_GROUP_TITLE_PREFIX.createKey(i), null); - boolean collapsedByDefault = prefs.readBoolean( - KEY_ZERO_SUGGEST_HEADER_GROUP_COLLAPSED_BY_DEFAULT_PREFIX.createKey(i), false); - - if (groupTitle == null) { - // Group definition incomplete. - // Note that an empty string is a valid group title. - continue; + if (encoded != null) { + try { + var serialized = Base64.decode(encoded, Base64.DEFAULT); + return GroupsInfo.parseFrom(serialized); + } catch (IllegalArgumentException e) { + // Bad Base64 encoding. + } catch (InvalidProtocolBufferException e) { + // Bad protobuf. } - - builder.putGroupConfigs(groupId, - GroupConfig.newBuilder() - .setHeaderText(groupTitle) - .setVisibility(collapsedByDefault - ? GroupConfig.Visibility.HIDDEN - : GroupConfig.Visibility.DEFAULT_VISIBLE) - .build()); + prefs.removeKey(ChromePreferenceKeys.OMNIBOX_CACHED_ZERO_SUGGEST_GROUPS_INFO); } - return builder.build(); + // Failed to decode or no cached groups info. + return GroupsInfo.newBuilder().build(); } /**
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/CachedZeroSuggestionsManagerUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/CachedZeroSuggestionsManagerUnitTest.java index c1c0fe3..e0f97e3 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/CachedZeroSuggestionsManagerUnitTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/CachedZeroSuggestionsManagerUnitTest.java
@@ -47,30 +47,8 @@ * they're not. Note that order is just as relevant as the content for caching. */ void assertAutocompleteResultEquals(AutocompleteResult data1, AutocompleteResult data2) { - assertGroupsInfoEquals(data1.getGroupsInfo(), data2.getGroupsInfo()); - final List<AutocompleteMatch> list1 = data1.getSuggestionsList(); - final List<AutocompleteMatch> list2 = data2.getSuggestionsList(); - Assert.assertEquals(list1, list2); - } - - /** - * Compare two instances of GroupsInfo to see if they are same, asserting if - * they're not. Note that right now CachedZeroSuggestManager does not persist the - * section info, so we compare individual fields. - */ - void assertGroupsInfoEquals(GroupsInfo info1, GroupsInfo info2) { - var groups1 = info1.getGroupConfigsMap(); - var groups2 = info2.getGroupConfigsMap(); - Assert.assertEquals(groups1.size(), groups2.size()); - - for (var entry : groups1.entrySet()) { - Assert.assertTrue(groups2.containsKey(entry.getKey())); - var group1 = entry.getValue(); - var group2 = groups2.get(entry.getKey()); - - Assert.assertEquals(group1.getHeaderText(), group2.getHeaderText()); - Assert.assertEquals(group1.getVisibility(), group2.getVisibility()); - } + Assert.assertEquals(data1.getSuggestionsList(), data2.getSuggestionsList()); + Assert.assertEquals(data1.getGroupsInfo(), data2.getGroupsInfo()); } /** @@ -186,6 +164,7 @@ @Test @SmallTest public void groupsDetails_restoreInvalidGroupsDetailsFromCache() { + final SharedPreferencesManager manager = SharedPreferencesManager.getInstance(); var groupsDetails = GroupsInfo.newBuilder() .putGroupConfigs(20, SECTION_2_EXPANDED_WITH_HEADER) .putGroupConfigs(30, SECTION_1_EXPANDED_NO_HEADER) @@ -200,13 +179,26 @@ AutocompleteResult dataFromCache = CachedZeroSuggestionsManager.readFromCache(); assertAutocompleteResultEquals(dataToCache, dataFromCache); - // Partially remove data, rendering details invalid - check it no longer works. - final SharedPreferencesManager manager = SharedPreferencesManager.getInstance(); - manager.removeKey( - ChromePreferenceKeys.KEY_ZERO_SUGGEST_HEADER_GROUP_TITLE_PREFIX.createKey(0)); - manager.removeKey( - ChromePreferenceKeys.KEY_ZERO_SUGGEST_HEADER_GROUP_TITLE_PREFIX.createKey(1)); + // Truncate the data. + var data = manager.readString( + ChromePreferenceKeys.OMNIBOX_CACHED_ZERO_SUGGEST_GROUPS_INFO, null); + data = data.substring(0, data.length() - 10); + manager.writeString(ChromePreferenceKeys.OMNIBOX_CACHED_ZERO_SUGGEST_GROUPS_INFO, data); + dataFromCache = CachedZeroSuggestionsManager.readFromCache(); + assertAutocompleteResultEquals(dataFromCache, AutocompleteResult.EMPTY_RESULT); + Assert.assertNull(manager.readString( + ChromePreferenceKeys.OMNIBOX_CACHED_ZERO_SUGGEST_GROUPS_INFO, null)); + // Corrupt the data. + manager.writeString( + ChromePreferenceKeys.OMNIBOX_CACHED_ZERO_SUGGEST_GROUPS_INFO, "abcdefgh"); + dataFromCache = CachedZeroSuggestionsManager.readFromCache(); + assertAutocompleteResultEquals(dataFromCache, AutocompleteResult.EMPTY_RESULT); + Assert.assertNull(manager.readString( + ChromePreferenceKeys.OMNIBOX_CACHED_ZERO_SUGGEST_GROUPS_INFO, null)); + + // Remove the data. + manager.removeKey(ChromePreferenceKeys.OMNIBOX_CACHED_ZERO_SUGGEST_GROUPS_INFO); dataFromCache = CachedZeroSuggestionsManager.readFromCache(); assertAutocompleteResultEquals(dataFromCache, AutocompleteResult.EMPTY_RESULT); } @@ -277,39 +269,6 @@ @Test @SmallTest - public void malformedCache_dropsMissingGroupConfig() { - // Clear cache explicitly, otherwise this test will be flaky until the suite is re-executed. - ContextUtils.getAppSharedPreferences().edit().clear().apply(); - - final SharedPreferencesManager manager = SharedPreferencesManager.getInstance(); - - // Write 3 wrong group groupsDetails to the cache - var groupsDetails = - GroupsInfo.newBuilder() - .putGroupConfigs(12, SECTION_2_COLLAPSED_WITH_HEADER) - .putGroupConfigs(34, SECTION_1_EXPANDED_NO_HEADER) - .putGroupConfigs(AutocompleteMatch.INVALID_GROUP, SECTION_INVALID) - .build(); - AutocompleteResult invalidDataToCache = AutocompleteResult.fromCache(null, groupsDetails); - CachedZeroSuggestionsManager.saveToCache(invalidDataToCache); - - // Report that we actually have 4 items in the cache. - manager.writeInt(ChromePreferenceKeys.KEY_ZERO_SUGGEST_HEADER_LIST_SIZE, 4); - - // Read raw suggestions from the cache. Note that the sparse array will only have 3 elements - // because we put one item with INVALID_GROUP, and additional INVALID_GROUP will be deduced - // from missing data with null title and default expanded state set to true. - GroupsInfo rawGroupsDetails = CachedZeroSuggestionsManager.readCachedGroupsDetails(manager); - assertGroupsInfoEquals(rawGroupsDetails, groupsDetails); - - AutocompleteResult wantDataFromCache = AutocompleteResult.fromCache(null, groupsDetails); - AutocompleteResult dataFromCache = CachedZeroSuggestionsManager.readFromCache(); - - assertAutocompleteResultEquals(dataFromCache, wantDataFromCache); - } - - @Test - @SmallTest public void removeInvalidSuggestions_dropsInvalidSuggestionsAndGroupsDetails() { // Write 3 wrong group groupsDetails to the cache var groupsDetailsExpected =
diff --git a/chrome/browser/ui/android/passwords/password_generation_dialog_view_android.cc b/chrome/browser/ui/android/passwords/password_generation_dialog_view_android.cc index 293a7406..07a1a9bc 100644 --- a/chrome/browser/ui/android/passwords/password_generation_dialog_view_android.cc +++ b/chrome/browser/ui/android/passwords/password_generation_dialog_view_android.cc
@@ -60,7 +60,7 @@ std::u16string explanation_text; if (account_info.has_value()) { explanation_text = l10n_util::GetStringFUTF16( - password_manager::features::UsesUnifiedPasswordManagerUi() + password_manager::features::UsesUnifiedPasswordManagerBranding() ? IDS_PASSWORD_GENERATION_DIALOG_DESCRIPTION_UPM_BRANDED : IDS_PASSWORD_GENERATION_DIALOG_DESCRIPTION, base::UTF8ToUTF16(account_info.value().email));
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index 4ca0dc0..6ed6285 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -208,11 +208,6 @@ return TabStripUILayout::GetContainerHeight(); } -void ChromeShellDelegate::BindBluetoothSystemFactory( - mojo::PendingReceiver<device::mojom::BluetoothSystemFactory> receiver) { - content::GetDeviceService().BindBluetoothSystemFactory(std::move(receiver)); -} - void ChromeShellDelegate::BindFingerprint( mojo::PendingReceiver<device::mojom::Fingerprint> receiver) { content::GetDeviceService().BindFingerprint(std::move(receiver));
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.h b/chrome/browser/ui/ash/chrome_shell_delegate.h index 6410030..4884216a 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.h +++ b/chrome/browser/ui/ash/chrome_shell_delegate.h
@@ -44,9 +44,6 @@ bool ShouldWaitForTouchPressAck(gfx::NativeWindow window) override; bool IsTabDrag(const ui::OSExchangeData& drop_data) override; int GetBrowserWebUITabStripHeight() override; - void BindBluetoothSystemFactory( - mojo::PendingReceiver<device::mojom::BluetoothSystemFactory> receiver) - override; void BindFingerprint( mojo::PendingReceiver<device::mojom::Fingerprint> receiver) override; void BindMultiDeviceSetup(
diff --git a/chrome/browser/ui/performance_controls/tab_discard_tab_helper.cc b/chrome/browser/ui/performance_controls/tab_discard_tab_helper.cc index 0d7f81a..1a7e6bf5 100644 --- a/chrome/browser/ui/performance_controls/tab_discard_tab_helper.cc +++ b/chrome/browser/ui/performance_controls/tab_discard_tab_helper.cc
@@ -35,7 +35,7 @@ PreDiscardResourceUsage::FromWebContents(&GetWebContents()); return pre_discard_resource_usage == nullptr ? 0 - : pre_discard_resource_usage->resident_set_size_estimate() * + : pre_discard_resource_usage->resident_set_size_estimate_kb() * kKiloByte; }
diff --git a/chrome/browser/ui/toolbar/app_menu_model_interactive_uitest.cc b/chrome/browser/ui/toolbar/app_menu_model_interactive_uitest.cc index dcc7b1b..854c1c3 100644 --- a/chrome/browser/ui/toolbar/app_menu_model_interactive_uitest.cc +++ b/chrome/browser/ui/toolbar/app_menu_model_interactive_uitest.cc
@@ -105,11 +105,8 @@ })) .Build()) .AddStep(ui::InteractionSequence::StepBuilder() - .SetType(ui::InteractionSequence::StepType::kHidden) - .SetElementID(kPrimaryTabPageElementId) - .Build()) - .AddStep(ui::InteractionSequence::StepBuilder() .SetType(ui::InteractionSequence::StepType::kShown) + .SetTransitionOnlyOnEvent(true) .SetElementID(kPrimaryTabPageElementId) .SetStartCallback(base::BindLambdaForTesting( [&](ui::InteractionSequence*,
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc b/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc index a768cfc..3c750df9 100644 --- a/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc +++ b/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc
@@ -6,6 +6,7 @@ #include "base/callback.h" #include "base/files/file_path.h" +#include "base/metrics/histogram_functions.h" #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/download/bubble/download_bubble_controller.h" @@ -579,6 +580,7 @@ if (ui_info_.has_subpage) { navigation_handler_->OpenSecurityDialog(this); } else { + RecordDownloadOpenButtonPressed(model_->IsDone()); DownloadCommands(model_->GetWeakPtr()) .ExecuteCommand(DownloadCommands::OPEN_WHEN_COMPLETE); }
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc index 0835134..2c5093a7 100644 --- a/chrome/browser/ui/views/download/download_item_view.cc +++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -20,6 +20,7 @@ #include "base/files/file_path.h" #include "base/location.h" #include "base/memory/raw_ptr.h" +#include "base/metrics/histogram_functions.h" #include "base/notreached.h" #include "base/numerics/math_constants.h" #include "base/ranges/algorithm.h" @@ -1255,6 +1256,7 @@ if (mode_ == download::DownloadItemMode::kNormal) { complete_animation_.End(); announce_accessible_alert_soon_ = true; + RecordDownloadOpenButtonPressed(model_->IsDone()); model_->OpenDownload(); // WARNING: |this| may be deleted! } else {
diff --git a/chrome/browser/ui/views/file_system_access/file_system_access_ui_helpers.cc b/chrome/browser/ui/views/file_system_access/file_system_access_ui_helpers.cc index 3be5ab1..548079a 100644 --- a/chrome/browser/ui/views/file_system_access/file_system_access_ui_helpers.cc +++ b/chrome/browser/ui/views/file_system_access/file_system_access_ui_helpers.cc
@@ -49,7 +49,7 @@ if (show_emphasis) { views::StyledLabel::RangeStyleInfo origin_style; - origin_style.text_style = views::style::STYLE_EMPHASIZED_SECONDARY; + origin_style.text_style = views::style::STYLE_EMPHASIZED; label->AddStyleRange( gfx::Range(offset, offset + origin_or_short_name.length()), origin_style); @@ -79,7 +79,7 @@ if (show_emphasis) { views::StyledLabel::RangeStyleInfo origin_style; - origin_style.text_style = views::style::STYLE_EMPHASIZED_SECONDARY; + origin_style.text_style = views::style::STYLE_EMPHASIZED; // All but the last offset should be the origin. for (size_t i = 0; i < offsets.size() - 1; ++i) { label->AddStyleRange( @@ -90,7 +90,7 @@ views::StyledLabel::RangeStyleInfo path_style; if (show_emphasis) - path_style.text_style = views::style::STYLE_EMPHASIZED_SECONDARY; + path_style.text_style = views::style::STYLE_EMPHASIZED; path_style.tooltip = path.LossyDisplayName(); label->AddStyleRange( gfx::Range(offsets.back(), offsets.back() + formatted_path.length()),
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc b/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc index d56c7aa..f2647f9 100644 --- a/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc +++ b/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc
@@ -605,6 +605,7 @@ UninstallWebApp(app_id); // Validate that state got changed to installable. + ASSERT_TRUE(result.app_banner_manager->WaitForInstallableCheck()); EXPECT_TRUE(pwa_install_view_->GetVisible()); } @@ -703,7 +704,7 @@ StartNavigateToUrl( https_server_.GetURL("/banners/manifest_test_page.html?manifest=" "manifest_prefer_related_chrome_app.json")); - ASSERT_TRUE(app_banner_manager_->WaitForInstallableCheck()); + ASSERT_FALSE(app_banner_manager_->WaitForInstallableCheck()); EXPECT_FALSE(pwa_install_view_->GetVisible()); EXPECT_TRUE(base::EqualsASCII( @@ -745,7 +746,7 @@ StartNavigateToUrl(https_server_.GetURL( "/banners/manifest_test_page.html?manifest=" + intercept_request_path_)); - ASSERT_TRUE(app_banner_manager_->WaitForInstallableCheck()); + ASSERT_FALSE(app_banner_manager_->WaitForInstallableCheck()); EXPECT_FALSE(pwa_install_view_->GetVisible()); EXPECT_TRUE(base::EqualsASCII( @@ -816,7 +817,7 @@ StartNavigateToUrl( https_server_.GetURL("/banners/manifest_test_page.html?manifest=" "manifest_listing_related_android_app.json")); - ASSERT_TRUE(app_banner_manager_->WaitForInstallableCheck()); + ASSERT_FALSE(app_banner_manager_->WaitForInstallableCheck()); EXPECT_FALSE(pwa_install_view_->GetVisible()); EXPECT_TRUE(base::EqualsASCII(
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc index 64c9c47..d5e938f3 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc
@@ -1190,8 +1190,7 @@ fps_button, l10n_util::GetStringFUTF16(IDS_PAGE_INFO_FPS_BUTTON_SUBTITLE, owner_name)); ExpectViewContainsText( - fps_button, - l10n_util::GetStringFUTF16(IDS_PAGE_INFO_FPS_BUTTON_TITLE, owner_name)); + fps_button, l10n_util::GetStringUTF16(IDS_PAGE_INFO_FPS_BUTTON_TITLE)); ExpectViewContainsText(api_->blocking_third_party_cookies_subtitle(), l10n_util::GetPluralStringFUTF16( IDS_PAGE_INFO_COOKIES_BLOCKED_SITES_COUNT,
diff --git a/chrome/browser/ui/views/page_info/page_info_cookies_content_view.cc b/chrome/browser/ui/views/page_info/page_info_cookies_content_view.cc index f8fd2585..a98d2fd 100644 --- a/chrome/browser/ui/views/page_info/page_info_cookies_content_view.cc +++ b/chrome/browser/ui/views/page_info/page_info_cookies_content_view.cc
@@ -306,8 +306,8 @@ InitFpsButton(fps_info->is_managed); fps_button_->SetVisible(true); - const std::u16string fps_button_title = l10n_util::GetStringFUTF16( - IDS_PAGE_INFO_FPS_BUTTON_TITLE, fps_info->owner_name); + const std::u16string fps_button_title = + l10n_util::GetStringUTF16(IDS_PAGE_INFO_FPS_BUTTON_TITLE); const std::u16string fps_button_subtitle = l10n_util::GetStringFUTF16( IDS_PAGE_INFO_FPS_BUTTON_SUBTITLE, fps_info->owner_name);
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view_browsertest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view_browsertest.cc index 08f5dbb2..5c9eb759 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view_browsertest.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view_browsertest.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/test/browser_test.h" @@ -53,7 +55,9 @@ class ReadAnythingToolbarViewTest : public InProcessBrowserTest { public: - ReadAnythingToolbarViewTest() = default; + ReadAnythingToolbarViewTest() { + scoped_feature_list_.InitWithFeatures({features::kUnifiedSidePanel}, {}); + } ~ReadAnythingToolbarViewTest() override = default; // InProcessBrowserTest: @@ -92,6 +96,7 @@ MockReadAnythingFontComboboxDelegate font_combobox_delegate_; private: + base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<ReadAnythingToolbarView> toolbar_view_; std::unique_ptr<MockReadAnythingCoordinator> coordinator_; };
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc index edf592c..29e2400c 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc +++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
@@ -558,9 +558,8 @@ base::Unretained(this))); combobox->SetSelectedIndex(combobox_model_->GetIndexForKey( (GetLastActiveEntryKey().value_or(SidePanelEntry::Key(kDefaultEntry))))); - // TODO(corising): Replace this with something appropriate. combobox->SetAccessibleName( - combobox_model_->GetItemAt(combobox->GetSelectedIndex().value())); + l10n_util::GetStringUTF16(IDS_ACCNAME_SIDE_PANEL_SELECTOR)); combobox->SetProperty( views::kFlexBehaviorKey, views::FlexSpecification(views::LayoutOrientation::kHorizontal,
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc index e319443..f9c1bb4 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -300,6 +300,12 @@ IDS_LENS_SEARCH_UPLOAD_DIALOG_DRAG_DROP_TITLE}, {"lensSearchUploadDialogLoadingText", IDS_LENS_SEARCH_UPLOAD_DIALOG_LOADING_TEXT}, + {"lensSearchUploadDialogOfflineText", + IDS_LENS_SEARCH_UPLOAD_DIALOG_OFFLINE_TEXT}, + {"lensSearchUploadDialogOfflineSubtitleText", + IDS_LENS_SEARCH_UPLOAD_DIALOG_OFFLINE_SUBTITLE_TEXT}, + {"lensSearchUploadDialogOfflineButtonLabel", + IDS_LENS_SEARCH_UPLOAD_DIALOG_OFFLINE_BUTTON_LABEL}, // Logo/doodle. {"copyLink", IDS_NTP_DOODLE_SHARE_DIALOG_COPY_LABEL},
diff --git a/chrome/browser/ui/webui/settings/ash/languages_section.cc b/chrome/browser/ui/webui/settings/ash/languages_section.cc index f859729..54097863 100644 --- a/chrome/browser/ui/webui/settings/ash/languages_section.cc +++ b/chrome/browser/ui/webui/settings/ash/languages_section.cc
@@ -218,6 +218,10 @@ IDS_SETTINGS_INPUT_METHOD_OPTIONS_JAPANESE_USE_SYSTEM_DICTIONARY}, {"inputMethodOptionsJapaneseNumberOfSuggestions", IDS_SETTINGS_INPUT_METHOD_OPTIONS_JAPANESE_NUMBER_OF_SUGGESTIONS}, + {"inputMethodOptionsJapaneseDisablePersonalizedSuggestions", + IDS_SETTINGS_INPUT_METHOD_OPTIONS_JAPANESE_DISABLE_PERSONALIZED_SUGGESTIONS}, + {"inputMethodOptionsJapaneseAutomaticallySendStatisticsToGoogle", + IDS_SETTINGS_INPUT_METHOD_OPTIONS_JAPANESE_SEND_STATISTICS_TO_GOOGLE}, {"inputMethodOptionsEnableDoubleSpacePeriod", IDS_SETTINGS_INPUT_METHOD_OPTIONS_ENABLE_DOUBLE_SPACE_PERIOD}, {"inputMethodOptionsEnableGestureTyping",
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc index 880afa7..0d9b21b 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
@@ -3072,7 +3072,7 @@ EXPECT_EQ("cr.webUIResponse", data.function_name()); EXPECT_EQ("getFpsMembershipLabel", data.arg1()->GetString()); ASSERT_TRUE(data.arg2()->GetBool()); - EXPECT_EQ("Allowed for 5 google.com sites", data.arg3()->GetString()); + EXPECT_EQ("5 sites in google.com's group", data.arg3()->GetString()); } TEST_F(SiteSettingsHandlerTest, HandleGetFormattedBytes) { @@ -3116,21 +3116,21 @@ handler()->HandleFetchUsageTotal(args); handler()->ServicePendingRequests(); ValidateUsageInfo("www.example.com", "2 B", "1 cookie", - "Allowed for 1 example.com site", true); + "1 site in example.com's group", true); args.clear(); args.Append("example.com"); handler()->HandleFetchUsageTotal(args); handler()->ServicePendingRequests(); ValidateUsageInfo("example.com", "", "1 cookie", - "Allowed for 1 example.com site", true); + "1 site in example.com's group", true); args.clear(); args.Append("google.com"); handler()->HandleFetchUsageTotal(args); handler()->ServicePendingRequests(); ValidateUsageInfo("google.com", "", "2 cookies", - "Allowed for 2 google.com sites", false); + "2 sites in google.com's group", false); args.clear(); args.Append("ungrouped.com"); handler()->HandleFetchUsageTotal(args);
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 6be8c5a8..b5448bb 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1665564264-86079b3091a531b2f51a786ece74692221251475.profdata +chrome-win32-main-1665586466-388e9b01906698ec86d653efab7419ec232700bb.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 2fa9463..72b586a 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1665575931-dc93e5aec8167821cac8f6ad5ae3491a46341045.profdata +chrome-win64-main-1665586466-c7cc31370b6807fde1cf26a4051835f758f5374d.profdata
diff --git a/chrome/common/logging_chrome.cc b/chrome/common/logging_chrome.cc index 544c013e..7534660 100644 --- a/chrome/common/logging_chrome.cc +++ b/chrome/common/logging_chrome.cc
@@ -465,8 +465,10 @@ if (chrome_logging_failed_) return; // We failed to initiailize logging, no cleanup. - DCHECK(chrome_logging_initialized_) - << "Attempted to clean up logging when it wasn't initialized."; + // Logging was not initialized, no cleanup required. This is happening with + // the Chrome early exit error paths (i.e Process Singleton). + if (!chrome_logging_initialized_) + return; CloseLogFile();
diff --git a/chrome/common/net/x509_certificate_model_unittest.cc b/chrome/common/net/x509_certificate_model_unittest.cc index 7173b61..13940021 100644 --- a/chrome/common/net/x509_certificate_model_unittest.cc +++ b/chrome/common/net/x509_certificate_model_unittest.cc
@@ -625,7 +625,7 @@ const uint8_t kSubject[] = {0x30, 0x10, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x16, 0x05, 0x61, 0x20, 0xf6, 0x20, 0x62}; - builder->SetSubject(kSubject); + builder->SetSubjectTLV(kSubject); x509_certificate_model::X509CertificateModel model( bssl::UpRef(builder->GetCertBuffer()), GetParam()); @@ -648,7 +648,7 @@ // SEQUENCE { SET { } } const uint8_t kSubject[] = {0x30, 0x02, 0x31, 0x00}; - builder->SetSubject(kSubject); + builder->SetSubjectTLV(kSubject); x509_certificate_model::X509CertificateModel model( bssl::UpRef(builder->GetCertBuffer()), GetParam()); @@ -663,7 +663,7 @@ // SEQUENCE { } const uint8_t kSubject[] = {0x30, 0x00}; - builder->SetSubject(kSubject); + builder->SetSubjectTLV(kSubject); { x509_certificate_model::X509CertificateModel model(
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 88643b4..9b3e3cd 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -3286,18 +3286,6 @@ // Boolean that specifies opting into --site-per-process (full Site Isolation). const char kSitePerProcess[] = "site_isolation.site_per_process"; -// Boolean that is true when the display-capture permissions-policy is enabled. -// This permissions-policy gates access to getDisplayMedia(), as per this spec: -// https://www.w3.org/TR/screen-capture/#feature-policy-integration -// However, if kDisplayCapturePermissionsPolicyEnabled is set to |false|, -// this requirement is not enforced, and getDisplayMedia() is allowed from -// contexts that would otherwise be forbidden. -// This Enterprise policy is temporary. It is intended to unblock Enterprise -// users whose application is non-spec compliant, but needs time to be fixed. -// TODO(crbug.com/1233969): Remove this around m100. -extern const char kDisplayCapturePermissionsPolicyEnabled[] = - "display_capture_permissions_policy_enabled"; - #if !BUILDFLAG(IS_ANDROID) // Boolean to allow SharedArrayBuffer in non-crossOriginIsolated contexts. // TODO(crbug.com/1144104) Remove when migration to COOP+COEP is complete.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 11961d8e..a522b2a 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -1115,8 +1115,6 @@ extern const char kIsolateOrigins[]; extern const char kSitePerProcess[]; -extern const char kDisplayCapturePermissionsPolicyEnabled[]; - #if !BUILDFLAG(IS_ANDROID) extern const char kSharedArrayBufferUnrestrictedAccessAllowed[]; extern const char kAutoplayAllowed[];
diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc index 5cb639a..080ce47c 100644 --- a/chrome/installer/setup/install.cc +++ b/chrome/installer/setup/install.cc
@@ -312,7 +312,7 @@ switch (install_static::GetChromeChannel()) { case version_info::Channel::BETA: { // Increase kBetaRolloutPercentage to roll out to beta channel. - constexpr int kBetaRolloutPercentage = 10; + constexpr int kBetaRolloutPercentage = 50; return base::RandInt(0, 99) < kBetaRolloutPercentage; } case version_info::Channel::STABLE: {
diff --git a/chrome/test/data/autofill/captured_sites/testcases.json b/chrome/test/data/autofill/captured_sites/testcases.json index 7529562e..55fab50 100644 --- a/chrome/test/data/autofill/captured_sites/testcases.json +++ b/chrome/test/data/autofill/captured_sites/testcases.json
@@ -5,7 +5,7 @@ { "site_name": "abebooks", "bug_number": 1269390 }, { "site_name": "abercrombie", "disabled": true, "bug_number": 1172845 }, { "site_name": "academy" }, - { "site_name": "accesscorrections" }, + { "site_name": "accesscorrections", "disabled": true, "bug_number": 1373680 }, { "site_name": "adameve", "disabled": true, "bug_number": 1373669 }, { "site_name": "advance_autoparts" }, { "site_name": "ae" }, @@ -209,7 +209,7 @@ { "site_name": "sixpm" }, { "site_name": "southwest", "disabled": true, "bug_number": 1373680 }, { "site_name": "speedycash" }, - { "site_name": "spencers_online" }, + { "site_name": "spencers_online", "disabled": true, "bug_number": 1373680 }, { "site_name": "spirit" }, { "site_name": "sportsmansguide" }, { "site_name": "star_city_games" },
diff --git a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js index ad8b0846..5ed4f02 100644 --- a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js +++ b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
@@ -3471,6 +3471,26 @@ document.body.appendChild(webview); } +// Inserting a webview element into a detached iframe's document shouldn't +// crash. +function testInsertIntoDetachedIframe() { + let webview = document.createElement('webview'); + webview.src = embedder.emptyGuestURL; + let iframe = document.createElement('iframe'); + + iframe.addEventListener('load', () => { + let doc = iframe.contentDocument; + iframe.remove(); + doc.body.appendChild(webview); + + setTimeout(() => { + embedder.test.succeed(); + }); + }); + + document.body.appendChild(iframe); +} + embedder.test.testList = { 'testAllowTransparencyAttribute': testAllowTransparencyAttribute, 'testAutosizeHeight': testAutosizeHeight, @@ -3604,6 +3624,7 @@ 'testWebRequestBlockedNavigation': testWebRequestBlockedNavigation, 'testAddFencedFrame': testAddFencedFrame, 'testActivatePortal': testActivatePortal, + 'testInsertIntoDetachedIframe': testInsertIntoDetachedIframe, }; onload = function() {
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 6acb876..d1c1a1e2 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -3313,44 +3313,7 @@ "reason_for_missing_test": "Policy was removed" }, "DisplayCapturePermissionsPolicyEnabled": { - "os": [ - "win", - "linux", - "mac", - "chromeos_lacros", - "chromeos_ash", - "fuchsia" - ], - "policy_pref_mapping_tests": [ - { - "policies": { - "DisplayCapturePermissionsPolicyEnabled": false - }, - "prefs": { - "display_capture_permissions_policy_enabled": { - "value": false - } - } - }, - { - "policies": { - "DisplayCapturePermissionsPolicyEnabled": true - }, - "prefs": { - "display_capture_permissions_policy_enabled": { - "value": true - } - } - }, - { - "policies": {}, - "prefs": { - "display_capture_permissions_policy_enabled": { - "default_value": true - } - } - } - ] + "reason_for_missing_test": "Policy was removed" }, "WebDriverOverridesIncompatiblePolicies": { "reason_for_missing_test": "Policy was removed"
diff --git a/chrome/test/data/webui/chromeos/diagnostics/BUILD.gn b/chrome/test/data/webui/chromeos/diagnostics/BUILD.gn index d5b46cb..a5f6630 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/BUILD.gn +++ b/chrome/test/data/webui/chromeos/diagnostics/BUILD.gn
@@ -183,6 +183,15 @@ ] } +js_library("drawing_provider_test") { + deps = [ + "../..:chai_assert", + "../..:test_util", + "//ash/webui/diagnostics_ui/mojom:mojom_webui_js", + "//ash/webui/diagnostics_ui/resources:drawing_provider", + ] +} + js_library("ethernet_info_test") { deps = [ "../..:chai_assert",
diff --git a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_unified_test.js b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_unified_test.js index 7c72e7ba..aa2c257 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_unified_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_unified_test.js
@@ -11,6 +11,7 @@ import {diagnosticsNetworkIconTestSuite} from './diagnostics_network_icon_test.js'; import {diagnosticsStickyBannerTestSuite} from './diagnostics_sticky_banner_test.js'; import {diagnosticsUtilsTestSuite} from './diagnostics_utils_test.js'; +import {drawingProviderTestSuite} from './drawing_provider_test.js'; import {ethernetInfoTestSuite} from './ethernet_info_test.js'; import {fakeNetworkHealthProviderTestSuite} from './fake_network_health_provider_test.js'; import {fakeSystemDataProviderTestSuite} from './fake_system_data_provider_test.js'; @@ -63,6 +64,7 @@ runSuite('DiagnosticsNetworkIcon', diagnosticsNetworkIconTestSuite, 'network'); runSuite('DiagnosticsStickyBanner', diagnosticsStickyBannerTestSuite); runSuite('DiagnosticsUtils', diagnosticsUtilsTestSuite); +runSuite('DrawingProvider', drawingProviderTestSuite); runSuite('EthernetInfo', ethernetInfoTestSuite, 'network'); runSuite('FakeMojoInterface', fakeMojoProviderTestSuite); runSuite('FakeNetworkHealthProvider', fakeNetworkHealthProviderTestSuite);
diff --git a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_browsertest.js b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_browsertest.js index 46e9858..78953fc7 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_browsertest.js +++ b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_browsertest.js
@@ -84,6 +84,7 @@ 'DiagnosticsNetworkIcon', 'DiagnosticsStickyBanner', 'DiagnosticsUtils', + 'DrawingProvider', 'EthernetInfo', 'FakeMojoInterface', 'FakeNetworkHealthProvider',
diff --git a/chrome/test/data/webui/chromeos/diagnostics/drawing_provider_test.js b/chrome/test/data/webui/chromeos/diagnostics/drawing_provider_test.js new file mode 100644 index 0000000..9a16475 --- /dev/null +++ b/chrome/test/data/webui/chromeos/diagnostics/drawing_provider_test.js
@@ -0,0 +1,95 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {CanvasDrawingProvider, DESTINATION_OVER, LINE_CAP, LINE_WIDTH, MARK_COLOR, MARK_RADIUS, TRAIL_COLOR} from 'chrome://diagnostics/drawing_provider.js'; + +import {assertDeepEquals, assertEquals} from '../../chai_assert.js'; + +/** + * FakeCanvasCtx class mocks various html Canvas API methods to make it easy to + * test the drawing behavior. + */ +class FakeCanvasCtx { + constructor() { + this.mock = []; + } + + getMock() { + return this.mock; + } + + beginPath() { + this.mock.push('beginPath'); + } + + stroke() { + this.mock.push('stroke'); + } + + fill() { + this.mock.push('fill'); + } + + moveTo(x, y) { + this.mock.push(`moveTo:${x}~${y}`); + } + + lineTo(x, y) { + this.mock.push(`lineTo:${x}~${y}`); + } + + arc(x, y, r, startAngle, endAngle) { + this.mock.push(`arc:${x}~${y}~${r}~${startAngle}~${endAngle}`); + } +} + +export function drawingProviderTestSuite() { + function initializeDrawingProvider() { + return new CanvasDrawingProvider(new FakeCanvasCtx()); + } + + test('SettingUpCanvasDrawingProvider', () => { + const drawingProvider = initializeDrawingProvider(); + + assertEquals(LINE_CAP, drawingProvider.getLineCap()); + assertEquals(LINE_WIDTH, drawingProvider.getLineWidth()); + }); + + test('TestDrawTrail', () => { + const x0 = 10; + const y0 = 15; + const x1 = 20; + const y1 = 25; + const expectedMock = [ + 'beginPath', + `moveTo:${x0}~${y0}`, + `lineTo:${x1}~${y1}`, + 'stroke', + ]; + + const drawingProvider = initializeDrawingProvider(); + drawingProvider.drawTrail(x0, y0, x1, y1); + + assertDeepEquals(expectedMock, drawingProvider.getCtx().getMock()); + assertEquals(TRAIL_COLOR, drawingProvider.getStrokeStyle()); + }); + + test('TestDrawTrailMark', () => { + const x = 10; + const y = 15; + const expectedMock = [ + 'beginPath', + `arc:${x}~${y}~${MARK_RADIUS}~${0}~${2 * Math.PI}`, + 'fill', + ]; + + const drawingProvider = initializeDrawingProvider(); + drawingProvider.drawTrailMark(x, y); + + assertDeepEquals(expectedMock, drawingProvider.getCtx().getMock()); + assertEquals(MARK_COLOR, drawingProvider.getFillStyle()); + assertEquals( + DESTINATION_OVER, drawingProvider.getGlobalCompositeOperation()); + }); +}
diff --git a/chrome/test/data/webui/new_tab_page/lens_upload_dialog_test.ts b/chrome/test/data/webui/new_tab_page/lens_upload_dialog_test.ts index 337b88d..054ff35d 100644 --- a/chrome/test/data/webui/new_tab_page/lens_upload_dialog_test.ts +++ b/chrome/test/data/webui/new_tab_page/lens_upload_dialog_test.ts
@@ -6,16 +6,24 @@ import 'chrome://new-tab-page/new_tab_page.js'; import {LensUploadDialogElement} from 'chrome://new-tab-page/lazy_load.js'; +import {WindowProxy} from 'chrome://new-tab-page/new_tab_page.js'; import {assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; +import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js'; + +import {installMock} from './test_support.js'; suite('LensUploadDialogTest', () => { let uploadDialog: LensUploadDialogElement; let wrapperElement: HTMLDivElement; let outsideClickTarget: HTMLDivElement; + let windowProxy: TestBrowserProxy; setup(() => { document.body.innerHTML = ''; + windowProxy = installMock(WindowProxy); + windowProxy.setResultFor('onLine', true); + // Larger than wrapper so that we can test outside clicks. document.body.style.width = '1000px'; @@ -65,7 +73,6 @@ test('clicking outside the upload dialog closes the dialog', async () => { // Arrange. uploadDialog.openDialog(); - await waitAfterNextRender(uploadDialog); // Act. @@ -74,4 +81,44 @@ // Assert. assertTrue(uploadDialog.$.dialog.hidden); }); + + test('opening dialog while offline shows offline UI', async () => { + // Arrange. + windowProxy.setResultFor('onLine', false); + + // Act. + uploadDialog.openDialog(); + await waitAfterNextRender(uploadDialog); + + // Assert. + assertTrue(uploadDialog.hasAttribute('is-offline_')); + + // Reset. + windowProxy.setResultFor('onLine', true); + }); + + test( + 'clicking try again in offline state when online updates UI', + async () => { + // Arrange. + windowProxy.setResultFor('onLine', false); + + // Act. + uploadDialog.openDialog(); + await waitAfterNextRender(uploadDialog); + + // Assert. (consistency check) + assertTrue(uploadDialog.hasAttribute('is-offline_')); + + // Arrange. + windowProxy.setResultFor('onLine', true); + + // Act. + (uploadDialog.shadowRoot!.querySelector('#offlineRetryButton') as + HTMLElement)!.click(); + await waitAfterNextRender(uploadDialog); + + // Assert. + assertFalse(uploadDialog.hasAttribute('is-offline_')); + }); });
diff --git a/chrome/test/data/webui/settings/BUILD.gn b/chrome/test/data/webui/settings/BUILD.gn index bfaba09..74ff3985 100644 --- a/chrome/test/data/webui/settings/BUILD.gn +++ b/chrome/test/data/webui/settings/BUILD.gn
@@ -138,6 +138,7 @@ "test_open_window_proxy.ts", "test_password_manager_proxy.ts", "test_performance_browser_proxy.ts", + "test_performance_metrics_proxy.ts", "test_privacy_page_browser_proxy.ts", "test_profile_info_browser_proxy.ts", "test_reset_browser_proxy.ts",
diff --git a/chrome/test/data/webui/settings/all_sites_tests.ts b/chrome/test/data/webui/settings/all_sites_tests.ts index 15df615..4468365 100644 --- a/chrome/test/data/webui/settings/all_sites_tests.ts +++ b/chrome/test/data/webui/settings/all_sites_tests.ts
@@ -1694,7 +1694,7 @@ assertEquals(testElement.$.allSitesList.items!.length, 2); await localDataBrowserProxy.whenCalled('getFpsMembershipLabel'); assertEquals( - '· Allowed for 2 google.com sites', + '· 2 sites in google.com\'s group', siteEntries[1]!.$.fpsMembership.innerText.trim()); // Remove first site group. @@ -1704,7 +1704,7 @@ assertEquals(testElement.$.allSitesList.items!.length, 1); await localDataBrowserProxy.whenCalled('getFpsMembershipLabel'); assertEquals( - '· Allowed for 1 google.com site', + '· 1 site in google.com\'s group', siteEntries[1]!.$.fpsMembership.innerText.trim()); }); @@ -1723,7 +1723,7 @@ assertEquals(testElement.$.allSitesList.items!.length, 2); await localDataBrowserProxy.whenCalled('getFpsMembershipLabel'); assertEquals( - '· Allowed for 2 google.com sites', + '· 2 sites in google.com\'s group', siteEntries[1]!.$.fpsMembership.innerText.trim()); let originList = siteEntries[0]!.$.originList.get(); @@ -1750,7 +1750,7 @@ // Ensure that first party set info is unaffected by origin removal. await localDataBrowserProxy.whenCalled('getFpsMembershipLabel'); assertEquals( - '· Allowed for 2 google.com sites', + '· 2 sites in google.com\'s group', siteEntries[1]!.$.fpsMembership.innerText.trim()); // Remove the last origin. @@ -1770,7 +1770,7 @@ assertEquals(testElement.$.allSitesList.items!.length, 2); await localDataBrowserProxy.whenCalled('getFpsMembershipLabel'); assertEquals( - '· Allowed for 2 google.com sites', + '· 2 sites in google.com\'s group', siteEntries[1]!.$.fpsMembership.innerText.trim()); });
diff --git a/chrome/test/data/webui/settings/battery_page_test.ts b/chrome/test/data/webui/settings/battery_page_test.ts index 1d7f622e..8c2c8a3 100644 --- a/chrome/test/data/webui/settings/battery_page_test.ts +++ b/chrome/test/data/webui/settings/battery_page_test.ts
@@ -2,30 +2,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off import 'chrome://settings/settings.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {OpenWindowProxyImpl, PerformanceBrowserProxyImpl, SettingsBatteryPageElement} from 'chrome://settings/settings.js'; +import {BATTERY_SAVER_MODE_PREF, BatterySaverModeState, OpenWindowProxyImpl, PerformanceBrowserProxyImpl, PerformanceMetricsProxyImpl, SettingsBatteryPageElement} from 'chrome://settings/settings.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {TestOpenWindowProxy} from './test_open_window_proxy.js'; import {TestPerformanceBrowserProxy} from './test_performance_browser_proxy.js'; -// clang-format on +import {TestPerformanceMetricsProxy} from './test_performance_metrics_proxy.js'; suite('BatteryPage', function() { let batteryPage: SettingsBatteryPageElement; let performanceBrowserProxy: TestPerformanceBrowserProxy; + let performanceMetricsProxy: TestPerformanceMetricsProxy; let openWindowProxy: TestOpenWindowProxy; - const batterySaverModeEnabledPref = - 'prefs.performance_tuning.battery_saver_mode.state.value'; - setup(function() { performanceBrowserProxy = new TestPerformanceBrowserProxy(); PerformanceBrowserProxyImpl.setInstance(performanceBrowserProxy); + performanceMetricsProxy = new TestPerformanceMetricsProxy(); + PerformanceMetricsProxyImpl.setInstance(performanceMetricsProxy); + openWindowProxy = new TestOpenWindowProxy(); OpenWindowProxyImpl.setInstance(openWindowProxy); @@ -37,7 +37,7 @@ battery_saver_mode: { state: { type: chrome.settingsPrivate.PrefType.NUMBER, - value: batteryPage.batterySaverModeStatePrefValues.disabled, + value: BatterySaverModeState.DISABLED, }, }, }, @@ -47,9 +47,8 @@ }); test('testBatterySaverModeEnabledOnBattery', function() { - batteryPage.set( - batterySaverModeEnabledPref, - batteryPage.batterySaverModeStatePrefValues.enabledOnBattery); + batteryPage.setPrefValue( + BATTERY_SAVER_MODE_PREF, BatterySaverModeState.ENABLED_ON_BATTERY); flush(); assertTrue( batteryPage.$.toggleButton.checked, @@ -60,15 +59,14 @@ 'collapse should be open when battery saver mode is enabled on ' + 'battery'); assertEquals( - String(batteryPage.batterySaverModeStatePrefValues.enabledOnBattery), + String(BatterySaverModeState.ENABLED_ON_BATTERY), batteryPage.$.radioGroup.selected, 'selected radio button should be enabled on battery'); }); test('testBatterySaverModeEnabledBelowThreshold', function() { - batteryPage.set( - batterySaverModeEnabledPref, - batteryPage.batterySaverModeStatePrefValues.enabledBelowThreshold); + batteryPage.setPrefValue( + BATTERY_SAVER_MODE_PREF, BatterySaverModeState.ENABLED_BELOW_THRESHOLD); flush(); assertTrue( batteryPage.$.toggleButton.checked, @@ -79,16 +77,14 @@ 'collapse should be open when battery saver mode is enabled below ' + 'threshold'); assertEquals( - String( - batteryPage.batterySaverModeStatePrefValues.enabledBelowThreshold), + String(BatterySaverModeState.ENABLED_BELOW_THRESHOLD), batteryPage.$.radioGroup.selected, 'selected radio button should be enabled below threshold'); }); test('testBatterySaverModeDisabled', function() { - batteryPage.set( - batterySaverModeEnabledPref, - batteryPage.batterySaverModeStatePrefValues.disabled); + batteryPage.setPrefValue( + BATTERY_SAVER_MODE_PREF, BatterySaverModeState.DISABLED); assertFalse( batteryPage.$.toggleButton.checked, 'toggle should be unchecked when battery saver mode is disabled'); @@ -97,6 +93,28 @@ 'collapse should be closed when battery saver mode is disabled'); }); + test('testBatterySaverModeMetrics', async function() { + batteryPage.setPrefValue( + BATTERY_SAVER_MODE_PREF, BatterySaverModeState.DISABLED); + + batteryPage.$.toggleButton.click(); + let state = await performanceMetricsProxy.whenCalled( + 'recordBatterySaverModeChanged'); + assertEquals(BatterySaverModeState.ENABLED_BELOW_THRESHOLD, state); + + performanceMetricsProxy.reset(); + batteryPage.$.enabledOnBatteryButton.click(); + state = await performanceMetricsProxy.whenCalled( + 'recordBatterySaverModeChanged'); + assertEquals(BatterySaverModeState.ENABLED_ON_BATTERY, state); + + performanceMetricsProxy.reset(); + batteryPage.$.toggleButton.click(); + state = await performanceMetricsProxy.whenCalled( + 'recordBatterySaverModeChanged'); + assertEquals(BatterySaverModeState.DISABLED, state); + }); + test('testLearnMoreLink', async function() { const learnMoreLink = batteryPage.$.toggleButton.shadowRoot!.querySelector<HTMLElement>(
diff --git a/chrome/test/data/webui/settings/performance_page_test.ts b/chrome/test/data/webui/settings/performance_page_test.ts index 1b988c3..15429a6 100644 --- a/chrome/test/data/webui/settings/performance_page_test.ts +++ b/chrome/test/data/webui/settings/performance_page_test.ts
@@ -6,23 +6,20 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {OpenWindowProxyImpl, PerformanceBrowserProxyImpl, SettingsPerformancePageElement, SUBMIT_EVENT, TabDiscardExceptionDialogElement, TabDiscardExceptionEntryElement, TabDiscardExceptionListElement} from 'chrome://settings/settings.js'; +import {HIGH_EFFICIENCY_MODE_PREF, HighEfficiencyModeExceptionListAction, OpenWindowProxyImpl, PerformanceBrowserProxyImpl, PerformanceMetricsProxyImpl, SettingsPerformancePageElement, SUBMIT_EVENT, TAB_DISCARD_EXCEPTIONS_PREF, TabDiscardExceptionDialogElement, TabDiscardExceptionEntryElement, TabDiscardExceptionListElement} from 'chrome://settings/settings.js'; import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {TestOpenWindowProxy} from './test_open_window_proxy.js'; import {TestPerformanceBrowserProxy} from './test_performance_browser_proxy.js'; +import {TestPerformanceMetricsProxy} from './test_performance_metrics_proxy.js'; suite('PerformancePage', function() { let performancePage: SettingsPerformancePageElement; let performanceBrowserProxy: TestPerformanceBrowserProxy; + let performanceMetricsProxy: TestPerformanceMetricsProxy; let openWindowProxy: TestOpenWindowProxy; let tabDiscardExceptionsList: TabDiscardExceptionListElement; - const highEfficiencyModeEnabledPref = - 'prefs.performance_tuning.high_efficiency_mode.enabled.value'; - const tabDiscardExceptionsPref = - 'prefs.performance_tuning.tab_discarding.exceptions.value'; - function getExceptionListEntries(): NodeListOf<TabDiscardExceptionEntryElement> { return tabDiscardExceptionsList.$.list.querySelectorAll( @@ -52,6 +49,9 @@ performanceBrowserProxy = new TestPerformanceBrowserProxy(); PerformanceBrowserProxyImpl.setInstance(performanceBrowserProxy); + performanceMetricsProxy = new TestPerformanceMetricsProxy(); + PerformanceMetricsProxyImpl.setInstance(performanceMetricsProxy); + openWindowProxy = new TestOpenWindowProxy(); OpenWindowProxyImpl.setInstance(openWindowProxy); @@ -81,19 +81,34 @@ }); test('testHighEfficiencyModeEnabled', function() { - performancePage.set(highEfficiencyModeEnabledPref, true); + performancePage.setPrefValue(HIGH_EFFICIENCY_MODE_PREF, true); assertTrue( performancePage.$.toggleButton.checked, 'toggle should be checked when pref is true'); }); test('testHighEfficiencyModeDisabled', function() { - performancePage.set(highEfficiencyModeEnabledPref, false); + performancePage.setPrefValue(HIGH_EFFICIENCY_MODE_PREF, false); assertFalse( performancePage.$.toggleButton.checked, 'toggle should not be checked when pref is false'); }); + test('testHighEfficiencyModeMetrics', async function() { + performancePage.setPrefValue(HIGH_EFFICIENCY_MODE_PREF, false); + + performancePage.$.toggleButton.click(); + let enabled = await performanceMetricsProxy.whenCalled( + 'recordHighEfficiencyModeChanged'); + assertTrue(enabled); + + performanceMetricsProxy.reset(); + performancePage.$.toggleButton.click(); + enabled = await performanceMetricsProxy.whenCalled( + 'recordHighEfficiencyModeChanged'); + assertFalse(enabled); + }); + test('testLearnMoreLink', async function() { const learnMoreLink = performancePage.$.toggleButton.shadowRoot!.querySelector<HTMLElement>( @@ -122,7 +137,7 @@ }); function setupExceptionListEntries(existingRules: string[]) { - performancePage.set(tabDiscardExceptionsPref, existingRules); + performancePage.setPrefValue(TAB_DISCARD_EXCEPTIONS_PREF, existingRules); flush(); assertDeepEquals(existingRules, tabDiscardExceptionsList.$.list.items); } @@ -137,7 +152,7 @@ assertTrue(tabDiscardExceptionsList.$.noSitesAdded.hidden); }); - test('testTabDiscardExceptionsListDelete', function() { + test('testTabDiscardExceptionsListDelete', async function() { setupExceptionListEntries(['foo', 'bar']); getExceptionListEntries()[0]!.$.button.click(); @@ -145,6 +160,10 @@ flush(); assertDeepEquals(['bar'], tabDiscardExceptionsList.$.list.items); + const action = + await performanceMetricsProxy.whenCalled('recordExceptionListAction'); + assertEquals(HighEfficiencyModeExceptionListAction.REMOVE, action); + getExceptionListEntries()[0]!.$.button.click(); clickDeleteMenuItem(); flush(); @@ -191,11 +210,14 @@ return editDialog; } - test('testTabDiscardExceptionsListAdd', function() { + test('testTabDiscardExceptionsListAdd', async function() { setupExceptionListEntries(['foo']); const dialog = openAddDialog(); dialog.fire(SUBMIT_EVENT, 'bar'); + const action = + await performanceMetricsProxy.whenCalled('recordExceptionListAction'); + assertEquals(HighEfficiencyModeExceptionListAction.ADD, action); assertDeepEquals( ['foo', 'bar'], tabDiscardExceptionsList.$.list.items, 'expected valid rule to be added to the end of the list'); @@ -214,11 +236,14 @@ 'add dialog should be opened instead of edit dialog'); }); - test('testTabDiscardExceptionsListEdit', function() { + test('testTabDiscardExceptionsListEdit', async function() { setupExceptionListEntries(['foo', 'bar']); const dialog = openEditDialog(getExceptionListEntries()[1]!); dialog.fire(SUBMIT_EVENT, 'baz'); + const action = + await performanceMetricsProxy.whenCalled('recordExceptionListAction'); + assertEquals(HighEfficiencyModeExceptionListAction.EDIT, action); assertDeepEquals( ['foo', 'baz'], tabDiscardExceptionsList.$.list.items, 'expected valid rule to be added to the end of the list');
diff --git a/chrome/test/data/webui/settings/site_entry_tests.ts b/chrome/test/data/webui/settings/site_entry_tests.ts index fa2ae86..083365d 100644 --- a/chrome/test/data/webui/settings/site_entry_tests.ts +++ b/chrome/test/data/webui/settings/site_entry_tests.ts
@@ -632,7 +632,7 @@ // Assert first party set membership information is set correctly. assertFalse(fpsMembershipLabel.hidden); assertEquals( - '· Allowed for 1 foo.com site', fpsMembershipLabel.innerText.trim()); + '· 1 site in foo.com\'s group', fpsMembershipLabel.innerText.trim()); }); test('first party set policy shown when managed key is true', function() {
diff --git a/chrome/test/data/webui/settings/test_local_data_browser_proxy.ts b/chrome/test/data/webui/settings/test_local_data_browser_proxy.ts index f83b787c..5876c2f7 100644 --- a/chrome/test/data/webui/settings/test_local_data_browser_proxy.ts +++ b/chrome/test/data/webui/settings/test_local_data_browser_proxy.ts
@@ -85,10 +85,9 @@ getFpsMembershipLabel(fpsNumMembers: number, fpsOwner: string) { this.methodCalled('getFpsMembershipLabel', fpsNumMembers, fpsOwner); return Promise.resolve([ - 'Allowed for', `${fpsNumMembers}`, - `${fpsOwner}`, (fpsNumMembers === 1 ? 'site' : 'sites'), + `in ${fpsOwner}'s group`, ].join(' ')); }
diff --git a/chrome/test/data/webui/settings/test_performance_browser_proxy.ts b/chrome/test/data/webui/settings/test_performance_browser_proxy.ts index 606720a..fc18f86 100644 --- a/chrome/test/data/webui/settings/test_performance_browser_proxy.ts +++ b/chrome/test/data/webui/settings/test_performance_browser_proxy.ts
@@ -1,4 +1,4 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. +// Copyright 2022 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file.
diff --git a/chrome/test/data/webui/settings/test_performance_metrics_proxy.ts b/chrome/test/data/webui/settings/test_performance_metrics_proxy.ts new file mode 100644 index 0000000..d50e37f --- /dev/null +++ b/chrome/test/data/webui/settings/test_performance_metrics_proxy.ts
@@ -0,0 +1,29 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {BatterySaverModeState, HighEfficiencyModeExceptionListAction, PerformanceMetricsProxy} from 'chrome://settings/settings.js'; +import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js'; + +export class TestPerformanceMetricsProxy extends TestBrowserProxy implements + PerformanceMetricsProxy { + constructor() { + super([ + 'recordBatterySaverModeChanged', + 'recordHighEfficiencyModeChanged', + 'recordExceptionListAction', + ]); + } + + recordBatterySaverModeChanged(state: BatterySaverModeState) { + this.methodCalled('recordBatterySaverModeChanged', state); + } + + recordHighEfficiencyModeChanged(enabled: boolean) { + this.methodCalled('recordHighEfficiencyModeChanged', enabled); + } + + recordExceptionListAction(action: HighEfficiencyModeExceptionListAction) { + this.methodCalled('recordExceptionListAction', action); + } +} \ No newline at end of file
diff --git a/chrome/test/interaction/webui_interaction_test_util_browsertest.cc b/chrome/test/interaction/webui_interaction_test_util_browsertest.cc index 04a3e0d..73de432 100644 --- a/chrome/test/interaction/webui_interaction_test_util_browsertest.cc +++ b/chrome/test/interaction/webui_interaction_test_util_browsertest.cc
@@ -165,6 +165,7 @@ .Build()) .AddStep(ui::InteractionSequence::StepBuilder() .SetType(ui::InteractionSequence::StepType::kHidden) + .SetTransitionOnlyOnEvent(true) .SetElementID(kWebUIInteractionTestUtilTestId) .Build()) .AddStep(ui::InteractionSequence::StepBuilder() @@ -192,6 +193,7 @@ .AddStep(ui::InteractionSequence::StepBuilder() .SetType(ui::InteractionSequence::StepType::kShown) .SetElementID(kWebUIInteractionTestUtilTestId) + .SetMustRemainVisible(false) .SetStartCallback(base::BindLambdaForTesting( [&](ui::InteractionSequence* sequence, ui::TrackedElement* element) { @@ -199,17 +201,18 @@ })) .Build()) .AddStep(ui::InteractionSequence::StepBuilder() - .SetType(ui::InteractionSequence::StepType::kHidden) - .SetElementID(kWebUIInteractionTestUtilTestId) - .Build()) - .AddStep(ui::InteractionSequence::StepBuilder() .SetType(ui::InteractionSequence::StepType::kShown) + .SetTransitionOnlyOnEvent(true) .SetElementID(kWebUIInteractionTestUtilTestId) + .SetStartCallback(base::BindLambdaForTesting( + [&](ui::InteractionSequence* sequence, + ui::TrackedElement* element) { + EXPECT_EQ(url, util->web_contents()->GetURL()); + })) .Build()) .Build(); EXPECT_CALL_IN_SCOPE(completed, Run, sequence->RunSynchronouslyForTesting()); - DCHECK_EQ(url, util->web_contents()->GetURL()); } IN_PROC_BROWSER_TEST_F(WebUIInteractionTestUtilTest, IsPageLoaded) { @@ -240,6 +243,7 @@ .AddStep(ui::InteractionSequence::StepBuilder() .SetType(ui::InteractionSequence::StepType::kHidden) .SetElementID(kWebUIInteractionTestUtilTestId) + .SetTransitionOnlyOnEvent(true) .SetStartCallback(base::BindLambdaForTesting( [&](ui::InteractionSequence* sequence, ui::TrackedElement* element) {
diff --git a/chrome/updater/win/installer/BUILD.gn b/chrome/updater/win/installer/BUILD.gn index 6cfc7e4..e4f5628 100644 --- a/chrome/updater/win/installer/BUILD.gn +++ b/chrome/updater/win/installer/BUILD.gn
@@ -118,6 +118,7 @@ ":lib", ":version", "//build/win:default_exe_manifest", + "//chrome/updater:base", ] } }
diff --git a/chrome/updater/win/installer/installer_main.cc b/chrome/updater/win/installer/installer_main.cc index 4c07e89..0495bf5 100644 --- a/chrome/updater/win/installer/installer_main.cc +++ b/chrome/updater/win/installer/installer_main.cc
@@ -8,6 +8,7 @@ #include <string> #include "chrome/updater/win/installer/installer.h" +#include "chrome/updater/win/ui/l10n_util.h" // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx extern "C" IMAGE_DOS_HEADER __ImageBase; @@ -19,10 +20,13 @@ updater::ProcessExitResult result = updater::WMain(reinterpret_cast<HMODULE>(&__ImageBase)); - if (result.exit_code != updater::SUCCESS_EXIT_CODE) { - std::wstring error = updater::GetLocalizedErrorString(result.exit_code); - ::MessageBoxEx(nullptr, error.c_str(), nullptr, 0, 0); + // If errors occur, display UI only when the metainstaller runs without + // command line arguments. + if (result.exit_code != updater::SUCCESS_EXIT_CODE && + wcslen(command_line) == 0) { + ::MessageBoxEx(nullptr, + updater::GetLocalizedErrorString(result.exit_code).c_str(), + nullptr, 0, 0); } - return result.exit_code; }
diff --git a/chromeos/ash/components/cryptohome/BUILD.gn b/chromeos/ash/components/cryptohome/BUILD.gn index 445d8b3..19d4a4f 100644 --- a/chromeos/ash/components/cryptohome/BUILD.gn +++ b/chromeos/ash/components/cryptohome/BUILD.gn
@@ -21,6 +21,7 @@ "//components/account_id", "//components/device_event_log", "//components/user_manager", + "//components/version_info", ] sources = [ "auth_factor.cc",
diff --git a/chromeos/ash/components/cryptohome/DEPS b/chromeos/ash/components/cryptohome/DEPS index 33ac5a1..51994700 100644 --- a/chromeos/ash/components/cryptohome/DEPS +++ b/chromeos/ash/components/cryptohome/DEPS
@@ -8,6 +8,7 @@ "+components/account_id", "+components/device_event_log", "+components/user_manager", + "+components/version_info", "+third_party/cros_system_api", # Abseil features must be allowlisted explicitly for now. See
diff --git a/chromeos/ash/components/cryptohome/auth_factor.cc b/chromeos/ash/components/cryptohome/auth_factor.cc index 85f8d80..7456f7c 100644 --- a/chromeos/ash/components/cryptohome/auth_factor.cc +++ b/chromeos/ash/components/cryptohome/auth_factor.cc
@@ -8,9 +8,12 @@ #include "base/check_op.h" #include "chromeos/ash/components/cryptohome/common_types.h" +#include "components/version_info/version_info.h" namespace cryptohome { +const char kFallbackFactorVersion[] = "0.0.0.0"; + // =============== `AuthFactorRef` =============== AuthFactorRef::AuthFactorRef(AuthFactorType type, KeyLabel label) : type_(type), label_(std::move(label)) { @@ -29,7 +32,15 @@ } // =============== `AuthFactorCommonMetadata` =============== -AuthFactorCommonMetadata::AuthFactorCommonMetadata() = default; +AuthFactorCommonMetadata::AuthFactorCommonMetadata() + : chrome_version_last_updated_( + ComponentVersion(version_info::GetVersionNumber())) {} + +AuthFactorCommonMetadata::AuthFactorCommonMetadata(ComponentVersion chrome, + ComponentVersion chromeos) + : chrome_version_last_updated_(std::move(chrome)), + chromeos_version_last_updated_(std::move(chromeos)) {} + AuthFactorCommonMetadata::AuthFactorCommonMetadata( AuthFactorCommonMetadata&&) noexcept = default; AuthFactorCommonMetadata& AuthFactorCommonMetadata::operator=( @@ -42,8 +53,10 @@ bool AuthFactorCommonMetadata::operator==( const AuthFactorCommonMetadata& other) const { - // TODO (b/241259026): update when we get actual metadata. - return true; + return (this->chrome_version_last_updated_ == + other.chrome_version_last_updated_) && + (this->chromeos_version_last_updated_ == + other.chromeos_version_last_updated_); } // =============== `AuthFactor` ===============
diff --git a/chromeos/ash/components/cryptohome/auth_factor.h b/chromeos/ash/components/cryptohome/auth_factor.h index 65f0955..489df78 100644 --- a/chromeos/ash/components/cryptohome/auth_factor.h +++ b/chromeos/ash/components/cryptohome/auth_factor.h
@@ -14,6 +14,16 @@ namespace cryptohome { +// All authfactors created/modified after AuthFactor API is launched should +// have OS/Chrome versions filled in CommonMetadata. +// However, any factor created before the launch would miss such information. +// In order to keep rest of the code simple, this "zero" value would be used +// upon receiving AuthFactor from cryptohome. +// Note that this value should not be passed back to cryptohome, this +// is guarded by CHECKs in serialization code. +COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_CRYPTOHOME) +extern const char kFallbackFactorVersion[]; + enum class AuthFactorType { // Special edge case - on old ChromeOS versions Kiosk keys and passwords for // regular users had no metadata to distinguish them on cryptohome level, @@ -80,7 +90,10 @@ class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_CRYPTOHOME) AuthFactorCommonMetadata { public: + // This constructor should be used for AuthFactors created on the Chrome side. + // It fills in current Chrome version, leaving ChromeOS version empty. AuthFactorCommonMetadata(); + AuthFactorCommonMetadata(ComponentVersion chrome, ComponentVersion chromeos); ~AuthFactorCommonMetadata(); AuthFactorCommonMetadata(AuthFactorCommonMetadata&&) noexcept; @@ -91,6 +104,18 @@ // Should only be used for testing purposes. bool operator==(const AuthFactorCommonMetadata& other) const; + + const ComponentVersion& chrome_version_last_updated() const { + return chrome_version_last_updated_; + } + + const ComponentVersion& chromeos_version_last_updated() const { + return chromeos_version_last_updated_; + } + + private: + ComponentVersion chrome_version_last_updated_; + ComponentVersion chromeos_version_last_updated_; }; // Per-factor statuses (read-only properties set by cryptohomed):
diff --git a/chromeos/ash/components/cryptohome/auth_factor_conversions.cc b/chromeos/ash/components/cryptohome/auth_factor_conversions.cc index f509264..c3e8e4f 100644 --- a/chromeos/ash/components/cryptohome/auth_factor_conversions.cc +++ b/chromeos/ash/components/cryptohome/auth_factor_conversions.cc
@@ -7,6 +7,7 @@ #include <utility> #include <vector> +#include "base/check_op.h" #include "base/logging.h" #include "base/notreached.h" #include "chromeos/ash/components/dbus/cryptohome/auth_factor.pb.h" @@ -85,7 +86,19 @@ out_proto->set_label(factor.ref().label().value()); // Do not do anything with is_active_for_login yet. - // TODO(b/241259026): fill in common metadata. + CHECK_NE(factor.GetCommonMetadata().chrome_version_last_updated().value(), + kFallbackFactorVersion); + CHECK_NE(factor.GetCommonMetadata().chromeos_version_last_updated().value(), + kFallbackFactorVersion); + + out_proto->mutable_common_metadata()->set_chrome_version_last_updated( + factor.GetCommonMetadata().chrome_version_last_updated().value()); + const auto& chromeos_version = + factor.GetCommonMetadata().chromeos_version_last_updated().value(); + if (!chromeos_version.empty()) { + out_proto->mutable_common_metadata()->set_chromeos_version_last_updated( + chromeos_version); + } switch (factor.ref().type()) { case AuthFactorType::kPassword: @@ -183,9 +196,22 @@ } } AuthFactorRef ref(type, KeyLabel{proto.label()}); - AuthFactorCommonMetadata common_metadata; + ComponentVersion chrome_ver{kFallbackFactorVersion}; + ComponentVersion chromeos_ver{kFallbackFactorVersion}; + if (proto.has_common_metadata()) { + if (!proto.common_metadata().chrome_version_last_updated().empty()) { + chrome_ver = ComponentVersion( + proto.common_metadata().chrome_version_last_updated()); + } + if (!proto.common_metadata().chromeos_version_last_updated().empty()) { + chromeos_ver = ComponentVersion( + proto.common_metadata().chromeos_version_last_updated()); + } + } + AuthFactorCommonMetadata common_metadata{std::move(chrome_ver), + std::move(chromeos_ver)}; + // Ignore is_active_for_login for now - // TODO(b/241259026) : fill in common metadata switch (type) { case AuthFactorType::kPassword: return AuthFactor(std::move(ref), std::move(common_metadata));
diff --git a/chromeos/ash/components/cryptohome/common_types.h b/chromeos/ash/components/cryptohome/common_types.h index 87bb26d93..8895f42 100644 --- a/chromeos/ash/components/cryptohome/common_types.h +++ b/chromeos/ash/components/cryptohome/common_types.h
@@ -23,6 +23,11 @@ // The salt we use for PINs. using PinSalt = base::StrongAlias<class PinSaltTag, std::string>; +// Type that denotes version of software component (Chrome or ChromeOS) +// that was used to set up a factor. +using ComponentVersion = + base::StrongAlias<class ComponentVersionTag, std::string>; + } // namespace cryptohome #endif // CHROMEOS_ASH_COMPONENTS_CRYPTOHOME_COMMON_TYPES_H_
diff --git a/chromeos/ash/components/dbus/hermes/hermes_response_status.cc b/chromeos/ash/components/dbus/hermes/hermes_response_status.cc index 4e8ec82..4712571 100644 --- a/chromeos/ash/components/dbus/hermes/hermes_response_status.cc +++ b/chromeos/ash/components/dbus/hermes/hermes_response_status.cc
@@ -8,6 +8,12 @@ namespace ash { +const std::array<HermesResponseStatus, 4> kHermesUserErrorCodes = { + HermesResponseStatus::kErrorMalformedResponse, + HermesResponseStatus::kErrorAlreadyDisabled, + HermesResponseStatus::kErrorAlreadyEnabled, + HermesResponseStatus::kErrorInvalidActivationCode}; + HermesResponseStatus HermesResponseStatusFromErrorName( const std::string& error_name) { if (error_name == hermes::kErrorAlreadyDisabled) {
diff --git a/chromeos/ash/components/dbus/hermes/hermes_response_status.h b/chromeos/ash/components/dbus/hermes/hermes_response_status.h index f3dc221..68f82007 100644 --- a/chromeos/ash/components/dbus/hermes/hermes_response_status.h +++ b/chromeos/ash/components/dbus/hermes/hermes_response_status.h
@@ -5,6 +5,7 @@ #ifndef CHROMEOS_ASH_COMPONENTS_DBUS_HERMES_HERMES_RESPONSE_STATUS_H_ #define CHROMEOS_ASH_COMPONENTS_DBUS_HERMES_HERMES_RESPONSE_STATUS_H_ +#include <array> #include <ostream> #include <string> #include "base/callback.h" @@ -40,6 +41,10 @@ kMaxValue = kErrorSendHttpsFailure }; +// Hermes codes returned that are possibly a result of user error. +extern const std::array<HermesResponseStatus, 4> COMPONENT_EXPORT(HERMES_CLIENT) + kHermesUserErrorCodes; + // Callback that receives only a HermesResponseStatus. using HermesResponseCallback = base::OnceCallback<void(HermesResponseStatus status)>;
diff --git a/chromeos/ash/components/network/cellular_esim_installer_unittest.cc b/chromeos/ash/components/network/cellular_esim_installer_unittest.cc index a9f3f20..7960cee 100644 --- a/chromeos/ash/components/network/cellular_esim_installer_unittest.cc +++ b/chromeos/ash/components/network/cellular_esim_installer_unittest.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/containers/contains.h" #include "base/run_loop.h" #include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" @@ -45,6 +46,8 @@ const char kTestEid[] = "12345678901234567890123456789012"; const char kInstallViaQrCodeHistogram[] = "Network.Cellular.ESim.InstallViaQrCode.Result"; +const char kESimInstallNonUserErrorSuccessRate[] = + "Network.Cellular.ESim.Installation.NonUserErrorSuccessRate"; const char kUserInstallOperationHistogram[] = "Network.Cellular.ESim.UserInstall.OperationResult.All"; @@ -227,6 +230,16 @@ kInstallViaQrCodeHistogram, expected_hermes_status, expected_count); HistogramTesterPtr()->ExpectBucketCount( kInstallESimResultHistogram, expected_install_result, expected_count); + + if (expected_hermes_status == HermesResponseStatus::kSuccess || + !base::Contains(kHermesUserErrorCodes, expected_hermes_status)) { + HistogramTesterPtr()->ExpectBucketCount( + kESimInstallNonUserErrorSuccessRate, expected_hermes_status, + expected_count); + } else { + HistogramTesterPtr()->ExpectBucketCount( + kESimInstallNonUserErrorSuccessRate, expected_hermes_status, 0); + } } void CheckDetailedESimInstallHistograms(
diff --git a/chromeos/ash/components/network/hermes_metrics_util.cc b/chromeos/ash/components/network/hermes_metrics_util.cc index d133700..5f19210 100644 --- a/chromeos/ash/components/network/hermes_metrics_util.cc +++ b/chromeos/ash/components/network/hermes_metrics_util.cc
@@ -4,6 +4,7 @@ #include "chromeos/ash/components/network/hermes_metrics_util.h" +#include "base/containers/contains.h" #include "base/metrics/histogram_functions.h" namespace ash::hermes_metrics { @@ -11,6 +12,12 @@ void LogInstallViaQrCodeResult(HermesResponseStatus status) { base::UmaHistogramEnumeration("Network.Cellular.ESim.InstallViaQrCode.Result", status); + + if (status == HermesResponseStatus::kSuccess || + !base::Contains(kHermesUserErrorCodes, status)) { + base::UmaHistogramEnumeration( + "Network.Cellular.ESim.Installation.NonUserErrorSuccessRate", status); + } } void LogInstallPendingProfileResult(HermesResponseStatus status) {
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index 23fe10c..ca714516 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -1624,6 +1624,8 @@ optional SelectorProto.SemanticFilter semantic_filter = 4; // The element's backend node id. optional int32 backend_node_id = 3; + // Whether this element was found using a feature override. + optional bool used_override = 5; reserved 1, 2; }
diff --git a/components/autofill_assistant/browser/web/element_finder.cc b/components/autofill_assistant/browser/web/element_finder.cc index a5e7ca8..6c59879b2 100644 --- a/components/autofill_assistant/browser/web/element_finder.cc +++ b/components/autofill_assistant/browser/web/element_finder.cc
@@ -123,7 +123,7 @@ if (selector_.proto.filters_size() > 1) { // The semantic filter was only the root, there are more filters to run. - // Log and retain teh current result and start a CSS lookup from here. + // Log and retain the current result and start a CSS lookup from here. UpdateLogInfo(status); current_result_ = std::move(result);
diff --git a/components/autofill_assistant/browser/web/semantic_element_finder.cc b/components/autofill_assistant/browser/web/semantic_element_finder.cc index 726b5b55..546d41a 100644 --- a/components/autofill_assistant/browser/web/semantic_element_finder.cc +++ b/components/autofill_assistant/browser/web/semantic_element_finder.cc
@@ -21,6 +21,7 @@ #include "content/public/browser/global_routing_id.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" +#include "element.h" namespace autofill_assistant { @@ -74,7 +75,7 @@ SendResult(status, ElementFinderResult::EmptyResult()); } -void SemanticElementFinder::ResultFound(const GlobalBackendNodeId& node_id, +void SemanticElementFinder::ResultFound(const SemanticNodeResult& node, const std::string& object_id, const std::string& devtools_frame_id) { if (!callback_) { @@ -82,10 +83,10 @@ } ElementFinderResult result; - result.SetRenderFrameHostGlobalId(node_id.host_id()); + result.SetRenderFrameHostGlobalId(node.id.host_id()); result.SetObjectId(object_id); result.SetNodeFrameId(devtools_frame_id); - result.SetBackendNodeId(node_id.backend_node_id()); + result.SetBackendNodeId(node.id.backend_node_id()); SendResult(OkClientStatus(), result); } @@ -120,13 +121,15 @@ auto* predicted_element = info.mutable_semantic_inference_result()->add_predicted_elements(); predicted_element->set_backend_node_id( - semantic_node_result.backend_node_id()); + semantic_node_result.id.backend_node_id()); *predicted_element->mutable_semantic_filter() = filter_; // TODO(b/217160707): For the ignore_objective case this is not correct // and the inferred objective should be returned from the Agent and used // here. + if (semantic_node_result.used_override) { + predicted_element->set_used_override(semantic_node_result.used_override); + } } - return info; } @@ -156,7 +159,6 @@ } void SemanticElementFinder::OnTimeout() { - VLOG(1) << "AnnotateDomModel timeout."; Finalize(); } @@ -194,20 +196,22 @@ node_data_frame_status_.emplace_back(status); - std::vector<GlobalBackendNodeId> node_ids; + std::vector<SemanticNodeResult> results; for (const auto& node : node_data) { - node_ids.emplace_back(GlobalBackendNodeId(host_id, node.backend_node_id)); + SemanticNodeResult node_result; + node_result.id = GlobalBackendNodeId(host_id, node.backend_node_id); + node_result.used_override = node.used_override; + results.emplace_back(node_result); } - - received_results_.emplace(host_id, std::move(node_ids)); + received_results_.emplace(host_id, std::move(results)); MarkRenderFrameProcessed(host_id); } void SemanticElementFinder::OnRunAnnotateDomModel() { - for (const auto& [backend_id, node_ids] : received_results_) { - semantic_node_results_.insert(semantic_node_results_.end(), - node_ids.begin(), node_ids.end()); + for (const auto& [backend_id, results] : received_results_) { + semantic_node_results_.insert(semantic_node_results_.end(), results.begin(), + results.end()); } // For now we only support finding a single element. @@ -238,7 +242,7 @@ // not have a session id in our |DevtoolsClient|). std::string devtools_frame_id; auto* frame = - content::RenderFrameHost::FromID(semantic_node_result.host_id()); + content::RenderFrameHost::FromID(semantic_node_result.id.host_id()); if (frame != nullptr && frame->IsRenderFrameLive() && web_contents_->GetPrimaryMainFrame()->GetProcess() != frame->GetProcess()) { @@ -249,7 +253,7 @@ devtools_client_->GetDOM()->ResolveNode( dom::ResolveNodeParams::Builder() - .SetBackendNodeId(semantic_node_result.backend_node_id()) + .SetBackendNodeId(semantic_node_result.id.backend_node_id()) .Build(), devtools_frame_id, base::BindOnce(&SemanticElementFinder::OnResolveNodeForAnnotateDom, @@ -258,7 +262,7 @@ } void SemanticElementFinder::OnResolveNodeForAnnotateDom( - const GlobalBackendNodeId& node, + const SemanticNodeResult& node, const std::string& devtools_frame_id, const DevtoolsClient::ReplyStatus& reply_status, std::unique_ptr<dom::ResolveNodeResult> result) {
diff --git a/components/autofill_assistant/browser/web/semantic_element_finder.h b/components/autofill_assistant/browser/web/semantic_element_finder.h index d558be94..a54d68d9 100644 --- a/components/autofill_assistant/browser/web/semantic_element_finder.h +++ b/components/autofill_assistant/browser/web/semantic_element_finder.h
@@ -36,6 +36,11 @@ class SemanticElementFinder : public BaseElementFinder, public content::WebContentsObserver { public: + struct SemanticNodeResult { + GlobalBackendNodeId id = GlobalBackendNodeId(nullptr, -1); + bool used_override = false; + }; + SemanticElementFinder(content::WebContents* web_contents, DevtoolsClient* devtools_client, AnnotateDomModelService* annotate_dom_model_service, @@ -59,7 +64,7 @@ // Builds a result from the provided information and returns it with an // ok status. - void ResultFound(const GlobalBackendNodeId& node_id, + void ResultFound(const SemanticNodeResult& node_id, const std::string& object_id, const std::string& devtools_frame_id); @@ -84,7 +89,7 @@ void OnRunAnnotateDomModel(); void OnResolveNodeForAnnotateDom( - const GlobalBackendNodeId& node, + const SemanticNodeResult& node, const std::string& devtools_frame_id, const DevtoolsClient::ReplyStatus& reply_status, std::unique_ptr<dom::ResolveNodeResult> result); @@ -111,11 +116,11 @@ // Elements gathered through all frames. Unused if the |selector_| does not // contain |SemanticInformation|. - std::vector<GlobalBackendNodeId> semantic_node_results_; + std::vector<SemanticNodeResult> semantic_node_results_; std::vector<mojom::NodeDataStatus> node_data_frame_status_; std::set<content::GlobalRenderFrameHostId> expected_frame_ids_; - std::map<content::GlobalRenderFrameHostId, std::vector<GlobalBackendNodeId>> + std::map<content::GlobalRenderFrameHostId, std::vector<SemanticNodeResult>> received_results_; std::unique_ptr<base::OneShotTimer> timer_ = nullptr;
diff --git a/components/autofill_assistant/browser/web/semantic_element_finder_browsertest.cc b/components/autofill_assistant/browser/web/semantic_element_finder_browsertest.cc index bbacd796..18937ea1 100644 --- a/components/autofill_assistant/browser/web/semantic_element_finder_browsertest.cc +++ b/components/autofill_assistant/browser/web/semantic_element_finder_browsertest.cc
@@ -328,6 +328,15 @@ ClientStatus status = RunWaitForDom(action_proto, /* use_observers= */ false, run_expectations.Get()); EXPECT_EQ(status.proto_status(), ACTION_APPLIED); + + ASSERT_EQ(log_info_.element_finder_info().size(), 1); + const auto& result = + log_info_.element_finder_info(0).semantic_inference_result(); + ASSERT_EQ(1, result.predicted_elements().size()); + EXPECT_EQ(backend_node_id, result.predicted_elements(0).backend_node_id()); + EXPECT_THAT(1, result.predicted_elements(0).semantic_filter().role()); + EXPECT_THAT(2, result.predicted_elements(0).semantic_filter().objective()); + EXPECT_FALSE(result.predicted_elements(0).used_override()); } IN_PROC_BROWSER_TEST_F(SemanticElementFinderBrowserTest, @@ -816,4 +825,56 @@ EXPECT_EQ(option_status.proto_status(), TIMED_OUT); } +#if BUILDFLAG(IS_ANDROID) +IN_PROC_BROWSER_TEST_F(SemanticElementFinderBrowserTest, + WaitForDomForSemanticElementWithOverride) { + // This element is unique. + SelectorProto baseline_selector = ToSelectorProto("#select"); + + ClientStatus element_status; + int backend_node_id = + GetBackendNodeId(Selector(baseline_selector), &element_status); + EXPECT_TRUE(element_status.ok()); + + NodeData node_data; + node_data.backend_node_id = backend_node_id; + node_data.used_override = true; + EXPECT_CALL(autofill_assistant_agent_, + GetSemanticNodes(1, 2, false, base::Milliseconds(5000), _)) + .WillOnce(RunOnceCallback<4>(mojom::NodeDataStatus::kSuccess, + std::vector<NodeData>{node_data})) + // Capture any other frames. + .WillRepeatedly(RunOnceCallback<4>( + mojom::NodeDataStatus::kUnexpectedError, std::vector<NodeData>())); + + ActionProto action_proto; + auto* wait_for_dom = action_proto.mutable_wait_for_dom(); + auto* condition = wait_for_dom->mutable_wait_condition(); + condition->mutable_client_id()->set_identifier("e"); + condition->set_require_unique_element(true); + auto* semantic_filter = + condition->mutable_match()->add_filters()->mutable_semantic(); + semantic_filter->set_role(1); + semantic_filter->set_objective(2); + + base::MockCallback<base::OnceCallback<void(ScriptExecutor*)>> + run_expectations; + EXPECT_CALL(run_expectations, Run(_)) + .WillOnce([](ScriptExecutor* script_executor) { + EXPECT_TRUE(script_executor->GetElementStore()->HasElement("e")); + }); + ClientStatus status = RunWaitForDom(action_proto, /* use_observers= */ false, + run_expectations.Get()); + EXPECT_EQ(status.proto_status(), ACTION_APPLIED); + ASSERT_EQ(log_info_.element_finder_info().size(), 1); + const auto& result = + log_info_.element_finder_info(0).semantic_inference_result(); + ASSERT_EQ(1, result.predicted_elements().size()); + EXPECT_EQ(backend_node_id, result.predicted_elements(0).backend_node_id()); + EXPECT_THAT(1, result.predicted_elements(0).semantic_filter().role()); + EXPECT_THAT(2, result.predicted_elements(0).semantic_filter().objective()); + EXPECT_TRUE(result.predicted_elements(0).used_override()); +} +#endif + } // namespace autofill_assistant
diff --git a/components/autofill_assistant/content/browser/content_autofill_assistant_driver.cc b/components/autofill_assistant/content/browser/content_autofill_assistant_driver.cc index 2aaf5a6..1ecfb91 100644 --- a/components/autofill_assistant/content/browser/content_autofill_assistant_driver.cc +++ b/components/autofill_assistant/content/browser/content_autofill_assistant_driver.cc
@@ -7,7 +7,6 @@ #include "base/files/file.h" #include "base/guid.h" #include "base/location.h" -#include "base/logging.h" #include "components/autofill_assistant/content/common/proto/semantic_feature_overrides.pb.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" @@ -35,7 +34,6 @@ pending_receiver, content::RenderFrameHost* render_frame_host) { DCHECK(render_frame_host); - auto* driver = ContentAutofillAssistantDriver::GetOrCreateForCurrentDocument( render_frame_host); if (driver) { @@ -78,7 +76,6 @@ base::TimeDelta timeout, GetAnnotateDomModelCallback callback) { if (!annotate_dom_model_service_) { - LOG(ERROR) << "No model service"; std::move(callback).Run(mojom::ModelStatus::kUnexpectedError, base::File(), /*overrides_policy=*/""); return; @@ -131,7 +128,6 @@ if (it == pending_calls_.end()) { return; } - DCHECK(it->second->callback_); std::move(it->second->callback_) .Run(model_status, std::move(model_file), GetOverridesPolicy()); @@ -140,12 +136,13 @@ void ContentAutofillAssistantDriver::SetAnnotateDomModelService( AnnotateDomModelService* annotate_dom_model_service) { - DCHECK(annotate_dom_model_service); annotate_dom_model_service_ = annotate_dom_model_service; } std::string ContentAutofillAssistantDriver::GetOverridesPolicy() const { - DCHECK(annotate_dom_model_service_); + if (!annotate_dom_model_service_) { + return ""; + } return annotate_dom_model_service_->GetOverridesPolicy(); }
diff --git a/components/autofill_assistant/content/common/autofill_assistant_types.mojom b/components/autofill_assistant/content/common/autofill_assistant_types.mojom index 38b4d90..0f594cf 100644 --- a/components/autofill_assistant/content/common/autofill_assistant_types.mojom +++ b/components/autofill_assistant/content/common/autofill_assistant_types.mojom
@@ -24,4 +24,7 @@ struct NodeData { // The BackendNodeId of this element. int32 backend_node_id; + + // Whether an override was used. + bool used_override; };
diff --git a/components/autofill_assistant/content/common/autofill_assistant_types_mojom_traits.cc b/components/autofill_assistant/content/common/autofill_assistant_types_mojom_traits.cc index 07a9348..7aa16daa 100644 --- a/components/autofill_assistant/content/common/autofill_assistant_types_mojom_traits.cc +++ b/components/autofill_assistant/content/common/autofill_assistant_types_mojom_traits.cc
@@ -14,6 +14,7 @@ Read(autofill_assistant::mojom::NodeDataDataView data, autofill_assistant::NodeData* out) { out->backend_node_id = data.backend_node_id(); + out->used_override = data.used_override(); return true; }
diff --git a/components/autofill_assistant/content/common/autofill_assistant_types_mojom_traits.h b/components/autofill_assistant/content/common/autofill_assistant_types_mojom_traits.h index 874b764..70b25a5 100644 --- a/components/autofill_assistant/content/common/autofill_assistant_types_mojom_traits.h +++ b/components/autofill_assistant/content/common/autofill_assistant_types_mojom_traits.h
@@ -20,6 +20,10 @@ return r.backend_node_id; } + static bool used_override(const autofill_assistant::NodeData& r) { + return r.used_override; + } + static bool Read(autofill_assistant::mojom::NodeDataDataView data, autofill_assistant::NodeData* out); };
diff --git a/components/autofill_assistant/content/common/node_data.h b/components/autofill_assistant/content/common/node_data.h index b0cec1e..1b827fc 100644 --- a/components/autofill_assistant/content/common/node_data.h +++ b/components/autofill_assistant/content/common/node_data.h
@@ -18,6 +18,7 @@ ~NodeData(); int32_t backend_node_id; + bool used_override; }; } // namespace autofill_assistant
diff --git a/components/autofill_assistant/content/renderer/BUILD.gn b/components/autofill_assistant/content/renderer/BUILD.gn index 81035a9c..a5fa3cd 100644 --- a/components/autofill_assistant/content/renderer/BUILD.gn +++ b/components/autofill_assistant/content/renderer/BUILD.gn
@@ -13,8 +13,7 @@ sources = [ "autofill_assistant_agent.cc", "autofill_assistant_agent.h", - "autofill_assistant_agent_debug_utils.cc", - "autofill_assistant_agent_debug_utils.h", + "autofill_assistant_model_executor_result.h", ] deps = [ @@ -34,6 +33,8 @@ if (build_with_tflite_lib) { sources += [ + "autofill_assistant_agent_debug_utils.cc", + "autofill_assistant_agent_debug_utils.h", "autofill_assistant_model_executor.cc", "autofill_assistant_model_executor.h", ]
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_agent.cc b/components/autofill_assistant/content/renderer/autofill_assistant_agent.cc index 7d0d7590..67ef6cd8a 100644 --- a/components/autofill_assistant/content/renderer/autofill_assistant_agent.cc +++ b/components/autofill_assistant/content/renderer/autofill_assistant_agent.cc
@@ -22,6 +22,7 @@ #if BUILDFLAG(BUILD_WITH_TFLITE_LIB) #include "components/autofill_assistant/content/common/proto/semantic_feature_overrides.pb.h" +#include "components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.h" #include "components/autofill_assistant/content/renderer/autofill_assistant_model_executor.h" #endif // BUILDFLAG(BUILD_WITH_TFLITE_LIB) @@ -86,8 +87,10 @@ std::string jsonEncodedSemanticEnums = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( autofill_assistant::switches::kAutofillAssistantDebugAnnotateDom); +#if BUILDFLAG(BUILD_WITH_TFLITE_LIB) semantic_labels = DecodeSemanticPredictionLabelsJson(jsonEncodedSemanticEnums); +#endif } } @@ -219,10 +222,11 @@ } } - if (result && result->first == role && - (result->second == objective || ignore_objective)) { + if (result && result->role == role && + (result->objective == objective || ignore_objective)) { NodeData node_data; node_data.backend_node_id = node_signal.backend_node_id; + node_data.used_override = result->used_override; nodes.push_back(node_data); } }
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_agent.h b/components/autofill_assistant/content/renderer/autofill_assistant_agent.h index 06962af8..b1e4044 100644 --- a/components/autofill_assistant/content/renderer/autofill_assistant_agent.h +++ b/components/autofill_assistant/content/renderer/autofill_assistant_agent.h
@@ -12,7 +12,6 @@ #include "components/autofill_assistant/content/common/autofill_assistant_agent.mojom.h" #include "components/autofill_assistant/content/common/autofill_assistant_driver.mojom.h" #include "components/autofill_assistant/content/common/node_data.h" -#include "components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.h" #include "content/public/renderer/render_frame_observer.h" #include "mojo/public/cpp/bindings/associated_receiver.h" #include "mojo/public/cpp/bindings/associated_remote.h" @@ -83,6 +82,9 @@ const std::u16string& value, bool send_events); + using SemanticPredictionLabelMap = base::flat_map<int, std::string>; + using SemanticLabelsPair = + std::pair<SemanticPredictionLabelMap, SemanticPredictionLabelMap>; SemanticLabelsPair semantic_labels; mojo::AssociatedRemote<mojom::AutofillAssistantDriver> driver_;
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_agent_browsertest.cc b/components/autofill_assistant/content/renderer/autofill_assistant_agent_browsertest.cc index a548d57..8357414 100644 --- a/components/autofill_assistant/content/renderer/autofill_assistant_agent_browsertest.cc +++ b/components/autofill_assistant/content/renderer/autofill_assistant_agent_browsertest.cc
@@ -18,6 +18,7 @@ #include "content/public/renderer/render_frame.h" #include "content/public/test/render_view_test.h" #include "mojo/public/cpp/bindings/associated_receiver_set.h" +#include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" @@ -32,6 +33,7 @@ using ::base::test::RunOnceCallback; using ::testing::_; +using ::testing::Field; using ::testing::SizeIs; constexpr int kDummySemanticRole = 9999; @@ -107,7 +109,9 @@ base::MockCallback<base::OnceCallback<void(mojom::NodeDataStatus, const std::vector<NodeData>&)>> callback; - EXPECT_CALL(callback, Run(mojom::NodeDataStatus::kSuccess, SizeIs(1))); + EXPECT_CALL(callback, + Run(mojom::NodeDataStatus::kSuccess, + ElementsAre(Field(&NodeData::used_override, false)))); LoadHTML(R"( <div> @@ -291,7 +295,9 @@ base::MockCallback<base::OnceCallback<void(mojom::NodeDataStatus, const std::vector<NodeData>&)>> callback; - EXPECT_CALL(callback, Run(mojom::NodeDataStatus::kSuccess, SizeIs(1))); + EXPECT_CALL(callback, + Run(mojom::NodeDataStatus::kSuccess, + ElementsAre(Field(&NodeData::used_override, true)))); autofill_assistant_agent_->GetSemanticNodes( kDummySemanticRole, kDummyObjective,
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.cc b/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.cc index 2144f16..ee30af96 100644 --- a/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.cc +++ b/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.cc
@@ -86,27 +86,30 @@ std::u16string SemanticPredictionResultToDebugString( SemanticPredictionLabelMap roles, SemanticPredictionLabelMap objectives, - const std::pair<int, int>& result, + const ModelExecutorResult& result, bool ignore_objective) { + int role = result.role; + int objective = result.objective; if (!roles.empty() || !objectives.empty()) { std::string result_label = - roles.contains(result.first) - ? roles.at(result.first) - : "(missing-label) " + base::NumberToString(result.first); + roles.contains(role) ? roles.at(role) + : "(missing-label) " + base::NumberToString(role); std::string objective_label = - objectives.contains(result.second) - ? objectives.at(result.second) - : "(missing-label) " + base::NumberToString(result.second); + objectives.contains(objective) + ? objectives.at(objective) + : "(missing-label) " + base::NumberToString(objective); return base::StrCat( {u"{role: ", std::u16string(result_label.begin(), result_label.end()), u", objective: ", std::u16string(objective_label.begin(), objective_label.end()), - (ignore_objective ? u"(ignored)}" : u"}")}); + (ignore_objective ? u"(ignored)}" : u"}"), + (result.used_override ? u"[override]" : u"")}); } - return base::StrCat({u"{role: ", base::NumberToString16(result.first), - u", objective: ", base::NumberToString16(result.second), - (ignore_objective ? u"(ignored)}" : u"}")}); + return base::StrCat({u"{role: ", base::NumberToString16(role), + u", objective: ", base::NumberToString16(objective), + (ignore_objective ? u"(ignored)}" : u"}"), + (result.used_override ? u"[override]" : u"")}); } } // namespace autofill_assistant
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.h b/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.h index df96538..1ef8ac6 100644 --- a/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.h +++ b/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils.h
@@ -8,6 +8,7 @@ #include <string> #include "base/containers/flat_map.h" +#include "components/autofill_assistant/content/renderer/autofill_assistant_model_executor_result.h" #include "third_party/blink/public/web/modules/autofill_assistant/node_signals.h" namespace autofill_assistant { @@ -33,7 +34,7 @@ std::u16string SemanticPredictionResultToDebugString( SemanticPredictionLabelMap roles, SemanticPredictionLabelMap objectives, - const std::pair<int, int>& result, + const ModelExecutorResult& result, bool ignore_objective); } // namespace autofill_assistant
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils_unittest.cc b/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils_unittest.cc index f32b6808..6c5d8cd1 100644 --- a/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils_unittest.cc +++ b/components/autofill_assistant/content/renderer/autofill_assistant_agent_debug_utils_unittest.cc
@@ -11,7 +11,11 @@ namespace autofill_assistant { namespace { -using SemanticLabelsJsonParsingTest = ::testing::Test; +class SemanticLabelsJsonParsingTest : public ::testing::Test { + protected: + ModelExecutorResult model_executor_result_ = + ModelExecutorResult(47, 7, false); +}; TEST_F(SemanticLabelsJsonParsingTest, ValidJson) { std::string json_input = R"({ @@ -28,7 +32,27 @@ SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json); std::u16string debug_string = SemanticPredictionResultToDebugString( - labels.first, labels.second, {47, 7}, false); + labels.first, labels.second, model_executor_result_, false); + EXPECT_EQ(debug_string, + std::u16string(expected_output.begin(), expected_output.end())); +} + +TEST_F(SemanticLabelsJsonParsingTest, UseOverrideField) { + std::string json_input = R"({ + "roles": [{"id": 47, "name": "ADDRESS_LINE1"}], + "objectives": [{"id": 7, "name": "FILL_DELIVERY_ADDRESS"}] + })"; + std::string expected_output = + "{role: ADDRESS_LINE1, objective: FILL_DELIVERY_ADDRESS}[override]"; + + // Encode the JSON and add it to the debug DOM annotations switch + std::string base64_json; + base::Base64Encode(json_input, &base64_json); + + SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json); + + std::u16string debug_string = SemanticPredictionResultToDebugString( + labels.first, labels.second, ModelExecutorResult(47, 7, true), false); EXPECT_EQ(debug_string, std::u16string(expected_output.begin(), expected_output.end())); } @@ -54,7 +78,7 @@ SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json); std::u16string debug_string = SemanticPredictionResultToDebugString( - labels.first, labels.second, {47, 7}, false); + labels.first, labels.second, model_executor_result_, false); EXPECT_EQ(debug_string, std::u16string(expected_output.begin(), expected_output.end())); } @@ -70,7 +94,7 @@ SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json); std::u16string debug_string = SemanticPredictionResultToDebugString( - labels.first, labels.second, {47, 7}, false); + labels.first, labels.second, model_executor_result_, false); EXPECT_EQ(debug_string, std::u16string(expected_output.begin(), expected_output.end())); } @@ -90,7 +114,7 @@ SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json); std::u16string debug_string = SemanticPredictionResultToDebugString( - labels.first, labels.second, {47, 7}, false); + labels.first, labels.second, model_executor_result_, false); EXPECT_EQ(debug_string, std::u16string(expected_output.begin(), expected_output.end())); } @@ -110,7 +134,7 @@ SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json); std::u16string debug_string = SemanticPredictionResultToDebugString( - labels.first, labels.second, {47, 7}, false); + labels.first, labels.second, model_executor_result_, false); EXPECT_EQ(debug_string, std::u16string(expected_output.begin(), expected_output.end())); } @@ -129,7 +153,7 @@ SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json); std::u16string debug_string = SemanticPredictionResultToDebugString( - labels.first, labels.second, {47, 7}, false); + labels.first, labels.second, model_executor_result_, false); EXPECT_EQ(debug_string, std::u16string(expected_output.begin(), expected_output.end())); } @@ -149,7 +173,7 @@ SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json); std::u16string debug_string = SemanticPredictionResultToDebugString( - labels.first, labels.second, {47, 7}, false); + labels.first, labels.second, model_executor_result_, false); EXPECT_EQ(debug_string, std::u16string(expected_output.begin(), expected_output.end())); } @@ -169,7 +193,7 @@ SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json); std::u16string debug_string = SemanticPredictionResultToDebugString( - labels.first, labels.second, {47, 7}, false); + labels.first, labels.second, model_executor_result_, false); EXPECT_EQ(debug_string, std::u16string(expected_output.begin(), expected_output.end())); } @@ -185,7 +209,7 @@ SemanticLabelsPair labels = DecodeSemanticPredictionLabelsJson(base64_json); std::u16string debug_string = SemanticPredictionResultToDebugString( - labels.first, labels.second, {47, 7}, false); + labels.first, labels.second, model_executor_result_, false); EXPECT_EQ(debug_string, std::u16string(expected_output.begin(), expected_output.end())); }
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.cc b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.cc index 496d218ac..8b3a60b 100644 --- a/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.cc +++ b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.cc
@@ -6,6 +6,7 @@ #include <ostream> +#include "autofill_assistant_model_executor.h" #include "base/command_line.h" #include "base/i18n/case_conversion.h" #include "base/no_destructor.h" @@ -112,7 +113,7 @@ std::make_unique<ExecutionTask>(std::move(tflite_engine), this); } -absl::optional<std::pair<int, int>> +absl::optional<ModelExecutorResult> AutofillAssistantModelExecutor::ExecuteModelWithInput( const blink::AutofillAssistantNodeSignals& node_signals) { if (!execution_task_) { @@ -252,7 +253,7 @@ return true; } -absl::optional<std::pair<int, int>> AutofillAssistantModelExecutor::Postprocess( +absl::optional<ModelExecutorResult> AutofillAssistantModelExecutor::Postprocess( const std::vector<const TfLiteTensor*>& output_tensors) { // Check if we have an override for this execution and return that instead. if (overrides_result_) { @@ -262,7 +263,8 @@ << ", objective: " << overrides_result_->second << ")"; } // Cleanup the result in case this executor is reused. - std::pair<int, int> result = *overrides_result_; + ModelExecutorResult result(overrides_result_->first, + overrides_result_->second, true); overrides_result_.reset(); return result; } @@ -296,7 +298,7 @@ int semantic_role = model_metadata_.output().semantic_role().classes(index_of_best_role); if (semantic_role == 0) { - return std::pair<int, int>(semantic_role, 0); + return ModelExecutorResult(/*r=*/0, /*o=*/0, /*with_override=*/false); } int block_index; @@ -308,7 +310,8 @@ return absl::nullopt; } - return std::pair<int, int>(semantic_role, objective); + ModelExecutorResult result(semantic_role, objective, false); + return result; } void AutofillAssistantModelExecutor::Tokenize(
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.h b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.h index 7e8822e..88d662b 100644 --- a/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.h +++ b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor.h
@@ -11,6 +11,7 @@ #include "base/files/file.h" #include "base/files/memory_mapped_file.h" +#include "components/autofill_assistant/content/renderer/autofill_assistant_model_executor_result.h" #include "components/autofill_assistant/content/renderer/model_metadata.pb.h" #include "components/optimization_guide/core/base_model_executor.h" #include "components/optimization_guide/core/base_model_executor_helpers.h" @@ -27,11 +28,11 @@ // node signals. class AutofillAssistantModelExecutor : public optimization_guide::BaseModelExecutor< - std::pair<int, int>, + ModelExecutorResult, const blink::AutofillAssistantNodeSignals&> { public: using ExecutionTask = optimization_guide::GenericModelExecutionTask< - std::pair<int, int>, + ModelExecutorResult, const blink::AutofillAssistantNodeSignals&>; using SparseVector = std::vector<std::pair<std::pair<int, int>, int>>; using SparseMap = base::flat_map<std::pair<int, int>, int>; @@ -49,7 +50,7 @@ bool InitializeModelFromFile(base::File model_file); // Execute the model with the given input. - absl::optional<std::pair<int, int>> ExecuteModelWithInput( + absl::optional<ModelExecutorResult> ExecuteModelWithInput( const blink::AutofillAssistantNodeSignals& node_signals); protected: @@ -57,7 +58,7 @@ bool Preprocess( const std::vector<TfLiteTensor*>& input_tensors, const blink::AutofillAssistantNodeSignals& node_signals) override; - absl::optional<std::pair<int, int>> Postprocess( + absl::optional<ModelExecutorResult> Postprocess( const std::vector<const TfLiteTensor*>& output_tensors) override; private:
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_model_executor_result.h b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor_result.h new file mode 100644 index 0000000..42c40fd --- /dev/null +++ b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor_result.h
@@ -0,0 +1,26 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_ASSISTANT_CONTENT_RENDERER_AUTOFILL_ASSISTANT_MODEL_EXECUTOR_RESULT_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_CONTENT_RENDERER_AUTOFILL_ASSISTANT_MODEL_EXECUTOR_RESULT_H_ + +namespace autofill_assistant { + +// Result used to communicated model execution results between interested +// parties. +struct ModelExecutorResult { + ModelExecutorResult() = default; + ModelExecutorResult(int r, int o, bool with_override) + : role(r), objective(o), used_override(with_override) {} + + // Role and objective pair. + int role = 0; + int objective = 0; + // Whether this result came from an override. + bool used_override = false; +}; + +} // namespace autofill_assistant + +#endif // COMPONENTS_AUTOFILL_ASSISTANT_CONTENT_RENDERER_AUTOFILL_ASSISTANT_MODEL_EXECUTOR_RESULT_H_
diff --git a/components/autofill_assistant/content/renderer/autofill_assistant_model_executor_unittest.cc b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor_unittest.cc index 1212e00..862620e 100644 --- a/components/autofill_assistant/content/renderer/autofill_assistant_model_executor_unittest.cc +++ b/components/autofill_assistant/content/renderer/autofill_assistant_model_executor_unittest.cc
@@ -101,8 +101,8 @@ auto result = model_executor_.ExecuteModelWithInput(node_signals); ASSERT_TRUE(result.has_value()); - EXPECT_EQ(result->first, 47 /* ADDRESS_LINE1 */); - EXPECT_EQ(result->second, 7 /* FILL_DELIVERY_ADDRESS */); + EXPECT_EQ(result->role, 47 /* ADDRESS_LINE1 */); + EXPECT_EQ(result->objective, 7 /* FILL_DELIVERY_ADDRESS */); } TEST_F(AutofillAssistantModelExecutorTest, OverridesMatch) { @@ -119,8 +119,9 @@ auto result = model_executor.ExecuteModelWithInput(node_signals); ASSERT_TRUE(result.has_value()); - EXPECT_EQ(result->first, 9999); - EXPECT_EQ(result->second, 1111); + EXPECT_EQ(result->role, 9999); + EXPECT_EQ(result->objective, 1111); + EXPECT_TRUE(result->used_override); } TEST_F(AutofillAssistantModelExecutorTest, OverridesNoMatch) { @@ -135,8 +136,9 @@ auto result = model_executor.ExecuteModelWithInput(node_signals); ASSERT_TRUE(result.has_value()); - EXPECT_NE(result->first, 9999); - EXPECT_NE(result->second, 1111); + EXPECT_NE(result->role, 9999); + EXPECT_NE(result->objective, 1111); + EXPECT_FALSE(result->used_override); } TEST_F(AutofillAssistantModelExecutorTest, OverridesResultNotReused) { @@ -153,8 +155,9 @@ auto result = model_executor.ExecuteModelWithInput(node_signals); ASSERT_TRUE(result.has_value()); - EXPECT_EQ(result->first, 9999); - EXPECT_EQ(result->second, 1111); + EXPECT_EQ(result->role, 9999); + EXPECT_EQ(result->objective, 1111); + EXPECT_TRUE(result->used_override); } // We expect the internal overrides result from the previous execution to have @@ -166,8 +169,9 @@ auto result = model_executor.ExecuteModelWithInput(node_signals); ASSERT_TRUE(result.has_value()); - EXPECT_NE(result->first, 9999); - EXPECT_NE(result->second, 1111); + EXPECT_NE(result->role, 9999); + EXPECT_NE(result->objective, 1111); + EXPECT_FALSE(result->used_override); } }
diff --git a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomMediatorUnitTest.java b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomMediatorUnitTest.java index 0d897d8..a30138e 100644 --- a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomMediatorUnitTest.java +++ b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomMediatorUnitTest.java
@@ -87,12 +87,12 @@ when(mHostZoomMapMock.getZoomLevel(any())).thenReturn(2.22); mMediator.setWebContents(mWebContentsMock); Assert.assertEquals( - CURRENT_ZOOM_FAILURE, 125, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); + CURRENT_ZOOM_FAILURE, 100, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); mMediator.handleDecreaseClicked(null); verify(mHostZoomMapMock, times(1).description(DECREASE_ZOOM_FAILURE_NO_JNI)) .setZoomLevel(mWebContentsMock, 1.56, 1.56); Assert.assertEquals( - CURRENT_ZOOM_FAILURE, 108, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); + CURRENT_ZOOM_FAILURE, 83, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); } @Test @@ -102,12 +102,12 @@ when(mHostZoomMapMock.getZoomLevel(any())).thenReturn(2.22); mMediator.setWebContents(mWebContentsMock); Assert.assertEquals( - CURRENT_ZOOM_FAILURE, 151, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); + CURRENT_ZOOM_FAILURE, 126, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); mMediator.handleDecreaseClicked(null); verify(mHostZoomMapMock, times(1).description(DECREASE_ZOOM_FAILURE_NO_JNI)) .setZoomLevel(mWebContentsMock, 3.07, 2.18); Assert.assertEquals( - CURRENT_ZOOM_FAILURE, 150, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); + CURRENT_ZOOM_FAILURE, 125, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); } @Test @@ -116,12 +116,12 @@ when(mHostZoomMapMock.getZoomLevel(any())).thenReturn(2.22); mMediator.setWebContents(mWebContentsMock); Assert.assertEquals( - CURRENT_ZOOM_FAILURE, 125, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); + CURRENT_ZOOM_FAILURE, 100, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); mMediator.handleIncreaseClicked(null); verify(mHostZoomMapMock, times(1).description(INCREASE_ZOOM_FAILURE_NO_JNI)) .setZoomLevel(mWebContentsMock, 3.07, 3.07); Assert.assertEquals( - CURRENT_ZOOM_FAILURE, 150, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); + CURRENT_ZOOM_FAILURE, 125, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); } @Test @@ -131,12 +131,12 @@ when(mHostZoomMapMock.getZoomLevel(any())).thenReturn(2.22); mMediator.setWebContents(mWebContentsMock); Assert.assertEquals( - CURRENT_ZOOM_FAILURE, 90, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); + CURRENT_ZOOM_FAILURE, 65, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); mMediator.handleIncreaseClicked(null); verify(mHostZoomMapMock, times(1).description(INCREASE_ZOOM_FAILURE_NO_JNI)) .setZoomLevel(mWebContentsMock, 1.22, 2.66); Assert.assertEquals( - CURRENT_ZOOM_FAILURE, 100, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); + CURRENT_ZOOM_FAILURE, 75, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); } @Test @@ -145,21 +145,21 @@ when(mHostZoomMapMock.getZoomLevel(any())).thenReturn(2.22); mMediator.setWebContents(mWebContentsMock); Assert.assertEquals( - CURRENT_ZOOM_FAILURE, 125, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); - mMediator.handleSeekBarValueChanged(133); + CURRENT_ZOOM_FAILURE, 100, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); + mMediator.handleSeekBarValueChanged(108); verify(mHostZoomMapMock, times(1).description(SEEKBAR_VALUE_FAILURE_NO_JNI)) .setZoomLevel(eq(mWebContentsMock), ArgumentMatchers.doubleThat(argument -> Math.abs(2.51 - argument) <= 0.001), ArgumentMatchers.doubleThat( argument -> Math.abs(2.51 - argument) <= 0.001)); Assert.assertEquals( - SEEKBAR_VALUE_FAILURE, 133, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); + SEEKBAR_VALUE_FAILURE, 108, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); } @Test public void testDecreaseZoomEnabledChange() { // Verify that when already at the minimum zoom, the decrease button is disabled. - when(mHostZoomMapMock.getZoomLevel(any())).thenReturn(-7.6); + when(mHostZoomMapMock.getZoomLevel(any())).thenReturn(-3.8); mMediator.setWebContents(mWebContentsMock); Assert.assertEquals( CURRENT_ZOOM_FAILURE, 0, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); @@ -175,10 +175,10 @@ @Test public void testIncreaseZoomEnabledChange() { // Verify that when already at the maximum zoom, the increase button is disabled - when(mHostZoomMapMock.getZoomLevel(any())).thenReturn(8.83); + when(mHostZoomMapMock.getZoomLevel(any())).thenReturn(6.03); mMediator.setWebContents(mWebContentsMock); Assert.assertEquals( - CURRENT_ZOOM_FAILURE, 475, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); + CURRENT_ZOOM_FAILURE, 250, mModel.get(PageZoomProperties.CURRENT_SEEK_VALUE)); Assert.assertFalse( INCREASE_DISABLED_FAILURE, mModel.get(PageZoomProperties.INCREASE_ZOOM_ENABLED));
diff --git a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomUtils.java b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomUtils.java index 59b8854..786238b 100644 --- a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomUtils.java +++ b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomUtils.java
@@ -22,7 +22,7 @@ * * The zoom of a page is calculated internally with a base an exponent. The base is set to * |kTextSizeMultiplierRatio| = 1.2. See: third_party/blink/common/page/page_zoom.cc. - * E.g. To get a zoom level of 25%, internally the number -7.6 is used, because: 1.2^-7.6 = 0.25. + * E.g. To get a zoom level of 50%, internally the number -3.8 is used, because: 1.2^-3.8 = 0.50. * * To help with confusion, we will consistently stick to the following verbiage: * @@ -34,11 +34,10 @@ * For example, some common zoom values are: * * string factor level seek value - * 25% | -7.6 | 0.25 | 0 | - * 50% | -3.8 | 0.50 | 25 | - * 100% | 0.0 | 1.00 | 125 | - * 250% | 5.03 | 2.50 | 275 | - * 500% | 8.83 | 5.00 | 475 | + * 50% | -3.8 | 0.50 | 0 | + * 100% | 0.0 | 1.00 | 50 | + * 250% | 5.03 | 2.50 | 200 | + * 300% | 6.03 | 3.00 | 250 | * */ public class PageZoomUtils { @@ -46,11 +45,11 @@ public static final int PAGE_ZOOM_DEFAULT_SEEK_VALUE = convertZoomFactorToSeekBarValue(0.0); // The max value for the seek bar to help with rounding effects (not shown to user). - public static final int PAGE_ZOOM_MAXIMUM_SEEKBAR_VALUE = 475; + public static final int PAGE_ZOOM_MAXIMUM_SEEKBAR_VALUE = 250; - // The minimum and maximum zoom values as a percentage (e.g. 25% = 0.25, 500% = 5.0) - private static final float PAGE_ZOOM_MINIMUM_ZOOM_LEVEL = 0.25f; - private static final float PAGE_ZOOM_MAXIMUM_ZOOM_LEVEL = 5.00f; + // The minimum and maximum zoom values as a percentage (e.g. 50% = 0.50, 300% = 3.0) + private static final float PAGE_ZOOM_MINIMUM_ZOOM_LEVEL = 0.50f; + private static final float PAGE_ZOOM_MAXIMUM_ZOOM_LEVEL = 3.00f; /** * Returns whether the Accessibility Settings page should include the 'Zoom' UI. The page @@ -76,7 +75,7 @@ + ((PAGE_ZOOM_MAXIMUM_ZOOM_LEVEL - PAGE_ZOOM_MINIMUM_ZOOM_LEVEL) * seekbarPercent); // The zoom level maps internally to a zoom factor, which is the exponent that - // |kTextSizeMultiplierRatio| = 1.2 is raised to. For example, 1.2^-7.6 = 0.25, or + // |kTextSizeMultiplierRatio| = 1.2 is raised to. For example, 1.2^-3.8 = 0.50, or // 1.2^3.8 = 2.0. See: third_party/blink/common/page/page_zoom.cc // This means zoomFactor = log_base1.2(chosenZoomLevel). Java has natural log and base // 10, we can rewrite the above as: log10(chosenZoomLevel) / log10(1.2);
diff --git a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomUtilsUnitTest.java b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomUtilsUnitTest.java index 787a322..fc3dc7b 100644 --- a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomUtilsUnitTest.java +++ b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/PageZoomUtilsUnitTest.java
@@ -60,21 +60,21 @@ public void testConvertSeekBarValueToZoomFactor() { // Cached zoom factor Assert.assertEquals(SEEKBAR_VALUE_TO_ZOOM_FACTOR_FAILURE, 2.22, - PageZoomUtils.convertSeekBarValueToZoomFactor(125), 0.0001); + PageZoomUtils.convertSeekBarValueToZoomFactor(100), 0.0001); // Non-cached zoom factor Assert.assertEquals(SEEKBAR_VALUE_TO_ZOOM_FACTOR_FAILURE, 2.26, - PageZoomUtils.convertSeekBarValueToZoomFactor(126), 0.0001); + PageZoomUtils.convertSeekBarValueToZoomFactor(101), 0.0001); } @Test public void testConvertZoomFactorToSeekBarValue() { // Cached zoom factor - Assert.assertEquals(ZOOM_FACTOR_TO_SEEKBAR_VALUE_FAILURE, 125, + Assert.assertEquals(ZOOM_FACTOR_TO_SEEKBAR_VALUE_FAILURE, 100, PageZoomUtils.convertZoomFactorToSeekBarValue(2.22)); // Non-cached zoom factor - Assert.assertEquals(ZOOM_FACTOR_TO_SEEKBAR_VALUE_FAILURE, 126, + Assert.assertEquals(ZOOM_FACTOR_TO_SEEKBAR_VALUE_FAILURE, 101, PageZoomUtils.convertZoomFactorToSeekBarValue(2.26)); } @@ -82,32 +82,32 @@ public void testConvertSeekBarValueToZoomLevel() { // Cached zoom level Assert.assertEquals(SEEKBAR_VALUE_TO_ZOOM_LEVEL_FAILURE, 1.5, - PageZoomUtils.convertSeekBarValueToZoomLevel(125), 0.0001); + PageZoomUtils.convertSeekBarValueToZoomLevel(100), 0.0001); // Non-cached zoom level Assert.assertEquals(SEEKBAR_VALUE_TO_ZOOM_FACTOR_FAILURE, 1.51, - PageZoomUtils.convertSeekBarValueToZoomLevel(126), 0.0001); + PageZoomUtils.convertSeekBarValueToZoomLevel(101), 0.0001); } @Test public void testGetNextIndexIncrease() { - Assert.assertEquals(GET_NEXT_INDEX_INCREASE_FAILURE, 9, + Assert.assertEquals(GET_NEXT_INDEX_INCREASE_FAILURE, 7, PageZoomUtils.getNextIndex(false, 1.00), 0.0001); } @Test(expected = IllegalArgumentException.class) public void testGetNextIndexIncreaseMax() { - PageZoomUtils.getNextIndex(false, 8.83); + PageZoomUtils.getNextIndex(false, 6.03); } @Test public void testGetNextIndexDecrease() { Assert.assertEquals( - GET_NEXT_INDEX_DECREASE_FAILURE, 8, PageZoomUtils.getNextIndex(true, 1.00), 0.0001); + GET_NEXT_INDEX_DECREASE_FAILURE, 6, PageZoomUtils.getNextIndex(true, 1.00), 0.0001); } @Test(expected = IllegalArgumentException.class) public void testGetNextIndexDecreaseMin() { - PageZoomUtils.getNextIndex(true, -7.60); + PageZoomUtils.getNextIndex(true, -3.80); } } \ No newline at end of file
diff --git a/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/ManagedPreferencesUtils.java b/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/ManagedPreferencesUtils.java index 826f8de..6646ca3 100644 --- a/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/ManagedPreferencesUtils.java +++ b/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/ManagedPreferencesUtils.java
@@ -197,6 +197,10 @@ ImageView button = view.findViewById(R.id.image_view_widget); button.setImageDrawable(getManagedIconDrawable(delegate, preference)); + if (delegate.isPreferenceControlledByPolicy(preference)) { + button.setContentDescription(preference.getContext().getResources().getString( + R.string.managed_by_your_organization)); + } button.setOnClickListener((View v) -> { if (delegate.isPreferenceControlledByPolicy(preference)) { showManagedByAdministratorToast(preference.getContext());
diff --git a/components/browser_ui/site_settings/DEPS b/components/browser_ui/site_settings/DEPS index 91dc26e..9afe3bd8 100644 --- a/components/browser_ui/site_settings/DEPS +++ b/components/browser_ui/site_settings/DEPS
@@ -13,6 +13,7 @@ "+components/user_prefs", "+content/public/android/java/src/org/chromium/content_public", "+content/public/browser", + "+net/cookies", "+services/device/public", "+services/network/public", "+storage/browser",
diff --git a/components/browser_ui/site_settings/android/BUILD.gn b/components/browser_ui/site_settings/android/BUILD.gn index eee71fab..3c06671 100644 --- a/components/browser_ui/site_settings/android/BUILD.gn +++ b/components/browser_ui/site_settings/android/BUILD.gn
@@ -54,6 +54,7 @@ "java/src/org/chromium/components/browser_ui/site_settings/ClearWebsiteStorageDialog.java", "java/src/org/chromium/components/browser_ui/site_settings/ContentSettingException.java", "java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java", + "java/src/org/chromium/components/browser_ui/site_settings/CookiesInfo.java", "java/src/org/chromium/components/browser_ui/site_settings/DesktopSiteMetrics.java", "java/src/org/chromium/components/browser_ui/site_settings/FPSCookieInfo.java", "java/src/org/chromium/components/browser_ui/site_settings/FPSCookieSettings.java",
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/CookiesInfo.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/CookiesInfo.java new file mode 100644 index 0000000..082cc190 --- /dev/null +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/CookiesInfo.java
@@ -0,0 +1,26 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.components.browser_ui.site_settings; + +import java.io.Serializable; + +/** + * Cookies information for a given origin. + */ +public class CookiesInfo implements Serializable { + private int mCookies; + + public CookiesInfo() { + mCookies = 0; + } + + public void increment() { + mCookies++; + } + + public int getCount() { + return mCookies; + } +}
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/Website.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/Website.java index 13e7c32c..b713b70 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/Website.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/Website.java
@@ -42,6 +42,7 @@ private LocalStorageInfo mLocalStorageInfo; private FPSCookieInfo mFPSCookieInfo; + private CookiesInfo mCookiesInfo; private final List<StorageInfo> mStorageInfo = new ArrayList<>(); // The collection of chooser-based permissions (e.g. USB device access) granted to this site. @@ -287,6 +288,14 @@ return new ArrayList<StorageInfo>(mStorageInfo); } + public void setCookiesInfo(CookiesInfo info) { + mCookiesInfo = info; + } + + public CookiesInfo getCookiesInfo() { + return mCookiesInfo; + } + public void clearAllStoredData( BrowserContextHandle browserContextHandle, final StoredDataClearedCallback callback) { // Wait for callbacks from each mStorageInfo and another callback from @@ -346,6 +355,12 @@ } @Override + public int getNumberOfCookies() { + if (mCookiesInfo == null) return 0; + return mCookiesInfo.getCount(); + } + + @Override public boolean matches(String search) { return getTitle().contains(search); }
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteEntry.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteEntry.java index 5815d2d..3a92690 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteEntry.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteEntry.java
@@ -21,6 +21,9 @@ /** @return the total bytes used for associated storage. */ long getTotalUsage(); + /** @return the total number of cookies associated with the entry. */ + int getNumberOfCookies(); + /** * @return whether either the eTLD+1 or one of the origins associated with it matches the given * search query.
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteGroup.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteGroup.java index 2c1cdd2..daae413c 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteGroup.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteGroup.java
@@ -23,6 +23,8 @@ private final List<Website> mWebsites; // Total storage taken up by all the stored websites. private final long mTotalUsage; + // Total number of cookies associated with the websites. + private final int mCookiesCount; // First Party Sets info relative to the eTLD+1. private FPSCookieInfo mFPSInfo; @@ -67,6 +69,12 @@ mFPSInfo = websites.get(0).getFPSCookieInfo(); } mTotalUsage = totalUsage; + + int cookiesCount = 0; + for (Website website : websites) { + cookiesCount += website.getNumberOfCookies(); + } + mCookiesCount = cookiesCount; } // WebsiteEntry implementation. @@ -91,6 +99,11 @@ } @Override + public int getNumberOfCookies() { + return mCookiesCount; + } + + @Override public boolean matches(String search) { // eTLD+1 matches. if (mDomainAndRegistry.contains(search)) return true;
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java index 75268f0..6cadbc7d 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java
@@ -201,6 +201,10 @@ private void addAllFetchers(TaskQueue queue) { addFetcherForStorage(queue); + // Fetch cookies if the new UI is enabled. + if (SiteSettingsFeatureList.isEnabled(SiteSettingsFeatureList.SITE_DATA_IMPROVEMENTS)) { + queue.add(new CookiesInfoFetcher()); + } for (@ContentSettingsType int type = 0; type < ContentSettingsType.NUM_TYPES; type++) { addFetcherForContentSettingsType(queue, type); } @@ -477,6 +481,25 @@ } } + private class CookiesInfoFetcher extends Task { + @Override + public void runAsync(final TaskQueue queue) { + mWebsitePreferenceBridge.fetchCookiesInfo( + mBrowserContextHandle, new Callback<Map<String, CookiesInfo>>() { + @Override + public void onResult(Map<String, CookiesInfo> result) { + for (Map.Entry<String, CookiesInfo> entry : result.entrySet()) { + String address = entry.getKey(); + if (address == null) continue; + findOrCreateSite(address, null) + .setCookiesInfo(entry.getValue()); + } + queue.next(); + } + }); + } + } + private class FirstPartySetsInfoFetcher extends Task { final SiteSettingsDelegate mSiteSettingsDelegate;
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java index e838d21..8be35c09 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
@@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Utility class that interacts with native to retrieve and set website settings. @@ -90,6 +91,21 @@ .put(origin, new LocalStorageInfo(origin, size, important)); } + @CalledByNative + private static Object createCookiesInfoMap() { + return new HashMap<String, CookiesInfo>(); + } + + @CalledByNative + private static void insertCookieIntoMap(Map<String, CookiesInfo> map, String origin) { + CookiesInfo cookies_info = map.get(origin); + if (cookies_info == null) { + cookies_info = new CookiesInfo(); + map.put(origin, cookies_info); + } + cookies_info.increment(); + } + public List<ContentSettingException> getContentSettingsExceptions( BrowserContextHandle browserContextHandle, @ContentSettingsType int contentSettingsType) { @@ -120,6 +136,11 @@ WebsitePreferenceBridgeJni.get().fetchStorageInfo(browserContextHandle, callback); } + public void fetchCookiesInfo(BrowserContextHandle browserContextHandle, + Callback<Map<String, CookiesInfo>> callback) { + WebsitePreferenceBridgeJni.get().fetchCookiesInfo(browserContextHandle, callback); + } + /** * Returns the list of all chosen object permissions for the given ContentSettingsType. * @@ -391,6 +412,7 @@ @ContentSettingsType int type, String origin, String object); boolean isContentSettingsPatternValid(String pattern); boolean urlMatchesContentSettingsPattern(String url, String pattern); + void fetchCookiesInfo(BrowserContextHandle browserContextHandle, Object callback); void fetchStorageInfo(BrowserContextHandle browserContextHandle, Object callback); void fetchLocalStorageInfo(BrowserContextHandle browserContextHandle, Object callback, boolean includeImportant);
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteRowPreference.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteRowPreference.java index e2c012dd..fb054660 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteRowPreference.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteRowPreference.java
@@ -96,6 +96,18 @@ summary = Formatter.formatShortFileSize(getContext(), usage); } + int cookies = mSiteEntry.getNumberOfCookies(); + if (cookies > 0) { + String cookie_str = getContext().getResources().getQuantityString( + R.plurals.cookies_count, cookies, cookies); + if (summary.isEmpty()) { + summary = cookie_str; + } else { + summary = String.format(getContext().getString(R.string.summary_with_one_bullet), + cookie_str, summary); + } + } + // When a single HTTP origin is represented, mark it as such. if (isSiteEntryASingleHttpOrigin()) { if (summary.isEmpty()) {
diff --git a/components/browser_ui/site_settings/android/website_preference_bridge.cc b/components/browser_ui/site_settings/android/website_preference_bridge.cc index d2a5e2d4..48b586b 100644 --- a/components/browser_ui/site_settings/android/website_preference_bridge.cc +++ b/components/browser_ui/site_settings/android/website_preference_bridge.cc
@@ -23,6 +23,7 @@ #include "base/notreached.h" #include "components/browser_ui/site_settings/android/site_settings_jni_headers/WebsitePreferenceBridge_jni.h" #include "components/browser_ui/site_settings/android/storage_info_fetcher.h" +#include "components/browsing_data/content/cookie_helper.h" #include "components/browsing_data/content/local_storage_helper.h" #include "components/cdm/browser/media_drm_storage_impl.h" #include "components/content_settings/core/browser/cookie_settings.h" @@ -41,6 +42,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/permission_controller.h" #include "content/public/browser/storage_partition.h" +#include "net/cookies/cookie_util.h" #include "services/network/public/mojom/cookie_manager.mojom.h" #include "storage/browser/quota/quota_manager.h" #include "third_party/blink/public/common/storage_key/storage_key.h" @@ -521,6 +523,24 @@ } } +void OnCookiesInfoReady(const ScopedJavaGlobalRef<jobject>& java_callback, + const net::CookieList& entries) { + JNIEnv* env = base::android::AttachCurrentThread(); + ScopedJavaLocalRef<jobject> map = + Java_WebsitePreferenceBridge_createCookiesInfoMap(env); + + for (const net::CanonicalCookie& cookie : entries) { + std::string origin = + net::cookie_util::CookieOriginToURL(cookie.Domain(), cookie.IsSecure()) + .spec(); + ScopedJavaLocalRef<jstring> java_origin = + ConvertUTF8ToJavaString(env, origin); + Java_WebsitePreferenceBridge_insertCookieIntoMap(env, map, java_origin); + } + + base::android::RunObjectCallbackAndroid(java_callback, map); +} + void OnStorageInfoReady(const ScopedJavaGlobalRef<jobject>& java_callback, const storage::UsageInfoEntries& entries) { JNIEnv* env = base::android::AttachCurrentThread(); @@ -600,6 +620,17 @@ // helpers keep a reference to themselves for the duration of their tasks, // which includes callback invocation. +static void JNI_WebsitePreferenceBridge_FetchCookiesInfo( + JNIEnv* env, + const JavaParamRef<jobject>& jbrowser_context_handle, + const JavaParamRef<jobject>& java_callback) { + BrowserContext* browser_context = unwrap(jbrowser_context_handle); + auto cookie_helper = base::MakeRefCounted<browsing_data::CookieHelper>( + browser_context->GetDefaultStoragePartition(), base::NullCallback()); + cookie_helper->StartFetching(base::BindOnce( + &OnCookiesInfoReady, ScopedJavaGlobalRef<jobject>(java_callback))); +} + static void JNI_WebsitePreferenceBridge_FetchLocalStorageInfo( JNIEnv* env, const JavaParamRef<jobject>& jbrowser_context_handle,
diff --git a/components/browser_ui/strings/android/site_settings.grdp b/components/browser_ui/strings/android/site_settings.grdp index 8280769..3a95d57 100644 --- a/components/browser_ui/strings/android/site_settings.grdp +++ b/components/browser_ui/strings/android/site_settings.grdp
@@ -164,6 +164,9 @@ <message name="IDS_DOMAIN_SETTINGS_SITES_IN_GROUP" desc="Title for the section that lists sites in the group for a given domain."> Sites under <ph name="DOMAIN">%1$s<ex>google.com</ex></ph> </message> + <message name="IDS_COOKIES_COUNT" desc="Used to display how many cookies are associated with a given site/domain."> + {COOKIES, plural, =1 {# cookie} other {# cookies}} + </message> <!-- Site settings: Possible permission values for a single site --> <message name="IDS_WEBSITE_SETTINGS_SITE_CATEGORY" desc="The headline above the website name on the website details page.">
diff --git a/components/browser_ui/strings/android/site_settings_grdp/IDS_COOKIES_COUNT.png.sha1 b/components/browser_ui/strings/android/site_settings_grdp/IDS_COOKIES_COUNT.png.sha1 new file mode 100644 index 0000000..882b4d2 --- /dev/null +++ b/components/browser_ui/strings/android/site_settings_grdp/IDS_COOKIES_COUNT.png.sha1
@@ -0,0 +1 @@ +18bb2d6b6ea165480d5aba325da178d55738f9dd \ No newline at end of file
diff --git a/components/commerce_strings.grdp b/components/commerce_strings.grdp index 17ed687..651c3e7 100644 --- a/components/commerce_strings.grdp +++ b/components/commerce_strings.grdp
@@ -60,7 +60,7 @@ Track price </message> <message name="IDS_OMNIBOX_TRACK_PRICE_DIALOG_ERROR_DESCRIPTION" desc="The description text for the dialog that is shown when a user initiates price tracking for the product displayed on the current page from the dialog but the request fails. It tells user that the tracking request failed."> - Something went wrong. Your change wasn’t saved. + Something went wrong. Try again. </message> <message name="IDS_OMNIBOX_TRACK_PRICE_DIALOG_ERROR_BUTTON" desc="The action button text for the dialog that is shown when a user initiates price tracking for the product displayed on the current page from the dialog but the request fails. User can click this button to re-try tracking the product."> Try again @@ -106,6 +106,9 @@ <message name="IDS_BOOKMARK_STAR_DIALOG_TRACK_PRICE_DESCRIPTION" desc="The description text for the dialog that is shown when a user clicks the bookmark star icon on a product web page. It describes what will happen when price tracking is initiated."> Get email alerts if the price drops on any site </message> + <message name="IDS_BOOKMARK_STAR_DIALOG_TRACK_PRICE_DESCRIPTION_EMAIL_OFF" desc="The description text for the dialog that is shown when a user clicks the bookmark star icon on a product web page. We use this text only if the email notification is currently turned off by the user. It describes what will happen when price tracking is initiated."> + Track prices across multiple sites at the same time + </message> <message name="IDS_BOOKMARKS_MENU_TRACK_PRICE" desc="Text shown as a menu item when the user is on a product page and the product's price is not currently being tracked. User can click this button to track this product."> Track price @@ -177,10 +180,10 @@ Mobile </message> <message name="IDS_PRICE_NOTIFICATIONS_SETTINGS_MOBILE_DESCRIPTION_ON" desc="The description text for managing mobile price drop popup notifications when the notification is currently enabled. Shown on the detailed page settings in Google services. It tells users that they can disable the popup notification in the Chrome notification settings." formatter_data="android_java"> - Price drop alerts are on. You can change this in <ph name="BEGIN_LINK"><link></ph><ph name="NOTIFICATION_SETTINGS">%1$s<ex>settings</ex></ph><ph name="END_LINK"></link></ph> + Price drop alerts are on. You can change this in <ph name="BEGIN_LINK"><link></ph><ph name="NOTIFICATION_SETTINGS">%1$s<ex>settings</ex></ph><ph name="END_LINK"></link></ph>. </message> <message name="IDS_PRICE_NOTIFICATIONS_SETTINGS_MOBILE_DESCRIPTION_OFF" desc="The description text for managing mobile price drop popup notifications when the notification is currently disabled. Shown on the detailed page settings in Google services. It tells users that they can enable the popup notification in the Chrome notification settings." formatter_data="android_java"> - Chrome notifications must be on. You can turn them on in <ph name="BEGIN_LINK"><link></ph><ph name="NOTIFICATION_SETTINGS">%1$s<ex>settings</ex></ph><ph name="END_LINK"></link></ph> + Chrome notifications must be on. You can turn them on in <ph name="BEGIN_LINK"><link></ph><ph name="NOTIFICATION_SETTINGS">%1$s<ex>settings</ex></ph><ph name="END_LINK"></link></ph>. </message> <message name="IDS_CHROME_NOTIFICATION_SETTINGS_FOR_PRICE_TRACKING" desc="The button text within the description for managing mobile price drop popup notifications. When user clicks this button, we send them to the Chrome notification settings." formatter_data="android_java"> settings
diff --git a/components/commerce_strings_grdp/IDS_BOOKMARK_STAR_DIALOG_TRACK_PRICE_DESCRIPTION_EMAIL_OFF.png.sha1 b/components/commerce_strings_grdp/IDS_BOOKMARK_STAR_DIALOG_TRACK_PRICE_DESCRIPTION_EMAIL_OFF.png.sha1 new file mode 100644 index 0000000..8e24f9cf --- /dev/null +++ b/components/commerce_strings_grdp/IDS_BOOKMARK_STAR_DIALOG_TRACK_PRICE_DESCRIPTION_EMAIL_OFF.png.sha1
@@ -0,0 +1 @@ +27657c14f2d434002b7d5eaf591294ccdfd7fa75 \ No newline at end of file
diff --git a/components/commerce_strings_grdp/IDS_OMNIBOX_TRACK_PRICE_DIALOG_ERROR_DESCRIPTION.png.sha1 b/components/commerce_strings_grdp/IDS_OMNIBOX_TRACK_PRICE_DIALOG_ERROR_DESCRIPTION.png.sha1 index 92fc4a11..263fe511 100644 --- a/components/commerce_strings_grdp/IDS_OMNIBOX_TRACK_PRICE_DIALOG_ERROR_DESCRIPTION.png.sha1 +++ b/components/commerce_strings_grdp/IDS_OMNIBOX_TRACK_PRICE_DIALOG_ERROR_DESCRIPTION.png.sha1
@@ -1 +1 @@ -9e66d2ca8a5059fad88a21e98cb98105e1a232f3 \ No newline at end of file +60ce3536beac884c9aac2ef415c75d218b7cf720 \ No newline at end of file
diff --git a/components/cronet/cronet_context.cc b/components/cronet/cronet_context.cc index f5510b6..1597f77 100644 --- a/components/cronet/cronet_context.cc +++ b/components/cronet/cronet_context.cc
@@ -46,6 +46,7 @@ #include "net/cert/cert_verifier.h" #include "net/cert/x509_certificate.h" #include "net/cookies/cookie_monster.h" +#include "net/first_party_sets/first_party_set_metadata.h" #include "net/http/http_auth_handler_factory.h" #include "net/http/transport_security_state.h" #include "net/log/file_net_log_observer.h" @@ -120,6 +121,7 @@ // net::NetworkDelegate implementation. bool OnAnnotateAndMoveUserBlockedCookies( const net::URLRequest& request, + const net::FirstPartySetMetadata& first_party_set_metadata, net::CookieAccessResultList& maybe_included_cookies, net::CookieAccessResultList& excluded_cookies) override { // Disallow sending cookies by default.
diff --git a/components/download/internal/common/download_item_impl.cc b/components/download/internal/common/download_item_impl.cc index de251ac..667eb32b 100644 --- a/components/download/internal/common/download_item_impl.cc +++ b/components/download/internal/common/download_item_impl.cc
@@ -33,6 +33,7 @@ #include "base/guid.h" #include "base/json/string_escape.h" #include "base/logging.h" +#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/observer_list.h" #include "base/strings/string_piece.h" @@ -2039,6 +2040,14 @@ } } + // TODO(crbug.com/1372476): Remove these histograms after debugging. + if (!IsTemporary()) { + base::UmaHistogramBoolean("Download.Complete.IsOpenWhenCompleteSet", + GetOpenWhenComplete()); + base::UmaHistogramBoolean( + "Download.Complete.IsShouldOpenFileBasedOnExtensionSet", + ShouldOpenFileBasedOnExtension()); + } if (auto_opened_) { // If it was already handled by the delegate, do nothing. } else if (GetOpenWhenComplete() || ShouldOpenFileBasedOnExtension() ||
diff --git a/components/download/public/common/BUILD.gn b/components/download/public/common/BUILD.gn index 33b6b23..c4ad2ea 100644 --- a/components/download/public/common/BUILD.gn +++ b/components/download/public/common/BUILD.gn
@@ -19,6 +19,7 @@ "auto_resumption_handler.cc", "auto_resumption_handler.h", "base_file.h", + "download_content.cc", "download_content.h", "download_create_info.h", "download_danger_type.cc",
diff --git a/components/download/public/common/download_content.cc b/components/download/public/common/download_content.cc new file mode 100644 index 0000000..ac2b93f9 --- /dev/null +++ b/components/download/public/common/download_content.cc
@@ -0,0 +1,56 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/download/public/common/download_content.h" + +#include "base/notreached.h" + +namespace download { + +std::string GetDownloadContentString(const DownloadContent& download_content) { + switch (download_content) { + case DownloadContent::UNRECOGNIZED: + return "UNRECOGNIZED"; + case DownloadContent::TEXT: + return "TEXT"; + case DownloadContent::IMAGE: + return "IMAGE"; + case DownloadContent::AUDIO: + return "AUDIO"; + case DownloadContent::VIDEO: + return "VIDEO"; + case DownloadContent::OCTET_STREAM: + return "OCTET_STREAM"; + case DownloadContent::PDF: + return "PDF"; + case DownloadContent::DOCUMENT: + return "DOCUMENT"; + case DownloadContent::SPREADSHEET: + return "SPREADSHEET"; + case DownloadContent::PRESENTATION: + return "PRESENTATION"; + case DownloadContent::ARCHIVE: + return "ARCHIVE"; + case DownloadContent::EXECUTABLE: + return "EXECUTABLE"; + case DownloadContent::DMG: + return "DMG"; + case DownloadContent::CRX: + return "CRX"; + case DownloadContent::WEB: + return "WEB"; + case DownloadContent::EBOOK: + return "EBOOK"; + case DownloadContent::FONT: + return "FONT"; + case DownloadContent::APK: + return "APK"; + case DownloadContent::MAX: + return "MAX"; + } + NOTREACHED(); + return ""; +} + +} // namespace download
diff --git a/components/download/public/common/download_content.h b/components/download/public/common/download_content.h index e23e4d9..24f77813 100644 --- a/components/download/public/common/download_content.h +++ b/components/download/public/common/download_content.h
@@ -5,6 +5,10 @@ #ifndef COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_CONTENT_H_ #define COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_CONTENT_H_ +#include <string> + +#include "components/download/public/common/download_export.h" + // The type of download based on mimetype. // This is used by UMA and UKM metrics. namespace download { @@ -33,6 +37,11 @@ MAX = 18, }; +// Converts DownloadContent into their corresponding string, used only +// for metrics. +COMPONENTS_DOWNLOAD_EXPORT +std::string GetDownloadContentString(const DownloadContent& download_content); + } // namespace download #endif // COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_CONTENT_H_
diff --git a/components/embedder_support/DIR_METADATA b/components/embedder_support/DIR_METADATA new file mode 100644 index 0000000..4b93a605 --- /dev/null +++ b/components/embedder_support/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail: { + component: "Privacy>Fingerprinting" +}
diff --git a/components/history_clusters/core/config.cc b/components/history_clusters/core/config.cc index fdf339f..e42ae28 100644 --- a/components/history_clusters/core/config.cc +++ b/components/history_clusters/core/config.cc
@@ -112,6 +112,12 @@ internal::kPersistedClusters, "max_persisted_cluster_visits_to_fetch_soft_cap", max_persisted_cluster_visits_to_fetch_soft_cap); + + persist_clusters_recluster_window_days = + base::GetFieldTrialParamByFeatureAsInt( + internal::kPersistedClusters, + "persist_clusters_recluster_window_days", + persist_clusters_recluster_window_days); } // The `kOmniboxAction` feature and child params.
diff --git a/components/history_clusters/core/config.h b/components/history_clusters/core/config.h index 222e6e6..57182b0 100644 --- a/components/history_clusters/core/config.h +++ b/components/history_clusters/core/config.h
@@ -112,6 +112,12 @@ // visits in case there are a few very large clusters in the same batch. size_t max_persisted_cluster_visits_to_fetch_soft_cap = 1000; + // The number of days of persisted clusters to recluster when updating + // clusters. E.g., if set to 2, and clusters up to 1/10 have been persisted, + // then the next request will include visits from clusters from 1/8 and 1/9, + // and unclustered visits from 1/10. + size_t persist_clusters_recluster_window_days = 2; + // The `kOmniboxAction` feature and child params. // Enables the Journeys Omnibox Action chip. `kJourneys` must also be enabled
diff --git a/components/history_clusters/core/history_clusters_service_task_update_clusters.cc b/components/history_clusters/core/history_clusters_service_task_update_clusters.cc index 920cbb30..1cc2a1c1 100644 --- a/components/history_clusters/core/history_clusters_service_task_update_clusters.cc +++ b/components/history_clusters/core/history_clusters_service_task_update_clusters.cc
@@ -11,6 +11,7 @@ #include "base/strings/stringprintf.h" #include "components/history/core/browser/history_service.h" #include "components/history_clusters/core/clustering_backend.h" +#include "components/history_clusters/core/config.h" #include "components/history_clusters/core/history_clusters_db_tasks.h" #include "components/history_clusters/core/history_clusters_debug_jsons.h" #include "components/history_clusters/core/history_clusters_service.h" @@ -47,7 +48,8 @@ FROM_HERE, std::make_unique<GetAnnotatedVisitsToCluster>( incomplete_visit_context_annotations_, base::Time(), - continuation_params_, false, 2, false, + continuation_params_, false, + GetConfig().persist_clusters_recluster_window_days, false, base::BindOnce(&HistoryClustersServiceTaskUpdateClusters:: OnGotAnnotatedVisitsToCluster, weak_ptr_factory_.GetWeakPtr())),
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageAnimationCoordinatorUnitTest.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageAnimationCoordinatorUnitTest.java index fb86398..af3ff973 100644 --- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageAnimationCoordinatorUnitTest.java +++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageAnimationCoordinatorUnitTest.java
@@ -65,6 +65,57 @@ mAnimationCoordinator.setMessageQueueDelegate(mQueueDelegate); } + @Test + @SmallTest + public void testDoNothing_withoutStacking() { + MessageState m1 = buildMessageState(); + // Initial setup + mAnimationCoordinator.updateWithoutStacking(m1, false, () -> {}); + + // Again with same candidates. + mAnimationCoordinator.updateWithoutStacking(m1, false, () -> {}); + + verify(m1.handler, never()).hide(anyInt(), anyInt(), anyBoolean()); + verify(m1.handler).show(anyInt(), anyInt()); + } + + @Test + @SmallTest + public void testShowMessages_withoutStacking() { + // Initial values should be null. + var currentMessage = mAnimationCoordinator.getCurrentDisplayedMessage(); + Assert.assertNull(currentMessage); + + MessageState m1 = buildMessageState(); + MessageState m2 = buildMessageState(); + mAnimationCoordinator.updateWithoutStacking(m1, false, () -> {}); + + verify(m1.handler).show(Position.INVISIBLE, Position.FRONT); + verify(m1.handler, never()).hide(anyInt(), anyInt(), anyBoolean()); + + currentMessage = mAnimationCoordinator.getCurrentDisplayedMessage(); + Assert.assertEquals(m1, currentMessage); + } + + @Test + @SmallTest + public void testHideMessage_withoutStacking() { + MessageState m1 = buildMessageState(); + MessageState m2 = buildMessageState(); + mAnimationCoordinator.updateWithoutStacking(m1, false, () -> {}); + + verify(m1.handler).show(Position.INVISIBLE, Position.FRONT); + verify(m2.handler, never()).show(Position.INVISIBLE, Position.FRONT); + + mAnimationCoordinator.updateWithoutStacking(m2, false, + () -> { mAnimationCoordinator.updateWithoutStacking(m2, false, () -> {}); }); + verify(m1.handler).hide(Position.FRONT, Position.INVISIBLE, true); + verify(m2.handler).show(Position.INVISIBLE, Position.FRONT); + + var currentMessage = mAnimationCoordinator.getCurrentDisplayedMessage(); + Assert.assertEquals(m2, currentMessage); + } + // Test incoming candidates are same with current displayed ones. // [m1, m2] -> [m1, m2] @Test
diff --git a/components/mirroring/service/DEPS b/components/mirroring/service/DEPS index 7bac7d4..1b9a9644 100644 --- a/components/mirroring/service/DEPS +++ b/components/mirroring/service/DEPS
@@ -20,4 +20,5 @@ "+third_party/openscreen/src/platform/api", "+third_party/openscreen/src/platform/base", "+ui/base", + "+ui/gfx/geometry", ]
diff --git a/components/mirroring/service/fake_video_capture_host.cc b/components/mirroring/service/fake_video_capture_host.cc index 9e84722..ea654ff 100644 --- a/components/mirroring/service/fake_video_capture_host.cc +++ b/components/mirroring/service/fake_video_capture_host.cc
@@ -29,6 +29,7 @@ const media::VideoCaptureParams& params, mojo::PendingRemote<media::mojom::VideoCaptureObserver> observer) { ASSERT_TRUE(observer); + last_params_ = params; observer_.Bind(std::move(observer)); observer_->OnStateChanged(media::mojom::VideoCaptureResult::NewState( media::mojom::VideoCaptureState::STARTED)); @@ -65,4 +66,8 @@ observer_->OnBufferReady(std::move(buffer), {}); } +media::VideoCaptureParams FakeVideoCaptureHost::GetVideoCaptureParams() const { + return last_params_; +} + } // namespace mirroring
diff --git a/components/mirroring/service/fake_video_capture_host.h b/components/mirroring/service/fake_video_capture_host.h index e663cbeb..b880199a 100644 --- a/components/mirroring/service/fake_video_capture_host.h +++ b/components/mirroring/service/fake_video_capture_host.h
@@ -63,9 +63,13 @@ // Create one video frame and send it to |observer_|. void SendOneFrame(const gfx::Size& size, base::TimeTicks capture_time); + // Get the most recent capture parameters passed to Start(). + media::VideoCaptureParams GetVideoCaptureParams() const; + private: mojo::Receiver<media::mojom::VideoCaptureHost> receiver_; mojo::Remote<media::mojom::VideoCaptureObserver> observer_; + media::VideoCaptureParams last_params_; }; } // namespace mirroring
diff --git a/components/mirroring/service/mirroring_features.cc b/components/mirroring/service/mirroring_features.cc index 144db73f..55d0f30 100644 --- a/components/mirroring/service/mirroring_features.cc +++ b/components/mirroring/service/mirroring_features.cc
@@ -36,6 +36,14 @@ "CastForceEnableRemotingQuery", base::FEATURE_DISABLED_BY_DEFAULT); +// The mirroring sender has the ability to letterbox video frames to match the +// aspect ratio of the reciever's display. However, receivers can handle +// variable aspect ratio video so this is not needed any more. +// TODO(crbug.com/1363512): Remove support for sender side letterboxing. +BASE_FEATURE(kCastDisableLetterboxing, + "CastDisableLetterboxing", + base::FEATURE_ENABLED_BY_DEFAULT); + bool IsCastStreamingAV1Enabled() { #if BUILDFLAG(ENABLE_LIBAOM) return base::FeatureList::IsEnabled(features::kCastStreamingAv1);
diff --git a/components/mirroring/service/mirroring_features.h b/components/mirroring/service/mirroring_features.h index 43ec578d..48b8431 100644 --- a/components/mirroring/service/mirroring_features.h +++ b/components/mirroring/service/mirroring_features.h
@@ -22,6 +22,10 @@ COMPONENT_EXPORT(MIRRORING_SERVICE) BASE_DECLARE_FEATURE(kCastForceEnableRemotingQuery); +// TODO(crbug.com/1363512): Remove support for sender side letterboxing. +COMPONENT_EXPORT(MIRRORING_SERVICE) +BASE_DECLARE_FEATURE(kCastDisableLetterboxing); + bool IsCastStreamingAV1Enabled(); } // namespace features
diff --git a/components/mirroring/service/openscreen_session_host.cc b/components/mirroring/service/openscreen_session_host.cc index 2f8ddbe..0b781ac3 100644 --- a/components/mirroring/service/openscreen_session_host.cc +++ b/components/mirroring/service/openscreen_session_host.cc
@@ -775,8 +775,15 @@ std::min(video_config->max_frame_rate, static_cast<double>(video.maximum.frame_rate)); - // TODO(https://crbug.com/1363512): this can be removed. - mirror_settings_.SetSenderSideLetterboxingEnabled(!video.supports_scaling); + // TODO(crbug.com/1363512): Remove support for sender side letterboxing. + if (base::FeatureList::IsEnabled(features::kCastDisableLetterboxing)) { + mirror_settings_.SetSenderSideLetterboxingEnabled(false); + } else { + // Enable sender-side letterboxing if the receiver specifically does not + // opt-in to variable aspect ratio video. + mirror_settings_.SetSenderSideLetterboxingEnabled( + !video.supports_scaling); + } } if (audio_config) {
diff --git a/components/mirroring/service/openscreen_session_host_unittest.cc b/components/mirroring/service/openscreen_session_host_unittest.cc index 42153396..425d128c 100644 --- a/components/mirroring/service/openscreen_session_host_unittest.cc +++ b/components/mirroring/service/openscreen_session_host_unittest.cc
@@ -447,6 +447,9 @@ base::test::TaskEnvironment& task_environment() { return task_environment_; } + protected: + std::unique_ptr<FakeVideoCaptureHost> video_host_; + private: base::test::ScopedFeatureList feature_list_; base::test::TaskEnvironment task_environment_; @@ -463,7 +466,6 @@ int32_t target_playout_delay_ms_ = kDefaultPlayoutDelay; std::unique_ptr<OpenscreenSessionHost> session_host_; - std::unique_ptr<FakeVideoCaptureHost> video_host_; std::unique_ptr<MockNetworkContext> network_context_; std::unique_ptr<openscreen::cast::Answer> answer_; @@ -494,9 +496,31 @@ TEST_F(OpenscreenSessionHostTest, AnswerWithConstraints) { SetAnswer(std::make_unique<openscreen::cast::Answer>(kAnswerWithConstraints)); + media::VideoCaptureParams::SuggestedConstraints expected_constraints = { + .min_frame_size = gfx::Size(2, 2), + .max_frame_size = gfx::Size(1920, 1080), + .fixed_aspect_ratio = false}; CreateSession(SessionType::AUDIO_AND_VIDEO); StartSession(); StopSession(); + EXPECT_EQ(video_host_->GetVideoCaptureParams().SuggestConstraints(), + expected_constraints); +} + +// TODO(crbug.com/1363512): Remove support for sender side letterboxing. +TEST_F(OpenscreenSessionHostTest, AnswerWithConstraintsLetterboxEnabled) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndDisableFeature(features::kCastDisableLetterboxing); + SetAnswer(std::make_unique<openscreen::cast::Answer>(kAnswerWithConstraints)); + media::VideoCaptureParams::SuggestedConstraints expected_constraints = { + .min_frame_size = gfx::Size(320, 180), + .max_frame_size = gfx::Size(1920, 1080), + .fixed_aspect_ratio = true}; + CreateSession(SessionType::AUDIO_AND_VIDEO); + StartSession(); + StopSession(); + EXPECT_EQ(video_host_->GetVideoCaptureParams().SuggestConstraints(), + expected_constraints); } TEST_F(OpenscreenSessionHostTest, AnswerTimeout) {
diff --git a/components/mirroring/service/session.cc b/components/mirroring/service/session.cc index 75fc8c1a..b81ee4c 100644 --- a/components/mirroring/service/session.cc +++ b/components/mirroring/service/session.cc
@@ -597,8 +597,15 @@ std::min(video_config->max_frame_rate, static_cast<double>(video.maximum.frame_rate)); - // We only do sender-side letterboxing if the receiver doesn't support it. - mirror_settings_.SetSenderSideLetterboxingEnabled(!video.supports_scaling); + // TODO(crbug.com/1363512): Remove support for sender side letterboxing. + if (base::FeatureList::IsEnabled(features::kCastDisableLetterboxing)) { + mirror_settings_.SetSenderSideLetterboxingEnabled(false); + } else { + // Enable sender-side letterboxing if the receiver specifically does not + // opt-in to variable aspect ratio video. + mirror_settings_.SetSenderSideLetterboxingEnabled( + !video.supports_scaling); + } } if (audio_config) {
diff --git a/components/mirroring/service/session_unittest.cc b/components/mirroring/service/session_unittest.cc index 409c3c90..42ec5b9 100644 --- a/components/mirroring/service/session_unittest.cc +++ b/components/mirroring/service/session_unittest.cc
@@ -13,14 +13,17 @@ #include "base/callback.h" #include "base/json/json_reader.h" #include "base/run_loop.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/time/time.h" #include "base/values.h" #include "components/mirroring/service/fake_network_service.h" #include "components/mirroring/service/fake_video_capture_host.h" #include "components/mirroring/service/mirror_settings.h" +#include "components/mirroring/service/mirroring_features.h" #include "components/mirroring/service/receiver_response.h" #include "components/mirroring/service/value_util.h" +#include "media/capture/video_capture_types.h" #include "media/cast/test/utility/default_config.h" #include "media/cast/test/utility/net_utility.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -32,6 +35,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/openscreen/src/cast/streaming/ssrc.h" +#include "ui/gfx/geometry/size.h" using media::cast::FrameSenderConfig; using media::cast::Packet; @@ -46,6 +50,7 @@ using ::testing::InvokeWithoutArgs; using ::testing::Mock; using ::testing::NiceMock; +using ::testing::SaveArg; namespace mirroring { @@ -398,6 +403,9 @@ answer_ = std::move(answer); } + protected: + std::unique_ptr<FakeVideoCaptureHost> video_host_; + private: base::test::TaskEnvironment task_environment_; const net::IPEndPoint receiver_endpoint_ = @@ -415,7 +423,6 @@ int32_t target_playout_delay_ms_ = kDefaultPlayoutDelay; std::unique_ptr<Session> session_; - std::unique_ptr<FakeVideoCaptureHost> video_host_; std::unique_ptr<MockNetworkContext> network_context_; std::unique_ptr<openscreen::cast::Answer> answer_; }; @@ -443,9 +450,31 @@ TEST_F(SessionTest, AnswerWithConstraints) { SetAnswer(std::make_unique<openscreen::cast::Answer>(kAnswerWithConstraints)); + media::VideoCaptureParams::SuggestedConstraints expected_constraints = { + .min_frame_size = gfx::Size(2, 2), + .max_frame_size = gfx::Size(1280, 720), + .fixed_aspect_ratio = false}; CreateSession(SessionType::AUDIO_AND_VIDEO); StartSession(); StopSession(); + EXPECT_EQ(video_host_->GetVideoCaptureParams().SuggestConstraints(), + expected_constraints); +} + +// TODO(crbug.com/1363512): Remove support for sender side letterboxing. +TEST_F(SessionTest, AnswerWithConstraintsLetterboxEnabled) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndDisableFeature(features::kCastDisableLetterboxing); + SetAnswer(std::make_unique<openscreen::cast::Answer>(kAnswerWithConstraints)); + media::VideoCaptureParams::SuggestedConstraints expected_constraints = { + .min_frame_size = gfx::Size(320, 180), + .max_frame_size = gfx::Size(1280, 720), + .fixed_aspect_ratio = true}; + CreateSession(SessionType::AUDIO_AND_VIDEO); + StartSession(); + StopSession(); + EXPECT_EQ(video_host_->GetVideoCaptureParams().SuggestConstraints(), + expected_constraints); } TEST_F(SessionTest, AnswerTimeout) {
diff --git a/components/page_info_strings.grdp b/components/page_info_strings.grdp index 37f24ee..b25ec98a 100644 --- a/components/page_info_strings.grdp +++ b/components/page_info_strings.grdp
@@ -742,14 +742,14 @@ <message name="IDS_PAGE_INFO_COOKIES_DIALOG_BUTTON_TOOLTIP" desc="The text of the tooltip on the button opening cookies in use dialog in cookies subpage."> Show cookies </message> - <message name="IDS_PAGE_INFO_FPS_BUTTON_TOOLTIP" desc="The tooltip of first-party sets button in cookies subpage, which opens 'All Sites' settings page with a filter for this sets' pages." translateable="false"> - Show sites + <message name="IDS_PAGE_INFO_FPS_BUTTON_TOOLTIP" desc="The tooltip of first-party sets button in cookies subpage, which opens 'All Sites' settings page in a new tab with a filter for this set's pages."> + See related sites in a new tab </message> - <message name="IDS_PAGE_INFO_FPS_BUTTON_TITLE" desc="The title of first-party sets button in cookies subpage with placeholder for name of the owner of this set." translateable="false"> - See sites related to <ph name="SET_OWNER">$1<ex>gannett.com</ex></ph> + <message name="IDS_PAGE_INFO_FPS_BUTTON_TITLE" desc="The title of first-party sets button in cookies subpage with placeholder for name of the owner of this set."> + See related sites </message> - <message name="IDS_PAGE_INFO_FPS_BUTTON_SUBTITLE" desc="The subtitle of first-party sets button in cookies subpage with placeholder for name of the owner of this set." translateable="false"> - This site is in <ph name="SET_OWNER">$1<ex>gannett.com</ex></ph>'s group of sites that can see your activity in the group + <message name="IDS_PAGE_INFO_FPS_BUTTON_SUBTITLE" desc="The subtitle of first-party sets button in cookies subpage with placeholder for name of the owner of this set."> + This site is in a group, defined by <ph name="SET_OWNER">$1<ex>gannett.com</ex></ph>, that can see your activity </message> <!-- History strings -->
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_FPS_BUTTON_SUBTITLE.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_FPS_BUTTON_SUBTITLE.png.sha1 new file mode 100644 index 0000000..7061a60 --- /dev/null +++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_FPS_BUTTON_SUBTITLE.png.sha1
@@ -0,0 +1 @@ +4c15daff13534e23221a67f3d70f85e6f4f6c316 \ No newline at end of file
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_FPS_BUTTON_TITLE.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_FPS_BUTTON_TITLE.png.sha1 new file mode 100644 index 0000000..7061a60 --- /dev/null +++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_FPS_BUTTON_TITLE.png.sha1
@@ -0,0 +1 @@ +4c15daff13534e23221a67f3d70f85e6f4f6c316 \ No newline at end of file
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_FPS_BUTTON_TOOLTIP.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_FPS_BUTTON_TOOLTIP.png.sha1 new file mode 100644 index 0000000..7133cec --- /dev/null +++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_FPS_BUTTON_TOOLTIP.png.sha1
@@ -0,0 +1 @@ +571b07c50136a532891c986d5cedd91275901085 \ No newline at end of file
diff --git a/components/password_manager/core/browser/leak_detection_dialog_utils.cc b/components/password_manager/core/browser/leak_detection_dialog_utils.cc index f3e8ada..99e0b7a 100644 --- a/components/password_manager/core/browser/leak_detection_dialog_utils.cc +++ b/components/password_manager/core/browser/leak_detection_dialog_utils.cc
@@ -91,7 +91,7 @@ const bool uses_password_manager_google_branding = true; #elif BUILDFLAG(IS_ANDROID) const bool uses_password_manager_updated_naming = - password_manager::features::UsesUnifiedPasswordManagerUi(); + password_manager::features::UsesUnifiedPasswordManagerBranding(); const bool uses_password_manager_google_branding = password_manager_util::UsesPasswordManagerGoogleBranding( IsSyncingPasswordsNormally(leak_type)); @@ -152,7 +152,7 @@ password_manager::features::kIOSEnablePasswordManagerBrandingUpdate); #elif BUILDFLAG(IS_ANDROID) const bool uses_password_manager_updated_naming = - password_manager::features::UsesUnifiedPasswordManagerUi(); + password_manager::features::UsesUnifiedPasswordManagerBranding(); #else const bool uses_password_manager_updated_naming = true; #endif @@ -239,7 +239,7 @@ uses_password_manager_google_branding_(true) #elif BUILDFLAG(IS_ANDROID) uses_password_manager_updated_naming_( - password_manager::features::UsesUnifiedPasswordManagerUi()), + password_manager::features::UsesUnifiedPasswordManagerBranding()), uses_password_manager_google_branding_( password_manager_util::UsesPasswordManagerGoogleBranding( IsSyncingPasswordsNormally(leak_type)))
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc index 4c5a1d8..f681d5c 100644 --- a/components/password_manager/core/common/password_manager_features.cc +++ b/components/password_manager/core/common/password_manager_features.cc
@@ -285,6 +285,13 @@ BASE_FEATURE(kUnifiedPasswordManagerReenrollment, "UnifiedPasswordManagerReenrollment", base::FEATURE_DISABLED_BY_DEFAULT); + +// Enables all UI branding changes related to Unified Password Manager: +// the strings containing 'Password Manager' and the password manager +// icon. +BASE_FEATURE(kUnifiedPasswordManagerAndroidBranding, + "UnifiedPasswordManagerAndroidBranding", + base::FEATURE_DISABLED_BY_DEFAULT); #endif // Enables support of sending additional votes on username first flow. The votes @@ -381,9 +388,12 @@ NOTREACHED() << "Define explicitly whether UI is required!"; return false; } -#endif // IS_ANDROID -#if BUILDFLAG(IS_ANDROID) +bool UsesUnifiedPasswordManagerBranding() { + return (UsesUnifiedPasswordManagerUi() || + base::FeatureList::IsEnabled(kUnifiedPasswordManagerAndroidBranding)); +} + bool RequiresMigrationForUnifiedPasswordManager() { if (!base::FeatureList::IsEnabled(kUnifiedPasswordManagerAndroid)) return false; @@ -399,9 +409,7 @@ NOTREACHED() << "Define explicitly whether migration is required!"; return false; } -#endif // IS_ANDROID -#if BUILDFLAG(IS_ANDROID) bool ManagesLocalPasswordsInUnifiedPasswordManager() { if (!base::FeatureList::IsEnabled(kUnifiedPasswordManagerAndroid)) return false;
diff --git a/components/password_manager/core/common/password_manager_features.h b/components/password_manager/core/common/password_manager_features.h index 97bf188..d9cf629 100644 --- a/components/password_manager/core/common/password_manager_features.h +++ b/components/password_manager/core/common/password_manager_features.h
@@ -80,6 +80,7 @@ BASE_DECLARE_FEATURE(kUnifiedPasswordManagerErrorMessages); BASE_DECLARE_FEATURE(kUnifiedPasswordManagerSyncUsingAndroidBackendOnly); BASE_DECLARE_FEATURE(kUnifiedPasswordManagerReenrollment); +BASE_DECLARE_FEATURE(kUnifiedPasswordManagerAndroidBranding); #endif BASE_DECLARE_FEATURE(kUsernameFirstFlowFallbackCrowdsourcing); @@ -196,18 +197,19 @@ #if BUILDFLAG(IS_ANDROID) // Returns true if the unified password manager feature is active and in a stage -// that allows to use the new UI. +// that allows to use the new feature end-to-end. bool UsesUnifiedPasswordManagerUi(); -#endif // IS_ANDROID -#if BUILDFLAG(IS_ANDROID) +// Returns true when unified password manager strings & icons should be +// displayed. It provides the option to enable the UPM branding UI earlier then +// the UPM feature itself. +bool UsesUnifiedPasswordManagerBranding(); + // Returns true if the unified password manager feature is active and in a stage // that requires migrating existing credentials. Independent of // whether only non-syncable data needs to be migrated or full credentials. bool RequiresMigrationForUnifiedPasswordManager(); -#endif // IS_ANDROID -#if BUILDFLAG(IS_ANDROID) // Returns true if the unified password manager feature is active and in a stage // that uses the unified storage for passwords that remain local on the device. bool ManagesLocalPasswordsInUnifiedPasswordManager();
diff --git a/components/pdf/renderer/pdf_accessibility_tree.cc b/components/pdf/renderer/pdf_accessibility_tree.cc index 694094c..fdfc37c 100644 --- a/components/pdf/renderer/pdf_accessibility_tree.cc +++ b/components/pdf/renderer/pdf_accessibility_tree.cc
@@ -1532,9 +1532,16 @@ } void PdfAccessibilityTree::Finish() { + content::RenderAccessibility* render_accessibility = + GetRenderAccessibilityIfEnabled(); + if (!render_accessibility) + return; + doc_node_->relative_bounds.transform = MakeTransformFromViewInfo(); ui::AXTreeUpdate update; + update.has_tree_data = true; + update.tree_data.tree_id = render_accessibility->GetTreeIDForPluginHost(); update.root_id = doc_node_->id; for (const auto& node : nodes_) update.nodes.push_back(*node); @@ -1543,11 +1550,7 @@ LOG(FATAL) << tree_.error(); UpdateAXTreeDataFromSelection(); - - content::RenderAccessibility* render_accessibility = - GetRenderAccessibilityIfEnabled(); - if (render_accessibility) - render_accessibility->SetPluginTreeSource(this); + render_accessibility->SetPluginTreeSource(this); base::UmaHistogramBoolean("Accessibility.PDF.HasAccessibleText", did_get_a_text_run_);
diff --git a/components/performance_manager/BUILD.gn b/components/performance_manager/BUILD.gn index 82686f0..788824a 100644 --- a/components/performance_manager/BUILD.gn +++ b/components/performance_manager/BUILD.gn
@@ -109,6 +109,7 @@ "performance_manager_registry_impl.h", "performance_manager_tab_helper.cc", "performance_manager_tab_helper.h", + "power/battery_level_provider_creator.cc", "process_node_source.cc", "process_node_source.h", "public/decorators/page_live_state_decorator.h", @@ -143,6 +144,7 @@ "public/performance_manager_main_thread_observer.h", "public/performance_manager_owned.h", "public/performance_manager_registered.h", + "public/power/battery_level_provider_creator.h", "public/render_frame_host_proxy.h", "public/render_process_host_id.h", "public/render_process_host_proxy.h", @@ -189,6 +191,7 @@ deps = [ "//build:chromeos_buildflags", + "//components/content_settings/core/common", "//components/metrics", "//components/pref_registry:pref_registry", "//components/prefs:prefs",
diff --git a/components/performance_manager/DEPS b/components/performance_manager/DEPS index 66c5959..8a30e578 100644 --- a/components/performance_manager/DEPS +++ b/components/performance_manager/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+chromeos/dbus", + "+components/content_settings/core/common", "+components/memory_pressure", "+components/metrics", "+components/pref_registry",
diff --git a/components/performance_manager/decorators/page_live_state_decorator.cc b/components/performance_manager/decorators/page_live_state_decorator.cc index c898193..3f75bd8 100644 --- a/components/performance_manager/decorators/page_live_state_decorator.cc +++ b/components/performance_manager/decorators/page_live_state_decorator.cc
@@ -4,6 +4,9 @@ #include "components/performance_manager/public/decorators/page_live_state_decorator.h" +#include <utility> + +#include "base/bind.h" #include "base/memory/raw_ptr.h" #include "base/observer_list.h" #include "base/sequence_checker.h" @@ -12,7 +15,9 @@ #include "components/performance_manager/graph/page_node_impl.h" #include "components/performance_manager/public/graph/node_data_describer_registry.h" #include "components/performance_manager/public/performance_manager.h" +#include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/web_contents.h" namespace performance_manager { @@ -70,6 +75,11 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return is_active_tab_; } + bool IsContentSettingTypeAllowed(ContentSettingsType type) const override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + auto it = content_settings_.find(type); + return it != content_settings_.end() && it->second == CONTENT_SETTING_ALLOW; + } void SetIsConnectedToUSBDeviceForTesting(bool value) override { set_is_connected_to_usb_device(value); @@ -101,6 +111,10 @@ void SetIsActiveTabForTesting(bool value) override { set_is_active_tab(value); } + void SetContentSettingsForTesting( + const std::map<ContentSettingsType, ContentSetting>& settings) override { + set_content_settings(settings); + } void set_is_connected_to_usb_device(bool is_connected_to_usb_device) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -183,6 +197,17 @@ for (auto& obs : observers_) obs.OnIsActiveTabChanged(page_node_); } + void set_content_settings( + std::map<ContentSettingsType, ContentSetting> settings) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Content settings are set for the first time when the page navigates, and + // subsequently when a notification that they have changed is received. + // Therefore, no need to check to see if they're equal to the previous + // value. + content_settings_ = std::move(settings); + for (auto& obs : observers_) + obs.OnContentSettingsChanged(page_node_); + } private: // Make the impl our friend so it can access the constructor and any @@ -205,6 +230,8 @@ bool is_auto_discardable_ GUARDED_BY_CONTEXT(sequence_checker_) = true; bool was_discarded_ GUARDED_BY_CONTEXT(sequence_checker_) = false; bool is_active_tab_ GUARDED_BY_CONTEXT(sequence_checker_) = false; + std::map<ContentSettingsType, ContentSetting> content_settings_ + GUARDED_BY_CONTEXT(sequence_checker_); const raw_ptr<const PageNode> page_node_; }; @@ -213,6 +240,11 @@ } // namespace +PageLiveStateDecorator::PageLiveStateDecorator( + base::SequenceBound<Delegate> delegate) + : delegate_(std::move(delegate)) {} +PageLiveStateDecorator::~PageLiveStateDecorator() = default; + // static void PageLiveStateDecorator::OnIsConnectedToUSBDeviceChanged( content::WebContents* contents, @@ -299,12 +331,22 @@ contents, &PageLiveStateDataImpl::set_is_active_tab, is_active_tab); } +// static +void PageLiveStateDecorator::SetContentSettings( + content::WebContents* contents, + std::map<ContentSettingsType, ContentSetting> settings) { + SetPropertyForWebContentsPageNode( + contents, &PageLiveStateDataImpl::set_content_settings, settings); +} + void PageLiveStateDecorator::OnPassedToGraph(Graph* graph) { graph->GetNodeDataDescriberRegistry()->RegisterDescriber(this, kDescriberName); + graph->AddPageNodeObserver(this); } void PageLiveStateDecorator::OnTakenFromGraph(Graph* graph) { + graph->RemovePageNodeObserver(this); graph->GetNodeDataDescriberRegistry()->UnregisterDescriber(this); } @@ -330,6 +372,30 @@ return ret; } +void PageLiveStateDecorator::OnMainFrameUrlChanged(const PageNode* page_node) { + // Get the content settings from the main thread. + delegate_.AsyncCall(&Delegate::GetContentSettingsForUrl) + .WithArgs(page_node->GetContentsProxy(), page_node->GetMainFrameUrl()) + .Then(base::BindOnce(&PageLiveStateDecorator::OnContentSettingsReceived, + weak_factory_.GetWeakPtr(), + PageNodeImpl::FromNode(page_node)->GetWeakPtr(), + page_node->GetMainFrameUrl())); +} + +void PageLiveStateDecorator::OnContentSettingsReceived( + base::WeakPtr<const PageNode> page_node, + const GURL& url, + const std::map<ContentSettingsType, ContentSetting>& settings) { + // If the page node doesn't exist anymore, or it has navigated to a different + // URL, there's nothing to do. + if (!page_node || page_node->GetMainFrameUrl() != url) { + return; + } + + PageLiveStateDataImpl::GetOrCreate(PageNodeImpl::FromNode(page_node.get())) + ->set_content_settings(settings); +} + PageLiveStateDecorator::Data::Data() = default; PageLiveStateDecorator::Data::~Data() = default;
diff --git a/components/performance_manager/decorators/page_live_state_decorator_unittest.cc b/components/performance_manager/decorators/page_live_state_decorator_unittest.cc index cfd98f4..21ddcc8 100644 --- a/components/performance_manager/decorators/page_live_state_decorator_unittest.cc +++ b/components/performance_manager/decorators/page_live_state_decorator_unittest.cc
@@ -4,10 +4,14 @@ #include "components/performance_manager/public/decorators/page_live_state_decorator.h" +#include <memory> + #include "base/bind.h" #include "base/memory/raw_ptr.h" #include "base/run_loop.h" +#include "base/task/thread_pool.h" #include "components/performance_manager/test_support/decorators_utils.h" +#include "components/performance_manager/test_support/graph_test_harness.h" #include "components/performance_manager/test_support/performance_manager_test_harness.h" #include "content/public/browser/web_contents.h" #include "testing/gtest/include/gtest/gtest.h" @@ -40,6 +44,7 @@ kOnIsAutoDiscardableChanged, kOnWasDiscardedChanged, kOnIsActiveTabChanged, + kOnContentSettingsChanged, }; void OnIsConnectedToUSBDeviceChanged(const PageNode* page_node) override { @@ -85,11 +90,30 @@ latest_function_called_ = ObserverFunction::kOnIsActiveTabChanged; page_node_passed_ = page_node; } + void OnContentSettingsChanged(const PageNode* page_node) override { + latest_function_called_ = ObserverFunction::kOnContentSettingsChanged; + page_node_passed_ = page_node; + } ObserverFunction latest_function_called_ = ObserverFunction::kNone; raw_ptr<const PageNode> page_node_passed_ = nullptr; }; +class MockPageLiveStateDelegate + : public performance_manager::PageLiveStateDecorator::Delegate { + public: + MockPageLiveStateDelegate() = default; + + private: + std::map<ContentSettingsType, ContentSetting> GetContentSettingsForUrl( + WebContentsProxy web_contents_proxy, + const GURL& url) override { + return { + {ContentSettingsType::NOTIFICATIONS, CONTENT_SETTING_ALLOW}, + }; + } +}; + } // namespace class PageLiveStateDecoratorTest : public PerformanceManagerTestHarness { @@ -173,8 +197,19 @@ run_loop.Run(); } + void OnGraphCreated(GraphImpl* graph) override { + task_runner_ = base::ThreadPool::CreateSequencedTaskRunner({}); + graph->PassToGraph(std::make_unique<PageLiveStateDecorator>( + base::SequenceBound<MockPageLiveStateDelegate>(task_runner_))); + } + + scoped_refptr<base::SequencedTaskRunner> task_runner() { + return task_runner_; + } + private: std::unique_ptr<TestPageLiveStateObserver> observer_; + scoped_refptr<base::SequencedTaskRunner> task_runner_; }; TEST_F(PageLiveStateDecoratorTest, OnIsConnectedToUSBDeviceChanged) { @@ -273,4 +308,131 @@ TestPageLiveStateObserver::ObserverFunction::kOnIsActiveTabChanged); } +TEST_F(PageLiveStateDecoratorTest, OnContentSettingsChanged) { + base::WeakPtr<PageNode> node = + PerformanceManager::GetPrimaryPageNodeForWebContents(web_contents()); + + { + base::RunLoop run_loop; + PerformanceManager::CallOnGraph( + FROM_HERE, base::BindLambdaForTesting([&]() { + ASSERT_TRUE(node); + const PageLiveStateDecorator::Data* data = + PageLiveStateDecorator::Data::FromPageNode(node.get()); + ASSERT_TRUE(data); + EXPECT_EQ(data->IsContentSettingTypeAllowed( + ContentSettingsType::NOTIFICATIONS), + false); + run_loop.Quit(); + })); + run_loop.Run(); + } + + PageLiveStateDecorator::SetContentSettings( + web_contents(), + { + {ContentSettingsType::NOTIFICATIONS, CONTENT_SETTING_ALLOW}, + }); + + { + base::RunLoop run_loop; + PerformanceManager::CallOnGraph( + FROM_HERE, base::BindLambdaForTesting([&]() { + ASSERT_TRUE(node); + const PageLiveStateDecorator::Data* data = + PageLiveStateDecorator::Data::FromPageNode(node.get()); + ASSERT_TRUE(data); + EXPECT_EQ(data->IsContentSettingTypeAllowed( + ContentSettingsType::NOTIFICATIONS), + true); + run_loop.Quit(); + })); + run_loop.Run(); + } + + VerifyObserverExpectationOnPMSequence( + TestPageLiveStateObserver::ObserverFunction::kOnContentSettingsChanged); + + PageLiveStateDecorator::SetContentSettings( + web_contents(), + { + {ContentSettingsType::NOTIFICATIONS, CONTENT_SETTING_BLOCK}, + }); + + { + base::RunLoop run_loop; + PerformanceManager::CallOnGraph( + FROM_HERE, base::BindLambdaForTesting([&]() { + ASSERT_TRUE(node); + const PageLiveStateDecorator::Data* data = + PageLiveStateDecorator::Data::FromPageNode(node.get()); + ASSERT_TRUE(data); + EXPECT_EQ(data->IsContentSettingTypeAllowed( + ContentSettingsType::NOTIFICATIONS), + false); + run_loop.Quit(); + })); + run_loop.Run(); + } + + VerifyObserverExpectationOnPMSequence( + TestPageLiveStateObserver::ObserverFunction::kOnContentSettingsChanged); +} + +TEST_F(PageLiveStateDecoratorTest, GetContentSettingsOnNavigation) { + base::WeakPtr<PageNode> node = + PerformanceManager::GetPrimaryPageNodeForWebContents(web_contents()); + { + base::RunLoop run_loop; + auto quit_closure = run_loop.QuitClosure(); + PerformanceManager::CallOnGraph( + FROM_HERE, base::BindLambdaForTesting([&]() { + ASSERT_TRUE(node); + const PageLiveStateDecorator::Data* data = + PageLiveStateDecorator::Data::FromPageNode(node.get()); + ASSERT_TRUE(data); + EXPECT_EQ(data->IsContentSettingTypeAllowed( + ContentSettingsType::NOTIFICATIONS), + false); + PageNodeImpl::FromNode(node.get()) + ->OnMainFrameNavigationCommitted( + /*same_document=*/false, + /*navigation_committed_time=*/base::TimeTicks::Now(), + /*navigation_id=*/1, + /*url=*/GURL("http://www.example.com"), + /*contents_mime_type=*/"text/html"); + + // Posting the quit_closure run on the same task runner as the content + // settings fetch ensures it's run after the settings are done being + // retrieved. + task_runner()->PostTask(FROM_HERE, base::BindLambdaForTesting([&]() { + std::move(quit_closure).Run(); + })); + })); + run_loop.Run(); + } + + VerifyObserverExpectationOnPMSequence( + TestPageLiveStateObserver::ObserverFunction::kOnContentSettingsChanged); + + { + base::RunLoop run_loop; + PerformanceManager::CallOnGraph( + FROM_HERE, base::BindLambdaForTesting([&]() { + ASSERT_TRUE(node); + const PageLiveStateDecorator::Data* data = + PageLiveStateDecorator::Data::FromPageNode(node.get()); + ASSERT_TRUE(data); + EXPECT_EQ(data->IsContentSettingTypeAllowed( + ContentSettingsType::NOTIFICATIONS), + true); + run_loop.Quit(); + })); + run_loop.Run(); + } + + VerifyObserverExpectationOnPMSequence( + TestPageLiveStateObserver::ObserverFunction::kOnContentSettingsChanged); +} + } // namespace performance_manager
diff --git a/components/performance_manager/embedder/graph_features.h b/components/performance_manager/embedder/graph_features.h index a07d4c4..52ccbbce 100644 --- a/components/performance_manager/embedder/graph_features.h +++ b/components/performance_manager/embedder/graph_features.h
@@ -46,7 +46,6 @@ bool frame_visibility_decorator : 1; bool freezing_vote_decorator : 1; bool metrics_collector : 1; - bool page_live_state_decorator : 1; bool page_load_tracker_decorator : 1; bool page_node_impl_describer : 1; bool process_hosted_content_types_aggregator : 1; @@ -93,11 +92,6 @@ return *this; } - constexpr GraphFeatures& EnablePageLiveStateDecorator() { - flags_.page_live_state_decorator = true; - return *this; - } - constexpr GraphFeatures& EnablePageLoadTrackerDecorator() { flags_.page_load_tracker_decorator = true; return *this; @@ -157,7 +151,6 @@ EnableFrameVisibilityDecorator(); EnableFreezingVoteDecorator(); EnableMetricsCollector(); - EnablePageLiveStateDecorator(); EnablePageLoadTrackerDecorator(); EnablePageNodeImplDescriber(); EnableProcessHostedContentTypesAggregator();
diff --git a/components/performance_manager/graph_features.cc b/components/performance_manager/graph_features.cc index c245c55..8d283b7 100644 --- a/components/performance_manager/graph_features.cc +++ b/components/performance_manager/graph_features.cc
@@ -17,7 +17,6 @@ #include "components/performance_manager/graph/page_node_impl_describer.h" #include "components/performance_manager/graph/process_node_impl_describer.h" #include "components/performance_manager/graph/worker_node_impl_describer.h" -#include "components/performance_manager/public/decorators/page_live_state_decorator.h" #include "components/performance_manager/public/graph/graph.h" #include "components/performance_manager/public/metrics/metrics_collector.h" #include "components/performance_manager/v8_memory/v8_context_tracker.h" @@ -49,8 +48,6 @@ Install<MetricsCollector>(graph); if (flags_.freezing_vote_decorator) Install<FreezingVoteDecorator>(graph); - if (flags_.page_live_state_decorator) - Install<PageLiveStateDecorator>(graph); if (flags_.page_load_tracker_decorator) Install<PageLoadTrackerDecorator>(graph); if (flags_.page_node_impl_describer)
diff --git a/components/performance_manager/graph_features_unittest.cc b/components/performance_manager/graph_features_unittest.cc index 9028d13..910ed2f6f 100644 --- a/components/performance_manager/graph_features_unittest.cc +++ b/components/performance_manager/graph_features_unittest.cc
@@ -53,7 +53,7 @@ execution_context::ExecutionContextRegistry::GetFromGraph(&graph)); EXPECT_FALSE(v8_memory::V8ContextTracker::GetFromGraph(&graph)); - size_t graph_owned_count = 12; + size_t graph_owned_count = 11; #if !BUILDFLAG(IS_ANDROID) // The SiteDataRecorder is not available on Android. graph_owned_count++; @@ -64,7 +64,7 @@ features.ConfigureGraph(&graph); EXPECT_EQ(graph_owned_count, graph.GraphOwnedCountForTesting()); EXPECT_EQ(3u, graph.GraphRegisteredCountForTesting()); - EXPECT_EQ(8u, graph.NodeDataDescriberCountForTesting()); + EXPECT_EQ(7u, graph.NodeDataDescriberCountForTesting()); // Ensure the GraphRegistered objects can be queried directly. EXPECT_TRUE( execution_context::ExecutionContextRegistry::GetFromGraph(&graph));
diff --git a/components/performance_manager/power/battery_level_provider_chromeos.cc b/components/performance_manager/power/battery_level_provider_chromeos.cc index 773bc6a..2d130fa8a 100644 --- a/components/performance_manager/power/battery_level_provider_chromeos.cc +++ b/components/performance_manager/power/battery_level_provider_chromeos.cc
@@ -20,6 +20,14 @@ BatteryLevelProviderChromeOS::~BatteryLevelProviderChromeOS() = default; +// static +std::unique_ptr<base::BatteryLevelProvider> +BatteryLevelProviderChromeOS::Create() { + return std::make_unique< + performance_manager::power::BatteryLevelProviderChromeOS>( + chromeos::PowerManagerClient::Get()); +} + void BatteryLevelProviderChromeOS::GetBatteryState( base::OnceCallback< void(const absl::optional<base::BatteryLevelProvider::BatteryState>&)>
diff --git a/components/performance_manager/power/battery_level_provider_chromeos.h b/components/performance_manager/power/battery_level_provider_chromeos.h index ce2342590..ee9e6ae0 100644 --- a/components/performance_manager/power/battery_level_provider_chromeos.h +++ b/components/performance_manager/power/battery_level_provider_chromeos.h
@@ -20,6 +20,8 @@ chromeos::PowerManagerClient* power_manager_client); ~BatteryLevelProviderChromeOS() override; + static std::unique_ptr<base::BatteryLevelProvider> Create(); + private: friend class BatteryLevelProviderChromeOSTest;
diff --git a/components/performance_manager/power/battery_level_provider_creator.cc b/components/performance_manager/power/battery_level_provider_creator.cc new file mode 100644 index 0000000..69a2de84 --- /dev/null +++ b/components/performance_manager/power/battery_level_provider_creator.cc
@@ -0,0 +1,28 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/performance_manager/public/power/battery_level_provider_creator.h" + +#include <utility> + +#include "base/power_monitor/battery_level_provider.h" +#include "build/build_config.h" + +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "components/performance_manager/power/battery_level_provider_chromeos.h" +#endif + +namespace performance_manager::power { + +std::unique_ptr<base::BatteryLevelProvider> CreateBatteryLevelProvider() { + // TODO(crbug.com/1373560): Move all of the creation code into the + // platform-specific implementations once they're moved to components. +#if BUILDFLAG(IS_CHROMEOS_ASH) + return performance_manager::power::BatteryLevelProviderChromeOS::Create(); +#else + return base::BatteryLevelProvider::Create(); +#endif +} + +} // namespace performance_manager::power
diff --git a/components/performance_manager/public/decorators/page_live_state_decorator.h b/components/performance_manager/public/decorators/page_live_state_decorator.h index 09d11baf..a732421f 100644 --- a/components/performance_manager/public/decorators/page_live_state_decorator.h +++ b/components/performance_manager/public/decorators/page_live_state_decorator.h
@@ -5,12 +5,20 @@ #ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_DECORATORS_PAGE_LIVE_STATE_DECORATOR_H_ #define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_DECORATORS_PAGE_LIVE_STATE_DECORATOR_H_ +#include <map> + +#include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/observer_list_types.h" #include "base/sequence_checker.h" +#include "base/threading/sequence_bound.h" +#include "components/content_settings/core/common/content_settings.h" +#include "components/content_settings/core/common/content_settings_types.h" #include "components/performance_manager/public/graph/graph.h" #include "components/performance_manager/public/graph/node_data_describer.h" #include "components/performance_manager/public/graph/page_node.h" +#include "components/performance_manager/public/web_contents_proxy.h" +#include "url/gurl.h" namespace content { class WebContents; @@ -25,15 +33,24 @@ // All the functions that take a WebContents* as a parameter should only be // called from the UI thread, the event will be forwarded to the corresponding // PageNode on the Performance Manager's sequence. -class PageLiveStateDecorator - : public GraphOwnedDefaultImpl, - public NodeDataDescriberDefaultImpl { +class PageLiveStateDecorator : public GraphOwnedDefaultImpl, + public NodeDataDescriberDefaultImpl, + public PageNode::ObserverDefaultImpl { public: class Data; + class Delegate { + public: + virtual ~Delegate() = default; + // Invoked on the main thread. Returns the relevant content settings for + // `url` in the web contents' profile. + virtual std::map<ContentSettingsType, ContentSetting> + GetContentSettingsForUrl(WebContentsProxy web_contents_proxy, + const GURL& url) = 0; + }; // This object should only be used via its static methods. - PageLiveStateDecorator() = default; - ~PageLiveStateDecorator() override = default; + explicit PageLiveStateDecorator(base::SequenceBound<Delegate> delegate); + ~PageLiveStateDecorator() override; PageLiveStateDecorator(const PageLiveStateDecorator& other) = delete; PageLiveStateDecorator& operator=(const PageLiveStateDecorator&) = delete; @@ -69,13 +86,31 @@ static void SetIsActiveTab(content::WebContents* contents, bool is_active_tab); + static void SetContentSettings( + content::WebContents* contents, + std::map<ContentSettingsType, ContentSetting> settings); + private: + friend class PageLiveStateDecoratorTest; + // GraphOwned implementation: void OnPassedToGraph(Graph* graph) override; void OnTakenFromGraph(Graph* graph) override; // NodeDataDescriber implementation: base::Value DescribePageNodeData(const PageNode* node) const override; + + // PageNode::ObserverDefaultImpl implementation: + void OnMainFrameUrlChanged(const PageNode* page_node) override; + + void OnContentSettingsReceived( + base::WeakPtr<const PageNode> page_node, + const GURL& url, + const std::map<ContentSettingsType, ContentSetting>& settings); + + base::SequenceBound<Delegate> delegate_; + + base::WeakPtrFactory<PageLiveStateDecorator> weak_factory_{this}; }; class PageLiveStateDecorator::Data { @@ -98,6 +133,7 @@ virtual bool IsAutoDiscardable() const = 0; virtual bool WasDiscarded() const = 0; virtual bool IsActiveTab() const = 0; + virtual bool IsContentSettingTypeAllowed(ContentSettingsType type) const = 0; static const Data* FromPageNode(const PageNode* page_node); static Data* GetOrCreateForPageNode(const PageNode* page_node); @@ -112,6 +148,8 @@ virtual void SetIsAutoDiscardableForTesting(bool value) = 0; virtual void SetWasDiscardedForTesting(bool value) = 0; virtual void SetIsActiveTabForTesting(bool value) = 0; + virtual void SetContentSettingsForTesting( + const std::map<ContentSettingsType, ContentSetting>& settings) = 0; protected: base::ObserverList<PageLiveStateObserver> observers_ @@ -138,6 +176,7 @@ virtual void OnIsAutoDiscardableChanged(const PageNode* page_node) = 0; virtual void OnWasDiscardedChanged(const PageNode* page_node) = 0; virtual void OnIsActiveTabChanged(const PageNode* page_node) = 0; + virtual void OnContentSettingsChanged(const PageNode* page_node) = 0; }; } // namespace performance_manager
diff --git a/components/performance_manager/public/power/battery_level_provider_creator.h b/components/performance_manager/public/power/battery_level_provider_creator.h new file mode 100644 index 0000000..e37b9a4 --- /dev/null +++ b/components/performance_manager/public/power/battery_level_provider_creator.h
@@ -0,0 +1,20 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_POWER_BATTERY_LEVEL_PROVIDER_CREATOR_H_ +#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_POWER_BATTERY_LEVEL_PROVIDER_CREATOR_H_ + +#include <memory> + +namespace base { +class BatteryLevelProvider; +} // namespace base + +namespace performance_manager::power { + +std::unique_ptr<base::BatteryLevelProvider> CreateBatteryLevelProvider(); + +} // namespace performance_manager::power + +#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_POWER_BATTERY_LEVEL_PROVIDER_CREATOR_H_
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index ba58f95..1b48173 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -22926,7 +22926,8 @@ 'owners': ['eladalon@chromium.org', 'guidou@chromium.org'], 'type': 'main', 'schema': { 'type': 'boolean' }, - 'supported_on': ['chrome.*:94-', 'chrome_os:94-'], + 'deprecated': True, + 'supported_on': ['chrome.*:94-107', 'chrome_os:94-107'], 'future_on': ['fuchsia'], 'device_only': False, 'features': {
diff --git a/components/policy/resources/templates/policies.yaml b/components/policy/resources/templates/policies.yaml index 38e1973..bbb5339 100644 --- a/components/policy/resources/templates/policies.yaml +++ b/components/policy/resources/templates/policies.yaml
@@ -878,7 +878,7 @@ 877: DataLeakPreventionClipboardCheckSizeLimit 878: CrossOriginWebAssemblyModuleSharingEnabled 879: RestrictedManagedGuestSessionExtensionCleanupExemptList - 880: DisplayCapturePermissionsPolicyEnabled + 880: '' 881: ScreenCaptureAllowedByOrigins 882: WindowCaptureAllowedByOrigins 883: TabCaptureAllowedByOrigins
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/DisplayCapturePermissionsPolicyEnabled.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/DisplayCapturePermissionsPolicyEnabled.yaml deleted file mode 100644 index 46fa9a8..0000000 --- a/components/policy/resources/templates/policy_definitions/Miscellaneous/DisplayCapturePermissionsPolicyEnabled.yaml +++ /dev/null
@@ -1,38 +0,0 @@ -caption: Specifies whether the display-capture permissions-policy is checked or skipped. -default: true -desc: |2- - - The display-capture permissions-policy gates access to getDisplayMedia(), as per this spec: https://www.w3.org/TR/screen-capture/#feature-policy-integration. However, if this policy is Disabled, this requirement is not enforced, and getDisplayMedia() is allowed from contexts that would otherwise be forbidden. This Enterprise policy is temporary; it's intended to be removed after <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> version 100. It is intended to unblock Enterprise users whose application is non-spec compliant, but needs time to be fixed. - - When enabled or not set, sites can only call getDisplayMedia() from contexts which are allowlisted by the display-capture permissions-policy. - - When disabled, sites can call getDisplayMedia() even from contexts which are not allowlisted by the display-capture permissions policy. Note that other restrictions may still apply. -device_only: false -example_value: true -features: - dynamic_refresh: false - per_profile: true -future_on: -- fuchsia -items: -- caption: |2- - - Calls to getDisplayMedia originating from non-allowlisted contexts - are denied. - value: true -- caption: |2- - - Calls are not denied on account of originating from non-allowlisted - contexts. (Calls may still be denied for other reasons.) - value: false -owners: -- eladalon@chromium.org -- guidou@chromium.org -schema: - type: boolean -supported_on: -- chrome.*:94- -- chrome_os:94- -tags: -- system-security -type: main
diff --git a/components/resources/safe_browsing_resources.grdp b/components/resources/safe_browsing_resources.grdp index f41fb674..506f5ccf 100644 --- a/components/resources/safe_browsing_resources.grdp +++ b/components/resources/safe_browsing_resources.grdp
@@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <grit-part> - <include name="IDR_SAFE_BROWSING_HTML" file="..\..\components\safe_browsing\content\browser\web_ui\resources\safe_browsing.html" type="BINDATA" /> + <include name="IDR_SAFE_BROWSING_HTML" file="..\..\components\safe_browsing\content\browser\web_ui\resources\safe_browsing.html" preprocess="true" type="BINDATA" /> <include name="IDR_SAFE_BROWSING_CSS" file="..\..\components\safe_browsing\content\browser\web_ui\resources\safe_browsing.css" type="BINDATA" /> - <include name="IDR_SAFE_BROWSING_JS" file="..\..\components\safe_browsing\content\browser\web_ui\resources\safe_browsing.js" type="BINDATA" /> + <include name="IDR_SAFE_BROWSING_JS" file="..\..\components\safe_browsing\content\browser\web_ui\resources\safe_browsing.js" preprocess="true" type="BINDATA" /> <if expr="safe_browsing_mode != 0"> <include name="IDR_DOWNLOAD_FILE_TYPES_PB" file="${root_gen_dir}\components\safe_browsing\content\resources\download_file_types.pb" use_base_dir="false" type="BINDATA" compress="gzip" /> </if>
diff --git a/components/safe_browsing/content/browser/download/download_stats.cc b/components/safe_browsing/content/browser/download/download_stats.cc index 241c309..562c259 100644 --- a/components/safe_browsing/content/browser/download/download_stats.cc +++ b/components/safe_browsing/content/browser/download/download_stats.cc
@@ -9,6 +9,7 @@ #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #include "base/time/time.h" +#include "components/download/public/common/download_content.h" #include "components/download/public/common/download_danger_type.h" #include "components/safe_browsing/content/common/file_type_policies.h" @@ -132,69 +133,9 @@ download::DownloadContent download_content, base::Time download_opened_time, base::Time download_end_time) { - std::string download_content_str; - switch (download_content) { - case download::DownloadContent::UNRECOGNIZED: - download_content_str = "UNRECOGNIZED"; - break; - case download::DownloadContent::TEXT: - download_content_str = "TEXT"; - break; - case download::DownloadContent::IMAGE: - download_content_str = "IMAGE"; - break; - case download::DownloadContent::AUDIO: - download_content_str = "AUDIO"; - break; - case download::DownloadContent::VIDEO: - download_content_str = "VIDEO"; - break; - case download::DownloadContent::OCTET_STREAM: - download_content_str = "OCTET_STREAM"; - break; - case download::DownloadContent::PDF: - download_content_str = "PDF"; - break; - case download::DownloadContent::DOCUMENT: - download_content_str = "DOCUMENT"; - break; - case download::DownloadContent::SPREADSHEET: - download_content_str = "SPREADSHEET"; - break; - case download::DownloadContent::PRESENTATION: - download_content_str = "PRESENTATION"; - break; - case download::DownloadContent::ARCHIVE: - download_content_str = "ARCHIVE"; - break; - case download::DownloadContent::EXECUTABLE: - download_content_str = "EXECUTABLE"; - break; - case download::DownloadContent::DMG: - download_content_str = "DMG"; - break; - case download::DownloadContent::CRX: - download_content_str = "CRX"; - break; - case download::DownloadContent::WEB: - download_content_str = "WEB"; - break; - case download::DownloadContent::EBOOK: - download_content_str = "EBOOK"; - break; - case download::DownloadContent::FONT: - download_content_str = "FONT"; - break; - case download::DownloadContent::APK: - download_content_str = "APK"; - break; - case download::DownloadContent::MAX: - download_content_str = "MAX"; - break; - } base::UmaHistogramCustomTimes( "SBClientDownload.SafeDownloadOpenedLatencyByContentType." + - download_content_str, + download::GetDownloadContentString(download_content), /* sample */ download_opened_time - download_end_time, /* min */ base::Seconds(1), /* max */ base::Days(1), /* buckets */ 50);
diff --git a/components/safe_browsing/content/browser/web_ui/resources/safe_browsing.html b/components/safe_browsing/content/browser/web_ui/resources/safe_browsing.html index 24a3d63..ad01262 100644 --- a/components/safe_browsing/content/browser/web_ui/resources/safe_browsing.html +++ b/components/safe_browsing/content/browser/web_ui/resources/safe_browsing.html
@@ -116,8 +116,10 @@ <div class="content"> <p id="referrer-chain-content"></p> </div> +<if expr="is_android"> <h2>Most Recent Referring App Info (Android)</h2> <p id="referring-app-info" class="result-container"></p> +</if> </div> <div slot="panel"> <h2>Log Messages</h2>
diff --git a/components/safe_browsing/content/browser/web_ui/resources/safe_browsing.js b/components/safe_browsing/content/browser/web_ui/resources/safe_browsing.js index 8dc57bb..5f505121 100644 --- a/components/safe_browsing/content/browser/web_ui/resources/safe_browsing.js +++ b/components/safe_browsing/content/browser/web_ui/resources/safe_browsing.js
@@ -177,9 +177,11 @@ addDeepScan(result); }); + // <if expr="is_android"> sendWithPromise('getReferringAppInfo', []).then((info) => { addReferringAppInfo(info); }); + // </if> $('get-referrer-chain-form').addEventListener('submit', addReferrerChain); @@ -426,10 +428,12 @@ }); } +// <if expr="is_android"> function addReferringAppInfo(info) { $('referring-app-info').innerHTML = trustedTypes.emptyHTML; $('referring-app-info').textContent = info; } +// </if> function showTab(tabId) { const tabs = document.querySelectorAll('div[slot=\'tab\']');
diff --git a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc index 596cf88..92597a9 100644 --- a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc +++ b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc
@@ -1249,6 +1249,68 @@ return client_properties_dict; } +base::Value::Dict SerializeDownloadWarningAction( + const ClientSafeBrowsingReportRequest::DownloadWarningAction& + download_warning_action) { + base::Value::Dict action_dict; + std::string surface; + switch (download_warning_action.surface()) { + case ClientSafeBrowsingReportRequest::DownloadWarningAction:: + SURFACE_UNSPECIFIED: + surface = "SURFACE_UNSPECIFIED"; + break; + case ClientSafeBrowsingReportRequest::DownloadWarningAction:: + BUBBLE_MAINPAGE: + surface = "BUBBLE_MAINPAGE"; + break; + case ClientSafeBrowsingReportRequest::DownloadWarningAction::BUBBLE_SUBPAGE: + surface = "BUBBLE_SUBPAGE"; + break; + case ClientSafeBrowsingReportRequest::DownloadWarningAction::DOWNLOADS_PAGE: + surface = "DOWNLOADS_PAGE"; + break; + case ClientSafeBrowsingReportRequest::DownloadWarningAction:: + DOWNLOAD_PROMPT: + surface = "DOWNLOAD_PROMPT"; + break; + } + action_dict.Set("surface", surface); + std::string action; + switch (download_warning_action.action()) { + case ClientSafeBrowsingReportRequest::DownloadWarningAction:: + ACTION_UNSPECIFIED: + action = "ACTION_UNSPECIFIED"; + break; + case ClientSafeBrowsingReportRequest::DownloadWarningAction::PROCEED: + action = "PROCEED"; + break; + case ClientSafeBrowsingReportRequest::DownloadWarningAction::DISCARD: + action = "DISCARD"; + break; + case ClientSafeBrowsingReportRequest::DownloadWarningAction::KEEP: + action = "KEEP"; + break; + case ClientSafeBrowsingReportRequest::DownloadWarningAction::CLOSE: + action = "CLOSE"; + break; + case ClientSafeBrowsingReportRequest::DownloadWarningAction::CANCEL: + action = "CANCEL"; + break; + case ClientSafeBrowsingReportRequest::DownloadWarningAction::DISMISS: + action = "DISMISS"; + break; + case ClientSafeBrowsingReportRequest::DownloadWarningAction::BACK: + action = "BACK"; + break; + } + action_dict.Set("action", action); + action_dict.Set("is_terminal_action", + download_warning_action.is_terminal_action()); + action_dict.Set("interval_msec", + static_cast<double>(download_warning_action.interval_msec())); + return action_dict; +} + std::string SerializeCSBRR(const ClientSafeBrowsingReportRequest& report) { base::Value::Dict report_request; if (report.has_type()) { @@ -1361,6 +1423,14 @@ "client_properties", SerializeSafeBrowsingClientProperties(report.client_properties())); } + base::Value::List download_warning_action_list; + for (const auto& download_warning_action : + report.download_warning_actions()) { + download_warning_action_list.Append( + SerializeDownloadWarningAction(download_warning_action)); + } + report_request.Set("download_warning_actions", + std::move(download_warning_action_list)); std::string serialized; if (report.SerializeToString(&serialized)) { std::string base64_encoded; @@ -2730,17 +2800,14 @@ base::Value(referrer_chain_serialized)); } -void SafeBrowsingUIHandler::GetReferringAppInfo(const base::Value::List& args) { #if BUILDFLAG(IS_ANDROID) +void SafeBrowsingUIHandler::GetReferringAppInfo(const base::Value::List& args) { base::Value::Dict referring_app_value; LoginReputationClientRequest::ReferringAppInfo info = WebUIInfoSingleton::GetInstance()->GetReferringAppInfo( web_ui()->GetWebContents()); referring_app_value = SerializeReferringAppInfo(info); -#else - base::Value referring_app_value; - referring_app_value = base::Value("Not supported on current platform."); -#endif + std::string referring_app_serialized; JSONStringValueSerializer serializer(&referring_app_serialized); serializer.set_pretty_print(true); @@ -2752,6 +2819,7 @@ ResolveJavascriptCallback(base::Value(callback_id), base::Value(referring_app_serialized)); } +#endif void SafeBrowsingUIHandler::GetReportingEvents(const base::Value::List& args) { base::Value::List reporting_events; @@ -3012,10 +3080,12 @@ "getReferrerChain", base::BindRepeating(&SafeBrowsingUIHandler::GetReferrerChain, base::Unretained(this))); +#if BUILDFLAG(IS_ANDROID) web_ui()->RegisterMessageCallback( "getReferringAppInfo", base::BindRepeating(&SafeBrowsingUIHandler::GetReferringAppInfo, base::Unretained(this))); +#endif web_ui()->RegisterMessageCallback( "getReportingEvents", base::BindRepeating(&SafeBrowsingUIHandler::GetReportingEvents,
diff --git a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h index af975d5..28b8bc0 100644 --- a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h +++ b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h
@@ -173,9 +173,11 @@ // Get the current referrer chain for a given URL. void GetReferrerChain(const base::Value::List& args); +#if BUILDFLAG(IS_ANDROID) // Get the referring app info that launches Chrome on Android. Always set to // null if it's called from platforms other than Android. void GetReferringAppInfo(const base::Value::List& args); +#endif // Get the list of log messages that have been received since the oldest // currently open chrome://safe-browsing tab was opened.
diff --git a/components/safe_browsing/core/common/proto/csd.proto b/components/safe_browsing/core/common/proto/csd.proto index d332f2fe..8c20f88 100644 --- a/components/safe_browsing/core/common/proto/csd.proto +++ b/components/safe_browsing/core/common/proto/csd.proto
@@ -1633,6 +1633,61 @@ optional string safety_net_id = 25 [deprecated = true]; optional ChromeUserPopulation population = 26; + + // Logs user actions on download warnings. This field is useful for analyzing + // whether users pay attention to the warning, and why they decide to proceed + // or discard. + message DownloadWarningAction { + // The warning surface this action is performed on. See + // go/chrome-download-warning-surfaces for details. + enum Surface { + SURFACE_UNSPECIFIED = 0; + // Applicable actions: DISCARD + BUBBLE_MAINPAGE = 1; + // Applicable actions: PROCEED, DISCARD, DISMISS, CLOSE, BACK + BUBBLE_SUBPAGE = 2; + // Applicable actions: DISCARD, KEEP + DOWNLOADS_PAGE = 3; + // Applicable actions: PROCEED, CANCEL, CLOSE + DOWNLOAD_PROMPT = 4; + } + optional Surface surface = 1; + + enum Action { + ACTION_UNSPECIFIED = 0; + // The user clicks proceed, which means the user decides to bypass the + // warning. + PROCEED = 1; + // The user clicks discard, which means the user decides to obey the + // warning and the dangerous download is deleted from disk. + DISCARD = 2; + // The user has clicked the keep button on the surface. + KEEP = 3; + // The user has clicked the close button on the surface. + CLOSE = 4; + // The user clicks cancel on the download prompt. + CANCEL = 5; + // The user has dismissed the bubble by clicking anywhere outside + // the bubble. + DISMISS = 6; + // The user has clicked the back button on the bubble subpage to go back + // to the bubble main page. + BACK = 7; + } + optional Action action = 2; + + // Whether the action is terminal (i.e. the warning disappears after this + // action is performed). + optional bool is_terminal_action = 3; + + // Time intervals between when the download warning is first shown and + // when the user performs actions on that warning, measured on the + // client-side by the same clock. If the same warning has shown multiple + // times, the interval is anchored to the earliest warning. All intervals + // are measured in milliseconds. + optional int64 interval_msec = 4; + } + repeated DownloadWarningAction download_warning_actions = 27; } // An HTML Element on the page (eg: iframe, div, script, etc).
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index 2c955a1..daab4044 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -1706,6 +1706,18 @@ const DrawQuad* SkiaRenderer::CanPassBeDrawnDirectly( const AggregatedRenderPass* pass) { + bool is_directly_drawable_with_single_rpdq = false; + const auto* draw_quad = CanPassBeDrawnDirectlyInternal( + pass, &is_directly_drawable_with_single_rpdq); + UMA_HISTOGRAM_BOOLEAN( + "Compositing.SkiaRenderer.DirectlyDrawableRenderPassWithRPDQ", + is_directly_drawable_with_single_rpdq); + return draw_quad; +} + +const DrawQuad* SkiaRenderer::CanPassBeDrawnDirectlyInternal( + const AggregatedRenderPass* pass, + bool* is_directly_drawable_with_single_rpdq) { // If render pass bypassing is disabled for testing if (settings_->disable_render_pass_bypassing) return nullptr; @@ -1724,9 +1736,10 @@ // For simplicity in their draw implementations, debug borders, picture quads, // and nested render passes cannot bypass a render pass // (their draw functions do not accept DrawRPDQParams either). + // Note: The check for RPDQ is at the end of the function to log whether other + // vetoes would prevent optimizing this case. DCHECK_NE(quad->material, DrawQuad::Material::kCompositorRenderPass); - if (quad->material == DrawQuad::Material::kAggregatedRenderPass || - quad->material == DrawQuad::Material::kDebugBorder || + if (quad->material == DrawQuad::Material::kDebugBorder || quad->material == DrawQuad::Material::kPictureContent) return nullptr; @@ -1786,6 +1799,28 @@ if (ShouldApplyGradientMask(quad)) return nullptr; + if (quad->material == DrawQuad::Material::kAggregatedRenderPass) { + const auto* render_pass_quad = + AggregatedRenderPassDrawQuad::MaterialCast(quad); + if (render_pass_quad->mask_resource_id()) + return nullptr; + + const auto nested_render_pass_id = render_pass_quad->render_pass_id; + auto it = base::ranges::find_if( + *current_frame()->render_passes_in_draw_order, + [&nested_render_pass_id](const auto& render_pass) { + return render_pass->id == nested_render_pass_id; + }); + + DCHECK(it != current_frame()->render_passes_in_draw_order->end()); + const auto& nested_render_pass = *it; + if (nested_render_pass->filters.IsEmpty() && + nested_render_pass->backdrop_filters.IsEmpty()) { + *is_directly_drawable_with_single_rpdq = true; + } + return nullptr; + } + // The quad type knows how to apply RPDQ filters, and the quad settings can // be merged into the RPDQs settings in CalculateBypassParams. return quad;
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h index a427eb7..c6f95a3 100644 --- a/components/viz/service/display/skia_renderer.h +++ b/components/viz/service/display/skia_renderer.h
@@ -248,6 +248,10 @@ const DrawQuad* CanPassBeDrawnDirectly( const AggregatedRenderPass* pass) override; + const DrawQuad* CanPassBeDrawnDirectlyInternal( + const AggregatedRenderPass* pass, + bool* is_directly_drawable_with_single_rpdq); + void DrawDelegatedInkTrail() override; // Get a color filter that converts from |src| color space to |dst| color
diff --git a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc index a9627d97..038254e9 100644 --- a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc +++ b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc
@@ -265,9 +265,6 @@ void FrameSinkVideoCapturerImpl::SetFormat(media::VideoPixelFormat format) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DVLOG(3) << __func__ - << ": format=" << media::VideoPixelFormatToString(format); - bool format_changed = false; if (format != media::PIXEL_FORMAT_I420 && @@ -350,17 +347,9 @@ const gfx::Size& max_size, bool use_fixed_aspect_ratio) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - DVLOG(2) << __func__ << ": min_size=" << min_size.ToString() - << ", max_size=" << max_size.ToString() - << ", use_fixed_aspect_ratio=" << use_fixed_aspect_ratio; - TRACE_EVENT_INSTANT2("gpu.capture", "SetResolutionConstraints", - TRACE_EVENT_SCOPE_THREAD, "min_size.width", - min_size.width(), "min_size.height", min_size.height()); - TRACE_EVENT_INSTANT2("gpu.capture", "SetResolutionConstraints", - TRACE_EVENT_SCOPE_THREAD, "max_size.width", - max_size.width(), "max_size.height", max_size.height()); + TRACE_EVENT_SCOPE_THREAD, "min_size", + min_size.ToString(), "max_size", max_size.ToString()); if (min_size.width() <= 0 || min_size.height() <= 0 || max_size.width() > media::limits::kMaxDimension || @@ -593,12 +582,10 @@ if (capture_region.size() != oracle_->source_size()) { oracle_->SetSourceSize(capture_region.size()); InvalidateEntireSource(); - if (log_to_webrtc_) { - consumer_->OnLog( - base::StringPrintf("FrameSinkVideoCapturerImpl::RefreshInternal() " - "changed active frame size: %s", - capture_region.size().ToString().c_str())); - } + OnLog( + base::StringPrintf("FrameSinkVideoCapturerImpl::RefreshInternal() " + "changed active frame size: %s", + capture_region.size().ToString().c_str())); } MaybeCaptureFrame(event, gfx::Rect(), clock_->NowTicks(), @@ -636,11 +623,9 @@ } else { oracle_->SetSourceSize(capture_region.size()); InvalidateEntireSource(); - if (log_to_webrtc_ && consumer_) { - consumer_->OnLog(base::StringPrintf( - "FrameSinkVideoCapturerImpl::OnFrameDamaged() changed frame size: %s", - capture_region.size().ToString().c_str())); - } + OnLog(base::StringPrintf( + "FrameSinkVideoCapturerImpl::OnFrameDamaged() changed frame size: %s", + capture_region.size().ToString().c_str())); } MaybeCaptureFrame(VideoCaptureOracle::kCompositorUpdate, damage_rect, @@ -746,7 +731,10 @@ // TODO(https://crbug.com/1300943): we should likely just get the frame // region from the last aggregated surface. if (!compositor_frame_region.Contains(capture_region)) { - DVLOG(3) << __func__ << ": skipping capture!"; + TRACE_EVENT_INSTANT2("gpu.capture", "DroppingFrameWithUncontainedRegion", + TRACE_EVENT_SCOPE_THREAD, "compositor_frame_region", + compositor_frame_region.ToString(), "capture_region", + capture_region.ToString()); MaybeScheduleRefreshFrame(); return; } @@ -766,17 +754,11 @@ const gfx::Size capture_size = AdjustSizeForPixelFormat(oracle_->capture_size()); - // Size of the source that we are capturing: + // Size of the source that we are capturing. const gfx::Size source_size = oracle_->source_size(); DCHECK_EQ(capture_region.size(), source_size); DCHECK(!source_size.IsEmpty()); - DVLOG(3) << __func__ - << ": compositor_frame_region=" << compositor_frame_region.ToString() - << ", capture_region=" << capture_region.ToString() - << ", capture_size=" << capture_size.ToString() - << ", event=" << event; - const bool can_resurrect_content = CanResurrectFrame(capture_size); scoped_refptr<VideoFrame> frame; if (can_resurrect_content) { @@ -784,7 +766,10 @@ TRACE_EVENT_SCOPE_THREAD); frame = ResurrectFrame(); } else { - TRACE_EVENT0("gpu.capture", "ReservingVideoFrame"); + TRACE_EVENT_INSTANT2("gpu.capture", "ReservingVideoFrame", + TRACE_EVENT_SCOPE_THREAD, "compositor_frame_region", + compositor_frame_region.ToString(), "capture_region", + capture_region.ToString()); auto reserve_start_time = base::TimeTicks::Now(); frame = frame_pool_->ReserveVideoFrame(pixel_format_, capture_size); @@ -866,14 +851,6 @@ metadata.top_controls_visible_height = last_top_controls_visible_height_; oracle_->RecordCapture(utilization); - // Note: The following is used by - // chrome/browser/media/cast_mirroring_performance_browsertest.cc, in - // addition to the usual runtime tracing - // TODO(https://crbug.com/1322573): change to _NESTABLE_ variant of the macro - // once the bug is fixed. - TRACE_EVENT_ASYNC_BEGIN2("gpu.capture", "Capture", oracle_frame_number, - "frame_number", capture_frame_number, "trigger", - VideoCaptureOracle::EventAsString(event)); // `content_rect` is the region of the `frame` that we would like to populate. // We know our source is of size `source_size`, and we have @@ -890,9 +867,19 @@ // know would not require letterboxing). const gfx::Rect content_rect = GetContentRectangle(frame->visible_rect(), source_size, pixel_format_); - DVLOG(3) << __func__ << ": content_rect=" << content_rect.ToString() - << ", source_size=" << source_size.ToString() - << ", frame=" << frame->AsHumanReadableString(); + TRACE_EVENT_INSTANT2("gpu.capture", "ContentRectDeterminedForCapture", + TRACE_EVENT_SCOPE_THREAD, "content_rect", + content_rect.ToString(), "source_size", + source_size.ToString()); + + // Note: The following is used by + // chrome/browser/media/cast_mirroring_performance_browsertest.cc, in + // addition to the usual runtime tracing + // TODO(https://crbug.com/1322573): change to _NESTABLE_ variant of the macro + // once the bug is fixed. + TRACE_EVENT_ASYNC_BEGIN2("gpu.capture", "Capture", oracle_frame_number, + "frame_number", capture_frame_number, "trigger", + VideoCaptureOracle::EventAsString(event)); // Determine what rectangular region has changed since the last captured // frame. @@ -997,9 +984,15 @@ // that the stream has been successfully uncropped. metadata.crop_version = crop_version_; + // If subtree capture is enabled, we want to provide the actual frame size + // instead of the compositor frame region (which is the entire viewport). + const bool is_subtree_capture = + absl::holds_alternative<SubtreeCaptureId>(target_->sub_target); + const gfx::Rect active_frame_rect = + is_subtree_capture ? capture_region : compositor_frame_region; CaptureRequestProperties request_properties( capture_frame_number, oracle_frame_number, content_version_, content_rect, - capture_region, compositor_frame_region, std::move(frame), + capture_region, active_frame_rect, std::move(frame), base::TimeTicks::Now()); const bool use_nv12_with_textures = @@ -1230,15 +1223,18 @@ DCHECK_LE(result->size().height(), content_rect.height()); if (!frame->HasGpuMemoryBuffer()) { + const VideoCaptureOverlay::CapturedFrameProperties frame_properties{ + properties.active_frame_rect, properties.capture_rect, content_rect, + frame->format()}; + // For GMB-backed video frames, overlays were already applied by // CopyOutputRequest API. For in-memory frames, apply overlays here: auto overlay_renderer = VideoCaptureOverlay::MakeCombinedRenderer( - GetOverlaysInOrder(), - VideoCaptureOverlay::CapturedFrameProperties{ - properties.active_frame_rect, properties.capture_rect, - content_rect, frame->format()}); + GetOverlaysInOrder(), frame_properties); + if (overlay_renderer) { - TRACE_EVENT("gpu.capture", "BlendVideoCaptureOverlays"); + TRACE_EVENT1("gpu.capture", "BlendVideoCaptureOverlays", + "frame_properties", frame_properties.ToString()); std::move(overlay_renderer).Run(frame.get()); } } @@ -1246,12 +1242,6 @@ const gfx::Rect result_rect = gfx::Rect(content_rect.origin(), result->size()); DCHECK(IsCompatibleWithFormat(result_rect, pixel_format_)); - - DVLOG(3) << __func__ << ": result->size()=" << result->size().ToString() - << ", content_rect=" << content_rect.ToString() - << ", result_rect=" << result_rect.ToString() - << ", frame=" << frame->AsHumanReadableString(); - if (frame->visible_rect() != result_rect && !frame->HasGpuMemoryBuffer()) { // If there are parts of the frame that are visible but we have not wrote // into them, letterbox them. This is not needed for GMB-backed frames as
diff --git a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc index 67247bb..c1bb38c 100644 --- a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc +++ b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc
@@ -13,6 +13,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/shared_memory_mapping.h" #include "base/run_loop.h" +#include "base/test/bind.h" #include "base/test/test_mock_time_task_runner.h" #include "base/time/time.h" #include "base/unguessable_token.h" @@ -321,7 +322,7 @@ if (pending_copy_output_request.subtree_capture_id.is_valid()) { EXPECT_EQ(capture_bounds_, request->area()); } else { - EXPECT_EQ(size_set_.source_rect, request->area()); + EXPECT_TRUE(size_set_.source_rect.Contains(request->area())); } EXPECT_EQ(gfx::Rect(size_set_.expected_content_rect.size()), request->result_selection()); @@ -483,6 +484,28 @@ IsLetterboxedPlane(VideoFrame::kVPlane, color.v); } +class TestVideoCaptureOverlay : public VideoCaptureOverlay { + public: + using PropertiesCallback = + base::RepeatingCallback<void(const CapturedFrameProperties&)>; + TestVideoCaptureOverlay( + FrameSource* frame_source, + mojo::PendingReceiver<mojom::FrameSinkVideoCaptureOverlay> receiver, + PropertiesCallback properties_cb) + : VideoCaptureOverlay(frame_source, std::move(receiver)), + properties_cb_(std::move(properties_cb)) {} + ~TestVideoCaptureOverlay() override = default; + + OnceRenderer MakeRenderer( + const CapturedFrameProperties& properties) override { + properties_cb_.Run(properties); + return {}; + } + + private: + PropertiesCallback properties_cb_; +}; + } // namespace class FrameSinkVideoCapturerTest : public testing::Test { @@ -610,6 +633,11 @@ rect); } + void InsertOverlay(std::unique_ptr<VideoCaptureOverlay> overlay) { + capturer_->overlays_.insert_or_assign(capturer_->overlays_.size() + 1, + std::move(overlay)); + } + protected: SizeSet size_set_; scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; @@ -1706,6 +1734,53 @@ EXPECT_FALSE(IsRefreshRetryTimerRunning()); } +TEST_F(FrameSinkVideoCapturerTest, ProperlyHandlesCaptureSizeForOverlay) { + SwitchToSizeSet(kSizeSets[4]); + constexpr gfx::Rect kValidCropBounds{1, 2, 639, 477}; + (kSizeSets[4].source_rect.Contains(kValidCropBounds)); + const auto kCropId = RegionCaptureCropId::CreateRandom(); + + // First, create the overlay. + mojo::Remote<mojom::FrameSinkVideoCaptureOverlay> overlay_remote; + absl::optional<VideoCaptureOverlay::CapturedFrameProperties> frame_properties; + auto test_overlay = std::make_unique<TestVideoCaptureOverlay>( + capturer_.get(), overlay_remote.BindNewPipeAndPassReceiver(), + base::BindLambdaForTesting( + [&](const VideoCaptureOverlay::CapturedFrameProperties& properties) { + frame_properties = properties; + })); + InsertOverlay(std::move(test_overlay)); + + // Change to the appropriate target. + VideoCaptureTarget target(kVideoCaptureTarget.frame_sink_id, kCropId); + frame_sink_.set_crop_bounds(kValidCropBounds); + frame_sink_.SetCopyOutputColor(YUVColor{0x80, 0x80, 0x80}); + EXPECT_CALL(frame_sink_manager_, FindCapturableFrameSink(target)) + .WillRepeatedly(Return(&frame_sink_)); + capturer_->ChangeTarget(std::move(target), /*crop_version=*/0); + + MockConsumer consumer; + EXPECT_CALL(consumer, OnFrameCapturedMock()); + StartCapture(&consumer); + + // With the start, an immediate refresh occurred. Simulate a copy result and + // expect to see the refresh frame delivered to the consumer. + EXPECT_FALSE(IsRefreshRetryTimerRunning()); + + ASSERT_EQ(1, frame_sink_.num_copy_results()); + EXPECT_FALSE(IsRefreshRetryTimerRunning()); + frame_sink_.SendCopyOutputResult(0); + ASSERT_EQ(1, consumer.num_frames_received()); + consumer.SendDoneNotification(0); + + // The overlay should have been rendered with the compositor region using + // the entire frame, which is larger than the sub region. + EXPECT_TRUE(frame_properties) << "didn't produce an overlay."; + EXPECT_EQ(kSizeSets[4].source_rect, frame_properties->compositor_region); + EXPECT_EQ(kValidCropBounds, frame_properties->sub_region); + EXPECT_EQ((gfx::Rect{0, 2, 16, 12}), frame_properties->content_region); +} + TEST_F(FrameSinkVideoCapturerTest, HandlesSubtreeCaptureId) { SwitchToSizeSet(kSizeSets[4]); constexpr gfx::Rect kCaptureBounds{1, 2, 1024, 768}; @@ -1727,6 +1802,52 @@ EXPECT_EQ(kCaptureId, frame_sink_.current_capture_id()); } +TEST_F(FrameSinkVideoCapturerTest, ProperlyHandlesSubtreeSizeForOverlay) { + SwitchToSizeSet(kSizeSets[4]); + constexpr gfx::Rect kCaptureBounds{1, 2, 639, 477}; + constexpr SubtreeCaptureId kCaptureId{1234567u}; + + // First, create the overlay. + mojo::Remote<mojom::FrameSinkVideoCaptureOverlay> overlay_remote; + absl::optional<VideoCaptureOverlay::CapturedFrameProperties> frame_properties; + auto test_overlay = std::make_unique<TestVideoCaptureOverlay>( + capturer_.get(), overlay_remote.BindNewPipeAndPassReceiver(), + base::BindLambdaForTesting( + [&](const VideoCaptureOverlay::CapturedFrameProperties& properties) { + frame_properties = properties; + })); + InsertOverlay(std::move(test_overlay)); + + // Change to the appropriate target. + VideoCaptureTarget target(kVideoCaptureTarget.frame_sink_id, kCaptureId); + frame_sink_.set_capture_bounds(kCaptureBounds); + frame_sink_.SetCopyOutputColor(YUVColor{0x80, 0x80, 0x80}); + EXPECT_CALL(frame_sink_manager_, FindCapturableFrameSink(target)) + .WillRepeatedly(Return(&frame_sink_)); + capturer_->ChangeTarget(std::move(target), /*crop_version=*/0); + + MockConsumer consumer; + EXPECT_CALL(consumer, OnFrameCapturedMock()); + StartCapture(&consumer); + + // With the start, an immediate refresh occurred. Simulate a copy result and + // expect to see the refresh frame delivered to the consumer. + EXPECT_FALSE(IsRefreshRetryTimerRunning()); + + ASSERT_EQ(1, frame_sink_.num_copy_results()); + EXPECT_FALSE(IsRefreshRetryTimerRunning()); + frame_sink_.SendCopyOutputResult(0); + ASSERT_EQ(1, consumer.num_frames_received()); + consumer.SendDoneNotification(0); + + // The overlay should have been rendered with the content and compositor + // regions set to the same value. + EXPECT_TRUE(frame_properties) << "didn't produce an overlay."; + EXPECT_EQ(kCaptureBounds, frame_properties->compositor_region); + EXPECT_EQ(kCaptureBounds, frame_properties->sub_region); + EXPECT_EQ((gfx::Rect{0, 2, 16, 12}), frame_properties->content_region); +} + TEST_F(FrameSinkVideoCapturerTest, HandlesNullSubTargetPtrCorrectly) { SwitchToSizeSet(kSizeSets[4]); EXPECT_CALL(frame_sink_manager_, FindCapturableFrameSink(kVideoCaptureTarget))
diff --git a/components/viz/service/frame_sinks/video_capture/video_capture_overlay.h b/components/viz/service/frame_sinks/video_capture/video_capture_overlay.h index 2150818..551691f 100644 --- a/components/viz/service/frame_sinks/video_capture/video_capture_overlay.h +++ b/components/viz/service/frame_sinks/video_capture/video_capture_overlay.h
@@ -49,7 +49,7 @@ // // The blit algorithm uses naive linear blending. Thus, the use of non-linear // color spaces will cause losses in color accuracy. -class VIZ_SERVICE_EXPORT VideoCaptureOverlay final +class VIZ_SERVICE_EXPORT VideoCaptureOverlay : public mojom::FrameSinkVideoCaptureOverlay { public: // Interface for notifying the frame source when changes to the overlay's @@ -89,7 +89,7 @@ VideoCaptureOverlay(const VideoCaptureOverlay&) = delete; VideoCaptureOverlay& operator=(const VideoCaptureOverlay&) = delete; - ~VideoCaptureOverlay() final; + ~VideoCaptureOverlay() override; // mojom::FrameSinkVideoCaptureOverlay implementation: void SetImageAndBounds(const SkBitmap& image, const gfx::RectF& bounds) final; @@ -122,7 +122,7 @@ // a VideoFrame. The overlay's position and size are computed based on the // given content |region_in_frame|. Returns a null OnceCallback if there is // nothing to render at this time. - OnceRenderer MakeRenderer(const CapturedFrameProperties& properties); + virtual OnceRenderer MakeRenderer(const CapturedFrameProperties& properties); struct BlendInformation { // Source region that we will blend from, expressed in the coordinate system
diff --git a/components/webapps/browser/banners/app_banner_manager.cc b/components/webapps/browser/banners/app_banner_manager.cc index 5e0565f..dfab321 100644 --- a/components/webapps/browser/banners/app_banner_manager.cc +++ b/components/webapps/browser/banners/app_banner_manager.cc
@@ -334,6 +334,7 @@ case State::INACTIVE: case State::ACTIVE: case State::FETCHING_NATIVE_DATA: + case State::PENDING_WORKER: case State::PENDING_ENGAGEMENT: case State::SENDING_EVENT: case State::SENDING_EVENT_GOT_EARLY_PROMPT: @@ -367,9 +368,15 @@ InstallableParams params; params.valid_primary_icon = true; params.valid_manifest = true; + params.fetch_screenshots = true; + + return params; +} + +InstallableParams AppBannerManager::ParamsToPerformWorkerCheck() { + InstallableParams params; params.has_worker = true; params.wait_for_worker = true; - params.fetch_screenshots = true; return params; } @@ -396,30 +403,11 @@ return; UpdateState(State::ACTIVE); - if (data.worker_check_passed && data.valid_manifest) + if (data.valid_manifest) TrackDisplayEvent(DISPLAY_EVENT_WEB_APP_BANNER_REQUESTED); - bool no_matching_service_worker = - base::Contains(data.errors, NO_MATCHING_SERVICE_WORKER); - if (no_matching_service_worker) { - TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER); - } - bool is_installable = data.NoBlockingErrors(); - // When |features::SkipInstallServiceWorkerCheck| is true, a service worker is - // still required to display the banner prompt. This would mean that while a - // banner may not appear, the site is still considered installable if it only - // failed service worker checks. - bool worker_errors_ignored_for_installs = false; - if (features::SkipInstallServiceWorkerCheck() && - data.HasErrorOnlyServiceWorkerErrors()) { - DCHECK(!is_installable || base::FeatureList::IsEnabled( - features::kCreateShortcutIgnoresManifest)); - worker_errors_ignored_for_installs = true; - is_installable = true; - } - if (!is_installable) { DCHECK(!data.errors.empty()); SetInstallableWebAppCheckResult(InstallableWebAppCheckResult::kNo); @@ -442,27 +430,7 @@ return; } - if (worker_errors_ignored_for_installs) { - DCHECK(data.HasErrorOnlyServiceWorkerErrors()); - - SetInstallableWebAppCheckResult( - InstallableWebAppCheckResult::kYes_ByUserRequest); - Stop(SERVICE_WORKER_NOT_REQUIRED); - return; - } - - if (no_matching_service_worker && - base::FeatureList::IsEnabled(features::kCreateShortcutIgnoresManifest)) { - SetInstallableWebAppCheckResult( - InstallableWebAppCheckResult::kYes_ByUserRequest); - Stop(NO_MATCHING_SERVICE_WORKER); - return; - } - - SetInstallableWebAppCheckResult( - InstallableWebAppCheckResult::kYes_Promotable); - - DCHECK(data.worker_check_passed && data.valid_manifest); + DCHECK(data.valid_manifest); DCHECK(!data.primary_icon_url.is_empty()); DCHECK(data.primary_icon); @@ -470,16 +438,49 @@ primary_icon_ = *data.primary_icon; has_maskable_primary_icon_ = data.has_maskable_primary_icon; screenshots_ = data.screenshots; - // If we triggered the installability check on page load, then it's possible - // we don't have enough engagement yet. If that's the case, return here but - // don't call Terminate(). We wait for OnEngagementEvent to tell us that we - // should trigger. - if (!HasSufficientEngagement()) { - UpdateState(State::PENDING_ENGAGEMENT); + + if (features::SkipInstallServiceWorkerCheck() || + base::FeatureList::IsEnabled(features::kCreateShortcutIgnoresManifest)) { + SetInstallableWebAppCheckResult( + InstallableWebAppCheckResult::kYes_ByUserRequest); + } + + PerformServiceWorkerCheck(); +} + +void AppBannerManager::PerformServiceWorkerCheck() { + UpdateState(State::PENDING_WORKER); + manager_->GetData( + ParamsToPerformWorkerCheck(), + base::BindOnce(&AppBannerManager::OnDidPerformWorkerCheck, GetWeakPtr())); +} + +void AppBannerManager::OnDidPerformWorkerCheck(const InstallableData& data) { + if (!data.NoBlockingErrors()) { + TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER); + Stop(data.FirstNoBlockingError()); return; } - SendBannerPromptRequest(); + passed_worker_check_ = true; + + if (state_ == State::PENDING_WORKER) { + UpdateState(State::ACTIVE); + + SetInstallableWebAppCheckResult( + InstallableWebAppCheckResult::kYes_Promotable); + + // If we triggered the installability check on page load, then it's + // possible we don't have enough engagement yet. If that's the case, + // return here but don't call Terminate(). We wait for OnEngagementEvent + // to tell us that we should trigger. + if (!HasSufficientEngagement()) { + UpdateState(State::PENDING_ENGAGEMENT); + return; + } + + SendBannerPromptRequest(); + } } void AppBannerManager::RecordDidShowBanner() { @@ -521,6 +522,9 @@ BEFORE_INSTALL_EVENT_PROMPT_NOT_CALLED_AFTER_PREVENT_DEFAULT); } + if (state_ == State::PENDING_WORKER && !passed_worker_check_) + TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER); + if (state_ == State::PENDING_ENGAGEMENT && !has_sufficient_engagement_) TrackDisplayEvent(DISPLAY_EVENT_NOT_VISITED_ENOUGH); @@ -531,6 +535,9 @@ switch (state_) { case State::PENDING_PROMPT: return RENDERER_CANCELLED; + case State::PENDING_WORKER: + return passed_worker_check_ ? NO_ERROR_DETECTED + : NO_MATCHING_SERVICE_WORKER; case State::PENDING_ENGAGEMENT: return has_sufficient_engagement_ ? NO_ERROR_DETECTED : INSUFFICIENT_ENGAGEMENT; @@ -729,6 +736,7 @@ return; case State::ACTIVE: case State::FETCHING_NATIVE_DATA: + case State::PENDING_WORKER: case State::PENDING_ENGAGEMENT: case State::SENDING_EVENT: case State::SENDING_EVENT_GOT_EARLY_PROMPT: @@ -801,6 +809,7 @@ case State::FETCHING_MANIFEST: case State::FETCHING_NATIVE_DATA: case State::PENDING_INSTALLABLE_CHECK: + case State::PENDING_WORKER: case State::SENDING_EVENT: case State::SENDING_EVENT_GOT_EARLY_PROMPT: return true;
diff --git a/components/webapps/browser/banners/app_banner_manager.h b/components/webapps/browser/banners/app_banner_manager.h index 1bb4249..688d9512 100644 --- a/components/webapps/browser/banners/app_banner_manager.h +++ b/components/webapps/browser/banners/app_banner_manager.h
@@ -84,6 +84,9 @@ // engagement to trigger the banner. PENDING_ENGAGEMENT, + // The pipeline is waiting for service worker install to trigger the banner. + PENDING_WORKER, + // The beforeinstallprompt event has been sent and the pipeline is waiting // for the response. SENDING_EVENT, @@ -277,6 +280,10 @@ // necessary for a web app banner. virtual InstallableParams ParamsToPerformInstallableWebAppCheck(); + // Returns an InstallableParams object that requests service worker check + // only. + virtual InstallableParams ParamsToPerformWorkerCheck(); + // Run at the conclusion of OnDidGetManifest. For web app banners, this calls // back to the InstallableManager to continue checking criteria. For native // app banners, this checks whether native apps are preferred in the manifest, @@ -290,6 +297,15 @@ // all other installable properties. virtual void OnDidPerformInstallableWebAppCheck(const InstallableData& data); + // Run at the conclusion of OnDidPerformInstallableWebAppCheck. This calls + // back to the InstallableManager to continue checking service worker criteria + // for web app banners. + virtual void PerformServiceWorkerCheck(); + + // Callback invoked by the InstallableManager once it has finished checking + // service worker. + virtual void OnDidPerformWorkerCheck(const InstallableData& data); + // Records that a banner was shown. void RecordDidShowBanner(); @@ -430,6 +446,8 @@ bool has_sufficient_engagement_ = false; bool load_finished_ = false; + bool passed_worker_check_ = false; + std::unique_ptr<StatusReporter> status_reporter_; bool install_animation_pending_ = false; InstallableWebAppCheckResult installable_web_app_check_result_ =
diff --git a/components/webapps/browser/installable/installable_data.cc b/components/webapps/browser/installable/installable_data.cc index dbc4865..e00e0a5 100644 --- a/components/webapps/browser/installable/installable_data.cc +++ b/components/webapps/browser/installable/installable_data.cc
@@ -49,6 +49,10 @@ InstallableData::~InstallableData() = default; bool InstallableData::NoBlockingErrors() const { + return FirstNoBlockingError() == NO_ERROR_DETECTED; +} + +InstallableStatusCode InstallableData::FirstNoBlockingError() const { for (auto e : errors) { switch (e) { case WARN_NOT_OFFLINE_CAPABLE: @@ -60,12 +64,12 @@ continue; } #endif - return false; + [[fallthrough]]; default: - return false; + return e; } } - return true; + return NO_ERROR_DETECTED; } bool InstallableData::HasErrorOnlyServiceWorkerErrors() const {
diff --git a/components/webapps/browser/installable/installable_data.h b/components/webapps/browser/installable/installable_data.h index 543f127..498f5dd 100644 --- a/components/webapps/browser/installable/installable_data.h +++ b/components/webapps/browser/installable/installable_data.h
@@ -66,6 +66,10 @@ // M93. bool NoBlockingErrors() const; + // Returns the first no blocking error if any one exist. Otherwise returns + // NO_ERROR_DETECTED. + InstallableStatusCode FirstNoBlockingError() const; + // Returns true if there is any |errors| and all errors are service worker // errors, i.e.|NO_MATCHING_SERVICE_WORKER| or |NOT_OFFLINE_CAPABLE|. bool HasErrorOnlyServiceWorkerErrors() const;
diff --git a/components/webcrypto/algorithms/ecdsa.cc b/components/webcrypto/algorithms/ecdsa.cc index 24038fb..d525dfe 100644 --- a/components/webcrypto/algorithms/ecdsa.cc +++ b/components/webcrypto/algorithms/ecdsa.cc
@@ -190,20 +190,22 @@ if (status.IsError()) return status; - // NOTE: A call to EVP_DigestSignFinal() with a NULL second parameter - // returns a maximum allocation size, while the call without a NULL returns - // the real one, which may be smaller. + // NOTE: A call to EVP_DigestSign() with a NULL second parameter returns a + // maximum allocation size, while the call without a NULL returns the real + // one, which may be smaller. bssl::ScopedEVP_MD_CTX ctx; size_t sig_len = 0; if (!EVP_DigestSignInit(ctx.get(), nullptr, digest, nullptr, private_key) || - !EVP_DigestSignUpdate(ctx.get(), data.data(), data.size()) || - !EVP_DigestSignFinal(ctx.get(), nullptr, &sig_len)) { + !EVP_DigestSign(ctx.get(), nullptr, &sig_len, data.data(), + data.size())) { return Status::OperationError(); } buffer->resize(sig_len); - if (!EVP_DigestSignFinal(ctx.get(), buffer->data(), &sig_len)) + if (!EVP_DigestSign(ctx.get(), buffer->data(), &sig_len, data.data(), + data.size())) { return Status::OperationError(); + } buffer->resize(sig_len); // ECDSA signing in BoringSSL outputs a DER-encoded (r,s). WebCrypto however @@ -242,14 +244,13 @@ bssl::ScopedEVP_MD_CTX ctx; if (!EVP_DigestVerifyInit(ctx.get(), nullptr, digest, nullptr, - public_key) || - !EVP_DigestVerifyUpdate(ctx.get(), data.data(), data.size())) { + public_key)) { return Status::OperationError(); } *signature_match = - 1 == EVP_DigestVerifyFinal(ctx.get(), der_signature.data(), - der_signature.size()); + 1 == EVP_DigestVerify(ctx.get(), der_signature.data(), + der_signature.size(), data.data(), data.size()); return Status::Success(); } };
diff --git a/components/webcrypto/algorithms/rsa_sign.cc b/components/webcrypto/algorithms/rsa_sign.cc index d4e929f..1608108e 100644 --- a/components/webcrypto/algorithms/rsa_sign.cc +++ b/components/webcrypto/algorithms/rsa_sign.cc
@@ -76,8 +76,6 @@ return Status::ErrorUnexpectedKeyType(); crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); - bssl::ScopedEVP_MD_CTX ctx; - EVP_PKEY_CTX* pctx = nullptr; // Owned by |ctx|. EVP_PKEY* private_key = nullptr; const EVP_MD* digest = nullptr; @@ -85,9 +83,11 @@ if (status.IsError()) return status; - // NOTE: A call to EVP_DigestSignFinal() with a NULL second parameter - // returns a maximum allocation size, while the call without a NULL returns - // the real one, which may be smaller. + // NOTE: A call to EVP_DigestSign() with a NULL second parameter returns a + // maximum allocation size, while the call without a NULL returns the real + // one, which may be smaller. + bssl::ScopedEVP_MD_CTX ctx; + EVP_PKEY_CTX* pctx = nullptr; // Owned by |ctx|. size_t sig_len = 0; if (!EVP_DigestSignInit(ctx.get(), &pctx, digest, nullptr, private_key)) { return Status::OperationError(); @@ -98,14 +98,15 @@ if (status.IsError()) return status; - if (!EVP_DigestSignUpdate(ctx.get(), data.data(), data.size()) || - !EVP_DigestSignFinal(ctx.get(), nullptr, &sig_len)) { + if (!EVP_DigestSign(ctx.get(), nullptr, &sig_len, data.data(), data.size())) { return Status::OperationError(); } buffer->resize(sig_len); - if (!EVP_DigestSignFinal(ctx.get(), buffer->data(), &sig_len)) + if (!EVP_DigestSign(ctx.get(), buffer->data(), &sig_len, data.data(), + data.size())) { return Status::OperationError(); + } buffer->resize(sig_len); return Status::Success(); @@ -120,8 +121,6 @@ return Status::ErrorUnexpectedKeyType(); crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); - bssl::ScopedEVP_MD_CTX ctx; - EVP_PKEY_CTX* pctx = nullptr; // Owned by |ctx|. EVP_PKEY* public_key = nullptr; const EVP_MD* digest = nullptr; @@ -129,6 +128,8 @@ if (status.IsError()) return status; + bssl::ScopedEVP_MD_CTX ctx; + EVP_PKEY_CTX* pctx = nullptr; // Owned by |ctx|. if (!EVP_DigestVerifyInit(ctx.get(), &pctx, digest, nullptr, public_key)) return Status::OperationError(); @@ -137,11 +138,9 @@ if (status.IsError()) return status; - if (!EVP_DigestVerifyUpdate(ctx.get(), data.data(), data.size())) - return Status::OperationError(); - *signature_match = - 1 == EVP_DigestVerifyFinal(ctx.get(), signature.data(), signature.size()); + 1 == EVP_DigestVerify(ctx.get(), signature.data(), signature.size(), + data.data(), data.size()); return Status::Success(); }
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc index e2f53860..6965f86 100644 --- a/content/app/content_main_runner_impl.cc +++ b/content/app/content_main_runner_impl.cc
@@ -853,7 +853,6 @@ delegate_->BasicStartupComplete(); if (basic_startup_exit_code.has_value()) return basic_startup_exit_code.value(); - completed_basic_startup_ = true; const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); @@ -1249,14 +1248,11 @@ mojo_ipc_support_.reset(); - if (completed_basic_startup_) { - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - std::string process_type = - command_line.GetSwitchValueASCII(switches::kProcessType); - - delegate_->ProcessExiting(process_type); - } + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + std::string process_type = + command_line.GetSwitchValueASCII(switches::kProcessType); + delegate_->ProcessExiting(process_type); // The BrowserTaskExecutor needs to be destroyed before |exit_manager_|. BrowserTaskExecutor::Shutdown();
diff --git a/content/app/content_main_runner_impl.h b/content/app/content_main_runner_impl.h index 9dda5702..c96e733 100644 --- a/content/app/content_main_runner_impl.h +++ b/content/app/content_main_runner_impl.h
@@ -69,9 +69,6 @@ // True if the runner has been shut down. bool is_shutdown_ = false; - // True if basic startup was completed. - bool completed_basic_startup_ = false; - // The delegate will outlive this object. raw_ptr<ContentMainDelegate> delegate_ = nullptr;
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.h b/content/browser/accessibility/browser_accessibility_cocoa.h index 0676f51..41107c2 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.h +++ b/content/browser/accessibility/browser_accessibility_cocoa.h
@@ -103,7 +103,6 @@ - (NSString*)methodNameForAttribute:(NSString*)attribute; - (NSString*)valueForRange:(NSRange)range; -- (NSAttributedString*)attributedValueForRange:(NSRange)range; - (NSRect)frameForRange:(NSRange)range; // Find the index of the given row among the descendants of this object
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index 1cabcad..55cce7f 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -113,9 +113,6 @@ NSString* const NSAccessibilityBoundsForTextMarkerRangeParameterizedAttribute = @"AXBoundsForTextMarkerRange"; NSString* const - NSAccessibilityAttributedStringForTextMarkerRangeParameterizedAttribute = - @"AXAttributedStringForTextMarkerRange"; -NSString* const NSAccessibilityAttributedStringForTextMarkerRangeWithOptionsParameterizedAttribute = @"AXAttributedStringForTextMarkerRangeWithOptions"; NSString* const @@ -271,51 +268,6 @@ *focus_object, focus_offset, focus_affinity); } -void AddMisspelledTextAttributes(const AXRange& ax_range, - NSMutableAttributedString* attributed_string) { - int anchor_start_offset = 0; - [attributed_string beginEditing]; - for (const AXRange& leaf_text_range : ax_range) { - DCHECK(!leaf_text_range.IsNull()); - DCHECK_EQ(leaf_text_range.anchor()->GetAnchor(), - leaf_text_range.focus()->GetAnchor()) - << "An anchor range should only span a single object."; - - auto* manager = - BrowserAccessibilityManager::FromID(leaf_text_range.focus()->tree_id()); - DCHECK(manager) << "A non-null position should have an associated AX tree."; - const BrowserAccessibility* anchor = - manager->GetFromID(leaf_text_range.focus()->anchor_id()); - DCHECK(anchor) << "A non-null position should have a non-null anchor node."; - const std::vector<int32_t>& marker_types = - anchor->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerTypes); - const std::vector<int>& marker_starts = - anchor->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerStarts); - const std::vector<int>& marker_ends = - anchor->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerEnds); - for (size_t i = 0; i < marker_types.size(); ++i) { - if (!(marker_types[i] & - static_cast<int32_t>(ax::mojom::MarkerType::kSpelling))) { - continue; - } - - int misspelling_start = anchor_start_offset + marker_starts[i]; - int misspelling_end = anchor_start_offset + marker_ends[i]; - int misspelling_length = misspelling_end - misspelling_start; - DCHECK_LE(static_cast<unsigned long>(misspelling_end), - [attributed_string length]); - DCHECK_GT(misspelling_length, 0); - [attributed_string - addAttribute:NSAccessibilityMarkedMisspelledTextAttribute - value:@YES - range:NSMakeRange(misspelling_start, misspelling_length)]; - } - - anchor_start_offset += leaf_text_range.GetText().length(); - } - [attributed_string endEditing]; -} - NSString* GetTextForTextMarkerRange(id marker_range) { AXRange range = AXTextMarkerRangeToAXRange(marker_range); if (range.IsNull()) @@ -323,23 +275,6 @@ return base::SysUTF16ToNSString(range.GetText()); } -NSAttributedString* GetAttributedTextForTextMarkerRange(id marker_range) { - AXRange ax_range = AXTextMarkerRangeToAXRange(marker_range); - if (ax_range.IsNull()) - return nil; - - NSString* text = base::SysUTF16ToNSString(ax_range.GetText()); - if ([text length] == 0) - return nil; - - NSMutableAttributedString* attributed_text = - [[[NSMutableAttributedString alloc] initWithString:text] autorelease]; - // Currently, we only decorate the attributed string with misspelling - // information. - AddMisspelledTextAttributes(ax_range, attributed_text); - return attributed_text; -} - // GetState checks the bitmask used in AXNodeData to check // if the given state was set on the accessibility object. bool GetState(BrowserAccessibility* accessibility, ax::mojom::State state) { @@ -1694,32 +1629,6 @@ textContent.substr(range.location, range.length)); } -// Retrieves the text inside this object and decorates it with attributes -// indicating specific ranges of interest within the text, e.g. the location of -// misspellings. -- (NSAttributedString*)attributedValueForRange:(NSRange)range { - if (![self instanceActive]) - return nil; - - std::u16string textContent = _owner->GetTextContentUTF16(); - if (NSMaxRange(range) > textContent.length()) - return nil; - - // We potentially need to add text attributes to the whole text content - // because a spelling mistake might start or end outside the given range. - NSMutableAttributedString* attributedTextContent = - [[[NSMutableAttributedString alloc] - initWithString:base::SysUTF16ToNSString(textContent)] autorelease]; - if (!_owner->IsText()) { - AXRange ax_range( - _owner->CreateTextPositionAt(0), - _owner->CreateTextPositionAt(static_cast<int>(textContent.length()))); - AddMisspelledTextAttributes(ax_range, attributedTextContent); - } - - return [attributedTextContent attributedSubstringFromRange:range]; -} - - (NSRect)frameForRange:(NSRange)range { if (!_owner->IsText() && !_owner->IsAtomicTextField()) return CGRectNull; @@ -1750,11 +1659,6 @@ return [self valueForRange:[(NSValue*)parameter rangeValue]]; } -- (id)AXAttributedStringForRange:(id)parameter { - DCHECK([parameter isKindOfClass:[NSValue class]]); - return [self attributedValueForRange:[(NSValue*)parameter rangeValue]]; -} - - (id)AXLineForIndex:(id)parameter { DCHECK([parameter isKindOfClass:[NSNumber class]]); int lineIndex = [(NSNumber*)parameter intValue]; @@ -1813,12 +1717,6 @@ } if ([attribute - isEqualToString: - NSAccessibilityAttributedStringForRangeParameterizedAttribute]) { - return [self AXAttributedStringForRange:parameter]; - } - - if ([attribute isEqualToString:NSAccessibilityLineForIndexParameterizedAttribute]) { return [self AXLineForIndex:parameter]; } @@ -1888,11 +1786,6 @@ if ([attribute isEqualToString: - NSAccessibilityAttributedStringForTextMarkerRangeParameterizedAttribute]) - return GetAttributedTextForTextMarkerRange(parameter); - - if ([attribute - isEqualToString: NSAccessibilityNextTextMarkerForTextMarkerParameterizedAttribute]) { AXPosition position = AXTextMarkerToAXPosition(parameter); if (position->IsNullPosition()) @@ -2341,7 +2234,7 @@ return @(child->GetIndexInParent().value()); } - return nil; + return [super accessibilityAttributeValue:attribute forParameter:parameter]; } // Returns an array of parameterized attributes names that this object will @@ -2364,7 +2257,6 @@ NSAccessibilityStringForTextMarkerRangeParameterizedAttribute, NSAccessibilityTextMarkerForPositionParameterizedAttribute, NSAccessibilityBoundsForTextMarkerRangeParameterizedAttribute, - NSAccessibilityAttributedStringForTextMarkerRangeParameterizedAttribute, NSAccessibilityAttributedStringForTextMarkerRangeWithOptionsParameterizedAttribute, NSAccessibilityTextMarkerRangeForUnorderedTextMarkersParameterizedAttribute, NSAccessibilityNextTextMarkerForTextMarkerParameterizedAttribute, @@ -2409,7 +2301,6 @@ NSAccessibilityRangeForIndexParameterizedAttribute, NSAccessibilityBoundsForRangeParameterizedAttribute, NSAccessibilityRTFForRangeParameterizedAttribute, - NSAccessibilityAttributedStringForRangeParameterizedAttribute, NSAccessibilityStyleRangeForIndexParameterizedAttribute ]]; } @@ -2425,6 +2316,8 @@ ]]; } + NSArray* super_ret = [super accessibilityParameterizedAttributeNames]; + [ret addObjectsFromArray:super_ret]; return ret; }
diff --git a/content/browser/accessibility/browser_accessibility_manager_auralinux.h b/content/browser/accessibility/browser_accessibility_manager_auralinux.h index c0e8b0e8..ed15ad2 100644 --- a/content/browser/accessibility/browser_accessibility_manager_auralinux.h +++ b/content/browser/accessibility/browser_accessibility_manager_auralinux.h
@@ -10,7 +10,6 @@ #include "base/gtest_prod_util.h" #include "base/memory/raw_ptr.h" #include "content/browser/accessibility/browser_accessibility_manager.h" -#include "content/browser/accessibility/browser_accessibility_manager_android.h" #include "content/common/content_export.h" namespace content {
diff --git a/content/browser/aggregation_service/aggregatable_report_scheduler.cc b/content/browser/aggregation_service/aggregatable_report_scheduler.cc index b64fb17..a27c918 100644 --- a/content/browser/aggregation_service/aggregatable_report_scheduler.cc +++ b/content/browser/aggregation_service/aggregatable_report_scheduler.cc
@@ -86,7 +86,7 @@ std::move(on_scheduled_report_time_reached)), should_not_delay_reports_( base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kPrivateAggregationDebugMode)) { + switches::kPrivateAggregationDeveloperMode)) { DCHECK(storage_context); } AggregatableReportScheduler::TimerDelegate::~TimerDelegate() = default;
diff --git a/content/browser/aggregation_service/aggregatable_report_scheduler.h b/content/browser/aggregation_service/aggregatable_report_scheduler.h index 55702b1..c61bd25a 100644 --- a/content/browser/aggregation_service/aggregatable_report_scheduler.h +++ b/content/browser/aggregation_service/aggregatable_report_scheduler.h
@@ -129,7 +129,7 @@ // the typical size. std::set<AggregationServiceStorage::RequestId> in_progress_requests_; - // Set iff the private aggregation debug mode is set. + // Set iff the private aggregation developer mode is enabled. bool should_not_delay_reports_; base::WeakPtrFactory<AggregatableReportScheduler::TimerDelegate>
diff --git a/content/browser/aggregation_service/aggregatable_report_scheduler_unittest.cc b/content/browser/aggregation_service/aggregatable_report_scheduler_unittest.cc index 73cdcbe1..0c93a82 100644 --- a/content/browser/aggregation_service/aggregatable_report_scheduler_unittest.cc +++ b/content/browser/aggregation_service/aggregatable_report_scheduler_unittest.cc
@@ -525,16 +525,16 @@ task_environment_.FastForwardBy(kExampleTime - base::Time::Now()); } -class AggregatableReportSchedulerDebugModeTest +class AggregatableReportSchedulerDeveloperModeTest : public AggregatableReportSchedulerTest { public: - AggregatableReportSchedulerDebugModeTest() { + AggregatableReportSchedulerDeveloperModeTest() { base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kPrivateAggregationDebugMode); + switches::kPrivateAggregationDeveloperMode); } }; -TEST_F(AggregatableReportSchedulerDebugModeTest, +TEST_F(AggregatableReportSchedulerDeveloperModeTest, NetworkOffline_ReportsAreSentImmediatelyWhenOnline) { network::TestNetworkConnectionTracker::GetInstance()->SetConnectionType( network::mojom::ConnectionType::CONNECTION_NONE); // Offline @@ -571,8 +571,8 @@ network::TestNetworkConnectionTracker::GetInstance()->SetConnectionType( network::mojom::ConnectionType::CONNECTION_UNKNOWN); // Online - // With the debug mode flag, the report should not be delayed, so all we need - // to do is run any pending tasks. + // With the developer mode flag, the report should be sent immediately, so all + // we need to do is run any pending tasks. task_environment_.RunUntilIdle(); }
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.cc b/content/browser/devtools/devtools_url_loader_interceptor.cc index 421d9858..f19138f9 100644 --- a/content/browser/devtools/devtools_url_loader_interceptor.cc +++ b/content/browser/devtools/devtools_url_loader_interceptor.cc
@@ -14,6 +14,7 @@ #include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "base/time/time.h" +#include "base/trace_event/trace_event.h" #include "base/unguessable_token.h" #include "content/browser/devtools/protocol/network.h" #include "content/browser/devtools/protocol/network_handler.h" @@ -876,6 +877,7 @@ if (state_ == State::kAuthRequired) { state_ = State::kRequestSent; waiting_for_resolution_ = false; + TRACE_EVENT_NESTABLE_ASYNC_END0("devtools", "Fetch.requestPaused", this); std::move(pending_auth_callback_).Run(true, absl::nullopt); return; } @@ -889,7 +891,7 @@ "Invalid state for continueInterceptedRequest"); } waiting_for_resolution_ = false; - + TRACE_EVENT_NESTABLE_ASYNC_END0("devtools", "Fetch.requestPaused", this); if (modifications->intercept_response.isJust()) { if (modifications->intercept_response.fromJust()) { if (stage_ == InterceptionStage::REQUEST) @@ -1384,6 +1386,7 @@ protocol::NetworkHandler::CreateRequestFromResourceRequest( create_loader_params_->request, cookie_line); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("devtools", "Fetch.requestPaused", this); waiting_for_resolution_ = true; interceptor_->request_intercepted_callback_.Run(std::move(request_info)); }
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc index f4d3331d..f0e04f7 100644 --- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc +++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -3514,8 +3514,8 @@ const base::Value* sans = response.FindByDottedPath("response.securityDetails.sanList"); ASSERT_TRUE(sans); - ASSERT_EQ(1u, sans->GetListDeprecated().size()); - EXPECT_EQ(base::Value("127.0.0.1"), sans->GetListDeprecated()[0]); + ASSERT_EQ(1u, sans->GetList().size()); + EXPECT_EQ(base::Value("127.0.0.1"), sans->GetList()[0]); absl::optional<double> valid_from = response.FindDoubleByDottedPath("response.securityDetails.validFrom"); @@ -3652,13 +3652,13 @@ const base::Value* sans = response.FindByDottedPath("response.securityDetails.sanList"); ASSERT_TRUE(sans); - ASSERT_EQ(6u, sans->GetListDeprecated().size()); - EXPECT_EQ(base::Value("a.example"), sans->GetListDeprecated()[0]); - EXPECT_EQ(base::Value("b.example"), sans->GetListDeprecated()[1]); - EXPECT_EQ(base::Value("*.c.example"), sans->GetListDeprecated()[2]); - EXPECT_EQ(base::Value("127.0.0.1"), sans->GetListDeprecated()[3]); - EXPECT_EQ(base::Value("::1"), sans->GetListDeprecated()[4]); - EXPECT_EQ(base::Value("1.2.3.4"), sans->GetListDeprecated()[5]); + ASSERT_EQ(6u, sans->GetList().size()); + EXPECT_EQ(base::Value("a.example"), sans->GetList()[0]); + EXPECT_EQ(base::Value("b.example"), sans->GetList()[1]); + EXPECT_EQ(base::Value("*.c.example"), sans->GetList()[2]); + EXPECT_EQ(base::Value("127.0.0.1"), sans->GetList()[3]); + EXPECT_EQ(base::Value("::1"), sans->GetList()[4]); + EXPECT_EQ(base::Value("1.2.3.4"), sans->GetList()[5]); } class NetworkResponseProtocolECHTest : public NetworkResponseProtocolTest {
diff --git a/content/browser/devtools/protocol/tracing_handler.cc b/content/browser/devtools/protocol/tracing_handler.cc index f9239b5..a9b59a2 100644 --- a/content/browser/devtools/protocol/tracing_handler.cc +++ b/content/browser/devtools/protocol/tracing_handler.cc
@@ -100,7 +100,7 @@ if (value.is_list()) { base::Value out(base::Value::Type::LIST); - for (const auto& v : value.GetListDeprecated()) + for (const auto& v : value.GetList()) out.Append(ConvertDictKeyStyle(v)); return out; }
diff --git a/content/browser/devtools/web_contents_devtools_agent_host.cc b/content/browser/devtools/web_contents_devtools_agent_host.cc index 355496d..20976a4 100644 --- a/content/browser/devtools/web_contents_devtools_agent_host.cc +++ b/content/browser/devtools/web_contents_devtools_agent_host.cc
@@ -56,8 +56,10 @@ return; base::flat_set<scoped_refptr<DevToolsAgentHost>> pages = UpdateAssociatedPages(); - for (auto& page : pages) - DispatchTargetInfoChanged(page.get()); + if (update_target_info) { + for (auto& page : pages) + DispatchTargetInfoChanged(page.get()); + } } void WillInitiatePrerender(FrameTreeNode* ftn) {
diff --git a/content/browser/media/media_internals_unittest.cc b/content/browser/media/media_internals_unittest.cc index 2ea1f0f..9efaac40 100644 --- a/content/browser/media/media_internals_unittest.cc +++ b/content/browser/media/media_internals_unittest.cc
@@ -425,9 +425,9 @@ // Check JSON is what we expect. { base::Value found_sessions = GetSessionsFromValueAndReset(); - EXPECT_EQ(1u, found_sessions.GetListDeprecated().size()); + EXPECT_EQ(1u, found_sessions.GetList().size()); - const base::Value& session = found_sessions.GetListDeprecated()[0]; + const base::Value& session = found_sessions.GetList()[0]; EXPECT_EQ(base::Value(request_id1), *session.FindKey("id")); EXPECT_TRUE(session.FindKeyOfType("name", base::Value::Type::STRING)); EXPECT_TRUE(session.FindKeyOfType("owner", base::Value::Type::STRING)); @@ -449,15 +449,15 @@ // Check JSON is what we expect. { base::Value found_sessions = GetSessionsFromValueAndReset(); - EXPECT_EQ(2u, found_sessions.GetListDeprecated().size()); + EXPECT_EQ(2u, found_sessions.GetList().size()); - const base::Value& session1 = found_sessions.GetListDeprecated()[0]; + const base::Value& session1 = found_sessions.GetList()[0]; EXPECT_EQ(base::Value(request_id2), *session1.FindKey("id")); EXPECT_TRUE(session1.FindKeyOfType("name", base::Value::Type::STRING)); EXPECT_TRUE(session1.FindKeyOfType("owner", base::Value::Type::STRING)); EXPECT_TRUE(session1.FindKeyOfType("state", base::Value::Type::STRING)); - const base::Value& session2 = found_sessions.GetListDeprecated()[1]; + const base::Value& session2 = found_sessions.GetList()[1]; EXPECT_EQ(base::Value(request_id1), *session2.FindKey("id")); EXPECT_TRUE(session2.FindKeyOfType("name", base::Value::Type::STRING)); EXPECT_TRUE(session2.FindKeyOfType("owner", base::Value::Type::STRING)); @@ -471,9 +471,9 @@ // Check JSON is what we expect. { base::Value found_sessions = GetSessionsFromValueAndReset(); - EXPECT_EQ(1u, found_sessions.GetListDeprecated().size()); + EXPECT_EQ(1u, found_sessions.GetList().size()); - const base::Value& session = found_sessions.GetListDeprecated()[0]; + const base::Value& session = found_sessions.GetList()[0]; EXPECT_EQ(base::Value(request_id1), *session.FindKey("id")); EXPECT_TRUE(session.FindKeyOfType("name", base::Value::Type::STRING)); EXPECT_TRUE(session.FindKeyOfType("owner", base::Value::Type::STRING)); @@ -491,7 +491,7 @@ // Check JSON is what we expect. { base::Value found_sessions = GetSessionsFromValueAndReset(); - EXPECT_EQ(0u, found_sessions.GetListDeprecated().size()); + EXPECT_EQ(0u, found_sessions.GetList().size()); } }
diff --git a/content/browser/private_aggregation/private_aggregation_host.cc b/content/browser/private_aggregation/private_aggregation_host.cc index 136049a..9317972 100644 --- a/content/browser/private_aggregation/private_aggregation_host.cc +++ b/content/browser/private_aggregation/private_aggregation_host.cc
@@ -57,7 +57,7 @@ BrowserContext* browser_context) : should_not_delay_reports_( base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kPrivateAggregationDebugMode)), + switches::kPrivateAggregationDeveloperMode)), on_report_request_received_(std::move(on_report_request_received)), browser_context_(*browser_context) { DCHECK(!on_report_request_received_.is_null());
diff --git a/content/browser/private_aggregation/private_aggregation_host.h b/content/browser/private_aggregation/private_aggregation_host.h index 7cc01dd..2afbe3d 100644 --- a/content/browser/private_aggregation/private_aggregation_host.h +++ b/content/browser/private_aggregation/private_aggregation_host.h
@@ -72,7 +72,7 @@ private: struct ReceiverContext; - // Set iff the private aggregation debug mode is set. + // Set iff the private aggregation developer mode is set. bool should_not_delay_reports_; base::RepeatingCallback<void(AggregatableReportRequest,
diff --git a/content/browser/private_aggregation/private_aggregation_host_unittest.cc b/content/browser/private_aggregation/private_aggregation_host_unittest.cc index ad2570a..b56f049a 100644 --- a/content/browser/private_aggregation/private_aggregation_host_unittest.cc +++ b/content/browser/private_aggregation/private_aggregation_host_unittest.cc
@@ -448,15 +448,16 @@ EXPECT_TRUE(remote.is_connected()); } -class PrivateAggregationHostDebugModeTest : public PrivateAggregationHostTest { +class PrivateAggregationHostDeveloperModeTest + : public PrivateAggregationHostTest { public: - PrivateAggregationHostDebugModeTest() { + PrivateAggregationHostDeveloperModeTest() { base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kPrivateAggregationDebugMode); + switches::kPrivateAggregationDeveloperMode); } }; -TEST_F(PrivateAggregationHostDebugModeTest, +TEST_F(PrivateAggregationHostDeveloperModeTest, SendHistogramReport_ScheduledReportTimeIsNotDelayed) { const url::Origin kExampleOrigin = url::Origin::Create(GURL("https://example.com"));
diff --git a/content/common/common_param_traits_unittest.cc b/content/common/common_param_traits_unittest.cc index 0072001d..a214ec7 100644 --- a/content/common/common_param_traits_unittest.cc +++ b/content/common/common_param_traits_unittest.cc
@@ -86,28 +86,6 @@ EXPECT_FALSE(IPC::ParamTraits<SkBitmap>::Read(&bad_msg, &iter, &bad_output)); } -TEST(IPCMessageTest, ListValue) { - base::ListValue input; - input.GetList().Append(42.42); - input.GetList().Append("forty"); - input.GetList().Append(base::Value()); - - IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL); - IPC::WriteParam(&msg, input); - - base::ListValue output; - base::PickleIterator iter(msg); - EXPECT_TRUE(IPC::ReadParam(&msg, &iter, &output)); - - EXPECT_EQ(input, output); - - // Also test the corrupt case. - IPC::Message bad_msg(1, 2, IPC::Message::PRIORITY_NORMAL); - bad_msg.WriteInt(99); - iter = base::PickleIterator(bad_msg); - EXPECT_FALSE(IPC::ReadParam(&bad_msg, &iter, &output)); -} - TEST(IPCMessageTest, DictionaryValue) { base::DictionaryValue input; input.SetKey("null", base::Value());
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/HostZoomMap.java b/content/public/android/java/src/org/chromium/content_public/browser/HostZoomMap.java index 4d24b182..55dc409 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/HostZoomMap.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/HostZoomMap.java
@@ -15,9 +15,10 @@ public class HostZoomMap { // Preset zoom factors that the +/- buttons can "snap" the zoom level to if user chooses to // not use the slider. These zoom factors correspond to the zoom levels that are used on - // desktop, i.e. {0.25, 0.33, 0.50, 0.67, ... 3.00, 4.00, 5.00}. - public static final double[] AVAILABLE_ZOOM_FACTORS = new double[] {-7.60, -6.08, -3.80, -2.20, - -1.58, -1.22, -0.58, 0.00, 0.52, 1.22, 1.56, 2.22, 3.07, 3.80, 5.03, 6.03, 7.60, 8.83}; + // desktop, i.e. {0.50, 0.67, ... 3.00}, excluding the smallest/largest two, since they are + // of little value on a mobile device. + public static final double[] AVAILABLE_ZOOM_FACTORS = new double[] {-3.80, -2.20, -1.58, -1.22, + -0.58, 0.00, 0.52, 1.22, 1.56, 2.22, 3.07, 3.80, 5.03, 6.03}; // The value of the base for zoom factor, should match |kTextSizeMultiplierRatio|. public static final float TEXT_SIZE_MULTIPLIER_RATIO = 1.2f;
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/NavigationTest.java b/content/public/android/javatests/src/org/chromium/content/browser/NavigationTest.java index f82e0dcf..0867cff 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/NavigationTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/NavigationTest.java
@@ -12,8 +12,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.base.test.util.UrlUtils; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationController; @@ -65,7 +65,7 @@ @Test @MediumTest @Feature({"Navigation"}) - @FlakyTest(message = "https://crbug.com/1316064") + @DisabledTest(message = "https://crbug.com/1316064") public void testDirectedNavigationHistory() throws Throwable { ContentShellActivity activity = mActivityTestRule.launchContentShellWithUrl(URL_1); mActivityTestRule.waitForActiveShellToBeDoneLoading();
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/VideoFullscreenOrientationLockTest.java b/content/public/android/javatests/src/org/chromium/content/browser/VideoFullscreenOrientationLockTest.java index 40b4464..82989ab 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/VideoFullscreenOrientationLockTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/VideoFullscreenOrientationLockTest.java
@@ -23,7 +23,6 @@ import org.chromium.base.test.util.CriteriaNotSatisfiedException; import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.DisabledTest; -import org.chromium.base.test.util.FlakyTest; import org.chromium.base.test.util.Restriction; import org.chromium.content_public.browser.test.ContentJUnit4ClassRunner; import org.chromium.content_public.browser.test.util.DOMUtils; @@ -195,7 +194,7 @@ @Test @MediumTest @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) - @FlakyTest(message = "crbug.com/1228632") + @DisabledTest(message = "crbug.com/1228632") public void testExitFullscreenByRemovingVideo() throws Exception { // Start playback to guarantee it's properly loaded. Assert.assertTrue(DOMUtils.isMediaPaused(mActivityTestRule.getWebContents(), VIDEO_ID)); @@ -219,7 +218,7 @@ @Test @MediumTest @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) - @FlakyTest(message = "crbug.com/1228632") + @DisabledTest(message = "crbug.com/1228632") public void testExitFullscreenWithNavigation() throws Exception { // Start playback to guarantee it's properly loaded. Assert.assertTrue(DOMUtils.isMediaPaused(mActivityTestRule.getWebContents(), VIDEO_ID));
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java index f93f330..832616c 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java
@@ -18,7 +18,7 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.Batch; -import org.chromium.base.test.util.FlakyTest; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.content_public.browser.test.ContentJUnit4ClassRunner; @@ -134,7 +134,7 @@ @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1186376") + @DisabledTest(message = "https://crbug.com/1186376") public void test_addAlert() { performTest("add-alert.html", "add-alert-expected-android.txt"); } @@ -381,7 +381,7 @@ @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1190218") + @DisabledTest(message = "https://crbug.com/1190218") public void test_ariaMenuItemFocus() { performTest("aria-menuitem-focus.html", EMPTY_EXPECTATIONS_FILE); } @@ -530,7 +530,7 @@ @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1190218") + @DisabledTest(message = "https://crbug.com/1190218") public void test_ariaTreeItemFocus() { performTest("aria-treeitem-focus.html", EMPTY_EXPECTATIONS_FILE); } @@ -561,21 +561,21 @@ @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1186376") + @DisabledTest(message = "https://crbug.com/1186376") public void test_caretHide() { performTest("caret-hide.html", "caret-hide-expected-android.txt"); } @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1186376") + @DisabledTest(message = "https://crbug.com/1186376") public void test_caretMoveHiddenInput() { performTest("caret-move-hidden-input.html", "caret-move-hidden-input-expected-android.txt"); } @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1186376") + @DisabledTest(message = "https://crbug.com/1186376") public void test_caretMove() { performTest("caret-move.html", "caret-move-expected-android.txt"); } @@ -684,14 +684,14 @@ @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1190218") + @DisabledTest(message = "https://crbug.com/1190218") public void test_focusListbox() { performTest("focus-listbox.html", EMPTY_EXPECTATIONS_FILE); } @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1190218") + @DisabledTest(message = "https://crbug.com/1190218") public void test_focusListboxMultiselect() { performTest("focus-listbox-multiselect.html", EMPTY_EXPECTATIONS_FILE); } @@ -752,7 +752,7 @@ @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1190218") + @DisabledTest(message = "https://crbug.com/1190218") public void test_listboxFocus() { performTest("listbox-focus.html", EMPTY_EXPECTATIONS_FILE); } @@ -853,7 +853,7 @@ @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1190218") + @DisabledTest(message = "https://crbug.com/1190218") public void test_menulistFocus() { performTest("menulist-focus.html", EMPTY_EXPECTATIONS_FILE); } @@ -977,7 +977,7 @@ @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1186376") + @DisabledTest(message = "https://crbug.com/1186376") public void test_scrollHorizontalScrollPercentChanged() { performTest("scroll-horizontal-scroll-percent-change.html", "scroll-horizontal-scroll-percent-change-expected-android.txt"); @@ -985,7 +985,7 @@ @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1186376") + @DisabledTest(message = "https://crbug.com/1186376") public void test_scrollVerticalScrollPercentChanged() { performTest("scroll-vertical-scroll-percent-change.html", "scroll-vertical-scroll-percent-change-expected-android.txt"); @@ -1047,7 +1047,7 @@ @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1190218") + @DisabledTest(message = "https://crbug.com/1190218") public void test_tbodyFocus() { performTest("tbody-focus.html", EMPTY_EXPECTATIONS_FILE); } @@ -1098,14 +1098,14 @@ @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1190218") + @DisabledTest(message = "https://crbug.com/1190218") public void test_tfootFocus() { performTest("tfoot-focus.html", EMPTY_EXPECTATIONS_FILE); } @Test @SmallTest - @FlakyTest(message = "https://crbug.com/1190218") + @DisabledTest(message = "https://crbug.com/1190218") public void test_theadFocus() { performTest("thead-focus.html", EMPTY_EXPECTATIONS_FILE); }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeLollipopTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeLollipopTest.java index 2c48211..8622ad4 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeLollipopTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeLollipopTest.java
@@ -20,8 +20,8 @@ import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.content_public.browser.test.ContentJUnit4ClassRunner; import org.chromium.content_public.browser.test.util.TestThreadUtils; @@ -49,7 +49,7 @@ @Test @MediumTest @Feature({"TextInput"}) - @FlakyTest(message = "crbug.com/1153705") + @DisabledTest(message = "crbug.com/1153705") public void testUpdateCursorAnchorInfo() throws Throwable { requestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR);
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/TextSuggestionMenuTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/TextSuggestionMenuTest.java index 26432aa..8a2966f 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/TextSuggestionMenuTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/TextSuggestionMenuTest.java
@@ -27,7 +27,6 @@ import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.CriteriaNotSatisfiedException; import org.chromium.base.test.util.DisabledTest; -import org.chromium.base.test.util.FlakyTest; import org.chromium.content.R; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.test.ContentJUnit4ClassRunner; @@ -146,7 +145,7 @@ @Test @LargeTest - @FlakyTest(message = "https://crbug.com/1348267") + @DisabledTest(message = "https://crbug.com/1348267") public void testApplySuggestion() throws InterruptedException, Throwable, TimeoutException { WebContents webContents = mRule.getWebContents(); @@ -266,7 +265,7 @@ @Test @LargeTest - @FlakyTest(message = "https://crbug.com/1156419") + @DisabledTest(message = "https://crbug.com/1156419") public void suggestionMenuDismissal() throws InterruptedException, Throwable, TimeoutException { WebContents webContents = mRule.getWebContents();
diff --git a/content/public/app/content_main_delegate.h b/content/public/app/content_main_delegate.h index 94b0925..8420d43 100644 --- a/content/public/app/content_main_delegate.h +++ b/content/public/app/content_main_delegate.h
@@ -74,7 +74,10 @@ const std::string& process_type, MainFunctionParams main_function_params); - // Called right before the process exits. + // Called right before the process exits. Note: an empty process_type must not + // be assumed to be an exclusive browser process, processes that exit early + // (e.g. attempt and fail to be the browser process) will also go through this + // path. virtual void ProcessExiting(const std::string& process_type) {} #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 99921845..f42b7c2 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -60,13 +60,6 @@ const char kChangeStackGuardOnForkEnabled[] = "enable"; const char kChangeStackGuardOnForkDisabled[] = "disable"; -// Enables gating of getDisplayMedia by the display-capture permissions-policy. -// This switch supports the shipping of display-capture, as it allows admins to -// temporarily disable display-capture gating with an Enterprise policy. -// TODO(crbug.com/1233969): Remove this around m100. -const char kDisplayCapturePermissionsPolicyAllowed[] = - "display-capture-permissions-policy-allowed"; - // Disable antialiasing on 2d canvas. const char kDisable2dCanvasAntialiasing[] = "disable-canvas-aa"; @@ -607,8 +600,9 @@ // --no-sandbox as well or the sandbox won't allow the dialog to display. const char kPpapiStartupDialog[] = "ppapi-startup-dialog"; -// Causes the Private Aggregation API to run without delays. -const char kPrivateAggregationDebugMode[] = "private-aggregation-debug-mode"; +// Causes the Private Aggregation API to run without reporting delays. +const char kPrivateAggregationDeveloperMode[] = + "private-aggregation-developer-mode"; // Enable the "Process Per Site" process model for all domains. This mode // consolidates same-site pages so that they share a single process.
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 247ae4b8..6f44b6aef 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -30,7 +30,6 @@ CONTENT_EXPORT extern const char kChangeStackGuardOnFork[]; CONTENT_EXPORT extern const char kChangeStackGuardOnForkEnabled[]; CONTENT_EXPORT extern const char kChangeStackGuardOnForkDisabled[]; -CONTENT_EXPORT extern const char kDisplayCapturePermissionsPolicyAllowed[]; CONTENT_EXPORT extern const char kDisable2dCanvasAntialiasing[]; CONTENT_EXPORT extern const char kDisable2dCanvasImageChromium[]; CONTENT_EXPORT extern const char kDisable3DAPIs[]; @@ -183,7 +182,7 @@ extern const char kPpapiPluginLauncher[]; CONTENT_EXPORT extern const char kPpapiPluginProcess[]; extern const char kPpapiStartupDialog[]; -CONTENT_EXPORT extern const char kPrivateAggregationDebugMode[]; +CONTENT_EXPORT extern const char kPrivateAggregationDeveloperMode[]; CONTENT_EXPORT extern const char kProcessPerSite[]; CONTENT_EXPORT extern const char kProcessPerTab[]; CONTENT_EXPORT extern const char kProcessType[];
diff --git a/content/public/renderer/render_accessibility.h b/content/public/renderer/render_accessibility.h index 41af5b9..bd462ec 100644 --- a/content/public/renderer/render_accessibility.h +++ b/content/public/renderer/render_accessibility.h
@@ -10,6 +10,12 @@ #include "ui/accessibility/ax_tree_data.h" #include "ui/accessibility/ax_tree_source.h" +namespace ui { + +class AXTreeID; + +} // namespace ui + namespace content { // This interface exposes the accessibility tree for one RenderFrame. @@ -20,9 +26,13 @@ // These APIs allow a page with a single EMBED element to graft an // accessibility tree for the plugin content, implemented as a // PluginAXTreeSource, into the page's accessibility tree. + + // TODO(accessibility): Consider caching the `AXTreeID` and returning a const + // reference to it, due to its large object size (128 bytes). + virtual ui::AXTreeID GetTreeIDForPluginHost() const = 0; virtual void SetPluginTreeSource(PluginAXTreeSource* source) = 0; - virtual void OnPluginRootNodeUpdated() = 0; virtual void ShowPluginContextMenu() = 0; + virtual void OnPluginRootNodeUpdated() = 0; protected: ~RenderAccessibility() {}
diff --git a/content/renderer/accessibility/ax_tree_snapshotter_impl.cc b/content/renderer/accessibility/ax_tree_snapshotter_impl.cc index cf675b02..fba96ca1 100644 --- a/content/renderer/accessibility/ax_tree_snapshotter_impl.cc +++ b/content/renderer/accessibility/ax_tree_snapshotter_impl.cc
@@ -15,7 +15,6 @@ using blink::WebAXContext; using blink::WebAXObject; using blink::WebDocument; -using BlinkAXTreeSerializer = ui::AXTreeSerializer<blink::WebAXObject>; namespace content {
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc index 4e43bce..5ee30b51 100644 --- a/content/renderer/accessibility/render_accessibility_impl.cc +++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -746,6 +746,16 @@ return ax_context_->GenerateAXID(); } +ui::AXTreeID RenderAccessibilityImpl::GetTreeIDForPluginHost() const { + DCHECK(render_frame_) << "A plugin tree should be under active construction " + "only while this render frame is alive."; + DCHECK(render_frame_->GetWebFrame()) + << "A render frame that contains an actively constructed plugin tree " + "should be in the list of committed web frames."; + // TODO(nektar): Why are some frames without an embedding token? + return render_frame_->GetWebFrame()->GetAXTreeID(); +} + void RenderAccessibilityImpl::SetPluginTreeSource( PluginAXTreeSource* plugin_tree_source) { plugin_tree_source_ = plugin_tree_source;
diff --git a/content/renderer/accessibility/render_accessibility_impl.h b/content/renderer/accessibility/render_accessibility_impl.h index 9d8dbd6..50b12ec 100644 --- a/content/renderer/accessibility/render_accessibility_impl.h +++ b/content/renderer/accessibility/render_accessibility_impl.h
@@ -37,10 +37,13 @@ } // namespace blink namespace ui { + struct AXActionData; class AXActionTarget; struct AXEvent; -} +class AXTreeID; + +} // namespace ui namespace ukm { class MojoUkmRecorder; @@ -52,8 +55,6 @@ class RenderFrameImpl; class RenderAccessibilityManager; -using BlinkAXTreeSerializer = ui::AXTreeSerializer<blink::WebAXObject>; - // The browser process implements native accessibility APIs, allowing assistive // technology (e.g., screen readers, magnifiers) to access and control the web // contents with high-level APIs. These APIs are also used by automation tools, @@ -93,6 +94,7 @@ // RenderAccessibility implementation. int GenerateAXID() override; + ui::AXTreeID GetTreeIDForPluginHost() const override; void SetPluginTreeSource(PluginAXTreeSource* source) override; void OnPluginRootNodeUpdated() override; void ShowPluginContextMenu() override;
diff --git a/content/renderer/render_process_impl.cc b/content/renderer/render_process_impl.cc index ff83822..f2bdea3 100644 --- a/content/renderer/render_process_impl.cc +++ b/content/renderer/render_process_impl.cc
@@ -97,8 +97,6 @@ RenderProcessImpl::RenderProcessImpl() : RenderProcess(GetThreadPoolInitParams()) { - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - #if BUILDFLAG(IS_MAC) // Specified when launching the process in // RendererSandboxedProcessLauncherDelegate::EnableCpuSecurityMitigations @@ -198,7 +196,7 @@ // Bypass the SAB restriction when enabled by Enterprise Policy. if (!enable_shared_array_buffer_unconditionally && - command_line->HasSwitch( + base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kSharedArrayBufferUnrestrictedAccessAllowed)) { enable_shared_array_buffer_unconditionally = true; blink::WebRuntimeFeatures::EnableSharedArrayBufferUnrestrictedAccessAllowed( @@ -222,17 +220,6 @@ v8::V8::SetFlagsFromString(kSABPerContextFlag, sizeof(kSABPerContextFlag)); } - // The display-capture-permissions-policy-allowed flag is used to pass - // the kDisplayCapturePermissionsPolicyEnabled Enterprise policy from the - // browser process to the renderer process. This switch should be enabled by - // default for now, but after a few milestones that allow enterprises to fix - // broken applications, this flag will be removed. - // This switch will only be enabled by the Enterprise policy. - if (command_line->HasSwitch( - switches::kDisplayCapturePermissionsPolicyAllowed)) { - blink::WebRuntimeFeatures::EnableDisplayCapturePermissionsPolicy(true); - } - SetV8FlagIfFeature(features::kWebAssemblyTiering, "--wasm-tier-up"); SetV8FlagIfNotFeature(features::kWebAssemblyTiering, "--no-wasm-tier-up"); @@ -243,6 +230,9 @@ #if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(ARCH_CPU_X86_64) if (base::FeatureList::IsEnabled(features::kWebAssemblyTrapHandler)) { + base::CommandLine* const command_line = + base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kEnableCrashpad) || command_line->HasSwitch(switches::kEnableCrashReporter) || command_line->HasSwitch(switches::kEnableCrashReporterForTesting)) {
diff --git a/content/test/data/accessibility/mac/parameterized-attributes/ax-attributed-string-for-range-expected.txt b/content/test/data/accessibility/mac/parameterized-attributes/ax-attributed-string-for-range-expected.txt index b3c2e44..4b51107 100644 --- a/content/test/data/accessibility/mac/parameterized-attributes/ax-attributed-string-for-range-expected.txt +++ b/content/test/data/accessibility/mac/parameterized-attributes/ax-attributed-string-for-range-expected.txt
@@ -1,3 +1,5 @@ input.accessibilityParameterizedAttributeNames.has(AXAttributedStringForRange)='yes' input.accessibilityAttributeValue(AXAttributedStringForRange, {loc: 0, len: 8})='mispeled{ }' +not_applicable.accessibilityParameterizedAttributeNames.has(AXAttributedStringForRange)='no' +not_applicable.accessibilityAttributeValue(AXAttributedStringForRange, {loc: 0, len: 8})=NULL
diff --git a/content/test/data/accessibility/mac/parameterized-attributes/ax-attributed-string-for-range.html b/content/test/data/accessibility/mac/parameterized-attributes/ax-attributed-string-for-range.html index 89a02be..62e827ad 100644 --- a/content/test/data/accessibility/mac/parameterized-attributes/ax-attributed-string-for-range.html +++ b/content/test/data/accessibility/mac/parameterized-attributes/ax-attributed-string-for-range.html
@@ -2,6 +2,9 @@ @SCRIPT: input.accessibilityParameterizedAttributeNames.has(AXAttributedStringForRange) input.accessibilityAttributeValue(AXAttributedStringForRange, {loc: 0, len: 8}) + not_applicable.accessibilityParameterizedAttributeNames.has(AXAttributedStringForRange) + not_applicable.accessibilityAttributeValue(AXAttributedStringForRange, {loc: 0, len: 8}) --> <!DOCTYPE html> <input id="input" value="mispeled"> +<div id="not_applicable">foobar</div>
diff --git a/device/bluetooth/floss/floss_dbus_client.cc b/device/bluetooth/floss/floss_dbus_client.cc index 718e3c0..db8e145 100644 --- a/device/bluetooth/floss/floss_dbus_client.cc +++ b/device/bluetooth/floss/floss_dbus_client.cc
@@ -22,6 +22,7 @@ const char kAdapterInterface[] = "org.chromium.bluetooth.Bluetooth"; const char kGattInterface[] = "org.chromium.bluetooth.BluetoothGatt"; const char kManagerInterface[] = "org.chromium.bluetooth.Manager"; +const char kExperimentalInterface[] = "org.chromium.bluetooth.Experimental"; const char kManagerObject[] = "/org/chromium/bluetooth/Manager"; const char kAdapterObjectFormat[] = "/org/chromium/bluetooth/hci%d/adapter"; const char kGattObjectFormat[] = "/org/chromium/bluetooth/hci%d/gatt"; @@ -188,6 +189,10 @@ const char kOnPeriodicAdvertisingEnabled[] = "OnPeriodicAdvertisingEnabled"; } // namespace advertiser +namespace experimental { +const char kSetLLPrivacy[] = "SetLLPrivacy"; +} // namespace experimental + namespace { constexpr char kDeviceIdNameKey[] = "name"; constexpr char kDeviceIdAddressKey[] = "address";
diff --git a/device/bluetooth/floss/floss_dbus_client.h b/device/bluetooth/floss/floss_dbus_client.h index 21df5e8..f71112b 100644 --- a/device/bluetooth/floss/floss_dbus_client.h +++ b/device/bluetooth/floss/floss_dbus_client.h
@@ -30,6 +30,7 @@ extern DEVICE_BLUETOOTH_EXPORT const char kAdapterInterface[]; extern DEVICE_BLUETOOTH_EXPORT const char kGattInterface[]; extern DEVICE_BLUETOOTH_EXPORT const char kManagerInterface[]; +extern DEVICE_BLUETOOTH_EXPORT const char kExperimentalInterface[]; extern DEVICE_BLUETOOTH_EXPORT const char kManagerObject[]; extern DEVICE_BLUETOOTH_EXPORT const char kAdapterObjectFormat[]; extern DEVICE_BLUETOOTH_EXPORT const char kGattObjectFormat[]; @@ -188,6 +189,10 @@ extern DEVICE_BLUETOOTH_EXPORT const char kOnPeriodicAdvertisingEnabled[]; } // namespace advertiser +namespace experimental { +extern DEVICE_BLUETOOTH_EXPORT const char kSetLLPrivacy[]; +} // namespace experimental + // BluetoothDevice structure for DBus apis. struct DEVICE_BLUETOOTH_EXPORT FlossDeviceId { std::string address;
diff --git a/device/bluetooth/floss/floss_manager_client.cc b/device/bluetooth/floss/floss_manager_client.cc index 9c1df7e..761e163 100644 --- a/device/bluetooth/floss/floss_manager_client.cc +++ b/device/bluetooth/floss/floss_manager_client.cc
@@ -22,6 +22,7 @@ #include "dbus/exported_object.h" #include "dbus/message.h" #include "dbus/object_proxy.h" +#include "device/bluetooth/bluez/bluez_features.h" #include "device/bluetooth/floss/floss_dbus_client.h" #include "device/bluetooth/floss/floss_features.h" @@ -254,6 +255,12 @@ } } +void FlossManagerClient::SetLLPrivacy(ResponseCallback<Void> callback, + const bool enable) { + CallExperimentalMethod<Void>(std::move(callback), experimental::kSetLLPrivacy, + enable); +} + // Register manager client against manager. void FlossManagerClient::RegisterWithManager() { DCHECK(!manager_available_); @@ -361,6 +368,12 @@ kSetFlossRetryDelayMs, base::BindOnce(&FlossManagerClient::CompleteSetFlossEnabled, weak_ptr_factory_.GetWeakPtr())); + SetLLPrivacy( + base::BindOnce([](DBusResult<Void> ret) { + if (!ret.has_value()) + LOG(ERROR) << "Fail to set LL privacy.\n"; + }), + base::FeatureList::IsEnabled(bluez::features::kLinkLayerPrivacy)); } void FlossManagerClient::HandleGetAvailableAdapters(
diff --git a/device/bluetooth/floss/floss_manager_client.h b/device/bluetooth/floss/floss_manager_client.h index 8427b15..9ddd60d 100644 --- a/device/bluetooth/floss/floss_manager_client.h +++ b/device/bluetooth/floss/floss_manager_client.h
@@ -109,6 +109,9 @@ bool enabled, ResponseCallback<Void> callback); + // Invoke D-Bus API to enable or disable LL privacy. + virtual void SetLLPrivacy(ResponseCallback<Void> callback, const bool enable); + // Initializes the manager client. void Init(dbus::Bus* bus, const std::string& service_name, @@ -212,6 +215,15 @@ void OnSetAdapterEnabled(dbus::Response* response, dbus::ErrorResponse* error_response); + // Call methods in floss experimental interface + template <typename R, typename... Args> + void CallExperimentalMethod(ResponseCallback<R> callback, + const char* member, + Args... args) { + CallMethod(std::move(callback), bus_, service_name_, kExperimentalInterface, + dbus::ObjectPath(kManagerObject), member, args...); + } + // Object path for exported callbacks registered against manager interface. static const char kExportedCallbacksPath[];
diff --git a/device/vr/openxr/openxr_api_wrapper.cc b/device/vr/openxr/openxr_api_wrapper.cc index a40dd8c..f71aed23 100644 --- a/device/vr/openxr/openxr_api_wrapper.cc +++ b/device/vr/openxr/openxr_api_wrapper.cc
@@ -14,6 +14,7 @@ #include "base/containers/contains.h" #include "base/notreached.h" #include "base/ranges/algorithm.h" +#include "base/trace_event/typed_macros.h" #include "components/viz/common/gpu/context_provider.h" #include "device/base/features.h" #include "device/vr/openxr/openxr_input_helper.h" @@ -80,6 +81,34 @@ } } +const char* GetXrSessionStateName(XrSessionState state) { + switch (state) { + case XR_SESSION_STATE_UNKNOWN: + return "Unknown"; + case XR_SESSION_STATE_IDLE: + return "Idle"; + case XR_SESSION_STATE_READY: + return "Ready"; + case XR_SESSION_STATE_SYNCHRONIZED: + return "Synchronized"; + case XR_SESSION_STATE_VISIBLE: + return "Visible"; + case XR_SESSION_STATE_FOCUSED: + return "Focused"; + case XR_SESSION_STATE_STOPPING: + return "Stopping"; + case XR_SESSION_STATE_LOSS_PENDING: + return "Loss_Pending"; + case XR_SESSION_STATE_EXITING: + return "Exiting"; + case XR_SESSION_STATE_MAX_ENUM: + return "Max_Enum"; + } + + NOTREACHED(); + return "Unknown"; +} + } // namespace std::unique_ptr<OpenXrApiWrapper> OpenXrApiWrapper::Create( @@ -118,6 +147,7 @@ } void OpenXrApiWrapper::Reset() { + SetXrSessionState(XR_SESSION_STATE_UNKNOWN); anchor_manager_.reset(); unbounded_space_ = XR_NULL_HANDLE; local_space_ = XR_NULL_HANDLE; @@ -1258,6 +1288,7 @@ // We only have will only have one session and we should make sure the // session that is having state_changed event is ours. DCHECK(session_state_changed->session == session_); + SetXrSessionState(session_state_changed->state); switch (session_state_changed->state) { case XR_SESSION_STATE_READY: xr_result = BeginSession(); @@ -1286,6 +1317,10 @@ } } else if (event_data.type == XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING) { DCHECK(session_ != XR_NULL_HANDLE); + // TODO(https://crbug.com/1335240): Properly handle Instance Loss Pending. + LOG(ERROR) << "Received Instance Loss Event"; + TRACE_EVENT_INSTANT0("xr", "InstanceLossPendingEvent", + TRACE_EVENT_SCOPE_THREAD); Uninitialize(); return XR_ERROR_INSTANCE_LOST; } else if (event_data.type == @@ -1307,6 +1342,10 @@ reinterpret_cast<XrEventDataInteractionProfileChanged*>(&event_data); DCHECK_EQ(interaction_profile_changed->session, session_); xr_result = input_helper_->OnInteractionProfileChanged(); + } else { + DVLOG(1) << __func__ << " Unhandled event type: " << event_data.type; + TRACE_EVENT_INSTANT1("xr", "UnandledXrEvent", TRACE_EVENT_SCOPE_THREAD, + "type", event_data.type); } if (XR_FAILED(xr_result)) { @@ -1421,6 +1460,28 @@ return true; } +void OpenXrApiWrapper::SetXrSessionState(XrSessionState new_state) { + if (session_state_ == new_state) + return; + + const char* old_state_name = GetXrSessionStateName(session_state_); + const char* new_state_name = GetXrSessionStateName(new_state); + DVLOG(1) << __func__ << " Transitioning from: " << old_state_name + << " to: " << new_state_name; + + if (session_state_ != XR_SESSION_STATE_UNKNOWN) { + TRACE_EVENT_NESTABLE_ASYNC_END1("xr", "XRSessionState", this, "state", + old_state_name); + } + + if (new_state != XR_SESSION_STATE_UNKNOWN) { + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("xr", "XRSessionState", this, "state", + new_state_name); + } + + session_state_ = new_state; +} + bool OpenXrApiWrapper::StageParametersEnabled() const { return stage_parameters_enabled_; }
diff --git a/device/vr/openxr/openxr_api_wrapper.h b/device/vr/openxr/openxr_api_wrapper.h index 36076f1..07a2cb6 100644 --- a/device/vr/openxr/openxr_api_wrapper.h +++ b/device/vr/openxr/openxr_api_wrapper.h
@@ -160,6 +160,8 @@ void CreateSharedMailboxes(); void ReleaseColorSwapchainImages(); + void SetXrSessionState(XrSessionState new_state); + // The session is running only after xrBeginSession and before xrEndSession. // It is not considered running after creation but before xrBeginSession. bool session_running_; @@ -177,6 +179,9 @@ // OpenXR objects + // Tracks the session state throughout the lifetime of the Wrapper. + XrSessionState session_state_ = XR_SESSION_STATE_UNKNOWN; + // These objects are initialized on successful initialization. XrInstance instance_; XrSystemId system_;
diff --git a/extensions/renderer/resources/guest_view/guest_view.js b/extensions/renderer/resources/guest_view/guest_view.js index f6c6bc9..5dbeb89 100644 --- a/extensions/renderer/resources/guest_view/guest_view.js +++ b/extensions/renderer/resources/guest_view/guest_view.js
@@ -195,6 +195,17 @@ attachParams['instanceId'] = viewInstanceId; var contentWindow = getIframeContentWindow(viewInstanceId); + + // The internal iframe element may have a null contentWindow at this point. + // For example, we may be trying to attach a guest whose element is in + // another iframe which has already shutdown. + if (!contentWindow) { + this.state = GuestViewImpl.GuestState.GUEST_STATE_CREATED; + this.internalInstanceId = 0; + this.handleCallback(callback); + return; + } + // |contentWindow| is used to retrieve the RenderFrame in cpp. GuestViewInternalNatives.AttachIframeGuest( internalInstanceId, this.id, attachParams, contentWindow,
diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc index 01d3ac55..bbeec904 100644 --- a/extensions/renderer/script_injection.cc +++ b/extensions/renderer/script_injection.cc
@@ -312,17 +312,6 @@ should_execute_asynchronously ? blink::mojom::EvaluationTiming::kAsynchronous : blink::mojom::EvaluationTiming::kSynchronous; - // Historically, when `kSynchronous` is used, we did not block the load - // event. We preserve this here for now to ensure we don't break anything. - // However, this is probably wrong, since the execution context could be - // paused, triggering an asynchronous execution of the script even when - // `kSynchronous` is used. - // TODO(crbug.com/1354639): Change this to block the load event, even with - // `kSynchronous`. - blink::mojom::LoadEventBlockingOption blocking_option = - should_execute_asynchronously - ? blink::mojom::LoadEventBlockingOption::kBlock - : blink::mojom::LoadEventBlockingOption::kDoNotBlock; int32_t world_id = blink::kMainDOMWorldId; switch (injector_->GetExecutionWorld()) { @@ -339,7 +328,7 @@ } render_frame_->GetWebFrame()->RequestExecuteScript( world_id, sources, injector_->IsUserGesture(), execution_option, - blocking_option, + blink::mojom::LoadEventBlockingOption::kBlock, base::BindOnce(&ScriptInjection::OnJsInjectionCompleted, weak_ptr_factory_.GetWeakPtr()), blink::BackForwardCacheAware::kPossiblyDisallow,
diff --git a/fuchsia_web/shell/web_engine_shell.cmx b/fuchsia_web/shell/web_engine_shell.cmx index 61ead3f..fd05f24 100644 --- a/fuchsia_web/shell/web_engine_shell.cmx +++ b/fuchsia_web/shell/web_engine_shell.cmx
@@ -36,6 +36,8 @@ "fuchsia.sys.Launcher", "fuchsia.sys.Loader", "fuchsia.sysmem.Allocator", + "fuchsia.tracing.perfetto.ProducerConnector", + "fuchsia.tracing.provider.Registry", "fuchsia.ui.composition.Allocator", "fuchsia.ui.composition.Flatland", "fuchsia.ui.input3.Keyboard",
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc index 190369fd..f62d9a5 100644 --- a/gpu/command_buffer/tests/gl_manager.cc +++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -359,8 +359,8 @@ command_buffer_->set_handler(decoder_.get()); - surface_ = - gl::init::CreateOffscreenGLSurface(gl::GetDefaultDisplay(), gfx::Size()); + surface_ = gl::init::CreateOffscreenGLSurface(gl::GetDefaultDisplayEGL(), + gfx::Size()); ASSERT_TRUE(surface_.get() != nullptr) << "could not create offscreen surface";
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc index 2193cda..a994f05 100644 --- a/gpu/config/gpu_finch_features.cc +++ b/gpu/config/gpu_finch_features.cc
@@ -347,6 +347,12 @@ "IncreasedCmdBufferParseSlice", base::FEATURE_DISABLED_BY_DEFAULT); +// Kill switch for forcing restart GPU with context loss. +// See https://crbug.com/1172229 for detail. +BASE_FEATURE(kForceRestartGpuKillSwitch, + "ForceRestartGpuKillSwitch", + base::FEATURE_ENABLED_BY_DEFAULT); + bool UseGles2ForOopR() { #if BUILDFLAG(IS_ANDROID) // GLS3 + passthrough decoder break many tests on Android.
diff --git a/gpu/config/gpu_finch_features.h b/gpu/config/gpu_finch_features.h index 9c94919a..a0ce343 100644 --- a/gpu/config/gpu_finch_features.h +++ b/gpu/config/gpu_finch_features.h
@@ -72,6 +72,8 @@ GPU_EXPORT BASE_DECLARE_FEATURE(kForceGpuMainThreadToNormalPriorityDrDc); +GPU_EXPORT BASE_DECLARE_FEATURE(kForceRestartGpuKillSwitch); + #if BUILDFLAG(IS_ANDROID) // This flag is use additionally with kEnableDrDc to enable the feature for // vulkan enabled android devices.
diff --git a/gpu/ipc/common/gpu_param_traits_macros.h b/gpu/ipc/common/gpu_param_traits_macros.h index 82bd3b3..540acb68 100644 --- a/gpu/ipc/common/gpu_param_traits_macros.h +++ b/gpu/ipc/common/gpu_param_traits_macros.h
@@ -5,28 +5,17 @@ #ifndef GPU_IPC_COMMON_GPU_PARAM_TRAITS_MACROS_H_ #define GPU_IPC_COMMON_GPU_PARAM_TRAITS_MACROS_H_ -#include "components/viz/common/resources/resource_format.h" -#include "gpu/command_buffer/common/constants.h" -#include "gpu/command_buffer/common/context_result.h" -#include "gpu/command_buffer/common/scheduling_priority.h" #include "gpu/command_buffer/common/swap_buffers_complete_params.h" #include "gpu/gpu_export.h" -#include "gpu/ipc/common/gpu_command_buffer_traits.h" #include "ipc/ipc_message_macros.h" #include "ui/gfx/ipc/gfx_param_traits.h" -#include "url/ipc/url_param_traits.h" #undef IPC_MESSAGE_EXPORT #define IPC_MESSAGE_EXPORT GPU_EXPORT -IPC_ENUM_TRAITS_MAX_VALUE(gpu::SchedulingPriority, - gpu::SchedulingPriority::kLast) - IPC_STRUCT_TRAITS_BEGIN(gpu::SwapBuffersCompleteParams) IPC_STRUCT_TRAITS_MEMBER(ca_layer_params) IPC_STRUCT_TRAITS_MEMBER(swap_response) IPC_STRUCT_TRAITS_END() -IPC_ENUM_TRAITS_MAX_VALUE(viz::ResourceFormat, viz::RESOURCE_FORMAT_MAX) - #endif // GPU_IPC_COMMON_GPU_PARAM_TRAITS_MACROS_H_
diff --git a/gpu/ipc/service/command_buffer_stub.cc b/gpu/ipc/service/command_buffer_stub.cc index e27ec212..88de4e9 100644 --- a/gpu/ipc/service/command_buffer_stub.cc +++ b/gpu/ipc/service/command_buffer_stub.cc
@@ -700,7 +700,8 @@ bool was_lost_by_robustness = decoder_context_ && decoder_context_->WasContextLostByRobustnessExtension(); - channel_->gpu_channel_manager()->OnContextLost(!was_lost_by_robustness); + channel_->gpu_channel_manager()->OnContextLost(/*context_lost_count=*/-1, + !was_lost_by_robustness); } CheckCompleteWaits();
diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc index 0271885..a4bd4a0 100644 --- a/gpu/ipc/service/gpu_channel_manager.cc +++ b/gpu/ipc/service/gpu_channel_manager.cc
@@ -39,7 +39,6 @@ #include "gpu/command_buffer/service/memory_program_cache.h" #include "gpu/command_buffer/service/passthrough_program_cache.h" #include "gpu/command_buffer/service/scheduler.h" -#include "gpu/command_buffer/service/service_utils.h" #include "gpu/command_buffer/service/sync_point_manager.h" #include "gpu/config/gpu_crash_keys.h" #include "gpu/config/gpu_finch_features.h" @@ -420,8 +419,7 @@ workarounds.disable_program_disk_cache; // Use the EGL blob cache extension for the passthrough decoder. - if (gpu_preferences_.use_passthrough_cmd_decoder && - gles2::PassthroughCommandDecoderSupported()) { + if (use_passthrough_cmd_decoder()) { program_cache_ = std::make_unique<gles2::PassthroughProgramCache>( gpu_preferences_.gpu_program_cache_size, disable_disk_cache); } else { @@ -619,9 +617,10 @@ SharedContextState::ContextLostCallback GpuChannelManager::GetContextLostCallback() { - return base::BindPostTask(task_runner_, - base::BindOnce(&GpuChannelManager::OnContextLost, - weak_factory_.GetWeakPtr())); + return base::BindPostTask( + task_runner_, + base::BindOnce(&GpuChannelManager::OnContextLost, + weak_factory_.GetWeakPtr(), context_lost_count_ + 1)); } GpuChannelManager::OnMemoryAllocatedChangeCallback @@ -843,10 +842,8 @@ enable_angle_validation = true; #endif - const bool use_passthrough_decoder = - gles2::PassthroughCommandDecoderSupported() && - gpu_preferences_.use_passthrough_cmd_decoder; scoped_refptr<gl::GLShareGroup> share_group; + bool use_passthrough_decoder = use_passthrough_cmd_decoder(); if (use_passthrough_decoder) { share_group = new gl::GLShareGroup(); // Virtualized contexts don't work with passthrough command decoder. @@ -927,7 +924,8 @@ auto shared_context_state = base::MakeRefCounted<SharedContextState>( std::move(share_group), std::move(surface), std::move(context), use_virtualized_gl_contexts, - base::BindOnce(&GpuChannelManager::OnContextLost, base::Unretained(this)), + base::BindOnce(&GpuChannelManager::OnContextLost, base::Unretained(this), + context_lost_count_ + 1), gpu_preferences_.gr_context_type, vulkan_context_provider_, metal_context_provider_, dawn_context_provider_, peak_memory_monitor_.GetWeakPtr()); @@ -967,8 +965,22 @@ return shared_context_state_; } -void GpuChannelManager::OnContextLost(bool synthetic_loss) { +void GpuChannelManager::OnContextLost(int context_lost_count, + bool synthetic_loss) { + if (context_lost_count < 0) + context_lost_count = context_lost_count_ + 1; + // Because of the DrDC, we may receive context loss from the GPU main and + // thee DrDC thread. If a context loss happens on the GPU main thread first, + // a task will be post to the DrDC thread to trigger the context loss on + // the DrDC thread, and then the DrDC will report context loss to the GPU main + // thread again. So we use the |context_lost_count| to help us to ignore + // context loss which has been handled. + if (context_lost_count <= context_lost_count_) + return; + DCHECK_EQ(context_lost_count, context_lost_count_ + 1); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + // ANGLE doesn't support recovering from context lost very well. + bool force_restart = use_passthrough_cmd_decoder(); // Add crash keys for context lost count and time. static auto* const lost_count_crash_key = base::debug::AllocateCrashKeyString( @@ -987,14 +999,21 @@ auto lost_time = base::TimeTicks::Now() - creation_time_; SetCrashKeyTimeDelta(lost_time_crash_key, lost_time); + // If context lost 5 times, restart the GPU process. + force_restart |= context_lost_count_ >= 5; + if (!context_lost_time_.is_zero()) { auto interval = lost_time - context_lost_time_; SetCrashKeyTimeDelta(lost_interval_crash_key, interval); + // If context lost again in 5 seconds, restart the GPU process. + force_restart |= (interval <= base::Seconds(5)); } + force_restart &= + base::FeatureList::IsEnabled(features::kForceRestartGpuKillSwitch); context_lost_time_ = lost_time; bool is_gl = gpu_preferences_.gr_context_type == GrContextType::kGL; - if (synthetic_loss && is_gl) + if (!force_restart && synthetic_loss && is_gl) return; // Lose all other contexts. @@ -1005,7 +1024,7 @@ } // Work around issues with recovery by allowing a new GPU process to launch. - if (gpu_driver_bug_workarounds_.exit_on_context_lost || + if (force_restart || gpu_driver_bug_workarounds_.exit_on_context_lost || (shared_context_state_ && !shared_context_state_->GrContextIsGL())) { delegate_->MaybeExitOnContextLost(); }
diff --git a/gpu/ipc/service/gpu_channel_manager.h b/gpu/ipc/service/gpu_channel_manager.h index f01ac67..7a67bb4 100644 --- a/gpu/ipc/service/gpu_channel_manager.h +++ b/gpu/ipc/service/gpu_channel_manager.h
@@ -29,6 +29,7 @@ #include "gpu/command_buffer/service/memory_tracking.h" #include "gpu/command_buffer/service/passthrough_discardable_manager.h" #include "gpu/command_buffer/service/service_discardable_manager.h" +#include "gpu/command_buffer/service/service_utils.h" #include "gpu/command_buffer/service/shader_translator_cache.h" #include "gpu/command_buffer/service/shared_context_state.h" #include "gpu/config/gpu_driver_bug_workarounds.h" @@ -140,7 +141,7 @@ // Remove the channel for a particular renderer. void RemoveChannel(int client_id); - void OnContextLost(bool synthetic_loss); + void OnContextLost(int context_lost_count, bool synthetic_loss); const GpuPreferences& gpu_preferences() const { return gpu_preferences_; } const GpuDriverBugWorkarounds& gpu_driver_bug_workarounds() const { @@ -195,6 +196,11 @@ return shared_image_manager_; } + bool use_passthrough_cmd_decoder() const { + return gpu_preferences_.use_passthrough_cmd_decoder && + gles2::PassthroughCommandDecoderSupported(); + } + // Retrieve GPU Resource consumption statistics for the task manager void GetVideoMemoryUsageStats( VideoMemoryUsageStats* video_memory_usage_stats) const;
diff --git a/gpu/ipc/service/gpu_channel_unittest.cc b/gpu/ipc/service/gpu_channel_unittest.cc index a42ea06..4a804f9 100644 --- a/gpu/ipc/service/gpu_channel_unittest.cc +++ b/gpu/ipc/service/gpu_channel_unittest.cc
@@ -238,7 +238,8 @@ ASSERT_TRUE(channel); // Put channel manager into shutdown state. - channel_manager()->OnContextLost(false /* synthetic_loss */); + channel_manager()->OnContextLost(-1 /* context_lost_count */, + false /* synthetic_loss */); // Calling OnContextLost() above may destroy the gpu channel via post task. // Ensure that post task has happened. @@ -270,7 +271,8 @@ CreateFailsDuringLostContextShutdown_2) { // Put channel manager into shutdown state. Do this before creating a channel, // as doing this may destroy any active channels. - channel_manager()->OnContextLost(false /* synthetic_loss */); + channel_manager()->OnContextLost(-1 /* context_lost_count */, + false /* synthetic_loss */); int32_t kClientId = 1; GpuChannel* channel = CreateChannel(kClientId, false);
diff --git a/infra/config/generated/builders/ci/fuchsia-fyi-x64-wst/properties.json b/infra/config/generated/builders/ci/fuchsia-fyi-x64-wst/properties.json deleted file mode 100644 index fc3bce3..0000000 --- a/infra/config/generated/builders/ci/fuchsia-fyi-x64-wst/properties.json +++ /dev/null
@@ -1,17 +0,0 @@ -{ - "$build/goma": { - "enable_ats": true, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org", - "use_luci_auth": true - }, - "$recipe_engine/resultdb/test_presentation": { - "column_keys": [], - "grouping_keys": [ - "status", - "v.test_suite" - ] - }, - "builder_group": "chromium.fyi", - "recipe": "chromium" -} \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/fuchsia-x64-workstation/properties.json b/infra/config/generated/builders/ci/fuchsia-x64-workstation/properties.json new file mode 100644 index 0000000..0f89027 --- /dev/null +++ b/infra/config/generated/builders/ci/fuchsia-x64-workstation/properties.json
@@ -0,0 +1,72 @@ +{ + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "fuchsia-x64-workstation", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-fyi-archive", + "builder_group": "chromium.fuchsia.fyi", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 64, + "target_platform": "fuchsia" + }, + "legacy_gclient_config": { + "apply_configs": [ + "fuchsia_workstation" + ], + "config": "chromium" + }, + "legacy_test_results_config": { + "config": "staging_server" + }, + "run_tests_serially": true + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "fuchsia-x64-workstation", + "project": "chromium" + } + ], + "mirroring_builder_group_and_names": [ + { + "builder": "fuchsia-x64-workstation", + "group": "tryserver.chromium.fuchsia" + } + ] + } + }, + "$build/goma": { + "enable_ats": true, + "rpc_extra_params": "?prod", + "server_host": "goma.chromium.org", + "use_luci_auth": true + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "chromium.fuchsia.fyi", + "recipe": "chromium", + "sheriff_rotations": [ + "fuchsia" + ] +} \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-chromeos-annotator-rel/properties.json b/infra/config/generated/builders/ci/linux-chromeos-annotator-rel/properties.json index 342b501..60fb5f4 100644 --- a/infra/config/generated/builders/ci/linux-chromeos-annotator-rel/properties.json +++ b/infra/config/generated/builders/ci/linux-chromeos-annotator-rel/properties.json
@@ -1,4 +1,48 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "linux-chromeos-annotator-rel", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-fyi-archive", + "builder_group": "chromium.fyi", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "chromeos" + ], + "config": "chromium" + }, + "legacy_test_results_config": { + "config": "staging_server" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "linux-chromeos-annotator-rel", + "project": "chromium" + } + ] + } + }, "$build/reclient": { "instance": "rbe-chromium-trusted", "jobs": 500,
diff --git a/infra/config/generated/builders/try/fuchsia-x64-workstation/properties.json b/infra/config/generated/builders/try/fuchsia-x64-workstation/properties.json new file mode 100644 index 0000000..a8f3b57 --- /dev/null +++ b/infra/config/generated/builders/try/fuchsia-x64-workstation/properties.json
@@ -0,0 +1,63 @@ +{ + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "fuchsia-x64-workstation", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-fyi-archive", + "builder_group": "chromium.fuchsia.fyi", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 64, + "target_platform": "fuchsia" + }, + "legacy_gclient_config": { + "apply_configs": [ + "fuchsia_workstation" + ], + "config": "chromium" + }, + "legacy_test_results_config": { + "config": "staging_server" + }, + "run_tests_serially": true + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "fuchsia-x64-workstation", + "project": "chromium" + } + ] + } + }, + "$build/goma": { + "enable_ats": true, + "rpc_extra_params": "?prod", + "server_host": "goma.chromium.org", + "use_luci_auth": true + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "tryserver.chromium.fuchsia", + "recipe": "chromium_trybot" +} \ No newline at end of file
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index 5df3cb0b..00765b5 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -1965,6 +1965,10 @@ includable_only: true } builders { + name: "chromium/try/fuchsia-x64-workstation" + includable_only: true + } + builders { name: "chromium/try/fuchsia_arm64" includable_only: true }
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 4dc8877..5aaf0dc 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -4130,6 +4130,9 @@ ' "use_luci_auth": true' ' },' ' "$build/reclient": {' + ' "bootstrap_env": {' + ' "GLOG_vmodule": "bridge*=2"' + ' },' ' "cache_silo": "Comparison Mac - cache siloed",' ' "instance": "rbe-chromium-trusted-test",' ' "jobs": 250,' @@ -4217,6 +4220,9 @@ ' "use_luci_auth": true' ' },' ' "$build/reclient": {' + ' "bootstrap_env": {' + ' "GLOG_vmodule": "bridge*=2"' + ' },' ' "cache_silo": "Comparison Mac CQ - cache siloed",' ' "instance": "rbe-chromium-untrusted-test",' ' "jobs": 150,' @@ -4304,6 +4310,9 @@ ' "use_luci_auth": true' ' },' ' "$build/reclient": {' + ' "bootstrap_env": {' + ' "GLOG_vmodule": "bridge*=2"' + ' },' ' "cache_silo": "Comparison Mac - cache siloed",' ' "instance": "rbe-chromium-trusted-test",' ' "jobs": 250,' @@ -4390,6 +4399,9 @@ ' "use_luci_auth": true' ' },' ' "$build/reclient": {' + ' "bootstrap_env": {' + ' "GLOG_vmodule": "bridge*=2"' + ' },' ' "cache_silo": "Comparison Mac - cache siloed",' ' "instance": "rbe-chromium-trusted-test",' ' "jobs": 250,' @@ -32413,95 +32425,6 @@ } } builders { - name: "fuchsia-fyi-x64-wst" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "free_space:standard" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/chromium/bootstrapper/${platform}" - cipd_version: "latest" - cmd: "bootstrapper" - } - properties: - '{' - ' "$bootstrap/exe": {' - ' "exe": {' - ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' - ' "cipd_version": "refs/heads/main",' - ' "cmd": [' - ' "luciexe"' - ' ]' - ' }' - ' },' - ' "$bootstrap/properties": {' - ' "properties_file": "infra/config/generated/builders/ci/fuchsia-fyi-x64-wst/properties.json",' - ' "top_level_project": {' - ' "ref": "refs/heads/main",' - ' "repo": {' - ' "host": "chromium.googlesource.com",' - ' "project": "chromium/src"' - ' }' - ' }' - ' },' - ' "builder_group": "chromium.fyi",' - ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' - '}' - priority: 35 - execution_timeout_secs: 36000 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium_swarming.expose_merge_script_failures" - value: 10 - } - experiments { - key: "luci.buildbucket.omit_python2" - value: 100 - } - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_ci_test_results" - test_results { - predicate { - test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { name: "fuchsia-official" swarming_host: "chromium-swarm.appspot.com" dimensions: "builder:fuchsia-official" @@ -32936,6 +32859,93 @@ } } builders { + name: "fuchsia-x64-workstation" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "free_space:standard" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.ci" + dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/ci/fuchsia-x64-workstation/properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "chromium.fuchsia.fyi",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium",' + ' "sheriff_rotations": [' + ' "fuchsia"' + ' ]' + '}' + execution_timeout_secs: 36000 + build_numbers: YES + service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + experiments { + key: "chromium_swarming.expose_merge_script_failures" + value: 10 + } + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "ci_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_ci_test_results" + test_results { + predicate { + test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "gpu-fyi-chromeos-jacuzzi-exp" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" @@ -57076,10 +57086,11 @@ builders { name: "android-nougat-x86-rel" swarming_host: "chromium-swarm.appspot.com" + dimensions: "builder:android-nougat-x86-rel" dimensions: "cores:4" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try.orchestrator" + dimensions: "pool:luci.chromium.try" exe { cipd_package: "infra/chromium/bootstrapper/${platform}" cipd_version: "latest" @@ -57116,10 +57127,6 @@ seconds: 120 } caches { - name: "unused_builder_cache" - path: "builder" - } - caches { name: "win_toolchain" path: "win_toolchain" } @@ -58250,10 +58257,11 @@ builders { name: "android-pie-arm64-rel" swarming_host: "chromium-swarm.appspot.com" + dimensions: "builder:android-pie-arm64-rel" dimensions: "cores:4" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try.orchestrator" + dimensions: "pool:luci.chromium.try" exe { cipd_package: "infra/chromium/bootstrapper/${platform}" cipd_version: "latest" @@ -58290,10 +58298,6 @@ seconds: 120 } caches { - name: "unused_builder_cache" - path: "builder" - } - caches { name: "win_toolchain" path: "win_toolchain" } @@ -61786,10 +61790,11 @@ builders { name: "chromeos-amd64-generic-rel" swarming_host: "chromium-swarm.appspot.com" + dimensions: "builder:chromeos-amd64-generic-rel" dimensions: "cores:2" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try.orchestrator" + dimensions: "pool:luci.chromium.try" exe { cipd_package: "infra/chromium/bootstrapper/${platform}" cipd_version: "latest" @@ -61826,10 +61831,6 @@ seconds: 120 } caches { - name: "unused_builder_cache" - path: "builder" - } - caches { name: "win_toolchain" path: "win_toolchain" } @@ -65463,6 +65464,112 @@ } } builders { + name: "fuchsia-x64-workstation" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/fuchsia-x64-workstation/properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "tryserver.chromium.fuchsia",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' + '}' + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + caches { + name: "win_toolchain" + path: "win_toolchain" + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "chromium_swarming.expose_merge_script_failures" + value: 20 + } + experiments { + key: "enable_weetbix_queries" + value: 100 + } + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + experiments { + key: "weetbix.enable_weetbix_exonerations" + value: 100 + } + experiments { + key: "weetbix.retry_weak_exonerations" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "fuchsia_arm64" swarming_host: "chromium-swarm.appspot.com" dimensions: "builder:fuchsia_arm64" @@ -75514,10 +75621,11 @@ builders { name: "linux-chromeos-rel" swarming_host: "chromium-swarm.appspot.com" + dimensions: "builder:linux-chromeos-rel" dimensions: "cores:2" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try.orchestrator" + dimensions: "pool:luci.chromium.try" exe { cipd_package: "infra/chromium/bootstrapper/${platform}" cipd_version: "latest" @@ -75554,10 +75662,6 @@ seconds: 120 } caches { - name: "unused_builder_cache" - path: "builder" - } - caches { name: "win_toolchain" path: "win_toolchain" } @@ -77318,10 +77422,11 @@ builders { name: "linux-lacros-rel" swarming_host: "chromium-swarm.appspot.com" + dimensions: "builder:linux-lacros-rel" dimensions: "cores:2" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try.orchestrator" + dimensions: "pool:luci.chromium.try" exe { cipd_package: "infra/chromium/bootstrapper/${platform}" cipd_version: "latest" @@ -77358,10 +77463,6 @@ seconds: 120 } caches { - name: "unused_builder_cache" - path: "builder" - } - caches { name: "win_toolchain" path: "win_toolchain" } @@ -78380,10 +78481,11 @@ builders { name: "linux-rel" swarming_host: "chromium-swarm.appspot.com" + dimensions: "builder:linux-rel" dimensions: "cores:2" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try.orchestrator" + dimensions: "pool:luci.chromium.try" exe { cipd_package: "infra/chromium/bootstrapper/${platform}" cipd_version: "latest" @@ -78420,10 +78522,6 @@ seconds: 120 } caches { - name: "unused_builder_cache" - path: "builder" - } - caches { name: "win_toolchain" path: "win_toolchain" } @@ -81037,10 +81135,11 @@ builders { name: "linux_chromium_asan_rel_ng" swarming_host: "chromium-swarm.appspot.com" + dimensions: "builder:linux_chromium_asan_rel_ng" dimensions: "cores:2" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try.orchestrator" + dimensions: "pool:luci.chromium.try" exe { cipd_package: "infra/chromium/bootstrapper/${platform}" cipd_version: "latest" @@ -81077,10 +81176,6 @@ seconds: 120 } caches { - name: "unused_builder_cache" - path: "builder" - } - caches { name: "win_toolchain" path: "win_toolchain" } @@ -82427,10 +82522,11 @@ builders { name: "linux_chromium_tsan_rel_ng" swarming_host: "chromium-swarm.appspot.com" + dimensions: "builder:linux_chromium_tsan_rel_ng" dimensions: "cores:2" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try.orchestrator" + dimensions: "pool:luci.chromium.try" exe { cipd_package: "infra/chromium/bootstrapper/${platform}" cipd_version: "latest" @@ -82467,10 +82563,6 @@ seconds: 120 } caches { - name: "unused_builder_cache" - path: "builder" - } - caches { name: "win_toolchain" path: "win_toolchain" }
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg index 3cd5d42..2b33ebaaa 100644 --- a/infra/config/generated/luci/luci-milo.cfg +++ b/infra/config/generated/luci/luci-milo.cfg
@@ -1850,7 +1850,7 @@ short_name: "cov" } builders { - name: "buildbucket/luci.chromium.ci/fuchsia-fyi-x64-wst" + name: "buildbucket/luci.chromium.ci/fuchsia-x64-workstation" category: "fyi|x64" short_name: "work" } @@ -7209,6 +7209,11 @@ short_name: "x64" } builders { + name: "buildbucket/luci.chromium.ci/fuchsia-x64-workstation" + category: "fuchsia|x64" + short_name: "work" + } + builders { name: "buildbucket/luci.chrome.ci/fuchsia-builder-perf-fyi" category: "p/chrome|arm64" short_name: "perf-bld" @@ -8208,11 +8213,6 @@ short_name: "cfv2" } builders { - name: "buildbucket/luci.chromium.ci/fuchsia-fyi-x64-wst" - category: "fuchsia|x64" - short_name: "work" - } - builders { name: "buildbucket/luci.chromium.ci/ios-simulator-multi-window" category: "iOS" short_name: "mwd" @@ -16375,6 +16375,9 @@ name: "buildbucket/luci.chromium.try/fuchsia-x64-rel" } builders { + name: "buildbucket/luci.chromium.try/fuchsia-x64-workstation" + } + builders { name: "buildbucket/luci.chromium.try/fuchsia_arm64" } builders { @@ -17683,6 +17686,9 @@ name: "buildbucket/luci.chromium.try/fuchsia-x64-rel" } builders { + name: "buildbucket/luci.chromium.try/fuchsia-x64-workstation" + } + builders { name: "buildbucket/luci.chromium.try/fuchsia_arm64" } builders {
diff --git a/infra/config/generated/luci/luci-notify.cfg b/infra/config/generated/luci/luci-notify.cfg index 8670ac9..029ac63 100644 --- a/infra/config/generated/luci/luci-notify.cfg +++ b/infra/config/generated/luci/luci-notify.cfg
@@ -2794,19 +2794,6 @@ } notifiers { notifications { - on_change: true - email { - recipients: "chrome-fuchsia-gardener@grotations.appspotmail.com" - } - } - builders { - bucket: "ci" - name: "fuchsia-fyi-x64-wst" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { on_occurrence: FAILURE failed_step_regexp: "\\b(bot_update|compile|gclient runhooks|runhooks|update|\\w*nocompile_test)\\b" email { @@ -2895,6 +2882,19 @@ } notifiers { notifications { + on_change: true + email { + recipients: "chrome-fuchsia-gardener@grotations.appspotmail.com" + } + } + builders { + bucket: "ci" + name: "fuchsia-x64-workstation" + repository: "https://chromium.googlesource.com/chromium/src" + } +} +notifiers { + notifications { on_occurrence: FAILURE failed_step_regexp: "\\b(bot_update|compile|gclient runhooks|runhooks|update|\\w*nocompile_test)\\b" email {
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg index e6b56c9..bff57767 100644 --- a/infra/config/generated/luci/luci-scheduler.cfg +++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -5189,16 +5189,6 @@ } } job { - id: "fuchsia-fyi-x64-wst" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "ci" - builder: "fuchsia-fyi-x64-wst" - } -} -job { id: "fuchsia-official" realm: "ci" acl_sets: "ci" @@ -5249,6 +5239,16 @@ } } job { + id: "fuchsia-x64-workstation" + realm: "ci" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "ci" + builder: "fuchsia-x64-workstation" + } +} +job { id: "gpu-fyi-chromeos-jacuzzi-exp" realm: "ci" acl_sets: "ci" @@ -7482,12 +7482,12 @@ triggers: "fuchsia-fyi-cfv2-script" triggers: "fuchsia-fyi-x64-asan" triggers: "fuchsia-fyi-x64-dbg" - triggers: "fuchsia-fyi-x64-wst" triggers: "fuchsia-official" triggers: "fuchsia-x64-cast-receiver-rel" triggers: "fuchsia-x64-chrome-rel" triggers: "fuchsia-x64-dbg" triggers: "fuchsia-x64-rel" + triggers: "fuchsia-x64-workstation" triggers: "gpu-fyi-chromeos-jacuzzi-exp" triggers: "gpu-fyi-chromeos-octopus-exp" triggers: "gpu-fyi-chromeos-zork-exp"
diff --git a/infra/config/generated/sheriff-rotations/fuchsia.txt b/infra/config/generated/sheriff-rotations/fuchsia.txt index e3fbfe9..22e61bd3 100644 --- a/infra/config/generated/sheriff-rotations/fuchsia.txt +++ b/infra/config/generated/sheriff-rotations/fuchsia.txt
@@ -3,3 +3,4 @@ ci/fuchsia-fyi-x64-asan ci/fuchsia-fyi-x64-dbg ci/fuchsia-x64-chrome-rel +ci/fuchsia-x64-workstation
diff --git a/infra/config/subprojects/chromium/ci/chromium.fuchsia.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fuchsia.fyi.star index 8880d97..d6f5def 100644 --- a/infra/config/subprojects/chromium/ci/chromium.fuchsia.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.fuchsia.fyi.star
@@ -237,3 +237,41 @@ run_tests_serially = True, ), ) + +ci.builder( + name = "fuchsia-x64-workstation", + console_view_entry = [ + consoles.console_view_entry( + category = "fuchsia|x64", + short_name = "work", + ), + consoles.console_view_entry( + branch_selector = branches.MAIN, + console_view = "sheriff.fuchsia", + category = "fyi|x64", + short_name = "work", + ), + ], + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "fuchsia_workstation", + ], + ), + chromium_config = builder_config.chromium_config( + config = "chromium", + apply_configs = [ + "mb", + ], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + target_platform = builder_config.target_platform.FUCHSIA, + ), + test_results_config = builder_config.test_results_config( + config = "staging_server", + ), + build_gs_bucket = "chromium-fyi-archive", + run_tests_serially = True, + ), +)
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star index a841d80..ed4a4fe 100644 --- a/infra/config/subprojects/chromium/ci/chromium.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -244,24 +244,6 @@ ) ci.builder( - name = "fuchsia-fyi-x64-wst", - console_view_entry = [ - consoles.console_view_entry( - category = "fuchsia|x64", - short_name = "work", - ), - consoles.console_view_entry( - branch_selector = branches.MAIN, - console_view = "sheriff.fuchsia", - category = "fyi|x64", - short_name = "work", - ), - ], - notifies = ["cr-fuchsia"], - os = os.LINUX_DEFAULT, -) - -ci.builder( name = "lacros-amd64-generic-rel-fyi", console_view_entry = consoles.console_view_entry( category = "lacros", @@ -364,6 +346,26 @@ name = "linux-chromeos-annotator-rel", builderless = True, branch_selector = branches.STANDARD_MILESTONE, + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "chromeos", + ], + ), + chromium_config = builder_config.chromium_config( + config = "chromium", + apply_configs = [ + "mb", + ], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + ), + test_results_config = builder_config.test_results_config( + config = "staging_server", + ), + build_gs_bucket = "chromium-fyi-archive", + ), console_view_entry = consoles.console_view_entry( category = "release", short_name = "rel", @@ -1113,6 +1115,9 @@ reclient_jobs = 250, os = os.MAC_DEFAULT, cores = None, + reclient_bootstrap_env = { + "GLOG_vmodule": "bridge*=2", + }, ) ci.builder( @@ -1130,6 +1135,9 @@ reclient_jobs = 250, os = os.MAC_DEFAULT, cores = None, + reclient_bootstrap_env = { + "GLOG_vmodule": "bridge*=2", + }, ) ci.builder( @@ -1148,6 +1156,9 @@ os = os.MAC_DEFAULT, cores = None, cpu = cpu.ARM64, + reclient_bootstrap_env = { + "GLOG_vmodule": "bridge*=2", + }, ) ci.builder( @@ -1302,6 +1313,9 @@ os = os.MAC_DEFAULT, ssd = True, cores = None, + reclient_bootstrap_env = { + "GLOG_vmodule": "bridge*=2", + }, ) ci.builder(
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star index 8759761..7f50e0b4 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
@@ -257,7 +257,9 @@ experiments = { "remove_src_checkout_experiment": 100, }, - use_orchestrator_pool = True, + # TODO(crbug.com/1372179): Use orchestrator pool once overloaded test pools + # are addressed + # use_orchestrator_pool = True, ) try_.compilator_builder( @@ -377,7 +379,9 @@ experiments = { "remove_src_checkout_experiment": 100, }, - use_orchestrator_pool = True, + # TODO(crbug.com/1372179): Use orchestrator pool once overloaded test pools + # are addressed + # use_orchestrator_pool = True, ) try_.compilator_builder(
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star index 446dc7bf..a32a9346 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
@@ -63,7 +63,9 @@ experiments = { "remove_src_checkout_experiment": 100, }, - use_orchestrator_pool = True, + # TODO(crbug.com/1372179): Use orchestrator pool once overloaded test pools + # are addressed + # use_orchestrator_pool = True, ) try_.compilator_builder( @@ -276,7 +278,9 @@ experiments = { "remove_src_checkout_experiment": 100, }, - use_orchestrator_pool = True, + # TODO(crbug.com/1372179): Use orchestrator pool once overloaded test pools + # are addressed + # use_orchestrator_pool = True, ) try_.compilator_builder( @@ -308,7 +312,9 @@ experiments = { "remove_src_checkout_experiment": 100, }, - use_orchestrator_pool = True, + # TODO(crbug.com/1372179): Use orchestrator pool once overloaded test pools + # are addressed + # use_orchestrator_pool = True, ) try_.compilator_builder(
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star b/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star index 219fb4a..ee68ca9e 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star
@@ -187,6 +187,11 @@ }, ) +try_.builder( + name = "fuchsia-x64-workstation", + mirrors = ["ci/fuchsia-x64-workstation"], +) + # TODO(crbug.com/1294938): Remove this bot after the soft CQ transition. try_.builder( name = "fuchsia_arm64",
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star index 07039dca..30d8cd7c 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
@@ -212,7 +212,9 @@ experiments = { "remove_src_checkout_experiment": 100, }, - use_orchestrator_pool = True, + # TODO(crbug.com/1372179): Use orchestrator pool once overloaded test pools + # are addressed + # use_orchestrator_pool = True, ) try_.compilator_builder( @@ -360,7 +362,9 @@ experiments = { "remove_src_checkout_experiment": 100, }, - use_orchestrator_pool = True, + # TODO (crbug.com/1372179): Use orchestrator pool once overloaded test pools + # are addressed + # use_orchestrator_pool = True, ) try_.compilator_builder( @@ -520,7 +524,9 @@ experiments = { "remove_src_checkout_experiment": 100, }, - use_orchestrator_pool = True, + # TODO (crbug.com/1372179): Use orchestrator pool once overloaded test pools + # are addressed + # use_orchestrator_pool = True, ) try_.compilator_builder(
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn index 3f2e9df3..0d7423e3 100644 --- a/ios/chrome/app/BUILD.gn +++ b/ios/chrome/app/BUILD.gn
@@ -316,7 +316,6 @@ "//base", "//ios/chrome/app/application_delegate:app_state_header", "//ios/chrome/app/application_delegate:application_delegate_internal", - "//ios/chrome/browser/application_context:application_context", "//ios/chrome/browser/promos_manager:promos_manager", "//ios/chrome/browser/signin", "//ios/chrome/browser/signin:signin_util",
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index b2ba258..bd053470 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -508,9 +508,11 @@ addAgent:[[PostRestoreAppAgent alloc] initWithPromosManager:GetApplicationContext() ->GetPromosManager() - authenticationService: - AuthenticationServiceFactory::GetForBrowserState( - self.appState.mainBrowserState)]]; + authenticationService:AuthenticationServiceFactory:: + GetForBrowserState( + self.appState.mainBrowserState) + localState:GetApplicationContext() + ->GetLocalState()]]; } // This initialization must happen before any windows are created.
diff --git a/ios/chrome/app/post_restore_app_agent.h b/ios/chrome/app/post_restore_app_agent.h index a18a3df..7f3207f 100644 --- a/ios/chrome/app/post_restore_app_agent.h +++ b/ios/chrome/app/post_restore_app_agent.h
@@ -8,15 +8,17 @@ #import "ios/chrome/app/application_delegate/app_state_agent.h" #import "ios/chrome/app/application_delegate/app_state_observer.h" -class PromosManager; class AuthenticationService; +class PrefService; +class PromosManager; // App agent that displays the Post Restore UI when needed. @interface PostRestoreAppAgent : NSObject <AppStateAgent> - (instancetype)initWithPromosManager:(PromosManager*)promosManager authenticationService: - (AuthenticationService*)authenticationService; + (AuthenticationService*)authenticationService + localState:(PrefService*)localState; @end
diff --git a/ios/chrome/app/post_restore_app_agent.mm b/ios/chrome/app/post_restore_app_agent.mm index af2e8c8..27ce9e2a 100644 --- a/ios/chrome/app/post_restore_app_agent.mm +++ b/ios/chrome/app/post_restore_app_agent.mm
@@ -5,7 +5,6 @@ #import "ios/chrome/app/post_restore_app_agent.h" #import "ios/chrome/app/application_delegate/app_state.h" -#import "ios/chrome/browser/application_context/application_context.h" #import "ios/chrome/browser/promos_manager/promos_manager.h" #import "ios/chrome/browser/signin/authentication_service.h" #import "ios/chrome/browser/signin/signin_util.h" @@ -33,6 +32,9 @@ // The AuthenticationManager is used to reset the reauth infobar prompt. @property(nonatomic, assign) AuthenticationService* authenticationService; +// Local state is used to retrieve and/or clear the pre-restore identity. +@property(nonatomic, assign) PrefService* localState; + // Stores the PostRestoreSignInType which can be kAlert, kFullscreen, or // kDisabled. @property(nonatomic) @@ -54,13 +56,15 @@ - (instancetype)initWithPromosManager:(PromosManager*)promosManager authenticationService: - (AuthenticationService*)authenticationService { + (AuthenticationService*)authenticationService + localState:(PrefService*)localState { DCHECK(authenticationService); self = [super init]; if (self) { _promosManager = promosManager; _authenticationService = authenticationService; + _localState = localState; } return self; } @@ -99,9 +103,7 @@ _featureEnabled = _postRestoreSignInType != post_restore_signin::features::PostRestoreSignInType::kDisabled; - _hasAccountInfo = GetPreRestoreIdentity().has_value(); - if (_promosManager == nil) - _promosManager = GetApplicationContext()->GetPromosManager(); + _hasAccountInfo = GetPreRestoreIdentity(_localState).has_value(); } // Returns the correct promo type depending on which feature variation is @@ -128,8 +130,12 @@ // otherwise deregister the promo. - (void)maybeRegisterPromo { if (!self.shouldRegisterPromo) { - if (_promosManager) + if (_promosManager) { [self deregisterPromos]; + } + if (_hasAccountInfo) { + ClearPreRestoreIdentity(_localState); + } return; }
diff --git a/ios/chrome/app/post_restore_app_agent_unittest.mm b/ios/chrome/app/post_restore_app_agent_unittest.mm index 78919706..51db9b9 100644 --- a/ios/chrome/app/post_restore_app_agent_unittest.mm +++ b/ios/chrome/app/post_restore_app_agent_unittest.mm
@@ -50,7 +50,8 @@ void CreateAppAgent() { appAgent_ = [[PostRestoreAppAgent alloc] initWithPromosManager:CreatePromosManager() - authenticationService:CreateAuthService()]; + authenticationService:CreateAuthService() + localState:local_state_.Get()]; mockAppState_ = OCMClassMock([AppState class]); [appAgent_ setAppState:mockAppState_]; } @@ -95,7 +96,7 @@ void SetFakePreRestoreAccountInfo() { AccountInfo accountInfo; accountInfo.email = kFakePreRestoreAccountEmail; - StorePreRestoreIdentity(accountInfo); + StorePreRestoreIdentity(local_state_.Get(), accountInfo); } void EnableFeatureVariationFullscreen() { @@ -118,7 +119,7 @@ EXPECT_EQ(CountSingleDisplayActivePromos(), 0); // Scenarios which should not register a promo. - ClearPreRestoreIdentity(); + ClearPreRestoreIdentity(local_state_.Get()); MockAppStateChange(InitStageFinal); EXPECT_EQ(CountSingleDisplayActivePromos(), 0); @@ -126,7 +127,7 @@ MockAppStateChange(InitStageFinal); EXPECT_EQ(CountSingleDisplayActivePromos(), 0); - ClearPreRestoreIdentity(); + ClearPreRestoreIdentity(local_state_.Get()); EnableFeatureVariationFullscreen(); MockAppStateChange(InitStageFinal); EXPECT_EQ(CountSingleDisplayActivePromos(), 0); @@ -161,7 +162,7 @@ EXPECT_EQ(CountSingleDisplayActivePromos(), 1); EnableFeatureVariationAlert(); - ClearPreRestoreIdentity(); + ClearPreRestoreIdentity(local_state_.Get()); MockAppStateChange(InitStageFinal); EXPECT_EQ(CountSingleDisplayActivePromos(), 0); } @@ -172,7 +173,7 @@ EXPECT_EQ(CountSingleDisplayActivePromos(), 1); EnableFeatureVariationAlert(); - ClearPreRestoreIdentity(); + ClearPreRestoreIdentity(local_state_.Get()); MockAppStateChange(InitStageFinal); EXPECT_EQ(CountSingleDisplayActivePromos(), 0); }
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 5c7e4d25..e429f4d 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1366,9 +1366,21 @@ <message name="IDS_IOS_MANUAL_FALLBACK_USE_OTHER_PASSWORD" desc="The title for the manual fallback UI with all passwords without filter." meaning="The title for a list where the user is about to select a password or username to be filled in a form [Length: 10em]"> Passwords </message> + <message name="IDS_IOS_MANUAL_FALLBACK_SELECT_PASSWORD_WITH_DOTS" desc="The title for the button in the manual fallback passwords UI that allows the user to select a saved password from a list, and fill it into the active field. [30em]"> + Select Password... + </message> + <message name="IDS_IOS_MANUAL_FALLBACK_SELECT_PASSWORD_DIALOG_MESSAGE" desc="The contents of a dialog asking the user to confirm they trust the current site before selecting a saved password to fill."> + If you trust <ph name="SITE">$1<ex>example.com</ex></ph>, you can use a saved password to sign in. + </message> + <message name="IDS_IOS_MANUAL_FALLBACK_SELECT_PASSWORD_DIALOG_TITLE" desc="The title of a dialog asking the user to confirm they trust the current site before selecting a saved password to fill."> + Select Password + </message> <message name="IDS_IOS_MANUAL_FALLBACK_SUGGEST_PASSWORD_WITH_DOTS" desc="The title for the button in the manual fallback passwords UI that is used to trigger password generation on the active field. [30em]"> Suggest Password... </message> + <message name="IDS_IOS_MANUAL_FALLBACK_SUGGEST_STRONG_PASSWORD_WITH_DOTS" desc="The title for the button in the manual fallback passwords UI that is used to trigger password generation on the active field. 'Strong' refers to the fact that the password is randomly-generated, and thus hard to guess and unlikely to be reused. [30em]"> + Suggest Strong Password... + </message> <message name="IDS_IOS_MANUAL_FALLBACK_USE_OTHER_PASSWORD_WITH_DOTS" desc="The title for the button in the manual fallback passwords UI that is used to open a list of all the user credentials where they can select one to fill a form. This button is showed at the same time as a different button with IDS_IOS_MANUAL_FALLBACK_MANAGE_PASSWORDS as title. [30em]"> Use Other Password... </message> @@ -2591,6 +2603,9 @@ <message name="IDS_IOS_SETTINGS_PASSWORD_DELETE_BUTTON" desc="Button that the user can press to delete a saved password or a site-bound exception preventing saving passwords. [Length: single line available]"> Delete </message> + <message name="IDS_IOS_SETTINGS_PASSWORD_EMPTY_TITLE" desc="Text shown on the Password Manager screen when the user doesn't have any saved passwords to display."> + You'll find your passwords here + </message> <message name="IDS_IOS_SETTINGS_PASSWORD_HIDDEN_LABEL" desc="Accessibility label stating that the element is displaying a hidden password."> Hidden, Password </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_MANUAL_FALLBACK_SELECT_PASSWORD_DIALOG_MESSAGE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_MANUAL_FALLBACK_SELECT_PASSWORD_DIALOG_MESSAGE.png.sha1 new file mode 100644 index 0000000..b77ecc0 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_MANUAL_FALLBACK_SELECT_PASSWORD_DIALOG_MESSAGE.png.sha1
@@ -0,0 +1 @@ +a3a0eb2af61bfffa607a0bf3ccef639166ece8e4 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_MANUAL_FALLBACK_SELECT_PASSWORD_DIALOG_TITLE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_MANUAL_FALLBACK_SELECT_PASSWORD_DIALOG_TITLE.png.sha1 new file mode 100644 index 0000000..b77ecc0 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_MANUAL_FALLBACK_SELECT_PASSWORD_DIALOG_TITLE.png.sha1
@@ -0,0 +1 @@ +a3a0eb2af61bfffa607a0bf3ccef639166ece8e4 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_MANUAL_FALLBACK_SELECT_PASSWORD_WITH_DOTS.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_MANUAL_FALLBACK_SELECT_PASSWORD_WITH_DOTS.png.sha1 new file mode 100644 index 0000000..8712400 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_MANUAL_FALLBACK_SELECT_PASSWORD_WITH_DOTS.png.sha1
@@ -0,0 +1 @@ +194b1048f7b8ad480e46ac9b81afedbc98b9c81e \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_MANUAL_FALLBACK_SUGGEST_STRONG_PASSWORD_WITH_DOTS.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_MANUAL_FALLBACK_SUGGEST_STRONG_PASSWORD_WITH_DOTS.png.sha1 new file mode 100644 index 0000000..8712400 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_MANUAL_FALLBACK_SUGGEST_STRONG_PASSWORD_WITH_DOTS.png.sha1
@@ -0,0 +1 @@ +194b1048f7b8ad480e46ac9b81afedbc98b9c81e \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SETTINGS_PASSWORD_EMPTY_TITLE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SETTINGS_PASSWORD_EMPTY_TITLE.png.sha1 new file mode 100644 index 0000000..b316bd4 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SETTINGS_PASSWORD_EMPTY_TITLE.png.sha1
@@ -0,0 +1 @@ +b75e12029654f3776f06b38b92ea8eecd9b8a4f5 \ No newline at end of file
diff --git a/ios/chrome/browser/net/ios_chrome_network_delegate.cc b/ios/chrome/browser/net/ios_chrome_network_delegate.cc index 74cd323..e824cb6 100644 --- a/ios/chrome/browser/net/ios_chrome_network_delegate.cc +++ b/ios/chrome/browser/net/ios_chrome_network_delegate.cc
@@ -72,6 +72,7 @@ bool IOSChromeNetworkDelegate::OnAnnotateAndMoveUserBlockedCookies( const net::URLRequest& request, + const net::FirstPartySetMetadata& first_party_set_metadata, net::CookieAccessResultList& maybe_included_cookies, net::CookieAccessResultList& excluded_cookies) { // `cookie_settings_` is null during tests, or when we're running in the
diff --git a/ios/chrome/browser/net/ios_chrome_network_delegate.h b/ios/chrome/browser/net/ios_chrome_network_delegate.h index 9cf3ae49..8980369a 100644 --- a/ios/chrome/browser/net/ios_chrome_network_delegate.h +++ b/ios/chrome/browser/net/ios_chrome_network_delegate.h
@@ -10,6 +10,7 @@ #include "base/memory/ref_counted.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "net/base/network_delegate_impl.h" +#include "net/first_party_sets/first_party_set_metadata.h" #include "net/first_party_sets/same_party_context.h" class PrefService; @@ -55,6 +56,7 @@ GURL* new_url) override; bool OnAnnotateAndMoveUserBlockedCookies( const net::URLRequest& request, + const net::FirstPartySetMetadata& first_party_set_metadata, net::CookieAccessResultList& maybe_included_cookies, net::CookieAccessResultList& excluded_cookies) override; bool OnCanSetCookie(const net::URLRequest& request,
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm index cc7ff4d..59f8b0cd 100644 --- a/ios/chrome/browser/prefs/browser_prefs.mm +++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -160,6 +160,8 @@ registry->RegisterBooleanPref(metrics::prefs::kMetricsReportingEnabled, false); + registry->RegisterDictionaryPref(prefs::kIosPreRestoreAccountInfo); + registry->RegisterListPref(prefs::kIosPromosManagerActivePromos); registry->RegisterListPref(prefs::kIosPromosManagerImpressions); registry->RegisterListPref(prefs::kIosPromosManagerSingleDisplayActivePromos);
diff --git a/ios/chrome/browser/prefs/pref_names.cc b/ios/chrome/browser/prefs/pref_names.cc index 0b973422..c6d0ce1 100644 --- a/ios/chrome/browser/prefs/pref_names.cc +++ b/ios/chrome/browser/prefs/pref_names.cc
@@ -92,6 +92,9 @@ const char kIosDiscoverFeedLastRefreshTime[] = "ios.discover_feed.last_refresh_time"; +// The user's account info from before a device restore. +const char kIosPreRestoreAccountInfo[] = "ios.pre_restore_account_info"; + // List preference maintaining the list of continuous-display, active promo // campaigns. const char kIosPromosManagerActivePromos[] = "ios.promos_manager.active_promos";
diff --git a/ios/chrome/browser/prefs/pref_names.h b/ios/chrome/browser/prefs/pref_names.h index af1d1e3..7b27e7b3 100644 --- a/ios/chrome/browser/prefs/pref_names.h +++ b/ios/chrome/browser/prefs/pref_names.h
@@ -31,6 +31,7 @@ extern const char kIosShareChromeCount[]; extern const char kIosShareChromeLastShare[]; extern const char kIosDiscoverFeedLastRefreshTime[]; +extern const char kIosPreRestoreAccountInfo[]; extern const char kIosPromosManagerActivePromos[]; extern const char kIosPromosManagerImpressions[]; extern const char kIosPromosManagerSingleDisplayActivePromos[];
diff --git a/ios/chrome/browser/providers/BUILD.gn b/ios/chrome/browser/providers/BUILD.gn index 919b927..b8d16350 100644 --- a/ios/chrome/browser/providers/BUILD.gn +++ b/ios/chrome/browser/providers/BUILD.gn
@@ -44,6 +44,7 @@ "//ios/chrome/browser/providers/omaha:chromium_omaha", "//ios/chrome/browser/providers/overrides:chromium_overrides", "//ios/chrome/browser/providers/password_auto_fill:chromium_password_auto_fill", + "//ios/chrome/browser/providers/primes:chromium_primes", "//ios/chrome/browser/providers/push_notification:chromium_push_notification", "//ios/chrome/browser/providers/risk_data:chromium_risk_data", "//ios/chrome/browser/providers/signin:chromium_signin_error",
diff --git a/ios/chrome/browser/providers/primes/BUILD.gn b/ios/chrome/browser/providers/primes/BUILD.gn new file mode 100644 index 0000000..5c8aa04 --- /dev/null +++ b/ios/chrome/browser/providers/primes/BUILD.gn
@@ -0,0 +1,12 @@ +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("chromium_primes") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ "chromium_primes.mm" ] + deps = [ + "//base", + "//ios/public/provider/chrome/browser/primes:primes_api", + ] +}
diff --git a/ios/chrome/browser/providers/primes/chromium_primes.mm b/ios/chrome/browser/providers/primes/chromium_primes.mm new file mode 100644 index 0000000..0a50c97 --- /dev/null +++ b/ios/chrome/browser/providers/primes/chromium_primes.mm
@@ -0,0 +1,31 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "base/notreached.h" +#import "ios/public/provider/chrome/browser/primes/primes_api.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace ios { +namespace provider { + +bool IsPrimesSupported() { + // Primes is not used by Chromium + return false; +} + +void PrimesStartLogging() { + // Primes is not used by Chromium + NOTREACHED(); +} + +void PrimesStopLogging() { + // Primes is not used by Chromium + NOTREACHED(); +} + +} // namespace provider +} // namespace ios
diff --git a/ios/chrome/browser/signin/BUILD.gn b/ios/chrome/browser/signin/BUILD.gn index c31858d3..c02e9f5 100644 --- a/ios/chrome/browser/signin/BUILD.gn +++ b/ios/chrome/browser/signin/BUILD.gn
@@ -116,6 +116,7 @@ ":constants", ":signin_util_internal", "//base", + "//components/prefs", "//components/signin/public/identity_manager", "//ios/chrome/browser", "//ios/public/provider/chrome/browser/signin", @@ -244,6 +245,7 @@ "pattern_account_restriction_unittest.mm", "resized_avatar_cache_unittest.mm", "signin_browser_state_info_updater_unittest.mm", + "signin_util_unittest.mm", "user_approved_account_list_manager_unittest.mm", ] deps = [
diff --git a/ios/chrome/browser/signin/authentication_service.mm b/ios/chrome/browser/signin/authentication_service.mm index 1710600..1e88b0f4 100644 --- a/ios/chrome/browser/signin/authentication_service.mm +++ b/ios/chrome/browser/signin/authentication_service.mm
@@ -642,7 +642,8 @@ AccountInfo extended_account_info = identity_manager_->FindExtendedAccountInfoByAccountId( account_info.account_id); - StorePreRestoreIdentity(extended_account_info); + StorePreRestoreIdentity(GetApplicationContext()->GetLocalState(), + extended_account_info); } // Sign the user out.
diff --git a/ios/chrome/browser/signin/signin_util.h b/ios/chrome/browser/signin/signin_util.h index be1d86e..36a8d99f 100644 --- a/ios/chrome/browser/signin/signin_util.h +++ b/ios/chrome/browser/signin/signin_util.h
@@ -14,6 +14,7 @@ #include "ios/chrome/browser/signin/constants.h" @class ChromeIdentity; +class PrefService; namespace signin { enum class Tribool; @@ -38,13 +39,13 @@ // Stores a user's account info in memory, when we detect that it was // forgotten during a device restore. -void StorePreRestoreIdentity(AccountInfo account); +void StorePreRestoreIdentity(PrefService* local_state, AccountInfo account); // Clears the identity that was signed-in before the restore. -void ClearPreRestoreIdentity(); +void ClearPreRestoreIdentity(PrefService* local_state); // Returns the identity that was signed-in before the restore, but is now // not signed-in. -absl::optional<AccountInfo> GetPreRestoreIdentity(); +absl::optional<AccountInfo> GetPreRestoreIdentity(PrefService* local_state); #endif // IOS_CHROME_BROWSER_SIGNIN_SIGNIN_UTIL_H_
diff --git a/ios/chrome/browser/signin/signin_util.mm b/ios/chrome/browser/signin/signin_util.mm index 4f38b2b..0a74227 100644 --- a/ios/chrome/browser/signin/signin_util.mm +++ b/ios/chrome/browser/signin/signin_util.mm
@@ -5,8 +5,14 @@ #import "ios/chrome/browser/signin/signin_util.h" #import "base/strings/sys_string_conversions.h" +#import "base/values.h" +#import "components/prefs/pref_service.h" +#import "components/prefs/scoped_user_pref_update.h" #import "components/signin/public/identity_manager/tribool.h" +#import "google_apis/gaia/core_account_id.h" #import "google_apis/gaia/gaia_auth_util.h" +#import "ios/chrome/browser/application_context/application_context.h" +#import "ios/chrome/browser/prefs/pref_names.h" #import "ios/chrome/browser/signin/signin_util_internal.h" #import "ios/public/provider/chrome/browser/signin/chrome_identity.h" #import "ios/public/provider/chrome/browser/signin/signin_error_api.h" @@ -17,8 +23,41 @@ namespace { absl::optional<AccountInfo> g_pre_restore_identity; + +const char kAccountInfoKeyAccountId[] = "account_id"; +const char kAccountInfoKeyGaia[] = "gaia"; +const char kAccountInfoKeyEmail[] = "email"; +const char kAccountInfoKeyFullName[] = "full_name"; +const char kAccountInfoKeyGivenName[] = "given_name"; +const char kAccountInfoKeyPictureUrl[] = "picture_url"; + +// Copies a string value from a dictionary if the given key is present. +void CopyStringFromDict(std::string& to, + const base::Value::Dict& dict, + const char* key) { + const std::string* found = dict.FindString(key); + if (found) { + to = *found; + } } +// Returns an AccountInfo from the values in a dictionary. +AccountInfo DictToAccountInfo(const base::Value::Dict& dict) { + AccountInfo account; + const std::string* account_id_str = dict.FindString(kAccountInfoKeyAccountId); + if (account_id_str) { + account.account_id = CoreAccountId::FromString(*account_id_str); + } + CopyStringFromDict(account.gaia, dict, kAccountInfoKeyGaia); + CopyStringFromDict(account.email, dict, kAccountInfoKeyEmail); + CopyStringFromDict(account.full_name, dict, kAccountInfoKeyFullName); + CopyStringFromDict(account.given_name, dict, kAccountInfoKeyGivenName); + CopyStringFromDict(account.picture_url, dict, kAccountInfoKeyPictureUrl); + return account; +} + +} // namespace + NSArray* GetScopeArray(const std::set<std::string>& scopes) { NSMutableArray* scopes_array = [[NSMutableArray alloc] init]; for (const auto& scope : scopes) { @@ -63,14 +102,29 @@ return is_first_session_after_device_restore; } -void StorePreRestoreIdentity(AccountInfo account) { +void StorePreRestoreIdentity(PrefService* local_state, AccountInfo account) { g_pre_restore_identity = account; + ScopedDictPrefUpdate update(local_state, prefs::kIosPreRestoreAccountInfo); + update->Set(kAccountInfoKeyAccountId, account.account_id.ToString()); + update->Set(kAccountInfoKeyGaia, account.gaia); + update->Set(kAccountInfoKeyEmail, account.email); + update->Set(kAccountInfoKeyFullName, account.full_name); + update->Set(kAccountInfoKeyGivenName, account.given_name); + update->Set(kAccountInfoKeyPictureUrl, account.picture_url); } -void ClearPreRestoreIdentity() { +void ClearPreRestoreIdentity(PrefService* local_state) { g_pre_restore_identity.reset(); + local_state->ClearPref(prefs::kIosPreRestoreAccountInfo); } -absl::optional<AccountInfo> GetPreRestoreIdentity() { +absl::optional<AccountInfo> GetPreRestoreIdentity(PrefService* local_state) { + if (!g_pre_restore_identity.has_value()) { + const base::Value::Dict& dict = + local_state->GetDict(prefs::kIosPreRestoreAccountInfo); + if (!dict.empty()) { + g_pre_restore_identity = DictToAccountInfo(dict); + } + } return g_pre_restore_identity; }
diff --git a/ios/chrome/browser/signin/signin_util_unittest.mm b/ios/chrome/browser/signin/signin_util_unittest.mm new file mode 100644 index 0000000..e2a8569 --- /dev/null +++ b/ios/chrome/browser/signin/signin_util_unittest.mm
@@ -0,0 +1,86 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/signin/signin_util.h" + +#import "components/prefs/pref_registry_simple.h" +#import "components/prefs/testing_pref_service.h" +#import "google_apis/gaia/core_account_id.h" +#import "ios/chrome/browser/prefs/pref_names.h" +#import "testing/platform_test.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +class SigninUtilTest : public PlatformTest { + public: + explicit SigninUtilTest() { + local_state_.registry()->RegisterDictionaryPref( + prefs::kIosPreRestoreAccountInfo); + } + + AccountInfo FakeAccountFull() { + AccountInfo account; + account.account_id = CoreAccountId::FromString("account_id"); + account.gaia = "gaia"; + account.email = "person@example.org"; + account.full_name = "Full Name"; + account.given_name = "Given Name"; + account.picture_url = "https://example.org/path"; + return account; + } + + AccountInfo FakeAccountMinimal() { + AccountInfo account; + account.gaia = "gaia"; + account.email = "person@example.org"; + return account; + } + + void ExpectEqualAccountFields(const AccountInfo& a, const AccountInfo& b) { + EXPECT_EQ(a.account_id, b.account_id); + EXPECT_EQ(a.gaia, b.gaia); + EXPECT_EQ(a.email, b.email); + EXPECT_EQ(a.full_name, b.full_name); + EXPECT_EQ(a.given_name, b.given_name); + EXPECT_EQ(a.picture_url, b.picture_url); + } + + TestingPrefServiceSimple local_state_; +}; + +TEST_F(SigninUtilTest, StoreAndGetPreRestoreIdentityFull) { + ClearPreRestoreIdentity(&local_state_); + EXPECT_FALSE(GetPreRestoreIdentity(&local_state_).has_value()); + + AccountInfo account = FakeAccountFull(); + StorePreRestoreIdentity(&local_state_, account); + + // Verify that the retrieved account info is the same as what was stored. + auto retrieved_account = GetPreRestoreIdentity(&local_state_); + EXPECT_TRUE(retrieved_account.has_value()); + ExpectEqualAccountFields(account, retrieved_account.value()); +} + +TEST_F(SigninUtilTest, StoreAndGetPreRestoreIdentityMinimal) { + ClearPreRestoreIdentity(&local_state_); + EXPECT_FALSE(GetPreRestoreIdentity(&local_state_).has_value()); + + AccountInfo account = FakeAccountMinimal(); + StorePreRestoreIdentity(&local_state_, account); + + // Verify that the retrieved account info is the same as what was stored. + auto retrieved_account = GetPreRestoreIdentity(&local_state_); + EXPECT_TRUE(retrieved_account.has_value()); + ExpectEqualAccountFields(account, retrieved_account.value()); +} + +TEST_F(SigninUtilTest, ClearPreRestoreIdentity) { + StorePreRestoreIdentity(&local_state_, FakeAccountFull()); + EXPECT_TRUE(GetPreRestoreIdentity(&local_state_).has_value()); + + ClearPreRestoreIdentity(&local_state_); + EXPECT_FALSE(GetPreRestoreIdentity(&local_state_).has_value()); +}
diff --git a/ios/chrome/browser/ui/authentication/tangible_sync/BUILD.gn b/ios/chrome/browser/ui/authentication/tangible_sync/BUILD.gn index 308b4103..70eee39 100644 --- a/ios/chrome/browser/ui/authentication/tangible_sync/BUILD.gn +++ b/ios/chrome/browser/ui/authentication/tangible_sync/BUILD.gn
@@ -26,7 +26,6 @@ "//ios/chrome/browser/first_run", "//ios/chrome/browser/main:public", "//ios/chrome/browser/signin", - "//ios/chrome/browser/signin:constants", "//ios/chrome/browser/sync", "//ios/chrome/browser/ui/authentication", "//ios/chrome/browser/ui/authentication/signin",
diff --git a/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_coordinator.h b/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_coordinator.h index 7fb5e528..90384ee 100644 --- a/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_coordinator.h +++ b/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_coordinator.h
@@ -5,7 +5,7 @@ #ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_TANGIBLE_SYNC_TANGIBLE_SYNC_COORDINATOR_H_ #define IOS_CHROME_BROWSER_UI_AUTHENTICATION_TANGIBLE_SYNC_TANGIBLE_SYNC_COORDINATOR_H_ -#import "ios/chrome/browser/signin/constants.h" +#import "base/ios/block_types.h" #import "ios/chrome/browser/ui/first_run/interruptible_chrome_coordinator.h" // Coordinator for tangible sync view. The current implementation supports only @@ -13,8 +13,7 @@ @interface TangibleSyncCoordinator : InterruptibleChromeCoordinator // Completion block called once the dialog can be closed. -// `success` if YES, the user is syncing. -@property(nonatomic, copy) signin_ui::CompletionCallback coordinatorCompleted; +@property(nonatomic, copy) ProceduralBlock coordinatorCompleted; // TODO(crbug.com/1363812): Need to support to present as a modal dialog. - (instancetype)initWithBaseViewController:(UIViewController*)viewController
diff --git a/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_coordinator.mm b/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_coordinator.mm index 0be13f7..0376ecd 100644 --- a/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_coordinator.mm +++ b/ios/chrome/browser/ui/authentication/tangible_sync/tangible_sync_coordinator.mm
@@ -135,14 +135,14 @@ "FirstRun.Stage", first_run::kTangibleSyncScreenCompletionWithSync); } DCHECK(self.coordinatorCompleted); - self.coordinatorCompleted(YES); + self.coordinatorCompleted(); self.coordinatorCompleted = nil; } } - (void)tangibleSyncMediatorUserRemoved:(TangibleSyncMediator*)mediator { DCHECK(self.coordinatorCompleted); - self.coordinatorCompleted(NO); + self.coordinatorCompleted(); self.coordinatorCompleted = nil; } @@ -169,7 +169,7 @@ // sync as requested. syncService->StopAndClear(); DCHECK(self.coordinatorCompleted); - self.coordinatorCompleted(NO); + self.coordinatorCompleted(); self.coordinatorCompleted = nil; }
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/ui/browser_view/BUILD.gn index ac02fac9..57105997 100644 --- a/ios/chrome/browser/ui/browser_view/BUILD.gn +++ b/ios/chrome/browser/ui/browser_view/BUILD.gn
@@ -298,7 +298,6 @@ "//ios/chrome/browser/ui/toolbar", "//ios/chrome/browser/ui/toolbar/public", "//ios/chrome/browser/ui/toolbar/test", - "//ios/chrome/browser/ui/util", "//ios/chrome/browser/url_loading:url_loading", "//ios/chrome/browser/web", "//ios/chrome/browser/web:delegate",
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 99c1382..096ebd7a 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -133,6 +133,7 @@ #import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/common/ui/promo_style/promo_style_view_controller.h" #import "ios/chrome/common/ui/util/constraints_ui_util.h" +#import "ios/chrome/common/ui/util/ui_util.h" #import "ios/chrome/grit/ios_strings.h" #import "ios/components/webui/web_ui_url_constants.h" #import "ios/public/provider/chrome/browser/fullscreen/fullscreen_api.h"
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm index c4c54f2..990251b 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
@@ -50,7 +50,6 @@ #import "ios/chrome/browser/ui/toolbar/primary_toolbar_coordinator.h" #import "ios/chrome/browser/ui/toolbar/secondary_toolbar_coordinator.h" #import "ios/chrome/browser/ui/toolbar/toolbar_coordinator_adaptor.h" -#import "ios/chrome/browser/ui/util/ui_util.h" #import "ios/chrome/browser/url_loading/url_loading_notifier_browser_agent.h" #import "ios/chrome/browser/web/web_navigation_browser_agent.h" #import "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h"
diff --git a/ios/chrome/browser/ui/first_run/tangible_sync/tangible_sync_screen_coordinator.mm b/ios/chrome/browser/ui/first_run/tangible_sync/tangible_sync_screen_coordinator.mm index c558442d..b39f011 100644 --- a/ios/chrome/browser/ui/first_run/tangible_sync/tangible_sync_screen_coordinator.mm +++ b/ios/chrome/browser/ui/first_run/tangible_sync/tangible_sync_screen_coordinator.mm
@@ -78,8 +78,8 @@ initFirstRunWithBaseNavigationController:self.baseNavigationController browser:self.browser]; __weak __typeof(self) weakSelf = self; - _tangibleSyncCoordinator.coordinatorCompleted = ^(bool success) { - [weakSelf tangibleSyncCoordinatorCompletedWithSuccess:success]; + _tangibleSyncCoordinator.coordinatorCompleted = ^() { + [weakSelf tangibleSyncCoordinatorCompleted]; }; [_tangibleSyncCoordinator start]; } @@ -94,13 +94,9 @@ #pragma mark - Private -// Dismisses the current screen, and stops the FRE if `success` is `false`. -- (void)tangibleSyncCoordinatorCompletedWithSuccess:(bool)success { - if (success) { - [_delegate screenWillFinishPresenting]; - } else { - [_delegate skipAllScreens]; - } +// Dismisses the current screen. +- (void)tangibleSyncCoordinatorCompleted { + [_delegate screenWillFinishPresenting]; } @end
diff --git a/ios/chrome/browser/ui/lens/BUILD.gn b/ios/chrome/browser/ui/lens/BUILD.gn index 4d6b5f0..22f98fb 100644 --- a/ios/chrome/browser/ui/lens/BUILD.gn +++ b/ios/chrome/browser/ui/lens/BUILD.gn
@@ -7,6 +7,8 @@ sources = [ "lens_coordinator.h", "lens_coordinator.mm", + "lens_modal_animator.h", + "lens_modal_animator.mm", ] deps = [ ":lens_entrypoint",
diff --git a/ios/chrome/browser/ui/lens/lens_coordinator.mm b/ios/chrome/browser/ui/lens/lens_coordinator.mm index 1536880..90d00db 100644 --- a/ios/chrome/browser/ui/lens/lens_coordinator.mm +++ b/ios/chrome/browser/ui/lens/lens_coordinator.mm
@@ -16,6 +16,7 @@ #import "ios/chrome/browser/ui/commands/search_image_with_lens_command.h" #import "ios/chrome/browser/ui/commands/toolbar_commands.h" #import "ios/chrome/browser/ui/lens/lens_entrypoint.h" +#import "ios/chrome/browser/ui/lens/lens_modal_animator.h" #import "ios/chrome/browser/url_loading/url_loading_browser_agent.h" #import "ios/chrome/browser/url_loading/url_loading_params.h" #import "ios/chrome/browser/web/web_navigation_util.h" @@ -44,6 +45,9 @@ // The Lens viewController. @property(nonatomic, strong) UIViewController* viewController; +// The animator for dismissing the Lens view. +@property(nonatomic, strong) LensModalAnimator* transitionAnimator; + // Whether or not a Lens Web page load was triggered from the Lens UI. @property(nonatomic, assign) BOOL lensWebPageLoadTriggeredFromInputSelection; @@ -103,6 +107,7 @@ self.loadingWebState = nil; self.lensWebPageLoadTriggeredFromInputSelection = NO; + self.transitionAnimator = [[LensModalAnimator alloc] init]; _webStateListObservation->Observe(browser->GetWebStateList()); } @@ -112,6 +117,7 @@ [self dismissViewController]; self.loadingWebState = nullptr; + self.transitionAnimator = nil; self.lensWebPageLoadTriggeredFromInputSelection = NO; _webStateListObservation.reset(); @@ -188,6 +194,12 @@ self.viewController = viewController; + // Set the transitioning delegate of the view controller to customize + // modal dismiss animations. + const LensModalAnimator* transitionAnimator = self.transitionAnimator; + DCHECK(transitionAnimator); + [viewController setTransitioningDelegate:transitionAnimator]; + [viewController setModalPresentationStyle:UIModalPresentationOverCurrentContext];
diff --git a/ios/chrome/browser/ui/lens/lens_entrypoint.h b/ios/chrome/browser/ui/lens/lens_entrypoint.h index 063c106d..ca347e67 100644 --- a/ios/chrome/browser/ui/lens/lens_entrypoint.h +++ b/ios/chrome/browser/ui/lens/lens_entrypoint.h
@@ -13,7 +13,11 @@ HomeScreenWidget = 1, NewTabPage = 2, Keyboard = 3, - kMaxValue = Keyboard, + Spotlight = 4, + OmniboxPostCapture = 5, + ImageShareMenu = 6, + AppIconLongPress = 7, + kMaxValue = AppIconLongPress, }; extern const char kIOSLensEntrypoint[];
diff --git a/ios/chrome/browser/ui/lens/lens_modal_animator.h b/ios/chrome/browser/ui/lens/lens_modal_animator.h new file mode 100644 index 0000000..43da32b --- /dev/null +++ b/ios/chrome/browser/ui/lens/lens_modal_animator.h
@@ -0,0 +1,15 @@ +// Copyright 2022 The Chromium Authors +// 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_LENS_LENS_MODAL_ANIMATOR_H_ +#define IOS_CHROME_BROWSER_UI_LENS_LENS_MODAL_ANIMATOR_H_ + +#import <UIKit/UIKit.h> + +@interface LensModalAnimator : NSObject <UIViewControllerTransitioningDelegate, + UIViewControllerAnimatedTransitioning> + +@end + +#endif // IOS_CHROME_BROWSER_UI_LENS_LENS_MODAL_ANIMATOR_H_
diff --git a/ios/chrome/browser/ui/lens/lens_modal_animator.mm b/ios/chrome/browser/ui/lens/lens_modal_animator.mm new file mode 100644 index 0000000..4b01e51 --- /dev/null +++ b/ios/chrome/browser/ui/lens/lens_modal_animator.mm
@@ -0,0 +1,88 @@ +// Copyright 2022 The Chromium Authors +// 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/lens/lens_modal_animator.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +// The time it takes for the animation to complete. +static const CGFloat kTransitionAnimationDuration = .4; + +@interface LensModalAnimator () + +@end + +@implementation LensModalAnimator + +#pragma mark - UIViewControllerTransitioningDelegate + +- (id<UIViewControllerInteractiveTransitioning>) + interactionControllerForPresentation: + (id<UIViewControllerAnimatedTransitioning>)animator { + return nil; +} + +- (id<UIViewControllerInteractiveTransitioning>) + interactionControllerForDismissal: + (id<UIViewControllerAnimatedTransitioning>)animator { + return nil; +} + +- (id<UIViewControllerAnimatedTransitioning>) + animationControllerForPresentedController:(UIViewController*)presented + presentingController:(UIViewController*)presenting + sourceController:(UIViewController*)source { + return nil; +} + +- (id<UIViewControllerAnimatedTransitioning>) + animationControllerForDismissedController:(UIViewController*)dismissed { + // Only use this transitioning delegate for Lens modal dismissal. + return self; +} + +#pragma mark - UIViewControllerAnimatedTransitioning + +- (NSTimeInterval)transitionDuration: + (id<UIViewControllerContextTransitioning>)transitionContext { + return kTransitionAnimationDuration; +} + +- (void)animateTransition: + (id<UIViewControllerContextTransitioning>)transitionContext { + // This animator will only be used when dismissing Lens. + UIView* containerView = [transitionContext containerView]; + UIView* toView = [transitionContext viewForKey:UITransitionContextToViewKey]; + UIView* lensView = + [transitionContext viewForKey:UITransitionContextFromViewKey]; + + // Create and add a Lens view snapshot. + UIView* lensViewSnapshot = [lensView snapshotViewAfterScreenUpdates:YES]; + + [containerView addSubview:toView]; + [containerView addSubview:lensViewSnapshot]; + [lensView removeFromSuperview]; + [containerView bringSubviewToFront:lensViewSnapshot]; + + lensViewSnapshot.alpha = 1.0; + + [UIView animateWithDuration:[self transitionDuration:transitionContext] + animations:^{ + lensViewSnapshot.alpha = 0.0; + } + + completion:^(BOOL finished) { + BOOL success = ![transitionContext transitionWasCancelled]; + + if (success) { + [lensViewSnapshot removeFromSuperview]; + } + + [transitionContext completeTransition:success]; + }]; +} + +@end
diff --git a/ios/chrome/browser/ui/ntp/ntp_tile_saver_unittest.mm b/ios/chrome/browser/ui/ntp/ntp_tile_saver_unittest.mm index 12542c9..d7676ccd 100644 --- a/ios/chrome/browser/ui/ntp/ntp_tile_saver_unittest.mm +++ b/ios/chrome/browser/ui/ntp/ntp_tile_saver_unittest.mm
@@ -53,6 +53,14 @@ UIImage* CreateMockImage(UIColor* color) { mock_image_ = ui::test::uiimage_utils::UIImageWithSizeAndSolidColor( CGSizeMake(10, 10), color); + if (@available(iOS 16.1, *)) { + // Save the image to disk and reload it. + NSData* image_data = UIImagePNGRepresentation(mock_image_); + NSURL* mock_image_url = [NSFileManager.defaultManager.temporaryDirectory + URLByAppendingPathComponent:@"mock_image"]; + [image_data writeToURL:mock_image_url atomically:YES]; + mock_image_ = [UIImage imageWithContentsOfFile:mock_image_url.path]; + } return mock_image_; }
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn index f7d33b1..9a6f145 100644 --- a/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn
@@ -64,6 +64,7 @@ "//components/translate/core/browser", "//ios/chrome/app/strings", "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/commerce", "//ios/chrome/browser/find_in_page", "//ios/chrome/browser/follow:browser_agent", "//ios/chrome/browser/follow:enums",
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm index 0b2d9c1..0a4a6db 100644 --- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm +++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
@@ -23,6 +23,7 @@ #import "components/translate/core/browser/translate_manager.h" #import "components/translate/core/browser/translate_prefs.h" #import "ios/chrome/browser/browser_state/chrome_browser_state.h" +#import "ios/chrome/browser/commerce/price_alert_util.h" #import "ios/chrome/browser/find_in_page/find_tab_helper.h" #import "ios/chrome/browser/follow/follow_browser_agent.h" #import "ios/chrome/browser/follow/follow_menu_updater.h" @@ -224,6 +225,7 @@ @property(nonatomic, strong) OverflowMenuAction* addBookmarkAction; @property(nonatomic, strong) OverflowMenuAction* editBookmarkAction; @property(nonatomic, strong) OverflowMenuAction* readLaterAction; +@property(nonatomic, strong) OverflowMenuAction* openPriceNotificationsAction; @property(nonatomic, strong) OverflowMenuAction* translateAction; @property(nonatomic, strong) OverflowMenuAction* requestDesktopAction; @property(nonatomic, strong) OverflowMenuAction* requestMobileAction; @@ -700,6 +702,12 @@ [weakSelf addToReadingList]; }); + self.openPriceNotificationsAction = CreateOverflowMenuAction( + IDS_IOS_PRICE_NOTIFICATIONS_OVERFLOW_MENU_TITLE, kDownTrendSymbol, YES, + kToolsMenuPriceNotifications, ^{ + [weakSelf openPriceNotifications]; + }); + self.translateAction = CreateOverflowMenuAction(IDS_IOS_TOOLS_MENU_TRANSLATE, kTranslateSymbol, NO, kToolsMenuTranslateId, ^{ @@ -804,6 +812,13 @@ [weakSelf addToReadingList]; }); + self.openPriceNotificationsAction = CreateOverflowMenuAction( + IDS_IOS_PRICE_NOTIFICATIONS_OVERFLOW_MENU_TITLE, + @"overflow_menu_action_price_notifications", + kToolsMenuPriceNotifications, ^{ + [weakSelf openPriceNotifications]; + }); + self.translateAction = CreateOverflowMenuAction( IDS_IOS_TOOLS_MENU_TRANSLATE, @"overflow_menu_action_translate", kToolsMenuTranslateId, ^{ @@ -1074,6 +1089,10 @@ self.readLaterAction ]]; + if (IsPriceNotificationsEnabled()) { + [pageActions addObject:self.openPriceNotificationsAction]; + } + // Clear Browsing Data Action is not relevant in incognito, so don't show it. // History is also hidden for similar reasons. if (IsNewOverflowMenuCBDActionEnabled() && !self.isIncognito) { @@ -1660,6 +1679,15 @@ showCancelButton:NO]; } +// Dismisses the menu and opens price notifications list. +- (void)openPriceNotifications { + RecordAction(UserMetricsAction("MobileMenuPriceNotifications")); + [self.popupMenuCommandsHandler dismissPopupMenuAnimated:YES]; + // TODO(crbug.com/1371166) Once the Price Notifications coordinator has + // been merged into the codebase, access that coordinator to display the + // Price Notifications UI. +} + // Dismisses the menu and opens downloads. - (void)openDownloads { [self.popupMenuCommandsHandler dismissPopupMenuAnimated:YES];
diff --git a/ios/chrome/browser/ui/post_restore_signin/BUILD.gn b/ios/chrome/browser/ui/post_restore_signin/BUILD.gn index d0006b1..74f8587 100644 --- a/ios/chrome/browser/ui/post_restore_signin/BUILD.gn +++ b/ios/chrome/browser/ui/post_restore_signin/BUILD.gn
@@ -26,6 +26,7 @@ ":features", "//base", "//ios/chrome/app/strings", + "//ios/chrome/browser/application_context", "//ios/chrome/browser/promos_manager:constants", "//ios/chrome/browser/signin:signin_util", "//ios/chrome/browser/ui/authentication:authentication_constants", @@ -53,6 +54,7 @@ "//base/test:test_support", "//ios/chrome/browser/signin:signin_util", "//ios/chrome/browser/ui/post_restore_signin:features", + "//ios/chrome/test:test_support", "//third_party/ocmock", "//ui/base", ]
diff --git a/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider.mm b/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider.mm index f486220236..3b67623 100644 --- a/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider.mm +++ b/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider.mm
@@ -9,6 +9,7 @@ #import "base/notreached.h" #import "base/strings/sys_string_conversions.h" #import "components/signin/public/identity_manager/account_info.h" +#import "ios/chrome/browser/application_context/application_context.h" #import "ios/chrome/browser/promos_manager/constants.h" #import "ios/chrome/browser/signin/signin_util.h" #import "ios/chrome/browser/ui/commands/show_signin_command.h" @@ -32,6 +33,9 @@ // Returns the given name of the last account that was signed in pre-restore. @property(readonly) NSString* userGivenName; +// Local state is used to retrieve and/or clear the pre-restore identity. +@property(nonatomic, assign) PrefService* localState; + @end @implementation PostRestoreSignInProvider { @@ -42,8 +46,10 @@ #pragma mark - Initializers - (instancetype)init { - if (self = [super init]) - _accountInfo = GetPreRestoreIdentity(); + if (self = [super init]) { + _localState = GetApplicationContext()->GetLocalState(); + _accountInfo = GetPreRestoreIdentity(_localState); + } return self; } @@ -91,6 +97,7 @@ - (void)standardPromoAlertCancelAction { base::UmaHistogramEnumeration(kIOSPostRestoreSigninChoiceHistogram, IOSPostRestoreSigninChoice::Dismiss); + ClearPreRestoreIdentity(_localState); } #pragma mark - StandardPromoAlertProvider @@ -162,6 +169,7 @@ - (void)standardPromoDismissAction { base::UmaHistogramEnumeration(kIOSPostRestoreSigninChoiceHistogram, IOSPostRestoreSigninChoice::Dismiss); + ClearPreRestoreIdentity(_localState); } #pragma mark - Internal @@ -187,6 +195,7 @@ base::UmaHistogramEnumeration(kIOSPostRestoreSigninChoiceHistogram, IOSPostRestoreSigninChoice::Continue); + ClearPreRestoreIdentity(_localState); ShowSigninCommand* command = [[ShowSigninCommand alloc] initWithOperation:AuthenticationOperationReauthenticate
diff --git a/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider_unittest.mm b/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider_unittest.mm index 59485b0..4426426 100644 --- a/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider_unittest.mm +++ b/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider_unittest.mm
@@ -11,6 +11,7 @@ #import "ios/chrome/browser/ui/commands/promos_manager_commands.h" #import "ios/chrome/browser/ui/post_restore_signin/features.h" #import "ios/chrome/browser/ui/post_restore_signin/metrics.h" +#import "ios/chrome/test/ios_chrome_scoped_testing_local_state.h" #import "testing/platform_test.h" #import "third_party/ocmock/OCMock/OCMock.h" #import "third_party/ocmock/gtest_support.h" @@ -39,13 +40,13 @@ accountInfo.email = std::string(kFakePreRestoreAccountEmail); accountInfo.given_name = std::string(kFakePreRestoreAccountGivenName); accountInfo.full_name = std::string(kFakePreRestoreAccountFullName); - StorePreRestoreIdentity(accountInfo); + StorePreRestoreIdentity(local_state_.Get(), accountInfo); } void ClearUserName() { AccountInfo accountInfo; accountInfo.email = std::string(kFakePreRestoreAccountEmail); - StorePreRestoreIdentity(accountInfo); + StorePreRestoreIdentity(local_state_.Get(), accountInfo); // Reinstantiate a provider so that it picks up the changes. provider_ = [[PostRestoreSignInProvider alloc] init]; } @@ -69,6 +70,7 @@ {}); } + IOSChromeScopedTestingLocalState local_state_; base::test::ScopedFeatureList scoped_feature_list_; id mock_handler_; PostRestoreSignInProvider* provider_; @@ -161,3 +163,24 @@ histogram_tester.ExpectBucketCount(kIOSPostRestoreSigninDisplayedHistogram, true, 1); } + +TEST_F(PostRestoreSignInProviderTest, clearsPreRestoreIdentity) { + // Test the Alert cancel. + SetFakePreRestoreAccountInfo(); + EXPECT_TRUE(GetPreRestoreIdentity(local_state_.Get()).has_value()); + [provider_ standardPromoAlertCancelAction]; + EXPECT_FALSE(GetPreRestoreIdentity(local_state_.Get()).has_value()); + + // Test the Fullscreen cancel. + SetFakePreRestoreAccountInfo(); + EXPECT_TRUE(GetPreRestoreIdentity(local_state_.Get()).has_value()); + [provider_ standardPromoDismissAction]; + EXPECT_FALSE(GetPreRestoreIdentity(local_state_.Get()).has_value()); + + // Test that it is cleared when the user chooses to sign in. + SetFakePreRestoreAccountInfo(); + EXPECT_TRUE(GetPreRestoreIdentity(local_state_.Get()).has_value()); + SetupMockHandler(); + [provider_ standardPromoAlertDefaultAction]; + EXPECT_FALSE(GetPreRestoreIdentity(local_state_.Get()).has_value()); +}
diff --git a/ios/chrome/browser/ui/tabs/BUILD.gn b/ios/chrome/browser/ui/tabs/BUILD.gn index ee00c59d7..7265cc3 100644 --- a/ios/chrome/browser/ui/tabs/BUILD.gn +++ b/ios/chrome/browser/ui/tabs/BUILD.gn
@@ -119,7 +119,6 @@ "//ios/chrome/browser/tabs", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/main:scene_state_header", - "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web_state_list", "//ios/chrome/browser/web_state_list:test_support", "//ios/web/public",
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm index fabfd79..08ebdc9 100644 --- a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm +++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
@@ -55,6 +55,7 @@ #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h" #import "ios/chrome/browser/web_state_list/web_state_opener.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" +#import "ios/chrome/common/ui/util/ui_util.h" #import "ios/chrome/grit/ios_strings.h" #import "ios/public/provider/chrome/browser/fullscreen/fullscreen_api.h" #import "ios/web/public/navigation/navigation_manager.h"
diff --git a/ios/chrome/test/providers/BUILD.gn b/ios/chrome/test/providers/BUILD.gn index f914ab0..9dd6d42 100644 --- a/ios/chrome/test/providers/BUILD.gn +++ b/ios/chrome/test/providers/BUILD.gn
@@ -23,6 +23,7 @@ "//ios/chrome/test/providers/omaha", "//ios/chrome/test/providers/overrides", "//ios/chrome/test/providers/password_auto_fill", + "//ios/chrome/test/providers/primes", "//ios/chrome/test/providers/push_notification", "//ios/chrome/test/providers/risk_data", "//ios/chrome/test/providers/signin",
diff --git a/ios/chrome/test/providers/primes/BUILD.gn b/ios/chrome/test/providers/primes/BUILD.gn new file mode 100644 index 0000000..237ad170 --- /dev/null +++ b/ios/chrome/test/providers/primes/BUILD.gn
@@ -0,0 +1,13 @@ +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("primes") { + testonly = true + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ "test_primes.mm" ] + deps = [ + "//base", + "//ios/public/provider/chrome/browser/primes:primes_api", + ] +}
diff --git a/ios/chrome/test/providers/primes/test_primes.mm b/ios/chrome/test/providers/primes/test_primes.mm new file mode 100644 index 0000000..f7d2d0e --- /dev/null +++ b/ios/chrome/test/providers/primes/test_primes.mm
@@ -0,0 +1,31 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "base/notreached.h" +#import "ios/public/provider/chrome/browser/primes/primes_api.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace ios { +namespace provider { + +bool IsPrimesSupported() { + // Primes is not supported for tests. + return false; +} + +void PrimesStartLogging() { + // Primes is not supported for tests. + NOTREACHED(); +} + +void PrimesStopLogging() { + // Primes is not supported for tests. + NOTREACHED(); +} + +} // namespace provider +} // namespace ios
diff --git a/ios/public/provider/chrome/browser/primes/BUILD.gn b/ios/public/provider/chrome/browser/primes/BUILD.gn new file mode 100644 index 0000000..2e40ded8 --- /dev/null +++ b/ios/public/provider/chrome/browser/primes/BUILD.gn
@@ -0,0 +1,9 @@ +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("primes_api") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ "primes_api.h" ] + deps = [ "//base" ] +}
diff --git a/ios/public/provider/chrome/browser/primes/primes_api.h b/ios/public/provider/chrome/browser/primes/primes_api.h new file mode 100644 index 0000000..3bcfeabf --- /dev/null +++ b/ios/public/provider/chrome/browser/primes/primes_api.h
@@ -0,0 +1,23 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_PUBLIC_PROVIDER_CHROME_BROWSER_PRIMES_PRIMES_API_H_ +#define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_PRIMES_PRIMES_API_H_ + +namespace ios { +namespace provider { + +// Returns whether Primes logging is supported +bool IsPrimesSupported(); + +// Start Primes logging +void PrimesStartLogging(); + +// Stop Primes logging +void PrimesStopLogging(); + +} // namespace provider +} // namespace ios + +#endif // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_PRIMES_PRIMES_API_H_
diff --git a/ios/web/init/web_main_runner.mm b/ios/web/init/web_main_runner.mm index 66b25d6a..5dde8012 100644 --- a/ios/web/init/web_main_runner.mm +++ b/ios/web/init/web_main_runner.mm
@@ -96,7 +96,7 @@ //////////////////////////////////////////////////////////////////// // ContentMainRunner::Shutdown() // - if (completed_basic_startup_ && delegate_) { + if (delegate_) { delegate_->ProcessExiting(); }
diff --git a/ipc/ipc_message_unittest.cc b/ipc/ipc_message_unittest.cc index 8208b0f..80dbdf1 100644 --- a/ipc/ipc_message_unittest.cc +++ b/ipc/ipc_message_unittest.cc
@@ -104,28 +104,6 @@ EXPECT_FALSE(IPC::ReadParam(&bad_msg, &iter, &output)); } -TEST(IPCMessageTest, ListValue) { - base::ListValue input; - input.GetList().Append(42.42); - input.GetList().Append("forty"); - input.GetList().Append(base::Value()); - - IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL); - IPC::WriteParam(&msg, input); - - base::ListValue output; - base::PickleIterator iter(msg); - EXPECT_TRUE(IPC::ReadParam(&msg, &iter, &output)); - - EXPECT_EQ(input, output); - - // Also test the corrupt case. - IPC::Message bad_msg(1, 2, IPC::Message::PRIORITY_NORMAL); - bad_msg.WriteInt(99); - iter = base::PickleIterator(bad_msg); - EXPECT_FALSE(IPC::ReadParam(&bad_msg, &iter, &output)); -} - TEST(IPCMessageTest, DictionaryValue) { base::DictionaryValue input; input.SetKey("null", base::Value());
diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc index 9c0d759..21a3837 100644 --- a/ipc/ipc_message_utils.cc +++ b/ipc/ipc_message_utils.cc
@@ -1175,22 +1175,6 @@ ParamTraits<base::FilePath::StringType>::Log(p.value(), l); } -void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) { - WriteListValue(p.GetList(), 0, m); -} - -bool ParamTraits<base::ListValue>::Read(const base::Pickle* m, - base::PickleIterator* iter, - param_type* r) { - return ReadListValue(m, iter, 0, &(r->GetList())); -} - -void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) { - std::string json; - base::JSONWriter::Write(p, &json); - l->append(json); -} - void ParamTraits<base::Value::List>::Write(base::Pickle* m, const param_type& p) { WriteListValue(p, 0, m);
diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h index f723a05f..7a6422c 100644 --- a/ipc/ipc_message_utils.h +++ b/ipc/ipc_message_utils.h
@@ -724,16 +724,6 @@ }; template <> -struct COMPONENT_EXPORT(IPC) ParamTraits<base::ListValue> { - typedef base::ListValue param_type; - static void Write(base::Pickle* m, const param_type& p); - static bool Read(const base::Pickle* m, - base::PickleIterator* iter, - param_type* r); - static void Log(const param_type& p, std::string* l); -}; - -template <> struct COMPONENT_EXPORT(IPC) ParamTraits<base::Value::List> { typedef base::Value::List param_type; static void Write(base::Pickle* m, const param_type& p);
diff --git a/ipc/ipc_message_utils_unittest.cc b/ipc/ipc_message_utils_unittest.cc index 0b760f3..5eaff72 100644 --- a/ipc/ipc_message_utils_unittest.cc +++ b/ipc/ipc_message_utils_unittest.cc
@@ -271,20 +271,6 @@ EXPECT_EQ(dict_value, read_value); } -TEST(IPCMessageUtilsTest, LegacyListValueConversion) { - base::ListValue list_value; - list_value.Append(42); - list_value.Append(84); - - IPC::Message message; - ParamTraits<base::ListValue>::Write(&message, list_value); - - base::PickleIterator iter(message); - base::ListValue read_value; - ASSERT_TRUE(ParamTraits<base::ListValue>::Read(&message, &iter, &read_value)); - EXPECT_EQ(list_value, read_value); -} - TEST(IPCMessageUtilsTest, ListValueConversion) { base::Value::List list_value; list_value.Append(42);
diff --git a/media/capture/video_capture_types.h b/media/capture/video_capture_types.h index 351b2c7..e6d8961 100644 --- a/media/capture/video_capture_types.h +++ b/media/capture/video_capture_types.h
@@ -287,11 +287,17 @@ // format of frames in which the client would like to have captured frames // returned. struct CAPTURE_EXPORT VideoCaptureParams { - // Result struct for SuggestContraints() method. + // Result struct for SuggestConstraints() method. struct SuggestedConstraints { gfx::Size min_frame_size; gfx::Size max_frame_size; bool fixed_aspect_ratio; + + bool operator==(const SuggestedConstraints& other) const { + return min_frame_size == other.min_frame_size && + max_frame_size == other.max_frame_size && + fixed_aspect_ratio == other.fixed_aspect_ratio; + } }; VideoCaptureParams();
diff --git a/net/base/network_delegate.cc b/net/base/network_delegate.cc index faeefe0..e119ca3d7 100644 --- a/net/base/network_delegate.cc +++ b/net/base/network_delegate.cc
@@ -103,11 +103,13 @@ bool NetworkDelegate::AnnotateAndMoveUserBlockedCookies( const URLRequest& request, + const net::FirstPartySetMetadata& first_party_set_metadata, net::CookieAccessResultList& maybe_included_cookies, net::CookieAccessResultList& excluded_cookies) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); bool allowed = OnAnnotateAndMoveUserBlockedCookies( - request, maybe_included_cookies, excluded_cookies); + request, first_party_set_metadata, maybe_included_cookies, + excluded_cookies); cookie_util::DCheckIncludedAndExcludedCookieLists(maybe_included_cookies, excluded_cookies); return allowed;
diff --git a/net/base/network_delegate.h b/net/base/network_delegate.h index bb5f752..1012d26 100644 --- a/net/base/network_delegate.h +++ b/net/base/network_delegate.h
@@ -19,6 +19,7 @@ #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_inclusion_status.h" #include "net/cookies/site_for_cookies.h" +#include "net/first_party_sets/first_party_set_metadata.h" #include "net/first_party_sets/first_party_sets_cache_filter.h" #include "net/first_party_sets/same_party_context.h" #include "net/proxy_resolution/proxy_retry_info.h" @@ -80,6 +81,7 @@ void NotifyPACScriptError(int line_number, const std::u16string& error); bool AnnotateAndMoveUserBlockedCookies( const URLRequest& request, + const net::FirstPartySetMetadata& first_party_set_metadata, CookieAccessResultList& maybe_included_cookies, CookieAccessResultList& excluded_cookies); bool CanSetCookie(const URLRequest& request, @@ -262,6 +264,7 @@ // otherwise. virtual bool OnAnnotateAndMoveUserBlockedCookies( const URLRequest& request, + const net::FirstPartySetMetadata& first_party_set_metadata, net::CookieAccessResultList& maybe_included_cookies, net::CookieAccessResultList& excluded_cookies) = 0;
diff --git a/net/base/network_delegate_impl.cc b/net/base/network_delegate_impl.cc index 5fe976b..5654641 100644 --- a/net/base/network_delegate_impl.cc +++ b/net/base/network_delegate_impl.cc
@@ -50,6 +50,7 @@ bool NetworkDelegateImpl::OnAnnotateAndMoveUserBlockedCookies( const URLRequest& request, + const net::FirstPartySetMetadata& first_party_set_metadata, net::CookieAccessResultList& maybe_included_cookies, net::CookieAccessResultList& excluded_cookies) { return true;
diff --git a/net/base/network_delegate_impl.h b/net/base/network_delegate_impl.h index 2c1b348c..071dec1 100644 --- a/net/base/network_delegate_impl.h +++ b/net/base/network_delegate_impl.h
@@ -14,6 +14,7 @@ #include "net/base/net_export.h" #include "net/base/network_delegate.h" #include "net/cookies/canonical_cookie.h" +#include "net/first_party_sets/first_party_set_metadata.h" #include "net/first_party_sets/first_party_sets_cache_filter.h" #include "net/first_party_sets/same_party_context.h" #include "net/proxy_resolution/proxy_retry_info.h" @@ -70,6 +71,7 @@ bool OnAnnotateAndMoveUserBlockedCookies( const URLRequest& request, + const net::FirstPartySetMetadata& first_party_set_metadata, net::CookieAccessResultList& maybe_included_cookies, net::CookieAccessResultList& excluded_cookies) override;
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc index 38dd261..0fadd0c 100644 --- a/net/cert/cert_verify_proc_unittest.cc +++ b/net/cert/cert_verify_proc_unittest.cc
@@ -2896,7 +2896,7 @@ std::string issuer_cn = CertBuilder::MakeRandomHexString(12); leaf->SetIssuerTLV(CertBuilder::BuildNameWithCommonNameOfType( issuer_cn, CBS_ASN1_PRINTABLESTRING)); - intermediate->SetSubject(CertBuilder::BuildNameWithCommonNameOfType( + intermediate->SetSubjectTLV(CertBuilder::BuildNameWithCommonNameOfType( issuer_cn, CBS_ASN1_UTF8STRING)); ScopedTestRoot scoped_root(root->GetX509Certificate().get()); @@ -2934,7 +2934,7 @@ std::string issuer_hex = CertBuilder::MakeRandomHexString(12); leaf->SetIssuerTLV(CertBuilder::BuildNameWithCommonNameOfType( "Z" + issuer_hex, CBS_ASN1_PRINTABLESTRING)); - intermediate->SetSubject(CertBuilder::BuildNameWithCommonNameOfType( + intermediate->SetSubjectTLV(CertBuilder::BuildNameWithCommonNameOfType( "z" + issuer_hex, CBS_ASN1_PRINTABLESTRING)); ScopedTestRoot scoped_root(root->GetX509Certificate().get()); @@ -2960,7 +2960,7 @@ std::string issuer_hex = CertBuilder::MakeRandomHexString(12); leaf->SetIssuerTLV(CertBuilder::BuildNameWithCommonNameOfType( issuer_hex, CBS_ASN1_PRINTABLESTRING)); - intermediate->SetSubject(CertBuilder::BuildNameWithCommonNameOfType( + intermediate->SetSubjectTLV(CertBuilder::BuildNameWithCommonNameOfType( issuer_hex, CBS_ASN1_PRINTABLESTRING)); ScopedTestRoot scoped_root(root->GetX509Certificate().get());
diff --git a/net/cert/internal/system_trust_store.cc b/net/cert/internal/system_trust_store.cc index 970fb825..1ebd921 100644 --- a/net/cert/internal/system_trust_store.cc +++ b/net/cert/internal/system_trust_store.cc
@@ -287,7 +287,7 @@ TrustStoreMac::TrustImplType::kDomainCacheFullCerts; static base::NoDestructor<TrustStoreMac> static_trust_store_mac( kSecPolicyAppleSSL, GetTrustStoreImplParam(kDefaultMacTrustImplForCRS), - GetTrustStoreCacheSize(), TrustStoreMac::TrustDomains::kUserAndAdmin); + GetTrustStoreCacheSize()); return static_trust_store_mac.get(); }
diff --git a/net/cert/internal/trust_store_mac.cc b/net/cert/internal/trust_store_mac.cc index d76cce9..121fcb4 100644 --- a/net/cert/internal/trust_store_mac.cc +++ b/net/cert/internal/trust_store_mac.cc
@@ -23,7 +23,6 @@ #include "crypto/mac_security_services_lock.h" #include "net/base/hash_value.h" #include "net/base/network_notification_thread_mac.h" -#include "net/cert/known_roots_mac.h" #include "net/cert/pki/cert_errors.h" #include "net/cert/pki/cert_issuer_source_static.h" #include "net/cert/pki/extended_key_usage.h" @@ -54,12 +53,6 @@ DISTRUSTED }; -enum class KnownRootStatus { - UNKNOWN, - IS_KNOWN_ROOT, - NOT_KNOWN_ROOT, -}; - const void* kResultDebugDataKey = &kResultDebugDataKey; // Returns trust status of usage constraints dictionary |trust_dict| for a @@ -273,35 +266,9 @@ cert_handle, is_self_issued, policy_oid, trust_domain, debug_info); } -KnownRootStatus IsCertificateKnownRoot(const ParsedCertificate* cert) { - base::ScopedCFTypeRef<SecCertificateRef> cert_handle = - x509_util::CreateSecCertificateFromBytes(cert->der_cert().UnsafeData(), - cert->der_cert().Length()); - if (!cert_handle) - return KnownRootStatus::NOT_KNOWN_ROOT; - - base::ScopedCFTypeRef<CFArrayRef> trust_settings; - OSStatus err; - { - base::AutoLock lock(crypto::GetMacSecurityServicesLock()); - err = SecTrustSettingsCopyTrustSettings(cert_handle, - kSecTrustSettingsDomainSystem, - trust_settings.InitializeInto()); - } - return (err == errSecSuccess) ? KnownRootStatus::IS_KNOWN_ROOT - : KnownRootStatus::NOT_KNOWN_ROOT; -} - TrustStatus IsCertificateTrustedForPolicy(const ParsedCertificate* cert, const CFStringRef policy_oid, - TrustStoreMac::TrustDomains domains, - int* debug_info, - KnownRootStatus* out_is_known_root) { - // |*out_is_known_root| is intentionally not cleared before starting, as - // there may have been a value already calculated and cached independently. - // The caller is expected to initialize |*out_is_known_root| to UNKNOWN if - // the value has not been calculated. - + int* debug_info) { base::ScopedCFTypeRef<SecCertificateRef> cert_handle = x509_util::CreateSecCertificateFromBytes(cert->der_cert().UnsafeData(), cert->der_cert().Length()); @@ -311,15 +278,10 @@ const bool is_self_issued = cert->normalized_subject() == cert->normalized_issuer(); - // Evaluate trust domains in user, admin, system order. Admin settings can - // override system ones, and user settings can override both admin and system. + // Evaluate user trust domain, then admin. User settings can override + // admin (and both override the system domain, but we don't check that). for (const auto& trust_domain : - {kSecTrustSettingsDomainUser, kSecTrustSettingsDomainAdmin, - kSecTrustSettingsDomainSystem}) { - if (domains == TrustStoreMac::TrustDomains::kUserAndAdmin && - trust_domain == kSecTrustSettingsDomainSystem) { - continue; - } + {kSecTrustSettingsDomainUser, kSecTrustSettingsDomainAdmin}) { base::ScopedCFTypeRef<CFArrayRef> trust_settings; OSStatus err; { @@ -328,11 +290,6 @@ trust_settings.InitializeInto()); } if (err != errSecSuccess) { - if (out_is_known_root && trust_domain == kSecTrustSettingsDomainSystem) { - // If trust settings are not present for |cert| in the system domain, - // record it as not a known root. - *out_is_known_root = KnownRootStatus::NOT_KNOWN_ROOT; - } if (err == errSecItemNotFound) { // No trust settings for that domain.. try the next. continue; @@ -341,11 +298,6 @@ *debug_info |= TrustStoreMac::COPY_TRUST_SETTINGS_ERROR; continue; } - if (out_is_known_root && trust_domain == kSecTrustSettingsDomainSystem) { - // If trust settings are present for |cert| in the system domain, record - // it as a known root. - *out_is_known_root = KnownRootStatus::IS_KNOWN_ROOT; - } TrustStatus trust = IsTrustSettingsTrustedForPolicy( trust_settings, is_self_issued, policy_oid, debug_info); if (trust != TrustStatus::UNSPECIFIED) @@ -571,7 +523,7 @@ domain_name = "Admin"; break; case kSecTrustSettingsDomainSystem: - domain_name = "System"; + NOTREACHED(); break; } base::UmaHistogramCounts1000( @@ -751,7 +703,6 @@ public: virtual ~TrustImpl() = default; - virtual bool IsKnownRoot(const ParsedCertificate* cert) = 0; virtual TrustStatus IsCertTrusted(const ParsedCertificate* cert, base::SupportsUserData* debug_data) = 0; virtual bool ImplementsSyncGetIssuersOf() const { return false; } @@ -766,14 +717,9 @@ // modified. class TrustStoreMac::TrustImplDomainCache : public TrustStoreMac::TrustImpl { public: - explicit TrustImplDomainCache(CFStringRef policy_oid, TrustDomains domains) - : use_system_domain_cache_(domains == TrustDomains::kAll), - admin_domain_cache_(kSecTrustSettingsDomainAdmin, policy_oid), + explicit TrustImplDomainCache(CFStringRef policy_oid) + : admin_domain_cache_(kSecTrustSettingsDomainAdmin, policy_oid), user_domain_cache_(kSecTrustSettingsDomainUser, policy_oid) { - if (use_system_domain_cache_) { - system_domain_cache_ = std::make_unique<TrustDomainCache>( - kSecTrustSettingsDomainSystem, policy_oid); - } keychain_observer_ = std::make_unique<KeychainTrustObserver>(); } @@ -785,17 +731,6 @@ FROM_HERE, std::move(keychain_observer_)); } - // Returns true if |cert| is present in kSecTrustSettingsDomainSystem. - bool IsKnownRoot(const ParsedCertificate* cert) override { - if (!use_system_domain_cache_) - return false; - SHA256HashValue cert_hash = CalculateFingerprint256(cert->der_cert()); - - base::AutoLock lock(cache_lock_); - MaybeInitializeCache(); - return system_domain_cache_->ContainsCert(cert_hash); - } - // Returns the trust status for |cert|. TrustStatus IsCertTrusted(const ParsedCertificate* cert, base::SupportsUserData* debug_data) override { @@ -804,9 +739,8 @@ base::AutoLock lock(cache_lock_); MaybeInitializeCache(); - // Evaluate trust domains in user, admin, system order. Admin settings can - // override system ones, and user settings can override both admin and - // system. + // Evaluate user trust domain, then admin. User settings can override + // admin (and both override the system domain, but we don't check that). for (TrustDomainCache* trust_domain_cache : {&user_domain_cache_, &admin_domain_cache_}) { TrustStatus ts = @@ -814,9 +748,6 @@ if (ts != TrustStatus::UNSPECIFIED) return ts; } - if (use_system_domain_cache_) { - return system_domain_cache_->IsCertTrusted(cert, cert_hash, debug_data); - } // Cert did not have trust settings in any domain. return TrustStatus::UNSPECIFIED; @@ -840,26 +771,13 @@ iteration_ = keychain_iteration; user_domain_cache_.Initialize(); admin_domain_cache_.Initialize(); - if (use_system_domain_cache_ && !system_domain_initialized_) { - // In practice, the system trust domain does not change during runtime, - // and SecTrustSettingsCopyCertificates on the system domain is quite - // slow, so the system domain cache is not reset on keychain changes. - system_domain_cache_->Initialize(); - system_domain_initialized_ = true; - } } std::unique_ptr<KeychainTrustObserver> keychain_observer_; - // Store whether to use the system domain in a const bool that is initialized - // in constructor so it is safe to read without having to lock first. - const bool use_system_domain_cache_; base::Lock cache_lock_; // |cache_lock_| must be held while accessing any following members. int64_t iteration_ GUARDED_BY(cache_lock_) = -1; - bool system_domain_initialized_ GUARDED_BY(cache_lock_) = false; - std::unique_ptr<TrustDomainCache> system_domain_cache_ - GUARDED_BY(cache_lock_); TrustDomainCache admin_domain_cache_ GUARDED_BY(cache_lock_); TrustDomainCache user_domain_cache_ GUARDED_BY(cache_lock_); }; @@ -872,16 +790,10 @@ class TrustStoreMac::TrustImplDomainCacheFullCerts : public TrustStoreMac::TrustImpl { public: - explicit TrustImplDomainCacheFullCerts(CFStringRef policy_oid, - TrustDomains domains) + explicit TrustImplDomainCacheFullCerts(CFStringRef policy_oid) : policy_oid_(policy_oid, base::scoped_policy::RETAIN), - use_system_domain_cache_(domains == TrustDomains::kAll), admin_domain_cache_(kSecTrustSettingsDomainAdmin, policy_oid), user_domain_cache_(kSecTrustSettingsDomainUser, policy_oid) { - if (use_system_domain_cache_) { - system_domain_cache_ = std::make_unique<TrustDomainCacheFullCerts>( - kSecTrustSettingsDomainSystem, policy_oid); - } keychain_trust_observer_ = std::make_unique<KeychainTrustObserver>(); keychain_certs_observer_ = std::make_unique<KeychainCertsObserver>(); } @@ -897,17 +809,6 @@ FROM_HERE, std::move(keychain_certs_observer_)); } - // Returns true if |cert| is present in kSecTrustSettingsDomainSystem. - bool IsKnownRoot(const ParsedCertificate* cert) override { - if (!use_system_domain_cache_) - return false; - SHA256HashValue cert_hash = CalculateFingerprint256(cert->der_cert()); - - base::AutoLock lock(cache_lock_); - MaybeInitializeCache(); - return system_domain_cache_->ContainsCert(cert_hash); - } - // Returns the trust status for |cert|. TrustStatus IsCertTrusted(const ParsedCertificate* cert, base::SupportsUserData* debug_data) override { @@ -916,9 +817,8 @@ base::AutoLock lock(cache_lock_); MaybeInitializeCache(); - // Evaluate trust domains in user, admin, system order. Admin settings can - // override system ones, and user settings can override both admin and - // system. + // Evaluate user trust domain, then admin. User settings can override + // admin (and both override the system domain, but we don't check that). for (TrustDomainCacheFullCerts* trust_domain_cache : {&user_domain_cache_, &admin_domain_cache_}) { TrustStatus ts = @@ -926,9 +826,6 @@ if (ts != TrustStatus::UNSPECIFIED) return ts; } - if (use_system_domain_cache_) { - return system_domain_cache_->IsCertTrusted(cert, cert_hash, debug_data); - } // Cert did not have trust settings in any domain. return TrustStatus::UNSPECIFIED; @@ -942,10 +839,6 @@ MaybeInitializeCache(); user_domain_cache_.cert_issuer_source().SyncGetIssuersOf(cert, issuers); admin_domain_cache_.cert_issuer_source().SyncGetIssuersOf(cert, issuers); - if (system_domain_cache_) { - system_domain_cache_->cert_issuer_source().SyncGetIssuersOf(cert, - issuers); - } intermediates_cert_issuer_source_.SyncGetIssuersOf(cert, issuers); } @@ -969,13 +862,6 @@ trust_iteration_ = keychain_trust_iteration; user_domain_cache_.Initialize(); admin_domain_cache_.Initialize(); - if (use_system_domain_cache_ && !system_domain_initialized_) { - // In practice, the system trust domain does not change during runtime, - // and SecTrustSettingsCopyCertificates on the system domain is quite - // slow, so the system domain cache is not reset on keychain changes. - system_domain_cache_->Initialize(); - system_domain_initialized_ = true; - } base::UmaHistogramMediumTimes( "Net.CertVerifier.MacTrustDomainCacheInitTime", trust_domain_cache_init_timer.Elapsed()); @@ -1047,9 +933,7 @@ SHA256HashValue cert_hash = x509_util::CalculateFingerprint256(match_cert_handle); if (user_domain_cache_.ContainsCert(cert_hash) || - admin_domain_cache_.ContainsCert(cert_hash) || - (use_system_domain_cache_ && - system_domain_cache_->ContainsCert(cert_hash))) { + admin_domain_cache_.ContainsCert(cert_hash)) { continue; } @@ -1120,18 +1004,12 @@ std::unique_ptr<KeychainTrustObserver> keychain_trust_observer_; std::unique_ptr<KeychainCertsObserver> keychain_certs_observer_; const base::ScopedCFTypeRef<CFStringRef> policy_oid_; - // Store whether to use the system domain in a const bool that is initialized - // in constructor so it is safe to read without having to lock first. - const bool use_system_domain_cache_; base::Lock cache_lock_; // |cache_lock_| must be held while accessing any following members. int64_t trust_iteration_ GUARDED_BY(cache_lock_) = -1; int64_t certs_iteration_ GUARDED_BY(cache_lock_) = -1; - bool system_domain_initialized_ GUARDED_BY(cache_lock_) = false; - std::unique_ptr<TrustDomainCacheFullCerts> system_domain_cache_ - GUARDED_BY(cache_lock_); TrustDomainCacheFullCerts admin_domain_cache_ GUARDED_BY(cache_lock_); TrustDomainCacheFullCerts user_domain_cache_ GUARDED_BY(cache_lock_); @@ -1143,30 +1021,19 @@ // SecTrustSettingsCopyTrustSettings on every cert checked, with no caching. class TrustStoreMac::TrustImplNoCache : public TrustStoreMac::TrustImpl { public: - explicit TrustImplNoCache(CFStringRef policy_oid, TrustDomains domains) - : policy_oid_(policy_oid), domains_(domains) {} + explicit TrustImplNoCache(CFStringRef policy_oid) : policy_oid_(policy_oid) {} TrustImplNoCache(const TrustImplNoCache&) = delete; TrustImplNoCache& operator=(const TrustImplNoCache&) = delete; ~TrustImplNoCache() override = default; - // Returns true if |cert| is present in kSecTrustSettingsDomainSystem. - bool IsKnownRoot(const ParsedCertificate* cert) override { - if (domains_ == TrustDomains::kUserAndAdmin) - return false; - HashValue cert_hash(CalculateFingerprint256(cert->der_cert())); - base::AutoLock lock(crypto::GetMacSecurityServicesLock()); - return net::IsKnownRoot(cert_hash); - } - // Returns the trust status for |cert|. TrustStatus IsCertTrusted(const ParsedCertificate* cert, base::SupportsUserData* debug_data) override { int debug_info = 0; TrustStatus result = - IsCertificateTrustedForPolicy(cert, policy_oid_, domains_, &debug_info, - /*out_is_known_root=*/nullptr); + IsCertificateTrustedForPolicy(cert, policy_oid_, &debug_info); UpdateUserData(debug_info, debug_data, TrustStoreMac::TrustImplType::kSimple); return result; @@ -1178,7 +1045,6 @@ private: const CFStringRef policy_oid_; - const TrustDomains domains_; }; // TrustImplLRUCache is calls SecTrustSettingsCopyTrustSettings on every cert @@ -1186,12 +1052,8 @@ // keychain updates. class TrustStoreMac::TrustImplLRUCache : public TrustStoreMac::TrustImpl { public: - TrustImplLRUCache(CFStringRef policy_oid, - size_t cache_size, - TrustDomains domains) - : policy_oid_(policy_oid), - domains_(domains), - trust_status_cache_(cache_size) { + TrustImplLRUCache(CFStringRef policy_oid, size_t cache_size) + : policy_oid_(policy_oid), trust_status_cache_(cache_size) { keychain_observer_ = std::make_unique<KeychainTrustObserver>(); } @@ -1203,13 +1065,6 @@ FROM_HERE, std::move(keychain_observer_)); } - // Returns true if |cert| has trust settings in kSecTrustSettingsDomainSystem. - bool IsKnownRoot(const ParsedCertificate* cert) override { - if (domains_ == TrustDomains::kUserAndAdmin) - return false; - return GetKnownRootStatus(cert) == KnownRootStatus::IS_KNOWN_ROOT; - } - // Returns the trust status for |cert|. TrustStatus IsCertTrusted(const ParsedCertificate* cert, base::SupportsUserData* debug_data) override { @@ -1227,49 +1082,10 @@ struct TrustStatusDetails { TrustStatus trust_status = TrustStatus::UNKNOWN; int debug_info = 0; - KnownRootStatus is_known_root = KnownRootStatus::UNKNOWN; }; - KnownRootStatus GetKnownRootStatus(const ParsedCertificate* cert) { - SHA256HashValue cert_hash = CalculateFingerprint256(cert->der_cert()); - - int starting_cache_iteration = -1; - { - base::AutoLock lock(cache_lock_); - MaybeResetCache(); - starting_cache_iteration = iteration_; - auto cache_iter = trust_status_cache_.Get(cert_hash); - if (cache_iter != trust_status_cache_.end() && - cache_iter->second.is_known_root != KnownRootStatus::UNKNOWN) { - return cache_iter->second.is_known_root; - } - } - - KnownRootStatus is_known_root = IsCertificateKnownRoot(cert); - - { - base::AutoLock lock(cache_lock_); - MaybeResetCache(); - if (iteration_ != starting_cache_iteration) - return is_known_root; - - auto cache_iter = trust_status_cache_.Get(cert_hash); - // Update |is_known_root| on existing cache entry if there is one, - // otherwise create a new cache entry. - if (cache_iter != trust_status_cache_.end()) { - cache_iter->second.is_known_root = is_known_root; - } else { - TrustStatusDetails trust_details; - trust_details.is_known_root = is_known_root; - trust_status_cache_.Put(cert_hash, trust_details); - } - } - return is_known_root; - } - TrustStatusDetails GetTrustStatus(const ParsedCertificate* cert) { SHA256HashValue cert_hash = CalculateFingerprint256(cert->der_cert()); - TrustStatusDetails trust_details; int starting_cache_iteration = -1; { @@ -1280,15 +1096,12 @@ if (cache_iter != trust_status_cache_.end()) { if (cache_iter->second.trust_status != TrustStatus::UNKNOWN) return cache_iter->second; - // If there was a cache entry but the trust status was not initialized, - // copy the existing values. (|is_known_root| might already be cached.) - trust_details = cache_iter->second; } } + TrustStatusDetails trust_details; trust_details.trust_status = IsCertificateTrustedForPolicy( - cert, policy_oid_, domains_, &trust_details.debug_info, - &trust_details.is_known_root); + cert, policy_oid_, &trust_details.debug_info); { base::AutoLock lock(cache_lock_); @@ -1310,7 +1123,6 @@ } const CFStringRef policy_oid_; - const TrustDomains domains_; std::unique_ptr<KeychainTrustObserver> keychain_observer_; base::Lock cache_lock_; @@ -1328,27 +1140,24 @@ TrustStoreMac::TrustStoreMac(CFStringRef policy_oid, TrustImplType impl, - size_t cache_size, - TrustDomains domains) - : domains_(domains) { + size_t cache_size) { switch (impl) { case TrustImplType::kUnknown: DCHECK(false); break; case TrustImplType::kDomainCache: - trust_cache_ = - std::make_unique<TrustImplDomainCache>(policy_oid, domains); + trust_cache_ = std::make_unique<TrustImplDomainCache>(policy_oid); break; case TrustImplType::kSimple: - trust_cache_ = std::make_unique<TrustImplNoCache>(policy_oid, domains); + trust_cache_ = std::make_unique<TrustImplNoCache>(policy_oid); break; case TrustImplType::kLruCache: trust_cache_ = - std::make_unique<TrustImplLRUCache>(policy_oid, cache_size, domains); + std::make_unique<TrustImplLRUCache>(policy_oid, cache_size); break; case TrustImplType::kDomainCacheFullCerts: trust_cache_ = - std::make_unique<TrustImplDomainCacheFullCerts>(policy_oid, domains); + std::make_unique<TrustImplDomainCacheFullCerts>(policy_oid); break; } } @@ -1359,10 +1168,6 @@ trust_cache_->InitializeTrustCache(); } -bool TrustStoreMac::IsKnownRoot(const ParsedCertificate* cert) const { - return trust_cache_->IsKnownRoot(cert); -} - void TrustStoreMac::SyncGetIssuersOf(const ParsedCertificate* cert, ParsedCertificateList* issuers) { if (trust_cache_->ImplementsSyncGetIssuersOf()) { @@ -1375,7 +1180,7 @@ return; std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> matching_cert_buffers = - FindMatchingCertificatesForMacNormalizedSubject(name_data, domains_); + FindMatchingCertificatesForMacNormalizedSubject(name_data); // Convert to ParsedCertificate. for (auto& buffer : matching_cert_buffers) { @@ -1419,8 +1224,7 @@ // static std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( - CFDataRef name_data, - TrustDomains domains) { + CFDataRef name_data) { std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> matching_cert_buffers; base::ScopedCFTypeRef<CFMutableDictionaryRef> query( CFDictionaryCreateMutable(nullptr, 0, &kCFTypeDictionaryKeyCallBacks, @@ -1444,52 +1248,6 @@ } } -// Much of the Keychain API was marked deprecated as of the macOS 13 SDK. -// Removal of its use is tracked in https://crbug.com/1348251 but deprecation -// warnings are disabled in the meanwhile. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - - if (domains == TrustDomains::kAll) { - // If a TestKeychainSearchList is present, it will have already set - // |scoped_alternate_keychain_search_list|, which will be used as the - // basis for reordering the keychain. Otherwise, get the current keychain - // search list and use that. - if (!scoped_alternate_keychain_search_list) { - OSStatus status = SecKeychainCopySearchList( - scoped_alternate_keychain_search_list.InitializeInto()); - if (status) { - OSSTATUS_LOG(ERROR, status) << "SecKeychainCopySearchList error"; - return matching_cert_buffers; - } - } - - CFMutableArrayRef mutable_keychain_search_list = CFArrayCreateMutableCopy( - kCFAllocatorDefault, - CFArrayGetCount(scoped_alternate_keychain_search_list.get()) + 1, - scoped_alternate_keychain_search_list.get()); - if (!mutable_keychain_search_list) { - LOG(ERROR) << "CFArrayCreateMutableCopy"; - return matching_cert_buffers; - } - scoped_alternate_keychain_search_list.reset(mutable_keychain_search_list); - - base::ScopedCFTypeRef<SecKeychainRef> roots_keychain; - // The System Roots keychain is not normally searched by - // SecItemCopyMatching. Get a reference to it and include in the keychain - // search list. - OSStatus status = SecKeychainOpen( - "/System/Library/Keychains/SystemRootCertificates.keychain", - roots_keychain.InitializeInto()); - if (status) { - OSSTATUS_LOG(ERROR, status) << "SecKeychainOpen error"; - return matching_cert_buffers; - } - CFArrayAppendValue(mutable_keychain_search_list, roots_keychain); - } - -#pragma clang diagnostic pop - if (scoped_alternate_keychain_search_list) { CFDictionarySetValue(query, kSecMatchSearchList, scoped_alternate_keychain_search_list.get());
diff --git a/net/cert/internal/trust_store_mac.h b/net/cert/internal/trust_store_mac.h index dd50dc72..86119d55 100644 --- a/net/cert/internal/trust_store_mac.h +++ b/net/cert/internal/trust_store_mac.h
@@ -84,17 +84,6 @@ kDomainCacheFullCerts = 4, }; - enum class TrustDomains { - // Load trust settings and certificates from all three trust domains - // (user, admin, system). - kAll = 0, - - // Load trust settings and certificates from only the user and admin trust - // domains. This will find trust settings that have been set locally or by - // an enterprise, but not those distributed with the OS. - kUserAndAdmin = 1, - }; - class ResultDebugData : public base::SupportsUserData::Data { public: static const ResultDebugData* Get(const base::SupportsUserData* debug_data); @@ -125,10 +114,7 @@ // |impl| selects which internal implementation is used for checking trust // settings, and the interpretation of |cache_size| varies depending on // |impl|. - TrustStoreMac(CFStringRef policy_oid, - TrustImplType impl, - size_t cache_size, - TrustDomains domains); + TrustStoreMac(CFStringRef policy_oid, TrustImplType impl, size_t cache_size); TrustStoreMac(const TrustStoreMac&) = delete; TrustStoreMac& operator=(const TrustStoreMac&) = delete; @@ -138,10 +124,6 @@ // Initializes the trust cache, if it isn't already initialized. void InitializeTrustCache() const; - // Returns true if the given certificate is present in the system trust - // domain. - bool IsKnownRoot(const ParsedCertificate* cert) const; - // TrustStore implementation: void SyncGetIssuersOf(const ParsedCertificate* cert, ParsedCertificateList* issuers) override; @@ -159,8 +141,7 @@ // The result is an array of CRYPTO_BUFFERs containing the DER certificate // data. static std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> - FindMatchingCertificatesForMacNormalizedSubject(CFDataRef name_data, - TrustDomains domains); + FindMatchingCertificatesForMacNormalizedSubject(CFDataRef name_data); // Returns the OS-normalized issuer of |cert|. // macOS internally uses a normalized form of subject/issuer names for @@ -169,7 +150,6 @@ static base::ScopedCFTypeRef<CFDataRef> GetMacNormalizedIssuer( const ParsedCertificate* cert); - TrustDomains domains_; std::unique_ptr<TrustImpl> trust_cache_; };
diff --git a/net/cert/internal/trust_store_mac_unittest.cc b/net/cert/internal/trust_store_mac_unittest.cc index c7019b0..9b714f3 100644 --- a/net/cert/internal/trust_store_mac_unittest.cc +++ b/net/cert/internal/trust_store_mac_unittest.cc
@@ -20,7 +20,6 @@ #include "base/test/metrics/histogram_tester.h" #include "crypto/mac_security_services_lock.h" #include "crypto/sha2.h" -#include "net/cert/known_roots_mac.h" #include "net/cert/pem.h" #include "net/cert/pki/cert_errors.h" #include "net/cert/pki/parsed_certificate.h" @@ -105,11 +104,6 @@ ~DebugData() override = default; }; -enum IsKnownRootTestOrder { - TEST_IS_KNOWN_ROOT_BEFORE, - TEST_IS_KNOWN_ROOT_AFTER, -}; - const char* TrustImplTypeToString(TrustStoreMac::TrustImplType t) { switch (t) { case TrustStoreMac::TrustImplType::kDomainCache: @@ -125,30 +119,10 @@ } } -const char* IsKnownRootTestOrderToString(IsKnownRootTestOrder order) { - switch (order) { - case TEST_IS_KNOWN_ROOT_BEFORE: - return "IsKnownRootBefore"; - case TEST_IS_KNOWN_ROOT_AFTER: - return "IsKnownRootAfter"; - } -} - -const char* TrustDomainsToString(TrustStoreMac::TrustDomains domains) { - switch (domains) { - case TrustStoreMac::TrustDomains::kAll: - return "AllDomains"; - case TrustStoreMac::TrustDomains::kUserAndAdmin: - return "UserAndAdminDomains"; - } -} - } // namespace class TrustStoreMacImplTest - : public testing::TestWithParam<std::tuple<TrustStoreMac::TrustImplType, - IsKnownRootTestOrder, - TrustStoreMac::TrustDomains>> {}; + : public testing::TestWithParam<TrustStoreMac::TrustImplType> {}; // Much of the Keychain API was marked deprecated as of the macOS 13 SDK. // Removal of its use is tracked in https://crbug.com/1348251 but deprecation @@ -177,11 +151,8 @@ #pragma clang diagnostic pop - const TrustStoreMac::TrustImplType trust_impl = std::get<0>(GetParam()); - const IsKnownRootTestOrder is_known_root_test_order = std::get<1>(GetParam()); - const TrustStoreMac::TrustDomains trust_domains = std::get<2>(GetParam()); - TrustStoreMac trust_store(kSecPolicyAppleSSL, trust_impl, kDefaultCacheSize, - trust_domains); + const TrustStoreMac::TrustImplType trust_impl = GetParam(); + TrustStoreMac trust_store(kSecPolicyAppleSSL, trust_impl, kDefaultCacheSize); scoped_refptr<ParsedCertificate> a_by_b, b_by_c, b_by_f, c_by_d, c_by_e, f_by_e, d_by_d, e_by_e; @@ -241,8 +212,6 @@ // added and trusted the test certs on the machine the test is being run on). for (const auto& cert : {a_by_b, b_by_c, b_by_f, c_by_d, c_by_e, f_by_e, d_by_d, e_by_e}) { - if (is_known_root_test_order == TEST_IS_KNOWN_ROOT_BEFORE) - EXPECT_FALSE(trust_store.IsKnownRoot(cert.get())); DebugData debug_data; CertificateTrust trust = trust_store.GetTrust(cert.get(), &debug_data); EXPECT_EQ(CertificateTrustType::UNSPECIFIED, trust.type); @@ -253,8 +222,6 @@ ASSERT_TRUE(trust_debug_data); EXPECT_EQ(0, trust_debug_data->combined_trust_debug_info()); EXPECT_EQ(trust_impl, trust_debug_data->trust_impl()); - if (is_known_root_test_order == TEST_IS_KNOWN_ROOT_AFTER) - EXPECT_FALSE(trust_store.IsKnownRoot(cert.get())); } } @@ -287,13 +254,11 @@ ParseFindCertificateOutputToDerCerts( find_certificate_system_roots_output); - const TrustStoreMac::TrustImplType trust_impl = std::get<0>(GetParam()); - const IsKnownRootTestOrder is_known_root_test_order = std::get<1>(GetParam()); - const TrustStoreMac::TrustDomains trust_domains = std::get<2>(GetParam()); + const TrustStoreMac::TrustImplType trust_impl = GetParam(); base::HistogramTester histogram_tester; TrustStoreMac trust_store(kSecPolicyAppleX509Basic, trust_impl, - kDefaultCacheSize, trust_domains); + kDefaultCacheSize); base::ScopedCFTypeRef<SecPolicyRef> sec_policy(SecPolicyCreateBasicX509()); ASSERT_TRUE(sec_policy); @@ -333,16 +298,6 @@ continue; } - if (is_known_root_test_order == TEST_IS_KNOWN_ROOT_BEFORE) { - bool trust_store_is_known_root = trust_store.IsKnownRoot(cert.get()); - if (trust_domains == TrustStoreMac::TrustDomains::kAll) { - base::AutoLock lock(crypto::GetMacSecurityServicesLock()); - EXPECT_EQ(net::IsKnownRoot(cert_handle), trust_store_is_known_root); - } else { - EXPECT_FALSE(trust_store_is_known_root); - } - } - // Check if this cert is considered a trust anchor by TrustStoreMac. DebugData debug_data; CertificateTrust cert_trust = trust_store.GetTrust(cert.get(), &debug_data); @@ -364,16 +319,15 @@ kSecTrustOptionAllowExpired | kSecTrustOptionAllowExpiredRoot)); - if (trust_domains == TrustStoreMac::TrustDomains::kUserAndAdmin && - find_certificate_default_search_list_certs.count(cert_der) && + if (find_certificate_default_search_list_certs.count(cert_der) && find_certificate_system_roots_certs.count(cert_der)) { // If the same certificate is present in both the System and User/Admin // domains, and TrustStoreMac is only using trust settings from // User/Admin, then it's not possible for this test to know whether the // result from SecTrustEvaluate should match the TrustStoreMac result. // Just ignore such certificates. - } else if (trust_domains == TrustStoreMac::TrustDomains::kUserAndAdmin && - !find_certificate_default_search_list_certs.count(cert_der)) { + } else if (!find_certificate_default_search_list_certs.count(cert_der)) { + // Cert is only in the system domain. It should be untrusted. EXPECT_FALSE(is_trust_anchor); } else { SecTrustResultType trust_result; @@ -396,16 +350,6 @@ EXPECT_EQ(trust_impl, trust_debug_data->trust_impl()); } - if (is_known_root_test_order == TEST_IS_KNOWN_ROOT_AFTER) { - bool trust_store_is_known_root = trust_store.IsKnownRoot(cert.get()); - if (trust_domains == TrustStoreMac::TrustDomains::kAll) { - base::AutoLock lock(crypto::GetMacSecurityServicesLock()); - EXPECT_EQ(net::IsKnownRoot(cert_handle), trust_store_is_known_root); - } else { - EXPECT_FALSE(trust_store_is_known_root); - } - } - // Call GetTrust again on the same cert. This should exercise the code // that checks the trust value for a cert which has already been cached. DebugData debug_data2; @@ -430,32 +374,18 @@ "Net.CertVerifier.MacTrustDomainCertCount.User", 1); histogram_tester.ExpectTotalCount( "Net.CertVerifier.MacTrustDomainCertCount.Admin", 1); - histogram_tester.ExpectTotalCount( - "Net.CertVerifier.MacTrustDomainCertCount.System", - (trust_domains == TrustStoreMac::TrustDomains::kAll) ? 1 : 0); } } INSTANTIATE_TEST_SUITE_P( Impl, TrustStoreMacImplTest, - testing::Combine( - testing::Values(TrustStoreMac::TrustImplType::kDomainCache, - TrustStoreMac::TrustImplType::kSimple, - TrustStoreMac::TrustImplType::kLruCache, - TrustStoreMac::TrustImplType::kDomainCacheFullCerts), - // Some TrustImpls may calculate/cache IsKnownRoot values and trust - // values independently, so test with calling IsKnownRoot both before - // and after GetTrust to try to ensure there is no ordering issue with - // which one initializes the cache first. - testing::Values(TEST_IS_KNOWN_ROOT_BEFORE, TEST_IS_KNOWN_ROOT_AFTER), - testing::Values(TrustStoreMac::TrustDomains::kAll, - TrustStoreMac::TrustDomains::kUserAndAdmin)), + testing::Values(TrustStoreMac::TrustImplType::kDomainCache, + TrustStoreMac::TrustImplType::kSimple, + TrustStoreMac::TrustImplType::kLruCache, + TrustStoreMac::TrustImplType::kDomainCacheFullCerts), [](const testing::TestParamInfo<TrustStoreMacImplTest::ParamType>& info) { - return base::StrCat( - {TrustImplTypeToString(std::get<0>(info.param)), - IsKnownRootTestOrderToString(std::get<1>(info.param)), - TrustDomainsToString(std::get<2>(info.param))}); + return TrustImplTypeToString(info.param); }); } // namespace net
diff --git a/net/cert/pki/ocsp.cc b/net/cert/pki/ocsp.cc index d6384c9..07701b8 100644 --- a/net/cert/pki/ocsp.cc +++ b/net/cert/pki/ocsp.cc
@@ -4,7 +4,6 @@ #include "net/cert/pki/ocsp.h" -#include "base/base64.h" #include "base/containers/contains.h" #include "base/strings/string_util.h" #include "base/time/time.h"
diff --git a/net/cert/pki/ocsp_unittest.cc b/net/cert/pki/ocsp_unittest.cc index fea1d7e..57d260d 100644 --- a/net/cert/pki/ocsp_unittest.cc +++ b/net/cert/pki/ocsp_unittest.cc
@@ -4,12 +4,12 @@ #include "net/cert/pki/ocsp.h" -#include "base/base64.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "net/cert/pki/test_helpers.h" #include "net/der/encode_values.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/boringssl/src/include/openssl/base64.h" #include "third_party/boringssl/src/include/openssl/pool.h" #include "url/gurl.h" @@ -228,10 +228,15 @@ base::ReplaceSubstringsAfterOffset(&b64, 0, "%3D", "="); // Base64 decode the data. - std::string decoded; - ASSERT_TRUE(base::Base64Decode(b64, &decoded)); + size_t len; + EXPECT_TRUE(EVP_DecodedLength(&len, b64.size())); + std::vector<uint8_t> decoded(len); + EXPECT_TRUE(EVP_DecodeBase64(decoded.data(), &len, len, + reinterpret_cast<const uint8_t*>(b64.data()), + b64.size())); + std::string decoded_string(decoded.begin(), decoded.begin() + len); - EXPECT_EQ(request_data, decoded); + EXPECT_EQ(request_data, decoded_string); } } // namespace
diff --git a/net/cert/pki/test_helpers.cc b/net/cert/pki/test_helpers.cc index c407bfb..db1c5b5 100644 --- a/net/cert/pki/test_helpers.cc +++ b/net/cert/pki/test_helpers.cc
@@ -4,7 +4,6 @@ #include "net/cert/pki/test_helpers.h" -#include "base/base64.h" #include "base/base_paths.h" #include "base/files/file_util.h" #include "base/path_service.h"
diff --git a/net/cookies/cookie_inclusion_status.h b/net/cookies/cookie_inclusion_status.h index c3b944da..5f289dd 100644 --- a/net/cookies/cookie_inclusion_status.h +++ b/net/cookies/cookie_inclusion_status.h
@@ -96,6 +96,9 @@ EXCLUDE_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE = 20, // Cookie was set with a Domain attribute containing non ASCII characters. EXCLUDE_DOMAIN_NON_ASCII = 21, + // Special case for when a cookie is blocked by third-party cookie blocking + // but the two sites are in the same First-Party Set. + EXCLUDE_THIRD_PARTY_BLOCKED_WITHIN_FIRST_PARTY_SET = 22, // This should be kept last. NUM_EXCLUSION_REASONS
diff --git a/net/first_party_sets/first_party_set_metadata.cc b/net/first_party_sets/first_party_set_metadata.cc index 483b168..26521fa 100644 --- a/net/first_party_sets/first_party_set_metadata.cc +++ b/net/first_party_sets/first_party_set_metadata.cc
@@ -45,4 +45,10 @@ return os; } +bool FirstPartySetMetadata::AreSitesInSameFirstPartySet() const { + if (!frame_entry_ || !top_frame_entry_) + return false; + return frame_entry_->primary() == top_frame_entry_->primary(); +} + } // namespace net
diff --git a/net/first_party_sets/first_party_set_metadata.h b/net/first_party_sets/first_party_set_metadata.h index a7afec15..a532a261 100644 --- a/net/first_party_sets/first_party_set_metadata.h +++ b/net/first_party_sets/first_party_set_metadata.h
@@ -44,6 +44,12 @@ return top_frame_entry_; } + // Returns true if `frame_entry` and `top_frame_entry` are both non-null and + // have the same primary. This is different from `context_.context_type()` + // because it only checks if the the frames' sites are in the same set + // regardless of their ancestor chain. + bool AreSitesInSameFirstPartySet() const; + private: SamePartyContext context_ = SamePartyContext(); absl::optional<FirstPartySetEntry> frame_entry_ = absl::nullopt;
diff --git a/net/test/cert_builder.cc b/net/test/cert_builder.cc index 4c693b39..c133d0c6 100644 --- a/net/test/cert_builder.cc +++ b/net/test/cert_builder.cc
@@ -517,11 +517,12 @@ } void CertBuilder::SetSubjectCommonName(base::StringPiece common_name) { - SetSubject(BuildNameWithCommonNameOfType(common_name, CBS_ASN1_UTF8STRING)); + SetSubjectTLV( + BuildNameWithCommonNameOfType(common_name, CBS_ASN1_UTF8STRING)); Invalidate(); } -void CertBuilder::SetSubject(base::span<const uint8_t> subject_tlv) { +void CertBuilder::SetSubjectTLV(base::span<const uint8_t> subject_tlv) { subject_tlv_.assign(subject_tlv.begin(), subject_tlv.end()); Invalidate(); }
diff --git a/net/test/cert_builder.h b/net/test/cert_builder.h index 7974825..670aa9f 100644 --- a/net/test/cert_builder.h +++ b/net/test/cert_builder.h
@@ -158,7 +158,7 @@ void SetSubjectCommonName(base::StringPiece common_name); // Sets the subject to |subject_tlv|. - void SetSubject(base::span<const uint8_t> subject_tlv); + void SetSubjectTLV(base::span<const uint8_t> subject_tlv); // Sets the SAN for the certificate to a single dNSName. void SetSubjectAltName(base::StringPiece dns_name);
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index eba8acba..0a622f7f 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc
@@ -826,7 +826,8 @@ if (request()->network_delegate()) { can_get_cookies = request()->network_delegate()->AnnotateAndMoveUserBlockedCookies( - *request(), maybe_included_cookies, excluded_cookies); + *request(), first_party_set_metadata_, maybe_included_cookies, + excluded_cookies); } if (!can_get_cookies) {
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc index f22eca30..83ae112f 100644 --- a/net/url_request/url_request_test_util.cc +++ b/net/url_request/url_request_test_util.cc
@@ -499,6 +499,7 @@ bool TestNetworkDelegate::OnAnnotateAndMoveUserBlockedCookies( const URLRequest& request, + const net::FirstPartySetMetadata& first_party_set_metadata, net::CookieAccessResultList& maybe_included_cookies, net::CookieAccessResultList& excluded_cookies) { bool allow = true; @@ -603,6 +604,7 @@ bool FilteringTestNetworkDelegate::OnAnnotateAndMoveUserBlockedCookies( const URLRequest& request, + const net::FirstPartySetMetadata& first_party_set_metadata, net::CookieAccessResultList& maybe_included_cookies, net::CookieAccessResultList& excluded_cookies) { // Filter out cookies if |block_annotate_cookies_| is set and @@ -636,7 +638,8 @@ // Call the nested delegate's method first to avoid a short circuit. return TestNetworkDelegate::OnAnnotateAndMoveUserBlockedCookies( - request, maybe_included_cookies, excluded_cookies) && + request, first_party_set_metadata, maybe_included_cookies, + excluded_cookies) && allowed; }
diff --git a/net/url_request/url_request_test_util.h b/net/url_request/url_request_test_util.h index a43ebe82..67d4d21 100644 --- a/net/url_request/url_request_test_util.h +++ b/net/url_request/url_request_test_util.h
@@ -31,6 +31,7 @@ #include "net/cert/ct_policy_enforcer.h" #include "net/cookies/cookie_monster.h" #include "net/disk_cache/disk_cache.h" +#include "net/first_party_sets/first_party_set_metadata.h" #include "net/first_party_sets/first_party_sets_cache_filter.h" #include "net/first_party_sets/same_party_context.h" #include "net/http/http_auth_handler_factory.h" @@ -314,6 +315,7 @@ void OnURLRequestDestroyed(URLRequest* request) override; bool OnAnnotateAndMoveUserBlockedCookies( const URLRequest& request, + const net::FirstPartySetMetadata& first_party_set_metadata, net::CookieAccessResultList& maybe_included_cookies, net::CookieAccessResultList& excluded_cookies) override; NetworkDelegate::PrivacySetting OnForcePrivacyMode( @@ -405,6 +407,7 @@ bool OnAnnotateAndMoveUserBlockedCookies( const URLRequest& request, + const net::FirstPartySetMetadata& first_party_set_metadata, net::CookieAccessResultList& maybe_included_cookies, net::CookieAccessResultList& excluded_cookies) override;
diff --git a/printing/backend/print_backend.h b/printing/backend/print_backend.h index 06ae4d2..a89338d 100644 --- a/printing/backend/print_backend.h +++ b/printing/backend/print_backend.h
@@ -261,7 +261,8 @@ // This method uses the XPS API to get the printer capabilities. // Returns raw XML string on success, or mojom::ResultCode on failure. - base::expected<std::string, mojom::ResultCode> + // This method is virtual to support testing. + virtual base::expected<std::string, mojom::ResultCode> GetXmlPrinterCapabilitiesForXpsDriver(const std::string& printer_name); #endif // BUILDFLAG(IS_WIN)
diff --git a/printing/backend/test_print_backend.cc b/printing/backend/test_print_backend.cc index 786c9095..0a30332 100644 --- a/printing/backend/test_print_backend.cc +++ b/printing/backend/test_print_backend.cc
@@ -12,13 +12,30 @@ #include "base/containers/contains.h" #include "base/location.h" #include "base/logging.h" +#include "build/build_config.h" #include "printing/backend/print_backend.h" #include "printing/mojom/print.mojom.h" +#if BUILDFLAG(IS_WIN) +#include "base/types/expected.h" +#endif // BUILDFLAG(IS_WIN) + namespace printing { namespace { +#if BUILDFLAG(IS_WIN) +// Default XML with feature not of interest. +constexpr char kXmlDefaultCapabilities[] = + R"(<?xml version="1.0" encoding="UTF-8"?> + <psf:PrintCapabilities> + <!-- Need at least one psf:Feature for + ParseValueForXpsPrinterCapabilities() to consider it valid XML --> + <psf:Feature name="TestFeature"> + </psf:Feature> + </psf:PrintCapabilities>)"; +#endif // BUILDFLAG(IS_WIN) + mojom::ResultCode ReportErrorAccessDenied(const base::Location& from_here) { DLOG(ERROR) << from_here.ToString() << " failed, access denied"; return mojom::ResultCode::kAccessDenied; @@ -123,6 +140,26 @@ return base::Contains(printer_map_, printer_name); } +#if BUILDFLAG(IS_WIN) +base::expected<std::string, mojom::ResultCode> +TestPrintBackend::GetXmlPrinterCapabilitiesForXpsDriver( + const std::string& printer_name) { + auto found = printer_map_.find(printer_name); + if (found == printer_map_.end()) + return base::unexpected(ReportErrorNoDevice(FROM_HERE)); + + const PrinterData* data = found->second.get(); + if (data->blocked_by_permissions) + return base::unexpected(ReportErrorAccessDenied(FROM_HERE)); + + // XML capabilities might not have been provided. + if (data->capabilities_xml.empty()) + return base::unexpected(ReportErrorNoData(FROM_HERE)); + + return data->capabilities_xml; +} +#endif // BUILDFLAG(IS_WIN) + void TestPrintBackend::SetDefaultPrinterName(const std::string& printer_name) { if (default_printer_name_ == printer_name) return; @@ -151,6 +188,9 @@ std::unique_ptr<PrinterBasicInfo> info) { AddPrinter(printer_name, std::move(caps), std::move(info), /*blocked_by_permissions=*/false); +#if BUILDFLAG(IS_WIN) + SetXmlCapabilitiesForPrinter(printer_name, kXmlDefaultCapabilities); +#endif // BUILDFLAG(IS_WIN) } void TestPrintBackend::AddInvalidDataPrinter(const std::string& printer_name) { @@ -166,6 +206,20 @@ /*blocked_by_permissions=*/true); } +#if BUILDFLAG(IS_WIN) +void TestPrintBackend::SetXmlCapabilitiesForPrinter( + const std::string& printer_name, + const std::string& capabilities_xml) { + auto found = printer_map_.find(printer_name); + if (found == printer_map_.end()) { + DLOG(ERROR) << "Unable to find printer. Unknown printer name: " + << printer_name; + return; + } + found->second->capabilities_xml = capabilities_xml; +} +#endif // BUILDFLAG(IS_WIN) + void TestPrintBackend::AddPrinter( const std::string& printer_name, std::unique_ptr<PrinterSemanticCapsAndDefaults> caps,
diff --git a/printing/backend/test_print_backend.h b/printing/backend/test_print_backend.h index 11197e0..26334bdc7 100644 --- a/printing/backend/test_print_backend.h +++ b/printing/backend/test_print_backend.h
@@ -9,9 +9,14 @@ #include <string> #include "base/containers/flat_map.h" +#include "build/build_config.h" #include "printing/backend/print_backend.h" #include "printing/mojom/print.mojom.h" +#if BUILDFLAG(IS_WIN) +#include "base/types/expected.h" +#endif // BUILDFLAG(IS_WIN) + namespace printing { // PrintBackend which doesn't interact with the OS and responses @@ -35,6 +40,11 @@ PrinterCapsAndDefaults* printer_info) override; std::string GetPrinterDriverInfo(const std::string& printer_name) override; bool IsValidPrinter(const std::string& printer_name) override; +#if BUILDFLAG(IS_WIN) + base::expected<std::string, mojom::ResultCode> + GetXmlPrinterCapabilitiesForXpsDriver( + const std::string& printer_name) override; +#endif // BUILDFLAG(IS_WIN) // Methods for test setup: @@ -42,14 +52,14 @@ void SetDefaultPrinterName(const std::string& printer_name); // Adds a printer to satisfy IsValidPrinter(), EnumeratePrinters(), - // GetPrinterBasicInfo(), and GetPrinterSemanticCapsAndDefaults(). - // While `caps` can be null, it will cause queries for the capabilities to - // fail, and thus is likely not of interest for most tests. IsValidPrinter() - // will still show true even if `caps` is null, which provides the benefit of - // simulating a printer that exists in the system but cannot be queried. - // `info` can be null, which will result in queries for basic info to fail. - // Calling EnumeratePrinters() will include the identified `printer_name` - // even if either parameter is null. + // GetPrinterBasicInfo(), GetPrinterSemanticCapsAndDefaults(), and + // GetXmlPrinterCapabilitiesForXpsDriver(). While `caps` can be null, it will + // cause queries for the capabilities to fail, and thus is likely not of + // interest for most tests. IsValidPrinter() will still show true even if + // `caps` is null, which provides the benefit of simulating a printer that + // exists in the system but cannot be queried. `info` can be null, which will + // result in queries for basic info to fail. Calling EnumeratePrinters() will + // include the identified `printer_name` even if either parameter is null. void AddValidPrinter(const std::string& printer_name, std::unique_ptr<PrinterSemanticCapsAndDefaults> caps, std::unique_ptr<PrinterBasicInfo> info); @@ -61,6 +71,16 @@ // calls specific to a particular `printer_name`. void AddAccessDeniedPrinter(const std::string& printer_name); +#if BUILDFLAG(IS_WIN) + // Sets the XML capabilities of an existing printer to be used by + // GetXmlPrinterCapabilitiesForXpsDriver(). `printer_name` must be a valid + // name of an added printer. Passing an empty `capabilities_xml` will cause + // GetXmlPrinterCapabilitiesForXpsDriver() to fail, otherwise any string will + // succeed. + void SetXmlCapabilitiesForPrinter(const std::string& printer_name, + const std::string& capabilities_xml); +#endif // BUILDFLAG(IS_WIN) + protected: ~TestPrintBackend() override; @@ -79,6 +99,9 @@ std::unique_ptr<PrinterSemanticCapsAndDefaults> caps; std::unique_ptr<PrinterBasicInfo> info; bool blocked_by_permissions = false; +#if BUILDFLAG(IS_WIN) + std::string capabilities_xml; +#endif // BUILDFLAG(IS_WIN) }; std::string default_printer_name_;
diff --git a/printing/backend/test_print_backend_unittest.cc b/printing/backend/test_print_backend_unittest.cc index fbf8f1e3..5615b22a 100644 --- a/printing/backend/test_print_backend_unittest.cc +++ b/printing/backend/test_print_backend_unittest.cc
@@ -12,6 +12,7 @@ #include "base/memory/scoped_refptr.h" #include "base/test/gtest_util.h" +#include "build/build_config.h" #include "mojo/public/cpp/test_support/test_utils.h" #include "printing/backend/mojom/print_backend.mojom.h" #include "printing/backend/print_backend.h" @@ -20,6 +21,10 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/size.h" +#if BUILDFLAG(IS_WIN) +#include "base/types/expected.h" +#endif // BUILDFLAG(IS_WIN) + namespace printing { namespace { @@ -78,6 +83,9 @@ test_print_backend_->AddValidPrinter(kNullDataPrinterName, /*caps=*/nullptr, /*info=*/nullptr); +#if BUILDFLAG(IS_WIN) + test_print_backend_->SetXmlCapabilitiesForPrinter(kNullDataPrinterName, ""); +#endif // BUILDFLAG(IS_WIN) } void AddInvalidDataPrinter() { @@ -310,4 +318,35 @@ EXPECT_TRUE(GetPrintBackend()->IsValidPrinter(kAlternatePrinterName)); } +#if BUILDFLAG(IS_WIN) +TEST_F(TestPrintBackendTest, GetXmlPrinterCapabilitiesForXpsDriver) { + // Should fail when there are no printers in the environment. + base::expected<std::string, mojom::ResultCode> result = + GetPrintBackend()->GetXmlPrinterCapabilitiesForXpsDriver( + kDefaultPrinterName); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error(), mojom::ResultCode::kFailed); + + AddPrinters(); + + // The default XML string set for valid printers should be valid, so verify + // that we receive an XML string. + result = GetPrintBackend()->GetXmlPrinterCapabilitiesForXpsDriver( + kDefaultPrinterName); + ASSERT_TRUE(result.has_value()); + + result = GetPrintBackend()->GetXmlPrinterCapabilitiesForXpsDriver( + kInvalidPrinterName); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error(), mojom::ResultCode::kFailed); + + // Printers set with invalid XML should return failure. Invalid XML is + // considered an empty string for these tests. + result = GetPrintBackend()->GetXmlPrinterCapabilitiesForXpsDriver( + kNullDataPrinterName); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error(), mojom::ResultCode::kFailed); +} +#endif // BUILDFLAG(IS_WIN) + } // namespace printing
diff --git a/services/device/BUILD.gn b/services/device/BUILD.gn index f93bb7c..bad27dc 100644 --- a/services/device/BUILD.gn +++ b/services/device/BUILD.gn
@@ -72,10 +72,7 @@ } if (is_chromeos_ash && use_dbus) { - deps += [ - "//services/device/bluetooth:bluetooth_system", - "//services/device/media_transfer_protocol", - ] + deps += [ "//services/device/media_transfer_protocol" ] } if (is_serial_enabled_platform) { @@ -189,7 +186,6 @@ "//services/device/geolocation:test_support", "//services/device/power_monitor", "//services/device/public/cpp:device_features", - "//services/device/public/cpp/bluetooth:bluetooth_tests", "//services/device/public/cpp/power_monitor", "//services/device/public/mojom", "//services/device/wake_lock", @@ -242,7 +238,6 @@ "//chromeos/ash/components/dbus/biod:test_support", "//chromeos/ash/components/dbus/shill", "//chromeos/ash/components/network:test_support", - "//services/device/bluetooth:bluetooth_system_tests", "//services/device/fingerprint", "//third_party/protobuf:protobuf_lite", ]
diff --git a/services/device/bluetooth/BUILD.gn b/services/device/bluetooth/BUILD.gn deleted file mode 100644 index 81e1730..0000000 --- a/services/device/bluetooth/BUILD.gn +++ /dev/null
@@ -1,43 +0,0 @@ -# Copyright 2018 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/features.gni") - -source_set("bluetooth_system") { - visibility = [ - ":bluetooth_system_tests", - "//services/device:lib", - ] - - sources = [ - "bluetooth_system.cc", - "bluetooth_system.h", - "bluetooth_system_factory.cc", - "bluetooth_system_factory.h", - ] - - public_deps = [ "//services/device/public/mojom" ] - - deps = [ - "//base", - "//dbus", - "//device/bluetooth", - ] -} - -source_set("bluetooth_system_tests") { - testonly = true - - sources = [ "bluetooth_system_unittest.cc" ] - - deps = [ - ":bluetooth_system", - "//base/test:test_support", - "//dbus", - "//device/bluetooth", - "//net", - "//services/device:test_support", - "//testing/gtest", - ] -}
diff --git a/services/device/bluetooth/DEPS b/services/device/bluetooth/DEPS deleted file mode 100644 index 18af175..0000000 --- a/services/device/bluetooth/DEPS +++ /dev/null
@@ -1,9 +0,0 @@ -include_rules = [ - "+dbus", -] - -specific_include_rules = { - "bluetooth_system_unittest.cc": [ - "+third_party/cros_system_api/dbus/service_constants.h" - ], -}
diff --git a/services/device/bluetooth/DIR_METADATA b/services/device/bluetooth/DIR_METADATA deleted file mode 100644 index 9055fda..0000000 --- a/services/device/bluetooth/DIR_METADATA +++ /dev/null
@@ -1,11 +0,0 @@ -# Metadata information for this directory. -# -# For more information on DIR_METADATA files, see: -# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md -# -# For the schema of this file, see Metadata message: -# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto - -monorail { - component: "IO>Bluetooth" -} \ No newline at end of file
diff --git a/services/device/bluetooth/OWNERS b/services/device/bluetooth/OWNERS deleted file mode 100644 index b5fa4e4..0000000 --- a/services/device/bluetooth/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -file://device/bluetooth/OWNERS
diff --git a/services/device/bluetooth/bluetooth_system.cc b/services/device/bluetooth/bluetooth_system.cc deleted file mode 100644 index 8d0e2cf9..0000000 --- a/services/device/bluetooth/bluetooth_system.cc +++ /dev/null
@@ -1,321 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "services/device/bluetooth/bluetooth_system.h" - -#include <algorithm> -#include <array> -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/strings/string_util.h" -#include "dbus/object_path.h" -#include "device/bluetooth/bluetooth_device.h" -#include "device/bluetooth/dbus/bluetooth_adapter_client.h" -#include "device/bluetooth/dbus/bluetooth_admin_policy_client.h" -#include "device/bluetooth/dbus/bluetooth_device_client.h" -#include "device/bluetooth/dbus/bluez_dbus_manager.h" -#include "device/bluetooth/public/cpp/bluetooth_address.h" -#include "mojo/public/cpp/bindings/self_owned_receiver.h" -#include "third_party/abseil-cpp/absl/types/optional.h" - -namespace device { -namespace { - -bool GetDeviceIsBlockedByPolicy(const dbus::ObjectPath& device_path) { - bluez::BluetoothAdminPolicyClient::Properties* properties = - bluez::BluezDBusManager::Get() - ->GetAlternateBluetoothAdminPolicyClient() - ->GetProperties(device_path); - if (!properties) - return false; - - if (!properties->is_blocked_by_policy.is_valid()) - return false; - - return properties->is_blocked_by_policy.value(); -} - -} // namespace - -void BluetoothSystem::Create( - mojo::PendingReceiver<mojom::BluetoothSystem> receiver, - mojo::PendingRemote<mojom::BluetoothSystemClient> client) { - mojo::MakeSelfOwnedReceiver( - std::make_unique<BluetoothSystem>(std::move(client)), - std::move(receiver)); -} - -BluetoothSystem::BluetoothSystem( - mojo::PendingRemote<mojom::BluetoothSystemClient> client) - : client_(std::move(client)) { - GetBluetoothAdapterClient()->AddObserver(this); - - std::vector<dbus::ObjectPath> object_paths = - GetBluetoothAdapterClient()->GetAdapters(); - if (object_paths.empty()) - return; - - active_adapter_ = object_paths[0]; - auto* properties = - GetBluetoothAdapterClient()->GetProperties(active_adapter_.value()); - state_ = properties->powered.value() ? State::kPoweredOn : State::kPoweredOff; -} - -BluetoothSystem::~BluetoothSystem() = default; - -void BluetoothSystem::AdapterAdded(const dbus::ObjectPath& object_path) { - if (active_adapter_) - return; - - active_adapter_ = object_path; - UpdateStateAndNotifyIfNecessary(); -} - -void BluetoothSystem::AdapterRemoved(const dbus::ObjectPath& object_path) { - DCHECK(active_adapter_); - - if (active_adapter_.value() != object_path) - return; - - active_adapter_ = absl::nullopt; - - std::vector<dbus::ObjectPath> object_paths = - GetBluetoothAdapterClient()->GetAdapters(); - for (const auto& new_object_path : object_paths) { - // The removed adapter is still included in GetAdapters(). - if (new_object_path == object_path) - continue; - - active_adapter_ = new_object_path; - break; - } - - UpdateStateAndNotifyIfNecessary(); -} - -void BluetoothSystem::AdapterPropertyChanged( - const dbus::ObjectPath& object_path, - const std::string& property_name) { - // AdapterPropertyChanged is called for each property in the adapter before - // AdapterAdded is called. Immediately return in this case. - if (!active_adapter_) - return; - - if (active_adapter_.value() != object_path) - return; - - auto* properties = - GetBluetoothAdapterClient()->GetProperties(active_adapter_.value()); - - if (properties->powered.name() == property_name) - UpdateStateAndNotifyIfNecessary(); - else if (properties->discovering.name() == property_name) - client_->OnScanStateChanged(GetScanStateFromActiveAdapter()); -} - -void BluetoothSystem::GetState(GetStateCallback callback) { - std::move(callback).Run(state_); -} - -void BluetoothSystem::SetPowered(bool powered, SetPoweredCallback callback) { - switch (state_) { - case State::kUnsupported: - case State::kUnavailable: - std::move(callback).Run(SetPoweredResult::kFailedBluetoothUnavailable); - return; - case State::kTransitioning: - std::move(callback).Run(SetPoweredResult::kFailedInProgress); - return; - case State::kPoweredOff: - case State::kPoweredOn: - break; - } - - if ((state_ == State::kPoweredOn) == powered) { - std::move(callback).Run(SetPoweredResult::kSuccess); - return; - } - - DCHECK_NE(state_, State::kTransitioning); - state_ = State::kTransitioning; - client_->OnStateChanged(state_); - - GetBluetoothAdapterClient() - ->GetProperties(active_adapter_.value()) - ->powered.Set( - powered, - base::BindOnce(&BluetoothSystem::OnSetPoweredFinished, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); -} - -void BluetoothSystem::GetScanState(GetScanStateCallback callback) { - switch (state_) { - case State::kUnsupported: - case State::kUnavailable: - std::move(callback).Run(ScanState::kNotScanning); - return; - case State::kPoweredOff: - // The Scan State when the adapter is Off should always be - // kNotScanning, but the underlying layer makes no guarantees of this. - // To avoid hiding a bug in the underlying layer, get the state from - // the adapter even if it's Off. - case State::kTransitioning: - case State::kPoweredOn: - break; - } - - std::move(callback).Run(GetScanStateFromActiveAdapter()); -} - -void BluetoothSystem::StartScan(StartScanCallback callback) { - switch (state_) { - case State::kUnsupported: - case State::kUnavailable: - case State::kPoweredOff: - case State::kTransitioning: - std::move(callback).Run(StartScanResult::kFailedBluetoothUnavailable); - return; - case State::kPoweredOn: - break; - } - - GetBluetoothAdapterClient()->StartDiscovery( - active_adapter_.value(), - base::BindOnce(&BluetoothSystem::OnStartDiscovery, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); -} - -void BluetoothSystem::StopScan(StopScanCallback callback) { - switch (state_) { - case State::kUnsupported: - case State::kUnavailable: - case State::kPoweredOff: - case State::kTransitioning: - std::move(callback).Run(StopScanResult::kFailedBluetoothUnavailable); - return; - case State::kPoweredOn: - break; - } - - GetBluetoothAdapterClient()->StopDiscovery( - active_adapter_.value(), - base::BindOnce(&BluetoothSystem::OnStopDiscovery, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); -} - -void BluetoothSystem::GetAvailableDevices( - GetAvailableDevicesCallback callback) { - switch (state_) { - case State::kUnsupported: - case State::kUnavailable: - case State::kPoweredOff: - case State::kTransitioning: - std::move(callback).Run({}); - return; - case State::kPoweredOn: - break; - } - - std::vector<dbus::ObjectPath> device_paths = - GetBluetoothDeviceClient()->GetDevicesForAdapter(active_adapter_.value()); - - std::vector<mojom::BluetoothDeviceInfoPtr> devices; - for (const auto& device_path : device_paths) { - auto* properties = GetBluetoothDeviceClient()->GetProperties(device_path); - std::array<uint8_t, 6> parsed_address; - if (!ParseBluetoothAddress(properties->address.value(), parsed_address)) { - LOG(WARNING) << "Failed to parse device address '" - << properties->address.value() << "' for " - << device_path.value(); - continue; - } - - auto device_info = mojom::BluetoothDeviceInfo::New(); - device_info->address = std::move(parsed_address); - device_info->name = properties->name.is_valid() - ? absl::make_optional(properties->name.value()) - : absl::nullopt; - device_info->connection_state = - properties->connected.value() - ? mojom::BluetoothDeviceInfo::ConnectionState::kConnected - : mojom::BluetoothDeviceInfo::ConnectionState::kNotConnected; - device_info->is_paired = properties->paired.value(); - device_info->is_blocked_by_policy = GetDeviceIsBlockedByPolicy(device_path); - - // TODO(ortuno): Get the DeviceType from the device Class and Appearance. - devices.push_back(std::move(device_info)); - } - std::move(callback).Run(std::move(devices)); -} - -bluez::BluetoothAdapterClient* BluetoothSystem::GetBluetoothAdapterClient() { - // Use AlternateBluetoothAdapterClient to avoid interfering with users of the - // regular BluetoothAdapterClient. - return bluez::BluezDBusManager::Get()->GetAlternateBluetoothAdapterClient(); -} - -bluez::BluetoothDeviceClient* BluetoothSystem::GetBluetoothDeviceClient() { - // Use AlternateBluetoothDeviceClient to avoid interfering with users of the - // regular BluetoothDeviceClient. - return bluez::BluezDBusManager::Get()->GetAlternateBluetoothDeviceClient(); -} - -void BluetoothSystem::UpdateStateAndNotifyIfNecessary() { - State old_state = state_; - if (active_adapter_) { - auto* properties = - GetBluetoothAdapterClient()->GetProperties(active_adapter_.value()); - state_ = - properties->powered.value() ? State::kPoweredOn : State::kPoweredOff; - } else { - state_ = State::kUnavailable; - } - - if (old_state != state_) - client_->OnStateChanged(state_); -} - -BluetoothSystem::ScanState BluetoothSystem::GetScanStateFromActiveAdapter() { - bool discovering = GetBluetoothAdapterClient() - ->GetProperties(active_adapter_.value()) - ->discovering.value(); - return discovering ? ScanState::kScanning : ScanState::kNotScanning; -} - -void BluetoothSystem::OnSetPoweredFinished(SetPoweredCallback callback, - bool succeeded) { - if (!succeeded) { - // We change |state_| to `kTransitioning` before trying to set 'powered'. If - // the call to set 'powered' fails, then we need to change it back to - // `kPoweredOn` or `kPoweredOff` depending on the `active_adapter_` state. - UpdateStateAndNotifyIfNecessary(); - } - - std::move(callback).Run(succeeded ? SetPoweredResult::kSuccess - : SetPoweredResult::kFailedUnknownReason); -} - -void BluetoothSystem::OnStartDiscovery( - StartScanCallback callback, - const absl::optional<bluez::BluetoothAdapterClient::Error>& error) { - // TODO(https://crbug.com/897996): Use the name and message in |error| to - // return more specific error codes. - std::move(callback).Run(error ? StartScanResult::kFailedUnknownReason - : StartScanResult::kSuccess); -} - -void BluetoothSystem::OnStopDiscovery( - StopScanCallback callback, - const absl::optional<bluez::BluetoothAdapterClient::Error>& error) { - // TODO(https://crbug.com/897996): Use the name and message in |error| to - // return more specific error codes. - std::move(callback).Run(error ? StopScanResult::kFailedUnknownReason - : StopScanResult::kSuccess); -} - -} // namespace device
diff --git a/services/device/bluetooth/bluetooth_system.h b/services/device/bluetooth/bluetooth_system.h deleted file mode 100644 index 173e6ed..0000000 --- a/services/device/bluetooth/bluetooth_system.h +++ /dev/null
@@ -1,88 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SERVICES_DEVICE_BLUETOOTH_BLUETOOTH_SYSTEM_H_ -#define SERVICES_DEVICE_BLUETOOTH_BLUETOOTH_SYSTEM_H_ - -#include <string> - -#include "base/memory/weak_ptr.h" -#include "dbus/object_path.h" -#include "device/bluetooth/dbus/bluetooth_adapter_client.h" -#include "mojo/public/cpp/bindings/pending_receiver.h" -#include "mojo/public/cpp/bindings/pending_remote.h" -#include "mojo/public/cpp/bindings/remote.h" -#include "services/device/public/mojom/bluetooth_system.mojom.h" -#include "third_party/abseil-cpp/absl/types/optional.h" - -namespace bluez { -class BluetoothAdapterClient; -class BluetoothDeviceClient; -} - -namespace device { - -class BluetoothSystem : public mojom::BluetoothSystem, - public bluez::BluetoothAdapterClient::Observer { - public: - static void Create(mojo::PendingReceiver<mojom::BluetoothSystem> receiver, - mojo::PendingRemote<mojom::BluetoothSystemClient> client); - - explicit BluetoothSystem( - mojo::PendingRemote<mojom::BluetoothSystemClient> client); - - BluetoothSystem(const BluetoothSystem&) = delete; - BluetoothSystem& operator=(const BluetoothSystem&) = delete; - - ~BluetoothSystem() override; - - // bluez::BluetoothAdapterClient::Observer - void AdapterAdded(const dbus::ObjectPath& object_path) override; - void AdapterRemoved(const dbus::ObjectPath& object_path) override; - void AdapterPropertyChanged(const dbus::ObjectPath& object_path, - const std::string& property_name) override; - - // mojom::BluetoothSystem - void GetState(GetStateCallback callback) override; - void SetPowered(bool powered, SetPoweredCallback callback) override; - void GetScanState(GetScanStateCallback callback) override; - void StartScan(StartScanCallback callback) override; - void StopScan(StopScanCallback callback) override; - void GetAvailableDevices(GetAvailableDevicesCallback callback) override; - - private: - bluez::BluetoothAdapterClient* GetBluetoothAdapterClient(); - bluez::BluetoothDeviceClient* GetBluetoothDeviceClient(); - - void UpdateStateAndNotifyIfNecessary(); - - ScanState GetScanStateFromActiveAdapter(); - - void OnSetPoweredFinished(SetPoweredCallback callback, bool succeeded); - - void OnStartDiscovery( - StartScanCallback callback, - const absl::optional<bluez::BluetoothAdapterClient::Error>& error); - void OnStopDiscovery( - StopScanCallback callback, - const absl::optional<bluez::BluetoothAdapterClient::Error>& error); - - mojo::Remote<mojom::BluetoothSystemClient> client_; - - // The ObjectPath of the adapter being used. Updated as BT adapters are - // added and removed. nullopt if there is no adapter. - absl::optional<dbus::ObjectPath> active_adapter_; - - // State of |active_adapter_| or kUnavailable if there is no - // |active_adapter_|. - State state_ = State::kUnavailable; - - // Note: This should remain the last member so it'll be destroyed and - // invalidate its weak pointers before any other members are destroyed. - base::WeakPtrFactory<BluetoothSystem> weak_ptr_factory_{this}; -}; - -} // namespace device - -#endif // SERVICES_DEVICE_BLUETOOTH_BLUETOOTH_SYSTEM_H_
diff --git a/services/device/bluetooth/bluetooth_system_factory.cc b/services/device/bluetooth/bluetooth_system_factory.cc deleted file mode 100644 index 628347f..0000000 --- a/services/device/bluetooth/bluetooth_system_factory.cc +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "services/device/bluetooth/bluetooth_system_factory.h" - -#include <memory> -#include <utility> - -#include "mojo/public/cpp/bindings/self_owned_receiver.h" -#include "services/device/bluetooth/bluetooth_system.h" - -namespace device { - -void BluetoothSystemFactory::CreateFactory( - mojo::PendingReceiver<mojom::BluetoothSystemFactory> receiver) { - mojo::MakeSelfOwnedReceiver(std::make_unique<BluetoothSystemFactory>(), - std::move(receiver)); -} - -BluetoothSystemFactory::BluetoothSystemFactory() = default; - -BluetoothSystemFactory::~BluetoothSystemFactory() = default; - -void BluetoothSystemFactory::Create( - mojo::PendingReceiver<mojom::BluetoothSystem> system_receiver, - mojo::PendingRemote<mojom::BluetoothSystemClient> system_client) { - BluetoothSystem::Create(std::move(system_receiver), std::move(system_client)); -} - -} // namespace device
diff --git a/services/device/bluetooth/bluetooth_system_factory.h b/services/device/bluetooth/bluetooth_system_factory.h deleted file mode 100644 index 01fd5c5..0000000 --- a/services/device/bluetooth/bluetooth_system_factory.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SERVICES_DEVICE_BLUETOOTH_BLUETOOTH_SYSTEM_FACTORY_H_ -#define SERVICES_DEVICE_BLUETOOTH_BLUETOOTH_SYSTEM_FACTORY_H_ - -#include "mojo/public/cpp/bindings/pending_receiver.h" -#include "mojo/public/cpp/bindings/pending_remote.h" -#include "services/device/public/mojom/bluetooth_system.mojom.h" - -namespace device { - -class BluetoothSystemFactory : public mojom::BluetoothSystemFactory { - public: - static void CreateFactory( - mojo::PendingReceiver<mojom::BluetoothSystemFactory> receiver); - - BluetoothSystemFactory(); - - BluetoothSystemFactory(const BluetoothSystemFactory&) = delete; - BluetoothSystemFactory& operator=(const BluetoothSystemFactory&) = delete; - - ~BluetoothSystemFactory() override; - - // mojom::BluetoothSystemFactory - void Create( - mojo::PendingReceiver<mojom::BluetoothSystem> system_receiver, - mojo::PendingRemote<mojom::BluetoothSystemClient> system_client) override; -}; - -} // namespace device - -#endif // SERVICES_DEVICE_BLUETOOTH_BLUETOOTH_SYSTEM_FACTORY_H_
diff --git a/services/device/bluetooth/bluetooth_system_unittest.cc b/services/device/bluetooth/bluetooth_system_unittest.cc deleted file mode 100644 index 425412e9..0000000 --- a/services/device/bluetooth/bluetooth_system_unittest.cc +++ /dev/null
@@ -1,2114 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "services/device/bluetooth/bluetooth_system.h" - -#include <deque> -#include <map> -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/containers/contains.h" -#include "base/observer_list.h" -#include "base/run_loop.h" -#include "base/test/bind.h" -#include "device/bluetooth/dbus/bluetooth_adapter_client.h" -#include "device/bluetooth/dbus/bluetooth_admin_policy_client.h" -#include "device/bluetooth/dbus/bluetooth_device_client.h" -#include "device/bluetooth/dbus/bluez_dbus_manager.h" -#include "mojo/public/cpp/bindings/receiver.h" -#include "mojo/public/cpp/bindings/remote.h" -#include "services/device/device_service_test_base.h" -#include "services/device/public/mojom/bluetooth_system.mojom-test-utils.h" -#include "services/device/public/mojom/bluetooth_system.mojom.h" -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "third_party/cros_system_api/dbus/service_constants.h" - -namespace device { - -namespace { - -// Adapter object paths -constexpr const char kDefaultAdapterObjectPathStr[] = "fake/hci0"; -constexpr const char kAlternateAdapterObjectPathStr[] = "fake/hci1"; - -// Device object paths -constexpr const char kDefaultDeviceObjectPathStr[] = - "fake/hci0/dev_00_11_22_AA_BB_CC"; - -// Device addresses -constexpr const char kDefaultDeviceAddressStr[] = "00:11:22:AA:BB:CC"; -constexpr const char kAlternateDeviceAddressStr[] = "AA:BB:CC:DD:EE:FF"; - -constexpr const std::array<uint8_t, 6> kDefaultDeviceAddressArray = { - 0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC}; - -bool GetValueAndReset(absl::optional<bool>* opt) { - absl::optional<bool> tmp; - tmp.swap(*opt); - return tmp.value(); -} - -struct FakeDeviceOptions { - explicit FakeDeviceOptions( - const std::string& object_path = kDefaultDeviceObjectPathStr) - : object_path(object_path) {} - - dbus::ObjectPath object_path; - - std::string address{kDefaultDeviceAddressStr}; - dbus::ObjectPath adapter_object_path{kDefaultAdapterObjectPathStr}; - absl::optional<std::string> name; - bool paired = false; - bool connected = false; -}; - -// Exposes high-level methods to simulate Bluetooth events e.g. a new adapter -// was added, adapter power state changed, etc. -// -// As opposed to FakeBluetoothAdapterClient, the other fake implementation of -// BluetoothAdapterClient, this class does not have any built-in behavior -// e.g. it won't start triggering device discovery events when StartDiscovery is -// called. It's up to its users to call the relevant Simulate*() method to -// trigger each event. -class DEVICE_BLUETOOTH_EXPORT TestBluetoothAdapterClient - : public bluez::BluetoothAdapterClient { - public: - struct Properties : public bluez::BluetoothAdapterClient::Properties { - explicit Properties(const PropertyChangedCallback& callback) - : BluetoothAdapterClient::Properties( - nullptr, /* object_proxy */ - bluetooth_adapter::kBluetoothAdapterInterface, - callback) {} - ~Properties() override = default; - - void ResetCallCount() { - set_powered_call_count_ = 0; - last_set_powered_value_.reset(); - } - - void SetNextSetPoweredResponse(bool next_response) { - DCHECK(!next_set_powered_response_); - next_set_powered_response_ = next_response; - } - - bool GetLastSetPoweredValue() { return last_set_powered_value_.value(); } - - // dbus::PropertySet override - void Get(dbus::PropertyBase* property, - dbus::PropertySet::GetCallback callback) override { - DVLOG(1) << "Get " << property->name(); - NOTIMPLEMENTED(); - } - - void GetAll() override { - DVLOG(1) << "GetAll"; - NOTIMPLEMENTED(); - } - - void Set(dbus::PropertyBase* property, - dbus::PropertySet::SetCallback callback) override { - DVLOG(1) << "Set " << property->name(); - if (property->name() == powered.name()) { - ++set_powered_call_count_; - last_set_powered_value_ = powered.GetSetValueForTesting(); - if (next_set_powered_response_) { - std::move(callback).Run( - GetValueAndReset(&next_set_powered_response_)); - return; - } - set_powered_callbacks_.push_back(std::move(callback)); - } else { - NOTIMPLEMENTED(); - } - } - - size_t set_powered_call_count_ = 0; - absl::optional<bool> next_set_powered_response_; - absl::optional<bool> last_set_powered_value_; - - // Saved `Set('powered')` callbacks. If there is no next response set for a - // `Set()` call, then the callback is saved here. TestBluetoothAdapterClient - // runs all these callbacks after the adapter is removed. - std::deque<base::OnceCallback<void(bool)>> set_powered_callbacks_; - }; - - TestBluetoothAdapterClient() = default; - ~TestBluetoothAdapterClient() override = default; - - void ResetCallCount() { - for (auto& path_to_properties : adapter_object_paths_to_properties_) { - path_to_properties.second->ResetCallCount(); - } - - for (auto& path_to_call_counts : adapter_object_paths_to_call_counts_) { - path_to_call_counts.second = CallCounts(); - } - } - - // Low level methods to simulate events and operations. All actions are - // performed for `kDefaultAdapterObjectPathStr` unless a different one is - // specified. - - // Simulates a new adapter with |object_path_str|. Its properties are empty, - // 0, or false. - void SimulateAdapterAdded( - const std::string& object_path_str = kDefaultAdapterObjectPathStr) { - dbus::ObjectPath object_path(object_path_str); - - auto [it, was_inserted] = adapter_object_paths_to_properties_.emplace( - object_path, std::make_unique<Properties>(base::BindRepeating( - &TestBluetoothAdapterClient::OnPropertyChanged, - base::Unretained(this), object_path))); - DCHECK(was_inserted); - - DCHECK(!base::Contains(adapter_object_paths_to_call_counts_, object_path)); - adapter_object_paths_to_call_counts_[object_path]; - - DCHECK( - !base::Contains(adapter_object_paths_to_next_responses_, object_path)); - adapter_object_paths_to_next_responses_[object_path]; - - GetProperties(object_path)->powered.ReplaceValue(false); - GetProperties(object_path)->discovering.ReplaceValue(false); - - for (auto& observer : observers_) - observer.AdapterAdded(object_path); - } - - // Simulates the adapter at |object_path_str| being removed. - void SimulateAdapterRemoved( - const std::string& object_path_str = kDefaultAdapterObjectPathStr) { - dbus::ObjectPath object_path(object_path_str); - - // Properties are set to empty, 0, or false right before AdapterRemoved is - // called. - GetProperties(object_path)->powered.ReplaceValue(false); - GetProperties(object_path)->discovering.ReplaceValue(false); - - // When BlueZ calls into AdapterRemoved, the adapter is still exposed - // through GetAdapters() and its properties are still accessible. - for (auto& observer : observers_) - observer.AdapterRemoved(object_path); - - auto properties = - std::move(adapter_object_paths_to_properties_[object_path]); - size_t removed = adapter_object_paths_to_properties_.erase(object_path); - DCHECK_EQ(1u, removed); - removed = adapter_object_paths_to_call_counts_.erase(object_path); - DCHECK_EQ(1u, removed); - removed = adapter_object_paths_to_next_responses_.erase(object_path); - DCHECK_EQ(1u, removed); - - // After the adapter is removed, any pending Set calls get run with `false`. - for (auto& set_powered_callback : properties->set_powered_callbacks_) { - std::move(set_powered_callback).Run(false); - } - } - - // Simulates adapter at |object_path_str| changing its powered state to - // |powered|. - void SimulateAdapterPowerStateChanged( - bool powered, - const std::string& object_path_str = kDefaultAdapterObjectPathStr) { - auto* properties = GetProperties(dbus::ObjectPath(object_path_str)); - properties->powered.ReplaceValue(powered); - - // After the "powered" property changes to false, BlueZ emits a property - // changed event for "discovering" as well, even if the property was false - // already. - if (!powered) - properties->discovering.ReplaceValue(false); - } - - void SetNextSetPoweredResponse( - bool response, - const std::string& object_path_str = kDefaultAdapterObjectPathStr) { - GetProperties(dbus::ObjectPath(object_path_str)) - ->SetNextSetPoweredResponse(response); - } - - size_t GetSetPoweredCallCount( - const std::string& object_path_str = kDefaultAdapterObjectPathStr) { - auto it = adapter_object_paths_to_properties_.find( - dbus::ObjectPath(object_path_str)); - DCHECK(it != adapter_object_paths_to_properties_.end()); - - return it->second->set_powered_call_count_; - } - - bool GetLastSetPoweredValue( - const std::string& object_path_str = kDefaultAdapterObjectPathStr) { - return GetProperties(dbus::ObjectPath(object_path_str)) - ->GetLastSetPoweredValue(); - } - - void SimulateSetPoweredCompleted( - bool success, - const std::string& object_path_str = kDefaultAdapterObjectPathStr) { - auto& callbacks = GetProperties(dbus::ObjectPath(object_path_str)) - ->set_powered_callbacks_; - auto callback = std::move(callbacks.front()); - callbacks.pop_front(); - - std::move(callback).Run(success); - } - - // Simulates adapter at |object_path_str| changing its discovering state to - // |powered|. - void SimulateAdapterDiscoveringStateChanged( - bool discovering, - const std::string& object_path_str = kDefaultAdapterObjectPathStr) { - GetProperties(dbus::ObjectPath(object_path_str)) - ->discovering.ReplaceValue(discovering); - } - - void SetNextStartDiscoveryResponse( - bool response, - const std::string& object_path_str = kDefaultAdapterObjectPathStr) { - dbus::ObjectPath object_path(object_path_str); - - auto& next_response = - adapter_object_paths_to_next_responses_[object_path].start_discovery; - DCHECK(!next_response.has_value()); - next_response = response; - } - - size_t GetStartDiscoveryCallCount( - const std::string& object_path_str = kDefaultAdapterObjectPathStr) { - dbus::ObjectPath object_path(object_path_str); - return adapter_object_paths_to_call_counts_[object_path].start_discovery; - } - - void SetNextStopDiscoveryResponse( - bool response, - const std::string& object_path_str = kDefaultAdapterObjectPathStr) { - dbus::ObjectPath object_path(object_path_str); - auto& next_response = - adapter_object_paths_to_next_responses_[object_path].stop_discovery; - DCHECK(!next_response.has_value()); - next_response = response; - } - - size_t GetStopDiscoveryCallCount( - const std::string& object_path_str = kDefaultAdapterObjectPathStr) { - dbus::ObjectPath object_path(object_path_str); - return adapter_object_paths_to_call_counts_[object_path].stop_discovery; - } - - // Helper methods to perform multiple common operations. - - // Simultes adding an adapter and it changing its state to powered On. - void SimulatePoweredOnAdapter( - const std::string& object_path_str = kDefaultAdapterObjectPathStr) { - SimulateAdapterAdded(object_path_str); - SimulateAdapterPowerStateChanged(true, object_path_str); - } - - // BluetoothAdapterClient: - void Init(dbus::Bus* bus, - const std::string& bluetooth_service_name) override {} - - void AddObserver(Observer* observer) override { - observers_.AddObserver(observer); - } - - void RemoveObserver(Observer* observer) override { - observers_.RemoveObserver(observer); - } - - std::vector<dbus::ObjectPath> GetAdapters() override { - std::vector<dbus::ObjectPath> object_paths; - for (const auto& object_path_to_property : - adapter_object_paths_to_properties_) { - object_paths.push_back(object_path_to_property.first); - } - return object_paths; - } - - Properties* GetProperties(const dbus::ObjectPath& object_path) override { - auto it = adapter_object_paths_to_properties_.find(object_path); - if (it == adapter_object_paths_to_properties_.end()) - return nullptr; - return it->second.get(); - } - - void StartDiscovery(const dbus::ObjectPath& object_path, - ResponseCallback callback) override { - DCHECK(base::Contains(adapter_object_paths_to_call_counts_, object_path)); - ++adapter_object_paths_to_call_counts_[object_path].start_discovery; - - DCHECK( - base::Contains(adapter_object_paths_to_next_responses_, object_path)); - - absl::optional<bool> response; - response.swap( - adapter_object_paths_to_next_responses_[object_path].start_discovery); - - if (!response.value()) { - std::move(callback).Run(Error(kUnknownAdapterError, "Unknown error")); - return; - } - std::move(callback).Run(absl::nullopt); - } - - void StopDiscovery(const dbus::ObjectPath& object_path, - ResponseCallback callback) override { - DCHECK(base::Contains(adapter_object_paths_to_call_counts_, object_path)); - ++adapter_object_paths_to_call_counts_[object_path].stop_discovery; - - DCHECK( - base::Contains(adapter_object_paths_to_next_responses_, object_path)); - - absl::optional<bool> response; - response.swap( - adapter_object_paths_to_next_responses_[object_path].stop_discovery); - - if (!response.value()) { - std::move(callback).Run(Error(kUnknownAdapterError, "Unknown error")); - return; - } - std::move(callback).Run(absl::nullopt); - } - - void RemoveDevice(const dbus::ObjectPath& object_path, - const dbus::ObjectPath& device_path, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void SetDiscoveryFilter(const dbus::ObjectPath& object_path, - const DiscoveryFilter& discovery_filter, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void CreateServiceRecord(const dbus::ObjectPath& object_path, - const bluez::BluetoothServiceRecordBlueZ& record, - ServiceRecordCallback callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void RemoveServiceRecord(const dbus::ObjectPath& object_path, - uint32_t handle, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void ConnectDevice(const dbus::ObjectPath& object_path, - const std::string& address, - const absl::optional<AddressType>& address_type, - ConnectDeviceCallback callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - private: - // Keeps track of how many times methods have been called. - struct CallCounts { - size_t start_discovery; - size_t stop_discovery; - }; - - // Keeps track of the responses to send when a method is called. - struct NextResponses { - NextResponses() = default; - ~NextResponses() = default; - - absl::optional<bool> start_discovery; - absl::optional<bool> stop_discovery; - }; - - void OnPropertyChanged(const dbus::ObjectPath& object_path, - const std::string& property_name) { - for (auto& observer : observers_) { - observer.AdapterPropertyChanged(object_path, property_name); - } - } - - using ObjectPathToProperties = - std::map<dbus::ObjectPath, std::unique_ptr<Properties>>; - ObjectPathToProperties adapter_object_paths_to_properties_; - - // Keeps track of how many times each method has been called for a specific - // adapter ObjectPath. - std::map<dbus::ObjectPath, CallCounts> adapter_object_paths_to_call_counts_; - - // Keeps track of the next responses to send when methods are called for a - // specific adapter ObjectPath. - std::map<dbus::ObjectPath, NextResponses> - adapter_object_paths_to_next_responses_; - - base::ObserverList<Observer>::Unchecked observers_; -}; - -// Exposes high-level methods to simulate Bluetooth device events e.g. a new -// device was added, device connected, etc. -// -// As opposed to FakeBluetoothDeviceClient, the other fake implementation of -// BluetoothDeviceClient, this class does not have any built-in behavior -// e.g. it won't start triggering device discovery events when StartDiscovery is -// called. It's up to its users to call the relevant Simulate*() method to -// trigger each event. -class DEVICE_BLUETOOTH_EXPORT TestBluetoothDeviceClient - : public bluez::BluetoothDeviceClient { - public: - struct Properties : public bluez::BluetoothDeviceClient::Properties { - explicit Properties(const PropertyChangedCallback& callback) - : BluetoothDeviceClient::Properties( - nullptr /* object_proxy */, - bluetooth_device::kBluetoothDeviceInterface, - callback) {} - ~Properties() override = default; - - // dbus::PropertySet - void Get(dbus::PropertyBase* property, - dbus::PropertySet::GetCallback callback) override { - DVLOG(1) << "Get " << property->name(); - NOTIMPLEMENTED(); - } - - void GetAll() override { - DVLOG(1) << "GetAll"; - NOTIMPLEMENTED(); - } - - void Set(dbus::PropertyBase* property, - dbus::PropertySet::SetCallback callback) override { - DVLOG(1) << "Set " << property->name(); - NOTIMPLEMENTED(); - } - }; - - TestBluetoothDeviceClient() = default; - ~TestBluetoothDeviceClient() override = default; - - void SimulateDeviceAdded(const FakeDeviceOptions& options) { - auto [it, was_inserted] = device_object_paths_to_properties_.emplace( - options.object_path, - std::make_unique<Properties>( - base::BindLambdaForTesting([&](const std::string& property_name) { - for (auto& observer : observers_) - observer.DevicePropertyChanged(options.object_path, - property_name); - }))); - - DCHECK(was_inserted); - - auto* properties = GetProperties(options.object_path); - properties->address.ReplaceValue(options.address); - - if (options.name) { - properties->name.set_valid(true); - properties->name.ReplaceValue(options.name.value()); - } - - properties->paired.ReplaceValue(options.paired); - properties->connected.ReplaceValue(options.connected); - properties->adapter.ReplaceValue(options.adapter_object_path); - - for (auto& observer : observers_) - observer.DeviceAdded(options.object_path); - } - - // bluez::BluetoothDeviceClient - void Init(dbus::Bus* bus, - const std::string& bluetooth_service_name) override {} - - void AddObserver(Observer* observer) override { - observers_.AddObserver(observer); - } - - void RemoveObserver(Observer* observer) override { - observers_.RemoveObserver(observer); - } - - std::vector<dbus::ObjectPath> GetDevicesForAdapter( - const dbus::ObjectPath& adapter_path) override { - std::vector<dbus::ObjectPath> devices; - for (const auto& path_and_properties : device_object_paths_to_properties_) { - if (path_and_properties.second->adapter.value() == adapter_path) - devices.push_back(path_and_properties.first); - } - return devices; - } - - Properties* GetProperties(const dbus::ObjectPath& object_path) override { - auto it = device_object_paths_to_properties_.find(object_path); - if (it == device_object_paths_to_properties_.end()) - return nullptr; - return it->second.get(); - } - - void Connect(const dbus::ObjectPath& object_path, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void ConnectClassic(const dbus::ObjectPath& object_path, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void ConnectLE(const dbus::ObjectPath& object_path, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void Disconnect(const dbus::ObjectPath& object_path, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void DisconnectLE(const dbus::ObjectPath& object_path, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void ConnectProfile(const dbus::ObjectPath& object_path, - const std::string& uuid, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void DisconnectProfile(const dbus::ObjectPath& object_path, - const std::string& uuid, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void Pair(const dbus::ObjectPath& object_path, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void CancelPairing(const dbus::ObjectPath& object_path, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void GetConnInfo(const dbus::ObjectPath& object_path, - ConnInfoCallback callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void SetLEConnectionParameters(const dbus::ObjectPath& object_path, - const ConnectionParameters& conn_params, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void GetServiceRecords(const dbus::ObjectPath& object_path, - ServiceRecordsCallback callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void ExecuteWrite(const dbus::ObjectPath& object_path, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - void AbortWrite(const dbus::ObjectPath& object_path, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED(); - } - - private: - using ObjectPathToProperties = - std::map<dbus::ObjectPath, std::unique_ptr<Properties>>; - ObjectPathToProperties device_object_paths_to_properties_; - - base::ObserverList<Observer>::Unchecked observers_; -}; - -// Exposes high-level methods to retrieve Bluetooth device admin policy info. -class DEVICE_BLUETOOTH_EXPORT TestBluetoothAdminPolicyClient - : public bluez::BluetoothAdminPolicyClient { - public: - struct Properties : public bluez::BluetoothAdminPolicyClient::Properties { - explicit Properties(const PropertyChangedCallback& callback) - : BluetoothAdminPolicyClient::Properties( - /*object_proxy=*/nullptr, - bluetooth_admin_policy::kBluetoothAdminPolicyStatusInterface, - callback) {} - ~Properties() override = default; - - // dbus::PropertySet - void Get(dbus::PropertyBase* property, - dbus::PropertySet::GetCallback callback) override { - NOTIMPLEMENTED() << "Get " << property->name(); - } - - void GetAll() override { NOTIMPLEMENTED() << "GetAll"; } - - void Set(dbus::PropertyBase* property, - dbus::PropertySet::SetCallback callback) override { - NOTIMPLEMENTED() << "Set " << property->name(); - } - }; - - TestBluetoothAdminPolicyClient() = default; - ~TestBluetoothAdminPolicyClient() override = default; - - void SimulateAdminPolicyAdded(const dbus::ObjectPath& object_path, - bool is_blocked_by_policy) { - auto [it, was_inserted] = device_object_paths_to_properties_.emplace( - object_path, - std::make_unique<Properties>( - base::BindLambdaForTesting([&](const std::string& property_name) { - for (auto& observer : observers_) - observer.AdminPolicyPropertyChanged(object_path, property_name); - }))); - - DCHECK(was_inserted); - - auto* properties = GetProperties(object_path); - properties->is_blocked_by_policy.ReplaceValue(is_blocked_by_policy); - properties->is_blocked_by_policy.set_valid(true); - - for (auto& observer : observers_) - observer.AdminPolicyAdded(object_path); - } - - // bluez::BluetoothAdminPolicyClient - void Init(dbus::Bus* bus, - const std::string& bluetooth_service_name) override {} - - void AddObserver(Observer* observer) override { - observers_.AddObserver(observer); - } - - void RemoveObserver(Observer* observer) override { - observers_.RemoveObserver(observer); - } - - Properties* GetProperties(const dbus::ObjectPath& object_path) override { - auto it = device_object_paths_to_properties_.find(object_path); - if (it == device_object_paths_to_properties_.end()) - return nullptr; - return it->second.get(); - } - - void SetServiceAllowList(const dbus::ObjectPath& object_path, - const UUIDList& service_uuids, - base::OnceClosure callback, - ErrorCallback error_callback) override { - NOTIMPLEMENTED() << "SetServiceAllowList"; - } - - private: - using ObjectPathToProperties = - std::map<dbus::ObjectPath, std::unique_ptr<Properties>>; - ObjectPathToProperties device_object_paths_to_properties_; - - base::ObserverList<Observer>::Unchecked observers_; -}; - -} // namespace - -class BluetoothSystemTest : public DeviceServiceTestBase, - public mojom::BluetoothSystemClient { - public: - BluetoothSystemTest() = default; - - BluetoothSystemTest(const BluetoothSystemTest&) = delete; - BluetoothSystemTest& operator=(const BluetoothSystemTest&) = delete; - - ~BluetoothSystemTest() override = default; - - void SetUp() override { - DeviceServiceTestBase::SetUp(); - device_service()->BindBluetoothSystemFactory( - system_factory_.BindNewPipeAndPassReceiver()); - - auto test_bluetooth_adapter_client = - std::make_unique<TestBluetoothAdapterClient>(); - test_bluetooth_adapter_client_ = test_bluetooth_adapter_client.get(); - auto test_bluetooth_admin_policy_client = - std::make_unique<TestBluetoothAdminPolicyClient>(); - test_bluetooth_admin_policy_client_ = - test_bluetooth_admin_policy_client.get(); - auto test_bluetooth_device_client = - std::make_unique<TestBluetoothDeviceClient>(); - test_bluetooth_device_client_ = test_bluetooth_device_client.get(); - - std::unique_ptr<bluez::BluezDBusManagerSetter> dbus_setter = - bluez::BluezDBusManager::GetSetterForTesting(); - dbus_setter->SetAlternateBluetoothAdapterClient( - std::move(test_bluetooth_adapter_client)); - dbus_setter->SetAlternateBluetoothAdminPolicyClient( - std::move(test_bluetooth_admin_policy_client)); - dbus_setter->SetAlternateBluetoothDeviceClient( - std::move(test_bluetooth_device_client)); - } - - // Helper methods to avoid AsyncWaiter boilerplate. - mojom::BluetoothSystem::State GetStateAndWait( - mojom::BluetoothSystem* system) { - mojom::BluetoothSystemAsyncWaiter async_waiter(system); - - mojom::BluetoothSystem::State state; - async_waiter.GetState(&state); - - return state; - } - - mojom::BluetoothSystem::SetPoweredResult SetPoweredAndWait( - mojom::BluetoothSystem* system, - bool powered) { - mojom::BluetoothSystemAsyncWaiter async_waiter(system); - - mojom::BluetoothSystem::SetPoweredResult result; - async_waiter.SetPowered(powered, &result); - - return result; - } - - mojom::BluetoothSystem::ScanState GetScanStateAndWait( - mojom::BluetoothSystem* system) { - mojom::BluetoothSystemAsyncWaiter async_waiter(system); - - mojom::BluetoothSystem::ScanState scan_state; - async_waiter.GetScanState(&scan_state); - - return scan_state; - } - - mojom::BluetoothSystem::StartScanResult StartScanAndWait( - mojom::BluetoothSystem* system) { - mojom::BluetoothSystemAsyncWaiter async_waiter(system); - - mojom::BluetoothSystem::StartScanResult result; - async_waiter.StartScan(&result); - - return result; - } - - mojom::BluetoothSystem::StopScanResult StopScanAndWait( - mojom::BluetoothSystem* system) { - mojom::BluetoothSystemAsyncWaiter async_waiter(system); - - mojom::BluetoothSystem::StopScanResult result; - async_waiter.StopScan(&result); - - return result; - } - - std::vector<mojom::BluetoothDeviceInfoPtr> GetAvailableDevicesAndWait( - mojom::BluetoothSystem* system) { - mojom::BluetoothSystemAsyncWaiter async_waiter(system); - - std::vector<mojom::BluetoothDeviceInfoPtr> devices; - async_waiter.GetAvailableDevices(&devices); - - return devices; - } - - // mojom::BluetoothSystemClient - void OnStateChanged(mojom::BluetoothSystem::State state) override { - on_state_changed_states_.push_back(state); - } - - void OnScanStateChanged(mojom::BluetoothSystem::ScanState state) override { - on_scan_state_changed_states_.push_back(state); - } - - protected: - mojo::Remote<mojom::BluetoothSystem> CreateBluetoothSystem() { - mojo::Remote<mojom::BluetoothSystem> system; - system_factory_->Create(system.BindNewPipeAndPassReceiver(), - system_client_receiver_.BindNewPipeAndPassRemote()); - return system; - } - - void ResetResults() { - on_state_changed_states_.clear(); - on_scan_state_changed_states_.clear(); - } - - // Saves the states passed to OnStateChanged. - using StateVector = std::vector<mojom::BluetoothSystem::State>; - StateVector on_state_changed_states_; - - // Saves the states passed to OnScanStateChanged. - using ScanStateVector = std::vector<mojom::BluetoothSystem::ScanState>; - ScanStateVector on_scan_state_changed_states_; - - mojo::Remote<mojom::BluetoothSystemFactory> system_factory_; - - TestBluetoothAdapterClient* test_bluetooth_adapter_client_; - TestBluetoothAdminPolicyClient* test_bluetooth_admin_policy_client_; - TestBluetoothDeviceClient* test_bluetooth_device_client_; - - mojo::Receiver<mojom::BluetoothSystemClient> system_client_receiver_{this}; -}; - -// Tests that the Create method for BluetoothSystemFactory works. -TEST_F(BluetoothSystemTest, FactoryCreate) { - mojo::Remote<mojom::BluetoothSystem> system; - mojo::Receiver<mojom::BluetoothSystemClient> client_receiver(this); - - EXPECT_FALSE(system.is_bound()); - - system_factory_->Create(system.BindNewPipeAndPassReceiver(), - client_receiver.BindNewPipeAndPassRemote()); - base::RunLoop run_loop; - system.FlushAsyncForTesting(run_loop.QuitClosure()); - run_loop.Run(); - - EXPECT_TRUE(system.is_bound()); -} - -// Tests that the state is 'Unavailable' when there is no Bluetooth adapter -// present. -TEST_F(BluetoothSystemTest, State_NoAdapter) { - auto system = CreateBluetoothSystem(); - - EXPECT_EQ(mojom::BluetoothSystem::State::kUnavailable, - GetStateAndWait(system.get())); - EXPECT_TRUE(on_state_changed_states_.empty()); -} - -// Tests that the state is "Off" when the Bluetooth adapter is powered off. -TEST_F(BluetoothSystemTest, State_PoweredOffAdapter) { - test_bluetooth_adapter_client_->SimulateAdapterAdded(); - // Added adapters are Off by default. - - auto system = CreateBluetoothSystem(); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOff, - GetStateAndWait(system.get())); - EXPECT_TRUE(on_state_changed_states_.empty()); -} - -// Tests that the state is "On" when the Bluetooth adapter is powered on. -TEST_F(BluetoothSystemTest, State_PoweredOnAdapter) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_TRUE(on_state_changed_states_.empty()); -} - -// Tests that the state changes to On when the adapter turns on and then changes -// to Off when the adapter turns off. -TEST_F(BluetoothSystemTest, State_PoweredOnThenOff) { - test_bluetooth_adapter_client_->SimulateAdapterAdded(); - - auto system = CreateBluetoothSystem(); - - // The adapter is initially powered off. - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOff, - GetStateAndWait(system.get())); - EXPECT_TRUE(on_state_changed_states_.empty()); - - // Turn adapter on. - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(true); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOn}), - on_state_changed_states_); - ResetResults(); - - // Turn adapter off. - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(false); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOff, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOff}), - on_state_changed_states_); -} - -// Tests that the state is updated as expected when removing and re-adding the -// same adapter. -TEST_F(BluetoothSystemTest, State_AdapterRemoved) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - - // The adapter is initially powered on. - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_TRUE(on_state_changed_states_.empty()); - - // Remove the adapter. The state should change to Unavailable. - test_bluetooth_adapter_client_->SimulateAdapterRemoved(); - - EXPECT_EQ(mojom::BluetoothSystem::State::kUnavailable, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOff, - mojom::BluetoothSystem::State::kUnavailable}), - on_state_changed_states_); - ResetResults(); - - // Add the adapter again; it's off by default. - test_bluetooth_adapter_client_->SimulateAdapterAdded(); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOff, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOff}), - on_state_changed_states_); -} - -// Tests that the state is updated as expected when replacing the adapter with a -// different adapter. -TEST_F(BluetoothSystemTest, State_AdapterReplaced) { - // Start with a powered on adapter. - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter( - kDefaultAdapterObjectPathStr); - - auto system = CreateBluetoothSystem(); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_TRUE(on_state_changed_states_.empty()); - - // Remove the adapter. The state should change to Unavailable. - test_bluetooth_adapter_client_->SimulateAdapterRemoved( - kDefaultAdapterObjectPathStr); - - EXPECT_EQ(mojom::BluetoothSystem::State::kUnavailable, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOff, - mojom::BluetoothSystem::State::kUnavailable}), - on_state_changed_states_); - ResetResults(); - - // Add a different adapter. It's off by default. - test_bluetooth_adapter_client_->SimulateAdapterAdded( - kAlternateAdapterObjectPathStr); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOff, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOff}), - on_state_changed_states_); -} - -// Tests that the state is correctly updated when adding and removing multiple -// adapters. -TEST_F(BluetoothSystemTest, State_AddAndRemoveMultipleAdapters) { - // Start with a powered on default adapter. - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter( - kDefaultAdapterObjectPathStr); - - auto system = CreateBluetoothSystem(); - - // The default adapter is initially powered on. - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_TRUE(on_state_changed_states_.empty()); - - // Add an alternate adapter. The state should not change. - test_bluetooth_adapter_client_->SimulateAdapterAdded( - kAlternateAdapterObjectPathStr); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_TRUE(on_state_changed_states_.empty()); - - // Remove the default adapter. We should retrieve the state from the - // alternate adapter.. - test_bluetooth_adapter_client_->SimulateAdapterRemoved( - kDefaultAdapterObjectPathStr); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOff, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOff}), - on_state_changed_states_); - ResetResults(); - - // Change the alternate adapter's state to On. - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged( - true, kAlternateAdapterObjectPathStr); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOn}), - on_state_changed_states_); - ResetResults(); - - // Add the default adapter again. We should still retrieve the state from - // the alternate adapter. - test_bluetooth_adapter_client_->SimulateAdapterAdded( - kDefaultAdapterObjectPathStr); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_TRUE(on_state_changed_states_.empty()); -} - -// Tests that an extra adapter changing state does not interfer with the state. -TEST_F(BluetoothSystemTest, State_ChangeStateMultipleAdapters) { - // Start with a powered on default adapter. - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter( - kDefaultAdapterObjectPathStr); - - auto system = CreateBluetoothSystem(); - - // The default adapter is initially powered on. - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_TRUE(on_state_changed_states_.empty()); - - // Add an extra alternate adapter. The state should not change. - test_bluetooth_adapter_client_->SimulateAdapterAdded( - kAlternateAdapterObjectPathStr); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_TRUE(on_state_changed_states_.empty()); - - // Turn the alternate adapter on. The state should not change. - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged( - true, kAlternateAdapterObjectPathStr); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_TRUE(on_state_changed_states_.empty()); - - // Turn the alternate adapter off. The state should not change. - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged( - false, kAlternateAdapterObjectPathStr); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_TRUE(on_state_changed_states_.empty()); -} - -// Tests that SetPowered fails if there is no adapter. -TEST_F(BluetoothSystemTest, SetPowered_NoAdapter) { - auto system = CreateBluetoothSystem(); - - EXPECT_EQ( - mojom::BluetoothSystem::SetPoweredResult::kFailedBluetoothUnavailable, - SetPoweredAndWait(system.get(), false)); - EXPECT_EQ( - mojom::BluetoothSystem::SetPoweredResult::kFailedBluetoothUnavailable, - SetPoweredAndWait(system.get(), false)); -} - -// Tests setting powered to "Off" when the adapter is "Off" already. -TEST_F(BluetoothSystemTest, SetPoweredOff_SucceedsAdapterInitiallyOff) { - test_bluetooth_adapter_client_->SimulateAdapterAdded(); - // Added adapters are Off by default. - - auto system = CreateBluetoothSystem(); - - // The adapter is initially "Off" so a call to turn it "Off" should have no - // effect but the call should still succeed. - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess, - SetPoweredAndWait(system.get(), false)); - EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetSetPoweredCallCount()); -} - -// Tests setting powered to "On" when the adapter is "On" already. -TEST_F(BluetoothSystemTest, SetPoweredOn_SucceedsAdapterInitiallyOn) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - - // The adapter is initially "On" so a call to turn it "On" should have no - // effect but the call should still succeed. - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess, - SetPoweredAndWait(system.get(), true)); - EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetSetPoweredCallCount()); -} - -// Tests successfully setting powered to "Off when the adapter is "On". -TEST_F(BluetoothSystemTest, SetPoweredOff_SucceedsAdapterInitiallyOn) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - - // Try to power off the adapter. - test_bluetooth_adapter_client_->SetNextSetPoweredResponse(true); - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess, - SetPoweredAndWait(system.get(), false)); - EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetSetPoweredCallCount()); - EXPECT_FALSE(test_bluetooth_adapter_client_->GetLastSetPoweredValue()); - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kTransitioning}), - on_state_changed_states_); - ResetResults(); - - // Simulate the adapter actually powering off. - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(false); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOff, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOff}), - on_state_changed_states_); -} - -// Tests successfully setting powered to "On" when the adapter is "Off". -TEST_F(BluetoothSystemTest, SetPoweredOn_SucceedsAdapterInitiallyOff) { - test_bluetooth_adapter_client_->SimulateAdapterAdded(); - // Added adapters are Off by default. - - auto system = CreateBluetoothSystem(); - - // Try to power on the adapter. - test_bluetooth_adapter_client_->SetNextSetPoweredResponse(true); - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess, - SetPoweredAndWait(system.get(), true)); - EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetSetPoweredCallCount()); - EXPECT_TRUE(test_bluetooth_adapter_client_->GetLastSetPoweredValue()); - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kTransitioning}), - on_state_changed_states_); - ResetResults(); - - // Simulate the adapter actually powering on. - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(true); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOn}), - on_state_changed_states_); -} - -// Tests failing to set powered to "Off when the adapter is "On". -TEST_F(BluetoothSystemTest, SetPoweredOff_FailsAdapterInitiallyOn) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - - test_bluetooth_adapter_client_->SetNextSetPoweredResponse(false); - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kFailedUnknownReason, - SetPoweredAndWait(system.get(), false)); - EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetSetPoweredCallCount()); - EXPECT_FALSE(test_bluetooth_adapter_client_->GetLastSetPoweredValue()); - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kTransitioning, - mojom::BluetoothSystem::State::kPoweredOn}), - on_state_changed_states_); -} - -// Tests failing to set powered to "On" when the adapter is "Off". -TEST_F(BluetoothSystemTest, SetPoweredOn_FailsAdapterInitiallyOff) { - test_bluetooth_adapter_client_->SimulateAdapterAdded(); - // Added adapters are Off by default. - - auto system = CreateBluetoothSystem(); - - test_bluetooth_adapter_client_->SetNextSetPoweredResponse(false); - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kFailedUnknownReason, - SetPoweredAndWait(system.get(), true)); - EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetSetPoweredCallCount()); - EXPECT_TRUE(test_bluetooth_adapter_client_->GetLastSetPoweredValue()); - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOff, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kTransitioning, - mojom::BluetoothSystem::State::kPoweredOff}), - on_state_changed_states_); -} - -// Tests that the state is correctly updated if the adapter is removed -// when a call to set powered to "On" is pending. -TEST_F(BluetoothSystemTest, SetPoweredOn_AdapterRemovedWhilePending) { - test_bluetooth_adapter_client_->SimulateAdapterAdded(); - // Added adapters are Off by default. - - auto system = CreateBluetoothSystem(); - - absl::optional<mojom::BluetoothSystem::SetPoweredResult> result; - - // Start a SetPowered call and wait for the state to change to kTransitioning. - base::RunLoop set_powered_run_loop; - system->SetPowered(true, base::BindLambdaForTesting( - [&](mojom::BluetoothSystem::SetPoweredResult r) { - result = r; - set_powered_run_loop.Quit(); - })); - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kTransitioning}), - on_state_changed_states_); - ResetResults(); - - // Simulate the adapter being removed. This immediately changes the "powered" - // property of the adapter to `false` and then removes the adapter. - test_bluetooth_adapter_client_->SimulateAdapterRemoved(); - EXPECT_EQ(mojom::BluetoothSystem::State::kUnavailable, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOff, - mojom::BluetoothSystem::State::kUnavailable}), - on_state_changed_states_); - ResetResults(); - - // Wait for SetPowered() to reply. - set_powered_run_loop.Run(); - - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kFailedUnknownReason, - result.value()); - - // There should not be any state changes when SetPowered eventually fails. - EXPECT_TRUE(on_state_changed_states_.empty()); -} - -// Tests that the state is correctly updated if the adapter is removed -// when a call to set powered to "Off" is pending. -TEST_F(BluetoothSystemTest, SetPoweredOff_AdapterRemovedWhilePending) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - - absl::optional<mojom::BluetoothSystem::SetPoweredResult> result; - - // Start a SetPowered call and wait for the state to change to kTransitioning. - base::RunLoop set_powered_run_loop; - system->SetPowered(false, - base::BindLambdaForTesting( - [&](mojom::BluetoothSystem::SetPoweredResult r) { - result = r; - set_powered_run_loop.Quit(); - })); - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kTransitioning}), - on_state_changed_states_); - ResetResults(); - - // Simulate the adapter being removed. This immediately changes the "powered" - // property of the adapter to `false` and then removes the adapter. - test_bluetooth_adapter_client_->SimulateAdapterRemoved(); - EXPECT_EQ(mojom::BluetoothSystem::State::kUnavailable, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOff, - mojom::BluetoothSystem::State::kUnavailable}), - on_state_changed_states_); - ResetResults(); - - // Wait for SetPowered() to reply. - set_powered_run_loop.Run(); - - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kFailedUnknownReason, - result.value()); - - // There should not be any state changes when SetPowered eventually fails. - EXPECT_TRUE(on_state_changed_states_.empty()); -} - -// Tests power off call with pending power off call. -TEST_F(BluetoothSystemTest, SetPoweredOff_PendingSetPoweredOff) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - ASSERT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - - // Start powering off BT and wait for the state to change to - // kTransitioning. - base::RunLoop run_loop; - absl::optional<mojom::BluetoothSystem::SetPoweredResult> - set_powered_off_result; - system->SetPowered(false, - base::BindLambdaForTesting( - [&](mojom::BluetoothSystem::SetPoweredResult r) { - set_powered_off_result = r; - run_loop.Quit(); - })); - - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kTransitioning}), - on_state_changed_states_); - EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetSetPoweredCallCount()); - EXPECT_FALSE(test_bluetooth_adapter_client_->GetLastSetPoweredValue()); - - ResetResults(); - test_bluetooth_adapter_client_->ResetCallCount(); - - // Try to power off BT; should fail with kInProgress. - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kFailedInProgress, - SetPoweredAndWait(system.get(), false)); - - EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetSetPoweredCallCount()); - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector(), on_state_changed_states_); - - ResetResults(); - - // Finish initial call to power off BT. - test_bluetooth_adapter_client_->SimulateSetPoweredCompleted(true); - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(false); - run_loop.Run(); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOff, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOff}), - on_state_changed_states_); - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess, - set_powered_off_result.value()); -} - -// Tests power off call with pending power on call. -TEST_F(BluetoothSystemTest, SetPoweredOff_PendingSetPoweredOn) { - test_bluetooth_adapter_client_->SimulateAdapterAdded(); - - auto system = CreateBluetoothSystem(); - ASSERT_EQ(mojom::BluetoothSystem::State::kPoweredOff, - GetStateAndWait(system.get())); - - // Start powering on BT and wait for the state to change to - // kTransitioning. - base::RunLoop run_loop; - absl::optional<mojom::BluetoothSystem::SetPoweredResult> - set_powered_on_result; - system->SetPowered(true, base::BindLambdaForTesting( - [&](mojom::BluetoothSystem::SetPoweredResult r) { - set_powered_on_result = r; - run_loop.Quit(); - })); - - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kTransitioning}), - on_state_changed_states_); - EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetSetPoweredCallCount()); - EXPECT_TRUE(test_bluetooth_adapter_client_->GetLastSetPoweredValue()); - - ResetResults(); - test_bluetooth_adapter_client_->ResetCallCount(); - - // Try to power off BT; should fail with kInProgress. - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kFailedInProgress, - SetPoweredAndWait(system.get(), false)); - - EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetSetPoweredCallCount()); - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector(), on_state_changed_states_); - - ResetResults(); - - // Finish initial call to power on BT. - test_bluetooth_adapter_client_->SimulateSetPoweredCompleted(true); - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(true); - run_loop.Run(); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOn}), - on_state_changed_states_); - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess, - set_powered_on_result.value()); -} - -// Tests power on call with pending power off call. -TEST_F(BluetoothSystemTest, SetPoweredOn_PendingSetPoweredOff) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - ASSERT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - - // Start powering off BT and wait for the state to change to - // kTransitioning. - base::RunLoop run_loop; - absl::optional<mojom::BluetoothSystem::SetPoweredResult> - set_powered_off_result; - system->SetPowered(false, - base::BindLambdaForTesting( - [&](mojom::BluetoothSystem::SetPoweredResult r) { - set_powered_off_result = r; - run_loop.Quit(); - })); - - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kTransitioning}), - on_state_changed_states_); - EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetSetPoweredCallCount()); - EXPECT_FALSE(test_bluetooth_adapter_client_->GetLastSetPoweredValue()); - - ResetResults(); - test_bluetooth_adapter_client_->ResetCallCount(); - - // Try to power on BT; should fail with kInProgress. - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kFailedInProgress, - SetPoweredAndWait(system.get(), true)); - - EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetSetPoweredCallCount()); - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector(), on_state_changed_states_); - - ResetResults(); - - // Finish initial call to power off BT. - test_bluetooth_adapter_client_->SimulateSetPoweredCompleted(true); - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(false); - run_loop.Run(); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOff, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOff}), - on_state_changed_states_); - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess, - set_powered_off_result.value()); -} - -// Tests power on call with pending power on call. -TEST_F(BluetoothSystemTest, SetPoweredOn_PendingSetPoweredOn) { - test_bluetooth_adapter_client_->SimulateAdapterAdded(); - - auto system = CreateBluetoothSystem(); - ASSERT_EQ(mojom::BluetoothSystem::State::kPoweredOff, - GetStateAndWait(system.get())); - - // Start powering on BT and wait for the state to change to - // kTransitioning. - base::RunLoop run_loop; - absl::optional<mojom::BluetoothSystem::SetPoweredResult> - set_powered_on_result; - system->SetPowered(true, base::BindLambdaForTesting( - [&](mojom::BluetoothSystem::SetPoweredResult r) { - set_powered_on_result = r; - run_loop.Quit(); - })); - - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kTransitioning}), - on_state_changed_states_); - EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetSetPoweredCallCount()); - EXPECT_TRUE(test_bluetooth_adapter_client_->GetLastSetPoweredValue()); - - ResetResults(); - test_bluetooth_adapter_client_->ResetCallCount(); - - // Try to power on BT; should fail with kInProgress. - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kFailedInProgress, - SetPoweredAndWait(system.get(), true)); - - EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetSetPoweredCallCount()); - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector(), on_state_changed_states_); - - ResetResults(); - - // Finish initial call to power on BT. - test_bluetooth_adapter_client_->SimulateSetPoweredCompleted(true); - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(true); - run_loop.Run(); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOn}), - on_state_changed_states_); - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess, - set_powered_on_result.value()); -} - -// Tests scan state is kNotScanning when there is no adapter. -TEST_F(BluetoothSystemTest, ScanState_NoAdapter) { - auto system = CreateBluetoothSystem(); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_TRUE(on_scan_state_changed_states_.empty()); -} - -// Tests scan state is kNotScanning when the adapter is not scanning. -TEST_F(BluetoothSystemTest, ScanState_NotScanning) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - // Added adapters are not scanning by default. - - auto system = CreateBluetoothSystem(); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_TRUE(on_scan_state_changed_states_.empty()); -} - -// Tests scan state is kScanning when the adapter is scanning. -TEST_F(BluetoothSystemTest, ScanState_Scanning) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - test_bluetooth_adapter_client_->SimulateAdapterDiscoveringStateChanged(true); - - auto system = CreateBluetoothSystem(); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kScanning, - GetScanStateAndWait(system.get())); - EXPECT_TRUE(on_scan_state_changed_states_.empty()); -} - -// Tests scan state changes to kScanning when the adapter starts scanning and -// then changes to kNotScanning when the adapter stops scanning. -TEST_F(BluetoothSystemTest, ScanState_ScanningThenNotScanning) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_TRUE(on_scan_state_changed_states_.empty()); - - // Adapter starts scanning. - test_bluetooth_adapter_client_->SimulateAdapterDiscoveringStateChanged(true); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kScanning, - GetScanStateAndWait(system.get())); - EXPECT_EQ(ScanStateVector({mojom::BluetoothSystem::ScanState::kScanning}), - on_scan_state_changed_states_); - ResetResults(); - - // Adapter stops scanning. - test_bluetooth_adapter_client_->SimulateAdapterDiscoveringStateChanged(false); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_EQ(ScanStateVector({mojom::BluetoothSystem::ScanState::kNotScanning}), - on_scan_state_changed_states_); -} - -// Tests scan state is updated as expected when removing and re-adding the same -// adapter. -TEST_F(BluetoothSystemTest, ScanState_AdapterRemoved) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - test_bluetooth_adapter_client_->SimulateAdapterDiscoveringStateChanged(true); - - auto system = CreateBluetoothSystem(); - - // The adapter is initially scanning. - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kScanning, - GetScanStateAndWait(system.get())); - - // Remove the adapter. The state should change to not scanning. - test_bluetooth_adapter_client_->SimulateAdapterRemoved(); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_EQ(ScanStateVector({mojom::BluetoothSystem::ScanState::kNotScanning}), - on_scan_state_changed_states_); - ResetResults(); - - // Add the adapter again; it's not scanning by default. - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_TRUE(on_scan_state_changed_states_.empty()); - - // The adapter starts scanning again. - test_bluetooth_adapter_client_->SimulateAdapterDiscoveringStateChanged(true); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kScanning, - GetScanStateAndWait(system.get())); - EXPECT_EQ(ScanStateVector({mojom::BluetoothSystem::ScanState::kScanning}), - on_scan_state_changed_states_); -} - -// Tests that scan state is updated as expected when replacing the adapter with -// a different adapter. -TEST_F(BluetoothSystemTest, ScanState_AdapterReplaced) { - // Start with a scanning adapter. - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter( - kDefaultAdapterObjectPathStr); - test_bluetooth_adapter_client_->SimulateAdapterDiscoveringStateChanged( - true, kDefaultAdapterObjectPathStr); - - auto system = CreateBluetoothSystem(); - - // The adapter is initially scanning. - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kScanning, - GetScanStateAndWait(system.get())); - - // Remove the adapter. The state should change to kNotScanning. - test_bluetooth_adapter_client_->SimulateAdapterRemoved( - kDefaultAdapterObjectPathStr); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_EQ(ScanStateVector({mojom::BluetoothSystem::ScanState::kNotScanning}), - on_scan_state_changed_states_); - ResetResults(); - - // Add a different adapter. It's not scanning by default. - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter( - kAlternateAdapterObjectPathStr); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_TRUE(on_scan_state_changed_states_.empty()); - - // The new adapter starts scanning. - test_bluetooth_adapter_client_->SimulateAdapterDiscoveringStateChanged( - true, kAlternateAdapterObjectPathStr); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kScanning, - GetScanStateAndWait(system.get())); - EXPECT_EQ(ScanStateVector({mojom::BluetoothSystem::ScanState::kScanning}), - on_scan_state_changed_states_); -} - -// Tests that StartScan fails if there is no adapter. -TEST_F(BluetoothSystemTest, StartScan_NoAdapter) { - auto system = CreateBluetoothSystem(); - - EXPECT_EQ( - mojom::BluetoothSystem::StartScanResult::kFailedBluetoothUnavailable, - StartScanAndWait(system.get())); -} - -// Tests that StartScan fails if the adapter is "Off". -TEST_F(BluetoothSystemTest, StartScan_AdapterOff) { - test_bluetooth_adapter_client_->SimulateAdapterAdded(); - // Added adapters are Off by default. - - auto system = CreateBluetoothSystem(); - - EXPECT_EQ( - mojom::BluetoothSystem::StartScanResult::kFailedBluetoothUnavailable, - StartScanAndWait(system.get())); - EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetStartDiscoveryCallCount()); -} - -// Tests that StartScan succeeds and the scan state is correctly updated. -TEST_F(BluetoothSystemTest, StartScan_Succeeds) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - - test_bluetooth_adapter_client_->SetNextStartDiscoveryResponse(true); - EXPECT_EQ(mojom::BluetoothSystem::StartScanResult::kSuccess, - StartScanAndWait(system.get())); - EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetStartDiscoveryCallCount()); - - // TODO(ortuno): Test for kTransitioning once implemented. - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_EQ(ScanStateVector(), on_scan_state_changed_states_); - ResetResults(); - - test_bluetooth_adapter_client_->SimulateAdapterDiscoveringStateChanged(true); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kScanning, - GetScanStateAndWait(system.get())); - EXPECT_EQ(ScanStateVector({mojom::BluetoothSystem::ScanState::kScanning}), - on_scan_state_changed_states_); -} - -// Tests that StartScan fails and the scan state is correctly updated. -TEST_F(BluetoothSystemTest, StartScan_Fails) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - - test_bluetooth_adapter_client_->SetNextStartDiscoveryResponse(false); - EXPECT_EQ(mojom::BluetoothSystem::StartScanResult::kFailedUnknownReason, - StartScanAndWait(system.get())); - EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetStartDiscoveryCallCount()); - - // TODO(ortuno): Test for kTransitioning once implemented. - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_EQ(ScanStateVector(), on_scan_state_changed_states_); -} - -// Tests that StartScan fails when the adapter is powering on. -TEST_F(BluetoothSystemTest, StartScan_FailsDuringPowerOn) { - test_bluetooth_adapter_client_->SimulateAdapterAdded(); - // Added adapters are Off by default. - - auto system = CreateBluetoothSystem(); - - // Start powering on the adapter. - test_bluetooth_adapter_client_->SetNextSetPoweredResponse(true); - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess, - SetPoweredAndWait(system.get(), true)); - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - ResetResults(); - - // Start scan should fail without sending the command to the adapter. - EXPECT_EQ( - mojom::BluetoothSystem::StartScanResult::kFailedBluetoothUnavailable, - StartScanAndWait(system.get())); - EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetStartDiscoveryCallCount()); - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_TRUE(on_scan_state_changed_states_.empty()); - - // Finish powering on the adapter. - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(true); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOn}), - on_state_changed_states_); -} - -// Tests that StartScan fails when the adapter is powering off. -TEST_F(BluetoothSystemTest, StartScan_FailsDuringPowerOff) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - - // Start powering off the adapter. - test_bluetooth_adapter_client_->SetNextSetPoweredResponse(true); - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess, - SetPoweredAndWait(system.get(), false)); - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - ResetResults(); - - // Start scan should fail without sending the command to the adapter. - EXPECT_EQ( - mojom::BluetoothSystem::StartScanResult::kFailedBluetoothUnavailable, - StartScanAndWait(system.get())); - EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetStartDiscoveryCallCount()); - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_TRUE(on_scan_state_changed_states_.empty()); - - // Finish powering off the adapter. - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(false); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOff, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOff}), - on_state_changed_states_); -} - -// Tests that StopScan fails if there is no adapter. -TEST_F(BluetoothSystemTest, StopScan_NoAdapter) { - auto system = CreateBluetoothSystem(); - - EXPECT_EQ(mojom::BluetoothSystem::StopScanResult::kFailedBluetoothUnavailable, - StopScanAndWait(system.get())); -} - -// Tests that StopScan fails if the adapter is "Off". -TEST_F(BluetoothSystemTest, StopScan_AdapterOff) { - test_bluetooth_adapter_client_->SimulateAdapterAdded(); - // Added adapters are Off by default. - - auto system = CreateBluetoothSystem(); - - EXPECT_EQ(mojom::BluetoothSystem::StopScanResult::kFailedBluetoothUnavailable, - StopScanAndWait(system.get())); - EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetStopDiscoveryCallCount()); -} - -// Tests that StopScan succeeds and the scan state is correctly updated. -TEST_F(BluetoothSystemTest, StopScan_Succeeds) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - - // Successfully start scanning. - test_bluetooth_adapter_client_->SetNextStartDiscoveryResponse(true); - StartScanAndWait(system.get()); - test_bluetooth_adapter_client_->SimulateAdapterDiscoveringStateChanged(true); - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kScanning, - GetScanStateAndWait(system.get())); - ResetResults(); - - test_bluetooth_adapter_client_->SetNextStopDiscoveryResponse(true); - EXPECT_EQ(mojom::BluetoothSystem::StopScanResult::kSuccess, - StopScanAndWait(system.get())); - EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetStopDiscoveryCallCount()); - - // TODO(ortuno): Test for kTransitioning once implemented. - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kScanning, - GetScanStateAndWait(system.get())); - EXPECT_EQ(ScanStateVector(), on_scan_state_changed_states_); - ResetResults(); - - test_bluetooth_adapter_client_->SimulateAdapterDiscoveringStateChanged(false); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_EQ(ScanStateVector({mojom::BluetoothSystem::ScanState::kNotScanning}), - on_scan_state_changed_states_); -} - -// Tests that StopScan fails and the scan state is correctly updated. -TEST_F(BluetoothSystemTest, StopScan_Fails) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - - // Successfully start scanning. - test_bluetooth_adapter_client_->SetNextStartDiscoveryResponse(true); - StartScanAndWait(system.get()); - test_bluetooth_adapter_client_->SimulateAdapterDiscoveringStateChanged(true); - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kScanning, - GetScanStateAndWait(system.get())); - ResetResults(); - - test_bluetooth_adapter_client_->SetNextStopDiscoveryResponse(false); - EXPECT_EQ(mojom::BluetoothSystem::StopScanResult::kFailedUnknownReason, - StopScanAndWait(system.get())); - EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetStopDiscoveryCallCount()); - - // TODO(ortuno): Test for kTransitioning once implemented. - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kScanning, - GetScanStateAndWait(system.get())); - EXPECT_EQ(ScanStateVector(), on_scan_state_changed_states_); -} - -// Tests that StopScan fails if when the adapter is powering on. -TEST_F(BluetoothSystemTest, StopScan_FailsDuringPowerOn) { - test_bluetooth_adapter_client_->SimulateAdapterAdded(); - // Added adapters are Off by default. - - auto system = CreateBluetoothSystem(); - - // Start powering on the adapter. - test_bluetooth_adapter_client_->SetNextSetPoweredResponse(true); - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess, - SetPoweredAndWait(system.get(), true)); - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - ResetResults(); - - // Stop scan should fail without sending the command to the adapter. - EXPECT_EQ(mojom::BluetoothSystem::StopScanResult::kFailedBluetoothUnavailable, - StopScanAndWait(system.get())); - EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetStopDiscoveryCallCount()); - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_TRUE(on_scan_state_changed_states_.empty()); - - // Finish powering on the adapter. - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(true); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOn}), - on_state_changed_states_); -} - -TEST_F(BluetoothSystemTest, StopScan_FailsDuringPowerOff) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - - // Start scanning. - test_bluetooth_adapter_client_->SetNextStartDiscoveryResponse(true); - EXPECT_EQ(mojom::BluetoothSystem::StartScanResult::kSuccess, - StartScanAndWait(system.get())); - test_bluetooth_adapter_client_->SimulateAdapterDiscoveringStateChanged(true); - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kScanning, - GetScanStateAndWait(system.get())); - - // Start powering off the adapter. - test_bluetooth_adapter_client_->SetNextSetPoweredResponse(true); - EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess, - SetPoweredAndWait(system.get(), false)); - EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning, - GetStateAndWait(system.get())); - ResetResults(); - - // Stop scan should fail without sending the command to the adapter. - EXPECT_EQ(mojom::BluetoothSystem::StopScanResult::kFailedBluetoothUnavailable, - StopScanAndWait(system.get())); - EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetStopDiscoveryCallCount()); - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kScanning, - GetScanStateAndWait(system.get())); - EXPECT_TRUE(on_scan_state_changed_states_.empty()); - - // Finish powering off the adapter. - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(false); - - EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOff, - GetStateAndWait(system.get())); - EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOff}), - on_state_changed_states_); -} - -// Tests that the scan state is correctly updated if the adapter is removed -// during scanning. -TEST_F(BluetoothSystemTest, Scan_AdapterRemovedWhileScanning) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - - // Start scanning. - test_bluetooth_adapter_client_->SetNextStartDiscoveryResponse(true); - StartScanAndWait(system.get()); - test_bluetooth_adapter_client_->SimulateAdapterDiscoveringStateChanged(true); - ASSERT_EQ(mojom::BluetoothSystem::ScanState::kScanning, - GetScanStateAndWait(system.get())); - ResetResults(); - - // Remove the adapter. Scan state should change to kNotScanning. - test_bluetooth_adapter_client_->SimulateAdapterRemoved(); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_EQ(ScanStateVector({mojom::BluetoothSystem::ScanState::kNotScanning}), - on_scan_state_changed_states_); -} - -// Tests that the scan state is correctly updated if the adapter turns off -// during scanning. -TEST_F(BluetoothSystemTest, Scan_PowerOffWhileScanning) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - - auto system = CreateBluetoothSystem(); - - // Start scanning. - test_bluetooth_adapter_client_->SetNextStartDiscoveryResponse(true); - StartScanAndWait(system.get()); - test_bluetooth_adapter_client_->SimulateAdapterDiscoveringStateChanged(true); - ASSERT_EQ(mojom::BluetoothSystem::ScanState::kScanning, - GetScanStateAndWait(system.get())); - ResetResults(); - - // Power off the adapter. Scan state should change to kNotScanning. - test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(false); - - EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning, - GetScanStateAndWait(system.get())); - EXPECT_EQ(ScanStateVector({mojom::BluetoothSystem::ScanState::kNotScanning}), - on_scan_state_changed_states_); -} - -// Tests addresses are parsed correctly. -TEST_F(BluetoothSystemTest, GetAvailableDevices_AddressParser) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - auto system = CreateBluetoothSystem(); - - static const struct { - std::string object_path; - std::string address; - } device_cases[] = { - // Invalid addresses - {"1", "00:11"}, // Too short - {"2", "00:11:22:AA:BB:CC:DD"}, // Too long - {"3", "00|11|22|AA|BB|CC"}, // Invalid separator - {"4", "00:11:22:XX:BB:CC"}, // Invalid character - // Valid addresses - {"5", "00:11:22:aa:bb:cc"}, // Lowercase - {"6", "00:11:22:AA:BB:CC"}, // Uppercase - }; - - for (const auto& device : device_cases) { - FakeDeviceOptions fake_options(device.object_path); - fake_options.address = device.address; - test_bluetooth_device_client_->SimulateDeviceAdded(fake_options); - } - - auto devices = GetAvailableDevicesAndWait(system.get()); - ASSERT_EQ(2u, devices.size()); - - const std::array<uint8_t, 6> expected_address = {0x00, 0x11, 0x22, - 0xAA, 0xBB, 0xCC}; - EXPECT_EQ(expected_address, devices[0]->address); - EXPECT_EQ(expected_address, devices[1]->address); -} - -// Tests all properties of devices are returned correctly. -TEST_F(BluetoothSystemTest, GetAvailableDevices) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - auto system = CreateBluetoothSystem(); - - { - FakeDeviceOptions fake_options("1"); - fake_options.address = kDefaultDeviceAddressStr; - fake_options.name = "Fake Device"; - fake_options.paired = true; - fake_options.connected = true; - test_bluetooth_device_client_->SimulateDeviceAdded(fake_options); - test_bluetooth_admin_policy_client_->SimulateAdminPolicyAdded( - fake_options.object_path, /*is_blocked_by_policy=*/true); - } - { - FakeDeviceOptions fake_options("2"); - fake_options.address = kAlternateDeviceAddressStr; - fake_options.name = absl::nullopt; - fake_options.paired = false; - fake_options.connected = false; - test_bluetooth_device_client_->SimulateDeviceAdded(fake_options); - test_bluetooth_admin_policy_client_->SimulateAdminPolicyAdded( - fake_options.object_path, /*is_blocked_by_policy=*/false); - } - - auto devices = GetAvailableDevicesAndWait(system.get()); - ASSERT_EQ(2u, devices.size()); - - mojom::BluetoothDeviceInfoPtr device_with_name; - mojom::BluetoothDeviceInfoPtr device_without_name; - if (devices[0]->address == kDefaultDeviceAddressArray) { - device_with_name = std::move(devices[0]); - device_without_name = std::move(devices[1]); - } else { - device_with_name = std::move(devices[1]); - device_without_name = std::move(devices[0]); - } - - EXPECT_EQ(device_with_name->name.value(), "Fake Device"); - EXPECT_TRUE(device_with_name->is_paired); - EXPECT_TRUE(device_with_name->is_blocked_by_policy); - EXPECT_EQ(device_with_name->connection_state, - mojom::BluetoothDeviceInfo::ConnectionState::kConnected); - - EXPECT_FALSE(!!device_without_name->name); - EXPECT_FALSE(device_without_name->is_paired); - EXPECT_FALSE(device_without_name->is_blocked_by_policy); - EXPECT_EQ(device_without_name->connection_state, - mojom::BluetoothDeviceInfo::ConnectionState::kNotConnected); -} - -// Tests that if a device existed before BluetoothSystem was created, the -// device is still returned when calling GetAvailableDevices(). -TEST_F(BluetoothSystemTest, GetAvailableDevices_ExistingDevice) { - test_bluetooth_adapter_client_->SimulatePoweredOnAdapter(); - test_bluetooth_device_client_->SimulateDeviceAdded(FakeDeviceOptions()); - - auto system = CreateBluetoothSystem(); - - auto devices = GetAvailableDevicesAndWait(system.get()); - ASSERT_EQ(1u, devices.size()); - - EXPECT_EQ(kDefaultDeviceAddressArray, devices[0]->address); - EXPECT_FALSE(devices[0]->name); - EXPECT_EQ(mojom::BluetoothDeviceInfo::ConnectionState::kNotConnected, - devices[0]->connection_state); - EXPECT_FALSE(devices[0]->is_paired); -} - -} // namespace device
diff --git a/services/device/device_service.cc b/services/device/device_service.cc index e21ddc7..eb983158 100644 --- a/services/device/device_service.cc +++ b/services/device/device_service.cc
@@ -16,7 +16,6 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/system/message_pipe.h" #include "services/device/binder_overrides.h" -#include "services/device/bluetooth/bluetooth_system_factory.h" #include "services/device/compute_pressure/pressure_manager_impl.h" #include "services/device/device_posture/device_posture_platform_provider.h" #include "services/device/device_posture/device_posture_provider_impl.h" @@ -249,11 +248,6 @@ #endif #if BUILDFLAG(IS_CHROMEOS_ASH) -void DeviceService::BindBluetoothSystemFactory( - mojo::PendingReceiver<mojom::BluetoothSystemFactory> receiver) { - BluetoothSystemFactory::CreateFactory(std::move(receiver)); -} - void DeviceService::BindMtpManager( mojo::PendingReceiver<mojom::MtpManager> receiver) { if (!mtp_device_manager_)
diff --git a/services/device/device_service.h b/services/device/device_service.h index 17b67ea..ddf60de11 100644 --- a/services/device/device_service.h +++ b/services/device/device_service.h
@@ -51,7 +51,6 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "services/device/media_transfer_protocol/mtp_device_manager.h" -#include "services/device/public/mojom/bluetooth_system.mojom.h" #endif #if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(USE_UDEV) @@ -184,8 +183,6 @@ #endif #if BUILDFLAG(IS_CHROMEOS_ASH) - void BindBluetoothSystemFactory( - mojo::PendingReceiver<mojom::BluetoothSystemFactory> receiver) override; void BindMtpManager( mojo::PendingReceiver<mojom::MtpManager> receiver) override; #endif
diff --git a/services/device/public/cpp/bluetooth/BUILD.gn b/services/device/public/cpp/bluetooth/BUILD.gn index 561943a..2470ecf5 100644 --- a/services/device/public/cpp/bluetooth/BUILD.gn +++ b/services/device/public/cpp/bluetooth/BUILD.gn
@@ -8,27 +8,5 @@ "bluetooth_utils.h", ] - deps = [ - "//base", - "//device/bluetooth", - "//device/bluetooth/public/cpp:cpp", - "//device/bluetooth/strings", - "//services/device/public/mojom", - "//ui/base", - ] -} - -source_set("bluetooth_tests") { - testonly = true - - sources = [ "bluetooth_utils_unittest.cc" ] - - deps = [ - ":bluetooth", - "//base", - "//device/bluetooth/strings:strings_grit", - "//services/device/public/mojom", - "//testing/gtest", - "//ui/base", - ] + deps = [ "//device/bluetooth/public/cpp:cpp" ] }
diff --git a/services/device/public/cpp/bluetooth/bluetooth_system_mojom_traits.cc b/services/device/public/cpp/bluetooth/bluetooth_system_mojom_traits.cc deleted file mode 100644 index cd0b8e3..0000000 --- a/services/device/public/cpp/bluetooth/bluetooth_system_mojom_traits.cc +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "services/device/public/cpp/bluetooth/bluetooth_system_mojom_traits.h" - -namespace mojo { - -// static -bool StructTraits< - device::mojom::BluetoothAddressDataView, - std::array<uint8_t, 6>>::Read(device::mojom::BluetoothAddressDataView data, - std::array<uint8_t, 6>* out_address) { - ArrayDataView<uint8_t> address; - data.GetAddressDataView(&address); - if (address.is_null()) - return false; - - // The size is validated by the generated validation code. - DCHECK_EQ(6u, address.size()); - - std::copy_n(address.data(), 6, std::begin(*out_address)); - - return true; -} - -} // namespace mojo
diff --git a/services/device/public/cpp/bluetooth/bluetooth_system_mojom_traits.h b/services/device/public/cpp/bluetooth/bluetooth_system_mojom_traits.h deleted file mode 100644 index 45fac70e..0000000 --- a/services/device/public/cpp/bluetooth/bluetooth_system_mojom_traits.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SERVICES_DEVICE_PUBLIC_CPP_BLUETOOTH_BLUETOOTH_SYSTEM_MOJOM_TRAITS_H_ -#define SERVICES_DEVICE_PUBLIC_CPP_BLUETOOTH_BLUETOOTH_SYSTEM_MOJOM_TRAITS_H_ - -#include <vector> - -#include "base/containers/span.h" -#include "mojo/public/cpp/bindings/struct_traits.h" -#include "services/device/public/mojom/bluetooth_system.mojom.h" - -namespace mojo { - -template <> -class StructTraits<device::mojom::BluetoothAddressDataView, - std::array<uint8_t, 6>> { - public: - static base::span<const uint8_t, 6> address( - const std::array<uint8_t, 6>& addr) { - return base::make_span(addr); - } - - static bool Read(device::mojom::BluetoothAddressDataView data, - std::array<uint8_t, 6>* out_address); -}; - -} // namespace mojo - -#endif // SERVICES_DEVICE_PUBLIC_CPP_BLUETOOTH_BLUETOOTH_SYSTEM_MOJOM_TRAITS_H_
diff --git a/services/device/public/cpp/bluetooth/bluetooth_utils.cc b/services/device/public/cpp/bluetooth/bluetooth_utils.cc index 1c9c908..1aeb308 100644 --- a/services/device/public/cpp/bluetooth/bluetooth_utils.cc +++ b/services/device/public/cpp/bluetooth/bluetooth_utils.cc
@@ -4,87 +4,8 @@ #include "services/device/public/cpp/bluetooth/bluetooth_utils.h" -#include <string> - -#include "base/strings/string_number_conversions.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "device/bluetooth/string_util_icu.h" -#include "device/bluetooth/strings/grit/bluetooth_strings.h" -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "ui/base/l10n/l10n_util.h" - namespace device { -using DeviceType = mojom::BluetoothDeviceInfo::DeviceType; - -std::u16string GetBluetoothAddressForDisplay( - const std::array<uint8_t, 6>& address) { - static constexpr char kAddressFormat[] = - "%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX"; - - return base::UTF8ToUTF16( - base::StringPrintf(kAddressFormat, address[0], address[1], address[2], - address[3], address[4], address[5])); -} - -std::u16string GetBluetoothDeviceNameForDisplay( - const mojom::BluetoothDeviceInfoPtr& device_info) { - if (device_info->name) { - const std::string& device_name = device_info->name.value(); - if (HasGraphicCharacter(device_name)) - return base::UTF8ToUTF16(device_name); - } - - auto address_utf16 = GetBluetoothAddressForDisplay(device_info->address); - auto device_type = device_info->device_type; - switch (device_type) { - case DeviceType::kComputer: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_COMPUTER, - address_utf16); - case DeviceType::kPhone: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PHONE, - address_utf16); - case DeviceType::kModem: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MODEM, - address_utf16); - case DeviceType::kAudio: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_AUDIO, - address_utf16); - case DeviceType::kCarAudio: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_CAR_AUDIO, - address_utf16); - case DeviceType::kVideo: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_VIDEO, - address_utf16); - case DeviceType::kPeripheral: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PERIPHERAL, - address_utf16); - case DeviceType::kJoystick: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_JOYSTICK, - address_utf16); - case DeviceType::kGamepad: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_GAMEPAD, - address_utf16); - case DeviceType::kKeyboard: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_KEYBOARD, - address_utf16); - case DeviceType::kMouse: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MOUSE, - address_utf16); - case DeviceType::kTablet: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_TABLET, - address_utf16); - case DeviceType::kKeyboardMouseCombo: - return l10n_util::GetStringFUTF16( - IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO, address_utf16); - case DeviceType::kUnknown: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN, - address_utf16); - } - NOTREACHED(); -} - const BluetoothUUID& GetSerialPortProfileUUID() { // The Serial Port Profile (SPP) UUID is 1101. // https://chromium-review.googlesource.com/c/chromium/src/+/2334682/17..19
diff --git a/services/device/public/cpp/bluetooth/bluetooth_utils.h b/services/device/public/cpp/bluetooth/bluetooth_utils.h index 705f803..2cecfa9 100644 --- a/services/device/public/cpp/bluetooth/bluetooth_utils.h +++ b/services/device/public/cpp/bluetooth/bluetooth_utils.h
@@ -5,28 +5,10 @@ #ifndef SERVICES_DEVICE_PUBLIC_CPP_BLUETOOTH_BLUETOOTH_UTILS_H_ #define SERVICES_DEVICE_PUBLIC_CPP_BLUETOOTH_BLUETOOTH_UTILS_H_ -#include <string> - #include "device/bluetooth/public/cpp/bluetooth_uuid.h" -#include "services/device/public/mojom/bluetooth_system.mojom.h" namespace device { -// Returns the address suitable for displaying e.g. "AA:BB:CC:DD:00:11". -std::u16string GetBluetoothAddressForDisplay( - const std::array<uint8_t, 6>& address); - -// Returns the name of the device suitable for displaying, this may -// be a synthesized string containing the address and localized type name -// if the device has no obtained name. -std::u16string GetBluetoothDeviceNameForDisplay( - const mojom::BluetoothDeviceInfoPtr& device_info); - -// Returns an accessibility label for the device based on name or address and -// device type. -std::u16string GetBluetoothDeviceLabelForAccessibility( - const mojom::BluetoothDeviceInfoPtr& device_info); - // Returns a BluetoothUUID for a Bluetooth SPP device. const BluetoothUUID& GetSerialPortProfileUUID();
diff --git a/services/device/public/cpp/bluetooth/bluetooth_utils_unittest.cc b/services/device/public/cpp/bluetooth/bluetooth_utils_unittest.cc deleted file mode 100644 index 1a577f8..0000000 --- a/services/device/public/cpp/bluetooth/bluetooth_utils_unittest.cc +++ /dev/null
@@ -1,118 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "services/device/public/cpp/bluetooth/bluetooth_utils.h" - -#include "base/files/file_path.h" -#include "base/path_service.h" -#include "services/device/public/mojom/bluetooth_system.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "ui/base/l10n/l10n_util.h" - -namespace device { - -using mojom::BluetoothDeviceInfo; -using mojom::BluetoothDeviceInfoPtr; - -constexpr std::array<uint8_t, 6> kAddress = {0x00, 0x00, 0x00, - 0x00, 0x00, 0x00}; -constexpr char kName[] = "Foo Bar"; -constexpr char16_t kName16[] = u"Foo Bar"; -constexpr char kUnicodeName[] = "❤❤❤❤"; -constexpr char16_t kUnicodeName16[] = u"❤❤❤❤"; -constexpr char kEmptyName[] = ""; -constexpr char kWhitespaceName[] = " "; -constexpr char kUnicodeWhitespaceName[] = " "; - -TEST(BluetoothUtilsTest, - GetBluetoothDeviceNameForDisplay_NoNameAndNoUnknownDeviceType) { - BluetoothDeviceInfoPtr info = BluetoothDeviceInfo::New(); - info->address = kAddress; - info->name = absl::nullopt; - info->device_type = BluetoothDeviceInfo::DeviceType::kUnknown; - EXPECT_EQ(u"Unknown or Unsupported Device (00:00:00:00:00:00)", - GetBluetoothDeviceNameForDisplay(info)); -} - -TEST(BluetoothUtilsTest, - GetBluetoothDeviceNameForDisplay_NoNameAndPeripheralDeviceType) { - BluetoothDeviceInfoPtr info = BluetoothDeviceInfo::New(); - info->address = kAddress; - info->name = absl::nullopt; - info->device_type = BluetoothDeviceInfo::DeviceType::kPeripheral; - EXPECT_EQ(u"Peripheral (00:00:00:00:00:00)", - GetBluetoothDeviceNameForDisplay(info)); -} - -TEST(BluetoothUtilsTest, - GetBluetoothDeviceNameForDisplay_NoNameAndComputerDeviceType) { - BluetoothDeviceInfoPtr info = BluetoothDeviceInfo::New(); - info->address = kAddress; - info->name = absl::nullopt; - info->device_type = BluetoothDeviceInfo::DeviceType::kComputer; - EXPECT_EQ(u"Computer (00:00:00:00:00:00)", - GetBluetoothDeviceNameForDisplay(info)); -} - -TEST(BluetoothUtilsTest, - GetBluetoothDeviceNameForDisplay_NameAndUnknownDeviceType) { - BluetoothDeviceInfoPtr info = BluetoothDeviceInfo::New(); - info->address = kAddress; - info->name = kName; - info->device_type = BluetoothDeviceInfo::DeviceType::kUnknown; - EXPECT_EQ(kName16, GetBluetoothDeviceNameForDisplay(info)); -} - -TEST(BluetoothUtilsTest, - GetBluetoothDeviceNameForDisplay_NameAndComputerDeviceType) { - BluetoothDeviceInfoPtr info = BluetoothDeviceInfo::New(); - info->address = kAddress; - info->name = kName; - info->device_type = BluetoothDeviceInfo::DeviceType::kComputer; - EXPECT_EQ(kName16, GetBluetoothDeviceNameForDisplay(info)); -} - -TEST(BluetoothUtilsTest, GetBluetoothDeviceNameForDisplay_UnicodeName) { - BluetoothDeviceInfoPtr info = BluetoothDeviceInfo::New(); - info->address = kAddress; - info->name = kUnicodeName; - info->device_type = BluetoothDeviceInfo::DeviceType::kComputer; - EXPECT_EQ(kUnicodeName16, GetBluetoothDeviceNameForDisplay(info)); -} - -TEST(BluetoothUtilsTest, GetBluetoothDeviceNameForDisplay_EmptyName) { - BluetoothDeviceInfoPtr info = BluetoothDeviceInfo::New(); - info->address = kAddress; - info->name = kEmptyName; - info->device_type = BluetoothDeviceInfo::DeviceType::kComputer; - EXPECT_EQ(u"Computer (00:00:00:00:00:00)", - GetBluetoothDeviceNameForDisplay(info)); -} - -TEST(BluetoothUtilsTest, GetBluetoothDeviceNameForDisplay_WhitespaceName) { - BluetoothDeviceInfoPtr info = BluetoothDeviceInfo::New(); - info->address = kAddress; - info->name = kWhitespaceName; - info->device_type = BluetoothDeviceInfo::DeviceType::kComputer; - EXPECT_EQ(u"Computer (00:00:00:00:00:00)", - GetBluetoothDeviceNameForDisplay(info)); -} - -TEST(BluetoothUtilsTest, - GetBluetoothDeviceNameForDisplay_UnicodeWhitespaceName) { - BluetoothDeviceInfoPtr info = BluetoothDeviceInfo::New(); - info->address = kAddress; - info->name = kUnicodeWhitespaceName; - info->device_type = BluetoothDeviceInfo::DeviceType::kComputer; - EXPECT_EQ(u"Computer (00:00:00:00:00:00)", - GetBluetoothDeviceNameForDisplay(info)); -} - -TEST(BluetoothUtilsTest, GetBluetoothAddressForDisplay) { - EXPECT_EQ(u"AA:BB:CC:00:11:22", GetBluetoothAddressForDisplay( - {0xAA, 0xBB, 0xCC, 0x00, 0x11, 0x22})); -} - -} // namespace device
diff --git a/services/device/public/mojom/BUILD.gn b/services/device/public/mojom/BUILD.gn index 935a6d9..9eb8417 100644 --- a/services/device/public/mojom/BUILD.gn +++ b/services/device/public/mojom/BUILD.gn
@@ -11,7 +11,6 @@ sources = [ "battery_monitor.mojom", "battery_status.mojom", - "bluetooth_system.mojom", "device_posture_provider.mojom", "fingerprint.mojom", "geolocation.mojom", @@ -61,8 +60,6 @@ cpp = "::std::array<::uint8_t, 6>" }, ] - traits_headers = [ "//services/device/public/cpp/bluetooth/bluetooth_system_mojom_traits.h" ] - traits_sources = [ "//services/device/public/cpp/bluetooth/bluetooth_system_mojom_traits.cc" ] traits_public_deps = [ "//base" ] }, ]
diff --git a/services/device/public/mojom/bluetooth_system.mojom b/services/device/public/mojom/bluetooth_system.mojom deleted file mode 100644 index c89d36d..0000000 --- a/services/device/public/mojom/bluetooth_system.mojom +++ /dev/null
@@ -1,205 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module device.mojom; - -// MAC Address for Bluetooth devices. -// Bluetooth Device Address (or BD_ADDR) is a unique 48-bit identifier assigned -// to each Bluetooth device by the manufacturer. -struct BluetoothAddress { - array<uint8, 6> address; -}; - -// These fields are placed in a struct to be nullable. -struct BluetoothDeviceBatteryInfo { - // The remaining battery of the device. - uint8 battery_percentage; -}; - -// Holds information about a Bluetooth Device. -struct BluetoothDeviceInfo { - enum ConnectionState { - kNotConnected, - kConnecting, - kConnected, - }; - - // Represent the different types of Bluetooth devices that we support - // or are aware of. Based on the Device Classes specified by the Bluetooth SIG - // https://www.bluetooth.com/specifications/assigned-numbers/baseband. - enum DeviceType { - kUnknown, - kComputer, - kPhone, - kModem, - kAudio, - kCarAudio, - kVideo, - kPeripheral, - kJoystick, - kGamepad, - kKeyboard, - kMouse, - kTablet, - kKeyboardMouseCombo, - }; - - // The MAC Address of the device e.g. AA:BB:CC:00:11:22. - BluetoothAddress address; - - // Name of the device. Retrieved during the inquiry response for Classic - // devices, from the Advertisement from LE devices, or from the devices itself - // after connecting to it. - string? name; - - // Indicates whether the device is not connected, connecting, or already - // connected. - ConnectionState connection_state; - - // Indicates whether the device is paired to the system. - bool is_paired; - - // Retrieved from the the Bluetooth class[1] for Classic and Dual devices and - // from the appearance characteristic[2] for LE devices. - // - // [1] https://www.bluetooth.com/specifications/assigned-numbers/baseband - // [2] https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.appearance.xml - DeviceType device_type; - - BluetoothDeviceBatteryInfo? battery_info; - - // Indicates whether or not device features are restricted by admin policy. - bool is_blocked_by_policy = false; -}; - -// Factory to get an instance of the BluetoothSystem interface. -interface BluetoothSystemFactory { - Create(pending_receiver<BluetoothSystem> system, - pending_remote<BluetoothSystemClient> system_client); -}; - -// TODO(b/231254441): Remove BluetoothSystem. -// High level interface targeted towards UI level components that: -// - Show the BT radio state and allow users to change it. -// - Show a list of nearby, connected and paired BT Devices. -// - Start and stop BT scans. -// - Connect to and pair with BT devices. -// -// This interface is implemented only on Chrome OS and lives in the Device -// Service. -interface BluetoothSystem { - - // State of Bluetooth. - enum State { - // The platform does not support Bluetooth. - kUnsupported, - // The platform supports Bluetooth but we can’t use it right now e.g. a BT - // radio is not present. - kUnavailable, - // Bluetooth radio is off. - kPoweredOff, - // State is transitioning between PoweredOff and PoweredOn or vice versa. - kTransitioning, - // Bluetooth radio is on. - kPoweredOn, - }; - - GetState() => (State state); - - enum SetPoweredResult { - // Command successfully sent to BT radio or ignored if the new state matches - // the current state. OnStateChanged call is imminent if the former. - kSuccess, - // Unknown failure when sending the command to the BT radio. - kFailedUnknownReason, - // Can't use Bluetooth right now e.g. a BT radio is not present. - kFailedBluetoothUnavailable, - // Can't change the radio state right now, there is an in-progress call. - kFailedInProgress, - }; - - // Attempts to change the state of the Bluetooth to `kPoweredOn` if |powered| - // and `kPoweredOff` otherwise . Callback is run with `kSuccess` if the - // command was successfully sent to the BT radio. The state immediately - // changes to kTransitioning and once the BT radio actually changes state - // BluetoothSystemClient::OnStateChanged will be called. Does not support - // concurrent calls. - // - // To keep the implementation simple and because no clients need it (UI - // clients disable the power toggle during `kTransitioning`), this function - // does not support concurrent calls. Meaning, if there is a pending call to - // SetPowered(), all new calls to SetPowered() will immediately fail with - // `kFailedInProgress`. - // - // TODO(https://crbug.com/896113): This function is missing one feature: - // 1. The new state should be saved in the user's pref so that the next time - // the machine restarts the state matches the user pref. - SetPowered(bool powered) => (SetPoweredResult result); - - // Whether the BT radio is scanning for devices. - enum ScanState { - // The BT radio is not scanning for devices, Bluetooth is unavailable, or - // the BT radio is off. - kNotScanning, - // State is transitioning between Scanning and Not Scanning and vice versa. - kTransitioning, - // Scanning for devices. - kScanning, - }; - - GetScanState() => (ScanState scan_state); - - enum StartScanResult { - // Command successfully sent to BT radio or ignored if already scanning. - // OnScanStateChanged call is imminent if the former. - kSuccess, - // Unknown failure when sending the command to the BT radio. - kFailedUnknownReason, - // Can't use Bluetooth right now e.g. BT radio is off, not present, or - // transitioning between states. - kFailedBluetoothUnavailable, - // TODO(https://crbug.com/897996): Add more specific error codes. - }; - - // Attempts to start scanning for Bluetooth devices. Callback is run with - // `kSuccess` if the command was successfully sent to the BT radio. Once the - // BT radio actually starts scanning for devices, - // BluetoothSystemClient::OnScanStateChanged will be called. - // TODO(https://crbug.com/897996): This function is missing two features: - // 1. Support concurrent calls; currently BlueZ just drops other calls if - // there is one in progress already. - // 2. Return more detailed error codes. - StartScan() => (StartScanResult result); - - enum StopScanResult { - // Command successfully sent to BT radio. - kSuccess, - // Unknown failure when sending the command to the BT radio. - kFailedUnknownReason, - // Can't use Bluetooth right now e.g. BT radio is off, or not present. - kFailedBluetoothUnavailable, - // TODO(https://crbug.com/897996): Add more specific error codes. - }; - - // Attempts to stop scanning for Bluetooth devices. Callback is run with - // `kSuccess` if the command was successfully sent to the BT radio. Once the - // BT radio actually stops scanning for devices, - // BluetoothSystemClient::OnScanStateChanged will be called. - // TODO(https://crbug.com/897996): This function is missing two features: - // 1. Support concurrent calls; currently BlueZ just drops other calls if - // there is one in progress already. - // 2. Return more detailed error codes. - StopScan() => (StopScanResult result); - - // Returns a list of devices we consider to be active. This includes - // recently seen devices, paired devices, and connected devices. - GetAvailableDevices() => (array<BluetoothDeviceInfo> devices); -}; - -// Interface used by clients of BluetoothSystem to get notified of events -// like Bluetooth State changes. -interface BluetoothSystemClient { - OnStateChanged(BluetoothSystem.State new_state); - OnScanStateChanged(BluetoothSystem.ScanState new_state); -};
diff --git a/services/device/public/mojom/device_service.mojom b/services/device/public/mojom/device_service.mojom index 34205fa9..f8f1b90 100644 --- a/services/device/public/mojom/device_service.mojom +++ b/services/device/public/mojom/device_service.mojom
@@ -28,9 +28,6 @@ import "services/device/public/mojom/device_posture_provider.mojom"; [EnableIf=is_chromeos_ash] -import "services/device/public/mojom/bluetooth_system.mojom"; - -[EnableIf=is_chromeos_ash] import "services/device/public/mojom/mtp_manager.mojom"; [EnableIf=enable_hid] @@ -80,10 +77,6 @@ [EnableIf=enable_hid] BindHidManager(pending_receiver<HidManager> receiver); - // Binds a BluetoothSystemFactory endpoint. - [EnableIf=is_chromeos_ash] - BindBluetoothSystemFactory(pending_receiver<BluetoothSystemFactory> receiver); - // Binds a MtpManager endpoint. [EnableIf=is_chromeos_ash] BindMtpManager(pending_receiver<MtpManager> receiver);
diff --git a/services/network/cookie_settings.cc b/services/network/cookie_settings.cc index 9e89fa22..ef60df1a 100644 --- a/services/network/cookie_settings.cc +++ b/services/network/cookie_settings.cc
@@ -306,6 +306,7 @@ const GURL& url, const net::SiteForCookies& site_for_cookies, const url::Origin* top_frame_origin, + const net::FirstPartySetMetadata& first_party_set_metadata, net::CookieAccessResultList& maybe_included_cookies, net::CookieAccessResultList& excluded_cookies) const { const CookieSettingWithMetadata setting_with_metadata = @@ -324,6 +325,13 @@ } else { cookie.access_result.status.AddExclusionReason( net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES); + if (IsThirdPartyCookieBlockedInSamePartySites( + setting_with_metadata.third_party_blocking_outcome, + first_party_set_metadata)) { + cookie.access_result.status.AddExclusionReason( + net::CookieInclusionStatus:: + EXCLUDE_THIRD_PARTY_BLOCKED_WITHIN_FIRST_PARTY_SET); + } } } for (net::CookieWithAccessResult& cookie : excluded_cookies) { @@ -386,6 +394,18 @@ ThirdPartyBlockingOutcome::kPartitionedStateAllowed; } +// static +bool CookieSettings::IsThirdPartyCookieBlockedInSamePartySites( + ThirdPartyBlockingOutcome third_party_blocking_outcome, + const net::FirstPartySetMetadata& first_party_set_metadata) { + // If partitioned state is allowed only, it means the cookie was excluded due + // to the third-party cookie blocking setting. + if (third_party_blocking_outcome != + ThirdPartyBlockingOutcome::kPartitionedStateAllowed) + return false; + return first_party_set_metadata.AreSitesInSameFirstPartySet(); +} + bool CookieSettings::IsHypotheticalCookieAllowed( const CookieSettingWithMetadata& setting_with_metadata, bool is_same_party,
diff --git a/services/network/cookie_settings.h b/services/network/cookie_settings.h index ee083b7..5c56eb2 100644 --- a/services/network/cookie_settings.h +++ b/services/network/cookie_settings.h
@@ -16,6 +16,7 @@ #include "net/base/features.h" #include "net/base/network_delegate.h" #include "net/cookies/canonical_cookie.h" +#include "net/first_party_sets/first_party_set_metadata.h" #include "net/first_party_sets/same_party_context.h" #include "services/network/public/cpp/session_cookie_delete_predicate.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -134,6 +135,7 @@ const GURL& url, const net::SiteForCookies& site_for_cookies, const url::Origin* top_frame_origin, + const net::FirstPartySetMetadata& first_party_set_metadata, net::CookieAccessResultList& maybe_included_cookies, net::CookieAccessResultList& excluded_cookies) const; @@ -239,6 +241,12 @@ bool is_partitioned, ThirdPartyBlockingOutcome third_party_blocking_outcome); + // Checks if a cookie was blocked by third-party cookie blocking but the + // cookie belongs to a site in the same First-Party Set as the top-level site. + static bool IsThirdPartyCookieBlockedInSamePartySites( + ThirdPartyBlockingOutcome third_party_blocking_outcome, + const net::FirstPartySetMetadata& first_party_set_metadata); + // Returns whether *some* cookie would be allowed to be sent in this context, // according to the user's settings. Note that cookies may still be "excluded" // for other reasons, even if this method returns true.
diff --git a/services/network/cookie_settings_unittest.cc b/services/network/cookie_settings_unittest.cc index 94a0281..1195f6d 100644 --- a/services/network/cookie_settings_unittest.cc +++ b/services/network/cookie_settings_unittest.cc
@@ -794,8 +794,12 @@ url::Origin origin = url::Origin::Create(GURL(kURL)); EXPECT_FALSE(settings.AnnotateAndMoveUserBlockedCookies( - GURL(kURL), net::SiteForCookies(), &origin, maybe_included_cookies, - excluded_cookies)); + GURL(kURL), net::SiteForCookies(), &origin, + net::FirstPartySetMetadata( + net::SamePartyContext(net::SamePartyContext::Type::kCrossParty), + /*frame_entry=*/nullptr, + /*top_frame_entry=*/nullptr), + maybe_included_cookies, excluded_cookies)); EXPECT_THAT(maybe_included_cookies, IsEmpty()); EXPECT_THAT( @@ -834,6 +838,47 @@ ElementsAre(base::Bucket(/*min=*/1, /*count=*/1))); } +TEST_P(CookieSettingsTest, + AnnotateAndMoveUserBlockedCookies_SitesInFirstPartySet) { + CookieSettings settings; + settings.set_block_third_party_cookies(true); + + net::CookieAccessResultList maybe_included_cookies = { + {*MakeCanonicalCookie("third_party_but_member", kFPSMemberURL, + false /* sameparty */), + {}}}; + net::CookieAccessResultList excluded_cookies = {}; + + url::Origin origin = url::Origin::Create(GURL(kFPSOwnerURL)); + net::SchemefulSite primary((GURL(kFPSOwnerURL))); + + net::FirstPartySetEntry frame_entry(primary, net::SiteType::kAssociated, 1u); + net::FirstPartySetEntry top_frame_entry(primary, net::SiteType::kPrimary, + absl::nullopt); + + EXPECT_FALSE(settings.AnnotateAndMoveUserBlockedCookies( + GURL(kFPSMemberURL), net::SiteForCookies(), &origin, + net::FirstPartySetMetadata( + net::SamePartyContext(net::SamePartyContext::Type::kCrossParty), + &frame_entry, &top_frame_entry), + maybe_included_cookies, excluded_cookies)); + + EXPECT_EQ(0u, maybe_included_cookies.size()); + + EXPECT_THAT( + excluded_cookies, + ElementsAre(MatchesCookieWithAccessResult( + net::MatchesCookieWithName("third_party_but_member"), + MatchesCookieAccessResult( + HasExactlyExclusionReasonsForTesting( + std::vector<net::CookieInclusionStatus::ExclusionReason>{ + net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES, + net::CookieInclusionStatus:: + EXCLUDE_THIRD_PARTY_BLOCKED_WITHIN_FIRST_PARTY_SET, + }), + _, _, _)))); +} + TEST_P(SamePartyCookieSettingsTest, AnnotateAndMoveUserBlockedCookies) { base::HistogramTester histogram_tester; CookieSettings settings; @@ -867,6 +912,10 @@ const url::Origin fps_owner_origin = url::Origin::Create(GURL(kFPSOwnerURL)); EXPECT_TRUE(settings.AnnotateAndMoveUserBlockedCookies( GURL(kFPSMemberURL), net::SiteForCookies(), &fps_owner_origin, + net::FirstPartySetMetadata( + net::SamePartyContext(net::SamePartyContext::Type::kCrossParty), + /*frame_entry=*/nullptr, + /*top_frame_entry=*/nullptr), maybe_included_cookies, excluded_cookies)); EXPECT_THAT(maybe_included_cookies, @@ -951,6 +1000,10 @@ settings.set_block_third_party_cookies(true); EXPECT_TRUE(settings.AnnotateAndMoveUserBlockedCookies( GURL(kURL), net::SiteForCookies(), &top_level_origin, + net::FirstPartySetMetadata( + net::SamePartyContext(net::SamePartyContext::Type::kCrossParty), + /*frame_entry=*/nullptr, + /*top_frame_entry=*/nullptr), maybe_included_cookies, excluded_cookies)); EXPECT_THAT(maybe_included_cookies, ElementsAre(MatchesCookieWithAccessResult( @@ -973,6 +1026,10 @@ {CreateSetting(kURL, "*", CONTENT_SETTING_BLOCK)}); EXPECT_FALSE(settings.AnnotateAndMoveUserBlockedCookies( GURL(kURL), net::SiteForCookies(), &top_level_origin, + net::FirstPartySetMetadata( + net::SamePartyContext(net::SamePartyContext::Type::kCrossParty), + /*frame_entry=*/nullptr, + /*top_frame_entry=*/nullptr), maybe_included_cookies, excluded_cookies)); EXPECT_THAT(maybe_included_cookies, IsEmpty()); EXPECT_THAT( @@ -1000,6 +1057,10 @@ {CreateSetting(kOtherURL, "*", CONTENT_SETTING_BLOCK)}); EXPECT_FALSE(settings.AnnotateAndMoveUserBlockedCookies( GURL(kURL), net::SiteForCookies(), &top_level_origin, + net::FirstPartySetMetadata( + net::SamePartyContext(net::SamePartyContext::Type::kCrossParty), + /*frame_entry=*/nullptr, + /*top_frame_entry=*/nullptr), maybe_included_cookies, excluded_cookies)); EXPECT_THAT(maybe_included_cookies, IsEmpty()); EXPECT_THAT( @@ -1028,6 +1089,10 @@ {CreateSetting(kOtherURL, kUnrelatedURL, CONTENT_SETTING_BLOCK)}); EXPECT_TRUE(settings.AnnotateAndMoveUserBlockedCookies( GURL(kURL), net::SiteForCookies(), &top_level_origin, + net::FirstPartySetMetadata( + net::SamePartyContext(net::SamePartyContext::Type::kCrossParty), + /*frame_entry=*/nullptr, + /*top_frame_entry=*/nullptr), maybe_included_cookies, excluded_cookies)); EXPECT_THAT(maybe_included_cookies, ElementsAre(MatchesCookieWithAccessResult(
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc index 4d2841d..aa71fb1 100644 --- a/services/network/network_context_unittest.cc +++ b/services/network/network_context_unittest.cc
@@ -4331,15 +4331,27 @@ net::CookieAccessResultList included; net::CookieAccessResultList excluded; - EXPECT_TRUE( - network_context->url_request_context() - ->network_delegate() - ->AnnotateAndMoveUserBlockedCookies(*request, included, excluded)); + EXPECT_TRUE(network_context->url_request_context() + ->network_delegate() + ->AnnotateAndMoveUserBlockedCookies( + *request, + net::FirstPartySetMetadata( + net::SamePartyContext( + net::SamePartyContext::Type::kCrossParty), + /*frame_entry=*/nullptr, + /*top_frame_entry=*/nullptr), + included, excluded)); SetDefaultContentSetting(CONTENT_SETTING_BLOCK, network_context.get()); - EXPECT_FALSE( - network_context->url_request_context() - ->network_delegate() - ->AnnotateAndMoveUserBlockedCookies(*request, included, excluded)); + EXPECT_FALSE(network_context->url_request_context() + ->network_delegate() + ->AnnotateAndMoveUserBlockedCookies( + *request, + net::FirstPartySetMetadata( + net::SamePartyContext( + net::SamePartyContext::Type::kCrossParty), + /*frame_entry=*/nullptr, + /*top_frame_entry=*/nullptr), + included, excluded)); } TEST_F(NetworkContextTest, @@ -4354,10 +4366,16 @@ net::CookieAccessResultList excluded; SetDefaultContentSetting(CONTENT_SETTING_ALLOW, network_context.get()); - EXPECT_TRUE( - network_context->url_request_context() - ->network_delegate() - ->AnnotateAndMoveUserBlockedCookies(*request, included, excluded)); + EXPECT_TRUE(network_context->url_request_context() + ->network_delegate() + ->AnnotateAndMoveUserBlockedCookies( + *request, + net::FirstPartySetMetadata( + net::SamePartyContext( + net::SamePartyContext::Type::kCrossParty), + /*frame_entry=*/nullptr, + /*top_frame_entry=*/nullptr), + included, excluded)); } // Gets notified by the EmbeddedTestServer on incoming connections being
diff --git a/services/network/network_service_network_delegate.cc b/services/network/network_service_network_delegate.cc index ae73c13c..52d5860 100644 --- a/services/network/network_service_network_delegate.cc +++ b/services/network/network_service_network_delegate.cc
@@ -186,6 +186,7 @@ bool NetworkServiceNetworkDelegate::OnAnnotateAndMoveUserBlockedCookies( const net::URLRequest& request, + const net::FirstPartySetMetadata& first_party_set_metadata, net::CookieAccessResultList& maybe_included_cookies, net::CookieAccessResultList& excluded_cookies) { if (!network_context_->cookie_manager() @@ -193,7 +194,8 @@ .AnnotateAndMoveUserBlockedCookies( request.url(), request.site_for_cookies(), base::OptionalToPtr(request.isolation_info().top_frame_origin()), - maybe_included_cookies, excluded_cookies)) { + first_party_set_metadata, maybe_included_cookies, + excluded_cookies)) { // CookieSettings has already moved and annotated the cookies. return false; }
diff --git a/services/network/network_service_network_delegate.h b/services/network/network_service_network_delegate.h index caa1fe6a..0088e46 100644 --- a/services/network/network_service_network_delegate.h +++ b/services/network/network_service_network_delegate.h
@@ -11,6 +11,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "net/base/completion_once_callback.h" #include "net/base/network_delegate_impl.h" +#include "net/first_party_sets/first_party_set_metadata.h" #include "net/first_party_sets/first_party_sets_cache_filter.h" #include "net/first_party_sets/same_party_context.h" #include "services/network/cookie_settings.h" @@ -72,6 +73,7 @@ void OnPACScriptError(int line_number, const std::u16string& error) override; bool OnAnnotateAndMoveUserBlockedCookies( const net::URLRequest& request, + const net::FirstPartySetMetadata& first_party_set_metadata, net::CookieAccessResultList& maybe_included_cookies, net::CookieAccessResultList& excluded_cookies) override; bool OnCanSetCookie(const net::URLRequest& request,
diff --git a/services/network/restricted_cookie_manager.cc b/services/network/restricted_cookie_manager.cc index 89cad81..092b92c 100644 --- a/services/network/restricted_cookie_manager.cc +++ b/services/network/restricted_cookie_manager.cc
@@ -464,8 +464,8 @@ net::CookieAccessResultList maybe_included_cookies = cookie_list; net::CookieAccessResultList excluded_cookies = excluded_list; cookie_settings().AnnotateAndMoveUserBlockedCookies( - url, site_for_cookies, &top_frame_origin, maybe_included_cookies, - excluded_cookies); + url, site_for_cookies, &top_frame_origin, first_party_set_metadata_, + maybe_included_cookies, excluded_cookies); std::vector<net::CookieWithAccessResult> result; std::vector<mojom::CookieOrLineWithAccessResultPtr>
diff --git a/services/network/restricted_cookie_manager_unittest.cc b/services/network/restricted_cookie_manager_unittest.cc index ff4bb2fb..28f0f4b 100644 --- a/services/network/restricted_cookie_manager_unittest.cc +++ b/services/network/restricted_cookie_manager_unittest.cc
@@ -1116,7 +1116,9 @@ CookieOrLine("cookie-name=cookie-value", mojom::CookieOrLine::Tag::kCookie), net::CookieInclusionStatus::MakeFromReasonsForTesting( - {net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES}, + {net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES, + net::CookieInclusionStatus:: + EXCLUDE_THIRD_PARTY_BLOCKED_WITHIN_FIRST_PARTY_SET}, expected_warnings)))); cookie_settings_.set_block_third_party_cookies(false);
diff --git a/services/tracing/perfetto/privacy_filtered_fields-inl.h b/services/tracing/perfetto/privacy_filtered_fields-inl.h index d0e1d02f..97290d82 100644 --- a/services/tracing/perfetto/privacy_filtered_fields-inl.h +++ b/services/tracing/perfetto/privacy_filtered_fields-inl.h
@@ -368,6 +368,11 @@ constexpr MessageInfo kChromeSqlDiagnostics = {kChromeSqlDiagnosticsIndices, nullptr}; +// Proto Message: SequenceManagerTask +constexpr int kSequenceManagerTaskIndices[] = {1, 2, -1}; +constexpr MessageInfo kSequenceManagerTask = {kSequenceManagerTaskIndices, + nullptr}; + // Proto Message: AndroidToolbar constexpr int kAndroidToolbarIndices[] = {1, 2, 3, -1}; constexpr MessageInfo kAndroidToolbar = {kAndroidToolbarIndices, nullptr}; @@ -383,7 +388,7 @@ 35, 36, 38, 39, 40, 41, 42, 43, 47, 48, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1028, - 1031, 1032, 1033, 1034, 1036, 1038, 1039, 1041, 1042, -1}; + 1031, 1032, 1033, 1034, 1036, 1038, 1039, 1040, 1041, 1042, -1}; constexpr MessageInfo const* kTrackEventComplexMessages[] = { nullptr, nullptr, @@ -452,6 +457,7 @@ nullptr, &kAndroidIPC, &kChromeSqlDiagnostics, + &kSequenceManagerTask, &kAndroidToolbar, &kActiveProcesses}; constexpr MessageInfo kTrackEvent = {kTrackEventIndices,
diff --git a/testing/buildbot/chromium.fuchsia.fyi.json b/testing/buildbot/chromium.fuchsia.fyi.json index ef4ed1fb..ba47925d 100644 --- a/testing/buildbot/chromium.fuchsia.fyi.json +++ b/testing/buildbot/chromium.fuchsia.fyi.json
@@ -4139,5 +4139,309 @@ "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_fuchsia/" } ] + }, + "fuchsia-x64-workstation": { + "gtest_tests": [ + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.browser_tests.filter", + "--", + "--test-launcher-timeout=60000", + "--custom-image=workstation_eng.qemu-x64-release" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 40 + }, + "test": "browser_tests", + "test_id_prefix": "ninja://chrome/test:browser_tests/" + }, + { + "args": [ + "--", + "--disable-gpu", + "--headless", + "--ozone-platform=headless", + "--custom-image=workstation_eng.qemu-x64-release" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 8 + }, + "test": "content_browsertests", + "test_id_prefix": "ninja://content/test:content_browsertests/" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter", + "--custom-image=workstation_eng.qemu-x64-release" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "unit_tests", + "test_id_prefix": "ninja://chrome/test:unit_tests/" + } + ], + "isolated_scripts": [ + { + "args": [ + "info_collection", + "--show-stdout", + "--browser=fuchsia-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--expected-vendor-id", + "1ae0", + "--custom-image=workstation_eng.qemu-x64-release", + "--expected-device-id", + "c0de" + ], + "isolate_name": "telemetry_gpu_integration_test_fuchsia", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "info_collection_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_fuchsia/" + }, + { + "args": [ + "mediapipe", + "--show-stdout", + "--browser=fuchsia-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_higher_performance_gpu --use-cmd-decoder=validating", + "--custom-image=workstation_eng.qemu-x64-release" + ], + "isolate_name": "telemetry_gpu_integration_test_fuchsia", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "mediapipe_validating_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_fuchsia/" + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=fuchsia-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating", + "--dont-restore-color-profile-after-test", + "--test-machine-name", + "${buildername}", + "--custom-image=workstation_eng.qemu-x64-release", + "--git-revision=${got_revision}" + ], + "isolate_name": "telemetry_gpu_integration_test_fuchsia", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_validating_test", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_fuchsia/" + }, + { + "args": [ + "screenshot_sync", + "--show-stdout", + "--browser=fuchsia-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating", + "--dont-restore-color-profile-after-test", + "--custom-image=workstation_eng.qemu-x64-release" + ], + "isolate_name": "telemetry_gpu_integration_test_fuchsia", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "screenshot_sync_validating_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_fuchsia/" + }, + { + "args": [ + "trace_test", + "--show-stdout", + "--browser=fuchsia-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--custom-image=workstation_eng.qemu-x64-release" + ], + "isolate_name": "telemetry_gpu_integration_test_fuchsia", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "trace_test", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_fuchsia/" + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=fuchsia-chrome", + "--passthrough", + "-v", + "--stable-jobs", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--custom-image=workstation_eng.qemu-x64-release" + ], + "isolate_name": "telemetry_gpu_integration_test_fuchsia", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "webgl_conformance_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-18.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 18 + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_fuchsia/" + } + ] } }
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 541d4e0..16b2f9ac 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -22602,310 +22602,6 @@ } ] }, - "fuchsia-fyi-x64-wst": { - "gtest_tests": [ - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.browser_tests.filter", - "--", - "--test-launcher-timeout=60000", - "--custom-image=workstation.qemu-x64-release" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-18.04" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 40 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ - "--", - "--disable-gpu", - "--headless", - "--ozone-platform=headless", - "--custom-image=workstation.qemu-x64-release" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-18.04" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 8 - }, - "test": "content_browsertests", - "test_id_prefix": "ninja://content/test:content_browsertests/" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter", - "--custom-image=workstation.qemu-x64-release" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-18.04" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "unit_tests", - "test_id_prefix": "ninja://chrome/test:unit_tests/" - } - ], - "isolated_scripts": [ - { - "args": [ - "info_collection", - "--show-stdout", - "--browser=fuchsia-chrome", - "--passthrough", - "-v", - "--stable-jobs", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", - "--expected-vendor-id", - "1ae0", - "--custom-image=workstation.qemu-x64-release", - "--expected-device-id", - "c0de" - ], - "isolate_name": "telemetry_gpu_integration_test_fuchsia", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "info_collection_tests", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-18.04" - } - ], - "idempotent": false, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_fuchsia/" - }, - { - "args": [ - "mediapipe", - "--show-stdout", - "--browser=fuchsia-chrome", - "--passthrough", - "-v", - "--stable-jobs", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_higher_performance_gpu --use-cmd-decoder=validating", - "--custom-image=workstation.qemu-x64-release" - ], - "isolate_name": "telemetry_gpu_integration_test_fuchsia", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "mediapipe_validating_tests", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-18.04" - } - ], - "idempotent": false, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_fuchsia/" - }, - { - "args": [ - "pixel", - "--show-stdout", - "--browser=fuchsia-chrome", - "--passthrough", - "-v", - "--stable-jobs", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating", - "--dont-restore-color-profile-after-test", - "--test-machine-name", - "${buildername}", - "--custom-image=workstation.qemu-x64-release", - "--git-revision=${got_revision}" - ], - "isolate_name": "telemetry_gpu_integration_test_fuchsia", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "pixel_skia_gold_validating_test", - "precommit_args": [ - "--gerrit-issue=${patch_issue}", - "--gerrit-patchset=${patch_set}", - "--buildbucket-id=${buildbucket_build_id}" - ], - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-18.04" - } - ], - "idempotent": false, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_fuchsia/" - }, - { - "args": [ - "screenshot_sync", - "--show-stdout", - "--browser=fuchsia-chrome", - "--passthrough", - "-v", - "--stable-jobs", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating", - "--dont-restore-color-profile-after-test", - "--custom-image=workstation.qemu-x64-release" - ], - "isolate_name": "telemetry_gpu_integration_test_fuchsia", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "screenshot_sync_validating_tests", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-18.04" - } - ], - "idempotent": false, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_fuchsia/" - }, - { - "args": [ - "trace_test", - "--show-stdout", - "--browser=fuchsia-chrome", - "--passthrough", - "-v", - "--stable-jobs", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", - "--custom-image=workstation.qemu-x64-release" - ], - "isolate_name": "telemetry_gpu_integration_test_fuchsia", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "trace_test", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-18.04" - } - ], - "idempotent": false, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_fuchsia/" - }, - { - "args": [ - "webgl_conformance", - "--show-stdout", - "--browser=fuchsia-chrome", - "--passthrough", - "-v", - "--stable-jobs", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", - "--custom-image=workstation.qemu-x64-release" - ], - "isolate_name": "telemetry_gpu_integration_test_fuchsia", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "webgl_conformance_tests", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-18.04" - } - ], - "idempotent": false, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 18 - }, - "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test_fuchsia/" - } - ] - }, "ios-fieldtrial-rel": { "isolated_scripts": [ {
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index dccb7fe..776f1dbf 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -490,6 +490,13 @@ ], }, }, + 'fuchsia-test-workstation': { + '$mixin_append': { + 'args': [ + '--custom-image=workstation_eng.qemu-x64-release', + ], + } + }, 'fuchsia_logs': { '$mixin_append': { 'args': [
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index e9e5c07..1e2d4e7 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -2301,14 +2301,14 @@ '--expected-device-id', '1050', ], }, - 'fuchsia-fyi-x64-wst': { + 'fuchsia-x64-chrome-rel': { 'args': [ # Swarming does not report a GPU since tests are run in a VM, but # the VM does report that a GPU is present. '--expected-device-id', 'c0de', ], }, - 'fuchsia-x64-chrome-rel': { + 'fuchsia-x64-workstation': { 'args': [ # Swarming does not report a GPU since tests are run in a VM, but # the VM does report that a GPU is present. @@ -2343,7 +2343,7 @@ '--expected-vendor-id': '106b', }, }, - 'fuchsia-fyi-x64-wst': { + 'fuchsia-x64-chrome-rel': { 'args': { # The GPU information is not exposed in swarming since Fuchsia # launches an emulator on the GCE machine. @@ -2351,7 +2351,7 @@ '$$MAGIC_SUBSTITUTION_GPUExpectedDeviceId': None, }, }, - 'fuchsia-x64-chrome-rel': { + 'fuchsia-x64-workstation': { 'args': { # The GPU information is not exposed in swarming since Fuchsia # launches an emulator on the GCE machine.
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index bf8bda0..c737cc2 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -2597,6 +2597,28 @@ 'gtest_tests': 'fuchsia_chrome_large_gtests', }, }, + 'fuchsia-x64-workstation': { + 'browser_config': 'fuchsia-chrome', + 'os_type': 'fuchsia', + 'mixins': [ + 'fuchsia-test-workstation', + 'linux-bionic', + ], + 'swarming': { + 'dimension_sets': [ + { + 'kvm': '1', + }, + ], + }, + 'test_suites': { + # TODO(crbug.com/1372220): Consider running all telemetry tests. + 'gpu_telemetry_tests': 'gpu_fuchsia_telemetry_experimental_tests', + # TODO(crbug.com/1372220): Consider running more gtests here, Ideally + # "fuchsia_gtests". + 'gtest_tests': 'fuchsia_chrome_large_gtests', + }, + }, }, }, { @@ -3129,30 +3151,6 @@ 'gtest_tests': 'fuchsia_gtests', }, }, - 'fuchsia-fyi-x64-wst': { - 'browser_config': 'fuchsia-chrome', - 'os_type': 'fuchsia', - 'mixins': [ - 'linux-bionic', - ], - 'args': [ - '--custom-image=workstation.qemu-x64-release', - ], - 'swarming': { - 'dimension_sets': [ - { - 'kvm': '1', - }, - ], - }, - 'test_suites': { - # TODO(crbug.com/1372220): Consider running all telemetry tests. - 'gpu_telemetry_tests': 'gpu_fuchsia_telemetry_experimental_tests', - # TODO(crbug.com/1372220): Consider running more gtests here, Ideally - # "fuchsia_gtests". - 'gtest_tests': 'fuchsia_chrome_large_gtests', - }, - }, 'ios-fieldtrial-rel': { 'mixins': [ 'has_native_resultdb_integration',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index d0c0c242..aa90fea 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -413,8 +413,11 @@ ], "experiments": [ { - "name": "Enabled", + "name": "Holdback_20221012", "enable_features": [ + "AndroidBatteryMetricsReportOnUIThread" + ], + "disable_features": [ "AndroidScrollOptimizations" ] } @@ -4848,6 +4851,9 @@ "name": "ForceGpuMainThreadToNormalPriorityDrDc", "enable_features": [ "ForceGpuMainThreadToNormalPriorityDrDc" + ], + "disable_features": [ + "RawDraw" ] } ] @@ -8057,7 +8063,7 @@ ], "experiments": [ { - "name": "Denser", + "name": "Denser_V4", "params": { "mode": "denser" },
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc index a5a4473..938c111 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc
@@ -953,6 +953,15 @@ return ToMicrotaskQueue(ExecutionContext::From(script_state)); } +scheduler::EventLoop& ToEventLoop(ExecutionContext* execution_context) { + DCHECK(execution_context); + return *execution_context->GetAgent()->event_loop().get(); +} + +scheduler::EventLoop& ToEventLoop(ScriptState* script_state) { + return ToEventLoop(ExecutionContext::From(script_state)); +} + bool IsInParallelAlgorithmRunnable(ExecutionContext* execution_context, ScriptState* script_state) { if (!execution_context || execution_context->IsContextDestroyed())
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h index 8b0d7b4..5ef627e7 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h +++ b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h
@@ -53,6 +53,10 @@ namespace blink { +namespace scheduler { +class EventLoop; +} // namespace scheduler + // This file contains core-specific bindings utility functions. For functions // that are core independent, see platform/bindings/V8Binding.h. When adding a // new utility function, consider adding it to V8Binding.h instead unless it has @@ -517,6 +521,8 @@ CORE_EXPORT v8::MicrotaskQueue* ToMicrotaskQueue(ExecutionContext*); CORE_EXPORT v8::MicrotaskQueue* ToMicrotaskQueue(ScriptState*); +CORE_EXPORT scheduler::EventLoop& ToEventLoop(ExecutionContext*); +CORE_EXPORT scheduler::EventLoop& ToEventLoop(ScriptState*); // Helper finction used in the callback functions to validate context. // Returns true if the given execution context and V8 context are capable to run
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.cc b/third_party/blink/renderer/core/display_lock/display_lock_context.cc index af42138..3b2ac4eb 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
@@ -505,9 +505,11 @@ MarkAncestorsForPrePaintIfNeeded(); } - if (emit_warnings && v8::Isolate::GetCurrent()->InContext() && - !IsActivatable(DisplayLockActivationReason::kAny) && document_ && - element_) { + if (emit_warnings && v8::Isolate::GetCurrent()->InContext() && document_ && + element_ && + (!IsActivatable(DisplayLockActivationReason::kAny) || + RuntimeEnabledFeatures:: + WarnOnContentVisibilityRenderAccessEnabled())) { document_->GetDisplayLockDocumentState().IssueForcedRenderWarning( element_); }
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_document_state.cc b/third_party/blink/renderer/core/display_lock/display_lock_document_state.cc index 906f4fc..f69b618 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_document_state.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_document_state.cc
@@ -23,9 +23,9 @@ namespace { const char kForcedRendering[] = - "Rendering was performed in a subtree hidden by content-visibility:hidden."; + "Rendering was performed in a subtree hidden by content-visibility."; const char kForcedRenderingMax[] = - "Rendering was performed in a subtree hidden by content-visibility:hidden. " + "Rendering was performed in a subtree hidden by content-visibility. " "Further messages will be suppressed."; constexpr unsigned kMaxConsoleMessages = 500; @@ -452,9 +452,12 @@ // accessing content-visibility: hidden subtrees intentionally. if (forced_render_warnings_ < kMaxConsoleMessages) { forced_render_warnings_++; + auto level = + RuntimeEnabledFeatures::WarnOnContentVisibilityRenderAccessEnabled() + ? mojom::blink::ConsoleMessageLevel::kWarning + : mojom::blink::ConsoleMessageLevel::kVerbose; auto* console_message = MakeGarbageCollected<ConsoleMessage>( - mojom::blink::ConsoleMessageSource::kJavaScript, - mojom::blink::ConsoleMessageLevel::kVerbose, + mojom::blink::ConsoleMessageSource::kJavaScript, level, forced_render_warnings_ == kMaxConsoleMessages ? kForcedRenderingMax : kForcedRendering); console_message->SetNodes(document_->GetFrame(),
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 58c1cb1..18acdc3 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2599,7 +2599,16 @@ DCHECK(document.PopupsWaitingToHide().empty()); } - if (endpoint && endpoint->PopupType() == PopupValueType::kHint) { + auto close_all_open_pop_ups = [&document, &focus_behavior, &forcing_level]() { + while (auto* pop_up = document.TopmostPopupAutoOrHint()) { + pop_up->HidePopUpInternal(focus_behavior, forcing_level); + } + }; + + if (!endpoint) + return close_all_open_pop_ups(); + + if (endpoint->PopupType() == PopupValueType::kHint) { if (popup_independence == HidePopupIndependence::kHideUnrelated) { if (document.PopupHintShowing() != endpoint) { document.PopupHintShowing()->HidePopUpInternal(focus_behavior, @@ -2611,7 +2620,7 @@ } } } else { - DCHECK(!endpoint || endpoint->PopupType() == PopupValueType::kAuto); + DCHECK_EQ(endpoint->PopupType(), PopupValueType::kAuto); const Element* hint_ancestor = nullptr; if (document.PopupHintShowing()) { // If there is a hint showing that is a descendant of something on the @@ -2625,15 +2634,32 @@ forcing_level); } } - // Then hide everything in the popup=auto stack up to the specified - // endpoint. - while (!document.PopupStack().empty()) { + // Then hide everything in the popup=auto stack until the last_to_hide + // pop-up is closed, or the stack is empty. + const Element* last_to_hide = nullptr; + bool found_endpoint = false; + for (auto pop_up : document.PopupStack()) { + if (pop_up == endpoint) { + found_endpoint = true; + } else if (found_endpoint) { + last_to_hide = pop_up; + break; + } + } + if (!found_endpoint) + return close_all_open_pop_ups(); + if (!last_to_hide && document.PopupHintShowing() && + hint_ancestor == endpoint) { + // endpoint is the top of the pop-up stack, and there's a nested hint. + document.PopupHintShowing()->HidePopUpInternal(focus_behavior, + forcing_level); + } + while (last_to_hide && last_to_hide->popupOpen() && + !document.PopupStack().empty()) { if (document.PopupStack().back() == hint_ancestor) { document.PopupHintShowing()->HidePopUpInternal(focus_behavior, forcing_level); } - if (document.PopupStack().back() == endpoint) - break; document.PopupStack().back()->HidePopUpInternal(focus_behavior, forcing_level); }
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index 50cae52..3ef152f 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -2506,7 +2506,8 @@ frame = frame->Tree().TraverseNext()) { auto* local_frame = DynamicTo<LocalFrame>(frame); if (local_frame && local_frame->View()) { - local_frame->IncrementNavigationId(); + DCHECK(local_frame->DomWindow()); + local_frame->DomWindow()->IncrementNavigationId(); } }
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h index f576a1a..9373ba08 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.h +++ b/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -490,6 +490,9 @@ return closewatcher_stack_; } + void IncrementNavigationId() { navigation_id_++; } + uint32_t GetNavigationId() const { return navigation_id_; } + protected: // EventTarget overrides. void AddedEventListener(const AtomicString& event_type, @@ -617,6 +620,11 @@ // If set, this window is a Document Picture in Picture window. // https://github.com/steimelchrome/document-pip-explainer/blob/main/explainer.md bool is_picture_in_picture_window_ = false; + + // The navigation id of a document is to identify navigation of special types + // like bfcache navigation or soft navigation. It increments when navigations + // of these types occur. + uint32_t navigation_id_ = 1; }; template <>
diff --git a/third_party/blink/renderer/core/frame/local_dom_window_test.cc b/third_party/blink/renderer/core/frame/local_dom_window_test.cc index e1953ac..dcd0235 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window_test.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window_test.cc
@@ -335,5 +335,11 @@ *message_storage->at(i)->Category()); } } - +TEST_F(LocalDOMWindowTest, NavigationId) { + EXPECT_EQ(1u, GetFrame().DomWindow()->GetNavigationId()); + GetFrame().DomWindow()->IncrementNavigationId(); + EXPECT_EQ(2u, GetFrame().DomWindow()->GetNavigationId()); + GetFrame().DomWindow()->IncrementNavigationId(); + EXPECT_EQ(3u, GetFrame().DomWindow()->GetNavigationId()); +} } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index baac5c9..4296d02 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -787,8 +787,6 @@ // Invokes on first paint, this method could be invoked multiple times, refer // to FrameFirstPaint. void OnFirstPaint(bool text_painted, bool image_painted); - void IncrementNavigationId() { navigation_id_++; } - uint32_t GetNavigationId() { return navigation_id_; } #if BUILDFLAG(IS_MAC) void ResetTextInputHostForTesting(); @@ -1046,9 +1044,6 @@ // Indicate if the current document's color scheme was notified. bool notified_color_scheme_ = false; - // Tracks the number of times this document has been retrieved from the - // bfcache. - uint32_t navigation_id_ = 1; // Stores whether this frame is affected by a CSPEE policy (from any ancestor // frame). Calculated browser-side and used to help determine if this frame
diff --git a/third_party/blink/renderer/core/frame/local_frame_test.cc b/third_party/blink/renderer/core/frame/local_frame_test.cc index 8a68f6e5..5ed81756 100644 --- a/third_party/blink/renderer/core/frame/local_frame_test.cc +++ b/third_party/blink/renderer/core/frame/local_frame_test.cc
@@ -222,12 +222,4 @@ EXPECT_EQ(waiter.index(), 5ul); } #endif -TEST_F(LocalFrameTest, NavigationCounter) { - auto page_holder = std::make_unique<DummyPageHolder>(); - EXPECT_EQ(1u, page_holder->GetFrame().GetNavigationId()); - page_holder->GetFrame().IncrementNavigationId(); - EXPECT_EQ(2u, page_holder->GetFrame().GetNavigationId()); - page_holder->GetFrame().IncrementNavigationId(); - EXPECT_EQ(3u, page_holder->GetFrame().GetNavigationId()); -} } // namespace blink
diff --git a/third_party/blink/renderer/core/messaging/build.gni b/third_party/blink/renderer/core/messaging/build.gni index c82a5d06..c0ee4d1 100644 --- a/third_party/blink/renderer/core/messaging/build.gni +++ b/third_party/blink/renderer/core/messaging/build.gni
@@ -20,4 +20,5 @@ blink_core_tests_messaging = [ "blink_transferable_message_mojom_traits_test.cc", "message_port_descriptor_mojom_traits_test.cc", + "message_port_test.cc", ]
diff --git a/third_party/blink/renderer/core/messaging/message_port_test.cc b/third_party/blink/renderer/core/messaging/message_port_test.cc new file mode 100644 index 0000000..f045c5f3 --- /dev/null +++ b/third_party/blink/renderer/core/messaging/message_port_test.cc
@@ -0,0 +1,71 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/messaging/message_port.h" + +#include "base/run_loop.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/messaging/transferable_message.mojom-blink.h" +#include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/core/event_type_names.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h" +#include "third_party/blink/renderer/core/testing/dummy_page_holder.h" +#include "third_party/blink/renderer/core/testing/wait_for_event.h" + +namespace blink { +namespace { + +BlinkTransferableMessage MakeNullMessage() { + BlinkTransferableMessage message; + message.message = SerializedScriptValue::NullValue(); + message.sender_agent_cluster_id = base::UnguessableToken::Create(); + return message; +} + +TEST(MessagePortTest, DispatchMessageEvent) { + DummyPageHolder holder; + LocalDOMWindow* window = holder.GetFrame().DomWindow(); + + MessagePort* port = MakeGarbageCollected<MessagePort>(*window); + + base::RunLoop run_loop; + auto* wait = MakeGarbageCollected<WaitForEvent>(); + wait->AddEventListener(port, event_type_names::kMessage); + wait->AddEventListener(port, event_type_names::kMessageerror); + wait->AddCompletionClosure(run_loop.QuitClosure()); + + mojo::Message mojo_message = + mojom::blink::TransferableMessage::WrapAsMessage(MakeNullMessage()); + ASSERT_TRUE(static_cast<mojo::MessageReceiver*>(port)->Accept(&mojo_message)); + run_loop.Run(); + + EXPECT_EQ(wait->GetLastEvent()->type(), event_type_names::kMessage); +} + +TEST(MessagePortTest, DispatchMessageErrorEvent_LockedAgentCluster) { + DummyPageHolder holder; + LocalDOMWindow* window = holder.GetFrame().DomWindow(); + + MessagePort* port = MakeGarbageCollected<MessagePort>(*window); + + base::RunLoop run_loop; + auto* wait = MakeGarbageCollected<WaitForEvent>(); + wait->AddEventListener(port, event_type_names::kMessage); + wait->AddEventListener(port, event_type_names::kMessageerror); + wait->AddCompletionClosure(run_loop.QuitClosure()); + + auto message = MakeNullMessage(); + message.locked_to_sender_agent_cluster = true; + mojo::Message mojo_message = + mojom::blink::TransferableMessage::WrapAsMessage(std::move(message)); + ASSERT_TRUE(static_cast<mojo::MessageReceiver*>(port)->Accept(&mojo_message)); + run_loop.Run(); + + EXPECT_EQ(wait->GetLastEvent()->type(), event_type_names::kMessageerror); +} + +} // namespace +} // namespace blink
diff --git a/third_party/blink/renderer/core/timing/performance_entry.cc b/third_party/blink/renderer/core/timing/performance_entry.cc index 5562f182..e77d86d 100644 --- a/third_party/blink/renderer/core/timing/performance_entry.cc +++ b/third_party/blink/renderer/core/timing/performance_entry.cc
@@ -141,11 +141,7 @@ if (!local_dom_window) return kNavigationIdDefaultValue; - // Calling GetFrame() on a window of a detached frame returns null. - if (!local_dom_window->GetFrame()) - return kNavigationIdDefaultValue; - - return local_dom_window->GetFrame()->GetNavigationId(); + return local_dom_window->GetNavigationId(); } // static @@ -154,10 +150,7 @@ if (!local_dom_window) return kNavigationIdDefaultValue; - if (!local_dom_window->GetFrame()) - return kNavigationIdDefaultValue; - - return local_dom_window->GetFrame()->GetNavigationId(); + return local_dom_window->GetNavigationId(); } ScriptValue PerformanceEntry::toJSONForBinding(
diff --git a/third_party/blink/renderer/core/timing/performance_entry_test.cc b/third_party/blink/renderer/core/timing/performance_entry_test.cc index 1843c34..68c808b 100644 --- a/third_party/blink/renderer/core/timing/performance_entry_test.cc +++ b/third_party/blink/renderer/core/timing/performance_entry_test.cc
@@ -6,6 +6,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame.h" namespace blink { @@ -16,7 +17,7 @@ EXPECT_EQ(1u, PerformanceEntry::GetNavigationId(scope.GetScriptState())); - scope.GetFrame().IncrementNavigationId(); + scope.GetFrame().DomWindow()->IncrementNavigationId(); EXPECT_EQ(2u, PerformanceEntry::GetNavigationId(scope.GetExecutionContext())); } } // namespace blink
diff --git a/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc b/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc index c7accfb..187ab316 100644 --- a/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc +++ b/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
@@ -170,7 +170,7 @@ return; } ++soft_navigation_count_; - frame->IncrementNavigationId(); + window->IncrementNavigationId(); auto* performance = DOMWindowPerformance::performance(*window); DCHECK(!url_.IsNull()); performance->AddSoftNavigationEntry(AtomicString(url_),
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc index f321ec6..4d83dc494 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -3884,32 +3884,32 @@ size_t max_node_count, base::TimeDelta timeout, ui::AXTreeUpdate* response) { - BlinkAXTreeSource tree_source(*this); + BlinkAXTreeSource* tree_source = BlinkAXTreeSource::Create(*this); - tree_source.set_exclude_offscreen(exclude_offscreen); + tree_source->set_exclude_offscreen(exclude_offscreen); // The serializer returns an ui::AXTreeUpdate, which can store a complete // or a partial accessibility tree. AXTreeSerializer is stateful, but the // first time you serialize from a brand-new tree you're guaranteed to get a // complete tree. - ui::AXTreeSerializer<AXObject*> serializer(&tree_source); + ui::AXTreeSerializer<AXObject*> serializer(tree_source); if (max_node_count) serializer.set_max_node_count(max_node_count); if (!timeout.is_zero()) serializer.set_timeout(timeout); - tree_source.Freeze(); + tree_source->Freeze(); - if (!tree_source.GetRoot() || tree_source.GetRoot()->IsDetached()) { - tree_source.Thaw(); + if (!tree_source->GetRoot() || tree_source->GetRoot()->IsDetached()) { + tree_source->Thaw(); // TODO(chrishtr): not clear why this can happen. NOTREACHED(); return false; } - if (serializer.SerializeChanges(tree_source.GetRoot(), response)) { - tree_source.Thaw(); + if (serializer.SerializeChanges(tree_source->GetRoot(), response)) { + tree_source->Thaw(); return true; } @@ -3917,8 +3917,8 @@ // aria-owns rearranging the page while it's being scanned. Try a second // time. *response = ui::AXTreeUpdate(); - bool result = serializer.SerializeChanges(tree_source.GetRoot(), response); - tree_source.Thaw(); + bool result = serializer.SerializeChanges(tree_source->GetRoot(), response); + tree_source->Thaw(); return result; }
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.cc b/third_party/blink/renderer/modules/mediastream/media_devices.cc index 61fa5e2..d76e8e9 100644 --- a/third_party/blink/renderer/modules/mediastream/media_devices.cc +++ b/third_party/blink/renderer/modules/mediastream/media_devices.cc
@@ -17,7 +17,6 @@ #include "third_party/blink/public/mojom/media/capture_handle_config.mojom-blink.h" #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-blink.h" #include "third_party/blink/public/platform/task_type.h" -#include "third_party/blink/public/platform/web_runtime_features.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_capture_handle_config.h" @@ -329,25 +328,19 @@ WebFeature::kGetDisplayMediaWithoutUserActivation); } - // The kDisplayCapturePermissionsPolicyEnabled preference controls whether - // the display-capture permissions-policy is applied or skipped. - // The kDisplayCapturePermissionsPolicyEnabled preference is translated - // into DisplayCapturePermissionsPolicyEnabled RuntimeEnabledFeature. - if (RuntimeEnabledFeatures::DisplayCapturePermissionsPolicyEnabled()) { - const bool capture_allowed_by_permissions_policy = window->IsFeatureEnabled( - mojom::blink::PermissionsPolicyFeature::kDisplayCapture, - ReportOptions::kReportOnFailure); + const bool capture_allowed_by_permissions_policy = window->IsFeatureEnabled( + mojom::blink::PermissionsPolicyFeature::kDisplayCapture, + ReportOptions::kReportOnFailure); - base::UmaHistogramEnumeration( - "Media.Ui.GetDisplayMedia.DisplayCapturePolicyResult", - capture_allowed_by_permissions_policy - ? DisplayCapturePolicyResult::kAllowed - : DisplayCapturePolicyResult::kDisallowed); + base::UmaHistogramEnumeration( + "Media.Ui.GetDisplayMedia.DisplayCapturePolicyResult", + capture_allowed_by_permissions_policy + ? DisplayCapturePolicyResult::kAllowed + : DisplayCapturePolicyResult::kDisallowed); - if (!capture_allowed_by_permissions_policy) { - exception_state.ThrowSecurityError(kFeaturePolicyBlocked); - return ScriptPromise(); - } + if (!capture_allowed_by_permissions_policy) { + exception_state.ThrowSecurityError(kFeaturePolicyBlocked); + return ScriptPromise(); } if (options->hasAutoSelectAllScreens() && options->autoSelectAllScreens()) {
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_object.cc b/third_party/blink/renderer/modules/webgpu/dawn_object.cc index 832724c..984c080 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_object.cc +++ b/third_party/blink/renderer/modules/webgpu/dawn_object.cc
@@ -25,8 +25,8 @@ setLabelImpl(value); } -void DawnObjectBase::EnsureFlush() { - dawn_control_client_->EnsureFlush(); +void DawnObjectBase::EnsureFlush(scheduler::EventLoop& event_loop) { + dawn_control_client_->EnsureFlush(event_loop); } void DawnObjectBase::FlushNow() {
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_object.h b/third_party/blink/renderer/modules/webgpu/dawn_object.h index c7567d0..0ae6a109 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_object.h +++ b/third_party/blink/renderer/modules/webgpu/dawn_object.h
@@ -50,6 +50,10 @@ namespace blink { +namespace scheduler { +class EventLoop; +} // namespace scheduler + template <typename T> struct WGPUReleaseFn; @@ -84,7 +88,7 @@ // Ensure commands up until now on this object's parent device are flushed by // the end of the task. - void EnsureFlush(); + void EnsureFlush(scheduler::EventLoop& event_loop); // Flush commands up until now on this object's parent device immediately. void FlushNow();
diff --git a/third_party/blink/renderer/modules/webgpu/gpu.cc b/third_party/blink/renderer/modules/webgpu/gpu.cc index e7d26dc5..488030c 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu.cc
@@ -23,6 +23,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_request_adapter_options.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/execution_context/agent.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/execution_context/navigator_base.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" @@ -290,10 +291,9 @@ const GPURequestAdapterOptions* options) { auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); + ExecutionContext* execution_context = ExecutionContext::From(script_state); if (!dawn_control_client_ || dawn_control_client_->IsContextLost()) { - ExecutionContext* execution_context = ExecutionContext::From(script_state); - // TODO(natlee@microsoft.com): if GPU process is lost, wait for the GPU // process to come back instead of rejecting right away std::unique_ptr<WebGraphicsContext3DProvider> context_provider = @@ -328,9 +328,10 @@ dawn_control_client_->GetProcs().instanceRequestAdapter( dawn_control_client_->GetWGPUInstance(), &dawn_options, callback->UnboundCallback(), callback->AsUserdata()); - dawn_control_client_->EnsureFlush(); + dawn_control_client_->EnsureFlush( + *execution_context->GetAgent()->event_loop()); - UseCounter::Count(ExecutionContext::From(script_state), WebFeature::kWebGPU); + UseCounter::Count(execution_context, WebFeature::kWebGPU); return promise; }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc index 69fa8d96..0f15e946 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
@@ -235,7 +235,7 @@ GetProcs().adapterRequestDevice( handle_, &dawn_desc, callback->UnboundCallback(), callback->AsUserdata()); - EnsureFlush(); + EnsureFlush(ToEventLoop(script_state)); return promise; }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc b/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc index 6207eb05f..e808403 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc
@@ -258,7 +258,7 @@ // WebGPU guarantees that promises are resolved in finite time so we // need to ensure commands are flushed. - EnsureFlush(); + EnsureFlush(ToEventLoop(script_state)); return promise; }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.cc b/third_party/blink/renderer/modules/webgpu/gpu_device.cc index 08406c0..1953ec4 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_device.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
@@ -491,7 +491,7 @@ // WebGPU guarantees that promises are resolved in finite time so we need to // ensure commands are flushed. - EnsureFlush(); + EnsureFlush(ToEventLoop(script_state)); return promise; } @@ -514,7 +514,7 @@ callback->AsUserdata()); // WebGPU guarantees that promises are resolved in finite time so we need to // ensure commands are flushed. - EnsureFlush(); + EnsureFlush(ToEventLoop(script_state)); return promise; } @@ -559,7 +559,7 @@ // WebGPU guarantees that promises are resolved in finite time so we // need to ensure commands are flushed. - EnsureFlush(); + EnsureFlush(ToEventLoop(script_state)); return promise; }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc index 310052b..4f6fdb49e 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
@@ -257,53 +257,58 @@ GetHandle(), 0u, callback->UnboundCallback(), callback->AsUserdata()); // WebGPU guarantees that promises are resolved in finite time so we // need to ensure commands are flushed. - EnsureFlush(); + EnsureFlush(ToEventLoop(script_state)); return promise; } -void GPUQueue::writeBuffer(GPUBuffer* buffer, +void GPUQueue::writeBuffer(ScriptState* script_state, + GPUBuffer* buffer, uint64_t buffer_offset, const MaybeShared<DOMArrayBufferView>& data, uint64_t data_element_offset, ExceptionState& exception_state) { - WriteBufferImpl(buffer, buffer_offset, data->byteLength(), + WriteBufferImpl(script_state, buffer, buffer_offset, data->byteLength(), data->BaseAddressMaybeShared(), data->TypeSize(), data_element_offset, {}, exception_state); } -void GPUQueue::writeBuffer(GPUBuffer* buffer, +void GPUQueue::writeBuffer(ScriptState* script_state, + GPUBuffer* buffer, uint64_t buffer_offset, const MaybeShared<DOMArrayBufferView>& data, uint64_t data_element_offset, uint64_t data_element_count, ExceptionState& exception_state) { - WriteBufferImpl(buffer, buffer_offset, data->byteLength(), + WriteBufferImpl(script_state, buffer, buffer_offset, data->byteLength(), data->BaseAddressMaybeShared(), data->TypeSize(), data_element_offset, data_element_count, exception_state); } -void GPUQueue::writeBuffer(GPUBuffer* buffer, +void GPUQueue::writeBuffer(ScriptState* script_state, + GPUBuffer* buffer, uint64_t buffer_offset, const DOMArrayBufferBase* data, uint64_t data_byte_offset, ExceptionState& exception_state) { - WriteBufferImpl(buffer, buffer_offset, data->ByteLength(), + WriteBufferImpl(script_state, buffer, buffer_offset, data->ByteLength(), data->DataMaybeShared(), 1, data_byte_offset, {}, exception_state); } -void GPUQueue::writeBuffer(GPUBuffer* buffer, +void GPUQueue::writeBuffer(ScriptState* script_state, + GPUBuffer* buffer, uint64_t buffer_offset, const DOMArrayBufferBase* data, uint64_t data_byte_offset, uint64_t byte_size, ExceptionState& exception_state) { - WriteBufferImpl(buffer, buffer_offset, data->ByteLength(), + WriteBufferImpl(script_state, buffer, buffer_offset, data->ByteLength(), data->DataMaybeShared(), 1, data_byte_offset, byte_size, exception_state); } -void GPUQueue::WriteBufferImpl(GPUBuffer* buffer, +void GPUQueue::WriteBufferImpl(ScriptState* script_state, + GPUBuffer* buffer, uint64_t buffer_offset, uint64_t data_byte_length, const void* data_base_ptr, @@ -352,29 +357,33 @@ const uint8_t* data_ptr = data_base_ptr_bytes + data_byte_offset; GetProcs().queueWriteBuffer(GetHandle(), buffer->GetHandle(), buffer_offset, data_ptr, static_cast<size_t>(write_byte_size)); - EnsureFlush(); + EnsureFlush(ToEventLoop(script_state)); } -void GPUQueue::writeTexture(GPUImageCopyTexture* destination, +void GPUQueue::writeTexture(ScriptState* script_state, + GPUImageCopyTexture* destination, const MaybeShared<DOMArrayBufferView>& data, GPUImageDataLayout* data_layout, const V8GPUExtent3D* write_size, ExceptionState& exception_state) { - WriteTextureImpl(destination, data->BaseAddressMaybeShared(), + WriteTextureImpl(script_state, destination, data->BaseAddressMaybeShared(), data->byteLength(), data_layout, write_size, exception_state); } -void GPUQueue::writeTexture(GPUImageCopyTexture* destination, +void GPUQueue::writeTexture(ScriptState* script_state, + GPUImageCopyTexture* destination, const DOMArrayBufferBase* data, GPUImageDataLayout* data_layout, const V8GPUExtent3D* write_size, ExceptionState& exception_state) { - WriteTextureImpl(destination, data->DataMaybeShared(), data->ByteLength(), - data_layout, write_size, exception_state); + WriteTextureImpl(script_state, destination, data->DataMaybeShared(), + data->ByteLength(), data_layout, write_size, + exception_state); } -void GPUQueue::WriteTextureImpl(GPUImageCopyTexture* destination, +void GPUQueue::WriteTextureImpl(ScriptState* script_state, + GPUImageCopyTexture* destination, const void* data, size_t data_size, GPUImageDataLayout* data_layout, @@ -419,7 +428,7 @@ GetProcs().queueWriteTexture(GetHandle(), &dawn_destination, data_ptr, required_copy_size, &dawn_data_layout, &dawn_write_size); - EnsureFlush(); + EnsureFlush(ToEventLoop(script_state)); return; }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_queue.h b/third_party/blink/renderer/modules/webgpu/gpu_queue.h index 63f3e0b7..1c6852ed 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_queue.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_queue.h
@@ -38,34 +38,40 @@ // gpu_queue.idl void submit(const HeapVector<Member<GPUCommandBuffer>>& buffers); ScriptPromise onSubmittedWorkDone(ScriptState* script_state); - void writeBuffer(GPUBuffer* buffer, + void writeBuffer(ScriptState* script_state, + GPUBuffer* buffer, uint64_t buffer_offset, const MaybeShared<DOMArrayBufferView>& data, uint64_t data_element_offset, ExceptionState& exception_state); - void writeBuffer(GPUBuffer* buffer, + void writeBuffer(ScriptState* script_state, + GPUBuffer* buffer, uint64_t buffer_offset, const MaybeShared<DOMArrayBufferView>& data, uint64_t data_element_offset, uint64_t data_element_count, ExceptionState& exception_state); - void writeBuffer(GPUBuffer* buffer, + void writeBuffer(ScriptState* script_state, + GPUBuffer* buffer, uint64_t buffer_offset, const DOMArrayBufferBase* data, uint64_t data_byte_offset, ExceptionState& exception_state); - void writeBuffer(GPUBuffer* buffer, + void writeBuffer(ScriptState* script_state, + GPUBuffer* buffer, uint64_t buffer_offset, const DOMArrayBufferBase* data, uint64_t data_byte_offset, uint64_t byte_size, ExceptionState& exception_state); - void writeTexture(GPUImageCopyTexture* destination, + void writeTexture(ScriptState* script_state, + GPUImageCopyTexture* destination, const MaybeShared<DOMArrayBufferView>& data, GPUImageDataLayout* data_layout, const V8GPUExtent3D* write_size, ExceptionState& exception_state); - void writeTexture(GPUImageCopyTexture* destination, + void writeTexture(ScriptState* script_state, + GPUImageCopyTexture* destination, const DOMArrayBufferBase* data, GPUImageDataLayout* data_layout, const V8GPUExtent3D* write_size, @@ -86,7 +92,8 @@ bool dst_premultiplied_alpha, PredefinedColorSpace dst_color_space, bool flipY); - void WriteBufferImpl(GPUBuffer* buffer, + void WriteBufferImpl(ScriptState* script_state, + GPUBuffer* buffer, uint64_t buffer_offset, uint64_t data_byte_length, const void* data_base_ptr, @@ -94,7 +101,8 @@ uint64_t data_byte_offset, absl::optional<uint64_t> byte_size, ExceptionState& exception_state); - void WriteTextureImpl(GPUImageCopyTexture* destination, + void WriteTextureImpl(ScriptState* script_state, + GPUImageCopyTexture* destination, const void* data, size_t dataSize, GPUImageDataLayout* data_layout,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_queue.idl b/third_party/blink/renderer/modules/webgpu/gpu_queue.idl index ceacce7..ac4f4c9 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_queue.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_queue.idl
@@ -15,25 +15,25 @@ // TODO(crbug.com/1088107): Merge these overloads into one with // [AllowShared] BufferSource (or whatever the upstream spec has), which // would expand this to allow SharedArrayBuffer (can't be implemented now). - [RaisesException] void writeBuffer( + [CallWith=ScriptState, RaisesException] void writeBuffer( GPUBuffer buffer, GPUSize64 bufferOffset, [AllowShared] ArrayBufferView data, optional GPUSize64 dataElementOffset = 0, optional GPUSize64 dataElementCount); - [RaisesException] void writeBuffer( + [CallWith=ScriptState, RaisesException] void writeBuffer( GPUBuffer buffer, GPUSize64 bufferOffset, ArrayBuffer data, optional GPUSize64 dataByteOffset = 0, optional GPUSize64 byteSize); - [RaisesException] void writeTexture( + [CallWith=ScriptState, RaisesException] void writeTexture( GPUImageCopyTexture destination, [AllowShared] ArrayBufferView data, GPUImageDataLayout dataLayout, GPUExtent3D size); - [RaisesException] void writeTexture( + [CallWith=ScriptState, RaisesException] void writeTexture( GPUImageCopyTexture destination, ArrayBuffer data, GPUImageDataLayout dataLayout,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc b/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc index 2ac0988..fbc17426 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc
@@ -114,7 +114,7 @@ GetHandle(), callback->UnboundCallback(), callback->AsUserdata()); // WebGPU guarantees that promises are resolved in finite time so we // need to ensure commands are flushed. - EnsureFlush(); + EnsureFlush(ToEventLoop(script_state)); return promise; }
diff --git a/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.cc b/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.cc index b4abeba5..86fa626 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.cc
@@ -5,8 +5,8 @@ #include "third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h" #include "base/check.h" -#include "third_party/blink/renderer/platform/bindings/microtask.h" #include "third_party/blink/renderer/platform/graphics/gpu/webgpu_resource_provider_cache.h" +#include "third_party/blink/renderer/platform/scheduler/public/event_loop.h" #include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { @@ -107,7 +107,7 @@ } } -void DawnControlClientHolder::EnsureFlush() { +void DawnControlClientHolder::EnsureFlush(scheduler::EventLoop& event_loop) { auto context_provider = GetContextProviderWeakPtr(); if (UNLIKELY(!context_provider)) return; @@ -118,7 +118,7 @@ // is empty. Do nothing. return; } - Microtask::EnqueueMicrotask(WTF::BindOnce( + event_loop.EnqueueMicrotask(WTF::BindOnce( [](scoped_refptr<DawnControlClientHolder> dawn_control_client) { if (auto context_provider = dawn_control_client->GetContextProviderWeakPtr()) {
diff --git a/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h b/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h index 952dc74..eb5614a9 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h +++ b/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h
@@ -22,6 +22,10 @@ namespace blink { +namespace scheduler { +class EventLoop; +} // namespace scheduler + // This class holds the WebGraphicsContext3DProviderWrapper and a strong // reference to the WebGPU APIChannel. // DawnControlClientHolder::Destroy() should be called to destroy the @@ -57,7 +61,7 @@ // Flush commands on this client immediately. void Flush(); // Ensure commands on this client are flushed by the end of the task. - void EnsureFlush(); + void EnsureFlush(scheduler::EventLoop& event_loop); private: friend class RefCounted<DawnControlClientHolder>;
diff --git a/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc index eb293cf..86f6bd5 100644 --- a/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc +++ b/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc
@@ -83,7 +83,9 @@ namespace { -const int exifMarker = JPEG_APP0 + 1; +constexpr int kExifMarker = JPEG_APP0 + 1; +constexpr unsigned kExifAPP1SignatureSize = 6; +constexpr unsigned kExifHeaderSize = 8; // JPEG only supports a denominator of 8. const unsigned g_scale_denominator = 8; @@ -233,31 +235,38 @@ return float(nom) / float(denom); } -static bool CheckExifHeader(jpeg_saved_marker_ptr marker, - bool& is_big_endian, - unsigned& ifd_offset) { - // For exif data, the APP1 block is followed by 'E', 'x', 'i', 'f', '\0', - // then a fill byte, and then a tiff file that contains the metadata. - // A tiff file starts with 'I', 'I' (intel / little endian byte order) or - // 'M', 'M' (motorola / big endian byte order), followed by (uint16_t)42, - // followed by an uint32_t with the offset to the tag block, relative to the - // tiff file start. - const unsigned kExifHeaderSize = 14; - if (!(marker->marker == exifMarker && - marker->data_length >= kExifHeaderSize && marker->data[0] == 'E' && - marker->data[1] == 'x' && marker->data[2] == 'i' && - marker->data[3] == 'f' && - marker->data[4] == '\0' - // data[5] is a fill byte - && ((marker->data[6] == 'I' && marker->data[7] == 'I') || - (marker->data[6] == 'M' && marker->data[7] == 'M')))) +static bool IsExifData(jpeg_saved_marker_ptr marker) { + // For EXIF data, the APP1 block is followed by 'E', 'x', 'i', 'f', '\0', + // then a fill byte, and then a TIFF file that contains the metadata. + if (marker->marker != kExifMarker) return false; - - is_big_endian = marker->data[6] == 'M'; - if (ReadUint16(marker->data + 8, is_big_endian) != 42) + if (marker->data_length < kExifAPP1SignatureSize) return false; + const uint8_t kExifAPP1Signature[5] = {'E', 'x', 'i', 'f', '\0'}; + if (memcmp(marker->data, kExifAPP1Signature, sizeof(kExifAPP1Signature)) != 0) + return false; + return true; +} - ifd_offset = ReadUint32(marker->data + 10, is_big_endian); +static bool ReadExifHeader(base::span<const uint8_t> data, + bool& is_big_endian) { + // A TIFF file starts with 'I', 'I' (Intel / little endian byte order) or + // 'M', 'M' (Motorola / big endian byte order), followed by (uint16_t)42, + // followed by an uint32_t with the offset to the initial (0th) IFD tag + // block, relative to the TIFF file start. + // + // Header in summary: + // <byte-order tag> (2 bytes), <magic> (2 bytes), <0th IFD offset> (4 bytes) + if (data.size() < kExifHeaderSize) + return false; + const uint8_t byte_order = data[0]; + if (byte_order != data[1]) + return false; + if (byte_order != 'I' && byte_order != 'M') + return false; + is_big_endian = byte_order == 'M'; + if (ReadUint16(data.data() + 2, is_big_endian) != 42) + return false; return true; } @@ -321,9 +330,11 @@ const uint8_t* ifd = dir_start + 2; // Skip over the uint16 that was just read. - // Every ifd entry is 2 bytes of tag, 2 bytes of contents datatype, - // 4 bytes of number-of-elements, and 4 bytes of either offset to the - // tag data, or if the data is small enough, the inlined data itself. + // A TIFF image file directory (IFD) consists of a uint16_t describing the + // number of IFD entries, followed by that many entries. Every IFD entry is 2 + // bytes of tag, 2 bytes of contents datatype, 4 bytes of number-of-elements, + // and 4 bytes of either offset to the tag data, or if the data is small + // enough, the inlined data itself. const int kIfdEntrySize = 12; for (unsigned i = 0; i < tag_count && data_end - ifd >= kIfdEntrySize; ++i, ifd += kIfdEntrySize) { @@ -408,31 +419,33 @@ } } +static bool ReadExif(base::span<const uint8_t> data, + DecodedImageMetaData& metadata) { + bool is_big_endian; + if (!ReadExifHeader(data, is_big_endian)) + return false; + const unsigned ifd_offset = ReadUint32(data.data() + 4, is_big_endian); + if (ifd_offset < kExifHeaderSize || ifd_offset >= data.size()) + return false; + + const uint8_t* data_end = data.data() + data.size(); + const uint8_t* data_start = data.data(); + const uint8_t* ifd0 = data_start + ifd_offset; + ReadExifDirectory(ifd0, data_start, data_end, is_big_endian, metadata); + return true; +} + static void ReadImageMetaData(jpeg_decompress_struct* info, DecodedImageMetaData& metadata) { // The JPEG decoder looks at EXIF metadata. // FIXME: Possibly implement XMP and IPTC support. for (jpeg_saved_marker_ptr marker = info->marker_list; marker; marker = marker->next) { - bool is_big_endian; - unsigned ifd_offset; - if (!CheckExifHeader(marker, is_big_endian, ifd_offset)) + if (!IsExifData(marker)) continue; - const unsigned kOffsetToTiffData = - 6; // Account for 'Exif\0<fill byte>' header. - if (marker->data_length < kOffsetToTiffData || - ifd_offset >= marker->data_length - kOffsetToTiffData) - continue; - - // The jpeg exif container format contains a tiff block for metadata. - // A tiff image file directory (ifd) consists of a uint16_t describing - // the number of ifd entries, followed by that many entries. - // When touching this code, it's useful to look at the tiff spec: - // http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf - const uint8_t* data_end = marker->data + marker->data_length; - const uint8_t* data_start = marker->data + kOffsetToTiffData; - const uint8_t* ifd0 = data_start + ifd_offset; - - ReadExifDirectory(ifd0, data_start, data_end, is_big_endian, metadata); + base::span<const uint8_t> exif_data( + marker->data + kExifAPP1SignatureSize, + marker->data_length - kExifAPP1SignatureSize); + ReadExif(exif_data, metadata); } } @@ -499,7 +512,7 @@ setup_read_icc_profile(&info_); // Keep APP1 blocks, for obtaining exif data. - jpeg_save_markers(&info_, exifMarker, 0xFFFF); + jpeg_save_markers(&info_, kExifMarker, 0xFFFF); } JPEGImageReader(const JPEGImageReader&) = delete;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 25ca72fc..49e2693 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1004,15 +1004,6 @@ status: "experimental", }, { - // When on, the display-capture permissions-policy is enforced. - // When off, enforcement of this permissions-policy is skipped. - // This is driven from the browser process by the Enterprise policy - // called "DisplayCapturePermissionsPolicyEnabled". - // TODO(crbug.com/1233969): Remove this around m100. - name: "DisplayCapturePermissionsPolicy", - public: true, - }, - { name: "DisplayCutoutAPI", public: true, settable_from_internals: true, @@ -2778,6 +2769,12 @@ implied_by: ["SystemWakeLock"], }, { + // When enabled, this will issue a warning to the console any time + // rendering is forced withing content-visibility subtrees (both + // content-visibility: auto and content-visibility: hidden). + name: "WarnOnContentVisibilityRenderAccess", + }, + { name: "WebAnimationsAPI", status: "stable", implied_by: ["AnimationWorklet"],
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 2d3781df..0788300 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -313,8 +313,7 @@ crbug.com/784956 fast/history/frameset-repeated-name.html [ Failure Pass ] -# These are both related to images not painting as expected, and are primarily CQ hidden flakes -crbug.com/1284609 images/image-load-reset-on-new-base.html [ Failure Pass ] +# Image not painting as expected, primarily shows as CQ hidden flakes. crbug.com/1271092 paint/invalidation/scroll/fixed-img-src-change-after-scroll.html [ Failure Pass ] ########## Genuinely flaky ########## @@ -562,7 +561,6 @@ crbug.com/936891 virtual/threaded-prefer-compositing/fast/scrolling/document-level-touchmove-event-listener-passive-by-default.html [ Pass ] crbug.com/1049599 [ Linux ] virtual/threaded-prefer-compositing/fast/scrolling/events/overscroll-event-fired-to-element-with-overscroll-behavior.html [ Failure Pass Skip Timeout ] crbug.com/1193920 virtual/threaded-prefer-compositing/fast/scrolling/events/overscroll-event-fired-to-scrolled-element.html [ Failure Pass Timeout ] -crbug.com/1335172 [ Linux ] virtual/threaded-prefer-compositing/fast/scrolling/inertial-scrolling-with-pointer-events-none-overlay.html [ Failure Pass ] crbug.com/841567 [ Debug Mac11 ] virtual/threaded-prefer-compositing/fast/scrolling/listbox-wheel-event.html [ Failure Pass Timeout ] crbug.com/841567 [ Debug Mac12 ] virtual/threaded-prefer-compositing/fast/scrolling/listbox-wheel-event.html [ Failure Pass Timeout ] crbug.com/841567 virtual/threaded-prefer-compositing/fast/scrolling/overflow-scrollability.html [ Failure Pass Timeout ] @@ -6668,7 +6666,6 @@ crbug.com/1304956 storage/indexeddb/dont-wedge.html [ Failure Pass ] # Sheriff 2022-03-15 -crbug.com/626703 external/wpt/scroll-to-text-fragment/force-load-at-top.html [ Pass Timeout ] crbug.com/1269534 fast/spatial-navigation/snav-zero-margin-content.html [ Failure Pass ] crbug.com/1295980 virtual/fenced-frame-mparch/wpt_internal/fenced_frame/user-activation.https.html [ Failure Pass Timeout ] crbug.com/1295980 virtual/fenced-frame-shadow-dom/wpt_internal/fenced_frame/user-activation.https.html [ Failure Pass Timeout ]
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-light-dismiss.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-light-dismiss.tentative.html index 8eca7a64..265a8cb 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-light-dismiss.tentative.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-light-dismiss.tentative.html
@@ -27,6 +27,7 @@ <style> #p1 {top: 50px;} #p2 {top: 120px;} + [popup] {bottom:auto;} [popup]::backdrop { /* This should *not* affect anything: */ pointer-events: auto; @@ -502,3 +503,33 @@ assert_false(auto.matches(':open')); },'Light dismiss of mixed popup types'); </script> + + +<div popup id=p13>Pop-up 1 + <div popup id=p14>Pop-up 2 + <div popup id=p15>Pop-up 3</div> + </div> +</div> +<style> + #p13 {top: 100px;} + #p14 {top: 200px;} + #p15 {top: 300px;} +</style> +<script> +promise_test(async () => { + const p13 = document.querySelector('#p13'); + const p14 = document.querySelector('#p14'); + const p15 = document.querySelector('#p15'); + p13.showPopUp(); + p14.showPopUp(); + p15.showPopUp(); + p15.addEventListener('popuphide',() => { + p14.hidePopUp(); + },{once:true}); + assert_true(p13.matches(':open') && p14.matches(':open') && p15.matches(':open'),'all three should be open'); + p14.hidePopUp(); + assert_true(p13.matches(':open'),'p13 should still be open'); + assert_false(p14.matches(':open')); + assert_false(p15.matches(':open')); +},'Hide the target pop-up during "hide all popups until"'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/performance-timeline/navigation-id-reset.tentative.html b/third_party/blink/web_tests/external/wpt/performance-timeline/navigation-id-reset.tentative.html new file mode 100644 index 0000000..7386331 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/performance-timeline/navigation-id-reset.tentative.html
@@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="/common/dispatcher/dispatcher.js"></script> +<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js"></script> +<script> + const reload = () => { + window.location.reload(); + }; + + const getNavigationId = () => { + window.performance.mark('initial_load'); + let entries = window.performance.getEntriesByType('mark'); + return entries[entries.length - 1].navigationId; + } + + promise_test(async t => { + const pageA = new RemoteContext(token()); + const pageB = new RemoteContext(token()); + + const urlA = executorPath + pageA.context_id; + const urlB = originCrossSite + executorPath + pageB.context_id; + // Open url A. + window.open(urlA, '_blank', 'noopener') + await pageA.execute_script(waitForPageShow); + + // Assert navigation id is 1 when the document is loaded first time. + + let navigationId = await pageA.execute_script(getNavigationId); + assert_equals(navigationId, 1, 'Navigation Id should be 1 initially.'); + + // Navigate away to url B and back. + await navigateAndThenBack(pageA, pageB, urlB); + + // Assert navigation id increments to 2 when the document is load from bfcache. + navigationId = await pageA.execute_script(getNavigationId); + assert_equals(navigationId, 2, 'Navigation Id should be 2 after increment.'); + + // Reload page. + await pageA.execute_script(reload); + await pageA.execute_script(waitForPageShow); + + // Assert navigation id is reset to 1 after reload. + navigationId = await pageA.execute_script(getNavigationId); + assert_equals(navigationId, 1, 'Navigation Id should be 1 after reload.'); + }, 'Navigation Id should be reset to 1 after reload.'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/uievents/mouse/mouseenter-mouseleave-on-drag.html b/third_party/blink/web_tests/external/wpt/uievents/mouse/mouseenter-mouseleave-on-drag.html new file mode 100644 index 0000000..c36a150 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/uievents/mouse/mouseenter-mouseleave-on-drag.html
@@ -0,0 +1,187 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for redundant mouseenter or mouseleave events</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-actions.js"></script> + <script src="/resources/testdriver-vendor.js"></script> +</head> +<style> +#outer { + background: grey; + position: absolute; + left: 100px; + top: 100px; + width: 100px; + height: 100px; +} +#inner { + background: red; + position: absolute; + left: 30px; + top: 30px; + width: 40px; + height: 40px; +} +</style> + +<body> + <!-- Verifies that dragging mouse in/out of an element doesn't fire redundant + mouseenter or mouseleave events (crbug.com/356090 & crbug.com/470258) --> + <div id="outer"> + <div id="inner"></div> + </div> +</body> +<script> +let eventLog = []; +let nextUncheckedEventIndex = 0; + +// Ensure match to the next sequence of events in the event log. +function assert_next_events(target, expectedEventNames, message) { + for (let i = 0; i < expectedEventNames.length; i++) { + assert_true(nextUncheckedEventIndex < eventLog.length, + `${message}: empty event queue`); + const observed = eventLog[nextUncheckedEventIndex++]; + const expected = `${expectedEventNames[i]}@${target.id}`; + assert_equals(observed, expected,`${message}: Event mismatch`); + } +} + +// After validating the expected events, all entries in the event map +// must be false or we have recorded an unexpected event. +function assert_empty_event_queue(message) { + const uncheckedEvents = eventLog.length - nextUncheckedEventIndex; + assert_equals(uncheckedEvents, 0, + `${message}: Unexpected events ` + + `${eventLog.slice(-uncheckedEvents).join(", ")}`); +} + +function addEventListeners(test) { + const eventTypes = [ + 'mousedown', + 'mouseenter', + 'mouseleave', + 'mousemove', + 'mouseout', + 'mouseover', + 'mouseup' + ]; + ['inner', 'outer'].forEach(id => { + const element = document.getElementById(id); + eventTypes.forEach(eventType => { + const listener = (e) => { + if (e.eventPhase == Event.AT_TARGET) { + eventLog.push(`${eventType}@${id}`); + } + }; + element.addEventListener(eventType, listener); + test.add_cleanup(() => { + element.removeEventListener(eventType, listener); + }); + }) + }); +} + +// At the end of each action sequence we move the mouse over the root element. +// Once this event is detected, all other upstream events must be logged and +// we can proceed with the checks. +async function mousemoveOverRootElement() { + return new Promise(resolve => { + const listener = (e) => { + if (e.eventPhase == Event.AT_TARGET) { + document.documentElement.removeEventListener('mousemove', listener); + resolve(); + } + }; + document.documentElement.addEventListener('mousemove', listener); + }); +} + +window.onload = async () => { + const outer = document.getElementById('outer'); + const inner = document.getElementById('inner'); + const leftOuter = 100; + const rightOuter = 200; + const leftInner = 130; + const rightInner = 170; + const centerY = 150; + + promise_test(async t => { + addEventListeners(t); + const completionPromise = mousemoveOverRootElement(); + const actions =new test_driver.Actions(); + actions.pointerMove(leftOuter + 10, centerY) + .pointerDown({button: actions.ButtonType.LEFT}) + .pointerMove(rightOuter - 10, centerY) + .pointerUp({button: actions.ButtonType.LEFT}) + .pointerMove(0, 0) + .send(); + await actions; + await completionPromise; + + assert_next_events(outer, ['mouseover', 'mouseenter', 'mousemove'], + 'Move over outer element'); + assert_next_events(outer, ['mousedown', 'mousemove', 'mouseup'], + 'Drag across outer element'); + assert_next_events(outer, ['mouseout', 'mouseleave'], + 'Move to origin'); + assert_empty_event_queue('Drag across outer element'); + }, 'Test dragging across inner div'); + + promise_test(async t => { + addEventListeners(t); + const completionPromise = mousemoveOverRootElement(); + const actions =new test_driver.Actions(); + actions.pointerMove(leftOuter + 10, centerY) + .pointerDown({button: actions.ButtonType.LEFT}) + .pointerMove(leftInner + 10, centerY) + .pointerUp({button: actions.ButtonType.LEFT}) + .pointerMove(0, 0) + .send(); + await actions; + await completionPromise; + + assert_next_events(outer, ['mouseover', 'mouseenter', 'mousemove'], + 'Move over outer element'); + assert_next_events(outer, ['mousedown', 'mouseout'], + 'Initiate drag'); + assert_next_events(inner, + ['mouseover', 'mouseenter', 'mousemove', 'mouseup'], + 'Drag into inner element'); + assert_next_events(inner, ['mouseout', 'mouseleave'], + 'Move to origin'); + assert_next_events(outer, [ 'mouseleave'], + 'Move to origin'); + assert_empty_event_queue('Drag into inner element'); + }, 'Test dragging into inner div'); + + promise_test(async t => { + addEventListeners(t); + const completionPromise = mousemoveOverRootElement(); + const actions =new test_driver.Actions(); + actions.pointerMove(leftInner + 10, centerY) + .pointerDown({button: actions.ButtonType.LEFT}) + .pointerMove(rightInner + 10, centerY) + .pointerUp({button: actions.ButtonType.LEFT}) + .pointerMove(0, 0) + .send(); + await actions; + await completionPromise; + + assert_next_events(inner, ['mouseover'], 'Move over inner element'); + assert_next_events(outer, ['mouseenter'], 'Enter outer'); + assert_next_events(inner, ['mouseenter', 'mousemove'], + 'Move across inner element'); + assert_next_events(inner, ['mousedown', 'mouseout', 'mouseleave'], + 'Drag out of inner'); + assert_next_events(outer, ['mouseover', 'mousemove', 'mouseup'], + 'Drag into outer'); + assert_next_events(outer, ['mouseout', 'mouseleave'], + 'Move to origin'); + assert_empty_event_queue('Drag into inner element'); + }, 'Test dragging out of inner div'); +}; +</script> +</html>
diff --git a/third_party/blink/web_tests/fast/css/content-visibility-console-messages-expected.txt b/third_party/blink/web_tests/fast/css/content-visibility-console-messages-expected.txt index 8f91f50..058a65a 100644 --- a/third_party/blink/web_tests/fast/css/content-visibility-console-messages-expected.txt +++ b/third_party/blink/web_tests/fast/css/content-visibility-console-messages-expected.txt
@@ -1,10 +1,10 @@ CONSOLE MESSAGE: forcing layout on c-v:hidden should make a console warning. -CONSOLE DEBUG: Rendering was performed in a subtree hidden by content-visibility:hidden. +CONSOLE DEBUG: Rendering was performed in a subtree hidden by content-visibility. CONSOLE MESSAGE: forcing layout on c-v:auto should NOT make a console warning. CONSOLE MESSAGE: calling isVisible should NOT make a console warning. CONSOLE MESSAGE: forcing layout via range APIs on c-v:hidden should make a console warning. -CONSOLE DEBUG: Rendering was performed in a subtree hidden by content-visibility:hidden. +CONSOLE DEBUG: Rendering was performed in a subtree hidden by content-visibility. CONSOLE MESSAGE: forcing layout via range APIs on c-v:auto should NOT make a console warning. CONSOLE MESSAGE: forcing layout on c-v:hidden inside c-v:auto should make a console warning. -CONSOLE DEBUG: Rendering was performed in a subtree hidden by content-visibility:hidden. +CONSOLE DEBUG: Rendering was performed in a subtree hidden by content-visibility.
diff --git a/third_party/blink/web_tests/fast/events/mouseenter-mouseleave-on-drag-expected.txt b/third_party/blink/web_tests/fast/events/mouseenter-mouseleave-on-drag-expected.txt deleted file mode 100644 index 169b2f1..0000000 --- a/third_party/blink/web_tests/fast/events/mouseenter-mouseleave-on-drag-expected.txt +++ /dev/null
@@ -1,48 +0,0 @@ -Verifies that dragging mouse in/out of an element doesn't fire redundant mouseenter or mouseleave events (crbug.com/356090 & crbug.com/470258) - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - ---- drag across inner --- -outer received mouseover -outer received mouseenter -PASS wasInside['outer'] is false -outer received mousedown -outer received mouseout -inner received mouseover -inner received mouseenter -PASS wasInside['inner'] is false -inner received mouseout -inner received mouseleave -PASS wasInside['inner'] is true -outer received mouseover -outer received mouseup -outer received mouseout -outer received mouseleave -PASS wasInside['outer'] is true - - ---- drag into inner --- -outer received mouseover -outer received mouseenter -PASS wasInside['outer'] is false -outer received mousedown -outer received mouseout -inner received mouseover -inner received mouseenter -PASS wasInside['inner'] is false -inner received mouseup - - ---- drag out of inner --- -inner received mousedown -inner received mouseout -inner received mouseleave -PASS wasInside['inner'] is true -outer received mouseover -outer received mouseup - - -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/fast/events/mouseenter-mouseleave-on-drag.html b/third_party/blink/web_tests/fast/events/mouseenter-mouseleave-on-drag.html deleted file mode 100644 index 05c4342..0000000 --- a/third_party/blink/web_tests/fast/events/mouseenter-mouseleave-on-drag.html +++ /dev/null
@@ -1,95 +0,0 @@ -<!DOCTYPE HTML> -<script src="../../resources/js-test.js"></script> -<style> -#outer { - background: grey; - position: absolute; - left: 100px; - top: 100px; - width: 100px; - height: 100px; -} -#inner { - background: red; - position: absolute; - left: 30px; - top: 30px; - width: 40px; - height: 40px; -} -</style> - -<div id="outer"> - <div id="inner"></div> -</div> - -<div id="console"></div> - -<script> -description("Verifies that dragging mouse in/out of an element doesn't fire redundant mouseenter or mouseleave events (crbug.com/356090 & crbug.com/470258)"); - -var wasInside = {}; - -function init() { - ["outer", "inner"].forEach(function(id) { - wasInside[id] = false; - - var targetDiv = document.getElementById(id); - - targetDiv.addEventListener("mouseenter", function(event) { - debug(id + " received mouseenter"); - shouldBeFalse("wasInside['" + id + "']"); - wasInside[id] = true; - }); - - targetDiv.addEventListener("mouseleave", function(event) { - debug(id + " received mouseleave"); - shouldBeTrue("wasInside['" + id + "']"); - wasInside[id] = false; - }); - - ["mouseover", "mouseout", "mousedown", "mouseup"].forEach(function(eventName) { - targetDiv.addEventListener(eventName, function(event) { - if (event.eventPhase == Event.AT_TARGET) - debug(id + " received " + eventName); - }); - }); - }); -} - -init(); -if (window.eventSender) { - var y = 150; - - debug("--- drag across inner ---"); - eventSender.mouseMoveTo(1, y); - eventSender.mouseMoveTo(110, y); - eventSender.mouseDown(); - eventSender.mouseMoveTo(140, y); - eventSender.mouseMoveTo(150, y); - eventSender.mouseMoveTo(160, y); - eventSender.mouseMoveTo(190, y); - eventSender.mouseUp(); - eventSender.mouseMoveTo(201, y); - - debug(""); - - debug("--- drag into inner ---"); - eventSender.mouseMoveTo(190, y); - eventSender.mouseDown(); - eventSender.mouseMoveTo(150, y); - eventSender.mouseUp(); - - debug(""); - - debug("--- drag out of inner ---"); - eventSender.mouseDown(); - eventSender.mouseMoveTo(110, y); - eventSender.mouseUp(); - - debug(""); - -} else { - debug("This test requires eventSender"); -} -</script>
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/css/content-visibility-console-messages-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/css/content-visibility-console-messages-expected.txt index 8f91f50..058a65a 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/css/content-visibility-console-messages-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/css/content-visibility-console-messages-expected.txt
@@ -1,10 +1,10 @@ CONSOLE MESSAGE: forcing layout on c-v:hidden should make a console warning. -CONSOLE DEBUG: Rendering was performed in a subtree hidden by content-visibility:hidden. +CONSOLE DEBUG: Rendering was performed in a subtree hidden by content-visibility. CONSOLE MESSAGE: forcing layout on c-v:auto should NOT make a console warning. CONSOLE MESSAGE: calling isVisible should NOT make a console warning. CONSOLE MESSAGE: forcing layout via range APIs on c-v:hidden should make a console warning. -CONSOLE DEBUG: Rendering was performed in a subtree hidden by content-visibility:hidden. +CONSOLE DEBUG: Rendering was performed in a subtree hidden by content-visibility. CONSOLE MESSAGE: forcing layout via range APIs on c-v:auto should NOT make a console warning. CONSOLE MESSAGE: forcing layout on c-v:hidden inside c-v:auto should make a console warning. -CONSOLE DEBUG: Rendering was performed in a subtree hidden by content-visibility:hidden. +CONSOLE DEBUG: Rendering was performed in a subtree hidden by content-visibility.
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/portals/target-create-portal-target-info-changed.js b/third_party/blink/web_tests/http/tests/inspector-protocol/portals/target-create-portal-target-info-changed.js new file mode 100644 index 0000000..db9d0aa2 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/portals/target-create-portal-target-info-changed.js
@@ -0,0 +1,22 @@ +(async function(testRunner) { + const portalUrl = 'http://devtools.oopif-b.test:8000/inspector-protocol/portals/resources/portal.html'; + const {session, dp} = await testRunner.startBlank('Tests that no spurious targetInfoChanged events are emitted during portal creation.'); + + const tabs = (await dp.Target.getTargets({filter: [{type: "tab"}]})).result.targetInfos; + const tabUnderTest = tabs.find(target => target.url.endsWith("/inspector-protocol-page.html")); + const tp = (await testRunner.browserSession().attachChild(tabUnderTest.targetId)).protocol; + + await tp.Target.setAutoAttach({autoAttach: true, flatten: true, waitForDebuggerOnStart: false}); + + tp.Target.onTargetInfoChanged(event => testRunner.log(event.params, "FAILED: unexpected event")); + + await session.evaluateAsync(` + new Promise(resolve => { + const portal = document.createElement('portal'); + portal.src = '${portalUrl}'; + portal.onload = resolve; + document.body.appendChild(portal); + }) + `); + testRunner.completeTest(); +}) \ No newline at end of file
diff --git a/third_party/blink/web_tests/images/image-load-reset-on-new-base.html b/third_party/blink/web_tests/images/image-load-reset-on-new-base.html index 9275049c..ff3e61c 100644 --- a/third_party/blink/web_tests/images/image-load-reset-on-new-base.html +++ b/third_party/blink/web_tests/images/image-load-reset-on-new-base.html
@@ -1,16 +1,19 @@ <!doctype HTML> - <iframe id="frame"></iframe> <script> if (window.testRunner) window.testRunner.waitUntilDone(); -function test() { - var content = '<head><base href="resources/"></head><body><img src="base-test-resources/success.png"></body>'; - var doc = document.getElementById("frame").contentDocument; - doc.firstChild.innerHTML = content; +function done() { if (window.testRunner) window.testRunner.notifyDone(); } +function test() { + const content = '<head><base href="resources/"></head><body>' + + '<img src="base-test-resources/success.png" onload="parent.done()" onerror="parent.done()">' + + '</body>'; + const doc = document.getElementById("frame").contentDocument; + doc.firstChild.innerHTML = content; +} window.onload = test; </script>
diff --git a/third_party/blink/web_tests/images/svg-image-load-reset-on-new-base.html b/third_party/blink/web_tests/images/svg-image-load-reset-on-new-base.html index 70602b9..21f60c5 100644 --- a/third_party/blink/web_tests/images/svg-image-load-reset-on-new-base.html +++ b/third_party/blink/web_tests/images/svg-image-load-reset-on-new-base.html
@@ -1,19 +1,20 @@ <!doctype HTML> - <iframe id="frame"></iframe> <script> if (window.testRunner) window.testRunner.waitUntilDone(); -function test() { - var content = '<head><base href="resources/"></head><body>' + - '<svg width="100" height="100">' + - ' <image xlink:href="base-test-resources/success.png" />' + - '</svg></body>'; - var doc = document.getElementById("frame").contentDocument; - doc.firstChild.innerHTML = content; +function done() { if (window.testRunner) window.testRunner.notifyDone(); } +function test() { + const content = '<head><base href="resources/"></head><body>' + + '<svg width="100" height="100">' + + ' <image xlink:href="base-test-resources/success.png" onload="parent.done()" onerror="parent.done()"/>' + + '</svg></body>'; + const doc = document.getElementById("frame").contentDocument; + doc.firstChild.innerHTML = content; +} window.onload = test; </script>
diff --git a/third_party/blink/web_tests/touchadjustment/touch-links-active.html b/third_party/blink/web_tests/touchadjustment/touch-links-active.html index 19a16c0..7cadb5d 100644 --- a/third_party/blink/web_tests/touchadjustment/touch-links-active.html +++ b/third_party/blink/web_tests/touchadjustment/touch-links-active.html
@@ -135,7 +135,9 @@ testDirectTouches(); e.sandbox.style.display = 'none'; } + testRunner.waitUntilDone(); runTests(); + testRunner.notifyDone(); </script> </body> </html>
diff --git a/third_party/blink/web_tests/virtual/portals/http/tests/inspector-protocol/portals/target-create-portal-target-info-changed-expected.txt b/third_party/blink/web_tests/virtual/portals/http/tests/inspector-protocol/portals/target-create-portal-target-info-changed-expected.txt new file mode 100644 index 0000000..6758cd2 --- /dev/null +++ b/third_party/blink/web_tests/virtual/portals/http/tests/inspector-protocol/portals/target-create-portal-target-info-changed-expected.txt
@@ -0,0 +1,2 @@ +Tests that no spurious targetInfoChanged events are emitted during portal creation. +
diff --git a/third_party/blink/web_tests/wpt_internal/trust-tokens/resources/trust_token_issuance.py b/third_party/blink/web_tests/wpt_internal/trust-tokens/resources/trust_token_issuance.py index 89ca0a3..5dc0024 100644 --- a/third_party/blink/web_tests/wpt_internal/trust-tokens/resources/trust_token_issuance.py +++ b/third_party/blink/web_tests/wpt_internal/trust-tokens/resources/trust_token_issuance.py
@@ -15,9 +15,14 @@ def main(request, response): request_data = request.headers.get("Sec-Trust-Token").decode("utf-8") - issuance_response = tt.issue_trust_token(issuer=issuer, - request_data=request_data, - key_id=0) - - response.headers.set("Sec-Trust-Token", issuance_response.to_string()) - response.status = 200 + try: + issuance_response = tt.issue_trust_token(issuer=issuer, + request_data=request_data, + key_id=0) + response.headers.set("Sec-Trust-Token", issuance_response.to_string()) + response.status = 200 + # Add a response body for the iframe E2E test to read + response.content = "Trust token issuance succeeded." + except Exception: + response.status = 500 + response.content = "Trust token issuance failed."
diff --git a/third_party/blink/web_tests/wpt_internal/trust-tokens/resources/trust_token_redemption.py b/third_party/blink/web_tests/wpt_internal/trust-tokens/resources/trust_token_redemption.py index d430bb1..64c37371 100644 --- a/third_party/blink/web_tests/wpt_internal/trust-tokens/resources/trust_token_redemption.py +++ b/third_party/blink/web_tests/wpt_internal/trust-tokens/resources/trust_token_redemption.py
@@ -20,3 +20,5 @@ response.headers.set("Sec-Trust-Token", redemption_response.to_string()) response.status = 200 + # Add a response body for the iframe E2E test to read + response.content = "Trust token redemption succeeded."
diff --git a/third_party/blink/web_tests/wpt_internal/trust-tokens/resources/trust_token_send_redemption_record.py b/third_party/blink/web_tests/wpt_internal/trust-tokens/resources/trust_token_send_redemption_record.py index facd1479..567ce62 100644 --- a/third_party/blink/web_tests/wpt_internal/trust-tokens/resources/trust_token_send_redemption_record.py +++ b/third_party/blink/web_tests/wpt_internal/trust-tokens/resources/trust_token_send_redemption_record.py
@@ -15,5 +15,9 @@ "utf-8") if redemption_record: response.status = 200 + # Add a response body for the iframe E2E test to read + response.content = "Trust token RR succeeded." else: response.status = 400 + # Add a response body for the iframe E2E test to read + response.content = "Trust token RR failed."
diff --git a/third_party/blink/web_tests/wpt_internal/trust-tokens/trust-token-api-e2e-iframe.https.html b/third_party/blink/web_tests/wpt_internal/trust-tokens/trust-token-api-e2e-iframe.https.html new file mode 100644 index 0000000..1c666fda --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/trust-tokens/trust-token-api-e2e-iframe.https.html
@@ -0,0 +1,65 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Tests trust token issuance and redemption</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> + +<body> + <script> + 'use strict'; + + promise_test(() => { + const frame = document.createElement('iframe'); + frame.src = '/wpt_internal/trust-tokens/resources/trust_token_redemption.py'; + frame.trustToken = JSON.stringify({ type: 'token-redemption' }); + document.body.appendChild(frame); + + return new Promise(resolve => { + frame.addEventListener("error", resolve("iframe raised an error")); + }).then(event => { + assert_equals(event, "iframe raised an error"); + }); + }, 'Trust token redemption using iframes fails without prior issuance.'); + + promise_test(() => { + const frame = document.createElement('iframe'); + frame.src = '/wpt_internal/trust-tokens/resources/trust_token_issuance.py'; + frame.trustToken = JSON.stringify({ type: 'token-request' }); + document.body.appendChild(frame); + + return new Promise(resolve => { + frame.addEventListener("load", resolve); + }).then(event => { + assert_equals(frame.contentWindow.document.body.innerText, 'Trust token issuance succeeded.'); + }); + }, 'Trust token issuance succeeds using iframes.'); + + promise_test(() => { + const frame = document.createElement('iframe'); + frame.src = '/wpt_internal/trust-tokens/resources/trust_token_redemption.py'; + frame.trustToken = JSON.stringify({ type: 'token-redemption' }); + document.body.appendChild(frame); + + return new Promise(resolve => { + frame.addEventListener("load", resolve); + }).then(event => { + assert_equals(frame.contentWindow.document.body.innerText, 'Trust token redemption succeeded.'); + }); + }, 'Trust token redemption succeeds using iframes.'); + + promise_test(() => { + const host_info = get_host_info(); + const frame = document.createElement('iframe'); + frame.src = '/wpt_internal/trust-tokens/resources/trust_token_send_redemption_record.py'; + frame.trustToken = JSON.stringify({ type: 'send-redemption-record', issuers: [host_info.ORIGIN] }); + document.body.appendChild(frame); + + return new Promise(resolve => { + frame.addEventListener("load", resolve); + }).then(event => { + assert_equals(frame.contentWindow.document.body.innerText, 'Trust token RR succeeded.'); + }); + }, 'Trust token RR succeeds using iframes.'); + </script> +</body> \ No newline at end of file
diff --git a/tools/infra/reproduce.py b/tools/infra/reproduce.py deleted file mode 100755 index 60cac7c..0000000 --- a/tools/infra/reproduce.py +++ /dev/null
@@ -1,552 +0,0 @@ -#!/usr/bin/env vpython3 -# Copyright 2019 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -"""Debug chromium builds locally. - -Takes as input a build you want to reproduce locally. - -Will do the following: - * (Optionally) sync to the revision the build ran at - * Build using the GN args used in the build. - * Run a subset of the tests that failed in the build. - -Each command which is executed in the list of steps above will be printed as it -is executed. The script will prompt before running tests and syncing your -checkout. - -Bugs and feature requests should be given as bugs filed via -https://bit.ly/cci-generic-bug. -""" - -import argparse -import base64 -import collections -import json -import os -import platform -import sys -import subprocess -import tempfile -import traceback -from urllib import parse - - -# From vpython -import colorama -import requests - - -CHROMIUM_ROOT = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..', '..')) - -LOGDOG_BASE = 'https://logs.chromium.org/' -# TODO(martiniss): Allow this to be configured, to support internal builds. -TEST_RESULTS_BASE = 'https://test-results.appspot.com/' -BB_API_BASE = 'https://cr-buildbucket.appspot.com/' -CI_PREFIX = 'https://ci.chromium.org/p/chromium/builders/' - - -# Small named tuple for test suite entries in the -# //testing/buildbot/chromium.*.json files. -TestSuiteEntry = collections.namedtuple('TestSuiteEntry', [ - 'name', 'args', 'is_isolated', 'swarming']) - - -# Small named tuple to describe what builders a trybot uses to decide which -# tests to run. -BuilderDep = collections.namedtuple('BuilderDep', [ - 'builder', 'master', 'tester_builder', 'tester_master']) - - -def fetch_step_log(build, step, log): - """Fetches a log from a step in a build.""" - step = step.replace(' ', '_').replace('(', '_').replace(')', '_') - log_path = ( - 'buildbucket/cr-buildbucket.appspot.com/%s' - '/+/steps/%s/0/logs/%s/0' % (build, step, log)) - data = { - 'path': log_path.replace(' ', '_'), - # TODO(martiniss): Get actual project. - 'project': 'chromium', - } - headers = { - 'accept': 'application/json', - } - resp = requests.post( - LOGDOG_BASE + 'prpc/logdog.Logs/Get', json=data, headers=headers) - if resp.status_code != 200: - print('Unexpected status code %d' - ' when requesting build information from logdog' % resp.status_code) - return None - logdog_data = json.loads(resp.text[4:]) - text = "" - for packet in logdog_data['logs']: - for line in packet['text']['lines']: - text += base64.b64decode(line['value']) + line['delimiter'] - return text - - -def run_command(cmd): - """Small utility function to run a command. - - Prints out the command before running. - """ - print(colorama.Fore.RED + '>> RUNNING the following command: <<\n%s%s' % ( - colorama.Style.RESET_ALL, ' '.join(cmd))) - subprocess.check_call(cmd) - - -def guess_host_dimensions(): - """Guesses the approximate swarming dimensions for a host.""" - # For now, just do basic os. Can add later dimensions like gpus, number of - # cores, etc... - host_os = platform.system() - return { - 'os': { - # All the swarming bots are on ubuntu, so just assume that most dev - # machines which run linux would work for bots which run ubuntu, even - # if dev machines are a different distro. - 'linux': 'Ubuntu', - }.get(host_os.lower(), host_os) - } - - -class Build: - """All relevant information for an already executed build. - - The constructor does several HTTP requests to get needed information from - various LUCI services. - """ - def __init__(self, build_address): - # Build address of the build. - self.build_address = parse.unquote_plus(build_address) - assert len(self.build_address.split('/')) == 3, ( - 'Expected build address to look like <bucket>/<builder>/<buildnumber>, ' - 'but got %s' % self.build_address - ) - - - # Dimensions the user has acknowledged are different from the build they're - # trying to debug. Once a user acks that a dimension is different, we - # shouldn't prompt them about it again. - self.acked_dimensions = set() - - # List of failed test suites. - self.failed_suites = [] - - # Mastername of the bot. Needed to find the appropriate //testing/buildbot - # json file. - self._mastername = '' - - # Buildbot id number. Used to fetch data from logdog. - self._bb_id = '' - - # Chromium revision. Used to run `gclient sync`. - self.chromium_revision = '' - - # Patch information. Tuple of (repo url, patch ref). Used in `gclient sync`. - self.patch_info = ('', '') - - # Test results for each failed test. - self._test_results = [] - - # Builders this build is "emulating". Only useful for trybots. Trybots - # emulate a few builders, which means they run the tests those builders run. - # List of BuilderDep objects. - self.emulated_builders = [] - - @property - def builder(self): - return self.build_address.split('/')[1] - - @property - def buildnumber(self): - return self.build_address.split('/')[2] - - @property - def bucket(self): - return self.build_address.split('/')[0] - - @property - def mastername(self): - return self._mastername - - @property - def is_tryjob(self): - return bool(self.patch_info[0]) - - def _fetch_build_info(self): - """Fetch basic build information from buildbucket. - - Returns a tuple of (id, steps in the build, build properties)""" - assert '.' not in self.bucket, ( - 'Expected plain bucket with no \'.\' in it, got %s' % self.bucket) - bb_url = BB_API_BASE + 'prpc/buildbucket.v2.Builds/GetBuild' - data = { - 'builder': { - # TODO(martiniss): Remove this hard coding. - 'project': 'chromium', - 'bucket': self.bucket, - 'builder': self.builder, - }, - 'buildNumber': int(self.buildnumber), - 'fields': 'steps,output.properties,id' - } - headers = { - 'accept': 'application/json', - } - - res = requests.post(bb_url, json=data, headers=headers) - # Remove XSSI header. - resp = json.loads(res.text[4:]) - return ( - resp['id'], - resp['steps'], - resp['output']['properties'], - ) - - def _parse_failed_steps(self, steps): - failures = [ - step for step in steps - if 'tests' in step['name'] and step['status'] != u'SUCCESS' - ] - - if self.is_tryjob: - # Check for suites that were retried with patch. Suites which fail on - # 'with patch' but pass later won't show up this way (because they're - # flaky and shouldn't be re-run probably). - failures = [ - step for step in failures - if '(retry shards with patch)' in step['name'] - ] - - step_names = [] - for f in failures: - for log in f['logs']: - # Just want to check that the step has a step_metadata log in it. - if log['name'] == 'step_metadata': - metadata = json.loads(fetch_step_log( - self._bb_id, f['name'], 'step_metadata')) - if metadata: - step_names.append(metadata['canonical_step_name']) - else: - step_names.append(f['name']) - return step_names - - def _fetch_test_results(self, failed_suites): - results = [] - for suite in failed_suites: - test_results_url = TEST_RESULTS_BASE + 'testfile?%s' % parse.urlencode( - { - 'builder': self.builder, - 'name': 'full_results.json', - 'master': self.mastername, - 'testtype': '%s (with patch)' % suite, - 'buildnumber': self.buildnumber, - }) - data = requests.get(test_results_url).json() - results.append(data) - - return results - - def _parse_test_results(self, results): - test_results = {} - for suite, result in results.iteritems(): - failed = [] - # Need a recursive function to be able to search nested test results - # (blink web tests does this). - def helper(data, prefix=None): - if not prefix: - prefix = () - for test, test_data in data.iteritems(): - if 'expected' in test_data: - # This is a node containing test result information. - if test_data['expected'] != test_data['actual']: - if test_data['actual'].split(' ')[-1] == 'PASS': - continue - # Non blink tests use the test results format, but don't set this - # flag :(. - if (('webkit_layout' in suite or 'blink_web_tests' in suite) - and not test_data.get('is_unexpected')): - continue - failed.append('/'.join(prefix + (test,))) - else: - # This is just a prefix, doesn't contain actual result data. - helper(test_data, prefix + (test,)) - - helper(result['tests']) - test_results[suite] = failed - - return test_results - - def _fetch_build_emulation(self): - """Fetches logdog data about which builders this build emulates.""" - raw_data = fetch_step_log(self._bb_id, 'report_builders', 'bots.json') - if not raw_data: - # Try to guess, this should hopefully work. If it doesn't, something will - # throw an exception, and hopefully the user will file a bug. - return [ - BuilderDep( - self.builder, self.mastername, - self.builder, self.mastername) - ] - data = json.loads(raw_data) - return [ - BuilderDep( - entry['buildername'], entry['mastername'], - entry['tester_buildername'], entry['tester_mastername']) - for entry in data] - - def fetch_all_info(self): - """Fetches info from various LUCI services.""" - # Get basic build info. - bb_id, steps, properties = self._fetch_build_info() - self._bb_id = bb_id - self._mastername = properties['mastername'] - self.chromium_revision = properties.get('got_revision') - self.patch_info = ( - properties.get('patch_repository_url'), - properties.get('patch_ref'), - ) - - self.failed_suites = self._parse_failed_steps(steps) - - self._test_results = self._parse_test_results( - dict(zip(self.failed_suites, - self._fetch_test_results(self.failed_suites)))) - - self.emulated_builders = self._fetch_build_emulation() - - def guess_swarming_dimensions(self, suite): - explicit_dims = self.lookup_suite(suite).swarming.get('dimensions_sets', {}) - if 'os' not in explicit_dims: - # Copied from - # https://cs.chromium.org/chromium/build/scripts/slave/recipe_modules/swarming/api.py?l=422&rcl=181d7618c62947cbfd9941f3d48537c92c955acf - # Also very hacky, as it uses the mastername of the bot as a key. - explicit_dims['os'] = { - 'linux': 'Ubuntu-14.04', - # This is wrong often. Should refine this more. - 'mac': 'Mac-10.13', - 'win': 'Windows-10-15063', - }.get(self.mastername.split('.')[-1], 'Ubuntu-14.04') - - return explicit_dims - - def run_suite(self, suite_name, path): - suite = self.lookup_suite(suite_name) - - # Check that the build they're trying to reproduce is run on approximately - # the same hardware. - swarming_dimensions = self.guess_swarming_dimensions(suite_name) - host_dimensions = guess_host_dimensions() - # TODO(https://crbug.com/929332): Very specialized for os only for now, - # change to be more general. - for dimension in set(['os']) - self.acked_dimensions: - swarming_value = swarming_dimensions[dimension] - host_values = host_dimensions[dimension] - if not swarming_value.startswith(host_values): - print ( - 'You are attempting to run a test suite which requires different' - ' swarming dimensions than your current machine. The test suite' - ' requires a %r value of %r, but we think your host machine has ' - ' values of %r. Do you wish to proceed with running the test? ' - '(y/N)' % ( - dimension, swarming_value, host_values)) - response = input('>> ').lower() - if response != 'y': - print('Not running test suite %s...' % suite_name) - return 1 - self.acked_dimensions.add(dimension) - - cases = self._test_results[suite_name] - - # Blink web tests end with this. - suite_name = suite.name - if suite_name.endswith('_exparchive'): - suite_name = suite_name[:-len('_exparchive')] - cmd = [ - os.path.join(CHROMIUM_ROOT, 'tools', 'mb', 'mb.py'), 'run', '-m', - self.mastername, '-b', self.builder, path, suite.name, '--', - '--%s=%s' % ( - 'isolated-script-test-filter' if - suite.is_isolated else 'gtest_filter', - ('::' if suite.is_isolated else ':').join(cases)), - ] - cmd += suite.args - - temp_filename = None - if suite.is_isolated: - f, name = tempfile.mkstemp() - os.close(f) - temp_filename = name - cmd += ['--isolated-script-test-output', temp_filename] - - try: - run_command(cmd) - finally: - if suite.is_isolated: - os.unlink(temp_filename) - - return 0 - - def checkout_commands(self): - cmd = [ - 'gclient', - 'sync', - '-r', 'src@%s' % self.chromium_revision, - ] - if self.patch_info: - cmd.extend([ - '--patch-ref', - '@'.join(self.patch_info) - ]) - yield cmd - - def ensure_checkout(self): - for cmd in self.checkout_commands(): - run_command(cmd) - - def lookup_suite(self, suite_name): - """Looks up information about a suite from json files in chromium src. - - Returns: A list of TestSuiteEntry objects. - """ - found = [] - - for entry in self.emulated_builders: - with open(os.path.join( - CHROMIUM_ROOT, 'testing', 'buildbot', - '%s.json' % entry.tester_master)) as f: - data = json.load(f) - for file_buildername, builder_data in data.iteritems(): - if entry.tester_builder == file_buildername: - for gtest in builder_data.get('gtest_tests', {}): - name = gtest.get('name', gtest['test']) - if name == suite_name: - found.append(TestSuiteEntry( - gtest['test'], - gtest.get('args', []), - False, - gtest.get('swarming', {}), - )) - for isolated_script in builder_data.get('isolated_scripts', {}): - if isolated_script['name'] == suite_name: - found.append(TestSuiteEntry( - isolated_script['isolate_name'], - isolated_script.get('args', []), - True, - isolated_script.get('swarming', {}), - )) - break - - if not found: - raise Exception('Suite %s not found in //testing/buildbot files' % ( - suite_name)) - if len(found) > 1: - raise Exception('Suite %s found in multiple builder definitions.' % ( - suite_name)) - return found[0] - - -def main(): - parser = argparse.ArgumentParser( - description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) - - parser.add_argument('build_url', - help='the URL of a build you want to debug locally. ' - 'Usually something like ' - '%sluci.chromium.try/linux-rel/265964.' % CI_PREFIX) - parser.add_argument('path', nargs='?', default='//out/Default', - help='path to output directory to build. Default is ' - '%(default)s.') - parser.add_argument('-s', '--sync-checkout', action='store_true', - help='attempts to emulate the chromium checkout in the ' - 'build to reproduce. Does this by calling `gclient sync`') - parser.add_argument('-n', '--no-run-tests', action='store_false', - dest='run_tests', help='don\'t run any tests. Useful if ' - 'you just want to see what failed, or just want to sync ' - 'your checkout to match a failed build.') - args = parser.parse_args() - - if not args.build_url.startswith(CI_PREFIX): - raise Exception('Invalid build URL %s. Expected it to start with %s' % ( - args.build_url, CI_PREFIX)) - build_address = args.build_url[len(CI_PREFIX):] - print('Fetching build information...') - build = Build(build_address) - build.fetch_all_info() - - if args.sync_checkout: - print('The build you are attempting to debug is a %s.' % ( - 'tryjob' if build.is_tryjob else 'continuous build')) - print('The build checked out revision %s%s.' % ( - build.chromium_revision, - ' and applied the patch https://crrev.com/c/%s' % ( - '/'.join(build.patch_info[1].split('/')[3:]) - if build.is_tryjob else ''))) - # TODO(martiniss): Consider validating the user's gclient config. - print( - 'This script can attempt to reproduce the chromium checkout the build ' - 'executed with. It would do so by running the following commands:') - print() - for cmd in build.checkout_commands(): - print(' '.join(cmd)) - print() - - print('Would you like this script to run these commands? (Y/n)') - response = input('>> ').lower().strip() - if response in ('y', ''): - build.ensure_checkout() - else: - print('Using your existing checkout.') - - if not args.run_tests: - return 0 - - print('Found the following failed test suites for this build:') - for i, suite in enumerate(build.failed_suites, start=1): - print(' %s. %s' % (i, suite)) - print('Commands are:') - for cmd in ( - '1,2....n to run that specific test suite.', - 'A to run all the test suites', - 'Q to quit', - ): - print(' ' + cmd) - print('What would you like to do?') - - response = input('>> ').lower() - - try: - num = int(response) - - # Subtract one, since the suites start with an index of 1. - suite = build.failed_suites[num-1] - build.run_suite(suite, args.path) - return 0 - except ValueError: - # If the response isn't a number, just assume it was another command. - pass - - if response == 'a': - for failed_suite in build.failed_suites: - build.run_suite(failed_suite, args.path) - - if response != 'q': - print('Unrecognized command "%s"'% response) - - print('Exiting...') - return 0 - - -if __name__ == '__main__': - try: - sys.exit(main()) - except Exception: - traceback.print_exc() - print() - print() - print('If this exception is unexpected, please file a bug via ' - 'https://bit.ly/cci-generic-bug.') - sys.exit(1)
diff --git a/tools/infra/reproduce_unittest.py b/tools/infra/reproduce_unittest.py deleted file mode 100755 index afe6bba..0000000 --- a/tools/infra/reproduce_unittest.py +++ /dev/null
@@ -1,244 +0,0 @@ -#!/usr/bin/env vpython3 -# Copyright 2019 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Tests for reproduce.py""" -import json -import os -import unittest - -import reproduce - -# From vpython -import mock - - -class ReproduceTest(unittest.TestCase): - - @mock.patch('reproduce.fetch_step_log') - def test_parse_failed_steps_ci_build(self, fetch_log_mock): - b = reproduce.Build('ci/linux-rel/123') - b.patch_info = (False,) - fetch_log_mock.side_effect = [ - json.dumps({ - 'canonical_step_name': 'gl_unittests' - }) - ] - self.assertEqual( - b._parse_failed_steps([{ - 'name': 'bot update', - 'status': 'FAILURE', - }, { - 'name': 'base_unittests', - 'status': 'SUCCESS', - 'logs': [{ - 'name': 'step_metadata', - }], - }, { - 'name': 'gl_unittests', - 'status': 'FAILURE', - 'logs': [{ - 'name': 'step_metadata', - }], - }]), - ['gl_unittests']) - - @mock.patch('reproduce.fetch_step_log') - def test_parse_failed_steps_try_build(self, fetch_log_mock): - b = reproduce.Build('ci/linux-rel/123') - b.patch_info = (True,) - fetch_log_mock.side_effect = [ - json.dumps({ - 'canonical_step_name': 'gl_unittests' - }) - ] - self.assertEqual( - b._parse_failed_steps([{ - 'name': 'bot update', - 'status': 'FAILURE', - }, { - 'name': 'base_unittests (with patch)', - 'status': 'FAILURE', - 'logs': [{ - 'name': 'step_metadata', - }], - }, { - 'name': 'gl_unittests (with patch)', - 'status': 'FAILURE', - 'logs': [{ - 'name': 'step_metadata', - }], - }, { - 'name': 'base_unittests (retry shards with patch)', - 'status': 'SUCCESS', - 'logs': [{ - 'name': 'step_metadata', - }], - }, { - 'name': 'gl_unittests (retry shards with patch)', - 'status': 'FAILURE', - 'logs': [{ - 'name': 'step_metadata', - }], - }]), - ['gl_unittests']) - - @mock.patch('builtins.print') - @mock.patch('reproduce.guess_host_dimensions') - @mock.patch('builtins.input') - @mock.patch('reproduce.run_command') - def test_run_suite_gtest(self, run_mock, input_mock, guess_mock, print_mock): - # Just want to mock this so if something weird happens with the test it - # doesn't block for input. - del input_mock, print_mock - - guess_mock.side_effect = [{ - 'os': 'Windows', - }] - b = reproduce.Build('luci.chromium.ci/linux-rel/1') - b._mastername = 'chromium.linux' - b._test_results = { - 'gl_unittests': ['test.1', 'test.2'] - } - with mock.patch.object(b, 'guess_swarming_dimensions') as dims_mock: - dims_mock.side_effect = [{ - 'os': 'Windows', - }] - with mock.patch.object(b, 'lookup_suite') as lookup_mock: - entry = reproduce.TestSuiteEntry( - 'gl_unittests', - [], - False, - {} - ) - lookup_mock.side_effect = [entry] - b.run_suite('gl_unittests', '//out/Default') - - run_mock.assert_called_with([ - os.path.join(reproduce.CHROMIUM_ROOT, 'tools', 'mb', 'mb.py'), - 'run', '-m', 'chromium.linux', '-b', 'linux-rel', '//out/Default', - 'gl_unittests', '--', '--gtest_filter=test.1:test.2' - ]) - - @mock.patch('builtins.print') - @mock.patch('reproduce.guess_host_dimensions') - @mock.patch('builtins.input') - @mock.patch('reproduce.run_command') - def test_run_suite_isolated_script(self, run_mock, input_mock, guess_mock, - print_mock): - # Just want to mock this so if something weird happens with the test it - # doesn't block for input. - del input_mock, print_mock - - guess_mock.side_effect = [{ - 'os': 'Windows', - }] - b = reproduce.Build('luci.chromium.ci/linux-rel/1') - b._mastername = 'chromium.mac' - b._test_results = { - 'blink_web_tests': ['test.1', 'test.2'] - } - fake_tempfile_name = '/tmp/foobartmp' - with mock.patch.object(b, 'guess_swarming_dimensions') as dims_mock: - dims_mock.side_effect = [{ - 'os': 'Windows', - }] - with mock.patch('reproduce.os.unlink') as unlink_mock: - with mock.patch.object(b, 'lookup_suite') as lookup_mock: - entry = reproduce.TestSuiteEntry( - 'blink_web_tests', - [], - True, - {} - ) - lookup_mock.side_effect = [entry] - with mock.patch('reproduce.tempfile.mkstemp') as temp_mock: - # The script tries to close the file handler to the temp file when - # it creates it. Mock that out. - with mock.patch('reproduce.os.close'): - temp_mock.side_effect = [(5, fake_tempfile_name)] - b.run_suite('blink_web_tests', '//out/Default') - - unlink_mock.assert_called_with(fake_tempfile_name) - run_mock.assert_called_with([ - os.path.join(reproduce.CHROMIUM_ROOT, 'tools', 'mb', 'mb.py'), - 'run', '-m', 'chromium.mac', '-b', 'linux-rel', '//out/Default', - 'blink_web_tests', '--', - '--isolated-script-test-filter=test.1::test.2', - '--isolated-script-test-output', fake_tempfile_name, - ]) - - @mock.patch('builtins.print') - @mock.patch('reproduce.guess_host_dimensions') - @mock.patch('builtins.input') - @mock.patch('reproduce.run_command') - def test_run_suite_dimension_prompt(self, run_mock, input_mock, guess_mock, - print_mock): - guess_mock.side_effect = [{ - 'os': 'Windows', - }] - - b = reproduce.Build('luci.chromium.ci/linux-rel/1') - input_mock.side_effect = ['n'] - with mock.patch.object(b, 'guess_swarming_dimensions') as dims_mock: - dims_mock.side_effect = [{ - 'os': 'Linux', - }] - with mock.patch.object(b, 'lookup_suite') as lookup_mock: - entry = reproduce.TestSuiteEntry( - 'blink_web_tests', - [], - True, - {} - ) - lookup_mock.side_effect = [entry] - result = b.run_suite('blink_web_tests', '//out/Default') - self.assertEqual(result, 1) - input_mock.assert_called_with('>> ') - self.assertEqual(print_mock.call_count, 2) - run_mock.assert_not_called() - - @mock.patch('builtins.print') - @mock.patch('reproduce.guess_host_dimensions') - @mock.patch('builtins.input') - @mock.patch('reproduce.run_command') - def test_run_suite_already_prompted(self, run_mock, input_mock, guess_mock, - print_mock): - """Makes sure that the script remembers dimension warning bypassing.""" - # Just want to mock these so if something weird happens with the test it - # doesn't block for input. - del input_mock, print_mock - - guess_mock.side_effect = [{ - 'os': 'Windows', - }] - - b = reproduce.Build('luci.chromium.ci/linux-rel/1') - b._mastername = 'chromium.linux' - b._test_results = { - 'gl_unittests': ['test.1', 'test.2'] - } - b.acked_dimensions.add('os') - with mock.patch.object(b, 'guess_swarming_dimensions') as dims_mock: - dims_mock.side_effect = [{ - 'os': 'Linux', - }] - with mock.patch.object(b, 'lookup_suite') as lookup_mock: - entry = reproduce.TestSuiteEntry( - 'gl_unittests', - [], - False, - {} - ) - lookup_mock.side_effect = [entry] - b.run_suite('gl_unittests', '//out/Default') - - run_mock.assert_called_with([ - os.path.join(reproduce.CHROMIUM_ROOT, 'tools', 'mb', 'mb.py'), - 'run', '-m', 'chromium.linux', '-b', 'linux-rel', '//out/Default', - 'gl_unittests', '--', '--gtest_filter=test.1:test.2' - ]) - -if __name__ == '__main__': - unittest.main()
diff --git a/tools/ipc_fuzzer/fuzzer/fuzzer.cc b/tools/ipc_fuzzer/fuzzer/fuzzer.cc index 804d30d..506c5bd 100644 --- a/tools/ipc_fuzzer/fuzzer/fuzzer.cc +++ b/tools/ipc_fuzzer/fuzzer/fuzzer.cc
@@ -639,15 +639,6 @@ }; template <> -struct FuzzTraits<viz::ResourceFormat> { - static bool Fuzz(viz::ResourceFormat* p, Fuzzer* fuzzer) { - int format = RandInRange(viz::ResourceFormat::RESOURCE_FORMAT_MAX + 1); - *p = static_cast<viz::ResourceFormat>(format); - return true; - } -}; - -template <> struct FuzzTraits<blink::PageState> { static bool Fuzz(blink::PageState* p, Fuzzer* fuzzer) { std::string data = p->ToEncodedData(); @@ -801,19 +792,6 @@ }; template <> -struct FuzzTraits<gfx::PresentationFeedback> { - static bool Fuzz(gfx::PresentationFeedback* p, Fuzzer* fuzzer) { - if (!FuzzParam(&p->timestamp, fuzzer)) - return false; - if (!FuzzParam(&p->interval, fuzzer)) - return false; - if (!FuzzParam(&p->flags, fuzzer)) - return false; - return true; - } -}; - -template <> struct FuzzTraits<gfx::Rect> { static bool Fuzz(gfx::Rect* p, Fuzzer* fuzzer) { gfx::Point origin = p->origin(); @@ -1085,16 +1063,6 @@ }; template <> -struct FuzzTraits<gpu::SchedulingPriority> { - static bool Fuzz(gpu::SchedulingPriority* p, Fuzzer* fuzzer) { - int priority = - RandInRange(static_cast<int>(gpu::SchedulingPriority::kLast) + 1); - *p = static_cast<gpu::SchedulingPriority>(priority); - return true; - } -}; - -template <> struct FuzzTraits<gpu::SwapBuffersCompleteParams> { static bool Fuzz(gpu::SwapBuffersCompleteParams* p, Fuzzer* fuzzer) { if (!FuzzParam(&p->swap_response, fuzzer))
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 883d1ba..4728c74c 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -274,6 +274,7 @@ 'fuchsia-fyi-x64-asan': 'asan_lsan_bot_fuchsia', 'fuchsia-fyi-x64-dbg': 'debug_bot_fuchsia', 'fuchsia-x64-chrome-rel': 'release_bot_fuchsia_cfv2_script_chrome', + 'fuchsia-x64-workstation': 'release_bot_fuchsia_workstation', }, 'chromium.fuzz': { @@ -401,7 +402,6 @@ 'fuchsia-code-coverage': 'fuchsia_clang_code_coverage', 'fuchsia-fyi-arm64-cfv2-script': 'release_bot_fuchsia_cfv2_script_arm64', 'fuchsia-fyi-cfv2-script': 'release_bot_fuchsia_cfv2_script', - 'fuchsia-fyi-x64-wst': 'fuchsia_workstation_bot', 'ios-fieldtrial-rel': 'ios_simulator_debug_static_bot_xctest_arm64', 'ios-m1-simulator': 'ios_simulator_debug_static_bot_xctest_arm64', 'ios-m1-simulator-cronet': 'ios_cronet_xctest_arm64', @@ -1138,6 +1138,7 @@ 'fuchsia-x64-cast-receiver-rel': 'release_trybot_fuchsia_cast_receiver', 'fuchsia-x64-chrome-rel': 'release_trybot_fuchsia_cfv2_script_chrome', 'fuchsia-x64-rel': 'release_trybot_fuchsia', + 'fuchsia-x64-workstation': 'release_trybot_fuchsia_workstation', # TODO(crbug.com/1294938): Remove this bot after the transition. 'fuchsia_arm64': 'release_trybot_fuchsia_arm64', # TODO(crbug.com/1294938): Remove this bot after the transition. @@ -2566,11 +2567,6 @@ 'official_optimize_goma_trybot', 'fuchsia', ], - 'fuchsia_workstation_bot': [ - 'release_bot', 'fuchsia', 'fuchsia_include_workstation_image', - 'fuchsia_chrome' - ], - 'gn_linux_upload': [ 'gn_linux_upload', 'official', 'goma', ], @@ -3467,6 +3463,11 @@ 'release_bot', 'fuchsia', 'fuchsia_cfv2_script', 'fuchsia_chrome', ], + 'release_bot_fuchsia_workstation': [ + 'release_bot', 'fuchsia', 'fuchsia_include_workstation_image', + 'fuchsia_chrome' + ], + 'release_bot_mac_strip_minimal_symbols': [ 'release_bot', 'mac_strip', 'minimal_symbols', ], @@ -3612,6 +3613,11 @@ 'release_trybot', 'fuchsia', 'fuchsia_cfv2_script', 'fuchsia_chrome', ], + 'release_trybot_fuchsia_workstation': [ + 'release_trybot', 'fuchsia', 'fuchsia_include_workstation_image', + 'fuchsia_chrome' + ], + 'release_trybot_minimal_symbols_reclient': [ 'release_trybot_minimal_symbols_reclient', ],
diff --git a/tools/mb/mb_config_expectations/chromium.fuchsia.fyi.json b/tools/mb/mb_config_expectations/chromium.fuchsia.fyi.json index e181ea4..61d7325 100644 --- a/tools/mb/mb_config_expectations/chromium.fuchsia.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.fuchsia.fyi.json
@@ -51,5 +51,18 @@ "use_cfv2_script": true, "use_goma": true } + }, + "fuchsia-x64-workstation": { + "gn_args": { + "dcheck_always_on": false, + "fuchsia_additional_boot_images": [ + "//third_party/fuchsia-sdk/images/qemu-x64-release/" + ], + "fuchsia_browser_type": "chrome", + "is_component_build": false, + "is_debug": false, + "target_os": "fuchsia", + "use_goma": true + } } } \ No newline at end of file
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json index 0165108f..61c4f24 100644 --- a/tools/mb/mb_config_expectations/chromium.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -809,19 +809,6 @@ "use_goma": true } }, - "fuchsia-fyi-x64-wst": { - "gn_args": { - "dcheck_always_on": false, - "fuchsia_additional_boot_images": [ - "//third_party/fuchsia-sdk/images/qemu-x64-release/" - ], - "fuchsia_browser_type": "chrome", - "is_component_build": false, - "is_debug": false, - "target_os": "fuchsia", - "use_goma": true - } - }, "ios-fieldtrial-rel": { "gn_args": { "enable_run_ios_unittests_with_xctest": true,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.fuchsia.json b/tools/mb/mb_config_expectations/tryserver.chromium.fuchsia.json index f263926..79b250a 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.fuchsia.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.fuchsia.json
@@ -141,6 +141,20 @@ "use_goma": true } }, + "fuchsia-x64-workstation": { + "gn_args": { + "dcheck_always_on": true, + "fuchsia_additional_boot_images": [ + "//third_party/fuchsia-sdk/images/qemu-x64-release/" + ], + "fuchsia_browser_type": "chrome", + "is_component_build": false, + "is_debug": false, + "symbol_level": 0, + "target_os": "fuchsia", + "use_goma": true + } + }, "fuchsia_arm64": { "gn_args": { "dcheck_always_on": true,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 148e038..66431d8c 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -10926,6 +10926,13 @@ <int value="1" label="Dismissed bubble"/> </enum> +<enum name="BatterySaverModeState"> + <int value="0" label="Disabled"/> + <int value="1" label="Enabled below threshold"/> + <int value="2" label="Enabled on battery"/> + <int value="3" label="Enabled"/> +</enum> + <enum name="BatteryStatusNumberBatteries"> <obsolete> Removed 2021-08-11. https://crbug.com/1165237 @@ -27766,6 +27773,26 @@ <int value="5" label="Empty local path"/> </enum> +<enum name="DownloadCommand"> + <int value="1" label="Show in folder"/> + <int value="2" label="Open when complete"/> + <int value="3" label="Always open type"/> + <int value="4" label="Platform open"/> + <int value="5" label="Cancel"/> + <int value="6" label="Pause"/> + <int value="7" label="Resume"/> + <int value="8" label="Discard"/> + <int value="9" label="Keep"/> + <int value="10" label="Learn more scanning"/> + <int value="11" label="Learn more interrupted"/> + <int value="12" label="Learn more mixed content"/> + <int value="13" label="Copy to clipboard"/> + <int value="14" label="Deep scan"/> + <int value="15" label="Bypass deep scanning"/> + <int value="16" label="Review"/> + <int value="17" label="Retry"/> +</enum> + <enum name="DownloadConnectionSecurity"> <int value="0" label="Final download url and the redirects before it all use https"/> @@ -28683,6 +28710,13 @@ <int value="4" label="START_STICKY"/> </enum> +<enum name="DownloadNotPreferredOpeningInBrowserReason"> + <int value="0" label="TOTAL_DOWNLOAD_CHECKED"/> + <int value="1" label="DOWNLOAD_PATH_EMPTY"/> + <int value="2" label="NOT_PREFERRED_IN_DELEGATE"/> + <int value="3" label="CANNOT_BE_HANDLED_SAFELY"/> +</enum> + <enum name="DownloadOpenMethod"> <int value="0" label="Opened with plaform handler by default"/> <int value="1" label="Opened in browser by default"/> @@ -48436,6 +48470,12 @@ <int value="1" label="Dismiss dialog"/> </enum> +<enum name="HighEfficiencyModeExceptionListAction"> + <int value="0" label="Add"/> + <int value="1" label="Edit"/> + <int value="2" label="Remove"/> +</enum> + <enum name="HintCacheStoreEntryType"> <summary> Possible store entry types contained within the HintCacheStore. @@ -52504,6 +52544,13 @@ <int value="1" label="Home Screen Widget"/> <int value="2" label="New Tab Page"/> <int value="3" label="Omnibox Keyboard"/> + <int value="4" label="Spotlight"/> + <int value="5" label="Omnibox Post Capture"> + Lens was triggered via the "Search Copied Image" Omnibox entry + point. + </int> + <int value="6" label="Image Share Menu"/> + <int value="7" label="App Icon Long Press"/> </enum> <enum name="IOSLensSupportStatus"> @@ -59213,7 +59260,6 @@ <int value="-617851128" label="ForceGpuMainThreadToNormalPriorityDrDc:enabled"/> <int value="-617452890" label="media-router"/> - <int value="-617378214" label="private-aggregation-debug-mode"/> <int value="-616818899" label="SameSiteByDefaultCookies:enabled"/> <int value="-616508634" label="DisableCryptAuthV1DeviceSync:enabled"/> <int value="-615974325" label="ArcMouseWheelSmoothScroll:disabled"/> @@ -59480,6 +59526,7 @@ <int value="-455413094" label="FilesJsModules:enabled"/> <int value="-455203267" label="use_new_features_summary"/> <int value="-454362199" label="HelpAppV2:disabled"/> + <int value="-451898735" label="private-aggregation-developer-mode"/> <int value="-450976085" label="AutofillSaveCreditCardUsesImprovedMessaging:disabled"/> <int value="-450917820" label="EnableCbdSignOut:enabled"/> @@ -61437,6 +61484,7 @@ <int value="741760108" label="SidePanelPrototype:enabled"/> <int value="742083923" label="MimeHandlerViewInCrossProcessFrame:disabled"/> <int value="742363749" label="OSKResizesVisualViewportByDefault:disabled"/> + <int value="742797916" label="TabStripRedesign:disabled"/> <int value="743714331" label="HelpAppLauncherSearch:enabled"/> <int value="744342941" label="SafetyCheckChromeCleanerChild:enabled"/> <int value="745541471" label="PaintHolding:disabled"/> @@ -61691,6 +61739,7 @@ label="ThreadedScrollPreventRenderingStarvation:enabled"/> <int value="896506516" label="enable-canvas-context-lost-in-background (obsolete)"/> + <int value="897695337" label="TabStripRedesign:enabled"/> <int value="898311758" label="ReaderMode:disabled"/> <int value="899347105" label="NearbySharingWifiLan:enabled"/> <int value="900614020" label="ContentSuggestionsShowSummary:disabled"/> @@ -61923,6 +61972,7 @@ <int value="1044928476" label="AllowDownloadResumptionWithoutStrongValidators:enabled"/> <int value="1045152062" label="SecurePaymentConfirmationBrowser:enabled"/> + <int value="1045179357" label="NtpRealboxLensSearch:disabled"/> <int value="1046786976" label="RgbKeyboard:disabled"/> <int value="1046878091" label="PasswordForceSaving:enabled"/> <int value="1046981538" label="OfflinePagesShowAlternateDinoPage:disabled"/> @@ -63398,6 +63448,7 @@ <int value="1949908940" label="disable-zip-archiver-unpacker"/> <int value="1949996482" label="CSSColorSchemeUARendering:disabled"/> <int value="1950191981" label="OverlayNewLayout:enabled"/> + <int value="1950930453" label="NtpRealboxLensSearch:enabled"/> <int value="1951466218" label="enable-data-reduction-proxy-lite-page"/> <int value="1951645673" label="PasswordsKeyboardAccessory:disabled"/> <int value="1952339754"
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml index 80f0857..9b79ae4 100644 --- a/tools/metrics/histograms/metadata/blink/histograms.xml +++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -850,7 +850,7 @@ </summary> </histogram> -<histogram name="Blink.EffectiveZoom" units="%" expires_after="2022-11-23"> +<histogram name="Blink.EffectiveZoom" units="%" expires_after="2023-11-23"> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml index 0c42b333..d8e3981 100644 --- a/tools/metrics/histograms/metadata/compositing/histograms.xml +++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -711,6 +711,18 @@ </summary> </histogram> +<histogram name="Compositing.SkiaRenderer.DirectlyDrawableRenderPassWithRPDQ" + units="boolean" expires_after="2023-04-01"> + <owner>khushalsagar@chromium.org</owner> + <owner>vmpstr@chromium.org</owner> + <owner>graphics-dev@chromium.org</owner> + <summary> + Logged for every nested RenderPass to indicate whether it could have been + drawn directly because it has a single RPDQ and no other effect which would + require producing a render pass. + </summary> +</histogram> + <histogram name="Compositing.SkiaRenderer.DrawTileDrawQuad.CDT.IsTranslateOnly" units="boolean" expires_after="2022-12-04"> <owner>penghuang@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/download/histograms.xml b/tools/metrics/histograms/metadata/download/histograms.xml index 5a45b78e..80f6834 100644 --- a/tools/metrics/histograms/metadata/download/histograms.xml +++ b/tools/metrics/histograms/metadata/download/histograms.xml
@@ -119,6 +119,20 @@ </summary> </histogram> +<histogram name="Download.Bubble.ProcessedCommand" enum="DownloadCommand" + expires_after="2023-01-07"> + <owner>xinghuilu@chromium.org</owner> + <owner>chrome-counter-abuse-alerts@google.com</owner> + <summary> + Records each time a download command is executed on download bubble. For V1, + it is logged when the main button is clicked. For V2, it is logged when the + quick action is clicked. Actions on the security subpage is also included. + Actions on context menu are excluded. Clicking the trasparent button is also + excluded. This histogram is added for debugging purpose and will be removed + afterwards. + </summary> +</histogram> + <histogram name="Download.Bubble.Subpage.{DownloadDangerTypeString}.{ButtonType}ButtonActionTime" units="ms" expires_after="2023-03-07"> @@ -186,6 +200,30 @@ <summary>Records why the download is canceled.</summary> </histogram> +<histogram name="Download.Complete.IsOpenWhenCompleteSet" enum="BooleanSet" + expires_after="2023-01-07"> + <owner>xinghuilu@chromium.org</owner> + <owner>chrome-counter-abuse-alerts@google.com</owner> + <summary> + Records each time a non-temporary download is completed. If it is set to + true, this download will open immediately. This can happen if the user has + clicked the open button before the download is completed. This histogram is + added for debugging purpose and will be removed afterwards. + </summary> +</histogram> + +<histogram name="Download.Complete.IsShouldOpenFileBasedOnExtensionSet" + enum="BooleanSet" expires_after="2023-01-07"> + <owner>xinghuilu@chromium.org</owner> + <owner>chrome-counter-abuse-alerts@google.com</owner> + <summary> + Records each time a non-temporary download is completed. If it is set to + true, this download will open immediately. This can happen if the user has + set auto open for this file type. This histogram is added for debugging + purpose and will be removed afterwards. + </summary> +</histogram> + <histogram name="Download.ContentType.Audio" enum="DownloadAudioType" expires_after="never"> <!-- expires-never: Monitors download system health. --> @@ -720,6 +758,21 @@ </summary> </histogram> +<histogram name="Download.NotPreferredOpeningInBrowserReasons" + enum="DownloadNotPreferredOpeningInBrowserReason" + expires_after="2023-01-07"> + <owner>xinghuilu@chromium.org</owner> + <owner>chrome-counter-abuse-alerts@google.com</owner> + <summary> + Records each time when determining whether the download should be opened in + browser. For new download, it is logged when determining download target. + For old download, it is logged when the download is going to open or the + context menu is going to show. Logged at most one time for each download. + This histogram is added for debugging purpose and will be removed + afterwards. + </summary> +</histogram> + <histogram name="Download.Open.ContentType" enum="DownloadContentType" expires_after="2023-03-26"> <owner>bhatiarohit@google.com</owner> @@ -731,6 +784,22 @@ </summary> </histogram> +<histogram name="Download.OpenButtonPressed.IsDownloadCompleted" + enum="BooleanCompleted" expires_after="2023-01-07"> + <owner>xinghuilu@chromium.org</owner> + <owner>chrome-counter-abuse-alerts@google.com</owner> + <summary> + Records each time a download open button is pressed, either on download + shelf or download bubble. If the open button is pressed before the download + is completed, the download will be auto opened when it is completed. If the + open button is pressed when the download is already completed, the download + will open immediately, either in browser or in system handler. The total + count of this histogram is useful to compare whether download bubble has + changed user behavior on clicking the open button. This histogram is added + for debugging purpose and will be removed afterwards. + </summary> +</histogram> + <histogram name="Download.OpenDownloads.PerProfileType" enum="BrowserProfileType" expires_after="2023-02-12"> <owner>sideyilmaz@chromium.org</owner> @@ -767,6 +836,26 @@ </summary> </histogram> +<histogram name="Download.OpenMethod.{DownloadContent}" + enum="DownloadOpenMethod" expires_after="2023-01-06"> + <owner>xinghuilu@chromium.org</owner> + <owner>chrome-counter-abuse-alerts@google.com</owner> + <summary> + Invocation count for methods of opening a {DownloadContent} download. For + some file types, Chrome defaults to opening the file in the browser instead + of invoking the system handler. The user has the option of overriding this + behavior. This histogram is added for debugging purpose and will be removed + after it is done. + </summary> + <token key="DownloadContent"> + <variant name="DOCUMENT" summary="document"/> + <variant name="PDF" summary="pdf"/> + <variant name="SPREADSHEET" summary="spreadsheet"/> + <variant name="TEXT" summary="text"/> + <variant name="UNRECOGNIZED" summary="unrecognized"/> + </token> +</histogram> + <histogram name="Download.OpensOutstanding" units="units" expires_after="M77"> <owner>dtrainor@chromium.org</owner> <summary>The number of unopened downloads, when one is opened.</summary> @@ -1179,6 +1268,19 @@ </summary> </histogram> +<histogram name="Download.SetAlwaysOpenTo" enum="BooleanEnabled" + expires_after="2023-01-07"> + <owner>xinghuilu@chromium.org</owner> + <owner>chrome-counter-abuse-alerts@google.com</owner> + <summary> + Records each time the auto open setting is changed by the user. If it is set + to true, this type of download will be auto opened once it is completed. + This setting is false by default. Changes on this setting are preserved + across startup. This histogram is added for debugging purpose and will be + removed afterwards. + </summary> +</histogram> + <histogram name="Download.Shelf.DragEvent" enum="Download.Shelf.DragEvent" expires_after="M77"> <obsolete>
diff --git a/tools/metrics/histograms/metadata/network/histograms.xml b/tools/metrics/histograms/metadata/network/histograms.xml index 32eb1df..fd197af 100644 --- a/tools/metrics/histograms/metadata/network/histograms.xml +++ b/tools/metrics/histograms/metadata/network/histograms.xml
@@ -336,6 +336,23 @@ </summary> </histogram> +<histogram name="Network.Cellular.ESim.Installation.NonUserErrorSuccessRate" + enum="HermesResponseStatus" expires_after="2023-07-30"> + <owner>nikhilcn@chromium.org</owner> + <owner>hsuregan@chromium.org</owner> + <owner>cros-connectivity@google.com</owner> + <summary> + This metric is emitted when user attempts to install an eSIM profile. We + record all hermes response status codes that are within our control. User + and Carrier related errors such as invalid qr code, malformed carrier + response are omitted. This will be used to measure the success rate of + installing an eSIM profile when the input is valid and external dependencies + are operating without errors. + + Emitted once the operation completes. + </summary> +</histogram> + <histogram name="Network.Cellular.ESim.InstallationResult" enum="NetworkCellularESimInstallResult" expires_after="2023-04-09"> <owner>azeemarshad@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/performance_controls/histograms.xml b/tools/metrics/histograms/metadata/performance_controls/histograms.xml index 2eb449ae..3e9fa7a 100644 --- a/tools/metrics/histograms/metadata/performance_controls/histograms.xml +++ b/tools/metrics/histograms/metadata/performance_controls/histograms.xml
@@ -40,6 +40,17 @@ </summary> </histogram> +<histogram name="PerformanceControls.BatterySaver.SettingsChangeMode" + enum="BatterySaverModeState" expires_after="2023-03-01"> + <owner>charlesmeng@chromium.org</owner> + <owner>chrome-performance-ui-sea@google.com</owner> + <summary> + Logs the state of the battery saver mode pref when the user makes a change + to it through the settings page. This will be used to measure the + discoverability and usefulness of battery saver mode. + </summary> +</histogram> + <histogram name="PerformanceControls.HighEfficiency.BubbleAction" enum="HighEfficiencyBubbleActionType" expires_after="2023-03-01"> <owner>agale@chromium.org</owner> @@ -76,6 +87,30 @@ </summary> </histogram> +<histogram + name="PerformanceControls.HighEfficiency.SettingsChangeExceptionList" + enum="HighEfficiencyModeExceptionListAction" expires_after="2023-03-01"> + <owner>charlesmeng@chromium.org</owner> + <owner>chrome-performance-ui-sea@google.com</owner> + <summary> + Logs whether the user did an add, edit, or remove operation to the tab + discard exception list for high efficiency mode. This will be used to better + understand how users interact with the list, and to see if we need to + improve our heuristics for tab discarding. + </summary> +</histogram> + +<histogram name="PerformanceControls.HighEfficiency.SettingsChangeMode" + enum="BooleanEnabled" expires_after="2023-03-01"> + <owner>charlesmeng@chromium.org</owner> + <owner>chrome-performance-ui-sea@google.com</owner> + <summary> + Logs whether the user enabled or disabled the high efficiency mode pref when + it is changed through the settings page. This will be used to measure the + discoverability and usefulness of high efficiency mode. + </summary> +</histogram> + </histograms> </histogram-configuration>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index d7503b6..b82771b03 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -13,16 +13,16 @@ "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell" }, "mac": { - "hash": "f9c31955850dd33c34465b1847392f8d611aa920", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/89bf20dcc1e738cf572ecc96d7b2fcba19e61207/trace_processor_shell" + "hash": "ccf649ab59c48f142e3c32f983440973c32e861f", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/c356fc671b3cbf3b3f4f1ba332ed6005c9d3f78b/trace_processor_shell" }, "mac_arm64": { "hash": "e1ad4861384b06d911a65f035317914b8cc975c6", "full_remote_path": "perfetto-luci-artifacts/v25.0/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "72ad81fa2846d49d2b9f232f23cdb6e515d14852", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/c356fc671b3cbf3b3f4f1ba332ed6005c9d3f78b/trace_processor_shell" + "hash": "6006cedac850c9f14c1e4ab18d032731afcde121", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/4fcf7d61f3559fdb37fefda36e272f05e40f0fef/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/perf/core/upload_results_to_perf_dashboard.py b/tools/perf/core/upload_results_to_perf_dashboard.py index 038b182d..448dc96d 100755 --- a/tools/perf/core/upload_results_to_perf_dashboard.py +++ b/tools/perf/core/upload_results_to_perf_dashboard.py
@@ -224,7 +224,5 @@ versions['git_revision'] = git_revision versions['point_id'] = point_id # There are a lot of "bad" revisions to check for, so clean them all up here. - for key in versions: - if not versions[key] or versions[key] == 'undefined': - del versions[key] - return versions + new_versions = {k: v for k, v in versions.items() if v and v != 'undefined'} + return new_versions
diff --git a/ui/accessibility/ax_tree_manager.cc b/ui/accessibility/ax_tree_manager.cc index e0ebe9b..95ece47 100644 --- a/ui/accessibility/ax_tree_manager.cc +++ b/ui/accessibility/ax_tree_manager.cc
@@ -203,4 +203,23 @@ return FromID(parent_tree_id); } +bool AXTreeManager::IsRoot() const { + return GetParentTreeID() == ui::AXTreeIDUnknown(); +} + +AXTreeManager* AXTreeManager::GetRootManager() const { + if (IsRoot()) + return const_cast<AXTreeManager*>(this); + + AXTreeManager* parent = GetParentManager(); + if (!parent) { + // This can occur when the parent tree is not yet serialized. We can't + // prevent a child tree from serializing before the parent tree, so we just + // have to handle this case. Attempting to change this to a DCHECK() will + // cause a number of tests to fail. + return nullptr; + } + return parent->GetRootManager(); +} + } // namespace ui
diff --git a/ui/accessibility/ax_tree_manager.h b/ui/accessibility/ax_tree_manager.h index c8bc2238..25340a9 100644 --- a/ui/accessibility/ax_tree_manager.h +++ b/ui/accessibility/ax_tree_manager.h
@@ -73,6 +73,12 @@ // Returns the AXNode that is at the root of the current tree. AXNode* GetRoot() const; + bool IsRoot() const; + + // Returns the root AXTreeManager by walking up the tree to any parent trees. + // If there is a parent tree that is not yet connected, returns nullptr. + AXTreeManager* GetRootManager() const; + // If this tree has a parent tree, returns the node in the parent tree that // hosts the current tree. Returns nullptr if this tree doesn't have a parent // tree.
diff --git a/ui/accessibility/platform/ax_platform_node_cocoa.mm b/ui/accessibility/platform/ax_platform_node_cocoa.mm index f3becb8..491e45ea 100644 --- a/ui/accessibility/platform/ax_platform_node_cocoa.mm +++ b/ui/accessibility/platform/ax_platform_node_cocoa.mm
@@ -14,14 +14,18 @@ #include "base/trace_event/trace_event.h" #include "ui/accessibility/ax_action_data.h" #include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_range.h" #include "ui/accessibility/ax_role_properties.h" #include "ui/accessibility/platform/ax_platform_node_mac.h" #include "ui/accessibility/platform/ax_private_attributes_mac.h" #include "ui/accessibility/platform/ax_private_roles_mac.h" +#include "ui/accessibility/platform/ax_utils_mac.h" #include "ui/base/l10n/l10n_util.h" #import "ui/gfx/mac/coordinate_conversion.h" #include "ui/strings/grit/ax_strings.h" +using AXRange = ui::AXPlatformNodeDelegate::AXRange; + namespace ui { AXAnnouncementSpec::AXAnnouncementSpec() = default; @@ -707,6 +711,53 @@ return has_image_semantics; } +- (void)addMisspelledTextAttributes:(const AXRange&)axRange + toString: + (NSMutableAttributedString*)attributedString { + int anchorStartOffset = 0; + [attributedString beginEditing]; + for (const AXRange& leafTextRange : axRange) { + DCHECK(!leafTextRange.IsNull()); + DCHECK_EQ(leafTextRange.anchor()->GetAnchor(), + leafTextRange.focus()->GetAnchor()) + << "An anchor range should only span a single object."; + + ui::AXNode* anchor = leafTextRange.focus()->GetAnchor(); + + DCHECK(anchor) << "A non-null position should have a non-null anchor node."; + const std::vector<int32_t>& markerTypes = + anchor->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerTypes); + const std::vector<int>& markerStarts = + anchor->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerStarts); + const std::vector<int>& markerEnds = + anchor->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerEnds); + + DCHECK_EQ(markerTypes.size(), markerStarts.size()); + DCHECK_EQ(markerTypes.size(), markerEnds.size()); + + for (size_t i = 0; i < markerTypes.size(); ++i) { + if (!(markerTypes[i] & + static_cast<int32_t>(ax::mojom::MarkerType::kSpelling))) { + continue; + } + + int misspellingStart = anchorStartOffset + markerStarts[i]; + int misspellingEnd = anchorStartOffset + markerEnds[i]; + int misspellingLength = misspellingEnd - misspellingStart; + DCHECK_LE(static_cast<unsigned long>(misspellingEnd), + [attributedString length]); + DCHECK_GT(misspellingLength, 0); + [attributedString + addAttribute:NSAccessibilityMarkedMisspelledTextAttribute + value:@YES + range:NSMakeRange(misspellingStart, misspellingLength)]; + } + + anchorStartOffset += leafTextRange.GetText().length(); + } + [attributedString endEditing]; +} + - (NSString*)getName { return base::SysUTF8ToNSString(_node->GetName()); } @@ -1092,6 +1143,24 @@ return axAttributes.autorelease(); } +- (NSArray*)accessibilityParameterizedAttributeNames { + if (!_node) + return @[]; + + // General attributes. + NSMutableArray* ret = [NSMutableArray + arrayWithObjects: + NSAccessibilityAttributedStringForTextMarkerRangeParameterizedAttribute, + nil]; + + if (_node->HasState(ax::mojom::State::kEditable)) { + [ret addObjectsFromArray:@[ + NSAccessibilityAttributedStringForRangeParameterizedAttribute + ]]; + } + return ret; +} + // Despite it being deprecated, AppKit internally calls this function sometimes // in unclear circumstances. It is implemented in terms of the new a11y API // here. @@ -1755,14 +1824,48 @@ if (![parameter isKindOfClass:[NSValue class]]) return nil; - // TODO(https://crbug.com/958811): Implement this for real. - base::scoped_nsobject<NSAttributedString> attributedString( - [[NSAttributedString alloc] - initWithString:[self AXStringForRange:parameter]]); + // TODO(https://crbug.com/958811): Finish implementation. + // Currently, we only decorate the attributed string with misspelling + // information. // TODO(tapted): views::WordLookupClient has a way to obtain the actual // decorations, and BridgedContentView has a conversion function that creates // an NSAttributedString. Refactor things so they can be used here. - return attributedString.autorelease(); + + NSRange range = [(NSValue*)parameter rangeValue]; + std::u16string textContent = _node->GetTextContentUTF16(); + if (NSMaxRange(range) > textContent.length()) + return nil; + + // We potentially need to add text attributes to the whole text content + // because a spelling mistake might start or end outside the given range. + NSMutableAttributedString* attributedTextContent = + [[[NSMutableAttributedString alloc] + initWithString:base::SysUTF16ToNSString(textContent)] autorelease]; + if (!_node->IsText()) { + AXRange axRange(_node->GetDelegate()->CreateTextPositionAt(0), + _node->GetDelegate()->CreateTextPositionAt( + static_cast<int>(textContent.length()))); + [self addMisspelledTextAttributes:axRange toString:attributedTextContent]; + } + + return [attributedTextContent attributedSubstringFromRange:range]; +} + +- (NSAttributedString*)AXAttributedStringForTextMarkerRange:(id)markerRange { + AXRange axRange = ui::AXTextMarkerRangeToAXRange(markerRange); + if (axRange.IsNull()) + return nil; + + NSString* text = base::SysUTF16ToNSString(axRange.GetText()); + if ([text length] == 0) + return nil; + + NSMutableAttributedString* attributedText = + [[[NSMutableAttributedString alloc] initWithString:text] autorelease]; + // Currently, we only decorate the attributed string with misspelling + // information. + [self addMisspelledTextAttributes:axRange toString:attributedText]; + return attributedText; } - (NSString*)ChromeAXNodeId {
diff --git a/ui/accessibility/platform/ax_private_attributes_mac.h b/ui/accessibility/platform/ax_private_attributes_mac.h index 95c7d751..d36b72d47 100644 --- a/ui/accessibility/platform/ax_private_attributes_mac.h +++ b/ui/accessibility/platform/ax_private_attributes_mac.h
@@ -10,6 +10,9 @@ #include "ui/accessibility/ax_export.h" // Private WebKit accessibility attributes. +AX_EXPORT constexpr NSString* const + NSAccessibilityAttributedStringForTextMarkerRangeParameterizedAttribute = + @"AXAttributedStringForTextMarkerRange"; AX_EXPORT constexpr NSString* const NSAccessibilityAccessKeyAttribute = @"AXAccessKey"; AX_EXPORT constexpr NSString* const NSAccessibilityARIAAtomicAttribute =
diff --git a/ui/base/interaction/interaction_sequence.cc b/ui/base/interaction/interaction_sequence.cc index be24632..920910cd 100644 --- a/ui/base/interaction/interaction_sequence.cc +++ b/ui/base/interaction/interaction_sequence.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/callback_forward.h" +#include "base/callback_list.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/memory/weak_auto_reset.h" @@ -69,6 +70,14 @@ return; } + // If the following step is a re-show of the same element or element ID, the + // default is false. + if (next && next->type == InteractionSequence::StepType::kShown && + next->id == step->id && next->transition_only_on_event) { + step->must_remain_visible = false; + return; + } + // Otherwise for kShown steps, the default is true. step->must_remain_visible = true; } @@ -477,7 +486,9 @@ return; switch (next_step()->type) { + case StepType::kHidden: case StepType::kActivated: + case StepType::kShown: // We should know the identifier and name ahead of time for activation // steps, so just make sure nothing has gone awry. DCHECK(element->identifier() == next_step()->id); @@ -499,18 +510,23 @@ // Barring disaster, we will immediately transition as soon as we finish // processing the current step. - next_step()->element = element; trigger_during_callback_ = true; - // Since we've hit the trigger for the next step, we need to make sure we - // clean up (and possibly abort) if the element goes away before we can - // finish processing the current step. - next_step()->subscription = - ElementTracker::GetElementTracker()->AddElementHiddenCallback( - element->identifier(), element->context(), - base::BindRepeating( - &InteractionSequence::OnElementHiddenDuringStepTransition, - base::Unretained(this))); + if (next_step()->type == StepType::kHidden) { + next_step()->element = nullptr; + next_step()->subscription = base::CallbackListSubscription(); + } else { + // Since we've hit the trigger for the next step, we need to make sure we + // clean up (and possibly abort) if the element goes away before we can + // finish processing the current step. + next_step()->element = element; + next_step()->subscription = + ElementTracker::GetElementTracker()->AddElementHiddenCallback( + element->identifier(), element->context(), + base::BindRepeating( + &InteractionSequence::OnElementHiddenDuringStepTransition, + base::Unretained(this))); + } } void InteractionSequence::OnElementHiddenDuringStepTransition( @@ -554,26 +570,57 @@ return; } - if (next_step()->type == StepType::kActivated && next_step()->id) { - // If the next step is an activation step and we already know the ID (i.e. - // it's either not a named element or the element in question has been - // named) then add the appropriate temporary callback. - next_step()->subscription = - ElementTracker::GetElementTracker()->AddElementActivatedCallback( - next_step()->id, GetElementContext(named_element), - base::BindRepeating( - &InteractionSequence::OnTriggerDuringStepTransition, - base::Unretained((this)))); - } else if (next_step()->type == StepType::kCustomEvent) { - // If the next step is a custom event, we might not yet know the name or ID - // of the element, but we can still listen for the custom event type. We'll - // filter out irrelevant elements in the callback itself. - next_step()->subscription = - ElementTracker::GetElementTracker()->AddCustomEventCallback( - next_step()->custom_event_type, GetElementContext(named_element), - base::BindRepeating( - &InteractionSequence::OnTriggerDuringStepTransition, - base::Unretained((this)))); + // If the next step is a discrete event, listen for the event so we don't miss + // it during the step callback. + switch (next_step()->type) { + case StepType::kActivated: + // For activation events the ID of the next node must be known. + if (next_step()->id) { + next_step()->subscription = + ElementTracker::GetElementTracker()->AddElementActivatedCallback( + next_step()->id, GetElementContext(named_element), + base::BindRepeating( + &InteractionSequence::OnTriggerDuringStepTransition, + base::Unretained((this)))); + } + break; + case StepType::kCustomEvent: + // For custom events the ID is not necessary because ElementTracker allows + // just listening for the event. + next_step()->subscription = + ElementTracker::GetElementTracker()->AddCustomEventCallback( + next_step()->custom_event_type, GetElementContext(named_element), + base::BindRepeating( + &InteractionSequence::OnTriggerDuringStepTransition, + base::Unretained((this)))); + break; + case StepType::kShown: + // For shown events, the ID must be known and the event need only be + // observed if the state change itself is being observed or the element + // might immediately become invisible again. + if ((next_step()->transition_only_on_event || + !next_step()->must_remain_visible.value()) && + next_step()->id) { + next_step()->subscription = + ElementTracker::GetElementTracker()->AddElementShownCallback( + next_step()->id, GetElementContext(named_element), + base::BindRepeating( + &InteractionSequence::OnTriggerDuringStepTransition, + base::Unretained((this)))); + } + break; + case StepType::kHidden: + // For hidden events, the ID must be known. Only watch if the state change + // itself is the step transition. + if (next_step()->transition_only_on_event && next_step()->id) { + next_step()->subscription = + ElementTracker::GetElementTracker()->AddElementHiddenCallback( + next_step()->id, GetElementContext(named_element), + base::BindRepeating( + &InteractionSequence::OnTriggerDuringStepTransition, + base::Unretained((this)))); + } + break; } } @@ -670,11 +717,7 @@ void InteractionSequence::StageNextStep() { auto* const tracker = ElementTracker::GetElementTracker(); - Step* const next = next_step(); - DCHECK(!trigger_during_callback_ || next->type == StepType::kActivated || - next->type == StepType::kCustomEvent || - next->type == StepType::kHidden); // Note that if the target element for the next step was activated and then // hidden during the previous step transition, `next_element` could be null. @@ -707,7 +750,15 @@ switch (next->type) { case StepType::kShown: - if (next_element && !next->transition_only_on_event) { + if (trigger_during_callback_) { + trigger_during_callback_ = false; + if (next->must_remain_visible.value() && !next_element) { + Abort(AbortedReason::kElementHiddenDuringStep); + return; + } else { + DoStepTransition(next_element); + } + } else if (next_element && !next->transition_only_on_event) { DoStepTransition(next_element); } else { DCHECK(!next->uses_named_element());
diff --git a/ui/base/interaction/interaction_sequence_unittest.cc b/ui/base/interaction/interaction_sequence_unittest.cc index 17956bb6..bf0f3705 100644 --- a/ui/base/interaction/interaction_sequence_unittest.cc +++ b/ui/base/interaction/interaction_sequence_unittest.cc
@@ -1889,6 +1889,367 @@ EXPECT_FALSE(sequence); } +// Transition during step callback tests for show and hide events. +// These are tricky to get right, so all of the variations must be tested. + +TEST(InteractionSequenceTest, HideDuringStepTransitionSameElement) { + UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted); + UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed); + test::TestElement element1(kTestIdentifier1, kTestContext1); + element1.Show(); + + std::unique_ptr<InteractionSequence> sequence = + InteractionSequence::Builder() + .SetAbortedCallback(aborted.Get()) + .SetCompletedCallback(completed.Get()) + .SetContext(kTestContext1) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetStartCallback(base::BindLambdaForTesting( + [&]() { element1.Hide(); }))) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetType(InteractionSequence::StepType::kHidden) + .SetTransitionOnlyOnEvent(true)) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->Start()); +} + +TEST(InteractionSequenceTest, + HideDuringStepTransitionSameElementVisibilityBlinks) { + UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted); + UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed); + test::TestElement element1(kTestIdentifier1, kTestContext1); + element1.Show(); + + std::unique_ptr<InteractionSequence> sequence = + InteractionSequence::Builder() + .SetAbortedCallback(aborted.Get()) + .SetCompletedCallback(completed.Get()) + .SetContext(kTestContext1) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetStartCallback(base::BindLambdaForTesting([&]() { + element1.Hide(); + element1.Show(); + }))) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetType(InteractionSequence::StepType::kHidden) + .SetTransitionOnlyOnEvent(true)) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->Start()); +} + +TEST(InteractionSequenceTest, HideDuringStepTransitionDifferentElementSameID) { + UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted); + UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed); + test::TestElement element1(kTestIdentifier1, kTestContext1); + test::TestElement element2(kTestIdentifier1, kTestContext1); + element1.Show(); + element2.Show(); + + std::unique_ptr<InteractionSequence> sequence = + InteractionSequence::Builder() + .SetAbortedCallback(aborted.Get()) + .SetCompletedCallback(completed.Get()) + .SetContext(kTestContext1) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetStartCallback(base::BindLambdaForTesting( + [&]() { element2.Hide(); }))) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetType(InteractionSequence::StepType::kHidden) + .SetTransitionOnlyOnEvent(true)) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->Start()); +} + +TEST( + InteractionSequenceTest, + HideDuringStepTransitionDifferentElementSameIDSameElementVisibilityBlinks) { + UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted); + UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed); + test::TestElement element1(kTestIdentifier1, kTestContext1); + test::TestElement element2(kTestIdentifier1, kTestContext1); + element1.Show(); + element2.Show(); + + std::unique_ptr<InteractionSequence> sequence = + InteractionSequence::Builder() + .SetAbortedCallback(aborted.Get()) + .SetCompletedCallback(completed.Get()) + .SetContext(kTestContext1) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetStartCallback(base::BindLambdaForTesting([&]() { + element2.Hide(); + element2.Show(); + }))) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetType(InteractionSequence::StepType::kHidden) + .SetTransitionOnlyOnEvent(true)) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->Start()); +} + +TEST(InteractionSequenceTest, HideDuringStepTransitionDifferentID) { + UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted); + UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed); + test::TestElement element1(kTestIdentifier1, kTestContext1); + test::TestElement element2(kTestIdentifier2, kTestContext1); + element1.Show(); + element2.Show(); + + std::unique_ptr<InteractionSequence> sequence = + InteractionSequence::Builder() + .SetAbortedCallback(aborted.Get()) + .SetCompletedCallback(completed.Get()) + .SetContext(kTestContext1) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetStartCallback(base::BindLambdaForTesting( + [&]() { element2.Hide(); }))) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier2) + .SetType(InteractionSequence::StepType::kHidden) + .SetTransitionOnlyOnEvent(true)) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->Start()); +} + +TEST(InteractionSequenceTest, + HideDuringStepTransitionDifferentIDVisibilityBlinks) { + UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted); + UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed); + test::TestElement element1(kTestIdentifier1, kTestContext1); + test::TestElement element2(kTestIdentifier2, kTestContext1); + element1.Show(); + element2.Show(); + + std::unique_ptr<InteractionSequence> sequence = + InteractionSequence::Builder() + .SetAbortedCallback(aborted.Get()) + .SetCompletedCallback(completed.Get()) + .SetContext(kTestContext1) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetStartCallback(base::BindLambdaForTesting([&]() { + element2.Hide(); + element2.Show(); + }))) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier2) + .SetType(InteractionSequence::StepType::kHidden) + .SetTransitionOnlyOnEvent(true)) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->Start()); +} + +TEST(InteractionSequenceTest, + ShowDuringStepTransitionSameElementTransitionOnlyOnEvent) { + UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted); + UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed); + test::TestElement element1(kTestIdentifier1, kTestContext1); + element1.Show(); + + std::unique_ptr<InteractionSequence> sequence = + InteractionSequence::Builder() + .SetAbortedCallback(aborted.Get()) + .SetCompletedCallback(completed.Get()) + .SetContext(kTestContext1) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetStartCallback(base::BindLambdaForTesting([&]() { + element1.Hide(); + element1.Show(); + }))) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetType(InteractionSequence::StepType::kShown) + .SetTransitionOnlyOnEvent(true)) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->Start()); +} + +TEST(InteractionSequenceTest, + ShowDuringStepTransitionSameElementDoesNotNeedToRemainVisible) { + UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted); + UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed); + test::TestElement element1(kTestIdentifier1, kTestContext1); + element1.Show(); + + std::unique_ptr<InteractionSequence> sequence = + InteractionSequence::Builder() + .SetAbortedCallback(aborted.Get()) + .SetCompletedCallback(completed.Get()) + .SetContext(kTestContext1) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetMustRemainVisible(false) + .SetStartCallback(base::BindLambdaForTesting([&]() { + element1.Hide(); + element1.Show(); + element1.Hide(); + }))) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetType(InteractionSequence::StepType::kShown) + .SetMustRemainVisible(false)) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->Start()); +} + +TEST(InteractionSequenceTest, + ShowDuringStepTransitionSameIDTransitionOnlyOnEvent) { + UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted); + UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed); + test::TestElement element1(kTestIdentifier1, kTestContext1); + test::TestElement element2(kTestIdentifier1, kTestContext1); + element1.Show(); + + std::unique_ptr<InteractionSequence> sequence = + InteractionSequence::Builder() + .SetAbortedCallback(aborted.Get()) + .SetCompletedCallback(completed.Get()) + .SetContext(kTestContext1) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetMustRemainVisible(false) + .SetStartCallback(base::BindLambdaForTesting( + [&]() { element2.Show(); }))) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetType(InteractionSequence::StepType::kShown) + .SetTransitionOnlyOnEvent(true)) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->Start()); +} + +TEST(InteractionSequenceTest, + ShowDuringStepTransitionSameIDDoesNotNeedToRemainVisible) { + UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted); + UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed); + test::TestElement element1(kTestIdentifier1, kTestContext1); + test::TestElement element2(kTestIdentifier1, kTestContext1); + element1.Show(); + + std::unique_ptr<InteractionSequence> sequence = + InteractionSequence::Builder() + .SetAbortedCallback(aborted.Get()) + .SetCompletedCallback(completed.Get()) + .SetContext(kTestContext1) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetMustRemainVisible(false) + .SetStartCallback(base::BindLambdaForTesting([&]() { + element2.Show(); + element2.Hide(); + }))) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetType(InteractionSequence::StepType::kShown) + .SetMustRemainVisible(false)) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->Start()); +} + +TEST(InteractionSequenceTest, + ShowDuringStepTransitionDifferentIDTransitionOnlyOnEvent) { + UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted); + UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed); + test::TestElement element1(kTestIdentifier1, kTestContext1); + test::TestElement element2(kTestIdentifier2, kTestContext1); + element1.Show(); + + std::unique_ptr<InteractionSequence> sequence = + InteractionSequence::Builder() + .SetAbortedCallback(aborted.Get()) + .SetCompletedCallback(completed.Get()) + .SetContext(kTestContext1) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetMustRemainVisible(false) + .SetStartCallback(base::BindLambdaForTesting( + [&]() { element2.Show(); }))) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier2) + .SetType(InteractionSequence::StepType::kShown) + .SetTransitionOnlyOnEvent(true)) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->Start()); +} + +TEST(InteractionSequenceTest, + ShowDuringStepTransitionDifferentIDDoesNotNeedToRemainVisible) { + UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted); + UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed); + test::TestElement element1(kTestIdentifier1, kTestContext1); + test::TestElement element2(kTestIdentifier2, kTestContext1); + element1.Show(); + + std::unique_ptr<InteractionSequence> sequence = + InteractionSequence::Builder() + .SetAbortedCallback(aborted.Get()) + .SetCompletedCallback(completed.Get()) + .SetContext(kTestContext1) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetMustRemainVisible(false) + .SetStartCallback(base::BindLambdaForTesting([&]() { + element2.Show(); + element2.Hide(); + }))) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier2) + .SetType(InteractionSequence::StepType::kShown) + .SetMustRemainVisible(false)) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->Start()); +} + +TEST(InteractionSequenceTest, + ShowDuringStepTransitionDoesNotAbortAfterTrigger) { + UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted); + UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed); + test::TestElement element1(kTestIdentifier1, kTestContext1); + test::TestElement element2(kTestIdentifier2, kTestContext1); + element1.Show(); + + std::unique_ptr<InteractionSequence> sequence = + InteractionSequence::Builder() + .SetAbortedCallback(aborted.Get()) + .SetCompletedCallback(completed.Get()) + .SetContext(kTestContext1) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier1) + .SetStartCallback(base::BindLambdaForTesting([&]() { + element2.Show(); + element1.Hide(); + }))) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(kTestIdentifier2) + .SetType(InteractionSequence::StepType::kShown) + .SetMustRemainVisible(false)) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->Start()); +} + // Bait-and-switch tests - verify that when an element must start visible and // there are multiple such elements, it's okay if any of them receive the // following event. @@ -2390,6 +2751,53 @@ element3.Hide()); } +TEST(InteractionSequenceTest, + MustRemainVisible_DefaultsBasedOnCurrentAndNextStep_Reshow) { + UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted); + UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed); + test::TestElement element1(kTestIdentifier1, kTestContext1); + test::TestElement element2(kTestIdentifier2, kTestContext1); + element1.Show(); + auto sequence = + InteractionSequence::Builder() + .SetContext(element1.context()) + .SetAbortedCallback(aborted.Get()) + .SetCompletedCallback(completed.Get()) + // Shown followed by reshow defaults to must_remain_visible = false. + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(element1.identifier()) + .SetType(InteractionSequence::StepType::kShown) + .Build()) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(element1.identifier()) + .SetType(InteractionSequence::StepType::kShown) + .SetTransitionOnlyOnEvent(true) + .Build()) + // Shown followed by different element defaults to true. + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(element1.identifier()) + .SetType(InteractionSequence::StepType::kShown) + .Build()) + .AddStep(InteractionSequence::StepBuilder() + .SetElementID(element2.identifier()) + .SetType(InteractionSequence::StepType::kShown) + .SetTransitionOnlyOnEvent(true) + .Build()) + .Build(); + + sequence->Start(); + // Trigger step 2. + element1.Hide(); + element1.Show(); + // Break the sequence at step 3. + EXPECT_CALL_IN_SCOPE( + aborted, + Run(3, testing::_, element1.identifier(), + InteractionSequence::StepType::kShown, + InteractionSequence::AbortedReason::kElementHiddenDuringStep), + element1.Hide()); +} + // SetTransitionOnlyOnEvent tests: TEST(InteractionSequenceTest,
diff --git a/ui/gfx/geometry/BUILD.gn b/ui/gfx/geometry/BUILD.gn index e407c40..5a39634 100644 --- a/ui/gfx/geometry/BUILD.gn +++ b/ui/gfx/geometry/BUILD.gn
@@ -10,6 +10,7 @@ "axis_transform2d.h", "box_f.cc", "box_f.h", + "clamp_float_geometry.h", "cubic_bezier.cc", "cubic_bezier.h", "dip_util.cc",
diff --git a/ui/gfx/geometry/axis_transform2d.h b/ui/gfx/geometry/axis_transform2d.h index 470e651..8ab09b6 100644 --- a/ui/gfx/geometry/axis_transform2d.h +++ b/ui/gfx/geometry/axis_transform2d.h
@@ -6,6 +6,7 @@ #define UI_GFX_GEOMETRY_AXIS_TRANSFORM2D_H_ #include "base/check_op.h" +#include "ui/gfx/geometry/clamp_float_geometry.h" #include "ui/gfx/geometry/geometry_export.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/vector2d_f.h" @@ -17,6 +18,10 @@ // Internally this is stored as a vector for pre-scale, and another vector // for post-translation. The class constructor and member accessor follows // the same convention, but a scalar scale factor is also accepted. +// +// Results of the *Map* methods are clamped with ClampFloatGeometry(). +// See the definition of the function for details. +// class GEOMETRY_EXPORT AxisTransform2d { public: constexpr AxisTransform2d() = default; @@ -64,21 +69,26 @@ } PointF MapPoint(const PointF& p) const { - return ScalePoint(p, scale_.x(), scale_.y()) + translation_; + return PointF(MapX(p.x()), MapY(p.y())); } PointF InverseMapPoint(const PointF& p) const { - return ScalePoint(p - translation_, 1.f / scale_.x(), 1.f / scale_.y()); + return PointF(InverseMapX(p.x()), InverseMapY(p.y())); } - RectF MapRect(const RectF& r) const { DCHECK_GE(scale_.x(), 0.f); DCHECK_GE(scale_.y(), 0.f); - return ScaleRect(r, scale_.x(), scale_.y()) + translation_; + return RectF(MapX(r.x()), MapY(r.y()), + ClampFloatGeometry(r.width() * scale_.x()), + ClampFloatGeometry(r.height() * scale_.y())); } RectF InverseMapRect(const RectF& r) const { DCHECK_GT(scale_.x(), 0.f); DCHECK_GT(scale_.y(), 0.f); - return ScaleRect(r - translation_, 1.f / scale_.x(), 1.f / scale_.y()); + return RectF(InverseMapX(r.x()), InverseMapY(r.y()), + // |* (1.f / scale)| instead of '/ scale' to keep the same + // precision before crrev.com/c/3937107. + ClampFloatGeometry(r.width() * (1.f / scale_.x())), + ClampFloatGeometry(r.height() * (1.f / scale_.y()))); } const Vector2dF& scale() const { return scale_; } @@ -91,6 +101,23 @@ const Vector2dF& translation) : scale_(scale), translation_(translation) {} + float MapX(float x) const { + return ClampFloatGeometry(x * scale_.x() + translation_.x()); + } + float MapY(float y) const { + return ClampFloatGeometry(y * scale_.y() + translation_.y()); + } + float InverseMapX(float x) const { + // |* (1.f / scale)| instead of '/ scale' to keep the same precision + // before crrev.com/c/3937107. + return ClampFloatGeometry((x - translation_.x()) * (1.f / scale_.x())); + } + float InverseMapY(float y) const { + // |* (1.f / scale)| instead of '/ scale' to keep the same precision + // before crrev.com/c/3937107. + return ClampFloatGeometry((y - translation_.y()) * (1.f / scale_.y())); + } + // Scale is applied before translation, i.e. // this->Transform(p) == scale_ * p + translation_ Vector2dF scale_{1.f, 1.f};
diff --git a/ui/gfx/geometry/axis_transform2d_unittest.cc b/ui/gfx/geometry/axis_transform2d_unittest.cc index a49ec16..39519a5f 100644 --- a/ui/gfx/geometry/axis_transform2d_unittest.cc +++ b/ui/gfx/geometry/axis_transform2d_unittest.cc
@@ -87,5 +87,58 @@ ConcatAxisTransform2d(inv_inplace, t)); } +TEST(TransformationMatrixTest, ClampOutput) { + double entries[][2] = { + // The first entry is used to initialize the transform. + // The second entry is used to initialize the object to be mapped. + {std::numeric_limits<float>::max(), + std::numeric_limits<float>::infinity()}, + {1, std::numeric_limits<float>::infinity()}, + {-1, std::numeric_limits<float>::infinity()}, + {1, -std::numeric_limits<float>::infinity()}, + { + std::numeric_limits<float>::max(), + std::numeric_limits<float>::max(), + }, + { + std::numeric_limits<float>::lowest(), + -std::numeric_limits<float>::infinity(), + }, + }; + + for (double* entry : entries) { + const float mv = entry[0]; + const float factor = entry[1]; + + auto is_valid_point = [&](const PointF& p) -> bool { + return std::isfinite(p.x()) && std::isfinite(p.y()); + }; + auto is_valid_rect = [&](const RectF& r) -> bool { + return is_valid_point(r.origin()) && std::isfinite(r.width()) && + std::isfinite(r.height()); + }; + + auto test = [&](const AxisTransform2d& m) { + SCOPED_TRACE(base::StringPrintf("m: %s factor: %lg", m.ToString().c_str(), + factor)); + auto p = m.MapPoint(PointF(factor, factor)); + EXPECT_TRUE(is_valid_point(p)) << p.ToString(); + + // AxisTransform2d::MapRect() requires non-negative scales. + if (m.scale().x() >= 0 && m.scale().y() >= 0) { + auto r = m.MapRect(RectF(factor, factor, factor, factor)); + EXPECT_TRUE(is_valid_rect(r)) << r.ToString(); + } + }; + + test(AxisTransform2d::FromScaleAndTranslation(Vector2dF(mv, mv), + Vector2dF(mv, mv))); + test(AxisTransform2d::FromScaleAndTranslation(Vector2dF(mv, mv), + Vector2dF(0, 0))); + test(AxisTransform2d::FromScaleAndTranslation(Vector2dF(1, 1), + Vector2dF(mv, mv))); + } +} + } // namespace } // namespace gfx
diff --git a/ui/gfx/geometry/clamp_float_geometry.h b/ui/gfx/geometry/clamp_float_geometry.h new file mode 100644 index 0000000..bb9f62e --- /dev/null +++ b/ui/gfx/geometry/clamp_float_geometry.h
@@ -0,0 +1,39 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_GEOMETRY_CLAMP_FLOAT_GEOMETRY_H_ +#define UI_GFX_GEOMETRY_CLAMP_FLOAT_GEOMETRY_H_ + +#include <limits> + +#include "base/numerics/safe_conversions.h" + +namespace gfx { + +template <typename T> +struct FloatGeometrySaturationHandler { + static constexpr float NaN() { return 0; } + static constexpr float Overflow() { return max(); } + static constexpr float Underflow() { return lowest(); } + static constexpr float max() { + return std::numeric_limits<float>::max() / 1e6; + } + static constexpr float lowest() { + return std::numeric_limits<float>::lowest() / 1e6; + } +}; + +// Clamps |value| (float, double or long double) within the range of +// [numeric_limits<float>::lowest() / 1e6, numeric_limits<float::max() / 1e6f]. +// Returns 0 for NaN. This avoids NaN and infinity values immediately, and +// reduce the chance of producing NaN and infinity values for future unclamped +// operations like offsetting and scaling by devices / page scale factor. +template <typename T> +constexpr float ClampFloatGeometry(T value) { + return base::saturated_cast<float, FloatGeometrySaturationHandler, T>(value); +} + +} // namespace gfx + +#endif // UI_GFX_GEOMETRY_CLAMP_FLOAT_GEOMETRY_H_
diff --git a/ui/gfx/geometry/test/geometry_util.cc b/ui/gfx/geometry/test/geometry_util.cc index 07ae2b3..08903f5 100644 --- a/ui/gfx/geometry/test/geometry_util.cc +++ b/ui/gfx/geometry/test/geometry_util.cc
@@ -27,6 +27,7 @@ #include "ui/gfx/geometry/vector2d.h" #include "ui/gfx/geometry/vector2d_f.h" #include "ui/gfx/geometry/vector3d_f.h" +#include "ui/gfx/selection_bound.h" namespace gfx { @@ -399,4 +400,8 @@ *os << info.ToString(); } +void PrintTo(const SelectionBound& bound, ::std::ostream* os) { + *os << bound.ToString(); +} + } // namespace gfx
diff --git a/ui/gfx/geometry/transform.cc b/ui/gfx/geometry/transform.cc index bc90c79f..f85ad26 100644 --- a/ui/gfx/geometry/transform.cc +++ b/ui/gfx/geometry/transform.cc
@@ -9,6 +9,7 @@ #include "ui/gfx/geometry/angle_conversions.h" #include "ui/gfx/geometry/axis_transform2d.h" #include "ui/gfx/geometry/box_f.h" +#include "ui/gfx/geometry/clamp_float_geometry.h" #include "ui/gfx/geometry/point3_f.h" #include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/geometry/quaternion.h" @@ -421,8 +422,13 @@ } Vector2dF Transform::To2dTranslation() const { - return gfx::Vector2dF(SkScalarToFloat(matrix_.rc(0, 3)), - SkScalarToFloat(matrix_.rc(1, 3))); + return gfx::Vector2dF(ClampFloatGeometry(matrix_.rc(0, 3)), + ClampFloatGeometry(matrix_.rc(1, 3))); +} + +Vector2dF Transform::To2dScale() const { + return gfx::Vector2dF(ClampFloatGeometry(matrix_.rc(0, 0)), + ClampFloatGeometry(matrix_.rc(1, 1))); } Point Transform::MapPoint(const Point& point) const { @@ -443,12 +449,15 @@ SkScalar p[4] = {vector.x(), vector.y(), vector.z(), 0}; matrix_.mapScalars(p); - return Vector3dF(p[0], p[1], p[2]); + return Vector3dF(ClampFloatGeometry(p[0]), ClampFloatGeometry(p[1]), + ClampFloatGeometry(p[2])); } void Transform::TransformVector4(float vector[4]) const { DCHECK(vector); matrix_.mapScalars(vector); + for (int i = 0; i < 4; i++) + vector[i] = ClampFloatGeometry(vector[i]); } absl::optional<PointF> Transform::InverseMapPoint(const PointF& point) const { @@ -482,7 +491,9 @@ // TODO(crbug.com/1359528): Use local implementation. SkRect src = RectFToSkRect(rect); TransformToFlattenedSkMatrix(*this).mapRect(&src); - return SkRectToRectF(src); + return RectF(ClampFloatGeometry(src.x()), ClampFloatGeometry(src.y()), + ClampFloatGeometry(src.width()), + ClampFloatGeometry(src.height())); } Rect Transform::MapRect(const Rect& rect) const { @@ -500,10 +511,12 @@ if (!GetInverse(&inverse)) return absl::nullopt; - // TODO(crbug.com/1359528): Use local implementation. + // TODO(crbug.com/1359528): Use local implementation and clamp the results. SkRect src = RectFToSkRect(rect); TransformToFlattenedSkMatrix(inverse).mapRect(&src); - return SkRectToRectF(src); + return RectF(ClampFloatGeometry(src.x()), ClampFloatGeometry(src.y()), + ClampFloatGeometry(src.width()), + ClampFloatGeometry(src.height())); } absl::optional<Rect> Transform::InverseMapRect(const Rect& rect) const { @@ -563,9 +576,12 @@ if (p[3] != SK_Scalar1 && std::isnormal(p[3])) { float w_inverse = SK_Scalar1 / p[3]; - return gfx::Point3F(p[0] * w_inverse, p[1] * w_inverse, p[2] * w_inverse); + return gfx::Point3F(ClampFloatGeometry(p[0] * w_inverse), + ClampFloatGeometry(p[1] * w_inverse), + ClampFloatGeometry(p[2] * w_inverse)); } - return gfx::Point3F(p[0], p[1], p[2]); + return gfx::Point3F(ClampFloatGeometry(p[0]), ClampFloatGeometry(p[1]), + ClampFloatGeometry(p[2])); } PointF Transform::MapPointInternal(const Matrix44& xform, @@ -578,9 +594,10 @@ if (p[3] != SK_Scalar1 && std::isnormal(p[3])) { float w_inverse = SK_Scalar1 / p[3]; - return gfx::PointF(p[0] * w_inverse, p[1] * w_inverse); + return gfx::PointF(ClampFloatGeometry(p[0] * w_inverse), + ClampFloatGeometry(p[1] * w_inverse)); } - return gfx::PointF(p[0], p[1]); + return gfx::PointF(ClampFloatGeometry(p[0]), ClampFloatGeometry(p[1])); } Point Transform::MapPointInternal(const Matrix44& xform,
diff --git a/ui/gfx/geometry/transform.h b/ui/gfx/geometry/transform.h index b68fc145..88e7e4a 100644 --- a/ui/gfx/geometry/transform.h +++ b/ui/gfx/geometry/transform.h
@@ -11,7 +11,6 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/geometry/geometry_skia_export.h" #include "ui/gfx/geometry/matrix44.h" -#include "ui/gfx/geometry/vector2d_f.h" namespace gfx { @@ -23,6 +22,7 @@ class PointF; class Point3F; class Quaternion; +class Vector2dF; class Vector3dF; // 4x4 transformation matrix. Transform is cheap and explicitly allows @@ -291,54 +291,57 @@ // Returns true if the 3rd row and 3rd column are both (0, 0, 1, 0). bool IsFlat() const; - // Returns the x and y translation components of the matrix. + // Returns the x and y translation components of the matrix, clamped with + // ClampFloatGeometry(). Vector2dF To2dTranslation() const; - // Returns the x and y scale components of the matrix. - Vector2dF To2dScale() const { return gfx::Vector2dF(rc(0, 0), rc(1, 1)); } + // Returns the x and y scale components of the matrix, clamped with + // ClampFloatGeometry(). + Vector2dF To2dScale() const; - // Returns the point with the transformation applied to |point|. + // Returns the point with the transformation applied to |point|, clamped + // with ClampFloatGeometry(). [[nodiscard]] Point3F MapPoint(const Point3F& point) const; [[nodiscard]] PointF MapPoint(const PointF& point) const; [[nodiscard]] Point MapPoint(const Point& point) const; - // Returns the vector with the transformation applied to |vector|. - // It differs from MapPoint() by that the translation and perspective - // components of the matrix are ignored. + // Returns the vector with the transformation applied to |vector|, clamped + // with ClampFloatGeometry(). It differs from MapPoint() by that the + // translation and perspective components of the matrix are ignored. [[nodiscard]] Vector3dF MapVector(const Vector3dF& vector) const; - // Applies the transformation to the vector. + // Applies the transformation to the vector. The results are clamped with + // ClampFloatGeometry(). void TransformVector4(float vector[4]) const; - // Applies the reverse transformation on `point`. Returns `absl::nullopt` if - // the transformation cannot be inverted. + // Returns the point with reverse transformation applied to `point`, clamped + // with ClampFloatGeometry(), or `absl::nullopt` if the transformation cannot + // be inverted. [[nodiscard]] absl::optional<PointF> InverseMapPoint( const PointF& point) const; + [[nodiscard]] absl::optional<Point3F> InverseMapPoint( + const Point3F& point) const; // Applies the reverse transformation on `point`. Returns `absl::nullopt` if // the transformation cannot be inverted. Rounds the result to the nearest // point. [[nodiscard]] absl::optional<Point> InverseMapPoint(const Point& point) const; - // Applies the reverse transformation on `point`. Returns `absl::nullopt` if - // the transformation cannot be inverted. - [[nodiscard]] absl::optional<Point3F> InverseMapPoint( - const Point3F& point) const; - // Returns the rect that is the smallest axis aligned bounding rect - // containing the transformed rect. + // containing the transformed rect, clamped with ClampFloatGeometry(). [[nodiscard]] RectF MapRect(const RectF& rect) const; [[nodiscard]] Rect MapRect(const Rect& rect) const; // Applies the reverse transformation on the given rect. Returns // `absl::nullopt` if the transformation cannot be inverted, or the rect that - // is the smallest axis aligned bounding rect containing the transformed rect. + // is the smallest axis aligned bounding rect containing the transformed rect, + // clamped with ClampFloatGeometry(). [[nodiscard]] absl::optional<RectF> InverseMapRect(const RectF& rect) const; [[nodiscard]] absl::optional<Rect> InverseMapRect(const Rect& rect) const; // Returns the box with transformation applied on the given box. The returned // box will be the smallest axis aligned bounding box containing the - // transformed box. + // transformed box, clamped with ClampFloatGeometry(). [[nodiscard]] BoxF MapBox(const BoxF& box) const; // Decomposes |this| and |from|, interpolates the decomposed values, and
diff --git a/ui/gfx/geometry/transform_unittest.cc b/ui/gfx/geometry/transform_unittest.cc index 60a158f..4f474a88 100644 --- a/ui/gfx/geometry/transform_unittest.cc +++ b/ui/gfx/geometry/transform_unittest.cc
@@ -2991,6 +2991,86 @@ EXPECT_EQ(t, t1); } +TEST(TransformationMatrixTest, ClampOutput) { + double entries[][2] = { + // The first entry is used to initialize the transform. + // The second entry is used to initialize the object to be mapped. + {std::numeric_limits<float>::max(), + std::numeric_limits<float>::infinity()}, + {1, std::numeric_limits<float>::infinity()}, + {-1, std::numeric_limits<float>::infinity()}, + {1, -std::numeric_limits<float>::infinity()}, + { + std::numeric_limits<float>::max(), + std::numeric_limits<float>::max(), + }, + { + std::numeric_limits<float>::lowest(), + -std::numeric_limits<float>::infinity(), + }, + }; + + for (double* entry : entries) { + const float mv = entry[0]; + const float factor = entry[1]; + + auto is_valid_point = [&](const PointF& p) -> bool { + return std::isfinite(p.x()) && std::isfinite(p.y()); + }; + auto is_valid_point3 = [&](const Point3F& p) -> bool { + return std::isfinite(p.x()) && std::isfinite(p.y()) && + std::isfinite(p.z()); + }; + auto is_valid_vector2 = [&](const Vector2dF& v) -> bool { + return std::isfinite(v.x()) && std::isfinite(v.y()); + }; + auto is_valid_vector3 = [&](const Vector3dF& v) -> bool { + return std::isfinite(v.x()) && std::isfinite(v.y()) && + std::isfinite(v.z()); + }; + auto is_valid_rect = [&](const RectF& r) -> bool { + return is_valid_point(r.origin()) && std::isfinite(r.width()) && + std::isfinite(r.height()); + }; + auto is_valid_array = [&](const float* a, size_t size) -> bool { + for (size_t i = 0; i < size; i++) { + if (!std::isfinite(a[i])) + return false; + } + return true; + }; + + auto test = [&](const Transform& m) { + SCOPED_TRACE(base::StringPrintf("m: %s factor: %lg", m.ToString().c_str(), + factor)); + auto p = m.MapPoint(PointF(factor, factor)); + EXPECT_TRUE(is_valid_point(p)) << p.ToString(); + + auto p3 = m.MapPoint(Point3F(factor, factor, factor)); + EXPECT_TRUE(is_valid_point3(p3)) << p3.ToString(); + + auto r = m.MapRect(RectF(factor, factor, factor, factor)); + EXPECT_TRUE(is_valid_rect(r)) << r.ToString(); + + auto v3 = m.MapVector(Vector3dF(factor, factor, factor)); + EXPECT_TRUE(is_valid_vector3(v3)) << v3.ToString(); + + float v4[4] = {factor, factor, factor, factor}; + m.TransformVector4(v4); + EXPECT_TRUE(is_valid_array(v4, 4)); + + auto v2 = m.To2dTranslation(); + EXPECT_TRUE(is_valid_vector2(v2)) << v2.ToString(); + v2 = m.To2dScale(); + EXPECT_TRUE(is_valid_vector2(v2)) << v2.ToString(); + }; + + test(Transform::ColMajor(mv, mv, mv, mv, mv, mv, mv, mv, mv, mv, mv, mv, mv, + mv, mv, mv)); + test(Transform::MakeTranslation(mv, mv)); + } +} + } // namespace } // namespace gfx
diff --git a/ui/gfx/ipc/gfx_param_traits_macros.h b/ui/gfx/ipc/gfx_param_traits_macros.h index 442cd225..98050d1 100644 --- a/ui/gfx/ipc/gfx_param_traits_macros.h +++ b/ui/gfx/ipc/gfx_param_traits_macros.h
@@ -11,23 +11,13 @@ #include "build/build_config.h" #include "ipc/ipc_message_macros.h" #include "ui/gfx/ca_layer_params.h" -#include "ui/gfx/gpu_fence_handle.h" -#include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/ipc/gfx_ipc_export.h" -#include "ui/gfx/presentation_feedback.h" #include "ui/gfx/selection_bound.h" #include "ui/gfx/swap_result.h" -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) -#include "ui/gfx/native_pixmap_handle.h" -#endif - #undef IPC_MESSAGE_EXPORT #define IPC_MESSAGE_EXPORT GFX_IPC_EXPORT -IPC_ENUM_TRAITS_MAX_VALUE(gfx::GpuMemoryBufferType, - gfx::GPU_MEMORY_BUFFER_TYPE_LAST) - IPC_ENUM_TRAITS_MAX_VALUE(gfx::SwapResult, gfx::SwapResult::SWAP_RESULT_LAST) IPC_ENUM_TRAITS_MAX_VALUE(gfx::SelectionBound::Type, gfx::SelectionBound::LAST) @@ -42,52 +32,6 @@ #endif IPC_STRUCT_TRAITS_END() -IPC_STRUCT_TRAITS_BEGIN(gfx::GpuMemoryBufferHandle) - IPC_STRUCT_TRAITS_MEMBER(id) - IPC_STRUCT_TRAITS_MEMBER(type) - IPC_STRUCT_TRAITS_MEMBER(region) - IPC_STRUCT_TRAITS_MEMBER(offset) - IPC_STRUCT_TRAITS_MEMBER(stride) -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA) - IPC_STRUCT_TRAITS_MEMBER(native_pixmap_handle) -#elif BUILDFLAG(IS_APPLE) - IPC_STRUCT_TRAITS_MEMBER(io_surface) -#elif BUILDFLAG(IS_WIN) - IPC_STRUCT_TRAITS_MEMBER(dxgi_handle) -#elif BUILDFLAG(IS_ANDROID) - IPC_STRUCT_TRAITS_MEMBER(android_hardware_buffer) -#endif -IPC_STRUCT_TRAITS_END() - -IPC_STRUCT_TRAITS_BEGIN(gfx::GpuMemoryBufferId) - IPC_STRUCT_TRAITS_MEMBER(id) -IPC_STRUCT_TRAITS_END() - -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA) -IPC_STRUCT_TRAITS_BEGIN(gfx::NativePixmapPlane) - IPC_STRUCT_TRAITS_MEMBER(stride) - IPC_STRUCT_TRAITS_MEMBER(offset) - IPC_STRUCT_TRAITS_MEMBER(size) -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) - IPC_STRUCT_TRAITS_MEMBER(fd) -#elif BUILDFLAG(IS_FUCHSIA) - IPC_STRUCT_TRAITS_MEMBER(vmo) -#endif -IPC_STRUCT_TRAITS_END() - -IPC_STRUCT_TRAITS_BEGIN(gfx::NativePixmapHandle) - IPC_STRUCT_TRAITS_MEMBER(planes) -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) - IPC_STRUCT_TRAITS_MEMBER(modifier) -#endif -#if BUILDFLAG(IS_FUCHSIA) - IPC_STRUCT_TRAITS_MEMBER(buffer_collection_id) - IPC_STRUCT_TRAITS_MEMBER(buffer_index) - IPC_STRUCT_TRAITS_MEMBER(ram_coherency) -#endif -IPC_STRUCT_TRAITS_END() -#endif - IPC_STRUCT_TRAITS_BEGIN(gfx::SwapTimings) IPC_STRUCT_TRAITS_MEMBER(swap_start) IPC_STRUCT_TRAITS_MEMBER(swap_end) @@ -99,21 +43,6 @@ IPC_STRUCT_TRAITS_MEMBER(timings) IPC_STRUCT_TRAITS_END() -IPC_STRUCT_TRAITS_BEGIN(gfx::PresentationFeedback) - IPC_STRUCT_TRAITS_MEMBER(timestamp) - IPC_STRUCT_TRAITS_MEMBER(interval) - IPC_STRUCT_TRAITS_MEMBER(flags) -IPC_STRUCT_TRAITS_END() - -IPC_STRUCT_TRAITS_BEGIN(gfx::GpuFenceHandle) -#if BUILDFLAG(IS_POSIX) - IPC_STRUCT_TRAITS_MEMBER(owned_fd) -#endif -#if BUILDFLAG(IS_WIN) - IPC_STRUCT_TRAITS_MEMBER(owned_handle) -#endif -IPC_STRUCT_TRAITS_END() - #undef IPC_MESSAGE_EXPORT #define IPC_MESSAGE_EXPORT
diff --git a/ui/gfx/selection_bound.h b/ui/gfx/selection_bound.h index d2ab84c..55dd611 100644 --- a/ui/gfx/selection_bound.h +++ b/ui/gfx/selection_bound.h
@@ -78,6 +78,12 @@ GFX_EXPORT gfx::RectF RectFBetweenVisibleSelectionBounds( const SelectionBound& b1, const SelectionBound& b2); -} // namespace ui + +// This is declared here for use in gtest-based unit tests but is defined in +// the //ui/gfx:test_support target. Depend on that to use this in your unit +// test. This should not be used in production code - call ToString() instead. +void PrintTo(const SelectionBound& bound, ::std::ostream* os); + +} // namespace gfx #endif // UI_GFX_SELECTION_BOUND_H_
diff --git a/ui/views/controls/combobox/combobox.cc b/ui/views/controls/combobox/combobox.cc index 8ece700..1be7478 100644 --- a/ui/views/controls/combobox/combobox.cc +++ b/ui/views/controls/combobox/combobox.cc
@@ -432,6 +432,9 @@ } if (new_index.has_value()) { + if (menu_selection_at_callback_) + menu_selection_at_callback_.Run(new_index.value()); + SetSelectedIndex(new_index); OnPerformAction(); }
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc index 4e751b3..2b1429f 100644 --- a/ui/views/widget/native_widget_aura.cc +++ b/ui/views/widget/native_widget_aura.cc
@@ -597,9 +597,6 @@ } bool NativeWidgetAura::IsStackedAbove(gfx::NativeView native_view) { - if (!window_) - return false; - // If the root windows are not shared between two native views // it is likely that they are child windows of different top level windows. // In that scenario, just check the top level windows.
diff --git a/ui/views/widget/native_widget_mac.mm b/ui/views/widget/native_widget_mac.mm index 50c4b63..6f7fff2 100644 --- a/ui/views/widget/native_widget_mac.mm +++ b/ui/views/widget/native_widget_mac.mm
@@ -550,9 +550,6 @@ } bool NativeWidgetMac::IsStackedAbove(gfx::NativeView native_view) { - if (!GetNSWindowMojo()) - return false; - // -[NSApplication orderedWindows] are ordered front-to-back. NSWindow* first = GetNativeWindow().GetNativeNSWindow(); NSWindow* second = [native_view.GetNativeNSView() window];
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc index 8e2d497..a29153a 100644 --- a/ui/views/widget/widget.cc +++ b/ui/views/widget/widget.cc
@@ -321,9 +321,6 @@ void Widget::Init(InitParams params) { TRACE_EVENT0("views", "Widget::Init"); - DCHECK(!native_widget_initialized_) - << "This widget has already been initialized"; - if (params.name.empty() && params.delegate) { params.name = params.delegate->internal_name(); // If an internal name was not provided the class name of the contents view @@ -1345,16 +1342,10 @@ // Widget, NativeWidgetDelegate implementation: bool Widget::IsModal() const { - if (!widget_delegate_) - return false; - return widget_delegate_->GetModalType() != ui::MODAL_TYPE_NONE; } bool Widget::IsDialogBox() const { - if (!widget_delegate_) - return false; - return !!widget_delegate_->AsDialogDelegate(); }
diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc index 37ea31c..f440d3cf 100644 --- a/ui/views/widget/widget_unittest.cc +++ b/ui/views/widget/widget_unittest.cc
@@ -1059,16 +1059,6 @@ widget()->Hide(); } -TEST_P(WidgetWithDestroyedNativeViewTest, Init) { - Widget::InitParams params; - EXPECT_DEATH_IF_SUPPORTED({ widget()->Init(std::move(params)); }, - "This widget has already been initialized"); -} - -TEST_P(WidgetWithDestroyedNativeViewTest, is_secondary_widget) { - widget()->is_secondary_widget(); -} - TEST_P(WidgetWithDestroyedNativeViewTest, IsActive) { widget()->IsActive(); } @@ -1077,10 +1067,6 @@ widget()->IsClosed(); } -TEST_P(WidgetWithDestroyedNativeViewTest, IsDialogBox) { - widget()->IsDialogBox(); -} - TEST_P(WidgetWithDestroyedNativeViewTest, IsFullscreen) { widget()->IsFullscreen(); } @@ -1089,31 +1075,10 @@ widget()->IsMaximized(); } -TEST_P(WidgetWithDestroyedNativeViewTest, IsMinimized) { - widget()->IsMinimized(); -} - -TEST_P(WidgetWithDestroyedNativeViewTest, IsModal) { - widget()->IsModal(); -} - TEST_P(WidgetWithDestroyedNativeViewTest, IsMouseEventsEnabled) { widget()->IsMouseEventsEnabled(); } -TEST_P(WidgetWithDestroyedNativeViewTest, IsMoveLoopSupported) { - widget()->IsMoveLoopSupported(); -} - -TEST_P(WidgetWithDestroyedNativeViewTest, IsNativeWidgetInitialized) { - widget()->IsNativeWidgetInitialized(); -} - -TEST_P(WidgetWithDestroyedNativeViewTest, IsStackedAbove) { - std::unique_ptr<Widget> other_widget = CreateTestWidget(); - widget()->IsStackedAbove(other_widget->GetNativeView()); -} - TEST_P(WidgetWithDestroyedNativeViewTest, IsTranslucentWindowOpacitySupported) { widget()->IsTranslucentWindowOpacitySupported(); } @@ -1122,10 +1087,6 @@ widget()->IsVisible(); } -TEST_P(WidgetWithDestroyedNativeViewTest, IsVisibleOnAllWorkspaces) { - widget()->IsVisibleOnAllWorkspaces(); -} - TEST_P(WidgetWithDestroyedNativeViewTest, Maximize) { widget()->Maximize(); }