diff --git a/DEPS b/DEPS index 4e7e483..2d9ecece5 100644 --- a/DEPS +++ b/DEPS
@@ -307,7 +307,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '78c0f267c137a64fa233a198496eef10470b9e78', + 'skia_revision': '4cf2c682d5a75a8505633beacf1116f34829254d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -315,7 +315,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '1acf75726c9044e448c7415b5ad602f11df68fc8', + 'angle_revision': '9f693aa383b2d3ef32179cfefa253db5ddb8c1bb', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -386,7 +386,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': 'c307f39005a4c3ce708b8177148b099854a4de9c', + 'devtools_frontend_revision': 'a2189961b6f7f52d2154aa46d421c1ef594c1538', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -817,7 +817,7 @@ 'src/clank': { 'url': 'https://chrome-internal.googlesource.com/clank/internal/apps.git' + '@' + - '4eee750653bada2db85ea07433aeceb8af486db5', + 'f148bb485a5fb167266582ad9b257aa4739a9604', 'condition': 'checkout_android and checkout_src_internal and not checkout_clank_via_src_internal', }, @@ -1216,7 +1216,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' + '@' + '1cf7275d263df398ffe8ddb5560910fb4a71d874', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'f22595bdc3d7cc620d7310b3e2ba40e23448e806', 'condition': 'checkout_chromeos', }, @@ -1250,7 +1250,7 @@ Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + '97f91787281d208a642e37952e3fc2719af49443', + 'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + '1a9a2794f54b2b05d8260bf4b4f2ba7ef75d4585', 'condition': 'checkout_src_internal', }, @@ -1645,7 +1645,7 @@ }, 'src/third_party/openh264/src': - Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'fac04ceb3e966f613ed17e98178e9d690280bba6', + Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'db956674bbdfbaab5acdd3fdb4117c2fef5527e9', 'src/third_party/openscreen/src': Var('chromium_git') + '/openscreen' + '@' + '9be5eefa2605408a671cc11c695849400caecbbb', @@ -1665,7 +1665,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'cb8281edbb0e244234ce27dbf69b71c1334bc836', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '0cbb37ad93ee2bfcf4c1b0bc3e136eadbe4fb467', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1719,7 +1719,7 @@ 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'nZ7XBCAvVQaWVGQ5BLbVxRo-_KDC3r-9kQTcPquc2t8C', + 'version': 'zoicZU9zhNbJmgq7fa0FZxcPTPlmRi907Rn2MZ21rAsC', }, ], 'condition': 'checkout_android', @@ -1847,10 +1847,10 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'd1b65aa5a88f6efd900604dfcda840154e9f16e2', 'src/third_party/webgpu-cts/src': - Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'e113fd4de43cad41296384876a20b5937c117438', + Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '0f0cf479db365038b57a90403c3df7bc12937a7f', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'af512281b1b35759155b4151e8bf83467c28533c', + Var('webrtc_git') + '/src.git' + '@' + '4a3f26198d094c7b2cf0f65b755f33f20916c66c', # 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. @@ -1920,7 +1920,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0b1180978e38034fbe6694690ed0018a16fee5b4', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3d3673317c682c363504cc9cc07285884922527b', 'condition': 'checkout_src_internal', }, @@ -1950,7 +1950,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': '08bGj6dkBPAAsEKExEeVdDsCNDOXVDGkhFy_Rd7t4n8C', + 'version': 'GbzYVUZYWJYHgcr2RXp9eqqN6-oAX2Karf0qE58fvHoC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1961,7 +1961,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'vGJzNTqAywikH3aqgvFEvCcDhs2n4qH_TBGyglkgReMC', + 'version': '4jOgw4WTfNaMhARYeJ2738V8-pO80fUOjQIJ8jY-iJgC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/browser/gfx/browser_view_renderer.cc b/android_webview/browser/gfx/browser_view_renderer.cc index 54066e4..fed4a4f 100644 --- a/android_webview/browser/gfx/browser_view_renderer.cc +++ b/android_webview/browser/gfx/browser_view_renderer.cc
@@ -193,7 +193,7 @@ external_draw_constraints_.transform; gfx::Rect viewport_rect_for_tile_priority_in_view_space; - gfx::Transform screen_to_view(gfx::Transform::kSkipInitialization); + gfx::Transform screen_to_view; if (transform_for_tile_priority.GetInverse(&screen_to_view)) { // Convert from screen space to view space. viewport_rect_for_tile_priority_in_view_space =
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index dc401063..4e49373 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -538,8 +538,6 @@ "focus_cycler.h", "frame/frame_context_menu_controller.cc", "frame/frame_context_menu_controller.h", - "frame/header_view.cc", - "frame/header_view.h", "frame/non_client_frame_view_ash.cc", "frame/non_client_frame_view_ash.h", "frame/snap_controller_impl.cc",
diff --git a/ash/accessibility/magnifier/fullscreen_magnifier_controller.cc b/ash/accessibility/magnifier/fullscreen_magnifier_controller.cc index a864ffd..a34cdd7 100644 --- a/ash/accessibility/magnifier/fullscreen_magnifier_controller.cc +++ b/ash/accessibility/magnifier/fullscreen_magnifier_controller.cc
@@ -793,10 +793,8 @@ display::Screen::GetScreen()->GetDisplayNearestWindow(root_window_); gfx::Transform rotation_transform; rotation_transform.Rotate(display.PanelRotationAsDegree()); - gfx::Transform rotation_inverse_transform; - const bool result = - rotation_transform.GetInverse(&rotation_inverse_transform); - DCHECK(result); + gfx::Transform rotation_inverse_transform = + rotation_transform.GetCheckedInverse(); gfx::PointF scroll = rotation_inverse_transform.MapPoint( gfx::PointF(details.scroll_x(), details.scroll_y()));
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc index 8d394c4..a84fb82 100644 --- a/ash/app_list/app_list_controller_impl.cc +++ b/ash/app_list/app_list_controller_impl.cc
@@ -207,31 +207,6 @@ return Shell::Get()->session_controller()->GetLastActiveUserPrefService(); } -int GetSuggestedContentInfoShownCount() { - PrefService* prefs = GetLastActiveUserPrefService(); - return prefs->GetInteger(prefs::kSuggestedContentInfoShownInLauncher); -} - -void SetSuggestedContentInfoShownCount(int count) { - PrefService* prefs = GetLastActiveUserPrefService(); - prefs->SetInteger(prefs::kSuggestedContentInfoShownInLauncher, count); -} - -bool IsSuggestedContentInfoDismissed() { - PrefService* prefs = GetLastActiveUserPrefService(); - return prefs->GetBoolean(prefs::kSuggestedContentInfoDismissedInLauncher); -} - -void SetSuggestedContentInfoDismissed() { - PrefService* prefs = GetLastActiveUserPrefService(); - prefs->SetBoolean(prefs::kSuggestedContentInfoDismissedInLauncher, true); -} - -bool IsSuggestedContentEnabled() { - PrefService* prefs = GetLastActiveUserPrefService(); - return prefs->GetBoolean(chromeos::prefs::kSuggestedContentEnabled); -} - // Gets the MRU window shown over the applist when in tablet mode. // Returns nullptr if no windows are shown over the applist. aura::Window* GetTopVisibleWindow() { @@ -329,12 +304,6 @@ // static void AppListControllerImpl::RegisterProfilePrefs(PrefRegistrySimple* registry) { - registry->RegisterIntegerPref( - prefs::kSuggestedContentInfoShownInLauncher, 0, - user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF); - registry->RegisterBooleanPref( - prefs::kSuggestedContentInfoDismissedInLauncher, false, - user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF); registry->RegisterBooleanPref( prefs::kLauncherFeedbackOnContinueSectionSent, false, user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF); @@ -1390,13 +1359,6 @@ client_->OnSearchResultVisibilityChanged(id, visibility); } -void AppListControllerImpl::MaybeIncreaseSuggestedContentInfoShownCount() { - if (ShouldShowSuggestedContentInfo()) { - const int count = GetSuggestedContentInfoShownCount(); - SetSuggestedContentInfoShownCount(count + 1); - } -} - bool AppListControllerImpl::IsAssistantAllowedAndEnabled() const { if (!Shell::Get()->assistant_controller()->IsAssistantReady()) return false; @@ -1407,27 +1369,6 @@ state->assistant_status() != assistant::AssistantStatus::NOT_READY; } -bool AppListControllerImpl::ShouldShowSuggestedContentInfo() const { - if (!IsSuggestedContentEnabled()) { - // Don't show if user has interacted with the setting already. - SetSuggestedContentInfoDismissed(); - return false; - } - - if (IsSuggestedContentInfoDismissed()) { - return false; - } - - const int count = GetSuggestedContentInfoShownCount(); - constexpr int kThresholdToShow = 3; - return count >= 0 && count <= kThresholdToShow; -} - -void AppListControllerImpl::MarkSuggestedContentInfoDismissed() { - // User dismissed the privacy info view. Will not show the view again. - SetSuggestedContentInfoDismissed(); -} - void AppListControllerImpl::OnStateTransitionAnimationCompleted( AppListViewState state, bool was_animation_interrupted) {
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h index cb2383e..9fce936 100644 --- a/ash/app_list/app_list_controller_impl.h +++ b/ash/app_list/app_list_controller_impl.h
@@ -182,10 +182,7 @@ AssistantViewDelegate* GetAssistantViewDelegate() override; void OnSearchResultVisibilityChanged(const std::string& id, bool visibility) override; - void MaybeIncreaseSuggestedContentInfoShownCount() override; bool IsAssistantAllowedAndEnabled() const override; - bool ShouldShowSuggestedContentInfo() const override; - void MarkSuggestedContentInfoDismissed() override; void OnStateTransitionAnimationCompleted( AppListViewState state, bool was_animation_interrupted) override;
diff --git a/ash/app_list/app_list_presenter_unittest.cc b/ash/app_list/app_list_presenter_unittest.cc index 008a32d..faa4fde 100644 --- a/ash/app_list/app_list_presenter_unittest.cc +++ b/ash/app_list/app_list_presenter_unittest.cc
@@ -3210,10 +3210,6 @@ ResultSelectionController* result_selection_controller = GetResultSelectionController(); - // Mark the suggested content info as dismissed so that it does not interfere - // with the layout for the selection traversal. - Shell::Get()->app_list_controller()->MarkSuggestedContentInfoDismissed(); - // Add search results to the search model. SearchModel* search_model = GetSearchModel(); search_model->results()->Add(CreateOmniboxSuggestionResult("Suggestion1"));
diff --git a/ash/app_list/app_list_test_view_delegate.cc b/ash/app_list/app_list_test_view_delegate.cc index 7aefc5f..036c2f9 100644 --- a/ash/app_list/app_list_test_view_delegate.cc +++ b/ash/app_list/app_list_test_view_delegate.cc
@@ -88,11 +88,6 @@ is_tablet_mode_ = is_tablet_mode; } -void AppListTestViewDelegate::SetShouldShowSuggestedContentInfo( - bool should_show) { - should_show_suggested_content_info_ = should_show; -} - void AppListTestViewDelegate::ActivateItem( const std::string& id, int event_flags, @@ -173,20 +168,10 @@ const std::string& id, bool visibility) {} -void AppListTestViewDelegate::MaybeIncreaseSuggestedContentInfoShownCount() {} - bool AppListTestViewDelegate::IsAssistantAllowedAndEnabled() const { return false; } -bool AppListTestViewDelegate::ShouldShowSuggestedContentInfo() const { - return should_show_suggested_content_info_; -} - -void AppListTestViewDelegate::MarkSuggestedContentInfoDismissed() { - should_show_suggested_content_info_ = false; -} - void AppListTestViewDelegate::OnStateTransitionAnimationCompleted( AppListViewState state, bool was_animation_interrupted) {}
diff --git a/ash/app_list/app_list_test_view_delegate.h b/ash/app_list/app_list_test_view_delegate.h index b6c6c8f..9e9bfd35 100644 --- a/ash/app_list/app_list_test_view_delegate.h +++ b/ash/app_list/app_list_test_view_delegate.h
@@ -58,9 +58,6 @@ // Set whether tablet mode is enabled. void SetIsTabletModeEnabled(bool is_tablet_mode); - // Set whether the suggested content info should be shown. - void SetShouldShowSuggestedContentInfo(bool should_show); - // AppListViewDelegate overrides: bool KeyboardTraversalEngaged() override; void StartAssistant() override {} @@ -97,10 +94,7 @@ ash::AssistantViewDelegate* GetAssistantViewDelegate() override; void OnSearchResultVisibilityChanged(const std::string& id, bool visibility) override; - void MaybeIncreaseSuggestedContentInfoShownCount() override; bool IsAssistantAllowedAndEnabled() const override; - bool ShouldShowSuggestedContentInfo() const override; - void MarkSuggestedContentInfoDismissed() override; void OnStateTransitionAnimationCompleted( AppListViewState state, bool was_animation_interrupted) override; @@ -145,7 +139,6 @@ AppListState app_list_page_ = AppListState::kInvalidState; AppListViewState app_list_view_state_ = AppListViewState::kClosed; bool is_tablet_mode_ = false; - bool should_show_suggested_content_info_ = false; std::map<size_t, int> open_search_result_counts_; AppListModelProvider model_provider_; std::unique_ptr<AppListTestModel> model_;
diff --git a/ash/app_list/app_list_view_delegate.h b/ash/app_list/app_list_view_delegate.h index a091a4a..9f3d9935 100644 --- a/ash/app_list/app_list_view_delegate.h +++ b/ash/app_list/app_list_view_delegate.h
@@ -143,20 +143,9 @@ virtual void OnSearchResultVisibilityChanged(const std::string& id, bool visibility) = 0; - // If the |prefs::kSuggestedContentInfoShownInLauncher| value is in the range - // of allowed values, we will increment it. - virtual void MaybeIncreaseSuggestedContentInfoShownCount() = 0; - // Returns true if the Assistant feature is allowed and enabled. virtual bool IsAssistantAllowedAndEnabled() const = 0; - // Returns true if the Suggested Content privacy info view should be shown. - virtual bool ShouldShowSuggestedContentInfo() const = 0; - - // Called when close button in the Suggested Content privacy info view is - // pressed to indicate not to show the view any more. - virtual void MarkSuggestedContentInfoDismissed() = 0; - // Gets the app list page currently shown in the fullscreen app list, as // reported from the app list view using `OnAppListPageChanged()`. virtual AppListState GetCurrentAppListPage() const = 0;
diff --git a/ash/app_list/model/app_list_model_unittest.cc b/ash/app_list/model/app_list_model_unittest.cc index 9e251f5..d64a570 100644 --- a/ash/app_list/model/app_list_model_unittest.cc +++ b/ash/app_list/model/app_list_model_unittest.cc
@@ -270,13 +270,8 @@ model_->MergeItems(item0->id(), folder->id()); } -// Same test as above, but for ProductivityLauncher config types. -TEST_F(AppListModelFolderTest, - NonSharedConfigIconGenerationProductivityLauncher) { - // The configs tested here are only used by ProductivityLauncher. - base::test::ScopedFeatureList features; - features.InitAndEnableFeature(features::kProductivityLauncher); - +// Tests Icon generation configuration for folders on different grid types. +TEST_F(AppListModelFolderTest, NonSharedConfigIconGeneration) { // Ensure any configs set by previous tests are cleared. AppListConfigProvider::Get().ResetForTesting();
diff --git a/ash/app_list/views/app_list_folder_view_unittest.cc b/ash/app_list/views/app_list_folder_view_unittest.cc index 2698d2f..660dd47 100644 --- a/ash/app_list/views/app_list_folder_view_unittest.cc +++ b/ash/app_list/views/app_list_folder_view_unittest.cc
@@ -11,21 +11,19 @@ #include "ash/app_list/test/app_list_test_helper.h" #include "ash/app_list/views/app_list_a11y_announcer.h" #include "ash/app_list/views/scrollable_apps_grid_view.h" -#include "ash/constants/ash_features.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "base/test/bind.h" -#include "base/test/scoped_feature_list.h" #include "ui/events/keycodes/keyboard_codes_posix.h" #include "ui/views/accessibility/view_accessibility.h" #include "ui/views/controls/scroll_view.h" namespace ash { -class AppListFolderViewProductivityLauncherTest : public AshTestBase { +class AppListFolderViewTest : public AshTestBase { public: - AppListFolderViewProductivityLauncherTest() = default; - ~AppListFolderViewProductivityLauncherTest() override = default; + AppListFolderViewTest() = default; + ~AppListFolderViewTest() override = default; // testing::Test: void SetUp() override { @@ -37,13 +35,11 @@ /*profile_id=*/1, app_list_test_model_.get(), search_model_.get()); } - base::test::ScopedFeatureList feature_list_{features::kProductivityLauncher}; std::unique_ptr<test::AppListTestModel> app_list_test_model_; std::unique_ptr<SearchModel> search_model_; }; -TEST_F(AppListFolderViewProductivityLauncherTest, - ScrollViewSizeIsCappedForLargeFolders) { +TEST_F(AppListFolderViewTest, ScrollViewSizeIsCappedForLargeFolders) { // Create a large number of apps, more than a 4 rows. app_list_test_model_->CreateAndPopulateFolderWithApps(30); @@ -65,8 +61,7 @@ EXPECT_LT(scroll_view->height(), tile_height * 5); } -TEST_F(AppListFolderViewProductivityLauncherTest, - CloseFolderMakesA11yAnnouncement) { +TEST_F(AppListFolderViewTest, CloseFolderMakesA11yAnnouncement) { // Create a folder with a couple items. app_list_test_model_->CreateAndPopulateFolderWithApps(2);
diff --git a/ash/app_list/views/app_list_item_view_unittest.cc b/ash/app_list/views/app_list_item_view_unittest.cc index 7c03b33..6f6857f 100644 --- a/ash/app_list/views/app_list_item_view_unittest.cc +++ b/ash/app_list/views/app_list_item_view_unittest.cc
@@ -9,10 +9,8 @@ #include "ash/app_list/test/app_list_test_helper.h" #include "ash/app_list/views/paged_apps_grid_view.h" #include "ash/app_list/views/scrollable_apps_grid_view.h" -#include "ash/constants/ash_features.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" -#include "base/test/scoped_feature_list.h" #include "ui/accessibility/ax_enums.mojom-shared.h" #include "ui/accessibility/ax_node_data.h" #include "ui/views/controls/label.h" @@ -48,18 +46,7 @@ std::unique_ptr<SearchModel> search_model_; }; -// Tests with ProductivityLauncher enabled. -class AppListItemViewProductivityLauncherTest : public AppListItemViewTest { - public: - AppListItemViewProductivityLauncherTest() { - feature_list_.InitAndEnableFeature(features::kProductivityLauncher); - } - ~AppListItemViewProductivityLauncherTest() override = default; - - base::test::ScopedFeatureList feature_list_; -}; - -TEST_F(AppListItemViewProductivityLauncherTest, NewInstallDot) { +TEST_F(AppListItemViewTest, NewInstallDot) { AppListItem* item = CreateAppListItem("Google Buzz"); ASSERT_FALSE(item->is_new_install()); @@ -89,7 +76,7 @@ "New install"); } -TEST_F(AppListItemViewProductivityLauncherTest, LabelInsetWithNewInstallDot) { +TEST_F(AppListItemViewTest, LabelInsetWithNewInstallDot) { AppListItem* long_item = CreateAppListItem("Very very very very long name"); long_item->SetIsNewInstall(true); AppListItem* short_item = CreateAppListItem("Short");
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc index 7d1e01eb..de549e9 100644 --- a/ash/app_list/views/app_list_view.cc +++ b/ash/app_list/views/app_list_view.cc
@@ -737,20 +737,6 @@ } } -void AppListView::MaybeIncreasePrivacyInfoRowShownCounts( - AppListViewState new_state) { - AppListStateTransitionSource transition = - GetAppListStateTransitionSource(new_state); - switch (transition) { - case kFullscreenAllAppsToFullscreenSearch: - if (app_list_main_view()->contents_view()->IsShowingSearchResults()) - delegate_->MaybeIncreaseSuggestedContentInfoShownCount(); - break; - default: - break; - } -} - void AppListView::RecordStateTransitionForUma(AppListViewState new_state) { AppListStateTransitionSource transition = GetAppListStateTransitionSource(new_state); @@ -1005,7 +991,6 @@ state_transition_notifier_->Reset(new_state); StartAnimationForState(new_state); - MaybeIncreasePrivacyInfoRowShownCounts(new_state); RecordStateTransitionForUma(new_state); app_list_state_ = new_state; if (delegate_)
diff --git a/ash/app_list/views/app_list_view.h b/ash/app_list/views/app_list_view.h index c9ff9cf..034bced 100644 --- a/ash/app_list/views/app_list_view.h +++ b/ash/app_list/views/app_list_view.h
@@ -339,8 +339,6 @@ // in progress it will be interrupted. void StartAnimationForState(AppListViewState new_state); - void MaybeIncreasePrivacyInfoRowShownCounts(AppListViewState new_state); - // Applies a bounds animation on this views layer. void ApplyBoundsAnimation(AppListViewState target_state, base::TimeDelta duration_ms);
diff --git a/ash/app_list/views/app_list_view_unittest.cc b/ash/app_list/views/app_list_view_unittest.cc index 6155cad..c1ee1d5 100644 --- a/ash/app_list/views/app_list_view_unittest.cc +++ b/ash/app_list/views/app_list_view_unittest.cc
@@ -507,17 +507,6 @@ keyboard::KeyboardUIController keyboard_ui_controller_; }; -// Tests for the legacy "peeking" clamshell launcher. These can be deleted when -// ProductivityLauncher is the default. -class AppListViewPeekingTest : public AppListViewTest { - public: - AppListViewPeekingTest() { - feature_list_.InitAndDisableFeature(features::kProductivityLauncher); - } - - base::test::ScopedFeatureList feature_list_; -}; - // Tests app list view layout for different screen sizes. class AppListViewScalableLayoutTest : public AppListViewTest { public: @@ -881,17 +870,6 @@ INSTANTIATE_TEST_SUITE_P(Rtl, AppListViewFocusTest, testing::Bool()); -// Tests for the legacy "peeking" clamshell launcher. These can be deleted when -// ProductivityLauncher is the default. -class AppListViewPeekingFocusTest : public AppListViewFocusTest { - public: - AppListViewPeekingFocusTest() { - feature_list_.InitAndDisableFeature(features::kProductivityLauncher); - } - - base::test::ScopedFeatureList feature_list_; -}; - // Tests that the initial focus is on search box. TEST_F(AppListViewFocusTest, InitialFocus) { EXPECT_EQ(search_box_view()->search_box(), focused_view()); @@ -1318,15 +1296,6 @@ EXPECT_EQ(folder_item_view(), focused_view()); } -// Tests that opening the app list opens in fullscreen mode by default. -TEST_F(AppListViewPeekingTest, ShowFullscreenByDefault) { - Initialize(false /*is_tablet_mode*/); - - Show(); - - ASSERT_EQ(ash::AppListViewState::kFullscreenAllApps, view_->app_list_state()); -} - // Tests that in tablet mode, the app list opens in fullscreen by default. TEST_F(AppListViewTest, ShowFullscreenWhenInTabletMode) { Initialize(/*is_tablet_mode=*/true); @@ -1336,23 +1305,12 @@ ASSERT_EQ(ash::AppListViewState::kFullscreenAllApps, view_->app_list_state()); } -// Tests that setting empty text in the search box does not change the state. -TEST_F(AppListViewPeekingTest, EmptySearchTextStaysAtFullscreenAllApps) { - Initialize(false /*is_tablet_mode*/); - views::Textfield* search_box = - view_->app_list_main_view()->search_box_view()->search_box(); - - Show(); - search_box->SetText(std::u16string()); - - ASSERT_EQ(ash::AppListViewState::kFullscreenAllApps, view_->app_list_state()); -} - // Tests that typing when in fullscreen changes the state to fullscreen search. -TEST_F(AppListViewPeekingTest, TypingFullscreenToFullscreenSearch) { - Initialize(false /*is_tablet_mode*/); +TEST_F(AppListViewTest, TypingFullscreenToFullscreenSearch) { + Initialize(true /*is_tablet_mode*/); Show(); + view_->SetState(AppListViewState::kFullscreenAllApps); views::Textfield* search_box = view_->app_list_main_view()->search_box_view()->search_box(); @@ -1378,17 +1336,6 @@ EXPECT_EQ(ash::AppListViewState::kFullscreenSearch, view_->app_list_state()); } -// Tests that pressing escape when in fullscreen side-shelf closes the app list. -TEST_F(AppListViewPeekingTest, EscapeKeySideShelfFullscreenToClosed) { - // Put into fullscreen by using side-shelf. - Initialize(false /*is_tablet_mode*/); - - Show(/*is_side_shelf=*/true); - view_->AcceleratorPressed(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); - - ASSERT_EQ(1, delegate_->dismiss_count()); -} - // Tests that pressing escape when in tablet mode keeps app list in fullscreen. TEST_F(AppListViewTest, EscapeKeyTabletModeStayFullscreen) { // Put into fullscreen by using tablet mode. @@ -1445,27 +1392,6 @@ ASSERT_EQ(ash::AppListViewState::kFullscreenAllApps, view_->app_list_state()); } -// Tests that opening in fullscreen mode sets the correct height. -TEST_F(AppListViewPeekingTest, OpenInFullscreenCorrectHeight) { - Initialize(false /*is_tablet_mode*/); - - Show(); - const int y = view_->GetWidget()->GetWindowBoundsInScreen().y(); - ASSERT_EQ(0, y); -} - -// Tests that AppListView::SetState succeeds when the state has been set to -// CLOSED. -TEST_F(AppListViewPeekingTest, SetStateFailsWhenClosing) { - Initialize(false /*is_tablet_mode*/); - Show(); - view_->SetState(ash::AppListViewState::kClosed); - - view_->SetState(ash::AppListViewState::kFullscreenAllApps); - - ASSERT_EQ(ash::AppListViewState::kFullscreenAllApps, view_->app_list_state()); -} - TEST_F(AppListViewTest, AppsGridViewVisibilityOnReopening) { Initialize(/*is_tablet_mode=*/true); Show(); @@ -1482,30 +1408,6 @@ // Tests displaying the app list and performs a standard set of checks on its // top level views. -TEST_F(AppListViewPeekingTest, DisplayTest) { - Initialize(/*is_tablet_mode=*/false); - EXPECT_EQ(-1, GetPaginationModel()->total_pages()); - delegate_->GetTestModel()->PopulateApps(kInitialItems); - - Show(); - - // |view_| bounds equal to the root window's size. - EXPECT_EQ("800x600", view_->bounds().size().ToString()); - - EXPECT_EQ(2, GetPaginationModel()->total_pages()); - EXPECT_EQ(0, GetPaginationModel()->selected_page()); - - // Checks on the main view. - AppListMainView* main_view = view_->app_list_main_view(); - EXPECT_NO_FATAL_FAILURE(CheckView(main_view)); - EXPECT_NO_FATAL_FAILURE(CheckView(main_view->contents_view())); - - ash::AppListState expected = ash::AppListState::kStateApps; - EXPECT_TRUE(main_view->contents_view()->IsStateActive(expected)); - EXPECT_EQ(expected, delegate_->GetCurrentAppListPage()); -} - -// As above above, but tests tablet mode with and without ProductivityLauncher. TEST_F(AppListViewTest, DisplayTest) { Initialize(/*is_tablet_mode=*/true); EXPECT_EQ(-1, GetPaginationModel()->total_pages()); @@ -1668,33 +1570,6 @@ EXPECT_TRUE(view_->GetWidget()->IsVisible()); } -// Tests that context menus are not shown between app icons in clamshell mode. -TEST_F(AppListViewPeekingTest, DontShowContextMenuBetweenAppsInClamshellMode) { - Initialize(false /* disable tablet mode */); - delegate_->GetTestModel()->PopulateApps(kInitialItems); - Show(); - - // Tap between two apps in clamshell mode. - const gfx::Point middle = GetPointBetweenTwoApps(); - ui::GestureEvent tap(middle.x(), middle.y(), 0, base::TimeTicks(), - ui::GestureEventDetails(ui::ET_GESTURE_TWO_FINGER_TAP)); - view_->OnGestureEvent(&tap); - - // The wallpaper menu should not show. - EXPECT_EQ(0, show_wallpaper_context_menu_count()); - EXPECT_TRUE(view_->GetWidget()->IsVisible()); - - // Right click between two apps in clamshell mode. - ui::MouseEvent mouse_event(ui::ET_MOUSE_PRESSED, middle, middle, - ui::EventTimeForNow(), ui::EF_RIGHT_MOUSE_BUTTON, - ui::EF_RIGHT_MOUSE_BUTTON); - view_->OnMouseEvent(&mouse_event); - - // The wallpaper menu should not show. - EXPECT_EQ(0, show_wallpaper_context_menu_count()); - EXPECT_TRUE(view_->GetWidget()->IsVisible()); -} - // Tests the back action in home launcher. TEST_F(AppListViewTest, BackAction) { // Put into fullscreen using tablet mode.
diff --git a/ash/app_list/views/productivity_launcher_search_view_unittest.cc b/ash/app_list/views/productivity_launcher_search_view_unittest.cc index d228644..6504c941 100644 --- a/ash/app_list/views/productivity_launcher_search_view_unittest.cc +++ b/ash/app_list/views/productivity_launcher_search_view_unittest.cc
@@ -56,9 +56,7 @@ public: ProductivityLauncherSearchViewTest() : AshTestBase((base::test::TaskEnvironment::TimeSource::MOCK_TIME)), - test_under_tablet_(GetParam()) { - scoped_feature_list_.InitAndEnableFeature(features::kProductivityLauncher); - } + test_under_tablet_(GetParam()) {} ProductivityLauncherSearchViewTest( const ProductivityLauncherSearchViewTest&) = delete; ProductivityLauncherSearchViewTest& operator=( @@ -164,7 +162,6 @@ private: const bool test_under_tablet_; - base::test::ScopedFeatureList scoped_feature_list_; }; // An extension of ProductivityLauncherSearchViewTest to test launcher image
diff --git a/ash/constants/ash_pref_names.cc b/ash/constants/ash_pref_names.cc index 7c83925..0b228b3 100644 --- a/ash/constants/ash_pref_names.cc +++ b/ash/constants/ash_pref_names.cc
@@ -966,14 +966,6 @@ const char kUsbPeripheralCableSpeedNotificationShown[] = "ash.usb_peripheral_cable_speed_notification_shown"; -// An integer pref that specifies how many times the Suggested Content privacy -// info has been shown in Launcher. This value will increment by one every time -// when Launcher changes state from Peeking to Half or FullscreenSearch up to a -// predefined threshold, e.g. six times. If the info has been shown for more -// than the threshold, do not show the privacy info any more. -const char kSuggestedContentInfoShownInLauncher[] = - "ash.launcher.suggested_content_info_shown"; - // A dictionary value that determines whether the reorder nudge in app list // should show to the users. const char kAppListReorderNudge[] = "ash.launcher.app_list_reorder_nudge"; @@ -983,14 +975,6 @@ const char kLauncherFilesPrivacyNotice[] = "ash.launcher.continue_section_privacy_notice"; -// A boolean pref that indicates whether the Suggested Content privacy info may -// be displayed to user. A false value indicates that the info can be displayed -// if the value of |kSuggestedContentInfoShownInLauncher| is smaller than the -// predefined threshold. A true value implies that the user has dismissed the -// info view, and do not show the privacy info any more. -const char kSuggestedContentInfoDismissedInLauncher[] = - "ash.launcher.suggested_content_info_dismissed"; - // A boolean pref that indicates whether lock screen media controls are enabled. // Controlled by user policy. const char kLockScreenMediaControlsEnabled[] =
diff --git a/ash/constants/ash_pref_names.h b/ash/constants/ash_pref_names.h index dc27f7b..72b3c8b5 100644 --- a/ash/constants/ash_pref_names.h +++ b/ash/constants/ash_pref_names.h
@@ -432,10 +432,6 @@ extern const char kUsbPeripheralCableSpeedNotificationShown[]; COMPONENT_EXPORT(ASH_CONSTANTS) -extern const char kSuggestedContentInfoShownInLauncher[]; -COMPONENT_EXPORT(ASH_CONSTANTS) -extern const char kSuggestedContentInfoDismissedInLauncher[]; -COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kAppListReorderNudge[]; COMPONENT_EXPORT(ASH_CONSTANTS)
diff --git a/ash/display/output_protection_delegate.cc b/ash/display/output_protection_delegate.cc index 2ad374d8..eab160b 100644 --- a/ash/display/output_protection_delegate.cc +++ b/ash/display/output_protection_delegate.cc
@@ -23,6 +23,12 @@ void MaybeSetCaptureModeWindowProtection(aura::Window* window, uint32_t protection_mask) { + // `OutputProtectionDelegate` is not owned by ash. It is created by + // `OutputProtectionImpl` which exists in Chrome, and can invoke the delegate + // even after `Shell` has been destroyed. See b/256706119. + if (!Shell::HasInstance()) + return; + CaptureModeController::Get()->SetWindowProtectionMask(window, protection_mask); }
diff --git a/ash/fast_ink/cursor/cursor_view.cc b/ash/fast_ink/cursor/cursor_view.cc index 8755bec..afdadaf 100644 --- a/ash/fast_ink/cursor/cursor_view.cc +++ b/ash/fast_ink/cursor/cursor_view.cc
@@ -82,9 +82,8 @@ // Create transform used to convert cursor controller coordinates to screen // coordinates. - bool inversible = host()->window_to_buffer_transform().GetInverse( - &buffer_to_screen_transform_); - DCHECK(inversible); + buffer_to_screen_transform_ = + host()->window_to_buffer_transform().GetCheckedInverse(); ui::CursorController::GetInstance()->AddCursorObserver(this); }
diff --git a/ash/fast_ink/fast_ink_host.cc b/ash/fast_ink/fast_ink_host.cc index d2a050f..8e72fc7fd 100644 --- a/ash/fast_ink/fast_ink_host.cc +++ b/ash/fast_ink/fast_ink_host.cc
@@ -391,9 +391,8 @@ target_to_buffer_transform.Scale(1.f / device_scale_factor, 1.f / device_scale_factor); - gfx::Transform buffer_to_target_transform; - bool rv = target_to_buffer_transform.GetInverse(&buffer_to_target_transform); - DCHECK(rv); + gfx::Transform buffer_to_target_transform = + target_to_buffer_transform.GetCheckedInverse(); const viz::CompositorRenderPassId kRenderPassId{1}; auto render_pass = viz::CompositorRenderPass::Create();
diff --git a/ash/fast_ink/view_tree_host_root_view.cc b/ash/fast_ink/view_tree_host_root_view.cc index 5617ab29..e993fba 100644 --- a/ash/fast_ink/view_tree_host_root_view.cc +++ b/ash/fast_ink/view_tree_host_root_view.cc
@@ -449,9 +449,8 @@ buffer_size_, viz::RGBA_8888, is_overlay_candidate_); transferable_resource.id = id_generator_.GenerateNextId(); - gfx::Transform buffer_to_target_transform; - bool rv = rotate_transform_.GetInverse(&buffer_to_target_transform); - DCHECK(rv); + gfx::Transform buffer_to_target_transform = + rotate_transform_.GetCheckedInverse(); const viz::CompositorRenderPassId kRenderPassId{1}; auto render_pass = viz::CompositorRenderPass::Create();
diff --git a/ash/frame/non_client_frame_view_ash.cc b/ash/frame/non_client_frame_view_ash.cc index 00dedf9..e12fa5b 100644 --- a/ash/frame/non_client_frame_view_ash.cc +++ b/ash/frame/non_client_frame_view_ash.cc
@@ -9,7 +9,6 @@ #include <vector> #include "ash/constants/ash_features.h" -#include "ash/frame/header_view.h" #include "ash/public/cpp/tablet_mode_observer.h" #include "ash/public/cpp/window_properties.h" #include "ash/shell.h" @@ -24,6 +23,7 @@ #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" #include "chromeos/ui/frame/default_frame_header.h" #include "chromeos/ui/frame/frame_utils.h" +#include "chromeos/ui/frame/header_view.h" #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" @@ -157,7 +157,7 @@ public views::ViewTargeterDelegate { public: METADATA_HEADER(OverlayView); - explicit OverlayView(HeaderView* header_view); + explicit OverlayView(chromeos::HeaderView* header_view); OverlayView(const OverlayView&) = delete; OverlayView& operator=(const OverlayView&) = delete; ~OverlayView() override; @@ -170,10 +170,11 @@ bool DoesIntersectRect(const views::View* target, const gfx::Rect& rect) const override; - HeaderView* header_view_; + chromeos::HeaderView* header_view_; }; -NonClientFrameViewAsh::OverlayView::OverlayView(HeaderView* header_view) +NonClientFrameViewAsh::OverlayView::OverlayView( + chromeos::HeaderView* header_view) : header_view_(header_view) { AddChildView(header_view); SetEventTargeter(std::make_unique<views::ViewTargeter>(this)); @@ -213,7 +214,7 @@ NonClientFrameViewAsh::NonClientFrameViewAsh(views::Widget* frame) : frame_(frame), - header_view_(new HeaderView(frame, this)), + header_view_(new chromeos::HeaderView(frame, this)), overlay_view_(new OverlayView(header_view_)), frame_context_menu_controller_( std::make_unique<FrameContextMenuController>(frame, this)) { @@ -279,7 +280,7 @@ header_view_->UpdateCaptionButtons(); } -HeaderView* NonClientFrameViewAsh::GetHeaderView() { +chromeos::HeaderView* NonClientFrameViewAsh::GetHeaderView() { return header_view_; }
diff --git a/ash/frame/non_client_frame_view_ash.h b/ash/frame/non_client_frame_view_ash.h index ffd28ca..b307a15 100644 --- a/ash/frame/non_client_frame_view_ash.h +++ b/ash/frame/non_client_frame_view_ash.h
@@ -9,10 +9,10 @@ #include "ash/ash_export.h" #include "ash/frame/frame_context_menu_controller.h" -#include "ash/frame/header_view.h" #include "ash/wm/overview/overview_observer.h" #include "base/bind.h" #include "base/memory/weak_ptr.h" +#include "chromeos/ui/frame/header_view.h" #include "chromeos/ui/frame/highlight_border_overlay.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/metadata/metadata_header_macros.h" @@ -71,7 +71,7 @@ void SetFrameColors(SkColor active_frame_color, SkColor inactive_frame_color); // Get the view of the header. - HeaderView* GetHeaderView(); + chromeos::HeaderView* GetHeaderView(); // Calculate the client bounds for given window bounds. gfx::Rect GetClientBoundsForWindowBounds( @@ -160,7 +160,7 @@ views::Widget* const frame_; // View which contains the title and window controls. - HeaderView* header_view_ = nullptr; + chromeos::HeaderView* header_view_ = nullptr; OverlayView* overlay_view_ = nullptr;
diff --git a/ash/frame/non_client_frame_view_ash_unittest.cc b/ash/frame/non_client_frame_view_ash_unittest.cc index 3e0d7add..d984175 100644 --- a/ash/frame/non_client_frame_view_ash_unittest.cc +++ b/ash/frame/non_client_frame_view_ash_unittest.cc
@@ -8,7 +8,6 @@ #include "ash/accelerators/accelerator_controller_impl.h" #include "ash/constants/ash_pref_names.h" -#include "ash/frame/header_view.h" #include "ash/frame/wide_frame_view.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/session/session_controller_impl.h" @@ -32,6 +31,7 @@ #include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" #include "chromeos/ui/frame/default_frame_header.h" +#include "chromeos/ui/frame/header_view.h" #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" #include "chromeos/ui/vector_icons/vector_icons.h" @@ -97,7 +97,7 @@ return non_client_frame_view_; } - HeaderView* header_view() const { + chromeos::HeaderView* header_view() const { return non_client_frame_view_->header_view_; } @@ -416,7 +416,7 @@ std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate); NonClientFrameViewAsh* non_client_frame_view = delegate->non_client_frame_view(); - HeaderView* header_view = non_client_frame_view->GetHeaderView(); + chromeos::HeaderView* header_view = non_client_frame_view->GetHeaderView(); EXPECT_FALSE(header_view->in_immersive_mode()); EXPECT_TRUE(header_view->GetVisible()); widget->SetFullscreen(true); @@ -510,7 +510,7 @@ delegate->non_client_frame_view(); non_client_frame_view->SetCaptionButtonModel(std::move(model)); - HeaderView* header_view = non_client_frame_view->GetHeaderView(); + chromeos::HeaderView* header_view = non_client_frame_view->GetHeaderView(); EXPECT_FALSE(header_view->GetBackButton()); model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_BACK, true); non_client_frame_view->SizeConstraintsChanged(); @@ -593,7 +593,7 @@ delegate->non_client_frame_view(); non_client_frame_view->SetCaptionButtonModel(std::move(model)); - HeaderView* header_view = non_client_frame_view->GetHeaderView(); + chromeos::HeaderView* header_view = non_client_frame_view->GetHeaderView(); FrameCaptionButtonContainerView::TestApi test_api( header_view->caption_button_container()); @@ -680,14 +680,14 @@ NonClientFrameViewAsh* non_client_frame_view = delegate->non_client_frame_view(); - HeaderView* header_view = non_client_frame_view->GetHeaderView(); + chromeos::HeaderView* header_view = non_client_frame_view->GetHeaderView(); widget->Maximize(); std::unique_ptr<WideFrameView> wide_frame_view = std::make_unique<WideFrameView>(widget.get()); wide_frame_view->GetWidget()->Show(); - HeaderView* wide_header_view = wide_frame_view->header_view(); + chromeos::HeaderView* wide_header_view = wide_frame_view->header_view(); display::Screen* screen = display::Screen::GetScreen(); const gfx::Rect work_area = screen->GetPrimaryDisplay().work_area(); @@ -760,7 +760,7 @@ std::unique_ptr<WideFrameView> wide_frame_view = std::make_unique<WideFrameView>(widget.get()); wide_frame_view->GetWidget()->Show(); - HeaderView* header_view = wide_frame_view->header_view(); + chromeos::HeaderView* header_view = wide_frame_view->header_view(); FrameCaptionButtonContainerView::TestApi test_api( header_view->caption_button_container()); @@ -952,7 +952,7 @@ std::unique_ptr<WideFrameView> wide_frame_view = std::make_unique<WideFrameView>(widget.get()); - HeaderView* wide_header_view = wide_frame_view->header_view(); + chromeos::HeaderView* wide_header_view = wide_frame_view->header_view(); DefaultFrameHeader* header = wide_header_view->GetFrameHeader(); EXPECT_EQ(new_active_color, header->active_frame_color_for_testing()); EXPECT_EQ(new_inactive_color, header->inactive_frame_color_for_testing());
diff --git a/ash/frame/wide_frame_view.cc b/ash/frame/wide_frame_view.cc index 659c2eb..86a1b85 100644 --- a/ash/frame/wide_frame_view.cc +++ b/ash/frame/wide_frame_view.cc
@@ -5,7 +5,6 @@ #include "ash/frame/wide_frame_view.h" #include <memory> -#include "ash/frame/header_view.h" #include "ash/frame/non_client_frame_view_ash.h" #include "ash/public/cpp/window_properties.h" #include "ash/screen_util.h" @@ -17,6 +16,7 @@ #include "base/metrics/user_metrics.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" #include "chromeos/ui/frame/default_frame_header.h" +#include "chromeos/ui/frame/header_view.h" #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "ui/aura/window.h" #include "ui/aura/window_targeter.h" @@ -32,7 +32,7 @@ class WideFrameTargeter : public aura::WindowTargeter { public: - explicit WideFrameTargeter(HeaderView* header_view) + explicit WideFrameTargeter(chromeos::HeaderView* header_view) : header_view_(header_view) {} WideFrameTargeter(const WideFrameTargeter&) = delete; @@ -59,7 +59,7 @@ } private: - HeaderView* header_view_; + chromeos::HeaderView* header_view_; }; } // namespace @@ -102,7 +102,7 @@ // Use the HeaderView itself as a frame view because WideFrameView is // is the frame only. header_view_ = AddChildView( - std::make_unique<HeaderView>(target, /*frame view=*/nullptr)); + std::make_unique<chromeos::HeaderView>(target, /*frame view=*/nullptr)); header_view_->Init(); GetTargetHeaderView()->SetShouldPaintHeader(false); header_view_->set_context_menu_controller( @@ -143,7 +143,7 @@ if (widget_) widget_->CloseNow(); if (target_) { - HeaderView* target_header_view = GetTargetHeaderView(); + chromeos::HeaderView* target_header_view = GetTargetHeaderView(); target_header_view->SetShouldPaintHeader(true); target_header_view->GetFrameHeader()->UpdateFrameHeaderKey(); target_->GetNativeWindow()->RemoveObserver(this); @@ -248,7 +248,7 @@ gfx::Rect(point_in_header_coords, gfx::Size(1, 1))); } -HeaderView* WideFrameView::GetTargetHeaderView() { +chromeos::HeaderView* WideFrameView::GetTargetHeaderView() { auto* frame_view = static_cast<NonClientFrameViewAsh*>( target_->non_client_view()->frame_view()); return frame_view->GetHeaderView();
diff --git a/ash/frame/wide_frame_view.h b/ash/frame/wide_frame_view.h index ddefe88a..3daa320 100644 --- a/ash/frame/wide_frame_view.h +++ b/ash/frame/wide_frame_view.h
@@ -16,6 +16,7 @@ namespace chromeos { class ImmersiveFullscreenController; +class HeaderView; } namespace views { @@ -23,7 +24,6 @@ } namespace ash { -class HeaderView; // WideFrameView is used for the case where the widget's maximzed/fullscreen // doesn't cover the entire workarea/display area but the caption frame should @@ -57,7 +57,7 @@ void SetCaptionButtonModel( std::unique_ptr<chromeos::CaptionButtonModel> mode); - HeaderView* header_view() { return header_view_; } + chromeos::HeaderView* header_view() { return header_view_; } private: static gfx::Rect GetFrameBounds(views::Widget* target); @@ -85,7 +85,7 @@ bool ShouldShowContextMenu(views::View* source, const gfx::Point& screen_coords_point) override; - HeaderView* GetTargetHeaderView(); + chromeos::HeaderView* GetTargetHeaderView(); // The target widget this frame will control. views::Widget* target_; @@ -94,7 +94,7 @@ display::ScopedDisplayObserver display_observer_{this}; - HeaderView* header_view_ = nullptr; + chromeos::HeaderView* header_view_ = nullptr; std::unique_ptr<FrameContextMenuController> frame_context_menu_controller_;
diff --git a/ash/ime/ime_controller_impl.cc b/ash/ime/ime_controller_impl.cc index 0a21cb8..f092374 100644 --- a/ash/ime/ime_controller_impl.cc +++ b/ash/ime/ime_controller_impl.cc
@@ -301,7 +301,7 @@ } void ImeControllerImpl::OnScreenCaptureStart( - const base::RepeatingClosure& stop_callback, + base::OnceClosure stop_callback, const base::RepeatingClosure& source_callback, const std::u16string& screen_capture_status) { client_->UpdateCastingState(true);
diff --git a/ash/ime/ime_controller_impl.h b/ash/ime/ime_controller_impl.h index c2734ed2..2f9c80e 100644 --- a/ash/ime/ime_controller_impl.h +++ b/ash/ime/ime_controller_impl.h
@@ -127,7 +127,7 @@ // ScreenCaptureObserver: void OnScreenCaptureStart( - const base::RepeatingClosure& stop_callback, + base::OnceClosure stop_callback, const base::RepeatingClosure& source_callback, const std::u16string& screen_capture_status) override; void OnScreenCaptureStop() override;
diff --git a/ash/public/cpp/app_list/app_list_types.cc b/ash/public/cpp/app_list/app_list_types.cc index 31caf2d..8c659ecb 100644 --- a/ash/public/cpp/app_list/app_list_types.cc +++ b/ash/public/cpp/app_list/app_list_types.cc
@@ -23,6 +23,7 @@ case AppListSearchResultType::kArcAppShortcut: case AppListSearchResultType::kInstantApp: case AppListSearchResultType::kGames: + case AppListSearchResultType::kZeroStateApp: return true; case AppListSearchResultType::kUnknown: case AppListSearchResultType::kOmnibox: @@ -44,11 +45,12 @@ } } -bool IsContinueSectionResultType(AppListSearchResultType result_type) { +bool IsZeroStateResultType(AppListSearchResultType result_type) { switch (result_type) { case AppListSearchResultType::kZeroStateFile: case AppListSearchResultType::kZeroStateDrive: case AppListSearchResultType::kZeroStateHelpApp: + case AppListSearchResultType::kZeroStateApp: return true; case AppListSearchResultType::kUnknown: case AppListSearchResultType::kInstalledApp:
diff --git a/ash/public/cpp/app_list/app_list_types.h b/ash/public/cpp/app_list/app_list_types.h index df3dc9bb..eec7192 100644 --- a/ash/public/cpp/app_list/app_list_types.h +++ b/ash/public/cpp/app_list/app_list_types.h
@@ -375,16 +375,18 @@ kGames, // Game sarch results. kPersonalization, // Personalization search results. kZeroStateHelpApp, // Help App (aka Explore) results for zero-state. + kZeroStateApp, // App recommendations for zero-state / recent apps. // Add new values here. - kMaxValue = kZeroStateHelpApp, + kMaxValue = kZeroStateApp, }; ASH_PUBLIC_EXPORT bool IsAppListSearchResultAnApp( AppListSearchResultType result_type); // Returns whether the result type is a type of result shown in launcher -// continue section. -ASH_PUBLIC_EXPORT bool IsContinueSectionResultType( +// apps page, i.e. results shown in launcher "continue" section and among recent +// apps. +ASH_PUBLIC_EXPORT bool IsZeroStateResultType( AppListSearchResultType result_type); // The different categories a search result can be part of. Every search result
diff --git a/ash/quick_pair/repository/fast_pair_repository_impl.cc b/ash/quick_pair/repository/fast_pair_repository_impl.cc index 2247d3e9..3a886ee4 100644 --- a/ash/quick_pair/repository/fast_pair_repository_impl.cc +++ b/ash/quick_pair/repository/fast_pair_repository_impl.cc
@@ -238,7 +238,7 @@ const std::string& string_key = info.device().account_key(); const std::vector<uint8_t> binary_key(string_key.begin(), string_key.end()); - if (account_key_filter.Test(binary_key)) { + if (account_key_filter.IsAccountKeyInFilter(binary_key)) { nearby::fastpair::StoredDiscoveryItem device; if (device.ParseFromString(info.device().discovery_item_bytes())) { QP_LOG(INFO) << "Account key matched with a paired device: "
diff --git a/ash/system/accessibility/accessibility_detailed_view.cc b/ash/system/accessibility/accessibility_detailed_view.cc index 816e106..f54f504 100644 --- a/ash/system/accessibility/accessibility_detailed_view.cc +++ b/ash/system/accessibility/accessibility_detailed_view.cc
@@ -110,6 +110,17 @@ language_code == GetSodaFeatureLocale(feature); } +// Updates the check mark to `checked` on `view1` and `view2` if the views +// exist. +void UpdateCheckMark(bool checked, + HoverHighlightView* view1, + HoverHighlightView* view2) { + if (view1) + TrayPopupUtils::UpdateCheckMarkVisibility(view1, checked); + if (view2) + TrayPopupUtils::UpdateCheckMarkVisibility(view2, checked); +} + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -152,94 +163,89 @@ AccessibilityControllerImpl* controller = Shell::Get()->accessibility_controller(); - if (spoken_feedback_view_ && - controller->IsSpokenFeedbackSettingVisibleInTray()) { + if (controller->IsSpokenFeedbackSettingVisibleInTray()) { bool checked = controller->spoken_feedback().enabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(spoken_feedback_view_, checked); + UpdateCheckMark(checked, spoken_feedback_view_, spoken_feedback_top_view_); } - if (select_to_speak_view_ && - controller->IsSelectToSpeakSettingVisibleInTray()) { + if (controller->IsSelectToSpeakSettingVisibleInTray()) { bool checked = controller->select_to_speak().enabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(select_to_speak_view_, checked); + UpdateCheckMark(checked, select_to_speak_view_, select_to_speak_top_view_); } - if (dictation_view_ && controller->IsDictationSettingVisibleInTray()) { + if (controller->IsDictationSettingVisibleInTray()) { bool checked = controller->dictation().enabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(dictation_view_, checked); + UpdateCheckMark(checked, dictation_view_, dictation_top_view_); } - if (high_contrast_view_ && controller->IsHighContrastSettingVisibleInTray()) { + if (controller->IsHighContrastSettingVisibleInTray()) { bool checked = controller->high_contrast().enabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(high_contrast_view_, checked); + UpdateCheckMark(checked, high_contrast_view_, high_contrast_top_view_); } - if (screen_magnifier_view_ && - controller->IsFullScreenMagnifierSettingVisibleInTray()) { + if (controller->IsFullScreenMagnifierSettingVisibleInTray()) { bool checked = delegate->IsMagnifierEnabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(screen_magnifier_view_, checked); + UpdateCheckMark(checked, screen_magnifier_view_, + screen_magnifier_top_view_); } - if (docked_magnifier_view_ && - controller->IsDockedMagnifierSettingVisibleInTray()) { + if (controller->IsDockedMagnifierSettingVisibleInTray()) { bool checked = Shell::Get()->docked_magnifier_controller()->GetEnabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(docked_magnifier_view_, checked); + UpdateCheckMark(checked, docked_magnifier_view_, + docked_magnifier_top_view_); } - if (autoclick_view_ && controller->IsAutoclickSettingVisibleInTray()) { + if (controller->IsAutoclickSettingVisibleInTray()) { bool checked = controller->autoclick().enabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(autoclick_view_, checked); + UpdateCheckMark(checked, autoclick_view_, autoclick_top_view_); } - if (virtual_keyboard_view_ && - controller->IsVirtualKeyboardSettingVisibleInTray()) { + if (controller->IsVirtualKeyboardSettingVisibleInTray()) { bool checked = controller->virtual_keyboard().enabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(virtual_keyboard_view_, checked); + UpdateCheckMark(checked, virtual_keyboard_view_, + virtual_keyboard_top_view_); } - if (switch_access_view_ && controller->IsSwitchAccessSettingVisibleInTray()) { + if (controller->IsSwitchAccessSettingVisibleInTray()) { bool checked = controller->switch_access().enabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(switch_access_view_, checked); + UpdateCheckMark(checked, switch_access_view_, switch_access_top_view_); } - if (live_caption_view_ && controller->IsLiveCaptionSettingVisibleInTray()) { + if (controller->IsLiveCaptionSettingVisibleInTray()) { bool checked = controller->live_caption().enabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(live_caption_view_, checked); + UpdateCheckMark(checked, live_caption_view_, live_caption_top_view_); } - if (large_cursor_view_ && controller->IsLargeCursorSettingVisibleInTray()) { + if (controller->IsLargeCursorSettingVisibleInTray()) { bool checked = controller->large_cursor().enabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(large_cursor_view_, checked); + UpdateCheckMark(checked, large_cursor_view_, large_cursor_top_view_); } - if (mono_audio_view_ && controller->IsMonoAudioSettingVisibleInTray()) { + if (controller->IsMonoAudioSettingVisibleInTray()) { bool checked = controller->mono_audio().enabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(mono_audio_view_, checked); + UpdateCheckMark(checked, mono_audio_view_, mono_audio_top_view_); } - if (caret_highlight_view_ && - controller->IsCaretHighlightSettingVisibleInTray()) { + if (controller->IsCaretHighlightSettingVisibleInTray()) { bool checked = controller->caret_highlight().enabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(caret_highlight_view_, checked); + UpdateCheckMark(checked, caret_highlight_view_, caret_highlight_top_view_); } - if (highlight_mouse_cursor_view_ && - controller->IsCursorHighlightSettingVisibleInTray()) { + if (controller->IsCursorHighlightSettingVisibleInTray()) { bool checked = controller->cursor_highlight().enabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(highlight_mouse_cursor_view_, - checked); + UpdateCheckMark(checked, highlight_mouse_cursor_view_, + highlight_mouse_cursor_top_view_); } - if (highlight_keyboard_focus_view_ && - controller->IsFocusHighlightSettingVisibleInTray()) { + if (controller->IsFocusHighlightSettingVisibleInTray()) { bool checked = controller->focus_highlight().enabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(highlight_keyboard_focus_view_, - checked); + UpdateCheckMark(checked, highlight_keyboard_focus_view_, + highlight_keyboard_focus_top_view_); } - if (sticky_keys_view_ && controller->IsStickyKeysSettingVisibleInTray()) { + if (controller->IsStickyKeysSettingVisibleInTray()) { bool checked = controller->sticky_keys().enabled(); - TrayPopupUtils::UpdateCheckMarkVisibility(sticky_keys_view_, checked); + UpdateCheckMark(checked, sticky_keys_view_, sticky_keys_top_view_); } } @@ -262,8 +268,82 @@ } void AccessibilityDetailedView::AddEnabledFeatures(views::View* container) { - // TODO(b/252871844): Implement by creating a HoverHighlightView instance for - // each enabled feature, using the Add*View() helper methods. + AccessibilityControllerImpl* controller = + Shell::Get()->accessibility_controller(); + + if (controller->IsSpokenFeedbackSettingVisibleInTray() && + controller->spoken_feedback().enabled()) { + spoken_feedback_top_view_ = AddSpokenFeedbackView(container); + } + if (controller->IsSelectToSpeakSettingVisibleInTray() && + controller->select_to_speak().enabled()) { + select_to_speak_top_view_ = AddSelectToSpeakView(container); + } + if (controller->IsDictationSettingVisibleInTray() && + controller->dictation().enabled()) { + dictation_top_view_ = AddDictationView(container); + } + if (controller->IsHighContrastSettingVisibleInTray() && + controller->high_contrast().enabled()) { + high_contrast_top_view_ = AddHighContrastView(container); + } + if (controller->IsFullScreenMagnifierSettingVisibleInTray() && + Shell::Get()->accessibility_delegate()->IsMagnifierEnabled()) { + screen_magnifier_top_view_ = AddScreenMagnifierView(container); + } + if (controller->IsDockedMagnifierSettingVisibleInTray() && + Shell::Get()->docked_magnifier_controller()->GetEnabled()) { + docked_magnifier_top_view_ = AddDockedMagnifierView(container); + } + if (controller->IsAutoclickSettingVisibleInTray() && + controller->autoclick().enabled()) { + autoclick_top_view_ = AddAutoclickView(container); + } + if (controller->IsVirtualKeyboardSettingVisibleInTray() && + controller->virtual_keyboard().enabled()) { + virtual_keyboard_top_view_ = AddVirtualKeyboardView(container); + } + if (controller->IsSwitchAccessSettingVisibleInTray() && + controller->switch_access().enabled()) { + switch_access_top_view_ = AddSwitchAccessView(container); + } + if (controller->IsLiveCaptionSettingVisibleInTray() && + controller->live_caption().enabled()) { + live_caption_top_view_ = AddLiveCaptionView(container); + } + if (controller->IsLargeCursorSettingVisibleInTray() && + controller->large_cursor().enabled()) { + large_cursor_top_view_ = AddLargeCursorView(container); + } + if (controller->IsMonoAudioSettingVisibleInTray() && + controller->mono_audio().enabled()) { + mono_audio_top_view_ = AddMonoAudioView(container); + } + if (controller->IsCaretHighlightSettingVisibleInTray() && + controller->caret_highlight().enabled()) { + caret_highlight_top_view_ = AddCaretHighlightView(container); + } + if (controller->IsCursorHighlightSettingVisibleInTray() && + controller->cursor_highlight().enabled()) { + highlight_mouse_cursor_top_view_ = AddHighlightMouseCursorView(container); + } + // Focus highlighting can't be on when spoken feedback is on because + // ChromeVox does its own focus highlighting. + if (!controller->spoken_feedback().enabled() && + controller->IsFocusHighlightSettingVisibleInTray() && + controller->focus_highlight().enabled()) { + highlight_keyboard_focus_top_view_ = + AddHighlightKeyboardFocusView(container); + } + if (controller->IsStickyKeysSettingVisibleInTray() && + controller->sticky_keys().enabled()) { + sticky_keys_top_view_ = AddStickyKeysView(container); + } + + // Add a divider line if any features were added above. + if (!container->children().empty()) { + container->AddChildView(TrayPopupUtils::CreateListSubHeaderSeparator()); + } } void AccessibilityDetailedView::AddAllFeatures(views::View* container) { @@ -526,7 +606,10 @@ Shell::Get()->accessibility_controller(); using base::RecordAction; using base::UserMetricsAction; - if (spoken_feedback_view_ && view == spoken_feedback_view_ && + // Since `view` is never null, there's no need to check for the existence of + // individual views in the if statements below. + DCHECK(view); + if ((view == spoken_feedback_top_view_ || view == spoken_feedback_view_) && !controller->IsEnterpriseIconVisibleForSpokenFeedback()) { bool new_state = !controller->spoken_feedback().enabled(); RecordAction(new_state @@ -535,7 +618,8 @@ LogUserAccessibilityEvent(UserSettingsEvent::Event::SPOKEN_FEEDBACK, new_state); controller->SetSpokenFeedbackEnabled(new_state, A11Y_NOTIFICATION_NONE); - } else if (select_to_speak_view_ && view == select_to_speak_view_ && + } else if ((view == select_to_speak_top_view_ || + view == select_to_speak_view_) && !controller->IsEnterpriseIconVisibleForSelectToSpeak()) { bool new_state = !controller->select_to_speak().enabled(); RecordAction(new_state @@ -544,14 +628,14 @@ LogUserAccessibilityEvent(UserSettingsEvent::Event::SELECT_TO_SPEAK, new_state); controller->select_to_speak().SetEnabled(new_state); - } else if (dictation_view_ && view == dictation_view_ && + } else if ((view == dictation_top_view_ || view == dictation_view_) && !controller->IsEnterpriseIconVisibleForDictation()) { bool new_state = !controller->dictation().enabled(); RecordAction(new_state ? UserMetricsAction("StatusArea_DictationEnabled") : UserMetricsAction("StatusArea_DictationDisabled")); LogUserAccessibilityEvent(UserSettingsEvent::Event::DICTATION, new_state); controller->dictation().SetEnabled(new_state); - } else if (high_contrast_view_ && view == high_contrast_view_ && + } else if ((view == high_contrast_top_view_ || view == high_contrast_view_) && !controller->IsEnterpriseIconVisibleForHighContrast()) { bool new_state = !controller->high_contrast().enabled(); RecordAction(new_state @@ -560,14 +644,16 @@ LogUserAccessibilityEvent(UserSettingsEvent::Event::HIGH_CONTRAST, new_state); controller->high_contrast().SetEnabled(new_state); - } else if (screen_magnifier_view_ && view == screen_magnifier_view_ && + } else if ((view == screen_magnifier_top_view_ || + view == screen_magnifier_view_) && !controller->IsEnterpriseIconVisibleForFullScreenMagnifier()) { bool new_state = !delegate->IsMagnifierEnabled(); RecordAction(new_state ? UserMetricsAction("StatusArea_MagnifierEnabled") : UserMetricsAction("StatusArea_MagnifierDisabled")); LogUserAccessibilityEvent(UserSettingsEvent::Event::MAGNIFIER, new_state); delegate->SetMagnifierEnabled(new_state); - } else if (docked_magnifier_view_ && view == docked_magnifier_view_ && + } else if ((view == docked_magnifier_top_view_ || + view == docked_magnifier_view_) && !controller->IsEnterpriseIconVisibleForDockedMagnifier()) { auto* docked_magnifier_controller = Shell::Get()->docked_magnifier_controller(); @@ -585,7 +671,7 @@ LogUserAccessibilityEvent(UserSettingsEvent::Event::DOCKED_MAGNIFIER, new_state); docked_magnifier_controller->SetEnabled(new_state); - } else if (large_cursor_view_ && view == large_cursor_view_ && + } else if ((view == large_cursor_top_view_ || view == large_cursor_view_) && !controller->IsEnterpriseIconVisibleForLargeCursor()) { bool new_state = !controller->large_cursor().enabled(); RecordAction(new_state @@ -594,14 +680,15 @@ LogUserAccessibilityEvent(UserSettingsEvent::Event::LARGE_CURSOR, new_state); controller->large_cursor().SetEnabled(new_state); - } else if (autoclick_view_ && view == autoclick_view_ && + } else if ((view == autoclick_top_view_ || view == autoclick_view_) && !controller->IsEnterpriseIconVisibleForAutoclick()) { bool new_state = !controller->autoclick().enabled(); RecordAction(new_state ? UserMetricsAction("StatusArea_AutoClickEnabled") : UserMetricsAction("StatusArea_AutoClickDisabled")); LogUserAccessibilityEvent(UserSettingsEvent::Event::AUTO_CLICK, new_state); controller->autoclick().SetEnabled(new_state); - } else if (virtual_keyboard_view_ && view == virtual_keyboard_view_ && + } else if ((view == virtual_keyboard_top_view_ || + view == virtual_keyboard_view_) && !controller->IsEnterpriseIconVisibleForVirtualKeyboard()) { bool new_state = !controller->virtual_keyboard().enabled(); RecordAction(new_state @@ -610,7 +697,7 @@ LogUserAccessibilityEvent(UserSettingsEvent::Event::VIRTUAL_KEYBOARD, new_state); controller->virtual_keyboard().SetEnabled(new_state); - } else if (switch_access_view_ && view == switch_access_view_ && + } else if ((view == switch_access_top_view_ || view == switch_access_view_) && !controller->IsEnterpriseIconVisibleForSwitchAccess()) { bool new_state = !controller->switch_access().enabled(); RecordAction(new_state @@ -619,7 +706,7 @@ LogUserAccessibilityEvent(UserSettingsEvent::Event::SWITCH_ACCESS, new_state); controller->switch_access().SetEnabled(new_state); - } else if (live_caption_view_ && view == live_caption_view_) { + } else if (view == live_caption_top_view_ || view == live_caption_view_) { bool new_state = !controller->live_caption().enabled(); RecordAction(new_state ? UserMetricsAction("StatusArea_LiveCaptionEnabled") @@ -627,7 +714,8 @@ LogUserAccessibilityEvent(UserSettingsEvent::Event::LIVE_CAPTION, new_state); controller->live_caption().SetEnabled(new_state); - } else if (caret_highlight_view_ && view == caret_highlight_view_ && + } else if ((view == caret_highlight_top_view_ || + view == caret_highlight_view_) && !controller->IsEnterpriseIconVisibleForCaretHighlight()) { bool new_state = !controller->caret_highlight().enabled(); RecordAction(new_state @@ -636,15 +724,15 @@ LogUserAccessibilityEvent(UserSettingsEvent::Event::CARET_HIGHLIGHT, new_state); controller->caret_highlight().SetEnabled(new_state); - } else if (mono_audio_view_ && view == mono_audio_view_ && + } else if ((view == mono_audio_top_view_ || view == mono_audio_view_) && !controller->IsEnterpriseIconVisibleForMonoAudio()) { bool new_state = !controller->mono_audio().enabled(); RecordAction(new_state ? UserMetricsAction("StatusArea_MonoAudioEnabled") : UserMetricsAction("StatusArea_MonoAudioDisabled")); LogUserAccessibilityEvent(UserSettingsEvent::Event::MONO_AUDIO, new_state); controller->mono_audio().SetEnabled(new_state); - } else if (highlight_mouse_cursor_view_ && - view == highlight_mouse_cursor_view_ && + } else if ((view == highlight_mouse_cursor_top_view_ || + view == highlight_mouse_cursor_view_) && !controller->IsEnterpriseIconVisibleForCursorHighlight()) { bool new_state = !controller->cursor_highlight().enabled(); RecordAction( @@ -654,8 +742,8 @@ LogUserAccessibilityEvent(UserSettingsEvent::Event::HIGHLIGHT_MOUSE_CURSOR, new_state); controller->cursor_highlight().SetEnabled(new_state); - } else if (highlight_keyboard_focus_view_ && - view == highlight_keyboard_focus_view_ && + } else if ((view == highlight_keyboard_focus_top_view_ || + view == highlight_keyboard_focus_view_) && !controller->IsEnterpriseIconVisibleForFocusHighlight()) { bool new_state = !controller->focus_highlight().enabled(); RecordAction( @@ -665,7 +753,7 @@ LogUserAccessibilityEvent( UserSettingsEvent::Event::HIGHLIGHT_KEYBOARD_FOCUS, new_state); controller->focus_highlight().SetEnabled(new_state); - } else if (sticky_keys_view_ && view == sticky_keys_view_ && + } else if ((view == sticky_keys_top_view_ || view == sticky_keys_view_) && !controller->IsEnterpriseIconVisibleForStickyKeys()) { bool new_state = !controller->sticky_keys().enabled(); RecordAction(new_state
diff --git a/ash/system/accessibility/accessibility_detailed_view.h b/ash/system/accessibility/accessibility_detailed_view.h index 5239b86..7f72607 100644 --- a/ash/system/accessibility/accessibility_detailed_view.h +++ b/ash/system/accessibility/accessibility_detailed_view.h
@@ -128,6 +128,26 @@ HoverHighlightView* highlight_keyboard_focus_view_ = nullptr; HoverHighlightView* sticky_keys_view_ = nullptr; + // Views that appear in the top section listing enabled items. Created if the + // feature is enabled, otherwise nullptr. Owned by views hierarchy. + // Only used with QsRevamp. + HoverHighlightView* spoken_feedback_top_view_ = nullptr; + HoverHighlightView* select_to_speak_top_view_ = nullptr; + HoverHighlightView* dictation_top_view_ = nullptr; + HoverHighlightView* high_contrast_top_view_ = nullptr; + HoverHighlightView* screen_magnifier_top_view_ = nullptr; + HoverHighlightView* docked_magnifier_top_view_ = nullptr; + HoverHighlightView* large_cursor_top_view_ = nullptr; + HoverHighlightView* autoclick_top_view_ = nullptr; + HoverHighlightView* virtual_keyboard_top_view_ = nullptr; + HoverHighlightView* switch_access_top_view_ = nullptr; + HoverHighlightView* live_caption_top_view_ = nullptr; + HoverHighlightView* mono_audio_top_view_ = nullptr; + HoverHighlightView* caret_highlight_top_view_ = nullptr; + HoverHighlightView* highlight_mouse_cursor_top_view_ = nullptr; + HoverHighlightView* highlight_keyboard_focus_top_view_ = nullptr; + HoverHighlightView* sticky_keys_top_view_ = nullptr; + views::Button* help_view_ = nullptr; views::Button* settings_view_ = nullptr;
diff --git a/ash/system/accessibility/accessibility_detailed_view_unittest.cc b/ash/system/accessibility/accessibility_detailed_view_unittest.cc index 6bc6482..12286c2 100644 --- a/ash/system/accessibility/accessibility_detailed_view_unittest.cc +++ b/ash/system/accessibility/accessibility_detailed_view_unittest.cc
@@ -118,12 +118,24 @@ return speech::LanguageCode::kFrFr; } +// Returns true if `view` is marked checked for accessibility. +bool IsChecked(views::View* view) { + ui::AXNodeData node_data; + view->GetAccessibleNodeData(&node_data); + return node_data.GetCheckedState() == ax::mojom::CheckedState::kTrue; +} + } // namespace class AccessibilityDetailedViewTest : public AshTestBase, public AccessibilityObserver { public: - AccessibilityDetailedViewTest() = default; + AccessibilityDetailedViewTest() { + scoped_feature_list_.InitWithFeatures( + {media::kLiveCaption, media::kLiveCaptionSystemWideOnChromeOS, + ash::features::kOnDeviceSpeechRecognition}, + {}); + } AccessibilityDetailedViewTest(const AccessibilityDetailedViewTest&) = delete; AccessibilityDetailedViewTest& operator=( const AccessibilityDetailedViewTest&) = delete; @@ -131,10 +143,6 @@ protected: void SetUp() override { - scoped_feature_list_.InitWithFeatures( - {media::kLiveCaption, media::kLiveCaptionSystemWideOnChromeOS, - ash::features::kOnDeviceSpeechRecognition}, - {}); AshTestBase::SetUp(); controller_ = Shell::Get()->accessibility_controller(); controller_->AddObserver(this); @@ -310,11 +318,8 @@ // enabled. Check that the checked state and detailed_menu_'s local state are // the same. bool IsEnabledOnDetailMenu(bool enabled_state, views::View* view) const { - ui::AXNodeData node_data; - view->GetAccessibleNodeData(&node_data); - bool checked_for_accessibility = - node_data.GetCheckedState() == ax::mojom::CheckedState::kTrue; - DCHECK(enabled_state == checked_for_accessibility); + bool checked_for_accessibility = IsChecked(view); + DCHECK_EQ(enabled_state, checked_for_accessibility); return enabled_state && checked_for_accessibility; } @@ -410,6 +415,7 @@ return detailed_menu_->GetClassName(); } + AccessibilityControllerImpl* controller() { return controller_; } AccessibilityDetailedView* detailed_menu() { return detailed_menu_.get(); } // Accessors for list item views. @@ -462,6 +468,56 @@ return detailed_menu_->switch_access_view_; } + // Accessors for the top views listing enabled items. + HoverHighlightView* spoken_feedback_top_view() const { + return detailed_menu_->spoken_feedback_top_view_; + } + HoverHighlightView* select_to_speak_top_view() const { + return detailed_menu_->select_to_speak_top_view_; + } + HoverHighlightView* dictation_top_view() const { + return detailed_menu_->dictation_top_view_; + } + HoverHighlightView* high_contrast_top_view() const { + return detailed_menu_->high_contrast_top_view_; + } + HoverHighlightView* screen_magnifier_top_view() const { + return detailed_menu_->screen_magnifier_top_view_; + } + HoverHighlightView* docked_magnifier_top_view() const { + return detailed_menu_->docked_magnifier_top_view_; + } + HoverHighlightView* large_cursor_top_view() const { + return detailed_menu_->large_cursor_top_view_; + } + HoverHighlightView* live_caption_top_view() const { + return detailed_menu_->live_caption_top_view_; + } + HoverHighlightView* autoclick_top_view() const { + return detailed_menu_->autoclick_top_view_; + } + HoverHighlightView* virtual_keyboard_top_view() const { + return detailed_menu_->virtual_keyboard_top_view_; + } + HoverHighlightView* mono_audio_top_view() const { + return detailed_menu_->mono_audio_top_view_; + } + HoverHighlightView* caret_highlight_top_view() const { + return detailed_menu_->caret_highlight_top_view_; + } + HoverHighlightView* highlight_mouse_cursor_top_view() const { + return detailed_menu_->highlight_mouse_cursor_top_view_; + } + HoverHighlightView* highlight_keyboard_focus_top_view() const { + return detailed_menu_->highlight_keyboard_focus_top_view_; + } + HoverHighlightView* sticky_keys_top_view() const { + return detailed_menu_->sticky_keys_top_view_; + } + HoverHighlightView* switch_access_top_view() const { + return detailed_menu_->switch_access_top_view_; + } + private: // AccessibilityObserver: void OnAccessibilityStatusChanged() override { @@ -478,9 +534,18 @@ base::test::ScopedFeatureList scoped_feature_list_; }; -TEST_F(AccessibilityDetailedViewTest, ListItemsAreInRoundedContainer) { - base::test::ScopedFeatureList feature_list{features::kQsRevamp}; +class AccessibilityDetailedViewQsRevampTest + : public AccessibilityDetailedViewTest { + public: + AccessibilityDetailedViewQsRevampTest() { + feature_list_.InitAndEnableFeature(features::kQsRevamp); + } + private: + base::test::ScopedFeatureList feature_list_; +}; + +TEST_F(AccessibilityDetailedViewQsRevampTest, ListItemsAreInRoundedContainer) { CreateDetailedMenu(); auto has_rounded_container_parent = [](views::View* view) -> bool { return views::IsViewClass<RoundedContainer>(view->parent()); @@ -504,6 +569,214 @@ CloseDetailMenu(); } +TEST_F(AccessibilityDetailedViewQsRevampTest, + TopsViewsAreEmptyWithNoFeaturesEnabled) { + CreateDetailedMenu(); + + // By default none of the accessibility features are enabled, so none of the + // top-views are created. + EXPECT_FALSE(spoken_feedback_top_view()); + EXPECT_FALSE(select_to_speak_top_view()); + EXPECT_FALSE(dictation_top_view()); + EXPECT_FALSE(high_contrast_top_view()); + EXPECT_FALSE(screen_magnifier_top_view()); + EXPECT_FALSE(docked_magnifier_top_view()); + EXPECT_FALSE(large_cursor_top_view()); + EXPECT_FALSE(live_caption_top_view()); + EXPECT_FALSE(autoclick_top_view()); + EXPECT_FALSE(virtual_keyboard_top_view()); + EXPECT_FALSE(mono_audio_top_view()); + EXPECT_FALSE(caret_highlight_top_view()); + EXPECT_FALSE(highlight_mouse_cursor_top_view()); + EXPECT_FALSE(highlight_keyboard_focus_top_view()); + EXPECT_FALSE(sticky_keys_top_view()); + EXPECT_FALSE(switch_access_top_view()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, SpokenFeedbackTopView) { + EnableSpokenFeedback(true); + CreateDetailedMenu(); + ASSERT_TRUE(spoken_feedback_top_view()); + EXPECT_TRUE(IsChecked(spoken_feedback_top_view())); + + ClickView(spoken_feedback_top_view()); + EXPECT_FALSE(IsChecked(spoken_feedback_top_view())); + EXPECT_FALSE(controller()->spoken_feedback().enabled()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, SelectToSpeakTopView) { + EnableSelectToSpeak(true); + CreateDetailedMenu(); + ASSERT_TRUE(select_to_speak_top_view()); + EXPECT_TRUE(IsChecked(select_to_speak_top_view())); + + ClickView(select_to_speak_top_view()); + EXPECT_FALSE(IsChecked(select_to_speak_top_view())); + EXPECT_FALSE(controller()->select_to_speak().enabled()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, DictationTopView) { + EnableDictation(true); + CreateDetailedMenu(); + ASSERT_TRUE(dictation_top_view()); + EXPECT_TRUE(IsChecked(dictation_top_view())); + + ClickView(dictation_top_view()); + EXPECT_FALSE(IsChecked(dictation_top_view())); + EXPECT_FALSE(controller()->dictation().enabled()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, HighContrastTopView) { + EnableHighContrast(true); + CreateDetailedMenu(); + ASSERT_TRUE(high_contrast_top_view()); + EXPECT_TRUE(IsChecked(high_contrast_top_view())); + + ClickView(high_contrast_top_view()); + EXPECT_FALSE(IsChecked(high_contrast_top_view())); + EXPECT_FALSE(controller()->high_contrast().enabled()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, ScreenMagnifierTopView) { + Shell::Get()->accessibility_delegate()->SetMagnifierEnabled(true); + CreateDetailedMenu(); + ASSERT_TRUE(screen_magnifier_top_view()); + EXPECT_TRUE(IsChecked(screen_magnifier_top_view())); + + ClickView(screen_magnifier_top_view()); + // The test accessibility delegate doesn't notify observers of changes, so do + // it manually. + controller()->NotifyAccessibilityStatusChanged(); + + EXPECT_FALSE(IsChecked(screen_magnifier_top_view())); + EXPECT_FALSE(Shell::Get()->accessibility_delegate()->IsMagnifierEnabled()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, DockedMagnifierTopView) { + SetDockedMagnifierEnabled(true); + CreateDetailedMenu(); + ASSERT_TRUE(docked_magnifier_top_view()); + EXPECT_TRUE(IsChecked(docked_magnifier_top_view())); + + ClickView(docked_magnifier_top_view()); + EXPECT_FALSE(IsChecked(docked_magnifier_top_view())); + EXPECT_FALSE(Shell::Get()->docked_magnifier_controller()->GetEnabled()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, LargeCursorTopView) { + EnableLargeCursor(true); + CreateDetailedMenu(); + ASSERT_TRUE(large_cursor_top_view()); + EXPECT_TRUE(IsChecked(large_cursor_top_view())); + + ClickView(large_cursor_top_view()); + EXPECT_FALSE(IsChecked(large_cursor_top_view())); + EXPECT_FALSE(controller()->large_cursor().enabled()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, LiveCaptionTopView) { + EnableLiveCaption(true); + CreateDetailedMenu(); + ASSERT_TRUE(live_caption_top_view()); + EXPECT_TRUE(IsChecked(live_caption_top_view())); + + ClickView(live_caption_top_view()); + EXPECT_FALSE(IsChecked(live_caption_top_view())); + EXPECT_FALSE(controller()->live_caption().enabled()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, AutoClickTopView) { + EnableAutoclick(true); + CreateDetailedMenu(); + ASSERT_TRUE(autoclick_top_view()); + EXPECT_TRUE(IsChecked(autoclick_top_view())); + + ClickView(autoclick_top_view()); + EXPECT_FALSE(IsChecked(autoclick_top_view())); + EXPECT_FALSE(controller()->autoclick().enabled()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, VirtualKeyboardTopView) { + EnableVirtualKeyboard(true); + CreateDetailedMenu(); + ASSERT_TRUE(virtual_keyboard_top_view()); + EXPECT_TRUE(IsChecked(virtual_keyboard_top_view())); + + ClickView(virtual_keyboard_top_view()); + EXPECT_FALSE(IsChecked(virtual_keyboard_top_view())); + EXPECT_FALSE(controller()->virtual_keyboard().enabled()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, MonoAudioTopView) { + EnableMonoAudio(true); + CreateDetailedMenu(); + ASSERT_TRUE(mono_audio_top_view()); + EXPECT_TRUE(IsChecked(mono_audio_top_view())); + + ClickView(mono_audio_top_view()); + EXPECT_FALSE(IsChecked(mono_audio_top_view())); + EXPECT_FALSE(controller()->mono_audio().enabled()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, CaretHighlightTopView) { + SetCaretHighlightEnabled(true); + CreateDetailedMenu(); + ASSERT_TRUE(caret_highlight_top_view()); + EXPECT_TRUE(IsChecked(caret_highlight_top_view())); + + ClickView(caret_highlight_top_view()); + EXPECT_FALSE(IsChecked(caret_highlight_top_view())); + EXPECT_FALSE(controller()->caret_highlight().enabled()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, HighlightMouseCursorTopView) { + SetCursorHighlightEnabled(true); + CreateDetailedMenu(); + ASSERT_TRUE(highlight_mouse_cursor_top_view()); + EXPECT_TRUE(IsChecked(highlight_mouse_cursor_top_view())); + + ClickView(highlight_mouse_cursor_top_view()); + EXPECT_FALSE(IsChecked(highlight_mouse_cursor_top_view())); + EXPECT_FALSE(controller()->cursor_highlight().enabled()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, HighlightKeyboardFocusTopView) { + SetFocusHighlightEnabled(true); + CreateDetailedMenu(); + ASSERT_TRUE(highlight_keyboard_focus_top_view()); + EXPECT_TRUE(IsChecked(highlight_keyboard_focus_top_view())); + + ClickView(highlight_keyboard_focus_top_view()); + EXPECT_FALSE(IsChecked(highlight_keyboard_focus_top_view())); + EXPECT_FALSE(controller()->focus_highlight().enabled()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, StickyKeysTopView) { + EnableStickyKeys(true); + CreateDetailedMenu(); + ASSERT_TRUE(sticky_keys_top_view()); + EXPECT_TRUE(IsChecked(sticky_keys_top_view())); + + ClickView(sticky_keys_top_view()); + EXPECT_FALSE(IsChecked(sticky_keys_top_view())); + EXPECT_FALSE(controller()->sticky_keys().enabled()); +} + +TEST_F(AccessibilityDetailedViewQsRevampTest, SwitchAccessTopView) { + // Don't show the confirmation dialog when disabling switch access, so the + // feature will be disabled immediately. + controller()->DisableSwitchAccessDisableConfirmationDialogTesting(); + + EnableSwitchAccess(true); + CreateDetailedMenu(); + ASSERT_TRUE(switch_access_top_view()); + EXPECT_TRUE(IsChecked(switch_access_top_view())); + + ClickView(switch_access_top_view()); + EXPECT_FALSE(IsChecked(switch_access_top_view())); + EXPECT_FALSE(controller()->switch_access().enabled()); +} + TEST_F(AccessibilityDetailedViewTest, CheckMenuVisibilityOnDetailMenu) { // Except help & settings, others should be kept the same // in LOGIN | NOT LOGIN | LOCKED. https://crbug.com/632107.
diff --git a/ash/system/privacy/screen_capture_observer.h b/ash/system/privacy/screen_capture_observer.h index df5ec95..8b17ef23 100644 --- a/ash/system/privacy/screen_capture_observer.h +++ b/ash/system/privacy/screen_capture_observer.h
@@ -16,10 +16,8 @@ // Called when screen capture is started. // |stop_callback| is a callback to stop the stream. // |source_callback| is a callback to change the desktop capture source. - // These must be base::RepeatingCallbacks so that they can be passed to all - // observers. virtual void OnScreenCaptureStart( - const base::RepeatingClosure& stop_callback, + base::OnceClosure stop_callback, const base::RepeatingClosure& source_callback, const std::u16string& screen_capture_status) = 0;
diff --git a/ash/system/privacy/screen_security_controller.cc b/ash/system/privacy/screen_security_controller.cc index 4b6ad1f..b438098 100644 --- a/ash/system/privacy/screen_security_controller.cc +++ b/ash/system/privacy/screen_security_controller.cc
@@ -143,10 +143,10 @@ } void ScreenSecurityController::OnScreenCaptureStart( - const base::RepeatingClosure& stop_callback, + base::OnceClosure stop_callback, const base::RepeatingClosure& source_callback, const std::u16string& screen_capture_status) { - capture_stop_callbacks_.push_back(stop_callback); + capture_stop_callbacks_.emplace_back(std::move(stop_callback)); change_source_callback_ = source_callback; // We do not want to show the screen capture notification and the chromecast @@ -167,7 +167,7 @@ } void ScreenSecurityController::OnScreenShareStart( - const base::RepeatingClosure& stop_callback, + base::OnceClosure stop_callback, const std::u16string& helper_name) { share_stop_callbacks_.emplace_back(std::move(stop_callback));
diff --git a/ash/system/privacy/screen_security_controller.h b/ash/system/privacy/screen_security_controller.h index 8830395..869e3bb 100644 --- a/ash/system/privacy/screen_security_controller.h +++ b/ash/system/privacy/screen_security_controller.h
@@ -44,13 +44,13 @@ // ScreenCaptureObserver: void OnScreenCaptureStart( - const base::RepeatingClosure& stop_callback, + base::OnceClosure stop_callback, const base::RepeatingClosure& source_callback, const std::u16string& screen_capture_status) override; void OnScreenCaptureStop() override; // ScreenShareObserver: - void OnScreenShareStart(const base::RepeatingClosure& stop_callback, + void OnScreenShareStart(base::OnceClosure stop_callback, const std::u16string& helper_name) override; void OnScreenShareStop() override;
diff --git a/ash/system/privacy/screen_share_observer.h b/ash/system/privacy/screen_share_observer.h index 91f92d9..07f29f7c 100644 --- a/ash/system/privacy/screen_share_observer.h +++ b/ash/system/privacy/screen_share_observer.h
@@ -14,16 +14,14 @@ class ScreenShareObserver { public: // Called when screen share is started. - // |stop_callback| must be a base::RepeatingCallback so that it can be passed - // to all observers. - virtual void OnScreenShareStart(const base::RepeatingClosure& stop_callback, + virtual void OnScreenShareStart(base::OnceClosure stop_callback, const std::u16string& helper_name) = 0; // Called when screen share is stopped. virtual void OnScreenShareStop() = 0; protected: - virtual ~ScreenShareObserver() {} + virtual ~ScreenShareObserver() = default; }; } // namespace ash
diff --git a/ash/system/privacy/screen_switch_check_controller.cc b/ash/system/privacy/screen_switch_check_controller.cc index dee109a..823d9ec66 100644 --- a/ash/system/privacy/screen_switch_check_controller.cc +++ b/ash/system/privacy/screen_switch_check_controller.cc
@@ -22,7 +22,7 @@ // callback with the result. class CancelCastingDialog : public views::DialogDelegateView { public: - CancelCastingDialog(base::OnceCallback<void(bool)> callback) + explicit CancelCastingDialog(base::OnceCallback<void(bool)> callback) : callback_(std::move(callback)) { AddChildView(new views::MessageBoxView( l10n_util::GetStringUTF16(IDS_DESKTOP_CASTING_ACTIVE_MESSAGE))); @@ -87,7 +87,7 @@ } void ScreenSwitchCheckController::OnScreenCaptureStart( - const base::RepeatingClosure& stop_callback, + base::OnceClosure stop_callback, const base::RepeatingClosure& source_callback, const std::u16string& screen_capture_status) { has_capture_ = true; @@ -100,7 +100,7 @@ } void ScreenSwitchCheckController::OnScreenShareStart( - const base::RepeatingClosure& stop_callback, + base::OnceClosure stop_callback, const std::u16string& helper_name) { has_share_ = true; }
diff --git a/ash/system/privacy/screen_switch_check_controller.h b/ash/system/privacy/screen_switch_check_controller.h index f8a22d10..e203b97 100644 --- a/ash/system/privacy/screen_switch_check_controller.h +++ b/ash/system/privacy/screen_switch_check_controller.h
@@ -31,13 +31,13 @@ private: // ScreenCaptureObserver: void OnScreenCaptureStart( - const base::RepeatingClosure& stop_callback, + base::OnceClosure stop_callback, const base::RepeatingClosure& source_callback, const std::u16string& screen_capture_status) override; void OnScreenCaptureStop() override; // ScreenShareObserver: - void OnScreenShareStart(const base::RepeatingClosure& stop_callback, + void OnScreenShareStart(base::OnceClosure stop_callback, const std::u16string& helper_name) override; void OnScreenShareStop() override;
diff --git a/ash/system/tray/tray_detailed_view.cc b/ash/system/tray/tray_detailed_view.cc index 06bc37d2..776c692 100644 --- a/ash/system/tray/tray_detailed_view.cc +++ b/ash/system/tray/tray_detailed_view.cc
@@ -19,6 +19,7 @@ #include "ash/system/tray/tray_popup_utils.h" #include "ash/system/tray/tri_view.h" #include "base/bind.h" +#include "base/check.h" #include "base/containers/adapters.h" #include "third_party/skia/include/core/SkDrawLooper.h" #include "ui/base/l10n/l10n_util.h" @@ -369,6 +370,7 @@ TrayDetailedView::~TrayDetailedView() = default; void TrayDetailedView::OnViewClicked(views::View* sender) { + DCHECK(sender); HandleViewClicked(sender); }
diff --git a/ash/system/tray/view_click_listener.h b/ash/system/tray/view_click_listener.h index e3eb11d..505ea4a 100644 --- a/ash/system/tray/view_click_listener.h +++ b/ash/system/tray/view_click_listener.h
@@ -15,6 +15,7 @@ class ASH_EXPORT ViewClickListener { public: + // Called when `sender` is clicked. `sender` is non-null. virtual void OnViewClicked(views::View* sender) = 0; protected:
diff --git a/ash/webui/personalization_app/resources/js/ambient/album_list_element.html b/ash/webui/personalization_app/resources/js/ambient/album_list_element.html index d515608..ba83491 100644 --- a/ash/webui/personalization_app/resources/js/ambient/album_list_element.html +++ b/ash/webui/personalization_app/resources/js/ambient/album_list_element.html
@@ -12,13 +12,12 @@ <iron-list aria-setsize$="[[albums.length]]" as="album" grid id="grid" items="[[albums]]" role="listbox"> <template> - <wallpaper-grid-item aria-label$="[[album.title]]" + <wallpaper-grid-item aria-label$="[[album.title]]" aria-posinset$="[[getAriaIndex_(index)]]" class$="[[getAlbumItemClass_(album, albums)]]" index="[[index]]" is-google-photos="[[isGooglePhotos_(topicSource)]]" - on-click="onAlbumSelected_" - on-keypress="onAlbumSelected_" + on-wallpaper-grid-item-selected="onAlbumSelected_" primary-text="[[album.title]]" role="option" secondary-text="[[getSecondaryText_(album, topicSource)]]"
diff --git a/ash/webui/personalization_app/resources/js/ambient/album_list_element.ts b/ash/webui/personalization_app/resources/js/ambient/album_list_element.ts index c1e88716..da43159 100644 --- a/ash/webui/personalization_app/resources/js/ambient/album_list_element.ts +++ b/ash/webui/personalization_app/resources/js/ambient/album_list_element.ts
@@ -14,7 +14,7 @@ import {AmbientModeAlbum, TopicSource} from '../personalization_app.mojom-webui.js'; import {WithPersonalizationStore} from '../personalization_store.js'; -import {getCountText, isSelectionEvent} from '../utils.js'; +import {getCountText} from '../utils.js'; import {getTemplate} from './album_list_element.html.js'; import {isRecentHighlightsAlbum} from './utils.js'; @@ -61,12 +61,10 @@ /** Invoked on selection of an album. */ private onAlbumSelected_(e: Event&{model: {album: AmbientModeAlbum}}) { - if (isSelectionEvent(e)) { - e.model.album.checked = !e.model.album.checked; - this.dispatchEvent(new CustomEvent( - 'album_selected_changed', - {bubbles: true, composed: true, detail: {album: e.model.album}})); - } + e.model.album.checked = !e.model.album.checked; + this.dispatchEvent(new CustomEvent( + 'album_selected_changed', + {bubbles: true, composed: true, detail: {album: e.model.album}})); } private isAlbumSelected_(
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.html b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.html index c0a883660..2adb478d 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.html +++ b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.html
@@ -23,14 +23,13 @@ aria-label$="[[getAlbumAriaLabel_(album)]]" aria-posinset$="[[getAlbumAriaIndex_(index)]]" class="album" - src="[[album.preview]]" index="[[index]]" is-google-photos - on-click="onAlbumSelected_" - on-keypress="onAlbumSelected_" + on-wallpaper-grid-item-selected="onAlbumSelected_" primary-text="[[album.title]]" role="listitem" secondary-text="[[getSecondaryText_(album)]]" + src="[[album.preview]]" tabindex$="[[tabIndex]]"> </wallpaper-grid-item> </template>
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.ts index 6c55f95..48fe6c0 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.ts
@@ -21,7 +21,7 @@ import {PersonalizationRouter} from '../personalization_router_element.js'; import {PersonalizationStateError} from '../personalization_state.js'; import {WithPersonalizationStore} from '../personalization_store.js'; -import {getCountText, isSelectionEvent} from '../utils.js'; +import {getCountText} from '../utils.js'; import {getTemplate} from './google_photos_albums_element.html.js'; import {getLoadingPlaceholders} from './utils.js'; @@ -126,7 +126,7 @@ /** Invoked on selection of an album. */ private onAlbumSelected_(e: Event&{model: {album: GooglePhotosAlbum}}) { assert(e.model.album); - if (!this.isAlbumPlaceholder_(e.model.album) && isSelectionEvent(e)) { + if (!this.isAlbumPlaceholder_(e.model.album)) { PersonalizationRouter.instance().selectGooglePhotosAlbum(e.model.album); } }
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.html b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.html index 5d17fc9..e7ede95 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.html +++ b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.html
@@ -16,17 +16,16 @@ role="listbox"> <template> <wallpaper-grid-item - aria-disabled$="[[getPhotoAriaDisabled_(photo)]]" aria-label$="[[getPhotoAriaLabel_(photo)]]" aria-posinset$="[[getPhotoAriaIndex_(index)]]" class="photo" - src="[[photo.url]]" + disabled="[[isPhotoPlaceholder_(photo)]]" index="[[index]]" is-google-photos - on-click="onPhotoSelected_" - on-keypress="onPhotoSelected_" + on-wallpaper-grid-item-selected="onPhotoSelected_" role="option" selected="[[isPhotoSelected_(photo, currentSelected_, pendingSelected_)]]" + src="[[photo.url]]" tabindex$="[[tabIndex]]"> </wallpaper-grid-item> </template>
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.ts index f49785d..12aadc9 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.ts
@@ -21,13 +21,13 @@ import {CurrentWallpaper, GooglePhotosAlbum, GooglePhotosPhoto, WallpaperProviderInterface, WallpaperType} from '../personalization_app.mojom-webui.js'; import {PersonalizationStateError} from '../personalization_state.js'; import {WithPersonalizationStore} from '../personalization_store.js'; -import {isSelectionEvent} from '../utils.js'; import {DisplayableImage} from './constants.js'; import {recordWallpaperGooglePhotosSourceUMA, WallpaperGooglePhotosSource} from './google_photos_metrics_logger.js'; import {getTemplate} from './google_photos_photos_by_album_id_element.html.js'; import {getLoadingPlaceholders, isGooglePhotosPhoto, isImageAMatchForKey, isImageEqualToSelected} from './utils.js'; import {fetchGooglePhotosAlbum, selectWallpaper} from './wallpaper_controller.js'; +import {WallpaperGridItemSelectedEvent} from './wallpaper_grid_item_element.js'; import {getWallpaperProvider} from './wallpaper_interface_provider.js'; const ERROR_ID = 'GooglePhotosByAlbumId'; @@ -278,23 +278,16 @@ } } - /** Invoked on selection of a photo. */ - private onPhotoSelected_(e: Event&{model: {photo: GooglePhotosPhoto}}) { - assert(e.model.photo); - if (!this.isPhotoPlaceholder_(e.model.photo) && isSelectionEvent(e)) { + /** Invoked on selection of a photo. `e.model.photo` is added by iron-list. */ + private onPhotoSelected_(e: WallpaperGridItemSelectedEvent& + {model: {photo: GooglePhotosPhoto}}) { + assert(e.model.photo, 'google photos album photo selected event has photo'); + if (!this.isPhotoPlaceholder_(e.model.photo)) { selectWallpaper(e.model.photo, this.wallpaperProvider_, this.getStore()); recordWallpaperGooglePhotosSourceUMA(WallpaperGooglePhotosSource.ALBUMS); } } - /** - * Returns 'true' or 'false' depending on whether the specified |photo| is - * a placeholder. - */ - private getPhotoAriaDisabled_(photo: GooglePhotosPhoto|null): string { - return this.isPhotoPlaceholder_(photo).toString(); - } - /** Returns the aria label for the specified |photo|. */ private getPhotoAriaLabel_(photo: GooglePhotosPhoto|null): string|undefined { if (photo) {
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.html b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.html index 92799424..0439cfe 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.html +++ b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.html
@@ -69,19 +69,18 @@ <div class="photos"> <template is="dom-repeat" items="[[row]]" as="photo"> <wallpaper-grid-item - aria-disabled$="[[getPhotoAriaDisabled_(photo)]]" aria-label$="[[getPhotoAriaLabel_(photo)]]" aria-posinset$="[[getPhotoAriaIndex_(photo.index)]]" class="photo" colindex$="[[index]]" - src="[[photo.url]]" + disabled="[[isPhotoPlaceholder_(photo)]]" index="[[photo.index]]" is-google-photos - on-click="onPhotoSelected_" - on-keypress="onPhotoSelected_" + on-wallpaper-grid-item-selected="onPhotoSelected_" photoindex$="[[photo.index]]" role="option" selected="[[isPhotoSelected_(photo, currentSelected_, pendingSelected_)]]" + src="[[photo.url]]" tabindex="-1"> </wallpaper-grid-item> </template>
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.ts index 12d2d96..4793b7b 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.ts
@@ -20,13 +20,14 @@ import {CurrentWallpaper, GooglePhotosPhoto, WallpaperProviderInterface, WallpaperType} from '../personalization_app.mojom-webui.js'; import {PersonalizationStateError} from '../personalization_state.js'; import {WithPersonalizationStore} from '../personalization_store.js'; -import {getNumberOfGridItemsPerRow, isNonEmptyArray, isSelectionEvent} from '../utils.js'; +import {getNumberOfGridItemsPerRow, isNonEmptyArray} from '../utils.js'; import {DisplayableImage} from './constants.js'; import {recordWallpaperGooglePhotosSourceUMA, WallpaperGooglePhotosSource} from './google_photos_metrics_logger.js'; import {getTemplate} from './google_photos_photos_element.html.js'; import {getLoadingPlaceholders, isGooglePhotosPhoto, isImageAMatchForKey, isImageEqualToSelected} from './utils.js'; import {fetchGooglePhotosPhotos, selectWallpaper} from './wallpaper_controller.js'; +import {WallpaperGridItemSelectedEvent} from './wallpaper_grid_item_element.js'; import {getWallpaperProvider} from './wallpaper_interface_provider.js'; const ERROR_ID = 'GooglePhotosPhotos'; @@ -369,10 +370,11 @@ } } - /** Invoked on selection of a photo. */ - private onPhotoSelected_(e: Event&{model: {photo: GooglePhotosPhoto}}) { - assert(e.model.photo); - if (!this.isPhotoPlaceholder_(e.model.photo) && isSelectionEvent(e)) { + /** Invoked on selection of a photo. `e.model.photo` is added by iron-list. */ + private onPhotoSelected_(e: WallpaperGridItemSelectedEvent& + {model: {photo: GooglePhotosPhoto}}) { + assert(e.model.photo, 'google photos photos selected event has photo'); + if (!this.isPhotoPlaceholder_(e.model.photo)) { selectWallpaper(e.model.photo, this.wallpaperProvider_, this.getStore()); recordWallpaperGooglePhotosSourceUMA(WallpaperGooglePhotosSource.PHOTOS); } @@ -527,14 +529,6 @@ return getPlaceholders().length * getNumberOfGridItemsPerRow(); } - /** - * Returns 'true' or 'false' depending on whether the specified |photo| is - * a placeholder. - */ - private getPhotoAriaDisabled_(photo: GooglePhotosPhoto|null): string { - return this.isPhotoPlaceholder_(photo).toString(); - } - /** Returns the aria label for the specified |photo|. */ private getPhotoAriaLabel_(photo: GooglePhotosPhoto|null): string|undefined { if (photo) {
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/local_images_element.html b/ash/webui/personalization_app/resources/js/wallpaper/local_images_element.html index 7ea39e2..f00560e 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/local_images_element.html +++ b/ash/webui/personalization_app/resources/js/wallpaper/local_images_element.html
@@ -16,13 +16,12 @@ aria-setsize$="[[imagesToDisplay_.length]]"> <template> <wallpaper-grid-item - aria-disabled$="[[isImageLoading_(item, imageDataLoading_)]]" aria-label$="[[getAriaLabel_(item, imageDataLoading_)]]" aria-posinset$="[[getAriaIndex_(index)]]" data-id$="[[getImageDataId_(item)]]" + disabled="[[isImageLoading_(item, imageDataLoading_)]]" index="[[index]]" - on-click="onImageSelected_" - on-keypress="onImageSelected_" + on-wallpaper-grid-item-selected="onImageSelected_" role="option" selected="[[isImageSelected_(item, currentSelected_, pendingSelected_)]]" src="[[getImageData_(item, imageData_, imageDataLoading_)]]"
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/local_images_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/local_images_element.ts index d68cb1e..5a344212 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/local_images_element.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/local_images_element.ts
@@ -15,19 +15,20 @@ import '../../common/icons.html.js'; import '../../css/common.css.js'; -import {assert, assertNotReached} from 'chrome://resources/js/assert.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {FilePath} from 'chrome://resources/mojo/mojo/public/mojom/base/file_path.mojom-webui.js'; import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; import {afterNextRender} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {CurrentWallpaper, WallpaperProviderInterface, WallpaperType} from '../personalization_app.mojom-webui.js'; import {WithPersonalizationStore} from '../personalization_store.js'; -import {isImageDataUrl, isSelectionEvent} from '../utils.js'; +import {isImageDataUrl} from '../utils.js'; import {DefaultImageSymbol, DisplayableImage, kDefaultImageSymbol} from './constants.js'; import {getTemplate} from './local_images_element.html.js'; import {getPathOrSymbol, isDefaultImage, isFilePath} from './utils.js'; import {fetchLocalData, getDefaultImageThumbnail, selectWallpaper} from './wallpaper_controller.js'; +import {WallpaperGridItemSelectedEvent} from './wallpaper_grid_item_element.js'; import {getWallpaperProvider} from './wallpaper_interface_provider.js'; @@ -231,27 +232,13 @@ return isFilePath(image) ? image.path : image.toString(); } - private onImageSelected_(event: Event) { - if (!isSelectionEvent(event)) { - return; - } - const dataId = (event.currentTarget as HTMLElement).dataset['id']; + private onImageSelected_(event: WallpaperGridItemSelectedEvent& + {model: {item: FilePath | DefaultImageSymbol}}) { assert( - typeof dataId === 'string' && dataId.length > 0, - 'image data id is required'); - const image = this.images_!.find(image => { - if (isFilePath(image)) { - return dataId === image.path; - } - assert( - image === kDefaultImageSymbol, 'only one symbol should be present'); - return dataId === image.toString(); - }); - if (!image) { - assertNotReached('Image with that path not found'); - return; - } - selectWallpaper(image, this.wallpaperProvider_, this.getStore()); + event.model.item === kDefaultImageSymbol || + isFilePath(event.model.item), + 'local image is a file path or default image'); + selectWallpaper(event.model.item, this.wallpaperProvider_, this.getStore()); } private getAriaIndex_(i: number): number {
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html index 98b5ae4..6aaf0448 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html +++ b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html
@@ -50,6 +50,10 @@ width: 100%; } + :host([aria-disabled='true']) .item { + cursor: default; + } + :host(:focus-visible) .item { outline: 2px solid var(--cros-focus-ring-color); }
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.ts index 7bf6433c..34ae942 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.ts
@@ -13,6 +13,8 @@ import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {isSelectionEvent} from '../utils.js'; + import {getLoadingPlaceholderAnimationDelay} from './utils.js'; import {getTemplate} from './wallpaper_grid_item_element.html.js'; @@ -36,6 +38,27 @@ !imageStatus.includes(ImageStatus.ERROR)); } +const wallpaperGridItemSelectedEventName = 'wallpaper-grid-item-selected'; + +export class WallpaperGridItemSelectedEvent extends CustomEvent<null> { + constructor() { + super( + wallpaperGridItemSelectedEventName, + { + bubbles: true, + composed: true, + detail: null, + }, + ); + } +} + +declare global { + interface HTMLElementEventMap { + [wallpaperGridItemSelectedEventName]: WallpaperGridItemSelectedEvent; + } +} + export class WallpaperGridItem extends PolymerElement { static get is(): 'wallpaper-grid-item' { return 'wallpaper-grid-item'; @@ -66,6 +89,12 @@ observer: 'onSelectedChanged_', }, + disabled: { + type: Boolean, + value: false, + observer: 'onDisabledChanged_', + }, + imageStatus_: { type: Array, value() { @@ -105,9 +134,36 @@ */ selected: boolean|undefined; + /** + * Whether the grid item is currently disabled. Automatically sets the + * aria-disabled property. + * @default false + */ + disabled: boolean; + // Track if images are loaded, failed, or ready to display. private imageStatus_: ImageStatus[]; + override ready() { + super.ready(); + this.addEventListener('click', this.onUserSelection_); + this.addEventListener('keydown', this.onUserSelection_); + } + + private onUserSelection_(event: MouseEvent|KeyboardEvent) { + // Ignore extraneous events and let them continue. + // Also ignore click and keydown events if this grid item is disabled. + // These events will continue to propagate up in case someone else is + // interested that this item was interacted with. + if (!isSelectionEvent(event) || this.disabled) { + return; + } + + event.preventDefault(); + event.stopPropagation(); + this.dispatchEvent(new WallpaperGridItemSelectedEvent()); + } + // Invoked on changes to |imageSrc|. private onImageSrcChanged_( src: Url|Url[]|undefined, old: Url|Url[]|undefined) { @@ -132,6 +188,10 @@ } } + private onDisabledChanged_(disabled: boolean) { + this.setAttribute('aria-disabled', disabled.toString()); + } + private onImageStatusChanged_(imageStatus: ImageStatus[]) { if (shouldShowPlaceholder(imageStatus)) { this.setAttribute('placeholder', '');
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_images_element.html b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_images_element.html index 806e31d8..be88a87 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_images_element.html +++ b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_images_element.html
@@ -9,14 +9,11 @@ aria-setsize$="[[tiles_.length]]"> <template> <wallpaper-grid-item - aria-disabled$="[[isLoadingTile_(item)]]" aria-label$="[[getAriaLabel_(item)]]" aria-posinset$="[[getAriaIndex_(index)]]" - data-asset-id$="[[item.assetId]]" - data-unit-id$="[[item.unitId]]" + disabled="[[isLoadingTile_(item)]]" index="[[index]]" - on-click="onImageSelected_" - on-keypress="onImageSelected_" + on-wallpaper-grid-item-selected="onImageSelected_" role="option" selected="[[isTileSelected_(item, selectedAssetId_, pendingSelectedAssetId_)]]" src="[[item.preview]]"
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_images_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_images_element.ts index 78145dd0..f895051 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_images_element.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_images_element.ts
@@ -18,11 +18,12 @@ import {CurrentWallpaper, OnlineImageType, WallpaperCollection, WallpaperImage, WallpaperType} from '../personalization_app.mojom-webui.js'; import {PersonalizationRouter} from '../personalization_router_element.js'; import {WithPersonalizationStore} from '../personalization_store.js'; -import {isNonEmptyArray, isSelectionEvent} from '../utils.js'; +import {isNonEmptyArray} from '../utils.js'; import {ImageTile} from './constants.js'; import {getLoadingPlaceholderAnimationDelay, getLoadingPlaceholders, isWallpaperImage} from './utils.js'; import {selectWallpaper} from './wallpaper_controller.js'; +import {WallpaperGridItemSelectedEvent} from './wallpaper_grid_item_element'; import {getTemplate} from './wallpaper_images_element.html.js'; import {getWallpaperProvider} from './wallpaper_interface_provider.js'; @@ -307,18 +308,14 @@ } } - private onImageSelected_(e: Event) { - if (!isSelectionEvent(e)) { - return; - } - const imgElement = e.currentTarget as HTMLImageElement; - const assetId = imgElement.dataset['assetId']; - assert(assetId, 'assetId not found'); + private onImageSelected_(e: WallpaperGridItemSelectedEvent& + {model: {item: ImageTile}}) { + const assetId = e.model.item.assetId; + assert(assetId && typeof assetId === 'bigint', 'assetId not found'); const images = this.images_[this.collectionId]!; assert(isNonEmptyArray(images)); - const selectedImage = - images.find(choice => choice.assetId.toString() === assetId); - assert(selectedImage); + const selectedImage = images.find(choice => choice.assetId === assetId); + assert(selectedImage, 'could not find selected image'); selectWallpaper(selectedImage, getWallpaperProvider(), this.getStore()); }
diff --git a/ash/webui/shortcut_customization_ui/backend/BUILD.gn b/ash/webui/shortcut_customization_ui/backend/BUILD.gn index 1c4219e..64d373d 100644 --- a/ash/webui/shortcut_customization_ui/backend/BUILD.gn +++ b/ash/webui/shortcut_customization_ui/backend/BUILD.gn
@@ -17,6 +17,7 @@ "//ash/public/cpp", "//ash/public/mojom", "//ash/webui/shortcut_customization_ui/mojom", + "//ui/events/devices", ] } @@ -36,5 +37,7 @@ "//chromeos/ash/components:test_support", "//content/test:test_support", "//testing/gtest", + "//ui/events/devices", + "//ui/events/devices:test_support", ] }
diff --git a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.cc b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.cc index df3cf21..d026709 100644 --- a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.cc +++ b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.cc
@@ -15,6 +15,8 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote_set.h" +#include "ui/events/devices/device_data_manager.h" +#include "ui/events/devices/input_device.h" namespace ash { @@ -40,13 +42,20 @@ AcceleratorConfigurationProvider::AcceleratorConfigurationProvider() : ash_accelerator_configuration_( Shell::Get()->ash_accelerator_configuration()) { + // Observe connected keyboard events. + ui::DeviceDataManager::GetInstance()->AddObserver(this); + ash_accelerator_configuration_->AddAcceleratorsUpdatedCallback( base::BindRepeating( &AcceleratorConfigurationProvider::OnAcceleratorsUpdated, weak_ptr_factory_.GetWeakPtr())); + + UpdateKeyboards(); } -AcceleratorConfigurationProvider::~AcceleratorConfigurationProvider() = default; +AcceleratorConfigurationProvider::~AcceleratorConfigurationProvider() { + ui::DeviceDataManager::GetInstance()->RemoveObserver(this); +} void AcceleratorConfigurationProvider::IsMutable( ash::mojom::AcceleratorSource source, @@ -85,6 +94,13 @@ std::move(callback).Run(std::move(accelerator_config)); } +void AcceleratorConfigurationProvider::OnInputDeviceConfigurationChanged( + uint8_t input_device_types) { + if (input_device_types & (ui::InputDeviceEventObserver::kKeyboard)) { + UpdateKeyboards(); + } +} + void AcceleratorConfigurationProvider::BindInterface( mojo::PendingReceiver< shortcut_customization::mojom::AcceleratorConfigurationProvider> @@ -102,6 +118,14 @@ return mojom::AcceleratorType::kDefault; } +void AcceleratorConfigurationProvider::UpdateKeyboards() { + ui::DeviceDataManager* device_data_manager = + ui::DeviceDataManager::GetInstance(); + DCHECK(device_data_manager); + + connected_keyboards_ = device_data_manager->GetKeyboardDevices(); +} + void AcceleratorConfigurationProvider::OnAcceleratorsUpdated( mojom::AcceleratorSource source, const ActionIdToAcceleratorsMap& mapping) {
diff --git a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.h b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.h index 4333487f..47220e17e 100644 --- a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.h +++ b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.h
@@ -12,12 +12,15 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote_set.h" +#include "ui/events/devices/input_device.h" +#include "ui/events/devices/input_device_event_observer.h" namespace ash { namespace shortcut_ui { class AcceleratorConfigurationProvider - : shortcut_customization::mojom::AcceleratorConfigurationProvider { + : public shortcut_customization::mojom::AcceleratorConfigurationProvider, + public ui::InputDeviceEventObserver { public: using AcceleratorConfigurationMap = base::flat_map<mojom::AcceleratorSource, @@ -40,6 +43,9 @@ IsMutableCallback callback) override; void GetAccelerators(GetAcceleratorsCallback callback) override; + // ui::InputDeviceEventObserver: + void OnInputDeviceConfigurationChanged(uint8_t input_device_types) override; + void BindInterface( mojo::PendingReceiver< shortcut_customization::mojom::AcceleratorConfigurationProvider> @@ -53,11 +59,16 @@ mojom::AcceleratorType GetAcceleratorType(ui::Accelerator accelerator); + void UpdateKeyboards(); + std::vector<AcceleratorInfo> accelerator_infos_; std::map<AcceleratorActionId, std::vector<AcceleratorInfo>> id_to_accelerator_info_; + // Stores all connected keyboards. + std::vector<ui::InputDevice> connected_keyboards_; + mojo::Receiver< shortcut_customization::mojom::AcceleratorConfigurationProvider> receiver_{this};
diff --git a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc index 4ae7783ab..681f2bb 100644 --- a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc +++ b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc
@@ -23,6 +23,8 @@ #include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/events/devices/device_data_manager_test_api.h" +#include "ui/events/devices/input_device.h" namespace ash { @@ -50,6 +52,13 @@ key_display_equals && has_key_event_equals; } +void CompareInputDevices(const ui::InputDevice& expected, + const ui::InputDevice& actual) { + EXPECT_EQ(expected.type, actual.type); + EXPECT_EQ(expected.id, actual.id); + EXPECT_EQ(expected.name, actual.name); +} + void ExpectAllAcceleratorsEqual( const base::span<const ash::AcceleratorData>& expected, const std::vector<ash::AcceleratorInfo>& actual) { @@ -128,6 +137,10 @@ expected)); } + const std::vector<ui::InputDevice>& GetConnectedKeyboards() { + return provider_->connected_keyboards_; + } + std::unique_ptr<AcceleratorConfigurationProvider> provider_; }; @@ -208,6 +221,24 @@ base::RunLoop().RunUntilIdle(); } +// TODO(jimmyxgong): Update test to check accelerators sent via Mojo. +TEST_F(AcceleratorConfigurationProviderTest, ConnectedKeyboardsUpdated) { + const std::vector<ui::InputDevice>& devices = GetConnectedKeyboards(); + EXPECT_TRUE(devices.empty()); + + ui::InputDevice expected_test_keyboard( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"); + + std::vector<ui::InputDevice> keyboard_devices; + keyboard_devices.push_back(expected_test_keyboard); + + ui::DeviceDataManagerTestApi().SetKeyboardDevices(keyboard_devices); + + const std::vector<ui::InputDevice>& actual_devices = GetConnectedKeyboards(); + EXPECT_EQ(1u, actual_devices.size()); + CompareInputDevices(expected_test_keyboard, actual_devices[0]); +} + } // namespace shortcut_ui } // namespace ash
diff --git a/ash/wm/desks/templates/saved_desk_library_view.cc b/ash/wm/desks/templates/saved_desk_library_view.cc index 3a03876..619fdca 100644 --- a/ash/wm/desks/templates/saved_desk_library_view.cc +++ b/ash/wm/desks/templates/saved_desk_library_view.cc
@@ -23,7 +23,6 @@ #include "ash/wm/overview/overview_grid.h" #include "ash/wm/overview/overview_grid_event_handler.h" #include "base/functional/callback_helpers.h" -#include "base/notreached.h" #include "ui/aura/window_targeter.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" @@ -105,8 +104,8 @@ case DeskTemplateType::kSaveAndRecall: grouped.save_and_recall.push_back(saved_desk); break; + // Do nothing in the case of an unknown template. case DeskTemplateType::kUnknown: - NOTREACHED(); break; } } @@ -522,17 +521,14 @@ absl::optional<gfx::Rect> SavedDeskLibraryView::GetDeskPreviewBoundsForLaunch( const DeskMiniView* mini_view) { - gfx::Transform transform = mini_view->layer()->transform(); - gfx::Transform inversed; - if (!transform.GetInverse(&inversed)) - return absl::nullopt; - gfx::Rect desk_preview_bounds = mini_view->desk_preview()->GetBoundsInScreen(); - gfx::Point desk_preview_origin = - inversed.MapPoint(desk_preview_bounds.origin()); - - return gfx::Rect(desk_preview_origin, desk_preview_bounds.size()); + if (absl::optional<gfx::Point> desk_preview_origin = + mini_view->layer()->transform().InverseMapPoint( + desk_preview_bounds.origin())) { + return gfx::Rect(*desk_preview_origin, desk_preview_bounds.size()); + } + return absl::nullopt; } void SavedDeskLibraryView::AddedToWidget() {
diff --git a/ash/wm/desks/templates/saved_desk_unittest.cc b/ash/wm/desks/templates/saved_desk_unittest.cc index 883a9ba..63cb172 100644 --- a/ash/wm/desks/templates/saved_desk_unittest.cc +++ b/ash/wm/desks/templates/saved_desk_unittest.cc
@@ -4513,4 +4513,34 @@ EXPECT_EQ(2u, GetItemViewsFromDeskLibrary(overview_grid2).size()); } +// This tests that unknown desk types added into the desk model do not affect +// the UI. This is done by adding a template in the normal way and then +// injecting an unknown type template into the storage model. The result should +// be that the saved desk library only shows the normal template. +TEST_F(SavedDeskTest, UiIgnoresUnknownDeskTypes) { + // Add a window. + auto test_window = CreateAppWindow(); + + // Enter overview. + ToggleOverview(); + ASSERT_TRUE(GetOverviewSession()); + + // Save a normal template here. + aura::Window* root = Shell::GetPrimaryRootWindow(); + SavedDeskSaveDeskButton* save_template_button = + GetSaveDeskAsTemplateButtonForRoot(root); + ASSERT_TRUE(save_template_button); + ClickOnView(save_template_button); + WaitForDesksTemplatesUI(); + WaitForLibraryUI(); + + // Add unknown type into model. + AddEntry(base::GUID::GenerateRandomV4(), "Unknown desk type name\n", + base::Time::Now(), DeskTemplateType::kUnknown); + + // Ensure only the normal template appears in the overview grid. + OverviewGrid* overview_grid = GetOverviewGridList().front().get(); + EXPECT_EQ(1u, GetItemViewsFromDeskLibrary(overview_grid).size()); +} + } // namespace ash
diff --git a/ash/wm/float/float_controller_unittest.cc b/ash/wm/float/float_controller_unittest.cc index d3716e1..797e8b2e 100644 --- a/ash/wm/float/float_controller_unittest.cc +++ b/ash/wm/float/float_controller_unittest.cc
@@ -9,7 +9,6 @@ #include "ash/app_list/app_list_controller_impl.h" #include "ash/constants/ash_features.h" #include "ash/display/screen_orientation_controller_test_api.h" -#include "ash/frame/header_view.h" #include "ash/frame/non_client_frame_view_ash.h" #include "ash/public/cpp/shelf_config.h" #include "ash/public/cpp/test/shell_test_api.h" @@ -39,6 +38,7 @@ #include "base/containers/contains.h" #include "base/test/scoped_feature_list.h" #include "chromeos/ui/base/window_state_type.h" +#include "chromeos/ui/frame/header_view.h" #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "chromeos/ui/wm/constants.h" #include "chromeos/ui/wm/features.h" @@ -60,7 +60,7 @@ namespace ash { // Gets the header view for `window` so it can be dragged. -HeaderView* GetHeaderView(aura::Window* window) { +chromeos::HeaderView* GetHeaderView(aura::Window* window) { // Exiting immersive mode because of float does not seem to trigger a layout // like it does in production code. Here we force a layout, otherwise the // client view will remain the size of the widget, and dragging it will give @@ -133,7 +133,7 @@ std::unique_ptr<aura::Window> window = CreateFloatedWindow(); // Double click on the caption. The window should be maximized now. - HeaderView* header_view = GetHeaderView(window.get()); + chromeos::HeaderView* header_view = GetHeaderView(window.get()); auto* event_generator = GetEventGenerator(); event_generator->set_current_screen_location( header_view->GetBoundsInScreen().CenterPoint()); @@ -271,7 +271,7 @@ // does not update the display associated with the cursor, so we have to // manually do it here. auto* frame = NonClientFrameViewAsh::Get(window.get()); - HeaderView* header_view = frame->GetHeaderView(); + chromeos::HeaderView* header_view = frame->GetHeaderView(); auto* event_generator = GetEventGenerator(); event_generator->set_current_screen_location( header_view->GetBoundsInScreen().CenterPoint()); @@ -908,7 +908,7 @@ // Start dragging in the center of the header. When moving the touch, the // header should move with the touch such that the touch remains in the center // of the header. - HeaderView* header_view = GetHeaderView(window.get()); + chromeos::HeaderView* header_view = GetHeaderView(window.get()); auto* event_generator = GetEventGenerator(); event_generator->PressTouch(header_view->GetBoundsInScreen().CenterPoint()); @@ -929,7 +929,7 @@ std::unique_ptr<aura::Window> window = CreateFloatedWindow(); // Press the accelerator to maximize before releasing touch. - HeaderView* header_view = GetHeaderView(window.get()); + chromeos::HeaderView* header_view = GetHeaderView(window.get()); auto* event_generator = GetEventGenerator(); event_generator->PressTouch(header_view->GetBoundsInScreen().CenterPoint()); event_generator->MoveTouch(gfx::Point(100, 100)); @@ -994,7 +994,7 @@ // Move the mouse to towards the right edge. Test that on release, it snaps // right. - HeaderView* header_view = GetHeaderView(window.get()); + chromeos::HeaderView* header_view = GetHeaderView(window.get()); auto* event_generator = GetEventGenerator(); event_generator->set_current_screen_location( header_view->GetBoundsInScreen().CenterPoint());
diff --git a/ash/wm/immersive_fullscreen_controller_unittest.cc b/ash/wm/immersive_fullscreen_controller_unittest.cc index 4aab19f..dd62a6c 100644 --- a/ash/wm/immersive_fullscreen_controller_unittest.cc +++ b/ash/wm/immersive_fullscreen_controller_unittest.cc
@@ -4,7 +4,6 @@ #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" -#include "ash/frame/header_view.h" #include "ash/frame/non_client_frame_view_ash.h" #include "ash/public/cpp/shelf_config.h" #include "ash/public/cpp/shelf_types.h" @@ -17,6 +16,7 @@ #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_state.h" #include "base/test/scoped_feature_list.h" +#include "chromeos/ui/frame/header_view.h" #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_delegate.h" #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" #include "ui/aura/client/aura_constants.h" @@ -180,7 +180,7 @@ aura::Window* window() { return widget_->GetNativeWindow(); } - HeaderView* immersive_delegate() { + chromeos::HeaderView* immersive_delegate() { return NonClientFrameViewAsh::Get(window())->GetHeaderView(); }
diff --git a/base/BUILD.gn b/base/BUILD.gn index 2190bec..c9a77607 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -768,7 +768,6 @@ "task/sequence_manager/task_queue_impl.h", "task/sequence_manager/task_queue_selector.cc", "task/sequence_manager/task_queue_selector.h", - "task/sequence_manager/task_queue_selector_logic.h", "task/sequence_manager/task_time_observer.h", "task/sequence_manager/tasks.cc", "task/sequence_manager/tasks.h", @@ -1938,6 +1937,7 @@ # by public //base headers, which requires they be on the include path. # TODO(https://crbug.com/841171): Move these back to |deps|. public_deps += [ + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.component.runner", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.intl", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.io", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.logger",
diff --git a/base/fuchsia/startup_context.cc b/base/fuchsia/startup_context.cc index 8019b36..e93634c 100644 --- a/base/fuchsia/startup_context.cc +++ b/base/fuchsia/startup_context.cc
@@ -5,11 +5,13 @@ #include "base/fuchsia/startup_context.h" #include <tuple> +#include <utility> #include <fuchsia/io/cpp/fidl.h> #include <lib/sys/cpp/outgoing_directory.h> #include <lib/sys/cpp/service_directory.h> +#include "base/check.h" #include "base/check_op.h" #include "base/fuchsia/file_utils.h" #include "base/fuchsia/fuchsia_logging.h" @@ -17,6 +19,36 @@ namespace base { +StartupContext::StartupContext( + fuchsia::component::runner::ComponentStartInfo start_info) { + std::unique_ptr<sys::ServiceDirectory> incoming_services; + + // Component manager generates |flat_namespace|, so things are horribly broken + // if |flat_namespace| is malformed. + CHECK(start_info.has_ns()); + + // Find the /svc directory and wrap it into a sys::ServiceDirectory. + auto& namespace_entries = *start_info.mutable_ns(); + for (auto& entry : namespace_entries) { + CHECK(entry.has_path() && entry.has_directory()); + if (entry.path() == kServiceDirectoryPath) { + incoming_services = std::make_unique<sys::ServiceDirectory>( + std::move(*entry.mutable_directory())); + break; + } + } + + // If there is no service-directory in the namespace then `incoming_services` + // may be null, in which case `svc()` will be null. + component_context_ = + std::make_unique<sys::ComponentContext>(std::move(incoming_services)); + if (start_info.has_outgoing_dir()) { + outgoing_directory_request_ = std::move(*start_info.mutable_outgoing_dir()); + } +} + +StartupContext::~StartupContext() = default; + StartupContext::StartupContext(fuchsia::sys::StartupInfo startup_info) { std::unique_ptr<sys::ServiceDirectory> incoming_services; @@ -34,51 +66,6 @@ } } - // TODO(https://crbug.com/933834): Remove these workarounds when we migrate to - // the new component manager. - if (!incoming_services && startup_info.launch_info.flat_namespace) { - LOG(WARNING) << "Falling back to LaunchInfo namespace"; - for (size_t i = 0; - i < startup_info.launch_info.flat_namespace->paths.size(); ++i) { - if (startup_info.launch_info.flat_namespace->paths[i] == - kServiceDirectoryPath) { - incoming_services = std::make_unique<sys::ServiceDirectory>( - std::move(startup_info.launch_info.flat_namespace->directories[i])); - break; - } - } - } - - if (!incoming_services && startup_info.launch_info.additional_services) { - LOG(WARNING) << "Falling back to additional ServiceList services"; - - // Construct a OutgoingDirectory and publish the additional services into - // it. - additional_services_.Bind( - std::move(startup_info.launch_info.additional_services->provider)); - additional_services_directory_ = std::make_unique<sys::OutgoingDirectory>(); - for (auto& name : startup_info.launch_info.additional_services->names) { - zx_status_t status = additional_services_directory_->AddPublicService( - std::make_unique<vfs::Service>([this, name]( - zx::channel channel, - async_dispatcher_t* dispatcher) { - additional_services_->ConnectToService(name, std::move(channel)); - }), - name); - ZX_CHECK(status == ZX_OK, status) - << "AddPublicService(" << name << ") failed"; - } - - // Publish those services to the caller as |incoming_services|. - fidl::InterfaceHandle<fuchsia::io::Directory> incoming_directory; - additional_services_directory_->GetOrCreateDirectory("svc")->Serve( - fuchsia::io::OpenFlags::RIGHT_READABLE | - fuchsia::io::OpenFlags::RIGHT_WRITABLE, - incoming_directory.NewRequest().TakeChannel()); - incoming_services = - std::make_unique<sys::ServiceDirectory>(std::move(incoming_directory)); - } - if (!incoming_services) { LOG(WARNING) << "Component started without a service directory"; @@ -96,8 +83,6 @@ std::move(startup_info.launch_info.directory_request); } -StartupContext::~StartupContext() = default; - void StartupContext::ServeOutgoingDirectory() { DCHECK(outgoing_directory_request_); component_context_->outgoing()->Serve(std::move(outgoing_directory_request_));
diff --git a/base/fuchsia/startup_context.h b/base/fuchsia/startup_context.h index 263342b1..44c7236 100644 --- a/base/fuchsia/startup_context.h +++ b/base/fuchsia/startup_context.h
@@ -5,15 +5,17 @@ #ifndef BASE_FUCHSIA_STARTUP_CONTEXT_H_ #define BASE_FUCHSIA_STARTUP_CONTEXT_H_ +#include <fuchsia/component/runner/cpp/fidl.h> +#include <fuchsia/io/cpp/fidl.h> #include <fuchsia/sys/cpp/fidl.h> #include <lib/sys/cpp/component_context.h> #include <lib/zx/channel.h> + #include <memory> #include "base/base_export.h" namespace sys { -class ComponentContext; class ServiceDirectory; class OutgoingDirectory; } // namespace sys @@ -25,10 +27,15 @@ // directories, resolve launch URL etc). // Embedders may derived from StartupContext to e.g. add bound pointers to // embedder-specific services, as required. -class BASE_EXPORT StartupContext { +class BASE_EXPORT StartupContext final { public: + explicit StartupContext( + ::fuchsia::component::runner::ComponentStartInfo start_info); + ~StartupContext(); + + // TODO(https://crbug.com/1065707): Remove this overload once the CFv1 + // Runner implementations are removed. explicit StartupContext(::fuchsia::sys::StartupInfo startup_info); - virtual ~StartupContext(); StartupContext(const StartupContext&) = delete; StartupContext& operator=(const StartupContext&) = delete; @@ -56,11 +63,6 @@ } private: - // TODO(https://crbug.com/933834): Remove these when we migrate to the new - // component manager APIs. - ::fuchsia::sys::ServiceProviderPtr additional_services_; - std::unique_ptr<sys::OutgoingDirectory> additional_services_directory_; - std::unique_ptr<sys::ComponentContext> component_context_; // Used to store outgoing directory until ServeOutgoingDirectory() is called.
diff --git a/base/mac/mac_util.h b/base/mac/mac_util.h index 18510cc..4672b1e 100644 --- a/base/mac/mac_util.h +++ b/base/mac/mac_util.h
@@ -213,6 +213,53 @@ // Returns the serial number of the macOS device. BASE_EXPORT std::string GetPlatformSerialNumber(); +// System Settings (née System Preferences) pane or subpanes to open via +// `OpenSystemSettingsPane()`, below. The naming is based on the naming in the +// System Settings app in the latest macOS release, macOS 13 Ventura. +enum class SystemSettingsPane { + // Accessibility > Captions + kAccessibility_Captions, + + // Date & Time + kDateTime, + + // Network > Proxies + kNetwork_Proxies, + + // Printers & Scanners + kPrintersScanners, + + // Privacy & Security > Accessibility + kPrivacySecurity_Accessibility, + + // Privacy & Security > Bluetooth + // Available on macOS 11 and later. + kPrivacySecurity_Bluetooth, + + // Privacy & Security > Camera + // Available on macOS 10.14 and later. + kPrivacySecurity_Camera, + + // Privacy & Security > Extensions > Sharing + kPrivacySecurity_Extensions_Sharing, + + // Privacy & Security > Location Services + kPrivacySecurity_LocationServices, + + // Privacy & Security > Microphone + // Available on macOS 10.14 and later. + kPrivacySecurity_Microphone, + + // Privacy & Security > Screen Recording + // Available on macOS 10.15 and later. + kPrivacySecurity_ScreenRecording, +}; + +// Opens the specified System Settings pane. If the specified subpane does not +// exist on the release of macOS that is running, the parent pane will open +// instead. +BASE_EXPORT void OpenSystemSettingsPane(SystemSettingsPane pane); + } // namespace base::mac #endif // BASE_MAC_MAC_UTIL_H_
diff --git a/base/mac/mac_util.mm b/base/mac/mac_util.mm index 8f001488..4ea6802 100644 --- a/base/mac/mac_util.mm +++ b/base/mac/mac_util.mm
@@ -20,6 +20,7 @@ #include "base/mac/bundle_locations.h" #include "base/mac/foundation_util.h" #include "base/mac/mac_logging.h" +#include "base/mac/scoped_aedesc.h" #include "base/mac/scoped_cftyperef.h" #include "base/mac/scoped_ioobject.h" #include "base/mac/scoped_nsobject.h" @@ -485,4 +486,104 @@ return base::SysCFStringRefToUTF8(serial_number_cfstring); } +void OpenSystemSettingsPane(SystemSettingsPane pane) { + NSString* url = nil; + NSString* pane_file = nil; + NSData* subpane_data = nil; + switch (pane) { + case SystemSettingsPane::kAccessibility_Captions: + url = @"x-apple.systempreferences:com.apple.preference.universalaccess?" + @"Captioning"; + break; + case SystemSettingsPane::kDateTime: + if (IsAtLeastOS13()) { + url = @"x-apple.systempreferences:com.apple.preference.datetime"; + } else { + pane_file = @"/System/Library/PreferencePanes/DateAndTime.prefPane"; + } + break; + case SystemSettingsPane::kNetwork_Proxies: + if (IsAtLeastOS13()) { + url = @"x-apple.systempreferences:com.apple.preference.network?" + @"Proxies"; + } else { + pane_file = @"/System/Library/PreferencePanes/Network.prefPane"; + subpane_data = [@"Proxies" dataUsingEncoding:NSASCIIStringEncoding]; + } + break; + case SystemSettingsPane::kPrintersScanners: + if (IsAtLeastOS13()) { + url = @"x-apple.systempreferences:com.apple.preference.printfax"; + } else { + pane_file = @"/System/Library/PreferencePanes/PrintAndFax.prefPane"; + } + break; + case SystemSettingsPane::kPrivacySecurity_Accessibility: + url = @"x-apple.systempreferences:com.apple.preference.security?" + @"Privacy_Accessibility"; + break; + case SystemSettingsPane::kPrivacySecurity_Bluetooth: + url = @"x-apple.systempreferences:com.apple.preference.security?" + @"Privacy_Bluetooth"; + break; + case SystemSettingsPane::kPrivacySecurity_Camera: + url = @"x-apple.systempreferences:com.apple.preference.security?" + @"Privacy_Camera"; + break; + case SystemSettingsPane::kPrivacySecurity_Extensions_Sharing: + if (IsAtLeastOS13()) { + // See ShareKit, -[SHKSharingServicePicker openAppExtensionsPrefpane]. + url = @"x-apple.systempreferences:com.apple.ExtensionPreferences?" + @"Sharing"; + } else { + // This is equivalent to the implementation of AppKit's + // +[NSSharingServicePicker openAppExtensionsPrefPane]. + pane_file = @"/System/Library/PreferencePanes/Extensions.prefPane"; + NSDictionary* subpane_dict = @{ + @"action" : @"revealExtensionPoint", + @"protocol" : @"com.apple.share-services" + }; + subpane_data = [NSPropertyListSerialization + dataWithPropertyList:subpane_dict + format:NSPropertyListXMLFormat_v1_0 + options:0 + error:nil]; + } + break; + case SystemSettingsPane::kPrivacySecurity_LocationServices: + url = @"x-apple.systempreferences:com.apple.preference.security?" + @"Privacy_LocationServices"; + break; + case SystemSettingsPane::kPrivacySecurity_Microphone: + url = @"x-apple.systempreferences:com.apple.preference.security?" + @"Privacy_Microphone"; + break; + case SystemSettingsPane::kPrivacySecurity_ScreenRecording: + url = @"x-apple.systempreferences:com.apple.preference.security?" + @"Privacy_ScreenCapture"; + break; + } + + DCHECK(url != nil ^ pane_file != nil); + + if (url) { + [NSWorkspace.sharedWorkspace openURL:[NSURL URLWithString:url]]; + return; + } + + NSArray* pane_file_urls = @[ [NSURL fileURLWithPath:pane_file] ]; + + LSLaunchURLSpec launchSpec = {0}; + launchSpec.itemURLs = NSToCFCast(pane_file_urls); + if (subpane_data) { + base::scoped_nsobject<NSAppleEventDescriptor> descriptor( + [[NSAppleEventDescriptor alloc] initWithDescriptorType:'ptru' + data:subpane_data]); + launchSpec.passThruParams = descriptor.get().aeDesc; + } + launchSpec.launchFlags = kLSLaunchAsync | kLSLaunchDontAddToRecents; + + LSOpenFromURLSpec(&launchSpec, nullptr); +} + } // namespace base::mac
diff --git a/base/task/sequence_manager/task_queue_selector.h b/base/task/sequence_manager/task_queue_selector.h index 53c1473..7b57b3d 100644 --- a/base/task/sequence_manager/task_queue_selector.h +++ b/base/task/sequence_manager/task_queue_selector.h
@@ -16,7 +16,6 @@ #include "base/task/sequence_manager/sequence_manager.h" #include "base/task/sequence_manager/sequenced_task_source.h" #include "base/task/sequence_manager/task_order.h" -#include "base/task/sequence_manager/task_queue_selector_logic.h" #include "base/task/sequence_manager/work_queue_sets.h" #include "base/values.h" #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/base/task/sequence_manager/task_queue_selector_logic.h b/base/task/sequence_manager/task_queue_selector_logic.h deleted file mode 100644 index 46e62d1..0000000 --- a/base/task/sequence_manager/task_queue_selector_logic.h +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2015 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_TASK_SEQUENCE_MANAGER_TASK_QUEUE_SELECTOR_LOGIC_H_ -#define BASE_TASK_SEQUENCE_MANAGER_TASK_QUEUE_SELECTOR_LOGIC_H_ - -namespace base { -namespace sequence_manager { -namespace internal { - -// Used to describe the logic trigerred when a task queue is selected to -// service. -// This enum is used for histograms and should not be renumbered. -enum class TaskQueueSelectorLogic { - // Selected due to priority rules. - kControlPriorityLogic = 0, - kHighestPriorityLogic = 1, - kHighPriorityLogic = 2, - kNormalPriorityLogic = 3, - kLowPriorityLogic = 4, - kBestEffortPriorityLogic = 5, - - // Selected due to starvation logic. - kHighPriorityStarvationLogic = 6, - kNormalPriorityStarvationLogic = 7, - kLowPriorityStarvationLogic = 8, - - kCount = 9, -}; - -} // namespace internal -} // namespace sequence_manager -} // namespace base - -#endif // BASE_TASK_SEQUENCE_MANAGER_TASK_QUEUE_SELECTOR_LOGIC_H_
diff --git a/build/android/gyp/create_java_binary_script.py b/build/android/gyp/create_java_binary_script.py index 2c7ad27e..a2f701e 100755 --- a/build/android/gyp/create_java_binary_script.py +++ b/build/android/gyp/create_java_binary_script.py
@@ -82,15 +82,17 @@ help='Name of the java class with the "main" entry point.') parser.add_option('--classpath', action='append', default=[], help='Classpath for running the jar.') - parser.add_option('--noverify', action='store_true', - help='JVM flag: noverify.') + parser.add_option('--max-heap-size', default='1G', help='Argument for -Xmx') + parser.add_option('--noverify', + action='store_true', + help='JVM flag: noverify.') parser.add_option('--tiered-stop-at-level-one', action='store_true', help='JVM flag: -XX:TieredStopAtLevel=1.') options, extra_program_args = parser.parse_args(argv) - extra_flags = [] + extra_flags = [f'java_cmd.append("-Xmx{options.max_heap_size}")'] if options.noverify: extra_flags.append('java_cmd.append("-noverify")') if options.tiered_stop_at_level_one:
diff --git a/build/config/fuchsia/test/README.md b/build/config/fuchsia/test/README.md index 009cc2d..f2084d9 100644 --- a/build/config/fuchsia/test/README.md +++ b/build/config/fuchsia/test/README.md
@@ -40,7 +40,14 @@ For tests that test logging functionality by providing `fuchsia.logger.Log`. #### test_ui_stack.shard.test-cml -For tests that need an isolated Scenic by way of Fuchsia's test-ui-stack. +For tests that need an isolated UI subsystem, that supports the Flatland +API set. This allows tests to e.g. run with view-focus unaffected by any +other tests running concurrently on the device, as well as providing test-only +functionality such as input-injection support. + +#### gfx_test_ui_stack.shard.test-cml +For tests that need an isolated display subsystem supporting the legacy +Scenic/GFX APIs. ### WebEngine Fragments The following fragments are specific to WebEngine functionality as documented
diff --git a/build/config/fuchsia/test/gfx_test_ui_stack.shard.test-cml b/build/config/fuchsia/test/gfx_test_ui_stack.shard.test-cml new file mode 100644 index 0000000..e9c5067a --- /dev/null +++ b/build/config/fuchsia/test/gfx_test_ui_stack.shard.test-cml
@@ -0,0 +1,41 @@ +// 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. + +// Used in tests which are hard-coded for the Scenic/GFX API-set. +// Use test_ui_stack.shard.test-cml when tetsing for Flatland, or when the +// choice of API-set is not important. +{ + children: [ + { + name: "test_ui_stack", + url: "fuchsia-pkg://fuchsia.com/gfx-scene-manager-test-ui-stack#meta/test-ui-stack.cm", + }, + ], + offer: [ + { + protocol: [ + "fuchsia.logger.LogSink", + "fuchsia.scheduler.ProfileProvider", + "fuchsia.sysmem.Allocator", + "fuchsia.tracing.provider.Registry", + "fuchsia.vulkan.loader.Loader", + ], + from: "parent", + to: "#test_ui_stack", + }, + ], + use: [ + { + protocol: [ + "fuchsia.accessibility.semantics.SemanticsManager", + "fuchsia.element.GraphicalPresenter", + "fuchsia.ui.composition.Allocator", + "fuchsia.ui.composition.Flatland", + "fuchsia.ui.input3.Keyboard", + "fuchsia.ui.scenic.Scenic", + ], + from: "#test_ui_stack", + }, + ], +}
diff --git a/build/config/fuchsia/test/test_ui_stack.shard.test-cml b/build/config/fuchsia/test/test_ui_stack.shard.test-cml index a57d434..3ee8563 100644 --- a/build/config/fuchsia/test/test_ui_stack.shard.test-cml +++ b/build/config/fuchsia/test/test_ui_stack.shard.test-cml
@@ -25,6 +25,7 @@ { protocol: [ "fuchsia.accessibility.semantics.SemanticsManager", + "fuchsia.element.GraphicalPresenter", "fuchsia.ui.composition.Allocator", "fuchsia.ui.composition.Flatland", "fuchsia.ui.input3.Keyboard",
diff --git a/build/linux/unbundle/openh264.gn b/build/linux/unbundle/openh264.gn index 1a19ceed..f4abd9b 100644 --- a/build/linux/unbundle/openh264.gn +++ b/build/linux/unbundle/openh264.gn
@@ -11,7 +11,7 @@ shim_headers("openh264_shim") { prefix = "wels/" - root_path = "src/codec/api/svc" + root_path = "src/codec/api/wels" headers = [ "codec_api.h", "codec_app_def.h",
diff --git a/cc/base/math_util.cc b/cc/base/math_util.cc index e650c6b2..3946a919 100644 --- a/cc/base/math_util.cc +++ b/cc/base/math_util.cc
@@ -330,11 +330,9 @@ gfx::QuadF MathUtil::InverseMapQuadToLocalSpace( const gfx::Transform& device_transform, const gfx::QuadF& device_quad) { - gfx::Transform inverse_device_transform(gfx::Transform::kSkipInitialization); - DCHECK(device_transform.IsInvertible()); DCHECK(device_transform.IsFlat()); - bool did_invert = device_transform.GetInverse(&inverse_device_transform); - DCHECK(did_invert); + gfx::Transform inverse_device_transform = + device_transform.GetCheckedInverse(); bool clipped = false; gfx::QuadF local_quad = MathUtil::MapQuad(inverse_device_transform, device_quad, &clipped);
diff --git a/cc/benchmarks/invalidation_benchmark.cc b/cc/benchmarks/invalidation_benchmark.cc index 02d9470..a2ef2c6 100644 --- a/cc/benchmarks/invalidation_benchmark.cc +++ b/cc/benchmarks/invalidation_benchmark.cc
@@ -70,10 +70,8 @@ void InvalidationBenchmark::RunOnLayer(PictureLayer* layer) { gfx::Rect visible_layer_rect = gfx::Rect(layer->bounds()); - gfx::Transform from_screen; - bool invertible = layer->ScreenSpaceTransform().GetInverse(&from_screen); - if (!invertible) - from_screen = gfx::Transform(); + gfx::Transform from_screen = + layer->ScreenSpaceTransform().InverseOrIdentity(); gfx::Rect viewport_rect = MathUtil::ProjectEnclosingClippedRect( from_screen, layer->layer_tree_host()->device_viewport_rect()); visible_layer_rect.Intersect(viewport_rect);
diff --git a/cc/input/input_handler.cc b/cc/input/input_handler.cc index 929c396..3ebce36 100644 --- a/cc/input/input_handler.cc +++ b/cc/input/input_handler.cc
@@ -854,14 +854,11 @@ if (out_touch_action) { gfx::Transform layer_screen_space_transform = layer_impl_with_touch_handler->ScreenSpaceTransform(); - gfx::Transform inverse_layer_screen_space( - gfx::Transform::kSkipInitialization); - bool can_be_inversed = - layer_screen_space_transform.GetInverse(&inverse_layer_screen_space); // Getting here indicates that |layer_impl_with_touch_handler| is non-null, // which means that the |hit| in FindClosestMatchingLayer() is true, which // indicates that the inverse is available. - DCHECK(can_be_inversed); + gfx::Transform inverse_layer_screen_space = + layer_screen_space_transform.GetCheckedInverse(); bool clipped = false; gfx::Point3F planar_point = MathUtil::ProjectPoint3D( inverse_layer_screen_space, device_viewport_point, &clipped); @@ -1667,14 +1664,10 @@ // the scroll hit test in the first place. const gfx::Transform screen_space_transform = GetScrollTree().ScreenSpaceTransform(scroll_node.id); - DCHECK(screen_space_transform.IsInvertible()); - gfx::Transform inverse_screen_space_transform( - gfx::Transform::kSkipInitialization); - bool did_invert = - screen_space_transform.GetInverse(&inverse_screen_space_transform); // TODO(shawnsingh): With the advent of impl-side scrolling for non-root // layers, we may need to explicitly handle uninvertible transforms here. - DCHECK(did_invert); + gfx::Transform inverse_screen_space_transform = + screen_space_transform.GetCheckedInverse(); float scale_from_viewport_to_screen_space = compositor_delegate_.DeviceScaleFactor();
diff --git a/cc/input/scrollbar_controller.cc b/cc/input/scrollbar_controller.cc index e47ff01..5a00962b 100644 --- a/cc/input/scrollbar_controller.cc +++ b/cc/input/scrollbar_controller.cc
@@ -786,8 +786,7 @@ return gfx::PointF(0, 0); } - gfx::Transform inverse_screen_space_transform( - gfx::Transform::kSkipInitialization); + gfx::Transform inverse_screen_space_transform; gfx::Transform scaled_screen_space_transform( scrollbar->ScreenSpaceTransform());
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index 1354c0e4..6bd2ae13 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc
@@ -932,7 +932,7 @@ return true; } - gfx::Transform inverse(gfx::Transform::kSkipInitialization); + gfx::Transform inverse; if (b.GetInverse(&inverse)) { inverse *= a; return inverse.Preserves2dAxisAlignment();
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index c11493b..d977f656 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc
@@ -684,7 +684,7 @@ if (visible_rect_in_content_space.IsEmpty() || layer_tree_impl()->GetDeviceViewport() != viewport_rect_for_tile_priority) { - gfx::Transform view_to_layer(gfx::Transform::kSkipInitialization); + gfx::Transform view_to_layer; if (ScreenSpaceTransform().GetInverse(&view_to_layer)) { // Transform from view space to content space. visible_rect_in_content_space = MathUtil::ProjectEnclosingClippedRect(
diff --git a/cc/layers/render_surface_impl.cc b/cc/layers/render_surface_impl.cc index e7cbb0025..2e3bee3 100644 --- a/cc/layers/render_surface_impl.cc +++ b/cc/layers/render_surface_impl.cc
@@ -240,7 +240,7 @@ // Calculate projection from the target surface rect to local // space. Non-invertible draw transforms means no able to bring clipped rect // in target space back to local space, early out without clip. - gfx::Transform target_to_surface(gfx::Transform::kSkipInitialization); + gfx::Transform target_to_surface; if (!draw_transform().GetInverse(&target_to_surface)) return accumulated_content_rect();
diff --git a/cc/trees/draw_properties_unittest.cc b/cc/trees/draw_properties_unittest.cc index 7c12831a..fd3b0d4 100644 --- a/cc/trees/draw_properties_unittest.cc +++ b/cc/trees/draw_properties_unittest.cc
@@ -286,7 +286,7 @@ gfx::Transform translation_to_anchor; translation_to_anchor.Translate(5.0, 0.0); gfx::Transform expected_result = translation_to_anchor * layer_transform * - gfx::InvertAndCheck(translation_to_anchor); + translation_to_anchor.GetCheckedInverse(); SetTransformOrigin(layer, gfx::Point3F(5.f, 0.f, 0.f)); UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORM_EQ(expected_result, draw_property_utils::DrawTransform( @@ -299,8 +299,7 @@ // current implementation of CalculateDrawProperties does this implicitly, but // it is still worth testing to detect accidental regressions. expected_result = position_transform * translation_to_anchor * - layer_transform * - gfx::InvertAndCheck(translation_to_anchor); + layer_transform * translation_to_anchor.GetCheckedInverse(); SetPostTranslation(layer, gfx::Vector2dF(0.f, 1.2f)); UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORM_EQ(expected_result, draw_property_utils::DrawTransform( @@ -454,7 +453,7 @@ parent_translation_to_anchor.Translate(2.5, 3.0); gfx::Transform parent_composite_transform = parent_translation_to_anchor * parent_layer_transform * - gfx::InvertAndCheck(parent_translation_to_anchor); + parent_translation_to_anchor.GetCheckedInverse(); SetTransform(parent, parent_layer_transform); SetPostTranslation(parent, gfx::Vector2dF()); UpdateActiveTreeDrawProperties(); @@ -485,7 +484,7 @@ gfx::Transform parent_composite_transform = parent_translation_to_anchor * parent_layer_transform * - gfx::InvertAndCheck(parent_translation_to_anchor); + parent_translation_to_anchor.GetCheckedInverse(); gfx::Vector2dF parent_composite_scale = gfx::ComputeTransform2dScaleComponents(parent_composite_transform, 1.f); gfx::Transform surface_sublayer_transform; @@ -493,7 +492,7 @@ parent_composite_scale.y()); gfx::Transform surface_sublayer_composite_transform = parent_composite_transform * - gfx::InvertAndCheck(surface_sublayer_transform); + surface_sublayer_transform.GetCheckedInverse(); root->SetBounds(gfx::Size(1, 2)); parent->SetBounds(gfx::Size(100, 120)); @@ -573,7 +572,7 @@ layer_transform.Translate(1.0, 1.0); gfx::Transform A = translation_to_anchor * layer_transform * - gfx::InvertAndCheck(translation_to_anchor); + translation_to_anchor.GetCheckedInverse(); gfx::Vector2dF surface1_parent_transform_scale = gfx::ComputeTransform2dScaleComponents(A, 1.f); @@ -585,7 +584,7 @@ gfx::Transform SS1 = surface1_sublayer_transform; // S1 = transform to move from render_surface1 pixels to the layer space of // the owning layer - gfx::Transform S1 = gfx::InvertAndCheck(surface1_sublayer_transform); + gfx::Transform S1 = surface1_sublayer_transform.GetCheckedInverse(); gfx::Vector2dF surface2_parent_transform_scale = gfx::ComputeTransform2dScaleComponents(SS1 * A, 1.f); @@ -597,7 +596,7 @@ gfx::Transform SS2 = surface2_sublayer_transform; // S2 = transform to move from render_surface2 pixels to the layer space of // the owning layer - gfx::Transform S2 = gfx::InvertAndCheck(surface2_sublayer_transform); + gfx::Transform S2 = surface2_sublayer_transform.GetCheckedInverse(); root->SetBounds(gfx::Size(1, 2)); parent->SetBounds(gfx::Size(10, 10)); @@ -2034,7 +2033,7 @@ static bool ProjectionClips(const gfx::Transform& map_transform, const gfx::RectF& mapped_rect) { - gfx::Transform inverse(gfx::InvertAndCheck(map_transform)); + gfx::Transform inverse = map_transform.GetCheckedInverse(); bool clipped = false; if (!clipped) MathUtil::ProjectPoint(inverse, mapped_rect.top_right(), &clipped);
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 731b471..1de624f 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -3169,10 +3169,9 @@ SK_Scalar1 / device_scale_factor); surface_to_root_transform.FlattenTo2d(); // TODO(sunxd): Avoid losing precision by not using inverse if possible. - [[maybe_unused]] bool ok = - surface_to_root_transform.GetInverse(&hit_test_region->transform); - // Note: If |ok| is false, the |transform| is set to the identity before - // returning, which is what we want. + // Note: |transform| is set to the identity if |surface_to_root_transform| is + // not invertible, which is what we want. + hit_test_region->transform = surface_to_root_transform.InverseOrIdentity(); } absl::optional<viz::HitTestRegionList> LayerTreeHostImpl::BuildHitTestData() {
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 9081bde..3d199b4 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -2237,8 +2237,7 @@ float* distance_to_camera) { // If the transform is not invertible, then assume that this point doesn't hit // this rect. - gfx::Transform inverse_local_space_to_screen_space( - gfx::Transform::kSkipInitialization); + gfx::Transform inverse_local_space_to_screen_space; if (!local_space_to_screen_space_transform.GetInverse( &inverse_local_space_to_screen_space)) return false; @@ -2324,8 +2323,7 @@ // If the transform is not invertible, then assume that this point doesn't hit // this region. - gfx::Transform inverse_screen_space_transform( - gfx::Transform::kSkipInitialization); + gfx::Transform inverse_screen_space_transform; if (!screen_space_transform.GetInverse(&inverse_screen_space_transform)) return false;
diff --git a/cc/trees/occlusion.cc b/cc/trees/occlusion.cc index a0664c7e..5ced731 100644 --- a/cc/trees/occlusion.cc +++ b/cc/trees/occlusion.cc
@@ -56,7 +56,7 @@ if (unoccluded_rect_in_target_surface.IsEmpty()) return gfx::Rect(); - gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); + gfx::Transform inverse_draw_transform; bool ok = draw_transform_.GetInverse(&inverse_draw_transform); // TODO(ajuma): Skip drawing layers with uninvertible draw transforms, and // change this to a DCHECK. crbug.com/517170
diff --git a/cc/trees/occlusion_tracker.cc b/cc/trees/occlusion_tracker.cc index fdb210cf..d3248926 100644 --- a/cc/trees/occlusion_tracker.cc +++ b/cc/trees/occlusion_tracker.cc
@@ -81,8 +81,7 @@ static gfx::Rect ScreenSpaceClipRectInTargetSurface( const RenderSurfaceImpl* target_surface, const gfx::Rect& screen_space_clip_rect) { - gfx::Transform inverse_screen_space_transform( - gfx::Transform::kSkipInitialization); + gfx::Transform inverse_screen_space_transform; if (!target_surface->screen_space_transform().GetInverse( &inverse_screen_space_transform)) return target_surface->content_rect(); @@ -147,9 +146,7 @@ new_occlusion_immune_ancestor && new_occlusion_immune_ancestor != old_occlusion_immune_ancestor; - gfx::Transform inverse_new_target_screen_space_transform( - // Note carefully, not used if screen space transform is uninvertible. - gfx::Transform::kSkipInitialization); + gfx::Transform inverse_new_target_screen_space_transform; bool have_transform_from_screen_to_new_target = new_target_surface->screen_space_transform().GetInverse( &inverse_new_target_screen_space_transform);
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc index 4a30a227..1142eb7 100644 --- a/cc/trees/property_tree.cc +++ b/cc/trees/property_tree.cc
@@ -696,9 +696,7 @@ gfx::Transform root_to_screen; root_to_screen.Scale(screen_space_scale.x(), screen_space_scale.y()); - gfx::Transform root_from_screen; - bool invertible = root_to_screen.GetInverse(&root_from_screen); - DCHECK(invertible); + gfx::Transform root_from_screen = root_to_screen.GetCheckedInverse(); if (root_to_screen != ToScreen(kRootPropertyNodeId)) { SetToScreen(kRootPropertyNodeId, root_to_screen); SetFromScreen(kRootPropertyNodeId, root_from_screen);
diff --git a/cc/trees/proxy_impl.cc b/cc/trees/proxy_impl.cc index e690852..0024ba3 100644 --- a/cc/trees/proxy_impl.cc +++ b/cc/trees/proxy_impl.cc
@@ -401,6 +401,7 @@ } void ProxyImpl::OnHungCommit() { + UMA_HISTOGRAM_BOOLEAN("Compositing.Renderer.CommitHung", true); static auto* hung_commit_data = base::debug::AllocateCrashKeyString( "hung_commit", base::debug::CrashKeySize::Size256); std::string debug_info = scheduler_->GetHungCommitDebugInfo();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java index 2c317494..7f874085 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -1697,17 +1697,24 @@ // focus dependency is because doing it earlier can cause drawing bugs, e.g. crbug/673831. if (!mNativeInitialized || !hasWindowFocus()) return; - // The window background color is used as the resizing background color in Android N+ - // multi-window mode. See crbug.com/602366. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (!DeviceFormFactor.isNonMultiDisplayContextOnTablet(this) + && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { changeBackgroundColorForResizing(); } else { - // Post the removeWindowBackground() call as a separate task, as doing it synchronously - // here can cause redrawing glitches. See crbug.com/686662 for an example problem. + // Post the background update call as a separate task, as doing it synchronously + // here can cause redrawing glitches. See crbug.com/686662 and crbug.com/1260127 for + // example problems. Handler handler = new Handler(); - handler.post(() -> removeWindowBackground()); + handler.post(() -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + // The window background color is used as the resizing background color in + // Android N+ multi-window mode. See crbug.com/602366. + changeBackgroundColorForResizing(); + } else { + removeWindowBackground(); + } + }); } - mRemoveWindowBackgroundDone = true; }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 00a2779..03bed95 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -6200,7 +6200,7 @@ allow_circular_includes_from += [ "//chrome/browser/apps/app_shim" ] sources += [ "accessibility/caption_settings_dialog.h", - "accessibility/caption_settings_dialog_mac.mm", + "accessibility/caption_settings_dialog_mac.cc", "app_controller_mac.h", "app_controller_mac.mm", "apps/intent_helper/mac_intent_picker_helpers.h", @@ -6426,6 +6426,8 @@ "enterprise/connectors/device_trust/browser/browser_device_trust_connector_service.h", "enterprise/connectors/device_trust/signals/decorators/browser/browser_signals_decorator.cc", "enterprise/connectors/device_trust/signals/decorators/browser/browser_signals_decorator.h", + "enterprise/idle/browser_closer.cc", + "enterprise/idle/browser_closer.h", "enterprise/idle/idle_service.cc", "enterprise/idle/idle_service.h", "enterprise/idle/idle_service_factory.cc", @@ -6906,7 +6908,7 @@ ] } if (is_mac) { - sources += [ "printing/printer_manager_dialog_mac.mm" ] + sources += [ "printing/printer_manager_dialog_mac.cc" ] } if (is_chromeos_lacros) { sources += [
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 9cce2449..7320e545 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2412,14 +2412,6 @@ #endif // BUILDFLAG(IS_ANDROID) #if BUILDFLAG(IS_ANDROID) -const FeatureEntry::FeatureParam kLensOnQuickActionSearchWidgetOnTablet[] = { - {"enableCameraAssistedSearchOnTabletWidget", "true"}}; - -const FeatureEntry::FeatureVariation - kLensOnQuickActionSearchWidgetVariations[] = { - {"(on Tablet)", kLensOnQuickActionSearchWidgetOnTablet, - std::size(kLensOnQuickActionSearchWidgetOnTablet), nullptr}}; - const FeatureEntry::FeatureParam kLensCameraAssistedSearchLensButtonStart[] = { {"searchBoxStartVariantForLensCameraAssistedSearch", "true"}}; @@ -7419,14 +7411,6 @@ kLensCameraAssistedSearchVariations, "LensCameraAssistedSearch")}, - {"lens-on-quick-action-search-widget", - flag_descriptions::kLensOnQuickActionSearchWidgetName, - flag_descriptions::kLensOnQuickActionSearchWidgetDescription, kOsAndroid, - FEATURE_WITH_PARAMS_VALUE_TYPE( - chrome::android::kLensOnQuickActionSearchWidget, - kLensOnQuickActionSearchWidgetVariations, - "LensOnQuickActionSearchWidget")}, - {"enable-iph", flag_descriptions::kEnableIphName, flag_descriptions::kEnableIphDescription, kOsAndroid, FEATURE_VALUE_TYPE(feature_engagement::kEnableIPH)}, @@ -8378,11 +8362,6 @@ kOsCrOS | kOsLacros, FEATURE_VALUE_TYPE(features::kGetDisplayMediaSetAutoSelectAllScreens)}, - {"enable-vaapi-av1-decode-acceleration", - flag_descriptions::kVaapiAV1DecoderName, - flag_descriptions::kVaapiAV1DecoderDescription, kOsCrOS | kOsLacros, - FEATURE_VALUE_TYPE(media::kVaapiAV1Decoder)}, - {"default-chrome-apps-migration", flag_descriptions::kDefaultChromeAppsMigrationName, flag_descriptions::kDefaultChromeAppsMigrationDescription, kOsCrOS, @@ -8823,12 +8802,6 @@ FEATURE_VALUE_TYPE(ash::features::kPhoneHubFeatureSetupErrorHandling)}, #endif // BUILDFLAG(IS_CHROMEOS_ASH) - {"sameparty-cookies-considered-first-party", - flag_descriptions::kSamePartyCookiesConsideredFirstPartyName, - flag_descriptions::kSamePartyCookiesConsideredFirstPartyDescription, - kOsAll, - FEATURE_VALUE_TYPE(net::features::kSamePartyCookiesConsideredFirstParty)}, - {"partitioned-cookies", flag_descriptions::kPartitionedCookiesName, flag_descriptions::kPartitionedCookiesDescription, kOsAll, FEATURE_VALUE_TYPE(net::features::kPartitionedCookies)},
diff --git a/chrome/browser/accessibility/caption_settings_dialog_mac.cc b/chrome/browser/accessibility/caption_settings_dialog_mac.cc new file mode 100644 index 0000000..2181177 --- /dev/null +++ b/chrome/browser/accessibility/caption_settings_dialog_mac.cc
@@ -0,0 +1,16 @@ +// 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. + +#include "chrome/browser/accessibility/caption_settings_dialog.h" + +#include "base/mac/mac_util.h" + +namespace captions { + +void CaptionSettingsDialog::ShowCaptionSettingsDialog() { + base::mac::OpenSystemSettingsPane( + base::mac::SystemSettingsPane::kAccessibility_Captions); +} + +} // namespace captions
diff --git a/chrome/browser/accessibility/caption_settings_dialog_mac.mm b/chrome/browser/accessibility/caption_settings_dialog_mac.mm deleted file mode 100644 index 0213b08..0000000 --- a/chrome/browser/accessibility/caption_settings_dialog_mac.mm +++ /dev/null
@@ -1,20 +0,0 @@ -// 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. - -#include "chrome/browser/accessibility/caption_settings_dialog.h" - -#import <AppKit/AppKit.h> - -namespace captions { - -static NSString* kCaptionSettingsUrlString = - @"x-apple.systempreferences:com.apple.preference.universalaccess?" - @"Captioning"; - -void CaptionSettingsDialog::ShowCaptionSettingsDialog() { - [[NSWorkspace sharedWorkspace] - openURL:[NSURL URLWithString:kCaptionSettingsUrlString]]; -} - -} // namespace captions
diff --git a/chrome/browser/apps/platform_apps/app_browsertest.cc b/chrome/browser/apps/platform_apps/app_browsertest.cc index e30537e..f615451 100644 --- a/chrome/browser/apps/platform_apps/app_browsertest.cc +++ b/chrome/browser/apps/platform_apps/app_browsertest.cc
@@ -28,7 +28,6 @@ #include "chrome/browser/apps/app_service/browser_app_launcher.h" #include "chrome/browser/apps/app_service/launch_utils.h" #include "chrome/browser/apps/platform_apps/app_browsertest_util.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/extensions/api/permissions/permissions_api.h" #include "chrome/browser/extensions/component_loader.h" @@ -957,9 +956,9 @@ ASSERT_FALSE(GetFirstAppWindow()); // Relaunch the app and get a new AppWindow. - content::WindowedNotificationObserver app_loaded_observer( - content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, - content::NotificationService::AllSources()); + content::CreateAndLoadWebContentsObserver app_loaded_observer( + /*num_expected_contents=*/2); + apps::AppServiceProxyFactory::GetForProfile(browser()->profile()) ->BrowserAppLauncher() ->LaunchAppWithParamsForTesting(apps::AppLaunchParams( @@ -1098,9 +1097,7 @@ // Ensure that we wait until the background page is run (to register the // OnLaunched listener) before trying to open the application. This is similar // to LoadAndLaunchPlatformApp, but we want to load as a component extension. - content::WindowedNotificationObserver app_loaded_observer( - content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, - content::NotificationService::AllSources()); + content::CreateAndLoadWebContentsObserver app_loaded_observer; const Extension* extension = LoadExtensionAsComponent( test_data_dir_.AppendASCII("platform_apps").AppendASCII("component")); @@ -1162,9 +1159,7 @@ IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, ComponentAppBackgroundPage) { CheckExtensionInstalledObserver should_install(browser()->profile()); // Since we are forcing an upgrade, we need to wait for the load again. - content::WindowedNotificationObserver app_loaded_observer( - content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, - content::NotificationService::AllSources()); + content::CreateAndLoadWebContentsObserver app_loaded_observer; const Extension* extension = LoadExtensionAsComponent( test_data_dir_.AppendASCII("platform_apps").AppendASCII("component")); @@ -1188,9 +1183,7 @@ // Ensure that we wait until the background page is run (to register the // OnLaunched listener) before trying to open the application. This is similar // to LoadAndLaunchPlatformApp, but we want to load as a component extension. - content::WindowedNotificationObserver app_loaded_observer( - content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, - content::NotificationService::AllSources()); + content::CreateAndLoadWebContentsObserver app_loaded_observer; const Extension* extension = LoadExtensionAsComponent( test_data_dir_.AppendASCII("platform_apps").AppendASCII("component"));
diff --git a/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc b/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc index 47826b1..6a5437e 100644 --- a/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc +++ b/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc
@@ -312,8 +312,6 @@ void SetUpOnMainThread() override { SpokenFeedbackAppListBaseTest::SetUpOnMainThread(); - Shell::Get()->app_list_controller()->MarkSuggestedContentInfoDismissed(); - AppListClientImpl* app_list_client = AppListClientImpl::GetInstance(); // Reset default search controller, so the test has better control over the
diff --git a/chrome/browser/ash/crosapi/local_printer_ash.cc b/chrome/browser/ash/crosapi/local_printer_ash.cc index 72de4ff1..76d152e 100644 --- a/chrome/browser/ash/crosapi/local_printer_ash.cc +++ b/chrome/browser/ash/crosapi/local_printer_ash.cc
@@ -123,6 +123,26 @@ .Then(std::move(callback))); } +void OnOAuthAccessTokenObtained( + std::unique_ptr<ash::printing::PrinterAuthenticator> /* authenticator */, + mojom::LocalPrinter::GetOAuthAccessTokenCallback callback, + ash::printing::oauth2::StatusCode status, + std::string access_token) { + if (status != ash::printing::oauth2::StatusCode::kOK) { + // An error occurred. + std::move(callback).Run( + mojom::GetOAuthAccessTokenResult::NewError(mojom::OAuthError::New())); + return; + } + if (access_token.empty()) { + std::move(callback).Run(mojom::GetOAuthAccessTokenResult::NewNone( + mojom::OAuthNotNeeded::New())); + } else { + std::move(callback).Run(mojom::GetOAuthAccessTokenResult::NewToken( + mojom::OAuthAccessToken::New(std::move(access_token)))); + } +} + } // namespace LocalPrinterAsh::LocalPrinterAsh() @@ -569,6 +589,39 @@ std::move(callback).Run(); } +void LocalPrinterAsh::GetOAuthAccessToken( + const std::string& printer_id, + GetOAuthAccessTokenCallback callback) { + if (!chromeos::features::IsOAuthIppEnabled()) { + std::move(callback).Run(mojom::GetOAuthAccessTokenResult::NewNone( + mojom::OAuthNotNeeded::New())); + return; + } + Profile* profile = GetProfile(); + DCHECK(profile); + ash::CupsPrintersManager* printers_manager = + ash::CupsPrintersManagerFactory::GetForBrowserContext(profile); + DCHECK(printers_manager); + absl::optional<chromeos::Printer> printer = + printers_manager->GetPrinter(printer_id); + if (!printer) { + // If the printer was removed, the lookup will fail. + std::move(callback).Run( + mojom::GetOAuthAccessTokenResult::NewError(mojom::OAuthError::New())); + return; + } + ash::printing::oauth2::AuthorizationZonesManager* auth_manager = + ash::printing::oauth2::AuthorizationZonesManagerFactory:: + GetForBrowserContext(profile); + DCHECK(auth_manager); + auto authenticator = std::make_unique<ash::printing::PrinterAuthenticator>( + printers_manager, auth_manager, *printer); + ash::printing::PrinterAuthenticator* authenticator_ptr = authenticator.get(); + authenticator_ptr->ObtainAccessTokenIfNeeded( + base::BindOnce(OnOAuthAccessTokenObtained, std::move(authenticator), + std::move(callback))); +} + scoped_refptr<chromeos::PpdProvider> LocalPrinterAsh::CreatePpdProvider( Profile* profile) { return ash::CreatePpdProvider(profile);
diff --git a/chrome/browser/ash/crosapi/local_printer_ash.h b/chrome/browser/ash/crosapi/local_printer_ash.h index f6e40cb..28cc070 100644 --- a/chrome/browser/ash/crosapi/local_printer_ash.h +++ b/chrome/browser/ash/crosapi/local_printer_ash.h
@@ -116,6 +116,8 @@ void AddPrintJobObserver(mojo::PendingRemote<mojom::PrintJobObserver> remote, mojom::PrintJobSource source, AddPrintJobObserverCallback callback) override; + void GetOAuthAccessToken(const std::string& printer_id, + GetOAuthAccessTokenCallback callback) override; private: void NotifyPrintJobUpdate(base::WeakPtr<ash::CupsPrintJob> job,
diff --git a/chrome/browser/ash/crosapi/local_printer_ash_unittest.cc b/chrome/browser/ash/crosapi/local_printer_ash_unittest.cc index e456083..0216749 100644 --- a/chrome/browser/ash/crosapi/local_printer_ash_unittest.cc +++ b/chrome/browser/ash/crosapi/local_printer_ash_unittest.cc
@@ -11,14 +11,20 @@ #include <utility> #include <vector> +#include "ash/constants/ash_features.h" #include "base/bind.h" +#include "base/functional/callback.h" #include "base/memory/ref_counted.h" +#include "base/run_loop.h" #include "base/strings/string_piece.h" #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" #include "base/threading/sequenced_task_runner_handle.h" #include "chrome/browser/ash/crosapi/test_local_printer_ash.h" #include "chrome/browser/ash/printing/cups_printers_manager_factory.h" +#include "chrome/browser/ash/printing/oauth2/authorization_zones_manager_factory.h" +#include "chrome/browser/ash/printing/oauth2/mock_authorization_zones_manager.h" +#include "chrome/browser/ash/printing/oauth2/status_code.h" #include "chrome/browser/ash/printing/test_cups_printers_manager.h" #include "chrome/browser/ash/printing/test_printer_configurer.h" #include "chrome/browser/ash/profiles/profile_helper.h" @@ -42,6 +48,7 @@ #include "printing/backend/test_print_backend.h" #include "printing/buildflags/buildflags.h" #include "printing/printing_features.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/geometry/size.h" @@ -82,6 +89,14 @@ fetched_eula_url = eula_url; } +void RecordOAuthAccessToken( + crosapi::mojom::GetOAuthAccessTokenResultPtr& out, + base::OnceClosure closure, + crosapi::mojom::GetOAuthAccessTokenResultPtr param) { + out = std::move(param); + std::move(closure).Run(); +} + Printer CreateTestPrinter(const std::string& id, const std::string& name, const std::string& description) { @@ -998,4 +1013,169 @@ mojom->status_reasons[0]->severity); } +// Base testing class for `LocalPrinterAsh` with enabled OAuth2 feature. +class LocalPrinterAshWithOAuth2Test : public testing::Test { + public: + const std::vector<PrinterSemanticCapsAndDefaults::Paper> kPapers = { + {"bar", "vendor", {600, 600}}}; + + LocalPrinterAshWithOAuth2Test() = default; + LocalPrinterAshWithOAuth2Test(const LocalPrinterAshWithOAuth2Test&) = delete; + LocalPrinterAshWithOAuth2Test& operator=( + const LocalPrinterAshWithOAuth2Test&) = delete; + ~LocalPrinterAshWithOAuth2Test() override = default; + + sync_preferences::TestingPrefServiceSyncable* GetPrefs() { + return profile_.GetTestingPrefService(); + } + + void SetUp() override { + ppd_provider_ = base::MakeRefCounted<FakePpdProvider>(); + ash::CupsPrintersManagerFactory::GetInstance()->SetTestingFactoryAndUse( + &profile_, + base::BindLambdaForTesting([this](content::BrowserContext* context) + -> std::unique_ptr<KeyedService> { + auto printers_manager = + std::make_unique<ash::TestCupsPrintersManager>(); + printers_manager_ = printers_manager.get(); + return printers_manager; + })); + ash::printing::oauth2::AuthorizationZonesManagerFactory::GetInstance() + ->SetTestingFactoryAndUse( + &profile_, + base::BindLambdaForTesting([this](content::BrowserContext* context) + -> std::unique_ptr<KeyedService> { + auto auth_manager = std::make_unique<testing::StrictMock< + ash::printing::oauth2::MockAuthorizationZoneManager>>(); + auth_manager_ = auth_manager.get(); + return auth_manager; + })); + local_printer_ash_ = + std::make_unique<TestLocalPrinterAsh>(&profile_, ppd_provider_); + } + + protected: + ash::TestCupsPrintersManager& printers_manager() { + DCHECK(printers_manager_); + return *printers_manager_; + } + + ash::printing::oauth2::MockAuthorizationZoneManager& auth_manager() { + DCHECK(auth_manager_); + return *auth_manager_; + } + + crosapi::LocalPrinterAsh* local_printer_ash() { + return local_printer_ash_.get(); + } + + private: + // Enables the OAuth2 feature. + base::test::ScopedFeatureList feature_list_ = + base::test::ScopedFeatureList(::ash::features::kEnableOAuthIpp); + // Must outlive `profile_`. + content::BrowserTaskEnvironment task_environment_; + + // Must outlive `printers_manager_`. + TestingProfile profile_; + ash::TestCupsPrintersManager* printers_manager_ = nullptr; + testing::StrictMock<ash::printing::oauth2::MockAuthorizationZoneManager>* + auth_manager_ = nullptr; + scoped_refptr<FakePpdProvider> ppd_provider_; + std::unique_ptr<crosapi::LocalPrinterAsh> local_printer_ash_; +}; + +TEST_F(LocalPrinterAshWithOAuth2Test, GetOAuthAccessTokenUnknownPrinter) { + crosapi::mojom::GetOAuthAccessTokenResultPtr result; + base::RunLoop loop; + local_printer_ash()->GetOAuthAccessToken( + "printer_id", base::BindOnce(&RecordOAuthAccessToken, std::ref(result), + loop.QuitClosure())); + loop.Run(); + + ASSERT_TRUE(result); + EXPECT_TRUE(result->is_error()); +} + +TEST_F(LocalPrinterAshWithOAuth2Test, GetOAuthAccessTokenNonOAuthPrinter) { + Printer saved_printer = + CreateTestPrinter("printer_id", "saved", "description1"); + printers_manager().AddPrinter(saved_printer, PrinterClass::kSaved); + + chromeos::CupsPrinterStatus printer_status("printer_id"); + printers_manager().SetPrinterStatus(printer_status); + + crosapi::mojom::GetOAuthAccessTokenResultPtr result; + base::RunLoop loop; + local_printer_ash()->GetOAuthAccessToken( + "printer_id", base::BindOnce(&RecordOAuthAccessToken, std::ref(result), + loop.QuitClosure())); + loop.Run(); + + ASSERT_TRUE(result); + EXPECT_TRUE(result->is_none()); +} + +TEST_F(LocalPrinterAshWithOAuth2Test, GetOAuthAccessTokenOAuthConnectionError) { + Printer saved_printer = + CreateTestPrinter("printer_id", "saved", "description1"); + printers_manager().AddPrinter(saved_printer, PrinterClass::kSaved); + + chromeos::CupsPrinterStatus printer_status("printer_id"); + printer_status.SetAuthenticationInfo({"https://server/url", "scope"}); + printers_manager().SetPrinterStatus(printer_status); + + EXPECT_CALL(auth_manager(), GetEndpointAccessToken(testing::_, testing::_, + "scope", testing::_)) + .WillOnce([](const GURL& auth_server, const chromeos::Uri& ipp_endpoint, + const std::string& scope, + ash::printing::oauth2::StatusCallback callback) { + EXPECT_EQ(auth_server.spec(), "https://server/url"); + std::move(callback).Run( + ash::printing::oauth2::StatusCode::kConnectionError, + "error_message"); + }); + + crosapi::mojom::GetOAuthAccessTokenResultPtr result; + base::RunLoop loop; + local_printer_ash()->GetOAuthAccessToken( + "printer_id", base::BindOnce(&RecordOAuthAccessToken, std::ref(result), + loop.QuitClosure())); + loop.Run(); + + ASSERT_TRUE(result); + EXPECT_TRUE(result->is_error()); +} + +TEST_F(LocalPrinterAshWithOAuth2Test, GetOAuthAccessTokenSuccess) { + Printer saved_printer = + CreateTestPrinter("printer_id", "saved", "description1"); + printers_manager().AddPrinter(saved_printer, PrinterClass::kSaved); + + chromeos::CupsPrinterStatus printer_status("printer_id"); + printer_status.SetAuthenticationInfo({"https://server/url", "scope"}); + printers_manager().SetPrinterStatus(printer_status); + + EXPECT_CALL(auth_manager(), GetEndpointAccessToken(testing::_, testing::_, + "scope", testing::_)) + .WillOnce([](const GURL& auth_server, const chromeos::Uri& ipp_endpoint, + const std::string& scope, + ash::printing::oauth2::StatusCallback callback) { + EXPECT_EQ(auth_server.spec(), "https://server/url"); + std::move(callback).Run(ash::printing::oauth2::StatusCode::kOK, + "access_token"); + }); + + crosapi::mojom::GetOAuthAccessTokenResultPtr result; + base::RunLoop loop; + local_printer_ash()->GetOAuthAccessToken( + "printer_id", base::BindOnce(&RecordOAuthAccessToken, std::ref(result), + loop.QuitClosure())); + loop.Run(); + + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_token()); + EXPECT_EQ(result->get_token()->token, "access_token"); +} + } // namespace printing
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc index 8f7627d..c034411f 100644 --- a/chrome/browser/chrome_browser_main_win.cc +++ b/chrome/browser/chrome_browser_main_win.cc
@@ -859,6 +859,10 @@ if (!command_line.HasSwitch(switches::kRestoreLastSession)) restart_command.AppendSwitch(switches::kRestoreLastSession); + // This is used when recording launch mode metric. + if (!command_line.HasSwitch(switches::kRestart)) + restart_command.AppendSwitch(switches::kRestart); + // TODO(crbug.com/964541): Remove other unneeded switches, including // duplicates, perhaps harmonize with switches::RemoveSwitchesForAutostart. return restart_command;
diff --git a/chrome/browser/chrome_browser_main_win_unittest.cc b/chrome/browser/chrome_browser_main_win_unittest.cc index 42f8a242..1814a32 100644 --- a/chrome/browser/chrome_browser_main_win_unittest.cc +++ b/chrome/browser/chrome_browser_main_win_unittest.cc
@@ -27,7 +27,7 @@ // Simple command line with just the program. const base::CommandLine::StringType kNoArgsResult = - L" --restore-last-session"; + L" --restore-last-session --restart"; base::CommandLine restart_command_line = ChromeBrowserMainPartsWin::GetRestartCommandLine(simple_command_line); EXPECT_EQ(restart_command_line.GetCommandLineString(), kNoArgsResult); @@ -42,7 +42,7 @@ // Command line with a retained switch. const std::string kRetainedSwitch = "--enable-sandbox-audio"; const base::CommandLine::StringType kRetainedSwitchResult = - L" --enable-sandbox-audio --restore-last-session"; + L" --enable-sandbox-audio --restore-last-session --restart"; base::CommandLine retained_switch_command_line(chrome_path); retained_switch_command_line.AppendSwitch(kRetainedSwitch); restart_command_line = ChromeBrowserMainPartsWin::GetRestartCommandLine( @@ -85,7 +85,7 @@ EXPECT_EQ(restart_command_line.GetCommandLineString(), L" --enable-features=Exp2 --enable-foo" L" --enable-sandbox-audio" - L" --restore-last-session"); + L" --restore-last-session --restart"); } // Test RegisterApplicationRestart to make sure there are no crashes.
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index c362a60..ceff44e1 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1049,6 +1049,8 @@ "../ash/policy/handlers/fake_device_name_policy_handler.h", "../ash/policy/handlers/minimum_version_policy_test_helpers.cc", "../ash/policy/handlers/minimum_version_policy_test_helpers.h", + "../ash/printing/oauth2/mock_authorization_zones_manager.cc", + "../ash/printing/oauth2/mock_authorization_zones_manager.h", "../ash/printing/printing_stubs.cc", "../ash/printing/printing_stubs.h", "../ash/printing/test_cups_print_job_manager.cc", @@ -1820,8 +1822,6 @@ "../ash/printing/oauth2/http_exchange_unittest.cc", "../ash/printing/oauth2/ipp_endpoint_token_fetcher_unittest.cc", "../ash/printing/oauth2/log_entry_unittest.cc", - "../ash/printing/oauth2/mock_authorization_zones_manager.cc", - "../ash/printing/oauth2/mock_authorization_zones_manager.h", "../ash/printing/oauth2/profile_auth_servers_sync_bridge_unittest.cc", "../ash/printing/oauth2/test_authorization_server.cc", "../ash/printing/oauth2/test_authorization_server.h",
diff --git a/chrome/browser/enterprise/idle/browser_closer.cc b/chrome/browser/enterprise/idle/browser_closer.cc new file mode 100644 index 0000000..2eb62a03 --- /dev/null +++ b/chrome/browser/enterprise/idle/browser_closer.cc
@@ -0,0 +1,165 @@ +// 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/enterprise/idle/browser_closer.h" + +#include <iterator> +#include <utility> + +#include "base/check.h" +#include "base/check_is_test.h" +#include "base/containers/contains.h" +#include "base/ranges/algorithm.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_list.h" + +namespace enterprise_idle { + +namespace { + +constexpr base::TimeDelta kDialogTimeout = base::Seconds(30); + +bool ProfileHasBrowsers(const Profile* profile) { + DCHECK(profile); + profile = profile->GetOriginalProfile(); + return base::ranges::any_of( + *BrowserList::GetInstance(), [profile](Browser* browser) { + return browser->profile()->GetOriginalProfile() == profile; + }); +} + +} // namespace + +// static +BrowserCloser* BrowserCloser::GetInstance() { + static base::NoDestructor<BrowserCloser> instance; + return instance.get(); +} + +BrowserCloser::BrowserCloser() = default; + +BrowserCloser::~BrowserCloser() = default; + +base::CallbackListSubscription BrowserCloser::ShowDialogAndCloseBrowsers( + Profile* profile, + base::TimeDelta threshold, + base::OnceCallback<void(CloseResult)> on_finished) { + if (!ProfileHasBrowsers(profile)) { + // No browsers to close for this profile. No need to show a dialog or close + // browsers, so finish immediately. + std::move(on_finished).Run(CloseResult::kSkip); + return base::CallbackListSubscription(); + } + + // Passed the guards: we're really going to show the dialog and close + // browsers. + closing_profiles_.insert(profile->GetPath()); + base::CallbackListSubscription subscription = + callbacks_.Add(std::move(on_finished)); + + if (dialog_) { + // The dialog is already visible, re-use it. + return subscription; + } + + dialog_ = IdleDialog::Show( + kDialogTimeout, threshold, + base::BindRepeating(&BrowserCloser::OnDialogDismissedByUser, + base::Unretained(this))); + dialog_timer_.Start( + FROM_HERE, kDialogTimeout, + base::BindOnce(&BrowserCloser::OnDialogExpired, base::Unretained(this))); + return subscription; +} + +void BrowserCloser::DismissDialogForTesting() { + CHECK_IS_TEST(); + OnDialogDismissedByUser(); +} + +void BrowserCloser::OnDialogExpired() { + DCHECK(!closing_profiles_.empty()); + + if (dialog_) + dialog_->Close(); + dialog_.reset(); + dialog_timer_.Stop(); + + // If we did CloseAllbrowsersWithProfile() right away, OnCloseSuccess() might + // run immediately, in which case we would try to modify `closing_profiles_` + // while iterating on it. + // + // Collect the profiles in `profiles_to_close`, and iterate on *that* instead. + base::flat_set<Profile*> profiles_to_close; + base::ranges::transform( + closing_profiles_, + std::inserter(profiles_to_close, profiles_to_close.end()), + [](const base::FilePath& profile_dir) { + return g_browser_process->profile_manager()->GetProfileByPath( + profile_dir); + }); + + for (Profile* profile : profiles_to_close) { + if (!ProfileHasBrowsers(profile)) { + // Can't close a profile with no browsers. The browsers may have been + // closed programmatically (e.g. by an extension) during the 30s delay. + closing_profiles_.erase(profile->GetPath()); + continue; + } + // TODO(crbug.com/1316551): Get customer feedback on whether + // skip_beforeunload should be true or false. + BrowserList::CloseAllBrowsersWithProfile( + profile, + base::BindRepeating(&BrowserCloser::OnCloseSuccess, + base::Unretained(this)), + base::BindRepeating(&BrowserCloser::OnCloseAborted, + base::Unretained(this)), + /*skip_beforeunload=*/true); + } + + // We showed the dialog, but then no profiles needed closing. Count this as a + // "success". + if (closing_profiles_.empty()) + OnCloseSuccess(base::FilePath()); +} + +void BrowserCloser::OnDialogDismissedByUser() { + if (closing_profiles_.empty()) + return; + + if (dialog_) + dialog_->Close(); + dialog_.reset(); + dialog_timer_.Stop(); + + callbacks_.Notify(CloseResult::kAborted); + closing_profiles_.clear(); +} + +void BrowserCloser::OnCloseSuccess(const base::FilePath& profile_dir) { + if (!profile_dir.empty() && !base::Contains(closing_profiles_, profile_dir)) + return; // Out of date. + + // TODO(crbug.com/1316551): Reset `closing_profiles_` if something weird + // happens (e.g. new browser window is created by an extension). + closing_profiles_.erase(profile_dir); + if (!closing_profiles_.empty()) + return; // There are profiles left to close still. + + callbacks_.Notify(CloseResult::kSuccess); + closing_profiles_.clear(); +} + +void BrowserCloser::OnCloseAborted(const base::FilePath& profile_dir) { + if (!base::Contains(closing_profiles_, profile_dir)) + return; // Out of date. + + callbacks_.Notify(CloseResult::kAborted); + closing_profiles_.clear(); +} + +} // namespace enterprise_idle
diff --git a/chrome/browser/enterprise/idle/browser_closer.h b/chrome/browser/enterprise/idle/browser_closer.h new file mode 100644 index 0000000..a6c7594 --- /dev/null +++ b/chrome/browser/enterprise/idle/browser_closer.h
@@ -0,0 +1,90 @@ +// 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 CHROME_BROWSER_ENTERPRISE_IDLE_BROWSER_CLOSER_H_ +#define CHROME_BROWSER_ENTERPRISE_IDLE_BROWSER_CLOSER_H_ + +#include "base/callback_list.h" +#include "base/containers/flat_set.h" +#include "base/files/file_path.h" +#include "base/no_destructor.h" +#include "base/time/time.h" +#include "base/timer/timer.h" +#include "chrome/browser/ui/idle_dialog.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +class Profile; + +namespace enterprise_idle { + +// The "close_browsers" action is different from other actions. +// +// - It shows a 30s dialog before closing, which allows the user to abort the +// close. +// +// - It runs *before* other actions, so ActionsRunner needs to wait for this +// flow to finish (or abort). +// +// - If multiple Profiles ask to close at the same time, we want to run other +// actions after they're *all* done closing (which is asynchronous). +// +// A centralized BrowserCloser singleton receives close requests, and calls the +// observers when it's done. +class BrowserCloser { + public: + enum class CloseResult { + // The dialog expired, and then the browsers closed successfully. + kSuccess, + // One of these 2 scenarios: + // - The dialog was dismissed by the user, so we didn't close the browsers. + // - We tried to close browsers, but failed for some reason. + kAborted, + // No browsers to close, so nothing to do. Dialog was not shown. + kSkip, + }; + + static BrowserCloser* GetInstance(); + + // Shows the 30s dialog, then closes all browsers with `profile` or one of its + // OTR profiles (e.g. Incognito). + base::CallbackListSubscription ShowDialogAndCloseBrowsers( + Profile* profile, + base::TimeDelta threshold, + base::OnceCallback<void(CloseResult)> on_finished); + + void DismissDialogForTesting(); + + private: + friend class base::NoDestructor<BrowserCloser>; + + BrowserCloser(); + ~BrowserCloser(); + + // Runs after 30s without the user dismissing the dialog. + void OnDialogExpired(); + + // Runs when the user hits Escape, or clicks the "Continue using Chrome" + // button in the dialog. + void OnDialogDismissedByUser(); + + // Callbacks for BrowserList::CloseAllBrowsersWithProfile(). + void OnCloseSuccess(const base::FilePath& profile_dir); + void OnCloseAborted(const base::FilePath& profile_dir); + + // Set of profiles that are currently closing. Stored as FilePaths instead of + // Profile*, so we don't have to worry about dangling profile pointers. + base::flat_set<base::FilePath> closing_profiles_; + + // Pending `on_finished` callbacks. + base::OnceCallbackList<void(CloseResult)> callbacks_; + + base::WeakPtr<views::Widget> dialog_; + + // Timer for `dialog_`. Runs OnDialogExpired(). + base::OneShotTimer dialog_timer_; +}; + +} // namespace enterprise_idle + +#endif // CHROME_BROWSER_ENTERPRISE_IDLE_BROWSER_CLOSER_H_
diff --git a/chrome/browser/enterprise/idle/browser_closer_unittest.cc b/chrome/browser/enterprise/idle/browser_closer_unittest.cc new file mode 100644 index 0000000..c2ed121 --- /dev/null +++ b/chrome/browser/enterprise/idle/browser_closer_unittest.cc
@@ -0,0 +1,76 @@ +// 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/enterprise/idle/browser_closer.h" + +#include <memory> +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/run_loop.h" +#include "base/test/gmock_callback_support.h" +#include "base/test/mock_callback.h" +#include "base/time/time.h" +#include "chrome/test/base/browser_with_test_window_test.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile_manager.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "ui/views/test/scoped_views_test_helper.h" + +namespace enterprise_idle { + +using CloseResult = BrowserCloser::CloseResult; +using base::test::RunClosure; + +class BrowserCloserTest : public BrowserWithTestWindowTest { + public: + BrowserCloserTest() + : BrowserWithTestWindowTest( + base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} + + void SetUp() override { + test_views_delegate()->set_use_desktop_native_widgets(true); + BrowserWithTestWindowTest::SetUp(); + } +}; + +TEST_F(BrowserCloserTest, Basic) { + base::RunLoop run_loop; + base::MockOnceCallback<void(CloseResult)> callback; + EXPECT_CALL(callback, Run(CloseResult::kSuccess)) + .WillOnce(RunClosure(run_loop.QuitClosure())); + auto subscription = BrowserCloser::GetInstance()->ShowDialogAndCloseBrowsers( + profile(), base::Minutes(5), callback.Get()); + task_environment()->FastForwardBy(base::Seconds(30)); + run_loop.Run(); +} + +TEST_F(BrowserCloserTest, DismissedByUser) { + base::RunLoop run_loop; + base::MockOnceCallback<void(CloseResult)> callback; + EXPECT_CALL(callback, Run(CloseResult::kAborted)) + .WillOnce(RunClosure(run_loop.QuitClosure())); + auto subscription = BrowserCloser::GetInstance()->ShowDialogAndCloseBrowsers( + profile(), base::Minutes(5), callback.Get()); + BrowserCloser::GetInstance()->DismissDialogForTesting(); + run_loop.Run(); +} + +TEST_F(BrowserCloserTest, ProfileHasNoBrowsers) { + set_browser(nullptr); + + base::RunLoop run_loop; + base::MockOnceCallback<void(CloseResult)> callback; + EXPECT_CALL(callback, Run(CloseResult::kSkip)) + .WillOnce(RunClosure(run_loop.QuitClosure())); + auto subscription = BrowserCloser::GetInstance()->ShowDialogAndCloseBrowsers( + profile(), base::Minutes(5), callback.Get()); + run_loop.Run(); +} + +} // namespace enterprise_idle
diff --git a/chrome/browser/enterprise/idle/idle_service.cc b/chrome/browser/enterprise/idle/idle_service.cc index bfd169ae..77f43425 100644 --- a/chrome/browser/enterprise/idle/idle_service.cc +++ b/chrome/browser/enterprise/idle/idle_service.cc
@@ -4,231 +4,17 @@ #include "chrome/browser/enterprise/idle/idle_service.h" +#include <algorithm> + #include "base/bind.h" #include "base/callback.h" -#include "base/containers/flat_set.h" -#include "base/files/file_path.h" -#include "base/memory/singleton.h" -#include "base/no_destructor.h" -#include "base/ranges/algorithm.h" -#include "chrome/browser/enterprise/idle/idle_service_factory.h" +#include "chrome/browser/enterprise/idle/browser_closer.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/idle_dialog.h" #include "chrome/browser/ui/profile_picker.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" #include "ui/base/idle/idle.h" #include "ui/base/idle/idle_polling_service.h" -#include "ui/views/widget/widget.h" - -namespace { - -bool ProfileHasBrowsers(const Profile* profile) { - DCHECK(profile); - profile = profile->GetOriginalProfile(); - return base::ranges::any_of( - *BrowserList::GetInstance(), [profile](Browser* browser) { - return browser->profile()->GetOriginalProfile() == profile; - }); -} - -// Keeps track of the idle state of each Profile. Keeping all the states in a -// single place means we can do batch actions without duplicating. For instance, -// if 2 Profiles have the same threshold we can close all their windows, wait -// for BOTH profiles to close, and only show the Profile Picker once. -class IdleRegistry : public ui::IdlePollingService::Observer { - public: - static IdleRegistry& GetInstance() { - static base::NoDestructor<IdleRegistry> instance; - return *instance; - } - - // Start tracking a new Profile, or update its threshold if it's already being - // tracked. Called when the IdleProfileCloseTimeout policy changes value. - void AddOrUpdate(Profile* profile, base::TimeDelta threshold) { - DCHECK(!profile->IsSystemProfile()); - DCHECK(!profile->IsOffTheRecord()); - if (profiles_.find(profile) == profiles_.end()) { - profiles_[profile].threshold = threshold; - } - if (!polling_service_observation_.IsObserving()) { - polling_service_observation_.Observe( - ui::IdlePollingService::GetInstance()); - } - } - - // Stop tracking a Profile, if it's being tracked. Called during shutdown, or - // when the IdleProfileCloseTimeout policy becomes unset. - // - // If the profile is not tracked, this is a no-op. - void Remove(Profile* profile) { - profiles_.erase(profile); - if (profiles_.empty()) - polling_service_observation_.Reset(); - } - - void SetDialogTimeoutForTesting(base::TimeDelta dialog_timeout) { - dialog_timeout_ = dialog_timeout; - } - - private: - friend struct base::DefaultSingletonTraits<IdleRegistry>; - - // See `profiles_`. - struct ProfileState { - base::TimeDelta threshold; // From the IdleProfileCloseTimeout policy. - }; - - // ui::IdlePollingService::Observer: - void OnIdleStateChange( - const ui::IdlePollingService::State& polled_state) override { - base::flat_set<Profile*> profiles_to_close; - - for (auto& [profile, state] : profiles_) { - if (polled_state.idle_time < state.threshold) - continue; // Profile is not idle. - if (base::Contains(closing_profiles_, profile->GetPath())) - continue; // Profile is already closing. - if (!ProfileHasBrowsers(profile)) - continue; // Can't close a profile with no browsers... - - // Profile just became idle. - profiles_to_close.insert(profile); - } - - if (!profiles_to_close.empty()) { - // One or more profiles just became idle. Show the dialog, and start the - // 30s timer. - - // TODO(nicolaso): Don't show it every time, i.e. if it's already visible - // from a previous profile becoming idle right before this one. Running - // this code multiple times like that could cause race conditions/weird - // behaviour. - // - // ... but as currently written, it's impossible to reach that state. The - // dialog only shows for 30s, and there's at least 60s between 2 different - // profiles triggering idle state non-simultaneously. - // - // For now, this CHECK() should be enough. - DCHECK(closing_profiles_.empty()); - - should_open_profile_picker_ = true; - for (Profile* profile : profiles_to_close) - closing_profiles_.insert(profile->GetPath()); - - dialog_ = IdleDialog::Show( - dialog_timeout_, profiles_[*profiles_to_close.begin()].threshold, - base::BindRepeating(&IdleRegistry::OnDialogClosedByUser, - base::Unretained(this))); - dialog_timer_.Start(FROM_HERE, dialog_timeout_, - base::BindOnce(&IdleRegistry::OnDialogExpired, - base::Unretained(this))); - } - } - - // Abort the close operation. - void OnDialogClosedByUser() { - closing_profiles_.clear(); - should_open_profile_picker_ = false; - if (dialog_) - dialog_->Close(); - dialog_.reset(); - dialog_timer_.Stop(); - } - - // Perform the close operation, then show the profile picker in the callback - // to CloseAllBrowsersWithProfile(). - void OnDialogExpired() { - DCHECK(!closing_profiles_.empty()); - DCHECK(should_open_profile_picker_); - - if (dialog_) - dialog_->Close(); - dialog_.reset(); - - for (auto& [profile, state] : profiles_) { - if (!base::Contains(closing_profiles_, profile->GetPath())) - continue; - if (!ProfileHasBrowsers(profile)) { - // Can't close a profile with no browsers. The browsers may have been - // closed programmatically (e.g. by an extension) during the 30s delay. - closing_profiles_.erase(profile->GetPath()); - continue; - } - // TODO(crbug.com/1316551): Get customer feedback on whether - // skip_beforeunload should be true or false. - BrowserList::CloseAllBrowsersWithProfile( - profile, - base::BindRepeating(&IdleRegistry::OnCloseSuccess, - base::Unretained(this)), - base::BindRepeating(&IdleRegistry::OnCloseAborted, - base::Unretained(this)), - /*skip_beforeunload=*/true); - } - - if (closing_profiles_.empty()) { - // If no profile had any browsers, then we're not actually closing. - should_open_profile_picker_ = false; - } - } - - void OnCloseAborted(const base::FilePath& profile_dir) { - // TODO(crbug.com/1316551): What should we do if the profile's been "closed" - // and *then* a new window is created? - closing_profiles_.erase(profile_dir); - // Something aborted the close. Don't show the profile picker. - should_open_profile_picker_ = false; - } - - // BrowserListObserver: - void OnCloseSuccess(const base::FilePath& profile_dir) { - // TODO(crbug.com/1316551): Reset `closing_profiles_` and - // `should_open_profile_picker_` if something weird happens (e.g. new - // browser window is created by an extension). - if (profiles_.empty()) - return; - if (!base::Contains(closing_profiles_, profile_dir)) - return; - - closing_profiles_.erase(profile_dir); - - if (closing_profiles_.empty() && should_open_profile_picker_) { - // All windows are done closing for idle profiles. Show the Profile - // Picker. - should_open_profile_picker_ = false; - ProfilePicker::Show(ProfilePicker::Params::FromEntryPoint( - ProfilePicker::EntryPoint::kProfileIdle)); - } - } - - // Set of profiles being closed right now. Filled in when idle logic triggers - // and becomes empty again when: - // - // (a) All idle browsers finish closing. - // (b) The user aborts closing by dismissing the dialog. - base::flat_set<base::FilePath> closing_profiles_; - // Whether to open the profile picker after the last profile in - // `closing_profiles_` finishes closing. - bool should_open_profile_picker_ = false; - - std::map<Profile*, ProfileState> profiles_; - - // Dialog shown for 30s before doing the close operation. If the user - // dismisses it or clicks "Continue using Chrome", the idle timer resets to - // 0s. - base::WeakPtr<views::Widget> dialog_; - // 30s timer for |dialog_|. - base::OneShotTimer dialog_timer_; - base::TimeDelta dialog_timeout_ = base::Seconds(30); - - base::ScopedObservation<ui::IdlePollingService, - ui::IdlePollingService::Observer> - polling_service_observation_{this}; -}; - -} // namespace namespace enterprise_idle { @@ -242,27 +28,67 @@ OnIdleProfileCloseTimeoutPrefChanged(); } -IdleService::~IdleService() { - IdleRegistry::GetInstance().Remove(profile_); -} - -void IdleService::Shutdown() { - IdleRegistry::GetInstance().Remove(profile_); -} - -void IdleService::SetDialogTimeoutForTesting(base::TimeDelta dialog_timeout) { - IdleRegistry::GetInstance().SetDialogTimeoutForTesting( // IN-TEST - dialog_timeout); -} +IdleService::~IdleService() = default; void IdleService::OnIdleProfileCloseTimeoutPrefChanged() { int minutes = profile_->GetPrefs()->GetInteger(prefs::kIdleProfileCloseTimeout); if (minutes > 0) { - IdleRegistry::GetInstance().AddOrUpdate( - profile_, std::max(base::Minutes(5), base::Minutes(minutes))); + // TODO(crbug.com/1316551): Validate the policy value (e.g. clamp to a + // minimum) in a PolicyHandler, instead of here. + minutes = std::max(5, minutes); + // `is_idle_` will auto-update in 1 second, no need to set it here. + idle_threshold_ = base::Minutes(minutes); + if (!polling_service_observation_.IsObserving()) { + polling_service_observation_.Observe( + ui::IdlePollingService::GetInstance()); + } } else { - IdleRegistry::GetInstance().Remove(profile_); + is_idle_ = false; + idle_threshold_ = base::TimeDelta(); + polling_service_observation_.Reset(); + } +} + +void IdleService::OnIdleStateChange( + const ui::IdlePollingService::State& polled_state) { + if (is_idle_) { + if (polled_state.idle_time < idle_threshold_) { + // Profile just stopped being idle. + is_idle_ = false; + } + } else { + if (polled_state.idle_time >= idle_threshold_) { + // Profile just became idle. Show the dialog. + is_idle_ = true; + browser_close_subscription_ = + BrowserCloser::GetInstance()->ShowDialogAndCloseBrowsers( + profile_, idle_threshold_, + base::BindOnce(&IdleService::OnCloseFinished, + weak_ptr_factory_.GetWeakPtr())); + } + } +} + +void IdleService::OnCloseFinished(BrowserCloser::CloseResult result) { + switch (result) { + case BrowserCloser::CloseResult::kSuccess: + // Technically, this shows the ProfilePicker once per profile. However, + // all IdleServices run OnCloseFinished() in succession (once they're + // *all* closed), and there's only one ProfilePicker. + // + // Calling ProfilePicker::Show() multiple times like + // this is a no-op, so we don't need to bother de-duping work. + ProfilePicker::Show(ProfilePicker::Params::FromEntryPoint( + ProfilePicker::EntryPoint::kProfileIdle)); + break; + + case BrowserCloser::CloseResult::kAborted: + case BrowserCloser::CloseResult::kSkip: + break; + + default: + NOTREACHED(); } }
diff --git a/chrome/browser/enterprise/idle/idle_service.h b/chrome/browser/enterprise/idle/idle_service.h index 486968c..66492eb8 100644 --- a/chrome/browser/enterprise/idle/idle_service.h +++ b/chrome/browser/enterprise/idle/idle_service.h
@@ -5,9 +5,14 @@ #ifndef CHROME_BROWSER_ENTERPRISE_IDLE_IDLE_SERVICE_H_ #define CHROME_BROWSER_ENTERPRISE_IDLE_IDLE_SERVICE_H_ +#include "base/callback_list.h" +#include "base/memory/weak_ptr.h" +#include "base/scoped_observation.h" #include "base/time/time.h" +#include "chrome/browser/enterprise/idle/browser_closer.h" #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_change_registrar.h" +#include "ui/base/idle/idle_polling_service.h" class Profile; @@ -17,7 +22,8 @@ // policy. Keeps track of the policy's value, and listens for idle events. // Closes the profile's window when it becomes idle, and shows the profile // picker. -class IdleService : public KeyedService { +class IdleService : public KeyedService, + public ui::IdlePollingService::Observer { public: explicit IdleService(Profile* profile); @@ -26,19 +32,32 @@ ~IdleService() override; - // KeyedService: - void Shutdown() override; - - static void SetDialogTimeoutForTesting(base::TimeDelta dialog_timeout); + // ui::IdlePollingService::Observer: + void OnIdleStateChange( + const ui::IdlePollingService::State& polled_state) override; private: // Called when the IdleProfileCloseTimeout policy changes, via the // "idle_profile_close_timeout" pref it's mapped to. void OnIdleProfileCloseTimeoutPrefChanged(); + // Runs when the BrowserCloser finishes. Depending on the result, shows the + // Profile Picker. + void OnCloseFinished(BrowserCloser::CloseResult result); + + raw_ptr<Profile> const profile_; PrefChangeRegistrar pref_change_registrar_; - Profile* profile_; + bool is_idle_ = false; + base::TimeDelta idle_threshold_; + + base::CallbackListSubscription browser_close_subscription_; + + base::ScopedObservation<ui::IdlePollingService, + ui::IdlePollingService::Observer> + polling_service_observation_{this}; + + base::WeakPtrFactory<IdleService> weak_ptr_factory_{this}; }; } // namespace enterprise_idle
diff --git a/chrome/browser/enterprise/idle/idle_service_browsertest.cc b/chrome/browser/enterprise/idle/idle_service_browsertest.cc index d92b0a2..283742b 100644 --- a/chrome/browser/enterprise/idle/idle_service_browsertest.cc +++ b/chrome/browser/enterprise/idle/idle_service_browsertest.cc
@@ -15,6 +15,7 @@ #include "base/timer/mock_timer.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/enterprise/idle/browser_closer.h" #include "chrome/browser/enterprise/idle/idle_service.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/browser.h" @@ -93,7 +94,6 @@ scoped_idle_provider_ = std::make_unique<ui::test::ScopedIdleProviderForTest>( std::move(time_provider)); - IdleService::SetDialogTimeoutForTesting(base::Milliseconds(0)); } void TearDownOnMainThread() override { @@ -145,16 +145,47 @@ task_runner()->FastForwardBy(base::Seconds(1)); EXPECT_EQ(1, GetBrowserCount(profile)); - // 300s, threshold is reached. Close browsers, then show the Profile Picker. + // 300s, threshold is reached. This should show the dialog. EXPECT_CALL(provider(), CalculateIdleTime()) .WillOnce(Return(base::Seconds(300))); - BrowserCloseWaiter waiter({browser()}); task_runner()->FastForwardBy(base::Seconds(1)); + EXPECT_EQ(1, GetBrowserCount(profile)); + + EXPECT_CALL(provider(), CalculateIdleTime()) + .WillRepeatedly(Return(base::Seconds(15))); + BrowserCloseWaiter waiter({browser()}); + task_runner()->FastForwardBy(base::Seconds(30)); waiter.Wait(); EXPECT_EQ(0, GetBrowserCount(profile)); EXPECT_TRUE(ProfilePicker::IsOpen()); } +IN_PROC_BROWSER_TEST_F(IdleServiceTest, DidNotClose) { + ON_CALL(provider(), CheckIdleStateIsLocked()).WillByDefault(Return(false)); + + // Set the IdleProfileCloseTimeout policy to 1 minute, which should round up + // to 5 minutes (the minimum). + EXPECT_CALL(provider(), CalculateIdleTime()) + .WillOnce(Return(base::Seconds(298))); + Profile* profile = browser()->profile(); + profile->GetPrefs()->SetInteger("idle_profile_close_timeout", 1); + + EXPECT_EQ(1, GetBrowserCount(profile)); + + // 300s, threshold is reached. The user dismisses the dialog though, so we do + // nothing. + EXPECT_CALL(provider(), CalculateIdleTime()) + .WillOnce(Return(base::Seconds(300))); + task_runner()->FastForwardBy(base::Seconds(1)); + EXPECT_CALL(provider(), CalculateIdleTime()) + .WillRepeatedly(Return(base::Seconds(301))); + BrowserCloser::GetInstance()->DismissDialogForTesting(); + task_runner()->FastForwardBy(base::Seconds(30)); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, GetBrowserCount(profile)); + EXPECT_FALSE(ProfilePicker::IsOpen()); +} + IN_PROC_BROWSER_TEST_F(IdleServiceTest, TenMinutes) { ON_CALL(provider(), CheckIdleStateIsLocked()).WillByDefault(Return(false)); @@ -175,8 +206,13 @@ // 600s, threshold is reached. Close browsers, then show the Profile Picker. EXPECT_CALL(provider(), CalculateIdleTime()) .WillOnce(Return(base::Seconds(600))); - BrowserCloseWaiter waiter({browser()}); task_runner()->FastForwardBy(base::Seconds(1)); + EXPECT_EQ(1, GetBrowserCount(profile)); + + EXPECT_CALL(provider(), CalculateIdleTime()) + .WillRepeatedly(Return(base::Seconds(301))); + BrowserCloseWaiter waiter({browser()}); + task_runner()->FastForwardBy(base::Seconds(30)); waiter.Wait(); EXPECT_EQ(0, GetBrowserCount(profile)); EXPECT_TRUE(ProfilePicker::IsOpen()); @@ -236,8 +272,12 @@ // 300s, threshold is reached. Close browsers, then show the Profile Picker. EXPECT_CALL(provider(), CalculateIdleTime()) .WillOnce(Return(base::Seconds(300))); - BrowserCloseWaiter waiter({browser(), browser2, browser3}); task_runner()->FastForwardBy(base::Seconds(1)); + + EXPECT_CALL(provider(), CalculateIdleTime()) + .WillRepeatedly(Return(base::Seconds(315))); + BrowserCloseWaiter waiter({browser(), browser2, browser3}); + task_runner()->FastForwardBy(base::Seconds(30)); waiter.Wait(); EXPECT_EQ(0, GetBrowserCount(profile)); EXPECT_EQ(0, GetBrowserCount(profile2)); @@ -281,9 +321,12 @@ // Profile Picker. EXPECT_CALL(provider(), CalculateIdleTime()) .WillOnce(Return(base::Seconds(300))); + task_runner()->FastForwardBy(base::Seconds(1)); + EXPECT_CALL(provider(), CalculateIdleTime()) + .WillRepeatedly(Return(base::Seconds(315))); { BrowserCloseWaiter waiter({browser(), browser2}); - task_runner()->FastForwardBy(base::Seconds(1)); + task_runner()->FastForwardBy(base::Seconds(30)); waiter.Wait(); } EXPECT_EQ(0, GetBrowserCount(profile)); @@ -293,9 +336,12 @@ // 360s, threshold is reached for `profile2`. Close its browsers. EXPECT_CALL(provider(), CalculateIdleTime()) .WillOnce(Return(base::Seconds(360))); + task_runner()->FastForwardBy(base::Seconds(1)); + EXPECT_CALL(provider(), CalculateIdleTime()) + .WillRepeatedly(Return(base::Seconds(375))); { BrowserCloseWaiter waiter({browser3}); - task_runner()->FastForwardBy(base::Seconds(1)); + task_runner()->FastForwardBy(base::Seconds(30)); waiter.Wait(); } EXPECT_EQ(0, GetBrowserCount(profile));
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc index 5b8aeb7..6a7a19f 100644 --- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc +++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
@@ -62,6 +62,10 @@ #include "chrome/browser/web_applications/web_app_registrar.h" #endif +#if BUILDFLAG(IS_WIN) +#include "base/win/shlwapi.h" +#endif + namespace features { BASE_FEATURE(kFileSystemAccessPersistentPermissions, "kFileSystemAccessPersistentPermissions", @@ -270,6 +274,12 @@ DCHECK(!check_path.empty()); DCHECK(check_path.IsAbsolute()); +#if BUILDFLAG(IS_WIN) + // On Windows, UNC paths are rejected to avoid bypassing the block list. + if (PathIsUNC(check_path.value().c_str())) + return true; +#endif + base::FilePath nearest_ancestor; int nearest_ancestor_path_key = kNoBasePathKey; BlockType nearest_ancestor_block_type = kDontBlockChildren;
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc index 3887cdd..9f2e3f44 100644 --- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc +++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
@@ -395,9 +395,41 @@ permission_context(), PathType::kLocal, base::FilePath(FILE_PATH_LITERAL("/dev/foo")), HandleType::kFile, UserAction::kOpen)); +#elif BUILDFLAG(IS_WIN) + EXPECT_EQ(SensitiveDirectoryResult::kAbort, + ConfirmSensitiveEntryAccessSync( + permission_context(), PathType::kLocal, + base::FilePath(FILE_PATH_LITERAL("c:\\Program Files")), + HandleType::kDirectory, UserAction::kOpen)); #endif } +#if BUILDFLAG(IS_WIN) +TEST_F(ChromeFileSystemAccessPermissionContextTest, + ConfirmSensitiveEntryAccess_UNCPath) { + EXPECT_EQ( + SensitiveDirectoryResult::kAbort, + ConfirmSensitiveEntryAccessSync( + permission_context(), PathType::kLocal, + base::FilePath(FILE_PATH_LITERAL("\\\\127.0.0.1\\c:\\Program Files")), + HandleType::kDirectory, UserAction::kOpen)); + + EXPECT_EQ( + SensitiveDirectoryResult::kAbort, + ConfirmSensitiveEntryAccessSync( + permission_context(), PathType::kLocal, + base::FilePath(FILE_PATH_LITERAL("\\\\127.0.0.1\\c:\\foo\\bar")), + HandleType::kDirectory, UserAction::kOpen)); + + EXPECT_EQ( + SensitiveDirectoryResult::kAbort, + ConfirmSensitiveEntryAccessSync( + permission_context(), PathType::kLocal, + base::FilePath(FILE_PATH_LITERAL("\\\\localhost\\c:\\Program Files")), + HandleType::kDirectory, UserAction::kOpen)); +} +#endif + TEST_F(ChromeFileSystemAccessPermissionContextTest, ConfirmSensitiveEntryAccess_DangerousFile) { // Saving files with a harmless extension should be allowed.
diff --git a/chrome/browser/first_party_sets/first_party_sets_navigation_throttle.cc b/chrome/browser/first_party_sets/first_party_sets_navigation_throttle.cc index a0d83e0..7449498 100644 --- a/chrome/browser/first_party_sets/first_party_sets_navigation_throttle.cc +++ b/chrome/browser/first_party_sets/first_party_sets_navigation_throttle.cc
@@ -31,7 +31,7 @@ FirstPartySetsNavigationThrottle::~FirstPartySetsNavigationThrottle() = default; ThrottleCheckResult FirstPartySetsNavigationThrottle::WillStartRequest() { - if (!service_->is_ready()) { + if (service_->is_enabled() && !service_->is_ready()) { service_->RegisterThrottleResumeCallback(base::BindOnce( &FirstPartySetsNavigationThrottle::Resume, weak_factory_.GetWeakPtr())); return content::NavigationThrottle::DEFER;
diff --git a/chrome/browser/first_party_sets/first_party_sets_policy_service.cc b/chrome/browser/first_party_sets/first_party_sets_policy_service.cc index 173b044..ac7d31e 100644 --- a/chrome/browser/first_party_sets/first_party_sets_policy_service.cc +++ b/chrome/browser/first_party_sets/first_party_sets_policy_service.cc
@@ -173,10 +173,8 @@ void FirstPartySetsPolicyService::RegisterThrottleResumeCallback( base::OnceClosure resume_callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (is_ready() || !is_enabled()) { - std::move(resume_callback).Run(); - return; - } + DCHECK(!is_ready()); + DCHECK(is_enabled()); on_ready_callbacks_.push_back(std::move(resume_callback)); }
diff --git a/chrome/browser/first_party_sets/first_party_sets_policy_service.h b/chrome/browser/first_party_sets/first_party_sets_policy_service.h index a7a601dd..60164a2 100644 --- a/chrome/browser/first_party_sets/first_party_sets_policy_service.h +++ b/chrome/browser/first_party_sets/first_party_sets_policy_service.h
@@ -69,9 +69,8 @@ // First-Party Sets enabled pref changes. void OnFirstPartySetsEnabledChanged(bool enabled); - // Invoke the callback synchronously to resume navigation if the instance is - // ready; or stores the callback to be invoked when this service is ready to - // do so. + // Stores the callback to be invoked when this service is ready to do so. Must + // not be called when FPS is not enabled or the service is already ready. void RegisterThrottleResumeCallback(base::OnceClosure resume_callback); // KeyedService: @@ -91,6 +90,12 @@ // Exposes `Init` for use in tests. void InitForTesting(); + // Returns true iff the preference and feature are both enabled. + bool is_enabled() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return feature_enabled_ && pref_enabled_; + } + // Returns true when this instance has received the config thus has been fully // initialized. bool is_ready() const { @@ -149,12 +154,6 @@ const std::set<net::SchemefulSite>& party_context, base::OnceCallback<void(net::FirstPartySetMetadata)> callback) const; - // Returns true iff the preference and feature are both enabled. - bool is_enabled() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return feature_enabled_ && pref_enabled_; - } - // The remote delegates associated with the profile that created this // service. mojo::RemoteSet<network::mojom::FirstPartySetsAccessDelegate>
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 0fe3d48..d2cae38 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
@@ -667,46 +667,31 @@ class FirstPartySetsPolicyServiceResumeThrottleTest : public FirstPartySetsPolicyServiceTest, - public ::testing::WithParamInterface<std::tuple<bool, bool, PrefState>> { + public ::testing::WithParamInterface<bool> { public: FirstPartySetsPolicyServiceResumeThrottleTest() { - if (IsFeatureEnabled()) { - features_.InitAndEnableFeatureWithParameters( - features::kFirstPartySets, - {{features::kFirstPartySetsClearSiteDataOnChangedSets.name, - IsClearingFeatureEnabled() ? "true" : "false"}}); - } else { - features_.InitAndDisableFeature(features::kFirstPartySets); - } + features_.InitAndEnableFeatureWithParameters( + features::kFirstPartySets, + {{features::kFirstPartySetsClearSiteDataOnChangedSets.name, + GetParam() ? "true" : "false"}}); } - bool IsPrefEnabled() { return GetPrefState() == PrefState::kEnabled; } - private: - bool IsFeatureEnabled() { return std::get<0>(GetParam()); } - bool IsClearingFeatureEnabled() { return std::get<1>(GetParam()); } - PrefState GetPrefState() { return std::get<2>(GetParam()); } - base::test::ScopedFeatureList features_; }; // Verify the throttle resume callback is always invoked. TEST_P(FirstPartySetsPolicyServiceResumeThrottleTest, - MaybeAddNavigationThrottleResumeCallback) { - SetEnabledPref(IsPrefEnabled()); + RegisterThrottleResumeCallback) { + SetInvokeCallbacksAsynchronously(true); + service()->InitForTesting(); base::RunLoop run_loop; service()->RegisterThrottleResumeCallback(run_loop.QuitClosure()); - service()->InitForTesting(); run_loop.Run(); } -INSTANTIATE_TEST_SUITE_P( - All, - FirstPartySetsPolicyServiceResumeThrottleTest, - ::testing::Combine(::testing::Bool(), - ::testing::Bool(), - ::testing::Values(PrefState::kDefault, - PrefState::kDisabled, - PrefState::kEnabled))); +INSTANTIATE_TEST_SUITE_P(All, + FirstPartySetsPolicyServiceResumeThrottleTest, + ::testing::Bool()); } // namespace first_party_sets
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 728ad31..d0b95a4 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -661,7 +661,7 @@ { "name": "back-gesture-refactor-android", "owners": ["lazzzis@google.com", "jinsukkim", "twellington"], - "expiry_milestone": 109 + "expiry_milestone": 115 }, { "name": "batch-fetch-requests", @@ -676,12 +676,12 @@ { "name": "binding-manager-connection-limit", "owners": ["ckitagawa", "yfriedman"], - "expiry_milestone": 109 + "expiry_milestone": 111 }, { "name": "binding-manager-use-not-perceptible-binding", "owners": ["ckitagawa", "yfriedman"], - "expiry_milestone": 109 + "expiry_milestone": 111 }, { "name": "biometric-authentication-for-filling", @@ -4461,11 +4461,6 @@ "expiry_milestone": 114 }, { - "name": "lens-on-quick-action-search-widget", - "owners": [ "juanmojica@google.com", "schechter@google.com", "lens-chrome@google.com" ], - "expiry_milestone": 107 - }, - { "name": "lightweight-reactions-android", "owners": [ "gujen", "sophey", "chrome-with-friends-robots@google.com" ], "expiry_milestone": 110 @@ -5478,7 +5473,7 @@ { "name": "paint-preview-demo", "owners": [ "ckitagawa", "fredmello", "chrome-fdt@google.com" ], - "expiry_milestone": 109 + "expiry_milestone": 111 }, { "name": "paint-preview-startup", @@ -6026,11 +6021,6 @@ "expiry_milestone": 115 }, { - "name": "sameparty-cookies-considered-first-party", - "owners": ["cfredric", "chrome-first-party-sets@chromium.org"], - "expiry_milestone": 108 - }, - { "name": "sanitizer-api", "owners": [ "//third_party/blink/renderer/modules/sanitizer_api/OWNERS" ], "expiry_milestone": 109
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index c0629e5..100b7e4 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1778,12 +1778,6 @@ "Enables use of a static page in a new tab when using the Lens region " "search feature."; -const char kLensOnQuickActionSearchWidgetName[] = - "Google Lens in Chrome's Quick Action Search Widget"; -const char kLensOnQuickActionSearchWidgetDescription[] = - "Enable an entry point to Google Lens to allow users to search what they " - "see using their mobile camera in the Quick Action Search Widget."; - const char kLogJsConsoleMessagesName[] = "Log JS console messages in system logs"; const char kLogJsConsoleMessagesDescription[] = @@ -2550,12 +2544,6 @@ "When enabled, adds the unused sites permission module to Safety Check on " "desktop. The module will be shown depending on the browser state."; -const char kSamePartyCookiesConsideredFirstPartyName[] = - "Consider SameParty cookies to be first-party."; -const char kSamePartyCookiesConsideredFirstPartyDescription[] = - "If enabled, SameParty cookies will not be blocked even if third-party " - "cookies are blocked."; - const char kPartitionedCookiesName[] = "Partitioned cookies"; const char kPartitionedCookiesDescription[] = "Controls if the Partitioned cookie attribute is enabled."; @@ -6278,10 +6266,6 @@ "When enabled, the autoSelectAllScreens attribute is available for usage " "with the GetDisplayMediaSet API."; -const char kVaapiAV1DecoderName[] = "VA-API decode acceleration for AV1"; -const char kVaapiAV1DecoderDescription[] = - "Enable or disable decode acceleration of AV1 videos using the VA-API."; - const char kIntentChipSkipsPickerName[] = "Link capturing intent chip skips the intent picker bubble"; const char kIntentChipSkipsPickerDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 12912ab6..8fa909ec 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1428,9 +1428,6 @@ extern const char kSafetyCheckUnusedSitePermissionsName[]; extern const char kSafetyCheckUnusedSitePermissionsDescription[]; -extern const char kSamePartyCookiesConsideredFirstPartyName[]; -extern const char kSamePartyCookiesConsideredFirstPartyDescription[]; - extern const char kPartitionedCookiesName[]; extern const char kPartitionedCookiesDescription[]; // TODO(crbug.com/1296161): Remove this when the CHIPS OT ends. @@ -3602,9 +3599,6 @@ extern const char kGetDisplayMediaSetAutoSelectAllScreensName[]; extern const char kGetDisplayMediaSetAutoSelectAllScreensDescription[]; -extern const char kVaapiAV1DecoderName[]; -extern const char kVaapiAV1DecoderDescription[]; - extern const char kIntentChipSkipsPickerName[]; extern const char kIntentChipSkipsPickerDescription[];
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc index 4114d60..af0b1153 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -4054,7 +4054,9 @@ base::test::ScopedFeatureList scoped_feature_list_; }; -IN_PROC_BROWSER_TEST_P(NavigationPageLoadMetricsBrowserTest, FirstInputDelay) { +// Flaky. See https://crbug.com/1224780. +IN_PROC_BROWSER_TEST_P(NavigationPageLoadMetricsBrowserTest, + DISABLED_FirstInputDelay) { ASSERT_TRUE(embedded_test_server()->Start()); GURL url1(embedded_test_server()->GetURL("a.com", "/title1.html")); @@ -4067,35 +4069,19 @@ // 1) Navigate to url1. EXPECT_TRUE(content::NavigateToURL(web_contents(), url1)); - - // There is no FirstInputDelay in UMA before the simulated mouse click - histogram_tester_->ExpectTotalCount(internal::kHistogramFirstInputDelay, 0); content::RenderFrameHost* rfh_a = RenderFrameHost(); content::RenderProcessHost* rfh_a_process = rfh_a->GetProcess(); - // Create a Performance Observer to ensure the renderer receives the click - EXPECT_TRUE(content::ExecJs(web_contents(), - "waitFirstInput = async () => {" - "const observePromise = new Promise(resolve => {" - "new PerformanceObserver(e => {" - "e.getEntries().forEach(entry => {" - "resolve();" - "})" - "}).observe({type: 'first-input', buffered: true});" - "});" - "return await observePromise;" - "};" - )); - // Simulate mouse click. FirstInputDelay won't get updated immediately. content::SimulateMouseClickAt(web_contents(), 0, blink::WebMouseEvent::Button::kLeft, gfx::Point(100, 100)); - - // Run the Performance Observer - EXPECT_TRUE(ExecJs(web_contents(), "waitFirstInput()")); - + // Run arbitrary script and run tasks in the brwoser to ensure the input is + // processed in the renderer. + EXPECT_TRUE(content::ExecJs(rfh_a, "var foo = 42;")); + base::RunLoop().RunUntilIdle(); content::FetchHistogramsFromChildProcesses(); + histogram_tester_->ExpectTotalCount(internal::kHistogramFirstInputDelay, 0); // 2) Immediately navigate to url2. if (GetParam() == "CrossSiteRendererInitiated") { @@ -4107,13 +4093,6 @@ content::FetchHistogramsFromChildProcesses(); if (GetParam() != "CrossSiteBrowserInitiated" || rfh_a_process == RenderFrameHost()->GetProcess()) { - - // Let the program wait for 50ms to ensure the First Input Delay - // is ready in UMA - // TODO(crbug.com/1380108) : replace with test_waiter when it allows multiple page - // loads - base::PlatformThread::Sleep(base::Milliseconds(50)); - // - For "SameSite" case, since the old and new RenderFrame either share a // process (with RenderDocument/back-forward cache) or the RenderFrame is // reused the metrics update will be sent to the browser during commit and @@ -4123,7 +4102,6 @@ // - For "CrossSiteBrowserInitiated" case, if the old and new RenderFrame // share a process, the metrics update will be sent to the browser during // commit and won't get ignored, successfully updating the histogram. - histogram_tester_->ExpectTotalCount(internal::kHistogramFirstInputDelay, 1); } else { // Note that in some cases the metrics might flakily get updated in time,
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index bd3d290a..67fc241 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -767,6 +767,14 @@ // Deprecated 09/2022. const char kFirstPartySetsEnabled[] = "first_party_sets.enabled"; +#if BUILDFLAG(IS_CHROMEOS_ASH) +// Deprecated 10/2022. +const char kSuggestedContentInfoShownInLauncher[] = + "ash.launcher.suggested_content_info_shown"; +const char kSuggestedContentInfoDismissedInLauncher[] = + "ash.launcher.suggested_content_info_dismissed"; +#endif + // Register local state used only for migration (clearing or moving to a new // key). void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) { @@ -1014,6 +1022,13 @@ // Deprecated 10/2022. registry->RegisterBooleanPref(kLoadCryptoTokenExtension, false); #endif + +// Deprecated 10/2022. +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterIntegerPref(kSuggestedContentInfoShownInLauncher, 0); + registry->RegisterBooleanPref(kSuggestedContentInfoDismissedInLauncher, + false); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) } } // namespace @@ -2036,6 +2051,12 @@ profile_prefs->ClearPref(kLoadCryptoTokenExtension); #endif +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Added 10/2022. + profile_prefs->ClearPref(kSuggestedContentInfoShownInLauncher); + profile_prefs->ClearPref(kSuggestedContentInfoDismissedInLauncher); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + // Please don't delete the following line. It is used by PRESUBMIT.py. // END_MIGRATE_OBSOLETE_PROFILE_PREFS
diff --git a/chrome/browser/printing/printer_manager_dialog_mac.mm b/chrome/browser/printing/printer_manager_dialog_mac.cc similarity index 61% rename from chrome/browser/printing/printer_manager_dialog_mac.mm rename to chrome/browser/printing/printer_manager_dialog_mac.cc index 4c42c3c..2966452f 100644 --- a/chrome/browser/printing/printer_manager_dialog_mac.mm +++ b/chrome/browser/printing/printer_manager_dialog_mac.cc
@@ -4,15 +4,13 @@ #include "chrome/browser/printing/printer_manager_dialog.h" -#import <AppKit/AppKit.h> +#include "base/mac/mac_util.h" namespace printing { -static NSString* kPrintAndFaxPrefPane = - @"/System/Library/PreferencePanes/PrintAndFax.prefPane"; - void PrinterManagerDialog::ShowPrinterManagerDialog() { - [[NSWorkspace sharedWorkspace] openFile:kPrintAndFaxPrefPane]; + base::mac::OpenSystemSettingsPane( + base::mac::SystemSettingsPane::kPrintersScanners); } } // namespace printing
diff --git a/chrome/browser/resources/chromeos/parent_access/flows/local_web_approvals_after.html b/chrome/browser/resources/chromeos/parent_access/flows/local_web_approvals_after.html index 417f722b..04e4a30 100644 --- a/chrome/browser/resources/chromeos/parent_access/flows/local_web_approvals_after.html +++ b/chrome/browser/resources/chromeos/parent_access/flows/local_web_approvals_after.html
@@ -4,6 +4,7 @@ } .subtitle { + font-family: var(--cros-font-family-google-sans); font-size: 24px; font-weight: 500; margin-top: 32px;
diff --git a/chrome/browser/resources/new_tab_page/modules/cart/module.html b/chrome/browser/resources/new_tab_page/modules/cart/module.html index cc5049b..e698392 100644 --- a/chrome/browser/resources/new_tab_page/modules/cart/module.html +++ b/chrome/browser/resources/new_tab_page/modules/cart/module.html
@@ -179,7 +179,6 @@ font-weight: 400; overflow: hidden; text-overflow: ellipsis; - text-shadow: var(--ntp-theme-text-shadow); white-space: nowrap; }
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.ts b/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.ts index a98472f..d30e058 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.ts +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.ts
@@ -148,6 +148,12 @@ this.route_ = routes.A11Y_DISPLAY_AND_MAGNIFICATION; } + override ready() { + super.ready(); + + this.addFocusConfig(routes.DISPLAY, '#displaySubpageButton'); + } + /** * Note: Overrides RouteOriginBehavior implementation */
diff --git a/chrome/browser/safe_browsing/chrome_user_population_helper.cc b/chrome/browser/safe_browsing/chrome_user_population_helper.cc index 825e2a9..d725926 100644 --- a/chrome/browser/safe_browsing/chrome_user_population_helper.cc +++ b/chrome/browser/safe_browsing/chrome_user_population_helper.cc
@@ -47,20 +47,8 @@ const absl::optional<ChromeUserPopulation>& cached_population = GetCachedUserPopulation(profile); if (!cached_population) { - base::UmaHistogramEnumeration("SafeBrowsing.NoCachedPopulationReason", - GetNoCachedPopulationReason(profile)); return; } - - base::UmaHistogramBoolean( - "SafeBrowsing.PopulationMatchesCachedValue.Population", - cached_population->user_population() == population.user_population()); - base::UmaHistogramBoolean( - "SafeBrowsing.PopulationMatchesCachedValue.UserAgent", - cached_population->user_agent() == population.user_agent()); - base::UmaHistogramBoolean( - "SafeBrowsing.PopulationMatchesCachedValue.Mbb", - cached_population->is_mbb_enabled() == population.is_mbb_enabled()); } } // namespace
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 30e2d5a..acf41a30 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2064,6 +2064,8 @@ "app_list/search/app_search_provider.h", "app_list/search/app_service_app_result.cc", "app_list/search/app_service_app_result.h", + "app_list/search/app_zero_state_provider.cc", + "app_list/search/app_zero_state_provider.h", "app_list/search/arc/arc_app_shortcut_search_result.cc", "app_list/search/arc/arc_app_shortcut_search_result.h", "app_list/search/arc/arc_app_shortcuts_search_provider.cc",
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java index 92269ebc..6139280 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -706,6 +706,7 @@ mStartSurfaceToolbarCoordinator.onStartSurfaceStateChanged( newState, requestToShow, newLayoutType); updateToolbarLayoutVisibility(); + updateButtonVisibility(); } /**
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionMediator.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionMediator.java index 8205bf4..268a2a7a 100644 --- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionMediator.java +++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionMediator.java
@@ -373,6 +373,13 @@ properties.mIdpForDisplay = idpForDisplay; properties.mTermsOfServiceUrl = metadata.getTermsOfServiceUrl(); properties.mPrivacyPolicyUrl = metadata.getPrivacyPolicyUrl(); + properties.mTermsOfServiceClickRunnable = () -> { + RecordHistogram.recordBooleanHistogram( + "Blink.FedCm.SignUp.TermsOfServiceClicked", true); + }; + properties.mPrivacyPolicyClickRunnable = () -> { + RecordHistogram.recordBooleanHistogram("Blink.FedCm.SignUp.PrivacyPolicyClicked", true); + }; return new PropertyModel.Builder(DataSharingConsentProperties.ALL_KEYS) .with(DataSharingConsentProperties.PROPERTIES, properties)
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionProperties.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionProperties.java index 4ff6a8d..c6b960ad 100644 --- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionProperties.java +++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionProperties.java
@@ -84,6 +84,8 @@ public String mIdpForDisplay; public GURL mTermsOfServiceUrl; public GURL mPrivacyPolicyUrl; + public Runnable mTermsOfServiceClickRunnable; + public Runnable mPrivacyPolicyClickRunnable; } static final ReadableObjectPropertyKey<Properties> PROPERTIES =
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java index edec4f3..8f10bfc 100644 --- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java +++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java
@@ -143,13 +143,15 @@ } } - static SpanApplier.SpanInfo createLink(Context context, GURL url, String tag) { + static SpanApplier.SpanInfo createLink( + Context context, String tag, GURL url, Runnable clickRunnable) { if (GURL.isEmptyOrInvalid(url)) return null; String startTag = "<" + tag + ">"; String endTag = "</" + tag + ">"; Callback<View> onClickCallback = v -> { CustomTabActivity.showInfoPage(context, url.getSpec()); + clickRunnable.run(); }; return new SpanApplier.SpanInfo( startTag, endTag, new NoUnderlineClickableSpan(context, onClickCallback)); @@ -167,10 +169,10 @@ model.get(DataSharingConsentProperties.PROPERTIES); Context context = view.getContext(); - SpanApplier.SpanInfo privacyPolicySpan = - createLink(context, properties.mPrivacyPolicyUrl, "link_privacy_policy"); - SpanApplier.SpanInfo termsOfServiceSpan = - createLink(context, properties.mTermsOfServiceUrl, "link_terms_of_service"); + SpanApplier.SpanInfo privacyPolicySpan = createLink(context, "link_privacy_policy", + properties.mPrivacyPolicyUrl, properties.mPrivacyPolicyClickRunnable); + SpanApplier.SpanInfo termsOfServiceSpan = createLink(context, "link_terms_of_service", + properties.mTermsOfServiceUrl, properties.mTermsOfServiceClickRunnable); int consentTextId; if (privacyPolicySpan == null && termsOfServiceSpan == null) {
diff --git a/chrome/browser/ui/app_list/search/app_search_provider.cc b/chrome/browser/ui/app_list/search/app_search_provider.cc index a83365b4..69d5a39b 100644 --- a/chrome/browser/ui/app_list/search/app_search_provider.cc +++ b/chrome/browser/ui/app_list/search/app_search_provider.cc
@@ -37,13 +37,8 @@ } // namespace -AppSearchProvider::AppSearchProvider(Profile* profile, - AppListControllerDelegate* list_controller, - base::Clock* clock, - AppListModelUpdater* model_updater) - : model_updater_(model_updater) { - data_source_ = - std::make_unique<AppSearchDataSource>(profile, list_controller, clock); +AppSearchProvider::AppSearchProvider(AppSearchDataSource* data_source) + : data_source_(data_source) { app_updates_subscription_ = data_source_->SubscribeToAppUpdates(base::BindRepeating( &AppSearchProvider::UpdateResults, base::Unretained(this))); @@ -70,35 +65,17 @@ void AppSearchProvider::StartZeroState() { query_.clear(); - query_start_time_ = base::TimeTicks::Now(); - record_query_uma_ = true; - - { - // Prevent `UpdateResults()` from running as a result of a data source - // refresh callback to avoid double update. - base::AutoReset<bool> auto_reset(&updates_blocked_, true); - data_source_->RefreshIfNeeded(); - } - - UpdateResults(); + record_query_uma_ = false; } ash::AppListSearchResultType AppSearchProvider::ResultType() const { return ash::AppListSearchResultType::kInstalledApp; } -bool AppSearchProvider::ShouldBlockZeroState() const { - return true; -} +void AppSearchProvider::UpdateResults() { + if (updates_blocked_) + return; -void AppSearchProvider::UpdateRecommendedResults( - const base::flat_map<std::string, uint16_t>& id_to_app_list_index) { - SearchProvider::Results new_results = - data_source_->GetRecommendations(id_to_app_list_index); - PublishQueriedResultsOrRecommendation(false, &new_results); -} - -void AppSearchProvider::UpdateQueriedResults() { SearchProvider::Results new_results; const bool use_exact_match = @@ -111,48 +88,13 @@ new_results = data_source_->GetFuzzyMatches(query_); } - PublishQueriedResultsOrRecommendation(true, &new_results); -} - -void AppSearchProvider::PublishQueriedResultsOrRecommendation( - bool is_queried_search, - Results* new_results) { - MaybeRecordQueryLatencyHistogram(is_queried_search); - SwapResults(new_results); -} - -void AppSearchProvider::MaybeRecordQueryLatencyHistogram( - bool is_queried_search) { - // Record the query latency only if search provider is queried by user - // initiating a search or getting zero state suggestions. - if (!record_query_uma_) - return; - - if (is_queried_search) { + if (record_query_uma_) { + record_query_uma_ = false; UMA_HISTOGRAM_TIMES("Apps.AppList.AppSearchProvider.QueryTime", base::TimeTicks::Now() - query_start_time_); - } else { - UMA_HISTOGRAM_TIMES("Apps.AppList.AppSearchProvider.ZeroStateLatency", - base::TimeTicks::Now() - query_start_time_); } - record_query_uma_ = false; -} -void AppSearchProvider::UpdateResults() { - if (updates_blocked_) - return; - - const bool show_recommendations = query_.empty(); - - if (show_recommendations) { - // Get the map of app ids to their position in the app list, and then - // update results. - // Unretained is safe because the callback gets called synchronously. - model_updater_->GetIdToAppListIndexMap(base::BindOnce( - &AppSearchProvider::UpdateRecommendedResults, base::Unretained(this))); - } else { - UpdateQueriedResults(); - } + SwapResults(&new_results); } } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/app_search_provider.h b/chrome/browser/ui/app_list/search/app_search_provider.h index 2e62129..6ebd29c 100644 --- a/chrome/browser/ui/app_list/search/app_search_provider.h +++ b/chrome/browser/ui/app_list/search/app_search_provider.h
@@ -9,32 +9,16 @@ #include <string> #include "base/callback_list.h" -#include "base/containers/flat_map.h" #include "base/time/time.h" #include "chrome/browser/ui/app_list/search/search_provider.h" -class AppListControllerDelegate; -class AppListModelUpdater; -class Profile; - -namespace base { -class Clock; -} - namespace app_list { class AppSearchDataSource; class AppSearchProvider : public SearchProvider { public: - // |clock| should be used by tests that needs to overrides the time. - // Otherwise, pass a base::DefaultClock instance. This doesn't take the - // ownership of the clock. |clock| must outlive the AppSearchProvider - // instance. - AppSearchProvider(Profile* profile, - AppListControllerDelegate* list_controller, - base::Clock* clock, - AppListModelUpdater* model_updater); + explicit AppSearchProvider(AppSearchDataSource* data_source); AppSearchProvider(const AppSearchProvider&) = delete; AppSearchProvider& operator=(const AppSearchProvider&) = delete; @@ -45,33 +29,15 @@ void Start(const std::u16string& query) override; void StartZeroState() override; ash::AppListSearchResultType ResultType() const override; - bool ShouldBlockZeroState() const override; private: void UpdateResults(); - // Updates the zero-state app recommendations ("recent apps"). - void UpdateRecommendedResults( - const base::flat_map<std::string, uint16_t>& id_to_app_list_index); - - void UpdateQueriedResults(); - - // Publishes either the queried results or recommendation. - // |is_queried_search|: true for queried results, false for recommendation. - void PublishQueriedResultsOrRecommendation(bool is_queried_search, - Results* new_results); - - // Records the app search provider's latency when user initiates a search or - // gets the zero state suggestions. - // If |is_queried_search| is true, record query latency; otherwise, record - // zero state recommendation latency. - void MaybeRecordQueryLatencyHistogram(bool is_queried_search); + AppSearchDataSource* const data_source_; std::u16string query_; base::TimeTicks query_start_time_; bool record_query_uma_ = false; - AppListModelUpdater* const model_updater_; - std::unique_ptr<AppSearchDataSource> data_source_; // Used to skip result updates caused by data source changes due to an // explicit refresh request.
diff --git a/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc index e055cbb..d96d028 100644 --- a/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc
@@ -29,6 +29,8 @@ #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/app_list/arc/arc_app_test.h" #include "chrome/browser/ui/app_list/arc/arc_default_app_list.h" +#include "chrome/browser/ui/app_list/search/app_search_data_source.h" +#include "chrome/browser/ui/app_list/search/app_zero_state_provider.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/test/test_search_controller.h" #include "chrome/browser/ui/app_list/test/fake_app_list_model_updater.h" @@ -121,14 +123,16 @@ } // namespace -class AppSearchProviderTest : public AppListTestBase { +class AppSearchProviderTestBase : public AppListTestBase { public: - AppSearchProviderTest() = default; + explicit AppSearchProviderTestBase(bool zero_state_provider) + : zero_state_provider_(zero_state_provider) {} - AppSearchProviderTest(const AppSearchProviderTest&) = delete; - AppSearchProviderTest& operator=(const AppSearchProviderTest&) = delete; + AppSearchProviderTestBase(const AppSearchProviderTestBase&) = delete; + AppSearchProviderTestBase& operator=(const AppSearchProviderTestBase&) = + delete; - ~AppSearchProviderTest() override {} + ~AppSearchProviderTestBase() override = default; // AppListTestBase overrides: void SetUp() override { @@ -142,19 +146,34 @@ void CreateSearch() { search_controller_ = std::make_unique<TestSearchController>(); - auto app_search = std::make_unique<AppSearchProvider>( - profile_.get(), nullptr, &clock_, model_updater_.get()); + data_source_ = + std::make_unique<AppSearchDataSource>(profile_.get(), nullptr, &clock_); + + std::unique_ptr<SearchProvider> app_search; + if (zero_state_provider_) { + app_search = std::make_unique<AppZeroStateProvider>(data_source_.get(), + model_updater_.get()); + } else { + app_search = std::make_unique<AppSearchProvider>(data_source_.get()); + } + app_search_ = app_search.get(); + search_controller_->AddProvider(0, std::move(app_search)); } std::string RunQuery(const std::string& query) { - if (query.empty()) { - search_controller_->StartZeroState(base::DoNothing(), base::TimeDelta()); - } else { - search_controller_->StartSearch(base::UTF8ToUTF16(query)); - } + EXPECT_FALSE(query.empty()); + search_controller_->StartSearch(base::UTF8ToUTF16(query)); + return GetSortedResultsString(); + } + std::string RunZeroStateSearch() { + search_controller_->StartZeroState(base::DoNothing(), base::TimeDelta()); + return GetSortedResultsString(); + } + + std::string GetSortedResultsString() { // Sort results by relevance. std::vector<ChromeSearchResult*> sorted_results; for (const auto& result : results()) @@ -231,15 +250,37 @@ void CallViewClosing() { app_search_->ViewClosing(); } private: + // Whether the test is testing zero state, or queried apps search provider. + const bool zero_state_provider_; + base::SimpleTestClock clock_; base::ScopedTempDir temp_dir_; std::unique_ptr<FakeAppListModelUpdater> model_updater_; std::unique_ptr<TestSearchController> search_controller_; - AppSearchProvider* app_search_ = nullptr; + std::unique_ptr<AppSearchDataSource> data_source_; + SearchProvider* app_search_ = nullptr; std::unique_ptr<::test::TestAppListControllerDelegate> controller_; ArcAppTest arc_test_; }; +class AppSearchProviderTest : public AppSearchProviderTestBase { + public: + AppSearchProviderTest() + : AppSearchProviderTestBase(/*zero_state_provider=*/false) {} + AppSearchProviderTest(const AppSearchProviderTest&) = delete; + AppSearchProviderTest& operator=(const AppSearchProviderTest&) = delete; + ~AppSearchProviderTest() override = default; +}; + +class AppZeroStateProviderTest : public AppSearchProviderTestBase { + public: + AppZeroStateProviderTest() + : AppSearchProviderTestBase(/*zero_state_provider=*/true) {} + AppZeroStateProviderTest(const AppZeroStateProviderTest&) = delete; + AppZeroStateProviderTest& operator=(const AppZeroStateProviderTest&) = delete; + ~AppZeroStateProviderTest() override = default; +}; + TEST_F(AppSearchProviderTest, Basic) { arc_test().SetUp(profile()); std::vector<arc::mojom::AppInfoPtr> arc_apps; @@ -399,7 +440,7 @@ arc_test().TearDown(); } -TEST_F(AppSearchProviderTest, FetchRecommendations) { +TEST_F(AppZeroStateProviderTest, FetchRecommendations) { CreateSearch(); extensions::ExtensionPrefs* prefs = @@ -410,14 +451,14 @@ prefs->SetLastLaunchTime(kPackagedApp2Id, MicrosecondsSinceEpoch(5)); // Allow async callbacks to run. base::RunLoop().RunUntilIdle(); - EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2", RunQuery("")); + EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2", RunZeroStateSearch()); prefs->SetLastLaunchTime(kHostedAppId, MicrosecondsSinceEpoch(5)); prefs->SetLastLaunchTime(kPackagedApp1Id, MicrosecondsSinceEpoch(10)); prefs->SetLastLaunchTime(kPackagedApp2Id, MicrosecondsSinceEpoch(20)); // Allow async callbacks to run. base::RunLoop().RunUntilIdle(); - EXPECT_EQ("Packaged App 2,Packaged App 1,Hosted App", RunQuery("")); + EXPECT_EQ("Packaged App 2,Packaged App 1,Hosted App", RunZeroStateSearch()); // Times in the future should just be handled as highest priority. prefs->SetLastLaunchTime(kHostedAppId, base::Time::Now() + base::Seconds(5)); @@ -425,10 +466,15 @@ prefs->SetLastLaunchTime(kPackagedApp2Id, MicrosecondsSinceEpoch(5)); // Allow async callbacks to run. base::RunLoop().RunUntilIdle(); - EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2", RunQuery("")); + EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2", RunZeroStateSearch()); + + // Validate that queried search does not clear out zero state results. + RunQuery("No matches"); + EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2", + GetSortedResultsString()); } -TEST_F(AppSearchProviderTest, DefaultRecommendedAppRanking) { +TEST_F(AppZeroStateProviderTest, DefaultRecommendedAppRanking) { // Disable the pre-installed high-priority extensions. This test simulates // a brand new profile being added to a device, and should not include these. service_->UninstallExtension( @@ -472,7 +518,7 @@ base::RunLoop().RunUntilIdle(); CreateSearch(); - EXPECT_EQ("OsSettings,Help,Canvas,Camera", RunQuery("")); + EXPECT_EQ("OsSettings,Help,Canvas,Camera", RunZeroStateSearch()); // Install a normal (non-default-installed) app. const std::string normal_app_id = @@ -492,7 +538,7 @@ CreateSearch(); EXPECT_EQ( std::string(kRankingNormalAppName) + ",OsSettings,Help,Canvas,Camera", - RunQuery("")); + RunZeroStateSearch()); // Simulate launching one of the default apps. Expect that this brings it to // higher precedence than all the others. @@ -500,10 +546,10 @@ CreateSearch(); EXPECT_EQ("Canvas," + std::string(kRankingNormalAppName) + ",OsSettings,Help,Camera", - RunQuery("")); + RunZeroStateSearch()); } -TEST_F(AppSearchProviderTest, FetchUnlaunchedRecommendations) { +TEST_F(AppZeroStateProviderTest, FetchUnlaunchedRecommendations) { CreateSearch(); extensions::ExtensionPrefs* prefs = @@ -514,7 +560,7 @@ prefs->SetLastLaunchTime(kHostedAppId, base::Time::Now()); prefs->SetLastLaunchTime(kPackagedApp1Id, MicrosecondsSinceEpoch(0)); prefs->SetLastLaunchTime(kPackagedApp2Id, MicrosecondsSinceEpoch(0)); - EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2", RunQuery("")); + EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2", RunZeroStateSearch()); } TEST_F(AppSearchProviderTest, FilterDuplicate) { @@ -723,28 +769,23 @@ EXPECT_EQ(kKeyboardShortcutHelperInternalName, RunQuery("Helper")); } -enum class TestExtensionInstallType { - CONTROLLED_BY_POLICY, - CHROME_COMPONENT, - INSTALLED_BY_DEFAULT, - INSTALLED_BY_OEM, -}; - -class AppSearchProviderWithExtensionInstallType - : public AppSearchProviderTest, - public ::testing::WithParamInterface<TestExtensionInstallType> { +class AppSearchProviderOemAppTest + : public AppSearchProviderTestBase, + public ::testing::WithParamInterface</*test_zero_state_search=*/bool> { public: - AppSearchProviderWithExtensionInstallType() = default; + AppSearchProviderOemAppTest() + : AppSearchProviderTestBase(test_zero_state_search()) {} - AppSearchProviderWithExtensionInstallType( - const AppSearchProviderWithExtensionInstallType&) = delete; - AppSearchProviderWithExtensionInstallType& operator=( - const AppSearchProviderWithExtensionInstallType&) = delete; + AppSearchProviderOemAppTest(const AppSearchProviderOemAppTest&) = delete; + AppSearchProviderOemAppTest& operator=(const AppSearchProviderOemAppTest&) = + delete; - ~AppSearchProviderWithExtensionInstallType() override = default; + ~AppSearchProviderOemAppTest() override = default; + + bool test_zero_state_search() const { return GetParam(); } }; -TEST_P(AppSearchProviderWithExtensionInstallType, OemResultsOnFirstBoot) { +TEST_P(AppSearchProviderOemAppTest, OemResultsOnFirstBoot) { // Disable the pre-installed high-priority extensions. This test simulates // a brand new profile being added to a device, and should not include these. service_->UninstallExtension( @@ -784,8 +825,10 @@ base::RunLoop().RunUntilIdle(); CreateSearch(); + std::string results_string = + test_zero_state_search() ? RunZeroStateSearch() : RunQuery("Oem"); std::vector<std::string> results = base::SplitString( - RunQuery(""), ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + results_string, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); for (auto* app : kOemAppNames) { EXPECT_TRUE(base::Contains(results, app)); @@ -879,13 +922,7 @@ arc_test().TearDown(); } -INSTANTIATE_TEST_SUITE_P( - All, - AppSearchProviderWithExtensionInstallType, - ::testing::ValuesIn({TestExtensionInstallType::CONTROLLED_BY_POLICY, - TestExtensionInstallType::CHROME_COMPONENT, - TestExtensionInstallType::INSTALLED_BY_DEFAULT, - TestExtensionInstallType::INSTALLED_BY_OEM})); +INSTANTIATE_TEST_SUITE_P(All, AppSearchProviderOemAppTest, ::testing::Bool()); INSTANTIATE_TEST_SUITE_P( All,
diff --git a/chrome/browser/ui/app_list/search/app_zero_state_provider.cc b/chrome/browser/ui/app_list/search/app_zero_state_provider.cc new file mode 100644 index 0000000..6439c8b --- /dev/null +++ b/chrome/browser/ui/app_list/search/app_zero_state_provider.cc
@@ -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. + +#include "chrome/browser/ui/app_list/search/app_zero_state_provider.h" + +#include <string> +#include <utility> + +#include "ash/public/cpp/app_list/app_list_features.h" +#include "base/bind.h" +#include "base/metrics/histogram_macros.h" +#include "base/time/time.h" +#include "chrome/browser/ui/app_list/app_list_model_updater.h" +#include "chrome/browser/ui/app_list/search/app_search_data_source.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" + +namespace app_list { + +AppZeroStateProvider::AppZeroStateProvider(AppSearchDataSource* data_source, + AppListModelUpdater* model_updater) + : data_source_(data_source), model_updater_(model_updater) { + // NOTE: Unlike AppSearchProvider, AppZeroStateProvider does not have to + // update search model when app status, or other app information changes. The + // recent apps UI implementation updates app representations independently of + // search model, using app list model directly. The UI only uses search model + // to determine preferred app display order - updating search model may change + // order of apps, which would be undesirable UI behavior (it could be + // perceived as pop-in after app list has been shown). + // If the UI behavior changes, the decision not to update search model for + // recent apps whenever app service state changes should be reevaluated. +} + +AppZeroStateProvider::~AppZeroStateProvider() = default; + +void AppZeroStateProvider::StartZeroState() { + data_source_->RefreshIfNeeded(); + UpdateResults(); +} + +ash::AppListSearchResultType AppZeroStateProvider::ResultType() const { + return ash::AppListSearchResultType::kZeroStateApp; +} + +void AppZeroStateProvider::UpdateRecommendedResults( + const base::flat_map<std::string, uint16_t>& id_to_app_list_index) { + SearchProvider::Results new_results = + data_source_->GetRecommendations(id_to_app_list_index); + UMA_HISTOGRAM_TIMES("Apps.AppList.AppSearchProvider.ZeroStateLatency", + base::TimeTicks::Now() - query_start_time_); + + SwapResults(&new_results); +} + +void AppZeroStateProvider::UpdateResults() { + // Get the map of app ids to their position in the app list, and then + // update results. + // Unretained is safe because the callback gets called synchronously. + model_updater_->GetIdToAppListIndexMap(base::BindOnce( + &AppZeroStateProvider::UpdateRecommendedResults, base::Unretained(this))); +} + +} // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/app_zero_state_provider.h b/chrome/browser/ui/app_list/search/app_zero_state_provider.h new file mode 100644 index 0000000..1fa0762 --- /dev/null +++ b/chrome/browser/ui/app_list/search/app_zero_state_provider.h
@@ -0,0 +1,53 @@ +// 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 CHROME_BROWSER_UI_APP_LIST_SEARCH_APP_ZERO_STATE_PROVIDER_H_ +#define CHROME_BROWSER_UI_APP_LIST_SEARCH_APP_ZERO_STATE_PROVIDER_H_ + +#include <memory> +#include <string> + +#include "base/containers/flat_map.h" +#include "base/memory/weak_ptr.h" +#include "base/time/time.h" +#include "chrome/browser/ui/app_list/search/search_provider.h" + +class AppListModelUpdater; + +namespace app_list { + +class AppSearchDataSource; + +class AppZeroStateProvider : public SearchProvider { + public: + AppZeroStateProvider(AppSearchDataSource* data_source, + AppListModelUpdater* model_updater); + + AppZeroStateProvider(const AppZeroStateProvider&) = delete; + AppZeroStateProvider& operator=(const AppZeroStateProvider&) = delete; + + ~AppZeroStateProvider() override; + + // SearchProvider overrides: + void StartZeroState() override; + ash::AppListSearchResultType ResultType() const override; + + private: + void UpdateResults(); + + // Updates the zero-state app recommendations ("recent apps"). + void UpdateRecommendedResults( + const base::flat_map<std::string, uint16_t>& id_to_app_list_index); + + AppSearchDataSource* const data_source_; + AppListModelUpdater* const model_updater_; + + base::TimeTicks query_start_time_; + + base::WeakPtrFactory<AppZeroStateProvider> weak_ptr_factory_{this}; +}; + +} // namespace app_list + +#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_APP_ZERO_STATE_PROVIDER_H_
diff --git a/chrome/browser/ui/app_list/search/common/types_util.cc b/chrome/browser/ui/app_list/search/common/types_util.cc index 1dacd9c3..56a3a96 100644 --- a/chrome/browser/ui/app_list/search/common/types_util.cc +++ b/chrome/browser/ui/app_list/search/common/types_util.cc
@@ -14,6 +14,8 @@ return "Unknown"; case ash::AppListSearchResultType::kInstalledApp: return "Installed app"; + case ash::AppListSearchResultType::kZeroStateApp: + return "Zero state app"; case ash::AppListSearchResultType::kPlayStoreApp: return "Play store app"; case ash::AppListSearchResultType::kInstantApp:
diff --git a/chrome/browser/ui/app_list/search/files/file_result_unittest.cc b/chrome/browser/ui/app_list/search/files/file_result_unittest.cc index 718e0339..030bbe5 100644 --- a/chrome/browser/ui/app_list/search/files/file_result_unittest.cc +++ b/chrome/browser/ui/app_list/search/files/file_result_unittest.cc
@@ -7,18 +7,20 @@ #include "ash/public/cpp/app_list/app_list_types.h" #include "ash/public/cpp/test/test_app_list_color_provider.h" #include "base/files/file_path.h" -#include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" -#include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/app_list/search/common/icon_constants.h" #include "chrome/test/base/testing_profile.h" #include "chromeos/ash/components/string_matching/tokenized_string.h" +#include "chromeos/ui/base/file_icon_util.h" #include "content/public/test/browser_task_environment.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/skia_util.h" namespace app_list { @@ -97,4 +99,52 @@ } } +TEST_F(FileResultTest, Icons) { + const base::FilePath chipPath("/my/test/file.Pdf"); + FileResult chipResult( + /*id=*/"zero_state_file://" + chipPath.value(), chipPath, u"some details", + ash::AppListSearchResultType::kZeroStateFile, + ash::SearchResultDisplayType::kChip, 0.2f, std::u16string(), + FileResult::Type::kFile, profile_.get()); + EXPECT_FALSE(chipResult.chip_icon().isNull()); + EXPECT_TRUE(chipResult.icon().icon.isNull()); + + const base::FilePath excelPath("/my/test/mySheet.xlsx"); + FileResult fileResult( + /*id=*/"zero_state_file://" + excelPath.value(), excelPath, + u"some details", ash::AppListSearchResultType::kZeroStateFile, + ash::SearchResultDisplayType::kList, 0.2f, std::u16string(), + FileResult::Type::kFile, profile_.get()); + EXPECT_TRUE(fileResult.chip_icon().isNull()); + EXPECT_FALSE(fileResult.icon().icon.isNull()); + EXPECT_EQ(fileResult.icon().dimension, kSystemIconDimension); + EXPECT_TRUE(gfx::BitmapsAreEqual( + *fileResult.icon().icon.bitmap(), + *chromeos::GetIconForPath(excelPath, false).bitmap())); + + const base::FilePath folderPath("my/Maps"); + FileResult folderResult( + /*id=*/"zero_state_file://" + folderPath.value(), folderPath, + absl::nullopt, ash::AppListSearchResultType::kZeroStateFile, + ash::SearchResultDisplayType::kList, 0.2f, std::u16string(), + FileResult::Type::kDirectory, profile_.get()); + EXPECT_TRUE(folderResult.chip_icon().isNull()); + EXPECT_EQ(folderResult.icon().dimension, kSystemIconDimension); + EXPECT_TRUE(gfx::BitmapsAreEqual( + *folderResult.icon().icon.bitmap(), + *chromeos::GetIconFromType("folder", false).bitmap())); + + const base::FilePath sharedPath("my/Shared"); + FileResult sharedResult( + /*id=*/"zero_state_file://" + sharedPath.value(), sharedPath, + absl::nullopt, ash::AppListSearchResultType::kZeroStateFile, + ash::SearchResultDisplayType::kList, 0.2f, std::u16string(), + FileResult::Type::kSharedDirectory, profile_.get()); + EXPECT_TRUE(sharedResult.chip_icon().isNull()); + EXPECT_EQ(sharedResult.icon().dimension, kSystemIconDimension); + EXPECT_TRUE(gfx::BitmapsAreEqual( + *sharedResult.icon().icon.bitmap(), + *chromeos::GetIconFromType("shared", false).bitmap())); +} + } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.cc b/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.cc index fe18e240..8e0f3df 100644 --- a/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.cc +++ b/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.cc
@@ -156,10 +156,6 @@ return ash::AppListSearchResultType::kZeroStateDrive; } -bool ZeroStateDriveProvider::ShouldBlockZeroState() const { - return true; -} - void ZeroStateDriveProvider::StartZeroState() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.h b/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.h index 11dd2d24..20b83d6b 100644 --- a/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.h +++ b/chrome/browser/ui/app_list/search/files/zero_state_drive_provider.h
@@ -60,7 +60,6 @@ void StartZeroState() override; void ViewClosing() override; ash::AppListSearchResultType ResultType() const override; - bool ShouldBlockZeroState() const override; private: // Called when file suggestion data are fetched from the service.
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc index 807f1f0b..369e526 100644 --- a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc +++ b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc
@@ -78,10 +78,6 @@ return ash::AppListSearchResultType::kZeroStateFile; } -bool ZeroStateFileProvider::ShouldBlockZeroState() const { - return true; -} - void ZeroStateFileProvider::StartZeroState() { query_start_time_ = base::TimeTicks::Now();
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h index 33dc681..6e05f1a1 100644 --- a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h +++ b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h
@@ -41,7 +41,6 @@ // SearchProvider: void StartZeroState() override; ash::AppListSearchResultType ResultType() const override; - bool ShouldBlockZeroState() const override; private: // Called when file suggestion data are fetched from the service.
diff --git a/chrome/browser/ui/app_list/search/help_app_search_browsertest.cc b/chrome/browser/ui/app_list/search/help_app_search_browsertest.cc index 7fae2cb..8db26f3 100644 --- a/chrome/browser/ui/app_list/search/help_app_search_browsertest.cc +++ b/chrome/browser/ui/app_list/search/help_app_search_browsertest.cc
@@ -37,8 +37,10 @@ class HelpAppSearchBrowserTestBase : public AppListSearchBrowserTest { public: HelpAppSearchBrowserTestBase() { - scoped_feature_list_.InitAndEnableFeature( - chromeos::features::kHelpAppLauncherSearch); + scoped_feature_list_.InitWithFeaturesAndParameters( + {{ash::features::kProductivityLauncher, {{"enable_continue", "true"}}}, + {{chromeos::features::kHelpAppLauncherSearch}, {}}}, + {}); } ~HelpAppSearchBrowserTestBase() override = default; @@ -302,7 +304,7 @@ ShowAppListAndWaitForZeroStateResults( {ash::AppListSearchResultType::kZeroStateHelpApp, - ash::AppListSearchResultType::kInstalledApp}); + ash::AppListSearchResultType::kZeroStateApp}); auto* result = FindResult(web_app::kHelpAppId); ASSERT_TRUE(result); @@ -319,7 +321,7 @@ ShowAppListAndWaitForZeroStateResults( {ash::AppListSearchResultType::kZeroStateHelpApp, - ash::AppListSearchResultType::kInstalledApp}); + ash::AppListSearchResultType::kZeroStateApp}); auto* result = FindResult(web_app::kHelpAppId); ASSERT_TRUE(result);
diff --git a/chrome/browser/ui/app_list/search/help_app_zero_state_provider.cc b/chrome/browser/ui/app_list/search/help_app_zero_state_provider.cc index dda0a297..4b7729bd 100644 --- a/chrome/browser/ui/app_list/search/help_app_zero_state_provider.cc +++ b/chrome/browser/ui/app_list/search/help_app_zero_state_provider.cc
@@ -192,10 +192,6 @@ return ash::AppListSearchResultType::kZeroStateHelpApp; } -bool HelpAppZeroStateProvider::ShouldBlockZeroState() const { - return true; -} - void HelpAppZeroStateProvider::OnAppUpdate(const apps::AppUpdate& update) { if (update.AppId() == web_app::kHelpAppId && update.ReadinessChanged() && update.Readiness() == apps::Readiness::kReady) {
diff --git a/chrome/browser/ui/app_list/search/help_app_zero_state_provider.h b/chrome/browser/ui/app_list/search/help_app_zero_state_provider.h index 3ec615d..de2a9fa 100644 --- a/chrome/browser/ui/app_list/search/help_app_zero_state_provider.h +++ b/chrome/browser/ui/app_list/search/help_app_zero_state_provider.h
@@ -61,7 +61,6 @@ // SearchProvider: void StartZeroState() override; ash::AppListSearchResultType ResultType() const override; - bool ShouldBlockZeroState() const override; // apps::AppRegistryCache::Observer: void OnAppUpdate(const apps::AppUpdate& update) override;
diff --git a/chrome/browser/ui/app_list/search/ranking/best_match_ranker.cc b/chrome/browser/ui/app_list/search/ranking/best_match_ranker.cc index 38e23b2a..6d7c4aaf 100644 --- a/chrome/browser/ui/app_list/search/ranking/best_match_ranker.cc +++ b/chrome/browser/ui/app_list/search/ranking/best_match_ranker.cc
@@ -22,6 +22,7 @@ bool ShouldIgnoreProvider(ProviderType type) { switch (type) { // Continue providers: + case ProviderType::kZeroStateApp: case ProviderType::kZeroStateFile: case ProviderType::kZeroStateDrive: // Low-intent providers:
diff --git a/chrome/browser/ui/app_list/search/ranking/ranking_item_util.cc b/chrome/browser/ui/app_list/search/ranking/ranking_item_util.cc index e16a3b8..c224fb3e 100644 --- a/chrome/browser/ui/app_list/search/ranking/ranking_item_util.cc +++ b/chrome/browser/ui/app_list/search/ranking/ranking_item_util.cc
@@ -18,6 +18,7 @@ const ChromeSearchResult& result) { switch (result.result_type()) { case ash::AppListSearchResultType::kInstalledApp: + case ash::AppListSearchResultType::kZeroStateApp: case ash::AppListSearchResultType::kInternalApp: case ash::AppListSearchResultType::kGames: return RankingItemType::kApp;
diff --git a/chrome/browser/ui/app_list/search/ranking/util.cc b/chrome/browser/ui/app_list/search/ranking/util.cc index 5c96310c..7c4d4701 100644 --- a/chrome/browser/ui/app_list/search/ranking/util.cc +++ b/chrome/browser/ui/app_list/search/ranking/util.cc
@@ -32,6 +32,7 @@ Category ResultTypeToCategory(ResultType result_type) { switch (result_type) { case ResultType::kInstalledApp: + case ResultType::kZeroStateApp: case ResultType::kInstantApp: case ResultType::kInternalApp: case ResultType::kGames:
diff --git a/chrome/browser/ui/app_list/search/search_controller.h b/chrome/browser/ui/app_list/search/search_controller.h index 02ad31d9..c901473 100644 --- a/chrome/browser/ui/app_list/search/search_controller.h +++ b/chrome/browser/ui/app_list/search/search_controller.h
@@ -32,6 +32,7 @@ namespace app_list { +class AppSearchDataSource; class SearchProvider; enum class RankingItemType; @@ -79,6 +80,10 @@ virtual void InvokeResultAction(ChromeSearchResult* result, ash::SearchResultActionType action) = 0; + // Returns AppSearchDataSource instance that should be used with app search + // providers. + virtual AppSearchDataSource* GetAppSearchDataSource() = 0; + // Adds a new mixer group. See Mixer::AddGroup. virtual size_t AddGroup(size_t max_results) = 0;
diff --git a/chrome/browser/ui/app_list/search/search_controller_factory.cc b/chrome/browser/ui/app_list/search/search_controller_factory.cc index 7bd9555..4da8ec7e 100644 --- a/chrome/browser/ui/app_list/search/search_controller_factory.cc +++ b/chrome/browser/ui/app_list/search/search_controller_factory.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_utils.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/search/app_search_provider.h" +#include "chrome/browser/ui/app_list/search/app_zero_state_provider.h" #include "chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.h" #include "chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.h" #include "chrome/browser/ui/app_list/search/assistant_text_search_provider.h" @@ -99,10 +100,12 @@ ash::SharedAppListConfig::instance().max_search_result_list_items()); // Add search providers. + controller->AddProvider(apps_group_id, + std::make_unique<AppSearchProvider>( + controller->GetAppSearchDataSource())); controller->AddProvider( - apps_group_id, std::make_unique<AppSearchProvider>( - profile, list_controller, - base::DefaultClock::GetInstance(), model_updater)); + apps_group_id, std::make_unique<AppZeroStateProvider>( + controller->GetAppSearchDataSource(), model_updater)); if (crosapi::browser_util::IsLacrosEnabled()) { controller->AddProvider(
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl.cc b/chrome/browser/ui/app_list/search/search_controller_impl.cc index 0f6a5519d..a1a2f25 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl.cc +++ b/chrome/browser/ui/app_list/search/search_controller_impl.cc
@@ -16,10 +16,12 @@ #include "base/metrics/metrics_hashes.h" #include "base/strings/strcat.h" #include "base/strings/utf_string_conversions.h" +#include "base/time/default_clock.h" #include "base/time/time.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" #include "chrome/browser/ui/app_list/app_list_model_updater.h" +#include "chrome/browser/ui/app_list/search/app_search_data_source.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/common/string_util.h" #include "chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder.h" @@ -41,6 +43,10 @@ mixer_(std::make_unique<Mixer>(model_updater, this)), metrics_observer_( std::make_unique<SearchMetricsManager>(profile, notifier)), + app_search_data_source_(std::make_unique<AppSearchDataSource>( + profile, + list_controller, + base::DefaultClock::GetInstance())), list_controller_(list_controller), notifier_(notifier) { if (notifier_) @@ -117,6 +123,10 @@ result->InvokeAction(action); } +AppSearchDataSource* SearchControllerImpl::GetAppSearchDataSource() { + return app_search_data_source_.get(); +} + size_t SearchControllerImpl::AddGroup(size_t max_results) { return mixer_->AddGroup(max_results); }
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl.h b/chrome/browser/ui/app_list/search/search_controller_impl.h index 701540d..1e0b82d 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl.h +++ b/chrome/browser/ui/app_list/search/search_controller_impl.h
@@ -62,6 +62,7 @@ void OpenResult(ChromeSearchResult* result, int event_flags) override; void InvokeResultAction(ChromeSearchResult* result, ash::SearchResultActionType action) override; + AppSearchDataSource* GetAppSearchDataSource() override; size_t AddGroup(size_t max_results) override; void AddProvider(size_t group_id, std::unique_ptr<SearchProvider> provider) override; @@ -112,6 +113,7 @@ std::unique_ptr<Mixer> mixer_; std::unique_ptr<SearchMetricsManager> metrics_observer_; + std::unique_ptr<AppSearchDataSource> app_search_data_source_; using Providers = std::vector<std::unique_ptr<SearchProvider>>; Providers providers_; AppListControllerDelegate* list_controller_;
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl_new.cc b/chrome/browser/ui/app_list/search/search_controller_impl_new.cc index d44e1a8..23364f2f4 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl_new.cc +++ b/chrome/browser/ui/app_list/search/search_controller_impl_new.cc
@@ -15,10 +15,12 @@ #include "base/metrics/metrics_hashes.h" #include "base/strings/strcat.h" #include "base/strings/utf_string_conversions.h" +#include "base/time/default_clock.h" #include "base/time/time.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" #include "chrome/browser/ui/app_list/app_list_model_updater.h" +#include "chrome/browser/ui/app_list/search/app_search_data_source.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/common/string_util.h" #include "chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder.h" @@ -34,9 +36,9 @@ namespace app_list { namespace { -void ClearAllResultsExceptContinue(ResultsMap& results) { +void ClearNonZeroStateResults(ResultsMap& results) { for (auto it = results.begin(); it != results.end();) { - if (!ash::IsContinueSectionResultType(it->first)) { + if (!ash::IsZeroStateResultType(it->first)) { it = results.erase(it); } else { ++it; @@ -58,6 +60,10 @@ ranker_(std::make_unique<RankerDelegate>(profile, this)), metrics_manager_( std::make_unique<SearchMetricsManager>(profile, notifier)), + app_search_data_source_(std::make_unique<AppSearchDataSource>( + profile, + list_controller, + base::DefaultClock::GetInstance())), model_updater_(model_updater), list_controller_(list_controller) {} @@ -85,7 +91,7 @@ // // b) were in search query: do not publish these changes, so that the // old results stay on screen until the new ones are ready. - ClearAllResultsExceptContinue(results_); + ClearNonZeroStateResults(results_); if (last_query_.empty()) Publish(); @@ -189,6 +195,10 @@ } } +AppSearchDataSource* SearchControllerImplNew::GetAppSearchDataSource() { + return app_search_data_source_.get(); +} + size_t SearchControllerImplNew::AddGroup(size_t max_results) { // Unused. return 0ul; @@ -197,7 +207,7 @@ void SearchControllerImplNew::AddProvider( size_t group_id, std::unique_ptr<SearchProvider> provider) { - if (provider->ShouldBlockZeroState()) + if (ash::IsZeroStateResultType(provider->ResultType())) ++total_zero_state_blockers_; provider->set_controller(this); provider->set_result_changed_callback( @@ -240,7 +250,7 @@ const SearchProvider* provider) { Rank(provider->ResultType()); - if (provider->ShouldBlockZeroState()) + if (ash::IsZeroStateResultType(provider->ResultType())) ++returned_zero_state_blockers_; if (!on_zero_state_done_) {
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl_new.h b/chrome/browser/ui/app_list/search/search_controller_impl_new.h index 21f964dec..a5ce38c 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl_new.h +++ b/chrome/browser/ui/app_list/search/search_controller_impl_new.h
@@ -62,6 +62,7 @@ void OpenResult(ChromeSearchResult* result, int event_flags) override; void InvokeResultAction(ChromeSearchResult* result, ash::SearchResultActionType action) override; + AppSearchDataSource* GetAppSearchDataSource() override; size_t AddGroup(size_t max_results) override; void AddProvider(size_t group_id, std::unique_ptr<SearchProvider> provider) override; @@ -145,6 +146,7 @@ ResultsChangedCallback results_changed_callback_; std::unique_ptr<SearchMetricsManager> metrics_manager_; + std::unique_ptr<AppSearchDataSource> app_search_data_source_; using Providers = std::vector<std::unique_ptr<SearchProvider>>; Providers providers_; AppListModelUpdater* const model_updater_;
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl_new_unittest.cc b/chrome/browser/ui/app_list/search/search_controller_impl_new_unittest.cc index d1d7cad7..2b1db0fe 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl_new_unittest.cc +++ b/chrome/browser/ui/app_list/search/search_controller_impl_new_unittest.cc
@@ -40,11 +40,8 @@ class TestSearchProvider : public SearchProvider { public: TestSearchProvider(ash::AppListSearchResultType result_type, - bool block_zero_state, base::TimeDelta delay) - : result_type_(result_type), - block_zero_state_(block_zero_state), - delay_(delay) {} + : result_type_(result_type), delay_(delay) {} ~TestSearchProvider() override = default; @@ -53,8 +50,6 @@ results_ = std::move(results); } - bool ShouldBlockZeroState() const override { return block_zero_state_; } - ash::AppListSearchResultType ResultType() const override { return result_type_; } @@ -78,7 +73,6 @@ std::vector<std::unique_ptr<ChromeSearchResult>> results_; ash::AppListSearchResultType result_type_; - bool block_zero_state_; base::TimeDelta delay_; }; @@ -142,8 +136,8 @@ // SimpleProvider. static std::unique_ptr<SearchProvider> kProvider; SearchProvider* SimpleProvider(ash::AppListSearchResultType result_type) { - kProvider = std::make_unique<TestSearchProvider>(result_type, false, - base::Seconds(0)); + kProvider = + std::make_unique<TestSearchProvider>(result_type, base::Seconds(0)); return kProvider.get(); } @@ -592,7 +586,7 @@ ranker_delegate_->SetCategoryRanks({{Category::kApps, 0.1}}); auto provider = std::make_unique<TestSearchProvider>(Result::kInstalledApp, - false, base::Seconds(1)); + base::Seconds(1)); auto* provider_ptr = provider.get(); search_controller_->AddProvider(0, std::move(provider)); @@ -626,16 +620,16 @@ TEST_F(SearchControllerImplNewTest, ZeroStateResultsAreBlocked) { ranker_delegate_->SetCategoryRanks({{Category::kApps, 0.1}}); - // Set up four providers, two are zero-state blocking. One is slow. The - // particular result types and categories don't matter. - auto provider_a = std::make_unique<TestSearchProvider>( - Result::kInstalledApp, true, base::Seconds(1)); - auto provider_b = std::make_unique<TestSearchProvider>( - Result::kZeroStateFile, true, base::Seconds(2)); - auto provider_c = std::make_unique<TestSearchProvider>( - Result::kOsSettings, false, base::Seconds(1)); - auto provider_d = std::make_unique<TestSearchProvider>( - Result::kOmnibox, false, base::Seconds(4)); + // Set up four providers, two provide zero-state results. One is slow. The + // particular result categories don't matter. + auto provider_a = std::make_unique<TestSearchProvider>(Result::kZeroStateApp, + base::Seconds(1)); + auto provider_b = std::make_unique<TestSearchProvider>(Result::kZeroStateFile, + base::Seconds(2)); + auto provider_c = std::make_unique<TestSearchProvider>(Result::kOsSettings, + base::Seconds(1)); + auto provider_d = + std::make_unique<TestSearchProvider>(Result::kOmnibox, base::Seconds(4)); provider_a->SetNextResults( MakeResults({"a"}, {Category::kApps}, {-1}, {0.3})); @@ -675,10 +669,10 @@ TEST_F(SearchControllerImplNewTest, ZeroStateResultsGetTimedOut) { ranker_delegate_->SetCategoryRanks({{Category::kApps, 0.1}}); - auto provider_a = std::make_unique<TestSearchProvider>( - Result::kInstalledApp, true, base::Seconds(1)); - auto provider_b = std::make_unique<TestSearchProvider>( - Result::kZeroStateFile, true, base::Seconds(3)); + auto provider_a = std::make_unique<TestSearchProvider>(Result::kZeroStateApp, + base::Seconds(1)); + auto provider_b = std::make_unique<TestSearchProvider>(Result::kZeroStateFile, + base::Seconds(3)); provider_a->SetNextResults( MakeResults({"a"}, {Category::kApps}, {-1}, {0.3})); @@ -711,9 +705,9 @@ std::make_unique<RankerDelegate>(&profile_, search_controller_.get())); auto drive_provider = std::make_unique<TestSearchProvider>( - Result::kZeroStateDrive, true, base::Seconds(0)); + Result::kZeroStateDrive, base::Seconds(0)); auto local_provider = std::make_unique<TestSearchProvider>( - Result::kZeroStateFile, true, base::Seconds(0)); + Result::kZeroStateFile, base::Seconds(0)); drive_provider->SetNextResults(MakeResults( {"drive_a", "drive_b"}, {Category::kUnknown, Category::kUnknown},
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl_unittest.cc b/chrome/browser/ui/app_list/search/search_controller_impl_unittest.cc index 15151b2..8f1413c 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl_unittest.cc +++ b/chrome/browser/ui/app_list/search/search_controller_impl_unittest.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/ui/app_list/search/test/ranking_test_util.h" #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h" #include "chrome/test/base/chrome_ash_test_base.h" +#include "chrome/test/base/testing_profile.h" namespace app_list::test { @@ -36,14 +37,15 @@ void SetUp() override { ChromeAshTestBase::SetUp(); search_controller_ = std::make_unique<SearchControllerImpl>( - /*model_updater=*/nullptr, &list_controller_, /*profile=*/nullptr, - /*notifier=*/nullptr); + /*model_updater=*/nullptr, &list_controller_, + /*notifier=*/nullptr, &profile_); } SearchController& search_controller() { return *search_controller_; } TestAppListControllerDelegate& list_controller() { return list_controller_; } private: base::test::ScopedFeatureList scoped_feature_list_; + TestingProfile profile_; TestAppListControllerDelegate list_controller_; std::unique_ptr<SearchControllerImpl> search_controller_; };
diff --git a/chrome/browser/ui/app_list/search/search_provider.cc b/chrome/browser/ui/app_list/search/search_provider.cc index e8d2b7fa..caeffb60 100644 --- a/chrome/browser/ui/app_list/search/search_provider.cc +++ b/chrome/browser/ui/app_list/search/search_provider.cc
@@ -40,8 +40,4 @@ result_changed_callback_.Run(); } -bool SearchProvider::ShouldBlockZeroState() const { - return false; -} - } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/search_provider.h b/chrome/browser/ui/app_list/search/search_provider.h index 49ec4eb..d80d01b0 100644 --- a/chrome/browser/ui/app_list/search/search_provider.h +++ b/chrome/browser/ui/app_list/search/search_provider.h
@@ -45,11 +45,6 @@ // Returns the main result type created by this provider. virtual ash::AppListSearchResultType ResultType() const = 0; - // Returns true if this provider should prevent zero-state results from being - // published until it has returned. If this is true, a provider should only - // return results once per call to StartZeroState. - virtual bool ShouldBlockZeroState() const; - void set_controller(SearchController* controller) { search_controller_ = controller; }
diff --git a/chrome/browser/ui/app_list/search/test/test_continue_files_search_provider.cc b/chrome/browser/ui/app_list/search/test/test_continue_files_search_provider.cc index bef79be..cb0f7fb 100644 --- a/chrome/browser/ui/app_list/search/test/test_continue_files_search_provider.cc +++ b/chrome/browser/ui/app_list/search/test/test_continue_files_search_provider.cc
@@ -67,8 +67,4 @@ return ResultType::kUnknown; } -bool TestContinueFilesSearchProvider::ShouldBlockZeroState() const { - return true; -} - } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/test/test_continue_files_search_provider.h b/chrome/browser/ui/app_list/search/test/test_continue_files_search_provider.h index 0187ca9..9a7b612 100644 --- a/chrome/browser/ui/app_list/search/test/test_continue_files_search_provider.h +++ b/chrome/browser/ui/app_list/search/test/test_continue_files_search_provider.h
@@ -26,7 +26,6 @@ // SearchProvider overrides: void StartZeroState() override; ash::AppListSearchResultType ResultType() const override; - bool ShouldBlockZeroState() const override; void set_count(size_t count) { count_ = count; }
diff --git a/chrome/browser/ui/app_list/search/test/test_search_controller.cc b/chrome/browser/ui/app_list/search/test/test_search_controller.cc index 295f892..daaac6e6 100644 --- a/chrome/browser/ui/app_list/search/test/test_search_controller.cc +++ b/chrome/browser/ui/app_list/search/test/test_search_controller.cc
@@ -17,9 +17,8 @@ // The search controller used when categorical search is enabled clears all // results when starging another search query - simulate this behavior in // tests when categorical search is enabled. - if (!ash::IsContinueSectionResultType(provider_->ResultType())) { + if (!ash::IsZeroStateResultType(provider_->ResultType())) last_results_.clear(); - } provider_->Start(query); } @@ -38,6 +37,10 @@ ChromeSearchResult* result, ash::SearchResultActionType action) {} +AppSearchDataSource* TestSearchController::GetAppSearchDataSource() { + return nullptr; +} + size_t TestSearchController::AddGroup(size_t max_results) { return 0u; }
diff --git a/chrome/browser/ui/app_list/search/test/test_search_controller.h b/chrome/browser/ui/app_list/search/test/test_search_controller.h index 7214634..fd6c4da 100644 --- a/chrome/browser/ui/app_list/search/test/test_search_controller.h +++ b/chrome/browser/ui/app_list/search/test/test_search_controller.h
@@ -12,6 +12,7 @@ namespace app_list { +class AppSearchDataSource; class SearchProvider; class TestSearchController : public SearchController { @@ -32,6 +33,7 @@ void OpenResult(ChromeSearchResult* result, int event_flags) override; void InvokeResultAction(ChromeSearchResult* result, ash::SearchResultActionType action) override; + AppSearchDataSource* GetAppSearchDataSource() override; size_t AddGroup(size_t max_results) override; void AddProvider(size_t group_id, std::unique_ptr<SearchProvider> provider) override;
diff --git a/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.cc b/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.cc index 61b37844..2a61470 100644 --- a/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.cc +++ b/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.cc
@@ -33,17 +33,11 @@ #endif // BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_MAC) -#include "chrome/browser/external_protocol/external_protocol_handler.h" +#include "base/mac/mac_util.h" #endif namespace { -#if BUILDFLAG(IS_MAC) -static constexpr char kBluetoothSettingsUri[] = - "x-apple.systempreferences:com.apple.preference.security?Privacy_" - "Bluetooth"; -#endif - Browser* GetBrowser() { chrome::ScopedTabbedBrowserDisplayer browser_displayer( ProfileManager::GetLastUsedProfileAllowedByPolicy()); @@ -62,10 +56,7 @@ CreateExtensionAwareChooserTitle( owner, IDS_BLUETOOTH_DEVICE_CHOOSER_PROMPT_ORIGIN, - IDS_BLUETOOTH_DEVICE_CHOOSER_PROMPT_EXTENSION_NAME)) { - web_contents_ = - content::WebContents::FromRenderFrameHost(owner)->GetWeakPtr(); -} + IDS_BLUETOOTH_DEVICE_CHOOSER_PROMPT_EXTENSION_NAME)) {} ChromeBluetoothChooserController::~ChromeBluetoothChooserController() = default; @@ -86,11 +77,8 @@ void ChromeBluetoothChooserController::OpenPermissionPreferences() const { #if BUILDFLAG(IS_MAC) - if (web_contents_) { - ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck( - GURL(kBluetoothSettingsUri), web_contents_.get(), - content::WeakDocumentPtr()); - } + base::mac::OpenSystemSettingsPane( + base::mac::SystemSettingsPane::kPrivacySecurity_Bluetooth); #else NOTREACHED(); #endif
diff --git a/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.h b/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.h index abb7657..8910a1e 100644 --- a/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.h +++ b/chrome/browser/ui/bluetooth/chrome_bluetooth_chooser_controller.h
@@ -5,13 +5,11 @@ #ifndef CHROME_BROWSER_UI_BLUETOOTH_CHROME_BLUETOOTH_CHOOSER_CONTROLLER_H_ #define CHROME_BROWSER_UI_BLUETOOTH_CHROME_BLUETOOTH_CHOOSER_CONTROLLER_H_ -#include "base/memory/weak_ptr.h" #include "components/permissions/bluetooth_chooser_controller.h" #include "content/public/browser/bluetooth_chooser.h" namespace content { class RenderFrameHost; -class WebContents; } // namespace content // The concrete version of BluetoothChooserController for Chrome. @@ -37,9 +35,6 @@ // Opens the help center URL. void OpenHelpCenterUrl() const override; - - private: - base::WeakPtr<content::WebContents> web_contents_; }; #endif // CHROME_BROWSER_UI_BLUETOOTH_CHROME_BLUETOOTH_CHOOSER_CONTROLLER_H_
diff --git a/chrome/browser/ui/cocoa/share_menu_controller.mm b/chrome/browser/ui/cocoa/share_menu_controller.mm index 3ae1cddc..3d7c42c 100644 --- a/chrome/browser/ui/cocoa/share_menu_controller.mm +++ b/chrome/browser/ui/cocoa/share_menu_controller.mm
@@ -35,15 +35,6 @@ namespace { -NSString* const kExtensionPrefPanePath = - @"/System/Library/PreferencePanes/Extensions.prefPane"; -// Undocumented, used by Safari. -const UInt32 kOpenSharingSubpaneDescriptorType = 'ptru'; -NSString* const kOpenSharingSubpaneActionKey = @"action"; -NSString* const kOpenSharingSubpaneActionValue = @"revealExtensionPoint"; -NSString* const kOpenSharingSubpaneProtocolKey = @"protocol"; -NSString* const kOpenSharingSubpaneProtocolValue = @"com.apple.share-services"; - // The reminder service doesn't have a convenient NSSharingServiceName* // constant. NSString* const kRemindersSharingServiceName = @@ -225,26 +216,8 @@ // Opens the "Sharing" subpane of the "Extensions" macOS preference pane. - (void)openSharingPrefs:(NSMenuItem*)sender { - NSURL* prefPaneURL = - [NSURL fileURLWithPath:kExtensionPrefPanePath isDirectory:YES]; - NSDictionary* args = @{ - kOpenSharingSubpaneActionKey : kOpenSharingSubpaneActionValue, - kOpenSharingSubpaneProtocolKey : kOpenSharingSubpaneProtocolValue - }; - NSData* data = [NSPropertyListSerialization - dataWithPropertyList:args - format:NSPropertyListXMLFormat_v1_0 - options:0 - error:nil]; - base::scoped_nsobject<NSAppleEventDescriptor> descriptor( - [[NSAppleEventDescriptor alloc] - initWithDescriptorType:kOpenSharingSubpaneDescriptorType - data:data]); - [[NSWorkspace sharedWorkspace] openURLs:@[ prefPaneURL ] - withAppBundleIdentifier:nil - options:NSWorkspaceLaunchAsync - additionalEventParamDescriptor:descriptor - launchIdentifiers:NULL]; + base::mac::OpenSystemSettingsPane( + base::mac::SystemSettingsPane::kPrivacySecurity_Extensions_Sharing); } // Returns the image to be used for the "More..." menu item, or nil on macOS
diff --git a/chrome/browser/ui/color/chrome_color_id.h b/chrome/browser/ui/color/chrome_color_id.h index f0a131bc..2291934 100644 --- a/chrome/browser/ui/color/chrome_color_id.h +++ b/chrome/browser/ui/color/chrome_color_id.h
@@ -111,6 +111,7 @@ E_CPONLY(kColorInfoBarButtonIconDisabled) \ E_CPONLY(kColorInfoBarContentAreaSeparator) \ E_CPONLY(kColorInfoBarForeground) \ + /* There is also a kColorInfoBarIcon in /ui/color/color_id.h */ \ /* Intent Picker colors. */ \ E_CPONLY(kColorIntentPickerItemBackgroundHovered) \ E_CPONLY(kColorIntentPickerItemBackgroundSelected) \
diff --git a/chrome/browser/ui/color/chrome_color_mixer.cc b/chrome/browser/ui/color/chrome_color_mixer.cc index 90bb2d9..bec439e 100644 --- a/chrome/browser/ui/color/chrome_color_mixer.cc +++ b/chrome/browser/ui/color/chrome_color_mixer.cc
@@ -284,6 +284,12 @@ mixer[kColorInfoBarContentAreaSeparator] = ui::AlphaBlend(kColorToolbarButtonIcon, kColorInfoBarBackground, 0x3A); mixer[kColorInfoBarForeground] = {kColorToolbarText}; + // kColorInfoBarIcon is referenced in //components/infobars, so + // we can't use a color id from the chrome namespace. Here we're + // overriding the default color with something more suitable. + mixer[ui::kColorInfoBarIcon] = + ui::PickGoogleColor(ui::kColorAccent, kColorInfoBarBackground, + color_utils::kMinimumVisibleContrastRatio); mixer[kColorIntentPickerItemBackgroundHovered] = ui::SetAlpha( ui::GetColorWithMaxContrast(ui::kColorDialogBackground), 0x0F); // 6%. mixer[kColorIntentPickerItemBackgroundSelected] = ui::BlendForMinContrast(
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc index 41c9e1b..12a898f 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -25,7 +25,6 @@ #include "chrome/browser/content_settings/page_specific_content_settings_delegate.h" #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" #include "chrome/browser/download/download_request_limiter.h" -#include "chrome/browser/external_protocol/external_protocol_handler.h" #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" #include "chrome/browser/media/webrtc/permission_bubble_media_access_handler.h" #include "chrome/browser/permissions/permission_decision_auto_blocker_factory.h" @@ -86,6 +85,7 @@ #include "ui/resources/grit/ui_resources.h" #if BUILDFLAG(IS_MAC) +#include "base/mac/mac_util.h" #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/media/webrtc/system_media_capture_permissions_mac.h" #include "services/device/public/cpp/geolocation/geolocation_manager.h" @@ -105,18 +105,6 @@ using QuietUiReason = permissions::PermissionRequestManager::QuietUiReason; -#if BUILDFLAG(IS_MAC) -static constexpr char kCameraSettingsURI[] = - "x-apple.systempreferences:com.apple.preference.security?Privacy_" - "Camera"; -static constexpr char kMicSettingsURI[] = - "x-apple.systempreferences:com.apple.preference.security?Privacy_" - "Microphone"; -static constexpr char kLocationSettingsURI[] = - "x-apple.systempreferences:com.apple.preference.security?Privacy_" - "LocationServices"; -#endif // BUILDFLAG(IS_MAC) - // Returns a boolean indicating whether the setting should be managed by the // user (i.e. it is not controlled by policy). Also takes a (nullable) out-param // which is populated by the actual setting for the given URL. @@ -905,11 +893,11 @@ DCHECK(ShouldShowSystemMediaPermissions()); if (CameraAccessed()) { - ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck( - GURL(kCameraSettingsURI), web_contents(), content::WeakDocumentPtr()); + base::mac::OpenSystemSettingsPane( + base::mac::SystemSettingsPane::kPrivacySecurity_Camera); } else if (MicrophoneAccessed()) { - ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck( - GURL(kMicSettingsURI), web_contents(), content::WeakDocumentPtr()); + base::mac::OpenSystemSettingsPane( + base::mac::SystemSettingsPane::kPrivacySecurity_Microphone); } return; #endif // BUILDFLAG(IS_MAC) @@ -1286,8 +1274,8 @@ "ContentSettings.GeolocationDialog.OpenPreferencesClicked")); } - ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck( - GURL(kLocationSettingsURI), web_contents(), content::WeakDocumentPtr()); + base::mac::OpenSystemSettingsPane( + base::mac::SystemSettingsPane::kPrivacySecurity_LocationServices); return; #endif // BUILDFLAG(IS_MAC) }
diff --git a/chrome/browser/ui/views/exclusive_access_bubble_views.cc b/chrome/browser/ui/views/exclusive_access_bubble_views.cc index 8a040ab..fc5557e3 100644 --- a/chrome/browser/ui/views/exclusive_access_bubble_views.cc +++ b/chrome/browser/ui/views/exclusive_access_bubble_views.cc
@@ -221,13 +221,13 @@ accelerator = browser_fullscreen_exit_accelerator_; } else { accelerator = l10n_util::GetStringUTF16(IDS_APP_ESC_KEY); - } #if BUILDFLAG(IS_MAC) - // Mac keyboards use lowercase for everything except function keys, which are - // typically reserved for system use. Since |accelerator| is placed in a box - // to make it look like a keyboard key it looks weird to not follow suit. - accelerator = base::i18n::ToLower(accelerator); + // Mac keyboards use lowercase for the non-letter keys, and since the key is + // placed in a box to make it look like a keyboard key it looks weird to not + // follow suit. + accelerator = base::i18n::ToLower(accelerator); #endif + } view_->UpdateContent(GetInstructionText(accelerator)); }
diff --git a/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc b/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc index 015329b..284c21c 100644 --- a/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc +++ b/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc
@@ -215,7 +215,11 @@ "chrome://connection-help", "chrome://connection-monitoring-detected", "chrome://crashes", +#if !((BUILDFLAG(IS_LINUX) && !defined(NDEBUG)) || defined(ADDRESS_SANITIZER)) + // TODO(crbug.com/1380393): Failing on Linux debug builder and ASan (time + // out). "chrome://credits", +#endif "chrome://device-log", "chrome://dino", // TODO(crbug.com/1113446): Test failure due to excessive output.
diff --git a/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.cc b/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.cc index e8da4947..5d7788f8 100644 --- a/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.cc +++ b/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.cc
@@ -173,6 +173,7 @@ local_printer_->GetCapability( device_name, base::BindOnce(CapabilityToValue).Then(std::move(callback))); } + void LocalPrinterHandlerChromeos::StartPrint( const std::u16string& job_title, base::Value::Dict settings, @@ -215,6 +216,48 @@ settings.Set(kSettingUsername, *username); settings.Set(kSettingSendUserInfo, true); } + + const std::string* const printer_id = settings.FindString(kSettingDeviceName); + crosapi::mojom::LocalPrinter::GetOAuthAccessTokenCallback cb = + base::BindOnce(&LocalPrinterHandlerChromeos::OnOAuthTokenReady, + weak_ptr_factory_.GetWeakPtr(), std::move(settings), + std::move(print_data), std::move(callback)); + + if (!local_printer_) { + LOG(ERROR) << "Local printer not available"; + std::move(cb).Run(crosapi::mojom::GetOAuthAccessTokenResult::NewError( + crosapi::mojom::OAuthError::New())); + return; + } + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + if (local_printer_version_ < + int{crosapi::mojom::LocalPrinter::MethodMinVersions:: + kGetOAuthAccessTokenMinVersion}) { + LOG(WARNING) << "Ash LocalPrinter version " << local_printer_version_ + << " does not support GetOAuthToken()."; + std::move(cb).Run(crosapi::mojom::GetOAuthAccessTokenResult::NewNone( + crosapi::mojom::OAuthNotNeeded::New())); + return; + } +#endif + + local_printer_->GetOAuthAccessToken(printer_id ? *printer_id : "", + std::move(cb)); +} + +void LocalPrinterHandlerChromeos::OnOAuthTokenReady( + base::Value::Dict settings, + scoped_refptr<base::RefCountedMemory> print_data, + PrinterHandler::PrintCallback callback, + crosapi::mojom::GetOAuthAccessTokenResultPtr oauth_result) { + if (oauth_result->is_token()) { + settings.Set(kSettingChromeOSAccessOAuthToken, + oauth_result->get_token()->token); + } else if (oauth_result->is_error()) { + LOG(ERROR) << "Error when obtaining an oauth token for a local printer"; + } + StartLocalPrint(std::move(settings), std::move(print_data), preview_web_contents_, std::move(callback)); }
diff --git a/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.h b/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.h index b2b92284..14b173e 100644 --- a/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.h +++ b/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.h
@@ -84,6 +84,11 @@ scoped_refptr<base::RefCountedMemory> print_data, PrinterHandler::PrintCallback callback, const absl::optional<std::string>& username); + void OnOAuthTokenReady( + base::Value::Dict settings, + scoped_refptr<base::RefCountedMemory> print_data, + PrinterHandler::PrintCallback callback, + crosapi::mojom::GetOAuthAccessTokenResultPtr oauth_result); const raw_ptr<content::WebContents> preview_web_contents_; raw_ptr<crosapi::mojom::LocalPrinter> local_printer_ = nullptr;
diff --git a/chrome/browser/ui/webui/sandbox/sandbox_handler.cc b/chrome/browser/ui/webui/sandbox/sandbox_handler.cc index 16658a7..3a455ba 100644 --- a/chrome/browser/ui/webui/sandbox/sandbox_handler.cc +++ b/chrome/browser/ui/webui/sandbox/sandbox_handler.cc
@@ -89,8 +89,6 @@ FeatureToValue(sandbox::policy::features::kSharedSandboxPolicies)); features.Append(FeatureToValue( sandbox::policy::features::kWinSboxDisableExtensionPoints)); - features.Append( - FeatureToValue(sandbox::policy::features::kWinSboxDisableKtmComponent)); return features; }
diff --git a/chrome/browser/ui/webui/settings/settings_utils_mac.mm b/chrome/browser/ui/webui/settings/settings_utils_mac.mm index e94a2dd0..9feca41 100644 --- a/chrome/browser/ui/webui/settings/settings_utils_mac.mm +++ b/chrome/browser/ui/webui/settings/settings_utils_mac.mm
@@ -8,8 +8,7 @@ #include "base/logging.h" #include "base/mac/mac_logging.h" -#include "base/mac/scoped_aedesc.h" -#include "base/mac/scoped_nsautorelease_pool.h" +#include "base/mac/mac_util.h" #include "base/strings/sys_string_conversions.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" @@ -35,23 +34,8 @@ namespace settings_utils { void ShowNetworkProxySettings(content::WebContents* web_contents) { - NSArray* itemsToOpen = - @[ [NSURL fileURLWithPath:@"/System/Library/PreferencePanes/" - @"Network.prefPane"] ]; - - const char* proxyPrefCommand = "Proxies"; - base::mac::ScopedAEDesc<> openParams; - OSStatus status = - AECreateDesc('ptru', proxyPrefCommand, strlen(proxyPrefCommand), - openParams.OutPointer()); - OSSTATUS_LOG_IF(ERROR, status != noErr, status) - << "Failed to create open params"; - - LSLaunchURLSpec launchSpec = {0}; - launchSpec.itemURLs = (CFArrayRef)itemsToOpen; - launchSpec.passThruParams = openParams; - launchSpec.launchFlags = kLSLaunchAsync | kLSLaunchDontAddToRecents; - LSOpenFromURLSpec(&launchSpec, NULL); + base::mac::OpenSystemSettingsPane( + base::mac::SystemSettingsPane::kNetwork_Proxies); } void ShowManageSSLCertificates(content::WebContents* web_contents) {
diff --git a/chrome/browser/vr/elements/scaled_depth_adjuster.cc b/chrome/browser/vr/elements/scaled_depth_adjuster.cc index 63a315d..62587aa9 100644 --- a/chrome/browser/vr/elements/scaled_depth_adjuster.cc +++ b/chrome/browser/vr/elements/scaled_depth_adjuster.cc
@@ -36,10 +36,7 @@ inherited.PostConcat(anc->LocalTransform()); } } - bool success = inherited.GetInverse(&transform_); - DCHECK(success); - if (!success) - return false; + transform_ = inherited.GetCheckedInverse(); gfx::Point3F o = inherited.MapPoint(gfx::Point3F()); float z = -o.z() + delta_z_; transform_.Scale3d(z, z, z);
diff --git a/chrome/browser/vr/elements/viewport_aware_root.cc b/chrome/browser/vr/elements/viewport_aware_root.cc index afbbb38..e3ac459 100644 --- a/chrome/browser/vr/elements/viewport_aware_root.cc +++ b/chrome/browser/vr/elements/viewport_aware_root.cc
@@ -46,9 +46,8 @@ gfx::Vector3dF look_at = vr::GetForwardVector(head_pose); bool changed = AdjustRotationForHeadPose(look_at); if (recenter_on_rotate_) { - gfx::Transform world_from_head; - bool invertable = head_pose.GetInverse(&world_from_head); - DCHECK(invertable); // Pose data has been validated already. + // Pose data has been validated already. + gfx::Transform world_from_head = head_pose.GetCheckedInverse(); gfx::Point3F head_pos_in_world_space = world_from_head.MapPoint(gfx::Point3F()); changed = AdjustTranslation(head_pos_in_world_space.x(),
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.cc b/chrome/browser/webauthn/authenticator_request_dialog_model.cc index 56f6a33..7f11e64 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model.cc +++ b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
@@ -12,7 +12,6 @@ #include "base/feature_list.h" #include "base/metrics/histogram_functions.h" #include "base/observer_list.h" -#include "base/process/launch.h" #include "base/ranges/algorithm.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -358,13 +357,8 @@ #if BUILDFLAG(IS_MAC) void AuthenticatorRequestDialogModel::OpenBlePreferences() { DCHECK_EQ(current_step(), Step::kBlePermissionMac); - - base::LaunchOptions opts; - opts.disclaim_responsibility = true; - base::LaunchProcess({"open", - "x-apple.systempreferences:com.apple.preference." - "security?Privacy_Bluetooth"}, - opts); + base::mac::OpenSystemSettingsPane( + base::mac::SystemSettingsPane::kPrivacySecurity_Bluetooth); } #endif // IS_MAC
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 3e602ac..ec66532 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1667282374-24c862692204ee2c5deef0d32c07b005d8520e56.profdata +chrome-win32-main-1667314645-4ab448ff0ceee7e470574eb88603e0863606684e.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index e473bef..79a80f11 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1667217321-26e76a6404b888041e2dfe0b539b0d890b0820fc.profdata +chrome-win64-main-1667314645-d086e5bdb062721f30f0176adb953e61d398384e.profdata
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 1858b7d..d32d0c1 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -8553,6 +8553,7 @@ "../browser/browser_switcher/mock_alternative_browser_driver.cc", "../browser/browser_switcher/mock_alternative_browser_driver.h", "../browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service_unittest.cc", + "../browser/enterprise/idle/browser_closer_unittest.cc", "../browser/enterprise/remote_commands/rotate_attestation_credential_job_unittest.cc", "../browser/enterprise/signals/user_delegate_impl_unittest.cc", "../browser/net/disk_cache_dir_policy_handler_unittest.cc",
diff --git a/chrome/test/chromeos/printing/fake_local_printer_chromeos.cc b/chrome/test/chromeos/printing/fake_local_printer_chromeos.cc index f038bca..80fc6bb 100644 --- a/chrome/test/chromeos/printing/fake_local_printer_chromeos.cc +++ b/chrome/test/chromeos/printing/fake_local_printer_chromeos.cc
@@ -78,3 +78,9 @@ AddPrintJobObserverCallback callback) { FAIL(); } + +void FakeLocalPrinter::GetOAuthAccessToken( + const std::string& printer_id, + GetOAuthAccessTokenCallback callback) { + FAIL(); +}
diff --git a/chrome/test/chromeos/printing/fake_local_printer_chromeos.h b/chrome/test/chromeos/printing/fake_local_printer_chromeos.h index ff989ace..ef4acedf 100644 --- a/chrome/test/chromeos/printing/fake_local_printer_chromeos.h +++ b/chrome/test/chromeos/printing/fake_local_printer_chromeos.h
@@ -42,6 +42,8 @@ mojo::PendingRemote<crosapi::mojom::PrintJobObserver> remote, crosapi::mojom::PrintJobSource source, AddPrintJobObserverCallback callback) override; + void GetOAuthAccessToken(const std::string& printer_id, + GetOAuthAccessTokenCallback callback) override; }; #endif // CHROME_TEST_CHROMEOS_PRINTING_FAKE_LOCAL_PRINTER_CHROMEOS_H_
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts index 81cbfc7fe..26ceb3b 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts
@@ -266,4 +266,25 @@ 'none', getComputedStyle(querySelector('iron-icon')!).display, 'iron-icon is display none when aria selected is false'); }); + + test('sets aria-disabled attribute', async () => { + wallpaperGridItemElement = initElement(WallpaperGridItem); + await waitAfterNextRender(wallpaperGridItemElement); + + assertEquals( + 'false', wallpaperGridItemElement.getAttribute('aria-disabled'), + 'aria-disabled defaults to false'); + + wallpaperGridItemElement.disabled = true; + await waitAfterNextRender(wallpaperGridItemElement); + assertEquals( + 'true', wallpaperGridItemElement.getAttribute('aria-disabled'), + 'disabled sets aria-disabled attribute'); + + wallpaperGridItemElement.disabled = false; + await waitAfterNextRender(wallpaperGridItemElement); + assertEquals( + 'false', wallpaperGridItemElement.getAttribute('aria-disabled'), + 'disabled false sets aria-disabled attribute false'); + }); });
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_images_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_images_element_test.ts index 57bc393..4775dda 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_images_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_images_element_test.ts
@@ -6,7 +6,7 @@ import 'chrome://webui-test/mojo_webui_test_support.js'; import {OnlineImageType, PersonalizationRouter, WallpaperGridItem, WallpaperImages} from 'chrome://personalization/js/personalization_app.js'; -import {assertDeepEquals, assertEquals, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {assertDeepEquals, assertEquals} from 'chrome://webui-test/chai_assert.js'; import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; import {baseSetup, initElement, teardownElement} from './personalization_app_test_utils.js'; @@ -51,14 +51,15 @@ test('sets aria-selected for current wallpaper asset id', async () => { wallpaperImagesElement = await createWithDefaultData(); - const selectedElement: WallpaperGridItem = - wallpaperImagesElement.shadowRoot!.querySelector( - `${WallpaperGridItem.is}[aria-selected='true']`)!; + const selectedElements: WallpaperGridItem[] = + Array.from(wallpaperImagesElement.shadowRoot!.querySelectorAll( + `${WallpaperGridItem.is}[aria-selected='true']`)); - assertEquals( - selectedElement!.dataset['assetId'], - personalizationStore.data.wallpaper.currentSelected.key, - 'aria selected element has correct asset id'); + assertEquals(selectedElements.length, 1, '1 item aria selected'); + assertDeepEquals( + selectedElements[0]!.src, + [wallpaperProvider.images![2]!.url, wallpaperProvider.images![0]!.url], + `item has correct src`); const notSelectedElements: HTMLDivElement[] = Array.from(wallpaperImagesElement.shadowRoot!.querySelectorAll( @@ -70,17 +71,6 @@ assertEquals( uniqueUnitIds.size - 1, notSelectedElements.length, 'correct number of non-selected elements'); - - for (const notSelected of notSelectedElements) { - assertTrue( - notSelected.dataset['assetId']!.length > 0, - 'not selected elements have an assetId'); - - assertNotEquals( - wallpaperProvider.currentWallpaper.key, - notSelected.dataset['assetId'], - 'not selected elements have a different assetId'); - } }); test('displays images for current collectionId', async () => { @@ -127,25 +117,25 @@ await waitAfterNextRender(wallpaperImagesElement); assertDeepEquals( - ['1', '2'], + ['Image 0-1', 'Image 0-2'], Array .from(wallpaperImagesElement.shadowRoot! .querySelectorAll<WallpaperGridItem>( `${WallpaperGridItem.is}:not([hidden])`)) - .map(elem => elem.dataset['assetId']), - 'expected asset ids are displayed for collectionId `id_0`'); + .map(elem => elem.getAttribute('aria-label')), + 'expected aria labels are displayed for collectionId `id_0`'); wallpaperImagesElement.collectionId = 'id_1'; await waitAfterNextRender(wallpaperImagesElement); assertDeepEquals( - ['10', '20'], + ['Image 1-10', 'Image 1-20'], Array .from(wallpaperImagesElement.shadowRoot! .querySelectorAll<WallpaperGridItem>( `${WallpaperGridItem.is}:not([hidden])`)) - .map(elem => elem.dataset['assetId']), - 'expected asset ids are displayed for collectionId `id_1`'); + .map(elem => elem.getAttribute('aria-label')), + 'expected aria labels are displayed for collectionId `id_1`'); }); test('displays dark light tile for images with same unitId', async () => { @@ -179,9 +169,10 @@ test('selects an image when clicked', async () => { wallpaperImagesElement = await createWithDefaultData(); + // Click the first image that is not currently selected. wallpaperImagesElement.shadowRoot! .querySelector<WallpaperGridItem>( - `${WallpaperGridItem.is}[data-asset-id='2']`)!.click(); + `${WallpaperGridItem.is}[aria-selected='false']`)!.click(); const [assetId, previewMode] = await wallpaperProvider.whenCalled('selectWallpaper'); assertEquals(2n, assetId, 'correct asset id is passed');
diff --git a/chrome/test/data/webui/settings/chromeos/cursor_and_touchpad_page_tests.js b/chrome/test/data/webui/settings/chromeos/cursor_and_touchpad_page_tests.js new file mode 100644 index 0000000..7809c8ac --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/cursor_and_touchpad_page_tests.js
@@ -0,0 +1,253 @@ +// 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 'chrome://os-settings/chromeos/lazy_load.js'; + +import {DevicePageBrowserProxy, DevicePageBrowserProxyImpl, Router, routes} from 'chrome://os-settings/chromeos/os_settings.js'; +import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js'; +import {getDeepActiveElement} from 'chrome://resources/js/util.js'; +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {waitAfterNextRender, waitBeforeNextRender} from 'chrome://webui-test/polymer_test_util.js'; +import {eventToPromise, isVisible} from 'chrome://webui-test/test_util.js'; + +import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js'; + +suite('CursorAndTouchpadPageTests', function() { + let page = null; + let deviceBrowserProxy = null; + + /** @implements {DevicePageBrowserProxy} */ + class TestDevicePageBrowserProxy { + constructor() { + /** @private {boolean} */ + this.hasMouse_ = true; + /** @private {boolean} */ + this.hasTouchpad_ = true; + } + + /** @param {boolean} hasMouse */ + set hasMouse(hasMouse) { + this.hasMouse_ = hasMouse; + webUIListenerCallback('has-mouse-changed', this.hasMouse_); + } + + /** @param {boolean} hasTouchpad */ + set hasTouchpad(hasTouchpad) { + this.hasTouchpad_ = hasTouchpad; + webUIListenerCallback('has-touchpad-changed', this.hasTouchpad_); + } + + /** @override */ + initializePointers() { + webUIListenerCallback('has-mouse-changed', this.hasMouse_); + webUIListenerCallback('has-touchpad-changed', this.hasTouchpad_); + } + } + + function initPage(opt_prefs) { + page = document.createElement('settings-cursor-and-touchpad-page'); + page.prefs = opt_prefs || getDefaultPrefs(); + document.body.appendChild(page); + } + + function getDefaultPrefs() { + return { + 'settings': { + 'a11y': { + 'tablet_mode_shelf_nav_buttons_enabled': { + key: 'settings.a11y.tablet_mode_shelf_nav_buttons_enabled', + type: chrome.settingsPrivate.PrefType.BOOLEAN, + value: false, + }, + }, + 'accessibility': { + key: 'settings.accessibility', + type: chrome.settingsPrivate.PrefType.BOOLEAN, + value: false, + }, + }, + }; + } + + setup(function() { + deviceBrowserProxy = new TestDevicePageBrowserProxy(); + DevicePageBrowserProxyImpl.setInstanceForTesting(deviceBrowserProxy); + + PolymerTest.clearBody(); + Router.getInstance().navigateTo(routes.A11Y_CURSOR_AND_TOUCHPAD); + }); + + teardown(function() { + if (page) { + page.remove(); + } + Router.getInstance().resetRouteForTesting(); + }); + + test( + 'should focus pointerSubpageButton button when returning from Pointers subpage', + async () => { + const selector = '#pointerSubpageButton'; + const route = routes.POINTERS; + initPage(); + flush(); + const router = Router.getInstance(); + + const subpageButton = page.shadowRoot.querySelector(selector); + assertTrue(!!subpageButton); + + subpageButton.click(); + assertEquals(route, router.getCurrentRoute()); + assertNotEquals( + subpageButton, page.shadowRoot.activeElement, + `${selector} should not be focused`); + + const popStateEventPromise = eventToPromise('popstate', window); + router.navigateToPreviousRoute(); + await popStateEventPromise; + await waitBeforeNextRender(page); + + assertEquals(routes.A11Y_CURSOR_AND_TOUCHPAD, router.getCurrentRoute()); + assertEquals( + subpageButton, page.shadowRoot.activeElement, + `${selector} should be focused`); + }); + + test('Pointers row only visible if mouse/touchpad present', function() { + initPage(); + const row = page.shadowRoot.querySelector('#pointerSubpageButton'); + assertFalse(row.hidden); + + // Has touchpad, doesn't have mouse ==> not hidden. + deviceBrowserProxy.hasMouse = false; + assertFalse(row.hidden); + + // Doesn't have either ==> hidden. + deviceBrowserProxy.hasTouchpad = false; + assertTrue(row.hidden); + + // Has mouse, doesn't have touchpad ==> not hidden. + deviceBrowserProxy.hasMouse = true; + assertFalse(row.hidden); + + // Has both ==> not hidden. + deviceBrowserProxy.hasTouchpad = true; + assertFalse(row.hidden); + }); + + test('tablet mode buttons visible', function() { + loadTimeData.overrideValues({ + isKioskModeActive: false, + showTabletModeShelfNavigationButtonsSettings: true, + }); + initPage(); + flush(); + + assertTrue(isVisible(page.shadowRoot.querySelector( + '#shelfNavigationButtonsEnabledControl'))); + }); + + test('toggle tablet mode buttons', function() { + loadTimeData.overrideValues({ + isKioskModeActive: false, + showTabletModeShelfNavigationButtonsSettings: true, + }); + initPage(); + flush(); + + const navButtonsToggle = + page.shadowRoot.querySelector('#shelfNavigationButtonsEnabledControl'); + assertTrue(isVisible(navButtonsToggle)); + // The default pref value is false. + assertFalse(navButtonsToggle.checked); + + // Clicking the toggle should update the toggle checked value, and the + // backing preference. + navButtonsToggle.click(); + flush(); + + assertTrue(navButtonsToggle.checked); + assertFalse(navButtonsToggle.disabled); + assertTrue( + page.prefs.settings.a11y.tablet_mode_shelf_nav_buttons_enabled.value); + + navButtonsToggle.click(); + flush(); + + assertFalse(navButtonsToggle.checked); + assertFalse(navButtonsToggle.disabled); + assertFalse( + page.prefs.settings.a11y.tablet_mode_shelf_nav_buttons_enabled.value); + }); + + test('tablet mode buttons toggle disabled with spoken feedback', function() { + loadTimeData.overrideValues({ + isKioskModeActive: false, + showTabletModeShelfNavigationButtonsSettings: true, + }); + + const prefs = getDefaultPrefs(); + // Enable spoken feedback. + prefs.settings.accessibility.value = true; + + initPage(prefs); + flush(); + + const navButtonsToggle = + page.shadowRoot.querySelector('#shelfNavigationButtonsEnabledControl'); + assertTrue(isVisible(navButtonsToggle)); + + // If spoken feedback is enabled, the shelf nav buttons toggle should be + // disabled and checked. + assertTrue(navButtonsToggle.disabled); + assertTrue(navButtonsToggle.checked); + + // Clicking the toggle should have no effect. + navButtonsToggle.click(); + flush(); + + assertTrue(navButtonsToggle.disabled); + assertTrue(navButtonsToggle.checked); + assertFalse( + page.prefs.settings.a11y.tablet_mode_shelf_nav_buttons_enabled.value); + + // The toggle should be enabled if the spoken feedback gets disabled. + page.set('prefs.settings.accessibility.value', false); + flush(); + + assertFalse(!!navButtonsToggle.disabled); + assertFalse(navButtonsToggle.checked); + assertFalse( + page.prefs.settings.a11y.tablet_mode_shelf_nav_buttons_enabled.value); + + // Clicking the toggle should update the backing pref. + navButtonsToggle.click(); + flush(); + + assertFalse(!!navButtonsToggle.disabled); + assertTrue(navButtonsToggle.checked); + assertTrue( + page.prefs.settings.a11y.tablet_mode_shelf_nav_buttons_enabled.value); + }); + + test('some parts are hidden in kiosk mode', function() { + loadTimeData.overrideValues({ + isKioskModeActive: true, + showTabletModeShelfNavigationButtonsSettings: true, + }); + initPage(); + // Add mouse and touchpad to show some hidden settings. + deviceBrowserProxy.hasMouse = true; + deviceBrowserProxy.hasTouchpad = true; + flush(); + + // Shelf navigation buttons are not shown in kiosk mode, even if + // showTabletModeShelfNavigationButtonsSettings is true. + assertFalse(isVisible(page.shadowRoot.querySelector( + '#shelfNavigationButtonsEnabledControl'))); + + const subpageLinks = page.root.querySelectorAll('cr-link-row'); + subpageLinks.forEach(subpageLink => assertFalse(isVisible(subpageLink))); + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/display_and_magnification_page_tests.js b/chrome/test/data/webui/settings/chromeos/display_and_magnification_page_tests.js new file mode 100644 index 0000000..5170a31c0 --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/display_and_magnification_page_tests.js
@@ -0,0 +1,79 @@ +// 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 'chrome://os-settings/chromeos/lazy_load.js'; + +import {Router, routes} from 'chrome://os-settings/chromeos/os_settings.js'; +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {waitAfterNextRender, waitBeforeNextRender} from 'chrome://webui-test/polymer_test_util.js'; +import {eventToPromise, isVisible} from 'chrome://webui-test/test_util.js'; + +import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js'; + +suite('DisplayAndMagnificationPageTests', function() { + let page = null; + + function initPage() { + page = document.createElement('settings-display-and-magnification-page'); + document.body.appendChild(page); + } + + setup(function() { + PolymerTest.clearBody(); + loadTimeData.overrideValues( + {isAccessibilityOSSettingsVisibilityEnabled: true}); + Router.getInstance().navigateTo(routes.A11Y_DISPLAY_AND_MAGNIFICATION); + }); + + teardown(function() { + if (page) { + page.remove(); + } + Router.getInstance().resetRouteForTesting(); + }); + + [{selector: '#displaySubpageButton', route: routes.DISPLAY}, + ].forEach(({selector, route}) => { + test( + `should focus ${selector} button when returning from ${ + route.path} subpage`, + async () => { + initPage(); + flush(); + const router = Router.getInstance(); + + const subpageButton = page.shadowRoot.querySelector(selector); + assertTrue(!!subpageButton); + + subpageButton.click(); + assertEquals(route, router.getCurrentRoute()); + assertNotEquals( + subpageButton, page.shadowRoot.activeElement, + `${selector} should not be focused`); + + const popStateEventPromise = eventToPromise('popstate', window); + router.navigateToPreviousRoute(); + await popStateEventPromise; + await waitBeforeNextRender(page); + + assertEquals( + routes.A11Y_DISPLAY_AND_MAGNIFICATION, router.getCurrentRoute()); + assertEquals( + subpageButton, page.shadowRoot.activeElement, + `${selector} should be focused`); + }); + }); + + test('no subpages are available in kiosk mode', function() { + loadTimeData.overrideValues({ + isKioskModeActive: true, + showTabletModeShelfNavigationButtonsSettings: true, + }); + initPage(); + flush(); + + const subpageLinks = page.root.querySelectorAll('cr-link-row'); + subpageLinks.forEach(subpageLink => assertFalse(isVisible(subpageLink))); + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js index b79d3dd..832d09f 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -348,7 +348,17 @@ ['CupsPrinterEntry', 'cups_printer_entry_tests.js'], ['CupsPrinterLandingPage', 'cups_printer_landing_page_tests.js'], ['CupsPrinterPage', 'cups_printer_page_tests.js'], + [ + 'CursorAndTouchpadPage', + 'cursor_and_touchpad_page_tests.js', + {enabled: ['features::kAccessibilityOSSettingsVisibility']}, + ], ['DateTimePage', 'date_time_page_tests.js'], + [ + 'DisplayAndMagnificationPage', + 'display_and_magnification_page_tests.js', + {enabled: ['features::kAccessibilityOSSettingsVisibility']}, + ], ['EsimInstallErrorDialog', 'esim_install_error_dialog_test.js'], ['EsimRemoveProfileDialog', 'esim_remove_profile_dialog_test.js'], ['EsimRenameDialog', 'esim_rename_dialog_test.js'],
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn index 36dfddf..c9f90b7 100644 --- a/chrome/updater/BUILD.gn +++ b/chrome/updater/BUILD.gn
@@ -822,7 +822,12 @@ } if (is_linux) { - sources += [ "test/integration_tests_linux.cc" ] + sources += [ + "app/server/linux/rpc_unittests.cc", + "test/integration_tests_linux.cc", + ] + + deps += [ "//chrome/updater/app/server/linux/mojom" ] } }
diff --git a/chrome/updater/app/server/linux/mojom/updater_service.mojom b/chrome/updater/app/server/linux/mojom/updater_service.mojom index 83b6500..f278338 100644 --- a/chrome/updater/app/server/linux/mojom/updater_service.mojom +++ b/chrome/updater/app/server/linux/mojom/updater_service.mojom
@@ -4,10 +4,295 @@ module updater.mojom; +import "mojo/public/mojom/base/file_path.mojom"; + +// Struct containing the information required to register an application with +// the updater. Passed from client to server during RegisterApp and Install. +struct RegistrationRequest { + // Application ID of the app. + string app_id; + + // The brand code, a four character code attributing the app’s + // presence to a marketing campaign or similar effort. May be the empty + // string. + string brand_code; + + // A file path. Currently applicable to on Mac only: if a valid plist file + // exists at this path, the string value of key "KSBrandID" will override + // the `brand_code` above. + mojo_base.mojom.FilePath brand_path; + + // The ap value (e.g. from a tagged metainstaller). May be the empty string. + // This typically indicates channel, though it can carry additional data as + // well. + string ap; + + // The version of the app already installed. 0.0.0.0 if the app is not + // already installed. + string version; + + // A file path. A file exists at this path if and only if the app is + // still installed. This is used (on Mac, for example) to detect + // whether an app has been uninstalled via deletion. May be the empty + // string; if so, the app is assumed to be installed unconditionally. + mojo_base.mojom.FilePath existence_checker_path; +}; + +// Struct containing details on the state of an update. It is passed +// periodically from the server to the client via the StateChangeObserver. +struct UpdateState { + // Possible states for updating an app. Add new values at the end of + // the definition, and do not mutate the existing values. + enum State { + // This value represents the absence of a state. No update request has + // yet been issued. + kUnknown = 0, + + // This update has not been started, but has been requested. + kNotStarted, + + // The engine began issuing an update check request. + kCheckingForUpdates, + + // An update is available. + kUpdateAvailable, + + // The engine began downloading an update. + kDownloading, + + // The engine began running installation scripts. + kInstalling, + + // The engine found and installed an update for this product. The update + // is complete and the state will not change. + kUpdated, + + // The engine checked for updates. This product is already up to date. + // No update has been installed for this product. The update is complete + // and the state will not change. + kNoUpdate, + + // The engine encountered an error updating this product. The update has + // halted and the state will not change. + kUpdateError, + }; + + string app_id; + State state = State.kUnknown; + + // The version is initialized only after an update check has completed, and + // an update is available. + string next_version; + + int64 downloaded_bytes = -1; + int64 total_bytes = -1; + + // A value in the range [0, 100] if the install progress is known, or -1 + // if the install progress is not available or it could not be computed. + int8 install_progress = -1; + + UpdateService.ErrorCategory error_category = + UpdateService.ErrorCategory.kNone; + int32 error_code = 0; + int32 extra_code1 = 0; + + // Results collected from installer result API. See the definition of + // `update_client::CrxInstaller::Result` for the meaning of the members. + string installer_text; + string installer_cmd_line; +}; + +struct AppState { + string app_id; + string version; + string ap; + string brand_code; + mojo_base.mojom.FilePath brand_path; + mojo_base.mojom.FilePath ecp; +}; + // The UpdateService is the cross-platform core of the updater. // All functions and callbacks must be called on the same sequence. interface UpdateService { + // Defines the behavior of the update stack for over-installs. + // Typically, same versions updates are not allowed, in which case, the update + // server replies with `update not available'. But there are cases, such as + // re-installing an application again, when the server may respond with an + // update. + enum PolicySameVersionUpdate { + // The embedder does not allow over-installs with the same version. In this + // case, the server is expected to return `update not available` when it + // is queried for updates. + kNotAllowed = 0, + + // The embedder is capable of handling updates with the same version, and + // the server may respond with such an update. + kAllowed, + }; + + enum Result { + // Indicates that the service successfully handled the non-blocking function + // invocation. Returning this value provides no indication regarding the + // outcome of the function, such as whether the updates succeeded or not. + kSuccess = 0, + + // The function failed because there is an update in progress. Certain + // service functions can be parallelized but not all functions can run + // concurrently. + kUpdateInProgress, + + // Not used. TODO(crbug.com/1014591). + kUpdateCanceled, + + // The function failed because of a throttling policy such as load shedding. + kRetryLater, + + // This is a generic result indicating that an error occurred in the service + // such as a task failed to post, or allocation of a resource failed. + kServiceFailed, + + // An error handling the update check occurred. + kUpdateCheckFailed, + + // This value indicates that required metadata associated with the + // application was not available for any reason. + kAppNotFound, + + // A function argument was invalid. + kInvalidArgument, + + // This server is not the active server. + kInactive, + + // IPC connection to the remote process failed for some reason. + kIPCConnectionFailed, + + // Failed to run app installer. + kInstallFailed, + }; + + // Run time errors are organized in specific categories to indicate the + // component where such errors occurred. The category appears as a numeric + // value in the telemetry pings. The values of this enum must be kept stable. + enum ErrorCategory { + kNone = 0, + kDownload, + kUnpack, + kInstall, + kService, + kUpdateCheck, + }; + + // Urgency of the update service invocation. + enum Priority { + // The caller has not set a valid priority value. + kUnknown = 0, + + // The user is not waiting for this update. + kBackground, + + // The user is not waiting for this update. + kForeground, + }; + // Returns the version of the active updater. The version object is invalid // if an error (including timeout) occurs. GetVersion() => (string version); + + // Fetches policies from device management. + FetchPolicies() => (int32 result); + + // Registers given request to the updater. + RegisterApp(RegistrationRequest request) => (int32 result); + + // Gets state of all registered apps. + GetAppStates() => (array<AppState> app_states); + + // Runs periodic tasks such as checking for uninstallation of registered + // applications or doing background updates for registered applications. + RunPeriodicTasks() => (); + + // Initiates an update check for all registered applications. Receives state + // change notifications through the `state_change_observer`. Responds once + // the operation is complete. + UpdateAll() => + (pending_receiver<StateChangeObserver> observer); + + // Updates specified product. This update may be on-demand. + // + // Response: + // The final result from the update engine. + Update( + // ID of app to update. + string app_id, + + // Index of the server install data. + string install_data_index, + + // Priority for processing this update. + Priority priority, + + // Whether a same-version update is allowed. + PolicySameVersionUpdate policy_same_version_update) => + (pending_receiver<StateChangeObserver> observer); + + // Registers and installs an application from the network. + // + // Response: + // The final result from the update engine. + Install( + // Registration data about the app. + RegistrationRequest registration, + + // User provided install data. + string client_install_data, + + // Index of the server install data. Effective only + // when `client_install_data` is not set. + string install_data_index, + + // Priority for processing this update. + Priority priority) => + (pending_receiver<StateChangeObserver> observer); + + // Cancels any ongoing installations of the specified product. This does not + // interrupt any product installers that are currently running, but does + // prevent them from being run if they are not yet downloaded. + // + // Args: + // `app_id`: ID of the product to cancel installs of. + CancelInstalls(string app_id); + + // Install an app by running its installer. + // + // Result: + // The final result from the update engine. + RunInstaller( + // `app_id`: ID of app to install. + string app_id, + + // `app_installer`: Offline installer path. + mojo_base.mojom.FilePath installer_path, + + // `arguments`: Arguments to run the installer. + string install_args, + + // `install_data`: Server install data extracted from the offline manifest. + string install_data, + + // `install_settings`: An optional serialized dictionary to customize the + // installation. + string install_settings) => + (pending_receiver<StateChangeObserver> observer); +}; + +// Callback interface for repeated state change notifications produced by +// methods of the UpdateService interface. +interface StateChangeObserver { + // Repeated state change callback. + // state: the new state of this update request. + OnStateChange(UpdateState state); + + // A callback to be run with the final result of the operation. + OnComplete(UpdateService.Result result); };
diff --git a/chrome/updater/app/server/linux/rpc_unittests.cc b/chrome/updater/app/server/linux/rpc_unittests.cc new file mode 100644 index 0000000..bd7551a --- /dev/null +++ b/chrome/updater/app/server/linux/rpc_unittests.cc
@@ -0,0 +1,325 @@ +// 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 <memory> +#include <string> +#include <tuple> +#include <utility> +#include <vector> + +#include "base/files/file_path.h" +#include "base/functional/bind.h" +#include "base/functional/callback.h" +#include "base/memory/scoped_refptr.h" +#include "base/run_loop.h" +#include "base/test/task_environment.h" +#include "base/version.h" +#include "chrome/updater/app/server/linux/mojom/updater_service.mojom.h" +#include "chrome/updater/app/server/linux/update_service_stub.h" +#include "chrome/updater/ipc/update_service_proxy_linux.h" +#include "chrome/updater/registration_data.h" +#include "chrome/updater/update_service.h" +#include "chrome/updater/updater_scope.h" +#include "mojo/core/embedder/embedder.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace updater { + +class FakeUpdateService : public UpdateService { + public: + void GetVersion( + base::OnceCallback<void(const base::Version&)> callback) override { + std::move(callback).Run(base::Version("9")); + } + + void FetchPolicies(base::OnceCallback<void(int)> callback) override { + std::move(callback).Run(42); + } + + void RegisterApp(const RegistrationRequest& request, + base::OnceCallback<void(int)> callback) override { + std::move(callback).Run(42); + } + + void GetAppStates(base::OnceCallback<void(const std::vector<AppState>&)> + callback) override { + AppState ex1; + ex1.app_id = "ex1"; + ex1.version = base::Version("9.19.20"); + ex1.ap = "foo"; + ex1.brand_code = "FooBarInc"; + ex1.brand_path = base::FilePath("/path/to/foo_bar"); + ex1.ecp = base::FilePath("path/to/foo_ecp"); + + AppState ex2; + ex2.app_id = "ex2"; + ex2.version = base::Version("98.4.5"); + ex2.ap = "zaz"; + ex2.brand_code = "BazInc"; + ex2.brand_path = base::FilePath("/path/to/baz"); + ex2.ecp = base::FilePath("path/to/baz_ecp"); + + std::move(callback).Run({ex1, ex2}); + } + + void RunPeriodicTasks(base::OnceClosure callback) override { + std::move(callback).Run(); + } + + void UpdateAll(StateChangeCallback state_update, Callback callback) override { + DoStateChangeCallbacks(std::move(state_update), std::move(callback)); + } + + void Update(const std::string& app_id, + const std::string& install_data_index, + Priority priority, + PolicySameVersionUpdate policy_same_version_update, + StateChangeCallback state_update, + Callback callback) override { + DoStateChangeCallbacks(std::move(state_update), std::move(callback)); + } + + void Install(const RegistrationRequest& registration, + const std::string& client_install_data, + const std::string& install_data_index, + Priority priority, + StateChangeCallback state_update, + Callback callback) override { + DoStateChangeCallbacks(std::move(state_update), std::move(callback)); + } + + void CancelInstalls(const std::string& app_id) override {} + + void RunInstaller(const std::string& app_id, + const base::FilePath& installer_path, + const std::string& install_args, + const std::string& install_data, + const std::string& install_settings, + StateChangeCallback state_update, + Callback callback) override { + DoStateChangeCallbacks(std::move(state_update), std::move(callback)); + } + + void Uninitialize() override {} + + private: + ~FakeUpdateService() override = default; + + void DoStateChangeCallbacks(StateChangeCallback state_update, + Callback callback) { + UpdateService::UpdateState state1; + state1.app_id = "ex1"; + state1.state = UpdateService::UpdateState::State::kCheckingForUpdates; + state_update.Run(state1); + + UpdateService::UpdateState state2; + state2.app_id = "ex2"; + state2.state = UpdateService::UpdateState::State::kDownloading; + state2.next_version = base::Version("3.14"); + state2.downloaded_bytes = 1024; + state2.total_bytes = 2048; + state_update.Run(state2); + + UpdateService::UpdateState state3; + state3.app_id = "ex3"; + state3.state = UpdateService::UpdateState::State::kUpdateError; + state3.install_progress = 99; + state3.error_code = 0xDEAD; + state3.extra_code1 = 0xBEEF; + state3.installer_text = "Error: The beef has died."; + state3.installer_cmd_line = "path/to/updater --crash-me"; + state_update.Run(state3); + + std::move(callback).Run(UpdateService::Result::kInstallFailed); + } +}; + +class UpdaterIPCTestCase : public testing::Test { + public: + static void SetUpTestSuite() { mojo::core::Init(); } + + static void ExpectUpdateStatesEqual(const UpdateService::UpdateState& lhs, + const UpdateService::UpdateState& rhs) { + EXPECT_EQ(lhs.app_id, rhs.app_id); + EXPECT_EQ(lhs.state, rhs.state); + EXPECT_EQ(lhs.next_version.IsValid(), rhs.next_version.IsValid()); + if (lhs.next_version.IsValid() && rhs.next_version.IsValid()) + EXPECT_EQ(lhs.next_version, rhs.next_version); + EXPECT_EQ(lhs.downloaded_bytes, rhs.downloaded_bytes); + EXPECT_EQ(lhs.total_bytes, rhs.total_bytes); + EXPECT_EQ(lhs.install_progress, rhs.install_progress); + EXPECT_EQ(lhs.error_category, rhs.error_category); + EXPECT_EQ(lhs.error_code, rhs.error_code); + EXPECT_EQ(lhs.extra_code1, rhs.extra_code1); + EXPECT_EQ(lhs.installer_text, rhs.installer_text); + EXPECT_EQ(lhs.installer_cmd_line, rhs.installer_cmd_line); + } + + void SetUp() override { + scoped_refptr<UpdateService> service = + base::MakeRefCounted<FakeUpdateService>(); + mojo::Remote<mojom::UpdateService> remote; + service_stub_ = std::make_unique<UpdateServiceStub>( + remote.BindNewPipeAndPassReceiver(), std::move(service)); + client_proxy_ = + CreateUpdateServiceProxy(UpdaterScope::kUser, std::move(remote)); + } + + UpdateService::StateChangeCallback ExpectUpdateStatesCallback() { + UpdateService::UpdateState state1; + state1.app_id = "ex1"; + state1.state = UpdateService::UpdateState::State::kCheckingForUpdates; + + UpdateService::UpdateState state2; + state2.app_id = "ex2"; + state2.state = UpdateService::UpdateState::State::kDownloading; + state2.next_version = base::Version("3.14"); + state2.downloaded_bytes = 1024; + state2.total_bytes = 2048; + + UpdateService::UpdateState state3; + state3.app_id = "ex3"; + state3.state = UpdateService::UpdateState::State::kUpdateError; + state3.install_progress = 99; + state3.error_code = 0xDEAD; + state3.extra_code1 = 0xBEEF; + state3.installer_text = "Error: The beef has died."; + state3.installer_cmd_line = "path/to/updater --crash-me"; + + std::vector<UpdateService::UpdateState> states = {state3, state2, state1}; + + return base::BindRepeating( + [](std::vector<UpdateService::UpdateState>& states, + const UpdateService::UpdateState& state) { + ASSERT_GT(states.size(), 0U); + ExpectUpdateStatesEqual(state, states.back()); + states.pop_back(); + }, + base::OwnedRef(states)); + } + + UpdateService::Callback ExpectResultCallback() { + return base::BindOnce([](UpdateService::Result result) { + EXPECT_EQ(result, UpdateService::Result::kInstallFailed); + }) + .Then(run_loop_.QuitClosure()); + } + + protected: + base::test::TaskEnvironment environment_; + base::RunLoop run_loop_; + + std::unique_ptr<UpdateServiceStub> service_stub_; + scoped_refptr<UpdateService> client_proxy_; +}; + +TEST_F(UpdaterIPCTestCase, GetVersion) { + client_proxy_->GetVersion(base::BindOnce([](const base::Version& version) { + EXPECT_EQ(version, base::Version("9")); + }).Then(run_loop_.QuitClosure())); + run_loop_.Run(); +} + +TEST_F(UpdaterIPCTestCase, FetchPolicies) { + client_proxy_->FetchPolicies(base::BindOnce([](int result) { + EXPECT_EQ(result, 42); + }).Then(run_loop_.QuitClosure())); + run_loop_.Run(); +} + +TEST_F(UpdaterIPCTestCase, RegisterApp) { + client_proxy_->RegisterApp({}, base::BindOnce([](int result) { + EXPECT_EQ(result, 42); + }).Then(run_loop_.QuitClosure())); + run_loop_.Run(); +} + +TEST_F(UpdaterIPCTestCase, GetAppStates) { + client_proxy_->GetAppStates( + base::BindOnce([](const std::vector<UpdateService::AppState>& + app_states) { + ASSERT_EQ(app_states.size(), 2U); + + EXPECT_EQ(app_states[0].app_id, "ex1"); + EXPECT_EQ(app_states[0].version, base::Version("9.19.20")); + EXPECT_EQ(app_states[0].ap, "foo"); + EXPECT_EQ(app_states[0].brand_code, "FooBarInc"); + EXPECT_EQ(app_states[0].brand_path, base::FilePath("/path/to/foo_bar")); + EXPECT_EQ(app_states[0].ecp, base::FilePath("path/to/foo_ecp")); + + EXPECT_EQ(app_states[1].app_id, "ex2"); + EXPECT_EQ(app_states[1].version, base::Version("98.4.5")); + EXPECT_EQ(app_states[1].ap, "zaz"); + EXPECT_EQ(app_states[1].brand_code, "BazInc"); + EXPECT_EQ(app_states[1].brand_path, base::FilePath("/path/to/baz")); + EXPECT_EQ(app_states[1].ecp, base::FilePath("path/to/baz_ecp")); + }).Then(run_loop_.QuitClosure())); + run_loop_.Run(); +} + +TEST_F(UpdaterIPCTestCase, UpdateAll) { + client_proxy_->UpdateAll(ExpectUpdateStatesCallback(), + ExpectResultCallback()); + run_loop_.Run(); +} + +TEST_F(UpdaterIPCTestCase, Update) { + client_proxy_->Update("ex1", "install_data_index", + UpdateService::Priority::kBackground, + UpdateService::PolicySameVersionUpdate::kAllowed, + ExpectUpdateStatesCallback(), ExpectResultCallback()); + run_loop_.Run(); +} + +TEST_F(UpdaterIPCTestCase, Install) { + RegistrationRequest request; + + client_proxy_->Install(request, "client_install_data", "install_data_index", + UpdateService::Priority::kForeground, + ExpectUpdateStatesCallback(), ExpectResultCallback()); + run_loop_.Run(); +} + +TEST_F(UpdaterIPCTestCase, RunInstaller) { + RegistrationRequest request; + + client_proxy_->RunInstaller("ex1", base::FilePath("/path/to/installer"), + "install_args", "install_data", + "install_settings", ExpectUpdateStatesCallback(), + ExpectResultCallback()); + run_loop_.Run(); +} + +class UpdaterIPCErrorTestCase : public UpdaterIPCTestCase { + public: + void SetUp() override { + // Create a Mojo Remote with a bound message pipe but without a receiver. + // This will cause RPC calls to eventually be dropped. + mojo::Remote<mojom::UpdateService> remote; + std::ignore = remote.BindNewPipeAndPassReceiver(); + client_proxy_ = + CreateUpdateServiceProxy(UpdaterScope::kUser, std::move(remote)); + } +}; + +TEST_F(UpdaterIPCErrorTestCase, DroppedGetVersion) { + client_proxy_->GetVersion(base::BindOnce([](const base::Version& version) { + EXPECT_FALSE(version.IsValid()); + }).Then(run_loop_.QuitClosure())); + + run_loop_.Run(); +} + +TEST_F(UpdaterIPCErrorTestCase, DroppedUpdateAll) { + client_proxy_->UpdateAll( + base::BindRepeating([](const UpdateService::UpdateState& state) {}), + base::BindOnce([](UpdateService::Result result) { + EXPECT_EQ(result, UpdateService::Result::kIPCConnectionFailed); + }).Then(run_loop_.QuitClosure())); + + run_loop_.Run(); +} + +} // namespace updater
diff --git a/chrome/updater/app/server/linux/update_service_stub.cc b/chrome/updater/app/server/linux/update_service_stub.cc index fe70af0..6ce10e72 100644 --- a/chrome/updater/app/server/linux/update_service_stub.cc +++ b/chrome/updater/app/server/linux/update_service_stub.cc
@@ -4,15 +4,94 @@ #include "chrome/updater/app/server/linux/update_service_stub.h" +#include <iterator> #include <utility> -#include "base/callback.h" +#include "base/check.h" #include "base/functional/bind.h" #include "base/functional/callback.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_refptr.h" #include "base/version.h" +#include "chrome/updater/app/server/linux/mojom/updater_service.mojom-forward.h" +#include "chrome/updater/registration_data.h" +#include "mojo/public/cpp/bindings/remote.h" namespace updater { +namespace { + +// Helper functions for converting between mojom types and their native +// counterparts. +[[nodiscard]] updater::RegistrationRequest MakeRegistrationRequest( + const mojom::RegistrationRequestPtr& mojom) { + CHECK(mojom); + + updater::RegistrationRequest request; + request.app_id = mojom->app_id; + request.brand_code = mojom->brand_code; + request.brand_path = mojom->brand_path; + request.ap = mojom->ap; + request.version = base::Version(mojom->version); + request.existence_checker_path = mojom->existence_checker_path; + return request; +} + +[[nodiscard]] mojom::AppStatePtr MakeMojoAppState( + const updater::UpdateService::AppState& app_state) { + return mojom::AppState::New(app_state.app_id, app_state.version.GetString(), + app_state.ap, app_state.brand_code, + app_state.brand_path, app_state.ecp); +} + +[[nodiscard]] mojom::UpdateStatePtr MakeMojoUpdateState( + const updater::UpdateService::UpdateState& update_state) { + return mojom::UpdateState::New( + update_state.app_id, + static_cast<mojom::UpdateState::State>(update_state.state), + update_state.next_version.GetString(), update_state.downloaded_bytes, + update_state.total_bytes, update_state.install_progress, + static_cast<mojom::UpdateService::ErrorCategory>( + update_state.error_category), + update_state.error_code, update_state.extra_code1, + update_state.installer_text, update_state.installer_cmd_line); +} + +// A thin wrapper around a StateChangeObserver remote to allow for refcounting. +class StateChangeObserverWrapper + : public base::RefCountedThreadSafe<StateChangeObserverWrapper> { + public: + explicit StateChangeObserverWrapper( + std::unique_ptr<mojo::Remote<mojom::StateChangeObserver>> observer) + : observer_(std::move(observer)) {} + + void OnStateChange(const updater::UpdateService::UpdateState& update_state) { + (*observer_)->OnStateChange(MakeMojoUpdateState(update_state)); + } + + void OnComplete(updater::UpdateService::Result result) { + (*observer_)->OnComplete(static_cast<mojom::UpdateService::Result>(result)); + } + + private: + friend class base::RefCountedThreadSafe<StateChangeObserverWrapper>; + virtual ~StateChangeObserverWrapper() = default; + std::unique_ptr<mojo::Remote<mojom::StateChangeObserver>> observer_; +}; + +// Binds a callback that forwards state change callbacks and the OnComplete +// callback to a StateChangeObserver. +[[nodiscard]] std::pair<UpdateService::StateChangeCallback, + UpdateService::Callback> +MakeStateChangeObserverCallbacks( + std::unique_ptr<mojo::Remote<mojom::StateChangeObserver>> observer) { + scoped_refptr<StateChangeObserverWrapper> wrapper = + base::MakeRefCounted<StateChangeObserverWrapper>(std::move(observer)); + return { + base::BindRepeating(&StateChangeObserverWrapper::OnStateChange, wrapper), + base::BindOnce(&StateChangeObserverWrapper::OnComplete, wrapper)}; +} + +} // namespace UpdateServiceStub::UpdateServiceStub( mojo::PendingReceiver<mojom::UpdateService> receiver, @@ -29,4 +108,98 @@ std::move(callback))); } +void UpdateServiceStub::FetchPolicies(FetchPoliciesCallback callback) { + impl_->FetchPolicies(std::move(callback)); +} + +void UpdateServiceStub::RegisterApp(mojom::RegistrationRequestPtr request, + RegisterAppCallback callback) { + impl_->RegisterApp(MakeRegistrationRequest(request), std::move(callback)); +} + +void UpdateServiceStub::GetAppStates(GetAppStatesCallback callback) { + impl_->GetAppStates( + base::BindOnce([](const std::vector<updater::UpdateService::AppState>& + app_states) { + std::vector<mojom::AppStatePtr> app_states_mojom; + std::transform(app_states.begin(), app_states.end(), + std::back_inserter(app_states_mojom), &MakeMojoAppState); + return app_states_mojom; + }).Then(std::move(callback))); +} + +void UpdateServiceStub::RunPeriodicTasks(RunPeriodicTasksCallback callback) { + impl_->RunPeriodicTasks(std::move(callback)); +} + +void UpdateServiceStub::UpdateAll(UpdateAllCallback callback) { + std::unique_ptr<mojo::Remote<mojom::StateChangeObserver>> observer = + std::make_unique<mojo::Remote<mojom::StateChangeObserver>>(); + std::move(callback).Run(observer->BindNewPipeAndPassReceiver()); + + auto [state_change_callback, on_complete_callback] = + MakeStateChangeObserverCallbacks(std::move(observer)); + impl_->UpdateAll(std::move(state_change_callback), + std::move(on_complete_callback)); +} + +void UpdateServiceStub::Update( + const std::string& app_id, + const std::string& install_data_index, + UpdateService::Priority priority, + UpdateService::PolicySameVersionUpdate policy_same_version_update, + UpdateCallback callback) { + std::unique_ptr<mojo::Remote<mojom::StateChangeObserver>> observer = + std::make_unique<mojo::Remote<mojom::StateChangeObserver>>(); + std::move(callback).Run(observer->BindNewPipeAndPassReceiver()); + + auto [state_change_callback, on_complete_callback] = + MakeStateChangeObserverCallbacks(std::move(observer)); + impl_->Update(app_id, install_data_index, + static_cast<updater::UpdateService::Priority>(priority), + static_cast<updater::UpdateService::PolicySameVersionUpdate>( + policy_same_version_update), + std::move(state_change_callback), + std::move(on_complete_callback)); +} + +void UpdateServiceStub::Install(mojom::RegistrationRequestPtr registration, + const std::string& client_install_data, + const std::string& install_data_index, + UpdateService::Priority priority, + InstallCallback callback) { + std::unique_ptr<mojo::Remote<mojom::StateChangeObserver>> observer = + std::make_unique<mojo::Remote<mojom::StateChangeObserver>>(); + std::move(callback).Run(observer->BindNewPipeAndPassReceiver()); + + auto [state_change_callback, on_complete_callback] = + MakeStateChangeObserverCallbacks(std::move(observer)); + impl_->Install(MakeRegistrationRequest(registration), client_install_data, + install_data_index, + static_cast<updater::UpdateService::Priority>(priority), + std::move(state_change_callback), + std::move(on_complete_callback)); +} + +void UpdateServiceStub::CancelInstalls(const std::string& app_id) { + impl_->CancelInstalls(app_id); +} + +void UpdateServiceStub::RunInstaller(const std::string& app_id, + const ::base::FilePath& installer_path, + const std::string& install_args, + const std::string& install_data, + const std::string& install_settings, + RunInstallerCallback callback) { + std::unique_ptr<mojo::Remote<mojom::StateChangeObserver>> observer = + std::make_unique<mojo::Remote<mojom::StateChangeObserver>>(); + std::move(callback).Run(observer->BindNewPipeAndPassReceiver()); + + auto [state_change_callback, on_complete_callback] = + MakeStateChangeObserverCallbacks(std::move(observer)); + impl_->RunInstaller(app_id, installer_path, install_args, install_data, + install_settings, std::move(state_change_callback), + std::move(on_complete_callback)); +} + } // namespace updater
diff --git a/chrome/updater/app/server/linux/update_service_stub.h b/chrome/updater/app/server/linux/update_service_stub.h index 5a39f02c..950953da 100644 --- a/chrome/updater/app/server/linux/update_service_stub.h +++ b/chrome/updater/app/server/linux/update_service_stub.h
@@ -25,6 +25,29 @@ // updater::mojom::UpdateService void GetVersion(GetVersionCallback callback) override; + void FetchPolicies(FetchPoliciesCallback callback) override; + void RegisterApp(mojom::RegistrationRequestPtr request, + RegisterAppCallback callback) override; + void GetAppStates(GetAppStatesCallback callback) override; + void RunPeriodicTasks(RunPeriodicTasksCallback callback) override; + void UpdateAll(UpdateAllCallback callback) override; + void Update(const std::string& app_id, + const std::string& install_data_index, + UpdateService::Priority priority, + UpdateService::PolicySameVersionUpdate policy_same_version_update, + UpdateCallback callback) override; + void Install(mojom::RegistrationRequestPtr registration, + const std::string& client_install_data, + const std::string& install_data_index, + UpdateService::Priority priority, + InstallCallback callback) override; + void CancelInstalls(const std::string& app_id) override; + void RunInstaller(const std::string& app_id, + const ::base::FilePath& installer_path, + const std::string& install_args, + const std::string& install_data, + const std::string& install_settings, + RunInstallerCallback callback) override; private: mojo::Receiver<updater::mojom::UpdateService> receiver_;
diff --git a/chrome/updater/constants.h b/chrome/updater/constants.h index 0813a71..3172935 100644 --- a/chrome/updater/constants.h +++ b/chrome/updater/constants.h
@@ -351,6 +351,9 @@ inline constexpr int kErrorFailedToInstallLegacyUpdater = 34; +// A Mojo remote was unexpectedly disconnected. +inline constexpr int kErrorMojoDisconnect = 35; + inline constexpr int kErrorTagParsing = 50; // Metainstaller errors.
diff --git a/chrome/updater/ipc/update_service_proxy_linux.cc b/chrome/updater/ipc/update_service_proxy_linux.cc index 7b3bd537..604fe2f 100644 --- a/chrome/updater/ipc/update_service_proxy_linux.cc +++ b/chrome/updater/ipc/update_service_proxy_linux.cc
@@ -8,27 +8,134 @@ #include <string> #include <utility> +#include "base/check.h" +#include "base/files/file_path.h" #include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/logging.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_refptr.h" -#include "base/notreached.h" -#include "base/time/time.h" +#include "base/ranges/algorithm.h" #include "base/version.h" #include "chrome/updater/app/server/linux/mojom/updater_service.mojom.h" +#include "chrome/updater/constants.h" #include "chrome/updater/linux/ipc_constants.h" +#include "chrome/updater/registration_data.h" #include "chrome/updater/service_proxy_factory.h" #include "chrome/updater/update_service.h" #include "chrome/updater/updater_scope.h" #include "chrome/updater/util.h" #include "mojo/public/cpp/bindings/callback_helpers.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "mojo/public/cpp/platform/named_platform_channel.h" #include "mojo/public/cpp/system/invitation.h" +#include "mojo/public/cpp/system/message_pipe.h" + +namespace base { +class TimeDelta; +} namespace updater { +namespace { -// TODO(crbug.com/1276169) - implement. +[[nodiscard]] UpdateService::UpdateState MakeUpdateState( + const mojom::UpdateStatePtr& state_mojom) { + updater::UpdateService::UpdateState state; + state.app_id = state_mojom->app_id; + state.state = + static_cast<UpdateService::UpdateState::State>(state_mojom->state); + state.next_version = base::Version(state_mojom->next_version); + state.downloaded_bytes = state_mojom->downloaded_bytes; + state.total_bytes = state_mojom->total_bytes; + state.install_progress = state_mojom->install_progress; + state.error_category = + static_cast<UpdateService::ErrorCategory>(state_mojom->error_category); + state.error_code = state_mojom->error_code; + state.extra_code1 = state_mojom->extra_code1; + state.installer_text = state_mojom->installer_text; + state.installer_cmd_line = state_mojom->installer_cmd_line; + + return state; +} + +[[nodiscard]] UpdateService::AppState MakeAppState( + const mojom::AppStatePtr& app_state_mojo) { + UpdateService::AppState app_state; + app_state.app_id = app_state_mojo->app_id; + app_state.version = base::Version(app_state_mojo->version); + app_state.ap = app_state_mojo->ap; + app_state.brand_code = app_state_mojo->brand_code; + app_state.brand_path = app_state_mojo->brand_path; + app_state.ecp = app_state_mojo->ecp; + + return app_state; +} + +[[nodiscard]] mojom::RegistrationRequestPtr MakeRegistrationRequest( + const RegistrationRequest& request) { + return mojom::RegistrationRequest::New( + request.app_id, request.brand_code, request.brand_path, request.ap, + request.version.GetString(), request.existence_checker_path); +} + +class StateChangeObserverImpl : public mojom::StateChangeObserver { + public: + explicit StateChangeObserverImpl( + UpdateService::StateChangeCallback state_change_callback, + UpdateService::Callback complete_callback) + : state_change_callback_(std::move(state_change_callback)), + complete_callback_(std::move(complete_callback)) {} + StateChangeObserverImpl(const StateChangeObserverImpl&) = delete; + StateChangeObserverImpl& operator=(const StateChangeObserverImpl&) = delete; + ~StateChangeObserverImpl() override = default; + + // Overrides for mojom::StateChangeObserver. + void OnStateChange(mojom::UpdateStatePtr state_mojom) override { + DCHECK(complete_callback_) << "OnStateChange received after OnComplete"; + state_change_callback_.Run(MakeUpdateState(state_mojom)); + } + + void OnComplete(mojom::UpdateService::Result result) override { + DCHECK(complete_callback_) << "OnComplete received without a valid " + "callback. Was OnComplete run twice?"; + if (complete_callback_) { + std::move(complete_callback_) + .Run(static_cast<updater::UpdateService::Result>(result)); + } + } + + private: + UpdateService::StateChangeCallback state_change_callback_; + UpdateService::Callback complete_callback_; +}; + +// Binds a callback which creates a self-owned StateChangeObserverImpl to +// forward RPC callbacks to the provided native callbacks. +[[nodiscard]] base::OnceCallback< + void(mojo::PendingReceiver<mojom::StateChangeObserver>)> +MakeStateChangeObserver( + UpdateService::StateChangeCallback state_change_callback, + UpdateService::Callback complete_callback) { + complete_callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun( + std::move(complete_callback), + updater::UpdateService::Result::kIPCConnectionFailed); + return base::BindOnce( + [](UpdateService::StateChangeCallback state_change_callback, + UpdateService::Callback complete_callback, + mojo::PendingReceiver<mojom::StateChangeObserver> receiver) { + mojo::MakeSelfOwnedReceiver( + std::make_unique<StateChangeObserverImpl>( + std::move(state_change_callback), std::move(complete_callback)), + std::move(receiver)); + }, + std::move(state_change_callback), std::move(complete_callback)); +} + +} // namespace + class UpdateServiceProxyImpl : public base::RefCountedThreadSafe<UpdateServiceProxyImpl> { public: @@ -48,55 +155,83 @@ } void FetchPolicies(base::OnceCallback<void(int)> callback) { - NOTIMPLEMENTED(); + remote_->FetchPolicies(mojo::WrapCallbackWithDefaultInvokeIfNotRun( + std::move(callback), kErrorMojoDisconnect)); } void RegisterApp(const RegistrationRequest& request, base::OnceCallback<void(int)> callback) { - NOTIMPLEMENTED(); + remote_->RegisterApp(MakeRegistrationRequest(request), + mojo::WrapCallbackWithDefaultInvokeIfNotRun( + std::move(callback), kErrorMojoDisconnect)); } void GetAppStates( base::OnceCallback<void(const std::vector<UpdateService::AppState>&)> callback) { - NOTIMPLEMENTED(); + remote_->GetAppStates(mojo::WrapCallbackWithDefaultInvokeIfNotRun( + base::BindOnce([](std::vector<mojom::AppStatePtr> app_states_mojo) { + std::vector<updater::UpdateService::AppState> app_states; + base::ranges::transform( + app_states_mojo, std::back_inserter(app_states), &MakeAppState); + return app_states; + }).Then(std::move(callback)), + std::vector<mojom::AppStatePtr>())); } - void RunPeriodicTasks(base::OnceClosure callback) { NOTIMPLEMENTED(); } + void RunPeriodicTasks(base::OnceClosure callback) { + remote_->RunPeriodicTasks( + mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(callback))); + } - void UpdateAll(UpdateService::StateChangeCallback state_update, - UpdateService::Callback callback) { - NOTIMPLEMENTED(); + void UpdateAll(UpdateService::StateChangeCallback state_change_callback, + UpdateService::Callback complete_callback) { + remote_->UpdateAll(MakeStateChangeObserver(std::move(state_change_callback), + std::move(complete_callback))); } void Update(const std::string& app_id, const std::string& install_data_index, UpdateService::Priority priority, UpdateService::PolicySameVersionUpdate policy_same_version_update, - UpdateService::StateChangeCallback state_update, - UpdateService::Callback callback) { - NOTIMPLEMENTED(); + UpdateService::StateChangeCallback state_change_callback, + UpdateService::Callback complete_callback) { + remote_->Update(app_id, install_data_index, + static_cast<mojom::UpdateService::Priority>(priority), + static_cast<mojom::UpdateService::PolicySameVersionUpdate>( + policy_same_version_update), + MakeStateChangeObserver(std::move(state_change_callback), + std::move(complete_callback))); } void Install(const RegistrationRequest& registration, const std::string& client_install_data, const std::string& install_data_index, UpdateService::Priority priority, - UpdateService::StateChangeCallback state_update, - UpdateService::Callback callback) { - NOTIMPLEMENTED(); + UpdateService::StateChangeCallback state_change_callback, + UpdateService::Callback complete_callback) { + remote_->Install(MakeRegistrationRequest(registration), client_install_data, + install_data_index, + static_cast<mojom::UpdateService::Priority>(priority), + MakeStateChangeObserver(std::move(state_change_callback), + std::move(complete_callback))); } - void CancelInstalls(const std::string& app_id) { NOTIMPLEMENTED(); } + void CancelInstalls(const std::string& app_id) { + remote_->CancelInstalls(app_id); + } void RunInstaller(const std::string& app_id, const base::FilePath& installer_path, const std::string& install_args, const std::string& install_data, const std::string& install_settings, - UpdateService::StateChangeCallback state_update, - UpdateService::Callback callback) { - NOTIMPLEMENTED(); + UpdateService::StateChangeCallback state_change_callback, + UpdateService::Callback complete_callback) { + remote_->RunInstaller( + app_id, installer_path, install_args, install_data, install_settings, + MakeStateChangeObserver(std::move(state_change_callback), + std::move(complete_callback))); } private:
diff --git a/chrome/updater/ipc/update_service_proxy_linux.h b/chrome/updater/ipc/update_service_proxy_linux.h index d5f1026..a627f94 100644 --- a/chrome/updater/ipc/update_service_proxy_linux.h +++ b/chrome/updater/ipc/update_service_proxy_linux.h
@@ -8,14 +8,20 @@ #include "base/callback_forward.h" #include "base/memory/scoped_refptr.h" #include "base/sequence_checker.h" -#include "chrome/updater/app/server/linux/mojom/updater_service.mojom.h" +#include "chrome/updater/app/server/linux/mojom/updater_service.mojom-forward.h" #include "chrome/updater/update_service.h" -#include "chrome/updater/updater_scope.h" #include "mojo/public/cpp/bindings/remote.h" +namespace base { +class FilePath; +class Version; +} // namespace base + namespace updater { class UpdateServiceProxyImpl; +enum class UpdaterScope; +struct RegistrationRequest; // All functions and callbacks must be called on the same sequence. class UpdateServiceProxy : public UpdateService {
diff --git a/chromeos/ash/services/libassistant/constants.cc b/chromeos/ash/services/libassistant/constants.cc index 4d4fe8e..b0fa4f8 100644 --- a/chromeos/ash/services/libassistant/constants.cc +++ b/chromeos/ash/services/libassistant/constants.cc
@@ -19,6 +19,9 @@ const base::FilePath::CharType kAssistantBaseDirPath[] = FILE_PATH_LITERAL("/home/chronos/user/" ASSISTANT_DIR_STRING); +const base::FilePath::CharType kLibAssistantSocketPath[] = + FILE_PATH_LITERAL("/run/libassistant"); + const char kLibAssistantDlcRootPath[] = "/run/imageloader/assistant-dlc/package/root";
diff --git a/chromeos/ash/services/libassistant/constants.h b/chromeos/ash/services/libassistant/constants.h index 8c40e5a1..957a326 100644 --- a/chromeos/ash/services/libassistant/constants.h +++ b/chromeos/ash/services/libassistant/constants.h
@@ -27,11 +27,9 @@ COMPONENT_EXPORT(LIBASSISTANT_CONSTANTS) extern const base::FilePath::CharType kLibAssistantV2DlcPath[]; -#if !BUILDFLAG(IS_CHROMEOS_DEVICE) // A directory to save Libassistant socket files. COMPONENT_EXPORT(LIBASSISTANT_CONSTANTS) extern const base::FilePath::CharType kLibAssistantSocketPath[]; -#endif } // namespace ash::libassistant #endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_CONSTANTS_H_
diff --git a/chromeos/ash/services/libassistant/libassistant_loader_impl.cc b/chromeos/ash/services/libassistant/libassistant_loader_impl.cc index 34c14323..64daa4c 100644 --- a/chromeos/ash/services/libassistant/libassistant_loader_impl.cc +++ b/chromeos/ash/services/libassistant/libassistant_loader_impl.cc
@@ -107,16 +107,12 @@ // Since we are not in the main thread, we can call the blocking method. DCHECK(!entry_point_); -#if !BUILDFLAG(IS_CHROMEOS_DEVICE) // If the gRPC socket files exist, libassistant gRPC server could not start // because the binding to the new socket files will fail, with error message // that the files already exist. - // This cleanup is only needed for running the sandbox on gLinux. - // On a real device, these files will be cleaned up on the OS side when Chrome - // starts. DVLOG(3) << "Clean up temporary libassistant directory."; base::DeletePathRecursively(base::FilePath(kLibAssistantSocketPath)); -#endif + base::FilePath path = GetLibassisantPath(root_path); base::ScopedNativeLibrary library = base::ScopedNativeLibrary(path); OnLibraryLoaded(std::move(library));
diff --git a/chromeos/ash/services/quick_pair/public/cpp/account_key_filter.cc b/chromeos/ash/services/quick_pair/public/cpp/account_key_filter.cc index d70a9f6..174242b 100644 --- a/chromeos/ash/services/quick_pair/public/cpp/account_key_filter.cc +++ b/chromeos/ash/services/quick_pair/public/cpp/account_key_filter.cc
@@ -16,10 +16,45 @@ namespace ash { namespace quick_pair { +namespace { + constexpr int kBitsInByte = 8; + +// SASS enabled peripherals create their Bloom filters by changing the first +// byte of either the account key in use or the most recently used account key +// according to this spec: +// https://developers.google.com/nearby/fast-pair/early-access/specifications/extensions/sass#SassInUseAccountKey constexpr uint8_t kRecentlyUsedByte = 0x05; constexpr uint8_t kInUseByte = 0x06; +// Helper to AccountKeyFilter::IsAccountKeyInFilter(). +// Performs the test to see if |data| is in |bit_sets|, a Bloom filter. +bool AccountKeyFilterTest(const std::vector<uint8_t>& data, + const std::vector<uint8_t>& bit_sets) { + std::array<uint8_t, 32> hashed = crypto::SHA256Hash(data); + + // Iterate over the hashed input in 4 byte increments, combine those 4 + // bytes into an unsigned int and use it as the index into our + // |bit_sets|. + for (size_t i = 0; i < hashed.size(); i += 4) { + uint32_t hash = uint32_t{hashed[i]} << 24 | uint32_t{hashed[i + 1]} << 16 | + uint32_t{hashed[i + 2]} << 8 | hashed[i + 3]; + + size_t num_bits = bit_sets.size() * kBitsInByte; + size_t n = hash % num_bits; + size_t byte_index = floor(n / kBitsInByte); + size_t bit_index = n % kBitsInByte; + bool is_set = (bit_sets[byte_index] >> bit_index) & 0x01; + + if (!is_set) + return false; + } + + return true; +} + +} // namespace + AccountKeyFilter::AccountKeyFilter( const NotDiscoverableAdvertisement& advertisement) : bit_sets_(advertisement.account_key_filter) { @@ -54,30 +89,7 @@ AccountKeyFilter& AccountKeyFilter::operator=(AccountKeyFilter&&) = default; AccountKeyFilter::~AccountKeyFilter() = default; -bool AccountKeyFilter::IsAccountKeyInFilter(std::vector<uint8_t> data) const { - std::array<uint8_t, 32> hashed = crypto::SHA256Hash(data); - - // Iterate over the hashed input in 4 byte increments, combine those 4 - // bytes into an unsigned int and use it as the index into our - // |bit_sets_|. - for (size_t i = 0; i < hashed.size(); i += 4) { - uint32_t hash = uint32_t{hashed[i]} << 24 | uint32_t{hashed[i + 1]} << 16 | - uint32_t{hashed[i + 2]} << 8 | hashed[i + 3]; - - size_t num_bits = bit_sets_.size() * kBitsInByte; - size_t n = hash % num_bits; - size_t byte_index = floor(n / kBitsInByte); - size_t bit_index = n % kBitsInByte; - bool is_set = (bit_sets_[byte_index] >> bit_index) & 0x01; - - if (!is_set) - return false; - } - - return true; -} - -bool AccountKeyFilter::Test( +bool AccountKeyFilter::IsAccountKeyInFilter( const std::vector<uint8_t>& account_key_bytes) const { if (bit_sets_.empty()) return false; @@ -97,9 +109,9 @@ std::vector<uint8_t> in_use_account_key(default_account_key); in_use_account_key[0] = kInUseByte; - return IsAccountKeyInFilter(default_account_key) || - IsAccountKeyInFilter(in_use_account_key) || - IsAccountKeyInFilter(recently_used_account_key); + return AccountKeyFilterTest(default_account_key, bit_sets_) || + AccountKeyFilterTest(in_use_account_key, bit_sets_) || + AccountKeyFilterTest(recently_used_account_key, bit_sets_); } } // namespace quick_pair
diff --git a/chromeos/ash/services/quick_pair/public/cpp/account_key_filter.h b/chromeos/ash/services/quick_pair/public/cpp/account_key_filter.h index 470704aa..e59eaf7c 100644 --- a/chromeos/ash/services/quick_pair/public/cpp/account_key_filter.h +++ b/chromeos/ash/services/quick_pair/public/cpp/account_key_filter.h
@@ -24,14 +24,10 @@ AccountKeyFilter& operator=(AccountKeyFilter&&); ~AccountKeyFilter(); - // Helper to Test, specifically tests whether hashed |data| - // is in the account key filter. - bool IsAccountKeyInFilter(std::vector<uint8_t> data) const; - // Tests whether the |account_key_bytes| belong to this Account Key Filter. // Note: The return value may be a false positive, but will never be a false // negative. - bool Test(const std::vector<uint8_t>& account_key_bytes) const; + bool IsAccountKeyInFilter(const std::vector<uint8_t>& account_key_bytes) const; private: std::vector<uint8_t> bit_sets_;
diff --git a/chromeos/ash/services/quick_pair/public/cpp/account_key_filter_unittest.cc b/chromeos/ash/services/quick_pair/public/cpp/account_key_filter_unittest.cc index 5785a0c6..1463a9d 100644 --- a/chromeos/ash/services/quick_pair/public/cpp/account_key_filter_unittest.cc +++ b/chromeos/ash/services/quick_pair/public/cpp/account_key_filter_unittest.cc
@@ -34,6 +34,9 @@ const std::vector<uint8_t> kSalt3{0x6C, 0xE5}; const std::vector<uint8_t> kBatteryData3{0x33, 0xE4, 0xE4, 0x4C}; +// Values for SASS enabled Pixel Buds Pro that failed to subsequent pair prior +// to ccrev.com/3953062 landing. +// Value source: b/243855406#comment24. const std::vector<uint8_t> kAccountKey4{0x04, 0x3F, 0xC1, 0x8C, 0x63, 0xDC, 0x75, 0x1A, 0xE8, 0x1A, 0xCF, 0x65, 0x10, 0x15, 0x1D, 0xB0}; @@ -46,24 +49,24 @@ TEST_F(AccountKeyFilterTest, EmptyFilter) { AccountKeyFilter filter({}, {}); - EXPECT_FALSE(filter.Test(kAccountKey1)); - EXPECT_FALSE(filter.Test(kAccountKey2)); + EXPECT_FALSE(filter.IsAccountKeyInFilter(kAccountKey1)); + EXPECT_FALSE(filter.IsAccountKeyInFilter(kAccountKey2)); } TEST_F(AccountKeyFilterTest, EmptyVectorTest) { EXPECT_FALSE( - AccountKeyFilter(kFilterBytes1, {salt}).Test(std::vector<uint8_t>(0))); + AccountKeyFilter(kFilterBytes1, {salt}).IsAccountKeyInFilter(std::vector<uint8_t>(0))); } TEST_F(AccountKeyFilterTest, SingleAccountKey_AsBytes) { - EXPECT_TRUE(AccountKeyFilter(kFilterBytes1, {salt}).Test(kAccountKey1)); + EXPECT_TRUE(AccountKeyFilter(kFilterBytes1, {salt}).IsAccountKeyInFilter(kAccountKey1)); } TEST_F(AccountKeyFilterTest, TwoAccountKeys_AsBytes) { AccountKeyFilter filter(kFilterBytes1And2, {salt}); - EXPECT_TRUE(filter.Test(kAccountKey1)); - EXPECT_TRUE(filter.Test(kAccountKey2)); + EXPECT_TRUE(filter.IsAccountKeyInFilter(kAccountKey1)); + EXPECT_TRUE(filter.IsAccountKeyInFilter(kAccountKey2)); } TEST_F(AccountKeyFilterTest, MissingAccountKey) { @@ -71,8 +74,8 @@ 0x77, 0x88, 0x99, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; - EXPECT_FALSE(AccountKeyFilter(kFilterBytes1, {salt}).Test(account_key)); - EXPECT_FALSE(AccountKeyFilter(kFilterBytes1And2, {salt}).Test(account_key)); + EXPECT_FALSE(AccountKeyFilter(kFilterBytes1, {salt}).IsAccountKeyInFilter(account_key)); + EXPECT_FALSE(AccountKeyFilter(kFilterBytes1And2, {salt}).IsAccountKeyInFilter(account_key)); } TEST_F(AccountKeyFilterTest, WithBatteryData) { @@ -81,7 +84,7 @@ salt_values.push_back(byte); EXPECT_TRUE( - AccountKeyFilter(kFilterWithBattery, salt_values).Test(kAccountKey1)); + AccountKeyFilter(kFilterWithBattery, salt_values).IsAccountKeyInFilter(kAccountKey1)); } TEST_F(AccountKeyFilterTest, TwoSaltBytes) { @@ -92,17 +95,19 @@ salt_values.insert(salt_values.end(), kBatteryData3.begin(), kBatteryData3.end()); - EXPECT_TRUE(AccountKeyFilter(kFilter3, salt_values).Test(kAccountKey3)); + EXPECT_TRUE(AccountKeyFilter(kFilter3, salt_values).IsAccountKeyInFilter(kAccountKey3)); } +// Regression test for b/243855406. TEST_F(AccountKeyFilterTest, SassEnabledPeripheral) { - // Devices with battery data create account filters by concatenating data to - // end of salt bytes + // Account Key, Salt, and Battery Data values used are specific to an observed + // SASS device failure explained at the variable declaration for + // |kAccountKey4|, |kSalt4|, and |kBatteryData4|. std::vector<uint8_t> salt_values{}; salt_values.insert(salt_values.end(), kSalt4.begin(), kSalt4.end()); salt_values.insert(salt_values.end(), kBatteryData4.begin(), kBatteryData4.end()); - EXPECT_TRUE(AccountKeyFilter(kFilter4, salt_values).Test(kAccountKey4)); + EXPECT_TRUE(AccountKeyFilter(kFilter4, salt_values).IsAccountKeyInFilter(kAccountKey4)); } } // namespace quick_pair
diff --git a/chromeos/crosapi/mojom/local_printer.mojom b/chromeos/crosapi/mojom/local_printer.mojom index 4fe34ef..0ef61777 100644 --- a/chromeos/crosapi/mojom/local_printer.mojom +++ b/chromeos/crosapi/mojom/local_printer.mojom
@@ -272,6 +272,20 @@ kExtension, }; +// This union of structs represents the OAuth-related status of a printer. +[Stable] +struct OAuthNotNeeded {}; +[Stable] +struct OAuthError {}; +[Stable] +struct OAuthAccessToken { string token; }; +[Stable] +union GetOAuthAccessTokenResult { + OAuthNotNeeded none; + OAuthError error; + OAuthAccessToken token; +}; + // This interface is used to query information about local printers // associated with the current Ash profile that can be used for // printing from Lacros. @@ -339,4 +353,9 @@ AddPrintJobObserver@13( pending_remote<PrintJobObserver> observer, PrintJobSource source) => (); + + // Checks if the printer requires an OAuth. If yes, returns the access token. + [MinVersion=4] + GetOAuthAccessToken@14(string printer_id) + => (GetOAuthAccessTokenResult oauth_result); };
diff --git a/chromeos/profiles/orderfile.newest.txt b/chromeos/profiles/orderfile.newest.txt index a417860..9cfd6d2 100644 --- a/chromeos/profiles/orderfile.newest.txt +++ b/chromeos/profiles/orderfile.newest.txt
@@ -1 +1 @@ -chromeos-chrome-orderfile-field-108-5359.6-1666607304-benchmark-108.0.5359.24-r1.orderfile.xz +chromeos-chrome-orderfile-field-109-5344.0-1666002304-benchmark-109.0.5367.0-r1.orderfile.xz
diff --git a/chromeos/ui/frame/BUILD.gn b/chromeos/ui/frame/BUILD.gn index fe437d4..59b8b6c5 100644 --- a/chromeos/ui/frame/BUILD.gn +++ b/chromeos/ui/frame/BUILD.gn
@@ -34,6 +34,8 @@ "frame_header.h", "frame_utils.cc", "frame_utils.h", + "header_view.cc", + "header_view.h", "highlight_border_overlay.cc", "highlight_border_overlay.h", "immersive/immersive_context.cc",
diff --git a/ash/frame/header_view.cc b/chromeos/ui/frame/header_view.cc similarity index 89% rename from ash/frame/header_view.cc rename to chromeos/ui/frame/header_view.cc index 014bcfb..3208ffa 100644 --- a/ash/frame/header_view.cc +++ b/chromeos/ui/frame/header_view.cc
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/frame/header_view.h" +#include "chromeos/ui/frame/header_view.h" #include <memory> +#include <vector> -#include "ash/shell.h" -#include "ash/wm/tablet_mode/tablet_mode_controller.h" -#include "ash/wm/window_state.h" #include "base/auto_reset.h" +#include "chromeos/ui/base/tablet_state.h" #include "chromeos/ui/base/window_properties.h" +#include "chromeos/ui/base/window_state_type.h" #include "chromeos/ui/frame/caption_buttons/caption_button_model.h" #include "chromeos/ui/frame/caption_buttons/frame_back_button.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" @@ -19,11 +19,12 @@ #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/base/ui_base_features.h" #include "ui/compositor/layer.h" +#include "ui/display/screen.h" #include "ui/views/controls/image_view.h" #include "ui/views/widget/widget.h" #include "ui/views/window/non_client_view.h" -namespace ash { +namespace chromeos { using ::chromeos::DefaultFrameHeader; using ::chromeos::kFrameActiveColorKey; @@ -35,7 +36,8 @@ // as caption buttons. class HeaderView::HeaderContentView : public views::View { public: - HeaderContentView(HeaderView* header_view) : header_view_(header_view) {} + explicit HeaderContentView(HeaderView* header_view) + : header_view_(header_view) {} HeaderContentView(const HeaderContentView&) = delete; HeaderContentView& operator=(const HeaderContentView&) = delete; @@ -84,12 +86,11 @@ aura::Window* window = target_widget_->GetNativeWindow(); window_observation_.Observe(window); - Shell::Get()->tablet_mode_controller()->AddObserver(this); + display::Screen::GetScreen()->AddObserver(this); } HeaderView::~HeaderView() { - if (Shell::Get()->tablet_mode_controller()) - Shell::Get()->tablet_mode_controller()->RemoveObserver(this); + display::Screen::GetScreen()->RemoveObserver(this); } void HeaderView::SchedulePaintForTitle() { @@ -182,25 +183,6 @@ return views::View::IsDrawn(); } -void HeaderView::OnTabletModeStarted() { - UpdateCaptionButtonsVisibility(); - caption_button_container_->UpdateCaptionButtonState(true /*=animate*/); - parent()->Layout(); - if (target_widget_ && - Shell::Get()->tablet_mode_controller()->ShouldAutoHideTitlebars( - target_widget_)) { - target_widget_->non_client_view()->Layout(); - } -} - -void HeaderView::OnTabletModeEnded() { - UpdateCaptionButtonsVisibility(); - caption_button_container_->UpdateCaptionButtonState(true /*=animate*/); - parent()->Layout(); - if (target_widget_) - target_widget_->non_client_view()->Layout(); -} - void HeaderView::OnWindowPropertyChanged(aura::Window* window, const void* key, intptr_t old) { @@ -244,6 +226,30 @@ } } +void HeaderView::OnDisplayTabletStateChanged(display::TabletState state) { + switch (state) { + case display::TabletState::kInTabletMode: + UpdateCaptionButtonsVisibility(); + caption_button_container_->UpdateCaptionButtonState(true /*=animate*/); + parent()->Layout(); + if (target_widget_) { + target_widget_->non_client_view()->Layout(); + } + break; + case display::TabletState::kInClamshellMode: + UpdateCaptionButtonsVisibility(); + caption_button_container_->UpdateCaptionButtonState(true /*=animate*/); + parent()->Layout(); + if (target_widget_) + target_widget_->non_client_view()->Layout(); + break; + case display::TabletState::kEnteringTabletMode: + break; + case display::TabletState::kExitingTabletMode: + break; + } +} + views::View* HeaderView::avatar_icon() const { return avatar_icon_; } @@ -373,4 +379,4 @@ BEGIN_METADATA(HeaderView, views::View) END_METADATA -} // namespace ash +} // namespace chromeos
diff --git a/ash/frame/header_view.h b/chromeos/ui/frame/header_view.h similarity index 93% rename from ash/frame/header_view.h rename to chromeos/ui/frame/header_view.h index bc0e493..b185c45e9 100644 --- a/ash/frame/header_view.h +++ b/chromeos/ui/frame/header_view.h
@@ -2,14 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ASH_FRAME_HEADER_VIEW_H_ -#define ASH_FRAME_HEADER_VIEW_H_ +#ifndef CHROMEOS_UI_FRAME_HEADER_VIEW_H_ +#define CHROMEOS_UI_FRAME_HEADER_VIEW_H_ #include <memory> +#include <utility> +#include <vector> -#include "ash/ash_export.h" -#include "ash/public/cpp/tablet_mode_observer.h" #include "base/callback.h" +#include "base/component_export.h" #include "base/scoped_observation.h" #include "chromeos/ui/frame/frame_header.h" #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_delegate.h" @@ -20,11 +21,6 @@ #include "ui/display/display_observer.h" #include "ui/views/view.h" -namespace chromeos { -class DefaultFrameHeader; -class FrameCaptionButtonContainerView; -} - namespace gfx { class ImageSkia; } @@ -34,18 +30,20 @@ class ImageView; class Widget; class NonClientFrameView; -} +} // namespace views -namespace ash { +namespace chromeos { + +class DefaultFrameHeader; +class FrameCaptionButtonContainerView; enum class FrameBackButtonState; // View which paints the frame header (title, caption buttons...). It slides off // and on screen in immersive fullscreen. -class ASH_EXPORT HeaderView +class COMPONENT_EXPORT(CHROMEOS_UI_FRAME) HeaderView : public views::View, public chromeos::ImmersiveFullscreenControllerDelegate, - public TabletModeObserver, public aura::WindowObserver, public display::DisplayObserver { public: @@ -100,10 +98,6 @@ void ChildPreferredSizeChanged(views::View* child) override; bool IsDrawn() const override; - // TabletModeObserver: - void OnTabletModeStarted() override; - void OnTabletModeEnded() override; - // aura::WindowObserver: void OnWindowPropertyChanged(aura::Window* window, const void* key, @@ -113,6 +107,7 @@ // display::DisplayObserver: void OnDisplayMetricsChanged(const display::Display& display, uint32_t changed_metrics) override; + void OnDisplayTabletStateChanged(display::TabletState state) override; chromeos::FrameCaptionButtonContainerView* caption_button_container() { return caption_button_container_; @@ -195,6 +190,6 @@ window_observation_{this}; }; -} // namespace ash +} // namespace chromeos -#endif // ASH_FRAME_HEADER_VIEW_H_ +#endif // CHROMEOS_UI_FRAME_HEADER_VIEW_H_
diff --git a/components/desks_storage/core/desk_sync_bridge.cc b/components/desks_storage/core/desk_sync_bridge.cc index f5a54c53..1600da6 100644 --- a/components/desks_storage/core/desk_sync_bridge.cc +++ b/components/desks_storage/core/desk_sync_bridge.cc
@@ -12,7 +12,6 @@ #include "base/guid.h" #include "base/json/json_writer.h" #include "base/memory/ptr_util.h" -#include "base/notreached.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h"
diff --git a/components/desks_storage/core/desk_template_conversion.cc b/components/desks_storage/core/desk_template_conversion.cc index 3a84fda6..efc6c43 100644 --- a/components/desks_storage/core/desk_template_conversion.cc +++ b/components/desks_storage/core/desk_template_conversion.cc
@@ -991,7 +991,6 @@ case ash::DeskTemplateType::kSaveAndRecall: return kDeskTypeSaveAndRecall; case ash::DeskTemplateType::kUnknown: - NOTREACHED(); return kDeskTypeUnknown; } } @@ -1850,8 +1849,8 @@ out_entry_proto->set_desk_type( SyncDeskType::WorkspaceDeskSpecifics_DeskType_SAVE_AND_RECALL); return; + // Do nothing if type is unknown. case DeskTemplateType::kUnknown: - NOTREACHED(); return; } }
diff --git a/components/exo/client_controlled_shell_surface.cc b/components/exo/client_controlled_shell_surface.cc index 211a123..260bb4d3 100644 --- a/components/exo/client_controlled_shell_surface.cc +++ b/components/exo/client_controlled_shell_surface.cc
@@ -8,7 +8,6 @@ #include <utility> #include "ash/constants/ash_features.h" -#include "ash/frame/header_view.h" #include "ash/frame/non_client_frame_view_ash.h" #include "ash/frame/wide_frame_view.h" #include "ash/public/cpp/arc_resize_lock_type.h" @@ -43,6 +42,7 @@ #include "chromeos/ui/base/window_state_type.h" #include "chromeos/ui/frame/caption_buttons/caption_button_model.h" #include "chromeos/ui/frame/default_frame_header.h" +#include "chromeos/ui/frame/header_view.h" #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "components/exo/shell_surface_util.h" #include "components/exo/surface.h" @@ -1398,7 +1398,7 @@ float dsf_to_default_dsf = device_scale_factor / scale_; width = base::ClampRound(shadow_bounds_->width() * dsf_to_default_dsf); } - static_cast<ash::HeaderView*>(GetFrameView()->GetHeaderView()) + static_cast<chromeos::HeaderView*>(GetFrameView()->GetHeaderView()) ->SetWidthInPixels(width); }
diff --git a/components/exo/client_controlled_shell_surface_unittest.cc b/components/exo/client_controlled_shell_surface_unittest.cc index d478e7c..fa326c7 100644 --- a/components/exo/client_controlled_shell_surface_unittest.cc +++ b/components/exo/client_controlled_shell_surface_unittest.cc
@@ -5,7 +5,6 @@ #include "components/exo/client_controlled_shell_surface.h" #include "ash/display/screen_orientation_controller.h" -#include "ash/frame/header_view.h" #include "ash/frame/non_client_frame_view_ash.h" #include "ash/frame/wide_frame_view.h" #include "ash/public/cpp/arc_resize_lock_type.h" @@ -41,6 +40,7 @@ #include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/frame/caption_buttons/caption_button_model.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" +#include "chromeos/ui/frame/header_view.h" #include "components/app_restore/full_restore_utils.h" #include "components/app_restore/window_properties.h" #include "components/exo/buffer.h" @@ -1436,7 +1436,7 @@ static_cast<ash::NonClientFrameViewAsh*>( shell_surface->GetWidget()->non_client_view()->frame_view()); chromeos::FrameCaptionButtonContainerView* container = - static_cast<ash::HeaderView*>(frame_view->GetHeaderView()) + static_cast<chromeos::HeaderView*>(frame_view->GetHeaderView()) ->caption_button_container(); // Visible
diff --git a/components/heap_profiling/in_process/BUILD.gn b/components/heap_profiling/in_process/BUILD.gn index 9c25f7f..a58d45d 100644 --- a/components/heap_profiling/in_process/BUILD.gn +++ b/components/heap_profiling/in_process/BUILD.gn
@@ -20,6 +20,7 @@ "//components/metrics", "//components/metrics:child_call_stack_profile_builder", "//components/services/heap_profiling/public/cpp:cpp", + "//components/variations", "//components/version_info", ] } @@ -41,6 +42,7 @@ "//components/metrics", "//components/metrics:child_call_stack_profile_builder", "//components/metrics/public/mojom:call_stack_mojo_bindings", + "//components/variations", "//components/version_info", "//mojo/public/cpp/bindings", ]
diff --git a/components/heap_profiling/in_process/DEPS b/components/heap_profiling/in_process/DEPS index 3a5daea..9425fd8c 100644 --- a/components/heap_profiling/in_process/DEPS +++ b/components/heap_profiling/in_process/DEPS
@@ -2,6 +2,7 @@ "+components/metrics/call_stack_profile_builder.h", "+components/metrics/call_stack_profile_params.h", "+components/services/heap_profiling/public", + "+components/variations/variations_switches.h", "+components/version_info", ]
diff --git a/components/heap_profiling/in_process/heap_profiler_parameters.cc b/components/heap_profiling/in_process/heap_profiler_parameters.cc index c402ed1..b52e8b4d 100644 --- a/components/heap_profiling/in_process/heap_profiler_parameters.cc +++ b/components/heap_profiling/in_process/heap_profiler_parameters.cc
@@ -6,6 +6,7 @@ #include <string> +#include "base/command_line.h" #include "base/feature_list.h" #include "base/json/json_reader.h" #include "base/json/json_value_converter.h" @@ -15,6 +16,7 @@ #include "base/values.h" #include "build/build_config.h" #include "components/metrics/call_stack_profile_params.h" +#include "components/variations/variations_switches.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace heap_profiling { @@ -164,9 +166,15 @@ HeapProfilerParameters params = kDefaultHeapProfilerParameters; + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + variations::switches::kEnableBenchmarking) || + !base::FeatureList::IsEnabled(kHeapProfilerReporting)) { + params.is_supported = false; + return params; + } + // By default only the browser process is supported. - params.is_supported = base::FeatureList::IsEnabled(kHeapProfilerReporting) && - process_type == Process::kBrowser; + params.is_supported = (process_type == Process::kBrowser); // Override with field trial parameters if any are set. if (!params.UpdateFromJSON(kDefaultParameters.Get())) {
diff --git a/components/heap_profiling/in_process/heap_profiler_parameters_unittest.cc b/components/heap_profiling/in_process/heap_profiler_parameters_unittest.cc index 03df531..2efa3bc 100644 --- a/components/heap_profiling/in_process/heap_profiler_parameters_unittest.cc +++ b/components/heap_profiling/in_process/heap_profiler_parameters_unittest.cc
@@ -4,9 +4,11 @@ #include "components/heap_profiling/in_process/heap_profiler_parameters.h" +#include "base/command_line.h" #include "base/test/scoped_feature_list.h" #include "base/time/time.h" #include "components/metrics/call_stack_profile_params.h" +#include "components/variations/variations_switches.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -95,6 +97,25 @@ EXPECT_FALSE(params.is_supported); } +// Test that heap profiling is not supported for any process type when +// --enable-benchmarking is specified on the command line. +TEST(HeapProfilerParametersTest, EnableBenchmarking) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + variations::switches::kEnableBenchmarking); + + using Process = metrics::CallStackProfileParams::Process; + EXPECT_FALSE(GetDefaultHeapProfilerParameters().is_supported); + EXPECT_FALSE( + GetHeapProfilerParametersForProcess(Process::kBrowser).is_supported); + EXPECT_FALSE(GetHeapProfilerParametersForProcess(Process::kGpu).is_supported); + EXPECT_FALSE( + GetHeapProfilerParametersForProcess(Process::kRenderer).is_supported); + EXPECT_FALSE( + GetHeapProfilerParametersForProcess(Process::kUtility).is_supported); + EXPECT_FALSE(GetHeapProfilerParametersForProcess(Process::kNetworkService) + .is_supported); +} + TEST(HeapProfilerParametersTest, ApplyParameters) { constexpr char kDefaultParams[] = R"({ "is-supported": false,
diff --git a/components/history_clusters/core/history_clusters_db_tasks.cc b/components/history_clusters/core/history_clusters_db_tasks.cc index c2d9cfa0..c782ac6 100644 --- a/components/history_clusters/core/history_clusters_db_tasks.cc +++ b/components/history_clusters/core/history_clusters_db_tasks.cc
@@ -173,10 +173,8 @@ : false; if (is_clustered && recent_first_) continuation_params_.exhausted_unclustered_visits = true; - // Filter out visits from sync. - // TODO(manukh): Consider allowing the clustering backend to handle sync - // visits. - if (!is_clustered && visit.source != history::SOURCE_SYNCED) + + if (!is_clustered) annotated_visits_.push_back(std::move(visit)); }
diff --git a/components/history_clusters/core/history_clusters_service_unittest.cc b/components/history_clusters/core/history_clusters_service_unittest.cc index 5ba26595..81e7f82 100644 --- a/components/history_clusters/core/history_clusters_service_unittest.cc +++ b/components/history_clusters/core/history_clusters_service_unittest.cc
@@ -213,9 +213,8 @@ std::vector<history::AnnotatedVisit> visits = test_clustering_backend_->LastClusteredVisits(); - // Visits 2, 3, and 5 are 1-day-old; visit 3 is a synced visit and therefore - // excluded. - ASSERT_EQ(visits.size(), 2u); + // Visits 2, 3, and 5 are 1-day-old; visit 3 is a synced visit. + ASSERT_EQ(visits.size(), 3u); auto& visit = visits[0]; EXPECT_EQ(visit.visit_row.visit_id, 5); @@ -226,6 +225,14 @@ EXPECT_EQ(visit.context_annotations.page_end_reason, 5); visit = visits[1]; + EXPECT_EQ(visit.visit_row.visit_id, 3); + EXPECT_EQ(visit.visit_row.visit_time, + GetHardcodedTestVisits()[2].visit_row.visit_time); + EXPECT_EQ(visit.visit_row.visit_duration, base::Seconds(20)); + EXPECT_EQ(visit.url_row.url(), "https://synched-visit.com/"); + EXPECT_EQ(visit.context_annotations.page_end_reason, 5); + + visit = visits[2]; EXPECT_EQ(visit.visit_row.visit_id, 2); EXPECT_EQ(visit.visit_row.visit_time, GetHardcodedTestVisits()[1].visit_row.visit_time); @@ -432,13 +439,13 @@ QueryClustersContinuationParams continuation_params = {}; continuation_params.continuation_time = base::Time::Now(); - // 1st query should return visits 2, 5, & 6, the good, 1-day-old visits. - // Visits 3, 0, and 10, also 1-day-old, are excluded since they're synced, - // missing history rows, and non-visible transition respectively. + // 1st query should return visits 2, 3, 5, & 6, the good, 1-day-old visits. + // Visit 0 is excluded because it's missing history rows. Visit 10 is excluded + // because it has a non-visible transition. { const auto [clusters, visits] = NextQueryClusters(continuation_params); EXPECT_THAT(GetClusterIds(clusters), testing::ElementsAre()); - EXPECT_THAT(GetVisitIds(visits), testing::ElementsAre(5, 2, 6)); + EXPECT_THAT(GetVisitIds(visits), testing::ElementsAre(5, 3, 2, 6)); EXPECT_TRUE(continuation_params.is_continuation); EXPECT_FALSE(continuation_params.is_partial_day); } @@ -695,16 +702,6 @@ // Create 5 persisted visits with visit times 2, 1, 1, 60, and 1 days ago. AddHardcodedTestDataToHistoryService(); - // Add a sync visit on a day without other visits in order to verify a day - // with only sync visits doesn't interrupt `GetAnnotatedVisitsToCluster`'s - // intention of iterating until a visit is found. - history::AnnotatedVisit sync_visit; - sync_visit.url_row.set_id(1); - sync_visit.visit_row.visit_id = 10; - sync_visit.visit_row.visit_time = base::Time::Now() - base::Days(15); - sync_visit.source = history::VisitSource::SOURCE_SYNCED; - AddCompleteVisit(sync_visit); - // Helper to repeatedly schedule a `GetAnnotatedVisitsToCluster`, with the // continuation time returned from the previous task, and return the visits // it returns. @@ -731,10 +728,10 @@ } { // 3rd query should return the next oldest, 1-day-old visits. Visit 3 is - // excluded as it's from sync. + // is from sync, and is still included. const auto [clusters, visits] = NextVisits(continuation_params, false, 0); EXPECT_TRUE(clusters.empty()); - EXPECT_THAT(GetVisitIds(visits), testing::ElementsAre(5, 2)); + EXPECT_THAT(GetVisitIds(visits), testing::ElementsAre(5, 3, 2)); EXPECT_TRUE(continuation_params.is_continuation); EXPECT_FALSE(continuation_params.exhausted_unclustered_visits); EXPECT_FALSE(continuation_params.exhausted_all_visits); @@ -881,7 +878,7 @@ histogram_tester.ExpectBucketCount( "History.Clusters.Backend.NumClustersReturned", 2, 1); histogram_tester.ExpectBucketCount( - "History.Clusters.Backend.NumVisitsToCluster", 2, 1); + "History.Clusters.Backend.NumVisitsToCluster", 3, 1); histogram_tester.ExpectTotalCount( "History.Clusters.Backend.GetMostRecentClusters." "ComputeClustersLatency",
diff --git a/components/infobars/core/infobar_delegate.cc b/components/infobars/core/infobar_delegate.cc index 399556a..3b703d6b 100644 --- a/components/infobars/core/infobar_delegate.cc +++ b/components/infobars/core/infobar_delegate.cc
@@ -40,7 +40,8 @@ #if !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_ANDROID) const gfx::VectorIcon& vector_icon = GetVectorIcon(); if (!vector_icon.is_empty()) - return ui::ImageModel::FromVectorIcon(vector_icon, ui::kColorAccent, 20); + return ui::ImageModel::FromVectorIcon(vector_icon, ui::kColorInfoBarIcon, + 20); #endif int icon_id = GetIconId();
diff --git a/components/module_installer/android/java/src/org/chromium/components/module_installer/engine/SplitCompatEngine.java b/components/module_installer/android/java/src/org/chromium/components/module_installer/engine/SplitCompatEngine.java index bacb821..0c76f34 100644 --- a/components/module_installer/android/java/src/org/chromium/components/module_installer/engine/SplitCompatEngine.java +++ b/components/module_installer/android/java/src/org/chromium/components/module_installer/engine/SplitCompatEngine.java
@@ -90,25 +90,27 @@ private SplitInstallStateUpdatedListener getStatusUpdateListener() { return state -> { - if (state.moduleNames().size() != 1) { - throw new UnsupportedOperationException("Only one module supported."); - } + assert !state.moduleNames().isEmpty(); int status = state.status(); - String moduleName = state.moduleNames().get(0); + List<String> modules = state.moduleNames(); - switch (status) { - case SplitInstallSessionStatus.INSTALLED: - mFacade.updateCrashKeys(); - notifyListeners(moduleName, true); - break; - case SplitInstallSessionStatus.FAILED: - notifyListeners(moduleName, false); - mFacade.getLogger().logStatusFailure(moduleName, state.errorCode()); - break; + if (status == SplitInstallSessionStatus.INSTALLED) { + mFacade.updateCrashKeys(); } - mFacade.getLogger().logStatus(moduleName, status); + for (String moduleName : modules) { + switch (status) { + case SplitInstallSessionStatus.INSTALLED: + notifyListeners(moduleName, true); + break; + case SplitInstallSessionStatus.FAILED: + notifyListeners(moduleName, false); + mFacade.getLogger().logStatusFailure(moduleName, state.errorCode()); + break; + } + mFacade.getLogger().logStatus(moduleName, status); + } }; } @@ -118,6 +120,7 @@ } sSessions.remove(moduleName); + unregisterUpdateListener(); }
diff --git a/components/module_installer/android/junit/src/org/chromium/components/module_installer/engine/SplitCompatEngineTest.java b/components/module_installer/android/junit/src/org/chromium/components/module_installer/engine/SplitCompatEngineTest.java index d0bf3d0..a120fb0c 100644 --- a/components/module_installer/android/junit/src/org/chromium/components/module_installer/engine/SplitCompatEngineTest.java +++ b/components/module_installer/android/junit/src/org/chromium/components/module_installer/engine/SplitCompatEngineTest.java
@@ -209,82 +209,74 @@ verify(mLogger, times(2)).logRequestStart(moduleName); } - @Test(expected = UnsupportedOperationException.class) - public void whenInstallingWithMoreThanOneModule_verifyException() { - // Arrange. - String moduleName = "whenInstallingWithMoreThanOneModule_verifyException"; - InstallListener listener = mock(InstallListener.class); - - // Mock SplitInstallSessionState. - SplitInstallSessionState state = mock(SplitInstallSessionState.class); - doReturn(Arrays.asList("m1", "m2")).when(state).moduleNames(); - - ArgumentCaptor<SplitInstallStateUpdatedListener> arg = - ArgumentCaptor.forClass(SplitInstallStateUpdatedListener.class); - - // Act & Assert. - mInstaller.install(moduleName, listener); - verify(mManager).registerListener(arg.capture()); - arg.getValue().onStateUpdate(state); - } - @Test public void whenInstalled_verifyListenerAndLogger() { // Arrange. - String moduleName = "whenInstalled_verifyListenerAndLogger"; + String moduleName1 = "whenInstalled_verifyListenerAndLogger1"; + String moduleName2 = "whenInstalled_verifyListenerAndLogger2"; Integer status = SplitInstallSessionStatus.INSTALLED; - InstallListener listener = mock(InstallListener.class); + InstallListener listener1 = mock(InstallListener.class); + InstallListener listener2 = mock(InstallListener.class); // Mock SplitInstallSessionState. SplitInstallSessionState state = mock(SplitInstallSessionState.class); doReturn(status).when(state).status(); - doReturn(Arrays.asList(moduleName)).when(state).moduleNames(); + doReturn(Arrays.asList(moduleName1, moduleName2)).when(state).moduleNames(); - InOrder inOrder = inOrder(listener, mManager, mLogger, mInstallerFacade); + InOrder inOrder = inOrder(listener1, listener2, mManager, mLogger, mInstallerFacade); ArgumentCaptor<SplitInstallStateUpdatedListener> arg = ArgumentCaptor.forClass(SplitInstallStateUpdatedListener.class); // Act. - mInstaller.install(moduleName, listener); + mInstaller.install(moduleName1, listener1); + mInstaller.install(moduleName2, listener2); verify(mManager).registerListener(arg.capture()); arg.getValue().onStateUpdate(state); // Assert. inOrder.verify(mInstallerFacade, times(1)).updateCrashKeys(); - inOrder.verify(listener, times(1)).onComplete(true); + inOrder.verify(listener1, times(1)).onComplete(true); + inOrder.verify(mLogger, times(1)).logStatus(moduleName1, status); + inOrder.verify(listener2, times(1)).onComplete(true); inOrder.verify(mManager, times(1)).unregisterListener(any()); - inOrder.verify(mLogger, times(1)).logStatus(moduleName, status); + inOrder.verify(mLogger, times(1)).logStatus(moduleName2, status); inOrder.verifyNoMoreInteractions(); } @Test public void whenFailureToInstall_verifyListenerAndLogger() { // Arrange. - String moduleName = "whenFailureToInstall_verifyListenerAndLogger"; + String moduleName1 = "whenFailureToInstall_verifyListenerAndLogger1"; + String moduleName2 = "whenFailureToInstall_verifyListenerAndLogger2"; Integer status = SplitInstallSessionStatus.FAILED; Integer errorCode = SplitInstallErrorCode.NO_ERROR; - InstallListener listener = mock(InstallListener.class); + InstallListener listener1 = mock(InstallListener.class); + InstallListener listener2 = mock(InstallListener.class); // Mock SplitInstallSessionState. SplitInstallSessionState state = mock(SplitInstallSessionState.class); doReturn(status).when(state).status(); doReturn(errorCode).when(state).errorCode(); - doReturn(Arrays.asList(moduleName)).when(state).moduleNames(); + doReturn(Arrays.asList(moduleName1, moduleName2)).when(state).moduleNames(); - InOrder inOrder = inOrder(listener, mLogger, mManager); + InOrder inOrder = inOrder(listener1, listener2, mLogger, mManager); ArgumentCaptor<SplitInstallStateUpdatedListener> arg = ArgumentCaptor.forClass(SplitInstallStateUpdatedListener.class); // Act. - mInstaller.install(moduleName, listener); + mInstaller.install(moduleName1, listener1); + mInstaller.install(moduleName2, listener2); verify(mManager).registerListener(arg.capture()); arg.getValue().onStateUpdate(state); // Assert. - inOrder.verify(listener, times(1)).onComplete(false); + inOrder.verify(listener1, times(1)).onComplete(false); + inOrder.verify(mLogger, times(1)).logStatusFailure(moduleName1, errorCode); + inOrder.verify(mLogger, times(1)).logStatus(moduleName1, status); + inOrder.verify(listener2, times(1)).onComplete(false); inOrder.verify(mManager, times(1)).unregisterListener(any()); - inOrder.verify(mLogger, times(1)).logStatusFailure(moduleName, errorCode); - inOrder.verify(mLogger, times(1)).logStatus(moduleName, status); + inOrder.verify(mLogger, times(1)).logStatusFailure(moduleName2, errorCode); + inOrder.verify(mLogger, times(1)).logStatus(moduleName2, status); inOrder.verifyNoMoreInteractions(); }
diff --git a/components/reporting/storage/storage.cc b/components/reporting/storage/storage.cc index 32aca65..701db8d7 100644 --- a/components/reporting/storage/storage.cc +++ b/components/reporting/storage/storage.cc
@@ -486,19 +486,14 @@ dir_enum, base::BindRepeating( [](uint64_t new_file_index, const base::FilePath& full_name) { - const auto extension = full_name.Extension(); - if (extension.empty()) { - // Should not happen, will remove this file. - return true; - } - uint64_t file_index = 0; - if (!base::StringToUint64(extension.substr(1), &file_index)) { - // Bad extension - not a number. Should not happen, will remove - // this file. - return true; - } - if (file_index < new_file_index) { - // Lower index file, will remove it. + const auto file_index = + StorageQueue::GetFileSequenceIdFromPath(full_name); + if (!file_index.ok() || // Should not happen, will remove file. + file_index.ValueOrDie() < + static_cast<int64_t>( + new_file_index)) { // Lower index file, will remove + // it. + return true; } return false; @@ -522,25 +517,24 @@ // Duplicate file name. Should not happen. continue; } - const auto extension = full_name.Extension(); - if (extension.empty()) { - // Should not happen. + const auto file_index = + StorageQueue::GetFileSequenceIdFromPath(full_name); + if (!file_index.ok()) { // Shouldn't happen, something went wrong. continue; } - uint64_t file_index = 0; - bool success = base::StringToUint64(extension.substr(1), &file_index); - if (!success) { - // Bad extension - not a number. Should not happen (file is corrupt). - continue; - } - if (!found_key_files->emplace(file_index, full_name).second) { + if (!found_key_files + ->emplace(static_cast<uint64_t>(file_index.ValueOrDie()), + full_name) + .second) { // Duplicate extension (e.g., 01 and 001). Should not happen (file is // corrupt). continue; } // Set 'next_key_file_index_' to a number which is definitely not used. - if (next_key_file_index_.load() <= file_index) { - next_key_file_index_.store(file_index + 1); + if (static_cast<int64_t>(next_key_file_index_.load()) <= + file_index.ValueOrDie()) { + next_key_file_index_.store( + static_cast<uint64_t>(file_index.ValueOrDie() + 1)); } } }
diff --git a/components/reporting/storage/storage_queue.cc b/components/reporting/storage/storage_queue.cc index beda370..9567376 100644 --- a/components/reporting/storage/storage_queue.cc +++ b/components/reporting/storage/storage_queue.cc
@@ -304,11 +304,31 @@ return Status::StatusOK(); } +StatusOr<int64_t> StorageQueue::GetFileSequenceIdFromPath( + const base::FilePath& file_name) { + const auto extension = file_name.FinalExtension(); + if (extension.empty() || extension == FILE_PATH_LITERAL(".")) { + return Status(error::INTERNAL, + base::StrCat({"File has no extension: '", + file_name.MaybeAsASCII(), "'"})); + } + int64_t file_sequence_id = 0; + const bool success = + base::StringToInt64(extension.substr(1), &file_sequence_id); + if (!success) { + return Status(error::INTERNAL, + base::StrCat({"File extension does not parse: '", + file_name.MaybeAsASCII(), "'"})); + } + + return file_sequence_id; +} + StatusOr<int64_t> StorageQueue::AddDataFile( const base::FilePath& full_name, const base::FileEnumerator::FileInfo& file_info) { ASSIGN_OR_RETURN(int64_t file_sequence_id, - SingleFile::GetFileSequenceIdFromPath(full_name)); + GetFileSequenceIdFromPath(full_name)); RETURN_IF_ERROR(SetGenerationId(full_name)); auto file_or_status = SingleFile::Create(full_name, file_info.GetSize(), @@ -723,7 +743,7 @@ for (auto full_name = dir_enum.Next(); !full_name.empty(); full_name = dir_enum.Next()) { const auto file_sequence_id = - SingleFile::GetFileSequenceIdFromPath(dir_enum.GetInfo().GetName()); + GetFileSequenceIdFromPath(dir_enum.GetInfo().GetName()); if (!file_sequence_id.ok()) { continue; } @@ -796,8 +816,7 @@ dir_enum, base::BindRepeating( [](int64_t sequence_id_to_keep, const base::FilePath& full_name) { - const auto sequence_id = - SingleFile::GetFileSequenceIdFromPath(full_name); + const auto sequence_id = GetFileSequenceIdFromPath(full_name); if (!sequence_id.ok()) { return false; } @@ -1987,26 +2006,6 @@ new SingleFile(filename, size, memory_resource, disk_space_resource)); } -StatusOr<int64_t> StorageQueue::SingleFile::GetFileSequenceIdFromPath( - const base::FilePath& file_name) { - const auto extension = file_name.FinalExtension(); - if (extension.empty() || extension == FILE_PATH_LITERAL(".")) { - return Status(error::INTERNAL, - base::StrCat({"File has no extension: '", - file_name.MaybeAsASCII(), "'"})); - } - int64_t file_sequence_id = 0; - const bool success = - base::StringToInt64(extension.substr(1), &file_sequence_id); - if (!success) { - return Status(error::INTERNAL, - base::StrCat({"File extension does not parse: '", - file_name.MaybeAsASCII(), "'"})); - } - - return file_sequence_id; -} - StorageQueue::SingleFile::SingleFile( const base::FilePath& filename, int64_t size,
diff --git a/components/reporting/storage/storage_queue.h b/components/reporting/storage/storage_queue.h index 672ff20..78a7295 100644 --- a/components/reporting/storage/storage_queue.h +++ b/components/reporting/storage/storage_queue.h
@@ -136,6 +136,12 @@ // Access queue options. const QueueOptions& options() const { return options_; } + // Returns the file sequence ID (the first sequence ID in the file) if the + // sequence ID can be extracted from the extension. Otherwise, returns an + // error status. + static StatusOr<int64_t> GetFileSequenceIdFromPath( + const base::FilePath& file_name); + protected: virtual ~StorageQueue(); @@ -161,12 +167,6 @@ scoped_refptr<ResourceInterface> memory_resource, scoped_refptr<ResourceInterface> disk_space_resource); - // Returns the file sequence ID (the first sequence ID in the file) if the - // sequence ID can be extracted from the extension. Otherwise, returns an - // error status. - static StatusOr<int64_t> GetFileSequenceIdFromPath( - const base::FilePath& file_name); - Status Open(bool read_only); // No-op if already opened. void Close(); // No-op if not opened.
diff --git a/components/security_interstitials/content/utils.cc b/components/security_interstitials/content/utils.cc index 7a4cd19..7ad8cfc 100644 --- a/components/security_interstitials/content/utils.cc +++ b/components/security_interstitials/content/utils.cc
@@ -20,6 +20,10 @@ #include "components/security_interstitials/content/android/jni_headers/DateAndTimeSettingsHelper_jni.h" #endif +#if BUILDFLAG(IS_MAC) +#include "base/mac/mac_util.h" +#endif + #if BUILDFLAG(IS_WIN) #include "base/base_paths_win.h" #include "base/path_service.h" @@ -74,13 +78,8 @@ options.allow_new_privs = true; base::LaunchProcess(command, options); -#elif BUILDFLAG(IS_APPLE) - base::CommandLine command(base::FilePath("/usr/bin/open")); - command.AppendArg("/System/Library/PreferencePanes/DateAndTime.prefPane"); - - base::LaunchOptions options; - options.wait = false; - base::LaunchProcess(command, options); +#elif BUILDFLAG(IS_MAC) + base::mac::OpenSystemSettingsPane(base::mac::SystemSettingsPane::kDateTime); #elif BUILDFLAG(IS_WIN) base::FilePath path;
diff --git a/components/test/data/webcrypto/bad_rsa_keys.json b/components/test/data/webcrypto/bad_rsa_keys.json deleted file mode 100644 index 846cd20..0000000 --- a/components/test/data/webcrypto/bad_rsa_keys.json +++ /dev/null
@@ -1,124 +0,0 @@ -// This file contains incorrect key data in a variety of formats. -// "key" -- either a dictionary for JWK, or hex encoded bytes for PKCS8/SPKI. -// "key_format" -- one of: "jwk", "pkcs8", "spki" -// "error" -- The expected rejection reason when importing the key. -[ - // The provided SPKI is empty. - { - "key_format": "spki", - "key": "", - "error": "DataError" - }, - - // The provided PKCS8 is empty. - { - "key_format": "pkcs8", - "key": "", - "error": "DataError" - }, - - // Bad DER encoding for SPKI. - { - "key_format": "spki", - "key": "618333c4cb", - "error": "DataError" - }, - - // Bad DER encoding for PKCS8. - { - "key_format": "pkcs8", - "key": "618333c4cb", - "error": "DataError" - }, - - // Corrupted PKCS8 (byte index 50 was inverted, which is inside of "n") - { - "key_format": "pkcs8", - "key": "30820275020100300D06092A864886F70D01010105000482025F3082025B02010002818100A56E4A0E701017589A5187DC7E5741D156F2EC0E36AD52A44DFEB1E61F7AD991D8C51056FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5CD9508096D5B2B8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2D3F0CB35F29280E1386B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A2137020301000102818033A5042A90B27D4F5451CA9BBBD0B44771A101AF884340AEF9885F2A4BBE92E894A724AC3C568C8F97853AD07C0266C8C6A3CA0929F1E8F11231884429FC4D9AE55FEE896A10CE707C3ED7E734E44727A39574501A532683109C2ABACABA283C31B4BD2F53C3EE37E352CEE34F9E503BD80C0622AD79C6DCEE883547C6A3B325024100E7E8942720A877517273A356053EA2A1BC0C94AA72D55C6E86296B2DFC967948C0A72CBCCCA7EACB35706E09A1DF55A1535BD9B3CC34160B3B6DCD3EDA8E6443024100B69DCA1CF7D4D7EC81E75B90FCCA874ABCDE123FD2700180AA90479B6E48DE8D67ED24F9F19D85BA275874F542CD20DC723E6963364A1F9425452B269A6799FD024028FA13938655BE1F8A159CBACA5A72EA190C30089E19CD274A556F36C4F6E19F554B34C077790427BBDD8DD3EDE2448328F385D81B30E8E43B2FFFA02786197902401A8B38F398FA712049898D7FB79EE0A77668791299CDFA09EFC0E507ACB21ED74301EF5BFD48BE455EAEB6E1678255827580A8E4E8E14151D1510A82A3F2E729024027156ABA4126D24A81F3A528CBFB27F56886F840A9F6E86E17A44B94FE9319584B8E22FDDE1E5A2E3BD8AA5BA8D8584194EB2190ACF832B847F13A3D24A79F4D", - "error": "DataError" - }, - - // Corrupted PKCS8 (byte index 168 was inverted, which is inside of "e") - { - "key_format": "pkcs8", - "key": "30820275020100300D06092A864886F70D01010105000482025F3082025B02010002818100A56E4A0E701017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD991D8C51056FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5CD9508096D5B2B8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2D3F0CB35F29280E1386B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A2137020301FF0102818033A5042A90B27D4F5451CA9BBBD0B44771A101AF884340AEF9885F2A4BBE92E894A724AC3C568C8F97853AD07C0266C8C6A3CA0929F1E8F11231884429FC4D9AE55FEE896A10CE707C3ED7E734E44727A39574501A532683109C2ABACABA283C31B4BD2F53C3EE37E352CEE34F9E503BD80C0622AD79C6DCEE883547C6A3B325024100E7E8942720A877517273A356053EA2A1BC0C94AA72D55C6E86296B2DFC967948C0A72CBCCCA7EACB35706E09A1DF55A1535BD9B3CC34160B3B6DCD3EDA8E6443024100B69DCA1CF7D4D7EC81E75B90FCCA874ABCDE123FD2700180AA90479B6E48DE8D67ED24F9F19D85BA275874F542CD20DC723E6963364A1F9425452B269A6799FD024028FA13938655BE1F8A159CBACA5A72EA190C30089E19CD274A556F36C4F6E19F554B34C077790427BBDD8DD3EDE2448328F385D81B30E8E43B2FFFA02786197902401A8B38F398FA712049898D7FB79EE0A77668791299CDFA09EFC0E507ACB21ED74301EF5BFD48BE455EAEB6E1678255827580A8E4E8E14151D1510A82A3F2E729024027156ABA4126D24A81F3A528CBFB27F56886F840A9F6E86E17A44B94FE9319584B8E22FDDE1E5A2E3BD8AA5BA8D8584194EB2190ACF832B847F13A3D24A79F4D", - "error": "DataError" - }, - - // Corrupted PKCS8 (byte index 175 was inverted, which is inside of "d") - { - "key_format": "pkcs8", - "key": "30820275020100300D06092A864886F70D01010105000482025F3082025B02010002818100A56E4A0E701017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD991D8C51056FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5CD9508096D5B2B8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2D3F0CB35F29280E1386B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A2137020301000102818033A5FB2A90B27D4F5451CA9BBBD0B44771A101AF884340AEF9885F2A4BBE92E894A724AC3C568C8F97853AD07C0266C8C6A3CA0929F1E8F11231884429FC4D9AE55FEE896A10CE707C3ED7E734E44727A39574501A532683109C2ABACABA283C31B4BD2F53C3EE37E352CEE34F9E503BD80C0622AD79C6DCEE883547C6A3B325024100E7E8942720A877517273A356053EA2A1BC0C94AA72D55C6E86296B2DFC967948C0A72CBCCCA7EACB35706E09A1DF55A1535BD9B3CC34160B3B6DCD3EDA8E6443024100B69DCA1CF7D4D7EC81E75B90FCCA874ABCDE123FD2700180AA90479B6E48DE8D67ED24F9F19D85BA275874F542CD20DC723E6963364A1F9425452B269A6799FD024028FA13938655BE1F8A159CBACA5A72EA190C30089E19CD274A556F36C4F6E19F554B34C077790427BBDD8DD3EDE2448328F385D81B30E8E43B2FFFA02786197902401A8B38F398FA712049898D7FB79EE0A77668791299CDFA09EFC0E507ACB21ED74301EF5BFD48BE455EAEB6E1678255827580A8E4E8E14151D1510A82A3F2E729024027156ABA4126D24A81F3A528CBFB27F56886F840A9F6E86E17A44B94FE9319584B8E22FDDE1E5A2E3BD8AA5BA8D8584194EB2190ACF832B847F13A3D24A79F4D", - "error": "DataError" - }, - - // Corrupted PKCS8 (byte index 333 was inverted, which is inside of "p") - { - "key_format": "pkcs8", - "key": "30820275020100300D06092A864886F70D01010105000482025F3082025B02010002818100A56E4A0E701017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD991D8C51056FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5CD9508096D5B2B8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2D3F0CB35F29280E1386B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A2137020301000102818033A5042A90B27D4F5451CA9BBBD0B44771A101AF884340AEF9885F2A4BBE92E894A724AC3C568C8F97853AD07C0266C8C6A3CA0929F1E8F11231884429FC4D9AE55FEE896A10CE707C3ED7E734E44727A39574501A532683109C2ABACABA283C31B4BD2F53C3EE37E352CEE34F9E503BD80C0622AD79C6DCEE883547C6A3B325024100E7E8942720A877517273A356053EA2A1BC0C94AA72D55C6E86296B2DFC697948C0A72CBCCCA7EACB35706E09A1DF55A1535BD9B3CC34160B3B6DCD3EDA8E6443024100B69DCA1CF7D4D7EC81E75B90FCCA874ABCDE123FD2700180AA90479B6E48DE8D67ED24F9F19D85BA275874F542CD20DC723E6963364A1F9425452B269A6799FD024028FA13938655BE1F8A159CBACA5A72EA190C30089E19CD274A556F36C4F6E19F554B34C077790427BBDD8DD3EDE2448328F385D81B30E8E43B2FFFA02786197902401A8B38F398FA712049898D7FB79EE0A77668791299CDFA09EFC0E507ACB21ED74301EF5BFD48BE455EAEB6E1678255827580A8E4E8E14151D1510A82A3F2E729024027156ABA4126D24A81F3A528CBFB27F56886F840A9F6E86E17A44B94FE9319584B8E22FDDE1E5A2E3BD8AA5BA8D8584194EB2190ACF832B847F13A3D24A79F4D", - "error": "DataError" - }, - - // Corrupted PKCS8 (byte index 373 was inverted, which is inside of "q") - { - "key_format": "pkcs8", - "key": "30820275020100300D06092A864886F70D01010105000482025F3082025B02010002818100A56E4A0E701017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD991D8C51056FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5CD9508096D5B2B8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2D3F0CB35F29280E1386B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A2137020301000102818033A5042A90B27D4F5451CA9BBBD0B44771A101AF884340AEF9885F2A4BBE92E894A724AC3C568C8F97853AD07C0266C8C6A3CA0929F1E8F11231884429FC4D9AE55FEE896A10CE707C3ED7E734E44727A39574501A532683109C2ABACABA283C31B4BD2F53C3EE37E352CEE34F9E503BD80C0622AD79C6DCEE883547C6A3B325024100E7E8942720A877517273A356053EA2A1BC0C94AA72D55C6E86296B2DFC967948C0A72CBCCCA7EACB35706E09A1DF55A1535BD9B3CC34160B3B6DCD3EDA8E6443024100B69D351CF7D4D7EC81E75B90FCCA874ABCDE123FD2700180AA90479B6E48DE8D67ED24F9F19D85BA275874F542CD20DC723E6963364A1F9425452B269A6799FD024028FA13938655BE1F8A159CBACA5A72EA190C30089E19CD274A556F36C4F6E19F554B34C077790427BBDD8DD3EDE2448328F385D81B30E8E43B2FFFA02786197902401A8B38F398FA712049898D7FB79EE0A77668791299CDFA09EFC0E507ACB21ED74301EF5BFD48BE455EAEB6E1678255827580A8E4E8E14151D1510A82A3F2E729024027156ABA4126D24A81F3A528CBFB27F56886F840A9F6E86E17A44B94FE9319584B8E22FDDE1E5A2E3BD8AA5BA8D8584194EB2190ACF832B847F13A3D24A79F4D", - "error": "DataError" - }, - - // Corrupted PKCS8 (byte index 450 was inverted, which is inside of "dp") - { - "key_format": "pkcs8", - "key": "30820275020100300D06092A864886F70D01010105000482025F3082025B02010002818100A56E4A0E701017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD991D8C51056FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5CD9508096D5B2B8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2D3F0CB35F29280E1386B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A2137020301000102818033A5042A90B27D4F5451CA9BBBD0B44771A101AF884340AEF9885F2A4BBE92E894A724AC3C568C8F97853AD07C0266C8C6A3CA0929F1E8F11231884429FC4D9AE55FEE896A10CE707C3ED7E734E44727A39574501A532683109C2ABACABA283C31B4BD2F53C3EE37E352CEE34F9E503BD80C0622AD79C6DCEE883547C6A3B325024100E7E8942720A877517273A356053EA2A1BC0C94AA72D55C6E86296B2DFC967948C0A72CBCCCA7EACB35706E09A1DF55A1535BD9B3CC34160B3B6DCD3EDA8E6443024100B69DCA1CF7D4D7EC81E75B90FCCA874ABCDE123FD2700180AA90479B6E48DE8D67ED24F9F19D85BA275874F542CD20DC723E6963364A1F9425452B269A6799FD024028FA13938655BE1F8A159CBACAA572EA190C30089E19CD274A556F36C4F6E19F554B34C077790427BBDD8DD3EDE2448328F385D81B30E8E43B2FFFA02786197902401A8B38F398FA712049898D7FB79EE0A77668791299CDFA09EFC0E507ACB21ED74301EF5BFD48BE455EAEB6E1678255827580A8E4E8E14151D1510A82A3F2E729024027156ABA4126D24A81F3A528CBFB27F56886F840A9F6E86E17A44B94FE9319584B8E22FDDE1E5A2E3BD8AA5BA8D8584194EB2190ACF832B847F13A3D24A79F4D", - "error": "DataError" - }, - - // Corrupted PKCS8 (byte index 550 was inverted, which is inside of "dq") - { - "key_format": "pkcs8", - "key": "30820275020100300D06092A864886F70D01010105000482025F3082025B02010002818100A56E4A0E701017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD991D8C51056FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5CD9508096D5B2B8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2D3F0CB35F29280E1386B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A2137020301000102818033A5042A90B27D4F5451CA9BBBD0B44771A101AF884340AEF9885F2A4BBE92E894A724AC3C568C8F97853AD07C0266C8C6A3CA0929F1E8F11231884429FC4D9AE55FEE896A10CE707C3ED7E734E44727A39574501A532683109C2ABACABA283C31B4BD2F53C3EE37E352CEE34F9E503BD80C0622AD79C6DCEE883547C6A3B325024100E7E8942720A877517273A356053EA2A1BC0C94AA72D55C6E86296B2DFC967948C0A72CBCCCA7EACB35706E09A1DF55A1535BD9B3CC34160B3B6DCD3EDA8E6443024100B69DCA1CF7D4D7EC81E75B90FCCA874ABCDE123FD2700180AA90479B6E48DE8D67ED24F9F19D85BA275874F542CD20DC723E6963364A1F9425452B269A6799FD024028FA13938655BE1F8A159CBACA5A72EA190C30089E19CD274A556F36C4F6E19F554B34C077790427BBDD8DD3EDE2448328F385D81B30E8E43B2FFFA02786197902401A8B38F398FA712049898D7FB79EE0A77668791299CDFA09EFC0E507ACB21ED74301EF5BFD48BE455EAEB6E16782557D7580A8E4E8E14151D1510A82A3F2E729024027156ABA4126D24A81F3A528CBFB27F56886F840A9F6E86E17A44B94FE9319584B8E22FDDE1E5A2E3BD8AA5BA8D8584194EB2190ACF832B847F13A3D24A79F4D", - "error": "DataError" - }, - - // Corrupted PKCS8 (byte index 600 was inverted, which is inside of "qi") - { - "key_format": "pkcs8", - "key": "30820275020100300D06092A864886F70D01010105000482025F3082025B02010002818100A56E4A0E701017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD991D8C51056FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5CD9508096D5B2B8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2D3F0CB35F29280E1386B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A2137020301000102818033A5042A90B27D4F5451CA9BBBD0B44771A101AF884340AEF9885F2A4BBE92E894A724AC3C568C8F97853AD07C0266C8C6A3CA0929F1E8F11231884429FC4D9AE55FEE896A10CE707C3ED7E734E44727A39574501A532683109C2ABACABA283C31B4BD2F53C3EE37E352CEE34F9E503BD80C0622AD79C6DCEE883547C6A3B325024100E7E8942720A877517273A356053EA2A1BC0C94AA72D55C6E86296B2DFC967948C0A72CBCCCA7EACB35706E09A1DF55A1535BD9B3CC34160B3B6DCD3EDA8E6443024100B69DCA1CF7D4D7EC81E75B90FCCA874ABCDE123FD2700180AA90479B6E48DE8D67ED24F9F19D85BA275874F542CD20DC723E6963364A1F9425452B269A6799FD024028FA13938655BE1F8A159CBACA5A72EA190C30089E19CD274A556F36C4F6E19F554B34C077790427BBDD8DD3EDE2448328F385D81B30E8E43B2FFFA02786197902401A8B38F398FA712049898D7FB79EE0A77668791299CDFA09EFC0E507ACB21ED74301EF5BFD48BE455EAEB6E1678255827580A8E4E8E14151D1510A82A3F2E729024027156ABA4126D24A81F3A528CBFB27F56886F840A9F6E86E17A44B94FE9319A74B8E22FDDE1E5A2E3BD8AA5BA8D8584194EB2190ACF832B847F13A3D24A79F4D", - "error": "DataError" - }, - - // PKCS8 with only n, e, d parameters supplied, and all others are 0 - { - "key_format": "pkcs8", - "key": "30820138020100300D06092A864886F70D0101010500048201223082011E02010002818100A56E4A0E701017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD991D8C51056FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5CD9508096D5B2B8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2D3F0CB35F29280E1386B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A2137020301000102818033A5042A90B27D4F5451CA9BBBD0B44771A101AF884340AEF9885F2A4BBE92E894A724AC3C568C8F97853AD07C0266C8C6A3CA0929F1E8F11231884429FC4D9AE55FEE896A10CE707C3ED7E734E44727A39574501A532683109C2ABACABA283C31B4BD2F53C3EE37E352CEE34F9E503BD80C0622AD79C6DCEE883547C6A3B325020100020100020100020100020100", - "error": "DataError" - }, - - // Valid PKCS8, however it defines an EC key not an RSA key. - { - "key_format": "pkcs8", - "key": "308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B02010104201FE33950C5F461124AE992C2BDFDF1C73B1615F571BD567E60D19AA1F48CDF42A144034200047C110C66DCFDA807F6E69E45DDB3C74F69A1484D203E8DC5ADA8E9A9DD7CB3C70DF448986E51BDE5D1576F99901F9C2C6A806A47FD907643A72B835597EFC8C6", - "error": "DataError" - }, - - // Valid SPKI, however it defines an EC key not an RSA key. - { - "key_format": "spki", - "key": "3059301306072A8648CE3D020106082A8648CE3D030107034200049CB0CF69303DAFC761D4E4687B4ECF039E6D34AB964AF80810D8D558A4A8D6F72D51233A1788920A86EE08A1962C79EFA317FB7879E297DAD2146DB995FA1C78", - "error": "DataError" - }, - - // PKCS8 with extra data after it. - { - "key_format": "pkcs8", - "key": "30820275020100300D06092A864886F70D01010105000482025F3082025B02010002818100A56E4A0E701017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD991D8C51056FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5CD9508096D5B2B8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2D3F0CB35F29280E1386B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A2137020301000102818033A5042A90B27D4F5451CA9BBBD0B44771A101AF884340AEF9885F2A4BBE92E894A724AC3C568C8F97853AD07C0266C8C6A3CA0929F1E8F11231884429FC4D9AE55FEE896A10CE707C3ED7E734E44727A39574501A532683109C2ABACABA283C31B4BD2F53C3EE37E352CEE34F9E503BD80C0622AD79C6DCEE883547C6A3B325024100E7E8942720A877517273A356053EA2A1BC0C94AA72D55C6E86296B2DFC967948C0A72CBCCCA7EACB35706E09A1DF55A1535BD9B3CC34160B3B6DCD3EDA8E6443024100B69DCA1CF7D4D7EC81E75B90FCCA874ABCDE123FD2700180AA90479B6E48DE8D67ED24F9F19D85BA275874F542CD20DC723E6963364A1F9425452B269A6799FD024028FA13938655BE1F8A159CBACA5A72EA190C30089E19CD274A556F36C4F6E19F554B34C077790427BBDD8DD3EDE2448328F385D81B30E8E43B2FFFA02786197902401A8B38F398FA712049898D7FB79EE0A77668791299CDFA09EFC0E507ACB21ED74301EF5BFD48BE455EAEB6E1678255827580A8E4E8E14151D1510A82A3F2E729024027156ABA4126D24A81F3A528CBFB27F56886F840A9F6E86E17A44B94FE9319584B8E22FDDE1E5A2E3BD8AA5BA8D8584194EB2190ACF832B847F13A3D24A79F4D00000000", - "error": "DataError" - }, - - // SPKI with extra data after it. - { - "key_format": "spki", - "key": "30819F300D06092A864886F70D010101050003818D0030818902818100A56E4A0E701017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD991D8C51056FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5CD9508096D5B2B8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2D3F0CB35F29280E1386B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A2137020301000100000000", - "error": "DataError" - } -]
diff --git a/components/test/data/webcrypto/pkcs1v15_sign.json b/components/test/data/webcrypto/pkcs1v15_sign.json deleted file mode 100644 index 05e1ea1..0000000 --- a/components/test/data/webcrypto/pkcs1v15_sign.json +++ /dev/null
@@ -1,109 +0,0 @@ -// Use the NIST test vectors from Example 1 of -// ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15sign-vectors.txt -// These vectors are known answers for RSA PKCS#1 v1.5 Signature with a SHA-1 -// digest, using a predefined key pair. - -[ - // The following data are the input messages and corresponding computed RSA - // PKCS#1 v1.5 signatures from the NIST link above. - // PKCS#1 v1.5 Signature Example 1.1 - { - "message_hex": "cdc87da223d786df3b45e0bbbc721326d1ee2af806cc315475cc6f0d9c66e1b62371d45ce2392e1ac92844c310102f156a0d8d52c1f4c40ba3aa65095786cb769757a6563ba958fed0bcc984e8b517a3d5f515b23b8a41e74aa867693f90dfb061a6e86dfaaee64472c00e5f20945729cbebe77f06ce78e08f4098fba41f9d6193c0317e8b60d4b6084acb42d29e3808a3bc372d85e331170fcbf7cc72d0b71c296648b3a4d10f416295d0807aa625cab2744fd9ea8fd223c42537029828bd16be02546f130fd2e33b936d2676e08aed1b73318b750a0167d0", - "signature_hex": "6bc3a06656842930a247e30d5864b4d819236ba7c68965862ad7dbc4e24af28e86bb531f03358be5fb74777c6086f850caef893f0d6fcc2d0c91ec013693b4ea00b80cd49aac4ecb5f8911afe539ada4a8f3823d1d13e472d1490547c659c7617f3d24087ddb6f2b72096167fc097cab18e9a458fcb634cdce8ee35894c484d7" - }, - // PKCS#1 v1.5 Signature Example 1.2 - { - "message_hex": "851384cdfe819c22ed6c4ccb30daeb5cf059bc8e1166b7e3530c4c233e2b5f8f71a1cca582d43ecc72b1bca16dfc7013226b9e", - "signature_hex": "84fd2ce734ec1da828d0f15bf49a8707c15d05948136de537a3db421384167c86fae022587ee9e137daee754738262932d271c744c6d3a189ad4311bdb020492e322fbddc40406ea860d4e8ea2a4084aa98b9622a446756fdb740ddb3d91db7670e211661bbf8709b11c08a70771422d1a12def29f0688a192aebd89e0f896f8" - }, - // PKCS#1 v1.5 Signature Example1.3 - { - "message_hex": "a4b159941761c40c6a82f2b80d1b94f5aa2654fd17e12d588864679b54cd04ef8bd03012be8dc37f4b83af7963faff0dfa225477437c48017ff2be8191cf3955fc07356eab3f322f7f620e21d254e5db4324279fe067e0910e2e81ca2cab31c745e67a54058eb50d993cdb9ed0b4d029c06d21a94ca661c3ce27fae1d6cb20f4564d66ce4767583d0e5f060215b59017be85ea848939127bd8c9c4d47b51056c031cf336f17c9980f3b8f5b9b6878e8b797aa43b882684333e17893fe9caa6aa299f7ed1a18ee2c54864b7b2b99b72618fb02574d139ef50f019c9eef416971338e7d470", - "signature_hex": "0b1f2e5180e5c7b4b5e672929f664c4896e50c35134b6de4d5a934252a3a245ff48340920e1034b7d5a5b524eb0e1cf12befef49b27b732d2c19e1c43217d6e1417381111a1d36de6375cf455b3c9812639dbc27600c751994fb61799ecf7da6bcf51540afd0174db4033188556675b1d763360af46feeca5b60f882829ee7b2" - }, - // PKCS#1 v1.5 Signature Example 1.4 - { - "message_hex": "bc656747fa9eafb3f0", - "signature_hex": "45607ad611cf5747a41ac94d0ffec878bdaf63f6b57a4b088bf36e34e109f840f24b742ada16102dabf951cbc44f8982e94ed4cd09448d20ec0efa73545f80b65406bed6194a61c340b4ad1568cbb75851049f11af1734964076e02029aee200e40e80be0f4361f69841c4f92a4450a2286d43289b405554c54d25c6ecb584f4" - }, - // PKCS#1 v1.5 Signature Example 1.5 - { - "message_hex": "b45581547e5427770c768e8b82b75564e0ea4e9c32594d6bff706544de0a8776c7a80b4576550eee1b2acabc7e8b7d3ef7bb5b03e462c11047eadd00629ae575480ac1470fe046f13a2bf5af17921dc4b0aa8b02bee6334911651d7f8525d10f32b51d33be520d3ddf5a709955a3dfe78283b9e0ab54046d150c177f037fdccc5be4ea5f68b5e5a38c9d7edcccc4975f455a6909b4", - "signature_hex": "54be9d90877515f450279c15b5f61ad6f15ecc95f18cbed82b65b1667a575809587994668044f3bc2ae7f884501f64f0b43f588cfa205a6ab704328c2d4ab92a7ae13440614d3e085f401da9ad28e2105e4a0edb681a6424df047388ce051ee9df7bc2163fe347520ad51ccd518064383e741acad3cbdc2cb5a7c68e868464c2" - }, - // PKCS#1 v1.5 Signature Example 1.6 - { - "message_hex": "10aae9a0ab0b595d0841207b700d48d75faedde3b775cd6b4cc88ae06e4694ec74ba18f8520d4f5ea69cbbe7cc2beba43efdc10215ac4eb32dc302a1f53dc6c4352267e7936cfebf7c8d67035784a3909fa859c7b7b59b8e39c5c2349f1886b705a30267d402f7486ab4f58cad5d69adb17ab8cd0ce1caf5025af4ae24b1fb8794c6070cc09a51e2f9911311e3877d0044c71c57a993395008806b723ac38373d395481818528c1e7053739282053529510e935cd0fa77b8fa53cc2d474bd4fb3cc5c672d6ffdc90a00f9848712c4bcfe46c60573659b11e6457e861f0f604b6138d144f8ce4e2da73", - "signature_hex": "0e6ff63a856b9cbd5dbe423183122047dd39d6f76d1b2310e546fe9ee73b33efa7c78f9474455c9e5b88cb383aafc3698668e7b7a59a9cbb5b0897b6c5afb7f8bac4b924e98d760a15fc43d2814ab2d5187f79bed9915a93397ebc22a7677506a02e076d3ffdc0441dbd4db00453dc28d830e0573f77b817b505c38b4a4bb5d0" - }, - // PKCS#1 v1.5 Signature Example 1.7 - { - "message_hex": "efb5da1b4d1e6d9a5dff92d0184da7e31f877d1281ddda625664869e8379e67ad3b75eae74a580e9827abd6eb7a002cb5411f5266797768fb8e95ae40e3e8b3466f5ab15d69553952939ec23e61d58497fac76aa1c0bb5a3cb4a54383587c7bb78d13eefda205443e6ce4365802df55c64713497984e7ca96722b3edf84d56", - "signature_hex": "8385d58533a995f72df262b70f40b391ddf515f464b9d2cc2d66398fc05689d811632946d62eabdca7a31fcf6cd6c981d28bbc29083e4a6d5b2b378ca4e540f060b96d53ad2693f82178b94e2e2f86b9accfa02025107e062ab7080175684501028f676461d81c008fe4750671649970878fc175cf98e96b2ecbf6874d77dacb" - }, - // PKCS#1 v1.5 Signature Example 1.8 - { - "message_hex": "53bb58ce42f1984940552657233b14969af365c0a561a4132af18af39432280e3e437082434b19231837184f02cf2b2e726bebf74d7ae3256d8b72f3eafdb134d33de06f2991d299d59f5468d43b9958d6a968f5969edbbc6e7185cbc716c7c945dafa9cc71ddfaaa01094a452ddf5e2407320400bf05ea9729cafbf0600e78807ef9462e3fde32ed7d981a56f4751ef64fb4549910ecc911d728053b39943004740e6f5821fe8d75c0617bf2c6b24bbfc34013fc95f0dedf5ba297f504fb833da2a436d1d8ff1cc5193e2a64389fced918e7feb6716330f66801db9497549cf1d3bd97cf1bc6255", - "signature_hex": "8e1f3d26ec7c6bbb8c54c5d25f3120587803af6d3c2b99a37ced6a3657d4ae54266f63fffde660c866d65d0ab0589e1d12d9ce6054b05c8668ae127171ccaae7f1cd409677f52157b6123ab227f27a00966d1439b42a32169d1070394026fc8bc93545b1ac252d0f7da751c02e33a47831fbd71514c2bbbd3adb6740c0fd68ad" - }, - // PKCS#1 v1.5 Signature Example 1.9 - { - "message_hex": "27cadc698450945f204ec3cf8c6cbd8ceb4cc0cbe312274fa96b04deac855160c0e04e4ac5d38210c27c", - "signature_hex": "7b63f9223356f35f6117f68c8f8220034fc2384ab5dc6904141f139314d6ee89f54ec6ffd18c413a23c5931c7fbb13c555ccfd590e0eaa853c8c94d2520cd4250d9a05a193b65dc749b82478af0156ee1de55ddad33ec1f0099cad6c891a3617c7393d05fbfbbb00528a001df0b204ebdf1a341090dea89f870a877458427f7b" - }, - // PKCS#1 v1.5 Signature Example 1.10 - { - "message_hex": "716407e901b9ef92d761b013fd13eb7ad72aed", - "signature_hex": "2a22dbe3774d5b297201b55a0f17f42dce63b7845cb325cfe951d0badb5c5a14472143d896c86cc339f83671164215abc97862f2151654e75a3b357c37311b3d7268cab540202e23bee52736f2cd86cce0c7dbde95e1c600a47395dc5eb0a472153fbc4fb21b643e0c04ae14dd37e97e617a7567c89652219781001ba6f83298" - }, - // PKCS#1 v1.5 Signature Example 1.11 - { - "message_hex": "46c24e4103001629c712dd4ce8d747ee595d6c744ccc4f71347d9b8abf49d1b8fb2ef91b95dc899d4c0e3d2997e638f4cf3f68e0498de5aabd13f0dfe02ff26ba4379104e78ffa95ffbd15067ef8cbd7eb7860fecc71abe13d5c720a66851f2defd4e795054d7bec024bb422a46a7368b56d95b47aebafbeadd612812593a70db9f96d451ee15edb299308d777f4bb68ed3377c32156b41b7a9c92a14c8b81144399c56a5a432f4f770aa97da8415d0bda2e813206031e70620031c881d616bffd5f03bf147c1e73766c26246208", - "signature_hex": "12235b0b406126d9d260d447e923a11051fb243079f446fd73a70181d53634d7a0968e4ee27777eda63f6e4a3a91ad5985998a4848da59ce697b24bb332fa2ad9ce462ca4affdc21dab908e8ce15af6eb9105b1abcf39142aa17b34c4c092386a7abbfe028afdbebc14f2ce26fbee5edeca11502d39a6b7403154843d98a62a7" - }, - // PKCS#1 v1.5 Signature Example 1.12 - { - "message_hex": "bc99a932aa16d622bfff79c50b4c42358673261129e28d6a918ff1b0f1c4f46ad8afa98b0ca0f56f967975b0a29be882e93b6cd3fc33e1faef72e52b2ae0a3f12024506e25690e902e782982145556532284cf505789738f4da31fa1333d3af862b2ba6b6ce7ab4cce6aba", - "signature_hex": "872ec5ad4f1846256f17e9936ac50e43e9963ea8c1e76f15879b7874d77d122a609dc8c561145b94bf4ffdffdeb17e6e76ffc6c10c0747f5e37a9f434f5609e79da5250215a457afdf12c6507cc1551f54a28010595826a2c9b97fa0aa851cc68b705d7a06d720ba027e4a1c0b019500fb63b78071684dcfa9772700b982dc66" - }, - // PKCS#1 v1.5 Signature Example 1.13 - { - "message_hex": "731e172ac063992c5b11ba170dfb23bb000d47ba195329cf278061037381514c146064c5285db130dd5bae98b772225950eab05d3ea996f6fffb9a8c8622913f279914c89ada4f3dd77666a868bfcbff2b95b7daf453d4e2c9d75beee7f8e70905e4066a4f73aecc67f956aa5a3292b8488c917d317cfdc86253e690381e15ab", - "signature_hex": "76204eacc1d63ec1d6ad5bd0692e1a2f686df6e64ca945c77a824de212efa6d9782d81b4591403ff4020620298c07ebd3a8a61c5bf4dad62cbfc4ae6a03937be4b49a216d570fc6e81872937876e27bd19cf601effc30ddca573c9d56cd4569bdb4851c450c42cb21e738cdd61027b8be5e9b410fc46aa3f29e4be9e64451346" - }, - // PKCS#1 v1.5 Signature Example 1.14 - { - "message_hex": "0211382683a74d8d2a2cb6a06550563be1c26ca62821e4ff163b720464fc3a28d91bedddc62749a5538eaf41fbe0c82a77e06ad99383c9e985ffb8a93fd4d7c58db51ad91ba461d69a8fd7ddabe2496757a0c49122c1a79a85cc0553e8214d036dfe0185efa0d05860c612fa0882c82d246e5830a67355dff18a2c36b732f988cfedc562264c6254b40fcabb97b760947568dcd6a17cda6ee8855bddbab93702471aa0cfb1bed2e13118eba1175b73c96253c108d0b2aba05ab8e17e84392e20085f47404d8365527dc3fb8f2bb48a50038e71361ccf973407", - "signature_hex": "525500918331f1042eae0c5c2054aa7f92deb26991b5796634f229daf9b49eb2054d87319f3cfa9b466bd075ef6699aea4bd4a195a1c52968b5e2b75e092d846ea1b5cc27905a8e1d5e5de0edfdb21391ebb951864ebd9f0b0ec35b6542871360a317b7ef13ae06af684e38e21b1e19bc7298e5d6fe0013a164bfa25d3e7313d" - }, - // PKCS#1 v1.5 Signature Example 1.15 - { - "message_hex": "fc6b700d22583388ab2f8dafcaf1a05620698020da4bae44dafbd0877b5012506dc3181d5c66bf023f348b41fd9f94795ab96452a4219f2d39d72af359cf195651c7", - "signature_hex": "4452a6cc2626b01e95ab306df0d0cc7484fbab3c22e9703283567f66eadc248dbda58fce7dd0c70cce3f150fca4b369dff3b6237e2b16281ab55b53fb13089c85cd265056b3d62a88bfc2135b16791f7fbcab9fd2dc33becb617be419d2c046142a4d47b338314552edd4b6fe9ce1104ecec4a9958d7331e930fc09bf08a6e64" - }, - // PKCS#1 v1.5 Signature Example 1.16 - { - "message_hex": "13ba086d709cfa5fedaa557a89181a6140f2300ed6d7c3febb6cf68abebcbc678f2bca3dc2330295eec45bb1c4075f3ada987eae88b39c51606cb80429e649d98acc8441b1f8897db86c5a4ce0abf28b1b81dca3667697b850696b74a5ebd85dec56c90f8abe513efa857853720be319607921bca947522cd8fac8cace5b827c3e5a129e7ee57f6b84932f14141ac4274e8cbb46e6912b0d3e2177d499d1840cd47d4d7ae0b4cdc4d3", - "signature_hex": "1f3b5a87db72a2c97bb3eff2a65a301268eacd89f42abc1098c1f2de77b0832a65d7815feb35070063f221bb3453bd434386c9a3fde18e3ca1687fb649e86c51d658619dde5debb86fe15491ff77ab748373f1be508880d66ea81e870e91cdf1704875c17f0b10103188bc64eef5a3551b414c733670215b1a22702562581ab1" - }, - // PKCS#1 v1.5 Signature Example 1.17 - { - "message_hex": "eb1e5935", - "signature_hex": "370cb9839ae6074f84b2acd6e6f6b7921b4b523463757f6446716140c4e6c0e75bec6ad0197ebfa86bf46d094f5f6cd36dca3a5cc73c8bbb70e2c7c9ab5d964ec8e3dfde481b4a1beffd01b4ad15b31ae7aebb9b70344a9411083165fdf9c3754bbb8b94dd34bd4813dfada1f6937de4267d5597ca09a31e83d7f1a79dd19b5e" - }, - // PKCS#1 v1.5 Signature Example 1.18 - { - "message_hex": "6346b153e889c8228209630071c8a57783f368760b8eb908cfc2b276", - "signature_hex": "2479c975c5b1ae4c4e940f473a9045b8bf5b0bfca78ec29a38dfbedc8a749b7a2692f7c52d5bc7c831c7232372a00fed3b6b49e760ec99e074ff2eead5134e8305725dfa39212b84bd4b8d80bc8bc17a512823a3beb18fc08e45ed19c26c817707d67fb05832ef1f12a33e90cd93b8a780319e2963ca25a2af7b09ad8f595c21" - }, - // PKCS#1 v1.5 Signature Example 1.19 - { - "message_hex": "64702db9f825a0f3abc361974659f5e9d30c3aa4f56feac69050c72905e77fe0c22f88a378c21fcf45fe8a5c717302093929", - "signature_hex": "152f3451c858d69594e6567dfb31291c1ee7860b9d15ebd5a5edd276ac3e6f7a8d1480e42b3381d2be023acf7ebbdb28de3d2163ae44259c6df98c335d045b61dac9dba9dbbb4e6ab4a083cd76b580cbe472206a1a9fd60680ceea1a570a29b0881c775eaef5525d6d2f344c28837d0aca422bbb0f1aba8f6861ae18bd73fe44" - }, - // PKCS#1 v1.5 Signature Example 1.20 - { - "message_hex": "941921de4a1c9c1618d6f3ca3c179f6e29bae6ddf9a6a564f929e3ce82cf3265d7837d5e692be8dcc9e86c", - "signature_hex": "7076c287fc6fff2b20537435e5a3107ce4da10716186d01539413e609d27d1da6fd952c61f4bab91c045fa4f8683ecc4f8dde74227f773cff3d96db84718c4944b06affeba94b725f1b07d3928b2490a85c2f1abf492a9177a7cd2ea0c9668756f825bbec900fa8ac3824e114387ef573780ca334882387b94e5aad7a27a28dc" - } -]
diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc index e4cc6d8..395b18c 100644 --- a/components/viz/service/display/direct_renderer.cc +++ b/components/viz/service/display/direct_renderer.cc
@@ -915,7 +915,7 @@ // For the non-root render pass. gfx::Rect damage_rect = render_pass->damage_rect; if (!frame_buffer_damage.IsEmpty()) { - gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); + gfx::Transform inverse_transform; if (render_pass->transform_to_root_target.GetInverse(&inverse_transform)) { // |frame_buffer_damage| is in the root target space. Transform the damage // from the root to the non-root space before it's added.
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc index 78b1da4..8ebbec16d 100644 --- a/components/viz/service/display/display.cc +++ b/components/viz/service/display/display.cc
@@ -1268,13 +1268,11 @@ // positive scale check. if (current_sqs_intersects_occlusion && transform.IsPositiveScaleOrTranslation()) { - gfx::Transform reverse_transform; - bool is_invertible = transform.GetInverse(&reverse_transform); // Scale transform can be inverted by multiplying 1/scale (given // scale > 0) and translation transform can be inverted by applying // the reversed directional translation. Therefore, |transform| is // always invertible. - DCHECK(is_invertible); + gfx::Transform reverse_transform = transform.GetCheckedInverse(); DCHECK_LE(occlusion_in_target_space.GetRegionComplexity(), settings_.kMaximumOccluderComplexity);
diff --git a/components/viz/service/display/draw_polygon.cc b/components/viz/service/display/draw_polygon.cc index f23be82..26e88723 100644 --- a/components/viz/service/display/draw_polygon.cc +++ b/components/viz/service/display/draw_polygon.cc
@@ -143,12 +143,7 @@ // but normal information is no longer needed after sorting. void DrawPolygon::ApplyTransformToNormal(const gfx::Transform& transform) { // Now we use the inverse transpose of |transform| to transform the normal. - gfx::Transform inverse_transform; - bool inverted = transform.GetInverse(&inverse_transform); - DCHECK(inverted); - if (!inverted) - return; - + gfx::Transform inverse_transform = transform.GetCheckedInverse(); inverse_transform.Transpose(); normal_ = inverse_transform.MapVector(normal_);
diff --git a/components/viz/service/display/overlay_candidate_factory.cc b/components/viz/service/display/overlay_candidate_factory.cc index 28e06f9..96d07db1 100644 --- a/components/viz/service/display/overlay_candidate_factory.cc +++ b/components/viz/service/display/overlay_candidate_factory.cc
@@ -596,10 +596,10 @@ OverlayCandidate& candidate) const { auto& transform = quad->shared_quad_state->quad_to_target_transform; auto damage_rect = GetDamageRect(quad, candidate); - auto transformed_damage = damage_rect; - gfx::Transform inv; - if (transform.GetInverse(&inv)) { - transformed_damage = inv.MapRect(transformed_damage); + gfx::RectF transformed_damage; + if (absl::optional<gfx::RectF> transformed = + transform.InverseMapRect(damage_rect)) { + transformed_damage = *transformed; // The quad's |rect| is in content space. To get to buffer space we need // to remove the |rect|'s pixel offset. auto buffer_damage_origin =
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index dff2041..6907520e5 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -3378,17 +3378,15 @@ // We cannot handle rotation with clip rect or mask filter. DCHECK( shared_quad_state->quad_to_target_transform.Preserves2dAxisAlignment()); - quad_to_target_transform_inverse.emplace( - gfx::Transform::kSkipInitialization); + quad_to_target_transform_inverse.emplace(); // Flatten before inverting, since we're interested in how points // with z=0 in local space map to the clip rect, not in how the clip // rect at z=0 in device space maps to some other z in local space. gfx::Transform flat_quad_to_target_transform( shared_quad_state->quad_to_target_transform); flat_quad_to_target_transform.FlattenTo2d(); - bool result = flat_quad_to_target_transform.GetInverse( - &*quad_to_target_transform_inverse); - DCHECK(result) << "flat_quad_to_target_transform.GetInverse() failed"; + quad_to_target_transform_inverse = + flat_quad_to_target_transform.GetCheckedInverse(); } // The |clip_rect| is in the device coordinate and with all transforms
diff --git a/components/viz/service/display/surface_aggregator.cc b/components/viz/service/display/surface_aggregator.cc index 99c275f..7bc56f3 100644 --- a/components/viz/service/display/surface_aggregator.cc +++ b/components/viz/service/display/surface_aggregator.cc
@@ -116,7 +116,7 @@ gfx::Rect* quad_space_damage_rect) { gfx::Transform quad_to_root_transform = target_to_root_transform * quad_to_target_transform; - gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); + gfx::Transform inverse_transform; bool inverse_valid = quad_to_root_transform.GetInverse(&inverse_transform); if (!inverse_valid) return false; @@ -830,7 +830,7 @@ // might have incompleted copy request, or cached patially drawn render // pass. if (!RenderPassNeedsFullDamage(resolved_pass)) { - gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); + gfx::Transform inverse_transform; if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) { gfx::Rect damage_rect_in_render_pass_space = cc::MathUtil::ProjectEnclosingClippedRect(inverse_transform, @@ -1444,7 +1444,7 @@ // might have incompleted copy request, or cached patially drawn render // pass. if (!RenderPassNeedsFullDamage(resolved_pass)) { - gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); + gfx::Transform inverse_transform; if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) { gfx::Rect damage_rect_in_render_pass_space = cc::MathUtil::ProjectEnclosingClippedRect(inverse_transform, @@ -1507,8 +1507,7 @@ // this damage into the local space of the render pass for this purpose. gfx::Rect surface_root_rp_damage = resolved_frame.GetSurfaceDamage(); if (!surface_root_rp_damage.IsEmpty()) { - gfx::Transform root_to_target_transform( - gfx::Transform::kSkipInitialization); + gfx::Transform root_to_target_transform; if (target_to_root_transform.GetInverse(&root_to_target_transform)) { surface_root_rp_damage = cc::MathUtil::ProjectEnclosingClippedRect( root_to_target_transform, surface_root_rp_damage); @@ -1575,11 +1574,9 @@ accumulated_damage_in_child_space.Union(damage_from_parent); accumulated_damage_in_child_space.Union(surface_root_rp_damage); if (!accumulated_damage_in_child_space.IsEmpty()) { - gfx::Transform inverse(gfx::Transform::kSkipInitialization); - bool inverted = - quad->shared_quad_state->quad_to_target_transform.GetInverse( - &inverse); - DCHECK(inverted); + gfx::Transform inverse = + quad->shared_quad_state->quad_to_target_transform + .GetCheckedInverse(); inverse.PostScale(SK_Scalar1 / x_scale, SK_Scalar1 / y_scale); accumulated_damage_in_child_space = cc::MathUtil::ProjectEnclosingClippedRect( @@ -1829,9 +1826,7 @@ // transform. damage_rect = cc::MathUtil::MapEnclosedRectWith2dAxisAlignedTransform( root_surface_transform_, damage_rect); - gfx::Transform inverse(gfx::Transform::kSkipInitialization); - bool inverted = root_surface_transform_.GetInverse(&inverse); - DCHECK(inverted); + gfx::Transform inverse = root_surface_transform_.GetCheckedInverse(); damage_rect_surface_space = cc::MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(inverse, damage_rect);
diff --git a/components/webcrypto/algorithms/rsa_ssa_unittest.cc b/components/webcrypto/algorithms/rsa_ssa_unittest.cc index 5946d75ec..26b67055 100644 --- a/components/webcrypto/algorithms/rsa_ssa_unittest.cc +++ b/components/webcrypto/algorithms/rsa_ssa_unittest.cc
@@ -65,6 +65,12 @@ d.Set(b, std::move(*va)); } +std::string FlipHexByte(const std::string& hex, size_t index) { + auto bytes = HexStringToBytes(hex); + bytes[index] ^= 0xff; + return base::HexEncode(base::make_span(bytes)); +} + blink::WebCryptoAlgorithm RS256Algorithm() { return CreateRsaHashedImportAlgorithm( blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5, @@ -105,6 +111,27 @@ blink::kWebCryptoKeyUsageSign, &key); } +Status ImportSpkiRS256MustFail(const std::string& spki) { + auto spki_bytes = HexStringToBytes(spki); + blink::WebCryptoKey key; + // Note: SPKI keys can only be used for verification, not signing. + Status status = + ImportKey(blink::kWebCryptoKeyFormatSpki, spki_bytes, RS256Algorithm(), + true, blink::kWebCryptoKeyUsageVerify, &key); + CHECK(!status.IsSuccess()); + return status; +} + +Status ImportPkcs8RS256MustFail(const std::string& pkcs8) { + auto pkcs8_bytes = HexStringToBytes(pkcs8); + blink::WebCryptoKey key; + Status status = + ImportKey(blink::kWebCryptoKeyFormatPkcs8, pkcs8_bytes, RS256Algorithm(), + true, blink::kWebCryptoKeyUsageSign, &key); + CHECK(!status.IsSuccess()); + return status; +} + std::vector<uint8_t> ExportPkcs8OrDie(blink::WebCryptoKey key) { std::vector<uint8_t> exported; Status status = ExportKey(blink::kWebCryptoKeyFormatPkcs8, key, &exported); @@ -673,50 +700,6 @@ EXPECT_FALSE(is_match); } -TEST_F(WebCryptoRsaSsaTest, SignVerifyKnownAnswer) { - // Import the key pair. - blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm( - blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5, - blink::kWebCryptoAlgorithmIdSha1); - blink::WebCryptoKey public_key; - blink::WebCryptoKey private_key; - ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair( - HexStringToBytes(kPublicKeySpkiDerHex), - HexStringToBytes(kPrivateKeyPkcs8DerHex), import_algorithm, false, - blink::kWebCryptoKeyUsageVerify, blink::kWebCryptoKeyUsageSign, - &public_key, &private_key)); - - blink::WebCryptoAlgorithm algorithm = - CreateAlgorithm(blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5); - - // Validate the signatures are computed and verified as expected. - base::Value::List tests = ReadJsonTestFileAsList("pkcs1v15_sign.json"); - - std::vector<uint8_t> signature; - for (const auto& test_value : tests) { - SCOPED_TRACE(&test_value - &tests[0]); - - ASSERT_TRUE(test_value.is_dict()); - const base::DictionaryValue* test = - &base::Value::AsDictionaryValue(test_value); - - std::vector<uint8_t> test_message = - GetBytesFromHexString(test, "message_hex"); - std::vector<uint8_t> test_signature = - GetBytesFromHexString(test, "signature_hex"); - - signature.clear(); - ASSERT_EQ(Status::Success(), - Sign(algorithm, private_key, test_message, &signature)); - EXPECT_BYTES_EQ(test_signature, signature); - - bool is_match = false; - ASSERT_EQ(Status::Success(), Verify(algorithm, public_key, test_signature, - test_message, &is_match)); - EXPECT_TRUE(is_match); - } -} - // Try importing an RSA-SSA public key with unsupported key usages using SPKI // format. RSA-SSA public keys only support the 'verify' usage. TEST_F(WebCryptoRsaSsaTest, ImportRsaSsaPublicKeyBadUsage_SPKI) { @@ -1093,32 +1076,105 @@ StatusToString(ImportJwkRS256MustFail(key))); } -// Imports invalid JWK/SPKI/PKCS8 data and verifies that it fails as expected. -TEST_F(WebCryptoRsaSsaTest, ImportInvalidKeyData) { - base::Value::List tests = ReadJsonTestFileAsList("bad_rsa_keys.json"); - for (const auto& test_value : tests) { - SCOPED_TRACE(&test_value - &tests[0]); +TEST_F(WebCryptoRsaSsaTest, ImportInvalidSpki_Empty) { + EXPECT_EQ("DataError", StatusToString(ImportSpkiRS256MustFail(""))); +} - ASSERT_TRUE(test_value.is_dict()); - const base::DictionaryValue* test = - &base::Value::AsDictionaryValue(test_value); +TEST_F(WebCryptoRsaSsaTest, ImportInvalidSpki_BadDER) { + EXPECT_EQ("DataError", StatusToString(ImportSpkiRS256MustFail("618333c4cb"))); +} - blink::WebCryptoKeyFormat key_format = GetKeyFormatFromJsonTestCase(test); - std::vector<uint8_t> key_data = - GetKeyDataFromJsonTestCase(test, key_format); - std::string test_error; - ASSERT_TRUE(test->GetString("error", &test_error)); +TEST_F(WebCryptoRsaSsaTest, ImportInvalidSpki_NotRSA) { + EXPECT_EQ("DataError", + StatusToString(ImportSpkiRS256MustFail( + "3059301306072A8648CE3D020106082A8648CE3D030107034200049CB0CF69" + "303DAFC761D4E4687B4ECF039E6D34AB964AF80810D8D558A4A8D6F72D5123" + "3A1788920A86EE08A1962C79EFA317FB7879E297DAD2146DB995FA1C78"))); +} - blink::WebCryptoKeyUsageMask usages = blink::kWebCryptoKeyUsageSign; - if (key_format == blink::kWebCryptoKeyFormatSpki) - usages = blink::kWebCryptoKeyUsageVerify; - blink::WebCryptoKey key; - Status status = ImportKey(key_format, key_data, - CreateRsaHashedImportAlgorithm( - blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5, - blink::kWebCryptoAlgorithmIdSha256), - true, usages, &key); - EXPECT_EQ(test_error, StatusToString(status)); +TEST_F(WebCryptoRsaSsaTest, ImportInvalidSpki_TrailingData) { + EXPECT_EQ( + "DataError", + StatusToString(ImportSpkiRS256MustFail( + "30819F300D06092A864886F70D010101050003818D0030818902818100A56E4A0E70" + "1017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD991D8C51056FFEDB1" + "62B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5CD9508096D5B2B8B" + "6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2D3F0CB35F29280E1" + "386B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A2137020301000100000000"))); +} + +TEST_F(WebCryptoRsaSsaTest, ImportInvalidPkcs8_Empty) { + EXPECT_EQ("DataError", StatusToString(ImportPkcs8RS256MustFail(""))); +} + +TEST_F(WebCryptoRsaSsaTest, ImportInvalidPkcs8_BadDER) { + EXPECT_EQ("DataError", + StatusToString(ImportPkcs8RS256MustFail("618333c4cb"))); +} + +TEST_F(WebCryptoRsaSsaTest, ImportInvalidPkcs8_CRTValuesAreZero) { + EXPECT_EQ( + "DataError", + StatusToString(ImportPkcs8RS256MustFail( + "30820138020100300D06092A864886F70D0101010500048201223082011E02010002" + "818100A56E4A0E701017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD9" + "91D8C51056FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5" + "CD9508096D5B2B8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2" + "D3F0CB35F29280E1386B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A21370203010001" + "02818033A5042A90B27D4F5451CA9BBBD0B44771A101AF884340AEF9885F2A4BBE92" + "E894A724AC3C568C8F97853AD07C0266C8C6A3CA0929F1E8F11231884429FC4D9AE5" + "5FEE896A10CE707C3ED7E734E44727A39574501A532683109C2ABACABA283C31B4BD" + "2F53C3EE37E352CEE34F9E503BD80C0622AD79C6DCEE883547C6A3B3250201000201" + "00020100020100020100"))); +} + +TEST_F(WebCryptoRsaSsaTest, ImportInvalidPkcs8_NotRSA) { + EXPECT_EQ("DataError", + StatusToString(ImportPkcs8RS256MustFail( + "308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B" + "02010104201FE33950C5F461124AE992C2BDFDF1C73B1615F571BD567E60D1" + "9AA1F48CDF42A144034200047C110C66DCFDA807F6E69E45DDB3C74F69A148" + "4D203E8DC5ADA8E9A9DD7CB3C70DF448986E51BDE5D1576F99901F9C2C6A80" + "6A47FD907643A72B835597EFC8C6"))); +} + +TEST_F(WebCryptoRsaSsaTest, ImportInvalidPkcs8_TrailingData) { + EXPECT_EQ( + "DataError", + StatusToString(ImportPkcs8RS256MustFail( + "30820275020100300D06092A864886F70D01010105000482025F3082025B02010002" + "818100A56E4A0E701017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD9" + "91D8C51056FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5" + "CD9508096D5B2B8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2" + "D3F0CB35F29280E1386B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A21370203010001" + "02818033A5042A90B27D4F5451CA9BBBD0B44771A101AF884340AEF9885F2A4BBE92" + "E894A724AC3C568C8F97853AD07C0266C8C6A3CA0929F1E8F11231884429FC4D9AE5" + "5FEE896A10CE707C3ED7E734E44727A39574501A532683109C2ABACABA283C31B4BD" + "2F53C3EE37E352CEE34F9E503BD80C0622AD79C6DCEE883547C6A3B325024100E7E8" + "942720A877517273A356053EA2A1BC0C94AA72D55C6E86296B2DFC967948C0A72CBC" + "CCA7EACB35706E09A1DF55A1535BD9B3CC34160B3B6DCD3EDA8E6443024100B69DCA" + "1CF7D4D7EC81E75B90FCCA874ABCDE123FD2700180AA90479B6E48DE8D67ED24F9F1" + "9D85BA275874F542CD20DC723E6963364A1F9425452B269A6799FD024028FA139386" + "55BE1F8A159CBACA5A72EA190C30089E19CD274A556F36C4F6E19F554B34C0777904" + "27BBDD8DD3EDE2448328F385D81B30E8E43B2FFFA02786197902401A8B38F398FA71" + "2049898D7FB79EE0A77668791299CDFA09EFC0E507ACB21ED74301EF5BFD48BE455E" + "AEB6E1678255827580A8E4E8E14151D1510A82A3F2E729024027156ABA4126D24A81" + "F3A528CBFB27F56886F840A9F6E86E17A44B94FE9319584B8E22FDDE1E5A2E3BD8AA" + "5BA8D8584194EB2190ACF832B847F13A3D24A79F4D00000000"))); +} + +TEST_F(WebCryptoRsaSsaTest, ImportInvalidPkcs8_CorruptFields) { + const struct { + size_t byte; + const char* name; + } kTestCases[] = { + {50, "n"}, {168, "e"}, {175, "d"}, {333, "p"}, + {373, "q"}, {450, "dp"}, {550, "dq"}, {600, "qi"}, + }; + for (const auto& test : kTestCases) { + std::string key = FlipHexByte(kPrivateKeyPkcs8DerHex, test.byte); + EXPECT_EQ("DataError", StatusToString(ImportPkcs8RS256MustFail(key))) + << "byte flip should have invalidated key: " << test.name; } }
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index fe8fe424..d78a9bd 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -2802,8 +2802,6 @@ if (use_atk) { sources += [ - "accessibility/accessibility_event_recorder_auralinux.cc", - "accessibility/accessibility_event_recorder_auralinux.h", "accessibility/browser_accessibility_auralinux.cc", "accessibility/browser_accessibility_auralinux.h", "accessibility/browser_accessibility_manager_auralinux.cc",
diff --git a/content/browser/accessibility/dump_accessibility_node_browsertest.cc b/content/browser/accessibility/dump_accessibility_node_browsertest.cc index 3e368115..f89043c 100644 --- a/content/browser/accessibility/dump_accessibility_node_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_node_browsertest.cc
@@ -127,16 +127,6 @@ base::FilePath accname_file = test_path.Append(base::FilePath(file_path)); RunTest(accname_file, "accessibility/accname"); } - void RunAccDescTest(const base::FilePath::CharType* file_path) { - base::FilePath test_path = - GetTestFilePath("accessibility", "accdescription"); - { - base::ScopedAllowBlockingForTesting allow_blocking; - ASSERT_TRUE(base::PathExists(test_path)) << test_path.LossyDisplayName(); - } - base::FilePath accname_file = test_path.Append(base::FilePath(file_path)); - RunTest(accname_file, "accessibility/accdescription"); - } }; class DumpAccessibilityAccNameTestExceptUIA @@ -321,14 +311,6 @@ } // -// AccDescription tests. -// - -IN_PROC_BROWSER_TEST_P(DumpAccessibilityAccNameTest, DescriptionIgnoresSlot) { - RunAccDescTest(FILE_PATH_LITERAL("description-ignores-slot.html")); -} - -// // AccName tests. // IN_PROC_BROWSER_TEST_P(DumpAccessibilityAccNameTest, DescComboboxFocusable) { @@ -676,10 +658,6 @@ FILE_PATH_LITERAL("name-heading-combobox-focusable-alternative.html")); } -IN_PROC_BROWSER_TEST_P(DumpAccessibilityAccNameTest, NameIgnoresSlot) { - RunAccNameTest(FILE_PATH_LITERAL("name-ignores-slot.html")); -} - IN_PROC_BROWSER_TEST_P(DumpAccessibilityAccNameTest, NameImageCssAfterInLabel) { RunAccNameTest(FILE_PATH_LITERAL("name-image-css-after-in-label.html")); }
diff --git a/content/browser/attribution_reporting/aggregatable_attribution_utils_unittest.cc b/content/browser/attribution_reporting/aggregatable_attribution_utils_unittest.cc index 37a244d..d89961c 100644 --- a/content/browser/attribution_reporting/aggregatable_attribution_utils_unittest.cc +++ b/content/browser/attribution_reporting/aggregatable_attribution_utils_unittest.cc
@@ -49,35 +49,35 @@ absl::MakeUint128(/*high=*/0, /*low=*/1024), /*source_keys=*/{"key1", "key3"}, /*filters=*/ - AttributionFilterData::CreateForTesting({{"filter", {"value"}}}), - /*not_filters=*/AttributionFilterData()), + *AttributionFilters::Create({{"filter", {"value"}}}), + /*not_filters=*/AttributionFilters()), // The second trigger data applies to "key2", "key4" is ignored. AttributionAggregatableTriggerData::CreateForTesting( absl::MakeUint128(/*high=*/0, /*low=*/2688), /*source_keys=*/{"key2", "key4"}, /*filters=*/ - AttributionFilterData::CreateForTesting({{"a", {"b", "c"}}}), - /*not_filters=*/AttributionFilterData()), + *AttributionFilters::Create({{"a", {"b", "c"}}}), + /*not_filters=*/AttributionFilters()), // The third trigger will be ignored due to mismatched filters. AttributionAggregatableTriggerData::CreateForTesting( absl::MakeUint128(/*high=*/0, /*low=*/4096), /*source_keys=*/{"key1", "key2"}, /*filters=*/ - AttributionFilterData::CreateForTesting({{"filter", {}}}), - /*not_filters=*/AttributionFilterData()), + *AttributionFilters::Create({{"filter", {}}}), + /*not_filters=*/AttributionFilters()), // The fourth trigger will be ignored due to matched not_filters. AttributionAggregatableTriggerData::CreateForTesting( absl::MakeUint128(/*high=*/0, /*low=*/4096), /*source_keys=*/{"key1", "key2"}, - /*filters=*/AttributionFilterData(), + /*filters=*/AttributionFilters(), /*not_filters=*/ - AttributionFilterData::CreateForTesting({{"filter", {"value"}}}))}; + *AttributionFilters::Create({{"filter", {"value"}}}))}; absl::optional<AttributionFilterData> source_filter_data = - AttributionFilterData::FromSourceFilterValues({{"filter", {"value"}}}); + AttributionFilterData::Create({{"filter", {"value"}}}); ASSERT_TRUE(source_filter_data.has_value()); auto aggregatable_values = AttributionAggregatableValues::CreateForTesting(
diff --git a/content/browser/attribution_reporting/attribution_aggregatable_trigger_data.cc b/content/browser/attribution_reporting/attribution_aggregatable_trigger_data.cc index 15a383c..994bbd055 100644 --- a/content/browser/attribution_reporting/attribution_aggregatable_trigger_data.cc +++ b/content/browser/attribution_reporting/attribution_aggregatable_trigger_data.cc
@@ -17,8 +17,8 @@ AttributionAggregatableTriggerData::Create( absl::uint128 key_piece, base::flat_set<std::string> source_keys, - AttributionFilterData filters, - AttributionFilterData not_filters) { + AttributionFilters filters, + AttributionFilters not_filters) { if (source_keys.size() > blink::kMaxAttributionAggregationKeysPerSourceOrTrigger) { return absl::nullopt; @@ -40,8 +40,8 @@ AttributionAggregatableTriggerData::CreateForTesting( absl::uint128 key_piece, base::flat_set<std::string> source_keys, - AttributionFilterData filters_values, - AttributionFilterData not_filters_values) { + AttributionFilters filters_values, + AttributionFilters not_filters_values) { return AttributionAggregatableTriggerData(key_piece, std::move(source_keys), std::move(filters_values), std::move(not_filters_values)); @@ -50,8 +50,8 @@ AttributionAggregatableTriggerData::AttributionAggregatableTriggerData( absl::uint128 key_piece, base::flat_set<std::string> source_keys, - AttributionFilterData filters, - AttributionFilterData not_filters) + AttributionFilters filters, + AttributionFilters not_filters) : key_piece_(key_piece), source_keys_(std::move(source_keys)), filters_(std::move(filters)),
diff --git a/content/browser/attribution_reporting/attribution_aggregatable_trigger_data.h b/content/browser/attribution_reporting/attribution_aggregatable_trigger_data.h index c71a1d41..5e5fc82 100644 --- a/content/browser/attribution_reporting/attribution_aggregatable_trigger_data.h +++ b/content/browser/attribution_reporting/attribution_aggregatable_trigger_data.h
@@ -20,14 +20,14 @@ static absl::optional<AttributionAggregatableTriggerData> Create( absl::uint128 key_piece, base::flat_set<std::string> source_keys, - AttributionFilterData filters, - AttributionFilterData not_filters); + AttributionFilters filters, + AttributionFilters not_filters); static AttributionAggregatableTriggerData CreateForTesting( absl::uint128 key_piece, base::flat_set<std::string> source_keys, - AttributionFilterData filters, - AttributionFilterData not_filters); + AttributionFilters filters, + AttributionFilters not_filters); ~AttributionAggregatableTriggerData(); @@ -45,20 +45,20 @@ return source_keys_; } - const AttributionFilterData& filters() const { return filters_; } + const AttributionFilters& filters() const { return filters_; } - const AttributionFilterData& not_filters() const { return not_filters_; } + const AttributionFilters& not_filters() const { return not_filters_; } private: AttributionAggregatableTriggerData(absl::uint128 key_piece, base::flat_set<std::string> source_keys, - AttributionFilterData filters, - AttributionFilterData not_filters); + AttributionFilters filters, + AttributionFilters not_filters); absl::uint128 key_piece_; base::flat_set<std::string> source_keys_; - AttributionFilterData filters_; - AttributionFilterData not_filters_; + AttributionFilters filters_; + AttributionFilters not_filters_; }; } // namespace content
diff --git a/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc b/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc index f45f9fd..c799d66 100644 --- a/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc +++ b/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc
@@ -109,15 +109,13 @@ aggregatable_trigger_data.reserve(mojo.size()); for (auto& aggregatable_trigger : mojo) { - absl::optional<AttributionFilterData> filters = - AttributionFilterData::FromTriggerFilterValues( - std::move(aggregatable_trigger->filters->filter_values)); + absl::optional<AttributionFilters> filters = AttributionFilters::Create( + std::move(aggregatable_trigger->filters->filter_values)); if (!filters.has_value()) return absl::nullopt; - absl::optional<AttributionFilterData> not_filters = - AttributionFilterData::FromTriggerFilterValues( - std::move(aggregatable_trigger->not_filters->filter_values)); + absl::optional<AttributionFilters> not_filters = AttributionFilters::Create( + std::move(aggregatable_trigger->not_filters->filter_values)); if (!not_filters.has_value()) return absl::nullopt; @@ -394,7 +392,7 @@ // renderer. All of the validation here is also performed renderer-side. absl::optional<AttributionFilterData> filter_data = - AttributionFilterData::FromSourceFilterValues( + AttributionFilterData::Create( std::move(data->filter_data->filter_values)); if (!filter_data.has_value()) { RecordSourceDataHandleStatus(DataHandleStatus::kInvalidData); @@ -460,18 +458,16 @@ context.registration_type = RegistrationType::kTrigger; } - absl::optional<AttributionFilterData> filters = - AttributionFilterData::FromTriggerFilterValues( - std::move(data->filters->filter_values)); + absl::optional<AttributionFilters> filters = + AttributionFilters::Create(std::move(data->filters->filter_values)); if (!filters.has_value()) { RecordTriggerDataHandleStatus(DataHandleStatus::kInvalidData); mojo::ReportBadMessage("AttributionDataHost: Invalid top-level filters."); return; } - absl::optional<AttributionFilterData> not_filters = - AttributionFilterData::FromTriggerFilterValues( - std::move(data->not_filters->filter_values)); + absl::optional<AttributionFilters> not_filters = + AttributionFilters::Create(std::move(data->not_filters->filter_values)); if (!not_filters.has_value()) { RecordTriggerDataHandleStatus(DataHandleStatus::kInvalidData); mojo::ReportBadMessage( @@ -489,8 +485,8 @@ event_triggers.reserve(data->event_triggers.size()); for (auto& event_trigger : data->event_triggers) { - absl::optional<AttributionFilterData> event_filters = - AttributionFilterData::FromTriggerFilterValues( + absl::optional<AttributionFilters> event_filters = + AttributionFilters::Create( std::move(event_trigger->filters->filter_values)); if (!event_filters.has_value()) { RecordTriggerDataHandleStatus(DataHandleStatus::kInvalidData); @@ -499,8 +495,8 @@ return; } - absl::optional<AttributionFilterData> not_event_filters = - AttributionFilterData::FromTriggerFilterValues( + absl::optional<AttributionFilters> not_event_filters = + AttributionFilters::Create( std::move(event_trigger->not_filters->filter_values)); if (!not_event_filters.has_value()) { RecordTriggerDataHandleStatus(DataHandleStatus::kInvalidData);
diff --git a/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc b/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc index d3cb163f..6ee543d 100644 --- a/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc +++ b/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc
@@ -487,21 +487,21 @@ mock_manager_, HandleTrigger(AttributionTriggerMatches(AttributionTriggerMatcherConfig( destination_origin, reporting_origin, - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"a", {"b"}}, }), Optional(789), ElementsAre(EventTriggerDataMatches(EventTriggerDataMatcherConfig( 1, 2, Optional(3), - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"c", {"d"}}, }), - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"e", {"f"}}, }))), EventTriggerDataMatches(EventTriggerDataMatcherConfig( - 4, 5, Eq(absl::nullopt), AttributionFilterData(), - AttributionFilterData()))), + 4, 5, Eq(absl::nullopt), AttributionFilters(), + AttributionFilters()))), Optional(123))))); { @@ -515,7 +515,7 @@ trigger_data->debug_key = 789; trigger_data->filters = blink::mojom::AttributionFilterData::New( - AttributionFilterData::FilterValues({{"a", {"b"}}})); + AttributionFilterValues({{"a", {"b"}}})); trigger_data->not_filters = blink::mojom::AttributionFilterData::New(); trigger_data->event_triggers.push_back(blink::mojom::EventTriggerData::New( @@ -523,10 +523,10 @@ /*priority=*/2, /*dedup_key=*/3, /*filters=*/ blink::mojom::AttributionFilterData::New( - AttributionFilterData::FilterValues({{"c", {"d"}}})), + AttributionFilterValues({{"c", {"d"}}})), /*not_filters=*/ blink::mojom::AttributionFilterData::New( - AttributionFilterData::FilterValues({{"e", {"f"}}})))); + AttributionFilterValues({{"e", {"f"}}})))); trigger_data->event_triggers.push_back(blink::mojom::EventTriggerData::New( /*data=*/4,
diff --git a/content/browser/attribution_reporting/attribution_filter_data.cc b/content/browser/attribution_reporting/attribution_filter_data.cc index ef8f667..b20cadf9a 100644 --- a/content/browser/attribution_reporting/attribution_filter_data.cc +++ b/content/browser/attribution_reporting/attribution_filter_data.cc
@@ -23,16 +23,41 @@ using ::attribution_reporting::mojom::SourceRegistrationError; +bool IsValidForSourceOrTrigger(const AttributionFilterValues& filter_values) { + if (filter_values.size() > blink::kMaxAttributionFiltersPerSource) + return false; + + for (const auto& [filter, values] : filter_values) { + if (filter.size() > blink::kMaxBytesPerAttributionFilterString) + return false; + + if (values.size() > blink::kMaxValuesPerAttributionFilter) + return false; + + for (const auto& value : values) { + if (value.size() > blink::kMaxBytesPerAttributionFilterString) + return false; + } + } + + return true; +} + +bool IsValidForSource(const AttributionFilterValues& filter_values) { + return !filter_values.contains(AttributionFilterData::kSourceTypeFilterKey) && + IsValidForSourceOrTrigger(filter_values); +} + } // namespace // static -absl::optional<AttributionFilterData> -AttributionFilterData::DeserializeSourceFilterData(const std::string& string) { +absl::optional<AttributionFilterData> AttributionFilterData::Deserialize( + const std::string& string) { proto::AttributionFilterData msg; if (!msg.ParseFromString(string)) return absl::nullopt; - FilterValues::container_type filter_values; + AttributionFilterValues::container_type filter_values; filter_values.reserve(msg.filter_values().size()); for (google::protobuf::MapPair<std::string, proto::AttributionFilterValues>& @@ -51,30 +76,21 @@ std::make_move_iterator(values->end()))); } - return FromFilterValues(std::move(filter_values)); + return Create(std::move(filter_values)); } // static -absl::optional<AttributionFilterData> -AttributionFilterData::FromSourceFilterValues(FilterValues&& filter_values) { - absl::optional<AttributionFilterData> result = - FromFilterValues(std::move(filter_values)); - - if (!result || result->filter_values_.contains(kSourceTypeFilterKey)) +absl::optional<AttributionFilterData> AttributionFilterData::Create( + AttributionFilterValues filter_values) { + if (!IsValidForSource(filter_values)) return absl::nullopt; - return result; -} - -// static -absl::optional<AttributionFilterData> -AttributionFilterData::FromTriggerFilterValues(FilterValues&& filter_values) { - return FromFilterValues(std::move(filter_values)); + return AttributionFilterData(std::move(filter_values)); } // static base::expected<AttributionFilterData, SourceRegistrationError> -AttributionFilterData::FromSourceJSON(base::Value* input_value) { +AttributionFilterData::FromJSON(base::Value* input_value) { // TODO(johnidel): Consider logging registration JSON metrics here. if (!input_value) return AttributionFilterData(); @@ -92,7 +108,7 @@ SourceRegistrationError::kFilterDataHasSourceTypeKey); } - FilterValues::container_type filter_values; + AttributionFilterValues::container_type filter_values; filter_values.reserve(dict->size()); for (auto [filter, value] : *dict) { @@ -131,55 +147,31 @@ } return AttributionFilterData( - FilterValues(base::sorted_unique, std::move(filter_values))); + AttributionFilterValues(base::sorted_unique, std::move(filter_values))); } // static -AttributionFilterData AttributionFilterData::ForSourceType( +AttributionFilters AttributionFilters::ForSourceType( AttributionSourceType source_type) { std::vector<std::string> values; values.reserve(1); values.push_back(AttributionSourceTypeToString(source_type)); - AttributionFilterData::FilterValues filter_values; + AttributionFilterValues filter_values; filter_values.reserve(1); - filter_values.emplace(kSourceTypeFilterKey, std::move(values)); + filter_values.emplace(AttributionFilterData::kSourceTypeFilterKey, + std::move(values)); - return AttributionFilterData(std::move(filter_values)); -} - -// static -absl::optional<AttributionFilterData> AttributionFilterData::FromFilterValues( - FilterValues&& filter_values) { - if (filter_values.size() > blink::kMaxAttributionFiltersPerSource) - return absl::nullopt; - - for (const auto& [filter, values] : filter_values) { - if (filter.size() > blink::kMaxBytesPerAttributionFilterString) - return absl::nullopt; - - if (values.size() > blink::kMaxValuesPerAttributionFilter) - return absl::nullopt; - - for (const auto& value : values) { - if (value.size() > blink::kMaxBytesPerAttributionFilterString) - return absl::nullopt; - } - } - - return AttributionFilterData(std::move(filter_values)); -} - -// static -AttributionFilterData AttributionFilterData::CreateForTesting( - FilterValues filter_values) { - return AttributionFilterData(std::move(filter_values)); + return AttributionFilters(std::move(filter_values)); } AttributionFilterData::AttributionFilterData() = default; -AttributionFilterData::AttributionFilterData(FilterValues filter_values) - : filter_values_(std::move(filter_values)) {} +AttributionFilterData::AttributionFilterData( + AttributionFilterValues filter_values) + : filter_values_(std::move(filter_values)) { + DCHECK(IsValidForSource(filter_values_)); +} AttributionFilterData::~AttributionFilterData() = default; @@ -195,8 +187,6 @@ AttributionFilterData&&) = default; std::string AttributionFilterData::Serialize() const { - DCHECK(!filter_values_.contains(kSourceTypeFilterKey)); - proto::AttributionFilterData msg; for (const auto& [filter, values] : filter_values_) { @@ -214,4 +204,32 @@ return string; } +// static +absl::optional<AttributionFilters> AttributionFilters::Create( + AttributionFilterValues filter_values) { + if (!IsValidForSourceOrTrigger(filter_values)) + return absl::nullopt; + + return AttributionFilters(std::move(filter_values)); +} + +AttributionFilters::AttributionFilters() = default; + +AttributionFilters::AttributionFilters(AttributionFilterValues filter_values) + : filter_values_(std::move(filter_values)) { + DCHECK(IsValidForSourceOrTrigger(filter_values_)); +} + +AttributionFilters::~AttributionFilters() = default; + +AttributionFilters::AttributionFilters(const AttributionFilters&) = default; + +AttributionFilters::AttributionFilters(AttributionFilters&&) = default; + +AttributionFilters& AttributionFilters::operator=(const AttributionFilters&) = + default; + +AttributionFilters& AttributionFilters::operator=(AttributionFilters&&) = + default; + } // namespace content
diff --git a/content/browser/attribution_reporting/attribution_filter_data.h b/content/browser/attribution_reporting/attribution_filter_data.h index 6df22f9..0c80d09 100644 --- a/content/browser/attribution_reporting/attribution_filter_data.h +++ b/content/browser/attribution_reporting/attribution_filter_data.h
@@ -21,34 +21,23 @@ namespace content { +using AttributionFilterValues = + base::flat_map<std::string, std::vector<std::string>>; + +// Set on sources. // Supports persistence to disk via serializaton to/from proto. class CONTENT_EXPORT AttributionFilterData { public: static constexpr char kSourceTypeFilterKey[] = "source_type"; - using FilterValues = base::flat_map<std::string, std::vector<std::string>>; + static absl::optional<AttributionFilterData> Deserialize(const std::string&); - // Deserializes `string`, if valid. Returns `absl::nullopt` if not. - static absl::optional<AttributionFilterData> DeserializeSourceFilterData( - const std::string& string); - - // Source filter data is not allowed to contain a `source_type` filter. - static absl::optional<AttributionFilterData> FromSourceFilterValues( - FilterValues&& filter_values); - - // Trigger filter data is allowed to contain a `source_type` filter. - static absl::optional<AttributionFilterData> FromTriggerFilterValues( - FilterValues&& filter_values); + // Filter data is not allowed to contain a `source_type` filter. + static absl::optional<AttributionFilterData> Create(AttributionFilterValues); static base::expected<AttributionFilterData, attribution_reporting::mojom::SourceRegistrationError> - FromSourceJSON(base::Value* input_value); - - // Returns filter data that matches only the given source type. - static AttributionFilterData ForSourceType(AttributionSourceType source_type); - - // Creates without validation. - static AttributionFilterData CreateForTesting(FilterValues filter_values); + FromJSON(base::Value*); AttributionFilterData(); @@ -60,17 +49,45 @@ AttributionFilterData& operator=(const AttributionFilterData&); AttributionFilterData& operator=(AttributionFilterData&&); - const FilterValues& filter_values() const { return filter_values_; } + const AttributionFilterValues& filter_values() const { + return filter_values_; + } std::string Serialize() const; private: - static absl::optional<AttributionFilterData> FromFilterValues( - FilterValues&& filter_values); + explicit AttributionFilterData(AttributionFilterValues); - explicit AttributionFilterData(FilterValues filter_values); + AttributionFilterValues filter_values_; +}; - FilterValues filter_values_; +// Set on triggers. +class CONTENT_EXPORT AttributionFilters { + public: + // Filters are allowed to contain a `source_type` filter. + static absl::optional<AttributionFilters> Create(AttributionFilterValues); + + // Returns filters that match only the given source type. + static AttributionFilters ForSourceType(AttributionSourceType); + + AttributionFilters(); + + ~AttributionFilters(); + + AttributionFilters(const AttributionFilters&); + AttributionFilters(AttributionFilters&&); + + AttributionFilters& operator=(const AttributionFilters&); + AttributionFilters& operator=(AttributionFilters&&); + + const AttributionFilterValues& filter_values() const { + return filter_values_; + } + + private: + explicit AttributionFilters(AttributionFilterValues); + + AttributionFilterValues filter_values_; }; } // namespace content
diff --git a/content/browser/attribution_reporting/attribution_filter_data_unittest.cc b/content/browser/attribution_reporting/attribution_filter_data_unittest.cc index e305de4..43d8d2d5 100644 --- a/content/browser/attribution_reporting/attribution_filter_data_unittest.cc +++ b/content/browser/attribution_reporting/attribution_filter_data_unittest.cc
@@ -26,8 +26,7 @@ using ::testing::ElementsAre; using ::testing::Pair; -std::string CreateSerialized( - const AttributionFilterData::FilterValues& filter_values) { +std::string CreateSerialized(const AttributionFilterValues& filter_values) { proto::AttributionFilterData msg; for (const auto& [filter, values] : filter_values) { @@ -44,8 +43,8 @@ return string; } -AttributionFilterData::FilterValues CreateFilterValues(size_t n) { - AttributionFilterData::FilterValues filter_values; +AttributionFilterValues CreateFilterValues(size_t n) { + AttributionFilterValues filter_values; for (size_t i = 0; i < n; i++) { filter_values.emplace(base::NumberToString(i), std::vector<std::string>()); } @@ -55,61 +54,55 @@ // Tests that a "source_type" filter present in the serialized data is // removed. -TEST(AttributionFilterDataTest, - DeserializeSourceFilterData_RemovesSourceTypeFilter) { +TEST(AttributionFilterDataTest, Deserialize_RemovesSourceTypeFilter) { const std::string serialized = CreateSerialized({{"source_type", {"abc"}}, {"x", {"y"}}}); - EXPECT_THAT(AttributionFilterData::DeserializeSourceFilterData(serialized) - ->filter_values(), + EXPECT_THAT(AttributionFilterData::Deserialize(serialized)->filter_values(), ElementsAre(Pair("x", ElementsAre("y")))); } // Tests that serialized data is allowed // `blink::kMaxAttributionFiltersPerSource` filters. -TEST(AttributionFilterDataTest, - DeserializeSourceFilterData_AllowsOneExtraFilter) { - EXPECT_TRUE(AttributionFilterData::DeserializeSourceFilterData( +TEST(AttributionFilterDataTest, Deserialize_AllowsOneExtraFilter) { + EXPECT_TRUE(AttributionFilterData::Deserialize( CreateSerialized(CreateFilterValues( blink::kMaxAttributionFiltersPerSource))) .has_value()); - EXPECT_FALSE(AttributionFilterData::DeserializeSourceFilterData( + EXPECT_FALSE(AttributionFilterData::Deserialize( CreateSerialized(CreateFilterValues( blink::kMaxAttributionFiltersPerSource + 1))) .has_value()); } -TEST(AttributionFilterDataTest, - FromSourceFilterValues_ProhibitsSourceTypeFilter) { - EXPECT_FALSE(AttributionFilterData::FromSourceFilterValues( - {{"source_type", {"event"}}})); +TEST(AttributionFilterDataTest, Create_ProhibitsSourceTypeFilter) { + EXPECT_FALSE(AttributionFilterData::Create({{"source_type", {"event"}}})); } TEST(AttributionFilterDataTest, FromTriggerFilterValues_AllowsSourceTypeFilter) { - EXPECT_TRUE(AttributionFilterData::FromTriggerFilterValues( - {{"source_type", {"event"}}})); + EXPECT_TRUE(AttributionFilters::Create({{"source_type", {"event"}}})); } -TEST(AttributionFilterDatTest, FromSourceFilterValues_LimitsFilterCount) { - EXPECT_TRUE(AttributionFilterData::FromSourceFilterValues( +TEST(AttributionFilterDatTest, Create_LimitsFilterCount) { + EXPECT_TRUE(AttributionFilterData::Create( CreateFilterValues(blink::kMaxAttributionFiltersPerSource)) .has_value()); EXPECT_FALSE( - AttributionFilterData::FromSourceFilterValues( + AttributionFilterData::Create( CreateFilterValues(blink::kMaxAttributionFiltersPerSource + 1)) .has_value()); } TEST(AttributionFilterDatTest, FromTriggerFilterValues_LimitsFilterCount) { - EXPECT_TRUE(AttributionFilterData::FromTriggerFilterValues( + EXPECT_TRUE(AttributionFilters::Create( CreateFilterValues(blink::kMaxAttributionFiltersPerSource)) .has_value()); EXPECT_FALSE( - AttributionFilterData::FromTriggerFilterValues( + AttributionFilters::Create( CreateFilterValues(blink::kMaxAttributionFiltersPerSource + 1)) .has_value()); }
diff --git a/content/browser/attribution_reporting/attribution_header_utils.cc b/content/browser/attribution_reporting/attribution_header_utils.cc index 09ba6944..6798dfe 100644 --- a/content/browser/attribution_reporting/attribution_header_utils.cc +++ b/content/browser/attribution_reporting/attribution_header_utils.cc
@@ -93,7 +93,7 @@ absl::optional<uint64_t> debug_key = ParseDebugKey(registration); base::expected<AttributionFilterData, SourceRegistrationError> filter_data = - AttributionFilterData::FromSourceJSON(registration.Find("filter_data")); + AttributionFilterData::FromJSON(registration.Find("filter_data")); if (!filter_data.has_value()) return base::unexpected(filter_data.error());
diff --git a/content/browser/attribution_reporting/attribution_header_utils_unittest.cc b/content/browser/attribution_reporting/attribution_header_utils_unittest.cc index aff3a386..a9feebbd 100644 --- a/content/browser/attribution_reporting/attribution_header_utils_unittest.cc +++ b/content/browser/attribution_reporting/attribution_header_utils_unittest.cc
@@ -189,7 +189,7 @@ "c": ["e", "d"], "f": [] })json"), - AttributionFilterData::CreateForTesting({ + *AttributionFilterData::Create({ {"a", {"b"}}, {"c", {"e", "d"}}, {"f", {}}, @@ -241,30 +241,30 @@ }; for (auto& test_case : kTestCases) { - EXPECT_EQ(AttributionFilterData::FromSourceJSON( - base::OptionalToPtr(test_case.json)), - test_case.expected) + EXPECT_EQ( + AttributionFilterData::FromJSON(base::OptionalToPtr(test_case.json)), + test_case.expected) << test_case.description; } { base::Value json = make_filter_data_with_keys(50); - EXPECT_TRUE(AttributionFilterData::FromSourceJSON(&json).has_value()); + EXPECT_TRUE(AttributionFilterData::FromJSON(&json).has_value()); } { base::Value json = make_filter_data_with_key_length(25); - EXPECT_TRUE(AttributionFilterData::FromSourceJSON(&json).has_value()); + EXPECT_TRUE(AttributionFilterData::FromJSON(&json).has_value()); } { base::Value json = make_filter_data_with_values(50); - EXPECT_TRUE(AttributionFilterData::FromSourceJSON(&json).has_value()); + EXPECT_TRUE(AttributionFilterData::FromJSON(&json).has_value()); } { base::Value json = make_filter_data_with_value_length(25); - EXPECT_TRUE(AttributionFilterData::FromSourceJSON(&json).has_value()); + EXPECT_TRUE(AttributionFilterData::FromJSON(&json).has_value()); } } @@ -490,7 +490,7 @@ reporting_origin, source_time, default_expiry_time, source_type, /*priority=*/0, - AttributionFilterData::CreateForTesting({{"a", {"b"}}}), + *AttributionFilterData::Create({{"a", {"b"}}}), /*debug_key=*/absl::nullopt, AttributionAggregationKeys()), /*is_within_fenced_frame=*/false, /*debug_reporting=*/false),
diff --git a/content/browser/attribution_reporting/attribution_internals_browsertest.cc b/content/browser/attribution_reporting/attribution_internals_browsertest.cc index 9d1d917..a8cf8f1 100644 --- a/content/browser/attribution_reporting/attribution_internals_browsertest.cc +++ b/content/browser/attribution_reporting/attribution_internals_browsertest.cc
@@ -271,8 +271,8 @@ .SetPriority(std::numeric_limits<int64_t>::max()) .SetDedupKeys({13, 17}) .SetAggregatableBudgetConsumed(1300) - .SetFilterData(*AttributionFilterData::FromSourceFilterValues( - {{"a", {"b", "c"}}})) + .SetFilterData( + *AttributionFilterData::Create({{"a", {"b", "c"}}})) .SetAggregationKeys( *AttributionAggregationKeys::FromKeys({{"a", 1}})) .SetAggregatableDedupKeys({14, 18}) @@ -1011,8 +1011,8 @@ const AttributionTrigger trigger( url::Origin::Create(GURL("https://d.test")), url::Origin::Create(GURL("https://r.test")), - /*filters=*/AttributionFilterData::CreateForTesting({{"a", {"b"}}}), - /*not_filters=*/AttributionFilterData::CreateForTesting({{"g", {"h"}}}), + /*filters=*/*AttributionFilters::Create({{"a", {"b"}}}), + /*not_filters=*/*AttributionFilters::Create({{"g", {"h"}}}), /*debug_key=*/1, /*aggregatable_dedup_key=*/18, { @@ -1021,28 +1021,28 @@ /*priority=*/3, /*dedup_key=*/absl::nullopt, /*filters=*/ - AttributionFilterData::CreateForTesting({{"c", {"d"}}}), - /*not_filters=*/AttributionFilterData()), + *AttributionFilters::Create({{"c", {"d"}}}), + /*not_filters=*/AttributionFilters()), AttributionTrigger::EventTriggerData( /*data=*/4, /*priority=*/5, /*dedup_key=*/6, - /*filters=*/AttributionFilterData(), + /*filters=*/AttributionFilters(), /*not_filters=*/ - AttributionFilterData::CreateForTesting({{"e", {"f"}}})), + *AttributionFilters::Create({{"e", {"f"}}})), }, {AttributionAggregatableTriggerData::CreateForTesting( /*key_piece=*/345, /*source_keys=*/{"a"}, /*filters=*/ - AttributionFilterData::CreateForTesting({{"c", {"d"}}}), - /*not_filters=*/AttributionFilterData()), + *AttributionFilters::Create({{"c", {"d"}}}), + /*not_filters=*/AttributionFilters()), AttributionAggregatableTriggerData::CreateForTesting( /*key_piece=*/678, /*source_keys=*/{"b"}, - /*filters=*/AttributionFilterData(), + /*filters=*/AttributionFilters(), /*not_filters=*/ - AttributionFilterData::CreateForTesting({{"e", {"f"}}}))}, + *AttributionFilters::Create({{"e", {"f"}}}))}, /*aggregatable_values=*/ AttributionAggregatableValues::CreateForTesting( {{"a", 123}, {"b", 456}}));
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc index 7e57cb2c..35b914df 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
@@ -334,8 +334,7 @@ } absl::optional<AttributionFilterData> filter_data = - AttributionFilterData::DeserializeSourceFilterData( - statement.ColumnString(col++)); + AttributionFilterData::Deserialize(statement.ColumnString(col++)); if (!filter_data) return absl::nullopt;
diff --git a/content/browser/attribution_reporting/attribution_storage_unittest.cc b/content/browser/attribution_reporting/attribution_storage_unittest.cc index 37689f8..4d75502 100644 --- a/content/browser/attribution_reporting/attribution_storage_unittest.cc +++ b/content/browser/attribution_reporting/attribution_storage_unittest.cc
@@ -2494,8 +2494,7 @@ .SetSourceType(AttributionSourceType::kNavigation) .Build()); - auto filter_data = - AttributionFilterData::FromSourceFilterValues({{"abc", {"x", "y"}}}); + const auto filter_data = AttributionFilterData::Create({{"abc", {"x", "y"}}}); ASSERT_TRUE(filter_data.has_value()); storage()->StoreSource(SourceBuilder() @@ -2503,12 +2502,9 @@ .SetSourceType(AttributionSourceType::kEvent) .Build()); - EXPECT_THAT( - storage()->GetActiveSources(), - ElementsAre(SourceFilterDataIs(AttributionFilterData()), - SourceFilterDataIs(AttributionFilterData::CreateForTesting({ - {"abc", {"x", "y"}}, - })))); + EXPECT_THAT(storage()->GetActiveSources(), + ElementsAre(SourceFilterDataIs(AttributionFilterData()), + SourceFilterDataIs(filter_data))); } TEST_F(AttributionStorageTest, NoMatchingTriggerData_ReturnsError) { @@ -2520,23 +2516,23 @@ .SetReportingOrigin(origin) .Build()); - EXPECT_EQ(AttributionTrigger::EventLevelResult::kNoMatchingConfigurations, - MaybeCreateAndStoreEventLevelReport(AttributionTrigger( - origin, origin, - /*filters=*/AttributionFilterData(), - /*not_filters=*/AttributionFilterData(), - /*debug_key=*/absl::nullopt, - /*aggregatable_dedup_key=*/absl::nullopt, - {AttributionTrigger::EventTriggerData( - /*data=*/11, - /*priority=*/12, - /*dedup_key=*/13, - /*filters=*/ - AttributionFilterData::ForSourceType( - AttributionSourceType::kEvent), - /*not_filters=*/AttributionFilterData())}, - /*aggregatable_trigger_data=*/{}, - /*aggregatable_values=*/AttributionAggregatableValues()))); + EXPECT_EQ( + AttributionTrigger::EventLevelResult::kNoMatchingConfigurations, + MaybeCreateAndStoreEventLevelReport(AttributionTrigger( + origin, origin, + /*filters=*/AttributionFilters(), + /*not_filters=*/AttributionFilters(), + /*debug_key=*/absl::nullopt, + /*aggregatable_dedup_key=*/absl::nullopt, + {AttributionTrigger::EventTriggerData( + /*data=*/11, + /*priority=*/12, + /*dedup_key=*/13, + /*filters=*/ + AttributionFilters::ForSourceType(AttributionSourceType::kEvent), + /*not_filters=*/AttributionFilters())}, + /*aggregatable_trigger_data=*/{}, + /*aggregatable_values=*/AttributionAggregatableValues()))); EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty()); @@ -2552,8 +2548,7 @@ .SetSourceType(AttributionSourceType::kNavigation) .SetDestinationOrigin(origin) .SetReportingOrigin(origin) - .SetFilterData(*AttributionFilterData::FromSourceFilterValues( - {{"abc", {"123"}}})) + .SetFilterData(*AttributionFilterData::Create({{"abc", {"123"}}})) .Build()); const std::vector<AttributionTrigger::EventTriggerData> event_triggers = { @@ -2563,10 +2558,10 @@ /*priority=*/12, /*dedup_key=*/13, /*filters=*/ - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"abc", {"456"}}, }), - /*not_filters=*/AttributionFilterData()), + /*not_filters=*/AttributionFilters()), // Filters match, but negated filters do not. AttributionTrigger::EventTriggerData( @@ -2574,11 +2569,11 @@ /*priority=*/22, /*dedup_key=*/23, /*filters=*/ - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"abc", {"123"}}, }), /*not_filters=*/ - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"source_type", {"navigation"}}, })), @@ -2588,11 +2583,11 @@ /*priority=*/32, /*dedup_key=*/33, /*filters=*/ - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"abc", {"123"}}, }), /*not_filters=*/ - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"source_type", {"event"}}, })), @@ -2603,11 +2598,11 @@ /*priority=*/42, /*dedup_key=*/43, /*filters=*/ - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"abc", {"123"}}, }), /*not_filters=*/ - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"source_type", {"event"}}, })), }; @@ -2615,8 +2610,8 @@ EXPECT_EQ(AttributionTrigger::EventLevelResult::kSuccess, MaybeCreateAndStoreEventLevelReport(AttributionTrigger( origin, origin, - /*filters=*/AttributionFilterData(), - /*not_filters=*/AttributionFilterData(), + /*filters=*/AttributionFilters(), + /*not_filters=*/AttributionFilters(), /*debug_key=*/absl::nullopt, /*aggregatable_dedup_key=*/absl::nullopt, event_triggers, /*aggregatable_trigger_data=*/{}, @@ -2637,8 +2632,8 @@ AttributionAggregatableTriggerData::CreateForTesting( absl::MakeUint128(/*high=*/1, /*low=*/0), /*source_keys=*/{"0"}, - /*filters=*/AttributionFilterData(), - /*not_filters=*/AttributionFilterData())}; + /*filters=*/AttributionFilters(), + /*not_filters=*/AttributionFilters())}; auto aggregatable_values = AttributionAggregatableValues::CreateForTesting({{"0", 1}}); @@ -2647,17 +2642,16 @@ SourceBuilder() .SetDestinationOrigin(origin) .SetReportingOrigin(origin) - .SetFilterData(*AttributionFilterData::FromSourceFilterValues( - {{"abc", {"123"}}})) + .SetFilterData(*AttributionFilterData::Create({{"abc", {"123"}}})) .SetAggregationKeys(*AttributionAggregationKeys::FromKeys({{"0", 1}})) .Build()); AttributionTrigger trigger1(origin, origin, /*filters=*/ - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"abc", {"456"}}, }), - /*not_filters=*/AttributionFilterData(), + /*not_filters=*/AttributionFilters(), /*debug_key=*/absl::nullopt, /*aggregatable_dedup_key=*/absl::nullopt, /*event_triggers=*/{}, aggregatable_trigger_data, @@ -2665,10 +2659,10 @@ AttributionTrigger trigger2(origin, origin, /*filters=*/ - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"abc", {"123"}}, }), - /*not_filters=*/AttributionFilterData(), + /*not_filters=*/AttributionFilters(), /*debug_key=*/absl::nullopt, /*aggregatable_dedup_key=*/absl::nullopt, /*event_triggers=*/{}, aggregatable_trigger_data, @@ -2676,9 +2670,9 @@ AttributionTrigger trigger3( origin, origin, - /*filters=*/AttributionFilterData(), + /*filters=*/AttributionFilters(), /*not_filters=*/ - AttributionFilterData::ForSourceType(AttributionSourceType::kNavigation), + AttributionFilters::ForSourceType(AttributionSourceType::kNavigation), /*debug_key=*/absl::nullopt, /*aggregatable_dedup_key=*/absl::nullopt, /*event_triggers=*/{}, aggregatable_trigger_data, aggregatable_values); @@ -2815,8 +2809,7 @@ TEST_F(AttributionStorageTest, AggregatableReportFiltering) { storage()->StoreSource( SourceBuilder() - .SetFilterData(*AttributionFilterData::FromSourceFilterValues( - {{"abc", {"123"}}})) + .SetFilterData(*AttributionFilterData::Create({{"abc", {"123"}}})) .SetAggregationKeys(*AttributionAggregationKeys::FromKeys({{"0", 1}})) .Build()); @@ -2827,8 +2820,8 @@ absl::MakeUint128(/*high=*/1, /*low=*/0), /*source_keys=*/{"0"}, /*filters=*/ - AttributionFilterData(), - /*not_filters=*/AttributionFilterData())}) + AttributionFilters(), + /*not_filters=*/AttributionFilters())}) .Build()), AttributionTrigger::AggregatableResult::kNoHistograms); }
diff --git a/content/browser/attribution_reporting/attribution_test_utils.cc b/content/browser/attribution_reporting/attribution_test_utils.cc index fc155ba..87687126 100644 --- a/content/browser/attribution_reporting/attribution_test_utils.cc +++ b/content/browser/attribution_reporting/attribution_test_utils.cc
@@ -656,22 +656,22 @@ std::vector<AttributionTrigger::EventTriggerData> event_triggers; if (generate_event_trigger_data) { - event_triggers.emplace_back(trigger_data_, priority_, dedup_key_, - /*filters=*/ - AttributionFilterData::ForSourceType( - AttributionSourceType::kNavigation), - /*not_filters=*/AttributionFilterData()); + event_triggers.emplace_back( + trigger_data_, priority_, dedup_key_, + /*filters=*/ + AttributionFilters::ForSourceType(AttributionSourceType::kNavigation), + /*not_filters=*/AttributionFilters()); event_triggers.emplace_back( event_source_trigger_data_, priority_, dedup_key_, /*filters=*/ - AttributionFilterData::ForSourceType(AttributionSourceType::kEvent), - /*not_filters=*/AttributionFilterData()); + AttributionFilters::ForSourceType(AttributionSourceType::kEvent), + /*not_filters=*/AttributionFilters()); } return AttributionTrigger(destination_origin_, reporting_origin_, - /*filters=*/AttributionFilterData(), - /*not_filters=*/AttributionFilterData(), debug_key_, + /*filters=*/AttributionFilters(), + /*not_filters=*/AttributionFilters(), debug_key_, aggregatable_dedup_key_, std::move(event_triggers), aggregatable_trigger_data_, aggregatable_values_); } @@ -787,6 +787,10 @@ return a.filter_values() == b.filter_values(); } +bool operator==(const AttributionFilters& a, const AttributionFilters& b) { + return a.filter_values() == b.filter_values(); +} + bool operator==(const CommonSourceInfo& a, const CommonSourceInfo& b) { const auto tie = [](const CommonSourceInfo& source) { return std::make_tuple(source.source_event_id(), source.source_origin(), @@ -1096,12 +1100,15 @@ return out << "}"; } -std::ostream& operator<<(std::ostream& out, - const AttributionFilterData& filter_data) { +namespace { + +std::ostream& WriteAttributionFilterValues( + std::ostream& out, + const AttributionFilterValues& filter_values) { out << "{"; const char* outer_separator = ""; - for (const auto& [filter, values] : filter_data.filter_values()) { + for (const auto& [filter, values] : filter_values) { out << outer_separator << filter << "=["; const char* inner_separator = ""; @@ -1117,6 +1124,17 @@ return out << "}"; } +} // namespace + +std::ostream& operator<<(std::ostream& out, + const AttributionFilterData& filter_data) { + return WriteAttributionFilterValues(out, filter_data.filter_values()); +} + +std::ostream& operator<<(std::ostream& out, const AttributionFilters& filters) { + return WriteAttributionFilterValues(out, filters.filter_values()); +} + std::ostream& operator<<(std::ostream& out, const CommonSourceInfo& source) { return out << "{source_event_id=" << source.source_event_id() << ",source_origin=" << source.source_origin() @@ -1348,8 +1366,8 @@ ::testing::Matcher<uint64_t> data, ::testing::Matcher<int64_t> priority, ::testing::Matcher<absl::optional<uint64_t>> dedup_key, - ::testing::Matcher<const AttributionFilterData&> filters, - ::testing::Matcher<const AttributionFilterData&> not_filters) + ::testing::Matcher<const AttributionFilters&> filters, + ::testing::Matcher<const AttributionFilters&> not_filters) : data(std::move(data)), priority(std::move(priority)), dedup_key(std::move(dedup_key)), @@ -1375,7 +1393,7 @@ AttributionTriggerMatcherConfig::AttributionTriggerMatcherConfig( ::testing::Matcher<const url::Origin&> destination_origin, ::testing::Matcher<const url::Origin&> reporting_origin, - ::testing::Matcher<const AttributionFilterData&> filters, + ::testing::Matcher<const AttributionFilters&> filters, ::testing::Matcher<absl::optional<uint64_t>> debug_key, ::testing::Matcher<const std::vector<AttributionTrigger::EventTriggerData>&> event_triggers, @@ -1458,8 +1476,8 @@ AttributionAggregatableTriggerData::CreateForTesting( absl::MakeUint128(/*high=*/i, /*low=*/0), /*source_keys=*/base::flat_set<std::string>{key_id}, - /*filters=*/AttributionFilterData(), - /*not_filters=*/AttributionFilterData())); + /*filters=*/AttributionFilters(), + /*not_filters=*/AttributionFilters())); aggregatable_values.emplace(std::move(key_id), histogram_values[i]); }
diff --git a/content/browser/attribution_reporting/attribution_test_utils.h b/content/browser/attribution_reporting/attribution_test_utils.h index b650015..5465ca8 100644 --- a/content/browser/attribution_reporting/attribution_test_utils.h +++ b/content/browser/attribution_reporting/attribution_test_utils.h
@@ -623,6 +623,8 @@ bool operator==(const AttributionFilterData& a, const AttributionFilterData& b); +bool operator==(const AttributionFilters& a, const AttributionFilters& b); + bool operator==(const CommonSourceInfo& a, const CommonSourceInfo& b); bool operator==(const AttributionInfo& a, const AttributionInfo& b); @@ -674,6 +676,8 @@ std::ostream& operator<<(std::ostream& out, const AttributionFilterData& filter_data); +std::ostream& operator<<(std::ostream& out, const AttributionFilters& filters); + std::ostream& operator<<(std::ostream& out, const CommonSourceInfo& source); std::ostream& operator<<(std::ostream& out, @@ -900,17 +904,16 @@ ::testing::Matcher<uint64_t> data; ::testing::Matcher<int64_t> priority; ::testing::Matcher<absl::optional<uint64_t>> dedup_key; - ::testing::Matcher<const AttributionFilterData&> filters; - ::testing::Matcher<const AttributionFilterData&> not_filters; + ::testing::Matcher<const AttributionFilters&> filters; + ::testing::Matcher<const AttributionFilters&> not_filters; EventTriggerDataMatcherConfig() = delete; EventTriggerDataMatcherConfig( ::testing::Matcher<uint64_t> data = ::testing::_, ::testing::Matcher<int64_t> priority = ::testing::_, ::testing::Matcher<absl::optional<uint64_t>> dedup_key = ::testing::_, - ::testing::Matcher<const AttributionFilterData&> filters = ::testing::_, - ::testing::Matcher<const AttributionFilterData&> not_filters = - ::testing::_); + ::testing::Matcher<const AttributionFilters&> filters = ::testing::_, + ::testing::Matcher<const AttributionFilters&> not_filters = ::testing::_); ~EventTriggerDataMatcherConfig(); }; @@ -920,7 +923,7 @@ struct AttributionTriggerMatcherConfig { ::testing::Matcher<const url::Origin&> destination_origin = ::testing::_; ::testing::Matcher<const url::Origin&> reporting_origin = ::testing::_; - ::testing::Matcher<const AttributionFilterData&> filters = ::testing::_; + ::testing::Matcher<const AttributionFilters&> filters = ::testing::_; ::testing::Matcher<absl::optional<uint64_t>> debug_key = ::testing::_; ::testing::Matcher<const std::vector<AttributionTrigger::EventTriggerData>&> event_triggers = ::testing::_; @@ -931,7 +934,7 @@ AttributionTriggerMatcherConfig( ::testing::Matcher<const url::Origin&> destination_origin = ::testing::_, ::testing::Matcher<const url::Origin&> reporting_origin = ::testing::_, - ::testing::Matcher<const AttributionFilterData&> filters = ::testing::_, + ::testing::Matcher<const AttributionFilters&> filters = ::testing::_, ::testing::Matcher<absl::optional<uint64_t>> debug_key = ::testing::_, ::testing::Matcher<const std::vector< AttributionTrigger::EventTriggerData>&> event_triggers = ::testing::_,
diff --git a/content/browser/attribution_reporting/attribution_trigger.cc b/content/browser/attribution_reporting/attribution_trigger.cc index e24fe8cd..e80e402 100644 --- a/content/browser/attribution_reporting/attribution_trigger.cc +++ b/content/browser/attribution_reporting/attribution_trigger.cc
@@ -16,8 +16,8 @@ uint64_t data, int64_t priority, absl::optional<uint64_t> dedup_key, - AttributionFilterData filters, - AttributionFilterData not_filters) + AttributionFilters filters, + AttributionFilters not_filters) : data(data), priority(priority), dedup_key(dedup_key), @@ -27,8 +27,8 @@ AttributionTrigger::AttributionTrigger( url::Origin destination_origin, url::Origin reporting_origin, - AttributionFilterData filters, - AttributionFilterData not_filters, + AttributionFilters filters, + AttributionFilters not_filters, absl::optional<uint64_t> debug_key, absl::optional<uint64_t> aggregatable_dedup_key, std::vector<EventTriggerData> event_triggers,
diff --git a/content/browser/attribution_reporting/attribution_trigger.h b/content/browser/attribution_reporting/attribution_trigger.h index 12ad384..bc745048 100644 --- a/content/browser/attribution_reporting/attribution_trigger.h +++ b/content/browser/attribution_reporting/attribution_trigger.h
@@ -86,17 +86,17 @@ // The filters used to determine whether this `EventTriggerData'`s fields // are used. - AttributionFilterData filters; + AttributionFilters filters; // The negated filters used to determine whether this `EventTriggerData'`s // fields are used. - AttributionFilterData not_filters; + AttributionFilters not_filters; EventTriggerData(uint64_t data, int64_t priority, absl::optional<uint64_t> dedup_key, - AttributionFilterData filters, - AttributionFilterData not_filters); + AttributionFilters filters, + AttributionFilters not_filters); }; // Should only be created with values that the browser process has already @@ -105,8 +105,8 @@ AttributionTrigger( url::Origin destination_origin, url::Origin reporting_origin, - AttributionFilterData filters, - AttributionFilterData not_filters, + AttributionFilters filters, + AttributionFilters not_filters, absl::optional<uint64_t> debug_key, absl::optional<uint64_t> aggregatable_dedup_key, std::vector<EventTriggerData> event_triggers, @@ -123,9 +123,9 @@ const url::Origin& reporting_origin() const { return reporting_origin_; } - const AttributionFilterData& filters() const { return filters_; } + const AttributionFilters& filters() const { return filters_; } - const AttributionFilterData& not_filters() const { return not_filters_; } + const AttributionFilters& not_filters() const { return not_filters_; } absl::optional<uint64_t> debug_key() const { return debug_key_; } @@ -156,9 +156,9 @@ // reports. url::Origin reporting_origin_; - AttributionFilterData filters_; + AttributionFilters filters_; - AttributionFilterData not_filters_; + AttributionFilters not_filters_; absl::optional<uint64_t> debug_key_;
diff --git a/content/browser/attribution_reporting/attribution_utils.cc b/content/browser/attribution_reporting/attribution_utils.cc index c1fe43e..072ecb04 100644 --- a/content/browser/attribution_reporting/attribution_utils.cc +++ b/content/browser/attribution_reporting/attribution_utils.cc
@@ -127,7 +127,7 @@ bool AttributionFilterDataMatch(const AttributionFilterData& source, AttributionSourceType source_type, - const AttributionFilterData& trigger, + const AttributionFilters& trigger, bool negated) { // A filter is considered matched if the filter key is only present either on // the source or trigger, or the intersection of the filter values is @@ -172,8 +172,8 @@ bool AttributionFiltersMatch(const AttributionFilterData& source_filter_data, AttributionSourceType source_type, - const AttributionFilterData& trigger_filters, - const AttributionFilterData& trigger_not_filters) { + const AttributionFilters& trigger_filters, + const AttributionFilters& trigger_not_filters) { return AttributionFilterDataMatch(source_filter_data, source_type, trigger_filters) && AttributionFilterDataMatch(source_filter_data, source_type,
diff --git a/content/browser/attribution_reporting/attribution_utils.h b/content/browser/attribution_reporting/attribution_utils.h index 4468a9be..06c5c1e 100644 --- a/content/browser/attribution_reporting/attribution_utils.h +++ b/content/browser/attribution_reporting/attribution_utils.h
@@ -18,6 +18,7 @@ namespace content { class AttributionFilterData; +class AttributionFilters; class CommonSourceInfo; // Calculates the report time for a conversion associated with a given @@ -41,14 +42,14 @@ CONTENT_EXPORT bool AttributionFilterDataMatch( const AttributionFilterData& source, AttributionSourceType, - const AttributionFilterData& trigger, + const AttributionFilters& trigger, bool negated = false); CONTENT_EXPORT bool AttributionFiltersMatch( const AttributionFilterData& source_filter_data, AttributionSourceType, - const AttributionFilterData& trigger_filters, - const AttributionFilterData& trigger_not_filters); + const AttributionFilters& trigger_filters, + const AttributionFilters& trigger_not_filters); } // namespace content
diff --git a/content/browser/attribution_reporting/attribution_utils_unittest.cc b/content/browser/attribution_reporting/attribution_utils_unittest.cc index d42c268..91f8b3e 100644 --- a/content/browser/attribution_reporting/attribution_utils_unittest.cc +++ b/content/browser/attribution_reporting/attribution_utils_unittest.cc
@@ -11,193 +11,188 @@ #include "testing/gtest/include/gtest/gtest.h" namespace content { +namespace { TEST(AttributionUtilsTest, EmptyOrMissingAttributionFilters) { - auto empty_filter = AttributionFilterData(); + const auto empty_filter = AttributionFilterValues(); - auto empty_filter_values = - AttributionFilterData::FromSourceFilterValues({{"filter1", {}}}); - ASSERT_TRUE(empty_filter_values.has_value()); + const auto empty_filter_values = AttributionFilterValues({{"filter1", {}}}); - auto one_filter = - AttributionFilterData::FromSourceFilterValues({{"filter1", {"value1"}}}); - ASSERT_TRUE(one_filter.has_value()); + const auto one_filter = AttributionFilterValues({{"filter1", {"value1"}}}); const struct { - std::string description; - AttributionFilterData source_filter_data; - AttributionFilterData trigger_filter_data; - bool match_expected; - } kTestCases[] = {{"No source filters, no trigger filters", empty_filter, - empty_filter, true}, - {"No source filters, trigger filter without values", - empty_filter, *empty_filter_values, true}, - {"No source filters, trigger filter with value", - empty_filter, *one_filter, true}, + const char* description; + AttributionFilterValues filter_data; + AttributionFilterValues filters; + } kTestCases[] = { + {"No source filters, no trigger filters", empty_filter, empty_filter}, + {"No source filters, trigger filter without values", empty_filter, + empty_filter_values}, + {"No source filters, trigger filter with value", empty_filter, + one_filter}, - {"Source filter without values, no trigger filters", - *empty_filter_values, empty_filter, true}, + {"Source filter without values, no trigger filters", empty_filter_values, + empty_filter}, - {"Source filter with value, no trigger filters", - *one_filter, empty_filter, true}}; + {"Source filter with value, no trigger filters", one_filter, + empty_filter}}; // Behavior should match for for negated and non-negated filters as it // requires a value on each side. for (const auto& test_case : kTestCases) { - EXPECT_EQ(test_case.match_expected, - AttributionFilterDataMatch(test_case.source_filter_data, - AttributionSourceType::kNavigation, - test_case.trigger_filter_data)) + absl::optional<AttributionFilterData> filter_data = + AttributionFilterData::Create(test_case.filter_data); + ASSERT_TRUE(filter_data) << test_case.description; + + absl::optional<AttributionFilters> filters = + AttributionFilters::Create(test_case.filters); + ASSERT_TRUE(filters) << test_case.description; + + EXPECT_TRUE(AttributionFilterDataMatch( + *filter_data, AttributionSourceType::kNavigation, *filters)) << test_case.description; - EXPECT_EQ(test_case.match_expected, - AttributionFilterDataMatch(test_case.source_filter_data, - AttributionSourceType::kNavigation, - test_case.trigger_filter_data, - /*negated=*/true)) + EXPECT_TRUE(AttributionFilterDataMatch( + *filter_data, AttributionSourceType::kNavigation, *filters, + /*negated=*/true)) << test_case.description << " with negation"; } } TEST(AttributionUtilsTest, AttributionFilterDataMatch) { - auto empty_filter_values = - AttributionFilterData::FromSourceFilterValues({{"filter1", {}}}); - ASSERT_TRUE(empty_filter_values.has_value()); + const auto empty_filter_values = AttributionFilterValues({{"filter1", {}}}); - auto one_filter = - AttributionFilterData::FromSourceFilterValues({{"filter1", {"value1"}}}); - ASSERT_TRUE(one_filter.has_value()); + const auto one_filter = AttributionFilterValues({{"filter1", {"value1"}}}); - auto one_filter_different = - AttributionFilterData::FromSourceFilterValues({{"filter1", {"value2"}}}); - ASSERT_TRUE(one_filter_different.has_value()); + const auto one_filter_different = + AttributionFilterValues({{"filter1", {"value2"}}}); - auto two_filters = AttributionFilterData::FromSourceFilterValues( + const auto two_filters = AttributionFilterValues( {{"filter1", {"value1"}}, {"filter2", {"value2"}}}); - ASSERT_TRUE(two_filters.has_value()); - auto one_mismatched_filter = AttributionFilterData::FromSourceFilterValues( + const auto one_mismatched_filter = AttributionFilterValues( {{"filter1", {"value1"}}, {"filter2", {"value3"}}}); - ASSERT_TRUE(one_mismatched_filter.has_value()); - auto two_mismatched_filter = AttributionFilterData::FromSourceFilterValues( + const auto two_mismatched_filter = AttributionFilterValues( {{"filter1", {"value3"}}, {"filter2", {"value4"}}}); - ASSERT_TRUE(two_mismatched_filter.has_value()); const struct { - std::string description; - AttributionFilterData source_filter_data; - AttributionFilterData trigger_filter_data; + const char* description; + AttributionFilterValues filter_data; + AttributionFilterValues filters; bool match_expected; } kTestCases[] = { {"Source filter without values, trigger filter with value", - *empty_filter_values, *one_filter, false}, + empty_filter_values, one_filter, false}, {"Source filter without values, trigger filter without values", - *empty_filter_values, *empty_filter_values, true}, - {"Source filter with value, trigger filter without values", *one_filter, - *empty_filter_values, false}, + empty_filter_values, empty_filter_values, true}, + {"Source filter with value, trigger filter without values", one_filter, + empty_filter_values, false}, - {"One filter with matching values", *one_filter, *one_filter, true}, - {"One filter with no matching values", *one_filter, *one_filter_different, + {"One filter with matching values", one_filter, one_filter, true}, + {"One filter with no matching values", one_filter, one_filter_different, false}, - {"Two filters with matching values", *two_filters, *two_filters, true}, - {"Two filters no matching values", *one_mismatched_filter, - *two_mismatched_filter, false}, + {"Two filters with matching values", two_filters, two_filters, true}, + {"Two filters no matching values", one_mismatched_filter, + two_mismatched_filter, false}, - {"One filter not present in source, other matches", *one_filter, - *two_filters, true}, - {"One filter not present in trigger, other matches", *two_filters, - *one_filter, true}, + {"One filter not present in source, other matches", one_filter, + two_filters, true}, + {"One filter not present in trigger, other matches", two_filters, + one_filter, true}, - {"Two filters one filter no match", *two_filters, *one_mismatched_filter, + {"Two filters one filter no match", two_filters, one_mismatched_filter, false}, }; for (const auto& test_case : kTestCases) { + absl::optional<AttributionFilterData> filter_data = + AttributionFilterData::Create(test_case.filter_data); + ASSERT_TRUE(filter_data) << test_case.description; + + absl::optional<AttributionFilters> filters = + AttributionFilters::Create(test_case.filters); + ASSERT_TRUE(filters) << test_case.description; + EXPECT_EQ(test_case.match_expected, - AttributionFilterDataMatch(test_case.source_filter_data, - AttributionSourceType::kNavigation, - test_case.trigger_filter_data)) + AttributionFilterDataMatch( + *filter_data, AttributionSourceType::kNavigation, *filters)) << test_case.description; } } TEST(AttributionUtilsTest, NegatedAttributionFilterDataMatch) { - auto empty_filter_values = - AttributionFilterData::FromSourceFilterValues({{"filter1", {}}}); - ASSERT_TRUE(empty_filter_values.has_value()); + const auto empty_filter_values = AttributionFilterValues({{"filter1", {}}}); - auto one_filter = - AttributionFilterData::FromSourceFilterValues({{"filter1", {"value1"}}}); - ASSERT_TRUE(one_filter.has_value()); + const auto one_filter = AttributionFilterValues({{"filter1", {"value1"}}}); - auto one_filter_different = - AttributionFilterData::FromSourceFilterValues({{"filter1", {"value2"}}}); - ASSERT_TRUE(one_filter_different.has_value()); + const auto one_filter_different = + AttributionFilterValues({{"filter1", {"value2"}}}); - auto one_filter_one_different = AttributionFilterData::FromSourceFilterValues( - {{"filter1", {"value1", "value2"}}}); - ASSERT_TRUE(one_filter_different.has_value()); + const auto one_filter_one_different = + AttributionFilterValues({{"filter1", {"value1", "value2"}}}); - auto one_filter_multiple_different = - AttributionFilterData::FromSourceFilterValues( - {{"filter1", {"value2", "value3"}}}); - ASSERT_TRUE(one_filter_different.has_value()); + const auto one_filter_multiple_different = + AttributionFilterValues({{"filter1", {"value2", "value3"}}}); - auto two_filters = AttributionFilterData::FromSourceFilterValues( + const auto two_filters = AttributionFilterValues( {{"filter1", {"value1"}}, {"filter2", {"value2"}}}); - ASSERT_TRUE(two_filters.has_value()); - auto one_mismatched_filter = AttributionFilterData::FromSourceFilterValues( + const auto one_mismatched_filter = AttributionFilterValues( {{"filter1", {"value1"}}, {"filter2", {"value3"}}}); - ASSERT_TRUE(one_mismatched_filter.has_value()); - auto two_mismatched_filter = AttributionFilterData::FromSourceFilterValues( + const auto two_mismatched_filter = AttributionFilterValues( {{"filter1", {"value3"}}, {"filter2", {"value4"}}}); - ASSERT_TRUE(two_mismatched_filter.has_value()); const struct { - std::string description; - AttributionFilterData source_filter_data; - AttributionFilterData trigger_filter_data; + const char* description; + AttributionFilterValues filter_data; + AttributionFilterValues filters; bool match_expected; } kTestCases[] = { // True because there is not matching values within source. {"Source filter without values, trigger filter with value", - *empty_filter_values, *one_filter, true}, + empty_filter_values, one_filter, true}, {"Source filter without values, trigger filter without values", - *empty_filter_values, *empty_filter_values, false}, - {"Source filter with value, trigger filter without values", *one_filter, - *empty_filter_values, true}, + empty_filter_values, empty_filter_values, false}, + {"Source filter with value, trigger filter without values", one_filter, + empty_filter_values, true}, - {"One filter with matching values", *one_filter, *one_filter, false}, - {"One filter with non-matching value", *one_filter, *one_filter_different, + {"One filter with matching values", one_filter, one_filter, false}, + {"One filter with non-matching value", one_filter, one_filter_different, true}, - {"One filter with one non-matching value", *one_filter, - *one_filter_one_different, false}, - {"One filter with multiple non-matching values", *one_filter, - *one_filter_multiple_different, true}, + {"One filter with one non-matching value", one_filter, + one_filter_one_different, false}, + {"One filter with multiple non-matching values", one_filter, + one_filter_multiple_different, true}, - {"Two filters with matching values", *two_filters, *two_filters, false}, - {"Two filters no matching values", *one_mismatched_filter, - *two_mismatched_filter, true}, + {"Two filters with matching values", two_filters, two_filters, false}, + {"Two filters no matching values", one_mismatched_filter, + two_mismatched_filter, true}, - {"One filter not present in source, other matches", *one_filter, - *two_filters, false}, - {"One filter not present in trigger, other matches", *two_filters, - *one_filter, false}, + {"One filter not present in source, other matches", one_filter, + two_filters, false}, + {"One filter not present in trigger, other matches", two_filters, + one_filter, false}, - {"Two filters one filter no match", *two_filters, *one_mismatched_filter, + {"Two filters one filter no match", two_filters, one_mismatched_filter, false}, }; for (const auto& test_case : kTestCases) { + absl::optional<AttributionFilterData> filter_data = + AttributionFilterData::Create(test_case.filter_data); + ASSERT_TRUE(filter_data) << test_case.description; + + absl::optional<AttributionFilters> filters = + AttributionFilters::Create(test_case.filters); + ASSERT_TRUE(filters) << test_case.description; + EXPECT_EQ(test_case.match_expected, - AttributionFilterDataMatch(test_case.source_filter_data, - AttributionSourceType::kNavigation, - test_case.trigger_filter_data, - /*negated=*/true)) + AttributionFilterDataMatch( + *filter_data, AttributionSourceType::kNavigation, *filters, + /*negated=*/true)) << test_case.description << " with negation"; } } @@ -206,28 +201,28 @@ const struct { const char* description; AttributionSourceType source_type; - AttributionFilterData trigger_filters; + AttributionFilters filters; bool negated; bool match_expected; } kTestCases[] = { { .description = "empty-filters", .source_type = AttributionSourceType::kNavigation, - .trigger_filters = AttributionFilterData(), + .filters = AttributionFilters(), .negated = false, .match_expected = true, }, { .description = "empty-filters-negated", .source_type = AttributionSourceType::kNavigation, - .trigger_filters = AttributionFilterData(), + .filters = AttributionFilters(), .negated = true, .match_expected = true, }, { .description = "empty-filter-values", .source_type = AttributionSourceType::kNavigation, - .trigger_filters = AttributionFilterData::CreateForTesting({ + .filters = *AttributionFilters::Create({ {AttributionFilterData::kSourceTypeFilterKey, {}}, }), .negated = false, @@ -236,7 +231,7 @@ { .description = "empty-filter-values-negated", .source_type = AttributionSourceType::kNavigation, - .trigger_filters = AttributionFilterData::CreateForTesting({ + .filters = *AttributionFilters::Create({ {AttributionFilterData::kSourceTypeFilterKey, {}}, }), .negated = true, @@ -245,36 +240,32 @@ { .description = "same-source-type", .source_type = AttributionSourceType::kNavigation, - .trigger_filters = AttributionFilterData::CreateForTesting({ - {AttributionFilterData::kSourceTypeFilterKey, {"navigation"}}, - }), + .filters = AttributionFilters::ForSourceType( + AttributionSourceType::kNavigation), .negated = false, .match_expected = true, }, { .description = "same-source-type-negated", .source_type = AttributionSourceType::kNavigation, - .trigger_filters = AttributionFilterData::CreateForTesting({ - {AttributionFilterData::kSourceTypeFilterKey, {"navigation"}}, - }), + .filters = AttributionFilters::ForSourceType( + AttributionSourceType::kNavigation), .negated = true, .match_expected = false, }, { .description = "other-source-type", .source_type = AttributionSourceType::kNavigation, - .trigger_filters = AttributionFilterData::CreateForTesting({ - {AttributionFilterData::kSourceTypeFilterKey, {"event"}}, - }), + .filters = + AttributionFilters::ForSourceType(AttributionSourceType::kEvent), .negated = false, .match_expected = false, }, { .description = "other-source-type-negated", .source_type = AttributionSourceType::kNavigation, - .trigger_filters = AttributionFilterData::CreateForTesting({ - {AttributionFilterData::kSourceTypeFilterKey, {"event"}}, - }), + .filters = + AttributionFilters::ForSourceType(AttributionSourceType::kEvent), .negated = true, .match_expected = true, }, @@ -282,11 +273,12 @@ for (const auto& test_case : kTestCases) { EXPECT_EQ(test_case.match_expected, - AttributionFilterDataMatch( - AttributionFilterData(), test_case.source_type, - test_case.trigger_filters, test_case.negated)) + AttributionFilterDataMatch(AttributionFilterData(), + test_case.source_type, + test_case.filters, test_case.negated)) << test_case.description; } } +} // namespace } // namespace content
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h index abfc3eb..b6189e5 100644 --- a/content/browser/bad_message.h +++ b/content/browser/bad_message.h
@@ -314,6 +314,8 @@ MSDH_INCONSISTENT_AUDIO_TYPE_AND_REQUESTED_FIELDS = 287, MSDH_INCONSISTENT_VIDEO_TYPE_AND_REQUESTED_FIELDS = 288, MSDH_SUPPRESS_LOCAL_AUDIO_PLAYBACK_BUT_AUDIO_NOT_REQUESTED = 289, + MSDH_HOTWORD_ENABLED_BUT_AUDIO_NOT_REQUESTED = 290, + MSDH_DISABLE_LOCAL_ECHO_BUT_AUDIO_NOT_REQUESTED = 291, // Please add new elements here. The naming convention is abbreviated class // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc index 3eb80765..8c60e1c 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -759,6 +759,14 @@ return bad_message:: MSDH_SUPPRESS_LOCAL_AUDIO_PLAYBACK_BUT_AUDIO_NOT_REQUESTED; } + + if (controls.hotword_enabled) { + return bad_message::MSDH_HOTWORD_ENABLED_BUT_AUDIO_NOT_REQUESTED; + } + + if (controls.disable_local_echo) { + return bad_message::MSDH_DISABLE_LOCAL_ECHO_BUT_AUDIO_NOT_REQUESTED; + } } return absl::nullopt;
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc index 3b38c93f..be9ccac 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -590,68 +590,6 @@ EXPECT_FALSE(video_device(/*stream_index=*/0u).has_value()); } -class MediaStreamDispatcherHostStreamTypeCombinationTest - : public MediaStreamDispatcherHostTest, - public ::testing::WithParamInterface<std::tuple<int, int>> {}; - -TEST_P(MediaStreamDispatcherHostStreamTypeCombinationTest, - GenerateStreamWithStreamTypeCombination) { - using blink::mojom::MediaStreamType; - - std::set<std::tuple<MediaStreamType, MediaStreamType>> kValidCombinations = { - {MediaStreamType::NO_SERVICE, MediaStreamType::NO_SERVICE}, - {MediaStreamType::NO_SERVICE, MediaStreamType::DEVICE_VIDEO_CAPTURE}, - {MediaStreamType::NO_SERVICE, MediaStreamType::GUM_TAB_VIDEO_CAPTURE}, - {MediaStreamType::NO_SERVICE, MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE}, - {MediaStreamType::NO_SERVICE, MediaStreamType::DISPLAY_VIDEO_CAPTURE}, - {MediaStreamType::NO_SERVICE, MediaStreamType::DISPLAY_VIDEO_CAPTURE_SET}, - {MediaStreamType::NO_SERVICE, - MediaStreamType::DISPLAY_VIDEO_CAPTURE_THIS_TAB}, - {MediaStreamType::DEVICE_AUDIO_CAPTURE, MediaStreamType::NO_SERVICE}, - {MediaStreamType::DEVICE_AUDIO_CAPTURE, - MediaStreamType::DEVICE_VIDEO_CAPTURE}, - {MediaStreamType::GUM_TAB_AUDIO_CAPTURE, MediaStreamType::NO_SERVICE}, - {MediaStreamType::GUM_TAB_AUDIO_CAPTURE, - MediaStreamType::GUM_TAB_VIDEO_CAPTURE}, - {MediaStreamType::GUM_DESKTOP_AUDIO_CAPTURE, - MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE}, - {MediaStreamType::DISPLAY_AUDIO_CAPTURE, - MediaStreamType::DISPLAY_VIDEO_CAPTURE}, - {MediaStreamType::DISPLAY_AUDIO_CAPTURE, - MediaStreamType::DISPLAY_VIDEO_CAPTURE_THIS_TAB}}; - - blink::StreamControls controls; - - controls.audio.stream_type = - static_cast<MediaStreamType>(std::get<0>(GetParam())); - controls.audio.requested = - (controls.audio.stream_type != MediaStreamType::NO_SERVICE); - - controls.video.stream_type = - static_cast<MediaStreamType>(std::get<1>(GetParam())); - controls.video.requested = - (controls.video.stream_type != MediaStreamType::NO_SERVICE); - - SetupFakeUI(true); - EXPECT_CALL( - *this, MockOnBadMessage( - kProcessId, bad_message::MSDH_INVALID_STREAM_TYPE_COMBINATION)) - .Times(!kValidCombinations.count(std::make_tuple( - controls.audio.stream_type, controls.video.stream_type))); - host_->OnGenerateStreams(kPageRequestId, controls); -} - -INSTANTIATE_TEST_SUITE_P( - , - MediaStreamDispatcherHostStreamTypeCombinationTest, - ::testing::Combine( - ::testing::Range( - static_cast<int>(blink::mojom::MediaStreamType::NO_SERVICE), - static_cast<int>(blink::mojom::MediaStreamType::NUM_MEDIA_TYPES)), - ::testing::Range( - static_cast<int>(blink::mojom::MediaStreamType::NO_SERVICE), - static_cast<int>(blink::mojom::MediaStreamType::NUM_MEDIA_TYPES)))); - TEST_F(MediaStreamDispatcherHostTest, BadMessageIfAudioRequestedButTypeIsNoService) { using blink::mojom::MediaStreamType; @@ -717,6 +655,48 @@ host_->OnGenerateStreams(kPageRequestId, controls); } +TEST_F(MediaStreamDispatcherHostTest, + BadMessageIfAudioNotRequestedAndHotwordEnabled) { + using blink::mojom::MediaStreamType; + + blink::StreamControls controls; + controls.audio.requested = false; + controls.audio.stream_type = MediaStreamType::NO_SERVICE; + controls.video.requested = true; + controls.video.stream_type = MediaStreamType::DISPLAY_VIDEO_CAPTURE; + controls.hotword_enabled = true; + + SetupFakeUI(true); + + EXPECT_CALL(*this, + MockOnBadMessage( + kProcessId, + bad_message::MSDH_HOTWORD_ENABLED_BUT_AUDIO_NOT_REQUESTED)) + .Times(1); + host_->OnGenerateStreams(kPageRequestId, controls); +} + +TEST_F(MediaStreamDispatcherHostTest, + BadMessageIfAudioNotRequestedAndDisableLocalEcho) { + using blink::mojom::MediaStreamType; + + blink::StreamControls controls; + controls.audio.requested = false; + controls.audio.stream_type = MediaStreamType::NO_SERVICE; + controls.video.requested = true; + controls.video.stream_type = MediaStreamType::DISPLAY_VIDEO_CAPTURE; + controls.disable_local_echo = true; + + SetupFakeUI(true); + + EXPECT_CALL(*this, + MockOnBadMessage( + kProcessId, + bad_message::MSDH_DISABLE_LOCAL_ECHO_BUT_AUDIO_NOT_REQUESTED)) + .Times(1); + host_->OnGenerateStreams(kPageRequestId, controls); +} + // This test simulates a shutdown scenario: we don't setup a fake UI proxy for // MediaStreamManager, so it will create an ordinary one which will not find // a RenderFrameHostDelegate. This normally should only be the case at shutdown. @@ -1395,4 +1375,66 @@ } // TODO(crbug.com/1300883): Add test cases for multi stream generation. +class MediaStreamDispatcherHostStreamTypeCombinationTest + : public MediaStreamDispatcherHostTest, + public ::testing::WithParamInterface<std::tuple<int, int>> {}; + +TEST_P(MediaStreamDispatcherHostStreamTypeCombinationTest, + GenerateStreamWithStreamTypeCombination) { + using blink::mojom::MediaStreamType; + + std::set<std::tuple<MediaStreamType, MediaStreamType>> kValidCombinations = { + {MediaStreamType::NO_SERVICE, MediaStreamType::NO_SERVICE}, + {MediaStreamType::NO_SERVICE, MediaStreamType::DEVICE_VIDEO_CAPTURE}, + {MediaStreamType::NO_SERVICE, MediaStreamType::GUM_TAB_VIDEO_CAPTURE}, + {MediaStreamType::NO_SERVICE, MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE}, + {MediaStreamType::NO_SERVICE, MediaStreamType::DISPLAY_VIDEO_CAPTURE}, + {MediaStreamType::NO_SERVICE, MediaStreamType::DISPLAY_VIDEO_CAPTURE_SET}, + {MediaStreamType::NO_SERVICE, + MediaStreamType::DISPLAY_VIDEO_CAPTURE_THIS_TAB}, + {MediaStreamType::DEVICE_AUDIO_CAPTURE, MediaStreamType::NO_SERVICE}, + {MediaStreamType::DEVICE_AUDIO_CAPTURE, + MediaStreamType::DEVICE_VIDEO_CAPTURE}, + {MediaStreamType::GUM_TAB_AUDIO_CAPTURE, MediaStreamType::NO_SERVICE}, + {MediaStreamType::GUM_TAB_AUDIO_CAPTURE, + MediaStreamType::GUM_TAB_VIDEO_CAPTURE}, + {MediaStreamType::GUM_DESKTOP_AUDIO_CAPTURE, + MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE}, + {MediaStreamType::DISPLAY_AUDIO_CAPTURE, + MediaStreamType::DISPLAY_VIDEO_CAPTURE}, + {MediaStreamType::DISPLAY_AUDIO_CAPTURE, + MediaStreamType::DISPLAY_VIDEO_CAPTURE_THIS_TAB}}; + + blink::StreamControls controls; + + controls.audio.stream_type = + static_cast<MediaStreamType>(std::get<0>(GetParam())); + controls.audio.requested = + (controls.audio.stream_type != MediaStreamType::NO_SERVICE); + + controls.video.stream_type = + static_cast<MediaStreamType>(std::get<1>(GetParam())); + controls.video.requested = + (controls.video.stream_type != MediaStreamType::NO_SERVICE); + + SetupFakeUI(true); + EXPECT_CALL( + *this, MockOnBadMessage( + kProcessId, bad_message::MSDH_INVALID_STREAM_TYPE_COMBINATION)) + .Times(!kValidCombinations.count(std::make_tuple( + controls.audio.stream_type, controls.video.stream_type))); + host_->OnGenerateStreams(kPageRequestId, controls); +} + +INSTANTIATE_TEST_SUITE_P( + , + MediaStreamDispatcherHostStreamTypeCombinationTest, + ::testing::Combine( + ::testing::Range( + static_cast<int>(blink::mojom::MediaStreamType::NO_SERVICE), + static_cast<int>(blink::mojom::MediaStreamType::NUM_MEDIA_TYPES)), + ::testing::Range( + static_cast<int>(blink::mojom::MediaStreamType::NO_SERVICE), + static_cast<int>(blink::mojom::MediaStreamType::NUM_MEDIA_TYPES)))); + } // namespace content
diff --git a/content/browser/webid/federated_auth_request_impl_unittest.cc b/content/browser/webid/federated_auth_request_impl_unittest.cc index d2a2b20..4d97b04 100644 --- a/content/browser/webid/federated_auth_request_impl_unittest.cc +++ b/content/browser/webid/federated_auth_request_impl_unittest.cc
@@ -1087,7 +1087,7 @@ RequestExpectations request_not_in_list = { RequestTokenStatus::kError, FederatedAuthRequestResult::kErrorManifestNotInManifestList, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FetchedEndpoint::MANIFEST_LIST | FetchedEndpoint::MANIFEST}; IdentityProviderParameters identity_provider{"https://not-in-list.example", @@ -1112,7 +1112,7 @@ RequestExpectations expectations = { RequestTokenStatus::kError, FederatedAuthRequestResult::kErrorManifestNotInManifestList, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FetchedEndpoint::MANIFEST_LIST | FetchedEndpoint::MANIFEST}; RunAuthTest(parameters, expectations, config); } @@ -1124,7 +1124,7 @@ RequestExpectations expectations = { RequestTokenStatus::kError, FederatedAuthRequestResult::kErrorFetchingManifestInvalidResponse, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FetchedEndpoint::MANIFEST | FetchedEndpoint::MANIFEST_LIST}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); @@ -1146,7 +1146,7 @@ RequestExpectations expectations = { RequestTokenStatus::kError, FederatedAuthRequestResult::kErrorFetchingManifestInvalidResponse, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FetchedEndpoint::MANIFEST | FetchedEndpoint::MANIFEST_LIST}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); @@ -1182,7 +1182,7 @@ RequestExpectations expectations = { RequestTokenStatus::kError, FederatedAuthRequestResult::kErrorFetchingManifestInvalidResponse, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FetchedEndpoint::MANIFEST | FetchedEndpoint::MANIFEST_LIST}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); } @@ -1195,10 +1195,10 @@ std::vector<IdentityProviderParameters>{identity_provider}, /*prefer_auto_sign_in=*/false}; MockConfiguration configuration = kConfigurationValid; - RequestExpectations expectations = { - RequestTokenStatus::kError, FederatedAuthRequestResult::kError, - /* selected_idp_config_url=*/absl::nullopt, - /*fetched_endpoints=*/0}; + RequestExpectations expectations = {RequestTokenStatus::kError, + FederatedAuthRequestResult::kError, + /*selected_idp_config_url=*/absl::nullopt, + /*fetched_endpoints=*/0}; RunAuthTest(request, expectations, configuration); histogram_tester_.ExpectUniqueSample( @@ -1214,7 +1214,7 @@ RequestExpectations expectations = { RequestTokenStatus::kError, FederatedAuthRequestResult::kErrorFetchingAccountsNoResponse, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FetchedEndpoint::MANIFEST | FetchedEndpoint::ACCOUNTS | FetchedEndpoint::MANIFEST_LIST}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); @@ -1228,7 +1228,7 @@ RequestExpectations expectations = { RequestTokenStatus::kError, FederatedAuthRequestResult::kErrorFetchingAccountsInvalidResponse, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FetchedEndpoint::MANIFEST | FetchedEndpoint::ACCOUNTS | FetchedEndpoint::MANIFEST_LIST}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); @@ -1278,7 +1278,7 @@ RequestExpectations expectations = { RequestTokenStatus::kError, FederatedAuthRequestResult::kErrorFetchingManifestInvalidResponse, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FetchedEndpoint::MANIFEST | FetchedEndpoint::MANIFEST_LIST}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); std::vector<std::string> messages = @@ -1407,7 +1407,7 @@ RequestExpectations expectations = { RequestTokenStatus::kError, FederatedAuthRequestResult::kErrorFetchingIdTokenInvalidResponse, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FETCH_ENDPOINT_ALL_REQUEST_TOKEN}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); } @@ -1626,7 +1626,7 @@ configuration.customized_dialog = true; RequestExpectations expectations = { RequestTokenStatus::kError, FederatedAuthRequestResult::kShouldEmbargo, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FETCH_ENDPOINT_ALL_REQUEST_TOKEN & ~FetchedEndpoint::TOKEN}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); @@ -1688,7 +1688,7 @@ RequestExpectations expectations = { /*return_status=*/absl::nullopt, /*devtools_issue_status=*/absl::nullopt, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FETCH_ENDPOINT_ALL_REQUEST_TOKEN & ~FetchedEndpoint::TOKEN}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); task_environment()->FastForwardBy(base::Minutes(10)); @@ -1747,7 +1747,7 @@ RequestExpectations expectations = { RequestTokenStatus::kError, FederatedAuthRequestResult::kErrorRpPageNotVisible, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FETCH_ENDPOINT_ALL_REQUEST_TOKEN & ~FetchedEndpoint::TOKEN}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); @@ -1759,10 +1759,10 @@ std::make_pair(main_test_rfh()->GetLastCommittedOrigin(), ApiPermissionStatus::BLOCKED_THIRD_PARTY_COOKIES_BLOCKED); - RequestExpectations expectations = { - RequestTokenStatus::kError, FederatedAuthRequestResult::kError, - /* selected_idp_config_url=*/absl::nullopt, - /*fetched_endpoints=*/0}; + RequestExpectations expectations = {RequestTokenStatus::kError, + FederatedAuthRequestResult::kError, + /*selected_idp_config_url=*/absl::nullopt, + /*fetched_endpoints=*/0}; RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid); histogram_tester_.ExpectUniqueSample("Blink.FedCm.Status.RequestIdToken", @@ -1777,10 +1777,10 @@ std::make_pair(main_test_rfh()->GetLastCommittedOrigin(), ApiPermissionStatus::BLOCKED_VARIATIONS); - RequestExpectations expectations = { - RequestTokenStatus::kError, FederatedAuthRequestResult::kError, - /* selected_idp_config_url=*/absl::nullopt, - /*fetched_endpoints=*/0}; + RequestExpectations expectations = {RequestTokenStatus::kError, + FederatedAuthRequestResult::kError, + /*selected_idp_config_url=*/absl::nullopt, + /*fetched_endpoints=*/0}; RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid); histogram_tester_.ExpectUniqueSample("Blink.FedCm.Status.RequestIdToken", @@ -1797,11 +1797,10 @@ MockConfiguration configuration = kConfigurationValid; configuration.wait_for_callback = false; - RequestExpectations expectations = { - /*return_status=*/absl::nullopt, - /*devtools_issue_status*/ absl::nullopt, - /* selected_idp_config_url=*/absl::nullopt, - /*fetched_endpoints=*/0}; + RequestExpectations expectations = {/*return_status=*/absl::nullopt, + /*devtools_issue_status*/ absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, + /*fetched_endpoints=*/0}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); // Delete the request before DelayTimer kicks in. @@ -1823,11 +1822,10 @@ MockConfiguration configuration = kConfigurationValid; configuration.wait_for_callback = false; - RequestExpectations expectations = { - /*return_status=*/absl::nullopt, - /*devtools_issue_status*/ absl::nullopt, - /* selected_idp_config_url=*/absl::nullopt, - /*fetched_endpoints=*/0}; + RequestExpectations expectations = {/*return_status=*/absl::nullopt, + /*devtools_issue_status*/ absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, + /*fetched_endpoints=*/0}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); // Abort the request before DelayTimer kicks in. @@ -1966,7 +1964,7 @@ TEST_F(FederatedAuthRequestImplTest, RequestEmbargo) { RequestExpectations expectations = { RequestTokenStatus::kError, FederatedAuthRequestResult::kShouldEmbargo, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FETCH_ENDPOINT_ALL_REQUEST_TOKEN & ~FetchedEndpoint::TOKEN}; MockConfiguration configuration = kConfigurationValid; @@ -2012,7 +2010,7 @@ RequestExpectations expectations = { RequestTokenStatus::kError, FederatedAuthRequestResult::kErrorDisabledInSettings, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, /*fetched_endpoints=*/0}; RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid); } @@ -2055,7 +2053,7 @@ RequestExpectations expectation = { /*return_status=*/absl::nullopt, /*devtools_issue_status*/ absl::nullopt, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, /*fetched_endpoints=*/ fedcm_disabled ? 0 @@ -2107,7 +2105,7 @@ RequestExpectations expectations = { RequestTokenStatus::kError, FederatedAuthRequestResult::kErrorDisabledInSettings, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FETCH_ENDPOINT_ALL_REQUEST_TOKEN & ~FetchedEndpoint::TOKEN}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); @@ -2243,7 +2241,7 @@ RequestExpectations expectations = { RequestTokenStatus::kError, /*devtools_issue_status*/ absl::nullopt, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FetchedEndpoint::MANIFEST | FetchedEndpoint::CLIENT_METADATA | FetchedEndpoint::MANIFEST_LIST | FetchedEndpoint::ACCOUNTS}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); @@ -2269,7 +2267,7 @@ RequestExpectations expectations = { /*return_status*/ absl::nullopt, /*devtools_issue_status*/ absl::nullopt, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FetchedEndpoint::MANIFEST | FetchedEndpoint::CLIENT_METADATA | FetchedEndpoint::MANIFEST_LIST | FetchedEndpoint::ACCOUNTS}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); @@ -2336,7 +2334,7 @@ RequestExpectations expectations = { RequestTokenStatus::kError, FederatedAuthRequestResult::kErrorFetchingAccountsInvalidResponse, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FetchedEndpoint::MANIFEST | FetchedEndpoint::ACCOUNTS | FetchedEndpoint::MANIFEST_LIST}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); @@ -2369,7 +2367,7 @@ ParseStatus::kInvalidResponseError; RequestExpectations expectations = { RequestTokenStatus::kError, FederatedAuthRequestResult::kError, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FetchedEndpoint::MANIFEST | FetchedEndpoint::ACCOUNTS | FetchedEndpoint::MANIFEST_LIST}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); @@ -2392,10 +2390,10 @@ EXPECT_CALL(*mock_dialog_controller_, ShowFailureDialog(_, _, _, _, _)) .Times(0); MockConfiguration configuration = kConfigurationValid; - RequestExpectations expectations = { - RequestTokenStatus::kError, FederatedAuthRequestResult::kError, - /* selected_idp_config_url=*/absl::nullopt, - /*fetched_endpoints=*/0}; + RequestExpectations expectations = {RequestTokenStatus::kError, + FederatedAuthRequestResult::kError, + /*selected_idp_config_url=*/absl::nullopt, + /*fetched_endpoints=*/0}; RunAuthTest(kDefaultRequestParameters, expectations, configuration); } @@ -2482,7 +2480,7 @@ RequestExpectations expectations = { RequestTokenStatus::kError, absl::nullopt, - /* selected_idp_config_url=*/absl::nullopt, + /*selected_idp_config_url=*/absl::nullopt, FetchedEndpoint::MANIFEST_LIST | FetchedEndpoint::MANIFEST}; RunAuthTest(parameters, expectations, configuration);
diff --git a/content/public/browser/ax_inspect_factory_auralinux.cc b/content/public/browser/ax_inspect_factory_auralinux.cc index da6ea88..7db74b0 100644 --- a/content/public/browser/ax_inspect_factory_auralinux.cc +++ b/content/public/browser/ax_inspect_factory_auralinux.cc
@@ -5,9 +5,9 @@ #include "content/public/browser/ax_inspect_factory.h" #include "base/notreached.h" -#include "content/browser/accessibility/accessibility_event_recorder_auralinux.h" #include "content/browser/accessibility/accessibility_tree_formatter_blink.h" #include "content/browser/accessibility/browser_accessibility_manager.h" +#include "ui/accessibility/platform/inspect/ax_event_recorder_auralinux.h" #include "ui/accessibility/platform/inspect/ax_tree_formatter_auralinux.h" namespace content { @@ -59,8 +59,8 @@ switch (type) { case ui::AXApiType::kLinux: - return std::make_unique<AccessibilityEventRecorderAuraLinux>(manager, pid, - selector); + return std::make_unique<ui::AXEventRecorderAuraLinux>(manager, pid, + selector); default: NOTREACHED() << "Unsupported API type " << static_cast<std::string>(type); }
diff --git a/content/services/auction_worklet/direct_from_seller_signals_requester.cc b/content/services/auction_worklet/direct_from_seller_signals_requester.cc index 12094ca..297c6d5 100644 --- a/content/services/auction_worklet/direct_from_seller_signals_requester.cc +++ b/content/services/auction_worklet/direct_from_seller_signals_requester.cc
@@ -15,7 +15,9 @@ #include "base/check.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_refptr.h" +#include "base/metrics/histogram_functions.h" #include "base/strings/stringprintf.h" +#include "base/time/time.h" #include "content/services/auction_worklet/auction_downloader.h" #include "content/services/auction_worklet/auction_v8_helper.h" #include "net/http/http_response_headers.h" @@ -59,6 +61,15 @@ return absl::nullopt; } +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class DirectFromSellerSignalsRequestType { + kNetworkServiceFetch = 0, + kCache = 1, + kCoalesced = 2, + kMaxValue = kCoalesced, +}; + } // namespace DirectFromSellerSignalsRequester::Result::Result() = default; @@ -178,6 +189,9 @@ if (cached_result_.signals_url() == signals_url) { // Request completed from cache -- done. + base::UmaHistogramEnumeration( + "Ads.InterestGroup.Auction.DirectFromSellerSignals.RequestType", + DirectFromSellerSignalsRequestType::kCache); request->RunCallbackAsync(cached_result_); return request; } @@ -193,8 +207,15 @@ AuctionDownloader::MimeType::kJson, base::BindOnce( &DirectFromSellerSignalsRequester::OnSignalsDownloaded, - base::Unretained(this), signals_url)))); + base::Unretained(this), signals_url, base::TimeTicks::Now())))); DCHECK(inserted); + base::UmaHistogramEnumeration( + "Ads.InterestGroup.Auction.DirectFromSellerSignals.RequestType", + DirectFromSellerSignalsRequestType::kNetworkServiceFetch); + } else { + base::UmaHistogramEnumeration( + "Ads.InterestGroup.Auction.DirectFromSellerSignals.RequestType", + DirectFromSellerSignalsRequestType::kCoalesced); } // A download is running for `signals_url` -- register to receive the result, // and register the iterator with `request` so that the Request destructor can @@ -223,9 +244,20 @@ void DirectFromSellerSignalsRequester::OnSignalsDownloaded( GURL signals_url, + base::TimeTicks start_time, std::unique_ptr<std::string> response_body, scoped_refptr<net::HttpResponseHeaders> headers, absl::optional<std::string> error) { + if (response_body) { + // The request size isn't very meaningful, since the request is served from + // a subresource bundle, so don't record the request size. + base::UmaHistogramCounts10M( + "Ads.InterestGroup.Net.ResponseSizeBytes.DirectFromSellerSignals", + response_body->size()); + base::UmaHistogramTimes( + "Ads.InterestGroup.Net.DownloadTime.DirectFromSellerSignals", + base::TimeTicks::Now() - start_time); + } Result result(signals_url, std::move(response_body), std::move(headers), std::move(error)); cached_result_ = result; @@ -270,7 +302,4 @@ coalesced_downloads_.erase(map_it); } -// TODO(crbug.com/1320908): Add UMA for request and download size. -// TODO(crbug.com/1320908): Add UMA for cache hit rate. - } // namespace auction_worklet
diff --git a/content/services/auction_worklet/direct_from_seller_signals_requester.h b/content/services/auction_worklet/direct_from_seller_signals_requester.h index 105b6fe8..4947480d 100644 --- a/content/services/auction_worklet/direct_from_seller_signals_requester.h +++ b/content/services/auction_worklet/direct_from_seller_signals_requester.h
@@ -15,6 +15,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" +#include "base/time/time.h" #include "base/types/strong_alias.h" #include "content/common/content_export.h" #include "services/network/public/mojom/url_loader_factory.mojom-forward.h" @@ -228,6 +229,7 @@ // Validates headers, caches the results, and calls all callbacks held in // Result objects in `coalesced_downloads_` that are waiting on the URL. void OnSignalsDownloaded(GURL signals_url, + base::TimeTicks start_time, std::unique_ptr<std::string> response_body, scoped_refptr<net::HttpResponseHeaders> headers, absl::optional<std::string> error);
diff --git a/content/test/attribution_simulator_input_parser.cc b/content/test/attribution_simulator_input_parser.cc index ac3bc3e6..6e919e16 100644 --- a/content/test/attribution_simulator_input_parser.cc +++ b/content/test/attribution_simulator_input_parser.cc
@@ -284,8 +284,8 @@ ParseOrigin(trigger_dict, "destination_origin"); absl::optional<uint64_t> debug_key; - AttributionFilterData filters; - AttributionFilterData not_filters; + AttributionFilters filters; + AttributionFilters not_filters; std::vector<AttributionTrigger::EventTriggerData> event_triggers; std::vector<AttributionAggregatableTriggerData> aggregatable_trigger_data; AttributionAggregatableValues aggregatable_values; @@ -297,12 +297,8 @@ base::BindLambdaForTesting( [&](const base::Value::Dict& dict) { debug_key = ParseOptionalUint64(dict, "debug_key"); - filters = ParseFilterData( - dict, "filters", - &AttributionFilterData::FromTriggerFilterValues); - not_filters = ParseFilterData( - dict, "not_filters", - &AttributionFilterData::FromTriggerFilterValues); + filters = ParseFilters(dict, "filters"); + not_filters = ParseFilters(dict, "not_filters"); event_triggers = ParseEventTriggers(dict); aggregatable_trigger_data = @@ -359,12 +355,9 @@ absl::optional<uint64_t> dedup_key = ParseOptionalUint64(dict, "deduplication_key"); - AttributionFilterData filters = ParseFilterData( - dict, "filters", &AttributionFilterData::FromTriggerFilterValues); + AttributionFilters filters = ParseFilters(dict, "filters"); - AttributionFilterData not_filters = - ParseFilterData(dict, "not_filters", - &AttributionFilterData::FromTriggerFilterValues); + AttributionFilters not_filters = ParseFilters(dict, "not_filters"); if (has_error()) return; @@ -499,23 +492,18 @@ return true; } - using FromFilterValuesFunc = absl::optional<AttributionFilterData>( - AttributionFilterData::FilterValues&&); - - AttributionFilterData ParseFilterData( - const base::Value::Dict& dict, - base::StringPiece key, - FromFilterValuesFunc from_filter_values) { + AttributionFilters ParseFilters(const base::Value::Dict& dict, + base::StringPiece key) { auto context = PushContext(key); const base::Value* value = dict.Find(key); if (!value) - return AttributionFilterData(); + return AttributionFilters(); if (!EnsureDictionary(*value)) - return AttributionFilterData(); + return AttributionFilters(); - AttributionFilterData::FilterValues::container_type container; + AttributionFilterValues::container_type container; for (auto [filter, values_list] : value->GetDict()) { auto filter_context = PushContext(filter); std::vector<std::string> values; @@ -532,13 +520,13 @@ container.emplace_back(filter, std::move(values)); } - absl::optional<AttributionFilterData> filter_data = - from_filter_values(std::move(container)); + absl::optional<AttributionFilters> filters = + AttributionFilters::Create(std::move(container)); // TODO(apaseltiner): Provide more detailed information. - if (!filter_data) + if (!filters) *Error() << "invalid"; - return std::move(filter_data).value_or(AttributionFilterData()); + return std::move(filters).value_or(AttributionFilters()); } absl::uint128 ParseAggregationKey(const base::Value& key_value) { @@ -616,13 +604,11 @@ } } - AttributionFilterData filters = ParseFilterData( - trigger_dict, "filters", - &AttributionFilterData::FromTriggerFilterValues); + AttributionFilters filters = + ParseFilters(trigger_dict, "filters"); - AttributionFilterData not_filters = ParseFilterData( - trigger_dict, "not_filters", - &AttributionFilterData::FromTriggerFilterValues); + AttributionFilters not_filters = + ParseFilters(trigger_dict, "not_filters"); auto trigger_data = AttributionAggregatableTriggerData::Create( key, std::move(source_keys), std::move(filters),
diff --git a/content/test/attribution_simulator_input_parser_unittest.cc b/content/test/attribution_simulator_input_parser_unittest.cc index fcb8247b..64e57fa 100644 --- a/content/test/attribution_simulator_input_parser_unittest.cc +++ b/content/test/attribution_simulator_input_parser_unittest.cc
@@ -216,11 +216,10 @@ .SetPriority(0) // default .SetDebugKey(absl::nullopt) // default .SetDebugReporting(false) // default - .SetFilterData( - *AttributionFilterData::FromSourceFilterValues({ - {"a", {}}, - {"b", {"c", "d"}}, - })) + .SetFilterData(*AttributionFilterData::Create({ + {"a", {}}, + {"b", {"c", "d"}}, + })) .Build(), _), Pair( @@ -355,12 +354,12 @@ /*reporting_origin=*/ url::Origin::Create(GURL("https://a.r.test")), /*filters=*/ - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"a", {"b", "c"}}, {"d", {}}, }), /*not_filters=*/ - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"e", {"f"}}, }), /*debug_key=*/14, @@ -371,19 +370,19 @@ /*priority=*/-5, /*dedup_key=*/123, /*filters=*/ - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"x", {"y"}}, }), /*not_filters=*/ - *AttributionFilterData::FromTriggerFilterValues({ + *AttributionFilters::Create({ {"z", {}}, })), AttributionTrigger::EventTriggerData( /*data=*/0, /*priority=*/0, /*dedup_key=*/absl::nullopt, - /*filters=*/AttributionFilterData(), - /*not_filters=*/AttributionFilterData()), + /*filters=*/AttributionFilters(), + /*not_filters=*/AttributionFilters()), }, /*aggregatable_trigger_data=*/{}, /*aggregatable_values=*/AttributionAggregatableValues()), @@ -397,8 +396,8 @@ url::Origin::Create(GURL("https://a.d2.test")), /*reporting_origin=*/ url::Origin::Create(GURL("https://b.r.test")), - /*filters=*/AttributionFilterData(), - /*not_filters=*/AttributionFilterData(), + /*filters=*/AttributionFilters(), + /*not_filters=*/AttributionFilters(), /*debug_key=*/absl::nullopt, /*aggregatable_dedup_key=*/absl::nullopt, /*event_triggers=*/{}, @@ -414,16 +413,16 @@ url::Origin::Create(GURL("https://a.d2.test")), /*reporting_origin=*/ url::Origin::Create(GURL("https://b.r.test")), - /*filters=*/AttributionFilterData(), - /*not_filters=*/AttributionFilterData(), + /*filters=*/AttributionFilters(), + /*not_filters=*/AttributionFilters(), /*debug_key=*/absl::nullopt, /*aggregatable_dedup_key=*/789, /*event_triggers=*/{}, {AttributionAggregatableTriggerData::CreateForTesting( absl::MakeUint128(/*high=*/0, /*low=*/1), /*source_keys=*/{"a"}, - /*filters=*/AttributionFilterData(), - /*not_filters=*/AttributionFilterData())}, + /*filters=*/AttributionFilters(), + /*not_filters=*/AttributionFilters())}, /*aggregatable_values=*/ AttributionAggregatableValues::CreateForTesting( {{"a", 1}})),
diff --git a/content/test/data/accessibility/accdescription/description-ignores-slot-expected-blink.txt b/content/test/data/accessibility/accdescription/description-ignores-slot-expected-blink.txt deleted file mode 100644 index 08fb16d6..0000000 --- a/content/test/data/accessibility/accdescription/description-ignores-slot-expected-blink.txt +++ /dev/null
@@ -1 +0,0 @@ -button description='description' name='foobar' nameFrom=contents descriptionFrom=relatedElement
diff --git a/content/test/data/accessibility/accdescription/description-ignores-slot.html b/content/test/data/accessibility/accdescription/description-ignores-slot.html deleted file mode 100644 index c9e5c5c..0000000 --- a/content/test/data/accessibility/accdescription/description-ignores-slot.html +++ /dev/null
@@ -1,29 +0,0 @@ -<!-- -@BLINK-ALLOW:description=* -@BLINK-ALLOW:descriptionFrom=* ---> -<!-- AccName calculation should ignore slot element --> -<template id="template"> - <slot id="slot" aria-label="label on slot" name="my-slot">default content</slot> - <button aria-describedby="slot" id="test">foobar</button> -</template> - -<my-element> - <b slot="my-slot">description</b> -</my-element> - -<script> -customElements.define( - 'my-element', - class extends HTMLElement { - constructor() { - super(); - let template = document.getElementById('template'); - let templateContent = template.content; - - const shadowRoot = this.attachShadow({mode: 'open'}) - .appendChild(templateContent.cloneNode(true)); - } - } -); -</script>
diff --git a/content/test/data/accessibility/accname/name-ignores-slot-expected-blink.txt b/content/test/data/accessibility/accname/name-ignores-slot-expected-blink.txt deleted file mode 100644 index c5cb2c06..0000000 --- a/content/test/data/accessibility/accname/name-ignores-slot-expected-blink.txt +++ /dev/null
@@ -1 +0,0 @@ -button name='one two three' nameFrom=contents
diff --git a/content/test/data/accessibility/accname/name-ignores-slot.html b/content/test/data/accessibility/accname/name-ignores-slot.html deleted file mode 100644 index 242afd79..0000000 --- a/content/test/data/accessibility/accname/name-ignores-slot.html +++ /dev/null
@@ -1,28 +0,0 @@ -<!-- -@BLINK-ALLOW:name=* -@BLINK-ALLOW:nameFrom=* ---> -<!-- AccName calculation should ignore slot element --> -<template id="template"> - <button id="test">one <slot aria-label="label" name="my-slot"></slot> three</button> -</template> - -<my-element> - <b slot="my-slot">two</b> -</my-element> - -<script> -customElements.define( - 'my-element', - class extends HTMLElement { - constructor() { - super(); - let template = document.getElementById('template'); - let templateContent = template.content; - - const shadowRoot = this.attachShadow({mode: 'open'}) - .appendChild(templateContent.cloneNode(true)); - } - } -); -</script>
diff --git a/content/web_test/renderer/web_frame_test_proxy.cc b/content/web_test/renderer/web_frame_test_proxy.cc index 0dd00b8..40deb99 100644 --- a/content/web_test/renderer/web_frame_test_proxy.cc +++ b/content/web_test/renderer/web_frame_test_proxy.cc
@@ -351,11 +351,6 @@ level = "MESSAGE"; } std::string console_message(std::string("CONSOLE ") + level + ": "); - // Console messages shouldn't be included in the expected output for - // web-platform-tests because they may create non-determinism not - // intended by the test author. They are still included in the stderr - // output for debug purposes. - bool dump_to_stderr = test_runner()->IsWebPlatformTestsMode(); if (!message.text.IsEmpty()) { std::string new_message; new_message = message.text.Utf8(); @@ -368,11 +363,13 @@ } console_message += "\n"; - if (dump_to_stderr) { - test_runner()->PrintMessageToStderr(console_message); - } else { + // Console messages shouldn't be included in the expected output for + // web-platform-tests because they may create non-determinism not + // intended by the test author. They are still included in the stderr + // output for debugging purposes. + test_runner()->PrintMessageToStderr(console_message); + if (!test_runner()->IsWebPlatformTestsMode()) test_runner()->PrintMessage(console_message); - } } void WebFrameTestProxy::DidStartLoading() {
diff --git a/device/vr/android/arcore/arcore_gl.cc b/device/vr/android/arcore/arcore_gl.cc index 27e8e85..779fd57 100644 --- a/device/vr/android/arcore/arcore_gl.cc +++ b/device/vr/android/arcore/arcore_gl.cc
@@ -577,8 +577,7 @@ // Also calculate the inverse projection which is needed for converting // screen touches to world rays. - bool has_inverse = projection_.GetInverse(&inverse_projection_); - DCHECK(has_inverse); + inverse_projection_ = projection_.GetCheckedInverse(); // VRFieldOfView wants positive angles. mojom::VRFieldOfViewPtr field_of_view = mojom::VRFieldOfView::New();
diff --git a/device/vr/android/gvr/gvr_utils.cc b/device/vr/android/gvr/gvr_utils.cc index 8da5ac3..00d5d69b 100644 --- a/device/vr/android/gvr/gvr_utils.cc +++ b/device/vr/android/gvr/gvr_utils.cc
@@ -73,9 +73,7 @@ gvr::Mat4f eye_mat = gvr_api->GetEyeFromHeadMatrix(eye); gfx::Transform eye_from_head; device::gvr_utils::GvrMatToTransform(eye_mat, &eye_from_head); - gfx::Transform head_from_eye; - bool is_invertible = eye_from_head.GetInverse(&head_from_eye); - DCHECK(is_invertible); + gfx::Transform head_from_eye = eye_from_head.GetCheckedInverse(); view->mojo_from_view = mojo_from_head * head_from_eye; }
diff --git a/docs/testing/testing_in_chromium.md b/docs/testing/testing_in_chromium.md index a279c75..4166d66 100644 --- a/docs/testing/testing_in_chromium.md +++ b/docs/testing/testing_in_chromium.md
@@ -168,7 +168,7 @@ ## How to deal with flaky tests -Go to [Flake Portal] to find reports about flaky tests in your projects. +Go to [LUCI Analysis] to find reports about flaky tests in your projects. * [Addressing Flaky GTests](./gtest_flake_tips.md) * [Addressing Flaky Web Tests](./web_tests_addressing_flake.md) @@ -188,7 +188,7 @@ [Tast]: https://chromium.googlesource.com/chromiumos/platform/tast/+/HEAD/README.md [Web Tests]: ./web_tests.md [crbug/611756]: https://bugs.chromium.org/p/chromium/issues/detail?id=611756 -[Flake Portal]: https://analysis.chromium.org/p/chromium/flake-portal +[LUCI Analysis]: https://luci-analysis.appspot.com/ [Write Fuzz Target]: https://chromium.googlesource.com/chromium/src/+/main/testing/libfuzzer/getting_started.md#write-fuzz-target [Telemetry: Run benchmarks locally]: https://chromium.googlesource.com/catapult/+/HEAD/telemetry/docs/run_benchmarks_locally.md [Run fuzz target locally]: https://chromium.googlesource.com/chromium/src/+/main/testing/libfuzzer/getting_started.md#build-and-run-fuzz-target-locally
diff --git a/fuchsia_web/webengine/BUILD.gn b/fuchsia_web/webengine/BUILD.gn index feaf34d..a750d1b 100644 --- a/fuchsia_web/webengine/BUILD.gn +++ b/fuchsia_web/webengine/BUILD.gn
@@ -612,11 +612,11 @@ "//testing/gmock", "//testing/gtest", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.element", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.input.virtualkeyboard", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mediacodec", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mem", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.input3", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.policy", "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp", "//ui/gfx", "//ui/ozone", @@ -627,7 +627,7 @@ additional_manifest_fragments = [ "//build/config/fuchsia/test/fonts.shard.test-cml", "//build/config/fuchsia/test/network.shard.test-cml", - "//build/config/fuchsia/test/test_ui_stack.shard.test-cml", + "//build/config/fuchsia/test/gfx_test_ui_stack.shard.test-cml", "//third_party/fuchsia-sdk/sdk/pkg/vulkan/client.shard.cml", ]
diff --git a/fuchsia_web/webengine/browser/ax_tree_converter_unittest.cc b/fuchsia_web/webengine/browser/ax_tree_converter_unittest.cc index 6f23d1e..cbb1e097 100644 --- a/fuchsia_web/webengine/browser/ax_tree_converter_unittest.cc +++ b/fuchsia_web/webengine/browser/ax_tree_converter_unittest.cc
@@ -103,9 +103,7 @@ std::pair<ui::AXNodeData, Node> CreateSemanticNodeAllFieldsSet() { ui::AXRelativeBounds relative_bounds = ui::AXRelativeBounds(); relative_bounds.bounds = gfx::RectF(kRectX, kRectY, kRectWidth, kRectHeight); - relative_bounds.transform = - std::make_unique<gfx::Transform>(gfx::Transform::kSkipInitialization); - relative_bounds.transform->MakeIdentity(); + relative_bounds.transform = std::make_unique<gfx::Transform>(); relative_bounds.offset_container_id = -1; auto ax_node_data = CreateAXNodeData( ax::mojom::Role::kButton, ax::mojom::Action::kFocus, @@ -342,9 +340,7 @@ TEST_F(AXTreeConverterTest, FieldMismatch) { ui::AXRelativeBounds relative_bounds = ui::AXRelativeBounds(); relative_bounds.bounds = gfx::RectF(kRectX, kRectY, kRectWidth, kRectHeight); - relative_bounds.transform = - std::make_unique<gfx::Transform>(gfx::Transform::kSkipInitialization); - relative_bounds.transform->MakeIdentity(); + relative_bounds.transform = std::make_unique<gfx::Transform>(); auto source_node_data = CreateAXNodeData( ax::mojom::Role::kHeader, ax::mojom::Action::kSetValue, std::vector<int32_t>{kChildId1, kChildId2, kChildId3}, relative_bounds, @@ -398,9 +394,7 @@ TEST_F(AXTreeConverterTest, LocationFieldRespectsTypeInvariants) { ui::AXRelativeBounds relative_bounds = ui::AXRelativeBounds(); relative_bounds.bounds = gfx::RectF(kRectX, kRectY, kRectWidth, kRectHeight); - relative_bounds.transform = - std::make_unique<gfx::Transform>(gfx::Transform::kSkipInitialization); - relative_bounds.transform->MakeIdentity(); + relative_bounds.transform = std::make_unique<gfx::Transform>(); auto source_node_data = CreateAXNodeData( ax::mojom::Role::kHeader, ax::mojom::Action::kSetValue, std::vector<int32_t>{kChildId1, kChildId2, kChildId3}, relative_bounds, @@ -616,9 +610,7 @@ node_data.id = 1; ui::AXRelativeBounds relative_bounds = ui::AXRelativeBounds(); relative_bounds.bounds = gfx::RectF(kRectX, kRectY, kRectWidth, kRectHeight); - relative_bounds.transform = - std::make_unique<gfx::Transform>(gfx::Transform::kSkipInitialization); - relative_bounds.transform->MakeIdentity(); + relative_bounds.transform = std::make_unique<gfx::Transform>(); relative_bounds.offset_container_id = -1; node_data.relative_bounds = relative_bounds;
diff --git a/fuchsia_web/webengine/browser/frame_impl.cc b/fuchsia_web/webengine/browser/frame_impl.cc index 1570a5d..9ac69da 100644 --- a/fuchsia_web/webengine/browser/frame_impl.cc +++ b/fuchsia_web/webengine/browser/frame_impl.cc
@@ -785,7 +785,7 @@ } void FrameImpl::CreateView(fuchsia::ui::views::ViewToken view_token) { - scenic::ViewRefPair view_ref_pair = scenic::ViewRefPair::New(); + auto view_ref_pair = scenic::ViewRefPair::New(); CreateViewWithViewRef(std::move(view_token), std::move(view_ref_pair.control_ref), std::move(view_ref_pair.view_ref));
diff --git a/fuchsia_web/webengine/browser/frame_impl_browsertest.cc b/fuchsia_web/webengine/browser/frame_impl_browsertest.cc index f79a1ee..b14cc32 100644 --- a/fuchsia_web/webengine/browser/frame_impl_browsertest.cc +++ b/fuchsia_web/webengine/browser/frame_impl_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 <fuchsia/ui/policy/cpp/fidl.h> +#include <fuchsia/element/cpp/fidl.h> #include <lib/ui/scenic/cpp/view_token_pair.h> +#include "base/fuchsia/fuchsia_logging.h" #include "base/fuchsia/mem_buffer_util.h" #include "base/test/test_future.h" #include "build/build_config.h" @@ -22,6 +23,7 @@ #include "fuchsia_web/webengine/test/frame_for_test.h" #include "net/test/embedded_test_server/request_handler_util.h" #include "testing/gmock/include/gmock/gmock.h" +#include "ui/ozone/public/ozone_platform.h" using testing::_; using testing::AllOf; @@ -103,18 +105,41 @@ return visibility->data; } +::fuchsia::ui::views::ViewRef CloneViewRef( + const ::fuchsia::ui::views::ViewRef& view_ref) { + ::fuchsia::ui::views::ViewRef dup; + zx_status_t status = + view_ref.reference.duplicate(ZX_RIGHT_SAME_RIGHTS, &dup.reference); + ZX_CHECK(status == ZX_OK, status) << "zx_object_duplicate"; + return dup; +} + // Verifies that Frames are initially "hidden", changes to "visible" once the // View is attached to a Presenter and back to "hidden" when the View is // detached from the Presenter. -// TODO(https://crbug.com/1314086): Re-enable this test when we can make it work -// with the fake hardware display controller provider used for tests. -IN_PROC_BROWSER_TEST_F(FrameImplTest, DISABLED_VisibilityState) { +// TODO(crbug.com/1377994): Re-enable this test on Arm64 when femu is available +// for that architecture. This test requires Vulkan and Scenic to properly +// signal the Views visibility. +#if defined(ARCH_CPU_ARM_FAMILY) +#define MAYBE_VisibilityState DISABLED_VisibilityState +#else +#define MAYBE_VisibilityState VisibilityState +#endif +IN_PROC_BROWSER_TEST_F(FrameImplTest, MAYBE_VisibilityState) { + // This test uses the `fuchsia.ui.gfx` variant of `Frame.CreateView*()`. + ASSERT_EQ(ui::OzonePlatform::GetInstance()->GetPlatformNameForTest(), + "scenic"); + net::test_server::EmbeddedTestServerHandle test_server_handle; ASSERT_TRUE(test_server_handle = embedded_test_server()->StartAndReturnHandle()); GURL page_url(embedded_test_server()->GetURL(kVisibilityPath)); auto frame = FrameForTest::Create(context(), {}); + frame.ptr().set_error_handler([](zx_status_t status) { + ZX_LOG(ERROR, status); + ADD_FAILURE() << "Frame disconnected."; + }); base::RunLoop().RunUntilIdle(); // Navigate to a page and wait for it to finish loading. @@ -129,25 +154,35 @@ // Query the document.visibilityState after creating the View, but without it // actually "attached" to the view tree. auto view_tokens = scenic::ViewTokenPair::New(); - frame->CreateView(std::move(view_tokens.view_token)); + auto view_ref_pair = scenic::ViewRefPair::New(); + frame->CreateViewWithViewRef(std::move(view_tokens.view_token), + std::move(view_ref_pair.control_ref), + CloneViewRef(view_ref_pair.view_ref)); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(GetDocumentVisibilityState(frame.ptr().get()), "\"hidden\""); // Attach the View to a Presenter, the page should be visible. auto presenter = base::ComponentContextForProcess() ->svc() - ->Connect<::fuchsia::ui::policy::Presenter>(); - presenter.set_error_handler( - [](zx_status_t) { ADD_FAILURE() << "Presenter disconnected."; }); - presenter->PresentOrReplaceView(std::move(view_tokens.view_holder_token), - nullptr); + ->Connect<::fuchsia::element::GraphicalPresenter>(); + presenter.set_error_handler([](zx_status_t status) { + ZX_LOG(ERROR, status) << "GraphicalPresenter disconnected."; + ADD_FAILURE(); + }); + ::fuchsia::element::ViewSpec view_spec; + view_spec.set_view_holder_token(std::move(view_tokens.view_holder_token)); + view_spec.set_view_ref(std::move(view_ref_pair.view_ref)); + ::fuchsia::element::ViewControllerPtr view_controller; + presenter->PresentView(std::move(view_spec), nullptr, + view_controller.NewRequest(), + [](auto result) { EXPECT_FALSE(result.is_err()); }); frame.navigation_listener().RunUntilTitleEquals("visible"); - // Attach a new View to the Presenter, the page should be hidden again. - // This part of the test is a regression test for crbug.com/1141093. - auto view_tokens2 = scenic::ViewTokenPair::New(); - presenter->PresentOrReplaceView(std::move(view_tokens2.view_holder_token), - nullptr); + // Detach the ViewController, causing the View to be detached. + // This is a regression test for crbug.com/1141093, verifying that the page + // receives a "not visible" event as a result. + view_controller->Dismiss(); frame.navigation_listener().RunUntilTitleEquals("hidden"); } @@ -916,19 +951,34 @@ #define MAYBE_SetPageScale DISABLED_SetPageScale #endif IN_PROC_BROWSER_TEST_F(FrameImplTest, MAYBE_SetPageScale) { + // This test uses the `fuchsia.ui.gfx` variant of `Frame.CreateView*()`. + ASSERT_EQ(ui::OzonePlatform::GetInstance()->GetPlatformNameForTest(), + "scenic"); + auto frame = FrameForTest::Create(context(), {}); auto view_tokens = scenic::ViewTokenPair::New(); - frame->CreateView(std::move(view_tokens.view_token)); + auto view_ref_pair = scenic::ViewRefPair::New(); + frame->CreateViewWithViewRef(std::move(view_tokens.view_token), + std::move(view_ref_pair.control_ref), + CloneViewRef(view_ref_pair.view_ref)); // Attach the View to a Presenter, the page should be visible. auto presenter = base::ComponentContextForProcess() ->svc() - ->Connect<::fuchsia::ui::policy::Presenter>(); - presenter.set_error_handler( - [](zx_status_t) { ADD_FAILURE() << "Presenter disconnected."; }); - presenter->PresentOrReplaceView(std::move(view_tokens.view_holder_token), - nullptr); + ->Connect<::fuchsia::element::GraphicalPresenter>(); + presenter.set_error_handler([](zx_status_t status) { + ZX_LOG(ERROR, status) << "GraphicalPresenter disconnected."; + ADD_FAILURE(); + }); + + ::fuchsia::element::ViewSpec view_spec; + view_spec.set_view_holder_token(std::move(view_tokens.view_holder_token)); + view_spec.set_view_ref(std::move(view_ref_pair.view_ref)); + ::fuchsia::element::ViewControllerPtr view_controller; + presenter->PresentView(std::move(view_spec), nullptr, + view_controller.NewRequest(), + [](auto result) { EXPECT_FALSE(result.is_err()); }); net::test_server::EmbeddedTestServerHandle test_server_handle; ASSERT_TRUE(test_server_handle = @@ -996,10 +1046,15 @@ auto frame2 = FrameForTest::Create(context(), {}); view_tokens = scenic::ViewTokenPair::New(); - frame2->CreateView(std::move(view_tokens.view_token)); + view_ref_pair = scenic::ViewRefPair::New(); + frame->CreateViewWithViewRef(std::move(view_tokens.view_token), + std::move(view_ref_pair.control_ref), + CloneViewRef(view_ref_pair.view_ref)); - presenter->PresentOrReplaceView(std::move(view_tokens.view_holder_token), - nullptr); + view_spec.set_view_holder_token(std::move(view_tokens.view_holder_token)); + view_spec.set_view_ref(std::move(view_ref_pair.view_ref)); + presenter->PresentView(std::move(view_spec), nullptr, + view_controller.NewRequest(), [](auto) {}); EXPECT_TRUE(LoadUrlAndExpectResponse(frame2.GetNavigationController(), fuchsia::web::LoadUrlParams(),
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing.cc b/gpu/command_buffer/service/shared_image/d3d_image_backing.cc index 211533d4..883452df 100644 --- a/gpu/command_buffer/service/shared_image/d3d_image_backing.cc +++ b/gpu/command_buffer/service/shared_image/d3d_image_backing.cc
@@ -188,49 +188,6 @@ default; #endif -D3DImageBacking::SignaledFence::SignaledFence( - scoped_refptr<D3DSharedFence> fence, - uint64_t value) - : fence_(std::move(fence)), value_(value) { - DCHECK(fence_); - DCHECK_NE(value_, UINT64_MAX); -} -D3DImageBacking::SignaledFence::SignaledFence(const SignaledFence&) = default; -D3DImageBacking::SignaledFence& D3DImageBacking::SignaledFence::operator=( - const SignaledFence&) = default; -D3DImageBacking::SignaledFence::~SignaledFence() = default; - -bool D3DImageBacking::SignaledFence::WaitD3D11( - Microsoft::WRL::ComPtr<ID3D11Device> device) const { - // D3DSharedFence::WaitD3D11 skips the wait if the device created this fence. - return fence_->WaitD3D11(std::move(device), value_); -} - -bool D3DImageBacking::SignaledFence::IncrementAndSignalD3D11() { - if (!fence_->SignalD3D11(value_ + 1)) { - DLOG(ERROR) << "D3DSharedFence::Signal failed"; - return false; - } - value_++; - return true; -} - -bool D3DImageBacking::SignaledFence::Update(const SignaledFence& other) { - if (fence_ == other.fence_) { - if (value_ < other.value_ && other.value_ != UINT64_MAX) - value_ = other.value_; - return true; - } - return false; -} - -#if BUILDFLAG(USE_DAWN) -ExternalImageDXGIFenceDescriptor -D3DImageBacking::SignaledFence::AsDawnFenceDescriptor() const { - return ExternalImageDXGIFenceDescriptor{fence_->GetSharedHandle(), value_}; -} -#endif - // static std::unique_ptr<D3DImageBacking> D3DImageBacking::CreateFromSwapChainBuffer( const Mailbox& mailbox, @@ -718,12 +675,11 @@ // Create the D3D11 device fence on first Dawn access. if (!dxgi_shared_handle_state_->has_keyed_mutex() && !d3d11_device_fence_) { - auto fence = D3DSharedFence::CreateForD3D11(d3d11_device_); - if (!fence) { + d3d11_device_fence_ = D3DSharedFence::CreateForD3D11(d3d11_device_); + if (!d3d11_device_fence_) { DLOG(ERROR) << "Failed to create D3D11 signal fence"; return nullptr; } - d3d11_device_fence_ = SignaledFence(std::move(fence), 0); // Make D3D11 device wait for |write_fence_| since we'll replace it below. if (write_fence_ && !write_fence_->WaitD3D11(d3d11_device_)) { DLOG(ERROR) << "Failed to wait for write fence"; @@ -746,14 +702,17 @@ std::vector<ExternalImageDXGIFenceDescriptor> wait_fences; // Always wait for previous write for both read-only or read-write access. // Skip the wait if it's for the fence last signaled by the device. - if (write_fence_ && write_fence_->fence() != dawn_signaled_fence) - wait_fences.push_back(write_fence_->AsDawnFenceDescriptor()); + if (write_fence_ && write_fence_.get() != dawn_signaled_fence) + wait_fences.push_back(ExternalImageDXGIFenceDescriptor{ + write_fence_->GetSharedHandle(), write_fence_->GetFenceValue()}); // Also wait for all previous reads for read-write access. if (write_access) { for (const auto& read_fence : read_fences_) { // Skip the wait if it's for the fence last signaled by the device. - if (read_fence.fence() != dawn_signaled_fence) - wait_fences.push_back(read_fence.AsDawnFenceDescriptor()); + if (read_fence != dawn_signaled_fence) { + wait_fences.push_back(ExternalImageDXGIFenceDescriptor{ + read_fence->GetSharedHandle(), read_fence->GetFenceValue()}); + } } } @@ -803,7 +762,7 @@ ExternalImageDXGIFenceDescriptor descriptor; external_image->EndAccess(texture, &descriptor); - absl::optional<SignaledFence> signaled_fence; + scoped_refptr<D3DSharedFence> signaled_fence; if (descriptor.fenceHandle != nullptr) { scoped_refptr<D3DSharedFence>& cached_fence = it->second.signaled_fence; // Try to reuse the last signaled fence if it's the same fence. @@ -813,12 +772,13 @@ D3DSharedFence::CreateFromHandle(descriptor.fenceHandle); DCHECK(cached_fence); } - signaled_fence = SignaledFence(cached_fence, descriptor.fenceValue); + cached_fence->Update(descriptor.fenceValue); + signaled_fence = cached_fence; } // Dawn should be using either keyed mutex or fence synchronization. DCHECK((dxgi_shared_handle_state_ && dxgi_shared_handle_state_->has_keyed_mutex()) || - signaled_fence.has_value()); + signaled_fence); EndAccessCommon(std::move(signaled_fence)); } else { // Erase from cache if external image is invalid i.e. device was lost. @@ -848,7 +808,7 @@ if (write_access) { // For read-write access, wait for all previous reads, and reset fences. for (const auto& fence : read_fences_) { - if (!fence.WaitD3D11(d3d11_device_)) { + if (!fence->WaitD3D11(d3d11_device_)) { DLOG(ERROR) << "Failed to wait for read fence"; return false; } @@ -870,7 +830,7 @@ // If D3D11 device signaling fence is present, shared handle should be too. DCHECK(!d3d11_device_fence_ || dxgi_shared_handle_state_); - absl::optional<SignaledFence> signaled_fence; + scoped_refptr<D3DSharedFence> signaled_fence; if (d3d11_device_fence_ && d3d11_device_fence_->IncrementAndSignalD3D11()) signaled_fence = d3d11_device_fence_; @@ -893,26 +853,16 @@ } void D3DImageBacking::EndAccessCommon( - absl::optional<SignaledFence> signaled_fence) { + scoped_refptr<D3DSharedFence> signaled_fence) { if (in_write_access_) { - DCHECK(!write_fence_.has_value()); + DCHECK(!write_fence_); DCHECK(read_fences_.empty()); in_write_access_ = false; - if (signaled_fence) - write_fence_.emplace(*signaled_fence); + write_fence_ = std::move(signaled_fence); } else { num_readers_--; - if (signaled_fence) { - // First try to update an existing read fence, otherwise insert a new one. - for (auto& fence : read_fences_) { - if (fence.Update(*signaled_fence)) { - signaled_fence.reset(); - break; - } - } - if (signaled_fence) - read_fences_.emplace_back(*signaled_fence); - } + if (signaled_fence) + read_fences_.insert(std::move(signaled_fence)); } }
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing.h b/gpu/command_buffer/service/shared_image/d3d_image_backing.h index 50c5f48..3210a82 100644 --- a/gpu/command_buffer/service/shared_image/d3d_image_backing.h +++ b/gpu/command_buffer/service/shared_image/d3d_image_backing.h
@@ -154,42 +154,6 @@ scoped_refptr<SharedContextState> context_state) override; private: - // A simple wrapper around a D3DSharedFence and a value that was previously - // signaled on the fence. This supports copy semantics so that it can be - // stored in |read_fences_| or |write_fence_|. - class SignaledFence { - public: - SignaledFence(scoped_refptr<D3DSharedFence> fence, uint64_t value); - SignaledFence(const SignaledFence&); - SignaledFence& operator=(const SignaledFence&); - ~SignaledFence(); - - const D3DSharedFence* fence() const { return fence_.get(); } - - // Issues a wait on the |fence_| using |value_|. Wait is skipped if this - // fence is signaled by |device|. Returns true on success. - bool WaitD3D11(Microsoft::WRL::ComPtr<ID3D11Device> device) const; - - // Issues a signal for the |fence_| with |value_| + 1 on the D3D11 device - // this fence was created with, and increments |value_| only on success. - // Returns true on success. - bool IncrementAndSignalD3D11(); - - // Update fence value from |other| if the underlying fence is the same. - // Returns true if the underlying fence was the same and either the value of - // this fence was updated to the new value or retained because it was ahead. - bool Update(const SignaledFence& other); - -#if BUILDFLAG(USE_DAWN) - // Wrap shared handle for |fence_| and |value_| in a Dawn fence descriptor. - ExternalImageDXGIFenceDescriptor AsDawnFenceDescriptor() const; -#endif - - private: - scoped_refptr<D3DSharedFence> fence_; - uint64_t value_ = 0; - }; - #if BUILDFLAG(USE_DAWN) struct DawnExternalImageState { DawnExternalImageState(); @@ -234,7 +198,7 @@ bool ValidateBeginAccess(bool write_access) const; - void EndAccessCommon(absl::optional<SignaledFence> signaled_fence); + void EndAccessCommon(scoped_refptr<D3DSharedFence> fence); // Texture could be nullptr if an empty backing is needed for testing. Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture_; @@ -278,16 +242,16 @@ // Fences for previous reads. These will be waited on by the subsequent write, // but not by reads. - std::vector<SignaledFence> read_fences_; + base::flat_set<scoped_refptr<D3DSharedFence>> read_fences_; // Fence for the previous write. These will be waited on by subsequent reads // and/or write. - absl::optional<SignaledFence> write_fence_; + scoped_refptr<D3DSharedFence> write_fence_; // Fence used for signaling on this backing's |d3d11_device_|. Lazily created // and signaled on first Dawn access, and used on any subsequent D3D11 access. // TODO(sunnyps): Support multiple D3D11 devices. - absl::optional<SignaledFence> d3d11_device_fence_; + scoped_refptr<D3DSharedFence> d3d11_device_fence_; }; } // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image/d3d_shared_fence.cc b/gpu/command_buffer/service/shared_image/d3d_shared_fence.cc index 175fce74..644028b 100644 --- a/gpu/command_buffer/service/shared_image/d3d_shared_fence.cc +++ b/gpu/command_buffer/service/shared_image/d3d_shared_fence.cc
@@ -93,6 +93,10 @@ return shared_handle_.get(); } +uint64_t D3DSharedFence::GetFenceValue() const { + return fence_value_; +} + bool D3DSharedFence::IsSameFenceAsHandle(HANDLE shared_handle) const { using PFN_COMPARE_OBJECT_HANDLES = BOOL(WINAPI*)(HANDLE hFirstObjectHandle, HANDLE hSecondObjectHandle); @@ -118,9 +122,13 @@ return false; } +void D3DSharedFence::Update(uint64_t fence_value) { + if (fence_value > fence_value_) + fence_value_ = fence_value; +} + bool D3DSharedFence::WaitD3D11( - Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device, - uint64_t wait_value) { + Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device) { // Skip wait if passed in device is the same as signaling device. if (d3d11_device == d3d11_device_) return true; @@ -149,7 +157,7 @@ return false; const Microsoft::WRL::ComPtr<ID3D11Fence>& fence = it->second; - HRESULT hr = context4->Wait(fence.Get(), wait_value); + HRESULT hr = context4->Wait(fence.Get(), fence_value_); if (FAILED(hr)) { DLOG(ERROR) << "D3D11 fence wait failed: 0x" << std::hex << hr; return false; @@ -157,7 +165,7 @@ return true; } -bool D3DSharedFence::SignalD3D11(uint64_t signal_value) { +bool D3DSharedFence::IncrementAndSignalD3D11() { DCHECK(d3d11_device_); DCHECK(d3d11_signal_fence_); @@ -166,11 +174,12 @@ if (!context4) return false; - HRESULT hr = context4->Signal(d3d11_signal_fence_.Get(), signal_value); + HRESULT hr = context4->Signal(d3d11_signal_fence_.Get(), fence_value_ + 1); if (FAILED(hr)) { DLOG(ERROR) << "D3D11 fence signal failed: 0x" << std::hex << hr; return false; } + fence_value_++; return true; }
diff --git a/gpu/command_buffer/service/shared_image/d3d_shared_fence.h b/gpu/command_buffer/service/shared_image/d3d_shared_fence.h index 90a6042e..fbd924a 100644 --- a/gpu/command_buffer/service/shared_image/d3d_shared_fence.h +++ b/gpu/command_buffer/service/shared_image/d3d_shared_fence.h
@@ -23,7 +23,9 @@ class GPU_GLES2_EXPORT D3DSharedFence : public base::RefCounted<D3DSharedFence> { public: - // Create a new ID3D11Fence with initial value 0 on given |d3d11_device|. + // Create a new ID3D11Fence with initial value 0 on given |d3d11_device|. The + // provided device is considered the owning device for the fence, and is the + // device used for signaling the fence. static scoped_refptr<D3DSharedFence> CreateForD3D11( Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device); @@ -38,18 +40,24 @@ // Return the shared handle for the fence. HANDLE GetSharedHandle() const; + // Returns the fence value that was last known to be signaled on this fence, + // and should be used for waiting. + uint64_t GetFenceValue() const; + // Returns true if the underlying fence object is the same as |shared_handle|. bool IsSameFenceAsHandle(HANDLE shared_handle) const; + // Updates fence value to |fence_value| provided that it's larger. + void Update(uint64_t fence_value); + // Issue a wait for the fence on the immediate context of |d3d11_device| using // |wait_value|. The wait is skipped if the passed in device is the same as // |d3d11_device_|. Returns true on success. - bool WaitD3D11(Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device, - uint64_t wait_value); + bool WaitD3D11(Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device); // Issue a signal for the fence on the immediate context of |d3d11_device_| // using |signal_value|. Returns true on success. - bool SignalD3D11(uint64_t signal_value); + bool IncrementAndSignalD3D11(); private: friend class base::RefCounted<D3DSharedFence>; @@ -63,6 +71,9 @@ // Owned shared handle corresponding to the fence. base::win::ScopedHandle shared_handle_; + // Value last known to be signaled for this fence to be used for future waits. + uint64_t fence_value_ = 0; + // If present, this is the D3D11 device that the fence was created on, and // used to signal |d3d11_fence_|. Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_;
diff --git a/infra/config/console-header.star b/infra/config/console-header.star index 1f874250..14cf612f 100644 --- a/infra/config/console-header.star +++ b/infra/config/console-header.star
@@ -89,9 +89,9 @@ alt = "Chrome perf dashboard", ), headers.link( - text = "flake-portal", + text = "LUCI Analysis", branch_selector = branches.ALL_BRANCHES, - url = "https://analysis.chromium.org/p/chromium/flake-portal", + url = "https://luci-analysis.appspot.com", alt = "New flake portal", ), headers.link(
diff --git a/infra/config/dev/chromium-header.textpb b/infra/config/dev/chromium-header.textpb index 5dfa835..0b0bb6de 100644 --- a/infra/config/dev/chromium-header.textpb +++ b/infra/config/dev/chromium-header.textpb
@@ -30,8 +30,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links {
diff --git a/infra/config/generated/builders/try/gpu-fyi-try-mac-nvidia-retina-dbg/properties.json b/infra/config/generated/builders/try/gpu-fyi-try-mac-nvidia-retina-dbg/properties.json deleted file mode 100644 index 7aab3194..0000000 --- a/infra/config/generated/builders/try/gpu-fyi-try-mac-nvidia-retina-dbg/properties.json +++ /dev/null
@@ -1,15 +0,0 @@ -{ - "$build/goma": { - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org" - }, - "$recipe_engine/resultdb/test_presentation": { - "column_keys": [], - "grouping_keys": [ - "status", - "v.test_suite" - ] - }, - "builder_group": "tryserver.chromium.mac", - "recipe": "chromium_trybot" -} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/linux_chromium_archive_rel_ng/properties.json b/infra/config/generated/builders/try/linux_chromium_archive_rel_ng/properties.json index 3482017..5ca2ae5 100644 --- a/infra/config/generated/builders/try/linux_chromium_archive_rel_ng/properties.json +++ b/infra/config/generated/builders/try/linux_chromium_archive_rel_ng/properties.json
@@ -37,11 +37,6 @@ ] } }, - "$build/goma": { - "enable_ats": true, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org" - }, "$build/reclient": { "instance": "rbe-chromium-untrusted", "metrics_project": "chromium-reclient-metrics"
diff --git a/infra/config/generated/builders/try/linux_chromium_cfi_rel_ng/properties.json b/infra/config/generated/builders/try/linux_chromium_cfi_rel_ng/properties.json index 7650049..25cae13 100644 --- a/infra/config/generated/builders/try/linux_chromium_cfi_rel_ng/properties.json +++ b/infra/config/generated/builders/try/linux_chromium_cfi_rel_ng/properties.json
@@ -37,11 +37,6 @@ ] } }, - "$build/goma": { - "enable_ats": true, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org" - }, "$build/reclient": { "instance": "rbe-chromium-untrusted", "metrics_project": "chromium-reclient-metrics"
diff --git a/infra/config/generated/builders/try/linux_chromium_compile_rel_ng/properties.json b/infra/config/generated/builders/try/linux_chromium_compile_rel_ng/properties.json index db608376..c7a9e89 100644 --- a/infra/config/generated/builders/try/linux_chromium_compile_rel_ng/properties.json +++ b/infra/config/generated/builders/try/linux_chromium_compile_rel_ng/properties.json
@@ -79,11 +79,6 @@ "is_compile_only": true } }, - "$build/goma": { - "enable_ats": true, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org" - }, "$build/reclient": { "instance": "rbe-chromium-untrusted", "metrics_project": "chromium-reclient-metrics"
diff --git a/infra/config/generated/builders/try/linux_chromium_dbg_ng/properties.json b/infra/config/generated/builders/try/linux_chromium_dbg_ng/properties.json index 676301d..6e494d7c 100644 --- a/infra/config/generated/builders/try/linux_chromium_dbg_ng/properties.json +++ b/infra/config/generated/builders/try/linux_chromium_dbg_ng/properties.json
@@ -72,11 +72,6 @@ ] } }, - "$build/goma": { - "enable_ats": true, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org" - }, "$build/reclient": { "instance": "rbe-chromium-untrusted", "metrics_project": "chromium-reclient-metrics"
diff --git a/infra/config/generated/builders/try/linux_chromium_msan_focal/properties.json b/infra/config/generated/builders/try/linux_chromium_msan_focal/properties.json index 2500aa1c..937cf91 100644 --- a/infra/config/generated/builders/try/linux_chromium_msan_focal/properties.json +++ b/infra/config/generated/builders/try/linux_chromium_msan_focal/properties.json
@@ -35,12 +35,6 @@ ] } }, - "$build/goma": { - "enable_ats": true, - "jobs": 150, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org" - }, "$build/reclient": { "instance": "rbe-chromium-untrusted", "metrics_project": "chromium-reclient-metrics"
diff --git a/infra/config/generated/builders/try/linux_chromium_msan_rel_ng/properties.json b/infra/config/generated/builders/try/linux_chromium_msan_rel_ng/properties.json index 512e1d8..90b4eeb 100644 --- a/infra/config/generated/builders/try/linux_chromium_msan_rel_ng/properties.json +++ b/infra/config/generated/builders/try/linux_chromium_msan_rel_ng/properties.json
@@ -72,12 +72,6 @@ ] } }, - "$build/goma": { - "enable_ats": true, - "jobs": 150, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org" - }, "$build/reclient": { "instance": "rbe-chromium-untrusted", "metrics_project": "chromium-reclient-metrics"
diff --git a/infra/config/generated/builders/try/linux_chromium_ubsan_rel_ng/properties.json b/infra/config/generated/builders/try/linux_chromium_ubsan_rel_ng/properties.json index 0fe47da..3f61a56 100644 --- a/infra/config/generated/builders/try/linux_chromium_ubsan_rel_ng/properties.json +++ b/infra/config/generated/builders/try/linux_chromium_ubsan_rel_ng/properties.json
@@ -37,11 +37,6 @@ ] } }, - "$build/goma": { - "enable_ats": true, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org" - }, "$build/reclient": { "instance": "rbe-chromium-untrusted", "metrics_project": "chromium-reclient-metrics"
diff --git a/infra/config/generated/builders/try/linux_vr/properties.json b/infra/config/generated/builders/try/linux_vr/properties.json index f73afafc..1e5aaf0 100644 --- a/infra/config/generated/builders/try/linux_vr/properties.json +++ b/infra/config/generated/builders/try/linux_vr/properties.json
@@ -40,11 +40,6 @@ ] } }, - "$build/goma": { - "enable_ats": true, - "rpc_extra_params": "?prod", - "server_host": "goma.chromium.org" - }, "$build/reclient": { "instance": "rbe-chromium-untrusted", "metrics_project": "chromium-reclient-metrics"
diff --git a/infra/config/generated/cq-builders.md b/infra/config/generated/cq-builders.md index c02b15c..6bf5a405 100644 --- a/infra/config/generated/cq-builders.md +++ b/infra/config/generated/cq-builders.md
@@ -513,9 +513,6 @@ * [linux-rel-ml](https://ci.chromium.org/p/chromium/builders/try/linux-rel-ml) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""linux-rel-ml"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""linux-rel-ml"")) * Experiment percentage: 5.0 -* [mac-rel-inverse-fyi](https://ci.chromium.org/p/chromium/builders/try/mac-rel-inverse-fyi) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""mac-rel-inverse-fyi"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""mac-rel-inverse-fyi"")) - * Experiment percentage: 100.0 - * [mac12-arm64-rel](https://ci.chromium.org/p/chromium/builders/try/mac12-arm64-rel) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""mac12-arm64-rel"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""mac12-arm64-rel"")) * Experiment percentage: 100.0
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index 71ab097..c856372 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -1968,10 +1968,6 @@ includable_only: true } builders { - name: "chromium/try/gpu-fyi-try-mac-nvidia-retina-dbg" - includable_only: true - } - builders { name: "chromium/try/gpu-fyi-try-mac-nvidia-retina-exp" includable_only: true } @@ -3332,24 +3328,7 @@ } builders { name: "chromium/try/mac-rel-inverse-fyi" - experiment_percentage: 100 - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - path_regexp: "docs/.+" - exclude: true - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - path_regexp: "infra/config/.+" - exclude: true - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - path_regexp: "infra/config/generated/builders/try/mac-rel-inverse-fyi/.+" - } + includable_only: true } builders { name: "chromium/try/mac-swangle-chromium-try-x64"
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 0f18198..4b6e4a61 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -38086,7 +38086,7 @@ } experiments { key: "luci.buildbucket.omit_python2" - value: 0 + value: 100 } experiments { key: "luci.recipes.use_python3" @@ -69386,111 +69386,6 @@ } } builders { - name: "gpu-fyi-try-mac-nvidia-retina-dbg" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cpu:x86-64" - dimensions: "os:Mac" - dimensions: "pool:luci.chromium.gpu.mac.retina.nvidia.try" - 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/gpu-fyi-try-mac-nvidia-retina-dbg/properties.json",' - ' "top_level_project": {' - ' "ref": "refs/heads/main",' - ' "repo": {' - ' "host": "chromium.googlesource.com",' - ' "project": "chromium/src"' - ' }' - ' }' - ' },' - ' "builder_group": "tryserver.chromium.mac",' - ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium_trybot"' - '}' - execution_timeout_secs: 21600 - expiration_secs: 7200 - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium_swarming.expose_merge_script_failures" - value: 100 - } - experiments { - key: "enable_weetbix_queries" - value: 100 - } - experiments { - key: "luci.buildbucket.omit_python2" - 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: "gpu-fyi-try-mac-nvidia-retina-exp" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" @@ -75529,7 +75424,7 @@ } experiments { key: "luci.buildbucket.omit_python2" - value: 0 + value: 100 } experiments { key: "luci.recipes.use_python3" @@ -85272,6 +85167,10 @@ value: 5 } experiments { + key: "chromium_rts.inverted_rts" + value: 100 + } + experiments { key: "chromium_swarming.expose_merge_script_failures" value: 100 }
diff --git a/infra/config/generated/luci/luci-milo-dev.cfg b/infra/config/generated/luci/luci-milo-dev.cfg index bfb9c5f..481ef89 100644 --- a/infra/config/generated/luci/luci-milo-dev.cfg +++ b/infra/config/generated/luci/luci-milo-dev.cfg
@@ -62,8 +62,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links {
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg index f88b9b2..dde9bc6 100644 --- a/infra/config/generated/luci/luci-milo.cfg +++ b/infra/config/generated/luci/luci-milo.cfg
@@ -716,8 +716,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -1461,8 +1461,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -1965,8 +1965,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -2324,8 +2324,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -2947,8 +2947,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -3391,8 +3391,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -3731,8 +3731,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -4294,8 +4294,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -4682,8 +4682,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -5091,8 +5091,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -5538,8 +5538,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -6102,8 +6102,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -6581,8 +6581,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -6962,8 +6962,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -7341,8 +7341,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -7834,8 +7834,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -8705,8 +8705,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -9136,8 +9136,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -9541,8 +9541,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -9936,8 +9936,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -10593,8 +10593,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -11007,8 +11007,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -11426,8 +11426,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -11880,8 +11880,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -12244,8 +12244,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -12698,8 +12698,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -13053,8 +13053,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -13432,8 +13432,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -13916,8 +13916,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -14290,8 +14290,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -14705,8 +14705,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -15099,8 +15099,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -15504,8 +15504,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -15856,8 +15856,8 @@ alt: "Chrome perf dashboard" } links { - text: "flake-portal" - url: "https://analysis.chromium.org/p/chromium/flake-portal" + text: "LUCI Analysis" + url: "https://luci-analysis.appspot.com" alt: "New flake portal" } links { @@ -16532,9 +16532,6 @@ name: "buildbucket/luci.chromium.try/gpu-fyi-try-mac-intel-rel" } builders { - name: "buildbucket/luci.chromium.try/gpu-fyi-try-mac-nvidia-retina-dbg" - } - builders { name: "buildbucket/luci.chromium.try/gpu-fyi-try-mac-nvidia-retina-exp" } builders { @@ -18015,9 +18012,6 @@ name: "buildbucket/luci.chromium.try/gpu-fyi-try-mac-intel-rel" } builders { - name: "buildbucket/luci.chromium.try/gpu-fyi-try-mac-nvidia-retina-dbg" - } - builders { name: "buildbucket/luci.chromium.try/gpu-fyi-try-mac-nvidia-retina-exp" } builders {
diff --git a/infra/config/subprojects/chromium/ci/chromium.accessibility.star b/infra/config/subprojects/chromium/ci/chromium.accessibility.star index 72d185b5..7dbdeba 100644 --- a/infra/config/subprojects/chromium/ci/chromium.accessibility.star +++ b/infra/config/subprojects/chromium/ci/chromium.accessibility.star
@@ -19,9 +19,6 @@ reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI, reclient_instance = reclient.instance.DEFAULT_TRUSTED, service_account = ci.DEFAULT_SERVICE_ACCOUNT, - - # TODO(crbug.com/1362440): remove this. - omit_python2 = False, ) consoles.console_view(
diff --git a/infra/config/subprojects/chromium/gpu.try.star b/infra/config/subprojects/chromium/gpu.try.star index e680bbe..55a593c 100644 --- a/infra/config/subprojects/chromium/gpu.try.star +++ b/infra/config/subprojects/chromium/gpu.try.star
@@ -318,11 +318,6 @@ ) gpu_mac_builder( - name = "gpu-fyi-try-mac-nvidia-retina-dbg", - pool = "luci.chromium.gpu.mac.retina.nvidia.try", -) - -gpu_mac_builder( name = "gpu-fyi-try-mac-nvidia-retina-exp", # This bot has one machine backing its tests at the moment. # If it gets more, the modified execution_timeout should be removed.
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.accessibility.star b/infra/config/subprojects/chromium/try/tryserver.chromium.accessibility.star index 1728e0a..c2092ef6 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.accessibility.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.accessibility.star
@@ -18,9 +18,6 @@ os = os.LINUX_DEFAULT, pool = try_.DEFAULT_POOL, service_account = try_.DEFAULT_SERVICE_ACCOUNT, - - # TODO(crbug.com/1362440): remove this. - omit_python2 = False, ) consoles.list_view(
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star index 14b05cb..4f2e8e8 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
@@ -339,6 +339,7 @@ mirrors = [ "ci/linux-archive-rel", ], + goma_backend = None, ) try_.orchestrator_builder( @@ -375,6 +376,7 @@ cores = 32, # TODO(thakis): Remove once https://crbug.com/927738 is resolved. execution_timeout = 7 * time.hour, + goma_backend = None, ) try_.builder( @@ -457,6 +459,7 @@ include_all_triggered_testers = True, is_compile_only = True, ), + goma_backend = None, ) try_.builder( @@ -478,6 +481,7 @@ "build/.*check_gn_headers.*", ], ), + goma_backend = None, ) try_.builder( @@ -486,7 +490,7 @@ "ci/Linux MSan Focal", ], execution_timeout = 16 * time.hour, - goma_jobs = goma.jobs.J150, + goma_backend = None, os = os.LINUX_FOCAL, ) @@ -497,7 +501,7 @@ "ci/Linux MSan Tests", ], execution_timeout = 6 * time.hour, - goma_jobs = goma.jobs.J150, + goma_backend = None, ) try_.orchestrator_builder( @@ -531,6 +535,7 @@ mirrors = [ "ci/linux-ubsan-vptr", ], + goma_backend = None, ) try_.builder( @@ -601,6 +606,7 @@ "content/browser/xr/.+", ], ), + goma_backend = None, ) try_.builder(
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star index 45e7f0cb..286a862 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
@@ -110,6 +110,9 @@ use_clang_coverage = True, coverage_test_types = ["overall", "unit"], tryjob = try_.job(), + experiments = { + "chromium_rts.inverted_rts": 100, + }, # TODO (crbug.com/1372179): Use orchestrator pool once overloaded test pools # are addressed #use_orchestrator_pool = True, @@ -128,9 +131,6 @@ main_list_view = "try", use_clang_coverage = True, coverage_test_types = ["overall", "unit"], - tryjob = try_.job( - experiment_percentage = 100, - ), experiments = { "chromium_rts.inverted_rts": 100, "chromium_rts.inverted_rts_bail_early": 100,
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm index 51f7a46..1e514a0b 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -673,8 +673,6 @@ self.feedWrapperViewController; self.ntpViewController.overscrollDelegate = self; self.ntpViewController.ntpContentDelegate = self; - self.ntpViewController.identityDiscButton = - [self.headerController identityDiscButton]; self.ntpViewController.headerController = self.headerController;
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.h b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.h index 06264c3..a612ff4 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.h +++ b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.h
@@ -46,11 +46,7 @@ // controller. @property(nonatomic, weak) ViewRevealingVerticalPanHandler* panGestureHandler; -// Identity disc shown in the NTP. -// TODO(crbug.com/1170995): Remove once the Feed header properly supports -// ContentSuggestions. -@property(nonatomic, weak) UIButton* identityDiscButton; - +// The view controller representing the content suggestions. @property(nonatomic, strong) ContentSuggestionsViewController* contentSuggestionsViewController;
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm index 2542763d..8c1b5b6 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
@@ -86,6 +86,11 @@ @property(nonatomic, strong) NSMutableArray<UIViewController*>* viewControllersAboveFeed; +// Identity disc shown in the NTP. +// TODO(crbug.com/1170995): Remove once the Feed header properly supports +// ContentSuggestions. +@property(nonatomic, weak) UIButton* identityDiscButton; + @end @implementation NewTabPageViewController @@ -145,6 +150,9 @@ [self registerNotifications]; [self layoutContentInParentCollectionView]; + + self.identityDiscButton = [self.headerController identityDiscButton]; + DCHECK(self.identityDiscButton); } - (void)viewWillLayoutSubviews { @@ -197,10 +205,6 @@ // changed in another tab. This ensures that the sticky elements are correct // whenever an NTP reappears. [self handleStickyElementsForScrollPosition:[self scrollPosition] force:YES]; - - if (![self isInitialOffsetFromSavedState]) { - [self setContentOffsetToTop]; - } self.viewDidAppear = YES; }
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/BUILD.gn b/ios/chrome/browser/ui/omnibox/keyboard_assist/BUILD.gn index bceb414..ade75cc 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/BUILD.gn +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/BUILD.gn
@@ -28,6 +28,7 @@ "resources:keyboard_accessory_voice_search", "//base", "//base:i18n", + "//components/search_engines", "//ios/chrome/app/strings", "//ios/chrome/browser/flags:system_flags", "//ios/chrome/browser/search_engines:search_engines",
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h index f5656d3f..f5cf985cf 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h
@@ -13,7 +13,6 @@ @protocol LensCommands; @class OmniboxTextFieldIOS; @protocol QRScannerCommands; -class TemplateURLService; // Delegate protocol for the KeyboardAccessoryView. @protocol OmniboxAssistiveKeyboardDelegate @@ -21,10 +20,6 @@ // The layout guide center for the current scene. @property(nonatomic, strong) LayoutGuideCenter* layoutGuideCenter; -// The templateURLService used by this mediator to extract whether the default -// search engine is Google. -@property(nonatomic, assign) TemplateURLService* templateURLService; - // Notifies the delegate that the Voice Search button was tapped. - (void)keyboardAccessoryVoiceSearchTapped:(id)sender;
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm index 3e6ec29..715b66b 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm
@@ -26,7 +26,6 @@ @synthesize applicationCommandsHandler = _applicationCommandsHandler; @synthesize browserCommandsHandler = _browserCommandsHandler; -@synthesize templateURLService = _templateURLService; @synthesize layoutGuideCenter = _layoutGuideCenter; @synthesize qrScannerCommandsHandler = _qrScannerCommandsHandler; @synthesize omniboxTextField = _omniboxTextField;
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.h b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.h index 3fd2c21..4b45d038 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.h +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.h
@@ -8,18 +8,25 @@ #import <UIKit/UIKit.h> @protocol OmniboxAssistiveKeyboardDelegate; +@class OmniboxKeyboardAccessoryView; +class TemplateURLService; // Adds a keyboard assistive view [1] to `textField`. The assistive view // contains among other things a button to quickly enter `dotComTLD`, and the // callbacks are handled via `delegate`. `dotComTLD` must not be nil. +// `templateURLService' must be so the keyboard can be keep track of the default +// search engine. // // [1] // On iPhone the assistive view is a keyboard accessory view. // On iPad, the assitive view is an inputAssistantItem to handle split // keyboards. -void ConfigureAssistiveKeyboardViews( +// +// Returns the keyboard accessory view if on iPhone, otherwise returns nil. +OmniboxKeyboardAccessoryView* ConfigureAssistiveKeyboardViews( UITextField* textField, NSString* dotComTLD, - id<OmniboxAssistiveKeyboardDelegate> delegate); + id<OmniboxAssistiveKeyboardDelegate> delegate, + TemplateURLService* templateURLService); #endif // IOS_CHROME_BROWSER_UI_OMNIBOX_KEYBOARD_ASSIST_OMNIBOX_ASSISTIVE_KEYBOARD_VIEWS_H_
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.mm b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.mm index 7c2116d..f080f3f 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.mm +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.h" #import "base/check.h" +#import "components/search_engines/template_url_service.h" #import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h" #import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_input_assistant_items.h" #import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.h" @@ -14,10 +15,11 @@ #error "This file requires ARC support." #endif -void ConfigureAssistiveKeyboardViews( +OmniboxKeyboardAccessoryView* ConfigureAssistiveKeyboardViews( UITextField* textField, NSString* dotComTLD, - id<OmniboxAssistiveKeyboardDelegate> delegate) { + id<OmniboxAssistiveKeyboardDelegate> delegate, + TemplateURLService* templateURLService) { DCHECK(dotComTLD); NSArray<NSString*>* buttonTitles = @[ @":", @"-", @"/", dotComTLD ]; @@ -29,11 +31,16 @@ } else { textField.inputAssistantItem.leadingBarButtonGroups = @[]; textField.inputAssistantItem.trailingBarButtonGroups = @[]; - UIView* keyboardAccessoryView = - [[OmniboxKeyboardAccessoryView alloc] initWithButtons:buttonTitles - delegate:delegate - pasteTarget:textField]; + OmniboxKeyboardAccessoryView* keyboardAccessoryView = + [[OmniboxKeyboardAccessoryView alloc] + initWithButtons:buttonTitles + delegate:delegate + pasteTarget:textField + templateURLService:templateURLService]; [keyboardAccessoryView setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; [textField setInputAccessoryView:keyboardAccessoryView]; + return keyboardAccessoryView; } + + return nil; }
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.h b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.h index 304e41f..f77de95 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.h +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.h
@@ -9,6 +9,8 @@ #import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h" +class TemplateURLService; + // Accessory View above the keyboard. // Shows keys that are shortcuts to commonly used characters or strings, // and buttons to start Voice Search, Camera Search or Paste Search. @@ -20,6 +22,7 @@ - (instancetype)initWithButtons:(NSArray<NSString*>*)buttonTitles delegate:(id<OmniboxAssistiveKeyboardDelegate>)delegate pasteTarget:(id<UIPasteConfigurationSupporting>)pasteTarget + templateURLService:(TemplateURLService*)templateURLService NS_DESIGNATED_INITIALIZER; - (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; @@ -27,6 +30,10 @@ - (instancetype)initWithFrame:(CGRect)frame inputViewStyle:(UIInputViewStyle)inputViewStyle NS_UNAVAILABLE; +// The templateURLService used by this view to determine whether or not +// Google is the default search engine. +@property(nonatomic, assign) TemplateURLService* templateURLService; + @end #endif // IOS_CHROME_BROWSER_UI_OMNIBOX_KEYBOARD_ASSIST_OMNIBOX_KEYBOARD_ACCESSORY_VIEW_H_
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm index e87bf0c..aa210c77 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm
@@ -48,8 +48,8 @@ - (instancetype)initWithButtons:(NSArray<NSString*>*)buttonTitles delegate:(id<OmniboxAssistiveKeyboardDelegate>)delegate - pasteTarget: - (id<UIPasteConfigurationSupporting>)pasteTarget { + pasteTarget:(id<UIPasteConfigurationSupporting>)pasteTarget + templateURLService:(TemplateURLService*)templateURLService { self = [super initWithFrame:CGRectZero inputViewStyle:UIInputViewStyleKeyboard]; if (self) { @@ -58,10 +58,8 @@ _pasteTarget = pasteTarget; self.translatesAutoresizingMaskIntoConstraints = NO; self.allowsSelfSizing = YES; + self.templateURLService = templateURLService; [self addSubviews]; - - _searchEngineObserver = std::make_unique<SearchEngineObserverBridge>( - self, delegate.templateURLService); } return self; } @@ -101,7 +99,7 @@ // Voice search, camera/Lens search and paste search. BOOL useLens = ios::provider::IsLensSupported() && base::FeatureList::IsEnabled(kEnableLensInKeyboard) && - [self isGoogleSearchEngine:_delegate.templateURLService]; + [self isGoogleSearchEngine:self.templateURLService]; NSArray<UIControl*>* leadingControls = OmniboxAssistiveKeyboardLeadingControls(_delegate, self.pasteTarget, useLens); @@ -175,11 +173,14 @@ [_delegate keyPressed:[button currentTitle]]; } -#pragma mark - UIView overrides +#pragma mark - Setters -- (void)didMoveToSuperview { - [super didMoveToSuperview]; - if (!self.superview) { +- (void)setTemplateURLService:(TemplateURLService*)templateURLService { + _templateURLService = templateURLService; + if (_templateURLService) { + _searchEngineObserver = + std::make_unique<SearchEngineObserverBridge>(self, templateURLService); + } else { _searchEngineObserver.reset(); } }
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm b/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm index a7b58b7..082ae7b7 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm
@@ -35,6 +35,7 @@ #import "ios/chrome/browser/ui/main/scene_state_browser_agent.h" #import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h" #import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.h" +#import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.h" #import "ios/chrome/browser/ui/omnibox/omnibox_mediator.h" #import "ios/chrome/browser/ui/omnibox/omnibox_return_key_forwarding_delegate.h" #import "ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.h" @@ -77,6 +78,10 @@ @property(nonatomic, strong) ZeroSuggestPrefetchHelper* zeroSuggestPrefetchHelper; +// The keyboard accessory view. Will be nil if the app is running on an iPad. +@property(nonatomic, strong) + OmniboxKeyboardAccessoryView* keyboardAccessoryView; + @end @implementation OmniboxCoordinator { @@ -141,14 +146,13 @@ self.browser->GetCommandDispatcher(), QRScannerCommands); self.keyboardDelegate.layoutGuideCenter = LayoutGuideCenterForBrowser(self.browser); - self.keyboardDelegate.templateURLService = templateURLService; // TODO(crbug.com/1045047): Use HandlerForProtocol after commands protocol // clean up. self.keyboardDelegate.browserCommandsHandler = static_cast<id<BrowserCommands>>(self.browser->GetCommandDispatcher()); self.keyboardDelegate.omniboxTextField = self.textField; - ConfigureAssistiveKeyboardViews(self.textField, kDotComTLD, - self.keyboardDelegate); + self.keyboardAccessoryView = ConfigureAssistiveKeyboardViews( + self.textField, kDotComTLD, self.keyboardDelegate, templateURLService); if (base::FeatureList::IsEnabled(omnibox::kZeroSuggestPrefetching)) { self.zeroSuggestPrefetchHelper = [[ZeroSuggestPrefetchHelper alloc] @@ -164,6 +168,12 @@ self.editController = nil; self.viewController = nil; self.mediator.templateURLService = nullptr; // Unregister the observer. + if (self.keyboardAccessoryView) { + // Unregister the observer. + self.keyboardAccessoryView.templateURLService = nil; + } + + self.keyboardAccessoryView = nil; self.mediator = nil; self.returnDelegate = nil; self.zeroSuggestPrefetchHelper = nil;
diff --git a/media/DEPS b/media/DEPS index 605f574..671ab21 100644 --- a/media/DEPS +++ b/media/DEPS
@@ -22,7 +22,7 @@ "+third_party/libgav1", "+third_party/libvpx", "+third_party/libyuv", - "+third_party/openh264/src/codec/api/svc", + "+third_party/openh264/src/codec/api/wels", "+third_party/opus", "+third_party/skia", "+ui/base/x/x11_user_input_monitor.h",
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 28417a4c..1f909f2 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -590,11 +590,6 @@ base::FEATURE_DISABLED_BY_DEFAULT); #endif // BUILDFLAG(IS_LINUX) -// Enable VA-API hardware decode acceleration for AV1. -BASE_FEATURE(kVaapiAV1Decoder, - "VaapiAV1Decoder", - base::FEATURE_ENABLED_BY_DEFAULT); - // Enable VA-API hardware low power encoder for all codecs on intel Gen9x gpu. BASE_FEATURE(kVaapiLowPowerEncoderGen9x, "VaapiLowPowerEncoderGen9x", @@ -901,6 +896,11 @@ #endif // BUILDFLAG(IS_ANDROID) #if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION) +// Enable hardware AV1 decoder on ChromeOS. +BASE_FEATURE(kChromeOSHWAV1Decoder, + "ChromeOSHWAV1Decoder", + base::FEATURE_ENABLED_BY_DEFAULT); + // Enable Variable Bitrate encoding with hardware accelerated encoders on // ChromeOS. BASE_FEATURE(kChromeOSHWVBREncoding,
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index 4c64486..3c172924 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -219,7 +219,6 @@ MEDIA_EXPORT BASE_DECLARE_FEATURE(kVaapiVideoEncodeLinux); MEDIA_EXPORT BASE_DECLARE_FEATURE(kVaapiIgnoreDriverChecks); #endif // BUILDFLAG(IS_LINUX) -MEDIA_EXPORT BASE_DECLARE_FEATURE(kVaapiAV1Decoder); MEDIA_EXPORT BASE_DECLARE_FEATURE(kVaapiLowPowerEncoderGen9x); MEDIA_EXPORT BASE_DECLARE_FEATURE(kVaapiEnforceVideoMinMaxResolution); MEDIA_EXPORT BASE_DECLARE_FEATURE(kVaapiVideoMinResolutionForPerformance); @@ -256,6 +255,7 @@ #endif // BUILDFLAG(IS_ANDROID) #if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION) +MEDIA_EXPORT BASE_DECLARE_FEATURE(kChromeOSHWAV1Decoder); MEDIA_EXPORT BASE_DECLARE_FEATURE(kChromeOSHWVBREncoding); MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseChromeOSDirectVideoDecoder); MEDIA_EXPORT BASE_DECLARE_FEATURE(kLimitConcurrentDecoderInstances);
diff --git a/media/fuchsia/cdm/fuchsia_cdm.h b/media/fuchsia/cdm/fuchsia_cdm.h index 9eda5e2..075c410c 100644 --- a/media/fuchsia/cdm/fuchsia_cdm.h +++ b/media/fuchsia/cdm/fuchsia_cdm.h
@@ -106,9 +106,6 @@ void OnNewKey(); - CdmPromiseAdapter promises_; - base::flat_map<std::string, std::unique_ptr<CdmSession>> session_map_; - fuchsia::media::drm::ContentDecryptionModulePtr cdm_; ReadyCB ready_cb_; SessionCallbacks session_callbacks_; @@ -119,6 +116,12 @@ std::vector<base::RepeatingClosure> new_key_callbacks_ GUARDED_BY(new_key_callbacks_lock_); + CdmPromiseAdapter promises_; + + // CdmSession instances reference `session_callbacks_`, so they must be + // deleted before the callbacks. + base::flat_map<std::string, std::unique_ptr<CdmSession>> session_map_; + CallbackRegistry<EventCB::RunType> event_callbacks_; };
diff --git a/media/gpu/chromeos/dmabuf_video_frame_pool.h b/media/gpu/chromeos/dmabuf_video_frame_pool.h index 51c236b..3860d74 100644 --- a/media/gpu/chromeos/dmabuf_video_frame_pool.h +++ b/media/gpu/chromeos/dmabuf_video_frame_pool.h
@@ -24,10 +24,10 @@ class PlatformVideoFramePool; // Interface for allocating and managing DMA-buf VideoFrame. The client should -// set a task runner first, and guarantee both GetFrame() and the destructor are -// executed on this task runner. -// Note: other public methods might be called at different thread. The -// implementation must be thread-safe. +// set a task runner first via set_parent_task_runner(), and guarantee that +// Initialize(), GetFrame(), GetGpuBufferLayout() and the destructor are +// executed on this task runner. Note: other public methods might be called at +// different thread. The implementation must be thread-safe. class MEDIA_GPU_EXPORT DmabufVideoFramePool { public: using DmabufId = const std::vector<base::ScopedFD>*; @@ -94,6 +94,10 @@ // |parent_task_runner_| because it may invalidate weak ptrs. virtual void ReleaseAllFrames() = 0; + // Detailed information of the allocated GpuBufferLayout. Only valid after a + // successful Initialize() call, otherwise returns absl::nullopt. + virtual absl::optional<GpuBufferLayout> GetGpuBufferLayout() = 0; + // Returns true if and only if the pool is a mock pool used for testing. virtual bool IsFakeVideoFramePool();
diff --git a/media/gpu/chromeos/platform_video_frame_pool.cc b/media/gpu/chromeos/platform_video_frame_pool.cc index d20f651..86132db 100644 --- a/media/gpu/chromeos/platform_video_frame_pool.cc +++ b/media/gpu/chromeos/platform_video_frame_pool.cc
@@ -288,6 +288,12 @@ weak_this_ = weak_this_factory_.GetWeakPtr(); } +absl::optional<GpuBufferLayout> PlatformVideoFramePool::GetGpuBufferLayout() { + DCHECK(parent_task_runner_->RunsTasksInCurrentSequence()); + base::AutoLock auto_lock(lock_); + return frame_layout_; +} + // static void PlatformVideoFramePool::OnFrameReleasedThunk( absl::optional<base::WeakPtr<PlatformVideoFramePool>> pool,
diff --git a/media/gpu/chromeos/platform_video_frame_pool.h b/media/gpu/chromeos/platform_video_frame_pool.h index 9bcfefe..05187c8 100644 --- a/media/gpu/chromeos/platform_video_frame_pool.h +++ b/media/gpu/chromeos/platform_video_frame_pool.h
@@ -47,7 +47,6 @@ // DmabufVideoFramePool implementation. PlatformVideoFramePool* AsPlatformVideoFramePool() override; - CroStatus::Or<GpuBufferLayout> Initialize(const Fourcc& fourcc, const gfx::Size& coded_size, const gfx::Rect& visible_rect, @@ -59,6 +58,7 @@ bool IsExhausted() override; void NotifyWhenFrameAvailable(base::OnceClosure cb) override; void ReleaseAllFrames() override; + absl::optional<GpuBufferLayout> GetGpuBufferLayout() override; // Returns the original frame of a wrapped frame. We need this method to // determine whether the frame returned by GetFrame() is the same one after
diff --git a/media/gpu/chromeos/vda_video_frame_pool.cc b/media/gpu/chromeos/vda_video_frame_pool.cc index 0a21435..0b289a7 100644 --- a/media/gpu/chromeos/vda_video_frame_pool.cc +++ b/media/gpu/chromeos/vda_video_frame_pool.cc
@@ -180,6 +180,12 @@ // NOREACHED() for now in order to prevent a DCHECK when this occurs. } +absl::optional<GpuBufferLayout> VdaVideoFramePool::GetGpuBufferLayout() { + DVLOGF(3); + DCHECK_CALLED_ON_VALID_SEQUENCE(parent_sequence_checker_); + return layout_; +} + void VdaVideoFramePool::CallFrameAvailableCbIfNeeded() { DVLOGF(4); DCHECK_CALLED_ON_VALID_SEQUENCE(parent_sequence_checker_);
diff --git a/media/gpu/chromeos/vda_video_frame_pool.h b/media/gpu/chromeos/vda_video_frame_pool.h index c2e467dc..e5621e2 100644 --- a/media/gpu/chromeos/vda_video_frame_pool.h +++ b/media/gpu/chromeos/vda_video_frame_pool.h
@@ -72,6 +72,7 @@ bool IsExhausted() override; void NotifyWhenFrameAvailable(base::OnceClosure cb) override; void ReleaseAllFrames() override; + absl::optional<GpuBufferLayout> GetGpuBufferLayout() override; private: // Update the layout of the buffers. |vda_| calls this as
diff --git a/media/gpu/chromeos/video_decoder_pipeline_unittest.cc b/media/gpu/chromeos/video_decoder_pipeline_unittest.cc index ae91002..1e3d674 100644 --- a/media/gpu/chromeos/video_decoder_pipeline_unittest.cc +++ b/media/gpu/chromeos/video_decoder_pipeline_unittest.cc
@@ -69,6 +69,7 @@ MOCK_METHOD0(IsExhausted, bool()); MOCK_METHOD1(NotifyWhenFrameAvailable, void(base::OnceClosure)); MOCK_METHOD0(ReleaseAllFrames, void()); + MOCK_METHOD0(GetGpuBufferLayout, absl::optional<GpuBufferLayout>()); bool IsFakeVideoFramePool() override { return true; } };
diff --git a/media/gpu/test/video_player/video_player_test_environment.cc b/media/gpu/test/video_player/video_player_test_environment.cc index c5c9976..00d4acf8 100644 --- a/media/gpu/test/video_player/video_player_test_environment.cc +++ b/media/gpu/test/video_player/video_player_test_environment.cc
@@ -46,13 +46,9 @@ // there is no intersection between the enabled and disabled set. std::vector<base::test::FeatureRef> combined_enabled_features( enabled_features); - combined_enabled_features.push_back(media::kVp9kSVCHWDecoding); std::vector<base::test::FeatureRef> combined_disabled_features( disabled_features); #if BUILDFLAG(USE_VAAPI) - // TODO(b/172217032): remove once enabled by default. - combined_enabled_features.push_back(media::kVaapiAV1Decoder); - // Disable this feature so that the decoder test can test a // resolution which is denied for the sake of performance. See // b/171041334.
diff --git a/media/gpu/v4l2/v4l2_video_decoder.cc b/media/gpu/v4l2/v4l2_video_decoder.cc index 8877fed..e5175af 100644 --- a/media/gpu/v4l2/v4l2_video_decoder.cc +++ b/media/gpu/v4l2/v4l2_video_decoder.cc
@@ -465,34 +465,25 @@ // created by VideoFramePool. DmabufVideoFramePool* pool = client_->GetVideoFramePool(); if (pool) { - // TODO(andrescj): the call to PickDecoderOutputFormat() should have already - // initialized the frame pool, so this call to Initialize() is redundant. - // However, we still have to get the GpuBufferLayout to find out the - // modifier that we need to give to the driver. We should add a - // GetGpuBufferLayout() method to DmabufVideoFramePool to query that without - // having to re-initialize the pool. - CroStatus::Or<GpuBufferLayout> status_or_layout = pool->Initialize( - fourcc, adjusted_size, visible_rect, - aspect_ratio_.GetNaturalSize(visible_rect), num_output_frames_, - /*use_protected=*/false); - if (!status_or_layout.has_value()) { - VLOGF(1) << "Failed to setup format to VFPool"; - return std::move(status_or_layout).error().code(); - } - const GpuBufferLayout layout = std::move(status_or_layout).value(); - if (layout.size() != adjusted_size) { - VLOGF(1) << "The size adjusted by VFPool is different from one " - << "adjusted by a video driver. fourcc: " << fourcc.ToString() - << ", (video driver v.s. VFPool) " << adjusted_size.ToString() - << " != " << layout.size().ToString(); + absl::optional<GpuBufferLayout> layout = pool->GetGpuBufferLayout(); + if (!layout.has_value()) { + VLOGF(1) << "Failed to get format from VFPool"; return CroStatus::Codes::kFailedToChangeResolution; } - VLOGF(1) << "buffer modifier: " << std::hex << layout.modifier(); - if (layout.modifier() && - layout.modifier() != gfx::NativePixmapHandle::kNoModifier) { + if (layout->size() != adjusted_size) { + VLOGF(1) << "The size adjusted by VFPool is different from one " + << "adjusted by a video driver. fourcc: " << fourcc.ToString() + << ", (video driver v.s. VFPool) " << adjusted_size.ToString() + << " != " << layout->size().ToString(); + return CroStatus::Codes::kFailedToChangeResolution; + } + + VLOGF(1) << "buffer modifier: " << std::hex << layout->modifier(); + if (layout->modifier() && + layout->modifier() != gfx::NativePixmapHandle::kNoModifier) { absl::optional<struct v4l2_format> modifier_format = - output_queue_->SetModifierFormat(layout.modifier(), picked_size); + output_queue_->SetModifierFormat(layout->modifier(), picked_size); if (!modifier_format) return CroStatus::Codes::kFailedToChangeResolution;
diff --git a/media/gpu/vaapi/vaapi_unittest.cc b/media/gpu/vaapi/vaapi_unittest.cc index 558f5108..2a89811f 100644 --- a/media/gpu/vaapi/vaapi_unittest.cc +++ b/media/gpu/vaapi/vaapi_unittest.cc
@@ -122,14 +122,6 @@ : absl::nullopt; } -std::unique_ptr<base::test::ScopedFeatureList> CreateScopedFeatureList() { - auto scoped_feature_list = std::make_unique<base::test::ScopedFeatureList>(); - scoped_feature_list->InitWithFeatures( - /*enabled_features=*/{media::kVaapiAV1Decoder}, - /*disabled_features=*/{}); - return scoped_feature_list; -} - unsigned int ToVaRTFormat(uint32_t va_fourcc) { switch (va_fourcc) { case VA_FOURCC_I420: @@ -233,11 +225,8 @@ class VaapiTest : public testing::Test { public: - VaapiTest() : scoped_feature_list_(CreateScopedFeatureList()) {} + VaapiTest() = default; ~VaapiTest() override = default; - - private: - std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_; }; std::map<VAProfile, std::vector<VAEntrypoint>> ParseVainfo( @@ -931,28 +920,21 @@ int main(int argc, char** argv) { base::TestSuite test_suite(argc, argv); - { - // Enables/Disables features during PreSandboxInitialization(). We have to - // destruct ScopedFeatureList after it because base::TestSuite::Run() - // creates a ScopedFeatureList and multiple concurrent ScopedFeatureLists - // are not allowed. - auto scoped_feature_list = media::CreateScopedFeatureList(); #if defined(USE_OZONE) && BUILDFLAG(IS_LINUX) - // Initialize Ozone so that the VADisplayState can decide if we're running - // on top of a platform that can deal with VA-API buffers. - // TODO(b/230370976): we may no longer need to initialize Ozone since we - // don't use it for buffer allocation. - ui::OzonePlatform::InitParams params; - params.single_process = true; - ui::OzonePlatform::InitializeForUI(params); - ui::OzonePlatform::InitializeForGPU(params); + // Initialize Ozone so that the VADisplayState can decide if we're running + // on top of a platform that can deal with VA-API buffers. + // TODO(b/230370976): we may no longer need to initialize Ozone since we + // don't use it for buffer allocation. + ui::OzonePlatform::InitParams params; + params.single_process = true; + ui::OzonePlatform::InitializeForUI(params); + ui::OzonePlatform::InitializeForGPU(params); #endif - // PreSandboxInitialization() loads and opens the driver, queries its - // capabilities and fills in the VASupportedProfiles. - media::VaapiWrapper::PreSandboxInitialization(); - } + // PreSandboxInitialization() loads and opens the driver, queries its + // capabilities and fills in the VASupportedProfiles. + media::VaapiWrapper::PreSandboxInitialization(); return base::LaunchUnitTests( argc, argv,
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc index cc1c86f..9051c726 100644 --- a/media/gpu/vaapi/vaapi_wrapper.cc +++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -629,7 +629,7 @@ bool IsBlockedDriver(VaapiWrapper::CodecMode mode, VAProfile va_profile) { if (!IsModeEncoding(mode)) { return va_profile == VAProfileAV1Profile0 && - !base::FeatureList::IsEnabled(kVaapiAV1Decoder); + !base::FeatureList::IsEnabled(kChromeOSHWAV1Decoder); } // TODO(posciak): Remove once VP8 encoding is to be enabled by default.
diff --git a/media/video/openh264_video_encoder.h b/media/video/openh264_video_encoder.h index 09f4922..9d70cc31 100644 --- a/media/video/openh264_video_encoder.h +++ b/media/video/openh264_video_encoder.h
@@ -12,7 +12,7 @@ #include "media/base/video_encoder.h" #include "media/base/video_frame_pool.h" #include "media/formats/mp4/h264_annex_b_to_avc_bitstream_converter.h" -#include "third_party/openh264/src/codec/api/svc/codec_api.h" +#include "third_party/openh264/src/codec/api/wels/codec_api.h" #include "ui/gfx/geometry/size.h" namespace media {
diff --git a/net/BUILD.gn b/net/BUILD.gn index de630fff..1b1e66cb 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1257,8 +1257,6 @@ "base/net_errors_win.cc", "base/network_change_notifier_win.cc", "base/network_change_notifier_win.h", - "base/network_cost_change_notifier_win.cc", - "base/network_cost_change_notifier_win.h", "base/network_interfaces_win.cc", "base/network_interfaces_win.h", "base/platform_mime_util_win.cc", @@ -2174,8 +2172,6 @@ "test/ssl_test_util.cc", "test/ssl_test_util.h", "test/test_certificate_data.h", - "test/test_connection_cost_observer.cc", - "test/test_connection_cost_observer.h", "test/test_data_directory.cc", "test/test_data_directory.h", "test/test_doh_server.cc", @@ -2195,13 +2191,6 @@ "url_request/url_request_test_util.h", ] - if (is_win) { - sources += [ - "test/win/fake_network_cost_manager.cc", - "test/win/fake_network_cost_manager.h", - ] - } - if (is_mac) { sources += [ "test/keychain_test_util_mac.cc", @@ -4439,7 +4428,6 @@ if (is_win) { sources += [ "base/network_change_notifier_win_unittest.cc", - "base/network_cost_change_notifier_win_unittest.cc", "base/network_interfaces_win_unittest.cc", "cert/cert_verify_proc_win_unittest.cc", "http/http_auth_sspi_win_unittest.cc",
diff --git a/net/base/connection_endpoint_metadata.cc b/net/base/connection_endpoint_metadata.cc index 10b1968..e9a19473 100644 --- a/net/base/connection_endpoint_metadata.cc +++ b/net/base/connection_endpoint_metadata.cc
@@ -21,6 +21,15 @@ } // namespace ConnectionEndpointMetadata::ConnectionEndpointMetadata() = default; + +ConnectionEndpointMetadata::ConnectionEndpointMetadata( + std::vector<std::string> supported_protocol_alpns, + EchConfigList ech_config_list, + std::string target_name) + : supported_protocol_alpns(std::move(supported_protocol_alpns)), + ech_config_list(std::move(ech_config_list)), + target_name(std::move(target_name)) {} + ConnectionEndpointMetadata::~ConnectionEndpointMetadata() = default; ConnectionEndpointMetadata::ConnectionEndpointMetadata( const ConnectionEndpointMetadata&) = default;
diff --git a/net/base/connection_endpoint_metadata.h b/net/base/connection_endpoint_metadata.h index 8d81b5a..eeeac225 100644 --- a/net/base/connection_endpoint_metadata.h +++ b/net/base/connection_endpoint_metadata.h
@@ -25,6 +25,9 @@ using EchConfigList = std::vector<uint8_t>; ConnectionEndpointMetadata(); + ConnectionEndpointMetadata(std::vector<std::string> supported_protocol_alpns, + EchConfigList ech_config_list, + std::string target_name); ~ConnectionEndpointMetadata(); ConnectionEndpointMetadata(const ConnectionEndpointMetadata&);
diff --git a/net/base/load_flags_list.h b/net/base/load_flags_list.h index 38062cf..f936d95 100644 --- a/net/base/load_flags_list.h +++ b/net/base/load_flags_list.h
@@ -21,8 +21,9 @@ // All other caches are used as normal. LOAD_FLAG(VALIDATE_CACHE, 1 << 0) -// This is "shift-reload", meaning a "pragma: no-cache" end-to-end fetch. All -// other caches are used as normal. +// This is "shift-reload", meaning a "pragma: no-cache" end-to-end fetch. +// The response is not read from the HTTP cache but is written to the cache, +// unlike in `DISABLE_CACHE`. All other caches are used as normal. LOAD_FLAG(BYPASS_CACHE, 1 << 1) // This is a back/forward style navigation where the cached content should @@ -33,8 +34,9 @@ // resource from the cache (or some equivalent local store). LOAD_FLAG(ONLY_FROM_CACHE, 1 << 3) -// This is a navigation that will not use the cache at all. It does not -// impact the HTTP request headers. All other caches are used as normal. +// This is a request whose response will not be read or written to the HTTP +// cache. It does not impact the cache-related HTTP request headers. All other +// caches are used as normal. LOAD_FLAG(DISABLE_CACHE, 1 << 4) // If present, causes dependent network fetches (AIA, CRLs, OCSP) to be
diff --git a/net/base/network_change_notifier.cc b/net/base/network_change_notifier.cc index cc8d2bcb..233bb3d 100644 --- a/net/base/network_change_notifier.cc +++ b/net/base/network_change_notifier.cc
@@ -248,6 +248,11 @@ const scoped_refptr< base::ObserverListThreadSafe<DefaultNetworkActiveObserver>> default_network_active_observer_list_; + + // Indicates if connection cost observer was added before + // network_change_notifier was initialized, if so ConnectionCostObserverAdded + // is invoked from constructor. + std::atomic_bool connection_cost_observers_added_ = false; }; class NetworkChangeNotifier::SystemDnsConfigObserver @@ -682,8 +687,13 @@ void NetworkChangeNotifier::AddConnectionCostObserver( ConnectionCostObserver* observer) { DCHECK(!observer->observer_list_); + GetObserverList().connection_cost_observers_added_ = true; observer->observer_list_ = GetObserverList().connection_cost_observer_list_; observer->observer_list_->AddObserver(observer); + base::AutoLock auto_lock(NetworkChangeNotifierCreationLock()); + if (g_network_change_notifier) { + g_network_change_notifier->ConnectionCostObserverAdded(); + } } void NetworkChangeNotifier::AddDefaultNetworkActiveObserver( @@ -842,6 +852,9 @@ g_network_change_notifier = this; system_dns_config_notifier_->AddObserver(system_dns_config_observer_.get()); + if (GetObserverList().connection_cost_observers_added_) { + g_network_change_notifier->ConnectionCostObserverAdded(); + } } if (!omit_observers_in_constructor_for_testing) { network_change_calculator_ =
diff --git a/net/base/network_change_notifier.h b/net/base/network_change_notifier.h index c79374c..93108a8 100644 --- a/net/base/network_change_notifier.h +++ b/net/base/network_change_notifier.h
@@ -670,6 +670,13 @@ // as early as possible in the destructor to prevent races. void ClearGlobalPointer(); + // Called whenever a new ConnectionCostObserver is added. This method is + // needed so that the implementation class can be notified and + // potentially take action when an observer gets added. Since the act of + // adding an observer and the observer list itself are both static, the + // implementation class has no direct capability to watch for changes. + virtual void ConnectionCostObserverAdded() {} + // Listening for notifications of this type is expensive as they happen // frequently. For this reason, we report {de}registration to the // implementation class, so that it can decide to only listen to this type of
diff --git a/net/base/network_change_notifier_unittest.cc b/net/base/network_change_notifier_unittest.cc index 89013ac4..3f3fbd6 100644 --- a/net/base/network_change_notifier_unittest.cc +++ b/net/base/network_change_notifier_unittest.cc
@@ -8,7 +8,6 @@ #include "build/build_config.h" #include "net/base/mock_network_change_notifier.h" #include "net/base/network_interfaces.h" -#include "net/test/test_connection_cost_observer.h" #include "net/test/test_with_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" @@ -227,17 +226,37 @@ NetworkChangeNotifier::RemoveDNSObserver(&observer); } +class TestConnectionCostObserver + : public NetworkChangeNotifier::ConnectionCostObserver { + public: + void OnConnectionCostChanged( + NetworkChangeNotifier::ConnectionCost cost) override { + cost_changed_inputs_.push_back(cost); + ++cost_changed_calls_; + } + + int cost_changed_calls() const { return cost_changed_calls_; } + std::vector<NetworkChangeNotifier::ConnectionCost> cost_changed_inputs() + const { + return cost_changed_inputs_; + } + + private: + int cost_changed_calls_ = 0; + std::vector<NetworkChangeNotifier::ConnectionCost> cost_changed_inputs_; +}; + TEST_F(NetworkChangeNotifierMockedTest, TriggerConnectionCostChange) { TestConnectionCostObserver observer; NetworkChangeNotifier::AddConnectionCostObserver(&observer); - ASSERT_EQ(0u, observer.cost_changed_calls()); + ASSERT_EQ(0, observer.cost_changed_calls()); NetworkChangeNotifier::NotifyObserversOfConnectionCostChangeForTests( NetworkChangeNotifier::CONNECTION_COST_METERED); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1u, observer.cost_changed_calls()); + EXPECT_EQ(1, observer.cost_changed_calls()); EXPECT_EQ(NetworkChangeNotifier::CONNECTION_COST_METERED, observer.cost_changed_inputs()[0]); @@ -246,7 +265,7 @@ NetworkChangeNotifier::CONNECTION_COST_UNMETERED); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1u, observer.cost_changed_calls()); + EXPECT_EQ(1, observer.cost_changed_calls()); } TEST_F(NetworkChangeNotifierMockedTest, ConnectionCostDefaultsToCellular) {
diff --git a/net/base/network_change_notifier_win.cc b/net/base/network_change_notifier_win.cc index e12985b..234a662c 100644 --- a/net/base/network_change_notifier_win.cc +++ b/net/base/network_change_notifier_win.cc
@@ -21,7 +21,7 @@ #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" -#include "net/base/network_cost_change_notifier_win.h" +#include "base/win/windows_version.h" #include "net/base/winsock_init.h" #include "net/base/winsock_util.h" @@ -32,8 +32,88 @@ // Time between NotifyAddrChange retries, on failure. const int kWatchForAddressChangeRetryIntervalMs = 500; +HRESULT GetConnectionPoints(IUnknown* manager, + REFIID IIDSyncInterface, + IConnectionPoint** connection_point_raw) { + *connection_point_raw = nullptr; + Microsoft::WRL::ComPtr<IConnectionPointContainer> connection_point_container; + HRESULT hr = + manager->QueryInterface(IID_PPV_ARGS(&connection_point_container)); + if (FAILED(hr)) + return hr; + + // Find the interface + Microsoft::WRL::ComPtr<IConnectionPoint> connection_point; + hr = connection_point_container->FindConnectionPoint(IIDSyncInterface, + &connection_point); + if (FAILED(hr)) + return hr; + + *connection_point_raw = connection_point.Get(); + (*connection_point_raw)->AddRef(); + + return hr; +} + } // namespace +// This class is used as an event sink to register for notifications from the +// INetworkCostManagerEvents interface. In particular, we are focused on getting +// notified when the Connection Cost changes. This is only supported on Win10+. +class NetworkCostManagerEventSink + : public Microsoft::WRL::RuntimeClass< + Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, + INetworkCostManagerEvents> { + public: + using CostChangedCallback = base::RepeatingCallback<void()>; + + NetworkCostManagerEventSink(INetworkCostManager* cost_manager, + const CostChangedCallback& callback) + : network_cost_manager_(cost_manager), cost_changed_callback_(callback) {} + ~NetworkCostManagerEventSink() override = default; + + // INetworkCostManagerEvents members + IFACEMETHODIMP CostChanged(_In_ DWORD cost, + _In_opt_ NLM_SOCKADDR* /*pSockAddr*/) override { + cost_changed_callback_.Run(); + return S_OK; + } + + IFACEMETHODIMP DataPlanStatusChanged( + _In_opt_ NLM_SOCKADDR* /*pSockAddr*/) override { + return S_OK; + } + + HRESULT RegisterForNotifications() { + Microsoft::WRL::ComPtr<IUnknown> unknown; + HRESULT hr = QueryInterface(IID_PPV_ARGS(&unknown)); + if (hr != S_OK) + return hr; + + hr = GetConnectionPoints(network_cost_manager_.Get(), + IID_INetworkCostManagerEvents, &connection_point_); + if (hr != S_OK) + return hr; + + hr = connection_point_->Advise(unknown.Get(), &cookie_); + return hr; + } + + void UnRegisterForNotifications() { + if (connection_point_) { + connection_point_->Unadvise(cookie_); + connection_point_ = nullptr; + cookie_ = 0; + } + } + + private: + Microsoft::WRL::ComPtr<INetworkCostManager> network_cost_manager_; + Microsoft::WRL::ComPtr<IConnectionPoint> connection_point_; + DWORD cookie_ = 0; + CostChangedCallback cost_changed_callback_; +}; + NetworkChangeNotifierWin::NetworkChangeNotifierWin() : NetworkChangeNotifier(NetworkChangeCalculatorParamsWin()), blocking_task_runner_( @@ -45,10 +125,6 @@ base::SequencedTaskRunnerHandle::Get()) { memset(&addr_overlapped_, 0, sizeof addr_overlapped_); addr_overlapped_.hEvent = WSACreateEvent(); - - cost_change_notifier_ = NetworkCostChangeNotifierWin::CreateInstance( - base::BindRepeating(&NetworkChangeNotifierWin::OnCostChanged, - weak_factory_.GetWeakPtr())); } NetworkChangeNotifierWin::~NetworkChangeNotifierWin() { @@ -59,6 +135,11 @@ addr_watcher_.StopWatching(); } WSACloseEvent(addr_overlapped_.hEvent); + + if (network_cost_manager_event_sink_) { + network_cost_manager_event_sink_->UnRegisterForNotifications(); + network_cost_manager_event_sink_ = nullptr; + } } // static @@ -200,23 +281,115 @@ NetworkChangeNotifier::ConnectionCost NetworkChangeNotifierWin::GetCurrentConnectionCost() { - if (last_computed_connection_cost_ == - ConnectionCost::CONNECTION_COST_UNKNOWN) { - // Use the default logic when the Windows OS APIs do not have a cost for the - // current connection. + InitializeConnectionCost(); + + // Pre-Win10 use the default logic. + if (base::win::GetVersion() < base::win::Version::WIN10) return NetworkChangeNotifier::GetCurrentConnectionCost(); - } + + // If we don't have the event sink we aren't registered for automatic updates. + // In that case, we need to update the value at the time it is requested. + if (!network_cost_manager_event_sink_) + UpdateConnectionCostFromCostManager(); + return last_computed_connection_cost_; } -void NetworkChangeNotifierWin::OnCostChanged( - NetworkChangeNotifier::ConnectionCost new_cost) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +bool NetworkChangeNotifierWin::InitializeConnectionCostOnce() { + // Pre-Win10 this information cannot be retrieved and cached. + if (base::win::GetVersion() < base::win::Version::WIN10) { + SetCurrentConnectionCost(CONNECTION_COST_UNKNOWN); + return true; + } + HRESULT hr = + ::CoCreateInstance(CLSID_NetworkListManager, nullptr, CLSCTX_ALL, + IID_INetworkCostManager, &network_cost_manager_); + if (FAILED(hr)) { + SetCurrentConnectionCost(CONNECTION_COST_UNKNOWN); + return true; + } + + UpdateConnectionCostFromCostManager(); + + return true; +} + +void NetworkChangeNotifierWin::InitializeConnectionCost() { + static bool g_connection_cost_initialized = InitializeConnectionCostOnce(); + DCHECK(g_connection_cost_initialized); +} + +HRESULT NetworkChangeNotifierWin::UpdateConnectionCostFromCostManager() { + if (!network_cost_manager_) + return E_ABORT; + + DWORD cost = NLM_CONNECTION_COST_UNKNOWN; + HRESULT hr = network_cost_manager_->GetCost(&cost, nullptr); + if (FAILED(hr)) { + SetCurrentConnectionCost(CONNECTION_COST_UNKNOWN); + } else { + SetCurrentConnectionCost( + ConnectionCostFromNlmCost((NLM_CONNECTION_COST)cost)); + } + return hr; +} + +// static +NetworkChangeNotifier::ConnectionCost +NetworkChangeNotifierWin::ConnectionCostFromNlmCost(NLM_CONNECTION_COST cost) { + if (cost == NLM_CONNECTION_COST_UNKNOWN) + return CONNECTION_COST_UNKNOWN; + else if ((cost & NLM_CONNECTION_COST_UNRESTRICTED) != 0) + return CONNECTION_COST_UNMETERED; + else + return CONNECTION_COST_METERED; +} + +void NetworkChangeNotifierWin::SetCurrentConnectionCost( + ConnectionCost connection_cost) { + last_computed_connection_cost_ = connection_cost; +} + +void NetworkChangeNotifierWin::OnCostChanged() { + ConnectionCost old_cost = last_computed_connection_cost_; + // It is possible to get multiple notifications in a short period of time. + // Rather than worrying about whether this notification represents the latest, + // just get the current value from the CostManager so we know that we're + // actually getting the correct value. + UpdateConnectionCostFromCostManager(); // Only notify if there's actually a change. - if (last_computed_connection_cost_ != new_cost) { - last_computed_connection_cost_ = new_cost; + if (old_cost != GetCurrentConnectionCost()) NotifyObserversOfConnectionCostChange(); +} + +void NetworkChangeNotifierWin::ConnectionCostObserverAdded() { + sequence_runner_for_registration_->PostTask( + FROM_HERE, + base::BindOnce(&NetworkChangeNotifierWin::OnConnectionCostObserverAdded, + weak_factory_.GetWeakPtr())); +} + +void NetworkChangeNotifierWin::OnConnectionCostObserverAdded() { + DCHECK(sequence_runner_for_registration_->RunsTasksInCurrentSequence()); + InitializeConnectionCost(); + + // No need to register if we don't have a cost manager or if we're already + // registered. + if (!network_cost_manager_ || network_cost_manager_event_sink_) + return; + + network_cost_manager_event_sink_ = + Microsoft::WRL::Make<net::NetworkCostManagerEventSink>( + network_cost_manager_.Get(), + base::BindRepeating(&NetworkChangeNotifierWin::OnCostChanged, + weak_factory_.GetWeakPtr())); + HRESULT hr = network_cost_manager_event_sink_->RegisterForNotifications(); + if (hr != S_OK) { + // If registration failed for any reason, just destroy the event sink. The + // observer will remain connected but will not receive any updates. If + // another observer gets added later, we can re-attempt registration. + network_cost_manager_event_sink_ = nullptr; } } @@ -318,8 +491,8 @@ offline_polls_++; // If we continue to appear offline, delay sending out the notification in // case we appear to go online within 20 seconds. UMA histogram data shows - // we may not detect the transition to online state after 1 second but - // within 20 seconds we generally do. + // we may not detect the transition to online state after 1 second but within + // 20 seconds we generally do. if (last_announced_offline_ && current_offline && offline_polls_ <= 20) { timer_.Start(FROM_HERE, base::Seconds(1), this, &NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChange);
diff --git a/net/base/network_change_notifier_win.h b/net/base/network_change_notifier_win.h index c89af03..0d88afa 100644 --- a/net/base/network_change_notifier_win.h +++ b/net/base/network_change_notifier_win.h
@@ -5,9 +5,13 @@ #ifndef NET_BASE_NETWORK_CHANGE_NOTIFIER_WIN_H_ #define NET_BASE_NETWORK_CHANGE_NOTIFIER_WIN_H_ +#include <netlistmgr.h> +#include <ocidl.h> #include <windows.h> +#include <wrl.h> +#include <wrl/client.h> -#include <atomic> +#include <memory> #include "base/callback.h" #include "base/compiler_specific.h" @@ -15,7 +19,6 @@ #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" #include "base/thread_annotations.h" -#include "base/threading/sequence_bound.h" #include "base/timer/timer.h" #include "base/win/object_watcher.h" #include "net/base/net_export.h" @@ -27,7 +30,7 @@ namespace net { -class NetworkCostChangeNotifierWin; +class NetworkCostManagerEventSink; // NetworkChangeNotifierWin uses a SequenceChecker, as all its internal // notification code must be called on the sequence it is created and destroyed @@ -97,7 +100,25 @@ static NetworkChangeCalculatorParams NetworkChangeCalculatorParamsWin(); - void OnCostChanged(NetworkChangeNotifier::ConnectionCost new_cost); + // Gets the current network connection cost (if possible) and caches it. + void InitializeConnectionCost(); + // Does the work of initializing for thread safety. + bool InitializeConnectionCostOnce(); + // Retrieves the current network connection cost from the OS's Cost Manager. + HRESULT UpdateConnectionCostFromCostManager(); + // Converts the OS enum values to the enum values used in our code. + static ConnectionCost ConnectionCostFromNlmCost(NLM_CONNECTION_COST cost); + // Sets the cached network connection cost value. + void SetCurrentConnectionCost(ConnectionCost connection_cost); + // Callback method for the notification event sink. + void OnCostChanged(); + // Tells this class that an observer was added and therefore this class needs + // to register for notifications. + void ConnectionCostObserverAdded() override; + // Since ConnectionCostObserverAdded() can be called on any thread and we + // don't want to do a bunch of work on an arbitrary thread, this method used + // to post task to do the work. + void OnConnectionCostObserverAdded(); // All member variables may only be accessed on the sequence |this| was // created on. @@ -120,13 +141,8 @@ mutable base::Lock last_computed_connection_type_lock_; ConnectionType last_computed_connection_type_; - std::atomic<NetworkChangeNotifier::ConnectionCost> - last_computed_connection_cost_ = - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNKNOWN; - - // Provides the cost of the current connection. Uses the Windows OS APIs to - // monitor and determine cost. - base::SequenceBound<NetworkCostChangeNotifierWin> cost_change_notifier_; + std::atomic<ConnectionCost> last_computed_connection_cost_ = + ConnectionCost::CONNECTION_COST_UNKNOWN; // Result of IsOffline() when NotifyObserversOfConnectionTypeChange() // was last called. @@ -134,6 +150,10 @@ // Number of times polled to check if still offline. int offline_polls_; + Microsoft::WRL::ComPtr<INetworkCostManager> network_cost_manager_; + Microsoft::WRL::ComPtr<NetworkCostManagerEventSink> + network_cost_manager_event_sink_; + // Used to ensure that all registration actions are properly sequenced on the // same thread regardless of which thread was used to call into the // NetworkChangeNotifier API.
diff --git a/net/base/network_change_notifier_win_unittest.cc b/net/base/network_change_notifier_win_unittest.cc index cbb1b24..9abe200 100644 --- a/net/base/network_change_notifier_win_unittest.cc +++ b/net/base/network_change_notifier_win_unittest.cc
@@ -4,22 +4,16 @@ #include "net/base/network_change_notifier_win.h" -#include <memory> #include <utility> -#include <vector> #include "base/bind.h" #include "base/run_loop.h" -#include "base/sequence_checker.h" #include "base/task/single_thread_task_runner.h" -#include "base/test/scoped_os_info_override_win.h" #include "base/threading/thread_task_runner_handle.h" #include "base/win/windows_version.h" #include "net/base/network_change_notifier.h" #include "net/base/network_change_notifier_factory.h" -#include "net/test/test_connection_cost_observer.h" #include "net/test/test_with_task_environment.h" -#include "net/test/win/fake_network_cost_manager.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -37,6 +31,7 @@ TestNetworkChangeNotifierWin() { last_computed_connection_type_ = NetworkChangeNotifier::CONNECTION_UNKNOWN; last_announced_offline_ = false; + last_computed_connection_cost_ = ConnectionCost::CONNECTION_COST_UNKNOWN; sequence_runner_for_registration_ = base::SequencedTaskRunnerHandle::Get(); } @@ -60,18 +55,13 @@ // From NetworkChangeNotifierWin. MOCK_METHOD0(WatchForAddressChangeInternal, bool()); - - // Allow tests to compare results with the default implementation that does - // not depend on the INetworkCostManager Windows OS API. The default - // implementation is used as a fall back when INetworkCostManager fails. - ConnectionCost GetCurrentConnectionCostFromDefaultImplementation() { - return NetworkChangeNotifier::GetCurrentConnectionCost(); - } }; class TestIPAddressObserver : public NetworkChangeNotifier::IPAddressObserver { public: - TestIPAddressObserver() { NetworkChangeNotifier::AddIPAddressObserver(this); } + TestIPAddressObserver() { + NetworkChangeNotifier::AddIPAddressObserver(this); + } TestIPAddressObserver(const TestIPAddressObserver&) = delete; TestIPAddressObserver& operator=(const TestIPAddressObserver&) = delete; @@ -192,8 +182,7 @@ .Times(1) .WillOnce(Invoke(&run_loop, &base::RunLoop::QuitWhenIdle)); EXPECT_CALL(network_change_notifier_, WatchForAddressChangeInternal()) - .Times(1) - .WillOnce(Return(true)); + .Times(1).WillOnce(Return(true)); run_loop.Run(); @@ -230,19 +219,23 @@ base::RunLoop().RunUntilIdle(); } + bool HasNetworkCostManager() { + return network_change_notifier_.network_cost_manager_.Get() != nullptr; + } + + bool HasNetworkCostManagerEventSink() { + return network_change_notifier_.network_cost_manager_event_sink_.Get() != + nullptr; + } + + NetworkChangeNotifier::ConnectionCost LastComputedConnectionCost() { + return network_change_notifier_.last_computed_connection_cost_; + } + NetworkChangeNotifier::ConnectionCost GetCurrentConnectionCost() { return network_change_notifier_.GetCurrentConnectionCost(); } - NetworkChangeNotifier::ConnectionCost - GetCurrentConnectionCostFromDefaultImplementation() { - return network_change_notifier_ - .GetCurrentConnectionCostFromDefaultImplementation(); - } - - protected: - FakeNetworkCostManagerEnvironment fake_network_cost_manager_environment_; - private: // Note that the order of declaration here is important. @@ -294,102 +287,58 @@ RetryAndSucceed(); } -TEST_F(NetworkChangeNotifierWinTest, GetCurrentCost) { - if (base::win::GetVersion() < base::win::Version::WIN10) - return; - - fake_network_cost_manager_environment_.SetCost( - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNMETERED); - - // Wait for NetworkCostChangeNotifierWin to finish initializing. - RunUntilIdle(); - - EXPECT_EQ(GetCurrentConnectionCost(), - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNMETERED); - - fake_network_cost_manager_environment_.SetCost( - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_METERED); - - // Wait for NetworkCostChangeNotifierWin to handle the cost changed event. - RunUntilIdle(); - - EXPECT_EQ(GetCurrentConnectionCost(), - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_METERED); -} - -TEST_F(NetworkChangeNotifierWinTest, CostChangeObserver) { - if (base::win::GetVersion() < base::win::Version::WIN10) - return; - - fake_network_cost_manager_environment_.SetCost( - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNMETERED); - - // Wait for NetworkCostChangeNotifierWin to finish initializing. - RunUntilIdle(); - - TestConnectionCostObserver cost_observer; - NetworkChangeNotifier::AddConnectionCostObserver(&cost_observer); - - fake_network_cost_manager_environment_.SetCost( - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_METERED); - - cost_observer.WaitForConnectionCostChanged(); - - ASSERT_EQ(cost_observer.cost_changed_calls(), 1u); - EXPECT_EQ(cost_observer.last_cost_changed_input(), - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_METERED); - - NetworkChangeNotifier::RemoveConnectionCostObserver(&cost_observer); -} - -// Uses the fake implementation of INetworkCostManager to simulate GetCost() -// returning an error HRESULT. -class NetworkChangeNotifierWinCostErrorTest - : public NetworkChangeNotifierWinTest { - void SetUp() override { - if (base::win::GetVersion() < base::win::Version::WIN10) { - GTEST_SKIP(); - } - - fake_network_cost_manager_environment_.SimulateError( - NetworkCostManagerStatus::kErrorGetCostFailed); - - NetworkChangeNotifierWinTest::SetUp(); - } -}; - -TEST_F(NetworkChangeNotifierWinCostErrorTest, CostError) { - // Wait for NetworkCostChangeNotifierWin to finish initializing, which should - // fail with an error. - RunUntilIdle(); - - // NetworkChangeNotifierWin must use the default implementation when - // NetworkCostChangeNotifierWin returns an unknown cost. - EXPECT_EQ(GetCurrentConnectionCost(), - GetCurrentConnectionCostFromDefaultImplementation()); -} - -// Override the Windows OS version to simulate running on an OS that does not -// support INetworkCostManager. -class NetworkChangeNotifierWinCostUnsupportedOsTest - : public NetworkChangeNotifierWinTest { +class TestConnectionCostObserver + : public NetworkChangeNotifier::ConnectionCostObserver { public: - NetworkChangeNotifierWinCostUnsupportedOsTest() - : os_override_(base::test::ScopedOSInfoOverride::Type::kWin81Pro) {} + TestConnectionCostObserver() {} - protected: - base::test::ScopedOSInfoOverride os_override_; + TestConnectionCostObserver(const TestConnectionCostObserver&) = delete; + TestConnectionCostObserver& operator=(const TestConnectionCostObserver&) = + delete; + + ~TestConnectionCostObserver() override { + NetworkChangeNotifier::RemoveConnectionCostObserver(this); + } + + void OnConnectionCostChanged(NetworkChangeNotifier::ConnectionCost) override { + } + + void Register() { NetworkChangeNotifier::AddConnectionCostObserver(this); } }; -TEST_F(NetworkChangeNotifierWinCostUnsupportedOsTest, CostWithUnsupportedOS) { - // Wait for NetworkCostChangeNotifierWin to finish initializing, which should - // initialize with an unknown cost on an unsupported OS. - RunUntilIdle(); +TEST_F(NetworkChangeNotifierWinTest, NetworkCostManagerIntegration) { + // NetworkCostManager integration only exist on Win10+. + if (base::win::GetVersion() < base::win::Version::WIN10) + return; - // NetworkChangeNotifierWin must use the default implementation when - // NetworkCostChangeNotifierWin returns an unknown cost. - EXPECT_EQ(GetCurrentConnectionCost(), - GetCurrentConnectionCostFromDefaultImplementation()); + // Upon creation, none of the NetworkCostManager integration should be + // initialized yet. + ASSERT_FALSE(HasNetworkCostManager()); + ASSERT_FALSE(HasNetworkCostManagerEventSink()); + ASSERT_EQ(NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNKNOWN, + LastComputedConnectionCost()); + + // Asking for the current connection cost should initialize the + // NetworkCostManager integration, but not the event sink. + // Note that the actual ConnectionCost value return is irrelevant beyond the + // fact that it shouldn't be UNKNOWN anymore if the integration is initialized + // properly. + NetworkChangeNotifier::ConnectionCost current_connection_cost = + GetCurrentConnectionCost(); + EXPECT_NE(NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNKNOWN, + current_connection_cost); + EXPECT_EQ(current_connection_cost, LastComputedConnectionCost()); + EXPECT_TRUE(HasNetworkCostManager()); + EXPECT_FALSE(HasNetworkCostManagerEventSink()); + + // Adding a ConnectionCostObserver should initialize the event sink. If the + // subsequent registration for updates fails, the event sink will get + // destroyed. + TestConnectionCostObserver test_connection_cost_observer; + test_connection_cost_observer.Register(); + // The actual registration happens on a callback, so need to run until idle. + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(HasNetworkCostManagerEventSink()); } } // namespace net
diff --git a/net/base/network_cost_change_notifier_win.cc b/net/base/network_cost_change_notifier_win.cc deleted file mode 100644 index abc56a41..0000000 --- a/net/base/network_cost_change_notifier_win.cc +++ /dev/null
@@ -1,271 +0,0 @@ -// 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 "net/base/network_cost_change_notifier_win.h" - -#include <wrl.h> -#include <wrl/client.h> - -#include "base/check.h" -#include "base/no_destructor.h" -#include "base/task/bind_post_task.h" -#include "base/task/thread_pool.h" -#include "base/threading/scoped_thread_priority.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/win/com_init_util.h" -#include "base/win/windows_version.h" - -using Microsoft::WRL::ComPtr; - -namespace net { - -namespace { - -NetworkChangeNotifier::ConnectionCost ConnectionCostFromNlmConnectionCost( - DWORD connection_cost_flags) { - if (connection_cost_flags == NLM_CONNECTION_COST_UNKNOWN) - return NetworkChangeNotifier::CONNECTION_COST_UNKNOWN; - else if ((connection_cost_flags & NLM_CONNECTION_COST_UNRESTRICTED) != 0) - return NetworkChangeNotifier::CONNECTION_COST_UNMETERED; - else - return NetworkChangeNotifier::CONNECTION_COST_METERED; -} - -NetworkCostChangeNotifierWin::CoCreateInstanceCallback& -GetCoCreateInstanceOverride() { - static base::NoDestructor< - NetworkCostChangeNotifierWin::CoCreateInstanceCallback> - callback_for_testing; - return *callback_for_testing; -} - -} // namespace - -// This class is used as an event sink to register for notifications from the -// INetworkCostManagerEvents interface. In particular, we are focused on getting -// notified when the connection cost changes. This is only supported on Win10+. -class NetworkCostManagerEventSinkWin final - : public Microsoft::WRL::RuntimeClass< - Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, - INetworkCostManagerEvents> { - public: - static HRESULT CreateInstance( - INetworkCostManager* network_cost_manager, - base::RepeatingClosure cost_changed_callback, - ComPtr<NetworkCostManagerEventSinkWin>* result) { - ComPtr<NetworkCostManagerEventSinkWin> instance = - Microsoft::WRL::Make<net::NetworkCostManagerEventSinkWin>( - cost_changed_callback); - HRESULT hr = instance->RegisterForNotifications(network_cost_manager); - if (hr != S_OK) { - return hr; - } - - *result = instance; - return S_OK; - } - - void UnRegisterForNotifications() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - if (event_sink_connection_point_) { - event_sink_connection_point_->Unadvise(event_sink_connection_cookie_); - event_sink_connection_point_.Reset(); - } - } - - // Implement the INetworkCostManagerEvents interface. - HRESULT __stdcall CostChanged(DWORD /*cost*/, - NLM_SOCKADDR* /*socket_address*/) final { - // It is possible to get multiple notifications in a short period of time. - // Rather than worrying about whether this notification represents the - // latest, just notify the owner who can get the current value from the - // INetworkCostManager so we know that we're actually getting the correct - // value. - cost_changed_callback_.Run(); - return S_OK; - } - - HRESULT __stdcall DataPlanStatusChanged( - NLM_SOCKADDR* /*socket_address*/) final { - return S_OK; - } - - NetworkCostManagerEventSinkWin(base::RepeatingClosure cost_changed_callback) - : cost_changed_callback_(cost_changed_callback) {} - - NetworkCostManagerEventSinkWin(const NetworkCostManagerEventSinkWin&) = - delete; - NetworkCostManagerEventSinkWin& operator=( - const NetworkCostManagerEventSinkWin&) = delete; - - private: - ~NetworkCostManagerEventSinkWin() final = default; - - HRESULT RegisterForNotifications(INetworkCostManager* cost_manager) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_GE(base::win::GetVersion(), base::win::Version::WIN10); - - base::win::AssertComInitialized(); - base::win::AssertComApartmentType(base::win::ComApartmentType::STA); - - ComPtr<IUnknown> this_event_sink_unknown; - HRESULT hr = QueryInterface(IID_PPV_ARGS(&this_event_sink_unknown)); - - // `NetworkCostManagerEventSinkWin::QueryInterface` for `IUnknown` must - // succeed since it is implemented by this class. - DCHECK_EQ(hr, S_OK); - - ComPtr<IConnectionPointContainer> connection_point_container; - hr = - cost_manager->QueryInterface(IID_PPV_ARGS(&connection_point_container)); - if (hr != S_OK) { - return hr; - } - - Microsoft::WRL::ComPtr<IConnectionPoint> event_sink_connection_point; - hr = connection_point_container->FindConnectionPoint( - IID_INetworkCostManagerEvents, &event_sink_connection_point); - if (hr != S_OK) { - return hr; - } - - hr = event_sink_connection_point->Advise(this_event_sink_unknown.Get(), - &event_sink_connection_cookie_); - if (hr != S_OK) { - return hr; - } - - DCHECK_EQ(event_sink_connection_point_, nullptr); - event_sink_connection_point_ = event_sink_connection_point; - return S_OK; - } - - base::RepeatingClosure cost_changed_callback_; - - // The following members must be accessed on the sequence from - // `sequence_checker_` - SEQUENCE_CHECKER(sequence_checker_); - DWORD event_sink_connection_cookie_ = 0; - Microsoft::WRL::ComPtr<IConnectionPoint> event_sink_connection_point_; -}; - -// static -base::SequenceBound<NetworkCostChangeNotifierWin> -NetworkCostChangeNotifierWin::CreateInstance( - CostChangedCallback cost_changed_callback) { - scoped_refptr<base::SequencedTaskRunner> com_best_effort_task_runner = - base::ThreadPool::CreateCOMSTATaskRunner( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}); - - return base::SequenceBound<NetworkCostChangeNotifierWin>( - com_best_effort_task_runner, - // Ensure `cost_changed_callback` runs on the sequence of the creator and - // owner of `NetworkCostChangeNotifierWin`. - base::BindPostTask(base::SequencedTaskRunnerHandle::Get(), - cost_changed_callback)); -} - -NetworkCostChangeNotifierWin::NetworkCostChangeNotifierWin( - CostChangedCallback cost_changed_callback) - : cost_changed_callback_(cost_changed_callback) { - StartWatching(); -} - -NetworkCostChangeNotifierWin::~NetworkCostChangeNotifierWin() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - StopWatching(); -} - -void NetworkCostChangeNotifierWin::StartWatching() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - if (base::win::GetComApartmentTypeForThread() == - base::win::ComApartmentType::NONE) { - // TODO(crbug.com/1367360): INetworkCostManager inaccessible in network - // sandbox. Currently, the network sandbox does not allow COM. - return; - } - - base::win::AssertComInitialized(); - base::win::AssertComApartmentType(base::win::ComApartmentType::STA); - - if (base::win::GetVersion() < base::win::Version::WIN10) { - // INetworkCostManager requires Win10 or higher. - return; - } - - SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY(); - - // Create INetworkListManager using CoCreateInstance, but allow tests to - // provide an fake implementation of INetworkListManager through an override. - CoCreateInstanceCallback co_create_instance_callback = - base::BindRepeating(&CoCreateInstance); - if (GetCoCreateInstanceOverride()) { - co_create_instance_callback = GetCoCreateInstanceOverride(); - } - - ComPtr<INetworkCostManager> cost_manager; - HRESULT hr = co_create_instance_callback.Run( - CLSID_NetworkListManager, /*unknown_outer=*/nullptr, CLSCTX_ALL, - IID_INetworkCostManager, &cost_manager); - if (hr != S_OK) { - return; - } - - // Subscribe to cost changed events. - hr = NetworkCostManagerEventSinkWin::CreateInstance( - cost_manager.Get(), - // Cost changed callbacks must run on this sequence to get the new cost - // from `INetworkCostManager`. - base::BindPostTask( - base::SequencedTaskRunnerHandle::Get(), - base::BindRepeating(&NetworkCostChangeNotifierWin::HandleCostChanged, - weak_ptr_factory_.GetWeakPtr())), - &cost_manager_event_sink_); - - if (hr != S_OK) { - return; - } - - // Set the initial cost and inform observers of the initial value. - cost_manager_ = cost_manager; - HandleCostChanged(); -} - -void NetworkCostChangeNotifierWin::StopWatching() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - if (cost_manager_event_sink_) { - cost_manager_event_sink_->UnRegisterForNotifications(); - cost_manager_event_sink_.Reset(); - } - - cost_manager_.Reset(); -} - -void NetworkCostChangeNotifierWin::HandleCostChanged() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - DWORD connection_cost_flags; - HRESULT hr = cost_manager_->GetCost(&connection_cost_flags, - /*destination_ip_address=*/nullptr); - if (hr != S_OK) { - connection_cost_flags = NLM_CONNECTION_COST_UNKNOWN; - } - - NetworkChangeNotifier::ConnectionCost changed_cost = - ConnectionCostFromNlmConnectionCost(connection_cost_flags); - - cost_changed_callback_.Run(changed_cost); -} - -// static -void NetworkCostChangeNotifierWin::OverrideCoCreateInstanceForTesting( - CoCreateInstanceCallback callback_for_testing) { - GetCoCreateInstanceOverride() = callback_for_testing; -} - -} // namespace net
diff --git a/net/base/network_cost_change_notifier_win.h b/net/base/network_cost_change_notifier_win.h deleted file mode 100644 index 7868cd2..0000000 --- a/net/base/network_cost_change_notifier_win.h +++ /dev/null
@@ -1,83 +0,0 @@ -// 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 NET_BASE_NETWORK_COST_CHANGE_NOTIFIER_WIN_H_ -#define NET_BASE_NETWORK_COST_CHANGE_NOTIFIER_WIN_H_ - -#include <netlistmgr.h> -#include <wrl/client.h> - -#include "base/callback_forward.h" -#include "base/memory/weak_ptr.h" -#include "base/sequence_checker.h" -#include "base/threading/sequence_bound.h" -#include "net/base/net_export.h" -#include "net/base/network_change_notifier.h" - -namespace net { -class NetworkCostManagerEventSinkWin; - -// Uses the `INetworkCostManager` Windows OS API to monitor the cost of the -// current connection. `INetworkCostManager` performs blocking IO and -// synchronous RPC and must be accessed through a thread pool COM STA single -// threaded task runner. NetworkCostChangeNotifierWin uses -// `base::SequenceBound` to prevent these expensive operations from happening on -// the UI thread. -class NET_EXPORT_PRIVATE NetworkCostChangeNotifierWin final { - public: - using CostChangedCallback = - base::RepeatingCallback<void(NetworkChangeNotifier::ConnectionCost)>; - - // Constructs a new instance using a new COM STA single threaded task runner - // to post the task that creates NetworkCostChangeNotifierWin and subscribes - // to cost change events. - static base::SequenceBound<NetworkCostChangeNotifierWin> CreateInstance( - CostChangedCallback cost_changed_callback); - - // Tests use this hook to provide a fake implementation of the OS APIs. - // The fake implementation enables tests to simulate different cost values, - // cost changed events and OS errors. - using CoCreateInstanceCallback = base::RepeatingCallback< - HRESULT(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID*)>; - static void OverrideCoCreateInstanceForTesting( - CoCreateInstanceCallback callback_for_testing); - - NetworkCostChangeNotifierWin(const NetworkCostChangeNotifierWin&) = delete; - NetworkCostChangeNotifierWin& operator=(const NetworkCostChangeNotifierWin&) = - delete; - - private: - friend class base::SequenceBound<NetworkCostChangeNotifierWin>; - - explicit NetworkCostChangeNotifierWin( - CostChangedCallback cost_changed_callback); - ~NetworkCostChangeNotifierWin(); - - // Creates `INetworkCostManager` and subscribe to cost change events. - void StartWatching(); - - // Stops monitoring the cost of the current connection by unsubscribing to - // `INetworkCostManager` events and releasing all members. - void StopWatching(); - - // Gets the current cost from `cost_manager_` and then runs - // `cost_changed_callback_`. - void HandleCostChanged(); - - // All members must be accessed on the sequence from `sequence_checker_` - SEQUENCE_CHECKER(sequence_checker_); - - CostChangedCallback cost_changed_callback_; - - Microsoft::WRL::ComPtr<INetworkCostManager> cost_manager_; - - Microsoft::WRL::ComPtr<NetworkCostManagerEventSinkWin> - cost_manager_event_sink_; - - base::WeakPtrFactory<NetworkCostChangeNotifierWin> weak_ptr_factory_{this}; -}; - -} // namespace net - -#endif // NET_BASE_NETWORK_COST_CHANGE_NOTIFIER_WIN_H_
diff --git a/net/base/network_cost_change_notifier_win_unittest.cc b/net/base/network_cost_change_notifier_win_unittest.cc deleted file mode 100644 index ae35acc..0000000 --- a/net/base/network_cost_change_notifier_win_unittest.cc +++ /dev/null
@@ -1,236 +0,0 @@ -// 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 "net/base/network_cost_change_notifier_win.h" - -#include "base/run_loop.h" -#include "base/sequence_checker.h" -#include "base/test/scoped_os_info_override_win.h" -#include "base/win/windows_version.h" -#include "net/base/network_change_notifier.h" -#include "net/test/test_connection_cost_observer.h" -#include "net/test/test_with_task_environment.h" -#include "net/test/win/fake_network_cost_manager.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -class NetworkCostChangeNotifierWinTest : public TestWithTaskEnvironment { - public: - void SetUp() override { - if (base::win::GetVersion() < base::win::Version::WIN10) { - GTEST_SKIP(); - } - } - - protected: - FakeNetworkCostManagerEnvironment fake_network_cost_manager_environment_; -}; - -TEST_F(NetworkCostChangeNotifierWinTest, InitialCostUnknown) { - fake_network_cost_manager_environment_.SetCost( - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNKNOWN); - - TestConnectionCostObserver cost_change_observer; - auto cost_change_callback = - base::BindRepeating(&TestConnectionCostObserver::OnConnectionCostChanged, - base::Unretained(&cost_change_observer)); - - base::SequenceBound<NetworkCostChangeNotifierWin> cost_change_notifier = - NetworkCostChangeNotifierWin::CreateInstance(cost_change_callback); - - // Wait for `NetworkCostChangeNotifierWin` to finish initializing. - cost_change_observer.WaitForConnectionCostChanged(); - - // `NetworkCostChangeNotifierWin` must report an unknown cost after - // initializing. - EXPECT_EQ(cost_change_observer.cost_changed_calls(), 1u); - EXPECT_EQ(cost_change_observer.last_cost_changed_input(), - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNKNOWN); -} - -TEST_F(NetworkCostChangeNotifierWinTest, InitialCostKnown) { - fake_network_cost_manager_environment_.SetCost( - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNMETERED); - - TestConnectionCostObserver cost_change_observer; - auto cost_change_callback = - base::BindRepeating(&TestConnectionCostObserver::OnConnectionCostChanged, - base::Unretained(&cost_change_observer)); - - base::SequenceBound<NetworkCostChangeNotifierWin> cost_change_notifier = - NetworkCostChangeNotifierWin::CreateInstance(cost_change_callback); - - // Initializing changes the cost from unknown to unmetered. - cost_change_observer.WaitForConnectionCostChanged(); - - ASSERT_EQ(cost_change_observer.cost_changed_calls(), 1u); - EXPECT_EQ(cost_change_observer.last_cost_changed_input(), - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNMETERED); -} - -TEST_F(NetworkCostChangeNotifierWinTest, MultipleCostChangedEvents) { - fake_network_cost_manager_environment_.SetCost( - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNMETERED); - - TestConnectionCostObserver cost_change_observer; - auto cost_change_callback = - base::BindRepeating(&TestConnectionCostObserver::OnConnectionCostChanged, - base::Unretained(&cost_change_observer)); - - base::SequenceBound<NetworkCostChangeNotifierWin> cost_change_notifier = - NetworkCostChangeNotifierWin::CreateInstance(cost_change_callback); - - // Initializing changes the cost from unknown to unmetered. - cost_change_observer.WaitForConnectionCostChanged(); - - ASSERT_EQ(cost_change_observer.cost_changed_calls(), 1u); - EXPECT_EQ(cost_change_observer.last_cost_changed_input(), - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNMETERED); - - fake_network_cost_manager_environment_.SetCost( - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_METERED); - - // The simulated event changes the cost from unmetered to metered. - cost_change_observer.WaitForConnectionCostChanged(); - - ASSERT_EQ(cost_change_observer.cost_changed_calls(), 2u); - EXPECT_EQ(cost_change_observer.last_cost_changed_input(), - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_METERED); - - fake_network_cost_manager_environment_.SetCost( - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNKNOWN); - - // The simulated event changes the cost from metered to unknown. - cost_change_observer.WaitForConnectionCostChanged(); - - ASSERT_EQ(cost_change_observer.cost_changed_calls(), 3u); - EXPECT_EQ(cost_change_observer.last_cost_changed_input(), - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNKNOWN); -} - -TEST_F(NetworkCostChangeNotifierWinTest, DuplicateEvents) { - fake_network_cost_manager_environment_.SetCost( - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNMETERED); - - TestConnectionCostObserver cost_change_observer; - auto cost_change_callback = - base::BindRepeating(&TestConnectionCostObserver::OnConnectionCostChanged, - base::Unretained(&cost_change_observer)); - - base::SequenceBound<NetworkCostChangeNotifierWin> cost_change_notifier = - NetworkCostChangeNotifierWin::CreateInstance(cost_change_callback); - - // Initializing changes the cost from unknown to unmetered. - cost_change_observer.WaitForConnectionCostChanged(); - ASSERT_EQ(cost_change_observer.cost_changed_calls(), 1u); - - fake_network_cost_manager_environment_.SetCost( - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNMETERED); - - cost_change_observer.WaitForConnectionCostChanged(); - - // Changing from unmetered to unmetered must dispatch a cost changed event. - ASSERT_EQ(cost_change_observer.cost_changed_calls(), 2u); - EXPECT_EQ(cost_change_observer.last_cost_changed_input(), - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNMETERED); -} - -TEST_F(NetworkCostChangeNotifierWinTest, ShutdownImmediately) { - TestConnectionCostObserver cost_change_observer; - auto cost_change_callback = - base::BindRepeating(&TestConnectionCostObserver::OnConnectionCostChanged, - base::Unretained(&cost_change_observer)); - - base::SequenceBound<NetworkCostChangeNotifierWin> cost_change_notifier = - NetworkCostChangeNotifierWin::CreateInstance(cost_change_callback); - - // Shutting down immediately must not crash. - cost_change_notifier.Reset(); - - // Wait for `NetworkCostChangeNotifierWin` to finish initializing and shutting - // down. - RunUntilIdle(); - - // `NetworkCostChangeNotifierWin` reports a connection change after - // initializing. - EXPECT_EQ(cost_change_observer.cost_changed_calls(), 1u); - - fake_network_cost_manager_environment_.SetCost( - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_METERED); - - // Wait for `NetworkCostChangeNotifierWin` to handle the cost changed event. - RunUntilIdle(); - - // After shutdown, cost changed events must have no effect. - EXPECT_EQ(cost_change_observer.cost_changed_calls(), 1u); -} - -TEST_F(NetworkCostChangeNotifierWinTest, ErrorHandling) { - // Simulate the failure of each OS API while initializing - // `NetworkCostChangeNotifierWin`. - constexpr const NetworkCostManagerStatus kErrorList[] = { - NetworkCostManagerStatus::kErrorCoCreateInstanceFailed, - NetworkCostManagerStatus::kErrorQueryInterfaceFailed, - NetworkCostManagerStatus::kErrorFindConnectionPointFailed, - NetworkCostManagerStatus::kErrorAdviseFailed, - NetworkCostManagerStatus::kErrorGetCostFailed, - }; - for (auto error : kErrorList) { - fake_network_cost_manager_environment_.SetCost( - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNMETERED); - - fake_network_cost_manager_environment_.SimulateError(error); - - TestConnectionCostObserver cost_change_observer; - auto cost_change_callback = base::BindRepeating( - &TestConnectionCostObserver::OnConnectionCostChanged, - base::Unretained(&cost_change_observer)); - - base::SequenceBound<NetworkCostChangeNotifierWin> cost_change_notifier = - NetworkCostChangeNotifierWin::CreateInstance(cost_change_callback); - - if (error == NetworkCostManagerStatus::kErrorGetCostFailed) { - // `NetworkCostChangeNotifierWin` must report an unknown cost after - // `INetworkCostManager::GetCost()` fails. - cost_change_observer.WaitForConnectionCostChanged(); - - EXPECT_EQ(cost_change_observer.cost_changed_calls(), 1u); - EXPECT_EQ(cost_change_observer.last_cost_changed_input(), - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNKNOWN); - } else { - // Wait for `NetworkCostChangeNotifierWin` to finish initializing. - RunUntilIdle(); - - // `NetworkCostChangeNotifierWin` must NOT report a changed cost after - // failing to initialize. - EXPECT_EQ(cost_change_observer.cost_changed_calls(), 0u); - } - } -} - -TEST_F(NetworkCostChangeNotifierWinTest, UnsupportedOS) { - base::test::ScopedOSInfoOverride os_override( - base::test::ScopedOSInfoOverride::Type::kWin81Pro); - - fake_network_cost_manager_environment_.SetCost( - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNMETERED); - - TestConnectionCostObserver cost_change_observer; - auto cost_change_callback = - base::BindRepeating(&TestConnectionCostObserver::OnConnectionCostChanged, - base::Unretained(&cost_change_observer)); - - base::SequenceBound<NetworkCostChangeNotifierWin> cost_change_notifier = - NetworkCostChangeNotifierWin::CreateInstance(cost_change_callback); - - // Wait for `NetworkCostChangeNotifierWin` to finish initializing. - RunUntilIdle(); - - // `NetworkCostChangeNotifierWin` must NOT report a changed cost for - // unsupported OSes. - EXPECT_EQ(cost_change_observer.cost_changed_calls(), 0u); -} - -} // namespace net
diff --git a/net/dns/BUILD.gn b/net/dns/BUILD.gn index 4afa392..59f456a 100644 --- a/net/dns/BUILD.gn +++ b/net/dns/BUILD.gn
@@ -61,6 +61,8 @@ "dns_util.h", "host_cache.cc", "host_resolver.cc", + "host_resolver_internal_result.cc", + "host_resolver_internal_result.h", "host_resolver_manager.cc", "host_resolver_mdns_listener_impl.cc", "host_resolver_mdns_listener_impl.h", @@ -403,6 +405,7 @@ "dns_udp_tracker_unittest.cc", "dns_util_unittest.cc", "host_cache_unittest.cc", + "host_resolver_internal_result_unittest.cc", "host_resolver_manager_unittest.cc", "https_record_rdata_unittest.cc", "httpssvc_metrics_unittest.cc",
diff --git a/net/dns/host_cache.cc b/net/dns/host_cache.cc index add0637..c1448788 100644 --- a/net/dns/host_cache.cc +++ b/net/dns/host_cache.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <iterator> #include <map> +#include <memory> #include <ostream> #include <string> #include <type_traits> @@ -29,6 +30,7 @@ #include "net/base/ip_endpoint.h" #include "net/base/trace_constants.h" #include "net/dns/host_resolver.h" +#include "net/dns/host_resolver_internal_result.h" #include "net/dns/https_record_rdata.h" #include "net/dns/public/dns_protocol.h" #include "net/dns/public/host_resolver_source.h" @@ -261,7 +263,7 @@ HostCache::Entry::Entry(int error, Source source, absl::optional<base::TimeDelta> ttl) - : error_(error), source_(source), ttl_(ttl.value_or(base::Seconds(-1))) { + : error_(error), source_(source), ttl_(ttl.value_or(kUnknownTtl)) { // If |ttl| has a value, must not be negative. DCHECK_GE(ttl.value_or(base::TimeDelta()), base::TimeDelta()); DCHECK_NE(OK, error_); @@ -275,6 +277,125 @@ "`HostCache::Entry::HttpsRecordPriority` must be same type"); } +HostCache::Entry::Entry( + std::vector<std::unique_ptr<HostResolverInternalResult>> results, + base::Time now, + base::TimeTicks now_ticks) { + std::unique_ptr<HostResolverInternalResult> data_result; + std::unique_ptr<HostResolverInternalResult> metadata_result; + std::unique_ptr<HostResolverInternalResult> error_result; + std::vector<std::unique_ptr<HostResolverInternalResult>> alias_results; + + absl::optional<base::TimeDelta> smallest_ttl; + absl::optional<Source> source; + for (auto& result : results) { + if (result->expiration().has_value()) { + smallest_ttl = std::min(smallest_ttl.value_or(base::TimeDelta::Max()), + result->expiration().value() - now_ticks); + } + if (result->timed_expiration().has_value()) { + smallest_ttl = std::min(smallest_ttl.value_or(base::TimeDelta::Max()), + result->timed_expiration().value() - now); + } + + Source result_source; + switch (result->source()) { + case HostResolverInternalResult::Source::kDns: + result_source = SOURCE_DNS; + break; + case HostResolverInternalResult::Source::kHosts: + result_source = SOURCE_HOSTS; + break; + case HostResolverInternalResult::Source::kUnknown: + result_source = SOURCE_UNKNOWN; + break; + } + + switch (result->type()) { + case HostResolverInternalResult::Type::kData: + DCHECK(!data_result); // Expect at most one data result. + data_result = std::move(result); + break; + case HostResolverInternalResult::Type::kMetadata: + DCHECK(!metadata_result); // Expect at most one metadata result. + metadata_result = std::move(result); + break; + case HostResolverInternalResult::Type::kError: + DCHECK(!error_result); // Expect at most one error result. + error_result = std::move(result); + break; + case HostResolverInternalResult::Type::kAlias: + alias_results.push_back(std::move(result)); + break; + } + + // Expect all results to have the same source. + DCHECK(!source.has_value() || source.value() == result_source); + source = result_source; + } + + ttl_ = smallest_ttl.value_or(kUnknownTtl); + source_ = source.value_or(SOURCE_UNKNOWN); + + if (error_result) { + DCHECK(!data_result); + DCHECK(!metadata_result); + + error_ = error_result->AsError().error(); + + // For error results, should not create entry with a TTL unless it is a + // cacheable error. + if (!error_result->expiration().has_value() && + !error_result->timed_expiration().has_value()) { + ttl_ = kUnknownTtl; + } + } else if (!data_result && !metadata_result) { + // Only alias results (or completely empty results). Never cacheable due to + // being equivalent to an error result without TTL. + error_ = ERR_NAME_NOT_RESOLVED; + ttl_ = kUnknownTtl; + } else { + error_ = OK; + } + + if (data_result) { + DCHECK(!error_result); + DCHECK(!data_result->AsData().endpoints().empty() || + !data_result->AsData().strings().empty() || + !data_result->AsData().hosts().empty()); + // Data results should always be cacheable. + DCHECK(data_result->expiration().has_value() || + data_result->timed_expiration().has_value()); + + ip_endpoints_ = data_result->AsData().endpoints(); + text_records_ = data_result->AsData().strings(); + hostnames_ = data_result->AsData().hosts(); + canonical_names_ = {data_result->domain_name()}; + + aliases_.emplace(); + for (const auto& alias_result : alias_results) { + aliases_.value().insert(alias_result->domain_name()); + aliases_.value().insert(alias_result->AsAlias().alias_target()); + } + aliases_.value().insert(data_result->domain_name()); + } + if (metadata_result) { + DCHECK(!error_result); + // Metadata results should always be cacheable. + DCHECK(metadata_result->expiration().has_value() || + metadata_result->timed_expiration().has_value()); + + endpoint_metadatas_ = metadata_result->AsMetadata().metadatas(); + + // Even if otherwise empty, having the metadata result object signifies + // receiving a compatible HTTPS record. + https_record_compatibility_ = {true}; + + if (endpoint_metadatas_.value().empty()) + error_ = ERR_NAME_NOT_RESOLVED; + } +} + HostCache::Entry::Entry(const Entry& entry) = default; HostCache::Entry::Entry(Entry&& entry) = default; @@ -412,7 +533,7 @@ ip_endpoints_(std::move(ip_endpoints)), aliases_(std::move(aliases)), source_(source), - ttl_(ttl ? ttl.value() : base::Seconds(-1)) { + ttl_(ttl ? ttl.value() : kUnknownTtl) { DCHECK(!ttl || ttl.value() >= base::TimeDelta()); }
diff --git a/net/dns/host_cache.h b/net/dns/host_cache.h index 7e1fcd97c..f077893d 100644 --- a/net/dns/host_cache.h +++ b/net/dns/host_cache.h
@@ -47,6 +47,8 @@ namespace net { +class HostResolverInternalResult; + // Cache used by HostResolver to map hostnames to their resolved result. class NET_EXPORT HostCache { public: @@ -131,7 +133,7 @@ absl::optional<base::TimeDelta> ttl) : error_(error), source_(source), - ttl_(ttl ? ttl.value() : base::Seconds(-1)) { + ttl_(ttl ? ttl.value() : kUnknownTtl) { DCHECK(!ttl || ttl.value() >= base::TimeDelta()); SetResult(std::forward<T>(results)); } @@ -153,6 +155,12 @@ Source source, absl::optional<base::TimeDelta> ttl = absl::nullopt); + // Adaptor to construct from HostResolverInternalResults. Only supports + // results extracted from a single DnsTransaction. + Entry(std::vector<std::unique_ptr<HostResolverInternalResult>> results, + base::Time now, + base::TimeTicks now_ticks); + Entry(const Entry& entry); Entry(Entry&& entry); ~Entry(); @@ -267,6 +275,8 @@ friend class HostCache; + static constexpr base::TimeDelta kUnknownTtl = base::Seconds(-1); + Entry(const Entry& entry, base::TimeTicks now, base::TimeDelta ttl, @@ -349,7 +359,7 @@ absl::optional<std::set<std::string>> canonical_names_; // TTL obtained from the nameserver. Negative if unknown. - base::TimeDelta ttl_ = base::Seconds(-1); + base::TimeDelta ttl_ = kUnknownTtl; base::TimeTicks expires_; // Copied from the cache's network_changes_ when the entry is set; can
diff --git a/net/dns/host_cache_unittest.cc b/net/dns/host_cache_unittest.cc index a19b72d..1b15ed0 100644 --- a/net/dns/host_cache_unittest.cc +++ b/net/dns/host_cache_unittest.cc
@@ -6,8 +6,10 @@ #include <algorithm> #include <map> +#include <memory> #include <string> #include <utility> +#include <vector> #include "base/bind.h" #include "base/callback.h" @@ -23,9 +25,12 @@ #include "base/time/time.h" #include "base/values.h" #include "net/base/connection_endpoint_metadata.h" +#include "net/base/host_port_pair.h" +#include "net/base/ip_address.h" #include "net/base/ip_endpoint.h" #include "net/base/network_anonymization_key.h" #include "net/base/schemeful_site.h" +#include "net/dns/host_resolver_internal_result.h" #include "net/dns/host_resolver_results_test_util.h" #include "net/dns/https_record_rdata.h" #include "net/dns/public/host_resolver_results.h" @@ -2485,4 +2490,203 @@ EXPECT_THAT(*result.aliases(), UnorderedElementsAre("name2")); } +TEST(HostCacheTest, ConvertFromInternalAddressResult) { + const std::vector<IPEndPoint> kEndpoints{ + IPEndPoint(IPAddress(2, 2, 2, 2), 46)}; + constexpr base::TimeDelta kTtl1 = base::Minutes(45); + constexpr base::TimeDelta kTtl2 = base::Minutes(40); + constexpr base::TimeDelta kTtl3 = base::Minutes(55); + + std::vector<std::unique_ptr<HostResolverInternalResult>> results; + results.push_back(std::make_unique<HostResolverInternalDataResult>( + "endpoint.test", DnsQueryType::AAAA, base::TimeTicks() + kTtl1, + base::Time() + kTtl1, HostResolverInternalResult::Source::kDns, + kEndpoints, std::vector<std::string>{}, std::vector<HostPortPair>{})); + results.push_back(std::make_unique<HostResolverInternalAliasResult>( + "domain1.test", DnsQueryType::AAAA, base::TimeTicks() + kTtl2, + base::Time() + kTtl2, HostResolverInternalResult::Source::kDns, + "domain2.test")); + results.push_back(std::make_unique<HostResolverInternalAliasResult>( + "domain2.test", DnsQueryType::AAAA, base::TimeTicks() + kTtl3, + base::Time() + kTtl3, HostResolverInternalResult::Source::kDns, + "endpoint.test")); + + HostCache::Entry converted(std::move(results), base::Time(), + base::TimeTicks()); + + // Expect kTtl2 because it is the min TTL. + HostCache::Entry expected( + OK, kEndpoints, + /*aliases=*/{"domain1.test", "domain2.test", "endpoint.test"}, + HostCache::Entry::SOURCE_DNS, kTtl2); + expected.set_canonical_names(std::set<std::string>{"endpoint.test"}); + + // Entries converted from HostResolverInternalDataResults do not differentiate + // between empty and no-data for the various data types, so need to set empty + // strings and hostname entries into `expected`. + expected.set_text_records(std::vector<std::string>()); + expected.set_hostnames(std::vector<HostPortPair>()); + + EXPECT_EQ(converted, expected); +} + +TEST(HostCacheTest, ConvertFromInternalMetadataResult) { + const std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> + kMetadatas{{1, ConnectionEndpointMetadata({"h2", "h3"}, + /*ech_config_list=*/{}, + "target.test")}}; + constexpr base::TimeDelta kTtl1 = base::Minutes(45); + constexpr base::TimeDelta kTtl2 = base::Minutes(40); + constexpr base::TimeDelta kTtl3 = base::Minutes(55); + + std::vector<std::unique_ptr<HostResolverInternalResult>> results; + results.push_back(std::make_unique<HostResolverInternalMetadataResult>( + "endpoint.test", DnsQueryType::HTTPS, base::TimeTicks() + kTtl1, + base::Time() + kTtl1, HostResolverInternalResult::Source::kDns, + kMetadatas)); + results.push_back(std::make_unique<HostResolverInternalAliasResult>( + "domain1.test", DnsQueryType::HTTPS, base::TimeTicks() + kTtl2, + base::Time() + kTtl2, HostResolverInternalResult::Source::kDns, + "domain2.test")); + results.push_back(std::make_unique<HostResolverInternalAliasResult>( + "domain2.test", DnsQueryType::HTTPS, base::TimeTicks() + kTtl3, + base::Time() + kTtl3, HostResolverInternalResult::Source::kDns, + "endpoint.test")); + + HostCache::Entry converted(std::move(results), base::Time(), + base::TimeTicks()); + + // Expect kTtl2 because it is the min TTL. + HostCache::Entry expected(OK, kMetadatas, HostCache::Entry::SOURCE_DNS, + kTtl2); + expected.set_https_record_compatibility(std::vector<bool>{true}); + + EXPECT_EQ(converted, expected); +} + +// Test the case of compatible HTTPS records but no metadata of use to Chrome. +// Represented in internal result type as an empty metadata result. Represented +// in HostCache::Entry as empty metadata with at least one true in +// `https_record_compatibility_`. +TEST(HostCacheTest, ConvertFromCompatibleOnlyInternalMetadataResult) { + const std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> + kMetadatas; + constexpr base::TimeDelta kTtl1 = base::Minutes(45); + constexpr base::TimeDelta kTtl2 = base::Minutes(40); + constexpr base::TimeDelta kTtl3 = base::Minutes(55); + + std::vector<std::unique_ptr<HostResolverInternalResult>> results; + results.push_back(std::make_unique<HostResolverInternalMetadataResult>( + "endpoint.test", DnsQueryType::HTTPS, base::TimeTicks() + kTtl1, + base::Time() + kTtl1, HostResolverInternalResult::Source::kDns, + kMetadatas)); + results.push_back(std::make_unique<HostResolverInternalAliasResult>( + "domain1.test", DnsQueryType::HTTPS, base::TimeTicks() + kTtl2, + base::Time() + kTtl2, HostResolverInternalResult::Source::kDns, + "domain2.test")); + results.push_back(std::make_unique<HostResolverInternalAliasResult>( + "domain2.test", DnsQueryType::HTTPS, base::TimeTicks() + kTtl3, + base::Time() + kTtl3, HostResolverInternalResult::Source::kDns, + "endpoint.test")); + + HostCache::Entry converted(std::move(results), base::Time(), + base::TimeTicks()); + + // Expect kTtl2 because it is the min TTL. + HostCache::Entry expected(ERR_NAME_NOT_RESOLVED, kMetadatas, + HostCache::Entry::SOURCE_DNS, kTtl2); + expected.set_https_record_compatibility(std::vector<bool>{true}); + + EXPECT_EQ(converted, expected); +} + +TEST(HostCacheTest, ConvertFromInternalErrorResult) { + constexpr base::TimeDelta kTtl1 = base::Minutes(45); + constexpr base::TimeDelta kTtl2 = base::Minutes(40); + constexpr base::TimeDelta kTtl3 = base::Minutes(55); + + std::vector<std::unique_ptr<HostResolverInternalResult>> results; + results.push_back(std::make_unique<HostResolverInternalErrorResult>( + "endpoint.test", DnsQueryType::A, base::TimeTicks() + kTtl1, + base::Time() + kTtl1, HostResolverInternalResult::Source::kDns, + ERR_NAME_NOT_RESOLVED)); + results.push_back(std::make_unique<HostResolverInternalAliasResult>( + "domain1.test", DnsQueryType::A, base::TimeTicks() + kTtl2, + base::Time() + kTtl2, HostResolverInternalResult::Source::kDns, + "domain2.test")); + results.push_back(std::make_unique<HostResolverInternalAliasResult>( + "domain2.test", DnsQueryType::A, base::TimeTicks() + kTtl3, + base::Time() + kTtl3, HostResolverInternalResult::Source::kDns, + "endpoint.test")); + + HostCache::Entry converted(std::move(results), base::Time(), + base::TimeTicks()); + + // Expect kTtl2 because it is the min TTL. + HostCache::Entry expected(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS, + kTtl2); + + EXPECT_EQ(converted, expected); +} + +TEST(HostCacheTest, ConvertFromNonCachableInternalErrorResult) { + constexpr base::TimeDelta kTtl1 = base::Minutes(45); + constexpr base::TimeDelta kTtl2 = base::Minutes(40); + + std::vector<std::unique_ptr<HostResolverInternalResult>> results; + results.push_back(std::make_unique<HostResolverInternalErrorResult>( + "endpoint.test", DnsQueryType::AAAA, /*expiration=*/absl::nullopt, + /*timed_expiration=*/absl::nullopt, + HostResolverInternalResult::Source::kDns, ERR_NAME_NOT_RESOLVED)); + results.push_back(std::make_unique<HostResolverInternalAliasResult>( + "domain1.test", DnsQueryType::AAAA, base::TimeTicks() + kTtl1, + base::Time() + kTtl1, HostResolverInternalResult::Source::kDns, + "domain2.test")); + results.push_back(std::make_unique<HostResolverInternalAliasResult>( + "domain2.test", DnsQueryType::AAAA, base::TimeTicks() + kTtl2, + base::Time() + kTtl2, HostResolverInternalResult::Source::kDns, + "endpoint.test")); + + HostCache::Entry converted(std::move(results), base::Time(), + base::TimeTicks()); + + // Expect no TTL because error is non-cachable (has no TTL itself). + HostCache::Entry expected(ERR_NAME_NOT_RESOLVED, + HostCache::Entry::SOURCE_DNS); + + EXPECT_EQ(converted, expected); +} + +TEST(HostCacheTest, ConvertFromInternalAliasOnlyResult) { + constexpr base::TimeDelta kTtl1 = base::Minutes(45); + constexpr base::TimeDelta kTtl2 = base::Minutes(40); + + std::vector<std::unique_ptr<HostResolverInternalResult>> results; + results.push_back(std::make_unique<HostResolverInternalAliasResult>( + "domain1.test", DnsQueryType::A, base::TimeTicks() + kTtl1, + base::Time() + kTtl1, HostResolverInternalResult::Source::kDns, + "domain2.test")); + results.push_back(std::make_unique<HostResolverInternalAliasResult>( + "domain2.test", DnsQueryType::A, base::TimeTicks() + kTtl2, + base::Time() + kTtl2, HostResolverInternalResult::Source::kDns, + "endpoint.test")); + + HostCache::Entry converted(std::move(results), base::Time(), + base::TimeTicks()); + + // Expect no TTL because alias-only results are not cacheable. + HostCache::Entry expected(ERR_NAME_NOT_RESOLVED, + HostCache::Entry::SOURCE_DNS); + + EXPECT_EQ(converted, expected); +} + +TEST(HostCacheTest, ConvertFromEmptyInternalResult) { + HostCache::Entry converted({}, base::Time(), base::TimeTicks()); + HostCache::Entry expected(ERR_NAME_NOT_RESOLVED, + HostCache::Entry::SOURCE_UNKNOWN); + + EXPECT_EQ(converted, expected); +} + } // namespace net
diff --git a/net/dns/host_resolver_internal_result.cc b/net/dns/host_resolver_internal_result.cc new file mode 100644 index 0000000..487bf81 --- /dev/null +++ b/net/dns/host_resolver_internal_result.cc
@@ -0,0 +1,586 @@ +// 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 "net/dns/host_resolver_internal_result.h" + +#include <map> +#include <memory> +#include <ostream> +#include <string> +#include <utility> +#include <vector> + +#include "base/check_op.h" +#include "base/json/values_util.h" +#include "base/memory/ptr_util.h" +#include "base/strings/string_piece.h" +#include "base/time/time.h" +#include "base/values.h" +#include "net/base/connection_endpoint_metadata.h" +#include "net/base/host_port_pair.h" +#include "net/base/ip_endpoint.h" +#include "net/base/net_errors.h" +#include "net/dns/https_record_rdata.h" +#include "net/dns/public/dns_query_type.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/url_canon.h" +#include "url/url_canon_stdstring.h" + +namespace net { + +namespace { + +// base::Value keys +constexpr base::StringPiece kValueDomainNameKey = "domain_name"; +constexpr base::StringPiece kValueQueryTypeKey = "query_type"; +constexpr base::StringPiece kValueTypeKey = "type"; +constexpr base::StringPiece kValueSourceKey = "source"; +constexpr base::StringPiece kValueTimedExpirationKey = "timed_expiration"; +constexpr base::StringPiece kValueEndpointsKey = "endpoints"; +constexpr base::StringPiece kValueStringsKey = "strings"; +constexpr base::StringPiece kValueHostsKey = "hosts"; +constexpr base::StringPiece kValueMetadatasKey = "metadatas"; +constexpr base::StringPiece kValueMetadataWeightKey = "metadata_weight"; +constexpr base::StringPiece kValueMetadataValueKey = "metadata_value"; +constexpr base::StringPiece kValueErrorKey = "error"; +constexpr base::StringPiece kValueAliasTargetKey = "alias_target"; + +// Returns `domain_name` as-is if it could not be canonicalized. +std::string MaybeCanonicalizeName(std::string domain_name) { + std::string canonicalized; + url::StdStringCanonOutput output(&canonicalized); + url::CanonHostInfo host_info; + + url::CanonicalizeHostVerbose(domain_name.data(), + url::Component(0, domain_name.size()), &output, + &host_info); + + if (host_info.family == url::CanonHostInfo::Family::NEUTRAL) { + output.Complete(); + return canonicalized; + } else { + return domain_name; + } +} + +base::Value EndpointMetadataPairToValue( + const std::pair<HttpsRecordPriority, ConnectionEndpointMetadata>& pair) { + base::Value::Dict dictionary; + dictionary.Set(kValueMetadataWeightKey, pair.first); + dictionary.Set(kValueMetadataValueKey, pair.second.ToValue()); + return base::Value(std::move(dictionary)); +} + +absl::optional<std::pair<HttpsRecordPriority, ConnectionEndpointMetadata>> +EndpointMetadataPairFromValue(const base::Value& value) { + const base::Value::Dict* dict = value.GetIfDict(); + if (!dict) + return absl::nullopt; + + absl::optional<int> weight = dict->FindInt(kValueMetadataWeightKey); + if (!weight || !base::IsValueInRangeForNumericType<HttpsRecordPriority>( + weight.value())) { + return absl::nullopt; + } + + const base::Value* metadata_value = dict->Find(kValueMetadataValueKey); + if (!metadata_value) + return absl::nullopt; + absl::optional<ConnectionEndpointMetadata> metadata = + ConnectionEndpointMetadata::FromValue(*metadata_value); + if (!metadata) + return absl::nullopt; + + return std::make_pair(base::checked_cast<HttpsRecordPriority>(weight.value()), + std::move(metadata).value()); +} + +absl::optional<DnsQueryType> QueryTypeFromValue(const base::Value& value) { + const std::string* query_type_string = value.GetIfString(); + if (!query_type_string) + return absl::nullopt; + const auto* query_type_it = + base::ranges::find(kDnsQueryTypes, *query_type_string, + &decltype(kDnsQueryTypes)::value_type::second); + if (query_type_it == kDnsQueryTypes.end()) + return absl::nullopt; + + return query_type_it->first; +} + +base::Value TypeToValue(HostResolverInternalResult::Type type) { + switch (type) { + case HostResolverInternalResult::Type::kData: + return base::Value("data"); + case HostResolverInternalResult::Type::kMetadata: + return base::Value("metadata"); + case HostResolverInternalResult::Type::kError: + return base::Value("error"); + case HostResolverInternalResult::Type::kAlias: + return base::Value("alias"); + } +} + +absl::optional<HostResolverInternalResult::Type> TypeFromValue( + const base::Value& value) { + const std::string* string = value.GetIfString(); + if (!string) + return absl::nullopt; + + if (*string == "data") { + return HostResolverInternalResult::Type::kData; + } else if (*string == "metadata") { + return HostResolverInternalResult::Type::kMetadata; + } else if (*string == "error") { + return HostResolverInternalResult::Type::kError; + } else if (*string == "alias") { + return HostResolverInternalResult::Type::kAlias; + } else { + return absl::nullopt; + } +} + +base::Value SourceToValue(HostResolverInternalResult::Source source) { + switch (source) { + case HostResolverInternalResult::Source::kDns: + return base::Value("dns"); + case HostResolverInternalResult::Source::kHosts: + return base::Value("hosts"); + case HostResolverInternalResult::Source::kUnknown: + return base::Value("unknown"); + } +} + +absl::optional<HostResolverInternalResult::Source> SourceFromValue( + const base::Value& value) { + const std::string* string = value.GetIfString(); + if (!string) + return absl::nullopt; + + if (*string == "dns") { + return HostResolverInternalResult::Source::kDns; + } else if (*string == "hosts") { + return HostResolverInternalResult::Source::kHosts; + } else if (*string == "unknown") { + return HostResolverInternalResult::Source::kUnknown; + } else { + return absl::nullopt; + } +} + +} // namespace + +// static +std::unique_ptr<HostResolverInternalResult> +HostResolverInternalResult::FromValue(const base::Value& value) { + const base::Value::Dict* dict = value.GetIfDict(); + if (!dict) + return nullptr; + + const base::Value* type_value = dict->Find(kValueTypeKey); + if (!type_value) + return nullptr; + absl::optional<Type> type = TypeFromValue(*type_value); + if (!type.has_value()) + return nullptr; + + switch (type.value()) { + case Type::kData: + return HostResolverInternalDataResult::FromValue(value); + case Type::kMetadata: + return HostResolverInternalMetadataResult::FromValue(value); + case Type::kError: + return HostResolverInternalErrorResult::FromValue(value); + case Type::kAlias: + return HostResolverInternalAliasResult::FromValue(value); + } +} + +const HostResolverInternalDataResult& HostResolverInternalResult::AsData() + const { + CHECK_EQ(type_, Type::kData); + return *static_cast<const HostResolverInternalDataResult*>(this); +} + +const HostResolverInternalMetadataResult& +HostResolverInternalResult::AsMetadata() const { + CHECK_EQ(type_, Type::kMetadata); + return *static_cast<const HostResolverInternalMetadataResult*>(this); +} + +const HostResolverInternalErrorResult& HostResolverInternalResult::AsError() + const { + CHECK_EQ(type_, Type::kError); + return *static_cast<const HostResolverInternalErrorResult*>(this); +} + +const HostResolverInternalAliasResult& HostResolverInternalResult::AsAlias() + const { + CHECK_EQ(type_, Type::kAlias); + return *static_cast<const HostResolverInternalAliasResult*>(this); +} + +HostResolverInternalResult::HostResolverInternalResult( + std::string domain_name, + DnsQueryType query_type, + absl::optional<base::TimeTicks> expiration, + absl::optional<base::Time> timed_expiration, + Type type, + Source source) + : domain_name_(MaybeCanonicalizeName(std::move(domain_name))), + query_type_(query_type), + type_(type), + source_(source), + expiration_(expiration), + timed_expiration_(timed_expiration) { + DCHECK(!domain_name_.empty()); + // If `expiration` has a value, `timed_expiration` must too. + DCHECK(!expiration_.has_value() || timed_expiration.has_value()); +} + +HostResolverInternalResult::HostResolverInternalResult( + const base::Value::Dict& dict) + : domain_name_(*dict.FindString(kValueDomainNameKey)), + query_type_(QueryTypeFromValue(*dict.Find(kValueQueryTypeKey)).value()), + type_(TypeFromValue(*dict.Find(kValueTypeKey)).value()), + source_(SourceFromValue(*dict.Find(kValueSourceKey)).value()), + timed_expiration_( + dict.contains(kValueTimedExpirationKey) + ? base::ValueToTime(*dict.Find(kValueTimedExpirationKey)) + : absl::optional<base::Time>()) {} + +// static +bool HostResolverInternalResult::ValidateValueBaseDict( + const base::Value::Dict& dict, + bool require_timed_expiration) { + const std::string* domain_name = dict.FindString(kValueDomainNameKey); + if (!domain_name) + return false; + + const std::string* query_type_string = dict.FindString(kValueQueryTypeKey); + if (!query_type_string) + return false; + const auto* query_type_it = + base::ranges::find(kDnsQueryTypes, *query_type_string, + &decltype(kDnsQueryTypes)::value_type::second); + if (query_type_it == kDnsQueryTypes.end()) + return false; + + const base::Value* type_value = dict.Find(kValueTypeKey); + if (!type_value) + return false; + absl::optional<Type> type = TypeFromValue(*type_value); + if (!type.has_value()) + return false; + + const base::Value* source_value = dict.Find(kValueSourceKey); + if (!source_value) + return false; + absl::optional<Source> source = SourceFromValue(*source_value); + if (!source.has_value()) + return false; + + absl::optional<base::Time> timed_expiration; + const base::Value* timed_expiration_value = + dict.Find(kValueTimedExpirationKey); + if (require_timed_expiration && !timed_expiration_value) + return false; + if (timed_expiration_value) { + timed_expiration = base::ValueToTime(timed_expiration_value); + if (!timed_expiration.has_value()) + return false; + } + + return true; +} + +base::Value::Dict HostResolverInternalResult::ToValueBaseDict() const { + base::Value::Dict dict; + + dict.Set(kValueDomainNameKey, domain_name_); + dict.Set(kValueQueryTypeKey, kDnsQueryTypes.at(query_type_)); + dict.Set(kValueTypeKey, TypeToValue(type_)); + dict.Set(kValueSourceKey, SourceToValue(source_)); + + // `expiration_` is not serialized because it is TimeTicks. + + if (timed_expiration_.has_value()) { + dict.Set(kValueTimedExpirationKey, + base::TimeToValue(timed_expiration_.value())); + } + + return dict; +} + +// static +std::unique_ptr<HostResolverInternalDataResult> +HostResolverInternalDataResult::FromValue(const base::Value& value) { + const base::Value::Dict* dict = value.GetIfDict(); + if (!dict || !ValidateValueBaseDict(*dict, /*require_timed_expiration=*/true)) + return nullptr; + + const base::Value::List* endpoint_values = dict->FindList(kValueEndpointsKey); + if (!endpoint_values) + return nullptr; + + std::vector<IPEndPoint> endpoints; + endpoints.reserve(endpoint_values->size()); + for (const base::Value& endpoint_value : *endpoint_values) { + absl::optional<IPEndPoint> endpoint = IPEndPoint::FromValue(endpoint_value); + if (!endpoint.has_value()) + return nullptr; + + endpoints.push_back(std::move(endpoint).value()); + } + + const base::Value::List* string_values = dict->FindList(kValueStringsKey); + if (!string_values) + return nullptr; + + std::vector<std::string> strings; + strings.reserve(string_values->size()); + for (const base::Value& string_value : *string_values) { + const std::string* string = string_value.GetIfString(); + if (!string) + return nullptr; + + strings.push_back(*string); + } + + const base::Value::List* host_values = dict->FindList(kValueHostsKey); + if (!host_values) + return nullptr; + + std::vector<HostPortPair> hosts; + hosts.reserve(host_values->size()); + for (const base::Value& host_value : *host_values) { + absl::optional<HostPortPair> host = HostPortPair::FromValue(host_value); + if (!host.has_value()) + return nullptr; + + hosts.push_back(std::move(host).value()); + } + + // WrapUnique due to private constructor. + return base::WrapUnique(new HostResolverInternalDataResult( + *dict, std::move(endpoints), std::move(strings), std::move(hosts))); +} + +HostResolverInternalDataResult::HostResolverInternalDataResult( + std::string domain_name, + DnsQueryType query_type, + absl::optional<base::TimeTicks> expiration, + base::Time timed_expiration, + Source source, + std::vector<IPEndPoint> endpoints, + std::vector<std::string> strings, + std::vector<HostPortPair> hosts) + : HostResolverInternalResult(std::move(domain_name), + query_type, + expiration, + timed_expiration, + Type::kData, + source), + endpoints_(std::move(endpoints)), + strings_(std::move(strings)), + hosts_(std::move(hosts)) { + DCHECK(!endpoints_.empty() || !strings_.empty() || !hosts_.empty()); +} + +HostResolverInternalDataResult::~HostResolverInternalDataResult() = default; + +base::Value HostResolverInternalDataResult::ToValue() const { + base::Value::Dict dict = ToValueBaseDict(); + + base::Value::List endpoints_list; + endpoints_list.reserve(endpoints_.size()); + for (IPEndPoint endpoint : endpoints_) { + endpoints_list.Append(endpoint.ToValue()); + } + dict.Set(kValueEndpointsKey, std::move(endpoints_list)); + + base::Value::List strings_list; + strings_list.reserve(strings_.size()); + for (const std::string& string : strings_) { + strings_list.Append(string); + } + dict.Set(kValueStringsKey, std::move(strings_list)); + + base::Value::List hosts_list; + hosts_list.reserve(hosts_.size()); + for (const HostPortPair& host : hosts_) { + hosts_list.Append(host.ToValue()); + } + dict.Set(kValueHostsKey, std::move(hosts_list)); + + return base::Value(std::move(dict)); +} + +HostResolverInternalDataResult::HostResolverInternalDataResult( + const base::Value::Dict& dict, + std::vector<IPEndPoint> endpoints, + std::vector<std::string> strings, + std::vector<HostPortPair> hosts) + : HostResolverInternalResult(dict), + endpoints_(std::move(endpoints)), + strings_(std::move(strings)), + hosts_(std::move(hosts)) {} + +// static +std::unique_ptr<HostResolverInternalMetadataResult> +HostResolverInternalMetadataResult::FromValue(const base::Value& value) { + const base::Value::Dict* dict = value.GetIfDict(); + if (!dict || !ValidateValueBaseDict(*dict, /*require_timed_expiration=*/true)) + return nullptr; + + const base::Value::List* metadata_values = dict->FindList(kValueMetadatasKey); + if (!metadata_values) + return nullptr; + + std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadatas; + for (const base::Value& metadata_value : *metadata_values) { + absl::optional<std::pair<HttpsRecordPriority, ConnectionEndpointMetadata>> + metadata = EndpointMetadataPairFromValue(metadata_value); + if (!metadata.has_value()) + return nullptr; + metadatas.insert(std::move(metadata).value()); + } + + // WrapUnique due to private constructor. + return base::WrapUnique( + new HostResolverInternalMetadataResult(*dict, std::move(metadatas))); +} + +HostResolverInternalMetadataResult::HostResolverInternalMetadataResult( + std::string domain_name, + DnsQueryType query_type, + absl::optional<base::TimeTicks> expiration, + base::Time timed_expiration, + Source source, + std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadatas) + : HostResolverInternalResult(std::move(domain_name), + query_type, + expiration, + timed_expiration, + Type::kMetadata, + source), + metadatas_(std::move(metadatas)) {} + +HostResolverInternalMetadataResult::~HostResolverInternalMetadataResult() = + default; + +base::Value HostResolverInternalMetadataResult::ToValue() const { + base::Value::Dict dict = ToValueBaseDict(); + + base::Value::List metadatas_list; + metadatas_list.reserve(metadatas_.size()); + for (const std::pair<const HttpsRecordPriority, ConnectionEndpointMetadata>& + metadata_pair : metadatas_) { + metadatas_list.Append(EndpointMetadataPairToValue(metadata_pair)); + } + dict.Set(kValueMetadatasKey, std::move(metadatas_list)); + + return base::Value(std::move(dict)); +} + +HostResolverInternalMetadataResult::HostResolverInternalMetadataResult( + const base::Value::Dict& dict, + std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadatas) + : HostResolverInternalResult(dict), metadatas_(std::move(metadatas)) {} + +// static +std::unique_ptr<HostResolverInternalErrorResult> +HostResolverInternalErrorResult::FromValue(const base::Value& value) { + const base::Value::Dict* dict = value.GetIfDict(); + if (!dict || + !ValidateValueBaseDict(*dict, /*require_timed_expiration=*/false)) { + return nullptr; + } + + absl::optional<int> error = dict->FindInt(kValueErrorKey); + if (!error.has_value()) + return nullptr; + + // WrapUnique due to private constructor. + return base::WrapUnique( + new HostResolverInternalErrorResult(*dict, error.value())); +} + +HostResolverInternalErrorResult::HostResolverInternalErrorResult( + std::string domain_name, + DnsQueryType query_type, + absl::optional<base::TimeTicks> expiration, + absl::optional<base::Time> timed_expiration, + Source source, + int error) + : HostResolverInternalResult(std::move(domain_name), + query_type, + expiration, + timed_expiration, + Type::kError, + source), + error_(error) {} + +base::Value HostResolverInternalErrorResult::ToValue() const { + base::Value::Dict dict = ToValueBaseDict(); + + dict.Set(kValueErrorKey, error_); + + return base::Value(std::move(dict)); +} + +HostResolverInternalErrorResult::HostResolverInternalErrorResult( + const base::Value::Dict& dict, + int error) + : HostResolverInternalResult(dict), error_(error) { + DCHECK_NE(error_, OK); +} + +// static +std::unique_ptr<HostResolverInternalAliasResult> +HostResolverInternalAliasResult::FromValue(const base::Value& value) { + const base::Value::Dict* dict = value.GetIfDict(); + if (!dict || !ValidateValueBaseDict(*dict, /*require_timed_expiration=*/true)) + return nullptr; + + const std::string* target = dict->FindString(kValueAliasTargetKey); + if (!target) + return nullptr; + + // WrapUnique due to private constructor. + return base::WrapUnique(new HostResolverInternalAliasResult(*dict, *target)); +} + +HostResolverInternalAliasResult::HostResolverInternalAliasResult( + std::string domain_name, + DnsQueryType query_type, + absl::optional<base::TimeTicks> expiration, + base::Time timed_expiration, + Source source, + std::string alias_target) + : HostResolverInternalResult(std::move(domain_name), + query_type, + expiration, + timed_expiration, + Type::kAlias, + source), + alias_target_(MaybeCanonicalizeName(std::move(alias_target))) { + DCHECK(!alias_target_.empty()); +} + +base::Value HostResolverInternalAliasResult::ToValue() const { + base::Value::Dict dict = ToValueBaseDict(); + + dict.Set(kValueAliasTargetKey, alias_target_); + + return base::Value(std::move(dict)); +} + +HostResolverInternalAliasResult::HostResolverInternalAliasResult( + const base::Value::Dict& dict, + std::string alias_target) + : HostResolverInternalResult(dict), + alias_target_(MaybeCanonicalizeName(std::move(alias_target))) {} + +} // namespace net
diff --git a/net/dns/host_resolver_internal_result.h b/net/dns/host_resolver_internal_result.h new file mode 100644 index 0000000..cf3ec725 --- /dev/null +++ b/net/dns/host_resolver_internal_result.h
@@ -0,0 +1,268 @@ +// 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 NET_DNS_HOST_RESOLVER_INTERNAL_RESULT_H_ +#define NET_DNS_HOST_RESOLVER_INTERNAL_RESULT_H_ + +#include <map> +#include <memory> +#include <string> +#include <tuple> +#include <vector> + +#include "base/time/time.h" +#include "base/values.h" +#include "net/base/connection_endpoint_metadata.h" +#include "net/base/host_port_pair.h" +#include "net/base/ip_endpoint.h" +#include "net/base/net_export.h" +#include "net/dns/https_record_rdata.h" +#include "net/dns/public/dns_query_type.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace net { + +class HostResolverInternalDataResult; +class HostResolverInternalMetadataResult; +class HostResolverInternalErrorResult; +class HostResolverInternalAliasResult; + +// Parsed and extracted result type for use internally to HostResolver code. +class NET_EXPORT_PRIVATE HostResolverInternalResult { + public: + enum class Type { kData, kMetadata, kError, kAlias }; + enum class Source { kDns, kHosts, kUnknown }; + + // Nullptr if `value` is malformed to be deserialized. + static std::unique_ptr<HostResolverInternalResult> FromValue( + const base::Value& value); + + virtual ~HostResolverInternalResult() = default; + + const std::string& domain_name() const { return domain_name_; } + DnsQueryType query_type() const { return query_type_; } + Type type() const { return type_; } + Source source() const { return source_; } + absl::optional<base::TimeTicks> expiration() const { return expiration_; } + absl::optional<base::Time> timed_expiration() const { + return timed_expiration_; + } + + const HostResolverInternalDataResult& AsData() const; + const HostResolverInternalMetadataResult& AsMetadata() const; + const HostResolverInternalErrorResult& AsError() const; + const HostResolverInternalAliasResult& AsAlias() const; + + virtual base::Value ToValue() const = 0; + + protected: + HostResolverInternalResult(std::string domain_name, + DnsQueryType query_type, + absl::optional<base::TimeTicks> expiration, + absl::optional<base::Time> timed_expiration, + Type type, + Source source); + // Expect to only be called with a `dict` well-formed for deserialization. Can + // be checked via ValidateValueBaseDict(). + explicit HostResolverInternalResult(const base::Value::Dict& dict); + + bool operator==(const HostResolverInternalResult& other) const { + return std::tie(domain_name_, query_type_, type_, source_, expiration_, + timed_expiration_) == + std::tie(other.domain_name_, other.query_type_, other.type_, + other.source_, other.expiration_, other.timed_expiration_); + } + + static bool ValidateValueBaseDict(const base::Value::Dict& dict, + bool require_timed_expiration); + base::Value::Dict ToValueBaseDict() const; + + private: + const std::string domain_name_; + const DnsQueryType query_type_; + const Type type_; + const Source source_; + + // Expiration logic should prefer to be based on `expiration_` for correctness + // through system time changes. But if result has been serialized to disk, it + // may be that only `timed_expiration_` is available. + const absl::optional<base::TimeTicks> expiration_; + const absl::optional<base::Time> timed_expiration_; +}; + +// Parsed and extracted result containing result data. +class NET_EXPORT_PRIVATE HostResolverInternalDataResult final + : public HostResolverInternalResult { + public: + static std::unique_ptr<HostResolverInternalDataResult> FromValue( + const base::Value& value); + + // `domain_name` is dotted form. + HostResolverInternalDataResult(std::string domain_name, + DnsQueryType query_type, + absl::optional<base::TimeTicks> expiration, + base::Time timed_expiration, + Source source, + std::vector<IPEndPoint> endpoints, + std::vector<std::string> strings, + std::vector<HostPortPair> hosts); + ~HostResolverInternalDataResult() override; + + HostResolverInternalDataResult(const HostResolverInternalDataResult&) = + delete; + HostResolverInternalDataResult& operator=( + const HostResolverInternalDataResult&) = delete; + + bool operator==(const HostResolverInternalDataResult& other) const { + return HostResolverInternalResult::operator==(other) && + std::tie(endpoints_, strings_, hosts_) == + std::tie(other.endpoints_, other.strings_, other.hosts_); + } + + const std::vector<IPEndPoint>& endpoints() const { return endpoints_; } + const std::vector<std::string>& strings() const { return strings_; } + const std::vector<HostPortPair>& hosts() const { return hosts_; } + + base::Value ToValue() const override; + + private: + HostResolverInternalDataResult(const base::Value::Dict& dict, + std::vector<IPEndPoint> endpoints, + std::vector<std::string> strings, + std::vector<HostPortPair> hosts); + + // Corresponds to the `HostResolverEndpointResult::ip_endpoints` portion of + // `HostResolver::ResolveHostRequest::GetEndpointResults()`. + const std::vector<IPEndPoint> endpoints_; + + // Corresponds to `HostResolver::ResolveHostRequest::GetTextResults()`. + const std::vector<std::string> strings_; + + // Corresponds to `HostResolver::ResolveHostRequest::GetHostnameResults()`. + const std::vector<HostPortPair> hosts_; +}; + +// Parsed and extracted connection metadata, but not usable on its own without +// being paired with separate HostResolverInternalDataResult data (for the +// domain name specified by `ConnectionEndpointMetadata::target_name`). An empty +// metadata result signifies that compatible HTTPS records were received but +// with no contained metadata of use to Chrome. +class NET_EXPORT_PRIVATE HostResolverInternalMetadataResult final + : public HostResolverInternalResult { + public: + static std::unique_ptr<HostResolverInternalMetadataResult> FromValue( + const base::Value& value); + + // `domain_name` and `data_domain` are dotted form domain names. + HostResolverInternalMetadataResult( + std::string domain_name, + DnsQueryType query_type, + absl::optional<base::TimeTicks> expiration, + base::Time timed_expiration, + Source source, + std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadatas); + ~HostResolverInternalMetadataResult() override; + + HostResolverInternalMetadataResult( + const HostResolverInternalMetadataResult&) = delete; + HostResolverInternalMetadataResult& operator=( + const HostResolverInternalMetadataResult&) = delete; + + bool operator==(const HostResolverInternalMetadataResult& other) const { + return HostResolverInternalResult::operator==(other) && + metadatas_ == other.metadatas_; + } + + const std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>& + metadatas() const { + return metadatas_; + } + + base::Value ToValue() const override; + + private: + HostResolverInternalMetadataResult( + const base::Value::Dict& dict, + std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadatas); + + std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadatas_; +}; + +// Parsed and extracted error. +class NET_EXPORT_PRIVATE HostResolverInternalErrorResult final + : public HostResolverInternalResult { + public: + static std::unique_ptr<HostResolverInternalErrorResult> FromValue( + const base::Value& value); + + // `domain_name` is dotted form. `timed_expiration` may be `nullopt` for + // non-cacheable errors. + HostResolverInternalErrorResult(std::string domain_name, + DnsQueryType query_type, + absl::optional<base::TimeTicks> expiration, + absl::optional<base::Time> timed_expiration, + Source source, + int error); + ~HostResolverInternalErrorResult() override = default; + + HostResolverInternalErrorResult(const HostResolverInternalErrorResult&) = + delete; + HostResolverInternalErrorResult& operator=( + const HostResolverInternalErrorResult&) = delete; + + bool operator==(const HostResolverInternalErrorResult& other) const { + return HostResolverInternalResult::operator==(other) && + error_ == other.error_; + } + + int error() const { return error_; } + + base::Value ToValue() const override; + + private: + HostResolverInternalErrorResult(const base::Value::Dict& dict, int error); + + const int error_; +}; + +// Parsed and extracted alias (CNAME or alias-type HTTPS). +class NET_EXPORT_PRIVATE HostResolverInternalAliasResult final + : public HostResolverInternalResult { + public: + static std::unique_ptr<HostResolverInternalAliasResult> FromValue( + const base::Value& value); + + // `domain_name` and `alias_target` are dotted form domain names. + HostResolverInternalAliasResult(std::string domain_name, + DnsQueryType query_type, + absl::optional<base::TimeTicks> expiration, + base::Time timed_expiration, + Source source, + std::string alias_target); + ~HostResolverInternalAliasResult() override = default; + + HostResolverInternalAliasResult(const HostResolverInternalAliasResult&) = + delete; + HostResolverInternalAliasResult& operator=( + const HostResolverInternalAliasResult&) = delete; + + bool operator==(const HostResolverInternalAliasResult& other) const { + return HostResolverInternalResult::operator==(other) && + alias_target_ == other.alias_target_; + } + + const std::string& alias_target() const { return alias_target_; } + + base::Value ToValue() const override; + + private: + HostResolverInternalAliasResult(const base::Value::Dict& dict, + std::string alias_target); + + const std::string alias_target_; +}; + +} // namespace net + +#endif // NET_DNS_HOST_RESOLVER_INTERNAL_RESULT_H_
diff --git a/net/dns/host_resolver_internal_result_unittest.cc b/net/dns/host_resolver_internal_result_unittest.cc new file mode 100644 index 0000000..a7271d0a --- /dev/null +++ b/net/dns/host_resolver_internal_result_unittest.cc
@@ -0,0 +1,614 @@ +// 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 "net/dns/host_resolver_internal_result.h" + +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include "base/json/json_reader.h" +#include "base/time/time.h" +#include "net/base/connection_endpoint_metadata.h" +#include "net/base/host_port_pair.h" +#include "net/base/ip_address.h" +#include "net/base/ip_endpoint.h" +#include "net/base/net_errors.h" +#include "net/dns/https_record_rdata.h" +#include "net/dns/public/dns_query_type.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +using ::testing::ElementsAre; +using ::testing::Optional; +using ::testing::Ref; + +namespace net { +namespace { + +TEST(HostResolverInternalResultTest, DeserializeMalformedValue) { + base::Value non_dict(base::Value::Type::BOOLEAN); + EXPECT_FALSE(HostResolverInternalResult::FromValue(non_dict)); + + base::Value missing_type(base::Value::Type::DICTIONARY); + EXPECT_FALSE(HostResolverInternalResult::FromValue(missing_type)); + + base::Value bad_type(base::Value::Type::DICTIONARY); + bad_type.GetDict().Set("type", "foo"); + EXPECT_FALSE(HostResolverInternalResult::FromValue(bad_type)); +} + +TEST(HostResolverInternalResultTest, DataResult) { + auto result = std::make_unique<HostResolverInternalDataResult>( + "domain.test", DnsQueryType::AAAA, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kDns, + std::vector<IPEndPoint>{IPEndPoint(IPAddress(2, 2, 2, 2), 46)}, + std::vector<std::string>{"foo", "bar"}, + std::vector<HostPortPair>{HostPortPair("anotherdomain.test", 112)}); + + EXPECT_EQ(result->domain_name(), "domain.test"); + EXPECT_EQ(result->query_type(), DnsQueryType::AAAA); + EXPECT_EQ(result->type(), HostResolverInternalResult::Type::kData); + EXPECT_EQ(result->source(), HostResolverInternalResult::Source::kDns); + EXPECT_THAT(result->expiration(), Optional(base::TimeTicks())); + EXPECT_THAT(result->timed_expiration(), Optional(base::Time())); + + EXPECT_THAT(result->AsData(), Ref(*result)); + + EXPECT_THAT(result->endpoints(), + ElementsAre(IPEndPoint(IPAddress(2, 2, 2, 2), 46))); + EXPECT_THAT(result->strings(), ElementsAre("foo", "bar")); + EXPECT_THAT(result->hosts(), + ElementsAre(HostPortPair("anotherdomain.test", 112))); +} + +TEST(HostResolverInternalResultTest, RoundtripDataResultThroughSerialization) { + auto result = std::make_unique<HostResolverInternalDataResult>( + "domain.test", DnsQueryType::AAAA, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kDns, + std::vector<IPEndPoint>{IPEndPoint(IPAddress(2, 2, 2, 2), 46)}, + std::vector<std::string>{"foo", "bar"}, + std::vector<HostPortPair>{HostPortPair("anotherdomain.test", 112)}); + + base::Value value = result->ToValue(); + auto deserialized = HostResolverInternalResult::FromValue(value); + ASSERT_TRUE(deserialized); + ASSERT_EQ(deserialized->type(), HostResolverInternalResult::Type::kData); + + // Expect deserialized result to be the same as the original other than + // missing non-timed expiration. + EXPECT_EQ(deserialized->AsData(), + HostResolverInternalDataResult( + result->domain_name(), result->query_type(), + /*expiration=*/absl::nullopt, + result->timed_expiration().value(), result->source(), + result->endpoints(), result->strings(), result->hosts())); +} + +// Expect results to serialize to a consistent base::Value format for +// consumption by NetLog and similar. +TEST(HostResolverInternalResultTest, SerializepDataResult) { + auto result = std::make_unique<HostResolverInternalDataResult>( + "domain.test", DnsQueryType::AAAA, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kDns, + std::vector<IPEndPoint>{IPEndPoint(IPAddress(2, 2, 2, 2), 46)}, + std::vector<std::string>{"foo", "bar"}, + std::vector<HostPortPair>{HostPortPair("anotherdomain.test", 112)}); + base::Value value = result->ToValue(); + + absl::optional<base::Value> expected = base::JSONReader::Read( + R"( + { + "domain_name": "domain.test", + "endpoints": [ + { + "address": "2.2.2.2", + "port": 46 + } + ], + "hosts": [ + { + "host": "anotherdomain.test", + "port": 112 + } + ], + "query_type": "AAAA", + "source": "dns", + "strings": [ + "foo", + "bar" + ], + "timed_expiration": "0", + "type": "data" + } + )"); + ASSERT_TRUE(expected.has_value()); + + EXPECT_EQ(value, expected.value()); +} + +TEST(HostResolverInternalResultTest, DeserializeMalformedDataValue) { + auto result = std::make_unique<HostResolverInternalDataResult>( + "domain.test", DnsQueryType::AAAA, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kDns, + std::vector<IPEndPoint>{IPEndPoint(IPAddress(2, 2, 2, 2), 46)}, + std::vector<std::string>{"foo", "bar"}, + std::vector<HostPortPair>{HostPortPair("anotherdomain.test", 112)}); + base::Value valid_value = result->ToValue(); + ASSERT_TRUE(HostResolverInternalDataResult::FromValue(valid_value)); + + base::Value missing_domain = valid_value.Clone(); + ASSERT_TRUE(missing_domain.GetDict().Remove("domain_name")); + EXPECT_FALSE(HostResolverInternalDataResult::FromValue(missing_domain)); + + base::Value missing_qtype = valid_value.Clone(); + ASSERT_TRUE(missing_qtype.GetDict().Remove("query_type")); + EXPECT_FALSE(HostResolverInternalDataResult::FromValue(missing_qtype)); + base::Value unknown_qtype = valid_value.Clone(); + ASSERT_TRUE(unknown_qtype.GetDict().Set("query_type", "foo")); + EXPECT_FALSE(HostResolverInternalDataResult::FromValue(unknown_qtype)); + + base::Value missing_value_type = valid_value.Clone(); + ASSERT_TRUE(missing_value_type.GetDict().Remove("type")); + EXPECT_FALSE(HostResolverInternalDataResult::FromValue(missing_value_type)); + base::Value unknown_value_type = valid_value.Clone(); + ASSERT_TRUE(unknown_value_type.GetDict().Set("type", "foo")); + EXPECT_FALSE(HostResolverInternalDataResult::FromValue(unknown_value_type)); + + base::Value missing_source = valid_value.Clone(); + ASSERT_TRUE(missing_source.GetDict().Remove("source")); + EXPECT_FALSE(HostResolverInternalDataResult::FromValue(missing_source)); + base::Value unknown_source = valid_value.Clone(); + ASSERT_TRUE(unknown_source.GetDict().Set("source", "foo")); + EXPECT_FALSE(HostResolverInternalDataResult::FromValue(unknown_source)); + + base::Value missing_expiration = valid_value.Clone(); + ASSERT_TRUE(missing_expiration.GetDict().Remove("timed_expiration")); + EXPECT_FALSE(HostResolverInternalDataResult::FromValue(missing_expiration)); + base::Value invalid_expiration = valid_value.Clone(); + ASSERT_TRUE(invalid_expiration.GetDict().Set("timed_expiration", "foo")); + EXPECT_FALSE(HostResolverInternalDataResult::FromValue(invalid_expiration)); + + base::Value missing_endpoints = valid_value.Clone(); + ASSERT_TRUE(missing_endpoints.GetDict().Remove("endpoints")); + EXPECT_FALSE(HostResolverInternalDataResult::FromValue(missing_endpoints)); + base::Value invalid_endpoint = valid_value.Clone(); + invalid_endpoint.GetDict().FindList("endpoints")->front() = + base::Value("foo"); + EXPECT_FALSE(HostResolverInternalDataResult::FromValue(invalid_endpoint)); + + base::Value missing_strings = valid_value.Clone(); + ASSERT_TRUE(missing_strings.GetDict().Remove("strings")); + EXPECT_FALSE(HostResolverInternalDataResult::FromValue(missing_strings)); + base::Value invalid_string = valid_value.Clone(); + invalid_string.GetDict().FindList("strings")->front() = base::Value(5); + EXPECT_FALSE(HostResolverInternalDataResult::FromValue(invalid_string)); + + base::Value missing_hosts = valid_value.Clone(); + ASSERT_TRUE(missing_hosts.GetDict().Remove("hosts")); + EXPECT_FALSE(HostResolverInternalDataResult::FromValue(missing_hosts)); + base::Value invalid_hosts = valid_value.Clone(); + invalid_hosts.GetDict().FindList("hosts")->front() = base::Value("foo"); + EXPECT_FALSE(HostResolverInternalDataResult::FromValue(invalid_hosts)); +} + +TEST(HostResolverInternalResultTest, MetadataResult) { + const ConnectionEndpointMetadata kMetadata( + /*supported_protocol_alpns=*/{"http/1.1", "h3"}, + /*ech_config_list=*/{0x01, 0x13}, + /*target_name*/ "target.test"); + auto result = std::make_unique<HostResolverInternalMetadataResult>( + "domain1.test", DnsQueryType::HTTPS, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kDns, + std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>{ + {4, kMetadata}}); + + EXPECT_EQ(result->domain_name(), "domain1.test"); + EXPECT_EQ(result->query_type(), DnsQueryType::HTTPS); + EXPECT_EQ(result->type(), HostResolverInternalResult::Type::kMetadata); + EXPECT_EQ(result->source(), HostResolverInternalResult::Source::kDns); + EXPECT_THAT(result->expiration(), Optional(base::TimeTicks())); + EXPECT_THAT(result->timed_expiration(), Optional(base::Time())); + + EXPECT_THAT(result->AsMetadata(), Ref(*result)); + + EXPECT_THAT(result->metadatas(), ElementsAre(std::make_pair(4, kMetadata))); +} + +TEST(HostResolverInternalResultTest, + RoundtripMetadataResultThroughSerialization) { + const ConnectionEndpointMetadata kMetadata( + /*supported_protocol_alpns=*/{"http/1.1", "h2", "h3"}, + /*ech_config_list=*/{0x01, 0x13, 0x15}, + /*target_name*/ "target1.test"); + auto result = std::make_unique<HostResolverInternalMetadataResult>( + "domain2.test", DnsQueryType::HTTPS, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kDns, + std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>{ + {2, kMetadata}}); + + base::Value value = result->ToValue(); + auto deserialized = HostResolverInternalResult::FromValue(value); + ASSERT_TRUE(deserialized); + ASSERT_EQ(deserialized->type(), HostResolverInternalResult::Type::kMetadata); + + // Expect deserialized result to be the same as the original other than + // missing non-timed expiration. + EXPECT_EQ( + deserialized->AsMetadata(), + HostResolverInternalMetadataResult( + result->domain_name(), result->query_type(), + /*expiration=*/absl::nullopt, result->timed_expiration().value(), + result->source(), result->metadatas())); +} + +// Expect results to serialize to a consistent base::Value format for +// consumption by NetLog and similar. +TEST(HostResolverInternalResultTest, SerializepMetadataResult) { + const ConnectionEndpointMetadata kMetadata( + /*supported_protocol_alpns=*/{"http/1.1", "h2", "h3"}, + /*ech_config_list=*/{0x01, 0x13, 0x15}, + /*target_name*/ "target1.test"); + auto result = std::make_unique<HostResolverInternalMetadataResult>( + "domain2.test", DnsQueryType::HTTPS, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kDns, + std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>{ + {2, kMetadata}}); + base::Value value = result->ToValue(); + + // Note that the `ech_config_list` base64 encodes to "ARMV". + absl::optional<base::Value> expected = base::JSONReader::Read( + R"( + { + "domain_name": "domain2.test", + "metadatas": [ + { + "metadata_value": + { + "ech_config_list": "ARMV", + "supported_protocol_alpns": ["http/1.1", "h2", "h3"], + "target_name": "target1.test" + }, + "metadata_weight": 2 + } + ], + "query_type": "HTTPS", + "source": "dns", + "timed_expiration": "0", + "type": "metadata" + } + )"); + ASSERT_TRUE(expected.has_value()); + + EXPECT_EQ(value, expected.value()); +} + +TEST(HostResolverInternalResultTest, DeserializeMalformedMetadataValue) { + const ConnectionEndpointMetadata kMetadata( + /*supported_protocol_alpns=*/{"http/1.1", "h2", "h3"}, + /*ech_config_list=*/{0x01, 0x13, 0x15}, + /*target_name*/ "target1.test"); + auto result = std::make_unique<HostResolverInternalMetadataResult>( + "domain2.test", DnsQueryType::HTTPS, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kDns, + std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>{ + {2, kMetadata}}); + base::Value valid_value = result->ToValue(); + ASSERT_TRUE(HostResolverInternalMetadataResult::FromValue(valid_value)); + + base::Value missing_domain = valid_value.Clone(); + ASSERT_TRUE(missing_domain.GetDict().Remove("domain_name")); + EXPECT_FALSE(HostResolverInternalMetadataResult::FromValue(missing_domain)); + + base::Value missing_qtype = valid_value.Clone(); + ASSERT_TRUE(missing_qtype.GetDict().Remove("query_type")); + EXPECT_FALSE(HostResolverInternalMetadataResult::FromValue(missing_qtype)); + base::Value unknown_qtype = valid_value.Clone(); + ASSERT_TRUE(unknown_qtype.GetDict().Set("query_type", "foo")); + EXPECT_FALSE(HostResolverInternalMetadataResult::FromValue(unknown_qtype)); + + base::Value missing_value_type = valid_value.Clone(); + ASSERT_TRUE(missing_value_type.GetDict().Remove("type")); + EXPECT_FALSE( + HostResolverInternalMetadataResult::FromValue(missing_value_type)); + base::Value unknown_value_type = valid_value.Clone(); + ASSERT_TRUE(unknown_value_type.GetDict().Set("type", "foo")); + EXPECT_FALSE( + HostResolverInternalMetadataResult::FromValue(unknown_value_type)); + + base::Value missing_source = valid_value.Clone(); + ASSERT_TRUE(missing_source.GetDict().Remove("source")); + EXPECT_FALSE(HostResolverInternalMetadataResult::FromValue(missing_source)); + base::Value unknown_source = valid_value.Clone(); + ASSERT_TRUE(unknown_source.GetDict().Set("source", "foo")); + EXPECT_FALSE(HostResolverInternalMetadataResult::FromValue(unknown_source)); + + base::Value missing_expiration = valid_value.Clone(); + ASSERT_TRUE(missing_expiration.GetDict().Remove("timed_expiration")); + EXPECT_FALSE( + HostResolverInternalMetadataResult::FromValue(missing_expiration)); + base::Value invalid_expiration = valid_value.Clone(); + ASSERT_TRUE(invalid_expiration.GetDict().Set("timed_expiration", "foo")); + EXPECT_FALSE( + HostResolverInternalMetadataResult::FromValue(invalid_expiration)); + + base::Value missing_metadatas = valid_value.Clone(); + ASSERT_TRUE(missing_metadatas.GetDict().Remove("metadatas")); + EXPECT_FALSE( + HostResolverInternalMetadataResult::FromValue(missing_metadatas)); + base::Value invalid_metadatas = valid_value.Clone(); + *invalid_metadatas.GetDict().Find("metadatas") = base::Value(4); + EXPECT_FALSE( + HostResolverInternalMetadataResult::FromValue(invalid_metadatas)); + + base::Value missing_weight = valid_value.Clone(); + ASSERT_TRUE(missing_weight.GetDict() + .Find("metadatas") + ->GetList() + .front() + .GetDict() + .Remove("metadata_weight")); + EXPECT_FALSE(HostResolverInternalMetadataResult::FromValue(missing_weight)); + base::Value invalid_weight = valid_value.Clone(); + *invalid_weight.GetDict() + .Find("metadatas") + ->GetList() + .front() + .GetDict() + .Find("metadata_weight") = base::Value("foo"); + EXPECT_FALSE(HostResolverInternalMetadataResult::FromValue(invalid_weight)); + + base::Value missing_value = valid_value.Clone(); + ASSERT_TRUE(missing_value.GetDict() + .Find("metadatas") + ->GetList() + .front() + .GetDict() + .Remove("metadata_value")); + EXPECT_FALSE(HostResolverInternalMetadataResult::FromValue(missing_value)); + base::Value invalid_value = valid_value.Clone(); + *invalid_value.GetDict() + .Find("metadatas") + ->GetList() + .front() + .GetDict() + .Find("metadata_value") = base::Value("foo"); + EXPECT_FALSE(HostResolverInternalMetadataResult::FromValue(invalid_value)); +} + +TEST(HostResolverInternalResultTest, ErrorResult) { + auto result = std::make_unique<HostResolverInternalErrorResult>( + "domain3.test", DnsQueryType::PTR, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kUnknown, ERR_NAME_NOT_RESOLVED); + + EXPECT_EQ(result->domain_name(), "domain3.test"); + EXPECT_EQ(result->query_type(), DnsQueryType::PTR); + EXPECT_EQ(result->type(), HostResolverInternalResult::Type::kError); + EXPECT_EQ(result->source(), HostResolverInternalResult::Source::kUnknown); + EXPECT_THAT(result->expiration(), Optional(base::TimeTicks())); + EXPECT_THAT(result->timed_expiration(), Optional(base::Time())); + + EXPECT_THAT(result->AsError(), Ref(*result)); + + EXPECT_EQ(result->error(), ERR_NAME_NOT_RESOLVED); +} + +TEST(HostResolverInternalResultTest, NoncachableErrorResult) { + auto result = std::make_unique<HostResolverInternalErrorResult>( + "domain3.test", DnsQueryType::PTR, /*expiration=*/absl::nullopt, + /*timed_expiration=*/absl::nullopt, + HostResolverInternalResult::Source::kUnknown, ERR_NAME_NOT_RESOLVED); + + EXPECT_EQ(result->domain_name(), "domain3.test"); + EXPECT_EQ(result->query_type(), DnsQueryType::PTR); + EXPECT_EQ(result->type(), HostResolverInternalResult::Type::kError); + EXPECT_EQ(result->source(), HostResolverInternalResult::Source::kUnknown); + EXPECT_FALSE(result->expiration().has_value()); + EXPECT_FALSE(result->timed_expiration().has_value()); + + EXPECT_THAT(result->AsError(), Ref(*result)); + + EXPECT_EQ(result->error(), ERR_NAME_NOT_RESOLVED); +} + +TEST(HostResolverInternalResultTest, RoundtripErrorResultThroughSerialization) { + auto result = std::make_unique<HostResolverInternalErrorResult>( + "domain4.test", DnsQueryType::A, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kDns, ERR_DNS_SERVER_FAILED); + + base::Value value = result->ToValue(); + auto deserialized = HostResolverInternalResult::FromValue(value); + ASSERT_TRUE(deserialized); + ASSERT_EQ(deserialized->type(), HostResolverInternalResult::Type::kError); + + // Expect deserialized result to be the same as the original other than + // missing non-timed expiration. + EXPECT_EQ(deserialized->AsError(), + HostResolverInternalErrorResult(result->domain_name(), + result->query_type(), + /*expiration=*/absl::nullopt, + result->timed_expiration().value(), + result->source(), result->error())); +} + +// Expect results to serialize to a consistent base::Value format for +// consumption by NetLog and similar. +TEST(HostResolverInternalResultTest, SerializepErrorResult) { + auto result = std::make_unique<HostResolverInternalErrorResult>( + "domain4.test", DnsQueryType::A, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kDns, ERR_DNS_SERVER_FAILED); + base::Value value = result->ToValue(); + + absl::optional<base::Value> expected = base::JSONReader::Read( + R"( + { + "domain_name": "domain4.test", + "error": -802, + "query_type": "A", + "source": "dns", + "timed_expiration": "0", + "type": "error" + } + )"); + ASSERT_TRUE(expected.has_value()); + + EXPECT_EQ(value, expected.value()); +} + +TEST(HostResolverInternalResultTest, DeserializeMalformedErrorValue) { + auto result = std::make_unique<HostResolverInternalErrorResult>( + "domain4.test", DnsQueryType::A, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kDns, ERR_DNS_SERVER_FAILED); + base::Value valid_value = result->ToValue(); + ASSERT_TRUE(HostResolverInternalErrorResult::FromValue(valid_value)); + + base::Value missing_domain = valid_value.Clone(); + ASSERT_TRUE(missing_domain.GetDict().Remove("domain_name")); + EXPECT_FALSE(HostResolverInternalErrorResult::FromValue(missing_domain)); + + base::Value missing_qtype = valid_value.Clone(); + ASSERT_TRUE(missing_qtype.GetDict().Remove("query_type")); + EXPECT_FALSE(HostResolverInternalErrorResult::FromValue(missing_qtype)); + base::Value unknown_qtype = valid_value.Clone(); + ASSERT_TRUE(unknown_qtype.GetDict().Set("query_type", "foo")); + EXPECT_FALSE(HostResolverInternalErrorResult::FromValue(unknown_qtype)); + + base::Value missing_value_type = valid_value.Clone(); + ASSERT_TRUE(missing_value_type.GetDict().Remove("type")); + EXPECT_FALSE(HostResolverInternalErrorResult::FromValue(missing_value_type)); + base::Value unknown_value_type = valid_value.Clone(); + ASSERT_TRUE(unknown_value_type.GetDict().Set("type", "foo")); + EXPECT_FALSE(HostResolverInternalErrorResult::FromValue(unknown_value_type)); + + base::Value missing_source = valid_value.Clone(); + ASSERT_TRUE(missing_source.GetDict().Remove("source")); + EXPECT_FALSE(HostResolverInternalErrorResult::FromValue(missing_source)); + base::Value unknown_source = valid_value.Clone(); + ASSERT_TRUE(unknown_source.GetDict().Set("source", "foo")); + EXPECT_FALSE(HostResolverInternalErrorResult::FromValue(unknown_source)); + + base::Value invalid_expiration = valid_value.Clone(); + ASSERT_TRUE(invalid_expiration.GetDict().Set("timed_expiration", "foo")); + EXPECT_FALSE(HostResolverInternalErrorResult::FromValue(invalid_expiration)); + + base::Value missing_error = valid_value.Clone(); + ASSERT_TRUE(missing_error.GetDict().Remove("error")); + EXPECT_FALSE(HostResolverInternalErrorResult::FromValue(missing_error)); + base::Value invalid_error = valid_value.Clone(); + *invalid_error.GetDict().Find("error") = base::Value("foo"); + EXPECT_FALSE(HostResolverInternalErrorResult::FromValue(invalid_error)); +} + +TEST(HostResolverInternalResultTest, AliasResult) { + auto result = std::make_unique<HostResolverInternalAliasResult>( + "domain5.test", DnsQueryType::HTTPS, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kDns, "alias_target.test"); + + EXPECT_EQ(result->domain_name(), "domain5.test"); + EXPECT_EQ(result->query_type(), DnsQueryType::HTTPS); + EXPECT_EQ(result->type(), HostResolverInternalResult::Type::kAlias); + EXPECT_EQ(result->source(), HostResolverInternalResult::Source::kDns); + EXPECT_THAT(result->expiration(), Optional(base::TimeTicks())); + EXPECT_THAT(result->timed_expiration(), Optional(base::Time())); + + EXPECT_THAT(result->AsAlias(), Ref(*result)); + + EXPECT_THAT(result->alias_target(), "alias_target.test"); +} + +TEST(HostResolverInternalResultTest, RoundtripAliasResultThroughSerialization) { + auto result = std::make_unique<HostResolverInternalAliasResult>( + "domain6.test", DnsQueryType::AAAA, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kDns, "alias_target1.test"); + + base::Value value = result->ToValue(); + auto deserialized = HostResolverInternalResult::FromValue(value); + ASSERT_TRUE(deserialized); + ASSERT_EQ(deserialized->type(), HostResolverInternalResult::Type::kAlias); + + // Expect deserialized result to be the same as the original other than + // missing non-timed expiration. + EXPECT_EQ( + deserialized->AsAlias(), + HostResolverInternalAliasResult( + result->domain_name(), result->query_type(), + /*expiration=*/absl::nullopt, result->timed_expiration().value(), + result->source(), result->alias_target())); +} + +// Expect results to serialize to a consistent base::Value format for +// consumption by NetLog and similar. +TEST(HostResolverInternalResultTest, SerializepAliasResult) { + auto result = std::make_unique<HostResolverInternalAliasResult>( + "domain6.test", DnsQueryType::AAAA, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kDns, "alias_target1.test"); + base::Value value = result->ToValue(); + + absl::optional<base::Value> expected = base::JSONReader::Read( + R"( + { + "alias_target": "alias_target1.test", + "domain_name": "domain6.test", + "query_type": "AAAA", + "source": "dns", + "timed_expiration": "0", + "type": "alias" + } + )"); + ASSERT_TRUE(expected.has_value()); + + EXPECT_EQ(value, expected.value()); +} + +TEST(HostResolverInternalResultTest, DeserializeMalformedAliasValue) { + auto result = std::make_unique<HostResolverInternalAliasResult>( + "domain6.test", DnsQueryType::AAAA, base::TimeTicks(), base::Time(), + HostResolverInternalResult::Source::kDns, "alias_target1.test"); + base::Value valid_value = result->ToValue(); + ASSERT_TRUE(HostResolverInternalAliasResult::FromValue(valid_value)); + + base::Value missing_domain = valid_value.Clone(); + ASSERT_TRUE(missing_domain.GetDict().Remove("domain_name")); + EXPECT_FALSE(HostResolverInternalAliasResult::FromValue(missing_domain)); + + base::Value missing_qtype = valid_value.Clone(); + ASSERT_TRUE(missing_qtype.GetDict().Remove("query_type")); + EXPECT_FALSE(HostResolverInternalAliasResult::FromValue(missing_qtype)); + base::Value unknown_qtype = valid_value.Clone(); + ASSERT_TRUE(unknown_qtype.GetDict().Set("query_type", "foo")); + EXPECT_FALSE(HostResolverInternalAliasResult::FromValue(unknown_qtype)); + + base::Value missing_value_type = valid_value.Clone(); + ASSERT_TRUE(missing_value_type.GetDict().Remove("type")); + EXPECT_FALSE(HostResolverInternalAliasResult::FromValue(missing_value_type)); + base::Value unknown_value_type = valid_value.Clone(); + ASSERT_TRUE(unknown_value_type.GetDict().Set("type", "foo")); + EXPECT_FALSE(HostResolverInternalAliasResult::FromValue(unknown_value_type)); + + base::Value missing_source = valid_value.Clone(); + ASSERT_TRUE(missing_source.GetDict().Remove("source")); + EXPECT_FALSE(HostResolverInternalAliasResult::FromValue(missing_source)); + base::Value unknown_source = valid_value.Clone(); + ASSERT_TRUE(unknown_source.GetDict().Set("source", "foo")); + EXPECT_FALSE(HostResolverInternalAliasResult::FromValue(unknown_source)); + + base::Value missing_expiration = valid_value.Clone(); + ASSERT_TRUE(missing_expiration.GetDict().Remove("timed_expiration")); + EXPECT_FALSE(HostResolverInternalAliasResult::FromValue(missing_expiration)); + base::Value invalid_expiration = valid_value.Clone(); + ASSERT_TRUE(invalid_expiration.GetDict().Set("timed_expiration", "foo")); + EXPECT_FALSE(HostResolverInternalAliasResult::FromValue(invalid_expiration)); + + base::Value missing_alias = valid_value.Clone(); + ASSERT_TRUE(missing_alias.GetDict().Remove("alias_target")); + EXPECT_FALSE(HostResolverInternalAliasResult::FromValue(missing_alias)); + base::Value invalid_alias = valid_value.Clone(); + *invalid_alias.GetDict().Find("alias_target") = base::Value(5); + EXPECT_FALSE(HostResolverInternalAliasResult::FromValue(invalid_alias)); +} + +} // namespace +} // namespace net
diff --git a/net/test/test_connection_cost_observer.cc b/net/test/test_connection_cost_observer.cc deleted file mode 100644 index 7967e63e..0000000 --- a/net/test/test_connection_cost_observer.cc +++ /dev/null
@@ -1,51 +0,0 @@ -// 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 "net/test/test_connection_cost_observer.h" - -namespace net { - -TestConnectionCostObserver::TestConnectionCostObserver() = default; - -TestConnectionCostObserver::~TestConnectionCostObserver() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -} - -void TestConnectionCostObserver::OnConnectionCostChanged( - NetworkChangeNotifier::ConnectionCost cost) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - cost_changed_inputs_.push_back(cost); - - if (run_loop_) { - run_loop_->Quit(); - } -} - -void TestConnectionCostObserver::WaitForConnectionCostChanged() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - run_loop_ = std::make_unique<base::RunLoop>(); - run_loop_->Run(); - run_loop_.reset(); -} - -size_t TestConnectionCostObserver::cost_changed_calls() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return cost_changed_inputs_.size(); -} - -std::vector<NetworkChangeNotifier::ConnectionCost> -TestConnectionCostObserver::cost_changed_inputs() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return cost_changed_inputs_; -} - -NetworkChangeNotifier::ConnectionCost -TestConnectionCostObserver::last_cost_changed_input() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK_GT(cost_changed_inputs_.size(), 0u); - return cost_changed_inputs_.back(); -} - -} // namespace net
diff --git a/net/test/test_connection_cost_observer.h b/net/test/test_connection_cost_observer.h deleted file mode 100644 index 913368a..0000000 --- a/net/test/test_connection_cost_observer.h +++ /dev/null
@@ -1,47 +0,0 @@ -// 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 NET_TEST_TEST_CONNECTION_COST_OBSERVER_H_ -#define NET_TEST_TEST_CONNECTION_COST_OBSERVER_H_ - -#include "base/run_loop.h" -#include "base/sequence_checker.h" -#include "net/base/network_change_notifier.h" - -namespace net { - -class TestConnectionCostObserver final - : public NetworkChangeNotifier::ConnectionCostObserver { - public: - TestConnectionCostObserver(); - ~TestConnectionCostObserver() final; - - void OnConnectionCostChanged( - NetworkChangeNotifier::ConnectionCost cost) final; - - void WaitForConnectionCostChanged(); - - size_t cost_changed_calls() const; - std::vector<NetworkChangeNotifier::ConnectionCost> cost_changed_inputs() - const; - NetworkChangeNotifier::ConnectionCost last_cost_changed_input() const; - - TestConnectionCostObserver(const TestConnectionCostObserver&) = delete; - TestConnectionCostObserver& operator=(const TestConnectionCostObserver&) = - delete; - - private: - SEQUENCE_CHECKER(sequence_checker_); - - // Set and used to block in `WaitForConnectionCostChanged()` until the next - // cost changed event occurs. - std::unique_ptr<base::RunLoop> run_loop_; - - // Record each `OnConnectionCostChanged()` call. - std::vector<NetworkChangeNotifier::ConnectionCost> cost_changed_inputs_; -}; - -} // namespace net - -#endif // NET_TEST_TEST_CONNECTION_COST_OBSERVER_H_
diff --git a/net/test/win/fake_network_cost_manager.cc b/net/test/win/fake_network_cost_manager.cc deleted file mode 100644 index 7c053ff..0000000 --- a/net/test/win/fake_network_cost_manager.cc +++ /dev/null
@@ -1,309 +0,0 @@ -// 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 "net/test/win/fake_network_cost_manager.h" - -#include <netlistmgr.h> -#include <wrl/implements.h> - -#include <map> - -#include "net/base/network_cost_change_notifier_win.h" - -using Microsoft::WRL::ClassicCom; -using Microsoft::WRL::ComPtr; -using Microsoft::WRL::RuntimeClass; -using Microsoft::WRL::RuntimeClassFlags; - -namespace net { - -namespace { - -DWORD NlmConnectionCostFlagsFromConnectionCost( - NetworkChangeNotifier::ConnectionCost source_cost) { - switch (source_cost) { - case NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNMETERED: - return (NLM_CONNECTION_COST_UNRESTRICTED | NLM_CONNECTION_COST_CONGESTED); - case NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_METERED: - return (NLM_CONNECTION_COST_VARIABLE | NLM_CONNECTION_COST_ROAMING | - NLM_CONNECTION_COST_APPROACHINGDATALIMIT); - case NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNKNOWN: - default: - return NLM_CONNECTION_COST_UNKNOWN; - } -} - -void DispatchCostChangedEvent(ComPtr<INetworkCostManagerEvents> event_target, - DWORD cost) { - std::ignore = - event_target->CostChanged(cost, /*destination_address=*/nullptr); -} - -} // namespace - -// A fake implementation of INetworkCostManager that can simulate costs, changed -// costs and errors. -class FakeNetworkCostManager final - : public RuntimeClass<RuntimeClassFlags<ClassicCom>, - INetworkCostManager, - IConnectionPointContainer, - IConnectionPoint> { - public: - FakeNetworkCostManager(NetworkChangeNotifier::ConnectionCost connection_cost, - NetworkCostManagerStatus error_status) - : error_status_(error_status), connection_cost_(connection_cost) {} - - // For each event sink in `event_sinks_`, call - // `INetworkCostManagerEvents::CostChanged` with `changed_cost` on the event - // sink's task runner. - void PostCostChangedEvents( - NetworkChangeNotifier::ConnectionCost changed_cost) { - DWORD cost_for_changed_event; - std::map</*event_sink_cookie=*/DWORD, EventSinkRegistration> - event_sinks_for_changed_event; - { - base::AutoLock auto_lock(member_lock_); - connection_cost_ = changed_cost; - cost_for_changed_event = - NlmConnectionCostFlagsFromConnectionCost(changed_cost); - - // Get the snapshot of event sinks to notify. The snapshot collection - // creates a new ComPtr for each event sink, which increments each the - // event sink's reference count, ensuring that each event sink - // remains alive to receive the cost changed event notification. - event_sinks_for_changed_event = event_sinks_; - } - - for (const auto& pair : event_sinks_for_changed_event) { - const auto& registration = pair.second; - registration.event_sink_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&DispatchCostChangedEvent, registration.event_sink_, - cost_for_changed_event)); - } - } - - // Implement the INetworkCostManager interface. - HRESULT - __stdcall GetCost(DWORD* cost, - NLM_SOCKADDR* destination_ip_address) override { - if (error_status_ == NetworkCostManagerStatus::kErrorGetCostFailed) { - return E_FAIL; - } - - if (destination_ip_address != nullptr) { - NOTIMPLEMENTED(); - return E_NOTIMPL; - } - - { - base::AutoLock auto_lock(member_lock_); - *cost = NlmConnectionCostFlagsFromConnectionCost(connection_cost_); - } - return S_OK; - } - - HRESULT __stdcall GetDataPlanStatus( - NLM_DATAPLAN_STATUS* data_plan_status, - NLM_SOCKADDR* destination_ip_address) override { - NOTIMPLEMENTED(); - return E_NOTIMPL; - } - - HRESULT __stdcall SetDestinationAddresses( - UINT32 length, - NLM_SOCKADDR* destination_ip_address_list, - VARIANT_BOOL append) override { - NOTIMPLEMENTED(); - return E_NOTIMPL; - } - - // Implement the IConnectionPointContainer interface. - HRESULT __stdcall FindConnectionPoint(REFIID connection_point_id, - IConnectionPoint** result) override { - if (error_status_ == - NetworkCostManagerStatus::kErrorFindConnectionPointFailed) { - return E_ABORT; - } - - if (connection_point_id != IID_INetworkCostManagerEvents) { - return E_NOINTERFACE; - } - - *result = static_cast<IConnectionPoint*>(this); - AddRef(); - return S_OK; - } - - HRESULT __stdcall EnumConnectionPoints( - IEnumConnectionPoints** results) override { - NOTIMPLEMENTED(); - return E_NOTIMPL; - } - - // Implement the IConnectionPoint interface. - HRESULT __stdcall Advise(IUnknown* event_sink, - DWORD* event_sink_cookie) override { - if (error_status_ == NetworkCostManagerStatus::kErrorAdviseFailed) { - return E_NOT_VALID_STATE; - } - - ComPtr<INetworkCostManagerEvents> cost_manager_event_sink; - HRESULT hr = - event_sink->QueryInterface(IID_PPV_ARGS(&cost_manager_event_sink)); - if (hr != S_OK) { - return hr; - } - - base::AutoLock auto_lock(member_lock_); - - event_sinks_[next_event_sink_cookie_] = { - cost_manager_event_sink, base::SequencedTaskRunnerHandle::Get()}; - - *event_sink_cookie = next_event_sink_cookie_; - ++next_event_sink_cookie_; - - return S_OK; - } - - HRESULT __stdcall Unadvise(DWORD event_sink_cookie) override { - base::AutoLock auto_lock(member_lock_); - - auto it = event_sinks_.find(event_sink_cookie); - if (it == event_sinks_.end()) { - return ERROR_NOT_FOUND; - } - - event_sinks_.erase(it); - return S_OK; - } - - HRESULT __stdcall GetConnectionInterface(IID* result) override { - NOTIMPLEMENTED(); - return E_NOTIMPL; - } - - HRESULT __stdcall GetConnectionPointContainer( - IConnectionPointContainer** result) override { - NOTIMPLEMENTED(); - return E_NOTIMPL; - } - - HRESULT __stdcall EnumConnections(IEnumConnections** result) override { - NOTIMPLEMENTED(); - return E_NOTIMPL; - } - - // Implement the IUnknown interface. - HRESULT __stdcall QueryInterface(REFIID interface_id, - void** result) override { - if (error_status_ == NetworkCostManagerStatus::kErrorQueryInterfaceFailed) { - return E_NOINTERFACE; - } - return RuntimeClass<RuntimeClassFlags<ClassicCom>, INetworkCostManager, - IConnectionPointContainer, - IConnectionPoint>::QueryInterface(interface_id, result); - } - - FakeNetworkCostManager(const FakeNetworkCostManager&) = delete; - FakeNetworkCostManager& operator=(const FakeNetworkCostManager&) = delete; - - private: - // The error state for this FakeNetworkCostManager to simulate. Cannot be - // changed. - const NetworkCostManagerStatus error_status_; - - // Synchronizes access to all members below. - base::Lock member_lock_; - - NetworkChangeNotifier::ConnectionCost connection_cost_ - GUARDED_BY(member_lock_); - - DWORD next_event_sink_cookie_ GUARDED_BY(member_lock_) = 0; - - struct EventSinkRegistration { - ComPtr<INetworkCostManagerEvents> event_sink_; - scoped_refptr<base::SequencedTaskRunner> event_sink_task_runner_; - }; - std::map</*event_sink_cookie=*/DWORD, EventSinkRegistration> event_sinks_ - GUARDED_BY(member_lock_); -}; - -FakeNetworkCostManagerEnvironment::FakeNetworkCostManagerEnvironment() { - // Set up NetworkCostChangeNotifierWin to use the fake OS APIs. - NetworkCostChangeNotifierWin::OverrideCoCreateInstanceForTesting( - base::BindRepeating( - &FakeNetworkCostManagerEnvironment::FakeCoCreateInstance, - base::Unretained(this))); -} - -FakeNetworkCostManagerEnvironment::~FakeNetworkCostManagerEnvironment() { - // Restore NetworkCostChangeNotifierWin to use the real OS APIs. - NetworkCostChangeNotifierWin::OverrideCoCreateInstanceForTesting( - NetworkCostChangeNotifierWin::CoCreateInstanceCallback()); -} - -HRESULT FakeNetworkCostManagerEnvironment::FakeCoCreateInstance( - REFCLSID class_id, - LPUNKNOWN outer_aggregate, - DWORD context_flags, - REFIID interface_id, - LPVOID* result) { - NetworkChangeNotifier::ConnectionCost connection_cost_for_new_instance; - NetworkCostManagerStatus error_status_for_new_instance; - { - base::AutoLock auto_lock(member_lock_); - connection_cost_for_new_instance = connection_cost_; - error_status_for_new_instance = error_status_; - } - - if (error_status_for_new_instance == - NetworkCostManagerStatus::kErrorCoCreateInstanceFailed) { - return E_ACCESSDENIED; - } - - if (class_id != CLSID_NetworkListManager) { - return E_NOINTERFACE; - } - - if (interface_id != IID_INetworkCostManager) { - return E_NOINTERFACE; - } - - ComPtr<FakeNetworkCostManager> instance = - Microsoft::WRL::Make<FakeNetworkCostManager>( - connection_cost_for_new_instance, error_status_for_new_instance); - { - base::AutoLock auto_lock(member_lock_); - fake_network_cost_managers_.push_back(instance); - } - *result = instance.Detach(); - return S_OK; -} - -void FakeNetworkCostManagerEnvironment::SetCost( - NetworkChangeNotifier::ConnectionCost value) { - // Update the cost for each `INetworkCostManager` instance in - // `fake_network_cost_managers_`. - std::vector<Microsoft::WRL::ComPtr<FakeNetworkCostManager>> - fake_network_cost_managers_for_change_event; - { - base::AutoLock auto_lock(member_lock_); - connection_cost_ = value; - fake_network_cost_managers_for_change_event = fake_network_cost_managers_; - } - - for (const auto& network_cost_manager : - fake_network_cost_managers_for_change_event) { - network_cost_manager->PostCostChangedEvents(/*connection_cost=*/value); - } -} - -void FakeNetworkCostManagerEnvironment::SimulateError( - NetworkCostManagerStatus error_status) { - base::AutoLock auto_lock(member_lock_); - error_status_ = error_status; -} - -} // namespace net
diff --git a/net/test/win/fake_network_cost_manager.h b/net/test/win/fake_network_cost_manager.h deleted file mode 100644 index fd6348e..0000000 --- a/net/test/win/fake_network_cost_manager.h +++ /dev/null
@@ -1,84 +0,0 @@ -// 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 NET_TEST_WIN_FAKE_NETWORK_COST_MANAGER_H_ -#define NET_TEST_WIN_FAKE_NETWORK_COST_MANAGER_H_ - -#include <windows.h> -#include <wrl/client.h> - -#include <vector> - -#include "base/synchronization/lock.h" -#include "base/thread_annotations.h" -#include "net/base/network_change_notifier.h" - -namespace net { -class FakeNetworkCostManager; - -// Each value represents a different Windows OS API that can fail when -// monitoring the cost of network connections. Use with -// `FakeNetworkCostManagerEnvironment::SimulateError` to simulate Windows OS API -// failures that return error HRESULTS. -enum class NetworkCostManagerStatus { - kOk, - kErrorCoCreateInstanceFailed, - kErrorQueryInterfaceFailed, - kErrorFindConnectionPointFailed, - kErrorAdviseFailed, - kErrorGetCostFailed, -}; - -// Provides a fake implementation of the INetworkCostManager Windows OS API for -// NetworkCostChangeNotifierWin. Must be constructed before any -// NetworkCostChangeNotifierWin instances exist. Sets up the fake OS API in the -// constructor and restores the real OS API in the destructor. Tests should use -// this class to simulate different network costs, cost changed events and -// errors without depending on the actual OS APIs or current network -// environment. -class FakeNetworkCostManagerEnvironment { - public: - FakeNetworkCostManagerEnvironment(); - ~FakeNetworkCostManagerEnvironment(); - - void SetCost(NetworkChangeNotifier::ConnectionCost value); - void SimulateError(NetworkCostManagerStatus error_status); - - FakeNetworkCostManagerEnvironment(const FakeNetworkCostManagerEnvironment&) = - delete; - FakeNetworkCostManagerEnvironment& operator=( - const FakeNetworkCostManagerEnvironment&) = delete; - - private: - // Creates a fake implementation of INetworkCostManager. - HRESULT FakeCoCreateInstance(REFCLSID class_id, - LPUNKNOWN outer_aggregate, - DWORD context_flags, - REFIID interface_id, - LPVOID* result); - - // Members must be accessed while holding this lock to support the creation - // and use of `FakeNetworkCostManager` instances on any thread. - base::Lock member_lock_; - - // The connection cost to simulate. - NetworkChangeNotifier::ConnectionCost connection_cost_ - GUARDED_BY(member_lock_) = - NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNKNOWN; - - // When FakeNetworkCostManagerEnvironment creates a new - // FakeNetworkCostManager, the new FakeNetworkCostManager will simulate this - // error. - NetworkCostManagerStatus error_status_ GUARDED_BY(member_lock_) = - NetworkCostManagerStatus::kOk; - - // Holds the fake implementations of INetworkCostManager constructed through - // FakeCoCreateInstance. - std::vector<Microsoft::WRL::ComPtr<FakeNetworkCostManager>> - fake_network_cost_managers_ GUARDED_BY(member_lock_); -}; - -} // namespace net - -#endif // NET_TEST_WIN_FAKE_NETWORK_COST_MANAGER_H_
diff --git a/pdf/pdf_view_web_plugin_unittest.cc b/pdf/pdf_view_web_plugin_unittest.cc index 611198869..1620796 100644 --- a/pdf/pdf_view_web_plugin_unittest.cc +++ b/pdf/pdf_view_web_plugin_unittest.cc
@@ -2214,6 +2214,33 @@ } TEST_F(PdfViewWebPluginPrintPreviewTest, + HandleResetPrintPreviewModeMessageForPdf) { + EXPECT_CALL(*client_ptr_, CreateEngine) + .WillOnce([](PDFEngine::Client* client, + PDFiumFormFiller::ScriptOption script_option) { + EXPECT_EQ(PDFiumFormFiller::ScriptOption::kNoJavaScript, script_option); + + return std::make_unique<NiceMock<TestPDFiumEngine>>(client); + }); + + // The UI ID of 1 in the URL is arbitrary. + // The page index value of -1, AKA `kCompletePDFIndex`, is required for PDFs. + plugin_->OnMessage(ParseMessage(R"({ + "type": "resetPrintPreviewMode", + "url": "chrome-untrusted://print/1/-1/print.pdf", + "grayscale": false, + "pageCount": 0, + })")); + + EXPECT_CALL(*client_ptr_, PostMessage).Times(AnyNumber()); + EXPECT_CALL(*client_ptr_, PostMessage(base::test::IsJson(R"({ + "type": "printPreviewLoaded", + })"))); + plugin_->DocumentLoadComplete(); + pdf_receiver_.FlushForTesting(); +} + +TEST_F(PdfViewWebPluginPrintPreviewTest, HandleResetPrintPreviewModeMessageSetGrayscale) { EXPECT_CALL(*client_ptr_, CreateEngine) .WillOnce([](PDFEngine::Client* client,
diff --git a/printing/backend/cups_printer.cc b/printing/backend/cups_printer.cc index 9a7b982..272356a4 100644 --- a/printing/backend/cups_printer.cc +++ b/printing/backend/cups_printer.cc
@@ -6,6 +6,7 @@ #include <cups/cups.h> +#include <cstring> #include <string> #include <utility> @@ -15,6 +16,7 @@ #include "printing/backend/cups_connection.h" #include "printing/backend/print_backend.h" #include "printing/backend/print_backend_consts.h" +#include "printing/print_job_constants.h" namespace printing { @@ -79,6 +81,12 @@ if (!EnsureDestInfo()) return false; +#if BUILDFLAG(IS_CHROMEOS) + // OAuth token passed to CUPS as IPP attribute, see b/200086039. + if (name && strcmp(name, kSettingChromeOSAccessOAuthToken) == 0) + return true; +#endif + int supported = cupsCheckDestSupported(cups_http_, destination_.get(), dest_info_.get(), name, value); return supported == 1;
diff --git a/printing/print_job_constants.cc b/printing/print_job_constants.cc index d58cedb..b7af10b 100644 --- a/printing/print_job_constants.cc +++ b/printing/print_job_constants.cc
@@ -6,6 +6,8 @@ #include <limits> +#include "build/build_config.h" + namespace printing { // True if this is the first preview request. @@ -20,6 +22,12 @@ // Capabilities option. Contains the capabilities in CDD format. const char kSettingCapabilities[] = "capabilities"; +#if BUILDFLAG(IS_CHROMEOS) +// If set, contains OAuth token that must be used during communication with the +// printer. +const char kSettingChromeOSAccessOAuthToken[] = "chromeos-access-oauth-token"; +#endif + // Print job setting 'collate'. const char kSettingCollate[] = "collate";
diff --git a/printing/print_job_constants.h b/printing/print_job_constants.h index 8611e0b..ac68dbb0 100644 --- a/printing/print_job_constants.h +++ b/printing/print_job_constants.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include "base/component_export.h" +#include "build/build_config.h" namespace printing { @@ -17,6 +18,10 @@ COMPONENT_EXPORT(PRINTING_BASE) extern const char kPreviewUIID[]; COMPONENT_EXPORT(PRINTING_BASE) extern const char kSettingCapabilities[]; +#if BUILDFLAG(IS_CHROMEOS) +COMPONENT_EXPORT(PRINTING_BASE) +extern const char kSettingChromeOSAccessOAuthToken[]; +#endif COMPONENT_EXPORT(PRINTING_BASE) extern const char kSettingCollate[]; COMPONENT_EXPORT(PRINTING_BASE) extern const char kSettingColor[]; COMPONENT_EXPORT(PRINTING_BASE)
diff --git a/printing/print_settings.cc b/printing/print_settings.cc index 000ab5c..5d34915 100644 --- a/printing/print_settings.cc +++ b/printing/print_settings.cc
@@ -279,6 +279,7 @@ #if BUILDFLAG(IS_CHROMEOS) send_user_info_ = settings.send_user_info_; username_ = settings.username_; + oauth_token_ = settings.oauth_token_; pin_value_ = settings.pin_value_; #endif // BUILDFLAG(IS_CHROMEOS) return *this; @@ -318,6 +319,7 @@ #if BUILDFLAG(IS_CHROMEOS) send_user_info_ = false; username_.clear(); + oauth_token_.clear(); pin_value_.clear(); #endif // BUILDFLAG(IS_CHROMEOS) }
diff --git a/printing/print_settings.h b/printing/print_settings.h index 3faff443..f2907c1e 100644 --- a/printing/print_settings.h +++ b/printing/print_settings.h
@@ -237,6 +237,11 @@ void set_username(const std::string& username) { username_ = username; } const std::string& username() const { return username_; } + void set_oauth_token(const std::string& oauth_token) { + oauth_token_ = oauth_token; + } + const std::string& oauth_token() const { return oauth_token_; } + void set_pin_value(const std::string& pin_value) { pin_value_ = pin_value; } const std::string& pin_value() const { return pin_value_; } #endif // BUILDFLAG(IS_CHROMEOS) @@ -334,6 +339,9 @@ // Username if it's required by the printer. std::string username_; + // OAuth access token if it's required by the printer. + std::string oauth_token_; + // PIN code entered by the user. std::string pin_value_; #endif
diff --git a/printing/print_settings_conversion.cc b/printing/print_settings_conversion.cc index edc2bec..1c7afa9a 100644 --- a/printing/print_settings_conversion.cc +++ b/printing/print_settings_conversion.cc
@@ -280,6 +280,12 @@ settings->set_username(*username); } + const std::string* oauth_token = + job_settings.FindString(kSettingChromeOSAccessOAuthToken); + if (oauth_token) { + settings->set_oauth_token(*oauth_token); + } + const std::string* pin_value = job_settings.FindString(kSettingPinValue); if (pin_value) settings->set_pin_value(*pin_value);
diff --git a/printing/print_settings_conversion_unittest.cc b/printing/print_settings_conversion_unittest.cc index 74e49728..f9f496a 100644 --- a/printing/print_settings_conversion_unittest.cc +++ b/printing/print_settings_conversion_unittest.cc
@@ -45,6 +45,7 @@ "previewModifiable": true, "sendUserInfo": true, "username": "username@domain.net", + "chromeos-access-oauth-token": "this is an OAuth access token", "pinValue": "0000" })"; @@ -92,6 +93,7 @@ #if BUILDFLAG(IS_CHROMEOS) EXPECT_TRUE(settings->send_user_info()); EXPECT_EQ("username@domain.net", settings->username()); + EXPECT_EQ("this is an OAuth access token", settings->oauth_token()); EXPECT_EQ("0000", settings->pin_value()); #endif EXPECT_EQ(settings->dpi_horizontal(), 300);
diff --git a/printing/printing_context_chromeos.cc b/printing/printing_context_chromeos.cc index 71231e2..7754207 100644 --- a/printing/printing_context_chromeos.cc +++ b/printing/printing_context_chromeos.cc
@@ -183,6 +183,12 @@ ConstructOption(it.first, base::JoinString(it.second, ","))); } + // OAuth access token + if (!settings.oauth_token().empty()) { + options.push_back(ConstructOption(kSettingChromeOSAccessOAuthToken, + settings.oauth_token())); + } + return options; }
diff --git a/remoting/host/desktop_resizer_x11.cc b/remoting/host/desktop_resizer_x11.cc index eb5c107..82cc65a5 100644 --- a/remoting/host/desktop_resizer_x11.cc +++ b/remoting/host/desktop_resizer_x11.cc
@@ -430,9 +430,9 @@ x11::RandR::ModeInfo mode; mode.width = width; mode.height = height; - mode.dot_clock = 60; - mode.htotal = 1; - mode.vtotal = 1; + mode.dot_clock = 60 * 1e6; + mode.htotal = 1000; + mode.vtotal = 1000; mode.name_len = mode_name.size(); if (auto reply = randr_->CreateMode({root_, mode, mode_name.c_str()}).Sync()) {
diff --git a/remoting/host/mac/permission_utils.mm b/remoting/host/mac/permission_utils.mm index 556acdb..c7fdcb2b 100644 --- a/remoting/host/mac/permission_utils.mm +++ b/remoting/host/mac/permission_utils.mm
@@ -62,11 +62,8 @@ [alert setAlertStyle:NSAlertStyleWarning]; [alert_window makeKeyWindow]; if ([alert runModal] == NSAlertFirstButtonReturn) { - // Launch the Security and Preferences pane with Accessibility selected. - [[NSWorkspace sharedWorkspace] - openURL: - [NSURL URLWithString:@"x-apple.systempreferences:com.apple." - @"preference.security?Privacy_Accessibility"]]; + base::mac::OpenSystemSettingsPane( + base::mac::SystemSettingsPane::kPrivacySecurity_Accessibility); } } @@ -101,11 +98,8 @@ [alert setAlertStyle:NSAlertStyleWarning]; [alert_window makeKeyWindow]; if ([alert runModal] == NSAlertFirstButtonReturn) { - // Launch the Security and Preferences pane with Accessibility selected. - [[NSWorkspace sharedWorkspace] - openURL: - [NSURL URLWithString:@"x-apple.systempreferences:com.apple." - @"preference.security?Privacy_ScreenCapture"]]; + base::mac::OpenSystemSettingsPane( + base::mac::SystemSettingsPane::kPrivacySecurity_ScreenRecording); } }
diff --git a/remoting/host/mac/permission_wizard.mm b/remoting/host/mac/permission_wizard.mm index bed1c4c..1764ab5 100644 --- a/remoting/host/mac/permission_wizard.mm +++ b/remoting/host/mac/permission_wizard.mm
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" +#include "base/mac/mac_util.h" #include "base/memory/weak_ptr.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -365,18 +366,13 @@ } - (void)onLaunchA11y:(id)sender { - // Launch the Security and Preferences pane with Accessibility selected. - [[NSWorkspace sharedWorkspace] - openURL:[NSURL - URLWithString:@"x-apple.systempreferences:com.apple." - @"preference.security?Privacy_Accessibility"]]; + base::mac::OpenSystemSettingsPane( + base::mac::SystemSettingsPane::kPrivacySecurity_Accessibility); } - (void)onLaunchScreenRecording:(id)sender { - [[NSWorkspace sharedWorkspace] - openURL:[NSURL - URLWithString:@"x-apple.systempreferences:com.apple." - @"preference.security?Privacy_ScreenCapture"]]; + base::mac::OpenSystemSettingsPane( + base::mac::SystemSettingsPane::kPrivacySecurity_ScreenRecording); } - (void)onNext:(id)sender {
diff --git a/sandbox/policy/features.cc b/sandbox/policy/features.cc index 34a9a25e9..23b194d6 100644 --- a/sandbox/policy/features.cc +++ b/sandbox/policy/features.cc
@@ -19,12 +19,6 @@ #endif // !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_FUCHSIA) #if BUILDFLAG(IS_WIN) -// Emergency "off switch" for new Windows KTM security mitigation, -// sandbox::MITIGATION_KTM_COMPONENT. -BASE_FEATURE(kWinSboxDisableKtmComponent, - "WinSboxDisableKtmComponent", - base::FEATURE_ENABLED_BY_DEFAULT); - // Experiment for Windows sandbox security mitigation, // sandbox::MITIGATION_EXTENSION_POINT_DISABLE. BASE_FEATURE(kWinSboxDisableExtensionPoints,
diff --git a/sandbox/policy/features.h b/sandbox/policy/features.h index 3ca1bf75..069e23f 100644 --- a/sandbox/policy/features.h +++ b/sandbox/policy/features.h
@@ -20,7 +20,6 @@ #endif #if BUILDFLAG(IS_WIN) -SANDBOX_POLICY_EXPORT BASE_DECLARE_FEATURE(kWinSboxDisableKtmComponent); SANDBOX_POLICY_EXPORT BASE_DECLARE_FEATURE(kWinSboxDisableExtensionPoints); SANDBOX_POLICY_EXPORT BASE_DECLARE_FEATURE(kGpuAppContainer); SANDBOX_POLICY_EXPORT BASE_DECLARE_FEATURE(kGpuLPAC);
diff --git a/sandbox/policy/win/sandbox_policy_feature_test.cc b/sandbox/policy/win/sandbox_policy_feature_test.cc index c476fca..f31da33 100644 --- a/sandbox/policy/win/sandbox_policy_feature_test.cc +++ b/sandbox/policy/win/sandbox_policy_feature_test.cc
@@ -16,11 +16,6 @@ else disabled_features.push_back(features::kRendererAppContainer); - if (::testing::get<TestParameter::kEnableKtmMitigation>(GetParam())) - enabled_features.push_back(features::kWinSboxDisableKtmComponent); - else - disabled_features.push_back(features::kWinSboxDisableKtmComponent); - feature_list_.InitWithFeatures(enabled_features, disabled_features); } @@ -47,7 +42,8 @@ ::sandbox::MITIGATION_NONSYSTEM_FONT_DISABLE | ::sandbox::MITIGATION_IMAGE_LOAD_NO_REMOTE | ::sandbox::MITIGATION_IMAGE_LOAD_NO_LOW_LABEL | - ::sandbox::MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION; + ::sandbox::MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION | + ::sandbox::MITIGATION_KTM_COMPONENT; #if !defined(NACL_WIN64) // Win32k mitigation is only set on the operating systems it's available on @@ -55,9 +51,6 @@ flags = flags | ::sandbox::MITIGATION_WIN32K_DISABLE; #endif - if (::testing::get<TestParameter::kEnableKtmMitigation>(GetParam())) - flags = flags | ::sandbox::MITIGATION_KTM_COMPONENT; - return flags; }
diff --git a/sandbox/policy/win/sandbox_win.cc b/sandbox/policy/win/sandbox_win.cc index a338a80..a885e8cb 100644 --- a/sandbox/policy/win/sandbox_win.cc +++ b/sandbox/policy/win/sandbox_win.cc
@@ -744,10 +744,7 @@ MITIGATION_DEP_NO_ATL_THUNK | MITIGATION_EXTENSION_POINT_DISABLE | MITIGATION_SEHOP | MITIGATION_NONSYSTEM_FONT_DISABLE | MITIGATION_IMAGE_LOAD_NO_REMOTE | MITIGATION_IMAGE_LOAD_NO_LOW_LABEL | - MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION; - - if (base::FeatureList::IsEnabled(features::kWinSboxDisableKtmComponent)) - mitigations |= MITIGATION_KTM_COMPONENT; + MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION | MITIGATION_KTM_COMPONENT; // CET is enabled with the CETCOMPAT bit on chrome.exe so must be // disabled for processes we know are not compatible.
diff --git a/services/image_annotation/annotator.cc b/services/image_annotation/annotator.cc index 3043bfca..a36ba13f 100644 --- a/services/image_annotation/annotator.cc +++ b/services/image_annotation/annotator.cc
@@ -61,8 +61,16 @@ // For every language other than "zh" (Chinese), return only the language // and strip the locale. Image descriptions don't changed based on locale, // but zh-CN and zh-TW use different character sets. - if (tokens.size() == 1 || language_only != "zh") + if (tokens.size() == 1 || language_only != "zh") { + // For the case of Hebrew, Chrome uses "he" but vss uses "iw" internally. + // For Norwegian, vss uses "no" for all variants. + if (language_only == "he") { + return "iw"; + } else if (language_only == "nb" || language_only == "nn") { + return "no"; + } return language_only; + } // Normalize the locale to uppercase. std::string locale_only = base::ToUpperASCII(tokens[1]); @@ -454,7 +462,8 @@ api_key_(std::move(api_key)), batch_size_(batch_size), min_ocr_confidence_(min_ocr_confidence), - server_languages_({"de", "en", "es", "fr", "hi", "it"}) { + server_languages_({"cs", "de", "en", "es", "fi", "fr", "hi", "hr", "id", + "it", "iw", "nl", "no", "pt", "ru", "sv", "tr"}) { server_request_timer_ = std::make_unique<base::RepeatingTimer>( FROM_HERE, throttle, base::BindRepeating(&Annotator::SendRequestBatchToServer,
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index 7ffc102..f84ab193 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -34,7 +34,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -100,7 +100,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -175,7 +175,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -234,7 +234,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -293,7 +293,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -352,7 +352,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -411,7 +411,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -470,7 +470,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -529,7 +529,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -588,7 +588,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -692,7 +692,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -751,7 +751,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -817,7 +817,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -886,7 +886,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -946,7 +946,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -1008,7 +1008,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -1068,7 +1068,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -1129,7 +1129,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -1194,7 +1194,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" }
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 44cb0686..56ecf6c 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -8213,7 +8213,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -8273,7 +8273,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -8334,7 +8334,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -8393,7 +8393,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -8446,7 +8446,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -8497,7 +8497,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -8556,7 +8556,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -8615,7 +8615,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -8674,7 +8674,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -8734,7 +8734,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -8794,7 +8794,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -8853,7 +8853,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -8913,7 +8913,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -8972,7 +8972,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -9032,7 +9032,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -9091,7 +9091,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -9161,7 +9161,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -9230,7 +9230,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -9295,7 +9295,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -9355,7 +9355,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -9416,7 +9416,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -9540,7 +9540,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -9600,7 +9600,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -9661,7 +9661,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -9720,7 +9720,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -9779,7 +9779,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -9838,7 +9838,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -9897,7 +9897,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -9956,7 +9956,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10015,7 +10015,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10074,7 +10074,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10136,7 +10136,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10195,7 +10195,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10254,7 +10254,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10313,7 +10313,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10372,7 +10372,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10431,7 +10431,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10490,7 +10490,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10549,7 +10549,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10608,7 +10608,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10668,7 +10668,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10727,7 +10727,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10786,7 +10786,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10845,7 +10845,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10904,7 +10904,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -10963,7 +10963,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11022,7 +11022,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11082,7 +11082,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11142,7 +11142,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11201,7 +11201,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11260,7 +11260,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11319,7 +11319,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11378,7 +11378,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11437,7 +11437,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11496,7 +11496,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11555,7 +11555,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11614,7 +11614,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11673,7 +11673,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11733,7 +11733,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11792,7 +11792,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11852,7 +11852,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11920,7 +11920,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -11992,7 +11992,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12052,7 +12052,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12111,7 +12111,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12174,7 +12174,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12234,7 +12234,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12295,7 +12295,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12355,7 +12355,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12408,7 +12408,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12460,7 +12460,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12519,7 +12519,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12578,7 +12578,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12637,7 +12637,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12697,7 +12697,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12757,7 +12757,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12816,7 +12816,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12876,7 +12876,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12935,7 +12935,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -12995,7 +12995,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13054,7 +13054,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13124,7 +13124,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13193,7 +13193,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13259,7 +13259,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13319,7 +13319,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13379,7 +13379,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13440,7 +13440,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13501,7 +13501,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13561,7 +13561,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13622,7 +13622,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13681,7 +13681,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13741,7 +13741,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13800,7 +13800,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13859,7 +13859,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13918,7 +13918,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -13977,7 +13977,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14036,7 +14036,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14098,7 +14098,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14158,7 +14158,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14217,7 +14217,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14276,7 +14276,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14335,7 +14335,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14394,7 +14394,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14453,7 +14453,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14512,7 +14512,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14571,7 +14571,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14631,7 +14631,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14690,7 +14690,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14749,7 +14749,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14808,7 +14808,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14867,7 +14867,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14926,7 +14926,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -14985,7 +14985,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15046,7 +15046,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15106,7 +15106,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15166,7 +15166,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15225,7 +15225,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15284,7 +15284,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15343,7 +15343,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15402,7 +15402,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15461,7 +15461,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15520,7 +15520,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15579,7 +15579,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15638,7 +15638,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15697,7 +15697,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15757,7 +15757,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15816,7 +15816,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15875,7 +15875,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -15943,7 +15943,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16015,7 +16015,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16075,7 +16075,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16134,7 +16134,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16193,7 +16193,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16256,7 +16256,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16315,7 +16315,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16376,7 +16376,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16435,7 +16435,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16488,7 +16488,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16538,7 +16538,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16597,7 +16597,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16656,7 +16656,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16715,7 +16715,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16775,7 +16775,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16835,7 +16835,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16894,7 +16894,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -16954,7 +16954,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17013,7 +17013,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17072,7 +17072,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17131,7 +17131,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17197,7 +17197,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17265,7 +17265,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17330,7 +17330,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17390,7 +17390,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17449,7 +17449,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17509,7 +17509,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17569,7 +17569,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17629,7 +17629,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17689,7 +17689,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17748,7 +17748,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17807,7 +17807,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17866,7 +17866,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17925,7 +17925,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17984,7 +17984,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18043,7 +18043,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18102,7 +18102,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18163,7 +18163,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18222,7 +18222,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18281,7 +18281,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18340,7 +18340,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18399,7 +18399,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18458,7 +18458,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18517,7 +18517,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18576,7 +18576,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18635,7 +18635,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18694,7 +18694,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18753,7 +18753,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18812,7 +18812,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18871,7 +18871,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18930,7 +18930,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -18989,7 +18989,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19048,7 +19048,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19108,7 +19108,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19167,7 +19167,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19226,7 +19226,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19285,7 +19285,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19344,7 +19344,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19403,7 +19403,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19462,7 +19462,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19521,7 +19521,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19580,7 +19580,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19639,7 +19639,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19698,7 +19698,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19757,7 +19757,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19817,7 +19817,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19876,7 +19876,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19935,7 +19935,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -19995,7 +19995,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -20054,7 +20054,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -20113,7 +20113,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -23290,7 +23290,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -23358,7 +23358,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -23427,7 +23427,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -23489,7 +23489,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -23552,7 +23552,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -23614,7 +23614,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -23677,7 +23677,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -24277,7 +24277,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -24336,7 +24336,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -24395,7 +24395,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -24454,7 +24454,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -24513,7 +24513,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -24572,7 +24572,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -24632,7 +24632,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -24696,7 +24696,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -24755,7 +24755,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -24814,7 +24814,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -24873,7 +24873,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -24932,7 +24932,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -24991,7 +24991,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25050,7 +25050,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25114,7 +25114,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25173,7 +25173,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25232,7 +25232,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25291,7 +25291,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25350,7 +25350,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25409,7 +25409,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25469,7 +25469,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25533,7 +25533,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25592,7 +25592,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25651,7 +25651,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25710,7 +25710,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25769,7 +25769,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25828,7 +25828,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25887,7 +25887,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -25951,7 +25951,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26010,7 +26010,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26069,7 +26069,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26128,7 +26128,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26187,7 +26187,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26246,7 +26246,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26306,7 +26306,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26370,7 +26370,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26429,7 +26429,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26488,7 +26488,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26547,7 +26547,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26606,7 +26606,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26665,7 +26665,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26725,7 +26725,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26849,7 +26849,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26908,7 +26908,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -26967,7 +26967,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27026,7 +27026,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27085,7 +27085,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27144,7 +27144,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27204,7 +27204,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27273,7 +27273,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27333,7 +27333,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27362,7 +27362,7 @@ } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 9 }, "test": "android_browsertests", "test_id_prefix": "ninja://chrome/test:android_browsertests/" @@ -27395,7 +27395,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27455,7 +27455,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27509,7 +27509,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27560,7 +27560,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27620,7 +27620,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27680,7 +27680,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27741,7 +27741,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27802,7 +27802,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27863,7 +27863,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27923,7 +27923,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -27984,7 +27984,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -28044,7 +28044,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -28104,7 +28104,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -28170,7 +28170,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -28230,7 +28230,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -28370,7 +28370,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -28439,7 +28439,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -28505,7 +28505,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -28576,7 +28576,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -28637,7 +28637,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -28698,7 +28698,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -28949,7 +28949,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29010,7 +29010,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29070,7 +29070,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29130,7 +29130,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29190,7 +29190,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29250,7 +29250,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29310,7 +29310,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29370,7 +29370,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29430,7 +29430,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29493,7 +29493,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29553,7 +29553,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29613,7 +29613,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29673,7 +29673,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29733,7 +29733,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29793,7 +29793,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29853,7 +29853,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29913,7 +29913,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -29973,7 +29973,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30033,7 +30033,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30093,7 +30093,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30153,7 +30153,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30213,7 +30213,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30273,7 +30273,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30333,7 +30333,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30393,7 +30393,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30455,7 +30455,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30516,7 +30516,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30577,7 +30577,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30637,7 +30637,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30697,7 +30697,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30757,7 +30757,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30817,7 +30817,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30877,7 +30877,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30937,7 +30937,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -30997,7 +30997,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -31057,7 +31057,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -31117,7 +31117,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -31178,7 +31178,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -31238,7 +31238,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -31306,7 +31306,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -31367,7 +31367,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -31432,7 +31432,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -31493,7 +31493,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -31553,7 +31553,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -31613,7 +31613,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -31673,7 +31673,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -31719,7 +31719,7 @@ "device_os_flavor": null, "device_playstore_version": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -31770,7 +31770,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -31820,7 +31820,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -31867,7 +31867,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -36224,7 +36224,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -36345,7 +36345,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -36404,7 +36404,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -36457,7 +36457,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -36507,7 +36507,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -36566,7 +36566,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -36625,7 +36625,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -36684,7 +36684,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -36744,7 +36744,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -36804,7 +36804,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -36863,7 +36863,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -36923,7 +36923,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -36982,7 +36982,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37042,7 +37042,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37101,7 +37101,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37160,7 +37160,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37227,7 +37227,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37296,7 +37296,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37361,7 +37361,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37421,7 +37421,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37480,7 +37480,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37541,7 +37541,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37602,7 +37602,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37662,7 +37662,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37722,7 +37722,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37781,7 +37781,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37840,7 +37840,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37899,7 +37899,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -37958,7 +37958,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38017,7 +38017,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38076,7 +38076,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38135,7 +38135,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38197,7 +38197,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38256,7 +38256,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38315,7 +38315,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38374,7 +38374,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38433,7 +38433,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38492,7 +38492,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38551,7 +38551,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38610,7 +38610,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38669,7 +38669,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38728,7 +38728,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38787,7 +38787,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38846,7 +38846,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38905,7 +38905,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -38964,7 +38964,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39023,7 +39023,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39083,7 +39083,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39144,7 +39144,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39203,7 +39203,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39262,7 +39262,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39321,7 +39321,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39380,7 +39380,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39439,7 +39439,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39498,7 +39498,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39557,7 +39557,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39616,7 +39616,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39675,7 +39675,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39734,7 +39734,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39794,7 +39794,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39853,7 +39853,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39919,7 +39919,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -39980,7 +39980,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -40040,7 +40040,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -40099,7 +40099,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -40158,7 +40158,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -40243,7 +40243,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -40315,7 +40315,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "n1-standard-4|e2-standard-4", + "machine_type": "n1-standard-4|e2-standard-4|n2-standard-4", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" }
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index ec59a10..9a3ce1df 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5813,9 +5813,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "isolate_profile_data": true, "merge": { "args": [], @@ -5827,8 +5827,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "dimension_sets": [ @@ -5979,9 +5979,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "isolate_profile_data": true, "merge": { "args": [], @@ -5993,8 +5993,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "dimension_sets": [ @@ -6130,9 +6130,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "isolate_profile_data": true, "merge": { "args": [], @@ -6144,8 +6144,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 86d2366..e0018cf 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -17597,7 +17597,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17653,7 +17653,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17708,7 +17708,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17764,7 +17764,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -17819,7 +17819,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "machine_type": "e2-standard-8", + "machine_type": "e2-standard-8|n2-standard-8", "os": "Ubuntu-18.04", "pool": "chromium.tests.avd" } @@ -88143,9 +88143,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "isolate_profile_data": true, "merge": { "args": [], @@ -88157,8 +88157,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -88279,9 +88279,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "isolate_profile_data": true, "merge": { "args": [], @@ -88293,8 +88293,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -88405,9 +88405,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "isolate_profile_data": true, "merge": { "args": [], @@ -88419,8 +88419,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -89760,9 +89760,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -89773,8 +89773,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "dimension_sets": [ @@ -89926,9 +89926,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -89939,8 +89939,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "dimension_sets": [ @@ -90077,9 +90077,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -90090,8 +90090,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "dimension_sets": [ @@ -91612,9 +91612,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -91625,8 +91625,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "dimension_sets": [ @@ -91778,9 +91778,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -91791,8 +91791,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "dimension_sets": [ @@ -91929,9 +91929,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -91942,8 +91942,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "dimension_sets": [ @@ -92741,9 +92741,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -92754,8 +92754,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 6b091d21..3ff3ee8 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -20360,10 +20360,10 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome", "--test-launcher-print-test-stdio=always" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "isolate_profile_data": true, "merge": { "args": [], @@ -20375,8 +20375,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "dimension_sets": [ @@ -20534,10 +20534,10 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome", "--test-launcher-print-test-stdio=always" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "isolate_profile_data": true, "merge": { "args": [], @@ -20549,8 +20549,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "dimension_sets": [ @@ -20690,10 +20690,10 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome", "--test-launcher-print-test-stdio=always" ], - "description": "Run with ash-chrome version 109.0.5394.0", + "description": "Run with ash-chrome version 109.0.5395.0", "isolate_profile_data": true, "merge": { "args": [], @@ -20705,8 +20705,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v109.0.5394.0", - "revision": "version:109.0.5394.0" + "location": "lacros_version_skew_tests_v109.0.5395.0", + "revision": "version:109.0.5395.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json index 1c725ec..dba6b9f 100644 --- a/testing/buildbot/chromium.win.json +++ b/testing/buildbot/chromium.win.json
@@ -3708,7 +3708,8 @@ } ], "quickrun_shards": 3, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test": "sync_integration_tests", "test_id_prefix": "ninja://chrome/test:sync_integration_tests/"
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index 92d5d8b..15d7847 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -445,7 +445,7 @@ 'device_os': None, 'device_type': None, 'pool': 'chromium.tests.avd', - 'machine_type': 'n1-standard-4|e2-standard-4', + 'machine_type': 'n1-standard-4|e2-standard-4|n2-standard-4', }, }, }, @@ -455,7 +455,7 @@ 'device_os': None, 'device_type': None, 'pool': 'chromium.tests.avd', - 'machine_type': 'e2-standard-8', + 'machine_type': 'e2-standard-8|n2-standard-8', }, }, },
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 76dbaa3c..c9f5e248 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -50,7 +50,7 @@ }, 'android-nougat-x86-rel': { 'swarming': { - 'shards': 3, + 'shards': 9, }, }, 'android-pie-arm64-rel': { @@ -3278,6 +3278,7 @@ }, 'Win10 Tests x64': { 'swarming': { + 'shards': 3, 'quickrun_shards': 3, }, },
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index d5bc05e..769f765 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -22,16 +22,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5394.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v109.0.5395.0/test_ash_chrome', ], - 'description': 'Run with ash-chrome version 109.0.5394.0', + 'description': 'Run with ash-chrome version 109.0.5395.0', 'identifier': 'Lacros version skew testing ash canary', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v109.0.5394.0', - 'revision': 'version:109.0.5394.0', + 'location': 'lacros_version_skew_tests_v109.0.5395.0', + 'revision': 'version:109.0.5395.0', }, ], },
diff --git a/testing/scripts/run_finch_smoke_tests_android.py b/testing/scripts/run_finch_smoke_tests_android.py index 69caa166..f9411685 100755 --- a/testing/scripts/run_finch_smoke_tests_android.py +++ b/testing/scripts/run_finch_smoke_tests_android.py
@@ -220,6 +220,7 @@ rest_args = super(FinchTestCase, self).rest_args rest_args.extend([ + '--webdriver-arg=--disable-build-check', '--device-serial', self._device.serial, '--webdriver-binary',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index ed6f94e..b30acac9 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1599,6 +1599,26 @@ ] } ], + "AvoidRasterDuringElasticOverscroll": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AvoidRasterDuringElasticOverscroll" + ] + } + ] + } + ], "AvoidUnnecessaryBeforeUnloadCheckSync": [ { "platforms": [ @@ -3442,6 +3462,21 @@ ] } ], + "DefaultOfflineExperience": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PWAsDefaultOfflinePage" + ] + } + ] + } + ], "DefaultPassthroughCommandDecoder": [ { "platforms": [ @@ -4749,7 +4784,20 @@ ], "experiments": [ { - "name": "Enabled", + "name": "Enabled (Fullscreen)", + "params": { + "ios-new-post-restore-experience": "false" + }, + "enable_features": [ + "FullscreenPromosManager", + "IOSNewPostRestoreExperience" + ] + }, + { + "name": "Enabled (Alert)", + "params": { + "ios-new-post-restore-experience": "true" + }, "enable_features": [ "FullscreenPromosManager", "IOSNewPostRestoreExperience" @@ -4952,7 +5000,6 @@ "name": "Enabled_081722", "params": { "enableCameraAssistedSearchOnTablet": "true", - "enableCameraAssistedSearchOnTabletWidget": "true", "enableContextMenuSearchOnTablet": "true" }, "enable_features": [
diff --git a/third_party/blink/common/BUILD.gn b/third_party/blink/common/BUILD.gn index 95ea815e..aae649c7 100644 --- a/third_party/blink/common/BUILD.gn +++ b/third_party/blink/common/BUILD.gn
@@ -93,6 +93,26 @@ ] } +blink_python_runner("make_runtime_feature_state_contexts_impl") { + script = + "../renderer/build/scripts/make_runtime_feature_state_contexts_impl.py" + + inputs = scripts_for_json5_files + [ + "../renderer/platform/runtime_enabled_features.json5", + "../renderer/build/scripts/templates/runtime_feature_state_context.cc.tmpl", + ] + + outputs = [ "$root_gen_dir/third_party/blink/common/runtime_feature_state/runtime_feature_state_context.cc" ] + + args = [ + rebase_path("../renderer/platform/runtime_enabled_features.json5", + root_build_dir), + "--output_dir", + rebase_path("$root_gen_dir/third_party/blink/common/runtime_feature_state/", + root_build_dir), + ] +} + config("blink_common_implementation") { defines = [ "BLINK_COMMON_IMPLEMENTATION=1" ] } @@ -261,12 +281,14 @@ sources += get_target_outputs(":make_generated_features") sources += get_target_outputs(":make_generated_origin_trials") sources += get_target_outputs(":make_generated_permissions_policy_features") + sources += get_target_outputs(":make_runtime_feature_state_contexts_impl") public_deps = [ ":make_generated_document_policy_features", ":make_generated_features", ":make_generated_origin_trials", ":make_generated_permissions_policy_features", + ":make_runtime_feature_state_contexts_impl", "//third_party/blink/common/privacy_budget:privacy_budget", "//third_party/blink/public/common:common_export", "//third_party/blink/public/common:headers",
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn index 1a9cfd0..83d32afc 100644 --- a/third_party/blink/public/common/BUILD.gn +++ b/third_party/blink/public/common/BUILD.gn
@@ -56,6 +56,30 @@ ] } +blink_python_runner("make_runtime_feature_state_contexts_headers") { + script = "../../renderer/build/scripts/make_runtime_feature_state_contexts_headers.py" + + inputs = scripts_for_json5_files + [ + "../../renderer/platform/runtime_enabled_features.json5", + "../../renderer/build/scripts/templates/runtime_feature_state_context.h.tmpl", + "../../renderer/build/scripts/templates/runtime_feature_state_read_context.h.tmpl", + ] + + outputs = [ + "$root_gen_dir/third_party/blink/public/common/runtime_feature_state/runtime_feature_state_context.h", + "$root_gen_dir/third_party/blink/public/common/runtime_feature_state/runtime_feature_state_read_context.h", + ] + + args = [ + rebase_path("../../renderer/platform/runtime_enabled_features.json5", + root_build_dir), + "--output_dir", + rebase_path( + "$root_gen_dir/third_party/blink/public/common/runtime_feature_state/", + root_build_dir), + ] +} + # Public common API headers, mojom and libraries that can be linked and # referenced both by browser-side and renderer-side components. component("common") { @@ -290,10 +314,12 @@ sources += get_target_outputs(":make_generated_origin_trial_feature") sources += get_target_outputs(":make_generated_permissions_policy_helper") + sources += get_target_outputs(":make_runtime_feature_state_contexts_headers") public_deps = [ ":make_generated_origin_trial_feature", ":make_generated_permissions_policy_helper", + ":make_runtime_feature_state_contexts_headers", "//base", "//mojo/public/cpp/bindings", "//services/metrics/public/cpp:metrics_cpp",
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni index b275c7e..d5f40bb 100644 --- a/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -1054,6 +1054,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_playback_destination.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_sample_format.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_sample_format.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_sink_type.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_sink_type.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_automation_rate.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_automation_rate.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_avc_bitstream_format.cc", @@ -1521,6 +1523,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_processing_event.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_scheduled_source_node.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_scheduled_source_node.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_sink_info.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_sink_info.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_track.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_track.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_worklet.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni index a0df5701..ce2a17e 100644 --- a/third_party/blink/renderer/bindings/idl_in_modules.gni +++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -774,6 +774,7 @@ "//third_party/blink/renderer/modules/webaudio/audio_processing_event.idl", "//third_party/blink/renderer/modules/webaudio/audio_processing_event_init.idl", "//third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.idl", + "//third_party/blink/renderer/modules/webaudio/audio_sink_info.idl", "//third_party/blink/renderer/modules/webaudio/audio_timestamp.idl", "//third_party/blink/renderer/modules/webaudio/audio_worklet.idl", "//third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.idl",
diff --git a/third_party/blink/renderer/build/scripts/make_runtime_feature_state_contexts_headers.py b/third_party/blink/renderer/build/scripts/make_runtime_feature_state_contexts_headers.py new file mode 100755 index 0000000..093edc5 --- /dev/null +++ b/third_party/blink/renderer/build/scripts/make_runtime_feature_state_contexts_headers.py
@@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +# 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 json5_generator +import make_runtime_features +import make_runtime_features_utilities as util +import template_expander + + +class RunTimeFeatureStateContextHeaderWriter( + make_runtime_features.BaseRuntimeFeatureWriter): + file_basename = "runtime_feature_state_context" + + def __init__(self, json5_file_path, output_dir): + super(RunTimeFeatureStateContextHeaderWriter, + self).__init__(json5_file_path, output_dir) + self._outputs = { + (self.file_basename + '.h'): self.generate_header, + } + + self._browser_read_access_features = util.browser_read_access( + self._features) + self._browser_write_access_features = util.browser_write_access( + self._features) + + def _template_inputs(self): + return { + 'features': self._features, + 'browser_read_access_features': self._browser_read_access_features, + 'browser_write_access_features': + self._browser_write_access_features, + 'platforms': self._platforms(), + 'input_files': self._input_files, + 'header_guard': self._header_guard, + } + + @template_expander.use_jinja(f'templates/{file_basename}.h.tmpl') + def generate_header(self): + return self._template_inputs() + + +class RunTimeFeatureStateReadContextHeaderWriter( + make_runtime_features.BaseRuntimeFeatureWriter): + file_basename = "runtime_feature_state_read_context" + + def __init__(self, json5_file_path, output_dir): + super(RunTimeFeatureStateReadContextHeaderWriter, + self).__init__(json5_file_path, output_dir) + self._outputs = { + (self.file_basename + '.h'): self.generate_header, + } + self._browser_read_access_features = util.browser_read_access( + self._features) + self._browser_write_access_features = util.browser_write_access( + self._features) + + def _template_inputs(self): + return { + 'features': self._features, + 'browser_read_access_features': self._browser_read_access_features, + 'browser_write_access_features': + self._browser_write_access_features, + 'platforms': self._platforms(), + 'input_files': self._input_files, + 'header_guard': self._header_guard, + } + + @template_expander.use_jinja(f'templates/{file_basename}.h.tmpl') + def generate_header(self): + return self._template_inputs() + + +if __name__ == '__main__': + json5_generator.Maker(RunTimeFeatureStateReadContextHeaderWriter).main() + json5_generator.Maker(RunTimeFeatureStateContextHeaderWriter).main()
diff --git a/third_party/blink/renderer/build/scripts/make_runtime_feature_state_contexts_impl.py b/third_party/blink/renderer/build/scripts/make_runtime_feature_state_contexts_impl.py new file mode 100755 index 0000000..e7f4e0a8 --- /dev/null +++ b/third_party/blink/renderer/build/scripts/make_runtime_feature_state_contexts_impl.py
@@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +# 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 json5_generator +import make_runtime_features +import make_runtime_features_utilities as util +import template_expander + + +class RunTimeFeatureStateContextImplWriter( + make_runtime_features.BaseRuntimeFeatureWriter): + file_basename = "runtime_feature_state_context" + + def __init__(self, json5_file_path, output_dir): + super(RunTimeFeatureStateContextImplWriter, + self).__init__(json5_file_path, output_dir) + self._outputs = { + (self.file_basename + '.cc'): self.generate_implementation, + } + + self._browser_read_access_features = util.browser_read_access( + self._features) + + def _template_inputs(self): + return { + 'features': self._features, + 'browser_read_access_features': self._browser_read_access_features, + 'platforms': self._platforms(), + 'input_files': self._input_files, + 'header_guard': self._header_guard, + } + + @template_expander.use_jinja(f'templates/{file_basename}.cc.tmpl') + def generate_implementation(self): + return self._template_inputs() + + +if __name__ == '__main__': + json5_generator.Maker(RunTimeFeatureStateContextImplWriter).main()
diff --git a/third_party/blink/renderer/build/scripts/templates/runtime_feature_state_context.cc.tmpl b/third_party/blink/renderer/build/scripts/templates/runtime_feature_state_context.cc.tmpl new file mode 100644 index 0000000..80a9a1a2 --- /dev/null +++ b/third_party/blink/renderer/build/scripts/templates/runtime_feature_state_context.cc.tmpl
@@ -0,0 +1,26 @@ +{% from 'templates/macros.tmpl' import license, source_files_for_generated_file %} +{{license()}} + +{{source_files_for_generated_file(template_file, input_files)}} + +#include "third_party/blink/public/common/runtime_feature_state/runtime_feature_state_context.h" + +#include "base/containers/flat_map.h" +#include "third_party/blink/public/mojom/runtime_feature_state/runtime_feature_state.mojom-shared.h" +#include "third_party/blink/public/common/runtime_feature_state/runtime_feature_state_read_context.h" + +namespace blink { + +void RuntimeFeatureStateContext::PopulateInitialValues() { + // Write access implies read, so we are populating all inital values + initial_values_.reserve({{browser_read_access_features|length()}}); + + {% for feature in browser_read_access_features %} + // TODO(crbug.com/1377000): fetch current value. + initial_values_.insert( + {blink::mojom::RuntimeFeatureState::k{{feature.name}}, + false}); + {% endfor %} +} + +} // namespace blink \ No newline at end of file
diff --git a/third_party/blink/renderer/build/scripts/templates/runtime_feature_state_context.h.tmpl b/third_party/blink/renderer/build/scripts/templates/runtime_feature_state_context.h.tmpl new file mode 100644 index 0000000..e8ba619 --- /dev/null +++ b/third_party/blink/renderer/build/scripts/templates/runtime_feature_state_context.h.tmpl
@@ -0,0 +1,45 @@ +{% from 'templates/macros.tmpl' import license, source_files_for_generated_file %} +{{license()}} + +{{source_files_for_generated_file(template_file, input_files)}} + +#ifndef {{header_guard}} +#define {{header_guard}} + +#include "base/containers/flat_map.h" +#include "third_party/blink/public/common/common_export.h" +#include "third_party/blink/public/mojom/runtime_feature_state/runtime_feature_state.mojom-shared.h" +#include "third_party/blink/public/common/runtime_feature_state/runtime_feature_state_read_context.h" + +namespace blink { + +class BLINK_COMMON_EXPORT RuntimeFeatureStateContext + : public RuntimeFeatureStateReadContext { + public: + explicit RuntimeFeatureStateContext() { PopulateInitialValues(); } + + RuntimeFeatureStateReadContext GetRuntimeFeatureStateReadContext() const { + return static_cast<RuntimeFeatureStateReadContext>(*this); + } + + // Note: The Is*Enabled() functions are defined in the parent class. + + {% for feature in browser_write_access_features %} + void Set{{feature.name}}Enabled(bool enabled) { + return SetIsEnabled( + blink::mojom::RuntimeFeatureState::k{{feature.name}}, + enabled); + } + {% endfor %} + + private: + void PopulateInitialValues(); + + void SetIsEnabled(blink::mojom::RuntimeFeatureState feature, bool enabled) { + feature_overrides_[feature] = enabled; + } +}; + +} // namespace blink + +#endif // {{header_guard}}
diff --git a/third_party/blink/renderer/build/scripts/templates/runtime_feature_state_read_context.h.tmpl b/third_party/blink/renderer/build/scripts/templates/runtime_feature_state_read_context.h.tmpl new file mode 100644 index 0000000..06b2f49 --- /dev/null +++ b/third_party/blink/renderer/build/scripts/templates/runtime_feature_state_read_context.h.tmpl
@@ -0,0 +1,55 @@ +{% from 'templates/macros.tmpl' import license, source_files_for_generated_file %} +{{license()}} + +{{source_files_for_generated_file(template_file, input_files)}} + +#ifndef {{header_guard}} +#define {{header_guard}} + +#include "base/containers/flat_map.h" +#include "base/notreached.h" +#include "third_party/blink/public/common/common_export.h" +#include "third_party/blink/public/mojom/runtime_feature_state/runtime_feature_state.mojom-shared.h" + +namespace blink { + +class BLINK_COMMON_EXPORT RuntimeFeatureStateReadContext { + public: + // You probably don't want to instantiate this class directly, use + // RuntimeFeatureStateContext instead. + RuntimeFeatureStateReadContext() = default; + + const base::flat_map<blink::mojom::RuntimeFeatureState, bool>& + GetFeatureOverrides() const { + return feature_overrides_; + } + + {% for feature in browser_read_access_features %} + bool Is{{feature.name}}Enabled() { + return IsEnabled( + blink::mojom::RuntimeFeatureState::k{{feature.name}}); + } + {% endfor %} + + protected: + bool IsEnabled(blink::mojom::RuntimeFeatureState feature) const { + auto override_it = feature_overrides_.find(feature); + if (override_it != feature_overrides_.end()) + return override_it->second; + + auto initial_it = initial_values_.find(feature); + DCHECK(initial_it != initial_values_.end()); + return initial_it->second; + } + + // Sparse map of overrides collected during initial navigation. This map + // will be attached to the navigation on commit. + base::flat_map<blink::mojom::RuntimeFeatureState, bool> feature_overrides_; + + // Values for all read/write features on context creation. + base::flat_map<blink::mojom::RuntimeFeatureState, bool> initial_values_; +}; + +} // namespace blink + +#endif // {{header_guard}}
diff --git a/third_party/blink/renderer/core/animation/css_aspect_ratio_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_aspect_ratio_interpolation_type.cc index b68782b..ab0e551 100644 --- a/third_party/blink/renderer/core/animation/css_aspect_ratio_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_aspect_ratio_interpolation_type.cc
@@ -149,7 +149,7 @@ const NonInterpolableValue* non_interpolable_value, StyleResolverState& state) const { const auto& aspect_ratio = To<InterpolableAspectRatio>(interpolable_value); - state.Style()->SetAspectRatio(StyleAspectRatio( + state.StyleBuilder().SetAspectRatio(StyleAspectRatio( To<CSSAspectRatioNonInterpolableValue>(non_interpolable_value) ->GetAspectRatioType(), aspect_ratio.GetRatio()));
diff --git a/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc index 82fc97d3..3463107 100644 --- a/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc
@@ -186,11 +186,11 @@ state.CssToLengthConversionData()); switch (CssProperty().PropertyID()) { case CSSPropertyID::kShapeOutside: - state.Style()->SetShapeOutside(MakeGarbageCollected<ShapeValue>( + state.StyleBuilder().SetShapeOutside(MakeGarbageCollected<ShapeValue>( std::move(shape), CSSBoxType::kMissing)); break; case CSSPropertyID::kClipPath: - state.Style()->SetClipPath( + state.StyleBuilder().SetClipPath( ShapeClipPathOperation::Create(std::move(shape))); break; case CSSPropertyID::kObjectViewBox:
diff --git a/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc index 0a6882d..404b788 100644 --- a/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc
@@ -292,7 +292,7 @@ .CreateLength(state.CssToLengthConversionData(), Length::ValueRange::kAll); }; - state.Style()->SetClip( + state.StyleBuilder().SetClip( LengthBox(convert_index(autos.is_top_auto, kClipTop), convert_index(autos.is_right_auto, kClipRight), convert_index(autos.is_bottom_auto, kClipBottom),
diff --git a/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc index 43e7fe8..fd66b21 100644 --- a/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc
@@ -35,14 +35,14 @@ } void SetFilterList(const CSSProperty& property, - ComputedStyle& style, + ComputedStyleBuilder& builder, const FilterOperations& filter_operations) { switch (property.PropertyID()) { case CSSPropertyID::kBackdropFilter: - style.SetBackdropFilter(filter_operations); + builder.SetBackdropFilter(filter_operations); break; case CSSPropertyID::kFilter: - style.SetFilter(filter_operations); + builder.SetFilter(filter_operations); break; default: NOTREACHED(); @@ -264,7 +264,8 @@ To<InterpolableFilter>(interpolable_list.Get(i)) ->CreateFilterOperation(state)); } - SetFilterList(CssProperty(), *state.Style(), std::move(filter_operations)); + SetFilterList(CssProperty(), state.StyleBuilder(), + std::move(filter_operations)); } InterpolationValue
diff --git a/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc index 3c9a862..d4de67a 100644 --- a/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc
@@ -274,7 +274,7 @@ state.Style()->SetBorderImageSource(image); break; case CSSPropertyID::kListStyleImage: - state.Style()->SetListStyleImage(image); + state.StyleBuilder().SetListStyleImage(image); break; case CSSPropertyID::kWebkitMaskBoxImageSource: state.Style()->SetMaskBoxImageSource(image);
diff --git a/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.cc index 55af071..cf200a8 100644 --- a/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.cc
@@ -121,12 +121,12 @@ } void CSSIntrinsicLengthInterpolationType::SetIntrinsicDimension( - ComputedStyle* style, + ComputedStyleBuilder& builder, const absl::optional<StyleIntrinsicLength>& dimension) const { if (CssProperty().PropertyID() == CSSPropertyID::kContainIntrinsicWidth) - style->SetContainIntrinsicWidth(dimension); + builder.SetContainIntrinsicWidth(dimension); else - style->SetContainIntrinsicHeight(dimension); + builder.SetContainIntrinsicHeight(dimension); } InterpolationValue CSSIntrinsicLengthInterpolationType::MaybeConvertNeutral( @@ -196,10 +196,10 @@ const auto* non_interpolable = To<CSSIntrinsicLengthNonInterpolableValue>(non_interpolable_value); if (non_interpolable->IsNone()) { - SetIntrinsicDimension(state.Style(), absl::nullopt); + SetIntrinsicDimension(state.StyleBuilder(), absl::nullopt); } else { SetIntrinsicDimension( - state.Style(), + state.StyleBuilder(), StyleIntrinsicLength( non_interpolable->HasAuto(), interpolable.CreateLength(state.CssToLengthConversionData(),
diff --git a/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.h b/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.h index 1728e705..595887e5 100644 --- a/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.h
@@ -44,7 +44,7 @@ absl::optional<StyleIntrinsicLength> GetIntrinsicDimension( const ComputedStyle&) const; void SetIntrinsicDimension( - ComputedStyle*, + ComputedStyleBuilder&, const absl::optional<StyleIntrinsicLength>& dimension) const; InterpolationValue MaybeConvertNeutral(const InterpolationValue& underlying,
diff --git a/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc index cc6f6ca..a53c19c 100644 --- a/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc
@@ -142,8 +142,7 @@ state.CssToLengthConversionData().CopyWithAdjustedZoom(zoom); Length length = To<InterpolableLength>(interpolable_value) .CreateLength(conversion_data, value_range_); - if (LengthPropertyFunctions::SetLength(CssProperty(), style, builder, - length)) { + if (LengthPropertyFunctions::SetLength(CssProperty(), builder, length)) { #if DCHECK_IS_ON() scoped_refptr<const ComputedStyle> before_style = builder.ToStyle(); // Assert that setting the length on ComputedStyle directly is identical to
diff --git a/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc index 5a7c9011..d42f172 100644 --- a/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc
@@ -42,6 +42,7 @@ // Set the property to the given path() value. void SetPath(const CSSProperty& property, ComputedStyle& style, + ComputedStyleBuilder& builder, scoped_refptr<blink::StylePath> path) { switch (property.PropertyID()) { case CSSPropertyID::kD: @@ -51,7 +52,7 @@ style.SetOffsetPath(std::move(path)); return; case CSSPropertyID::kClipPath: - style.SetClipPath(ShapeClipPathOperation::Create(std::move(path))); + builder.SetClipPath(ShapeClipPathOperation::Create(std::move(path))); return; default: NOTREACHED(); @@ -65,7 +66,7 @@ const InterpolableValue& interpolable_value, const NonInterpolableValue* non_interpolable_value, StyleResolverState& state) const { - SetPath(CssProperty(), *state.Style(), + SetPath(CssProperty(), *state.Style(), state.StyleBuilder(), PathInterpolationFunctions::AppliedValue(interpolable_value, non_interpolable_value)); }
diff --git a/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc index a424d04..dbb9090 100644 --- a/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc
@@ -145,10 +145,10 @@ const InterpolableValue& interpolable_value, const NonInterpolableValue* non_interpolable_value, StyleResolverState& state) const { - ComputedStyle& style = *state.Style(); - style.SetTextIndent(To<InterpolableLength>(interpolable_value) - .CreateLength(state.CssToLengthConversionData(), - Length::ValueRange::kAll)); + state.StyleBuilder().SetTextIndent( + To<InterpolableLength>(interpolable_value) + .CreateLength(state.CssToLengthConversionData(), + Length::ValueRange::kAll)); } } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc index 5564da4..9c3237c 100644 --- a/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc
@@ -200,7 +200,7 @@ EVisibility visibility = To<CSSVisibilityNonInterpolableValue>(non_interpolable_value) ->Visibility(fraction); - state.Style()->SetVisibility(visibility); + state.StyleBuilder().SetVisibility(visibility); } } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/length_list_property_functions.cc b/third_party/blink/renderer/core/animation/length_list_property_functions.cc index b197be8..5574214 100644 --- a/third_party/blink/renderer/core/animation/length_list_property_functions.cc +++ b/third_party/blink/renderer/core/animation/length_list_property_functions.cc
@@ -214,7 +214,7 @@ return; case CSSPropertyID::kObjectPosition: - style.SetObjectPosition(PointFromVector(length_list)); + builder.SetObjectPosition(PointFromVector(length_list)); return; case CSSPropertyID::kOffsetAnchor: builder.SetOffsetAnchor(PointFromVector(length_list));
diff --git a/third_party/blink/renderer/core/animation/length_property_functions.cc b/third_party/blink/renderer/core/animation/length_property_functions.cc index b816b96f..a7c9374a 100644 --- a/third_party/blink/renderer/core/animation/length_property_functions.cc +++ b/third_party/blink/renderer/core/animation/length_property_functions.cc
@@ -320,7 +320,6 @@ } bool LengthPropertyFunctions::SetLength(const CSSProperty& property, - ComputedStyle& style, ComputedStyleBuilder& builder, const Length& value) { switch (property.PropertyID()) { @@ -342,7 +341,7 @@ builder.SetFlexBasis(value); return true; case CSSPropertyID::kHeight: - style.SetHeight(value); + builder.SetHeight(value); return true; case CSSPropertyID::kLeft: builder.SetLeft(value); @@ -399,7 +398,7 @@ builder.SetRight(value); return true; case CSSPropertyID::kShapeMargin: - style.SetShapeMargin(value); + builder.SetShapeMargin(value); return true; case CSSPropertyID::kStrokeDashoffset: builder.SetStrokeDashOffset(value); @@ -408,7 +407,7 @@ builder.SetTop(value); return true; case CSSPropertyID::kWidth: - style.SetWidth(value); + builder.SetWidth(value); return true; case CSSPropertyID::kWebkitPerspectiveOriginX: builder.SetPerspectiveOriginX(value);
diff --git a/third_party/blink/renderer/core/animation/length_property_functions.h b/third_party/blink/renderer/core/animation/length_property_functions.h index d343dde..1a2c9b6 100644 --- a/third_party/blink/renderer/core/animation/length_property_functions.h +++ b/third_party/blink/renderer/core/animation/length_property_functions.h
@@ -32,7 +32,6 @@ const ComputedStyle&, Length& result); static bool SetLength(const CSSProperty&, - ComputedStyle&, ComputedStyleBuilder&, const Length&); };
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc b/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc index b66a738..a969226 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc +++ b/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc
@@ -107,12 +107,13 @@ WritingMode::kVerticalRl}; Vector<TextDirection> directions = {TextDirection::kLtr, TextDirection::kRtl}; - scoped_refptr<ComputedStyle> style = - GetDocument().GetStyleResolver().CreateComputedStyle(); for (const WritingMode& writing_mode : writing_modes) { for (const TextDirection& direction : directions) { - style->SetWritingMode(writing_mode); - style->SetDirection(direction); + ComputedStyleBuilder style_builder = + GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); + style_builder.SetWritingMode(writing_mode); + style_builder.SetDirection(direction); + scoped_refptr<const ComputedStyle> style = style_builder.TakeStyle(); EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollDirection::kVertical, style.get()), CompositorScrollTimeline::ScrollDown); @@ -124,12 +125,12 @@ } TEST_F(ScrollTimelineUtilTest, ConvertOrientationLogical) { - scoped_refptr<ComputedStyle> style = - GetDocument().GetStyleResolver().CreateComputedStyle(); - // horizontal-tb, ltr - style->SetWritingMode(WritingMode::kHorizontalTb); - style->SetDirection(TextDirection::kLtr); + ComputedStyleBuilder builder = + GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); + builder.SetWritingMode(WritingMode::kHorizontalTb); + builder.SetDirection(TextDirection::kLtr); + scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); EXPECT_EQ( ConvertOrientation(ScrollTimeline::ScrollDirection::kBlock, style.get()), CompositorScrollTimeline::ScrollDown); @@ -138,8 +139,10 @@ CompositorScrollTimeline::ScrollRight); // vertical-lr, ltr - style->SetWritingMode(WritingMode::kVerticalLr); - style->SetDirection(TextDirection::kLtr); + builder = GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); + builder.SetWritingMode(WritingMode::kVerticalLr); + builder.SetDirection(TextDirection::kLtr); + style = builder.TakeStyle(); EXPECT_EQ( ConvertOrientation(ScrollTimeline::ScrollDirection::kBlock, style.get()), CompositorScrollTimeline::ScrollRight); @@ -148,8 +151,10 @@ CompositorScrollTimeline::ScrollDown); // vertical-rl, ltr - style->SetWritingMode(WritingMode::kVerticalRl); - style->SetDirection(TextDirection::kLtr); + builder = GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); + builder.SetWritingMode(WritingMode::kVerticalRl); + builder.SetDirection(TextDirection::kLtr); + style = builder.TakeStyle(); EXPECT_EQ( ConvertOrientation(ScrollTimeline::ScrollDirection::kBlock, style.get()), CompositorScrollTimeline::ScrollLeft); @@ -158,8 +163,10 @@ CompositorScrollTimeline::ScrollDown); // horizontal-tb, rtl - style->SetWritingMode(WritingMode::kHorizontalTb); - style->SetDirection(TextDirection::kRtl); + builder = GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); + builder.SetWritingMode(WritingMode::kHorizontalTb); + builder.SetDirection(TextDirection::kRtl); + style = builder.TakeStyle(); EXPECT_EQ( ConvertOrientation(ScrollTimeline::ScrollDirection::kBlock, style.get()), CompositorScrollTimeline::ScrollDown); @@ -168,8 +175,10 @@ CompositorScrollTimeline::ScrollLeft); // vertical-lr, rtl - style->SetWritingMode(WritingMode::kVerticalLr); - style->SetDirection(TextDirection::kRtl); + builder = GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); + builder.SetWritingMode(WritingMode::kVerticalLr); + builder.SetDirection(TextDirection::kRtl); + style = builder.TakeStyle(); EXPECT_EQ( ConvertOrientation(ScrollTimeline::ScrollDirection::kBlock, style.get()), CompositorScrollTimeline::ScrollRight); @@ -178,8 +187,10 @@ CompositorScrollTimeline::ScrollUp); // vertical-rl, rtl - style->SetWritingMode(WritingMode::kVerticalRl); - style->SetDirection(TextDirection::kRtl); + builder = GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); + builder.SetWritingMode(WritingMode::kVerticalRl); + builder.SetDirection(TextDirection::kRtl); + style = builder.TakeStyle(); EXPECT_EQ( ConvertOrientation(ScrollTimeline::ScrollDirection::kBlock, style.get()), CompositorScrollTimeline::ScrollLeft);
diff --git a/third_party/blink/renderer/core/css/container_query_evaluator_test.cc b/third_party/blink/renderer/core/css/container_query_evaluator_test.cc index 9a6b306..98f2b71 100644 --- a/third_party/blink/renderer/core/css/container_query_evaluator_test.cc +++ b/third_party/blink/renderer/core/css/container_query_evaluator_test.cc
@@ -64,10 +64,10 @@ double height, unsigned container_type, PhysicalAxes contained_axes) { - scoped_refptr<ComputedStyle> style = - GetDocument().GetStyleResolver().InitialStyleForElement(); - style->SetContainerType(container_type); - ContainerElement().SetComputedStyle(style); + ComputedStyleBuilder builder( + *GetDocument().GetStyleResolver().InitialStyleForElement()); + builder.SetContainerType(container_type); + ContainerElement().SetComputedStyle(builder.TakeStyle()); ContainerQuery* container_query = ParseContainer(query); DCHECK(container_query); @@ -113,10 +113,10 @@ PhysicalSize size, unsigned container_type, PhysicalAxes axes) { - scoped_refptr<ComputedStyle> style = - GetDocument().GetStyleResolver().InitialStyleForElement(); - style->SetContainerType(container_type); - ContainerElement().SetComputedStyle(style); + ComputedStyleBuilder builder( + *GetDocument().GetStyleResolver().InitialStyleForElement()); + builder.SetContainerType(container_type); + ContainerElement().SetComputedStyle(builder.TakeStyle()); return evaluator->SizeContainerChanged(GetDocument(), ContainerElement(), size, axes); } @@ -285,9 +285,10 @@ PhysicalSize size_100(LayoutUnit(100), LayoutUnit(100)); Element& container_element = ContainerElement(); - scoped_refptr<ComputedStyle> style = - GetDocument().GetStyleResolver().InitialStyleForElement(); - style->SetContainerType(type_inline_size); + ComputedStyleBuilder builder( + *GetDocument().GetStyleResolver().InitialStyleForElement()); + builder.SetContainerType(type_inline_size); + scoped_refptr<ComputedStyle> style = builder.TakeStyle(); container_element.SetComputedStyle(style); auto* evaluator = MakeGarbageCollected<ContainerQueryEvaluator>();
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5 index 9855af6..2584cd5 100644 --- a/third_party/blink/renderer/core/css/css_properties.json5 +++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -960,6 +960,7 @@ valid_for_marker: true, valid_for_formatted_text: true, valid_for_formatted_text_run: true, + readonly: true, }, { name: "font-family", @@ -1322,6 +1323,7 @@ style_builder_custom_functions: ["value"], type_name: "short", typedom_types: ["Number"], + readonly: true, }, { name: "text-orientation", @@ -1337,6 +1339,7 @@ priority: "High", computable: false, valid_for_formatted_text: true, + readonly: true, }, { name: "-webkit-text-orientation", @@ -1359,6 +1362,7 @@ style_builder_custom_functions: ["initial", "inherit", "value"], priority: "High", valid_for_formatted_text: true, + readonly: true, }, { name: "-webkit-writing-mode", @@ -1390,6 +1394,7 @@ // Setting zoom affects the _EffectiveZoom_, which in turns affects every px value // stored on ComputedStyle; see CSSToLengthConversionData::ZoomedComputedPixels. supports_incremental_style: false, + readonly: true, }, { name: "accent-color", @@ -1467,6 +1472,7 @@ keywords: ["none"], typedom_types: ["Keyword"], runtime_flag: "CSSAnchorPositioning", + readonly: true, }, { name: "anchor-scroll", @@ -1479,6 +1485,7 @@ keywords: ["none"], typedom_types: ["Keyword"], runtime_flag: "CSSAnchorPositioning", + readonly: true, }, { name: "aspect-ratio", @@ -1492,6 +1499,7 @@ converter: "ConvertAspectRatio", include_paths: ["third_party/blink/renderer/core/style/style_aspect_ratio.h"], computable: false, + readonly: true, }, { name: "backdrop-filter", @@ -1508,6 +1516,7 @@ style_builder_custom_functions: ["value"], keywords: ["none"], typedom_types: ["Keyword"], + readonly: true, }, { name: "backface-visibility", @@ -2175,6 +2184,7 @@ typedom_types: ["Keyword"], valid_for_first_letter: true, valid_for_first_line: true, + readonly: true, }, { name: "box-sizing", @@ -2184,6 +2194,7 @@ keywords: ["content-box", "border-box"], typedom_types: ["Keyword"], default_value: "content-box", + readonly: true, }, { name: "break-after", @@ -2198,6 +2209,7 @@ typedom_types: ["Keyword"], default_value: "auto", type_name: "EBreakBetween", + readonly: true, }, { name: "break-before", @@ -2212,6 +2224,7 @@ typedom_types: ["Keyword"], default_value: "auto", type_name: "EBreakBetween", + readonly: true, }, { name: "break-inside", @@ -2222,6 +2235,7 @@ keywords: ["auto", "avoid", "avoid-column", "avoid-page"], typedom_types: ["Keyword"], default_value: "auto", + readonly: true, }, { name: "buffered-rendering", @@ -2241,6 +2255,7 @@ keywords: ["top", "bottom"], typedom_types: ["Keyword"], default_value: "top", + readonly: true, }, { name: "caret-color", @@ -2267,6 +2282,7 @@ keywords: ["none", "left", "right", "both", "inline-start", "inline-end"], typedom_types: ["Keyword"], default_value: "none", + readonly: true, }, { name: "clip", @@ -2282,6 +2298,7 @@ converter: "ConvertClip", keywords: ["auto"], typedom_types: ["Keyword"], + readonly: true, }, { name: "clip-path", @@ -2298,6 +2315,7 @@ converter: "ConvertClipPath", keywords: ["none"], typedom_types: ["Keyword"], + readonly: true, }, { name: "clip-rule", @@ -2373,6 +2391,7 @@ getter: "GetColumnFill", typedom_types: ["Keyword"], computable: false, + readonly: true, }, { name: "contain", @@ -2387,6 +2406,7 @@ keywords: ["none", "strict", "content", "size", "layout", "style", "paint", "inline-size", "block-size"], typedom_types: ["Keyword"], computable: false, + readonly: true, }, { name: "contain-intrinsic-width", @@ -2399,6 +2419,7 @@ default_value: "absl::nullopt", type_name: "absl::optional<StyleIntrinsicLength>", converter: "ConvertIntrinsicDimension", + readonly: true, }, { name: "contain-intrinsic-height", @@ -2411,6 +2432,7 @@ default_value: "absl::optional<StyleIntrinsicLength>()", type_name: "absl::optional<StyleIntrinsicLength>", converter: "ConvertIntrinsicDimension", + readonly: true, }, { name: "container-name", @@ -2423,6 +2445,7 @@ keywords: ["none"], typedom_types: ["Keyword"], runtime_flag: "CSSContainerQueries", + readonly: true, }, { name: "container-type", @@ -2436,6 +2459,7 @@ converter: "ConvertFlags<EContainerType, CSSValueID::kNormal>", typedom_types: ["Keyword"], runtime_flag: "CSSContainerQueries", + readonly: true, }, { name: "content", @@ -2447,11 +2471,12 @@ default_value: "nullptr", separator: ",", type_name: "ContentData", - computed_style_custom_functions: ["getter", "setter"], + computed_style_custom_functions: ["getter"], style_builder_custom_functions: ["initial", "inherit", "value"], valid_for_marker: true, tree_scoped_value: true, supports_incremental_style: true, + readonly: true, }, { name: "counter-increment", @@ -2504,6 +2529,7 @@ style_builder_custom_functions: ["initial", "inherit", "value"], typedom_types: ["Keyword"], valid_for_highlight_legacy: true, + readonly: true, }, { name: "cx", @@ -2561,6 +2587,7 @@ // (e.g. OriginalDisplay is based on display, and setting float can cause blockification), // so we turn off incremental style for all them all. supports_incremental_style: false, + readonly: true, }, { name: "dominant-baseline", @@ -2583,6 +2610,7 @@ keywords: ["show", "hide"], typedom_types: ["Keyword"], default_value: "show", + readonly: true, }, { name: "fill", @@ -2647,6 +2675,7 @@ style_builder_custom_functions: ["value"], keywords: ["none"], typedom_types: ["Keyword"], + readonly: true, }, { name: "flex-basis", @@ -2715,6 +2744,7 @@ valid_for_first_letter: true, // See comment on display. supports_incremental_style: false, + readonly: true, }, { name: "flood-color", @@ -2903,6 +2933,7 @@ supports_incremental_style: true, valid_for_formatted_text: true, valid_for_position_fallback: true, + readonly: true, }, { name: "hyphenate-limit-chars", @@ -2916,6 +2947,7 @@ include_paths: ["third_party/blink/renderer/core/style/style_hyphenate_limit_chars.h"], converter: "ConvertHyphenateLimitChars", runtime_flag: "CSSHyphenateLimitChars", + readonly: true, }, { name: "hyphens", @@ -2928,6 +2960,7 @@ type_name: "Hyphens", typedom_types: ["Keyword"], valid_for_marker: true, + readonly: true, }, { name: "image-rendering", @@ -2941,6 +2974,7 @@ ], typedom_types: ["Keyword"], default_value: "auto", + readonly: true, }, { name: "image-orientation", @@ -2952,6 +2986,7 @@ name_for_methods: "RespectImageOrientation", type_name: "bool", converter: "ConvertImageOrientation", + readonly: true, }, { name: "initial-letter", @@ -2966,6 +3001,7 @@ runtime_flag: "CSSInitialLetter", type_name: "StyleInitialLetter", valid_for_first_letter: true, + readonly: true, }, { name: "isolation", @@ -2975,6 +3011,7 @@ keywords: ["auto", "isolate"], typedom_types: ["Keyword"], default_value: "auto", + readonly: true, }, { name: "justify-content", @@ -3091,6 +3128,7 @@ type_name: "uint8_t", converter: "ConvertComputedLength<uint8_t>", typedom_types: ["Length"], + readonly: true, }, { name: "list-style-image", @@ -3104,9 +3142,9 @@ default_value: "nullptr", typedom_types: ["Keyword", "Image"], type_name: "StyleImage", - computed_style_custom_functions: ["getter", "setter"], style_builder_custom_functions: ["value"], - keywords: ["none"] + keywords: ["none"], + readonly: true, }, { name: "list-style-position", @@ -3117,6 +3155,7 @@ keywords: ["outside", "inside"], typedom_types: ["Keyword"], default_value: "outside", + readonly: true, }, { name: "list-style-type", @@ -3132,8 +3171,9 @@ "disc", "circle", "square", "disclosure-open", "disclosure-closed", "decimal", "none" ], - style_builder_custom_functions: ["initial", "inherit", "value"], + style_builder_custom_functions: ["value"], tree_scoped_value: true, + readonly: true, }, { name: "margin-bottom", @@ -3293,7 +3333,8 @@ keywords: ["normal", "compact"], typedom_types: ["Keyword"], default_value: "normal", - runtime_flag: "CSSMathShift" + runtime_flag: "CSSMathShift", + readonly: true, }, { name: "math-style", @@ -3304,7 +3345,8 @@ keywords: ["normal", "compact"], typedom_types: ["Keyword"], default_value: "normal", - runtime_flag: "CSSMathStyle" + runtime_flag: "CSSMathStyle", + readonly: true, }, { name: "max-height", @@ -3391,6 +3433,7 @@ default_value: "normal", name_for_methods: "BlendMode", type_name: "BlendMode", + readonly: true, }, { name: "object-fit", @@ -3401,6 +3444,7 @@ typedom_types: ["Keyword"], default_value: "fill", getter: "GetObjectFit", + readonly: true, }, { name: "object-position", @@ -3413,6 +3457,7 @@ type_name: "LengthPoint", converter: "ConvertPosition", typedom_types: ["Keyword", "Position"], + readonly: true, }, { name: "object-view-box", @@ -3428,6 +3473,7 @@ keywords: ["none"], typedom_types: ["Keyword"], runtime_flag: "CSSObjectViewBox", + readonly: true, }, { name: "offset-anchor", @@ -3846,6 +3892,7 @@ keywords: ["auto"], typedom_types: ["Keyword"], computable: false, + readonly: true, }, { name: "page-orientation", @@ -3857,6 +3904,7 @@ default_value: "PageOrientation::kUpright", include_paths: ["third_party/blink/public/common/css/page_orientation.h"], computable: false, + readonly: true, }, { name: "page-transition-tag", @@ -3869,6 +3917,7 @@ keywords: ["none"], typedom_types: ["Keyword"], runtime_flag: "DocumentTransition", + readonly: true, }, { name: "paint-order", @@ -3926,6 +3975,7 @@ ], typedom_types: ["Keyword"], default_value: "auto", + readonly: true, }, { name: "position", @@ -3941,6 +3991,7 @@ style_builder_custom_functions: ["inherit"], // See comment on display. supports_incremental_style: false, + readonly: true, }, { name: "position-fallback", @@ -3953,6 +4004,7 @@ keywords: ["none"], typedom_types: ["Keyword"], runtime_flag: "CSSAnchorPositioning", + readonly: true, }, { name: "quotes", @@ -3968,6 +4020,7 @@ keywords: ["auto", "none"], typedom_types: ["Keyword"], computable: false, + readonly: true, }, { name: "content-visibility", @@ -3981,6 +4034,7 @@ // but that value is not unset if the inline style is set incrementally // back to content-visibility: visible. supports_incremental_style: false, + readonly: true, }, { name: "resize", @@ -3992,6 +4046,7 @@ keywords: ["none", "both", "horizontal", "vertical", "block", "inline"], typedom_types: ["Keyword"], default_value: "none", + readonly: true, }, { name: "right", @@ -4064,6 +4119,7 @@ "auto", "stable", "both-edges" ], typedom_types: ["Keyword"], + readonly: true, }, { name: "scrollbar-width", @@ -4075,6 +4131,7 @@ default_value: "auto", typedom_types: ["Keyword"], runtime_flag: "CSSScrollbars", + readonly: true, }, { name: "scroll-behavior", @@ -4404,6 +4461,7 @@ converter: "ConvertLength", keywords: ["none"], typedom_types: ["Length", "Percentage"], + readonly: true, }, { name: "shape-outside", @@ -4418,7 +4476,8 @@ type_name: "ShapeValue", computed_style_custom_functions: ["getter"], converter: "ConvertShapeValue", - keywords: ["none"] + keywords: ["none"], + readonly: true, }, { name: "shape-rendering", @@ -4448,6 +4507,7 @@ "no-punctuation" ], default_value: "normal", + readonly: true, }, { name: "stop-color", @@ -4610,6 +4670,7 @@ ], typedom_types: ["Keyword"], default_value: "auto", + readonly: true, }, { name: "tab-size", @@ -4643,6 +4704,7 @@ getter: "GetTextAlign", style_builder_custom_functions: ["value"], valid_for_formatted_text: true, + readonly: true, }, { name: "text-align-last", @@ -4653,6 +4715,7 @@ keywords: ["auto", "start", "end", "left", "right", "center", "justify"], default_value: "auto", typedom_types: ["Keyword"], + readonly: true, }, { name: "text-anchor", @@ -4678,6 +4741,7 @@ valid_for_marker: true, computable: false, valid_for_formatted_text: true, + readonly: true, }, { name: "text-decoration-color", @@ -4720,6 +4784,7 @@ valid_for_highlight: true, valid_for_formatted_text: true, valid_for_formatted_text_run: true, + readonly: true, }, { name: "text-decoration-skip-ink", @@ -4738,6 +4803,7 @@ valid_for_highlight: true, valid_for_formatted_text: true, valid_for_formatted_text_run: true, + readonly: true, }, { name: "text-decoration-style", @@ -4754,6 +4820,7 @@ valid_for_highlight: true, valid_for_formatted_text: true, valid_for_formatted_text_run: true, + readonly: true, }, { name: "text-decoration-thickness", @@ -4774,6 +4841,7 @@ computable: false, valid_for_formatted_text: true, valid_for_formatted_text_run: true, + readonly: true, }, { name: "text-indent", @@ -4783,8 +4851,9 @@ field_group: "*", field_template: "<length>", default_value: "Length::Fixed()", - style_builder_custom_functions: ["initial", "inherit", "value"], + style_builder_custom_functions: ["value"], typedom_types: ["Length", "Percentage"], + readonly: true, }, { name: "text-overflow", @@ -4819,6 +4888,7 @@ valid_for_highlight: true, valid_for_formatted_text: true, valid_for_formatted_text_run: true, + readonly: true, }, { name: "text-size-adjust", @@ -4850,6 +4920,7 @@ valid_for_marker: true, valid_for_formatted_text: true, valid_for_formatted_text_run: true, + readonly: true, }, { name: "text-underline-offset", @@ -4867,6 +4938,7 @@ computable: false, valid_for_formatted_text: true, valid_for_formatted_text_run: true, + readonly: true, }, { name: "text-underline-position", @@ -4885,6 +4957,7 @@ valid_for_first_line: true, valid_for_formatted_text: true, valid_for_formatted_text_run: true, + readonly: true, }, { name: "toggle-group", @@ -4901,6 +4974,7 @@ supports_incremental_style: true, keywords: ["none"], typedom_types: ["Keyword"], + readonly: true, }, { name: "toggle-root", @@ -4917,6 +4991,7 @@ supports_incremental_style: true, keywords: ["none"], typedom_types: ["Keyword"], + readonly: true, }, { name: "toggle-trigger", @@ -4933,6 +5008,7 @@ supports_incremental_style: true, keywords: ["none"], typedom_types: ["Keyword"], + readonly: true, }, { name: "toggle-visibility", @@ -4946,6 +5022,7 @@ supports_incremental_style: true, keywords: ["normal"], typedom_types: ["Keyword"], + readonly: true, }, { name: "top", @@ -4978,6 +5055,7 @@ converter: "ConvertFlags<blink::TouchAction>", keywords: ["auto", "none", "pan-x", "pan-left", "pan-right", "pan-y", "pan-up", "pan-down", "pinch-zoom", "manipulation"], typedom_types: ["Keyword"], + readonly: true, }, { name: "transform", @@ -5099,6 +5177,7 @@ default_value: "normal", type_name: "UnicodeBidi", valid_for_marker: true, + readonly: true, }, { name: "vector-effect", @@ -5170,6 +5249,7 @@ valid_for_first_letter: true, valid_for_first_line: true, valid_for_cue: true, + readonly: true, }, { name: "x", @@ -5205,6 +5285,7 @@ computed_style_custom_functions: ["getter"], default_value: "kNoControlPart", type_name: "ControlPart", + readonly: true, }, { name: "-webkit-appearance", @@ -5219,6 +5300,7 @@ default_value: "none", name_for_methods: "DraggableRegionMode", style_builder_custom_functions: ["initial", "inherit", "value"], + readonly: true, }, { name: "-webkit-app-region", @@ -5772,7 +5854,8 @@ converter: "ConvertStyleColor", style_builder_template: "color", valid_for_highlight_legacy: true, - valid_for_highlight: true + valid_for_highlight: true, + readonly: true, }, { name: "-webkit-text-security", @@ -5892,6 +5975,7 @@ default_value: "normal", valid_for_cue: true, valid_for_marker: true, + readonly: true, }, { name: "widows", @@ -5924,6 +6008,7 @@ supports_incremental_style: true, valid_for_formatted_text: true, valid_for_position_fallback: true, + readonly: true, }, { name: "will-change", @@ -5943,6 +6028,7 @@ default_value: "normal", typedom_types: ["Keyword"], valid_for_marker: true, + readonly: true, }, { name: "word-spacing",
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc index 6490ebc..15b80c0 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
@@ -548,7 +548,7 @@ void BackdropFilter::ApplyValue(StyleResolverState& state, const CSSValue& value) const { - state.Style()->SetBackdropFilter( + state.StyleBuilder().SetBackdropFilter( StyleBuilderConverter::ConvertFilterOperations(state, value, PropertyID())); } @@ -2211,7 +2211,7 @@ } void Content::ApplyInitial(StyleResolverState& state) const { - state.Style()->SetContent(nullptr); + state.StyleBuilder().SetContent(nullptr); } void Content::ApplyInherit(StyleResolverState& state) const { @@ -2226,14 +2226,15 @@ void Content::ApplyValue(StyleResolverState& state, const ScopedCSSValue& scoped_value) const { + ComputedStyleBuilder& builder = state.StyleBuilder(); const CSSValue& value = scoped_value.GetCSSValue(); if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { DCHECK(identifier_value->GetValueID() == CSSValueID::kNormal || identifier_value->GetValueID() == CSSValueID::kNone); if (identifier_value->GetValueID() == CSSValueID::kNone) - state.Style()->SetContent(MakeGarbageCollected<NoneContentData>()); + builder.SetContent(MakeGarbageCollected<NoneContentData>()); else - state.Style()->SetContent(nullptr); + builder.SetContent(nullptr); return; } const CSSValueList& outer_list = To<CSSValueList>(value); @@ -2311,7 +2312,7 @@ prev_content->SetNext(alt_content); } DCHECK(first_content); - state.Style()->SetContent(first_content); + builder.SetContent(first_content); } const int kCounterIncrementDefaultValue = 1; @@ -2451,35 +2452,35 @@ } void Cursor::ApplyInitial(StyleResolverState& state) const { - state.Style()->ClearCursorList(); - state.Style()->SetCursor(ComputedStyleInitialValues::InitialCursor()); + ComputedStyleBuilder& builder = state.StyleBuilder(); + builder.ClearCursorList(); + builder.SetCursor(ComputedStyleInitialValues::InitialCursor()); } void Cursor::ApplyInherit(StyleResolverState& state) const { - state.Style()->SetCursor(state.ParentStyle()->Cursor()); - state.Style()->SetCursorList(state.ParentStyle()->Cursors()); + ComputedStyleBuilder& builder = state.StyleBuilder(); + builder.SetCursor(state.ParentStyle()->Cursor()); + builder.SetCursorList(state.ParentStyle()->Cursors()); } void Cursor::ApplyValue(StyleResolverState& state, const CSSValue& value) const { - state.Style()->ClearCursorList(); + ComputedStyleBuilder& builder = state.StyleBuilder(); + builder.ClearCursorList(); if (auto* value_list = DynamicTo<CSSValueList>(value)) { - state.Style()->SetCursor(ECursor::kAuto); + builder.SetCursor(ECursor::kAuto); for (const auto& item : *value_list) { if (const auto* cursor = DynamicTo<cssvalue::CSSCursorImageValue>(*item)) { const CSSValue& image = cursor->ImageValue(); - state.Style()->AddCursor( - state.GetStyleImage(CSSPropertyID::kCursor, image), - cursor->HotSpotSpecified(), cursor->HotSpot()); + builder.AddCursor(state.GetStyleImage(CSSPropertyID::kCursor, image), + cursor->HotSpotSpecified(), cursor->HotSpot()); } else { - state.Style()->SetCursor( - To<CSSIdentifierValue>(*item).ConvertTo<ECursor>()); + builder.SetCursor(To<CSSIdentifierValue>(*item).ConvertTo<ECursor>()); } } } else { - state.Style()->SetCursor( - To<CSSIdentifierValue>(value).ConvertTo<ECursor>()); + builder.SetCursor(To<CSSIdentifierValue>(value).ConvertTo<ECursor>()); } } @@ -2535,7 +2536,7 @@ void Direction::ApplyValue(StyleResolverState& state, const CSSValue& value) const { - state.Style()->SetDirection( + state.StyleBuilder().SetDirection( To<CSSIdentifierValue>(value).ConvertTo<TextDirection>()); } @@ -2776,7 +2777,7 @@ void Filter::ApplyValue(StyleResolverState& state, const CSSValue& value) const { - state.Style()->SetFilter(StyleBuilderConverter::ConvertFilterOperations( + state.StyleBuilder().SetFilter(StyleBuilderConverter::ConvertFilterOperations( state, value, PropertyID())); } @@ -4597,7 +4598,7 @@ void ListStyleImage::ApplyValue(StyleResolverState& state, const CSSValue& value) const { - state.Style()->SetListStyleImage( + state.StyleBuilder().SetListStyleImage( state.GetStyleImage(CSSPropertyID::kListStyleImage, value)); } @@ -4637,15 +4638,6 @@ style.ListStyleType()->GetCounterStyleName()); } -void ListStyleType::ApplyInitial(StyleResolverState& state) const { - state.Style()->SetListStyleType( - ComputedStyleInitialValues::InitialListStyleType()); -} - -void ListStyleType::ApplyInherit(StyleResolverState& state) const { - state.Style()->SetListStyleType(state.ParentStyle()->ListStyleType()); -} - void ListStyleType::ApplyValue(StyleResolverState& state, const CSSValue& value) const { NOTREACHED(); @@ -4653,22 +4645,23 @@ void ListStyleType::ApplyValue(StyleResolverState& state, const ScopedCSSValue& scoped_value) const { + ComputedStyleBuilder& builder = state.StyleBuilder(); const CSSValue& value = scoped_value.GetCSSValue(); if (const auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { DCHECK_EQ(CSSValueID::kNone, identifier_value->GetValueID()); - state.Style()->SetListStyleType(nullptr); + builder.SetListStyleType(nullptr); return; } if (const auto* string_value = DynamicTo<CSSStringValue>(value)) { - state.Style()->SetListStyleType( + builder.SetListStyleType( ListStyleTypeData::CreateString(AtomicString(string_value->Value()))); return; } DCHECK(value.IsCustomIdentValue()); const auto& custom_ident_value = To<CSSCustomIdentValue>(value); - state.Style()->SetListStyleType(ListStyleTypeData::CreateCounterStyle( + builder.SetListStyleType(ListStyleTypeData::CreateCounterStyle( custom_ident_value.Value(), scoped_value.GetTreeScope())); } @@ -4946,20 +4939,21 @@ void MathDepth::ApplyValue(StyleResolverState& state, const CSSValue& value) const { + ComputedStyleBuilder& builder = state.StyleBuilder(); if (const auto* list = DynamicTo<CSSValueList>(value)) { DCHECK_EQ(list->length(), 1U); const auto& relative_value = To<CSSPrimitiveValue>(list->Item(0)); - state.Style()->SetMathDepth(base::ClampAdd(state.ParentStyle()->MathDepth(), - relative_value.GetIntValue())); + builder.SetMathDepth(base::ClampAdd(state.ParentStyle()->MathDepth(), + relative_value.GetIntValue())); } else if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { DCHECK(identifier_value->GetValueID() == CSSValueID::kAutoAdd); int16_t depth = 0; if (state.ParentStyle()->MathStyle() == EMathStyle::kCompact) depth += 1; - state.Style()->SetMathDepth( + builder.SetMathDepth( base::ClampAdd(state.ParentStyle()->MathDepth(), depth)); } else if (DynamicTo<CSSPrimitiveValue>(value)) { - state.Style()->SetMathDepth( + builder.SetMathDepth( ClampTo<int16_t>(To<CSSPrimitiveValue>(value).GetIntValue())); } } @@ -5954,7 +5948,7 @@ void Position::ApplyInherit(StyleResolverState& state) const { if (!state.ParentNode()->IsDocumentNode()) - state.Style()->SetPosition(state.ParentStyle()->GetPosition()); + state.StyleBuilder().SetPosition(state.ParentStyle()->GetPosition()); } const CSSValue* PositionFallback::ParseSingleValue( @@ -6050,7 +6044,7 @@ } else { r = identifier_value.ConvertTo<EResize>(); } - state.Style()->SetResize(r); + state.StyleBuilder().SetResize(r); } const CSSValue* Right::ParseSingleValue( @@ -7103,6 +7097,7 @@ void TextAlign::ApplyValue(StyleResolverState& state, const CSSValue& value) const { + ComputedStyleBuilder& builder = state.StyleBuilder(); const auto* ident_value = DynamicTo<CSSIdentifierValue>(value); if (ident_value && ident_value->GetValueID() != CSSValueID::kWebkitMatchParent) { @@ -7112,19 +7107,19 @@ if (ident_value->GetValueID() == CSSValueID::kInternalCenter && state.ParentStyle()->GetTextAlign() != ComputedStyleInitialValues::InitialTextAlign()) - state.Style()->SetTextAlign(state.ParentStyle()->GetTextAlign()); + builder.SetTextAlign(state.ParentStyle()->GetTextAlign()); else - state.Style()->SetTextAlign(ident_value->ConvertTo<ETextAlign>()); + builder.SetTextAlign(ident_value->ConvertTo<ETextAlign>()); } else if (state.ParentStyle()->GetTextAlign() == ETextAlign::kStart) { - state.Style()->SetTextAlign(state.ParentStyle()->IsLeftToRightDirection() - ? ETextAlign::kLeft - : ETextAlign::kRight); + builder.SetTextAlign(state.ParentStyle()->IsLeftToRightDirection() + ? ETextAlign::kLeft + : ETextAlign::kRight); } else if (state.ParentStyle()->GetTextAlign() == ETextAlign::kEnd) { - state.Style()->SetTextAlign(state.ParentStyle()->IsLeftToRightDirection() - ? ETextAlign::kRight - : ETextAlign::kLeft); + builder.SetTextAlign(state.ParentStyle()->IsLeftToRightDirection() + ? ETextAlign::kRight + : ETextAlign::kLeft); } else { - state.Style()->SetTextAlign(state.ParentStyle()->GetTextAlign()); + builder.SetTextAlign(state.ParentStyle()->GetTextAlign()); } } @@ -7270,14 +7265,6 @@ return list; } -void TextIndent::ApplyInitial(StyleResolverState& state) const { - state.Style()->SetTextIndent(ComputedStyleInitialValues::InitialTextIndent()); -} - -void TextIndent::ApplyInherit(StyleResolverState& state) const { - state.Style()->SetTextIndent(state.ParentStyle()->TextIndent()); -} - void TextIndent::ApplyValue(StyleResolverState& state, const CSSValue& value) const { Length length_or_percentage_value; @@ -7292,7 +7279,7 @@ } } - state.Style()->SetTextIndent(length_or_percentage_value); + state.StyleBuilder().SetTextIndent(length_or_percentage_value); } const CSSValue* TextOrientation::CSSValueFromComputedStyleInternal( @@ -7993,10 +7980,10 @@ void AppRegion::ApplyValue(StyleResolverState& state, const CSSValue& value) const { const auto& identifier_value = To<CSSIdentifierValue>(value); - state.Style()->SetDraggableRegionMode(identifier_value.GetValueID() == - CSSValueID::kDrag - ? EDraggableRegionMode::kDrag - : EDraggableRegionMode::kNoDrag); + state.StyleBuilder().SetDraggableRegionMode( + identifier_value.GetValueID() == CSSValueID::kDrag + ? EDraggableRegionMode::kDrag + : EDraggableRegionMode::kNoDrag); state.GetDocument().SetHasAnnotatedRegions(true); }
diff --git a/third_party/blink/renderer/core/css/resolver/element_style_resources.cc b/third_party/blink/renderer/core/css/resolver/element_style_resources.cc index bd837a1..ee4010d 100644 --- a/third_party/blink/renderer/core/css/resolver/element_style_resources.cc +++ b/third_party/blink/renderer/core/css/resolver/element_style_resources.cc
@@ -276,16 +276,17 @@ } } -void ElementStyleResources::LoadPendingSVGResources(ComputedStyle& style) { +void ElementStyleResources::LoadPendingSVGResources( + ComputedStyleBuilder& builder) { Document& document = element_.GetDocument(); for (CSSPropertyID property : pending_svg_resource_properties_) { switch (property) { case CSSPropertyID::kBackdropFilter: - LoadResourcesForFilter(style.MutableBackdropFilter().Operations(), + LoadResourcesForFilter(builder.MutableBackdropFilter().Operations(), document); break; case CSSPropertyID::kFilter: - LoadResourcesForFilter(style.MutableFilter().Operations(), document); + LoadResourcesForFilter(builder.MutableFilter().Operations(), document); break; default: NOTREACHED(); @@ -299,7 +300,8 @@ return nullptr; } -void ElementStyleResources::LoadPendingImages(ComputedStyle& style) { +void ElementStyleResources::LoadPendingImages(ComputedStyleBuilder& builder) { + ComputedStyle& style = *builder.MutableInternalStyle(); // We must loop over the properties and then look at the style to see if // a pending image exists, and only load that image. For example: // @@ -364,7 +366,7 @@ } case CSSPropertyID::kListStyleImage: { if (auto* pending_value = PendingCssValue(style.ListStyleImage())) - style.SetListStyleImage(loader.Load(*pending_value)); + builder.SetListStyleImage(loader.Load(*pending_value)); break; } case CSSPropertyID::kBorderImageSource: { @@ -417,9 +419,9 @@ } void ElementStyleResources::LoadPendingResources( - ComputedStyle& computed_style) { - LoadPendingImages(computed_style); - LoadPendingSVGResources(computed_style); + ComputedStyleBuilder& builder) { + LoadPendingImages(builder); + LoadPendingSVGResources(builder); } void ElementStyleResources::UpdateLengthConversionData(
diff --git a/third_party/blink/renderer/core/css/resolver/element_style_resources.h b/third_party/blink/renderer/core/css/resolver/element_style_resources.h index 9022645..54fbff8 100644 --- a/third_party/blink/renderer/core/css/resolver/element_style_resources.h +++ b/third_party/blink/renderer/core/css/resolver/element_style_resources.h
@@ -32,7 +32,7 @@ namespace blink { class CSSValue; -class ComputedStyle; +class ComputedStyleBuilder; class Element; class PseudoElement; class SVGResource; @@ -77,7 +77,7 @@ SVGResource* GetSVGResourceFromValue(CSSPropertyID, const cssvalue::CSSURIValue&); - void LoadPendingResources(ComputedStyle&); + void LoadPendingResources(ComputedStyleBuilder&); void UpdateLengthConversionData(const CSSToLengthConversionData*); @@ -85,8 +85,8 @@ bool IsPending(const CSSValue&) const; StyleImage* CachedStyleImage(const CSSValue&) const; - void LoadPendingSVGResources(ComputedStyle&); - void LoadPendingImages(ComputedStyle&); + void LoadPendingSVGResources(ComputedStyleBuilder&); + void LoadPendingImages(ComputedStyleBuilder&); Element& element_; HashSet<CSSPropertyID> pending_image_properties_;
diff --git a/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc b/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc index 87d4e1d..3e49204 100644 --- a/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc +++ b/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc
@@ -83,7 +83,10 @@ class MatchedPropertiesCacheTest : public PageTestBase { public: scoped_refptr<ComputedStyle> CreateStyle() { - return GetDocument().GetStyleResolver().InitialStyleForElement(); + return GetDocument().GetStyleResolver().CreateComputedStyle(); + } + ComputedStyleBuilder CreateStyleBuilder() { + return GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); } }; @@ -203,12 +206,16 @@ TEST_F(MatchedPropertiesCacheTest, WritingModeDependency) { TestCache cache(GetDocument()); - auto parent_a = CreateStyle(); - auto parent_b = CreateStyle(); + auto parent_builder_a = CreateStyleBuilder(); + parent_builder_a.SetWritingMode(WritingMode::kHorizontalTb); + auto parent_builder_b = CreateStyleBuilder(); + parent_builder_b.SetWritingMode(WritingMode::kVerticalRl); + + auto parent_a = parent_builder_a.TakeStyle(); + auto parent_b = parent_builder_b.TakeStyle(); + auto style_a = CreateStyle(); auto style_b = CreateStyle(); - parent_a->SetWritingMode(WritingMode::kHorizontalTb); - parent_b->SetWritingMode(WritingMode::kVerticalRl); TestKey key("display:block", 1, GetDocument()); @@ -221,12 +228,16 @@ TEST_F(MatchedPropertiesCacheTest, DirectionDependency) { TestCache cache(GetDocument()); - auto parent_a = CreateStyle(); - auto parent_b = CreateStyle(); + auto parent_builder_a = CreateStyleBuilder(); + parent_builder_a.SetDirection(TextDirection::kLtr); + auto parent_builder_b = CreateStyleBuilder(); + parent_builder_b.SetDirection(TextDirection::kRtl); + + auto parent_a = parent_builder_a.TakeStyle(); + auto parent_b = parent_builder_b.TakeStyle(); + auto style_a = CreateStyle(); auto style_b = CreateStyle(); - parent_a->SetDirection(TextDirection::kLtr); - parent_b->SetDirection(TextDirection::kRtl); TestKey key("display:block", 1, GetDocument());
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc index 9a6ffad..8348da06 100644 --- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc +++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -120,18 +120,19 @@ return false; } -void AdjustStyleForSvgElement(const SVGElement& element, ComputedStyle& style) { +void AdjustStyleForSvgElement(const SVGElement& element, + ComputedStyleBuilder& builder) { // Disable some of text decoration properties. // // Note that SetFooBar() is more efficient than ResetFooBar() if the current // value is same as the reset value. - style.SetTextDecorationSkipInk(ETextDecorationSkipInk::kAuto); - style.SetTextDecorationStyle( + builder.SetTextDecorationSkipInk(ETextDecorationSkipInk::kAuto); + builder.SetTextDecorationStyle( ETextDecorationStyle::kSolid); // crbug.com/1246719 - style.SetTextDecorationThickness(TextDecorationThickness(Length::Auto())); - style.SetTextEmphasisMark(TextEmphasisMark::kNone); - style.SetTextUnderlineOffset(Length()); // crbug.com/1247912 - style.SetTextUnderlinePosition(kTextUnderlinePositionAuto); + builder.SetTextDecorationThickness(TextDecorationThickness(Length::Auto())); + builder.MutableInternalStyle()->SetTextEmphasisMark(TextEmphasisMark::kNone); + builder.SetTextUnderlineOffset(Length()); // crbug.com/1247912 + builder.SetTextUnderlinePosition(kTextUnderlinePositionAuto); } // Adjust style for anchor() and anchor-size() queries. @@ -308,16 +309,17 @@ return layout_parent_style.IsDisplayFlexibleOrGridBox(); } -void StyleAdjuster::AdjustStyleForEditing(ComputedStyle& style) { +void StyleAdjuster::AdjustStyleForEditing(ComputedStyleBuilder& builder) { + const ComputedStyle& style = *builder.InternalStyle(); if (style.UserModify() != EUserModify::kReadWritePlaintextOnly) return; // Collapsing whitespace is harmful in plain-text editing. - if (style.WhiteSpace() == EWhiteSpace::kNormal) - style.SetWhiteSpace(EWhiteSpace::kPreWrap); - else if (style.WhiteSpace() == EWhiteSpace::kNowrap) - style.SetWhiteSpace(EWhiteSpace::kPre); - else if (style.WhiteSpace() == EWhiteSpace::kPreLine) - style.SetWhiteSpace(EWhiteSpace::kPreWrap); + if (builder.WhiteSpace() == EWhiteSpace::kNormal) + builder.SetWhiteSpace(EWhiteSpace::kPreWrap); + else if (builder.WhiteSpace() == EWhiteSpace::kNowrap) + builder.SetWhiteSpace(EWhiteSpace::kPre); + else if (builder.WhiteSpace() == EWhiteSpace::kPreLine) + builder.SetWhiteSpace(EWhiteSpace::kPreWrap); } void StyleAdjuster::AdjustStyleForTextCombine(ComputedStyleBuilder& builder) { @@ -330,32 +332,32 @@ const auto line_height = style.GetFontHeight().LineHeight(); const auto size = LengthSize(Length::Fixed(line_height), Length::Fixed(one_em)); - style.SetContainIntrinsicWidth(StyleIntrinsicLength(false, size.Width())); - style.SetContainIntrinsicHeight(StyleIntrinsicLength(false, size.Height())); - style.SetHeight(size.Height()); + builder.SetContainIntrinsicWidth(StyleIntrinsicLength(false, size.Width())); + builder.SetContainIntrinsicHeight(StyleIntrinsicLength(false, size.Height())); + builder.SetHeight(size.Height()); builder.SetLineHeight(size.Height()); builder.SetMaxHeight(size.Height()); builder.SetMaxWidth(size.Width()); builder.SetMinHeight(size.Height()); builder.SetMinWidth(size.Width()); - style.SetWidth(size.Width()); + builder.SetWidth(size.Width()); AdjustStyleForCombinedText(builder); } void StyleAdjuster::AdjustStyleForCombinedText(ComputedStyleBuilder& builder) { ComputedStyle& style = *builder.MutableInternalStyle(); - style.ResetTextCombine(); + builder.ResetTextCombine(); style.SetLetterSpacing(0.0f); - style.SetTextAlign(ETextAlign::kCenter); - style.SetTextDecorationLine(TextDecorationLine::kNone); + builder.SetTextAlign(ETextAlign::kCenter); + builder.SetTextDecorationLine(TextDecorationLine::kNone); style.SetTextEmphasisMark(TextEmphasisMark::kNone); style.SetVerticalAlign(EVerticalAlign ::kMiddle); - style.SetWordBreak(EWordBreak::kKeepAll); + builder.SetWordBreak(EWordBreak::kKeepAll); style.SetWordSpacing(0.0f); - style.SetWritingMode(WritingMode::kHorizontalTb); + builder.SetWritingMode(WritingMode::kHorizontalTb); style.ClearAppliedTextDecorations(); - style.ResetTextIndent(); + builder.ResetTextIndent(); style.UpdateFontOrientation(); DCHECK_EQ(style.GetFont().GetFontDescription().Orientation(), @@ -400,7 +402,7 @@ style.SetDisplay(EDisplay::kInlineBlock); // Do not break inside the marker, and honor the trailing spaces. - style.SetWhiteSpace(EWhiteSpace::kPre); + builder.SetWhiteSpace(EWhiteSpace::kPre); // Compute margins for 'outside' during layout, because it requires the // layout size of the marker. @@ -430,7 +432,7 @@ if (style.GetTextAlign() == ETextAlign::kWebkitLeft || style.GetTextAlign() == ETextAlign::kWebkitCenter || style.GetTextAlign() == ETextAlign::kWebkitRight) - style.SetTextAlign(ETextAlign::kStart); + builder.SetTextAlign(ETextAlign::kStart); return; } @@ -438,9 +440,9 @@ // Frames and framesets never honor position:relative or position:absolute. // This is necessary to fix a crash where a site tries to position these // objects. They also never honor display nor floating. - style.SetPosition(EPosition::kStatic); - style.SetDisplay(EDisplay::kBlock); - style.SetFloating(EFloat::kNone); + builder.SetPosition(EPosition::kStatic); + builder.SetDisplay(EDisplay::kBlock); + builder.SetFloating(EFloat::kNone); return; } @@ -483,8 +485,8 @@ if (IsA<HTMLRTElement>(element)) { // Ruby text does not support float or position. This might change with // evolution of the specification. - style.SetPosition(EPosition::kStatic); - style.SetFloating(EFloat::kNone); + builder.SetPosition(EPosition::kStatic); + builder.SetFloating(EFloat::kNone); return; } @@ -603,6 +605,7 @@ } static void AdjustStyleForDisplay(ComputedStyle& style, + ComputedStyleBuilder& builder, const ComputedStyle& layout_parent_style, const Element* element, Document* document) { @@ -638,8 +641,8 @@ style.Display() == EDisplay::kTableHeaderGroup || style.Display() == EDisplay::kTableRow || style.Display() == EDisplay::kTableRowGroup) { - style.SetWritingMode(layout_parent_style.GetWritingMode()); - style.SetTextOrientation(layout_parent_style.GetTextOrientation()); + builder.SetWritingMode(layout_parent_style.GetWritingMode()); + builder.SetTextOrientation(layout_parent_style.GetTextOrientation()); style.UpdateFontOrientation(); } } @@ -853,7 +856,7 @@ if (style.Display() != EDisplay::kNone) { if (svg_element) - AdjustStyleForSvgElement(*svg_element, style); + AdjustStyleForSvgElement(*svg_element, builder); bool is_document_element = element && element->GetDocument().documentElement() == element; @@ -864,7 +867,7 @@ if (IsInTopLayer(element, style) && !is_document_element) { if (style.GetPosition() == EPosition::kStatic || style.GetPosition() == EPosition::kRelative) { - style.SetPosition(EPosition::kAbsolute); + builder.SetPosition(EPosition::kAbsolute); } if (style.Display() == EDisplay::kContents) { // See crbug.com/1240701 for more details. @@ -898,7 +901,7 @@ AdjustStyleForFirstLetter(style); AdjustStyleForMarker(style, builder, parent_style, state.GetElement()); - AdjustStyleForDisplay(style, layout_parent_style, element, + AdjustStyleForDisplay(style, builder, layout_parent_style, element, element ? &element->GetDocument() : nullptr); // If this is a child of a LayoutNGCustom, we need the name of the parent @@ -912,7 +915,7 @@ // The root element of the main frame has no backdrop, so don't allow // it to have a backdrop filter either. if (is_document_element && is_in_main_frame && style.HasBackdropFilter()) - style.MutableBackdropFilter().clear(); + builder.MutableBackdropFilter().clear(); } else { AdjustStyleForFirstLetter(style); } @@ -974,7 +977,7 @@ AdjustStyleForInert(style, element); - AdjustStyleForEditing(style); + AdjustStyleForEditing(builder); bool is_svg_root = false; @@ -983,7 +986,7 @@ if (!is_svg_root) { // Only the root <svg> element in an SVG document fragment tree honors css // position. - style.SetPosition(ComputedStyleInitialValues::InitialPosition()); + builder.SetPosition(ComputedStyleInitialValues::InitialPosition()); } if (style.Display() == EDisplay::kContents && @@ -1031,7 +1034,7 @@ if (style.GetWritingMode() != WritingMode::kHorizontalTb) { // TODO(rbuis): this will not work with logical CSS properties. // Disable vertical writing-mode for now. - style.SetWritingMode(WritingMode::kHorizontalTb); + builder.SetWritingMode(WritingMode::kHorizontalTb); style.UpdateFontOrientation(); } }
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.h b/third_party/blink/renderer/core/css/resolver/style_adjuster.h index 34de511..e4d3b77 100644 --- a/third_party/blink/renderer/core/css/resolver/style_adjuster.h +++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.h
@@ -43,7 +43,7 @@ public: CORE_EXPORT static void AdjustComputedStyle(StyleResolverState&, Element*); static void AdjustStyleForCombinedText(ComputedStyleBuilder&); - static void AdjustStyleForEditing(ComputedStyle&); + static void AdjustStyleForEditing(ComputedStyleBuilder&); static void AdjustStyleForTextCombine(ComputedStyleBuilder&); private:
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_test.cc b/third_party/blink/renderer/core/css/resolver/style_builder_test.cc index 61547bfb4..b4da625 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_test.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder_test.cc
@@ -35,15 +35,15 @@ for (const CSSValue* value : values) { auto parent_style = GetDocument().GetStyleResolver().CreateComputedStyle(); - auto style = GetDocument().GetStyleResolver().CreateComputedStyle(); - // This test assumes that initial 'writing-mode' is not 'vertical-lr'. - ASSERT_NE(WritingMode::kVerticalLr, style->GetWritingMode()); - style->SetWritingMode(WritingMode::kVerticalLr); - StyleResolverState state(GetDocument(), *GetDocument().body(), nullptr /* StyleRecalcContext */, StyleRequest(parent_style.get())); - state.SetStyle(style); + state.SetStyle(GetDocument().GetStyleResolver().CreateComputedStyle()); + + // This test assumes that initial 'writing-mode' is not 'vertical-lr'. + ASSERT_NE(WritingMode::kVerticalLr, + state.StyleBuilder().GetWritingMode()); + state.StyleBuilder().SetWritingMode(WritingMode::kVerticalLr); ASSERT_FALSE(state.GetFontBuilder().FontDirty()); StyleBuilder::ApplyProperty(*property, state, @@ -69,15 +69,15 @@ for (const CSSValue* value : values) { auto parent_style = GetDocument().GetStyleResolver().CreateComputedStyle(); - auto style = GetDocument().GetStyleResolver().CreateComputedStyle(); - // This test assumes that initial 'text-orientation' is not 'upright'. - ASSERT_NE(ETextOrientation::kUpright, style->GetTextOrientation()); - style->SetTextOrientation(ETextOrientation::kUpright); - StyleResolverState state(GetDocument(), *GetDocument().body(), nullptr /* StyleRecalcContext */, StyleRequest(parent_style.get())); - state.SetStyle(style); + state.SetStyle(GetDocument().GetStyleResolver().CreateComputedStyle()); + + // This test assumes that initial 'text-orientation' is not 'upright'. + ASSERT_NE(ETextOrientation::kUpright, + state.StyleBuilder().GetTextOrientation()); + state.StyleBuilder().SetTextOrientation(ETextOrientation::kUpright); ASSERT_FALSE(state.GetFontBuilder().FontDirty()); StyleBuilder::ApplyProperty(*property, state,
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc index 4266d9ee..f87d093 100644 --- a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc +++ b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
@@ -438,7 +438,7 @@ EXPECT_EQ("10px", cascade.ComputedValue("--x")); EXPECT_EQ("20px", cascade.ComputedValue("width")); - cascade.State().StyleRef().SetWidth(Length::Auto()); + cascade.State().StyleBuilder().SetWidth(Length::Auto()); cascade.State().StyleRef().SetVariableData("--x", nullptr, true); EXPECT_EQ(g_null_atom, cascade.ComputedValue("--x")); EXPECT_EQ("auto", cascade.ComputedValue("width"));
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc index d882b987..6099df2 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -867,8 +867,7 @@ builder.SetOverflowX(EOverflow::kAuto); builder.SetOverflowY(EOverflow::kAuto); - GetDocument().GetStyleEngine().ApplyVisionDeficiencyStyle( - builder.MutableInternalStyle()); + GetDocument().GetStyleEngine().ApplyVisionDeficiencyStyle(builder); return builder.TakeStyle(); } @@ -2399,7 +2398,7 @@ new_viewport_style_builder.SetBackgroundColor( StyleColor(background_color)); new_viewport_style->AccessBackgroundLayers() = background_layers; - new_viewport_style->SetImageRendering(image_rendering); + new_viewport_style_builder.SetImageRendering(image_rendering); } }
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc index 24ff3317..c74c6ad7 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
@@ -175,7 +175,7 @@ return; } - element_style_resources_.LoadPendingResources(StyleRef()); + element_style_resources_.LoadPendingResources(StyleBuilder()); } const FontDescription& StyleResolverState::ParentFontDescription() const { @@ -187,7 +187,7 @@ ? ParentStyle()->EffectiveZoom() : ComputedStyleInitialValues::InitialZoom(); - StyleRef().SetZoom(f); + StyleBuilder().SetZoom(f); if (f != 1.f) GetDocument().CountUse(WebFeature::kCascadedCSSZoomNotEqualToOne); @@ -202,17 +202,17 @@ } void StyleResolverState::SetWritingMode(WritingMode new_writing_mode) { - if (StyleRef().GetWritingMode() == new_writing_mode) { + if (StyleBuilder().GetWritingMode() == new_writing_mode) { return; } - StyleRef().SetWritingMode(new_writing_mode); + StyleBuilder().SetWritingMode(new_writing_mode); UpdateLengthConversionData(); font_builder_.DidChangeWritingMode(); } void StyleResolverState::SetTextOrientation(ETextOrientation text_orientation) { - if (StyleRef().GetTextOrientation() != text_orientation) { - StyleRef().SetTextOrientation(text_orientation); + if (StyleBuilder().GetTextOrientation() != text_orientation) { + StyleBuilder().SetTextOrientation(text_orientation); font_builder_.DidChangeTextOrientation(); } }
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index 0a16d0dd..50a7cbee 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -2464,12 +2464,12 @@ } void StyleEngine::ApplyVisionDeficiencyStyle( - scoped_refptr<ComputedStyle> layout_view_style) { + ComputedStyleBuilder& layout_view_style_builder) { LoadVisionDeficiencyFilter(); if (vision_deficiency_filter_) { FilterOperations ops; ops.Operations().push_back(vision_deficiency_filter_); - layout_view_style->SetFilter(ops); + layout_view_style_builder.SetFilter(ops); } }
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index 7870052..04edbdb 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -71,6 +71,7 @@ namespace blink { +class ComputedStyleBuilder; class CounterStyle; class CounterStyleMap; class CSSFontSelector; @@ -493,7 +494,7 @@ void VisionDeficiencyChanged(); void ApplyVisionDeficiencyStyle( - scoped_refptr<ComputedStyle> layout_view_style); + ComputedStyleBuilder& layout_view_style_builder); void CollectMatchingUserRules(ElementRuleCollector&) const;
diff --git a/third_party/blink/renderer/core/document_transition/document_transition.h b/third_party/blink/renderer/core/document_transition/document_transition.h index 32d8849..de4b4341 100644 --- a/third_party/blink/renderer/core/document_transition/document_transition.h +++ b/third_party/blink/renderer/core/document_transition/document_transition.h
@@ -9,6 +9,7 @@ #include "base/memory/scoped_refptr.h" #include "base/task/single_thread_task_runner.h" +#include "base/unguessable_token.h" #include "third_party/blink/public/common/frame/view_transition_state.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_function.h" @@ -26,6 +27,10 @@ #include "third_party/blink/renderer/platform/heap/forward.h" #include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" +namespace viz { +using NavigationID = base::UnguessableToken; +} + namespace blink { class Document;
diff --git a/third_party/blink/renderer/core/document_transition/document_transition_request_forward.h b/third_party/blink/renderer/core/document_transition/document_transition_request_forward.h index 4c5ba5c..3e998d8 100644 --- a/third_party/blink/renderer/core/document_transition/document_transition_request_forward.h +++ b/third_party/blink/renderer/core/document_transition/document_transition_request_forward.h
@@ -5,8 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOCUMENT_TRANSITION_DOCUMENT_TRANSITION_REQUEST_FORWARD_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_DOCUMENT_TRANSITION_DOCUMENT_TRANSITION_REQUEST_FORWARD_H_ -#include "cc/document_transition/document_transition_request.h" - namespace cc { class DocumentTransitionRequest; }
diff --git a/third_party/blink/renderer/core/document_transition/document_transition_supplement.h b/third_party/blink/renderer/core/document_transition/document_transition_supplement.h index 558b20d..eb9cee7 100644 --- a/third_party/blink/renderer/core/document_transition/document_transition_supplement.h +++ b/third_party/blink/renderer/core/document_transition/document_transition_supplement.h
@@ -8,6 +8,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_document_transition_callback.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/document_transition/document_transition.h" +#include "third_party/blink/renderer/core/document_transition/document_transition_request.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
diff --git a/third_party/blink/renderer/core/dom/pseudo_element.cc b/third_party/blink/renderer/core/dom/pseudo_element.cc index 094d7a6..17cf3706 100644 --- a/third_party/blink/renderer/core/dom/pseudo_element.cc +++ b/third_party/blink/renderer/core/dom/pseudo_element.cc
@@ -212,13 +212,13 @@ // For display:contents we should not generate a box, but we generate a non- // observable inline box for pseudo elements to be able to locate the // anonymous layout objects for generated content during DetachLayoutTree(). - scoped_refptr<ComputedStyle> layout_style = - GetDocument().GetStyleResolver().CreateComputedStyle(); - layout_style->InheritFrom(style); - layout_style->SetContent(style.GetContentData()); - layout_style->SetDisplay(EDisplay::kInline); - layout_style->SetStyleType(pseudo_id_); - return layout_style; + ComputedStyleBuilder builder = + GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); + builder.MutableInternalStyle()->InheritFrom(style); + builder.SetContent(style.GetContentData()); + builder.SetDisplay(EDisplay::kInline); + builder.MutableInternalStyle()->SetStyleType(pseudo_id_); + return builder.TakeStyle(); } void PseudoElement::Dispose() {
diff --git a/third_party/blink/renderer/core/frame/frame_view.cc b/third_party/blink/renderer/core/frame/frame_view.cc index 6c5f619..fe499af 100644 --- a/third_party/blink/renderer/core/frame/frame_view.cc +++ b/third_party/blink/renderer/core/frame/frame_view.cc
@@ -131,7 +131,7 @@ owner_layout_object->PhysicalContentBoxOffset()); TransformationMatrix matrix = parent_frame_to_iframe_content_transform.AccumulatedTransform() - .Inverse(); + .InverseOrIdentity(); if (geometry.IsIntersecting()) { PhysicalRect intersection_rect = PhysicalRect::EnclosingRect( matrix
diff --git a/third_party/blink/renderer/core/frame/remote_frame_view.cc b/third_party/blink/renderer/core/frame/remote_frame_view.cc index 2f7819d0..3e24e52 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_view.cc +++ b/third_party/blink/renderer/core/frame/remote_frame_view.cc
@@ -149,7 +149,7 @@ owner_layout_object->MapLocalToAncestor(nullptr, local_root_transform_state, kTraverseDocumentBoundaries); TransformationMatrix matrix = - local_root_transform_state.AccumulatedTransform().Inverse(); + local_root_transform_state.AccumulatedTransform().InverseOrIdentity(); PhysicalRect local_viewport_rect = PhysicalRect::EnclosingRect( matrix.ProjectQuad(gfx::QuadF(gfx::RectF(viewport_rect))).BoundingBox()); gfx::Rect compositing_rect = ToEnclosingRect(local_viewport_rect);
diff --git a/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc b/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc index 686ddb6..398febd 100644 --- a/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc +++ b/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc
@@ -582,7 +582,7 @@ const StyleRecalcContext& style_recalc_context) { // TODO(crbug.com/1181868): This is a kind of layout. We might want to // introduce new LayoutObject. - scoped_refptr<ComputedStyle> style = + scoped_refptr<const ComputedStyle> original_style = OriginalStyleForLayoutObject(style_recalc_context); float width = 0; for (Node* child = FieldsWrapperElement()->firstChild(); child; @@ -594,17 +594,18 @@ // We need to pass the ComputedStyle of this element because child // elements can't resolve inherited style at this timing. width += static_cast<DateTimeFieldElement*>(child_element) - ->MaximumWidth(*style); + ->MaximumWidth(*original_style); } else { // ::-webkit-datetime-edit-text case. It has no // border/padding/margin in html.css. width += DateTimeFieldElement::ComputeTextWidth( - *style, child_element->textContent()); + *original_style, child_element->textContent()); } } - style->SetWidth(Length::Fixed(ceilf(width))); - style->SetCustomStyleCallbackDependsOnFont(); - return style; + ComputedStyleBuilder builder(*original_style); + builder.SetWidth(Length::Fixed(ceilf(width))); + builder.SetCustomStyleCallbackDependsOnFont(); + return builder.TakeStyle(); } void DateTimeEditElement::DidBlurFromField(mojom::blink::FocusType focus_type) {
diff --git a/third_party/blink/renderer/core/html/forms/file_input_type.cc b/third_party/blink/renderer/core/html/forms/file_input_type.cc index a8328e8a..bb7b41ca 100644 --- a/third_party/blink/renderer/core/html/forms/file_input_type.cc +++ b/third_party/blink/renderer/core/html/forms/file_input_type.cc
@@ -213,8 +213,11 @@ } } -void FileInputType::CustomStyleForLayoutObject(ComputedStyle& style) { - style.SetShouldIgnoreOverflowPropertyForInlineBlockBaseline(); +scoped_refptr<ComputedStyle> FileInputType::CustomStyleForLayoutObject( + scoped_refptr<ComputedStyle> original_style) { + ComputedStyleBuilder builder(*original_style); + builder.SetShouldIgnoreOverflowPropertyForInlineBlockBaseline(); + return builder.TakeStyle(); } LayoutObject* FileInputType::CreateLayoutObject(const ComputedStyle& style,
diff --git a/third_party/blink/renderer/core/html/forms/file_input_type.h b/third_party/blink/renderer/core/html/forms/file_input_type.h index 46281970..773d3fc 100644 --- a/third_party/blink/renderer/core/html/forms/file_input_type.h +++ b/third_party/blink/renderer/core/html/forms/file_input_type.h
@@ -73,7 +73,8 @@ String ValueMissingText() const override; void HandleDOMActivateEvent(Event&) override; void OpenPopupView() override; - void CustomStyleForLayoutObject(ComputedStyle& style) override; + scoped_refptr<ComputedStyle> CustomStyleForLayoutObject( + scoped_refptr<ComputedStyle> original_style) override; LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) const override; FileList* Files() override;
diff --git a/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc b/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc index a8912ea..f7a6f0d 100644 --- a/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc +++ b/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc
@@ -87,10 +87,9 @@ EXPECT_EQ(TextDirection::kRtl, message_dir); EXPECT_EQ(TextDirection::kLtr, sub_message_dir); - scoped_refptr<ComputedStyle> rtl_style = - ComputedStyle::Clone(input->GetLayoutObject()->StyleRef()); - rtl_style->SetDirection(TextDirection::kRtl); - input->GetLayoutObject()->SetStyle(std::move(rtl_style)); + ComputedStyleBuilder rtl_style_builder(input->GetLayoutObject()->StyleRef()); + rtl_style_builder.SetDirection(TextDirection::kRtl); + input->GetLayoutObject()->SetStyle(rtl_style_builder.TakeStyle()); input->FindCustomValidationMessageTextDirection(message, message_dir, sub_message, sub_message_dir); EXPECT_EQ(TextDirection::kRtl, message_dir);
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.cc b/third_party/blink/renderer/core/html/forms/html_input_element.cc index 21daa0d3..f165d36d 100644 --- a/third_party/blink/renderer/core/html/forms/html_input_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_input_element.cc
@@ -2184,10 +2184,10 @@ scoped_refptr<ComputedStyle> HTMLInputElement::CustomStyleForLayoutObject( const StyleRecalcContext& style_recalc_context) { - scoped_refptr<ComputedStyle> style = + scoped_refptr<ComputedStyle> original_style = OriginalStyleForLayoutObject(style_recalc_context); - input_type_view_->CustomStyleForLayoutObject(*style); - return style; + return input_type_view_->CustomStyleForLayoutObject( + std::move(original_style)); } void HTMLInputElement::DidNotifySubtreeInsertionsToDocument() {
diff --git a/third_party/blink/renderer/core/html/forms/image_input_type.cc b/third_party/blink/renderer/core/html/forms/image_input_type.cc index bd271cb..cf437ea 100644 --- a/third_party/blink/renderer/core/html/forms/image_input_type.cc +++ b/third_party/blink/renderer/core/html/forms/image_input_type.cc
@@ -276,9 +276,14 @@ HTMLImageFallbackHelper::CreateAltTextShadowTree(GetElement()); } -void ImageInputType::CustomStyleForLayoutObject(ComputedStyle& style) { - if (use_fallback_content_) - HTMLImageFallbackHelper::CustomStyleForAltText(GetElement(), style); +scoped_refptr<ComputedStyle> ImageInputType::CustomStyleForLayoutObject( + scoped_refptr<ComputedStyle> original_style) { + if (!use_fallback_content_) + return original_style; + + ComputedStyleBuilder builder(*original_style); + HTMLImageFallbackHelper::CustomStyleForAltText(GetElement(), builder); + return builder.TakeStyle(); } } // namespace blink
diff --git a/third_party/blink/renderer/core/html/forms/image_input_type.h b/third_party/blink/renderer/core/html/forms/image_input_type.h index b943a39..d6c4a47 100644 --- a/third_party/blink/renderer/core/html/forms/image_input_type.h +++ b/third_party/blink/renderer/core/html/forms/image_input_type.h
@@ -41,7 +41,8 @@ class ImageInputType final : public BaseButtonInputType { public: explicit ImageInputType(HTMLInputElement&); - void CustomStyleForLayoutObject(ComputedStyle& style) override; + scoped_refptr<ComputedStyle> CustomStyleForLayoutObject( + scoped_refptr<ComputedStyle> original_style) override; private: void CountUsage() override;
diff --git a/third_party/blink/renderer/core/html/forms/input_type_view.cc b/third_party/blink/renderer/core/html/forms/input_type_view.cc index f285ce0..661c0b7 100644 --- a/third_party/blink/renderer/core/html/forms/input_type_view.cc +++ b/third_party/blink/renderer/core/html/forms/input_type_view.cc
@@ -98,7 +98,10 @@ return LayoutObject::CreateObject(&GetElement(), style, legacy); } -void InputTypeView::CustomStyleForLayoutObject(ComputedStyle&) {} +scoped_refptr<ComputedStyle> InputTypeView::CustomStyleForLayoutObject( + scoped_refptr<ComputedStyle> original_style) { + return original_style; +} ControlPart InputTypeView::AutoAppearance() const { return kNoControlPart;
diff --git a/third_party/blink/renderer/core/html/forms/input_type_view.h b/third_party/blink/renderer/core/html/forms/input_type_view.h index 7bb5707..b1679eb6 100644 --- a/third_party/blink/renderer/core/html/forms/input_type_view.h +++ b/third_party/blink/renderer/core/html/forms/input_type_view.h
@@ -109,7 +109,8 @@ virtual void SubtreeHasChanged(); virtual LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) const; - virtual void CustomStyleForLayoutObject(ComputedStyle& style); + virtual scoped_refptr<ComputedStyle> CustomStyleForLayoutObject( + scoped_refptr<ComputedStyle> original_style); virtual ControlPart AutoAppearance() const; virtual TextDirection ComputedTextDirection(); virtual void OpenPopupView();
diff --git a/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc b/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc index f89cf1ef..d8d16ed 100644 --- a/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc +++ b/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc
@@ -376,17 +376,20 @@ ClosePopupView(); } -void MultipleFieldsTemporalInputTypeView::CustomStyleForLayoutObject( - ComputedStyle& style) { - EDisplay original_display = style.Display(); +scoped_refptr<ComputedStyle> +MultipleFieldsTemporalInputTypeView::CustomStyleForLayoutObject( + scoped_refptr<ComputedStyle> original_style) { + EDisplay original_display = original_style->Display(); EDisplay new_display = original_display; if (original_display == EDisplay::kInline || original_display == EDisplay::kInlineBlock) new_display = EDisplay::kInlineFlex; else if (original_display == EDisplay::kBlock) new_display = EDisplay::kFlex; - style.SetDisplay(new_display); - style.SetDirection(ComputedTextDirection()); + ComputedStyleBuilder builder(*original_style); + builder.SetDisplay(new_display); + builder.SetDirection(ComputedTextDirection()); + return builder.TakeStyle(); } void MultipleFieldsTemporalInputTypeView::CreateShadowSubtree() {
diff --git a/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h b/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h index c00ad8f2..ffe02b5 100644 --- a/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h +++ b/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h
@@ -98,7 +98,8 @@ void OpenPopupView() override; void ClosePopupView() override; bool HasOpenedPopup() const override; - void CustomStyleForLayoutObject(ComputedStyle& style) override; + scoped_refptr<ComputedStyle> CustomStyleForLayoutObject( + scoped_refptr<ComputedStyle> original_style) override; void CreateShadowSubtree() final; void DestroyShadowSubtree() final; void DisabledAttributeChanged() final;
diff --git a/third_party/blink/renderer/core/html/forms/select_type.cc b/third_party/blink/renderer/core/html/forms/select_type.cc index 838879e..be4bd2d 100644 --- a/third_party/blink/renderer/core/html/forms/select_type.cc +++ b/third_party/blink/renderer/core/html/forms/select_type.cc
@@ -509,16 +509,16 @@ ((option_style->Direction() != inner_style->Direction() || option_style->GetUnicodeBidi() != inner_style->GetUnicodeBidi() || option_style->GetTextAlign(true) != inner_style->GetTextAlign(true)))) { - scoped_refptr<ComputedStyle> cloned_style = - ComputedStyle::Clone(*inner_style); - cloned_style->SetDirection(option_style->Direction()); - cloned_style->SetUnicodeBidi(option_style->GetUnicodeBidi()); - cloned_style->SetTextAlign(option_style->GetTextAlign(true)); + ComputedStyleBuilder builder(*inner_style); + builder.SetDirection(option_style->Direction()); + builder.SetUnicodeBidi(option_style->GetUnicodeBidi()); + builder.SetTextAlign(option_style->GetTextAlign(true)); + scoped_refptr<const ComputedStyle> new_style = builder.TakeStyle(); if (auto* inner_layout = inner_element.GetLayoutObject()) { inner_layout->SetModifiedStyleOutsideStyleRecalc( - std::move(cloned_style), LayoutObject::ApplyStyleChanges::kYes); + std::move(new_style), LayoutObject::ApplyStyleChanges::kYes); } else { - inner_element.SetComputedStyle(std::move(cloned_style)); + inner_element.SetComputedStyle(std::move(new_style)); } } if (select_->GetLayoutObject())
diff --git a/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc b/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc index ffd1759..a7f27bd 100644 --- a/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc +++ b/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
@@ -290,21 +290,21 @@ Element* host = OwnerShadowHost(); DCHECK(host); const ComputedStyle& host_style = host->ComputedStyleRef(); - scoped_refptr<ComputedStyle> style = - OriginalStyleForLayoutObject(style_recalc_context); + ComputedStyleBuilder builder( + *OriginalStyleForLayoutObject(style_recalc_context)); if (host_style.EffectiveAppearance() == kSliderVerticalPart) - style->SetEffectiveAppearance(kSliderThumbVerticalPart); + builder.SetEffectiveAppearance(kSliderThumbVerticalPart); else if (host_style.EffectiveAppearance() == kSliderHorizontalPart) - style->SetEffectiveAppearance(kSliderThumbHorizontalPart); + builder.SetEffectiveAppearance(kSliderThumbHorizontalPart); else if (host_style.EffectiveAppearance() == kMediaSliderPart) - style->SetEffectiveAppearance(kMediaSliderThumbPart); + builder.SetEffectiveAppearance(kMediaSliderThumbPart); else if (host_style.EffectiveAppearance() == kMediaVolumeSliderPart) - style->SetEffectiveAppearance(kMediaVolumeSliderThumbPart); - if (style->HasEffectiveAppearance()) - LayoutTheme::GetTheme().AdjustSliderThumbSize(*style); + builder.SetEffectiveAppearance(kMediaVolumeSliderThumbPart); + if (builder.InternalStyle()->HasEffectiveAppearance()) + LayoutTheme::GetTheme().AdjustSliderThumbSize(builder); - return style; + return builder.TakeStyle(); } // --------------------------------
diff --git a/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc b/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc index ea4dca2..29097aa7 100644 --- a/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc +++ b/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc
@@ -146,8 +146,8 @@ // TODO(https://crbug.com/1101564): The custom inheritance done here means we // need to mark for style recalc inside style recalc. See the workaround in // LayoutTextControl::StyleDidChange. - text_block_style->SetDirection(start_style.Direction()); - text_block_style->SetUnicodeBidi(start_style.GetUnicodeBidi()); + text_block_style_builder.SetDirection(start_style.Direction()); + text_block_style_builder.SetUnicodeBidi(start_style.GetUnicodeBidi()); text_block_style_builder.SetUserSelect(EUserSelect::kText); text_block_style->SetUserModify( To<HTMLFormControlElement>(host)->IsDisabledOrReadOnly() @@ -158,7 +158,7 @@ text_block_style->SetShouldIgnoreOverflowPropertyForInlineBlockBaseline(); if (!IsA<HTMLTextAreaElement>(host)) { - text_block_style->SetWhiteSpace(EWhiteSpace::kPre); + text_block_style_builder.SetWhiteSpace(EWhiteSpace::kPre); text_block_style_builder.SetOverflowWrap(EOverflowWrap::kNormal); text_block_style_builder.SetTextOverflow( ToTextControl(host)->ValueForTextOverflow()); @@ -206,7 +206,7 @@ // Using StyleAdjuster::adjustComputedStyle updates unwanted style. We'd like // to apply only editing-related and alignment-related. - StyleAdjuster::AdjustStyleForEditing(*text_block_style); + StyleAdjuster::AdjustStyleForEditing(text_block_style_builder); if (!is_visible_) text_block_style_builder.SetOpacity(0);
diff --git a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc index 5475e65..42ba85db 100644 --- a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc +++ b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
@@ -289,10 +289,13 @@ return InputTypeView::ShouldSubmitImplicitly(event); } -void TextFieldInputType::CustomStyleForLayoutObject(ComputedStyle& style) { +scoped_refptr<ComputedStyle> TextFieldInputType::CustomStyleForLayoutObject( + scoped_refptr<ComputedStyle> original_style) { // The flag is necessary in order that a text field <input> with non-'visible' // overflow property doesn't change its baseline. - style.SetShouldIgnoreOverflowPropertyForInlineBlockBaseline(); + ComputedStyleBuilder builder(*original_style); + builder.SetShouldIgnoreOverflowPropertyForInlineBlockBaseline(); + return builder.TakeStyle(); } LayoutObject* TextFieldInputType::CreateLayoutObject(
diff --git a/third_party/blink/renderer/core/html/forms/text_field_input_type.h b/third_party/blink/renderer/core/html/forms/text_field_input_type.h index 20a921f..820d386 100644 --- a/third_party/blink/renderer/core/html/forms/text_field_input_type.h +++ b/third_party/blink/renderer/core/html/forms/text_field_input_type.h
@@ -68,7 +68,8 @@ TextFieldEventBehavior, TextControlSetValueSelection) override; void UpdateView() override; - void CustomStyleForLayoutObject(ComputedStyle& style) override; + scoped_refptr<ComputedStyle> CustomStyleForLayoutObject( + scoped_refptr<ComputedStyle> original_style) override; LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) const override; ControlPart AutoAppearance() const override;
diff --git a/third_party/blink/renderer/core/html/html_html_element.cc b/third_party/blink/renderer/core/html/html_html_element.cc index 3d66083..4d118c3 100644 --- a/third_party/blink/renderer/core/html/html_html_element.cc +++ b/third_party/blink/renderer/core/html/html_html_element.cc
@@ -75,11 +75,11 @@ scoped_refptr<const ComputedStyle> CreateLayoutStyle( const ComputedStyle& style, const ComputedStyle& propagated_style) { - scoped_refptr<ComputedStyle> layout_style = ComputedStyle::Clone(style); - layout_style->SetDirection(propagated_style.Direction()); - layout_style->SetWritingMode(propagated_style.GetWritingMode()); - layout_style->UpdateFontOrientation(); - return layout_style; + ComputedStyleBuilder builder(style); + builder.SetDirection(propagated_style.Direction()); + builder.SetWritingMode(propagated_style.GetWritingMode()); + builder.MutableInternalStyle()->UpdateFontOrientation(); + return builder.TakeStyle(); } } // namespace
diff --git a/third_party/blink/renderer/core/html/html_image_element.cc b/third_party/blink/renderer/core/html/html_image_element.cc index 0cc50785..d83d864 100644 --- a/third_party/blink/renderer/core/html/html_image_element.cc +++ b/third_party/blink/renderer/core/html/html_image_element.cc
@@ -927,10 +927,10 @@ case LayoutDisposition::kCollapsed: return OriginalStyleForLayoutObject(style_recalc_context); case LayoutDisposition::kFallbackContent: { - scoped_refptr<ComputedStyle> style = - OriginalStyleForLayoutObject(style_recalc_context); - HTMLImageFallbackHelper::CustomStyleForAltText(*this, *style); - return style; + ComputedStyleBuilder builder( + *OriginalStyleForLayoutObject(style_recalc_context)); + HTMLImageFallbackHelper::CustomStyleForAltText(*this, builder); + return builder.TakeStyle(); } default: NOTREACHED();
diff --git a/third_party/blink/renderer/core/html/html_image_fallback_helper.cc b/third_party/blink/renderer/core/html/html_image_fallback_helper.cc index b7be6e25..5b31dee0 100644 --- a/third_party/blink/renderer/core/html/html_image_fallback_helper.cc +++ b/third_party/blink/renderer/core/html/html_image_fallback_helper.cc
@@ -138,8 +138,9 @@ element.EnsureUserAgentShadowRoot().AppendChild(container); } -void HTMLImageFallbackHelper::CustomStyleForAltText(Element& element, - ComputedStyle& new_style) { +void HTMLImageFallbackHelper::CustomStyleForAltText( + Element& element, + ComputedStyleBuilder& builder) { // If we have an author shadow root or have not created the UA shadow root // yet, bail early. We can't use ensureUserAgentShadowRoot() here because that // would alter the DOM tree during style recalc. @@ -165,20 +166,20 @@ if (element.GetDocument().InQuirksMode()) { // Mimic the behaviour of the image host by setting symmetric dimensions if // only one dimension is specified. - if (!new_style.Width().IsAuto() && new_style.Height().IsAuto()) - new_style.SetHeight(new_style.Width()); - else if (!new_style.Height().IsAuto() && new_style.Width().IsAuto()) - new_style.SetWidth(new_style.Height()); + if (!builder.Width().IsAuto() && builder.Height().IsAuto()) + builder.SetHeight(builder.Width()); + else if (!builder.Height().IsAuto() && builder.Width().IsAuto()) + builder.SetWidth(builder.Height()); - if (!new_style.Width().IsAuto() && !new_style.Height().IsAuto()) + if (!builder.Width().IsAuto() && !builder.Height().IsAuto()) fallback.AlignToBaseline(); } bool has_intrinsic_dimensions = - !new_style.Width().IsAuto() && !new_style.Height().IsAuto(); + !builder.Width().IsAuto() && !builder.Height().IsAuto(); bool has_dimensions_from_ar = - !new_style.AspectRatio().IsAuto() && - (!new_style.Width().IsAuto() || !new_style.Height().IsAuto()); + !builder.AspectRatio().IsAuto() && + (!builder.Width().IsAuto() || !builder.Height().IsAuto()); bool has_no_alt_attribute = element.getAttribute(html_names::kAltAttr).empty(); bool treat_as_replaced = @@ -193,24 +194,23 @@ // attribute, or the Document is in quirks mode The user agent is expected // to treat the element as a replaced element whose content is the text that // the element represents, if any." - fallback.ShowAsReplaced(new_style.Width(), new_style.Height(), - new_style.EffectiveZoom()); + fallback.ShowAsReplaced(builder.Width(), builder.Height(), + builder.EffectiveZoom()); // 16px for the image and 2px for its top/left border/padding offset. int pixels_for_alt_image = 18; - if (ImageSmallerThanAltImage(pixels_for_alt_image, new_style.Width(), - new_style.Height())) { + if (ImageSmallerThanAltImage(pixels_for_alt_image, builder.Width(), + builder.Height())) { fallback.HideBrokenImageIcon(); } else { fallback.ShowBorder(); - fallback.ShowBrokenImageIcon(new_style.IsLeftToRightDirection()); + fallback.ShowBrokenImageIcon(builder.Direction() == TextDirection::kLtr); } } else { - if (new_style.Display() == EDisplay::kInline) { - new_style.SetWidth(Length()); - new_style.SetHeight(Length()); - new_style.SetAspectRatio( - ComputedStyleInitialValues::InitialAspectRatio()); + if (builder.Display() == EDisplay::kInline) { + builder.SetWidth(Length()); + builder.SetHeight(Length()); + builder.SetAspectRatio(ComputedStyleInitialValues::InitialAspectRatio()); } if (ElementRepresentsNothing(element)) { // "If the element is an img element that represents nothing and the user @@ -226,7 +226,7 @@ // the text, optionally with an icon indicating that an image is missing, // so that the user can request the image be displayed or investigate why // it is not rendering." - fallback.ShowBrokenImageIcon(new_style.IsLeftToRightDirection()); + fallback.ShowBrokenImageIcon(builder.Direction() == TextDirection::kLtr); } } }
diff --git a/third_party/blink/renderer/core/html/html_image_fallback_helper.h b/third_party/blink/renderer/core/html/html_image_fallback_helper.h index c2b3e860..00f45ac 100644 --- a/third_party/blink/renderer/core/html/html_image_fallback_helper.h +++ b/third_party/blink/renderer/core/html/html_image_fallback_helper.h
@@ -10,14 +10,14 @@ namespace blink { class Element; -class ComputedStyle; +class ComputedStyleBuilder; class HTMLImageFallbackHelper { STATIC_ONLY(HTMLImageFallbackHelper); public: static void CreateAltTextShadowTree(Element&); - static void CustomStyleForAltText(Element&, ComputedStyle& new_style); + static void CustomStyleForAltText(Element&, ComputedStyleBuilder&); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc index 5c67b3c..952a621 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
@@ -379,7 +379,7 @@ kTraverseDocumentBoundaries | kApplyRemoteMainFrameTransform); TransformationMatrix matrix = implicit_root_to_target_document_transform.AccumulatedTransform() - .Inverse(); + .InverseOrIdentity(); intersection_rect_ = PhysicalRect::EnclosingRect( matrix.ProjectQuad(gfx::QuadF(gfx::RectF(intersection_rect_))) .BoundingBox());
diff --git a/third_party/blink/renderer/core/layout/anchor_scroll_data.cc b/third_party/blink/renderer/core/layout/anchor_scroll_data.cc index e85cd75..37c846a 100644 --- a/third_party/blink/renderer/core/layout/anchor_scroll_data.cc +++ b/third_party/blink/renderer/core/layout/anchor_scroll_data.cc
@@ -42,6 +42,19 @@ return nullptr; } +// Returns the PaintLayer of the scroll container of an anchor-positioned |box|. +const PaintLayer* ContainingScrollContainerLayerForAnchorScroll( + const LayoutBox* box) { + // Normally, |scroller_layer| is the result. There's only one special case + // where |box| is fixed-positioned and |scroller_layer| is the LayoutView, + // then |box| doesn't actually scroll with |scroller_layer|, and null should + // be returned. + bool is_fixed_to_view = false; + const PaintLayer* scroller_layer = + box->Layer()->ContainingScrollContainerLayer(&is_fixed_to_view); + return is_fixed_to_view ? nullptr : scroller_layer; +} + } // namespace AnchorScrollData::AnchorScrollData(Element* element) @@ -65,12 +78,14 @@ const PaintLayer* starting_layer = anchor->ContainingScrollContainer()->Layer(); const PaintLayer* bounding_layer = - owner_->GetLayoutBox()->Layer()->ContainingScrollContainerLayer(); + ContainingScrollContainerLayerForAnchorScroll(owner_->GetLayoutBox()); for (const PaintLayer* layer = starting_layer; layer != bounding_layer; layer = layer->ContainingScrollContainerLayer()) { - // |bounding_layer| must be an ancestor of |starting_layer|, so we'll - // never reach a null layer here. + // |bounding_layer| must be either null (for fixed-positioned |owner_|) or + // an ancestor of |starting_layer|, so we'll never have a null layer here. DCHECK(layer); + if (!layer->GetScrollableArea()->HasOverflow()) + continue; new_scroll_container_layers.push_back(layer); new_accumulated_scroll_offset += layer->GetScrollableArea()->GetScrollOffset();
diff --git a/third_party/blink/renderer/core/layout/anchor_scroll_data_test.cc b/third_party/blink/renderer/core/layout/anchor_scroll_data_test.cc index f64952c..7f10b80 100644 --- a/third_party/blink/renderer/core/layout/anchor_scroll_data_test.cc +++ b/third_party/blink/renderer/core/layout/anchor_scroll_data_test.cc
@@ -47,10 +47,11 @@ SetBodyInnerHTML(R"HTML( <div style="position: relative"> - <div style="overflow: scroll; height: 1px;"> + <div style="overflow: scroll; height: 20px;"> Lorem ipsum <span id="anchor" style="anchor-name: --a1">anchor</span> dolor sit amet + <div style="height: 100px"></div> </div> <div id="anchored" style="position: absolute; anchor-scroll: --a1"> anchored @@ -87,10 +88,11 @@ SetBodyInnerHTML(R"HTML( <style>.anchored { position: absolute; anchor-scroll: --a1; }</style> <div style="position: relative> - <div style="overflow: scroll; height: 1px;"> + <div style="overflow: scroll; height: 20px;"> Lorem ipsum <span id="anchor" style="anchor-name: --a1">anchor</span> dolor sit amet + <div style="height: 100px"></div> </div> <div class="anchored" id="remove">Will be removed</div>
diff --git a/third_party/blink/renderer/core/layout/geometry/transform_state.cc b/third_party/blink/renderer/core/layout/geometry/transform_state.cc index 6dbd142..72617705 100644 --- a/third_party/blink/renderer/core/layout/geometry/transform_state.cc +++ b/third_party/blink/renderer/core/layout/geometry/transform_state.cc
@@ -164,9 +164,10 @@ ? accumulated_offset_ : -accumulated_offset_); if (accumulated_transform_) { - point = direction_ == kApplyTransformDirection - ? accumulated_transform_->MapPoint(point) - : accumulated_transform_->Inverse().ProjectPoint(point); + point = + direction_ == kApplyTransformDirection + ? accumulated_transform_->MapPoint(point) + : accumulated_transform_->InverseOrIdentity().ProjectPoint(point); } return PhysicalOffset::FromPointFRound(point); } @@ -182,7 +183,7 @@ if (direction_ == kApplyTransformDirection) return accumulated_transform_->MapQuad(quad); - return accumulated_transform_->Inverse().ProjectQuad(quad); + return accumulated_transform_->InverseOrIdentity().ProjectQuad(quad); } const TransformationMatrix& TransformState::AccumulatedTransform() const { @@ -197,11 +198,12 @@ if (map_quad_) last_planar_quad_ = t.MapQuad(last_planar_quad_); } else { - TransformationMatrix inverse_transform = t.Inverse(); - if (map_point_) - last_planar_point_ = inverse_transform.ProjectPoint(last_planar_point_); - if (map_quad_) { - last_planar_quad_ = inverse_transform.ProjectQuad(last_planar_quad_); + TransformationMatrix inverse_transform; + if (t.GetInverse(&inverse_transform)) { + if (map_point_) + last_planar_point_ = inverse_transform.ProjectPoint(last_planar_point_); + if (map_quad_) + last_planar_quad_ = inverse_transform.ProjectQuad(last_planar_quad_); } }
diff --git a/third_party/blink/renderer/core/layout/layout_inline.cc b/third_party/blink/renderer/core/layout/layout_inline.cc index 30e3042..25afe0a 100644 --- a/third_party/blink/renderer/core/layout/layout_inline.cc +++ b/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -240,10 +240,9 @@ InFlowPositionedInlineAncestor(block_flow->InlineElementContinuation())) continue; - scoped_refptr<ComputedStyle> new_block_style = - ComputedStyle::Clone(block->StyleRef()); - new_block_style->SetPosition(new_style.GetPosition()); - block->SetStyle(new_block_style); + ComputedStyleBuilder new_block_style_builder(block->StyleRef()); + new_block_style_builder.SetPosition(new_style.GetPosition()); + block->SetStyle(new_block_style_builder.TakeStyle()); } }
diff --git a/third_party/blink/renderer/core/layout/layout_list_item.cc b/third_party/blink/renderer/core/layout/layout_list_item.cc index 826cc78..d2b6f3d 100644 --- a/third_party/blink/renderer/core/layout/layout_list_item.cc +++ b/third_party/blink/renderer/core/layout/layout_list_item.cc
@@ -235,10 +235,13 @@ if (layout_object.StyleRef().LogicalHeight() == height) return; - scoped_refptr<ComputedStyle> new_style = - ComputedStyle::Clone(layout_object.StyleRef()); - new_style->SetLogicalHeight(height); - layout_object.SetStyle(std::move(new_style), + ComputedStyleBuilder builder(layout_object.StyleRef()); + if (layout_object.IsHorizontalWritingMode()) { + builder.SetHeight(height); + } else { + builder.SetWidth(height); + } + layout_object.SetStyle(builder.TakeStyle(), LayoutObject::ApplyStyleChanges::kNo); }
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 8c33d6bb..93c53aa8 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -2507,15 +2507,15 @@ // avoid getting an inline with positioning or an invalid display. // if (IsImage() || IsQuote()) { - scoped_refptr<ComputedStyle> style = - GetDocument().GetStyleResolver().CreateComputedStyle(); - style->InheritFrom(*pseudo_style); + ComputedStyleBuilder builder = + GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); + builder.MutableInternalStyle()->InheritFrom(*pseudo_style); if (match_parent_size) { DCHECK(IsImage()); - style->SetWidth(Length::Percent(100)); - style->SetHeight(Length::Percent(100)); + builder.SetWidth(Length::Percent(100)); + builder.SetHeight(Length::Percent(100)); } - SetStyle(std::move(style)); + SetStyle(builder.TakeStyle()); return; }
diff --git a/third_party/blink/renderer/core/layout/layout_object_test.cc b/third_party/blink/renderer/core/layout/layout_object_test.cc index 62ec2b4..51cc4ee0 100644 --- a/third_party/blink/renderer/core/layout/layout_object_test.cc +++ b/third_party/blink/renderer/core/layout/layout_object_test.cc
@@ -783,7 +783,10 @@ EXPECT_EQ(PhysicalRect(10, 10, 20, 20), mock_object->LocalVisualRect()); EXPECT_EQ(PhysicalRect(10, 10, 20, 20), mock_object->LocalVisualRect()); - style->SetVisibility(EVisibility::kHidden); + ComputedStyleBuilder builder(*style); + builder.SetVisibility(EVisibility::kHidden); + mock_object->SetStyle(builder.TakeStyle(), + LayoutObject::ApplyStyleChanges::kNo); EXPECT_CALL(*mock_object, VisualRectRespectsVisibility()) .WillOnce(Return(true)); EXPECT_TRUE(mock_object->LocalVisualRect().IsEmpty());
diff --git a/third_party/blink/renderer/core/layout/layout_table_cell.cc b/third_party/blink/renderer/core/layout/layout_table_cell.cc index 551b23e..0209b4bb 100644 --- a/third_party/blink/renderer/core/layout/layout_table_cell.cc +++ b/third_party/blink/renderer/core/layout/layout_table_cell.cc
@@ -462,10 +462,10 @@ void LayoutTableCell::UpdateStyleWritingModeFromRow(const LayoutObject* row) { NOT_DESTROYED(); DCHECK_NE(StyleRef().GetWritingMode(), row->StyleRef().GetWritingMode()); - scoped_refptr<ComputedStyle> new_style = ComputedStyle::Clone(StyleRef()); - new_style->SetWritingMode(row->StyleRef().GetWritingMode()); - new_style->UpdateFontOrientation(); - SetStyle(new_style, LayoutObject::ApplyStyleChanges::kNo); + ComputedStyleBuilder new_style_builder(StyleRef()); + new_style_builder.SetWritingMode(row->StyleRef().GetWritingMode()); + new_style_builder.MutableInternalStyle()->UpdateFontOrientation(); + SetStyle(new_style_builder.TakeStyle(), LayoutObject::ApplyStyleChanges::kNo); SetHorizontalWritingMode(StyleRef().IsHorizontalWritingMode()); UnmarkOrthogonalWritingModeRoot();
diff --git a/third_party/blink/renderer/core/layout/layout_table_row.cc b/third_party/blink/renderer/core/layout/layout_table_row.cc index 94f6572..14aba72 100644 --- a/third_party/blink/renderer/core/layout/layout_table_row.cc +++ b/third_party/blink/renderer/core/layout/layout_table_row.cc
@@ -69,9 +69,9 @@ // Legacy tables cannont handle relative/fixed rows. if (StyleRef().HasInFlowPosition()) { - scoped_refptr<ComputedStyle> new_style = ComputedStyle::Clone(StyleRef()); - new_style->SetPosition(EPosition::kStatic); - SetStyle(new_style, LayoutObject::ApplyStyleChanges::kNo); + ComputedStyleBuilder builder(StyleRef()); + builder.SetPosition(EPosition::kStatic); + SetStyle(builder.TakeStyle(), LayoutObject::ApplyStyleChanges::kNo); } LayoutTableBoxComponent::StyleDidChange(diff, old_style);
diff --git a/third_party/blink/renderer/core/layout/layout_table_section.cc b/third_party/blink/renderer/core/layout/layout_table_section.cc index 73a4980..9bf9637 100644 --- a/third_party/blink/renderer/core/layout/layout_table_section.cc +++ b/third_party/blink/renderer/core/layout/layout_table_section.cc
@@ -124,9 +124,9 @@ // Legacy tables cannot handle relative/sticky sections. if (StyleRef().HasInFlowPosition()) { - scoped_refptr<ComputedStyle> new_style = ComputedStyle::Clone(StyleRef()); - new_style->SetPosition(EPosition::kStatic); - SetStyle(new_style, LayoutObject::ApplyStyleChanges::kNo); + ComputedStyleBuilder builder(StyleRef()); + builder.SetPosition(EPosition::kStatic); + SetStyle(builder.TakeStyle(), LayoutObject::ApplyStyleChanges::kNo); } LayoutTableBoxComponent::StyleDidChange(diff, old_style);
diff --git a/third_party/blink/renderer/core/layout/layout_theme.cc b/third_party/blink/renderer/core/layout/layout_theme.cc index 5ab89da..ca131cb 100644 --- a/third_party/blink/renderer/core/layout/layout_theme.cc +++ b/third_party/blink/renderer/core/layout/layout_theme.cc
@@ -270,9 +270,9 @@ return AdjustMenuListButtonStyle(builder); case kSliderThumbHorizontalPart: case kSliderThumbVerticalPart: - return AdjustSliderThumbStyle(style); + return AdjustSliderThumbStyle(builder); case kSearchFieldCancelButtonPart: - return AdjustSearchFieldCancelButtonStyle(style); + return AdjustSearchFieldCancelButtonStyle(builder); default: break; } @@ -466,13 +466,13 @@ DCHECK(IsSliderContainer(element)); if (style.EffectiveAppearance() == kSliderVerticalPart) { - style.SetTouchAction(TouchAction::kPanX); - style.SetWritingMode(WritingMode::kVerticalRl); + builder.SetTouchAction(TouchAction::kPanX); + builder.SetWritingMode(WritingMode::kVerticalRl); // It's always in RTL because the slider value increases up even in LTR. - style.SetDirection(TextDirection::kRtl); + builder.SetDirection(TextDirection::kRtl); } else { - style.SetTouchAction(TouchAction::kPanY); - style.SetWritingMode(WritingMode::kHorizontalTb); + builder.SetTouchAction(TouchAction::kPanY); + builder.SetWritingMode(WritingMode::kHorizontalTb); if (To<HTMLInputElement>(element.OwnerShadowHost())->list()) { builder.SetAlignSelf(StyleSelfAlignmentData(ItemPosition::kCenter, OverflowAlignment::kUnsafe)); @@ -481,13 +481,14 @@ style.SetEffectiveAppearance(kNoControlPart); } -void LayoutTheme::AdjustSliderThumbStyle(ComputedStyle& style) const { - AdjustSliderThumbSize(style); +void LayoutTheme::AdjustSliderThumbStyle(ComputedStyleBuilder& builder) const { + AdjustSliderThumbSize(builder); } -void LayoutTheme::AdjustSliderThumbSize(ComputedStyle&) const {} +void LayoutTheme::AdjustSliderThumbSize(ComputedStyleBuilder&) const {} -void LayoutTheme::AdjustSearchFieldCancelButtonStyle(ComputedStyle&) const {} +void LayoutTheme::AdjustSearchFieldCancelButtonStyle( + ComputedStyleBuilder&) const {} void LayoutTheme::PlatformColorsDidChange() { UpdateForcedColorsState();
diff --git a/third_party/blink/renderer/core/layout/layout_theme.h b/third_party/blink/renderer/core/layout/layout_theme.h index 16c459e..04220a8 100644 --- a/third_party/blink/renderer/core/layout/layout_theme.h +++ b/third_party/blink/renderer/core/layout/layout_theme.h
@@ -145,7 +145,7 @@ virtual Color SystemColor(CSSValueID, mojom::blink::ColorScheme color_scheme) const; - virtual void AdjustSliderThumbSize(ComputedStyle&) const; + virtual void AdjustSliderThumbSize(ComputedStyleBuilder&) const; virtual int PopupInternalPaddingStart(const ComputedStyle&) const { return 0; @@ -222,8 +222,8 @@ virtual void AdjustSliderContainerStyle(const Element&, ComputedStyle&, ComputedStyleBuilder&) const; - virtual void AdjustSliderThumbStyle(ComputedStyle&) const; - virtual void AdjustSearchFieldCancelButtonStyle(ComputedStyle&) const; + virtual void AdjustSliderThumbStyle(ComputedStyleBuilder&) const; + virtual void AdjustSearchFieldCancelButtonStyle(ComputedStyleBuilder&) const; bool HasCustomFocusRingColor() const; Color GetCustomFocusRingColor() const;
diff --git a/third_party/blink/renderer/core/layout/layout_theme_default.cc b/third_party/blink/renderer/core/layout/layout_theme_default.cc index 17f62c0..de8b873 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_default.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_default.cc
@@ -146,17 +146,18 @@ return 7; } -void LayoutThemeDefault::AdjustSliderThumbSize(ComputedStyle& style) const { +void LayoutThemeDefault::AdjustSliderThumbSize( + ComputedStyleBuilder& builder) const { gfx::Size size = WebThemeEngineHelper::GetNativeThemeEngine()->GetSize( WebThemeEngine::kPartSliderThumb); - float zoom_level = style.EffectiveZoom(); - if (style.EffectiveAppearance() == kSliderThumbHorizontalPart) { - style.SetWidth(Length::Fixed(size.width() * zoom_level)); - style.SetHeight(Length::Fixed(size.height() * zoom_level)); - } else if (style.EffectiveAppearance() == kSliderThumbVerticalPart) { - style.SetWidth(Length::Fixed(size.height() * zoom_level)); - style.SetHeight(Length::Fixed(size.width() * zoom_level)); + float zoom_level = builder.EffectiveZoom(); + if (builder.EffectiveAppearance() == kSliderThumbHorizontalPart) { + builder.SetWidth(Length::Fixed(size.width() * zoom_level)); + builder.SetHeight(Length::Fixed(size.height() * zoom_level)); + } else if (builder.EffectiveAppearance() == kSliderThumbVerticalPart) { + builder.SetWidth(Length::Fixed(size.height() * zoom_level)); + builder.SetHeight(Length::Fixed(size.width() * zoom_level)); } } @@ -199,14 +200,15 @@ } void LayoutThemeDefault::AdjustSearchFieldCancelButtonStyle( - ComputedStyle& style) const { + ComputedStyleBuilder& builder) const { // Scale the button size based on the font size - float font_scale = style.FontSize() / kDefaultControlFontPixelSize; + float font_scale = + builder.InternalStyle()->FontSize() / kDefaultControlFontPixelSize; int cancel_button_size = static_cast<int>(lroundf(std::min( std::max(kMinCancelButtonSize, kDefaultCancelButtonSize * font_scale), kMaxCancelButtonSize))); - style.SetWidth(Length::Fixed(cancel_button_size)); - style.SetHeight(Length::Fixed(cancel_button_size)); + builder.SetWidth(Length::Fixed(cancel_button_size)); + builder.SetHeight(Length::Fixed(cancel_button_size)); } void LayoutThemeDefault::AdjustMenuListStyle(
diff --git a/third_party/blink/renderer/core/layout/layout_theme_default.h b/third_party/blink/renderer/core/layout/layout_theme_default.h index bb2c28d3..e7e1af5 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_default.h +++ b/third_party/blink/renderer/core/layout/layout_theme_default.h
@@ -59,7 +59,7 @@ gfx::Size SliderTickSize() const override; int SliderTickOffsetFromTrackCenter() const override; - void AdjustSliderThumbSize(ComputedStyle&) const override; + void AdjustSliderThumbSize(ComputedStyleBuilder&) const override; void AdjustInnerSpinButtonStyle(ComputedStyleBuilder&) const override; void AdjustButtonStyle(ComputedStyleBuilder&) const override; @@ -74,7 +74,7 @@ Color inactive_foreground_color) override; Color PlatformFocusRingColor() const override; - void AdjustSearchFieldCancelButtonStyle(ComputedStyle&) const override; + void AdjustSearchFieldCancelButtonStyle(ComputedStyleBuilder&) const override; // MenuList refers to an unstyled menulist (meaning a menulist without // background-color or border set) and MenuListButton refers to a styled
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc index 8ef4ebf..3a553699 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc
@@ -47,16 +47,19 @@ LayoutBlockFlow* GetLayoutBlockFlow() const { return block_flow_; } void SetWhiteSpace(EWhiteSpace whitespace) { - style_->SetWhiteSpace(whitespace); + ComputedStyleBuilder builder(*style_); + builder.SetWhiteSpace(whitespace); + style_ = builder.TakeStyle(); + block_flow_->SetStyle(style_, LayoutObject::ApplyStyleChanges::kNo); } - scoped_refptr<ComputedStyle> GetStyle(EWhiteSpace whitespace) { + scoped_refptr<const ComputedStyle> GetStyle(EWhiteSpace whitespace) { if (whitespace == EWhiteSpace::kNormal) return style_; - scoped_refptr<ComputedStyle> style( - GetDocument().GetStyleResolver().CreateComputedStyle()); - style->SetWhiteSpace(whitespace); - return style; + ComputedStyleBuilder builder = + GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); + builder.SetWhiteSpace(whitespace); + return builder.TakeStyle(); } bool HasRuby(const NGInlineItemsBuilder& builder) const { @@ -466,10 +469,12 @@ TEST_F(NGInlineItemsBuilderTest, BidiBlockOverride) { HeapVector<NGInlineItem> items; NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items); - scoped_refptr<ComputedStyle> block_style( - GetDocument().GetStyleResolver().CreateComputedStyle()); - block_style->SetUnicodeBidi(UnicodeBidi::kBidiOverride); - block_style->SetDirection(TextDirection::kRtl); + ComputedStyleBuilder block_style_builder( + *GetDocument().GetStyleResolver().CreateComputedStyle()); + block_style_builder.SetUnicodeBidi(UnicodeBidi::kBidiOverride); + block_style_builder.SetDirection(TextDirection::kRtl); + scoped_refptr<const ComputedStyle> block_style = + block_style_builder.TakeStyle(); builder.EnterBlock(block_style.get()); AppendText("Hello", &builder); builder.ExitBlock(); @@ -484,12 +489,12 @@ static LayoutInline* CreateLayoutInline( Document* document, - void (*initialize_style)(ComputedStyle*)) { - scoped_refptr<ComputedStyle> style( - document->GetStyleResolver().CreateComputedStyle()); - initialize_style(style.get()); + void (*initialize_style)(ComputedStyleBuilder&)) { + ComputedStyleBuilder builder = + document->GetStyleResolver().CreateComputedStyleBuilder(); + initialize_style(builder); LayoutInline* const node = LayoutInline::CreateAnonymous(document); - node->SetStyle(std::move(style), LayoutObject::ApplyStyleChanges::kNo); + node->SetStyle(builder.TakeStyle(), LayoutObject::ApplyStyleChanges::kNo); node->SetIsInLayoutNGInlineFormattingContext(true); return node; } @@ -499,9 +504,9 @@ NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items); AppendText("Hello ", &builder); LayoutInline* const isolate_rtl = - CreateLayoutInline(&GetDocument(), [](ComputedStyle* style) { - style->SetUnicodeBidi(UnicodeBidi::kIsolate); - style->SetDirection(TextDirection::kRtl); + CreateLayoutInline(&GetDocument(), [](ComputedStyleBuilder& builder) { + builder.SetUnicodeBidi(UnicodeBidi::kIsolate); + builder.SetDirection(TextDirection::kRtl); }); builder.EnterInline(isolate_rtl); AppendText(u"\u05E2\u05D1\u05E8\u05D9\u05EA", &builder); @@ -524,9 +529,9 @@ NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items); AppendText("Hello ", &builder); LayoutInline* const isolate_override_rtl = - CreateLayoutInline(&GetDocument(), [](ComputedStyle* style) { - style->SetUnicodeBidi(UnicodeBidi::kIsolateOverride); - style->SetDirection(TextDirection::kRtl); + CreateLayoutInline(&GetDocument(), [](ComputedStyleBuilder& builder) { + builder.SetUnicodeBidi(UnicodeBidi::kIsolateOverride); + builder.SetDirection(TextDirection::kRtl); }); builder.EnterInline(isolate_override_rtl); AppendText(u"\u05E2\u05D1\u05E8\u05D9\u05EA", &builder);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h b/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h index 042bde1..688008a 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h
@@ -257,6 +257,10 @@ void SetShouldPropagateChildBreakValues( bool propagate_child_break_values = true) { + // Don't create rare data if `propagate_child_break_values` is already + // false. + if (!space_.HasRareData() && !propagate_child_break_values) + return; space_.EnsureRareData()->propagate_child_break_values = propagate_child_break_values; }
diff --git a/third_party/blink/renderer/core/paint/hit_testing_transform_state.cc b/third_party/blink/renderer/core/paint/hit_testing_transform_state.cc index 184c565..64f363e3 100644 --- a/third_party/blink/renderer/core/paint/hit_testing_transform_state.cc +++ b/third_party/blink/renderer/core/paint/hit_testing_transform_state.cc
@@ -53,20 +53,24 @@ } void HitTestingTransformState::Flatten() { - TransformationMatrix inverse_transform = accumulated_transform_.Inverse(); - last_planar_point_ = inverse_transform.ProjectPoint(last_planar_point_); - last_planar_quad_ = inverse_transform.ProjectQuad(last_planar_quad_); - last_planar_area_ = inverse_transform.ProjectQuad(last_planar_area_); + TransformationMatrix inverse_transform; + if (accumulated_transform_.GetInverse(&inverse_transform)) { + last_planar_point_ = inverse_transform.ProjectPoint(last_planar_point_); + last_planar_quad_ = inverse_transform.ProjectQuad(last_planar_quad_); + last_planar_area_ = inverse_transform.ProjectQuad(last_planar_area_); + } accumulated_transform_.MakeIdentity(); } gfx::PointF HitTestingTransformState::MappedPoint() const { - return accumulated_transform_.Inverse().ProjectPoint(last_planar_point_); + return accumulated_transform_.InverseOrIdentity().ProjectPoint( + last_planar_point_); } gfx::QuadF HitTestingTransformState::MappedQuad() const { - return accumulated_transform_.Inverse().ProjectQuad(last_planar_quad_); + return accumulated_transform_.InverseOrIdentity().ProjectQuad( + last_planar_quad_); } PhysicalRect HitTestingTransformState::BoundsOfMappedQuad() const { @@ -80,7 +84,7 @@ PhysicalRect HitTestingTransformState::BoundsOfMappedQuadInternal( const gfx::QuadF& q) const { gfx::RectF rect = - accumulated_transform_.Inverse().ProjectQuad(q).BoundingBox(); + accumulated_transform_.InverseOrIdentity().ProjectQuad(q).BoundingBox(); PhysicalOffset offset(LayoutUnit::FromFloatRound(rect.x()), LayoutUnit::FromFloatRound(rect.y())); PhysicalSize size(LayoutUnit::FromFloatRound(rect.right()) - offset.left,
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_combine_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_text_combine_painter.cc index a111d7e..14bc17da 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_text_combine_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_text_combine_painter.cc
@@ -105,10 +105,10 @@ const NGTextDecorationOffset decoration_offset(style_, style_); - // Paint text decorations except line through - PaintDecorationsExceptLineThrough( - NGTextFragmentPaintInfo{}, decoration_offset, decoration_info, - ~TextDecorationLine::kNone, paint_info, text_style); + // Paint underline and overline text decorations + PaintUnderOrOverLineDecorations(NGTextFragmentPaintInfo{}, decoration_offset, + decoration_info, ~TextDecorationLine::kNone, + paint_info, text_style); // Paint line through if needed PaintDecorationsOnlyLineThrough(decoration_info, paint_info, text_style);
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc index 61a51b5..897d917 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc
@@ -285,7 +285,7 @@ decoration_info, lines_to_paint, paint_info, text_style); } else { - NGTextPainterBase::PaintDecorationsExceptLineThrough( + NGTextPainterBase::PaintUnderOrOverLineDecorations( fragment_paint_info, decoration_offset, decoration_info, lines_to_paint, paint_info, text_style, nullptr); } @@ -508,7 +508,7 @@ if (SetupPaintForSvgText(state, graphics_context_, style_to_paint, SvgPaintMode::kTextDecoration, *resource_mode, flags)) { - NGTextPainterBase::PaintDecorationsExceptLineThrough( + NGTextPainterBase::PaintUnderOrOverLineDecorations( fragment_paint_info, decoration_offset, decoration_info, lines_to_paint, paint_info, text_style, &flags); }
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.cc b/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.cc index 2066804..afecde7 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.cc
@@ -22,12 +22,12 @@ namespace blink { -// We have two functions to paint text decoations, because we should paint +// We have two functions to paint text decorations, because we should paint // text and decorations in following order: -// 1. Paint text decorations except line through +// 1. Paint underline or overline text decorations // 2. Paint text -// 3. Paint line throguh -void NGTextPainterBase::PaintDecorationsExceptLineThrough( +// 3. Paint line through +void NGTextPainterBase::PaintUnderOrOverLineDecorations( const NGTextFragmentPaintInfo& fragment_paint_info, const TextDecorationOffsetBase& decoration_offset, TextDecorationInfo& decoration_info, @@ -44,8 +44,72 @@ GraphicsContext& context = paint_info.context; GraphicsContextStateSaver state_saver(context); - UpdateGraphicsContext(context, text_style, state_saver); + // Updating Graphics Context for text only (kTextProperOnly), + // instead of the default text and shadows (kBothShadowsAndTextProper), + // because shadows will be painted by + // NGTextPainterBase::PaintUnderOrOverLineDecorationShadows. + UpdateGraphicsContext(context, text_style, state_saver, + ShadowMode::kTextProperOnly); + + PaintUnderOrOverLineDecorationShadows(fragment_paint_info, decoration_offset, + decoration_info, lines_to_paint, flags, + text_style, context); + + PaintUnderOrOverLineDecorations(fragment_paint_info, decoration_offset, + decoration_info, lines_to_paint, flags, + context); +} + +void NGTextPainterBase::PaintUnderOrOverLineDecorationShadows( + const NGTextFragmentPaintInfo& fragment_paint_info, + const TextDecorationOffsetBase& decoration_offset, + TextDecorationInfo& decoration_info, + TextDecorationLine lines_to_paint, + const cc::PaintFlags* flags, + const TextPaintStyle& text_style, + GraphicsContext& context) { + if (text_style.shadow == nullptr) + return; + + const ShadowList* shadow_list = text_style.shadow.get(); + if (shadow_list == nullptr) + return; + + for (const auto& shadow : shadow_list->Shadows()) { + const Color& color = shadow.GetColor().Resolve(text_style.current_color, + text_style.color_scheme); + // Detect when there's no effective shadow. + if (color.IsTransparent()) + continue; + + const gfx::Vector2dF& offset = shadow.Location().OffsetFromOrigin(); + + float blur = shadow.Blur(); + DCHECK_GE(blur, 0); + const auto sigma = BlurRadiusToStdDev(blur); + + context.BeginLayer( + 1.0f, SkBlendMode::kSrcOver, nullptr, kColorFilterNone, + sk_make_sp<DropShadowPaintFilter>( + offset.x(), offset.y(), sigma, sigma, color.toSkColor4f(), + DropShadowPaintFilter::ShadowMode::kDrawShadowOnly, nullptr)); + + PaintUnderOrOverLineDecorations(fragment_paint_info, decoration_offset, + decoration_info, lines_to_paint, flags, + context); + + context.EndLayer(); + } +} + +void NGTextPainterBase::PaintUnderOrOverLineDecorations( + const NGTextFragmentPaintInfo& fragment_paint_info, + const TextDecorationOffsetBase& decoration_offset, + TextDecorationInfo& decoration_info, + TextDecorationLine lines_to_paint, + const cc::PaintFlags* flags, + GraphicsContext& context) { for (wtf_size_t i = 0; i < decoration_info.AppliedDecorationCount(); i++) { decoration_info.SetDecorationIndex(i); context.SetStrokeThickness(decoration_info.ResolvedThickness());
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.h b/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.h index 3c13cb10..5208b3e 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.h +++ b/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.h
@@ -45,12 +45,12 @@ ~NGTextPainterBase() = default; protected: - // We have two functions to paint text decoations, because we should paint + // We have two functions to paint text decorations, because we should paint // text and decorations in following order: - // 1. Paint text decorations except line through + // 1. Paint underline or overline text decorations // 2. Paint text - // 3. Paint line through - void PaintDecorationsExceptLineThrough( + // 3. Paint line through text decoration + void PaintUnderOrOverLineDecorations( const NGTextFragmentPaintInfo& fragment_paint_info, const TextDecorationOffsetBase& decoration_offset, TextDecorationInfo& decoration_info, @@ -59,6 +59,12 @@ const TextPaintStyle& text_style, const cc::PaintFlags* flags = nullptr); + virtual void ClipDecorationsStripe(const NGTextFragmentPaintInfo&, + float upper, + float stripe_width, + float dilation) = 0; + + private: void PaintDecorationUnderOrOverLine( const NGTextFragmentPaintInfo& fragment_paint_info, GraphicsContext& context, @@ -66,10 +72,22 @@ TextDecorationLine line, const cc::PaintFlags* flags = nullptr); - virtual void ClipDecorationsStripe(const NGTextFragmentPaintInfo&, - float upper, - float stripe_width, - float dilation) = 0; + void PaintUnderOrOverLineDecorationShadows( + const NGTextFragmentPaintInfo& fragment_paint_info, + const TextDecorationOffsetBase& decoration_offset, + TextDecorationInfo& decoration_info, + TextDecorationLine lines_to_paint, + const cc::PaintFlags* flags, + const TextPaintStyle& text_style, + GraphicsContext& context); + + void PaintUnderOrOverLineDecorations( + const NGTextFragmentPaintInfo& fragment_paint_info, + const TextDecorationOffsetBase& decoration_offset, + TextDecorationInfo& decoration_info, + TextDecorationLine lines_to_paint, + const cc::PaintFlags* flags, + GraphicsContext& context); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc index d4073c1d..1a54db9 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.cc +++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -1643,7 +1643,7 @@ if (local_transform_state && layout_object.StyleRef().BackfaceVisibility() == EBackfaceVisibility::kHidden) { STACK_UNINITIALIZED TransformationMatrix inverted_matrix = - local_transform_state->AccumulatedTransform().Inverse(); + local_transform_state->AccumulatedTransform().InverseOrIdentity(); // If the z-vector of the matrix is negative, the back is facing towards the // viewer. TODO(crbug.com/1359528): Use something like // gfx::Transform::IsBackfaceVisible().
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc index 4f6937c..1157bdb 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -808,6 +808,7 @@ .FirstFragment() .PaintProperties() ->ScrollTranslation(); + DCHECK(inner_most_scroll_container); scoped_refptr<const TransformPaintPropertyNode> outer_most_scroll_container = anchor_scroll_data.ScrollContainerLayers() @@ -816,6 +817,7 @@ .FirstFragment() .PaintProperties() ->ScrollTranslation(); + DCHECK(outer_most_scroll_container); state.anchor_scroll_containers_data = std::make_unique< TransformPaintPropertyNode::AnchorScrollContainersData>( std::move(inner_most_scroll_container),
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc index f7dd7dfb..76ad462 100644 --- a/third_party/blink/renderer/core/style/computed_style.cc +++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -1206,28 +1206,10 @@ return false; } -void ComputedStyle::AddCursor(StyleImage* image, - bool hot_spot_specified, - const gfx::Point& hot_spot) { - if (!CursorDataInternal()) - SetCursorDataInternal(MakeGarbageCollected<CursorList>()); - MutableCursorDataInternal()->push_back( - CursorData(image, hot_spot_specified, hot_spot)); -} - -void ComputedStyle::SetCursorList(CursorList* other) { - SetCursorDataInternal(other); -} - bool ComputedStyle::QuotesDataEquivalent(const ComputedStyle& other) const { return base::ValuesEquivalent(Quotes(), other.Quotes()); } -void ComputedStyle::ClearCursorList() { - if (CursorDataInternal()) - SetCursorDataInternal(nullptr); -} - static bool HasPropertyThatCreatesStackingContext( const Vector<CSSPropertyID>& properties) { for (CSSPropertyID property : properties) { @@ -1296,10 +1278,6 @@ MutableCallbackSelectorsInternal().push_back(selector); } -void ComputedStyle::SetContent(ContentData* content_data) { - SetContentInternal(content_data); -} - static bool IsWillChangeTransformHintProperty(CSSPropertyID property) { switch (ResolveCSSPropertyID(property)) { case CSSPropertyID::kTransform: @@ -1561,13 +1539,6 @@ return base::ValuesEquivalent(TextShadow(), other.TextShadow()); } -StyleImage* ComputedStyle::ListStyleImage() const { - return ListStyleImageInternal(); -} -void ComputedStyle::SetListStyleImage(StyleImage* v) { - SetListStyleImageInternal(v); -} - bool ComputedStyle::SetEffectiveZoom(float f) { // Clamp the effective zoom value to a smaller (but hopeful still large // enough) range, to avoid overflow in derived computations.
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index 673cd492..1fb2355 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -500,31 +500,18 @@ DCHECK(BackdropFilterInternal().Get()); return BackdropFilterInternal()->operations_; } - FilterOperations& MutableBackdropFilter() { - DCHECK(BackdropFilterInternal().Get()); - return MutableBackdropFilterInternal()->operations_; - } // For containing blocks, use |HasNonInitialBackdropFilter()| which includes // will-change: backdrop-filter. bool HasBackdropFilter() const { DCHECK(BackdropFilterInternal().Get()); return !BackdropFilterInternal()->operations_.Operations().empty(); } - void SetBackdropFilter(const FilterOperations& ops) { - DCHECK(BackdropFilterInternal().Get()); - if (BackdropFilterInternal()->operations_ != ops) - MutableBackdropFilterInternal()->operations_ = ops; - } bool BackdropFilterDataEquivalent(const ComputedStyle& o) const { return base::ValuesEquivalent(BackdropFilterInternal(), o.BackdropFilterInternal()); } // filter (aka -webkit-filter) - FilterOperations& MutableFilter() { - DCHECK(FilterInternal().Get()); - return MutableFilterInternal()->operations_; - } const FilterOperations& Filter() const { DCHECK(FilterInternal().Get()); return FilterInternal()->operations_; @@ -535,11 +522,6 @@ DCHECK(FilterInternal().Get()); return !FilterInternal()->operations_.Operations().empty(); } - void SetFilter(const FilterOperations& v) { - DCHECK(FilterInternal().Get()); - if (FilterInternal()->operations_ != v) - MutableFilterInternal()->operations_ = v; - } bool FilterDataEquivalent(const ComputedStyle& o) const { return base::ValuesEquivalent(FilterInternal(), o.FilterInternal()); } @@ -633,20 +615,6 @@ // in more easily accessible memory. return HasClipPath() ? ClipPathInternal().get() : nullptr; } - void SetClipPath(scoped_refptr<ClipPathOperation> clip_path) { - SetHasClipPath(clip_path.get()); - SetClipPathInternal(std::move(clip_path)); - } - - // clip - void SetClip(const LengthBox& box) { - SetHasAutoClipInternal(false); - SetClipInternal(box); - } - void SetHasAutoClip() { - SetHasAutoClipInternal(true); - SetClipInternal(ComputedStyleInitialValues::InitialClip()); - } // column-rule-width uint16_t ColumnRuleWidth() const { @@ -658,7 +626,6 @@ // content ContentData* GetContentData() const { return ContentInternal().Get(); } - void SetContent(ContentData*); // -webkit-line-clamp bool HasLineClamp() const { return LineClamp() > 0; } @@ -838,9 +805,6 @@ Length LineHeight() const; // List style properties. - // list-style-image - CORE_EXPORT StyleImage* ListStyleImage() const; - void SetListStyleImage(StyleImage*); // list-style-type const AtomicString& ListStyleStringValue() const; @@ -1247,21 +1211,6 @@ const Length& LogicalHeight() const { return IsHorizontalWritingMode() ? Height() : Width(); } - void SetLogicalWidth(const Length& v) { - if (IsHorizontalWritingMode()) { - SetWidth(v); - } else { - SetHeight(v); - } - } - - void SetLogicalHeight(const Length& v) { - if (IsHorizontalWritingMode()) { - SetHeight(v); - } else { - SetWidth(v); - } - } const Length& LogicalMaxWidth() const { return IsHorizontalWritingMode() ? MaxWidth() : MaxHeight(); } @@ -1825,11 +1774,6 @@ // Cursor utility functions. CursorList* Cursors() const { return CursorDataInternal().Get(); } - CORE_EXPORT void AddCursor(StyleImage*, - bool hot_spot_specified, - const gfx::Point& hot_spot = gfx::Point()); - void SetCursorList(CursorList*); - void ClearCursorList(); // Resize utility functions. bool HasResize() const { @@ -2850,6 +2794,33 @@ } #endif // DCHECK_IS_ON() + // backdrop-filter + FilterOperations& MutableBackdropFilter() { + DCHECK(BackdropFilterInternal().Get()); + return MutableBackdropFilterInternal()->operations_; + } + void SetBackdropFilter(const FilterOperations& ops) { + DCHECK(BackdropFilterInternal().Get()); + if (BackdropFilterInternal()->operations_ != ops) + MutableBackdropFilterInternal()->operations_ = ops; + } + + // clip + void SetClip(const LengthBox& box) { + SetHasAutoClipInternal(false); + SetClipInternal(box); + } + void SetHasAutoClip() { + SetHasAutoClipInternal(true); + SetClipInternal(ComputedStyleInitialValues::InitialClip()); + } + + // clip-patch + void SetClipPath(scoped_refptr<ClipPathOperation> clip_path) { + SetHasClipPath(clip_path.get()); + SetClipPathInternal(std::move(clip_path)); + } + // column-count void SetColumnCount(uint16_t c) { SetHasAutoColumnCountInternal(false); @@ -2875,6 +2846,32 @@ SetColumnWidthInternal(0); } + // cursor + void AddCursor(StyleImage* image, + bool hot_spot_specified, + const gfx::Point& hot_spot = gfx::Point()) { + if (!CursorDataInternal()) + SetCursorDataInternal(MakeGarbageCollected<CursorList>()); + MutableCursorDataInternal()->push_back( + CursorData(image, hot_spot_specified, hot_spot)); + } + void SetCursorList(CursorList* list) { SetCursorDataInternal(list); } + void ClearCursorList() { + if (CursorDataInternal()) + SetCursorDataInternal(nullptr); + } + + // filter + FilterOperations& MutableFilter() { + DCHECK(FilterInternal().Get()); + return MutableFilterInternal()->operations_; + } + void SetFilter(const FilterOperations& v) { + DCHECK(FilterInternal().Get()); + if (FilterInternal()->operations_ != v) + MutableFilterInternal()->operations_ = v; + } + // margin-* void SetMarginTop(const Length& v) { if (MarginTop() != v) {
diff --git a/third_party/blink/renderer/core/style/computed_style_test.cc b/third_party/blink/renderer/core/style/computed_style_test.cc index d3ff35e..792203549 100644 --- a/third_party/blink/renderer/core/style/computed_style_test.cc +++ b/third_party/blink/renderer/core/style/computed_style_test.cc
@@ -65,11 +65,11 @@ TEST_F(ComputedStyleTest, ShapeOutsideBoxEqual) { auto* shape1 = MakeGarbageCollected<ShapeValue>(CSSBoxType::kContent); auto* shape2 = MakeGarbageCollected<ShapeValue>(CSSBoxType::kContent); - scoped_refptr<ComputedStyle> style1 = CreateComputedStyle(); - scoped_refptr<ComputedStyle> style2 = CreateComputedStyle(); - style1->SetShapeOutside(shape1); - style2->SetShapeOutside(shape2); - EXPECT_EQ(*style1, *style2); + ComputedStyleBuilder builder1 = CreateComputedStyleBuilder(); + ComputedStyleBuilder builder2 = CreateComputedStyleBuilder(); + builder1.SetShapeOutside(shape1); + builder2.SetShapeOutside(shape2); + EXPECT_EQ(*builder1.TakeStyle(), *builder2.TakeStyle()); } TEST_F(ComputedStyleTest, ShapeOutsideCircleEqual) { @@ -79,11 +79,11 @@ CSSBoxType::kContent); auto* shape2 = MakeGarbageCollected<ShapeValue>(std::move(circle2), CSSBoxType::kContent); - scoped_refptr<ComputedStyle> style1 = CreateComputedStyle(); - scoped_refptr<ComputedStyle> style2 = CreateComputedStyle(); - style1->SetShapeOutside(shape1); - style2->SetShapeOutside(shape2); - EXPECT_EQ(*style1, *style2); + ComputedStyleBuilder builder1 = CreateComputedStyleBuilder(); + ComputedStyleBuilder builder2 = CreateComputedStyleBuilder(); + builder1.SetShapeOutside(shape1); + builder2.SetShapeOutside(shape2); + EXPECT_EQ(*builder1.TakeStyle(), *builder2.TakeStyle()); } TEST_F(ComputedStyleTest, ClipPathEqual) { @@ -92,11 +92,11 @@ ShapeClipPathOperation::Create(shape); scoped_refptr<ShapeClipPathOperation> path2 = ShapeClipPathOperation::Create(shape); - scoped_refptr<ComputedStyle> style1 = CreateComputedStyle(); - scoped_refptr<ComputedStyle> style2 = CreateComputedStyle(); - style1->SetClipPath(path1); - style2->SetClipPath(path2); - EXPECT_EQ(*style1, *style2); + ComputedStyleBuilder builder1 = CreateComputedStyleBuilder(); + ComputedStyleBuilder builder2 = CreateComputedStyleBuilder(); + builder1.SetClipPath(path1); + builder2.SetClipPath(path2); + EXPECT_EQ(*builder1.TakeStyle(), *builder2.TakeStyle()); } TEST_F(ComputedStyleTest, SVGStackingContext) { @@ -118,10 +118,14 @@ } TEST_F(ComputedStyleTest, LayoutContainmentStackingContext) { - scoped_refptr<ComputedStyle> style = CreateComputedStyle(); + scoped_refptr<const ComputedStyle> style = CreateComputedStyle(); EXPECT_FALSE(style->IsStackingContextWithoutContainment()); - style->SetContain(kContainsLayout); - style->UpdateIsStackingContextWithoutContainment(false, false, false); + + ComputedStyleBuilder builder(*style); + builder.SetContain(kContainsLayout); + builder.MutableInternalStyle()->UpdateIsStackingContextWithoutContainment( + false, false, false); + style = builder.TakeStyle(); // Containment doesn't change IsStackingContextWithoutContainment EXPECT_FALSE(style->IsStackingContextWithoutContainment()); } @@ -287,11 +291,12 @@ TEST_F(ComputedStyleTest, UpdatePropertySpecificDifferencesCompositingReasonsContainsPaint) { - scoped_refptr<ComputedStyle> style = CreateComputedStyle(); - scoped_refptr<ComputedStyle> other = ComputedStyle::Clone(*style); - + scoped_refptr<const ComputedStyle> style = CreateComputedStyle(); + ComputedStyleBuilder builder(*style); // This induces a flat used transform style. - other->SetContain(kContainsPaint); + builder.SetContain(kContainsPaint); + scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + StyleDifference diff; style->UpdatePropertySpecificDifferences(*other, diff); EXPECT_TRUE(diff.CompositingReasonsChanged()); @@ -332,9 +337,6 @@ } TEST_F(ComputedStyleTest, CursorList) { - scoped_refptr<ComputedStyle> style = CreateComputedStyle(); - scoped_refptr<ComputedStyle> other = CreateComputedStyle(); - auto* gradient = MakeGarbageCollected<cssvalue::CSSLinearGradientValue>( nullptr, nullptr, nullptr, nullptr, nullptr, cssvalue::kRepeating); @@ -345,8 +347,13 @@ EXPECT_TRUE(base::ValuesEquivalent(image_value, other_image_value)); - style->AddCursor(image_value, false); - other->AddCursor(other_image_value, false); + ComputedStyleBuilder builder = CreateComputedStyleBuilder(); + builder.AddCursor(image_value, false); + scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + + builder = CreateComputedStyleBuilder(); + builder.AddCursor(other_image_value, false); + scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); EXPECT_EQ(*style, *other); } @@ -1500,11 +1507,14 @@ TEST_F(ComputedStyleTest, DebugDiffFields) { using DebugField = ComputedStyleBase::DebugField; - scoped_refptr<ComputedStyle> style1 = CreateComputedStyle(); - scoped_refptr<ComputedStyle> style2 = CreateComputedStyle(); + ComputedStyleBuilder builder1 = CreateComputedStyleBuilder(); + ComputedStyleBuilder builder2 = CreateComputedStyleBuilder(); - style1->SetWidth(Length(100.0, Length::kFixed)); - style2->SetWidth(Length(200.0, Length::kFixed)); + builder1.SetWidth(Length(100.0, Length::kFixed)); + builder2.SetWidth(Length(200.0, Length::kFixed)); + + scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); + scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); EXPECT_EQ(0u, style1->DebugDiffFields(*style1).size()); EXPECT_EQ(0u, style2->DebugDiffFields(*style2).size());
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index a44d76ce0..9c3b55a 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -3973,12 +3973,6 @@ bool already_visited = visited.Contains(this); visited.insert(this); - // Slots are elements that cannot be named. - if (IsA<HTMLSlotElement>(GetNode())) { - *found_text_alternative = false; - return String(); - } - // Step 2A from: http://www.w3.org/TR/accname-aam-1.1 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. if (IsHiddenForTextAlternativeCalculation(aria_label_or_description_root)) {
diff --git a/third_party/blink/renderer/modules/mediarecorder/DEPS b/third_party/blink/renderer/modules/mediarecorder/DEPS index 38a0c54..81ff459c 100644 --- a/third_party/blink/renderer/modules/mediarecorder/DEPS +++ b/third_party/blink/renderer/modules/mediarecorder/DEPS
@@ -19,7 +19,7 @@ '+third_party/opus', "+third_party/libvpx", "+third_party/libyuv", - "+third_party/openh264/src/codec/api/svc", + "+third_party/openh264/src/codec/api/wels", "+ui/gfx/geometry", ]
diff --git a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc index 88e4877..423abec 100644 --- a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc +++ b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
@@ -22,8 +22,8 @@ #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/vector.h" -#include "third_party/openh264/src/codec/api/svc/codec_app_def.h" -#include "third_party/openh264/src/codec/api/svc/codec_def.h" +#include "third_party/openh264/src/codec/api/wels/codec_app_def.h" +#include "third_party/openh264/src/codec/api/wels/codec_def.h" #include "ui/gfx/geometry/size.h" using media::VideoFrame;
diff --git a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.h b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.h index 7eb18a1..6dadffc 100644 --- a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.h +++ b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.h
@@ -14,7 +14,7 @@ #include "base/time/time.h" #include "third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h" -#include "third_party/openh264/src/codec/api/svc/codec_api.h" +#include "third_party/openh264/src/codec/api/wels/codec_api.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webaudio/BUILD.gn b/third_party/blink/renderer/modules/webaudio/BUILD.gn index 490c4b4..382234f 100644 --- a/third_party/blink/renderer/modules/webaudio/BUILD.gn +++ b/third_party/blink/renderer/modules/webaudio/BUILD.gn
@@ -58,6 +58,8 @@ "audio_scheduled_source_handler.h", "audio_scheduled_source_node.cc", "audio_scheduled_source_node.h", + "audio_sink_info.cc", + "audio_sink_info.h", "audio_summing_junction.cc", "audio_summing_junction.h", "audio_worklet.cc",
diff --git a/third_party/blink/renderer/modules/webaudio/audio_sink_info.cc b/third_party/blink/renderer/modules/webaudio/audio_sink_info.cc new file mode 100644 index 0000000..60e86905 --- /dev/null +++ b/third_party/blink/renderer/modules/webaudio/audio_sink_info.cc
@@ -0,0 +1,22 @@ +// 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/modules/webaudio/audio_sink_info.h" + +namespace blink { + +AudioSinkInfo* AudioSinkInfo::Create(const String& type) { + return MakeGarbageCollected<AudioSinkInfo>(type); +} + +AudioSinkInfo::AudioSinkInfo(const String& type) {} + +AudioSinkInfo::~AudioSinkInfo() = default; + +String AudioSinkInfo::type() const { + // Currently "none" is the only `type` available. + return "none"; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/webaudio/audio_sink_info.h b/third_party/blink/renderer/modules/webaudio/audio_sink_info.h new file mode 100644 index 0000000..e6a953722 --- /dev/null +++ b/third_party/blink/renderer/modules/webaudio/audio_sink_info.h
@@ -0,0 +1,27 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_AUDIO_SINK_INFO_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_AUDIO_SINK_INFO_H_ + +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +class AudioSinkInfo : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + static AudioSinkInfo* Create(const String&); + + explicit AudioSinkInfo(const String&); + ~AudioSinkInfo() override; + + String type() const; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_AUDIO_SINK_INFO_H_
diff --git a/third_party/blink/renderer/modules/webaudio/audio_sink_info.idl b/third_party/blink/renderer/modules/webaudio/audio_sink_info.idl new file mode 100644 index 0000000..2fa736e0 --- /dev/null +++ b/third_party/blink/renderer/modules/webaudio/audio_sink_info.idl
@@ -0,0 +1,11 @@ +// 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. + +enum AudioSinkType { + "none" +}; + +[Exposed=Window, RuntimeEnabled=AudioContextSetSinkId] interface AudioSinkInfo { + readonly attribute AudioSinkType type; +};
diff --git a/third_party/blink/renderer/modules/xr/xr_frame.cc b/third_party/blink/renderer/modules/xr/xr_frame.cc index 99f79d1..9d5cf2b 100644 --- a/third_party/blink/renderer/modules/xr/xr_frame.cc +++ b/third_party/blink/renderer/modules/xr/xr_frame.cc
@@ -392,11 +392,8 @@ return {}; } - const TransformationMatrix& mojo_from_stationary_space = - reference_space_information->mojo_from_space; - - DCHECK(mojo_from_stationary_space.IsInvertible()); - auto stationary_space_from_mojo = mojo_from_stationary_space.Inverse(); + auto stationary_space_from_mojo = + reference_space_information->mojo_from_space.GetCheckedInverse(); // We now have 2 spaces - the dynamic one passed in to create anchor // call, and the stationary one. We also have a rigid transform
diff --git a/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc b/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc index da8736c..0dea09d 100644 --- a/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc +++ b/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc
@@ -80,12 +80,8 @@ return {}; } - const TransformationMatrix& mojo_from_space = - reference_space_information->mojo_from_space; - - DCHECK(mojo_from_space.IsInvertible()); - - auto space_from_mojo = mojo_from_space.Inverse(); + auto space_from_mojo = + reference_space_information->mojo_from_space.GetCheckedInverse(); auto space_from_anchor = space_from_mojo * TransformationMatrix(mojo_from_this_.ToTransform());
diff --git a/third_party/blink/renderer/modules/xr/xr_space.cc b/third_party/blink/renderer/modules/xr/xr_space.cc index 47b9aae..93a23757 100644 --- a/third_party/blink/renderer/modules/xr/xr_space.cc +++ b/third_party/blink/renderer/modules/xr/xr_space.cc
@@ -58,8 +58,7 @@ if (!mojo_from_native) return absl::nullopt; - DCHECK(mojo_from_native->IsInvertible()); - return mojo_from_native->Inverse(); + return mojo_from_native->GetCheckedInverse(); } bool XRSpace::EmulatedPosition() const {
diff --git a/third_party/blink/renderer/modules/xr/xr_view.cc b/third_party/blink/renderer/modules/xr/xr_view.cc index cb1dce9..09449cf 100644 --- a/third_party/blink/renderer/modules/xr/xr_view.cc +++ b/third_party/blink/renderer/modules/xr/xr_view.cc
@@ -148,7 +148,7 @@ double canvas_height) { // Recompute the inverse projection matrix if needed. if (inv_projection_dirty_) { - inv_projection_ = projection_matrix_.Inverse(); + inv_projection_ = projection_matrix_.InverseOrIdentity(); inv_projection_dirty_ = false; } @@ -183,7 +183,7 @@ -point_in_view_space.z()); // LookAt matrices are view matrices (inverted), so invert before returning. - return inv_pointer.Inverse(); + return inv_pointer.InverseOrIdentity(); } XRRigidTransform* XRView::refSpaceFromView() const {
diff --git a/third_party/blink/renderer/platform/graphics/color.h b/third_party/blink/renderer/platform/graphics/color.h index 00978ee6..6bc8bf16 100644 --- a/third_party/blink/renderer/platform/graphics/color.h +++ b/third_party/blink/renderer/platform/graphics/color.h
@@ -252,9 +252,12 @@ bool SetFromString(const String&); bool SetNamedColor(const String&); - // Return true if the color is not opaque. + // Returns true if the color is not opaque. bool HasAlpha() const { return Alpha() < 255; } + // Returns true if the color is transparent. + bool IsTransparent() const { return Alpha() == 0; } + // Access the color as though it were created using rgba syntax. This will // clamp all colors to an 8-bit sRGB representation. All callers of these // functions should be audited. The function Rgb(), despite the name, does
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc index 143da7c2..6d6a715 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc
@@ -425,7 +425,7 @@ cc::PaintOpType::Restore})); // </t1> EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 2); EXPECT_TRANSFORM_MATRIX(t1->Matrix(), *output, 1); - EXPECT_TRANSFORM_MATRIX(t1->Matrix().Inverse(), *output, 4); + EXPECT_TRANSFORM_MATRIX(t1->Matrix().GetCheckedInverse(), *output, 4); } TEST_P(PaintChunksToCcLayerTest, FilterEffectSpaceInversion) { @@ -459,7 +459,7 @@ cc::PaintOpType::Restore})); // </t1> EXPECT_TRANSFORM_MATRIX(t1->Matrix(), *output, 1); EXPECT_EFFECT_BOUNDS(0, 0, 50, 50, *output, 2); - EXPECT_TRANSFORM_MATRIX(t1->Matrix().Inverse(), *output, 4); + EXPECT_TRANSFORM_MATRIX(t1->Matrix().GetCheckedInverse(), *output, 4); } TEST_P(PaintChunksToCcLayerTest, NonRootLayerSimple) {
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc index 55358e65..f0fbef6 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -250,9 +250,7 @@ gfx::Transform to_screen; to_screen.Scale(device_scale_factor, device_scale_factor); transform_tree_.SetToScreen(cc::kRootPropertyNodeId, to_screen); - gfx::Transform from_screen; - bool invertible = to_screen.GetInverse(&from_screen); - DCHECK(invertible); + gfx::Transform from_screen = to_screen.GetCheckedInverse(); transform_tree_.SetFromScreen(cc::kRootPropertyNodeId, from_screen); transform_tree_.set_needs_update(true);
diff --git a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.cc b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.cc index d82ad98..6949832 100644 --- a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.cc +++ b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.cc
@@ -104,7 +104,7 @@ plane_root_transform_->to_plane_root.MakeIdentity(); parent.ApplyToPlaneRoot(plane_root_transform_->to_plane_root); plane_root_transform_->to_plane_root.PreConcat(local); - plane_root_transform_->from_plane_root = local.Inverse(); + plane_root_transform_->from_plane_root = local.GetCheckedInverse(); parent.ApplyFromPlaneRoot(plane_root_transform_->from_plane_root); plane_root_transform_->has_animation = parent.has_animation_to_plane_root() ||
diff --git a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache_test.cc b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache_test.cc index fa50686..01d2da2 100644 --- a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache_test.cc +++ b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache_test.cc
@@ -67,14 +67,14 @@ EXPECT_EQ(&t0(), cache.plane_root()); EXPECT_EQ(to_plane_root, cache.to_plane_root()); - EXPECT_EQ(to_plane_root.Inverse(), cache.from_plane_root()); + EXPECT_EQ(to_plane_root.InverseOrIdentity(), cache.from_plane_root()); TransformationMatrix actual_to_screen; cache.ApplyToScreen(actual_to_screen); EXPECT_EQ(to_plane_root, actual_to_screen); TransformationMatrix actual_projection_from_screen; cache.ApplyProjectionFromScreen(actual_projection_from_screen); - EXPECT_EQ(to_plane_root.Inverse(), actual_projection_from_screen); + EXPECT_EQ(to_plane_root.InverseOrIdentity(), actual_projection_from_screen); } static void CheckPlaneRootSameAs2dTranslationRoot( @@ -97,7 +97,7 @@ EXPECT_EQ(to_screen, cache.to_screen()); auto projection_from_screen = to_screen; projection_from_screen.FlattenTo2d(); - projection_from_screen = projection_from_screen.Inverse(); + projection_from_screen = projection_from_screen.InverseOrIdentity(); EXPECT_EQ(projection_from_screen, cache.projection_from_screen()); } @@ -121,11 +121,11 @@ EXPECT_EQ(&plane_root, cache.plane_root()); EXPECT_EQ(to_plane_root, cache.to_plane_root()); - EXPECT_EQ(to_plane_root.Inverse(), cache.from_plane_root()); + EXPECT_EQ(to_plane_root.InverseOrIdentity(), cache.from_plane_root()); EXPECT_EQ(to_screen, cache.to_screen()); auto projection_from_screen = to_screen; projection_from_screen.FlattenTo2d(); - projection_from_screen = projection_from_screen.Inverse(); + projection_from_screen = projection_from_screen.InverseOrIdentity(); EXPECT_EQ(projection_from_screen, cache.projection_from_screen()); }
diff --git a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h index 84995f4..d59b560 100644 --- a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h +++ b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
@@ -140,7 +140,8 @@ if (other.IsIdentityOr2DTranslation()) return Matrix().Preserves2dAxisAlignment(); // TODO(crbug.com/960481): Consider more rare corner cases. - return (Matrix().Inverse() * other.Matrix()).Preserves2dAxisAlignment(); + return (Matrix().InverseOrIdentity() * other.Matrix()) + .Preserves2dAxisAlignment(); } private:
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc index ed2a0845..000c6017 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc +++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
@@ -939,8 +939,9 @@ &WebMediaPlayerImpl::OnDataSourceRedirected, weak_this_)); mb_data_source_->SetPreload(preload_); mb_data_source_->SetIsClientAudioElement(client_->IsAudioElement()); - mb_data_source_->Initialize( - base::BindOnce(&WebMediaPlayerImpl::DataSourceInitialized, weak_this_)); + + mb_data_source_->Initialize(base::BindOnce( + &WebMediaPlayerImpl::MultiBufferDataSourceInitialized, weak_this_)); } } @@ -1941,7 +1942,7 @@ .SchemeIsCryptographic(); bool manifest_url_is_cryptographic = loaded_url_.SchemeIsCryptographic() && - mb_data_source_->GetUrlAfterRedirects().SchemeIsCryptographic(); + data_source_->GetUrlAfterRedirects().SchemeIsCryptographic(); UMA_HISTOGRAM_BOOLEAN( "Media.WebMediaPlayerImpl.HLS.IsMixedContent", frame_url_is_cryptographic && !manifest_url_is_cryptographic); @@ -1949,7 +1950,7 @@ renderer_factory_selector_->SetBaseRendererType( media::RendererType::kMediaPlayer); - loaded_url_ = mb_data_source_->GetUrlAfterRedirects(); + loaded_url_ = data_source_->GetUrlAfterRedirects(); DCHECK(data_source_); data_source_->Stop(); mb_data_source_ = nullptr; @@ -2749,9 +2750,6 @@ DVLOG(1) << __func__; DCHECK(main_task_runner_->BelongsToCurrentThread()); - if (observer_ && mb_data_source_) - observer_->OnDataSourceInitialized(mb_data_source_->GetUrlAfterRedirects()); - if (!success) { SetNetworkState(WebMediaPlayer::kNetworkStateFormatError); media_metrics_provider_->OnError(media::PIPELINE_ERROR_NETWORK); @@ -2763,13 +2761,21 @@ return; } - // No point in preloading data as we'll probably just throw it away anyways. - if (IsStreaming() && preload_ > media::DataSource::METADATA) - data_source_->SetPreload(media::DataSource::METADATA); - StartPipeline(); } +void WebMediaPlayerImpl::MultiBufferDataSourceInitialized(bool success) { + DVLOG(1) << __func__; + DCHECK(data_source_); + if (observer_) + observer_->OnDataSourceInitialized(data_source_->GetUrlAfterRedirects()); + + // No point in preloading data as we'll probably just throw it away anyways. + if (success && IsStreaming() && preload_ > media::DataSource::METADATA) + data_source_->SetPreload(media::DataSource::METADATA); + DataSourceInitialized(success); +} + void WebMediaPlayerImpl::OnDataSourceRedirected() { DVLOG(1) << __func__; DCHECK(main_task_runner_->BelongsToCurrentThread()); @@ -3985,7 +3991,7 @@ } GURL WebMediaPlayerImpl::GetSrcAfterRedirects() { - return mb_data_source_ ? mb_data_source_->GetUrlAfterRedirects() : GURL(); + return data_source_ ? data_source_->GetUrlAfterRedirects() : GURL(); } void WebMediaPlayerImpl::UpdateSmoothnessHelper() {
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.h b/third_party/blink/renderer/platform/media/web_media_player_impl.h index b6e77d9..9f40456a 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_impl.h +++ b/third_party/blink/renderer/platform/media/web_media_player_impl.h
@@ -392,9 +392,13 @@ CorsMode cors_mode, bool is_cache_disabled); - // Called after asynchronous initialization of a data source completed. + // Called after synchronous initialization of a data source completes. void DataSourceInitialized(bool success); + // Called after asynchronous initialization of a multibuffer data source + // completes. + void MultiBufferDataSourceInitialized(bool success); + // Called if the |MultiBufferDataSource| is redirected. void OnDataSourceRedirected();
diff --git a/third_party/blink/renderer/platform/transforms/transformation_matrix.cc b/third_party/blink/renderer/platform/transforms/transformation_matrix.cc index 05e0a3e..3570976 100644 --- a/third_party/blink/renderer/platform/transforms/transformation_matrix.cc +++ b/third_party/blink/renderer/platform/transforms/transformation_matrix.cc
@@ -691,7 +691,7 @@ return InternalInverse<true>(nullptr); } -TransformationMatrix TransformationMatrix::Inverse() const { +TransformationMatrix TransformationMatrix::InverseOrIdentity() const { TransformationMatrix m; InternalInverse<false>(&m); return m; @@ -706,6 +706,13 @@ return false; } +TransformationMatrix TransformationMatrix::GetCheckedInverse() const { + TransformationMatrix m; + bool invertible = InternalInverse<false>(&m); + DCHECK(invertible); + return m; +} + template <bool check_invertibility_only> bool TransformationMatrix::InternalInverse(TransformationMatrix* result) const { DCHECK_EQ(check_invertibility_only, !result);
diff --git a/third_party/blink/renderer/platform/transforms/transformation_matrix.h b/third_party/blink/renderer/platform/transforms/transformation_matrix.h index d3c4eef..6de9c5c 100644 --- a/third_party/blink/renderer/platform/transforms/transformation_matrix.h +++ b/third_party/blink/renderer/platform/transforms/transformation_matrix.h
@@ -280,7 +280,7 @@ // This method returns the identity matrix if it is not invertible. // Use GetInverse() if you also need to know the invertibility. - [[nodiscard]] TransformationMatrix Inverse() const; + [[nodiscard]] TransformationMatrix InverseOrIdentity() const; // If this matrix is invertible, this method sets |result| to the inverse of // this matrix and returns true, otherwise sets |result| to identity and @@ -288,6 +288,9 @@ // consistent with gfx::Transform::GetInverse()). [[nodiscard]] bool GetInverse(TransformationMatrix* result) const; + // Same as above except that it assumes success, otherwise DCHECK fails. + [[nodiscard]] TransformationMatrix GetCheckedInverse() const; + // decompose the matrix into its component parts typedef struct { double scale_x, scale_y, scale_z;
diff --git a/third_party/blink/renderer/platform/transforms/transformation_matrix_test.cc b/third_party/blink/renderer/platform/transforms/transformation_matrix_test.cc index eb04062..1b30343 100644 --- a/third_party/blink/renderer/platform/transforms/transformation_matrix_test.cc +++ b/third_party/blink/renderer/platform/transforms/transformation_matrix_test.cc
@@ -473,50 +473,6 @@ column_major_constructor.ToString()); } -TEST(TransformationMatrix, IsInvertible) { - EXPECT_FALSE(TransformationMatrix::ColMajor(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0) - .IsInvertible()); - EXPECT_TRUE(TransformationMatrix().IsInvertible()); - TransformationMatrix t; - t.Translate3d(10, 20, 30); - EXPECT_TRUE(t.IsInvertible()); - EXPECT_TRUE(MakeScaleMatrix(1e-8).IsInvertible()); - EXPECT_FALSE(MakeScaleMatrix(0).IsInvertible()); - EXPECT_FALSE( - MakeScaleMatrix(std::numeric_limits<double>::quiet_NaN()).IsInvertible()); - EXPECT_FALSE( - MakeScaleMatrix(std::numeric_limits<double>::min()).IsInvertible()); -} - -TEST(TransformationMatrix, Inverse) { - EXPECT_EQ(TransformationMatrix(), MakeScaleMatrix(0).Inverse()); - EXPECT_EQ(TransformationMatrix(), TransformationMatrix().Inverse()); - - auto t1 = MakeTranslationMatrix(-10, 20, -30); - auto t2 = MakeTranslationMatrix(10, -20, 30); - EXPECT_EQ(t1, t2.Inverse()); - EXPECT_EQ(t2, t1.Inverse()); - - auto s1 = MakeScaleMatrix(2, -4, 0.5); - auto s2 = MakeScaleMatrix(0.5, -0.25, 2); - EXPECT_EQ(s1, s2.Inverse()); - EXPECT_EQ(s2, s1.Inverse()); - - TransformationMatrix m1; - m1.RotateAboutZAxis(-30); - m1.RotateAboutYAxis(10); - m1.RotateAboutXAxis(20); - m1.ApplyPerspectiveDepth(100); - TransformationMatrix m2; - m2.ApplyPerspectiveDepth(-100); - m2.RotateAboutXAxis(-20); - m2.RotateAboutYAxis(-10); - m2.RotateAboutZAxis(30); - EXPECT_TRANSFORMATION_MATRIX(m1, m2.Inverse()); - EXPECT_TRANSFORMATION_MATRIX(m2, m1.Inverse()); -} - TEST(TransformationMatrixTest, Blend2dXFlipTest) { // Test 2D x-flip (crbug.com/797472). auto from = TransformationMatrix::Affine(1, 0, 0, 1, 100, 150);
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py index e9e94f4..f1c35a1 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py
@@ -184,6 +184,10 @@ results = json.load(results_file) metadata = results.get('metadata') or {} + if 'num_failures_by_type' in results and 'PASS' in results[ + 'num_failures_by_type']: + num_passes = results['num_failures_by_type']['PASS'] + results['num_passes'] = num_passes test_names = self._extract_artifacts( results['tests'], delim=results['path_delimiter'],
diff --git a/third_party/blink/tools/run_wpt_tests.py b/third_party/blink/tools/run_wpt_tests.py index 4c55342..7530bf4 100755 --- a/third_party/blink/tools/run_wpt_tests.py +++ b/third_party/blink/tools/run_wpt_tests.py
@@ -860,6 +860,9 @@ def main(): + # This environment fix is needed on windows as codec is trying + # to encode in cp1252 rather than utf-8 and throwing errors. + os.environ['PYTHONUTF8'] = '1' adapter = WPTAdapter() return adapter.run_test()
diff --git a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility index de107b2..2bf79c2 100644 --- a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility +++ b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
@@ -25,6 +25,7 @@ svg/text/select-x-list-4.svg [ Crash ] # Unknown cause: crbug.com/1225856 virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-display-none-editable.html [ Crash ] +crbug.com/1380449 external/wpt/css/css-contain/content-visibility/content-visibility-063.html [ Crash ] # Failures # isUseCounted() difference:
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 1fd414c..3d741fe 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3383,7 +3383,7 @@ crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-060.html [ Failure ] crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-061.html [ Failure ] crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-062.html [ Failure ] -crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-063.html [ Failure ] +crbug.com/626703 crbug.com/1380449 external/wpt/css/css-contain/content-visibility/content-visibility-063.html [ Failure Crash ] crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-065.html [ Failure ] crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-066.html [ Failure ] crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-067.html [ Failure ] @@ -3392,7 +3392,7 @@ crbug.com/626703 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-060.html [ Failure ] crbug.com/626703 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-061.html [ Failure ] crbug.com/626703 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-062.html [ Failure ] -crbug.com/626703 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-063.html [ Failure ] +crbug.com/626703 crbug.com/1380449 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-063.html [ Failure Crash ] crbug.com/626703 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-065.html [ Failure ] crbug.com/626703 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-066.html [ Failure ] crbug.com/626703 virtual/offsetparent-old-behavior/external/wpt/css/css-contain/content-visibility/content-visibility-067.html [ Failure ] @@ -7751,4 +7751,4 @@ crbug.com/1376679 virtual/threaded/external/wpt/scroll-animations/css/scroll-timeline-dynamic.tentative.html [ Skip ] # Sheriff 2022-11-01 -crbug.com/1380381 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html [ Failure Pass ] \ No newline at end of file +crbug.com/1380381 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 1fdfeaf..9e45982 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -271940,6 +271940,10 @@ "e67b97276818d50adb0e47105fbecab3c91e52c7", [] ], + "import-conditions-expected.txt": [ + "e1615689ea83cfadf93534f90e8f41460ebe7ea0", + [] + ], "important-prop-ref.html": [ "004679da7309ccc08640fe8c92b6f069090a37b6", [] @@ -343370,6 +343374,10 @@ "3c072829e6f8cd5c2b94f12a8feeb5d860abc6cd", [] ], + "scroll-timeline-dynamic.tentative-expected.txt": [ + "57145213b5c3390eab9a2a397931d4505cf590f5", + [] + ], "scroll-timeline-frame-size-changed-ref.html": [ "ea7628ac723f4dea27bf5c60467a5896904930a3", [] @@ -394635,6 +394643,13 @@ {} ] ], + "import-conditions.html": [ + "d4a0918a5b245f12a28d6c96bd41a5b07bd29c09", + [ + null, + {} + ] + ], "important-vs-inline-001.html": [ "33b33bf943833ce2ea0f2c3e3ece08cf91189729", [ @@ -548251,7 +548266,7 @@ ] ], "scroll-timeline-dynamic.tentative.html": [ - "b78f15c0b7f8b457ae1866e346b022708a9b3443", + "b0880a7cc5ac8f831fdb1fd29fd477935f3a3fe9", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-scroll-fixedpos.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-scroll-fixedpos.tentative.html new file mode 100644 index 0000000..ee7d2260 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-scroll-fixedpos.tentative.html
@@ -0,0 +1,38 @@ +<!DOCTYPE html> +<title>Tests that anchor-scroll adjusts location of fixed-positioned elements correctly</title> +<link rel="author" href="mailto:xiaochengh@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-anchor-1/"> +<link rel="match" href="reference/anchor-scroll-fixedpos-ref.html"> +<style> +body { + margin: 0; + height: 2000px; +} + +div { + width: 100px; + height: 100px; +} + +#anchor { + anchor-name: --a1; + margin: 300px; + background: orange; +} + +#anchored { + position: fixed; + anchor-scroll: --a1; + left: anchor(--a1 right); + top: anchor(--a1 top); + background: green; +} + +</style> + +<div id="anchor"></div> +<div id="anchored"></div> + +<script> +document.documentElement.scrollTop = 200; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-scroll-no-overflow-crash.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-scroll-no-overflow-crash.html new file mode 100644 index 0000000..d8fa382 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-scroll-no-overflow-crash.html
@@ -0,0 +1,41 @@ +<!DOCTYPE html> +<title>Tests that anchor-scroll doesn't crash renderer when anchor is in a scroller whose content doesn't overflow</title> +<link rel="author" href="mailto:xiaochengh@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-anchor-1/"> +<style> +#container { + position: relative; +} + +#scroller { + overflow: scroll; + width: 400px; + height: 400px; +} + +#anchor { + anchor-name: --a; + margin: 100px; + width: 100px; + height: 100px; + background: green; +} + +#anchored { + position: absolute; + anchor-scroll: --a; + left: anchor(--a left); + bottom: anchor(--a top); + width: 100px; + height: 100px; + background: orange; +} + +</style> + +<div id="container"> + <div id="scroller"> + <div id="anchor">anchor</div> + </div> + <div id="anchored">anchored</div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/reference/anchor-scroll-fixedpos-ref.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/reference/anchor-scroll-fixedpos-ref.html new file mode 100644 index 0000000..e73354d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/reference/anchor-scroll-fixedpos-ref.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<style> +body { + margin: 0; + height: 2000px; +} + +div { + width: 100px; + height: 100px; +} + +#anchor { + margin: 300px; + background: orange; +} + +#anchored { + position: fixed; + left: 400px; + top: 100px; + background: green; +} + +</style> + +<div id="anchor"></div> +<div id="anchored"></div> + +<script> +document.documentElement.scrollTop = 200; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-dynamic.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-dynamic.tentative-expected.txt new file mode 100644 index 0000000..5714521 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-dynamic.tentative-expected.txt
@@ -0,0 +1,19 @@ +This is a testharness.js-based test. +PASS Switching between document and scroll timelines [immediate] +PASS Switching between document and scroll timelines [scroll] +PASS Switching pending animation from document to scroll timelines [immediate] +PASS Switching pending animation from document to scroll timelines [scroll] +PASS Changing computed value of animation-timeline changes effective timeline [immediate] +PASS Changing computed value of animation-timeline changes effective timeline [scroll] +FAIL Changing to/from animation-timeline:none [immediate] assert_equals: expected "120px" but got "0px" +FAIL Changing to/from animation-timeline:none [scroll] assert_equals: expected "120px" but got "0px" +PASS Changing scroll-timeline on preceding elements affects target element [immediate] +PASS Changing scroll-timeline on preceding elements affects target element [scroll] +PASS Reverse animation direction [immediate] +PASS Reverse animation direction [scroll] +PASS Switching timelines while paused [immediate] +PASS Switching timelines while paused [scroll] +PASS Switching timelines and pausing at the same time [immediate] +PASS Switching timelines and pausing at the same time [scroll] +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-dynamic.tentative.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-dynamic.tentative.html index b78f15c..b0880a7c 100644 --- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-dynamic.tentative.html +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-dynamic.tentative.html
@@ -1,4 +1,5 @@ <!DOCTYPE html> +<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1"> <link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timelines"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> @@ -172,7 +173,7 @@ // ScrollTimeline -> none element.style.animationTimeline = 'none'; - await assert_width(element, '0px'); + await assert_width(element, '120px'); // none -> ScrollTimeline element.style.animationTimeline = 'timeline';
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/shadow-multiple-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/shadow-multiple-expected.png new file mode 100644 index 0000000..98c30647 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/text-antialias/stroking-decorations-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/text-antialias/stroking-decorations-expected.png new file mode 100644 index 0000000..1ce47d45 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/text-antialias/stroking-decorations-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/fast/writing-mode/english-lr-text-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/fast/writing-mode/english-lr-text-expected.png new file mode 100644 index 0000000..5a864bc --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/highdpi/fast/writing-mode/english-lr-text-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/writing-mode/english-lr-text-expected.png b/third_party/blink/web_tests/platform/linux/fast/writing-mode/english-lr-text-expected.png index 5a864bc..963778b 100644 --- a/third_party/blink/web_tests/platform/linux/fast/writing-mode/english-lr-text-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/writing-mode/english-lr-text-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/ietestcenter/css3/text/textshadow-002-expected.png b/third_party/blink/web_tests/platform/linux/ietestcenter/css3/text/textshadow-002-expected.png index cbbf441..ce9e65e 100644 --- a/third_party/blink/web_tests/platform/linux/ietestcenter/css3/text/textshadow-002-expected.png +++ b/third_party/blink/web_tests/platform/linux/ietestcenter/css3/text/textshadow-002-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/shadow-multiple-expected.png b/third_party/blink/web_tests/platform/linux/paint/invalidation/shadow-multiple-expected.png index 98c30647..cabdfa8f 100644 --- a/third_party/blink/web_tests/platform/linux/paint/invalidation/shadow-multiple-expected.png +++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/stroking-decorations-expected.png b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/stroking-decorations-expected.png index 1ce47d45..ed35105 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/stroking-decorations-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/stroking-decorations-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/stroking-decorations-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/stroking-decorations-expected.png index ff1e445e..8a20ce0 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/stroking-decorations-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/stroking-decorations-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/paint/invalidation/shadow-multiple-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/paint/invalidation/shadow-multiple-expected.png new file mode 100644 index 0000000..575d2b5 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/paint/invalidation/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/paint/invalidation/shadow-multiple-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/paint/invalidation/shadow-multiple-expected.png new file mode 100644 index 0000000..575d2b5 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/paint/invalidation/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/writing-mode/english-lr-text-expected.png b/third_party/blink/web_tests/platform/mac/fast/writing-mode/english-lr-text-expected.png index 2c1a028..2035c2b 100644 --- a/third_party/blink/web_tests/platform/mac/fast/writing-mode/english-lr-text-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/writing-mode/english-lr-text-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/ietestcenter/css3/text/textshadow-002-expected.png b/third_party/blink/web_tests/platform/mac/ietestcenter/css3/text/textshadow-002-expected.png index 44ec0ed..f5d1059 100644 --- a/third_party/blink/web_tests/platform/mac/ietestcenter/css3/text/textshadow-002-expected.png +++ b/third_party/blink/web_tests/platform/mac/ietestcenter/css3/text/textshadow-002-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/shadow-multiple-expected.png b/third_party/blink/web_tests/platform/mac/paint/invalidation/shadow-multiple-expected.png index 44789bb7..4876e755b3 100644 --- a/third_party/blink/web_tests/platform/mac/paint/invalidation/shadow-multiple-expected.png +++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/stroking-decorations-expected.png b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/stroking-decorations-expected.png index 70c851f6..d6589be3 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/stroking-decorations-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/stroking-decorations-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/writing-mode/english-lr-text-expected.png b/third_party/blink/web_tests/platform/win/fast/writing-mode/english-lr-text-expected.png index cf160afd..53ed456 100644 --- a/third_party/blink/web_tests/platform/win/fast/writing-mode/english-lr-text-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/writing-mode/english-lr-text-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/ietestcenter/css3/text/textshadow-002-expected.png b/third_party/blink/web_tests/platform/win/ietestcenter/css3/text/textshadow-002-expected.png index f8aa958..57ddf1d 100644 --- a/third_party/blink/web_tests/platform/win/ietestcenter/css3/text/textshadow-002-expected.png +++ b/third_party/blink/web_tests/platform/win/ietestcenter/css3/text/textshadow-002-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/shadow-multiple-expected.png b/third_party/blink/web_tests/platform/win/paint/invalidation/shadow-multiple-expected.png index 16410b0..fa2baf5 100644 --- a/third_party/blink/web_tests/platform/win/paint/invalidation/shadow-multiple-expected.png +++ b/third_party/blink/web_tests/platform/win/paint/invalidation/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/text-antialias/stroking-decorations-expected.png b/third_party/blink/web_tests/platform/win/virtual/text-antialias/stroking-decorations-expected.png index a60df6b1..85afa7d 100644 --- a/third_party/blink/web_tests/platform/win/virtual/text-antialias/stroking-decorations-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/text-antialias/stroking-decorations-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index c12858e..88f030f 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -398,6 +398,10 @@ method start method stop setter onended +interface AudioSinkInfo + attribute @@toStringTag + getter type + method constructor interface AudioTrack attribute @@toStringTag getter enabled
diff --git a/third_party/openh264/BUILD.gn b/third_party/openh264/BUILD.gn index 421f98cc..e5e71a7 100644 --- a/third_party/openh264/BUILD.gn +++ b/third_party/openh264/BUILD.gn
@@ -12,7 +12,7 @@ buildflag_header("buildflags") { header = "buildflags.h" header_dir = "third_party/openh264" - flags = [ "OPENH264_API_WELS=0" ] + flags = [ "OPENH264_API_WELS=1" ] } # Config shared by all openh264 targets.
diff --git a/third_party/openh264/README.chromium b/third_party/openh264/README.chromium index 599e7d4f..a877a92 100644 --- a/third_party/openh264/README.chromium +++ b/third_party/openh264/README.chromium
@@ -3,7 +3,7 @@ URL: http://www.openh264.org/ Version: unknown CPEPrefix: cpe:/a:cisco:openh264:2.1.1 -(Cut at 3dd5b80bc4f172dd82925bb259cb7c82348409c5, which is 2.1.1) +(Cut at db956674bbdfbaab5acdd3fdb4117c2fef5527e9, which is 2.3.0) License: 2-Clause BSD License File: src/LICENSE Security Critical: yes
diff --git a/third_party/openh264/openh264_sources.gni b/third_party/openh264/openh264_sources.gni index e714dad9..01d06eb 100644 --- a/third_party/openh264/openh264_sources.gni +++ b/third_party/openh264/openh264_sources.gni
@@ -1,6 +1,6 @@ # Common openh264_common_include_dirs = [ - "//third_party/openh264/src/codec/api/svc", + "//third_party/openh264/src/codec/api/wels", "//third_party/openh264/src/codec/common/arm", "//third_party/openh264/src/codec/common/inc", "//third_party/openh264/src/codec/common/src", @@ -87,7 +87,7 @@ # Processing openh264_processing_include_dirs = [ - "//third_party/openh264/src/codec/api/svc", + "//third_party/openh264/src/codec/api/wels", "//third_party/openh264/src/codec/common/arm", "//third_party/openh264/src/codec/common/inc", "//third_party/openh264/src/codec/common/src", @@ -164,7 +164,7 @@ # Encoder openh264_encoder_include_dirs = [ - "//third_party/openh264/src/codec/api/svc", + "//third_party/openh264/src/codec/api/wels", "//third_party/openh264/src/codec/common/arm/", "//third_party/openh264/src/codec/common/inc", "//third_party/openh264/src/codec/common/src",
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index a63407b..828b87d 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -1181,34 +1181,34 @@ 'linux-x64-castos': 'cast_release_trybot', 'linux-x64-castos-audio': 'cast_audio_release_trybot', 'linux-x64-castos-dbg': 'cast_debug_bot', - 'linux_chromium_archive_rel_ng': 'release_bot', + 'linux_chromium_archive_rel_ng': 'release_bot_reclient', 'linux_chromium_asan_rel_ng': 'asan_lsan_release_trybot_minimum_symbols_reclient', - 'linux_chromium_cfi_rel_ng': 'cfi_full_cfi_icall_cfi_diag_thin_lto_release_static_dcheck_always_on_goma', + 'linux_chromium_cfi_rel_ng': 'cfi_full_cfi_icall_cfi_diag_thin_lto_release_static_dcheck_always_on_reclient', 'linux_chromium_chromeos_asan_rel_ng': 'asan_lsan_chromeos_release_bot_dcheck_always_on', 'linux_chromium_chromeos_msan_focal': 'chromeos_msan_release_bot', 'linux_chromium_chromeos_msan_rel_ng': 'chromeos_msan_release_bot', 'linux_chromium_clobber_deterministic': 'release_trybot', 'linux_chromium_clobber_rel_ng': 'release_trybot', 'linux_chromium_compile_dbg_ng': 'debug_bot_reclient', - 'linux_chromium_compile_rel_ng': 'release_trybot', - 'linux_chromium_dbg_ng': 'gpu_tests_debug_bot', + 'linux_chromium_compile_rel_ng': 'release_trybot_reclient', + 'linux_chromium_dbg_ng': 'gpu_tests_debug_bot_reclient', # This is intentionally a release_bot and not a release_trybot; # enabling DCHECKs seems to cause flaky failures that don't show up # on the continuous builder. - 'linux_chromium_msan_focal': 'msan_release_bot', - 'linux_chromium_msan_rel_ng': 'msan_release_bot', + 'linux_chromium_msan_focal': 'msan_release_bot_reclient', + 'linux_chromium_msan_rel_ng': 'msan_release_bot_reclient', 'linux_chromium_tsan_rel_ng': 'tsan_disable_nacl_release_trybot_reclient', # This is intentionally a release_bot and not a release_trybot to match # the CI configuration, where no debug builder exists. - 'linux_chromium_ubsan_rel_ng': 'ubsan_vptr_release_bot', + 'linux_chromium_ubsan_rel_ng': 'ubsan_vptr_release_bot_reclient', 'linux_layout_tests_layout_ng_disabled': 'release_trybot_reclient', 'linux_optional_gpu_tests_rel': 'gpu_fyi_tests_release_trybot_reclient', 'linux_upload_clang': 'release_bot', - 'linux_vr': 'vr_release_trybot', + 'linux_vr': 'vr_release_trybot_reclient', 'network_service_linux': 'release_trybot', }, @@ -1986,10 +1986,6 @@ 'cfi_full', 'cfi_icall', 'cfi_diag', 'cfi_recover', 'thin_lto', 'release', 'static', 'reclient', ], - 'cfi_full_cfi_icall_cfi_diag_thin_lto_release_static_dcheck_always_on_goma': [ - 'cfi_full', 'cfi_icall', 'cfi_diag', 'thin_lto', 'release', 'static', 'dcheck_always_on', 'goma', - ], - 'cfi_full_cfi_icall_cfi_diag_thin_lto_release_static_dcheck_always_on_reclient': [ 'cfi_full', 'cfi_icall', 'cfi_diag', 'thin_lto', 'release', 'static', 'dcheck_always_on', 'reclient', ], @@ -3680,18 +3676,6 @@ 'ubsan', 'release_bot_reclient', ], - 'ubsan_vptr_release_bot': [ - 'ubsan_vptr', 'release_bot', - ], - - 'ubsan_vptr_release_bot': [ - 'ubsan_vptr', 'ubsan_no_recover_hack', 'release_bot', - ], - - 'ubsan_vptr_release_bot_reclient': [ - 'ubsan_vptr', 'release_bot_reclient', - ], - 'ubsan_vptr_release_bot_reclient': [ 'ubsan_vptr', 'ubsan_no_recover_hack', 'release_bot_reclient', ], @@ -3740,8 +3724,8 @@ 'vr', 'release_bot_reclient', 'ozone', ], - 'vr_release_trybot': [ - 'vr', 'release_trybot', 'ozone', + 'vr_release_trybot_reclient': [ + 'vr', 'release_trybot_reclient', 'ozone', ], 'win32_arm64_release_bot_reclient': [
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json index 39134879..4bc2af4c 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
@@ -591,7 +591,7 @@ "dcheck_always_on": false, "is_component_build": false, "is_debug": false, - "use_goma": true + "use_remoteexec": true } }, "linux_chromium_asan_rel_ng": { @@ -614,7 +614,7 @@ "use_cfi_cast": true, "use_cfi_diag": true, "use_cfi_icall": true, - "use_goma": true, + "use_remoteexec": true, "use_thin_lto": true } }, @@ -684,7 +684,7 @@ "is_component_build": false, "is_debug": false, "symbol_level": 0, - "use_goma": true + "use_remoteexec": true } }, "linux_chromium_dbg_ng": { @@ -694,7 +694,7 @@ "is_debug": true, "proprietary_codecs": true, "symbol_level": 1, - "use_goma": true + "use_remoteexec": true } }, "linux_chromium_msan_focal": { @@ -704,7 +704,7 @@ "is_debug": false, "is_msan": true, "msan_track_origins": 2, - "use_goma": true + "use_remoteexec": true } }, "linux_chromium_msan_rel_ng": { @@ -714,7 +714,7 @@ "is_debug": false, "is_msan": true, "msan_track_origins": 2, - "use_goma": true + "use_remoteexec": true } }, "linux_chromium_tsan_rel_ng": { @@ -735,7 +735,7 @@ "is_debug": false, "is_ubsan_no_recover": true, "is_ubsan_vptr": true, - "use_goma": true + "use_remoteexec": true } }, "linux_layout_tests_layout_ng_disabled": { @@ -774,8 +774,8 @@ "is_component_build": false, "is_debug": false, "symbol_level": 0, - "use_goma": true, - "use_ozone": true + "use_ozone": true, + "use_remoteexec": true } }, "network_service_linux": {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 1b73d20..689180e 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -10851,6 +10851,8 @@ <int value="288" label="MSDH_INCONSISTENT_VIDEO_TYPE_AND_REQUESTED_FIELDS"/> <int value="289" label="MSDH_SUPPRESS_LOCAL_AUDIO_PLAYBACK_BUT_AUDIO_NOT_REQUESTED"/> + <int value="290" label="MSDH_HOTWORD_ENABLED_BUT_AUDIO_NOT_REQUESTED"/> + <int value="291" label="MSDH_DISABLE_LOCAL_ECHO_BUT_AUDIO_NOT_REQUESTED"/> </enum> <enum name="BadMessageReasonExtensions"> @@ -26827,6 +26829,12 @@ <int value="2" label="Bind and video processor blit"/> </enum> +<enum name="DirectFromSellerSignalsRequestType"> + <int value="0" label="Network service fetch"/> + <int value="1" label="Cache"/> + <int value="2" label="Coalesced"/> +</enum> + <enum name="DirectoryDatabaseRepairResult"> <int value="0" label="Succeeded"/> <int value="1" label="Failed"/>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index de6a84e..fa26feb 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -594,6 +594,17 @@ </summary> </histogram> +<histogram name="Ash.BrowserDataMigrator.MoveMigrator.ExtraSpaceRequiredMB" + units="MB" expires_after="M121"> + <owner>ythjkt@chromium.org</owner> + <owner>hidehiko@chromium.org</owner> + <summary> + This is recorded if move profile migration is aborted due to the lack of + extra space required on disk. The amount of space required to be freed is + recorded. + </summary> +</histogram> + <histogram name="Ash.BrowserDataMigrator.MoveMigrator.PosixErrno.{TaskStatus}" units="errno" expires_after="M121"> <owner>ythjkt@chromium.org</owner> @@ -4773,7 +4784,7 @@ </histogram> <histogram name="Ash.TouchView.TouchViewInactive" units="ms" - expires_after="2022-11-03"> + expires_after="2023-03-19"> <owner>girard@chromium.org</owner> <summary>The length of time between TouchView activations.</summary> </histogram>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml index 03b597c..b070087 100644 --- a/tools/metrics/histograms/metadata/blink/histograms.xml +++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -952,6 +952,26 @@ </summary> </histogram> +<histogram name="Blink.FedCm.SignUp.PrivacyPolicyClicked" enum="BooleanHit" + expires_after="M120"> + <owner>pkotwicz@chromium.org</owner> + <owner>web-identity-eng@google.com</owner> + <summary> + Recorded each time that the privacy-policy link in the FedCM prompt is + clicked. + </summary> +</histogram> + +<histogram name="Blink.FedCm.SignUp.TermsOfServiceClicked" enum="BooleanHit" + expires_after="M120"> + <owner>pkotwicz@chromium.org</owner> + <owner>web-identity-eng@google.com</owner> + <summary> + Recorded each time that the terms-of-service link in the FedCM prompt is + clicked. + </summary> +</histogram> + <histogram name="Blink.FedCm.Status.Csp" enum="FedCmCspStatus" expires_after="M120"> <owner>cbiesinger@chromium.org</owner> @@ -1925,7 +1945,7 @@ </summary> </histogram> -<histogram base="true" name="Blink.LocalFrameRoot.DidReachFirstContentfulPaint" +<histogram name="Blink.LocalFrameRoot.DidReachFirstContentfulPaint" units="Boolean" expires_after="2023-03-19"> <owner>pdr@chromium.org</owner> <owner>paint-dev@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml index de9770d1..ce2ccdee 100644 --- a/tools/metrics/histograms/metadata/compositing/histograms.xml +++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -576,6 +576,16 @@ </summary> </histogram> +<histogram name="Compositing.Renderer.CommitHung" units="boolean" + expires_after="2023-01-31"> + <owner>skobes@chromium.org</owner> + <owner>input-dev@chromium.org</owner> + <summary> + Records when the renderer compositor thread is hung (14 seconds) waiting to + run the commit after the main thread signalled that it is ready to commit. + </summary> +</histogram> + <histogram name="Compositing.Renderer.FirstSurfaceActivationUpdateDuration.{Surface}" units="ms" expires_after="2023-04-28">
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index f1d9057..38b2f8e 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -116,6 +116,8 @@ summary="post-auction forDebuggingOnly.reportAdAuctionLoss() report"/> <variant name="DebugWinReport" summary="post-auction forDebuggingOnly.reportAdAuctionWin() report"/> + <variant name="DirectFromSellerSignals" + summary="auction directFromSellerSignals"/> <variant name="ScoringScriptJS" summary="seller JavaScript scoring script"/> <variant name="SendReportToReport" summary="post-auction sendReportTo() report (from either the winning @@ -428,6 +430,25 @@ </summary> </histogram> +<histogram name="Ads.InterestGroup.Auction.DirectFromSellerSignals.RequestType" + enum="DirectFromSellerSignalsRequestType" expires_after="2023-07-31"> + <owner>caraitto@chromium.org</owner> + <owner>pauljensen@chromium.org</owner> + <owner>privacy-sandbox-dev@chromium.org</owner> + <summary> + For each request made for a DirectFromSellerSignals bundle subresource, + records whether the request was made to the network service, or whether the + request was elided due to either loading from the + DirectFromSellerSignalsRequester cache, or coalescing with an exiting + request for the same subresource URL. + + Reported at each DirectFromSellerSignalsRequester request. + + See https://github.com/WICG/turtledove/blob/main/FLEDGE.md for the latest + version of the FLEDGE explainer. + </summary> +</histogram> + <histogram name="Ads.InterestGroup.Auction.First6AuctionsBitsPerPage" units="bitfield" expires_after="2023-07-31"> <owner>caraitto@chromium.org</owner> @@ -13866,27 +13887,6 @@ </summary> </histogram> -<histogram name="TaskQueueManager.ActiveQueuesCount" units="units" - expires_after="M85"> - <owner>altimin@chromium.org</owner> - <owner>farahcharab@chromium.org</owner> - <summary> - Used to track the number of active task queues in the task queue manager. - Reported every time a task is selected for execution. - </summary> -</histogram> - -<histogram name="TaskQueueSelector.TaskServicedPerSelectorLogic" - enum="TaskQueueSelectorLogic" expires_after="M85"> - <owner>altimin@chromium.org</owner> - <owner>farahcharab@chromium.org</owner> - <summary> - Used to track the number of tasks serviced due to starvation versus the - number of tasks serviced due to priroity. Incremented whenever a task queue - is selected to service. - </summary> -</histogram> - <histogram name="ThirdPartyModules.Certificates.Microsoft" units="certificates" expires_after="M85"> <owner>chrisha@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index 5761d9e..b34c0387 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -833,16 +833,6 @@ </summary> </histogram> -<histogram name="SafeBrowsing.NoCachedPopulationReason" - enum="SafeBrowsingNoCachedPopulationReason" expires_after="2022-11-11"> - <owner>drubery@chromium.org</owner> - <owner>chrome-counter-abuse-alerts@google.com</owner> - <summary> - Whenever Safe Browsing sends a request with no cached user population to - compare it to, we record the reason the cache is empty. - </summary> -</histogram> - <histogram name="SafeBrowsing.PageLoadToken.ClearReason" enum="SafeBrowsingPageLoadTokenClearReason" expires_after="2023-03-05"> <owner>xinghuilu@chromium.org</owner> @@ -922,23 +912,6 @@ </token> </histogram> -<histogram name="SafeBrowsing.PopulationMatchesCachedValue.{Field}" - enum="BooleanMatched" expires_after="2022-11-11"> - <owner>drubery@chromium.org</owner> - <owner>chrome-counter-abuse-alerts@google.com</owner> - <summary> - Whenever the ChromeUserPopulation proto is created (almost every time Safe - Browsing is contacted), we compare it to a cached value. This histogram - records whether the cached value has the same value in {Field} as the newly - created value. - </summary> - <token key="Field"> - <variant name="Mbb" summary="Make Browsing Better preference"/> - <variant name="Population" summary="Safe Browsing population"/> - <variant name="UserAgent" summary="User agent"/> - </token> -</histogram> - <histogram name="SafeBrowsing.Pref.Daily.Extended" enum="BooleanEnabled" expires_after="2023-04-30"> <owner>xinghuilu@chromium.org</owner> @@ -1572,7 +1545,7 @@ </histogram> <histogram name="SafeBrowsing.TailoredSecurityUnconsentedMessageDismissReason" - enum="MessageDismissReason" expires_after="2022-11-11"> + enum="MessageDismissReason" expires_after="2023-11-11"> <owner>drubery@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary> @@ -1583,7 +1556,7 @@ </histogram> <histogram name="SafeBrowsing.TailoredSecurityUnconsentedModalOutcome" - enum="SafeBrowsingTailoredSecurityOutcome" expires_after="2022-11-11"> + enum="SafeBrowsingTailoredSecurityOutcome" expires_after="2023-11-11"> <owner>drubery@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary> @@ -1606,7 +1579,7 @@ </histogram> <histogram name="SafeBrowsing.TailoredSecurityUnconsented{Flow}MessageOutcome" - enum="SafeBrowsingTailoredSecurityOutcome" expires_after="2022-11-11"> + enum="SafeBrowsingTailoredSecurityOutcome" expires_after="2023-11-11"> <owner>drubery@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index b1d4143..1f3903d9d 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -21,8 +21,8 @@ "full_remote_path": "perfetto-luci-artifacts/v30.0/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "3fe8d9f8334d7872cebb94cd83f6f1d4b0965670", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/cb8281edbb0e244234ce27dbf69b71c1334bc836/trace_processor_shell" + "hash": "2ef6d0c4d75184e5139cfab6a4485ddfd488a1ae", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/0cbb37ad93ee2bfcf4c1b0bc3e136eadbe4fb467/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/accessibility/ax_position.h b/ui/accessibility/ax_position.h index 3a325267..074e35a 100644 --- a/ui/accessibility/ax_position.h +++ b/ui/accessibility/ax_position.h
@@ -1047,15 +1047,22 @@ // '\n' character in a <br> element unless multiple consecutive <br> // elements are present and so empty paragraphs have been created. // - // Note that `!AtStartOfAnchor()` implies that `MaxTextOffset()` > 0 and - // `text_offset()` > 0. Therefore, - // `text_position->GetText().at(text_position->text_offset_ - 1)` will - // always be valid. + // Note that, in theory, `!AtStartOfAnchor()` implies that + // `MaxTextOffset()` > 0 and `text_offset()` > 0. Therefore, + // `text_position->GetText().at(text_position->text_offset_ - 1)` should + // always be valid. However, as reported by https://crbug.com/1379716, + // this logic appears to have flaws. + // + // TODO(accessibility): Investigate what are these edge cases that lead + // to have a `text_offset_` greater than or equal to the `text` length. if (!text_position->AtStartOfAnchor()) { - if (!text_position->IsPointingToLineBreak() && - text_position->GetText().at(text_position->text_offset_ - 1) == - '\n') { - return true; + if (!text_position->IsPointingToLineBreak()) { + const std::u16string text = text_position->GetText(); + if (static_cast<size_t>(text_position->text_offset_) < + text.length() && + text.at(text_position->text_offset_) == '\n') { + return true; + } } return false; } @@ -1116,16 +1123,23 @@ // character in a <br> element unless multiple consecutive <br> elements // are present and so empty paragraphs have been created. // - // Note that `!AtEndOfAnchor()` implies `AtStartOfAnchor()` != - // `AtEndOfAnchor()` which in turn implies that `MaxTextOffset()` > 0 - // and `text_offset()` < `MaxTextOffset()`. Therefore, - // `text_position->GetText().at(text_position->text_offset_)` will - // always be valid. + // Note that, in theory, `!AtEndOfAnchor()` implies + // `AtStartOfAnchor()` != `AtEndOfAnchor()` which in turn implies that + // `MaxTextOffset()` > 0 and `text_offset()` < `MaxTextOffset()`. + // Therefore, `text_position->GetText().at(text_position->text_offset_)` + // should always be valid. However, as reported by + // https://crbug.com/1379716, this logic appears to have flaws. + // + // TODO(accessibility): Investigate what are these edge cases that lead + // to have a `text_offset_` greater than or equal to the `text` length. if (!text_position->AtEndOfAnchor()) { - if (!text_position->IsPointingToLineBreak() && - text_position->GetText().at(text_position->text_offset_) == - '\n') { - return true; + if (!text_position->IsPointingToLineBreak()) { + const std::u16string text = text_position->GetText(); + if (static_cast<size_t>(text_position->text_offset_) < + text.length() && + text.at(text_position->text_offset_) == '\n') { + return true; + } } return false; }
diff --git a/ui/accessibility/platform/BUILD.gn b/ui/accessibility/platform/BUILD.gn index 8eb556b9f..11de200 100644 --- a/ui/accessibility/platform/BUILD.gn +++ b/ui/accessibility/platform/BUILD.gn
@@ -248,6 +248,8 @@ "ax_platform_node_auralinux.h", "inspect/ax_call_statement_invoker_auralinux.cc", "inspect/ax_call_statement_invoker_auralinux.h", + "inspect/ax_event_recorder_auralinux.cc", + "inspect/ax_event_recorder_auralinux.h", "inspect/ax_inspect_utils_auralinux.cc", "inspect/ax_inspect_utils_auralinux.h", "inspect/ax_tree_formatter_auralinux.cc",
diff --git a/content/browser/accessibility/accessibility_event_recorder_auralinux.cc b/ui/accessibility/platform/inspect/ax_event_recorder_auralinux.cc similarity index 88% rename from content/browser/accessibility/accessibility_event_recorder_auralinux.cc rename to ui/accessibility/platform/inspect/ax_event_recorder_auralinux.cc index 8cbf52bf..3f6f678a 100644 --- a/content/browser/accessibility/accessibility_event_recorder_auralinux.cc +++ b/ui/accessibility/platform/inspect/ax_event_recorder_auralinux.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/accessibility/accessibility_event_recorder_auralinux.h" +#include "ui/accessibility/platform/inspect/ax_event_recorder_auralinux.h" #include <atk/atk.h> #include <atk/atkutil.h> @@ -10,22 +10,15 @@ #include "base/no_destructor.h" #include "base/process/process_handle.h" -#include "base/ranges/algorithm.h" +#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "content/browser/accessibility/browser_accessibility_auralinux.h" #include "ui/accessibility/platform/ax_platform_tree_manager.h" #include "ui/accessibility/platform/inspect/ax_inspect_utils_auralinux.h" -namespace content { - -using ui::AtkRoleToString; -using ui::ATSPIRoleToString; -using ui::ATSPIStateToString; -using ui::FindAccessible; +namespace ui { // static -AccessibilityEventRecorderAuraLinux* - AccessibilityEventRecorderAuraLinux::instance_ = nullptr; +AXEventRecorderAuraLinux* AXEventRecorderAuraLinux::instance_ = nullptr; // static std::vector<unsigned int>& GetATKListenerIds() { @@ -34,7 +27,7 @@ } // static -gboolean AccessibilityEventRecorderAuraLinux::OnATKEventReceived( +gboolean AXEventRecorderAuraLinux::OnATKEventReceived( GSignalInvocationHint* hint, unsigned int n_params, const GValue* params, @@ -55,14 +48,14 @@ return true; } -bool AccessibilityEventRecorderAuraLinux::ShouldUseATSPI() { +bool AXEventRecorderAuraLinux::ShouldUseATSPI() { return pid_ != base::GetCurrentProcId() || !selector_.empty(); } -AccessibilityEventRecorderAuraLinux::AccessibilityEventRecorderAuraLinux( - ui::AXPlatformTreeManager* manager, +AXEventRecorderAuraLinux::AXEventRecorderAuraLinux( + AXPlatformTreeManager* manager, base::ProcessId pid, - const ui::AXTreeSelector& selector) + const AXTreeSelector& selector) : manager_(manager), pid_(pid), selector_(selector) { CHECK(!instance_) << "There can be only one instance of" << " AccessibilityEventRecorder at a time."; @@ -76,13 +69,12 @@ instance_ = this; } -AccessibilityEventRecorderAuraLinux::~AccessibilityEventRecorderAuraLinux() { +AXEventRecorderAuraLinux::~AXEventRecorderAuraLinux() { RemoveATSPIEventListeners(); instance_ = nullptr; } -void AccessibilityEventRecorderAuraLinux::AddATKEventListener( - const char* event_name) { +void AXEventRecorderAuraLinux::AddATKEventListener(const char* event_name) { unsigned id = atk_add_global_event_listener(OnATKEventReceived, event_name); if (!id) LOG(FATAL) << "atk_add_global_event_listener failed for " << event_name; @@ -91,7 +83,7 @@ atk_listener_ids.push_back(id); } -void AccessibilityEventRecorderAuraLinux::AddATKEventListeners() { +void AXEventRecorderAuraLinux::AddATKEventListeners() { if (GetATKListenerIds().size() >= 1) return; GObject* gobject = G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr, nullptr)); @@ -113,7 +105,7 @@ AddATKEventListener("ATK:AtkTable:row-reordered"); } -void AccessibilityEventRecorderAuraLinux::RemoveATKEventListeners() { +void AXEventRecorderAuraLinux::RemoveATKEventListeners() { std::vector<unsigned int>& atk_listener_ids = GetATKListenerIds(); for (const auto& id : atk_listener_ids) atk_remove_global_event_listener(id); @@ -121,9 +113,8 @@ atk_listener_ids.clear(); } -std::string AccessibilityEventRecorderAuraLinux::AtkObjectToString( - AtkObject* obj, - bool include_name) { +std::string AXEventRecorderAuraLinux::AtkObjectToString(AtkObject* obj, + bool include_name) { std::string role = AtkRoleToString(atk_object_get_role(obj)); base::ReplaceChars(role, " ", "_", &role); std::string str = @@ -135,10 +126,9 @@ return str; } -void AccessibilityEventRecorderAuraLinux::ProcessATKEvent( - const char* event, - unsigned int n_params, - const GValue* params) { +void AXEventRecorderAuraLinux::ProcessATKEvent(const char* event, + unsigned int n_params, + const GValue* params) { // If we don't have a root object, it means the tree is being destroyed. if (!manager_->RootDelegate()) { RemoveATKEventListeners(); @@ -283,12 +273,11 @@ }; static void OnATSPIEventReceived(AtspiEvent* event, void* data) { - static_cast<AccessibilityEventRecorderAuraLinux*>(data)->ProcessATSPIEvent( - event); + static_cast<AXEventRecorderAuraLinux*>(data)->ProcessATSPIEvent(event); g_boxed_free(ATSPI_TYPE_EVENT, static_cast<void*>(event)); } -void AccessibilityEventRecorderAuraLinux::AddATSPIEventListeners() { +void AXEventRecorderAuraLinux::AddATSPIEventListeners() { atspi_init(); atspi_event_listener_ = atspi_event_listener_new(OnATSPIEventReceived, this, nullptr); @@ -304,7 +293,7 @@ } } -void AccessibilityEventRecorderAuraLinux::RemoveATSPIEventListeners() { +void AXEventRecorderAuraLinux::RemoveATSPIEventListeners() { if (!atspi_event_listener_) return; @@ -323,8 +312,7 @@ atspi_event_listener_ = nullptr; } -void AccessibilityEventRecorderAuraLinux::ProcessATSPIEvent( - const AtspiEvent* event) { +void AXEventRecorderAuraLinux::ProcessATSPIEvent(const AtspiEvent* event) { GError* error = nullptr; // Ignore irrelevant events, i.e. fired for other applications. @@ -399,4 +387,4 @@ OnEvent(output.str()); } -} // namespace content +} // namespace ui
diff --git a/content/browser/accessibility/accessibility_event_recorder_auralinux.h b/ui/accessibility/platform/inspect/ax_event_recorder_auralinux.h similarity index 66% rename from content/browser/accessibility/accessibility_event_recorder_auralinux.h rename to ui/accessibility/platform/inspect/ax_event_recorder_auralinux.h index 43cf43d3..2e76415 100644 --- a/content/browser/accessibility/accessibility_event_recorder_auralinux.h +++ b/ui/accessibility/platform/inspect/ax_event_recorder_auralinux.h
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_EVENT_RECORDER_AURALINUX_H_ -#define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_EVENT_RECORDER_AURALINUX_H_ +#ifndef UI_ACCESSIBILITY_PLATFORM_INSPECT_AX_EVENT_RECORDER_AURALINUX_H_ +#define UI_ACCESSIBILITY_PLATFORM_INSPECT_AX_EVENT_RECORDER_AURALINUX_H_ #include <atk/atk.h> #include <atspi/atspi.h> #include "base/memory/raw_ptr.h" #include "base/process/process_handle.h" -#include "content/common/content_export.h" +#include "ui/accessibility/ax_export.h" #include "ui/accessibility/platform/inspect/ax_event_recorder.h" #include "ui/accessibility/platform/inspect/ax_inspect.h" @@ -18,10 +18,6 @@ class AXPlatformTreeManager; -} // namespace ui - -namespace content { - // This class has two distinct event recording code paths. When we are // recording events in-process (typically this is used for // DumpAccessibilityEvents tests), we use ATK's global event handlers. Since @@ -31,20 +27,16 @@ // TODO(crbug.com/1133330) AT-SPI2 should be capable of intercepting events // in-process as well, thus it should be possible to remove the ATK code path // entirely. -class CONTENT_EXPORT AccessibilityEventRecorderAuraLinux - : public ui::AXEventRecorder { +class AX_EXPORT AXEventRecorderAuraLinux : public AXEventRecorder { public: - explicit AccessibilityEventRecorderAuraLinux( - ui::AXPlatformTreeManager* manager, - base::ProcessId pid, - const ui::AXTreeSelector& selector); + AXEventRecorderAuraLinux(AXPlatformTreeManager* manager, + base::ProcessId pid, + const AXTreeSelector& selector); - AccessibilityEventRecorderAuraLinux( - const AccessibilityEventRecorderAuraLinux&) = delete; - AccessibilityEventRecorderAuraLinux& operator=( - const AccessibilityEventRecorderAuraLinux&) = delete; + AXEventRecorderAuraLinux(const AXEventRecorderAuraLinux&) = delete; + AXEventRecorderAuraLinux& operator=(const AXEventRecorderAuraLinux&) = delete; - ~AccessibilityEventRecorderAuraLinux() override; + ~AXEventRecorderAuraLinux() override; void ProcessATKEvent(const char* event, unsigned int n_params, @@ -70,12 +62,12 @@ raw_ptr<AtspiEventListener> atspi_event_listener_ = nullptr; // TODO: should be either removed or converted to a weakptr. - const raw_ptr<ui::AXPlatformTreeManager> manager_; + const raw_ptr<AXPlatformTreeManager> manager_; base::ProcessId pid_; - ui::AXTreeSelector selector_; - static AccessibilityEventRecorderAuraLinux* instance_; + AXTreeSelector selector_; + static AXEventRecorderAuraLinux* instance_; }; -} // namespace content +} // namespace ui -#endif // CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_EVENT_RECORDER_AURALINUX_H_ +#endif // UI_ACCESSIBILITY_PLATFORM_INSPECT_AX_EVENT_RECORDER_AURALINUX_H_
diff --git a/ui/color/color_id.h b/ui/color/color_id.h index 813deda1..8603662 100644 --- a/ui/color/color_id.h +++ b/ui/color/color_id.h
@@ -185,6 +185,9 @@ E_CPONLY(kColorIcon) \ E_CPONLY(kColorIconDisabled) \ E_CPONLY(kColorIconSecondary) \ + /* This is declared here so //components can access it, but we expect \ + * this to be set in the embedder. */ \ + E_CPONLY(kColorInfoBarIcon) \ E_CPONLY(kColorLabelForeground) \ E_CPONLY(kColorLabelForegroundDisabled) \ E_CPONLY(kColorLabelForegroundSecondary) \
diff --git a/ui/color/ui_color_mixer.cc b/ui/color/ui_color_mixer.cc index 3e7ef72..ffe9479 100644 --- a/ui/color/ui_color_mixer.cc +++ b/ui/color/ui_color_mixer.cc
@@ -69,6 +69,7 @@ mixer[kColorIcon] = {kColorSecondaryForeground}; mixer[kColorIconDisabled] = SetAlpha(kColorIcon, gfx::kDisabledControlAlpha); mixer[kColorIconSecondary] = {gfx::kGoogleGrey600}; + mixer[kColorInfoBarIcon] = {kColorAccent}; mixer[kColorLabelForeground] = {kColorPrimaryForeground}; mixer[kColorLabelForegroundDisabled] = {kColorDisabledForeground}; mixer[kColorLabelForegroundSecondary] = {kColorSecondaryForeground};
diff --git a/ui/gfx/geometry/test/geometry_util.cc b/ui/gfx/geometry/test/geometry_util.cc index bd304a4..502f2df 100644 --- a/ui/gfx/geometry/test/geometry_util.cc +++ b/ui/gfx/geometry/test/geometry_util.cc
@@ -211,13 +211,6 @@ return ::testing::AssertionSuccess(); } -Transform InvertAndCheck(const Transform& transform) { - Transform result(Transform::kSkipInitialization); - bool inverted_successfully = transform.GetInverse(&result); - DCHECK(inverted_successfully); - return result; -} - ::testing::AssertionResult AssertBoxFloatEqual(const char* lhs_expr, const char* rhs_expr, const BoxF& lhs,
diff --git a/ui/gfx/geometry/test/geometry_util.h b/ui/gfx/geometry/test/geometry_util.h index 4706f11..57968bae8 100644 --- a/ui/gfx/geometry/test/geometry_util.h +++ b/ui/gfx/geometry/test/geometry_util.h
@@ -101,10 +101,6 @@ const DecomposedTransform& rhs, float abs_error); -// Should be used in test code only, for convenience. Production code should use -// the gfx::Transform::GetInverse() API. -Transform InvertAndCheck(const Transform& transform); - #define EXPECT_BOXF_EQ(a, b) \ EXPECT_PRED_FORMAT2(::gfx::AssertBoxFloatEqual, a, b)
diff --git a/ui/gfx/geometry/transform.cc b/ui/gfx/geometry/transform.cc index e3c0080e..d8e8f37 100644 --- a/ui/gfx/geometry/transform.cc +++ b/ui/gfx/geometry/transform.cc
@@ -6,6 +6,7 @@ #include "base/check_op.h" #include "base/no_destructor.h" +#include "base/notreached.h" #include "base/strings/stringprintf.h" #include "ui/gfx/geometry/angle_conversions.h" #include "ui/gfx/geometry/axis_transform2d.h" @@ -75,7 +76,6 @@ Transform::Transform() = default; Transform::~Transform() = default; -Transform::Transform(SkipInitialization) {} Transform::Transform(Transform&&) = default; Transform& Transform::operator=(Transform&&) = default; @@ -490,9 +490,9 @@ return false; } - if (transform != this) { + if (!transform->matrix_) transform->matrix_ = std::make_unique<Matrix44>(Matrix44::kUninitialized); - } + if (matrix_->GetInverse(*transform->matrix_)) return true; @@ -502,6 +502,20 @@ return false; } +Transform Transform::GetCheckedInverse() const { + Transform inverse; + if (!GetInverse(&inverse)) + NOTREACHED() << ToString() << " is not invertible"; + return inverse; +} + +Transform Transform::InverseOrIdentity() const { + Transform inverse; + bool invertible = GetInverse(&inverse); + DCHECK(invertible || inverse.IsIdentity()); + return inverse; +} + bool Transform::Preserves2dAxisAlignment() const { if (LIKELY(!matrix_)) return true; @@ -732,7 +746,7 @@ return axis_2d_.InverseMapRect(rect); } - Transform inverse(kSkipInitialization); + Transform inverse; if (!GetInverse(&inverse)) return absl::nullopt;
diff --git a/ui/gfx/geometry/transform.h b/ui/gfx/geometry/transform.h index 6861d12..7ffb8f8 100644 --- a/ui/gfx/geometry/transform.h +++ b/ui/gfx/geometry/transform.h
@@ -47,10 +47,6 @@ Transform(); ~Transform(); - // TODO(crbug.com/1359528): This is same as Transform(). Remove this. - enum SkipInitialization { kSkipInitialization }; - explicit Transform(SkipInitialization); - Transform(const Transform& rhs); Transform& operator=(const Transform& rhs); Transform(Transform&&); @@ -341,14 +337,24 @@ return LIKELY(!matrix_) ? axis_2d_.IsInvertible() : matrix_->IsInvertible(); } + // If |this| is invertible, inverts |this| and stores the result in + // |*transform|, and returns true. Otherwise sets |*transform| to identity + // and returns false. + [[nodiscard]] bool GetInverse(Transform* transform) const; + + // Same as above except that it assumes success, otherwise DCHECK fails. + // This is suitable when the transform is known to be invertible. + [[nodiscard]] Transform GetCheckedInverse() const; + + // Same as GetInverse() except that it returns the the inverse of |this| or + // identity, instead of a bool. This is suitable when it's good to fallback + // to identity silently. + [[nodiscard]] Transform InverseOrIdentity() const; + // Returns true if a layer with a forward-facing normal of (0, 0, 1) would // have its back side facing frontwards after applying the transform. bool IsBackFaceVisible() const; - // Inverts the transform which is passed in. Returns true if successful, or - // sets |transform| to the identify matrix on failure. - [[nodiscard]] bool GetInverse(Transform* transform) const; - // Transposes this transform in place. void Transpose();
diff --git a/ui/gfx/geometry/transform_unittest.cc b/ui/gfx/geometry/transform_unittest.cc index d23edb7..8de9ac5 100644 --- a/ui/gfx/geometry/transform_unittest.cc +++ b/ui/gfx/geometry/transform_unittest.cc
@@ -1354,14 +1354,22 @@ EXPECT_FALSE(transform.IsIdentityOrIntegerTranslation()); } -TEST(XFormTest, verifyMatrixInversion) { +TEST(XFormTest, Inverse) { + { + Transform identity; + Transform inverse_identity; + EXPECT_TRUE(identity.GetInverse(&inverse_identity)); + EXPECT_EQ(identity, inverse_identity); + EXPECT_EQ(identity, identity.InverseOrIdentity()); + } + { // Invert a translation - gfx::Transform translation; + Transform translation; translation.Translate3d(2.0, 3.0, 4.0); EXPECT_TRUE(translation.IsInvertible()); - gfx::Transform inverse_translation; + Transform inverse_translation; bool is_invertible = translation.GetInverse(&inverse_translation); EXPECT_TRUE(is_invertible); EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, -2.0f, inverse_translation); @@ -1369,6 +1377,8 @@ EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, -4.0f, inverse_translation); EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, inverse_translation); + EXPECT_EQ(inverse_translation, translation.InverseOrIdentity()); + // GetInverse with the parameter pointing to itself. EXPECT_TRUE(translation.GetInverse(&translation)); EXPECT_EQ(translation, inverse_translation); @@ -1376,30 +1386,50 @@ { // Invert a non-uniform scale - gfx::Transform scale; + Transform scale; scale.Scale3d(4.0, 10.0, 100.0); EXPECT_TRUE(scale.IsInvertible()); - gfx::Transform inverse_scale; + Transform inverse_scale; bool is_invertible = scale.GetInverse(&inverse_scale); EXPECT_TRUE(is_invertible); EXPECT_ROW1_EQ(0.25f, 0.0f, 0.0f, 0.0f, inverse_scale); EXPECT_ROW2_EQ(0.0f, 0.1f, 0.0f, 0.0f, inverse_scale); EXPECT_ROW3_EQ(0.0f, 0.0f, 0.01f, 0.0f, inverse_scale); EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, inverse_scale); + + EXPECT_EQ(inverse_scale, scale.InverseOrIdentity()); + } + + { + Transform m1; + m1.RotateAboutZAxis(-30); + m1.RotateAboutYAxis(10); + m1.RotateAboutXAxis(20); + m1.ApplyPerspectiveDepth(100); + Transform m2; + m2.ApplyPerspectiveDepth(-100); + m2.RotateAboutXAxis(-20); + m2.RotateAboutYAxis(-10); + m2.RotateAboutZAxis(30); + Transform inverse_m1, inverse_m2; + EXPECT_TRUE(m1.GetInverse(&inverse_m1)); + EXPECT_TRUE(m2.GetInverse(&inverse_m2)); + EXPECT_TRANSFORM_NEAR(m1, inverse_m2, 1e-6); + EXPECT_TRANSFORM_NEAR(m2, inverse_m1, 1e-6); } { // Try to invert a matrix that is not invertible. // The inverse() function should reset the output matrix to identity. - gfx::Transform uninvertible; + Transform uninvertible; uninvertible.set_rc(0, 0, 0.f); uninvertible.set_rc(1, 1, 0.f); uninvertible.set_rc(2, 2, 0.f); uninvertible.set_rc(3, 3, 0.f); EXPECT_FALSE(uninvertible.IsInvertible()); - gfx::Transform inverse_of_uninvertible; + Transform inverse_of_uninvertible; // Add a scale just to more easily ensure that inverse_of_uninvertible is // reset to identity. @@ -1412,6 +1442,8 @@ EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, inverse_of_uninvertible); EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, inverse_of_uninvertible); EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, inverse_of_uninvertible); + + EXPECT_EQ(inverse_of_uninvertible, uninvertible.InverseOrIdentity()); } }
diff --git a/ui/gl/gl_image_native_pixmap.cc b/ui/gl/gl_image_native_pixmap.cc index 85a4d85..d492ad8f 100644 --- a/ui/gl/gl_image_native_pixmap.cc +++ b/ui/gl/gl_image_native_pixmap.cc
@@ -245,13 +245,6 @@ return true; } -bool GLImageNativePixmap::InitializeForOverlay( - scoped_refptr<gfx::NativePixmap> pixmap) { - DCHECK(!pixmap_); - pixmap_ = pixmap; - return true; -} - bool GLImageNativePixmap::InitializeFromTexture(uint32_t texture_id) { if (GLInternalFormat(format_) == GL_NONE) { LOG(ERROR) << "Unsupported format: " << gfx::BufferFormatToString(format_);
diff --git a/ui/gl/gl_image_native_pixmap.h b/ui/gl/gl_image_native_pixmap.h index c4f9b3cd..59bd313 100644 --- a/ui/gl/gl_image_native_pixmap.h +++ b/ui/gl/gl_image_native_pixmap.h
@@ -23,7 +23,6 @@ // Create an EGLImage from a given NativePixmap. bool Initialize(scoped_refptr<gfx::NativePixmap> pixmap); - bool InitializeForOverlay(scoped_refptr<gfx::NativePixmap> pixmap); // Create an EGLImage from a given GL texture. bool InitializeFromTexture(uint32_t texture_id); // Export the wrapped EGLImage to dmabuf fds.
diff --git a/ui/ozone/platform/flatland/flatland_sysmem_buffer_collection.cc b/ui/ozone/platform/flatland/flatland_sysmem_buffer_collection.cc index 9a66eb3..e483bdf 100644 --- a/ui/ozone/platform/flatland/flatland_sysmem_buffer_collection.cc +++ b/ui/ozone/platform/flatland/flatland_sysmem_buffer_collection.cc
@@ -621,7 +621,7 @@ std::make_unique<base::MessagePumpForIO::ZxHandleWatchController>( FROM_HERE); bool watch_result = base::CurrentIOThread::Get()->WatchZxHandle( - handle_.get(), /*persistent=*/true, ZX_EVENTPAIR_PEER_CLOSED, + handle_.get(), /*persistent=*/false, ZX_EVENTPAIR_PEER_CLOSED, handle_watch_.get(), this); if (!watch_result) { @@ -674,5 +674,7 @@ for (auto& callback : on_released_) { std::move(callback).Run(); } + on_released_.clear(); } + } // namespace ui
diff --git a/ui/ozone/platform/scenic/scenic_window.cc b/ui/ozone/platform/scenic/scenic_window.cc index 5d225bd..4bc521e 100644 --- a/ui/ozone/platform/scenic/scenic_window.cc +++ b/ui/ozone/platform/scenic/scenic_window.cc
@@ -244,7 +244,6 @@ } PlatformWindowState ScenicWindow::GetPlatformWindowState() const { - NOTIMPLEMENTED_LOG_ONCE(); if (is_fullscreen_) return PlatformWindowState::kFullScreen; if (!is_view_attached_)
diff --git a/ui/ozone/platform/scenic/sysmem_buffer_collection.cc b/ui/ozone/platform/scenic/sysmem_buffer_collection.cc index 55f9b93..64ef074 100644 --- a/ui/ozone/platform/scenic/sysmem_buffer_collection.cc +++ b/ui/ozone/platform/scenic/sysmem_buffer_collection.cc
@@ -579,7 +579,7 @@ std::make_unique<base::MessagePumpForIO::ZxHandleWatchController>( FROM_HERE); bool watch_result = base::CurrentIOThread::Get()->WatchZxHandle( - handle_.get(), true /* persistent */, ZX_EVENTPAIR_PEER_CLOSED, + handle_.get(), /*persistent=*/false, ZX_EVENTPAIR_PEER_CLOSED, handle_watch_.get(), this); if (!watch_result) { @@ -632,6 +632,7 @@ for (auto& callback : on_released_) { std::move(callback).Run(); } + on_released_.clear(); } } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_output.cc b/ui/ozone/platform/wayland/host/wayland_output.cc index a5a6ee7..bb133cca 100644 --- a/ui/ozone/platform/wayland/host/wayland_output.cc +++ b/ui/ozone/platform/wayland/host/wayland_output.cc
@@ -61,6 +61,27 @@ connection->wayland_output_manager_->AddWaylandOutput(name, output.release()); } +WaylandOutput::Metrics::Metrics() = default; +WaylandOutput::Metrics::Metrics(Id output_id, + gfx::Point origin, + gfx::Size logical_size, + gfx::Size physical_size, + gfx::Insets insets, + float scale_factor, + int32_t panel_transform, + int32_t logical_transform, + const std::string& description) + : output_id(output_id), + origin(origin), + logical_size(logical_size), + physical_size(physical_size), + insets(insets), + scale_factor(scale_factor), + panel_transform(panel_transform), + logical_transform(logical_transform), + description(description) {} +WaylandOutput::Metrics::~Metrics() = default; + WaylandOutput::WaylandOutput(Id output_id, wl_output* output, WaylandConnection* connection) @@ -116,6 +137,13 @@ : scale_factor(); } +WaylandOutput::Metrics WaylandOutput::GetMetrics() const { + // TODO(aluh): Change to designated initializers once C++20 is supported. + return {output_id(), origin(), logical_size(), physical_size(), + insets(), scale_factor(), panel_transform(), logical_transform(), + description()}; +} + int32_t WaylandOutput::logical_transform() const { if (aura_output_ && aura_output_->logical_transform()) { return *aura_output_->logical_transform(); @@ -168,9 +196,7 @@ scale_factor_ = max_physical_side / max_logical_side; } } - delegate_->OnOutputHandleMetrics( - output_id_, origin(), logical_size(), physical_size_, insets(), - scale_factor_, panel_transform_, logical_transform(), description()); + delegate_->OnOutputHandleMetrics(GetMetrics()); } // static
diff --git a/ui/ozone/platform/wayland/host/wayland_output.h b/ui/ozone/platform/wayland/host/wayland_output.h index 31f7c50..8c2463e 100644 --- a/ui/ozone/platform/wayland/host/wayland_output.h +++ b/ui/ozone/platform/wayland/host/wayland_output.h
@@ -42,17 +42,39 @@ const std::string& interface, uint32_t version); + // All parameters are in DIP screen coordinates/units except |physical_size|, + // which is in physical pixels. + struct Metrics { + // TODO(aluh): Remove explicit constructors/destructor to enable aggregate + // initialization if chromium-style check for complex struct is removed. + // See: + // https://groups.google.com/a/google.com/g/chromeos-chatty-eng/c/nM1_QC6qcuA + Metrics(); + Metrics(Id output_id, + gfx::Point origin, + gfx::Size logical_size, + gfx::Size physical_size, + gfx::Insets insets, + float scale_factor, + int32_t panel_transform, + int32_t logical_transform, + const std::string& description); + ~Metrics(); + + Id output_id = 0; + gfx::Point origin; + gfx::Size logical_size; + gfx::Size physical_size; + gfx::Insets insets; + float scale_factor = 0.0; + int32_t panel_transform = 0; + int32_t logical_transform = 0; + std::string description; + }; + class Delegate { public: - virtual void OnOutputHandleMetrics(Id output_id, - const gfx::Point& origin, - const gfx::Size& logical_size, - const gfx::Size& physical_size, - const gfx::Insets& insets, - float scale_factor, - int32_t panel_transform, - int32_t logical_transform, - const std::string& description) = 0; + virtual void OnOutputHandleMetrics(const Metrics& metrics) = 0; protected: virtual ~Delegate() = default; @@ -71,6 +93,7 @@ void InitializeColorManagementOutput(WaylandZcrColorManager* manager); float GetUIScaleFactor() const; + Metrics GetMetrics() const; Id output_id() const { return output_id_; } bool has_output(wl_output* output) const { return output_.get() == output; } float scale_factor() const { return scale_factor_; }
diff --git a/ui/ozone/platform/wayland/host/wayland_output_manager.cc b/ui/ozone/platform/wayland/host/wayland_output_manager.cc index ad29fbf0..a5d96045 100644 --- a/ui/ozone/platform/wayland/host/wayland_output_manager.cc +++ b/ui/ozone/platform/wayland/host/wayland_output_manager.cc
@@ -117,12 +117,7 @@ // changes. for (const auto& output : output_list_) { if (output.second->is_ready()) { - screen->OnOutputAddedOrUpdated( - output.second->output_id(), output.second->origin(), - output.second->logical_size(), output.second->physical_size(), - output.second->insets(), output.second->scale_factor(), - output.second->panel_transform(), output.second->logical_transform(), - output.second->description()); + screen->OnOutputAddedOrUpdated(output.second->GetMetrics()); } } } @@ -147,19 +142,9 @@ } void WaylandOutputManager::OnOutputHandleMetrics( - WaylandOutput::Id output_id, - const gfx::Point& origin, - const gfx::Size& logical_size, - const gfx::Size& physical_size, - const gfx::Insets& insets, - float scale_factor, - int32_t panel_transform, - int32_t logical_transform, - const std::string& description) { + const WaylandOutput::Metrics& metrics) { if (wayland_screen_) { - wayland_screen_->OnOutputAddedOrUpdated( - output_id, origin, logical_size, physical_size, insets, scale_factor, - panel_transform, logical_transform, description); + wayland_screen_->OnOutputAddedOrUpdated(metrics); } // Update scale of the windows currently associated with |output_id|. i.e: @@ -167,10 +152,11 @@ // which have not yet entered any output (i.e: no wl_surface.enter event // received for their root surface) and |output_id| is the primary output. const bool is_primary = - wayland_screen_ && output_id == wayland_screen_->GetPrimaryDisplay().id(); + wayland_screen_ && + metrics.output_id == wayland_screen_->GetPrimaryDisplay().id(); for (auto* window : connection_->wayland_window_manager()->GetAllWindows()) { auto entered_output = window->GetPreferredEnteredOutputId(); - if (entered_output == output_id || (!entered_output && is_primary)) + if (entered_output == metrics.output_id || (!entered_output && is_primary)) window->UpdateWindowScale(true); } }
diff --git a/ui/ozone/platform/wayland/host/wayland_output_manager.h b/ui/ozone/platform/wayland/host/wayland_output_manager.h index 123c45b..268d494 100644 --- a/ui/ozone/platform/wayland/host/wayland_output_manager.h +++ b/ui/ozone/platform/wayland/host/wayland_output_manager.h
@@ -59,15 +59,7 @@ private: // WaylandOutput::Delegate: - void OnOutputHandleMetrics(WaylandOutput::Id output_id, - const gfx::Point& origin, - const gfx::Size& logical_size, - const gfx::Size& physical_size, - const gfx::Insets& insets, - float scale_factor, - int32_t panel_transform, - int32_t logical_transform, - const std::string& description) override; + void OnOutputHandleMetrics(const WaylandOutput::Metrics& metrics) override; OutputList output_list_;
diff --git a/ui/ozone/platform/wayland/host/wayland_screen.cc b/ui/ozone/platform/wayland/host/wayland_screen.cc index 67b1a16..b49d539a7 100644 --- a/ui/ozone/platform/wayland/host/wayland_screen.cc +++ b/ui/ozone/platform/wayland/host/wayland_screen.cc
@@ -125,17 +125,9 @@ WaylandScreen::~WaylandScreen() = default; -void WaylandScreen::OnOutputAddedOrUpdated(WaylandOutput::Id output_id, - const gfx::Point& origin, - const gfx::Size& logical_size, - const gfx::Size& physical_size, - const gfx::Insets& insets, - float scale, - int32_t panel_transform, - int32_t logical_transform, - const std::string& label) { - AddOrUpdateDisplay(output_id, origin, logical_size, physical_size, insets, - scale, panel_transform, logical_transform, label); +void WaylandScreen::OnOutputAddedOrUpdated( + const WaylandOutput::Metrics& metrics) { + AddOrUpdateDisplay(metrics); } void WaylandScreen::OnOutputRemoved(WaylandOutput::Id output_id) { @@ -158,53 +150,46 @@ display_list_.RemoveDisplay(output_id); } -void WaylandScreen::AddOrUpdateDisplay(WaylandOutput::Id output_id, - const gfx::Point& origin, - const gfx::Size& logical_size, - const gfx::Size& physical_size, - const gfx::Insets& insets, - float scale_factor, - int32_t panel_transform, - int32_t logical_transform, - const std::string& label) { - display::Display changed_display(output_id); +void WaylandScreen::AddOrUpdateDisplay(const WaylandOutput::Metrics& metrics) { + display::Display changed_display(metrics.output_id); - DCHECK_GE(panel_transform, WL_OUTPUT_TRANSFORM_NORMAL); - DCHECK_LE(panel_transform, WL_OUTPUT_TRANSFORM_FLIPPED_270); + DCHECK_GE(metrics.panel_transform, WL_OUTPUT_TRANSFORM_NORMAL); + DCHECK_LE(metrics.panel_transform, WL_OUTPUT_TRANSFORM_FLIPPED_270); display::Display::Rotation panel_rotation = - WaylandTransformToRotation(panel_transform); + WaylandTransformToRotation(metrics.panel_transform); changed_display.set_panel_rotation(panel_rotation); - DCHECK_GE(logical_transform, WL_OUTPUT_TRANSFORM_NORMAL); - DCHECK_LE(logical_transform, WL_OUTPUT_TRANSFORM_FLIPPED_270); + DCHECK_GE(metrics.logical_transform, WL_OUTPUT_TRANSFORM_NORMAL); + DCHECK_LE(metrics.logical_transform, WL_OUTPUT_TRANSFORM_FLIPPED_270); display::Display::Rotation rotation = - WaylandTransformToRotation(logical_transform); + WaylandTransformToRotation(metrics.logical_transform); changed_display.set_rotation(rotation); - gfx::Size size_in_pixels(physical_size); + gfx::Size size_in_pixels(metrics.physical_size); if (panel_rotation == display::Display::Rotation::ROTATE_90 || panel_rotation == display::Display::Rotation::ROTATE_270) { size_in_pixels.Transpose(); } changed_display.set_size_in_pixels(size_in_pixels); - if (!logical_size.IsEmpty()) { - changed_display.set_bounds(gfx::Rect(origin, logical_size)); - changed_display.SetScale(scale_factor); + if (!metrics.logical_size.IsEmpty()) { + changed_display.set_bounds(gfx::Rect(metrics.origin, metrics.logical_size)); + changed_display.SetScale(metrics.scale_factor); } else { // Fallback to calculating using physical size. // This can happen if xdg_output.logical_size was not sent. - changed_display.SetScaleAndBounds(scale_factor, gfx::Rect(size_in_pixels)); + changed_display.SetScaleAndBounds(metrics.scale_factor, + gfx::Rect(size_in_pixels)); gfx::Rect new_bounds(changed_display.bounds()); - new_bounds.set_origin(origin); + new_bounds.set_origin(metrics.origin); changed_display.set_bounds(new_bounds); } - changed_display.UpdateWorkAreaFromInsets(insets); + changed_display.UpdateWorkAreaFromInsets(metrics.insets); gfx::DisplayColorSpaces color_spaces; #if BUILDFLAG(IS_CHROMEOS_LACROS) auto* wayland_output = - connection_->wayland_output_manager()->GetOutput(output_id); + connection_->wayland_output_manager()->GetOutput(metrics.output_id); auto* color_management_output = wayland_output ? wayland_output->color_management_output() : nullptr; @@ -241,7 +226,7 @@ type = display::DisplayList::Type::PRIMARY; } - changed_display.set_label(label); + changed_display.set_label(metrics.description); display_list_.AddOrUpdateDisplay(changed_display, type);
diff --git a/ui/ozone/platform/wayland/host/wayland_screen.h b/ui/ozone/platform/wayland/host/wayland_screen.h index 3b2f385..37b55e34 100644 --- a/ui/ozone/platform/wayland/host/wayland_screen.h +++ b/ui/ozone/platform/wayland/host/wayland_screen.h
@@ -19,6 +19,7 @@ #include "ui/gfx/buffer_types.h" #include "ui/gfx/geometry/point.h" #include "ui/ozone/platform/wayland/common/wayland_object.h" +#include "ui/ozone/platform/wayland/host/wayland_output.h" #include "ui/ozone/public/platform_screen.h" namespace gfx { @@ -41,15 +42,7 @@ WaylandScreen& operator=(const WaylandScreen&) = delete; ~WaylandScreen() override; - void OnOutputAddedOrUpdated(uint32_t output_id, - const gfx::Point& origin, - const gfx::Size& logical_size, - const gfx::Size& physical_size, - const gfx::Insets& insets, - float scale, - int32_t panel_transform, - int32_t logical_transform, - const std::string& label); + void OnOutputAddedOrUpdated(const WaylandOutput::Metrics& metrics); void OnOutputRemoved(uint32_t output_id); void OnTabletStateChanged(display::TabletState tablet_state); @@ -110,17 +103,7 @@ bool is_suspending_ = false; }; - // All parameters are in DIP screen coordinates/units except |physical_size|, - // which is in physical pixels. - void AddOrUpdateDisplay(uint32_t output_id, - const gfx::Point& origin, - const gfx::Size& logical_size, - const gfx::Size& physical_size, - const gfx::Insets& insets, - float scale, - int32_t panel_transform, - int32_t logical_transform, - const std::string& label); + void AddOrUpdateDisplay(const WaylandOutput::Metrics& metrics); raw_ptr<WaylandConnection> connection_ = nullptr;
diff --git a/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc b/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc index 62944faa..919969b 100644 --- a/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
@@ -321,8 +321,8 @@ // Test with missing logical size. Should fall back to calculating from // physical size. platform_screen_->OnOutputAddedOrUpdated( - display_id, origin, gfx::Size(), physical_size, insets, scale, - panel_transform, logical_transform, "display"); + {display_id, origin, gfx::Size(), physical_size, insets, scale, + panel_transform, logical_transform, "display"}); const display::Display new_display(observer.GetDisplay()); EXPECT_EQ(new_display.id(), display_id); @@ -347,15 +347,15 @@ display::Display display2(2, gfx::Rect(800, 0, 700, 500)); platform_screen_->OnOutputAddedOrUpdated( - display1.id(), display1.bounds().origin(), display1.size(), - display1.GetSizeInPixel(), display1.GetWorkAreaInsets(), - display1.device_scale_factor(), WL_OUTPUT_TRANSFORM_NORMAL, - WL_OUTPUT_TRANSFORM_NORMAL, std::string()); + {static_cast<uint32_t>(display1.id()), display1.bounds().origin(), + display1.size(), display1.GetSizeInPixel(), display1.GetWorkAreaInsets(), + display1.device_scale_factor(), WL_OUTPUT_TRANSFORM_NORMAL, + WL_OUTPUT_TRANSFORM_NORMAL, std::string()}); platform_screen_->OnOutputAddedOrUpdated( - display2.id(), display2.bounds().origin(), display2.size(), - display2.GetSizeInPixel(), display2.GetWorkAreaInsets(), - display2.device_scale_factor(), WL_OUTPUT_TRANSFORM_NORMAL, - WL_OUTPUT_TRANSFORM_NORMAL, std::string()); + {static_cast<uint32_t>(display2.id()), display2.bounds().origin(), + display2.size(), display2.GetSizeInPixel(), display2.GetWorkAreaInsets(), + display2.device_scale_factor(), WL_OUTPUT_TRANSFORM_NORMAL, + WL_OUTPUT_TRANSFORM_NORMAL, std::string()}); EXPECT_EQ(platform_screen_->GetPrimaryDisplay(), display1); @@ -366,15 +366,15 @@ // Purposely send the output metrics out of order. platform_screen_->OnOutputAddedOrUpdated( - display2.id(), display2.bounds().origin(), display2.size(), - display2.GetSizeInPixel(), display2.GetWorkAreaInsets(), - display2.device_scale_factor(), WL_OUTPUT_TRANSFORM_NORMAL, - WL_OUTPUT_TRANSFORM_NORMAL, std::string()); + {static_cast<uint32_t>(display2.id()), display2.bounds().origin(), + display2.size(), display2.GetSizeInPixel(), display2.GetWorkAreaInsets(), + display2.device_scale_factor(), WL_OUTPUT_TRANSFORM_NORMAL, + WL_OUTPUT_TRANSFORM_NORMAL, std::string()}); platform_screen_->OnOutputAddedOrUpdated( - display1.id(), display1.bounds().origin(), display1.size(), - display1.GetSizeInPixel(), display1.GetWorkAreaInsets(), - display1.device_scale_factor(), WL_OUTPUT_TRANSFORM_NORMAL, - WL_OUTPUT_TRANSFORM_NORMAL, std::string()); + {static_cast<uint32_t>(display1.id()), display1.bounds().origin(), + display1.size(), display1.GetSizeInPixel(), display1.GetWorkAreaInsets(), + display1.device_scale_factor(), WL_OUTPUT_TRANSFORM_NORMAL, + WL_OUTPUT_TRANSFORM_NORMAL, std::string()}); EXPECT_EQ(platform_screen_->GetPrimaryDisplay(), display2);
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.cc b/ui/views/controls/tabbed_pane/tabbed_pane.cc index bcfed7b..9dae4ce 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane.cc +++ b/ui/views/controls/tabbed_pane/tabbed_pane.cc
@@ -30,6 +30,7 @@ #include "ui/views/accessibility/view_accessibility.h" #include "ui/views/border.h" #include "ui/views/controls/label.h" +#include "ui/views/controls/scroll_view.h" #include "ui/views/controls/tabbed_pane/tabbed_pane_listener.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" @@ -394,13 +395,13 @@ // larger. if (GetOrientation() == TabbedPane::Orientation::kHorizontal) { return GetLayoutManager()->GetPreferredSize(this); - } else { - // In vertical mode, Tabstrips don't require any minimum space along their - // main axis, and can shrink all the way to zero size. Only the cross axis - // thickness matters. - const gfx::Size size = GetLayoutManager()->GetPreferredSize(this); - return gfx::Size(size.width(), 0); } + + // In vertical mode, Tabstrips don't require any minimum space along their + // main axis, and can shrink all the way to zero size. Only the cross axis + // thickness matters. + const gfx::Size size = GetLayoutManager()->GetPreferredSize(this); + return gfx::Size(size.width(), 0); } void TabStrip::OnPaintBorder(gfx::Canvas* canvas) { @@ -495,13 +496,24 @@ END_METADATA TabbedPane::TabbedPane(TabbedPane::Orientation orientation, - TabbedPane::TabStripStyle style) { + TabbedPane::TabStripStyle style, + bool scrollable) { DCHECK(orientation != TabbedPane::Orientation::kHorizontal || style != TabbedPane::TabStripStyle::kHighlight); auto* layout = SetLayoutManager(std::make_unique<views::FlexLayout>()); if (orientation == TabbedPane::Orientation::kHorizontal) layout->SetOrientation(views::LayoutOrientation::kVertical); - tab_strip_ = AddChildView(std::make_unique<TabStrip>(orientation, style)); + + auto tab_strip = std::make_unique<TabStrip>(orientation, style); + if (scrollable) { + scroll_view_ = AddChildView( + std::make_unique<ScrollView>(ScrollView::ScrollWithLayers::kEnabled)); + tab_strip_ = tab_strip.get(); + scroll_view_->SetContents(std::move(tab_strip)); + scroll_view_->ClipHeightTo(0, 0); + } else { + tab_strip_ = AddChildView(std::move(tab_strip)); + } contents_ = AddChildView(std::make_unique<View>()); contents_->SetProperty( views::kFlexBehaviorKey, @@ -583,6 +595,10 @@ SelectTab(tab, animate); } +ScrollView* TabbedPane::GetScrollView() { + return scroll_view_; +} + TabbedPane::Orientation TabbedPane::GetOrientation() const { return tab_strip_->GetOrientation(); }
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.h b/ui/views/controls/tabbed_pane/tabbed_pane.h index 1f7d7bf..2437c9dc 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane.h +++ b/ui/views/controls/tabbed_pane/tabbed_pane.h
@@ -47,7 +47,8 @@ }; explicit TabbedPane(Orientation orientation = Orientation::kHorizontal, - TabStripStyle style = TabStripStyle::kBorder); + TabStripStyle style = TabStripStyle::kBorder, + bool scrollable = false); TabbedPane(const TabbedPane&) = delete; TabbedPane& operator=(const TabbedPane&) = delete; @@ -90,6 +91,9 @@ // Selects |tab| (the tabstrip view, not its content) if it is valid. void SelectTab(TabbedPaneTab* tab, bool animate = true); + // Gets the scroll view containing the tab strip, if it exists + ScrollView* GetScrollView(); + // Gets the orientation of the tab alignment. Orientation GetOrientation() const; @@ -137,6 +141,10 @@ // correspond to match each TabbedPaneTab with its respective content View. raw_ptr<TabStrip> tab_strip_ = nullptr; raw_ptr<View> contents_ = nullptr; + + // The scroll view containing the tab strip, if |scrollable| is specified on + // creation. + raw_ptr<ScrollView> scroll_view_ = nullptr; }; // The tab view shown in the tab strip.
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc b/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc index 3f68fd1..df1058d 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc +++ b/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
@@ -9,6 +9,7 @@ #include "base/memory/raw_ptr.h" #include "base/strings/utf_string_conversions.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/accessibility/ax_action_data.h" #include "ui/accessibility/ax_enums.mojom.h" @@ -22,8 +23,7 @@ using base::ASCIIToUTF16; -namespace views { -namespace test { +namespace views::test { namespace { std::u16string DefaultTabTitle() { @@ -74,6 +74,27 @@ EXPECT_EQ(tabbed_pane->GetStyle(), TabbedPane::TabStripStyle::kHighlight); } +TEST_F(TabbedPaneTest, ScrollingDisabled) { + auto tabbed_pane = std::make_unique<TabbedPane>( + TabbedPane::Orientation::kVertical, TabbedPane::TabStripStyle::kBorder); + EXPECT_EQ(tabbed_pane->GetScrollView(), nullptr); +} + +TEST_F(TabbedPaneTest, ScrollingEnabled) { + auto tabbed_pane_vertical = + std::make_unique<TabbedPane>(TabbedPane::Orientation::kVertical, + TabbedPane::TabStripStyle::kBorder, true); + ASSERT_NE(tabbed_pane_vertical->GetScrollView(), nullptr); + EXPECT_THAT(tabbed_pane_vertical->GetScrollView(), testing::A<ScrollView*>()); + + auto tabbed_pane_horizontal = + std::make_unique<TabbedPane>(TabbedPane::Orientation::kHorizontal, + TabbedPane::TabStripStyle::kBorder, true); + ASSERT_NE(tabbed_pane_horizontal->GetScrollView(), nullptr); + EXPECT_THAT(tabbed_pane_horizontal->GetScrollView(), + testing::A<ScrollView*>()); +} + // Tests the preferred size and layout when tabs are aligned vertically.. TEST_F(TabbedPaneTest, SizeAndLayoutInVerticalOrientation) { auto tabbed_pane = std::make_unique<TabbedPane>( @@ -368,5 +389,4 @@ EXPECT_EQ(0, counter.GetCount(ax::mojom::Event::kSelectedChildrenChanged)); } -} // namespace test -} // namespace views +} // namespace views::test
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc index d64e918..a3c39629 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -651,7 +651,7 @@ aura::client::SetDragDropDelegate(content_window_, this); if (params.type != Widget::InitParams::TYPE_TOOLTIP) { - tooltip_manager_ = std::make_unique<TooltipManagerAura>(GetWidget()); + tooltip_manager_ = std::make_unique<TooltipManagerAura>(this); tooltip_controller_ = std::make_unique<corewm::TooltipController>( desktop_window_tree_host_->CreateTooltip(), wm::GetActivationClient(host_->window())); @@ -1276,7 +1276,7 @@ DCHECK(content_window_->IsVisible()); if (tooltip_manager_.get()) tooltip_manager_->UpdateTooltip(); - TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget()); + TooltipManagerAura::UpdateTooltipManagerForCapture(this); native_widget_delegate_->OnMouseEvent(event); // WARNING: we may have been deleted. }
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc index 0dbdbeab..9ee7b6c7 100644 --- a/ui/views/widget/native_widget_aura.cc +++ b/ui/views/widget/native_widget_aura.cc
@@ -290,7 +290,7 @@ : aura::EventTargetingPolicy::kNone); DCHECK(GetWidget()->GetRootView()); if (params.type != Widget::InitParams::TYPE_TOOLTIP) - tooltip_manager_ = std::make_unique<views::TooltipManagerAura>(GetWidget()); + tooltip_manager_ = std::make_unique<views::TooltipManagerAura>(this); drop_helper_ = std::make_unique<DropHelper>(GetWidget()->GetRootView()); if (params.type != Widget::InitParams::TYPE_TOOLTIP && @@ -1119,7 +1119,7 @@ if (tooltip_manager_.get()) tooltip_manager_->UpdateTooltip(); - TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget()); + TooltipManagerAura::UpdateTooltipManagerForCapture(this); delegate_->OnMouseEvent(event); }
diff --git a/ui/views/widget/tooltip_manager_aura.cc b/ui/views/widget/tooltip_manager_aura.cc index 1de0108..b8e4fc8 100644 --- a/ui/views/widget/tooltip_manager_aura.cc +++ b/ui/views/widget/tooltip_manager_aura.cc
@@ -10,6 +10,7 @@ #include "ui/base/resource/resource_bundle.h" #include "ui/display/screen.h" #include "ui/gfx/geometry/rect.h" +#include "ui/views/widget/native_widget_aura.h" #include "ui/views/widget/widget.h" #include "ui/wm/public/tooltip_client.h" @@ -18,8 +19,9 @@ //////////////////////////////////////////////////////////////////////////////// // TooltipManagerAura public: -TooltipManagerAura::TooltipManagerAura(Widget* widget) - : widget_(widget->AsWidget()->GetWeakPtr()) { +TooltipManagerAura::TooltipManagerAura( + internal::NativeWidgetPrivate* native_widget) + : native_widget_(native_widget) { wm::SetTooltipText(GetWindow(), &tooltip_text_); } @@ -34,7 +36,8 @@ } // static -void TooltipManagerAura::UpdateTooltipManagerForCapture(Widget* source) { +void TooltipManagerAura::UpdateTooltipManagerForCapture( + internal::NativeWidgetPrivate* source) { if (!source->HasCapture()) return; @@ -61,13 +64,14 @@ screen_position_client->ConvertPointFromScreen(target, &target_loc); target = target->GetEventHandlerForPoint(target_loc); while (target) { - Widget* target_widget = Widget::GetWidgetForNativeView(target); - if (target_widget == source) + internal::NativeWidgetPrivate* target_native_widget = + internal::NativeWidgetPrivate::GetNativeWidgetForNativeView(target); + if (target_native_widget == source) return; - if (target_widget) { - if (target_widget->GetTooltipManager()) - target_widget->GetTooltipManager()->UpdateTooltip(); + if (target_native_widget) { + if (target_native_widget->GetTooltipManager()) + target_native_widget->GetTooltipManager()->UpdateTooltip(); return; } target = target->parent(); @@ -82,14 +86,14 @@ } int TooltipManagerAura::GetMaxWidth(const gfx::Point& point) const { - return wm::GetTooltipClient(widget_->GetNativeView()->GetRootWindow()) + return wm::GetTooltipClient(native_widget_->GetNativeView()->GetRootWindow()) ->GetMaxWidth(point); } void TooltipManagerAura::UpdateTooltip() { aura::Window* root_window = GetWindow()->GetRootWindow(); if (wm::GetTooltipClient(root_window)) { - if (!widget_->IsVisible()) { + if (!native_widget_->IsVisible()) { UpdateTooltipForTarget(nullptr, gfx::Point(), root_window); return; } @@ -115,7 +119,10 @@ } View* TooltipManagerAura::GetViewUnderPoint(const gfx::Point& point) { - View* root_view = widget_->GetRootView(); + View* root_view = native_widget_->GetWidget() + ? native_widget_->GetWidget()->GetRootView() + : nullptr; + if (root_view) return root_view->GetTooltipHandlerForPoint(point); return nullptr; @@ -138,7 +145,7 @@ } aura::Window* TooltipManagerAura::GetWindow() { - return widget_->GetNativeView(); + return native_widget_->GetNativeView(); } } // namespace views.
diff --git a/ui/views/widget/tooltip_manager_aura.h b/ui/views/widget/tooltip_manager_aura.h index 338b335e..5b73520 100644 --- a/ui/views/widget/tooltip_manager_aura.h +++ b/ui/views/widget/tooltip_manager_aura.h
@@ -7,7 +7,7 @@ #include <string> -#include "base/memory/weak_ptr.h" +#include "base/memory/raw_ptr.h" #include "ui/gfx/geometry/point.h" #include "ui/views/views_export.h" #include "ui/views/widget/tooltip_manager.h" @@ -21,13 +21,13 @@ } namespace views { - -class Widget; - +namespace internal { +class NativeWidgetPrivate; +} // TooltipManager implementation for Aura. class VIEWS_EXPORT TooltipManagerAura : public TooltipManager { public: - explicit TooltipManagerAura(Widget* widget); + explicit TooltipManagerAura(internal::NativeWidgetPrivate* native_widget); TooltipManagerAura(const TooltipManagerAura&) = delete; TooltipManagerAura& operator=(const TooltipManagerAura&) = delete; @@ -38,7 +38,8 @@ // UpdateTooltip() on it's TooltipManager. This is necessary as when capture // is held mouse events are only delivered to the Window that has capture even // though we may show tooltips for the Window under the mouse. - static void UpdateTooltipManagerForCapture(Widget* source); + static void UpdateTooltipManagerForCapture( + internal::NativeWidgetPrivate* source); // Returns the FontList used by all TooltipManagerAuras. static const gfx::FontList& GetDefaultFontList(); @@ -58,7 +59,7 @@ // Returns the Window the tooltip text is installed on. aura::Window* GetWindow(); - base::WeakPtr<Widget> widget_; + base::raw_ptr<internal::NativeWidgetPrivate> native_widget_; std::u16string tooltip_text_; };