diff --git a/DEPS b/DEPS index 9f3afdd..b066896 100644 --- a/DEPS +++ b/DEPS
@@ -308,7 +308,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'src_internal_revision': 'ee061f481382201645e2569b5cfb8bc70f5685ef', + 'src_internal_revision': '9f3d71f2b078ed96b1334c3921e47d2a2735a9c5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. @@ -316,11 +316,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '408938972fdca848d564d0bd80139df8a90e53a5', + 'v8_revision': '68087ab41a76501a5364273a52cd395f0e7033b3', # 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': '69f5e9ca60cd6adfecd9eb8c969beeec30a4813d', + 'angle_revision': '1ceddbf6977926d674c0c5a78b398f684d0052b1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -347,7 +347,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling googletest # and whatever else without interference from each other. - 'googletest_revision': '76bb2afb8b522d24496ad1c757a49784fbfa2e42', + 'googletest_revision': 'dda72ef32181edbfcd32a8c52b4740cd8061ab6f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling lighttpd # and whatever else without interference from each other. @@ -387,7 +387,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling chromium_variations # and whatever else without interference from each other. - 'chromium_variations_revision': '32e2e5c8d0343434cf154f2b928775c2d95ad8c5', + 'chromium_variations_revision': '2f49c50b79ab7a6ee16f324656f0185a44fa50a6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling CrossBench # and whatever else without interference from each other. @@ -827,12 +827,12 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '5ac8fb250ea25c91a12158f768d4f5c03976f15e', + 'eadffcd4b5ec79ec69e29f75c6695edf9c69aff1', 'condition': 'checkout_android and checkout_src_internal', }, 'src/docs/website': { - 'url': Var('chromium_git') + '/website.git' + '@' + '7918c586771aed5e170cb5ce33fdfc38f6203063', + 'url': Var('chromium_git') + '/website.git' + '@' + 'f2eab19faaecbab4992d4633704136e5778faabc', }, 'src/ios/third_party/earl_grey2/src': { @@ -1049,7 +1049,7 @@ 'packages': [ { 'package': 'chromium/third_party/android_build_tools/lint', - 'version': 'H3namO3zonlUj075eXGd_my1zHGpGDoXubhIWd9CG0EC', + 'version': 'KICH09fjzlFXmYj2dj16tG91b6Ueo_BM3DDwKcjK0b0C', }, ], 'condition': 'checkout_android', @@ -1199,7 +1199,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '1ac3eb7b9844751478c7bdae4614f4d1e8b9b0f8', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'fbb0301f1f70813fb62e1f64e05410b730c8417e', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1654,7 +1654,7 @@ Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '09a4f3ec842a8932341b195c5b01e141c8a16eb7', 'src/third_party/openscreen/src': - Var('chromium_git') + '/openscreen' + '@' + 'ab2e34151f1f147f3dd56f73cdf3ea5c6ad2d0a5', + Var('chromium_git') + '/openscreen' + '@' + '614d391f2236a5035b6e7be8d0278db63bddbce0', 'src/third_party/openxr/src': { 'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + '95fe35ffb383710a6e0567e958ead9a3b66e930c', @@ -1850,7 +1850,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '98673cc24786be6c10dd8908e0b0b4ed27625c6a', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'e5ac106a357e2a1a088b732f0232d470de42f0cb', + Var('webrtc_git') + '/src.git' + '@' + 'ede75295d43032370f24bd4295693972ad27aaf0', # 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.
diff --git a/ash/birch/birch_model.cc b/ash/birch/birch_model.cc index eb8c0208..7be307b 100644 --- a/ash/birch/birch_model.cc +++ b/ash/birch/birch_model.cc
@@ -5,6 +5,7 @@ #include "ash/birch/birch_model.h" #include <algorithm> +#include <limits> #include <memory> #include <vector> @@ -13,6 +14,7 @@ #include "ash/birch/birch_weather_provider.h" #include "ash/constants/ash_features.h" #include "ash/shell.h" +#include "base/containers/cxx20_erase_vector.h" #include "base/functional/callback_forward.h" #include "base/time/time.h" @@ -145,6 +147,80 @@ return all_items; } +std::vector<std::unique_ptr<BirchItem>> BirchModel::GetItemsForDisplay() { + std::vector<std::unique_ptr<BirchItem>> all_items = GetAllItems(); + + // Remove any items with no ranking. + base::EraseIf(all_items, [](const auto& item) { + return item->ranking == std::numeric_limits<float>::max(); + }); + + std::vector<std::unique_ptr<BirchItem>> results; + + // Make multiple passes through all items, with each pass putting at most one + // item of each type in the results vector. + constexpr int kMaxResults = 4; + for (int pass = 0; pass < 2 && results.size() < kMaxResults; ++pass) { + bool have_calendar = false; + bool have_attachment = false; + bool have_tab = false; + bool have_file = false; + bool have_weather = false; + for (auto it = all_items.begin(); it != all_items.end(); ++it) { + // Early exit once enough results are found. + if (results.size() == kMaxResults) { + break; + } + // An earlier pass might have left this item null. + if (!*it) { + continue; + } + // If this is the first time an item of this type is encountered, move it + // into the results list. Set the `all_items` entry to null so the item + // will be ignored on future passes through the list. + if ((*it)->GetItemType() == BirchCalendarItem::kItemType && + !have_calendar) { + results.push_back(std::move(*it)); + *it = nullptr; + have_calendar = true; + continue; + } + if ((*it)->GetItemType() == BirchAttachmentItem::kItemType && + !have_attachment) { + results.push_back(std::move(*it)); + *it = nullptr; + have_attachment = true; + continue; + } + if ((*it)->GetItemType() == BirchTabItem::kItemType && !have_tab) { + results.push_back(std::move(*it)); + *it = nullptr; + have_tab = true; + continue; + } + if ((*it)->GetItemType() == BirchFileItem::kItemType && !have_file) { + results.push_back(std::move(*it)); + *it = nullptr; + have_file = true; + continue; + } + if ((*it)->GetItemType() == BirchWeatherItem::kItemType && + !have_weather) { + results.push_back(std::move(*it)); + *it = nullptr; + have_weather = true; + continue; + } + } + } + // Sort the returned items by ranking. + std::sort(results.begin(), results.end(), + [](const auto& item_a, const auto& item_b) { + return item_a->ranking < item_b->ranking; + }); + return results; +} + bool BirchModel::IsDataFresh() { return (!birch_client_ || (is_calendar_data_fresh_ && is_attachment_data_fresh_ &&
diff --git a/ash/birch/birch_model.h b/ash/birch/birch_model.h index e8a137c..85d9a29 100644 --- a/ash/birch/birch_model.h +++ b/ash/birch/birch_model.h
@@ -56,6 +56,10 @@ std::vector<std::unique_ptr<BirchItem>> GetAllItems(); + // Returns at most 4 items. Prefers higher ranked items. Prefers not to + // return multiple items of the same type, where possible. + std::vector<std::unique_ptr<BirchItem>> GetItemsForDisplay(); + // Returns whether all data in the model is currently fresh. bool IsDataFresh();
diff --git a/ash/birch/birch_model_unittest.cc b/ash/birch/birch_model_unittest.cc index cff16725..fec132b 100644 --- a/ash/birch/birch_model_unittest.cc +++ b/ash/birch/birch_model_unittest.cc
@@ -434,4 +434,168 @@ EXPECT_STREQ(all_items[4]->GetItemType(), BirchWeatherItem::kItemType); } +TEST_F(BirchModelTest, GetItemsForDisplay_EnoughTypes) { + BirchModel* model = Shell::Get()->birch_model(); + + // Insert one item of each type. + std::vector<BirchCalendarItem> calendar_item_list; + calendar_item_list.emplace_back(u"Event 1"); + calendar_item_list.back().ranking = 5.f; + model->SetCalendarItems(std::move(calendar_item_list)); + + std::vector<BirchAttachmentItem> attachment_item_list; + attachment_item_list.emplace_back(u"Attachment 1"); + attachment_item_list.back().ranking = 4.f; + model->SetAttachmentItems(std::move(attachment_item_list)); + + std::vector<BirchTabItem> tab_item_list; + tab_item_list.emplace_back(u"tab", GURL("foo.bar"), base::Time(), + GURL("favicon"), "session"); + tab_item_list.back().ranking = 3.f; + model->SetRecentTabItems(std::move(tab_item_list)); + + std::vector<BirchFileItem> file_item_list; + file_item_list.emplace_back(base::FilePath("test path 1"), base::Time()); + file_item_list.back().ranking = 2.f; + model->SetFileSuggestItems(std::move(file_item_list)); + + std::vector<BirchWeatherItem> weather_item_list; + weather_item_list.emplace_back(u"cloudy", u"16 c", ui::ImageModel()); + weather_item_list.back().ranking = 1.f; + model->SetWeatherItems(std::move(weather_item_list)); + + std::vector<std::unique_ptr<BirchItem>> items = model->GetItemsForDisplay(); + + // The maximum of 4 items are returned. + ASSERT_EQ(items.size(), 4u); + + // The items are in priority order. + EXPECT_FLOAT_EQ(items[0]->ranking, 1.f); + EXPECT_STREQ(items[0]->GetItemType(), BirchWeatherItem::kItemType); + EXPECT_FLOAT_EQ(items[1]->ranking, 2.f); + EXPECT_STREQ(items[1]->GetItemType(), BirchFileItem::kItemType); + EXPECT_FLOAT_EQ(items[2]->ranking, 3.f); + EXPECT_STREQ(items[2]->GetItemType(), BirchTabItem::kItemType); + EXPECT_FLOAT_EQ(items[3]->ranking, 4.f); + EXPECT_STREQ(items[3]->GetItemType(), BirchAttachmentItem::kItemType); +} + +TEST_F(BirchModelTest, GetItemsForDisplay_AvoidDuplicateTypes) { + BirchModel* model = Shell::Get()->birch_model(); + + // Insert 2 calendar events with high priority. + std::vector<BirchCalendarItem> calendar_item_list; + calendar_item_list.emplace_back(u"Event 1"); + calendar_item_list.back().ranking = 1.f; + calendar_item_list.emplace_back(u"Event 2"); + calendar_item_list.back().ranking = 2.f; + model->SetCalendarItems(std::move(calendar_item_list)); + + // Then insert 3 other items with lower priority. + std::vector<BirchAttachmentItem> attachment_item_list; + attachment_item_list.emplace_back(u"Attachment 1"); + attachment_item_list.back().ranking = 3.f; + model->SetAttachmentItems(std::move(attachment_item_list)); + + std::vector<BirchTabItem> tab_item_list; + tab_item_list.emplace_back(u"tab", GURL("foo.bar"), base::Time(), + GURL("favicon"), "session"); + tab_item_list.back().ranking = 4.f; + model->SetRecentTabItems(std::move(tab_item_list)); + + std::vector<BirchFileItem> file_item_list; + file_item_list.emplace_back(base::FilePath("test path 1"), base::Time()); + file_item_list.back().ranking = 5.f; + model->SetFileSuggestItems(std::move(file_item_list)); + + std::vector<std::unique_ptr<BirchItem>> items = model->GetItemsForDisplay(); + + // The maximum of 4 items are returned. + ASSERT_EQ(items.size(), 4u); + + // The second calendar event is skipped, despite being high priority, because + // the algorithm avoids duplicate types. + EXPECT_FLOAT_EQ(items[0]->ranking, 1.f); + EXPECT_STREQ(items[0]->GetItemType(), BirchCalendarItem::kItemType); + EXPECT_FLOAT_EQ(items[1]->ranking, 3.f); + EXPECT_STREQ(items[1]->GetItemType(), BirchAttachmentItem::kItemType); + EXPECT_FLOAT_EQ(items[2]->ranking, 4.f); + EXPECT_STREQ(items[2]->GetItemType(), BirchTabItem::kItemType); + EXPECT_FLOAT_EQ(items[3]->ranking, 5.f); + EXPECT_STREQ(items[3]->GetItemType(), BirchFileItem::kItemType); +} + +TEST_F(BirchModelTest, GetItemsForDisplay_TwoDuplicateTypes) { + BirchModel* model = Shell::Get()->birch_model(); + + // Insert 2 items of the same type. + std::vector<BirchCalendarItem> calendar_item_list; + calendar_item_list.emplace_back(u"Event 1"); + calendar_item_list.back().ranking = 1.f; + calendar_item_list.emplace_back(u"Event 2"); + calendar_item_list.back().ranking = 2.f; + model->SetCalendarItems(std::move(calendar_item_list)); + + // Insert 2 more items of a different type. + std::vector<BirchAttachmentItem> attachment_item_list; + attachment_item_list.emplace_back(u"Attachment 1"); + attachment_item_list.back().ranking = 3.f; + attachment_item_list.emplace_back(u"Attachment 2"); + attachment_item_list.back().ranking = 4.f; + model->SetAttachmentItems(std::move(attachment_item_list)); + + std::vector<std::unique_ptr<BirchItem>> items = model->GetItemsForDisplay(); + + ASSERT_EQ(items.size(), 4u); + EXPECT_FLOAT_EQ(items[0]->ranking, 1.f); + EXPECT_STREQ(items[0]->GetItemType(), BirchCalendarItem::kItemType); + EXPECT_FLOAT_EQ(items[1]->ranking, 2.f); + EXPECT_STREQ(items[1]->GetItemType(), BirchCalendarItem::kItemType); + EXPECT_FLOAT_EQ(items[2]->ranking, 3.f); + EXPECT_STREQ(items[2]->GetItemType(), BirchAttachmentItem::kItemType); + EXPECT_FLOAT_EQ(items[3]->ranking, 4.f); + EXPECT_STREQ(items[3]->GetItemType(), BirchAttachmentItem::kItemType); +} + +TEST_F(BirchModelTest, GetItemsForDisplay_NotEnoughItems) { + BirchModel* model = Shell::Get()->birch_model(); + + // Insert 3 items of the same type. + std::vector<BirchCalendarItem> calendar_item_list; + calendar_item_list.emplace_back(u"Event 1"); + calendar_item_list.back().ranking = 1.f; + calendar_item_list.emplace_back(u"Event 2"); + calendar_item_list.back().ranking = 2.f; + calendar_item_list.emplace_back(u"Event 3"); + calendar_item_list.back().ranking = 3.f; + model->SetCalendarItems(std::move(calendar_item_list)); + + std::vector<std::unique_ptr<BirchItem>> items = model->GetItemsForDisplay(); + + // Only 2 items are returned. + ASSERT_EQ(items.size(), 2u); + EXPECT_FLOAT_EQ(items[0]->ranking, 1.f); + EXPECT_STREQ(items[0]->GetItemType(), BirchCalendarItem::kItemType); + EXPECT_FLOAT_EQ(items[1]->ranking, 2.f); + EXPECT_STREQ(items[1]->GetItemType(), BirchCalendarItem::kItemType); +} + +TEST_F(BirchModelTest, GetItemsForDisplay_NotRankedItem) { + BirchModel* model = Shell::Get()->birch_model(); + + // Insert 1 regular item and 1 item with no ranking. + std::vector<BirchCalendarItem> calendar_item_list; + calendar_item_list.emplace_back(u"Ranked"); + calendar_item_list.back().ranking = 1.f; + calendar_item_list.emplace_back(u"Unranked"); + model->SetCalendarItems(std::move(calendar_item_list)); + + std::vector<std::unique_ptr<BirchItem>> items = model->GetItemsForDisplay(); + + // Only 1 item is returned because the unranked item is discarded. + ASSERT_EQ(items.size(), 1u); + EXPECT_FLOAT_EQ(items[0]->ranking, 1.f); + EXPECT_STREQ(items[0]->GetItemType(), BirchCalendarItem::kItemType); +} + } // namespace ash
diff --git a/ash/login/ui/lock_screen_media_controls_view.h b/ash/login/ui/lock_screen_media_controls_view.h index 0ac194664..be21d5a2 100644 --- a/ash/login/ui/lock_screen_media_controls_view.h +++ b/ash/login/ui/lock_screen_media_controls_view.h
@@ -121,6 +121,9 @@ void MediaControllerImageChanged( media_session::mojom::MediaSessionImageType type, const SkBitmap& bitmap) override; + // This view is used before `media::kGlobalMediaControlsCrOSUpdatedUI` is + // enabled. So we don't need to implement this method since there's no chapter + // images in this view. void MediaControllerChapterImageChanged(int chapter_index, const SkBitmap& bitmap) override {}
diff --git a/ash/login/ui/lock_screen_media_view.cc b/ash/login/ui/lock_screen_media_view.cc index ed87bf7..22e9eeab 100644 --- a/ash/login/ui/lock_screen_media_view.cc +++ b/ash/login/ui/lock_screen_media_view.cc
@@ -270,6 +270,17 @@ view_->UpdateWithMediaArtwork(gfx::ImageSkia::CreateFrom1xBitmap(bitmap)); } +void LockScreenMediaView::MediaControllerChapterImageChanged( + int chapter_index, + const SkBitmap& bitmap) { + if (switch_media_delay_timer_->IsRunning()) { + return; + } + + view_->UpdateWithChapterArtwork(chapter_index, + gfx::ImageSkia::CreateFrom1xBitmap(bitmap)); +} + /////////////////////////////////////////////////////////////////////////////// // media_message_center::MediaNotificationContainer implementations:
diff --git a/ash/login/ui/lock_screen_media_view.h b/ash/login/ui/lock_screen_media_view.h index 4c5471b..2973c526 100644 --- a/ash/login/ui/lock_screen_media_view.h +++ b/ash/login/ui/lock_screen_media_view.h
@@ -69,7 +69,7 @@ media_session::mojom::MediaSessionImageType type, const SkBitmap& bitmap) override; void MediaControllerChapterImageChanged(int chapter_index, - const SkBitmap& bitmap) override {} + const SkBitmap& bitmap) override; // media_message_center::MediaNotificationContainer: void OnExpanded(bool expanded) override {}
diff --git a/ash/public/cpp/external_arc/message_center/arc_notification_content_view.cc b/ash/public/cpp/external_arc/message_center/arc_notification_content_view.cc index 6589d642..c1fe13d8 100644 --- a/ash/public/cpp/external_arc/message_center/arc_notification_content_view.cc +++ b/ash/public/cpp/external_arc/message_center/arc_notification_content_view.cc
@@ -554,6 +554,15 @@ UpdateMask(false /* force_update */); } +void ArcNotificationContentView::SetVisible(bool visible) { + NativeViewHost::SetVisible(visible); + if (visible) { + EnsureSurfaceAttached(); + } else { + EnsureSurfaceDetached(); + } +} + void ArcNotificationContentView::EnsureSurfaceAttached() { if (!surface_ || surface_->IsAttached()) { return;
diff --git a/ash/public/cpp/external_arc/message_center/arc_notification_content_view.h b/ash/public/cpp/external_arc/message_center/arc_notification_content_view.h index 16e93bf3..e597dae 100644 --- a/ash/public/cpp/external_arc/message_center/arc_notification_content_view.h +++ b/ash/public/cpp/external_arc/message_center/arc_notification_content_view.h
@@ -65,11 +65,12 @@ void OnContainerAnimationStarted(); void OnContainerAnimationEnded(); void ActivateWidget(bool activate); - void EnsureSurfaceAttached(); - void EnsureSurfaceDetached(); bool slide_in_progress() const { return slide_in_progress_; } + // views::NativeViewHost + void SetVisible(bool visible) override; + private: friend class ArcNotificationViewTest; friend class ArcNotificationContentViewTest; @@ -92,6 +93,8 @@ bool IsExpanded() const; void SetManuallyExpandedOrCollapsed(bool value); bool IsManuallyExpandedOrCollapsed() const; + void EnsureSurfaceAttached(); + void EnsureSurfaceDetached(); void ShowCopiedSurface(); void HideCopiedSurface();
diff --git a/ash/public/cpp/external_arc/message_center/arc_notification_view.cc b/ash/public/cpp/external_arc/message_center/arc_notification_view.cc index b96ca3b2..d4495906 100644 --- a/ash/public/cpp/external_arc/message_center/arc_notification_view.cc +++ b/ash/public/cpp/external_arc/message_center/arc_notification_view.cc
@@ -273,11 +273,6 @@ collapsed_summary_view_->SetVisible(!expanded); content_view_->SetVisible(expanded); - if (expanded) { - content_view_->EnsureSurfaceAttached(); - } else { - content_view_->EnsureSurfaceDetached(); - } } void ArcNotificationView::AnimateGroupedChildExpandedCollapse(bool expanded) {
diff --git a/ash/system/input_device_settings/input_device_settings_controller_impl.cc b/ash/system/input_device_settings/input_device_settings_controller_impl.cc index 8fdde22..e3cf3d93 100644 --- a/ash/system/input_device_settings/input_device_settings_controller_impl.cc +++ b/ash/system/input_device_settings/input_device_settings_controller_impl.cc
@@ -1756,6 +1756,14 @@ return; } + // If there is no active account id or local state isn't initialized, use + // default graphics tablet settings. This can happen as an uncommon race + // condition when first signing in on the login screen. + if (!active_account_id_ || !local_state_) { + graphics_tablet->settings = mojom::GraphicsTabletSettings::New(); + return; + } + graphics_tablet_pref_handler_->InitializeLoginScreenGraphicsTabletSettings( local_state_, active_account_id_.value(), graphics_tablet); }
diff --git a/ash/system/input_device_settings/input_device_settings_controller_unittest.cc b/ash/system/input_device_settings/input_device_settings_controller_unittest.cc index 8d753d4..6645eea 100644 --- a/ash/system/input_device_settings/input_device_settings_controller_unittest.cc +++ b/ash/system/input_device_settings/input_device_settings_controller_unittest.cc
@@ -287,6 +287,7 @@ void InitializeWithDefaultKeyboardSettings( const mojom::KeyboardPolicies& keyboard_policies, mojom::Keyboard* keyboard) override { + keyboard->settings = CreateNewKeyboardSettings(); num_initialize_default_keyboard_settings_calls_++; } @@ -489,22 +490,27 @@ auto user_2_prefs = std::make_unique<TestingPrefServiceSimple>(); RegisterUserProfilePrefs(user_2_prefs->registry(), /*country=*/"", /*for_test=*/true); - session_controller->AddUserSession(kUserEmail1, - user_manager::UserType::kRegular, - /*provide_pref_service=*/false); - session_controller->SetUserPrefService(account_id_1, - std::move(user_1_prefs)); - session_controller->AddUserSession(kUserEmail2, - user_manager::UserType::kRegular, - /*provide_pref_service=*/false); - session_controller->SetUserPrefService(account_id_2, - std::move(user_2_prefs)); - session_controller->AddUserSession(kUserEmail3, - user_manager::UserType::kRegular, - /*provide_pref_service=*/false); - session_controller->SwitchActiveUser(account_id_1); - session_controller->SetSessionState(session_manager::SessionState::ACTIVE); + if (should_sign_in_) { + session_controller->AddUserSession(kUserEmail1, + user_manager::UserType::kRegular, + /*provide_pref_service=*/false); + session_controller->SetUserPrefService(account_id_1, + std::move(user_1_prefs)); + session_controller->AddUserSession(kUserEmail2, + user_manager::UserType::kRegular, + /*provide_pref_service=*/false); + session_controller->SetUserPrefService(account_id_2, + std::move(user_2_prefs)); + session_controller->AddUserSession(kUserEmail3, + user_manager::UserType::kRegular, + /*provide_pref_service=*/false); + + session_controller->SwitchActiveUser(account_id_1); + session_controller->SetSessionState( + session_manager::SessionState::ACTIVE); + } + // Reset the `num_keyboard_settings_initialized_` to account for the // `InitializeKeyboardSettings` call made after test setup where we // simualate @@ -542,6 +548,11 @@ scoped_resetter_; raw_ptr<FakeKeyboardPrefHandler, DanglingUntriaged> keyboard_pref_handler_ = nullptr; + + // Used by other instances of the InputDeviceSettingsControllerTest to control + // whether or not to sign in within the SetUp() function. Configured to sign + // in by default. + bool should_sign_in_ = true; }; TEST_F(InputDeviceSettingsControllerTest, KeyboardAddingOne) { @@ -1560,4 +1571,59 @@ EXPECT_EQ(2u, observer_->num_pointing_stick_settings_updated()); } +class InputDeviceSettingsControllerNoSignInTest + : public InputDeviceSettingsControllerTest { + public: + InputDeviceSettingsControllerNoSignInTest() { should_sign_in_ = false; } +}; + +TEST_F(InputDeviceSettingsControllerNoSignInTest, + NoCrashOnPodSelectionRaceConditionMouse) { + ui::DeviceDataManagerTestApi().SetMouseDevices({kSampleMouseUsb}); + + auto* mouse = controller_->GetMouse(kSampleMouseUsb.id); + ASSERT_TRUE(mouse); + ASSERT_TRUE(mouse->settings); +} + +TEST_F(InputDeviceSettingsControllerNoSignInTest, + NoCrashOnPodSelectionRaceConditionKeyboard) { + ui::DeviceDataManagerTestApi().SetKeyboardDevices({kSampleKeyboardInternal}); + + auto* keyboard = controller_->GetKeyboard(kSampleKeyboardInternal.id); + ASSERT_TRUE(keyboard); + ASSERT_TRUE(keyboard->settings); +} + +TEST_F(InputDeviceSettingsControllerNoSignInTest, + NoCrashOnPodSelectionRaceConditionTouchpad) { + ui::DeviceDataManagerTestApi().SetTouchpadDevices({kSampleTouchpadInternal}); + + auto* touchpad = controller_->GetTouchpad(kSampleTouchpadInternal.id); + ASSERT_TRUE(touchpad); + ASSERT_TRUE(touchpad->settings); +} + +TEST_F(InputDeviceSettingsControllerNoSignInTest, + NoCrashOnPodSelectionRaceConditionPointingStick) { + ui::DeviceDataManagerTestApi().SetPointingStickDevices( + {kSamplePointingStickExternal}); + + auto* pointing_stick = + controller_->GetPointingStick(kSamplePointingStickExternal.id); + ASSERT_TRUE(pointing_stick); + ASSERT_TRUE(pointing_stick->settings); +} + +TEST_F(InputDeviceSettingsControllerNoSignInTest, + NoCrashOnPodSelectionRaceConditionGraphicsTablet) { + ui::DeviceDataManagerTestApi().SetGraphicsTabletDevices( + {kSampleGraphicsTablet}); + + auto* graphics_tablet = + controller_->GetGraphicsTablet(kSampleGraphicsTablet.id); + ASSERT_TRUE(graphics_tablet); + ASSERT_TRUE(graphics_tablet->settings); +} + } // namespace ash
diff --git a/ash/system/mahi/mahi_panel_view.cc b/ash/system/mahi/mahi_panel_view.cc index 96693ee..fc06576 100644 --- a/ash/system/mahi/mahi_panel_view.cc +++ b/ash/system/mahi/mahi_panel_view.cc
@@ -5,6 +5,7 @@ #include "ash/system/mahi/mahi_panel_view.h" #include <algorithm> +#include <climits> #include <memory> #include <string> @@ -32,11 +33,13 @@ #include "ui/views/background.h" #include "ui/views/controls/label.h" #include "ui/views/controls/link.h" +#include "ui/views/controls/scroll_view.h" #include "ui/views/highlight_border.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/box_layout_view.h" #include "ui/views/layout/flex_layout_view.h" #include "ui/views/layout/layout_types.h" +#include "ui/views/metadata/view_factory_internal.h" #include "ui/views/view.h" #include "ui/views/view_class_properties.h" #include "ui/views/widget/widget.h" @@ -50,6 +53,7 @@ constexpr gfx::Insets kPanelPadding = gfx::Insets(16); constexpr int kPanelChildSpacing = 8; constexpr int kHeaderRowSpacing = 8; +constexpr float kScrollerViewCornerRadius = 16; } // namespace @@ -57,10 +61,12 @@ END_METADATA MahiPanelView::MahiPanelView() { - SetOrientation(views::BoxLayout::Orientation::kVertical); - SetMainAxisAlignment(views::BoxLayout::MainAxisAlignment::kStart); - SetInsideBorderInsets(kPanelPadding); - SetBetweenChildSpacing(kPanelChildSpacing); + SetOrientation(views::LayoutOrientation::kVertical); + SetMainAxisAlignment(views::LayoutAlignment::kStart); + SetInteriorMargin(kPanelPadding); + SetDefault(views::kMarginsKey, gfx::Insets::VH(kPanelChildSpacing, 0)); + SetIgnoreDefaultMainAxisMargins(true); + SetCollapseMargins(true); SetBackground(views::CreateThemedRoundedRectBackground( cros_tokens::kCrosSysSystemBaseElevated, kPanelCornerRadius)); @@ -77,6 +83,7 @@ views::HighlightBorder::Type::kHighlightBorderOnShadow, /*insets_type=*/views::HighlightBorder::InsetsType::kHalfInsets)); + // Views constructions. auto header_row = std::make_unique<views::FlexLayoutView>(); header_row->SetOrientation(views::LayoutOrientation::kHorizontal); @@ -116,7 +123,34 @@ AddChildView(std::move(header_row)); - AddChildView(std::make_unique<SummaryOutlinesSection>()); + // Scrollable contents, which should contain the summary outline section and + // the Q&A section. + auto scroll_view = + views::Builder<views::ScrollView>() + .SetBackgroundThemeColorId(cros_tokens::kCrosSysSystemOnBase) + .SetProperty(views::kFlexBehaviorKey, + views::FlexSpecification(views::FlexSpecification( + views::MinimumFlexSizeRule::kPreferred, + views::MaximumFlexSizeRule::kUnbounded))) + .ClipHeightTo(/*min_height=*/0, /*max_height=*/INT_MAX) + .SetDrawOverflowIndicator(false) + .Build(); + + scroll_view->SetContents( + views::Builder<views::View>() + .SetUseDefaultFillLayout(true) + .AddChild(views::Builder<SummaryOutlinesSection>()) + // TODO(b/319731486): Change this view to the Q&A section and + // show/hide it accordingly. + .AddChild(views::Builder<views::View>()) + .Build()); + + // Add layer for rounded corners. + scroll_view->SetPaintToLayer(); + scroll_view->layer()->SetRoundedCornerRadius( + gfx::RoundedCornersF{kScrollerViewCornerRadius}); + + AddChildView(std::move(scroll_view)); auto feedback_view = std::make_unique<views::BoxLayoutView>(); feedback_view->SetOrientation(views::BoxLayout::Orientation::kHorizontal);
diff --git a/ash/system/mahi/mahi_panel_view.h b/ash/system/mahi/mahi_panel_view.h index 54e412c81..69048c2 100644 --- a/ash/system/mahi/mahi_panel_view.h +++ b/ash/system/mahi/mahi_panel_view.h
@@ -9,7 +9,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "ui/base/metadata/metadata_header_macros.h" -#include "ui/views/layout/box_layout_view.h" +#include "ui/views/layout/flex_layout_view.h" namespace ui { class Event; @@ -19,8 +19,8 @@ // The code for Mahi main panel view. This view is placed within // `MahiPanelWidget`. -class ASH_EXPORT MahiPanelView : public views::BoxLayoutView { - METADATA_HEADER(MahiPanelView, views::BoxLayoutView) +class ASH_EXPORT MahiPanelView : public views::FlexLayoutView { + METADATA_HEADER(MahiPanelView, views::FlexLayoutView) public: MahiPanelView();
diff --git a/ash/system/mahi/summary_outlines_section.cc b/ash/system/mahi/summary_outlines_section.cc index 468daacc..231c856 100644 --- a/ash/system/mahi/summary_outlines_section.cc +++ b/ash/system/mahi/summary_outlines_section.cc
@@ -19,7 +19,6 @@ #include "ui/chromeos/styles/cros_tokens_color_mappings.h" #include "ui/gfx/text_constants.h" #include "ui/gfx/vector_icon_types.h" -#include "ui/views/background.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" #include "ui/views/layout/box_layout.h" @@ -34,7 +33,6 @@ constexpr int64_t kSectionHeaderIconSize = 20; constexpr gfx::Insets kSectionPadding = gfx::Insets::TLBR(8, 8, 16, 8); constexpr int64_t kSectionChildSpacing = 8; -constexpr int64_t kSectionCornerRadius = 16; std::unique_ptr<views::View> CreateSectionHeader(const gfx::VectorIcon& icon, int name_id) { @@ -62,9 +60,6 @@ SetInsideBorderInsets(kSectionPadding); SetBetweenChildSpacing(kSectionChildSpacing); - SetBackground(views::CreateThemedRoundedRectBackground( - cros_tokens::kCrosSysSystemOnBase, kSectionCornerRadius)); - AddChildView(CreateSectionHeader(chromeos::kMahiSummarizeIcon, IDS_MAHI_PANEL_SUMMARY_SECTION_NAME));
diff --git a/ash/system/mahi/summary_outlines_section.h b/ash/system/mahi/summary_outlines_section.h index 70f32a2..cd82052 100644 --- a/ash/system/mahi/summary_outlines_section.h +++ b/ash/system/mahi/summary_outlines_section.h
@@ -10,6 +10,7 @@ #include "base/memory/weak_ptr.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/views/layout/box_layout_view.h" +#include "ui/views/metadata/view_factory.h" namespace ash { @@ -27,6 +28,11 @@ base::WeakPtrFactory<SummaryOutlinesSection> weak_ptr_factory_{this}; }; +BEGIN_VIEW_BUILDER(ASH_EXPORT, SummaryOutlinesSection, views::BoxLayoutView) +END_VIEW_BUILDER + } // namespace ash +DEFINE_VIEW_BUILDER(ASH_EXPORT, ash::SummaryOutlinesSection) + #endif // ASH_SYSTEM_MAHI_SUMMARY_OUTLINES_SECTION_H_
diff --git a/ash/system/media/unified_media_controls_controller.h b/ash/system/media/unified_media_controls_controller.h index 837ddda..0528e28 100644 --- a/ash/system/media/unified_media_controls_controller.h +++ b/ash/system/media/unified_media_controls_controller.h
@@ -54,6 +54,9 @@ void MediaControllerImageChanged( media_session::mojom::MediaSessionImageType type, const SkBitmap& bitmap) override; + // This view will be deprecated after `kBackgroundListening` is enabled. So we + // don't need to implement this method since there's no chapter images in this + // view. void MediaControllerChapterImageChanged(int chapter_index, const SkBitmap& bitmap) override {}
diff --git a/ash/webui/print_preview_cros/resources/js/data/print_ticket_manager.ts b/ash/webui/print_preview_cros/resources/js/data/print_ticket_manager.ts index 0e38a7e..9d12832 100644 --- a/ash/webui/print_preview_cros/resources/js/data/print_ticket_manager.ts +++ b/ash/webui/print_preview_cros/resources/js/data/print_ticket_manager.ts
@@ -13,6 +13,11 @@ * signaling updates to subscribed listeners. */ +export const PRINT_REQUEST_STARTED_EVENT = + 'print-ticket-manager.print-request-started'; +export const PRINT_REQUEST_FINISHED_EVENT = + 'print-ticket-manager.print-request-finished'; + export class PrintTicketManager extends EventTarget { private static instance: PrintTicketManager|null = null; @@ -30,6 +35,7 @@ // Non-static properties: private printPreviewPageHandler: PrintPreviewPageHandler|null; + private printRequestInProgress = false; // Prevent additional initialization. private constructor() { @@ -39,15 +45,32 @@ this.printPreviewPageHandler = getPrintPreviewPageHandler(); } + // Custom event dispatch helper. + private dispatch(eventName: string): void { + this.dispatchEvent( + new CustomEvent(eventName, {bubbles: true, composed: true})); + } + + // Handles notifying start and finish print request. // TODO(b/323421684): Takes current print ticket uses PrintPreviewPageHandler - // to initiate actual print request. Also handles print request start and - // finish events. + // to initiate actual print request. sendPrintRequest(): void { assert(this.printPreviewPageHandler); + if (this.printRequestInProgress) { + // Print is already in progress, wait for request to resolve before + // allowing a second attempt. + return; + } + this.printRequestInProgress = true; + this.dispatch(PRINT_REQUEST_STARTED_EVENT); + // TODO(b/323421684): Handle result from page handler and update UI if error // occurred. - this.printPreviewPageHandler!.print(); + this.printPreviewPageHandler!.print().finally(() => { + this.printRequestInProgress = false; + this.dispatch(PRINT_REQUEST_FINISHED_EVENT); + }); } // Does cleanup for print request. @@ -55,4 +78,15 @@ assert(this.printPreviewPageHandler); this.printPreviewPageHandler!.cancel(); } + + isPrintRequestInProgress(): boolean { + return this.printRequestInProgress; + } +} + +declare global { + interface HTMLElementEventMap { + [PRINT_REQUEST_FINISHED_EVENT]: CustomEvent<void>; + [PRINT_REQUEST_STARTED_EVENT]: CustomEvent<void>; + } }
diff --git a/ash/webui/print_preview_cros/resources/js/fakes/fake_print_preview_page_handler.ts b/ash/webui/print_preview_cros/resources/js/fakes/fake_print_preview_page_handler.ts index faa3414..01025ab9 100644 --- a/ash/webui/print_preview_cros/resources/js/fakes/fake_print_preview_page_handler.ts +++ b/ash/webui/print_preview_cros/resources/js/fakes/fake_print_preview_page_handler.ts
@@ -3,6 +3,7 @@ // found in the LICENSE file. import {FakeMethodResolver} from 'chrome://resources/ash/common/fake_method_resolver.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {type PrintPreviewPageHandler, type PrintRequestOutcome} from '../utils/print_preview_cros_app_types.js'; @@ -29,6 +30,7 @@ export class FakePrintPreviewPageHandler implements PrintPreviewPageHandler { private methods: FakeMethodResolver = new FakeMethodResolver(); private callCount: Map<string, number> = new Map<string, number>(); + private testDelayMs = 0; constructor() { this.registerMethods(); } @@ -46,6 +48,7 @@ this.callCount.clear(); this.methods = new FakeMethodResolver(); this.registerMethods(); + this.testDelayMs = 0; } setPrintResult(result: PrintRequestOutcome) { @@ -56,7 +59,7 @@ print(): Promise<PrintRequestOutcome> { const prevCallCount = this.callCount.get(PRINT_METHOD) ?? 0; this.callCount.set(PRINT_METHOD, prevCallCount + 1); - return this.methods.resolveMethod(PRINT_METHOD); + return this.methods.resolveMethodWithDelay(PRINT_METHOD, this.testDelayMs); } getCallCount(method: string): number { @@ -68,4 +71,13 @@ const prevCallCount = this.callCount.get(CANCEL_METHOD) ?? 0; this.callCount.set(CANCEL_METHOD, prevCallCount + 1); } + + useTestDelay(delay: number): void { + assert(delay >= 0); + this.testDelayMs = delay; + } + + getMethodsForTesting(): FakeMethodResolver { + return this.methods; + } }
diff --git a/ash/webui/print_preview_cros/resources/js/summary_panel.html b/ash/webui/print_preview_cros/resources/js/summary_panel.html index 1987bc7..5bd2948 100644 --- a/ash/webui/print_preview_cros/resources/js/summary_panel.html +++ b/ash/webui/print_preview_cros/resources/js/summary_panel.html
@@ -23,6 +23,7 @@ </cros-button> <!-- TODO(b/323585997): Replace label localized string. --> <cros-button id="print" label="Print" button-style="primary" - on-click="onPrintClicked"> + on-click="onPrintClicked" + disabled="[[printButtonDisabled]]"> </cros-button> </div> \ No newline at end of file
diff --git a/ash/webui/print_preview_cros/resources/js/summary_panel.ts b/ash/webui/print_preview_cros/resources/js/summary_panel.ts index 6833507..df656497 100644 --- a/ash/webui/print_preview_cros/resources/js/summary_panel.ts +++ b/ash/webui/print_preview_cros/resources/js/summary_panel.ts
@@ -7,7 +7,7 @@ import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './summary_panel.html.js'; -import {SHEETS_USED_CHANGED_EVENT, SummaryPanelController} from './summary_panel_controller.js'; +import {PRINT_BUTTON_DISABLED_CHANGED_EVENT, SHEETS_USED_CHANGED_EVENT, SummaryPanelController} from './summary_panel_controller.js'; /** * @fileoverview @@ -27,26 +27,32 @@ static get properties() { return { sheetsUsedText: String, + printButtonDisabled: Boolean, }; } private controller: SummaryPanelController = new SummaryPanelController(); private sheetsUsedText: string; + private printButtonDisabled: boolean; override connectedCallback(): void { super.connectedCallback(); this.controller.addEventListener( + PRINT_BUTTON_DISABLED_CHANGED_EVENT, + (e: Event) => this.onPrintButtonDisabledChanged(e)); + this.controller.addEventListener( SHEETS_USED_CHANGED_EVENT, (e: Event) => this.onSheetsUsedChanged(e)); // Initialize properties using controller. this.sheetsUsedText = this.controller.getSheetsUsedText(); + this.printButtonDisabled = this.controller.shouldDisablePrintButton(); } - getControllerForTesting() { + getControllerForTesting(): SummaryPanelController { return this.controller; } - private onSheetsUsedChanged(_event: Event) { + private onSheetsUsedChanged(_event: Event): void { this.sheetsUsedText = this.controller.getSheetsUsedText(); } @@ -59,6 +65,12 @@ protected onCancelClicked(_event: Event): void { this.controller.handleCancelClicked(); } + + // Ensure `#print` disabled state updates based on controller's + // shouldDisablePrintButton method on `PRINT_BUTTON_DISABLED_CHANGED_EVENT`. + private onPrintButtonDisabledChanged(_event: Event): void { + this.printButtonDisabled = this.controller.shouldDisablePrintButton(); + } } declare global {
diff --git a/ash/webui/print_preview_cros/resources/js/summary_panel_controller.ts b/ash/webui/print_preview_cros/resources/js/summary_panel_controller.ts index afa2a75..ade8779 100644 --- a/ash/webui/print_preview_cros/resources/js/summary_panel_controller.ts +++ b/ash/webui/print_preview_cros/resources/js/summary_panel_controller.ts
@@ -4,7 +4,7 @@ import {assert} from 'chrome://resources/js/assert.js'; -import {PrintTicketManager} from './data/print_ticket_manager.js'; +import {PRINT_REQUEST_FINISHED_EVENT, PRINT_REQUEST_STARTED_EVENT, PrintTicketManager} from './data/print_ticket_manager.js'; /** * @fileoverview @@ -13,6 +13,8 @@ * to update. */ +export const PRINT_BUTTON_DISABLED_CHANGED_EVENT = + 'summary-panel-controller.print-button-disabled-changed'; export const SHEETS_USED_CHANGED_EVENT = 'summary-panel-controller.sheets-used-changed'; @@ -22,6 +24,16 @@ private sheetsUsed = 0; private printTicketManger = PrintTicketManager.getInstance(); + constructor() { + super(); + this.printTicketManger.addEventListener( + PRINT_REQUEST_STARTED_EVENT, + (e: Event) => this.onPrintRequestStarted(e)); + this.printTicketManger.addEventListener( + PRINT_REQUEST_FINISHED_EVENT, + (e: Event) => this.onPrintRequestFinished(e)); + } + // Returns localized string based on current number of sheets in document and // whether document is being saved to a digital destination or printed to a // physical location. @@ -38,8 +50,7 @@ setSheetsUsedForTesting(sheetsUsed: number): void { assert(sheetsUsed >= 0); this.sheetsUsed = sheetsUsed; - this.dispatchEvent(new CustomEvent<void>( - SHEETS_USED_CHANGED_EVENT, {bubbles: true, composed: true})); + this.dispatch(SHEETS_USED_CHANGED_EVENT); } // Handles behavior for when the print button is clicked. @@ -52,6 +63,27 @@ handleCancelClicked(): void { this.printTicketManger.cancelPrintRequest(); } + + // CustomEvent dispatch helper. + private dispatch(eventName: string): void { + this.dispatchEvent( + new CustomEvent<void>(eventName, {bubbles: true, composed: true})); + } + + // Handles notifying UI to update state when print request starts. + private onPrintRequestStarted(_e: Event): void { + this.dispatch(PRINT_BUTTON_DISABLED_CHANGED_EVENT); + } + + // Handles notifying UI to update state when print request finishes. + private onPrintRequestFinished(_e: Event): void { + this.dispatch(PRINT_BUTTON_DISABLED_CHANGED_EVENT); + } + + // Whether the print button should be enabled for the current state. + shouldDisablePrintButton(): boolean { + return this.printTicketManger.isPrintRequestInProgress(); + } } declare global {
diff --git a/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts b/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts index 9a08d713..b16d2450 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts +++ b/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts
@@ -294,8 +294,9 @@ } private handleKeyDown(e: CustomEvent): void { - // Announce the key pressed. - this.makeA11yAnnouncement(e.detail.keyEvent.keyDisplay); + // Announce the icon label or key pressed. + const keyOrIcon = e.detail.keyEvent.keyDisplay; + this.makeA11yAnnouncement(getKeyDisplay(keyOrIcon)); const rewrittenKeyEvent = e.detail.keyEvent; const pendingAccelerator = keyEventToAccelerator(rewrittenKeyEvent); if (this.hasError) {
diff --git a/ash/webui/shortcut_customization_ui/resources/js/shortcut_utils.ts b/ash/webui/shortcut_customization_ui/resources/js/shortcut_utils.ts index 60c57a6..80052ef 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/shortcut_utils.ts +++ b/ash/webui/shortcut_customization_ui/resources/js/shortcut_utils.ts
@@ -375,12 +375,12 @@ /** * * @param keyOrIcon the text for an individual accelerator key. - * @returns the associated icon name for the given `keyOrIcon` text if it + * @returns the associated icon label for the given `keyOrIcon` text if it * exists, otherwise returns `keyOrIcon` itself. */ export const getKeyDisplay = (keyOrIcon: string): string => { const iconName = keyToIconNameMap[keyOrIcon]; - return iconName ? iconName : keyOrIcon; + return iconName ? loadTimeData.getString(`iconLabel${keyOrIcon}`) : keyOrIcon; }; /**
diff --git a/ash/wm/lock_state_controller.cc b/ash/wm/lock_state_controller.cc index 0bfcf6e..7e774c1 100644 --- a/ash/wm/lock_state_controller.cc +++ b/ash/wm/lock_state_controller.cc
@@ -9,6 +9,7 @@ #include <utility> #include "ash/accessibility/accessibility_controller.h" +#include "ash/app_list/app_list_controller_impl.h" #include "ash/cancel_mode.h" #include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" @@ -23,6 +24,7 @@ #include "ash/wallpaper/views/wallpaper_widget_controller.h" #include "ash/wallpaper/wallpaper_controller_impl.h" #include "ash/wm/desks/desks_util.h" +#include "ash/wm/overview/overview_controller.h" #include "ash/wm/session_state_animator_impl.h" #include "ash/wm/window_restore/window_restore_util.h" #include "base/command_line.h" @@ -134,6 +136,23 @@ } } +// TODO(minch): Check whether the screenshot should be taken in kiosk mode or +// locked mode. +// Returns true if the pine screenshot should be taken on shutdown. +bool ShouldTakePineScreeshot(aura::Window* active_desk) { + auto* shell = Shell::Get(); + // Do not take the pine screenshot if it is in overview mode, lock screen or + // in the home launcher page. + if (shell->overview_controller()->InOverviewSession() || + shell->session_controller()->IsScreenLocked() || + shell->app_list_controller()->IsHomeScreenVisible()) { + return false; + } + + // Do not take the pine screenshot if the active desk has no windows. + return !active_desk->children().empty(); +} + } // namespace // static @@ -703,10 +722,9 @@ CHECK(active_desk); const base::FilePath file_path = GetShutdownPineImagePath(); - if (active_desk->children().empty()) { - // If there are no windows in the desk container, taking the pine image will - // fail. Delete any existing pine image so on next startup no pine image - // preview will be shown. + if (!ShouldTakePineScreeshot(active_desk)) { + // Delete any existing pine image if we should not take the screenshot on + // this shutdown, then no stale screenshot will be shown on next startup. auto delete_image_cb = base::BindOnce(base::IgnoreResult(&base::DeleteFile), file_path); MaybeAppendTestCallback(delete_image_cb, pine_image_callback_for_test_);
diff --git a/ash/wm/lock_state_controller_unittest.cc b/ash/wm/lock_state_controller_unittest.cc index cc5bdc62..070fc2a0 100644 --- a/ash/wm/lock_state_controller_unittest.cc +++ b/ash/wm/lock_state_controller_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "ash/app_list/app_list_controller_impl.h" #include "ash/constants/ash_pref_names.h" #include "ash/constants/ash_switches.h" #include "ash/public/cpp/shutdown_controller.h" @@ -24,6 +25,7 @@ #include "ash/wm/lock_state_controller_test_api.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/session_state_animator.h" +#include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h" #include "ash/wm/test/test_session_state_animator.h" #include "ash/wm/window_restore/window_restore_util.h" #include "base/barrier_closure.h" @@ -1051,6 +1053,7 @@ CHECK(temp_dir_.CreateUniqueTempDir()); file_path_ = temp_dir_.GetPath().AppendASCII("test_pine.png"); SetPineImagePathForTest(file_path_); + Initialize(ButtonType::NORMAL, LoginStatus::USER); } void TearDown() override { @@ -1069,7 +1072,6 @@ // Tests that a pine image is taken when there are windows open. TEST_F(LockStateControllerPineTest, ShutdownWithWindows) { - Initialize(ButtonType::NORMAL, LoginStatus::USER); std::unique_ptr<aura::Window> window = CreateTestWindow(); base::RunLoop run_loop; @@ -1097,8 +1099,6 @@ // Tests that no pine image is taken when there are no windows opened and the // existing pine image should be deleted. TEST_F(LockStateControllerPineTest, ShutdownWithoutWindows) { - Initialize(ButtonType::NORMAL, LoginStatus::USER); - // Create an empty file to simulate an old pine image. ASSERT_TRUE(base::WriteFile(file_path(), "")); @@ -1112,4 +1112,67 @@ EXPECT_FALSE(base::PathExists(file_path())); } +TEST_F(LockStateControllerPineTest, ShutdownInOverview) { + // Create an empty file to simulate an old pine image. + ASSERT_TRUE(base::WriteFile(file_path(), "")); + + // Create a window and enter the overview before requesting shutdown. + CreateTestWindow(); + EnterOverview(); + + base::RunLoop run_loop; + lock_state_test_api_->set_pine_image_callback(run_loop.QuitClosure()); + lock_state_controller_->RequestShutdown( + ShutdownReason::TRAY_SHUT_DOWN_BUTTON); + run_loop.Run(); + + // The pine image should not be taken if it is in overview when shutting down. + // The existing pine image should be deleted as well. + EXPECT_FALSE(base::PathExists(file_path())); +} + +TEST_F(LockStateControllerPineTest, ShutdownInLockScreen) { + // Create an empty file to simulate an old pine image. + ASSERT_TRUE(base::WriteFile(file_path(), "")); + + // Create a window and go the lock screen before requesting shutdown. + CreateTestWindowInShellWithId(0); + GetSessionControllerClient()->LockScreen(); + EXPECT_TRUE(Shell::Get()->session_controller()->IsScreenLocked()); + + base::RunLoop run_loop; + lock_state_test_api_->set_pine_image_callback(run_loop.QuitClosure()); + lock_state_controller_->RequestShutdown( + ShutdownReason::TRAY_SHUT_DOWN_BUTTON); + run_loop.Run(); + + // The pine image should not be taken if it is in the lock screen. The + // existing pine image should be deleted as well. + EXPECT_FALSE(base::PathExists(file_path())); +} + +TEST_F(LockStateControllerPineTest, ShutdownInHomeLauncher) { + // Create an empty file to simulate an old pine image. + ASSERT_TRUE(base::WriteFile(file_path(), "")); + + // Create a window and go to the home launcher page before requesting + // shutdown. + std::unique_ptr<aura::Window> window(CreateTestWindow()); + TabletModeControllerTestApi().EnterTabletMode(); + auto* app_list_controller = Shell::Get()->app_list_controller(); + app_list_controller->GoHome(GetPrimaryDisplay().id()); + ASSERT_TRUE(app_list_controller->IsHomeScreenVisible()); + EXPECT_TRUE(WindowState::Get(window.get())->IsMinimized()); + + base::RunLoop run_loop; + lock_state_test_api_->set_pine_image_callback(run_loop.QuitClosure()); + lock_state_controller_->RequestShutdown( + ShutdownReason::TRAY_SHUT_DOWN_BUTTON); + run_loop.Run(); + + // The pine image should not be taken if it is in the home launcher page when + // shutting down. The existing image should be deleted as well. + EXPECT_FALSE(base::PathExists(file_path())); +} + } // namespace ash
diff --git a/ash/wm/overview/overview_constants.h b/ash/wm/overview/overview_constants.h index 897c240..28ec7ca 100644 --- a/ash/wm/overview/overview_constants.h +++ b/ash/wm/overview/overview_constants.h
@@ -35,6 +35,9 @@ constexpr SystemShadow::Type kDraggedShadowType = SystemShadow::Type::kElevation24; +// Rounded corner radii applied on the wallpaper clip rect. +constexpr gfx::RoundedCornersF kWallpaperClipRoundedCornerRadii(20.f); + } // namespace ash #endif // ASH_WM_OVERVIEW_OVERVIEW_CONSTANTS_H_
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index 52556cc..e754d315 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -28,6 +28,8 @@ #include "ash/style/ash_color_id.h" #include "ash/style/typography.h" #include "ash/system/toast/toast_manager_impl.h" +#include "ash/wallpaper/views/wallpaper_view.h" +#include "ash/wallpaper/views/wallpaper_widget_controller.h" #include "ash/wallpaper/wallpaper_controller_impl.h" #include "ash/wm/desks/default_desk_button.h" #include "ash/wm/desks/desk_bar_view_base.h" @@ -88,12 +90,16 @@ #include "components/app_restore/full_restore_utils.h" #include "ui/aura/client/aura_constants.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/chromeos/styles/cros_tokens_color_mappings.h" #include "ui/compositor/compositor_observer.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animator.h" +#include "ui/compositor/layer_type.h" #include "ui/compositor/presentation_time_recorder.h" #include "ui/compositor/throughput_tracker.h" #include "ui/display/screen.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/rounded_corners_f.h" #include "ui/gfx/geometry/size_f.h" #include "ui/gfx/geometry/transform.h" #include "ui/gfx/geometry/transform_util.h" @@ -157,6 +163,10 @@ // visible. constexpr int kFeedbackGridMinHeight = 100; +// Vertical spacing between the desk bar widget's bottom edge and the clipped +// wallpaper's top edge. +const int kSpaceBetweenBottomOfDeskBarAndClipWallpaper = 16; + // The bottom padding applied to the bottom of the birch bar. constexpr int kBirchBarBottomPadding = 16; @@ -572,6 +582,7 @@ animator->RemoveObserver(this); } + RefreshClipWallpaper(); Shell::Get()->wallpaper_controller()->RemoveObserver(this); grid_event_handler_.reset(); @@ -643,6 +654,8 @@ MaybeInitBirchBarWidget(); + RefreshClipWallpaper(); + if (root_window_ == Shell::GetPrimaryRootWindow() && overview_session_->enter_exit_overview_type() == OverviewEnterExitType::kPine) { @@ -1047,6 +1060,7 @@ bounds_ = bounds_in_screen; MaybeUpdateDesksWidgetBounds(); MaybeUpdateBirchBarWidgetBounds(); + RefreshClipWallpaper(); PositionWindows(animate, ignored_items); if (bounds_updated && saved_desk_library_widget_) @@ -1091,6 +1105,61 @@ split_view_drag_indicators_->SetWindowDraggingState(window_dragging_state); } +void OverviewGrid::RefreshClipWallpaper() { + if (!features::IsForestFeatureEnabled()) { + return; + } + + WallpaperWidgetController* wallpaper_widget_controller = + RootWindowController::ForWindow(root_window_) + ->wallpaper_widget_controller(); + auto* wallpaper_view_layer = + wallpaper_widget_controller->wallpaper_view()->layer(); + auto* wallpaper_view_layer_parent = wallpaper_view_layer->parent(); + + // Reset the clip wallpaper visuals on overview session shutting down. + // TODO(http://b/327663425): Use scoped object to ensure wallpaper will be + // restored to its original state on overview exit. + if (overview_session_->is_shutting_down()) { + if (wallpaper_underlay_layer_) { + CHECK_EQ(wallpaper_underlay_layer_->parent(), + wallpaper_view_layer_parent); + wallpaper_view_layer_parent->Remove(wallpaper_underlay_layer_.get()); + wallpaper_underlay_layer_.reset(); + wallpaper_view_layer->SetClipRect(gfx::Rect()); + wallpaper_view_layer->SetBounds( + display::Screen::GetScreen() + ->GetDisplayNearestWindow(root_window_) + .bounds()); + wallpaper_view_layer->SetRoundedCornerRadius(gfx::RoundedCornersF()); + } + return; + } + + const gfx::Rect current_grid_bounds = GetGridBoundsInScreen(root_window_); + const gfx::Rect effective_grid_bounds = GetGridEffectiveBounds(); + if (wallpaper_underlay_layer_) { + wallpaper_underlay_layer_->SetBounds(current_grid_bounds); + wallpaper_view_layer->SetClipRect(effective_grid_bounds); + } else { + wallpaper_underlay_layer_ = + std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR); + wallpaper_underlay_layer_->SetBounds(current_grid_bounds); + // TODO(http://b/327663905): Implement on theme change for the + // `wallpaper_underlay_layer_`. + wallpaper_underlay_layer_->SetColor( + wallpaper_widget_controller->GetWidget()->GetColorProvider()->GetColor( + cros_tokens::kCrosSysSystemBase)); + wallpaper_view_layer->SetRoundedCornerRadius( + kWallpaperClipRoundedCornerRadii); + wallpaper_view_layer->SetClipRect(effective_grid_bounds); + wallpaper_view_layer_parent->Add(wallpaper_underlay_layer_.get()); + wallpaper_view_layer_parent->StackBelow(wallpaper_underlay_layer_.get(), + wallpaper_view_layer); + // TODO(http://b/327515857): Apply animation on the `wallpaper_view_layer`. + } +} + bool OverviewGrid::MaybeUpdateDesksWidgetBounds() { if (!desks_widget_) return false; @@ -1646,7 +1715,11 @@ // TODO(http://b/326087216): extend the expanded desk bar height by 16px for // Forest feature. - vertical_paddings.set_top(has_desk_bar ? GetDesksBarHeight() : 0); + const int desk_bar_padding_with_clip_wallpaper = + forest_enabled ? kSpaceBetweenBottomOfDeskBarAndClipWallpaper : 0; + vertical_paddings.set_top( + has_desk_bar ? GetDesksBarHeight() + desk_bar_padding_with_clip_wallpaper + : 0); // TODO(http://b/325963519): implement the paddings in tablet mode when the // design is finalized.
diff --git a/ash/wm/overview/overview_grid.h b/ash/wm/overview/overview_grid.h index d4a1e31..e6e56d8e 100644 --- a/ash/wm/overview/overview_grid.h +++ b/ash/wm/overview/overview_grid.h
@@ -202,6 +202,12 @@ void SetSplitViewDragIndicatorsWindowDraggingState( SplitViewDragIndicators::WindowDraggingState window_dragging_state); + // Clips wallpaper and adds `wallpaper_mask_layer_` upon overview entry. + // Updates the bounds of clip rect and `wallpaper_mask_layer_` when grid + // bounds change. Restores the wallpaper to its original state upon overview + // exit. + void RefreshClipWallpaper(); + // Updates the desks bar widget bounds if necessary. // Returns true if the desks widget's bounds have been updated. bool MaybeUpdateDesksWidgetBounds(); @@ -659,6 +665,9 @@ // if split view is unsupported (see |ShouldAllowSplitView|). std::unique_ptr<SplitViewDragIndicators> split_view_drag_indicators_; + // A solid-color layer stacked below the clipped wallpaper. + std::unique_ptr<ui::Layer> wallpaper_underlay_layer_; + // Widget that contains the DeskBarView contents when the Virtual Desks // feature is enabled. std::unique_ptr<views::Widget> desks_widget_;
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc index 1e3c057..1ad2dd6 100644 --- a/ash/wm/overview/overview_session_unittest.cc +++ b/ash/wm/overview/overview_session_unittest.cc
@@ -20,6 +20,7 @@ #include "ash/constants/app_types.h" #include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" +#include "ash/constants/ash_switches.h" #include "ash/display/screen_orientation_controller.h" #include "ash/display/screen_orientation_controller_test_api.h" #include "ash/frame_throttler/frame_throttling_controller.h" @@ -39,6 +40,8 @@ #include "ash/test/ash_test_base.h" #include "ash/test/raster_scale_change_tracker.h" #include "ash/test/test_window_builder.h" +#include "ash/wallpaper/views/wallpaper_view.h" +#include "ash/wallpaper/views/wallpaper_widget_controller.h" #include "ash/wm/desks/desk.h" #include "ash/wm/desks/desk_action_button.h" #include "ash/wm/desks/desk_action_view.h" @@ -86,6 +89,7 @@ #include "ash/wm/window_util.h" #include "ash/wm/wm_constants.h" #include "ash/wm/wm_event.h" +#include "ash/wm/wm_metrics.h" #include "ash/wm/workspace/workspace_window_resizer.h" #include "base/containers/contains.h" #include "base/containers/to_vector.h" @@ -121,6 +125,7 @@ #include "ui/events/gesture_detection/gesture_configuration.h" #include "ui/events/test/event_generator.h" #include "ui/gfx/geometry/point_conversions.h" +#include "ui/gfx/geometry/rounded_corners_f.h" #include "ui/gfx/geometry/transform.h" #include "ui/gfx/geometry/transform_util.h" #include "ui/gfx/geometry/vector2d.h" @@ -10745,4 +10750,130 @@ EXPECT_FALSE(SplitViewController::Get(root_windows[1])->InSplitViewMode()); } +// ----------------------------------------------------------------------------- +// OverviewWallpaperClipTest: + +// Test fixture to validate wallpaper clipping behavior during overview +// transitions. +class OverviewWallpaperClipTest : public OverviewTestBase { + public: + OverviewWallpaperClipTest() { + scoped_feature_list_.InitWithFeatures( + /*enabled_features=*/{features::kForestFeature, + features::kFasterSplitScreenSetup, + features::kOsSettingsRevampWayfinding}, + /*disabled_features=*/{}); + switches::SetIgnoreForestSecretKeyForTest(true); + } + OverviewWallpaperClipTest(const OverviewWallpaperClipTest&) = delete; + OverviewWallpaperClipTest& operator=(const OverviewWallpaperClipTest&) = + delete; + ~OverviewWallpaperClipTest() override { + switches::SetIgnoreForestSecretKeyForTest(false); + } + + void SnapOneTestWindow(aura::Window* window, + WindowStateType state_type, + float snap_ratio, + WindowSnapActionSource snap_action_source) { + WindowState* window_state = WindowState::Get(window); + const WindowSnapWMEvent snap_event( + state_type == WindowStateType::kPrimarySnapped + ? WM_EVENT_SNAP_PRIMARY + : WM_EVENT_SNAP_SECONDARY, + snap_ratio, snap_action_source); + window_state->OnWMEvent(&snap_event); + EXPECT_EQ(state_type, window_state->GetStateType()); + } + + gfx::Rect GetDisplayBoundsForRootWindow(aura::Window* root_window) { + return display::Screen::GetScreen() + ->GetDisplayNearestWindow(root_window) + .bounds(); + } + + ui::Layer* GetWallpaperViewLayer() { + return Shell::GetPrimaryRootWindowController() + ->wallpaper_widget_controller() + ->wallpaper_view() + ->layer(); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +// Tests that the wallpaper layer is correctly clipped with rounded corners +// during overview sessions, and fully restored upon exiting overview. +TEST_F(OverviewWallpaperClipTest, WallpaperClipRectAndRoundedCorners) { + const gfx::Rect display_bounds( + GetDisplayBoundsForRootWindow(Shell::GetPrimaryRootWindow())); + auto* wallpaper_view_layer = GetWallpaperViewLayer(); + // Ensure the wallpaper begins with its original dimensions (matching the + // active display) and has square corners. + EXPECT_EQ(display_bounds, wallpaper_view_layer->bounds()); + EXPECT_TRUE(wallpaper_view_layer->clip_rect().IsEmpty()); + EXPECT_TRUE(wallpaper_view_layer->rounded_corner_radii().IsEmpty()); + + // Enter overview mode and verify that the wallpaper is clipped with rounded + // corners. + ToggleOverview(); + OverviewGrid* overview_grid = GetOverviewSession()->grid_list()[0].get(); + EXPECT_EQ(overview_grid->GetGridEffectiveBounds(), + wallpaper_view_layer->clip_rect()); + EXPECT_EQ(kWallpaperClipRoundedCornerRadii, + wallpaper_view_layer->rounded_corner_radii()); + + // Exit overview. Check that the wallpaper has been fully restored.. + ToggleOverview(); + EXPECT_EQ(display_bounds, wallpaper_view_layer->bounds()); + EXPECT_TRUE(wallpaper_view_layer->clip_rect().IsEmpty()); + EXPECT_TRUE(wallpaper_view_layer->rounded_corner_radii().IsEmpty()); +} + +// Tests that the wallpaper is clipped in partial overview mode and adjusts +// correctly when the snapped window is resized. +TEST_F(OverviewWallpaperClipTest, PartialOverviewVisualsAndResize) { + const gfx::Rect display_bounds( + GetDisplayBoundsForRootWindow(Shell::GetPrimaryRootWindow())); + auto* wallpaper_view_layer = GetWallpaperViewLayer(); + std::unique_ptr<aura::Window> win1( + CreateAppWindow(gfx::Rect(10, 10, 100, 100))); + std::unique_ptr<aura::Window> win2( + CreateAppWindow(gfx::Rect(500, 10, 200, 200))); + // Check the wallpaper's original state before initiating partial overview. + EXPECT_EQ(display_bounds, wallpaper_view_layer->bounds()); + EXPECT_TRUE(wallpaper_view_layer->clip_rect().IsEmpty()); + EXPECT_TRUE(wallpaper_view_layer->rounded_corner_radii().IsEmpty()); + + // Snap one test window to start partial overview. + SnapOneTestWindow(win1.get(), chromeos::WindowStateType::kPrimarySnapped, + chromeos::kDefaultSnapRatio, + WindowSnapActionSource::kSnapByWindowLayoutMenu); + ASSERT_TRUE(IsInOverviewSession()); + OverviewGrid* overview_grid = GetOverviewSession()->grid_list()[0].get(); + // Verify that wallpaper is clipped properly with rounded corners applied in + // partial overview. + EXPECT_EQ(overview_grid->GetGridEffectiveBounds(), + wallpaper_view_layer->clip_rect()); + EXPECT_EQ(kWallpaperClipRoundedCornerRadii, + wallpaper_view_layer->rounded_corner_radii()); + + // Verify that the wallpaper's clip rect updates responsively when the snapped + // window is dragged in partial overview. + auto* event_generator = GetEventGenerator(); + const gfx::Point drag_starting_point = + win1.get()->GetBoundsInScreen().right_center(); + event_generator->set_current_screen_location(drag_starting_point); + event_generator->PressLeftButton(); + event_generator->MoveMouseBy(-10, 0); + ASSERT_TRUE(IsInOverviewSession()); + EXPECT_TRUE(WindowState::Get(win1.get())->is_dragged()); + EXPECT_EQ(overview_grid->GetGridEffectiveBounds(), + wallpaper_view_layer->clip_rect()); + EXPECT_EQ(kWallpaperClipRoundedCornerRadii, + wallpaper_view_layer->rounded_corner_radii()); + event_generator->ReleaseLeftButton(); +} + } // namespace ash
diff --git a/ash/wm/overview/overview_test_base.cc b/ash/wm/overview/overview_test_base.cc index 97876e8..a3fe3fd 100644 --- a/ash/wm/overview/overview_test_base.cc +++ b/ash/wm/overview/overview_test_base.cc
@@ -69,7 +69,7 @@ } OverviewController* OverviewTestBase::GetOverviewController() { - return Shell::Get()->overview_controller(); + return OverviewController::Get(); } OverviewSession* OverviewTestBase::GetOverviewSession() {
diff --git a/ash/wm/window_restore/pine_controller.cc b/ash/wm/window_restore/pine_controller.cc index cb4ad12..bb413e2 100644 --- a/ash/wm/window_restore/pine_controller.cc +++ b/ash/wm/window_restore/pine_controller.cc
@@ -128,8 +128,15 @@ LOG(WARNING) << "Forcing Birch data fetch"; Shell::Get()->birch_model()->RequestBirchDataFetch(base::BindOnce([]() { // Dump the items that were fetched. - auto items = Shell::Get()->birch_model()->GetAllItems(); - for (const auto& item : items) { + LOG(WARNING) << "All items:"; + auto all_items = Shell::Get()->birch_model()->GetAllItems(); + for (const auto& item : all_items) { + LOG(WARNING) << item->ToString(); + } + // Dump the items for display. + LOG(WARNING) << "Items for display:"; + auto display_items = Shell::Get()->birch_model()->GetItemsForDisplay(); + for (const auto& item : display_items) { LOG(WARNING) << item->ToString(); } }));
diff --git a/base/BUILD.gn b/base/BUILD.gn index 8ffd60e..c72848e7 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -3166,6 +3166,7 @@ "command_line_unittest.cc", "component_export_unittest.cc", "containers/adapters_unittest.cc", + "containers/buffer_iterator_unittest.cc", "containers/checked_iterators_unittest.cc", "containers/circular_deque_unittest.cc", "containers/contains_unittest.cc", @@ -3508,6 +3509,7 @@ "types/token_type_unittest.cc", "types/variant_util_unittest.cc", "unguessable_token_unittest.cc", + "unsafe_buffers_unittest.cc", "uuid_unittest.cc", "value_iterators_unittest.cc", "values_unittest.cc", @@ -3568,9 +3570,6 @@ "//third_party/icu", "//third_party/modp_b64", ] - if (is_clang) { - deps += [ ":base_unsafe_buffers_unittest_sources" ] - } data_deps = [ "//base/test:immediate_crash_test_helper", @@ -4167,26 +4166,9 @@ if (enable_nocompile_tests) { deps += [ ":base_nocompile_tests" ] - if (is_clang) { - deps += [ ":base_unsafe_buffers_nocompile_tests" ] - } } } -source_set("base_unsafe_buffers_unittest_sources") { - testonly = true - visibility = [ ":*" ] - configs += [ "//build/config/compiler:unsafe_buffer_warning" ] - sources = [ - "containers/buffer_iterator_unittest.cc", - "unsafe_buffers_unittest.cc", - ] - deps = [ - "//base", - "//testing/gtest", - ] -} - # Test that CFG is enabled in Rust code. if (is_win && toolchain_has_rust) { source_set("rust_cfg_win_test") { @@ -4218,6 +4200,7 @@ "allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_nocompile.nc", "allocator/partition_allocator/src/partition_alloc/pointers/raw_ref_nocompile.nc", "callback_list_nocompile.nc", + "containers/buffer_iterator_nocompile.nc", "containers/checked_iterators_nocompile.nc", "containers/contains_nocompile.nc", "containers/enum_set_nocompile.nc", @@ -4247,18 +4230,13 @@ "traits_bag_nocompile.nc", "types/pass_key_nocompile.nc", "types/variant_util_nocompile.nc", + "unsafe_buffers_nocompile.nc", "values_nocompile.nc", ] - deps = [ ":base" ] - } - - nocompile_source_set("base_unsafe_buffers_nocompile_tests") { - configs = [ "//build/config/compiler:unsafe_buffer_warning" ] - sources = [ - "containers/buffer_iterator_nocompile.nc", - "unsafe_buffers_nocompile.nc", + deps = [ + ":base", + "//build/config/clang:unsafe_buffers_buildflags", ] - deps = [ ":base" ] } }
diff --git a/base/compiler_specific.h b/base/compiler_specific.h index c7dd9ab..17ba104 100644 --- a/base/compiler_specific.h +++ b/base/compiler_specific.h
@@ -502,13 +502,6 @@ // explanation requires cooperation of code that is not fully encapsulated close // to the UNSAFE_BUFFERS() usage, it should be rejected and replaced with safer // coding patterns or stronger guarantees. -// -// UNSAFE_BUFFERS_INCLUDE_BEGIN / UNSAFE_BUFFERS_INCLUDE_END can be used to -// wrap an `#include` statement for a header which has not been made clean for -// the -Wunsafe-buffer-usage warning. As these disable warnings for the entire -// header, and its transitive dependencies, it's clear these should be temporary -// and the header converted to use safe operations via `span` (or use -// UNSAFE_BUFFERS() explicitly in rare cases). #if defined(__clang__) // clang-format off // Formatting is off so that we can put each _Pragma on its own line, as @@ -518,12 +511,8 @@ __VA_ARGS__ \ _Pragma("clang unsafe_buffer_usage end") // clang-format on -#define UNSAFE_BUFFERS_INCLUDE_BEGIN _Pragma("clang unsafe_buffer_usage begin") -#define UNSAFE_BUFFERS_INCLUDE_END _Pragma("clang unsafe_buffer_usage end") #else #define UNSAFE_BUFFERS(...) __VA_ARGS__ -#define UNSAFE_BUFFERS_INCLUDE_BEGIN -#define UNSAFE_BUFFERS_INCLUDE_END #endif #endif // BASE_COMPILER_SPECIFIC_H_
diff --git a/base/containers/span.h b/base/containers/span.h index 60bbb4c..b6d7967 100644 --- a/base/containers/span.h +++ b/base/containers/span.h
@@ -20,11 +20,7 @@ #include "base/check.h" #include "base/compiler_specific.h" -// TODO(crbug.com/40284755): checked_iterators should use UNSAFE_BUFFERS() -// internally. -UNSAFE_BUFFERS_INCLUDE_BEGIN #include "base/containers/checked_iterators.h" -UNSAFE_BUFFERS_INCLUDE_END #include "base/numerics/safe_conversions.h" #include "base/template_util.h" #include "base/types/to_address.h"
diff --git a/base/files/file_util_unittest.cc b/base/files/file_util_unittest.cc index ada4463..0f6076ff 100644 --- a/base/files/file_util_unittest.cc +++ b/base/files/file_util_unittest.cc
@@ -45,6 +45,7 @@ #include "base/threading/thread.h" #include "base/time/time.h" #include "base/uuid.h" +#include "build/branding_buildflags.h" #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/multiprocess_func_list.h" @@ -4485,7 +4486,20 @@ EXPECT_EQ(GetUniquePathNumber(some_file), -1); } -TEST_F(FileUtilTest, PreReadFile_ExistingFile_NoSize) { +#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) && \ + defined(ARCH_CPU_32_BITS) +// TODO(crbug.com/327582285): Re-enable these tests. They may be failing due to +// prefetching failing under memory pressure. +#define FLAKY_327582285 1 +#endif + +#if defined(FLAKY_327582285) +#define MAYBE_PreReadFileExistingFileNoSize \ + DISABLED_PreReadFileExistingFileNoSize +#else +#define MAYBE_PreReadFileExistingFileNoSize PreReadFileExistingFileNoSize +#endif +TEST_F(FileUtilTest, MAYBE_PreReadFileExistingFileNoSize) { FilePath text_file = temp_dir_.GetPath().Append(FPL("text_file")); CreateTextFile(text_file, bogus_content); @@ -4493,7 +4507,13 @@ PreReadFile(text_file, /*is_executable=*/false, /*sequential=*/false)); } -TEST_F(FileUtilTest, PreReadFile_ExistingFile_ExactSize) { +#if defined(FLAKY_327582285) +#define MAYBE_PreReadFileExistingFileExactSize \ + DISABLED_PreReadFileExistingFileExactSize +#else +#define MAYBE_PreReadFileExistingFileExactSize PreReadFileExistingFileExactSize +#endif +TEST_F(FileUtilTest, MAYBE_PreReadFileExistingFileExactSize) { FilePath text_file = temp_dir_.GetPath().Append(FPL("text_file")); CreateTextFile(text_file, bogus_content); @@ -4501,7 +4521,13 @@ /*sequential=*/false, std::size(bogus_content))); } -TEST_F(FileUtilTest, PreReadFile_ExistingFile_OverSized) { +#if defined(FLAKY_327582285) +#define MAYBE_PreReadFileExistingFileOverSized \ + DISABLED_PreReadFileExistingFileOverSized +#else +#define MAYBE_PreReadFileExistingFileOverSized PreReadFileExistingFileOverSized +#endif +TEST_F(FileUtilTest, MAYBE_PreReadFileExistingFileOverSized) { FilePath text_file = temp_dir_.GetPath().Append(FPL("text_file")); CreateTextFile(text_file, bogus_content); @@ -4509,7 +4535,14 @@ /*sequential=*/false, std::size(bogus_content) * 2)); } -TEST_F(FileUtilTest, PreReadFile_ExistingFile_UnderSized) { +#if defined(FLAKY_327582285) +#define MAYBE_PreReadFileExistingFileUnderSized \ + DISABLED_PreReadFileExistingFileUnderSized +#else +#define MAYBE_PreReadFileExistingFileUnderSized \ + PreReadFileExistingFileUnderSized +#endif +TEST_F(FileUtilTest, MAYBE_PreReadFileExistingFileUnderSized) { FilePath text_file = temp_dir_.GetPath().Append(FPL("text_file")); CreateTextFile(text_file, bogus_content); @@ -4517,7 +4550,7 @@ /*sequential=*/false, std::size(bogus_content) / 2)); } -TEST_F(FileUtilTest, PreReadFile_ExistingFile_ZeroSize) { +TEST_F(FileUtilTest, PreReadFileExistingFileZeroSize) { FilePath text_file = temp_dir_.GetPath().Append(FPL("text_file")); CreateTextFile(text_file, bogus_content); @@ -4525,7 +4558,7 @@ /*sequential=*/false, /*max_bytes=*/0)); } -TEST_F(FileUtilTest, PreReadFile_ExistingEmptyFile_NoSize) { +TEST_F(FileUtilTest, PreReadFileExistingEmptyFileNoSize) { FilePath text_file = temp_dir_.GetPath().Append(FPL("text_file")); CreateTextFile(text_file, L""); // The test just asserts that this doesn't crash. The Windows implementation @@ -4534,20 +4567,25 @@ PreReadFile(text_file, /*is_executable=*/false, /*sequential=*/false); } -TEST_F(FileUtilTest, PreReadFile_ExistingEmptyFile_ZeroSize) { +TEST_F(FileUtilTest, PreReadFileExistingEmptyFileZeroSize) { FilePath text_file = temp_dir_.GetPath().Append(FPL("text_file")); CreateTextFile(text_file, L""); EXPECT_TRUE(PreReadFile(text_file, /*is_executable=*/false, /*sequential=*/false, /*max_bytes=*/0)); } -TEST_F(FileUtilTest, PreReadFile_InexistentFile) { +TEST_F(FileUtilTest, PreReadFileInexistentFile) { FilePath inexistent_file = temp_dir_.GetPath().Append(FPL("inexistent_file")); EXPECT_FALSE(PreReadFile(inexistent_file, /*is_executable=*/false, /*sequential=*/false)); } -TEST_F(FileUtilTest, PreReadFile_Executable) { +#if defined(FLAKY_327582285) +#define MAYBE_PreReadFileExecutable DISABLED_PreReadFileExecutable +#else +#define MAYBE_PreReadFileExecutable PreReadFileExecutable +#endif +TEST_F(FileUtilTest, MAYBE_PreReadFileExecutable) { FilePath exe_data_dir; ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &exe_data_dir)); exe_data_dir = exe_data_dir.Append(FPL("pe_image_reader")); @@ -4561,7 +4599,13 @@ PreReadFile(test_exe, /*is_executable=*/true, /*sequential=*/false)); } -TEST_F(FileUtilTest, PreReadFileWithSequentialAccess) { +#if defined(FLAKY_327582285) +#define MAYBE_PreReadFileWithSequentialAccess \ + DISABLED_PreReadFileWithSequentialAccess +#else +#define MAYBE_PreReadFileWithSequentialAccess PreReadFileWithSequentialAccess +#endif +TEST_F(FileUtilTest, MAYBE_PreReadFileWithSequentialAccess) { FilePath text_file = temp_dir_.GetPath().Append(FPL("text_file")); CreateTextFile(text_file, bogus_content); @@ -4569,6 +4613,8 @@ PreReadFile(text_file, /*is_executable=*/false, /*sequential=*/true)); } +#undef FLAKY_327582285 + // Test that temp files obtained racily are all unique (no interference between // threads). Mimics file operations in DoLaunchChildTestProcess() to rule out // thread-safety issues @ https://crbug.com/826408#c17.
diff --git a/base/memory/raw_ptr.h b/base/memory/raw_ptr.h index 9bd2aba..0d81133 100644 --- a/base/memory/raw_ptr.h +++ b/base/memory/raw_ptr.h
@@ -7,12 +7,9 @@ #include "base/compiler_specific.h" -// TODO(crbug.com/40284755): raw_ptr should use UNSAFE_BUFFERS() internally. -UNSAFE_BUFFERS_INCLUDE_BEGIN // Although `raw_ptr` is part of the standalone PA distribution, it is // easier to use the shorter path in `//base/memory`. We retain this // facade header for ease of typing. #include "base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr.h" // IWYU pragma: export -UNSAFE_BUFFERS_INCLUDE_END #endif // BASE_MEMORY_RAW_PTR_H_
diff --git a/base/memory/raw_ref.h b/base/memory/raw_ref.h index 4faa6ed..3aa2798 100644 --- a/base/memory/raw_ref.h +++ b/base/memory/raw_ref.h
@@ -7,12 +7,9 @@ #include "base/compiler_specific.h" -// TODO(crbug.com/40284755): raw_ref should use UNSAFE_BUFFERS() internally. -UNSAFE_BUFFERS_INCLUDE_BEGIN // Although `raw_ref` is part of the standalone PA distribution, it is // easier to use the shorter path in `//base/memory`. We retain this // facade header for ease of typing. #include "base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ref.h" // IWYU pragma: export -UNSAFE_BUFFERS_INCLUDE_END #endif // BASE_MEMORY_RAW_REF_H_
diff --git a/base/unsafe_buffers_nocompile.nc b/base/unsafe_buffers_nocompile.nc index f0e245b..f58e025b 100644 --- a/base/unsafe_buffers_nocompile.nc +++ b/base/unsafe_buffers_nocompile.nc
@@ -6,6 +6,7 @@ // http://dev.chromium.org/developers/testing/no-compile-tests #include "base/compiler_specific.h" +#include "build/config/clang/unsafe_buffers_buildflags.h" namespace base { @@ -15,7 +16,11 @@ void CallToUnsafeBufferFunctionDisallowed() { int arr[] = {1, 2}; +#if BUILDFLAG(UNSAFE_BUFFERS_WARNING_ENABLED) uses_pointer_as_array(arr); // expected-error {{function introduces unsafe buffer manipulation}} +#else + uses_pointer_as_array(arr); // expected-no-diagnostics: No error when not enabled. +#endif } } // namespace base
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 2694fe99..223693d 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn
@@ -386,8 +386,9 @@ if (is_clang && !is_nacl) { default_compiler_configs += [ - "//build/config/clang:find_bad_constructs", "//build/config/clang:extra_warnings", + "//build/config/clang:find_bad_constructs", + "//build/config/clang:unsafe_buffers", ] } @@ -517,6 +518,29 @@ "visibility", ] +# Sets default dependencies for static_library and source_set targets. +foreach(_target_type, + [ + "static_library", + "source_set", + ]) { + template(_target_type) { + target(_target_type, target_name) { + forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) + forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) + if (!defined(inputs)) { + inputs = [] + } + + # Consumed by the unsafe-buffers plugin during compile. + # + # TODO(crbug.com/326584510): Reclient doesn't respect this variable, see + # rbe_bug_326584510_missing_inputs in //build/config/rbe.gni. + inputs += [ "//build/config/unsafe_buffers_paths.txt" ] + } + } +} + # Sets default dependencies for executable and shared_library targets. # # Variables @@ -538,6 +562,15 @@ "*", TESTONLY_AND_VISIBILITY + [ "no_default_deps" ]) forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) + if (!defined(inputs)) { + inputs = [] + } + + # Consumed by the unsafe-buffers plugin during compile. + # + # TODO(crbug.com/326584510): Reclient doesn't respect this variable, see + # rbe_bug_326584510_missing_inputs in //build/config/rbe.gni. + inputs += [ "//build/config/unsafe_buffers_paths.txt" ] if (!defined(deps)) { deps = [] }
diff --git a/build/config/clang/BUILD.gn b/build/config/clang/BUILD.gn index 6ff3521..e639905 100644 --- a/build/config/clang/BUILD.gn +++ b/build/config/clang/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/buildflag_header.gni") import("//build/config/rust.gni") import("clang.gni") @@ -84,6 +85,28 @@ } } +# A plugin for incrementally applying the -Wunsafe-buffer-usage warning. +config("unsafe_buffers") { + if (clang_use_chrome_plugins) { + cflags = [ + "-Xclang", + "-add-plugin", + "-Xclang", + "unsafe-buffers", + + "-Xclang", + "-plugin-arg-unsafe-buffers", + "-Xclang", + rebase_path("//build/config/unsafe_buffers_paths.txt", root_build_dir), + ] + } +} + +buildflag_header("unsafe_buffers_buildflags") { + header = "unsafe_buffers_buildflags.h" + flags = [ "UNSAFE_BUFFERS_WARNING_ENABLED=$clang_use_chrome_plugins" ] +} + # Enables some extra Clang-specific warnings. Some third-party code won't # compile with these so may want to remove this config. config("extra_warnings") {
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 62088a0..5312e68a 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1966,35 +1966,6 @@ } } -# unsafe_buffer_warning ------------------------------------------------------- - -# Paths of third-party headers that violate Wunsafe-buffer-usage, but which we -# have been unable to fix yet. We use this list to be able to make progress and -# enable the warning on code that we do control/own. -# -# WARNING: This will disable all warnings in the files. ONLY USE THIS for -# third-party code which we do not control/own. Fix the warnings instead in -# our own code. -if (is_clang) { - unsafe_buffer_warning_header_allowlist = - [ "third_party/googletest/src/googletest/include/gtest" ] -} - -# Enables warnings on pointer arithmetic/indexing or calls to functions -# annotated with `UNSAFE_BUFFER_USAGE`. -config("unsafe_buffer_warning") { - if (is_clang) { - cflags = [ "-Wunsafe-buffer-usage" ] - foreach(h, unsafe_buffer_warning_header_allowlist) { - if (is_win) { - cflags += [ "/clang:--system-header-prefix=$h" ] - } else { - cflags += [ "--system-header-prefix=$h" ] - } - } - } -} - # chromium_code --------------------------------------------------------------- # # Toggles between higher and lower warnings for code that is (or isn't)
diff --git a/build/config/unsafe_buffers_paths.txt b/build/config/unsafe_buffers_paths.txt new file mode 100644 index 0000000..329334a --- /dev/null +++ b/build/config/unsafe_buffers_paths.txt
@@ -0,0 +1,22 @@ +# Copyright 2024 The Chromium Project. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# The set of path prefixes that should be checked for unsafe buffer usage (see +# -Wunsafe-buffer-usage in Clang). +# +# *** +# Paths should be written as relative to the root of the source tree with +# unix-style path separators. Directory prefixes should end with `/`, such +# as `base/`. +# *** +# +# Files in this set are known to not use pointer arithmetic/subscripting, and +# make use of constructs like base::span or containers like std::vector instead. +# +# See `docs/unsafe_buffers.md`. + +base/containers/buffer_iterator_nocompile.nc +base/containers/span.h +base/unsafe_buffers_unittest.cc +base/unsafe_buffers_nocompile.nc
diff --git a/build/toolchain/apple/toolchain.gni b/build/toolchain/apple/toolchain.gni index 2d5ea81..2ad540c 100644 --- a/build/toolchain/apple/toolchain.gni +++ b/build/toolchain/apple/toolchain.gni
@@ -171,7 +171,7 @@ } # C/C++ (clang) rewrapper prefix to use when use_remoteexec is true. - compiler_prefix = "${rbe_bin_dir}/rewrapper -cfg=${toolchain_rbe_cc_cfg_file} -exec_root=${rbe_exec_root} " + compiler_prefix = "${rbe_bin_dir}/rewrapper -cfg=${toolchain_rbe_cc_cfg_file}${rbe_bug_326584510_missing_inputs} -exec_root=${rbe_exec_root} " } else if (toolchain_uses_goma) { assert(toolchain_cc_wrapper == "", "Goma and cc_wrapper can't be used together.")
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni index 94592ec..a74a4ffb 100644 --- a/build/toolchain/gcc_toolchain.gni +++ b/build/toolchain/gcc_toolchain.gni
@@ -214,7 +214,7 @@ } # C/C++ (clang) rewrapper prefix to use when use_remoteexec is true. - compiler_prefix = "${rbe_bin_dir}/rewrapper -cfg=${toolchain_rbe_cc_cfg_file} -exec_root=${rbe_exec_root} " + compiler_prefix = "${rbe_bin_dir}/rewrapper -cfg=${toolchain_rbe_cc_cfg_file}${rbe_bug_326584510_missing_inputs} -exec_root=${rbe_exec_root} " } else if (toolchain_uses_goma && (!defined(invoker.needs_gomacc_path_arg) || !invoker.needs_gomacc_path_arg)) {
diff --git a/build/toolchain/rbe.gni b/build/toolchain/rbe.gni index 7975b49..5652700 100644 --- a/build/toolchain/rbe.gni +++ b/build/toolchain/rbe.gni
@@ -1,3 +1,7 @@ +# Copyright 2024 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + # Defines the configuration of Remote Build Execution (RBE). declare_args() { @@ -73,3 +77,13 @@ use_remoteexec_links = false } } + +# TODO(crbug.com/326584510): Reclient does not upload `inputs` from C/C++ +# targets. This file is added to `inputs` for all C targets in +# //build/config/BUILDCONFIG.gn. We work around the bug in Reclient by +# specifying the file here. +# +# This is a comma-delimited list of paths relative to the source tree root. The +# leading space is important, if the string is non-empty. :) +rbe_bug_326584510_missing_inputs = + " -inputs=build/config/unsafe_buffers_paths.txt"
diff --git a/build/toolchain/win/toolchain.gni b/build/toolchain/win/toolchain.gni index 9a70191..de45c13e 100644 --- a/build/toolchain/win/toolchain.gni +++ b/build/toolchain/win/toolchain.gni
@@ -81,7 +81,7 @@ if (toolchain_uses_remoteexec) { if (toolchain_is_clang) { - cl_prefix = "${rbe_bin_dir}/rewrapper -cfg=${rbe_cc_cfg_file} -exec_root=${rbe_exec_root} -labels=type=compile,compiler=clang-cl,lang=cpp " + cl_prefix = "${rbe_bin_dir}/rewrapper -cfg=${rbe_cc_cfg_file}${rbe_bug_326584510_missing_inputs} -exec_root=${rbe_exec_root} -labels=type=compile,compiler=clang-cl,lang=cpp " } else { cl_prefix = "" }
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 4e81896a8..c12a671 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -993,8 +993,6 @@ // DrawResult::kSuccess if the frame should be drawn. DrawResult CalculateRenderPasses(FrameData* frame); - void StartScrollbarFadeRecursive(LayerImpl* layer); - // Once a resource is uploaded or deleted, it is no longer an evicted id, this // removes it from the evicted set, and updates if we're able to draw now that // all UIResources are valid.
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/SelectableTabListEditorTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/SelectableTabListEditorTest.java index 590d262..5ee841b 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/SelectableTabListEditorTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/SelectableTabListEditorTest.java
@@ -156,7 +156,7 @@ boolean isTabSwitcherReady = TestThreadUtils.runOnUiThreadBlockingNoException( () -> { - return cta.getTabSwitcherForTesting() != null; + return cta.getTabSwitcherSupplierForTesting().get() != null; }); if (!isTabSwitcherReady) { TabUiTestHelper.enterTabSwitcher(cta);
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherTabletTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherTabletTest.java index 955769c..e3cc076 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherTabletTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherTabletTest.java
@@ -8,17 +8,19 @@ import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.matcher.ViewMatchers.Visibility.GONE; import static androidx.test.espresso.matcher.ViewMatchers.Visibility.VISIBLE; +import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility; import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static androidx.test.espresso.matcher.ViewMatchers.withParent; import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import android.graphics.Bitmap; @@ -42,25 +44,24 @@ import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CriteriaHelper; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Features.DisableFeatures; -import org.chromium.base.test.util.Features.EnableFeatures; import org.chromium.base.test.util.RequiresRestart; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.compositor.layouts.Layout; -import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome; import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutHelperManager; import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutTab; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; -import org.chromium.chrome.browser.layouts.LayoutStateProvider; -import org.chromium.chrome.browser.layouts.LayoutStateProvider.LayoutStateObserver; +import org.chromium.chrome.browser.layouts.LayoutTestUtils; import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabLaunchType; +import org.chromium.chrome.browser.tabmodel.TabCreator; import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; -import org.chromium.chrome.features.start_surface.TabSwitcherAndStartSurfaceLayout; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.R; @@ -69,15 +70,14 @@ import org.chromium.chrome.test.util.TabStripUtils; import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; +import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.test.util.TestThreadUtils; -import org.chromium.ui.test.util.DisableAnimationsTestRule; import org.chromium.ui.test.util.UiRestriction; import java.lang.ref.WeakReference; import java.util.HashSet; import java.util.Set; import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** Tests for the {@link TabSwitcher} on tablet */ @@ -86,7 +86,7 @@ ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, "force-fieldtrials=Study/Group" }) -@DisableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION}) +@DisableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION, ChromeFeatureList.ANDROID_HUB}) @Restriction({ Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE, UiRestriction.RESTRICTION_TYPE_TABLET @@ -96,10 +96,6 @@ private static final long CALLBACK_WAIT_TIMEOUT = 15L; @ClassRule - public static DisableAnimationsTestRule sEnableAnimationsRule = - new DisableAnimationsTestRule(false); - - @ClassRule public static final ChromeTabbedActivityTestRule sActivityTestRule = new ChromeTabbedActivityTestRule(); @@ -107,102 +103,87 @@ public final BlankCTATabInitialStateRule mInitialStateRule = new BlankCTATabInitialStateRule(sActivityTestRule, false); - private CallbackHelper mLayoutChangedCallbackHelper = new CallbackHelper(); - private int mCurrentlyActiveLayout; - private Callback<LayoutManagerImpl> mLayoutManagerCallback; - private Set<WeakReference<Bitmap>> mAllBitmaps = new HashSet<>(); private TabSwitcher.TabListDelegate mTabListDelegate; @Before public void setUp() throws ExecutionException { - CriteriaHelper.pollUiThread( - sActivityTestRule.getActivity().getTabModelSelectorSupplier().get() - ::isTabStateInitialized); + ChromeTabbedActivity cta = sActivityTestRule.getActivity(); + CriteriaHelper.pollUiThread(cta.getTabModelSelectorSupplier().get()::isTabStateInitialized); - LayoutStateObserver mLayoutObserver = - new LayoutStateProvider.LayoutStateObserver() { - @Override - public void onFinishedHiding(int layoutType) { - mCurrentlyActiveLayout = layoutType; - mLayoutChangedCallbackHelper.notifyCalled(); - } - - @Override - public void onStartedShowing(int layoutType) { - if (layoutType != LayoutType.TAB_SWITCHER) { - return; - } - setupForThumbnailCheck(); - } - }; - mLayoutManagerCallback = (manager) -> manager.addObserver(mLayoutObserver); TestThreadUtils.runOnUiThreadBlocking( - () -> - sActivityTestRule - .getActivity() - .getLayoutManagerSupplier() - .addObserver(mLayoutManagerCallback)); + () -> { + cta.getTabSwitcherSupplierForTesting() + .onAvailable(this::setupForThumbnailCheck); + }); } @After public void cleanup() throws TimeoutException { - final ChromeTabbedActivity activity = sActivityTestRule.getActivity(); - TestThreadUtils.runOnUiThreadBlocking( - () -> { - activity.getLayoutManagerSupplier().removeObserver(mLayoutManagerCallback); - }); + ChromeTabbedActivity cta = sActivityTestRule.getActivity(); if (mTabListDelegate != null) mTabListDelegate.resetBitmapFetchCountForTesting(); + + LayoutManagerChrome layoutManager = cta.getLayoutManager(); + if (layoutManager.isLayoutVisible(LayoutType.TAB_SWITCHER) + && !layoutManager.isLayoutStartingToHide(LayoutType.TAB_SWITCHER)) { + TabModelSelector selector = cta.getTabModelSelectorSupplier().get(); + if (selector.getModel(false).getCount() == 0) { + TestThreadUtils.runOnUiThreadBlockingNoException( + () -> { + TabCreator tabCreator = cta.getTabCreator(/* incognito= */ false); + return tabCreator.createNewTab( + new LoadUrlParams("about:blank"), + TabLaunchType.FROM_CHROME_UI, + null, + 0); + }); + LayoutTestUtils.waitForLayout(layoutManager, LayoutType.BROWSING); + } else { + if (selector.getCurrentModel().isIncognito()) { + clickIncognitoToggleButton(); + } + exitSwitcherWithTabClick(0); + } + } else { + LayoutTestUtils.waitForLayout(layoutManager, LayoutType.BROWSING); + } } @Test @MediumTest @RequiresRestart - @DisabledTest(message = "https://crbug.com/327457591") public void testEnterAndExitTabSwitcher() throws TimeoutException { - Layout layout = sActivityTestRule.getActivity().getLayoutManager().getOverviewLayout(); - assertNull("StartSurface layout should not be initialized", layout); - ViewStub tabSwitcherStub = - (ViewStub) - sActivityTestRule - .getActivity() - .findViewById(R.id.tab_switcher_view_holder_stub); - assertTrue( - "TabSwitcher view stub should not be inflated", - tabSwitcherStub.getParent() != null); + ChromeTabbedActivity cta = sActivityTestRule.getActivity(); + checkTabSwitcherLayout(cta, false); + checkTabSwitcherViewHolderStub(cta, true); + checkTabSwitcherViewHolder(cta, false); TabUiTestHelper.prepareTabsWithThumbnail(sActivityTestRule, 1, 0, null); enterGTSWithThumbnailChecking(); - layout = sActivityTestRule.getActivity().getLayoutManager().getOverviewLayout(); - assertTrue( - "OverviewLayout should be TabSwitcherAndStartSurfaceLayout layout", - layout instanceof TabSwitcherAndStartSurfaceLayout); - ViewGroup tabSwitcherViewHolder = - sActivityTestRule.getActivity().findViewById(R.id.tab_switcher_view_holder); - assertNotNull("TabSwitcher view should be inflated", tabSwitcherViewHolder); + ensureTabSwitcherLayout(); + + checkTabSwitcherLayout(cta, true); + checkTabSwitcherViewHolderStub(cta, false); + checkTabSwitcherViewHolder(cta, true); exitGTSAndVerifyThumbnailsAreReleased(1); - assertFalse( - sActivityTestRule - .getActivity() - .getLayoutManager() - .isLayoutVisible(LayoutType.TAB_SWITCHER)); + assertFalse(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER)); } @Test @MediumTest public void testToggleIncognitoSwitcher() throws Exception { + ChromeTabbedActivity cta = sActivityTestRule.getActivity(); prepareTabs(1, 1); - TabUiTestHelper.enterTabSwitcher(sActivityTestRule.getActivity()); + TabUiTestHelper.enterTabSwitcher(cta); // Start with incognito switcher. - assertTrue( - "Expected to be in Incognito model", - sActivityTestRule.getActivity().getCurrentTabModel().isIncognito()); + assertTrue("Expected to be in Incognito model", cta.getCurrentTabModel().isIncognito()); + // Toggle to normal switcher. clickIncognitoToggleButton(); - final Tab newTab = sActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0); + final Tab newTab = cta.getCurrentTabModel().getTabAt(0); assertFalse(newTab.isIncognito()); exitSwitcherWithTabClick(0); @@ -211,20 +192,16 @@ @Test @MediumTest public void testTabSwitcherScrim() throws TimeoutException { + ChromeTabbedActivity cta = sActivityTestRule.getActivity(); prepareTabs(1, 1); - TabUiTestHelper.enterTabSwitcher(sActivityTestRule.getActivity()); + TabUiTestHelper.enterTabSwitcher(cta); ScrimCoordinator scrimCoordinator = - sActivityTestRule - .getActivity() - .getRootUiCoordinatorForTesting() - .getScrimCoordinator(); + cta.getRootUiCoordinatorForTesting().getScrimCoordinator(); assertTrue(scrimCoordinator.isShowingScrim()); assertEquals( - ChromeColors.getPrimaryBackgroundColor(sActivityTestRule.getActivity(), true), - sActivityTestRule - .getActivity() - .getRootUiCoordinatorForTesting() + ChromeColors.getPrimaryBackgroundColor(cta, true), + cta.getRootUiCoordinatorForTesting() .getStatusBarColorController() .getScrimColorForTesting()); @@ -234,13 +211,22 @@ @Test @MediumTest - public void testGridTabSwitcherOnNoNextTab() throws ExecutionException { + public void testGridTabSwitcherOnNoNextTab_WithoutRestart() throws ExecutionException { + ChromeTabbedActivity cta = sActivityTestRule.getActivity(); + ensureTabSwitcherLayout(); + + checkTabSwitcherLayout(cta, /* isInitialized= */ true); + checkTabSwitcherViewHolderStub(cta, /* exists= */ false); + checkTabSwitcherViewHolder(cta, /* exists= */ true); + // Assert the grid tab switcher is not yet showing. onView(withId(R.id.tab_switcher_view_holder)).check(matches(withEffectiveVisibility(GONE))); // Close the only tab through the tab strip. closeTab(false, sActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getId()); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.TAB_SWITCHER); + // Assert the grid tab switcher is shown automatically, since there is no next tab. onView(withId(R.id.tab_switcher_view_holder)) .check(matches(withEffectiveVisibility(VISIBLE))); @@ -248,14 +234,45 @@ @Test @MediumTest - public void testGridTabSwitcherOnCloseAllTabs() throws ExecutionException { + @RequiresRestart + public void testGridTabSwitcherOnNoNextTab_WithRestart() throws ExecutionException { + ChromeTabbedActivity cta = sActivityTestRule.getActivity(); + checkTabSwitcherLayout(cta, /* isInitialized= */ false); + checkTabSwitcherViewHolderStub(cta, /* exists= */ true); + checkTabSwitcherViewHolder(cta, /* exists= */ false); + + // Close the only tab through the tab strip. + closeTab(false, sActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getId()); + + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.TAB_SWITCHER); + + // Assert the grid tab switcher is shown automatically, since there is no next tab. + onView(withId(R.id.tab_switcher_view_holder)) + .check(matches(withEffectiveVisibility(VISIBLE))); + + checkTabSwitcherLayout(cta, /* isInitialized= */ true); + checkTabSwitcherViewHolderStub(cta, /* exists= */ false); + checkTabSwitcherViewHolder(cta, /* exists= */ true); + } + + @Test + @MediumTest + public void testGridTabSwitcherOnCloseAllTabs_WithoutRestart() throws ExecutionException { + ChromeTabbedActivity cta = sActivityTestRule.getActivity(); + ensureTabSwitcherLayout(); + + checkTabSwitcherLayout(cta, /* isInitialized= */ true); + checkTabSwitcherViewHolderStub(cta, /* exists= */ false); + checkTabSwitcherViewHolder(cta, /* exists= */ true); + // Assert the grid tab switcher is not yet showing. onView(withId(R.id.tab_switcher_view_holder)).check(matches(withEffectiveVisibility(GONE))); // Close all tabs. ChromeTabUtils.closeAllTabs( - InstrumentationRegistry.getInstrumentation(), - sActivityTestRule.getActivity().getTabModelSelectorSupplier()); + InstrumentationRegistry.getInstrumentation(), cta.getTabModelSelectorSupplier()); + + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.TAB_SWITCHER); // Assert the grid tab switcher is shown automatically, since there is no next tab. onView(withId(R.id.tab_switcher_view_holder)) @@ -265,162 +282,112 @@ @Test @MediumTest public void testGridTabSwitcherToggleIncognitoWithNoRegularTab() throws ExecutionException { + ChromeTabbedActivity cta = sActivityTestRule.getActivity(); + TabModel regularModel = cta.getTabModelSelectorSupplier().get().getModel(false); + + // Open an incognito tab. + prepareTabs(1, 1); + // Close all the regular tabs. TestThreadUtils.runOnUiThreadBlocking( () -> { - sActivityTestRule - .getActivity() - .getCurrentTabModel() - .closeTab(sActivityTestRule.getActivity().getActivityTab()); + regularModel.closeTab(regularModel.getTabAt(0)); }); - assertEquals( - "Expected to be 0 tabs in regular model", - 0, - sActivityTestRule - .getActivity() - .getTabModelSelectorSupplier() - .get() - .getModel(false) - .getCount()); - // Open an incognito tab. - prepareTabs(0, 1); - assertTrue( - "Expected to be in Incognito model", - sActivityTestRule.getActivity().getCurrentTabModel().isIncognito()); + assertEquals("Expected to be 0 tabs in regular model", 0, regularModel.getCount()); + assertTrue("Expected to be in Incognito model", cta.getCurrentTabModel().isIncognito()); + // Assert the grid tab switcher is not yet showing. onView(withId(R.id.tab_switcher_view_holder)).check(matches(withEffectiveVisibility(GONE))); + + TabUiTestHelper.enterTabSwitcher(cta); + // Toggle to normal switcher. clickIncognitoToggleButton(); - // Assert the grid tab switcher is shown automatically, since there is no regular tab. + onView(withId(R.id.tab_switcher_view_holder)) .check(matches(withEffectiveVisibility(VISIBLE))); } - @Test - @MediumTest - public void testGridTabSwitcher() throws ExecutionException { - prepareTabs(2, 0); - // Verifies that the dialog visibility supplier doesn't crash when closing a Tab without the - // grid tab switcher is inflated. - TestThreadUtils.runOnUiThreadBlocking( - () -> { - sActivityTestRule - .getActivity() - .getCurrentTabModel() - .closeTab(sActivityTestRule.getActivity().getActivityTab()); - }); - - Layout layout = - sActivityTestRule.getActivity().getLayoutManager().getTabSwitcherLayoutForTesting(); - assertNull("StartSurface layout should not be initialized", layout); - ViewStub tabSwitcherStub = - (ViewStub) - sActivityTestRule - .getActivity() - .findViewById(R.id.tab_switcher_view_holder_stub); - assertTrue( - "TabSwitcher view stub should not be inflated", - tabSwitcherStub.getParent() != null); - - // Click tab switcher button - TabUiTestHelper.enterTabSwitcher(sActivityTestRule.getActivity()); - - layout = - sActivityTestRule.getActivity().getLayoutManager().getTabSwitcherLayoutForTesting(); - assertTrue( - "OverviewLayout should be TabSwitcherAndStartSurfaceLayout layout", - layout instanceof TabSwitcherLayout); - ViewGroup tabSwitcherViewHolder = - sActivityTestRule.getActivity().findViewById(R.id.tab_switcher_view_holder); - assertNotNull("TabSwitcher view should be inflated", tabSwitcherViewHolder); - } - // Regression test for crbug.com/1487114. @Test @MediumTest - @EnableFeatures({ChromeFeatureList.DEFER_TAB_SWITCHER_LAYOUT_CREATION}) + @RequiresRestart public void testGridTabSwitcher_DeferredTabSwitcherLayoutCreation() throws ExecutionException { + ChromeTabbedActivity cta = sActivityTestRule.getActivity(); prepareTabs(2, 0); // Verifies that the dialog visibility supplier doesn't crash when closing a Tab without the // grid tab switcher is inflated. TestThreadUtils.runOnUiThreadBlocking( () -> { - sActivityTestRule - .getActivity() - .getCurrentTabModel() - .closeTab(sActivityTestRule.getActivity().getActivityTab()); + cta.getCurrentTabModel().closeTab(cta.getActivityTab()); }); - Layout layout = - sActivityTestRule.getActivity().getLayoutManager().getTabSwitcherLayoutForTesting(); - assertNull("StartSurface layout should not be initialized", layout); - ViewStub tabSwitcherStub = - (ViewStub) - sActivityTestRule - .getActivity() - .findViewById(R.id.tab_switcher_view_holder_stub); - assertTrue( - "TabSwitcher view stub should not be inflated", - tabSwitcherStub.getParent() != null); + checkTabSwitcherLayout(cta, /* isInitialized= */ false); + checkTabSwitcherViewHolderStub(cta, /* exists= */ true); + checkTabSwitcherViewHolder(cta, /* exists= */ false); // Click tab switcher button TabUiTestHelper.enterTabSwitcher(sActivityTestRule.getActivity()); - layout = - sActivityTestRule.getActivity().getLayoutManager().getTabSwitcherLayoutForTesting(); - assertTrue( - "OverviewLayout should be TabSwitcherAndStartSurfaceLayout layout", - layout instanceof TabSwitcherLayout); - ViewGroup tabSwitcherViewHolder = - sActivityTestRule.getActivity().findViewById(R.id.tab_switcher_view_holder); - assertNotNull("TabSwitcher view should be inflated", tabSwitcherViewHolder); + checkTabSwitcherLayout(cta, /* isInitialized= */ true); + checkTabSwitcherViewHolderStub(cta, /* exists= */ false); + checkTabSwitcherViewHolder(cta, /* exists= */ true); } @Test @MediumTest public void testEmptyStateView() throws Exception { + ChromeTabbedActivity cta = sActivityTestRule.getActivity(); prepareTabs(1, 0); - TabUiTestHelper.enterTabSwitcher(sActivityTestRule.getActivity()); + TabUiTestHelper.enterTabSwitcher(cta); // Close the last tab. - closeTab(false, sActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getId()); + closeTab(false, cta.getCurrentTabModel().getTabAt(0).getId()); + + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.TAB_SWITCHER); // Check whether empty view show up. onView( allOf( withId(R.id.empty_state_container), - withParent(withId(R.id.tab_switcher_view_holder)))) + isDescendantOfA(withId(R.id.tab_switcher_view_holder)))) .check(matches(isDisplayed())); } @Test @MediumTest public void testEmptyStateView_ToggleIncognito() throws Exception { + ChromeTabbedActivity cta = sActivityTestRule.getActivity(); prepareTabs(1, 1); TabUiTestHelper.enterTabSwitcher(sActivityTestRule.getActivity()); // Close the last normal tab. - closeTab(false, sActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getId()); - - // Switch to incognito tab switcher. - clickIncognitoToggleButton(); + TestThreadUtils.runOnUiThreadBlocking( + () -> { + TabModel model = cta.getTabModelSelector().getModel(false); + model.closeTab(model.getTabAt(0)); + }); // Check empty view should never show up in incognito tab switcher. onView( allOf( withId(R.id.empty_state_container), - withParent(withId(R.id.tab_switcher_view_holder)))) + isDescendantOfA(withId(R.id.tab_switcher_view_holder)))) .check(matches(not(isDisplayed()))); // Close the last incognito tab. - closeTab(true, sActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getId()); + TestThreadUtils.runOnUiThreadBlocking( + () -> { + TabModel model = cta.getTabModelSelector().getModel(true); + model.closeTab(model.getTabAt(0)); + }); // Incognito tab switcher should exit to go to normal tab switcher and we should see empty // view. onView( allOf( withId(R.id.empty_state_container), - withParent(withId(R.id.tab_switcher_view_holder)))) + isDescendantOfA(withId(R.id.tab_switcher_view_holder)))) .check(matches(isDisplayed())); } @@ -464,11 +431,12 @@ private void exitSwitcherWithTabClick(int index) throws TimeoutException { TabUiTestHelper.clickNthCardFromTabSwitcher(sActivityTestRule.getActivity(), index); - mLayoutChangedCallbackHelper.waitForCallback(1, 1, CALLBACK_WAIT_TIMEOUT, TimeUnit.SECONDS); - assertTrue(mCurrentlyActiveLayout == LayoutType.TAB_SWITCHER); + LayoutTestUtils.waitForLayout( + sActivityTestRule.getActivity().getLayoutManager(), LayoutType.BROWSING); } private void enterGTSWithThumbnailChecking() { + ChromeTabbedActivity cta = sActivityTestRule.getActivity(); Tab currentTab = sActivityTestRule.getActivity().getTabModelSelector().getCurrentTab(); // Native tabs need to be invalidated first to trigger thumbnail taking, so skip them. boolean checkThumbnail = !currentTab.isNativePage(); @@ -476,16 +444,12 @@ if (checkThumbnail) { TestThreadUtils.runOnUiThreadBlocking( () -> { - sActivityTestRule - .getActivity() - .getTabContentManager() - .removeTabThumbnail(currentTab.getId()); + cta.getTabContentManager().removeTabThumbnail(currentTab.getId()); }); } - TabUiTestHelper.enterTabSwitcher(sActivityTestRule.getActivity()); + TabUiTestHelper.enterTabSwitcher(cta); - TabUiTestHelper.verifyAllTabsHaveThumbnail( - sActivityTestRule.getActivity().getCurrentTabModel()); + TabUiTestHelper.verifyAllTabsHaveThumbnail(cta.getCurrentTabModel()); } private void closeTab(final boolean incognito, final int id) { @@ -503,35 +467,29 @@ }); } - private void retrieveTabListDelegate() { - Layout overviewLayout = - sActivityTestRule.getActivity().getLayoutManager().getOverviewLayout(); - - if (overviewLayout == null) { - Layout tabSwitcherLayout = - sActivityTestRule.getActivity().getLayoutManager().getTabSwitcherLayoutForTesting(); - assertTrue("Layout not instance of TabSwitcherLayout -" + tabSwitcherLayout, - tabSwitcherLayout instanceof TabSwitcherLayout); - mTabListDelegate = - ((TabSwitcherLayout) tabSwitcherLayout) - .getTabSwitcherForTesting() - .getTabListDelegate(); - return; + private TabSwitcherLayout ensureTabSwitcherLayout() { + LayoutManagerChrome layoutManager = sActivityTestRule.getActivity().getLayoutManager(); + Layout tabSwitcherLayout = layoutManager.getTabSwitcherLayoutForTesting(); + if (tabSwitcherLayout == null) { + TestThreadUtils.runOnUiThreadBlocking(layoutManager::initTabSwitcherLayoutForTesting); + tabSwitcherLayout = layoutManager.getTabSwitcherLayoutForTesting(); } - - assertTrue("Layout not instance of TabSwitcherAndStartSurfaceLayout" + overviewLayout, - overviewLayout instanceof TabSwitcherAndStartSurfaceLayout); - - mTabListDelegate = - ((TabSwitcherAndStartSurfaceLayout) overviewLayout) - .getStartSurfaceForTesting() - .getGridTabListDelegate(); + assertTrue( + "Layout not instance of TabSwitcherLayout -" + tabSwitcherLayout, + tabSwitcherLayout instanceof TabSwitcherLayout); + return (TabSwitcherLayout) tabSwitcherLayout; } - private void setupForThumbnailCheck() { - retrieveTabListDelegate(); + private void retrieveTabListDelegate() { + TabSwitcherLayout tabSwitcherLayout = ensureTabSwitcherLayout(); + mTabListDelegate = tabSwitcherLayout.getTabSwitcherForTesting().getTabListDelegate(); + } + + private void setupForThumbnailCheck(TabSwitcher tabSwitcher) { + mTabListDelegate = tabSwitcher.getTabListDelegate(); Callback<Bitmap> mBitmapListener = (bitmap) -> mAllBitmaps.add(new WeakReference<>(bitmap)); mTabListDelegate.setBitmapCallbackForTesting(mBitmapListener); + mTabListDelegate.resetBitmapFetchCountForTesting(); assertEquals(0, mTabListDelegate.getBitmapFetchCountForTesting()); } @@ -545,7 +503,7 @@ if (mTabListDelegate == null) retrieveTabListDelegate(); assertTrue(mTabListDelegate.getBitmapFetchCountForTesting() > 0); - assertEquals(tabsWithThumbnail, mAllBitmaps.size()); + assertThat(mAllBitmaps.size(), greaterThanOrEqualTo(tabsWithThumbnail)); final int index = sActivityTestRule.getActivity().getCurrentTabModel().index(); exitSwitcherWithTabClick(index); @@ -563,4 +521,35 @@ return true; }); } + + private void checkTabSwitcherLayout(ChromeTabbedActivity cta, boolean isInitialized) { + Layout layout = cta.getLayoutManager().getTabSwitcherLayoutForTesting(); + if (isInitialized) { + assertNotNull("TabSwitcherLayout should be initialized", layout); + } else { + assertNull("TabSwitcherLayout should not be initialized", layout); + } + } + + private void checkTabSwitcherViewHolderStub(ChromeTabbedActivity cta, boolean exists) { + ViewStub tabSwitcherStub = (ViewStub) cta.findViewById(R.id.tab_switcher_view_holder_stub); + if (exists) { + assertTrue( + "TabSwitcher view stub should not be inflated", + tabSwitcherStub != null && tabSwitcherStub.getParent() != null); + } else { + assertTrue( + "TabSwitcher view stub should have been inflated", + tabSwitcherStub == null || tabSwitcherStub.getParent() == null); + } + } + + private void checkTabSwitcherViewHolder(ChromeTabbedActivity cta, boolean exists) { + ViewGroup tabSwitcherViewHolder = cta.findViewById(R.id.tab_switcher_view_holder); + if (exists) { + assertNotNull("TabSwitcher view should be inflated", tabSwitcherViewHolder); + } else { + assertNull("TabSwitcher view should not be inflated", tabSwitcherViewHolder); + } + } }
diff --git a/chrome/android/features/tab_ui/public/BUILD.gn b/chrome/android/features/tab_ui/public/BUILD.gn index ec1b9f61..02feadfa 100644 --- a/chrome/android/features/tab_ui/public/BUILD.gn +++ b/chrome/android/features/tab_ui/public/BUILD.gn
@@ -31,6 +31,7 @@ deps = [ ":ui_java_resources", + "//base:base_java", "//chrome/browser/flags:java", "//chrome/browser/ui/android/theme:java", "//components/browser_ui/styles/android:java",
diff --git a/chrome/android/features/tab_ui/public/android/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeUtil.java b/chrome/android/features/tab_ui/public/android/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeUtil.java index d0fa0cc..60196df5 100644 --- a/chrome/android/features/tab_ui/public/android/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeUtil.java +++ b/chrome/android/features/tab_ui/public/android/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeUtil.java
@@ -7,9 +7,12 @@ import android.content.Context; import androidx.annotation.ColorInt; +import androidx.annotation.ColorRes; import androidx.annotation.DrawableRes; +import androidx.annotation.Px; import androidx.core.content.res.ResourcesCompat; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.ui.theme.ChromeSemanticColorUtils; import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.ui.util.ColorUtils; @@ -26,19 +29,42 @@ * * @param context {@link Context} used to retrieve color. * @param isIncognito Whether the color is used for incognito mode. - * @return The {@link ColorInt} for tab strip redesign background. + * @param isActivityFocused Whether the activity containing the tab strip is focused. + * @return The {@link ColorInt} for the tab strip background. */ - public static @ColorInt int getTabStripBackgroundColor(Context context, boolean isIncognito) { - // Use black color for incognito and night mode for folio. + public static @ColorInt int getTabStripBackgroundColor( + Context context, boolean isIncognito, boolean isActivityFocused) { + // Default specs for incognito, dark and light themes, used when + // TAB_STRIP_LAYOUT_OPTIMIZATION is disabled or when the activity is focused when this + // feature is enabled. + @ColorRes int incognitoColor = R.color.default_bg_color_dark_elev_2_baseline; + @Px + float darkThemeElevation = + context.getResources().getDimensionPixelSize(R.dimen.default_elevation_2); + @Px + float lightThemeElevation = + context.getResources().getDimensionPixelSize(R.dimen.default_elevation_3); + + // Specs for when the activity containing the tab strip is not focused. + // TODO (crbug.com/326290073): Use another boolean to allow using the default spec even when + // the activity is not in focus, when this feature is enabled. + // TODO (crbug.com/326290073): Update this to use the helper method from + // TabUiFeatureUtilities. + if (ChromeFeatureList.sTabStripLayoutOptimization.isEnabled() && !isActivityFocused) { + incognitoColor = R.color.default_bg_color_dark_elev_1_baseline; + darkThemeElevation = + context.getResources().getDimensionPixelSize(R.dimen.default_elevation_1); + lightThemeElevation = + context.getResources().getDimensionPixelSize(R.dimen.default_elevation_2); + } + if (isIncognito) { - return context.getColor(R.color.default_bg_color_dark_elev_2_baseline); + return context.getColor(incognitoColor); } - if (ColorUtils.inNightMode(context)) { - return ChromeColors.getSurfaceColor(context, R.dimen.default_elevation_2); - } - - return ChromeColors.getSurfaceColor(context, R.dimen.default_elevation_3); + return ChromeColors.getSurfaceColor( + context, + ColorUtils.inNightMode(context) ? darkThemeElevation : lightThemeElevation); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index b1d5548..0a4c00b8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -3744,8 +3744,8 @@ return mStartSurfaceSupplier.get(); } - public TabSwitcher getTabSwitcherForTesting() { - return mTabSwitcherSupplier.get(); + public OneshotSupplier<TabSwitcher> getTabSwitcherSupplierForTesting() { + return mTabSwitcherSupplier; } private ComposedBrowserControlsVisibilityDelegate getAppBrowserControlsVisibilityDelegate() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java index 51746fb..402c071 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java
@@ -48,6 +48,7 @@ import org.chromium.chrome.browser.layouts.scene_layer.SceneOverlayLayer; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver; +import org.chromium.chrome.browser.lifecycle.TopResumedActivityChangedObserver; import org.chromium.chrome.browser.multiwindow.MultiInstanceManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab.LoadUrlResult; @@ -89,7 +90,10 @@ * all input and model events to the proper destination. */ public class StripLayoutHelperManager - implements SceneOverlay, PauseResumeWithNativeObserver, TabStripHeightObserver { + implements SceneOverlay, + PauseResumeWithNativeObserver, + TabStripHeightObserver, + TopResumedActivityChangedObserver { /** * POD type that contains the necessary tab model info on startup. Used in the startup flicker @@ -172,6 +176,8 @@ private final ViewStub mTabHoverCardViewStub; private float mModelSelectorWidth; + private boolean mIsTopResumedActivity; + // 3-dots menu button with tab strip end padding private float mStripEndPadding; private TabModelSelectorTabModelObserver mTabModelSelectorTabModelObserver; @@ -497,6 +503,10 @@ } } + // TODO (crbug.com/326290073): Update this to check the actual activity resumption state + // because it is technically possible for the current activity to lose the top resumed + // activity status before the StripLayoutHelperManager instance is instantiated. + mIsTopResumedActivity = true; onContextChanged(context); } @@ -741,6 +751,15 @@ return mStripTransitionScrimOpacity; } + @Override + public void onTopResumedActivityChanged(boolean isTopResumedActivity) { + // TODO (crbug.com/326290073): Update this to use the helper method from + // TabUiFeatureUtilities. + if (!ChromeFeatureList.sTabStripLayoutOptimization.isEnabled()) return; + mIsTopResumedActivity = isTopResumedActivity; + mUpdateHost.requestUpdate(); + } + private float getModelSelectorButtonWidthWithEndPadding() { return mModelSelectorWidth + mStripEndPadding; } @@ -1096,7 +1115,8 @@ } public @ColorInt int getBackgroundColor() { - return TabUiThemeUtil.getTabStripBackgroundColor(mContext, mIsIncognito); + return TabUiThemeUtil.getTabStripBackgroundColor( + mContext, mIsIncognito, mIsTopResumedActivity); } /** @@ -1204,4 +1224,8 @@ public TabDragSource getTabDragSourceForTesting() { return mTabDragSource; } + + public void setIsIncognitoForTesting(boolean isIncognito) { + mIsIncognito = isIncognito; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ActivityLifecycleDispatcherImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ActivityLifecycleDispatcherImpl.java index b1ccb087..87a9781 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/ActivityLifecycleDispatcherImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ActivityLifecycleDispatcherImpl.java
@@ -24,6 +24,7 @@ import org.chromium.chrome.browser.lifecycle.RecreateObserver; import org.chromium.chrome.browser.lifecycle.SaveInstanceStateObserver; import org.chromium.chrome.browser.lifecycle.StartStopWithNativeObserver; +import org.chromium.chrome.browser.lifecycle.TopResumedActivityChangedObserver; import org.chromium.chrome.browser.lifecycle.WindowFocusChangedObserver; /** @@ -51,6 +52,8 @@ private final ObserverList<RecreateObserver> mRecreateObservers = new ObserverList<>(); private final ObserverList<OnUserLeaveHintObserver> mOnUserLeaveHintObservers = new ObserverList<>(); + private final ObserverList<TopResumedActivityChangedObserver> + mTopResumedActivityChangedObservers = new ObserverList<>(); private final Activity mActivity; @@ -98,6 +101,10 @@ if (observer instanceof OnUserLeaveHintObserver) { mOnUserLeaveHintObservers.addObserver((OnUserLeaveHintObserver) observer); } + if (observer instanceof TopResumedActivityChangedObserver) { + mTopResumedActivityChangedObservers.addObserver( + (TopResumedActivityChangedObserver) observer); + } } @Override @@ -136,6 +143,10 @@ if (observer instanceof OnUserLeaveHintObserver) { mOnUserLeaveHintObservers.removeObserver((OnUserLeaveHintObserver) observer); } + if (observer instanceof TopResumedActivityChangedObserver) { + mTopResumedActivityChangedObservers.removeObserver( + (TopResumedActivityChangedObserver) observer); + } } @Override @@ -236,6 +247,7 @@ mConfigurationChangedListeners.clear(); mDestroyables.clear(); mRecreateObservers.clear(); + mTopResumedActivityChangedObservers.clear(); } void dispatchOnSaveInstanceState(Bundle outBundle) { @@ -273,4 +285,10 @@ observer.onUserLeaveHint(); } } + + void dispatchOnTopResumedActivityChanged(boolean isTopResumedActivity) { + for (TopResumedActivityChangedObserver observer : mTopResumedActivityChangedObservers) { + observer.onTopResumedActivityChanged(isTopResumedActivity); + } + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java index 061c25c..b9762a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java
@@ -776,6 +776,14 @@ Thread.dumpStack(); } + @CallSuper + @Override + public void onTopResumedActivityChanged(boolean isTopResumedActivity) { + super.onTopResumedActivityChanged(isTopResumedActivity); + + mLifecycleDispatcher.dispatchOnTopResumedActivityChanged(isTopResumedActivity); + } + /** * @return Whether the activity is running in tablet mode. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index d7c4376..1cba20d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -148,7 +148,6 @@ import org.chromium.chrome.browser.ui.appmenu.AppMenuCoordinator; import org.chromium.chrome.browser.ui.appmenu.AppMenuDelegate; import org.chromium.chrome.browser.ui.appmenu.MenuButtonDelegate; -import org.chromium.chrome.browser.ui.edge_to_edge.EdgeToEdgeController; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.browser.ui.native_page.NativePage; import org.chromium.chrome.browser.ui.system.StatusBarColorController; @@ -260,7 +259,6 @@ private final CompositorViewHolder mCompositorViewHolder; private final BrowserControlsSizer mBrowserControlsSizer; private final FullscreenManager mFullscreenManager; - private final ObservableSupplier<EdgeToEdgeController> mEdgeToEdgeControllerSupplier; private LocationBarFocusScrimHandler mLocationBarFocusHandler; private ComponentCallbacks mComponentCallbacks; private final LoadProgressCoordinator mProgressBarCoordinator; @@ -465,8 +463,6 @@ * @param activity The Android activity. * @param controlsSizer The {@link BrowserControlsSizer} for the activity. * @param fullscreenManager The {@link FullscreenManager} for the activity. - * @param edgeToEdgeControllerSupplier Supplies an {@link EdgeToEdgeController} needed for - * Bottom Controls Toolbar. * @param controlContainer The container of the toolbar. * @param compositorViewHolder Class that holds a {@link CompositorView}. * @param urlFocusChangedCallback The callback to be notified when the URL focus changes. @@ -518,7 +514,6 @@ AppCompatActivity activity, BrowserControlsSizer controlsSizer, FullscreenManager fullscreenManager, - ObservableSupplier<EdgeToEdgeController> edgeToEdgeControllerSupplier, ToolbarControlContainer controlContainer, CompositorViewHolder compositorViewHolder, Callback<Boolean> urlFocusChangedCallback, @@ -569,7 +564,6 @@ mCompositorViewHolder = compositorViewHolder; mBrowserControlsSizer = controlsSizer; mFullscreenManager = fullscreenManager; - mEdgeToEdgeControllerSupplier = edgeToEdgeControllerSupplier; mActionBarDelegate = new ViewShiftingActionBarDelegate( activity.getSupportActionBar(), @@ -1656,7 +1650,6 @@ mCompositorViewHolder.getResourceManager(), mBrowserControlsSizer, mFullscreenManager, - mEdgeToEdgeControllerSupplier, (ScrollingBottomViewResourceFrameLayout) root, mTabGroupUi, mTabObscuringHandler,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java index 83e1bc4..4b1698b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
@@ -1395,7 +1395,6 @@ mActivity, mBrowserControlsManager, mFullscreenManager, - mEdgeToEdgeControllerSupplier, toolbarContainer, mCompositorViewHolderSupplier.get(), urlFocusChangedCallback,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java index 7e946287..67f44970 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java
@@ -515,9 +515,15 @@ } if (mIsTablet) { + // When applicable, the status bar should use the focused activity tab strip color + // (default), and should not be affected by an activity focus change. + // TODO (crbug.com/326290073): Use another boolean to allow using the default color spec + // even when the activity is not in focus, to avoid any confusion stemming from why + // |isActivityFocused| is always true in this invocation here. return mTabStripHiddenOnTablet ? mToolbarColor - : TabUiThemeUtil.getTabStripBackgroundColor(mWindow.getContext(), mIsIncognito); + : TabUiThemeUtil.getTabStripBackgroundColor( + mWindow.getContext(), mIsIncognito, /* isActivityFocused= */ true); } // When Omnibox gains focus, we want to clear the status bar theme color.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java index ab46358..f2b44a4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
@@ -751,7 +751,8 @@ tabListMode = mActivityTestRule .getActivity() - .getTabSwitcherForTesting() + .getTabSwitcherSupplierForTesting() + .get() .getTabListDelegate() .getListModeForTesting(); } else {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java index 0c37a178..eee0d64b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java
@@ -503,7 +503,7 @@ () -> statusBarColorController.updateStatusBarColor()); assertEquals( "Wrong value returned for Tab Strip Redesign Folio.", - TabUiThemeUtil.getTabStripBackgroundColor(activity, false), + TabUiThemeUtil.getTabStripBackgroundColor(activity, false, true), activity.getWindow().getStatusBarColor()); } @@ -552,7 +552,7 @@ "Status bar color on tablet should use the tab strip transition scrim overlay" + " during a strip transition.", ColorUtils.getColorWithOverlay( - TabUiThemeUtil.getTabStripBackgroundColor(activity, false), + TabUiThemeUtil.getTabStripBackgroundColor(activity, false, true), toolbarColor, 0.5f), activity.getWindow().getStatusBarColor()); @@ -566,7 +566,7 @@ assertEquals( "Status bar color on tablet should match the tab strip background when the tab" + " strip is visible.", - TabUiThemeUtil.getTabStripBackgroundColor(activity, false), + TabUiThemeUtil.getTabStripBackgroundColor(activity, false, true), activity.getWindow().getStatusBarColor()); ToolbarFeatures.USE_TOOLBAR_BG_COLOR_FOR_STRIP_TRANSITION_SCRIM.setForTesting(false); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManagerTest.java index 20f21566..822f146 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManagerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManagerTest.java
@@ -182,11 +182,80 @@ } @Test - public void testGetBackgroundColor() { - mStripLayoutHelperManager.onContextChanged(mContext); + @DisableFeatures(ChromeFeatureList.TAB_STRIP_LAYOUT_OPTIMIZATION) + public void testGetBackgroundColor_ActivityFocusChange_TsloDisabled() { assertEquals( + "Initial strip background color is incorrect.", ChromeColors.getSurfaceColor(mContext, R.dimen.default_elevation_3), mStripLayoutHelperManager.getBackgroundColor()); + // Assume the current activity lost focus. + mStripLayoutHelperManager.onTopResumedActivityChanged(false); + assertEquals( + "Strip background color should not be updated when activity focus state changes", + ChromeColors.getSurfaceColor(mContext, R.dimen.default_elevation_3), + mStripLayoutHelperManager.getBackgroundColor()); + } + + @Test + @EnableFeatures(ChromeFeatureList.TAB_STRIP_LAYOUT_OPTIMIZATION) + public void testGetBackgroundColor_ActivityFocusChange_LightTheme() { + doTestBackgroundColorOnActivityFocusChange( + /* isNightMode= */ false, /* isIncognito= */ false); + } + + @Test + @Config(qualifiers = "night") + @EnableFeatures(ChromeFeatureList.TAB_STRIP_LAYOUT_OPTIMIZATION) + public void testGetBackgroundColor_ActivityFocusChange_DarkTheme() { + doTestBackgroundColorOnActivityFocusChange( + /* isNightMode= */ true, /* isIncognito= */ false); + } + + @Test + @EnableFeatures(ChromeFeatureList.TAB_STRIP_LAYOUT_OPTIMIZATION) + public void testGetBackgroundColor_ActivityFocusChange_Incognito() { + mStripLayoutHelperManager.setIsIncognitoForTesting(true); + doTestBackgroundColorOnActivityFocusChange( + /* isNightMode= */ false, /* isIncognito= */ true); + } + + private void doTestBackgroundColorOnActivityFocusChange( + boolean isNightMode, boolean isIncognito) { + @ColorInt + int focusedColor = + ChromeColors.getSurfaceColor( + mContext, + isNightMode ? R.dimen.default_elevation_2 : R.dimen.default_elevation_3); + @ColorInt + int unfocusedColor = + ChromeColors.getSurfaceColor( + mContext, + isNightMode ? R.dimen.default_elevation_1 : R.dimen.default_elevation_2); + + if (isIncognito) { + focusedColor = mContext.getColor(R.color.default_bg_color_dark_elev_2_baseline); + unfocusedColor = mContext.getColor(R.color.default_bg_color_dark_elev_1_baseline); + } + + // Initially use the default tab strip background. + assertEquals( + "Initial strip background color is incorrect.", + focusedColor, + mStripLayoutHelperManager.getBackgroundColor()); + // Assume the current activity lost focus. + mStripLayoutHelperManager.onTopResumedActivityChanged(false); + assertEquals( + "Strip background color should be updated when activity focus state changes to" + + " false.", + unfocusedColor, + mStripLayoutHelperManager.getBackgroundColor()); + // Assume the current activity gained focus. + mStripLayoutHelperManager.onTopResumedActivityChanged(true); + assertEquals( + "Strip background color should be updated when activity focus state changes to" + + " true.", + focusedColor, + mStripLayoutHelperManager.getBackgroundColor()); } @Test
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn index f8116214..be528e1 100644 --- a/chrome/app/vector_icons/BUILD.gn +++ b/chrome/app/vector_icons/BUILD.gn
@@ -161,6 +161,7 @@ "palette.icon", "paste_menu.icon", "payments/save_card_and_vcn_success_confirmation.icon", + "payments/save_card_and_vcn_success_confirmation_dark.icon", "performance.icon", "person_filled_padded_large.icon", "person_filled_padded_small.icon",
diff --git a/chrome/app/vector_icons/payments/save_card_and_vcn_success_confirmation.icon b/chrome/app/vector_icons/payments/save_card_and_vcn_success_confirmation.icon index aeb0a5b..b492619a 100644 --- a/chrome/app/vector_icons/payments/save_card_and_vcn_success_confirmation.icon +++ b/chrome/app/vector_icons/payments/save_card_and_vcn_success_confirmation.icon
@@ -2,93 +2,95 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 104, +CANVAS_DIMENSIONS, 103, PATH_COLOR_ARGB, 0xFF, 0x34, 0xA8, 0x53, -MOVE_TO, 48.9f, 35.38f, -R_CUBIC_TO, -12.15f, 0, -22.02f, 9.87f, -22.02f, 22.02f, -R_CUBIC_TO, 0, 12.15f, 9.86f, 22.02f, 22.02f, 22.02f, -R_CUBIC_TO, 12.15f, 0, 22.02f, -9.86f, 22.02f, -22.02f, -R_CUBIC_TO, 0, -12.15f, -9.86f, -22.02f, -22.02f, -22.02f, +MOVE_TO, 48.29f, 35.38f, +CUBIC_TO, 36.13f, 35.38f, 26.27f, 45.24f, 26.27f, 57.4f, +CUBIC_TO, 26.27f, 69.55f, 36.13f, 79.42f, 48.29f, 79.42f, +CUBIC_TO, 60.44f, 79.42f, 70.3f, 69.55f, 70.3f, 57.4f, +CUBIC_TO, 70.3f, 45.24f, 60.44f, 35.38f, 48.29f, 35.38f, CLOSE, -R_MOVE_TO, -4.4f, 33.03f, -LINE_TO, 35.69f, 59.6f, -R_LINE_TO, 3.08f, -3.08f, -R_LINE_TO, 5.73f, 5.72f, -R_LINE_TO, 14.53f, -14.53f, -R_LINE_TO, 3.08f, 3.08f, -R_LINE_TO, -17.61f, 17.61f, +MOVE_TO, 43.88f, 68.41f, +LINE_TO, 35.08f, 59.6f, +LINE_TO, 38.16f, 56.52f, +LINE_TO, 43.88f, 62.24f, +LINE_TO, 58.41f, 47.71f, +LINE_TO, 61.5f, 50.79f, +LINE_TO, 43.88f, 68.41f, CLOSE, NEW_PATH, PATH_COLOR_ARGB, 0xFF, 0x39, 0x82, 0xF8, -MOVE_TO, 77.15f, 34.11f, -R_CUBIC_TO, 2.01f, 0, 3.64f, -1.69f, 3.64f, -3.77f, -R_CUBIC_TO, 0, -2.08f, -1.63f, -3.77f, -3.64f, -3.77f, -R_CUBIC_TO, -2.01f, 0, -3.64f, 1.69f, -3.64f, 3.77f, -R_CUBIC_TO, 0, 2.08f, 1.63f, 3.77f, 3.65f, 3.77f, +MOVE_TO, 76.53f, 34.11f, +CUBIC_TO, 78.54f, 34.11f, 80.18f, 32.42f, 80.18f, 30.33f, +CUBIC_TO, 80.18f, 28.25f, 78.54f, 26.56f, 76.53f, 26.56f, +CUBIC_TO, 74.52f, 26.56f, 72.89f, 28.25f, 72.89f, 30.33f, +CUBIC_TO, 72.89f, 32.42f, 74.52f, 34.11f, 76.53f, 34.11f, CLOSE, NEW_PATH, PATH_COLOR_ARGB, 0xFF, 0xE8, 0xEA, 0xED, -MOVE_TO, 4.26f, 70.92f, -R_CUBIC_TO, 2.01f, 0, 3.64f, -1.69f, 3.64f, -3.77f, -R_CUBIC_TO, 0, -2.08f, -1.63f, -3.77f, -3.64f, -3.77f, -R_CUBIC_TO, -2.01f, 0, -3.64f, 1.69f, -3.64f, 3.77f, -R_CUBIC_TO, 0, 2.09f, 1.63f, 3.78f, 3.65f, 3.78f, +MOVE_TO, 3.64f, 70.92f, +CUBIC_TO, 5.66f, 70.92f, 7.29f, 69.23f, 7.29f, 67.15f, +CUBIC_TO, 7.29f, 65.06f, 5.66f, 63.37f, 3.64f, 63.37f, +CUBIC_TO, 1.63f, 63.37f, 0, 65.06f, 0, 67.15f, +CUBIC_TO, 0, 69.23f, 1.63f, 70.92f, 3.64f, 70.92f, CLOSE, NEW_PATH, PATH_COLOR_ARGB, 0xFF, 0x34, 0xA8, 0x53, -MOVE_TO, 93.13f, 83.11f, -R_CUBIC_TO, 1.43f, 0.46f, 2.22f, 2.04f, 1.78f, 3.52f, -R_CUBIC_TO, -0.45f, 1.48f, -1.97f, 2.3f, -3.4f, 1.84f, -R_LINE_TO, -5.17f, -1.68f, -R_CUBIC_TO, -1.43f, -0.46f, -2.22f, -2.04f, -1.78f, -3.52f, -R_CUBIC_TO, 0.45f, -1.48f, 1.97f, -2.3f, 3.4f, -1.84f, -R_LINE_TO, 5.18f, 1.68f, +MOVE_TO, 92.52f, 83.11f, +CUBIC_TO, 93.95f, 83.58f, 94.74f, 85.15f, 94.29f, 86.63f, +CUBIC_TO, 93.85f, 88.11f, 92.32f, 88.94f, 90.9f, 88.47f, +LINE_TO, 85.72f, 86.79f, +CUBIC_TO, 84.29f, 86.33f, 83.5f, 84.75f, 83.94f, 83.27f, +CUBIC_TO, 84.39f, 81.79f, 85.91f, 80.97f, 87.34f, 81.43f, +LINE_TO, 92.52f, 83.11f, CLOSE, NEW_PATH, PATH_COLOR_ARGB, 0xFF, 0xFB, 0xBC, 0x04, -MOVE_TO, 11.02f, 27.22f, -R_CUBIC_TO, -1.73f, -1.72f, -1.78f, -4.56f, -0.12f, -6.35f, -R_ARC_TO, 4.23f, 4.23f, 0, 0, 1, 6.13f, -0.12f, -R_LINE_TO, 6.25f, 6.23f, -R_CUBIC_TO, 1.73f, 1.72f, 1.78f, 4.56f, 0.12f, 6.35f, -R_ARC_TO, 4.23f, 4.23f, 0, 0, 1, -6.13f, 0.12f, -R_LINE_TO, -6.25f, -6.23f, +MOVE_TO, 10.4f, 27.22f, +CUBIC_TO, 8.67f, 25.5f, 8.62f, 22.66f, 10.28f, 20.87f, +CUBIC_TO, 11.94f, 19.08f, 14.68f, 19.03f, 16.41f, 20.75f, +LINE_TO, 22.66f, 26.98f, +CUBIC_TO, 24.38f, 28.7f, 24.44f, 31.54f, 22.78f, 33.33f, +CUBIC_TO, 21.12f, 35.12f, 18.37f, 35.17f, 16.65f, 33.45f, +LINE_TO, 10.4f, 27.22f, CLOSE, NEW_PATH, PATH_COLOR_ARGB, 0xFF, 0xEA, 0x43, 0x35, -MOVE_TO, 25.45f, 87.96f, -R_CUBIC_TO, 1.16f, -1.17f, 1.18f, -3.09f, 0.05f, -4.29f, -R_ARC_TO, 2.86f, 2.86f, 0, 0, 0, -4.14f, -0.05f, -R_LINE_TO, -4.19f, 4.23f, -R_CUBIC_TO, -1.16f, 1.17f, -1.18f, 3.09f, -0.05f, 4.29f, -R_ARC_TO, 2.86f, 2.86f, 0, 0, 0, 4.14f, 0.05f, -R_LINE_TO, 4.19f, -4.23f, +MOVE_TO, 24.84f, 87.96f, +CUBIC_TO, 25.99f, 86.79f, 26.02f, 84.88f, 24.89f, 83.68f, +CUBIC_TO, 23.76f, 82.48f, 21.91f, 82.45f, 20.75f, 83.62f, +LINE_TO, 16.56f, 87.86f, +CUBIC_TO, 15.4f, 89.02f, 15.37f, 90.94f, 16.5f, 92.14f, +CUBIC_TO, 17.63f, 93.34f, 19.48f, 93.37f, 20.64f, 92.2f, +LINE_TO, 24.84f, 87.96f, CLOSE, NEW_PATH, PATH_COLOR_ARGB, 0xFF, 0xFB, 0xBC, 0x04, -MOVE_TO, 93.7f, 55.07f, -R_CUBIC_TO, -1.77f, 0.93f, -3.93f, 0.2f, -4.83f, -1.63f, -R_CUBIC_TO, -0.9f, -1.83f, -0.19f, -4.07f, 1.58f, -5, -R_LINE_TO, 6.41f, -3.36f, -R_CUBIC_TO, 1.77f, -0.93f, 3.93f, -0.2f, 4.83f, 1.64f, -R_CUBIC_TO, 0.9f, 1.83f, 0.19f, 4.07f, -1.58f, 5, -R_LINE_TO, -6.41f, 3.36f, +MOVE_TO, 93.08f, 55.06f, +CUBIC_TO, 91.31f, 55.99f, 89.15f, 55.26f, 88.25f, 53.43f, +CUBIC_TO, 87.36f, 51.6f, 88.07f, 49.36f, 89.83f, 48.43f, +LINE_TO, 96.24f, 45.07f, +CUBIC_TO, 98.01f, 44.14f, 100.17f, 44.87f, 101.07f, 46.7f, +CUBIC_TO, 101.97f, 48.53f, 101.26f, 50.77f, 99.49f, 51.7f, +LINE_TO, 93.08f, 55.06f, CLOSE, NEW_PATH, PATH_COLOR_ARGB, 0xFF, 0xE8, 0xEA, 0xED, -MOVE_TO, 49.67f, 6.42f, -R_ARC_TO, 1, 1, 0, 0, 1, 1.5f, -0.87f, -R_LINE_TO, 11, 6.3f, -R_ARC_TO, 1, 1, 0, 0, 1, 0.01f, 1.73f, -R_LINE_TO, -10.95f, 6.38f, -R_ARC_TO, 1, 1, 0, 0, 1, -1.5f, -0.86f, -R_LINE_TO, -0.05f, -12.68f, +MOVE_TO, 49.06f, 6.42f, +CUBIC_TO, 49.05f, 5.65f, 49.89f, 5.17f, 50.55f, 5.55f, +LINE_TO, 61.56f, 11.85f, +CUBIC_TO, 62.22f, 12.23f, 62.23f, 13.19f, 61.56f, 13.58f, +LINE_TO, 50.61f, 19.96f, +CUBIC_TO, 49.94f, 20.35f, 49.11f, 19.87f, 49.11f, 19.1f, +LINE_TO, 49.06f, 6.42f, CLOSE, -MOVE_TO, 64.84f, 94.97f, -R_ARC_TO, 1, 1, 0, 0, 1, -1.5f, 0.87f, -R_LINE_TO, -6.88f, -3.97f, -R_ARC_TO, 1, 1, 0, 0, 1, 0, -1.73f, -R_LINE_TO, 6.88f, -3.97f, -R_ARC_TO, 1, 1, 0, 0, 1, 1.5f, 0.87f, -R_V_LINE_TO, 7.95f, +NEW_PATH, +PATH_COLOR_ARGB, 0xFF, 0xE8, 0xEA, 0xED, +MOVE_TO, 64.23f, 94.97f, +CUBIC_TO, 64.23f, 95.74f, 63.39f, 96.22f, 62.73f, 95.84f, +LINE_TO, 55.84f, 91.86f, +CUBIC_TO, 55.18f, 91.48f, 55.18f, 90.52f, 55.84f, 90.13f, +LINE_TO, 62.73f, 86.16f, +CUBIC_TO, 63.39f, 85.77f, 64.23f, 86.25f, 64.23f, 87.02f, +LINE_TO, 64.23f, 94.97f, CLOSE
diff --git a/chrome/app/vector_icons/payments/save_card_and_vcn_success_confirmation_dark.icon b/chrome/app/vector_icons/payments/save_card_and_vcn_success_confirmation_dark.icon new file mode 100644 index 0000000..1e68036d6 --- /dev/null +++ b/chrome/app/vector_icons/payments/save_card_and_vcn_success_confirmation_dark.icon
@@ -0,0 +1,96 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 103, +PATH_COLOR_ARGB, 0xFF, 0x81, 0xC9, 0x95, +MOVE_TO, 48.29f, 35.38f, +CUBIC_TO, 36.13f, 35.38f, 26.27f, 45.24f, 26.27f, 57.4f, +CUBIC_TO, 26.27f, 69.55f, 36.13f, 79.42f, 48.29f, 79.42f, +CUBIC_TO, 60.44f, 79.42f, 70.3f, 69.55f, 70.3f, 57.4f, +CUBIC_TO, 70.3f, 45.24f, 60.44f, 35.38f, 48.29f, 35.38f, +CLOSE, +MOVE_TO, 43.88f, 68.41f, +LINE_TO, 35.08f, 59.6f, +LINE_TO, 38.16f, 56.52f, +LINE_TO, 43.88f, 62.24f, +LINE_TO, 58.41f, 47.71f, +LINE_TO, 61.5f, 50.79f, +LINE_TO, 43.88f, 68.41f, +CLOSE, +NEW_PATH, +PATH_COLOR_ARGB, 0xFF, 0x8A, 0xB4, 0xF8, +MOVE_TO, 76.53f, 34.11f, +CUBIC_TO, 78.54f, 34.11f, 80.18f, 32.42f, 80.18f, 30.33f, +CUBIC_TO, 80.18f, 28.25f, 78.54f, 26.56f, 76.53f, 26.56f, +CUBIC_TO, 74.52f, 26.56f, 72.89f, 28.25f, 72.89f, 30.33f, +CUBIC_TO, 72.89f, 32.42f, 74.52f, 34.11f, 76.53f, 34.11f, +CLOSE, +NEW_PATH, +PATH_COLOR_ARGB, 0xFF, 0x5F, 0x63, 0x68, +MOVE_TO, 3.64f, 70.92f, +CUBIC_TO, 5.66f, 70.92f, 7.29f, 69.23f, 7.29f, 67.15f, +CUBIC_TO, 7.29f, 65.06f, 5.66f, 63.37f, 3.64f, 63.37f, +CUBIC_TO, 1.63f, 63.37f, 0, 65.06f, 0, 67.15f, +CUBIC_TO, 0, 69.23f, 1.63f, 70.92f, 3.64f, 70.92f, +CLOSE, +NEW_PATH, +PATH_COLOR_ARGB, 0xFF, 0x81, 0xC9, 0x95, +MOVE_TO, 92.52f, 83.11f, +CUBIC_TO, 93.95f, 83.58f, 94.74f, 85.15f, 94.29f, 86.63f, +CUBIC_TO, 93.85f, 88.11f, 92.32f, 88.94f, 90.9f, 88.47f, +LINE_TO, 85.72f, 86.79f, +CUBIC_TO, 84.29f, 86.33f, 83.5f, 84.75f, 83.94f, 83.27f, +CUBIC_TO, 84.39f, 81.79f, 85.91f, 80.97f, 87.34f, 81.43f, +LINE_TO, 92.52f, 83.11f, +CLOSE, +NEW_PATH, +PATH_COLOR_ARGB, 0xFF, 0xFD, 0xD6, 0x63, +MOVE_TO, 10.4f, 27.22f, +CUBIC_TO, 8.67f, 25.5f, 8.62f, 22.66f, 10.28f, 20.87f, +CUBIC_TO, 11.94f, 19.08f, 14.68f, 19.03f, 16.41f, 20.75f, +LINE_TO, 22.66f, 26.98f, +CUBIC_TO, 24.38f, 28.7f, 24.44f, 31.54f, 22.78f, 33.33f, +CUBIC_TO, 21.12f, 35.12f, 18.37f, 35.17f, 16.65f, 33.45f, +LINE_TO, 10.4f, 27.22f, +CLOSE, +NEW_PATH, +PATH_COLOR_ARGB, 0xFF, 0xF2, 0x8B, 0x82, +MOVE_TO, 24.84f, 87.96f, +CUBIC_TO, 25.99f, 86.79f, 26.02f, 84.88f, 24.89f, 83.68f, +CUBIC_TO, 23.76f, 82.48f, 21.91f, 82.45f, 20.75f, 83.62f, +LINE_TO, 16.56f, 87.86f, +CUBIC_TO, 15.4f, 89.02f, 15.37f, 90.94f, 16.5f, 92.14f, +CUBIC_TO, 17.63f, 93.34f, 19.48f, 93.37f, 20.64f, 92.2f, +LINE_TO, 24.84f, 87.96f, +CLOSE, +NEW_PATH, +PATH_COLOR_ARGB, 0xFF, 0xFD, 0xD6, 0x63, +MOVE_TO, 93.08f, 55.06f, +CUBIC_TO, 91.31f, 55.99f, 89.15f, 55.26f, 88.25f, 53.43f, +CUBIC_TO, 87.36f, 51.6f, 88.07f, 49.36f, 89.83f, 48.43f, +LINE_TO, 96.24f, 45.07f, +CUBIC_TO, 98.01f, 44.14f, 100.17f, 44.87f, 101.07f, 46.7f, +CUBIC_TO, 101.97f, 48.53f, 101.26f, 50.77f, 99.49f, 51.7f, +LINE_TO, 93.08f, 55.06f, +CLOSE, +NEW_PATH, +PATH_COLOR_ARGB, 0xFF, 0x5F, 0x63, 0x68, +MOVE_TO, 49.06f, 6.42f, +CUBIC_TO, 49.05f, 5.65f, 49.89f, 5.17f, 50.55f, 5.55f, +LINE_TO, 61.56f, 11.85f, +CUBIC_TO, 62.22f, 12.23f, 62.23f, 13.19f, 61.56f, 13.58f, +LINE_TO, 50.61f, 19.96f, +CUBIC_TO, 49.94f, 20.35f, 49.11f, 19.87f, 49.11f, 19.1f, +LINE_TO, 49.06f, 6.42f, +CLOSE, +NEW_PATH, +PATH_COLOR_ARGB, 0xFF, 0x5F, 0x63, 0x68, +MOVE_TO, 64.23f, 94.97f, +CUBIC_TO, 64.23f, 95.74f, 63.39f, 96.22f, 62.73f, 95.84f, +LINE_TO, 55.84f, 91.86f, +CUBIC_TO, 55.18f, 91.48f, 55.18f, 90.52f, 55.84f, 90.13f, +LINE_TO, 62.73f, 86.16f, +CUBIC_TO, 63.39f, 85.77f, 64.23f, 86.25f, 64.23f, 87.02f, +LINE_TO, 64.23f, 94.97f, +CLOSE
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 9b8a614e..8d84b51 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -5808,8 +5808,8 @@ "policy/restricted_mgs_policy_provider.h", "policy/system_features_disable_list_policy_handler.cc", "policy/system_features_disable_list_policy_handler.h", - "renderer_context_menu/quick_answers_menu_observer.cc", - "renderer_context_menu/quick_answers_menu_observer.h", + "renderer_context_menu/read_write_card_observer.cc", + "renderer_context_menu/read_write_card_observer.h", "speech/tts_crosapi_util.cc", "speech/tts_crosapi_util.h", "usb/usb_pinned_notification.cc",
diff --git a/chrome/browser/android/lifecycle/BUILD.gn b/chrome/browser/android/lifecycle/BUILD.gn index f13cce7..3370908f 100644 --- a/chrome/browser/android/lifecycle/BUILD.gn +++ b/chrome/browser/android/lifecycle/BUILD.gn
@@ -20,6 +20,7 @@ "java/src/org/chromium/chrome/browser/lifecycle/RecreateObserver.java", "java/src/org/chromium/chrome/browser/lifecycle/SaveInstanceStateObserver.java", "java/src/org/chromium/chrome/browser/lifecycle/StartStopWithNativeObserver.java", + "java/src/org/chromium/chrome/browser/lifecycle/TopResumedActivityChangedObserver.java", "java/src/org/chromium/chrome/browser/lifecycle/WindowFocusChangedObserver.java", ] }
diff --git a/chrome/browser/android/lifecycle/java/src/org/chromium/chrome/browser/lifecycle/TopResumedActivityChangedObserver.java b/chrome/browser/android/lifecycle/java/src/org/chromium/chrome/browser/lifecycle/TopResumedActivityChangedObserver.java new file mode 100644 index 0000000..ce98d32 --- /dev/null +++ b/chrome/browser/android/lifecycle/java/src/org/chromium/chrome/browser/lifecycle/TopResumedActivityChangedObserver.java
@@ -0,0 +1,19 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.lifecycle; + +import android.app.Activity; + +/** + * Implement this interface and register in {@link ActivityLifecycleDispatcher} to receive + * onTopResumedActivityChanged events. + */ +public interface TopResumedActivityChangedObserver extends LifecycleObserver { + /** + * Called when an activity gets or loses the top resumed position in the system. See {@link + * Activity#onTopResumedActivityChanged(boolean)}. + */ + void onTopResumedActivityChanged(boolean isTopResumedActivity); +}
diff --git a/chrome/browser/ash/app_list/search/ranking/removed_results_ranker.cc b/chrome/browser/ash/app_list/search/ranking/removed_results_ranker.cc index e47a270a..1aef969 100644 --- a/chrome/browser/ash/app_list/search/ranking/removed_results_ranker.cc +++ b/chrome/browser/ash/app_list/search/ranking/removed_results_ranker.cc
@@ -30,8 +30,8 @@ DCHECK(profile_); DCHECK(proto_); - proto_->RegisterOnRead( - base::BindOnce(&RemovedResultsRanker::OnRemovedResultsProtoReady, + on_init_subscription_ = proto_->RegisterOnInit( + base::BindOnce(&RemovedResultsRanker::OnRemovedResultsProtoInit, weak_ptr_factory_.GetWeakPtr())); } @@ -77,8 +77,7 @@ } } -void RemovedResultsRanker::OnRemovedResultsProtoReady( - app_list::ReadStatus read_status) { +void RemovedResultsRanker::OnRemovedResultsProtoInit() { // Record `proto_` size in KB. base::UmaHistogramMemoryKB("Apps.AppList.RemovedResultsProto.SizeInKB", (*proto_)->ByteSizeLong() / 1000);
diff --git a/chrome/browser/ash/app_list/search/ranking/removed_results_ranker.h b/chrome/browser/ash/app_list/search/ranking/removed_results_ranker.h index ab355535..4a0d55e5 100644 --- a/chrome/browser/ash/app_list/search/ranking/removed_results_ranker.h +++ b/chrome/browser/ash/app_list/search/ranking/removed_results_ranker.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_ASH_APP_LIST_SEARCH_RANKING_REMOVED_RESULTS_RANKER_H_ #define CHROME_BROWSER_ASH_APP_LIST_SEARCH_RANKING_REMOVED_RESULTS_RANKER_H_ +#include "base/callback_list.h" #include "base/files/file_path.h" #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" @@ -43,9 +44,8 @@ private: friend class RemovedResultsRankerTest; - // Called when `proto_` finishes initialization. Note: `proto_` is initialized - // asyncly. - void OnRemovedResultsProtoReady(app_list::ReadStatus read_status); + // Called when `proto_` finishes init. Note: `proto_` is initialized asyncly. + void OnRemovedResultsProtoInit(); ash::FileSuggestKeyedService* GetFileSuggestKeyedService(); @@ -61,6 +61,8 @@ // should own a proto that contains only non-file result ids. const raw_ptr<PersistentProto<RemovedResultsProto>> proto_; + base::CallbackListSubscription on_init_subscription_; + base::WeakPtrFactory<RemovedResultsRanker> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/ash/app_list/search/util/ftrl_optimizer.cc b/chrome/browser/ash/app_list/search/util/ftrl_optimizer.cc index 64d04a2..2f43124 100644 --- a/chrome/browser/ash/app_list/search/util/ftrl_optimizer.cc +++ b/chrome/browser/ash/app_list/search/util/ftrl_optimizer.cc
@@ -7,6 +7,7 @@ #include <cmath> #include "base/files/file_path.h" +#include "base/functional/bind.h" #include "base/numerics/safe_conversions.h" namespace app_list { @@ -41,8 +42,10 @@ DCHECK_LE(params.gamma, 1.0); DCHECK_GT(params.num_experts, 0u); - proto_.RegisterOnRead( - base::BindOnce(&FtrlOptimizer::OnProtoRead, weak_factory_.GetWeakPtr())); + // `proto_` is a class member so it is safe to call `RegisterOnInitUnsafe()`. + proto_.RegisterOnInitUnsafe( + base::BindOnce(&FtrlOptimizer::OnProtoInit, base::Unretained(this))); + proto_.Init(); } @@ -132,7 +135,7 @@ return static_cast<double>(rank) / last_expert_scores_.size(); } -void FtrlOptimizer::OnProtoRead(ReadStatus status) { +void FtrlOptimizer::OnProtoInit() { if (!proto_->has_version() || proto_->version() != kVersion || params_.num_experts != base::checked_cast<size_t>(proto_->weights_size())) {
diff --git a/chrome/browser/ash/app_list/search/util/ftrl_optimizer.h b/chrome/browser/ash/app_list/search/util/ftrl_optimizer.h index c87614f..7c9f12a 100644 --- a/chrome/browser/ash/app_list/search/util/ftrl_optimizer.h +++ b/chrome/browser/ash/app_list/search/util/ftrl_optimizer.h
@@ -9,7 +9,6 @@ #include <vector> #include "base/files/file_path.h" -#include "base/memory/weak_ptr.h" #include "chrome/browser/ash/app_list/search/util/ftrl_optimizer.pb.h" #include "chrome/browser/ash/app_list/search/util/persistent_proto.h" @@ -82,7 +81,7 @@ private: double Loss(size_t expert, const std::string& item); - void OnProtoRead(ReadStatus status); + void OnProtoInit(); Params params_; @@ -92,8 +91,6 @@ std::map<std::string, std::vector<double>> last_expert_scores_; PersistentProto<FtrlOptimizerProto> proto_; - - base::WeakPtrFactory<FtrlOptimizer> weak_factory_{this}; }; } // namespace app_list
diff --git a/chrome/browser/ash/app_list/search/util/mrfu_cache.cc b/chrome/browser/ash/app_list/search/util/mrfu_cache.cc index 3b2006f8..e0e1d6b 100644 --- a/chrome/browser/ash/app_list/search/util/mrfu_cache.cc +++ b/chrome/browser/ash/app_list/search/util/mrfu_cache.cc
@@ -7,6 +7,7 @@ #include <cmath> #include "base/files/file_path.h" +#include "base/functional/bind.h" #include "base/logging.h" #include "base/numerics/safe_conversions.h" #include "base/time/time.h" @@ -74,8 +75,10 @@ MrfuCache::MrfuCache(MrfuCache::Proto proto, const Params& params) : proto_(std::move(proto)) { - proto_.RegisterOnRead( - base::BindOnce(&MrfuCache::OnProtoRead, weak_factory_.GetWeakPtr())); + // `proto_` is a class member so it is safe to call `RegisterOnInitUnsafe()`. + proto_.RegisterOnInitUnsafe( + base::BindOnce(&MrfuCache::OnProtoInit, base::Unretained(this))); + proto_.Init(); // See header comment for explanation. decay_coeff_ = exp(log(0.5f) / params.half_life); @@ -238,7 +241,7 @@ proto_.QueueWrite(); } -void MrfuCache::OnProtoRead(ReadStatus status) { +void MrfuCache::OnProtoInit() { if (!proto_->has_version() || proto_->version() != kVersion) { proto_.Purge(); }
diff --git a/chrome/browser/ash/app_list/search/util/mrfu_cache.h b/chrome/browser/ash/app_list/search/util/mrfu_cache.h index e10f80a0..18aba10 100644 --- a/chrome/browser/ash/app_list/search/util/mrfu_cache.h +++ b/chrome/browser/ash/app_list/search/util/mrfu_cache.h
@@ -8,7 +8,6 @@ #include <map> #include <string> -#include "base/memory/weak_ptr.h" #include "chrome/browser/ash/app_list/search/util/mrfu_cache.pb.h" #include "chrome/browser/ash/app_list/search/util/persistent_proto.h" @@ -143,7 +142,7 @@ void Decay(Score* score); void MaybeCleanup(); - void OnProtoRead(ReadStatus status); + void OnProtoInit(); PersistentProto<MrfuCacheProto> proto_; @@ -151,8 +150,6 @@ float boost_coeff_; size_t max_items_; float min_score_; - - base::WeakPtrFactory<MrfuCache> weak_factory_{this}; }; } // namespace app_list
diff --git a/chrome/browser/ash/app_list/search/util/persistent_proto.cc b/chrome/browser/ash/app_list/search/util/persistent_proto.cc new file mode 100644 index 0000000..d0340ba --- /dev/null +++ b/chrome/browser/ash/app_list/search/util/persistent_proto.cc
@@ -0,0 +1,25 @@ +// Copyright 2024 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/ash/app_list/search/util/persistent_proto.h" + +namespace app_list::internal { + +WriteStatus Write(const base::FilePath& filepath, std::string_view proto_str) { + if (const base::FilePath directory = filepath.DirName(); + !base::DirectoryExists(directory)) { + base::CreateDirectory(directory); + } + + base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, + base::BlockingType::MAY_BLOCK); + if (!base::ImportantFileWriter::WriteFileAtomically( + filepath, proto_str, "AppListPersistentProto")) { + return WriteStatus::kWriteError; + } + + return WriteStatus::kOk; +} + +} // namespace app_list::internal
diff --git a/chrome/browser/ash/app_list/search/util/persistent_proto.h b/chrome/browser/ash/app_list/search/util/persistent_proto.h index 8c2437f..d801c7a 100644 --- a/chrome/browser/ash/app_list/search/util/persistent_proto.h +++ b/chrome/browser/ash/app_list/search/util/persistent_proto.h
@@ -5,9 +5,16 @@ #ifndef CHROME_BROWSER_ASH_APP_LIST_SEARCH_UTIL_PERSISTENT_PROTO_H_ #define CHROME_BROWSER_ASH_APP_LIST_SEARCH_UTIL_PERSISTENT_PROTO_H_ +#include <memory> +#include <string> +#include <string_view> +#include <utility> + +#include "base/callback_list.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/important_file_writer.h" +#include "base/functional/bind.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/metrics/histogram_functions.h" @@ -20,6 +27,10 @@ namespace app_list { +namespace internal { + +// Data types ------------------------------------------------------------------ + // The result of reading a backing file from disk. These values persist to logs. // Entries should not be renumbered and numeric values should never be reused. enum class ReadStatus { @@ -42,7 +53,7 @@ kMaxValue = kSerializationError, }; -namespace { +// Helpers --------------------------------------------------------------------- template <class T> std::pair<ReadStatus, std::unique_ptr<T>> Read(const base::FilePath& filepath) { @@ -62,52 +73,40 @@ return {ReadStatus::kOk, std::move(proto)}; } -WriteStatus Write(const base::FilePath& filepath, - const std::string& proto_str) { - const auto directory = filepath.DirName(); - if (!base::DirectoryExists(directory)) - base::CreateDirectory(directory); +// Writes `proto_str` to the file specified by `filepath`. +WriteStatus Write(const base::FilePath& filepath, std::string_view proto_str); - bool write_result; - { - base::ScopedBlockingCall scoped_blocking_call( - FROM_HERE, base::BlockingType::MAY_BLOCK); - write_result = base::ImportantFileWriter::WriteFileAtomically( - filepath, proto_str, "AppListPersistentProto"); - } - - if (!write_result) - return WriteStatus::kWriteError; - return WriteStatus::kOk; -} - -} // namespace +} // namespace internal // PersistentProto wraps a proto class and persists it to disk. Usage summary: -// - Init is asynchronous, usage before |on_read| is called will crash. -// - pproto->Method() will call Method on the underlying proto. -// - Call QueueWrite() to write to disk. +// 1. Init is asynchronous. Using the object before initialization is complete +// will result in a crash. +// 2. pproto->Method() will call Method on the underlying proto. +// 3. Call `QueueWrite()` to write to disk. // -// Reading. The backing file is read asynchronously from disk once at -// initialization, and the |on_read| callback is run once this is done. Until -// |on_read| is called, has_value is false and get() will always return nullptr. -// If no proto file exists on disk, or it is invalid, a blank proto is -// constructed and immediately written to disk. +// Reading. The backing file is loaded asynchronously during initialization. +// Until initialization completed, `has_value()` will be false and `get()` will +// return `nullptr`. Register an init callback to be notified of completion. // // Writing. Writes must be triggered manually. Two methods are available: -// - QueueWrite() delays writing to disk for |write_delay| time, in order to +// 1. `QueueWrite()` delays writing to disk for `write_delay` time, in order to // batch successive writes. -// - StartWrite() writes to disk as soon as the task scheduler allows. -// The |on_write| callback is run each time a write has completed. +// 2. `StartWrite()` writes to disk as soon as the task scheduler allows. +// Registered write callbacks are executed whenever a write operation finishes. template <class T> class PersistentProto { public: - using ReadCallback = base::OnceCallback<void(ReadStatus)>; - using WriteCallback = base::RepeatingCallback<void(WriteStatus)>; + using InitCallback = base::OnceClosure; + using WriteCallback = base::RepeatingCallback<void(/*success=*/bool)>; PersistentProto(const base::FilePath& path, const base::TimeDelta write_delay) : path_(path), write_delay_(write_delay), + on_init_callbacks_( + std::make_unique<base::OnceCallbackList<InitCallback::RunType>>()), + on_write_callbacks_( + std::make_unique< + base::RepeatingCallbackList<WriteCallback::RunType>>()), task_runner_(base::ThreadPool::CreateSequencedTaskRunner( {base::TaskPriority::BEST_EFFORT, base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {} @@ -123,25 +122,33 @@ initialized_ = other.initialized_; write_is_queued_ = false; purge_after_reading_ = other.purge_after_reading_; - read_callbacks_ = std::move(other.read_callbacks_); - write_callbacks_ = std::move(other.write_callbacks_); + on_init_callbacks_ = std::move(other.on_init_callbacks_); + on_write_callbacks_ = std::move(other.on_write_callbacks_); task_runner_ = std::move(other.task_runner_); proto_ = std::move(other.proto_); } void Init() { task_runner_->PostTaskAndReplyWithResult( - FROM_HERE, base::BindOnce(&Read<T>, path_), + FROM_HERE, base::BindOnce(&internal::Read<T>, path_), base::BindOnce(&PersistentProto<T>::OnReadComplete, weak_factory_.GetWeakPtr())); } - void RegisterOnRead(ReadCallback on_read) { - read_callbacks_.push_back(std::move(on_read)); + [[nodiscard]] base::CallbackListSubscription RegisterOnInit( + InitCallback on_init) { + return on_init_callbacks_->Add(std::move(on_init)); } - void RegisterOnWrite(WriteCallback on_write) { - write_callbacks_.push_back(std::move(on_write)); + // NOTE: The caller must ensure `on_init` to be valid when init completes. + void RegisterOnInitUnsafe(InitCallback on_init) { + on_init_callbacks_->AddUnsafe(std::move(on_init)); + } + + // NOTE: The caller must ensure `on_write` to be valid during the life cycle + // of `PersistentProto`. + void RegisterOnWriteUnsafe(WriteCallback on_write) { + on_write_callbacks_->AddUnsafe(std::move(on_write)); } T* get() { return proto_.get(); } @@ -167,7 +174,7 @@ constexpr explicit operator bool() const { return has_value(); } - // Write the backing proto to disk after |save_delay_ms_| has elapsed. + // Write the backing proto to disk after `save_delay_ms_` has elapsed. void QueueWrite() { DCHECK(proto_); if (!proto_) @@ -197,13 +204,13 @@ // causing a crash. std::string proto_str; if (!proto_->SerializeToString(&proto_str)) - OnWriteComplete(WriteStatus::kSerializationError); + OnWriteComplete(internal::WriteStatus::kSerializationError); // The SequentialTaskRunner ensures the writes won't trip over each other, // so we can schedule without checking whether another write is currently // active. task_runner_->PostTaskAndReplyWithResult( - FROM_HERE, base::BindOnce(&Write, path_, proto_str), + FROM_HERE, base::BindOnce(&internal::Write, path_, proto_str), base::BindOnce(&PersistentProto<T>::OnWriteComplete, weak_factory_.GetWeakPtr())); } @@ -212,7 +219,7 @@ // the proto, because it ensures the proto is purged even if called before the // backing file is read from disk. In this case, the file is overwritten after // it has been read. In either case, the file is written as soon as possible, - // skipping the |save_delay_ms_| wait time. + // skipping the `save_delay_ms_` wait time. void Purge() { if (proto_) { proto_.reset(); @@ -224,10 +231,13 @@ } private: - void OnReadComplete(std::pair<ReadStatus, std::unique_ptr<T>> result) { + void OnReadComplete( + std::pair<internal::ReadStatus, std::unique_ptr<T>> result) { + const internal::ReadStatus status = result.first; base::UmaHistogramEnumeration("Apps.AppList.PersistentProto.ReadStatus", - result.first); - if (result.first == ReadStatus::kOk) { + status); + + if (status == internal::ReadStatus::kOk) { proto_ = std::move(result.second); } else { proto_ = std::make_unique<T>(); @@ -242,23 +252,19 @@ } initialized_ = true; - for (auto& cb : read_callbacks_) { - std::move(cb).Run(result.first); - } - read_callbacks_.clear(); + on_init_callbacks_->Notify(); } - void OnWriteComplete(const WriteStatus status) { + void OnWriteComplete(const internal::WriteStatus status) { base::UmaHistogramEnumeration("Apps.AppList.PersistentProto.WriteStatus", status); - for (auto& cb : write_callbacks_) { - cb.Run(status); - } + on_write_callbacks_->Notify(/*success=*/status == + internal::WriteStatus::kOk); } void OnQueueWrite() { // Reset the queued flag before posting the task. Last-moment updates to - // |proto_| will post another task to write the proto, avoiding race + // `proto_` will post another task to write the proto, avoiding race // conditions. write_is_queued_ = false; StartWrite(); @@ -270,8 +276,8 @@ // How long to delay writing to disk for on a call to QueueWrite. base::TimeDelta write_delay_; - // Whether the proto has finished reading from disk. |proto_| will be empty - // before |initialized_| is true. + // Whether the proto has finished reading from disk. `proto_` will be empty + // before `initialized_` is true. bool initialized_ = false; // Whether or not a write is currently scheduled. @@ -280,11 +286,13 @@ // Whether we should immediately clear the proto after reading it. bool purge_after_reading_ = false; - // Run when the cache finishes reading from disk. - std::vector<ReadCallback> read_callbacks_; + // Run when `proto_` finishes initialization. + std::unique_ptr<base::OnceCallbackList<InitCallback::RunType>> + on_init_callbacks_; // Run when the cache finishes writing to disk. - std::vector<WriteCallback> write_callbacks_; + std::unique_ptr<base::RepeatingCallbackList<WriteCallback::RunType>> + on_write_callbacks_; // The proto itself. std::unique_ptr<T> proto_;
diff --git a/chrome/browser/ash/app_list/search/util/persistent_proto_unittest.cc b/chrome/browser/ash/app_list/search/util/persistent_proto_unittest.cc index 420ef42..5df86769 100644 --- a/chrome/browser/ash/app_list/search/util/persistent_proto_unittest.cc +++ b/chrome/browser/ash/app_list/search/util/persistent_proto_unittest.cc
@@ -4,12 +4,12 @@ #include "chrome/browser/ash/app_list/search/util/persistent_proto.h" -#include <memory> #include <string> #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "base/time/time.h" #include "chrome/browser/ash/app_list/search/util/persistent_proto_test.pb.h" @@ -67,21 +67,18 @@ ASSERT_TRUE(base::WriteFile(GetPath(), proto.SerializeAsString())); } - void OnRead(const ReadStatus status) { - read_status_ = status; - ++read_count_; + void OnInit() { ++read_count_; } + + base::OnceClosure GetInitCallback() { + return base::BindOnce(&PersistentProtoTest::OnInit, base::Unretained(this)); } - base::OnceCallback<void(ReadStatus)> ReadCallback() { - return base::BindOnce(&PersistentProtoTest::OnRead, base::Unretained(this)); - } - - void OnWrite(const WriteStatus status) { - ASSERT_EQ(status, WriteStatus::kOk); + void OnWrite(bool success) { + ASSERT_TRUE(success); ++write_count_; } - base::RepeatingCallback<void(WriteStatus)> WriteCallback() { + base::RepeatingCallback<void(bool)> GetWriteCallback() { return base::BindRepeating(&PersistentProtoTest::OnWrite, base::Unretained(this)); } @@ -89,7 +86,6 @@ void Wait() { task_environment_.RunUntilIdle(); } // Records the information passed to the callbacks for later expectation. - ReadStatus read_status_; int read_count_ = 0; int write_count_ = 0; @@ -99,12 +95,12 @@ base::ScopedTempDir temp_dir_; }; -// Test that the underlying proto is nullptr until a read is complete, and isn't -// after that. +// Test that the underlying proto is nullptr until proto initialization +// completes, and isn't after that. TEST_F(PersistentProtoTest, Initialization) { PersistentProto<TestProto> pproto(GetPath(), WriteDelay()); - pproto.RegisterOnRead(ReadCallback()); - pproto.RegisterOnWrite(WriteCallback()); + pproto.RegisterOnInitUnsafe(GetInitCallback()); + pproto.RegisterOnWriteUnsafe(GetWriteCallback()); pproto.Init(); EXPECT_EQ(pproto.get(), nullptr); Wait(); @@ -114,8 +110,8 @@ // Test bool conversion and has_value. TEST_F(PersistentProtoTest, BoolTests) { PersistentProto<TestProto> pproto(GetPath(), WriteDelay()); - pproto.RegisterOnRead(ReadCallback()); - pproto.RegisterOnWrite(WriteCallback()); + pproto.RegisterOnInitUnsafe(GetInitCallback()); + pproto.RegisterOnWriteUnsafe(GetWriteCallback()); pproto.Init(); EXPECT_EQ(pproto.get(), nullptr); EXPECT_FALSE(pproto); @@ -129,8 +125,8 @@ // Test -> and *. TEST_F(PersistentProtoTest, Getters) { PersistentProto<TestProto> pproto(GetPath(), WriteDelay()); - pproto.RegisterOnRead(ReadCallback()); - pproto.RegisterOnWrite(WriteCallback()); + pproto.RegisterOnInitUnsafe(GetInitCallback()); + pproto.RegisterOnWriteUnsafe(GetWriteCallback()); pproto.Init(); Wait(); // We're really just checking these don't crash. @@ -143,15 +139,19 @@ // Test that the pproto correctly saves the in-memory proto to disk. TEST_F(PersistentProtoTest, Read) { + // Build a `PersistentProto` whose underlying file does not exist before init. PersistentProto<TestProto> pproto(GetPath(), WriteDelay()); - pproto.RegisterOnRead(ReadCallback()); - pproto.RegisterOnWrite(WriteCallback()); + pproto.RegisterOnInitUnsafe(GetInitCallback()); + pproto.RegisterOnWriteUnsafe(GetWriteCallback()); pproto.Init(); // Underlying proto should be nullptr until read is complete. EXPECT_EQ(pproto.get(), nullptr); + base::HistogramTester histogram_tester; Wait(); - EXPECT_EQ(read_status_, ReadStatus::kMissing); + histogram_tester.ExpectBucketCount("Apps.AppList.PersistentProto.ReadStatus", + internal::ReadStatus::kMissing, + /*expected_count=*/1); EXPECT_EQ(read_count_, 1); EXPECT_EQ(write_count_, 1); @@ -168,12 +168,17 @@ TEST_F(PersistentProtoTest, ReadInvalidProto) { ASSERT_TRUE(base::WriteFile(GetPath(), "this isn't a valid proto")); + // Build a `PersistentProto` with an invalid proto file. PersistentProto<TestProto> pproto(GetPath(), WriteDelay()); - pproto.RegisterOnRead(ReadCallback()); - pproto.RegisterOnWrite(WriteCallback()); + + pproto.RegisterOnInitUnsafe(GetInitCallback()); + pproto.RegisterOnWriteUnsafe(GetWriteCallback()); pproto.Init(); + base::HistogramTester histogram_tester; Wait(); - EXPECT_EQ(read_status_, ReadStatus::kParseError); + histogram_tester.ExpectBucketCount("Apps.AppList.PersistentProto.ReadStatus", + internal::ReadStatus::kParseError, + /*expected_count=*/1); EXPECT_EQ(read_count_, 1); EXPECT_EQ(write_count_, 1); } @@ -184,13 +189,16 @@ WriteToDisk(test_proto); PersistentProto<TestProto> pproto(GetPath(), WriteDelay()); - pproto.RegisterOnRead(ReadCallback()); - pproto.RegisterOnWrite(WriteCallback()); + pproto.RegisterOnInitUnsafe(GetInitCallback()); + pproto.RegisterOnWriteUnsafe(GetWriteCallback()); pproto.Init(); EXPECT_EQ(pproto.get(), nullptr); + base::HistogramTester histogram_tester; Wait(); - EXPECT_EQ(read_status_, ReadStatus::kOk); + histogram_tester.ExpectBucketCount("Apps.AppList.PersistentProto.ReadStatus", + internal::ReadStatus::kOk, + /*expected_count=*/1); EXPECT_EQ(read_count_, 1); EXPECT_EQ(write_count_, 0); EXPECT_NE(pproto.get(), nullptr); @@ -200,8 +208,8 @@ // Test that several saves all happen correctly. TEST_F(PersistentProtoTest, MultipleWrites) { PersistentProto<TestProto> pproto(GetPath(), WriteDelay()); - pproto.RegisterOnRead(ReadCallback()); - pproto.RegisterOnWrite(WriteCallback()); + pproto.RegisterOnInitUnsafe(GetInitCallback()); + pproto.RegisterOnWriteUnsafe(GetWriteCallback()); pproto.Init(); EXPECT_EQ(pproto.get(), nullptr); @@ -223,8 +231,8 @@ // write. TEST_F(PersistentProtoTest, QueueWrites) { PersistentProto<TestProto> pproto(GetPath(), WriteDelay()); - pproto.RegisterOnRead(ReadCallback()); - pproto.RegisterOnWrite(WriteCallback()); + pproto.RegisterOnInitUnsafe(GetInitCallback()); + pproto.RegisterOnWriteUnsafe(GetWriteCallback()); pproto.Init(); Wait(); EXPECT_EQ(write_count_, 1);
diff --git a/chrome/browser/ash/app_list/search/util/score_normalizer.cc b/chrome/browser/ash/app_list/search/util/score_normalizer.cc index 92d0a0e..1920aa4 100644 --- a/chrome/browser/ash/app_list/search/util/score_normalizer.cc +++ b/chrome/browser/ash/app_list/search/util/score_normalizer.cc
@@ -8,6 +8,7 @@ #include <cmath> #include <limits> +#include "base/functional/bind.h" #include "base/logging.h" namespace app_list { @@ -61,8 +62,10 @@ ScoreNormalizer::ScoreNormalizer(ScoreNormalizer::Proto proto, const Params& params) : proto_(std::move(proto)), params_(params) { - proto_.RegisterOnRead(base::BindOnce(&ScoreNormalizer::OnProtoRead, - weak_factory_.GetWeakPtr())); + // `proto_` is a class member so it is safe to call `RegisterOnInitUnsafe()`. + proto_.RegisterOnInitUnsafe( + base::BindOnce(&ScoreNormalizer::OnProtoInit, base::Unretained(this))); + proto_.Init(); } @@ -244,7 +247,7 @@ proto_.QueueWrite(); } -void ScoreNormalizer::OnProtoRead(ReadStatus status) { +void ScoreNormalizer::OnProtoInit() { DCHECK(proto_.initialized()); if ((proto_->has_model_version() &&
diff --git a/chrome/browser/ash/app_list/search/util/score_normalizer.h b/chrome/browser/ash/app_list/search/util/score_normalizer.h index f6025358..bd9f84c 100644 --- a/chrome/browser/ash/app_list/search/util/score_normalizer.h +++ b/chrome/browser/ash/app_list/search/util/score_normalizer.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_ASH_APP_LIST_SEARCH_UTIL_SCORE_NORMALIZER_H_ #define CHROME_BROWSER_ASH_APP_LIST_SEARCH_UTIL_SCORE_NORMALIZER_H_ -#include "base/memory/weak_ptr.h" #include "chrome/browser/ash/app_list/search/util/persistent_proto.h" #include "chrome/browser/ash/app_list/search/util/score_normalizer.pb.h" @@ -56,12 +55,10 @@ private: friend class test::ScoreNormalizerTest; - void OnProtoRead(ReadStatus status); + void OnProtoInit(); PersistentProto<ScoreNormalizerProto> proto_; Params params_; - - base::WeakPtrFactory<ScoreNormalizer> weak_factory_{this}; }; } // namespace app_list
diff --git a/chrome/browser/ash/file_suggest/file_suggest_keyed_service.cc b/chrome/browser/ash/file_suggest/file_suggest_keyed_service.cc index f90ba07..fb6c19f 100644 --- a/chrome/browser/ash/file_suggest/file_suggest_keyed_service.cc +++ b/chrome/browser/ash/file_suggest/file_suggest_keyed_service.cc
@@ -6,6 +6,7 @@ #include "ash/constants/ash_features.h" #include "ash/public/cpp/app_list/app_list_types.h" +#include "base/functional/bind.h" #include "chrome/browser/ash/file_manager/fileapi_util.h" #include "chrome/browser/ash/file_suggest/drive_file_suggestion_provider.h" #include "chrome/browser/ash/file_suggest/drive_recent_file_suggestion_provider.h" @@ -25,9 +26,11 @@ : profile_(profile), proto_(std::move(proto)) { DCHECK(profile_); - proto_.RegisterOnRead( + // `proto_` is a class member so it is safe to call `RegisterOnInitUnsafe()`. + proto_.RegisterOnInitUnsafe( base::BindOnce(&FileSuggestKeyedService::OnRemovedSuggestionProtoReady, - weak_factory_.GetWeakPtr())); + base::Unretained(this))); + proto_.Init(); if (features::IsLauncherContinueSectionWithRecentsEnabled() || @@ -189,8 +192,7 @@ return proto_.initialized(); } -void FileSuggestKeyedService::OnRemovedSuggestionProtoReady( - app_list::ReadStatus read_status) { +void FileSuggestKeyedService::OnRemovedSuggestionProtoReady() { OnSuggestionProviderUpdated(FileSuggestionType::kDriveFile); if (local_file_suggestion_provider_->IsInitialized()) {
diff --git a/chrome/browser/ash/file_suggest/file_suggest_keyed_service.h b/chrome/browser/ash/file_suggest/file_suggest_keyed_service.h index 2e42ba16..f26c0a6 100644 --- a/chrome/browser/ash/file_suggest/file_suggest_keyed_service.h +++ b/chrome/browser/ash/file_suggest/file_suggest_keyed_service.h
@@ -117,7 +117,7 @@ private: // Called when `proto_` is ready to read. - void OnRemovedSuggestionProtoReady(app_list::ReadStatus read_status); + void OnRemovedSuggestionProtoReady(); // Removes the suggestions specified by type-id pairs. void RemoveSuggestionsByTypeIdPairs(
diff --git a/chrome/browser/ash/file_suggest/local_file_suggestion_provider.cc b/chrome/browser/ash/file_suggest/local_file_suggestion_provider.cc index 892243c..64b4644a 100644 --- a/chrome/browser/ash/file_suggest/local_file_suggestion_provider.cc +++ b/chrome/browser/ash/file_suggest/local_file_suggestion_provider.cc
@@ -99,9 +99,13 @@ app_list::RankerStateDirectory(profile).AppendASCII( "zero_state_local_files.pb"), kSaveDelay); - proto.RegisterOnRead( + + // `proto` is owned by `files_ranker_` which is a class member so it is safe + // to call `RegisterOnInitUnsafe()`. + proto.RegisterOnInitUnsafe( base::BindOnce(&LocalFileSuggestionProvider::OnProtoInitialized, base::Unretained(this))); + files_ranker_ = std::make_unique<app_list::MrfuCache>(std::move(proto), params); } @@ -189,8 +193,7 @@ } } -void LocalFileSuggestionProvider::OnProtoInitialized( - app_list::ReadStatus status) { +void LocalFileSuggestionProvider::OnProtoInitialized() { NotifySuggestionUpdate(FileSuggestionType::kLocalFile); }
diff --git a/chrome/browser/ash/file_suggest/local_file_suggestion_provider.h b/chrome/browser/ash/file_suggest/local_file_suggestion_provider.h index cc9f116..717637b 100644 --- a/chrome/browser/ash/file_suggest/local_file_suggestion_provider.h +++ b/chrome/browser/ash/file_suggest/local_file_suggestion_provider.h
@@ -55,7 +55,7 @@ private: - void OnProtoInitialized(app_list::ReadStatus status); + void OnProtoInitialized(); void OnValidationComplete(std::pair<std::vector<LocalFileData>, std::vector<base::FilePath>> results);
diff --git a/chrome/browser/autofill/autofill_across_iframes_browsertest.cc b/chrome/browser/autofill/autofill_across_iframes_browsertest.cc index 3a04715..625740f 100644 --- a/chrome/browser/autofill/autofill_across_iframes_browsertest.cc +++ b/chrome/browser/autofill/autofill_across_iframes_browsertest.cc
@@ -43,7 +43,6 @@ #include "net/test/embedded_test_server/http_response.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/switches.h" using base::ASCIIToUTF16; @@ -215,9 +214,6 @@ // go/autofill-iframes-race-condition-explainer for some explanation. class AutofillAcrossIframesTest : public InProcessBrowserTest { public: - AutofillAcrossIframesTest() - : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} - void SetUpOnMainThread() override { InProcessBrowserTest::SetUpOnMainThread(); // Prevent the Keychain from coming up on Mac. @@ -227,8 +223,8 @@ // Every hostname is handled by that server. host_resolver()->AddRule("*", "127.0.0.1"); cert_verifier_.mock_cert_verifier()->set_default_result(net::OK); - https_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_OK); - https_server_.RegisterRequestHandler(base::BindRepeating( + embedded_https_test_server().SetSSLConfig(net::EmbeddedTestServer::CERT_OK); + embedded_https_test_server().RegisterRequestHandler(base::BindRepeating( [](const std::map<std::string, std::string>* pages, const net::test_server::HttpRequest& request) -> std::unique_ptr<net::test_server::HttpResponse> { @@ -243,8 +239,8 @@ return response; }, base::Unretained(&pages_))); - ASSERT_TRUE(https_server_.InitializeAndListen()); - https_server_.StartAcceptingConnections(); + ASSERT_TRUE(embedded_https_test_server().InitializeAndListen()); + embedded_https_test_server().StartAcceptingConnections(); } void TearDownOnMainThread() override { @@ -263,7 +259,7 @@ command_line->AppendSwitch(blink::switches::kAllowPreCommitInput); } - // Registers the response `content_html` for a given `relative_path`, wth + // Registers the response `content_html` for a given `relative_path`, with // all placeholders $1, $2, ... in `content_html` replaced with the // corresponding hostname from `kHostnames`. // This response is served by for *every* hostname. @@ -273,9 +269,9 @@ std::vector<std::string> replacements; replacements.reserve(std::size(kHostnames)); for (const char* hostname : kHostnames) { - replacements.push_back(std::string( - base::TrimString(https_server_.GetURL(hostname, "/").spec(), "/", - base::TRIM_TRAILING))); + replacements.push_back(std::string(base::TrimString( + embedded_https_test_server().GetURL(hostname, "/").spec(), "/", + base::TRIM_TRAILING))); } pages_[std::move(relative_path)] = base::ReplaceStringPlaceholders(content_html, replacements, nullptr); @@ -292,9 +288,10 @@ // advance. const FormStructure* NavigateToUrl(base::StringPiece relative_url, size_t num_fields) { - NavigateParams params(browser(), - https_server_.GetURL(kMainHostname, relative_url), - ui::PAGE_TRANSITION_LINK); + NavigateParams params( + browser(), + embedded_https_test_server().GetURL(kMainHostname, relative_url), + ui::PAGE_TRANSITION_LINK); params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; ui_test_utils::NavigateToURL(¶ms); return GetOrWaitForFormWithFocusableFields( @@ -360,7 +357,6 @@ test::AutofillBrowserTestEnvironment autofill_test_environment_; base::test::ScopedFeatureList feature_list_{ features::kAutofillSharedAutofill}; - net::EmbeddedTestServer https_server_; content::ContentMockCertVerifier cert_verifier_; // Maps relative paths to HTML content. std::map<std::string, std::string> pages_;
diff --git a/chrome/browser/autofill/autofill_server_browsertest.cc b/chrome/browser/autofill/autofill_server_browsertest.cc index 9454d41..219ae08e 100644 --- a/chrome/browser/autofill/autofill_server_browsertest.cc +++ b/chrome/browser/autofill/autofill_server_browsertest.cc
@@ -25,14 +25,17 @@ #include "components/autofill/core/browser/personal_data_manager_observer.h" #include "components/autofill/core/common/autofill_features.h" #include "components/version_info/version_info.h" +#include "content/public/browser/web_contents.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" +#include "content/public/test/content_mock_cert_verifier.h" #include "content/public/test/test_utils.h" #include "content/public/test/url_loader_interceptor.h" +#include "net/dns/mock_host_resolver.h" #include "services/network/test/test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "url/third_party/mozilla/url_parse.h" +#include "third_party/blink/public/common/switches.h" using testing::AllOf; using testing::Eq; @@ -110,37 +113,78 @@ std::unique_ptr<content::URLLoaderInterceptor> interceptor_; }; -} // namespace - class AutofillServerTest : public InProcessBrowserTest { public: - void SetUp() override { - // Enable data-url support. - // TODO(crbug.com/894428) - fix this suite to use the embedded test server - // instead of data urls. + AutofillServerTest() { scoped_feature_list_.InitWithFeatures( // Enabled. - {features::test::kAutofillAllowNonHttpActivation, - features::test::kAutofillServerCommunication, + {features::test::kAutofillServerCommunication, features::kAutofillEnableSupportForApartmentNumbers}, // Disabled. {}); - - // Note that features MUST be enabled/disabled before continuing with - // SetUp(); otherwise, the feature state doesn't propagate to the test - // browser instance. - InProcessBrowserTest::SetUp(); } void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + // Prevent the Keychain from coming up on Mac. + test::DisableSystemServices(browser()->profile()->GetPrefs()); + // Wait for Personal Data Manager to be fully loaded as the events about // being loaded may throw off the tests and cause flakiness. WaitForPersonalDataManagerToBeLoaded(browser()->profile()); + + // Set up the HTTPS (!) server (embedded_test_server() is an HTTP server). + // Every hostname is handled by that server. + host_resolver()->AddRule("a.com", "127.0.0.1"); + cert_verifier_.mock_cert_verifier()->set_default_result(net::OK); + embedded_https_test_server().SetSSLConfig(net::EmbeddedTestServer::CERT_OK); + embedded_https_test_server().RegisterRequestHandler(base::BindRepeating( + [](const std::map<std::string, std::string>* pages, + const net::test_server::HttpRequest& request) + -> std::unique_ptr<net::test_server::HttpResponse> { + auto it = pages->find(request.GetURL().path()); + if (it == pages->end()) { + return nullptr; + } + auto response = + std::make_unique<net::test_server::BasicHttpResponse>(); + response->set_code(net::HTTP_OK); + response->set_content_type("text/html;charset=utf-8"); + response->set_content(it->second); + return response; + }, + base::Unretained(&pages_))); + ASSERT_TRUE(embedded_https_test_server().InitializeAndListen()); + embedded_https_test_server().StartAcceptingConnections(); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + cert_verifier_.SetUpCommandLine(command_line); + // Slower test bots (ChromeOS, debug, etc.) are flaky due to slower loading + // interacting with deferred commits. + command_line->AppendSwitch(blink::switches::kAllowPreCommitInput); + } + + void NavigateToUrl(base::StringPiece relative_url) { + NavigateParams params( + browser(), embedded_https_test_server().GetURL("a.com", relative_url), + ui::PAGE_TRANSITION_LINK); + params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; + ui_test_utils::NavigateToURL(¶ms); + } + + // Registers the response `content_html` for a given `relative_path`. + void SetUrlContent(std::string relative_path, + base::StringPiece content_html) { + ASSERT_EQ(relative_path[0], '/'); + pages_[std::move(relative_path)] = content_html; } private: test::AutofillBrowserTestEnvironment autofill_test_environment_; base::test::ScopedFeatureList scoped_feature_list_; + content::ContentMockCertVerifier cert_verifier_; + std::map<std::string, std::string> pages_; }; MATCHER_P(EqualsUploadProto, expected_const, "") { @@ -186,26 +230,26 @@ personal_data_observer.Wait(); // Load the test page. Expect a query request upon loading the page. - const char kDataURIPrefix[] = "data:text/html;charset=utf-8,"; - const char kFormHtml[] = - "<form id='test_form' action='about:blank'>" - " <input name='one'>" - " <input name='two' autocomplete='off'>" - " <input name='three'>" - " <input name='four' autocomplete='off'>" - " <input type='submit'>" - "</form>" - "<script>" - " document.onclick = function() {" - " document.getElementById('test_form').submit();" - " };" - "</script>"; + SetUrlContent("/test.html", R"( + <form id=test_form action=about:blank> + <input name=one> + <input name=two autocomplete=off> + <input name=three> + <input name=four autocomplete=off> + <input type=submit> + </form> + <script> + document.onclick = function() { + document.getElementById('test_form').submit(); + }; + </script> + )"); AutofillPageQueryRequest query; query.set_client_version(std::string(GetProductNameAndVersionForUserAgent())); auto* query_form = query.add_forms(); - query_form->set_signature(15916856893790176210U); - query_form->set_alternative_signature(1512434549531087U); + query_form->set_signature(16565345157617645697U); + query_form->set_alternative_signature(11880064796695671551U); query_form->add_fields()->set_signature(2594484045U); query_form->add_fields()->set_signature(2750915947U); @@ -217,8 +261,7 @@ WindowedNetworkObserver query_network_observer(expected_query_string); - ASSERT_TRUE(ui_test_utils::NavigateToURL( - browser(), GURL(std::string(kDataURIPrefix) + kFormHtml))); + NavigateToUrl("/test.html"); query_network_observer.Wait(); // Submit the form, using a simulated mouse click because form submissions not @@ -229,7 +272,7 @@ upload->set_submission(true); upload->set_client_version( std::string(GetProductNameAndVersionForUserAgent())); - upload->set_form_signature(15916856893790176210U); + upload->set_form_signature(16565345157617645697U); upload->set_autofill_used(false); // The `data_present` fields is a bit mask of field types that are associated @@ -275,20 +318,20 @@ // of user defined autocomplete types. IN_PROC_BROWSER_TEST_F(AutofillServerTest, AlwaysQueryForPasswordFields) { // Load the test page. Expect a query request upon loading the page. - const char kDataURIPrefix[] = "data:text/html;charset=utf-8,"; - const char kFormHtml[] = - "<form id='test_form'>" - " <input type='text' id='one' autocomplete='username'>" - " <input type='text' id='two' autocomplete='off'>" - " <input type='password' id='three'>" - " <input type='submit'>" - "</form>"; + SetUrlContent("/test.html", R"( + <form id=test_form> + <input type=text id=one autocomplete=username> + <input type=text id=two autocomplete=off> + <input type=password id=three> + <input type=submit> + </form> + )"); AutofillPageQueryRequest query; query.set_client_version(std::string(GetProductNameAndVersionForUserAgent())); auto* query_form = query.add_forms(); - query_form->set_signature(8900697631820480876U); - query_form->set_alternative_signature(8962829409320837774U); + query_form->set_signature(4875414400744072230U); + query_form->set_alternative_signature(130271417830211693U); query_form->add_fields()->set_signature(2594484045U); query_form->add_fields()->set_signature(2750915947U); @@ -298,9 +341,9 @@ ASSERT_TRUE(query.SerializeToString(&expected_query_string)); WindowedNetworkObserver query_network_observer(expected_query_string); - ASSERT_TRUE(ui_test_utils::NavigateToURL( - browser(), GURL(std::string(kDataURIPrefix) + kFormHtml))); + NavigateToUrl("/test.html"); query_network_observer.Wait(); } +} // namespace } // namespace autofill
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc index a26c98c..0d7f6d21 100644 --- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc +++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
@@ -122,6 +122,7 @@ #include "net/dns/mock_host_resolver.h" #include "net/http/http_request_headers.h" #include "net/http/http_status_code.h" +#include "net/test/embedded_test_server/controllable_http_response.h" #include "net/test/embedded_test_server/default_handlers.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" @@ -6937,6 +6938,85 @@ bfcache_render_frame_host_delete_observer->WaitUntilDeleted(); } +class DeclarativeNetRequestControllableResponseTest + : public DeclarativeNetRequestBrowserTest { + public: + DeclarativeNetRequestControllableResponseTest() = default; + + void SetUpOnMainThread() override { + // The controllable response handler needs to be set up first before the + // test server can be started, which is why the SetUpOnMainThread from the + // super class which starts the test server is called afterwards here. + controllable_http_response_.emplace(embedded_test_server(), + "/pages_with_script/index.html"); + DeclarativeNetRequestBrowserTest::SetUpOnMainThread(); + } + + protected: + net::test_server::ControllableHttpResponse& controllable_http_response() { + return *controllable_http_response_; + } + + private: + std::optional<net::test_server::ControllableHttpResponse> + controllable_http_response_; +}; + +// Test that DNR actions from an extension are cleaned up when the extension is +// disabled. This fixes a crash/bug where DNR actions such as modifyHeaders +// which are created on the OnBeforeRequest phase when an extension was enabled +// are supposed to take effect in a later request stage but the extension may no +// longer be enabled at that point. +// Regression for crbug.com/40072083 which would've caused a crash in this test. +IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestControllableResponseTest, + EraseActionsOnExtensionDisabled) { + // Create an extension with a rule that modifies response headers. This + // extension will match its rule during OnBeforeRequest but the rule would not + // be applied until OnHeadersReceived which is after when the request is sent + // and the response has started. + TestRule headers_rule = CreateModifyHeadersRule( + kMinValidID, kMinValidPriority, "google.com", std::nullopt, + std::vector<TestHeaderInfo>( + {TestHeaderInfo("resp-header", "append", "resp-value")})); + headers_rule.condition->resource_types = + std::vector<std::string>({"main_frame"}); + + ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules( + {headers_rule}, "extension_1", {URLPattern::kAllUrlsPattern})); + const ExtensionId& extension_id = last_loaded_extension_id(); + + const GURL page_url = embedded_test_server()->GetURL( + "google.com", "/pages_with_script/index.html"); + + ui_test_utils::NavigateToURLWithDisposition( + browser(), page_url, WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB); + + controllable_http_response().WaitForRequest(); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + controllable_http_response().Send(net::HTTP_OK, "text/html", + "<html>Hello, World!</html>"); + + // Disable the extension after the response has been sent but before the + // request has finished. + DisableExtension(extension_id); + + controllable_http_response().Done(); + + // Block until the web contents have been fully loaded to be certain that the + // web request event router finishes processing all events after the request + // has finished, such as OnHeadersReceived, and that the extension will be + // disabled at that point. The test should not crash at this point. + // TODO(crbug.com/40072083): Follow up with verifying the values of response + // headers. This may require initiating a request from a JS script injected + // into the page. + ASSERT_TRUE(content::WaitForLoadStop(web_contents)); + EXPECT_FALSE(extension_service()->IsExtensionEnabled(extension_id)); +} + INSTANTIATE_TEST_SUITE_P(All, DeclarativeNetRequestBrowserTest, ::testing::Values(ExtensionLoadType::PACKED, @@ -6982,6 +7062,10 @@ ::testing::Values(ExtensionLoadType::PACKED, ExtensionLoadType::UNPACKED)); +INSTANTIATE_TEST_SUITE_P(All, + DeclarativeNetRequestControllableResponseTest, + ::testing::Values(ExtensionLoadType::PACKED, + ExtensionLoadType::UNPACKED)); } // namespace } // namespace declarative_net_request } // namespace extensions
diff --git a/chrome/browser/extensions/api/printing/printing_test_utils.cc b/chrome/browser/extensions/api/printing/printing_test_utils.cc index 266322c..2b43196 100644 --- a/chrome/browser/extensions/api/printing/printing_test_utils.cc +++ b/chrome/browser/extensions/api/printing/printing_test_utils.cc
@@ -48,9 +48,19 @@ constexpr int kHorizontalDpi = 300; constexpr int kVerticalDpi = 400; -constexpr int kMediaSizeWidth = 210000; -constexpr int kMediaSizeHeight = 297000; -constexpr char kMediaSizeVendorId[] = "iso_a4_210x297mm"; + +// Size of ISO A4 paper in microns. +constexpr int kIsoA4Width = 210000; +constexpr int kIsoA4Height = 297000; + +// Size of NA Letter paper in microns. +constexpr int kNaLetterWidth = 215900; +constexpr int kNaLetterHeight = 279400; + +// Size of a custom paper with variable height in microns. +constexpr int kCustomPaperWidth = 200000; +constexpr int kCustomPaperHeight = 250000; +constexpr int kCustomPaperMaxHeight = 300000; // Mapping of the different extension types used in the test to the specific // manifest file names to create an extension of that type. The actual location @@ -225,10 +235,18 @@ capabilities->copies_max = 2; capabilities->default_dpi = {kHorizontalDpi, kVerticalDpi}; capabilities->dpis.emplace_back(capabilities->default_dpi); - printing::PrinterSemanticCapsAndDefaults::Paper paper( - /*display_name=*/"", kMediaSizeVendorId, - {kMediaSizeWidth, kMediaSizeHeight}); - capabilities->papers.push_back(std::move(paper)); + printing::PrinterSemanticCapsAndDefaults::Paper iso_a4_paper( + /*display_name=*/"", /*vendor_id=*/"", {kIsoA4Width, kIsoA4Height}); + printing::PrinterSemanticCapsAndDefaults::Paper na_letter_paper( + /*display_name=*/"", /*vendor_id=*/"", {kNaLetterWidth, kNaLetterHeight}); + printing::PrinterSemanticCapsAndDefaults::Paper custom_paper( + /*display_name=*/"", /*vendor_id=*/"", + {kCustomPaperWidth, kCustomPaperHeight}, + /*printable_area_um=*/{kCustomPaperWidth, kCustomPaperHeight}, + /*max_height_um=*/kCustomPaperMaxHeight); + capabilities->default_paper = iso_a4_paper; + capabilities->papers = {std::move(iso_a4_paper), std::move(na_letter_paper), + std::move(custom_paper)}; capabilities->collate_capable = true; return capabilities; }
diff --git a/chrome/browser/extensions/events_apitest.cc b/chrome/browser/extensions/events_apitest.cc index 4cad0c1..d73548b 100644 --- a/chrome/browser/extensions/events_apitest.cc +++ b/chrome/browser/extensions/events_apitest.cc
@@ -36,6 +36,10 @@ namespace extensions { +namespace { + +using ContextType = ExtensionBrowserTest::ContextType; + IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Events) { ASSERT_TRUE(RunExtensionTest("events")) << message_; } @@ -614,44 +618,58 @@ EXPECT_FALSE(observed_extension_names().count("chrome updates non listener")); } -class EventPageEventDispatchingApiTest : public ExtensionApiTest { +// TODO(crbug.com/41493334): Also test extensions with service workers and their +// equivalent to ExtensionHost (EventAckData) for these scenarios: +// 1. Dispatch to background context acks (duplicate of +// DispatchToBackgroundPage_Acks) +// 2. Dispatch to content script doesn't ack (duplicate of +// DispatchToContentScript_DoesNotRecordMessageForAcking) +// 2. Dispatch guest view event (EventRouter::DispatchEventToSender()) acks +// (similar to DispatchToPage_Acks) + +class EventDispatchingApiTest + : public ExtensionApiTest, + public testing::WithParamInterface<ContextType> { public: - EventPageEventDispatchingApiTest() = default; + EventDispatchingApiTest() = default; - EventPageEventDispatchingApiTest(const EventPageEventDispatchingApiTest&) = - delete; - EventPageEventDispatchingApiTest& operator=( - const EventPageEventDispatchingApiTest&) = delete; - - void SetUpOnMainThread() override { - ExtensionApiTest::SetUpOnMainThread(); - host_resolver()->AddRule("*", "127.0.0.1"); - ASSERT_TRUE(StartEmbeddedTestServer()); - } - - content::WebContents* web_contents() { - return browser()->tab_strip_model()->GetActiveWebContents(); - } + EventDispatchingApiTest(const EventDispatchingApiTest&) = delete; + EventDispatchingApiTest& operator=(const EventDispatchingApiTest&) = delete; }; -// Tests that an event page will receive an event message and properly track -// and remove the unacked event message in ExtensionHost. -IN_PROC_BROWSER_TEST_F(EventPageEventDispatchingApiTest, - DispatchToEventPage_Acks) { - // Load an extension with a chrome.storage.onChanged listener. +// Tests that background pages will receive an event message (routed through the +// EventRouter::DispatchToProcess() flow) and properly track and remove the +// unacked event message in ExtensionHost. Rather than send generate webRequest +// events this uses storage events to use this flow. +IN_PROC_BROWSER_TEST_P(EventDispatchingApiTest, DispatchToBackgroundPage_Acks) { + // Load either a persistent background page or a event page script. + static constexpr char kManifestPersistentBackgroundScript[] = + R"("persistent": true)"; + static constexpr char kManifestEventPageBackgroundScript[] = + R"("persistent": false)"; + + // Load an extension with a chrome.storage.onChanged + // (EventRouter::DispatchToProcess()) listener and wait for the + // chrome.runtime.onInstalled listener to fire. static constexpr char kManifest[] = R"({ - "name": "Event page", - "version": "0.1", - "manifest_version": 2, - "background": { - "scripts": ["background.js"], - "persistent": false - }, - "permissions": ["storage"] - })"; + "name": "Background page", + "version": "0.1", + "manifest_version": 2, + "background": { + "scripts": ["background.js"], + %s + }, + "permissions": ["storage"] + })"; + bool persistent_background_extension = + GetParam() == ContextType::kPersistentBackground; + const char* background_script = persistent_background_extension + ? kManifestPersistentBackgroundScript + : kManifestEventPageBackgroundScript; + std::string manifest = base::StringPrintf(kManifest, background_script); TestExtensionDir test_dir; - test_dir.WriteManifest(kManifest); + test_dir.WriteManifest(manifest); constexpr char kBackgroundJs[] = R"( chrome.runtime.onInstalled.addListener((details) => { @@ -685,7 +703,7 @@ process_manager->GetBackgroundHostForExtension(extension->id()); ASSERT_EQ(extension_host->GetUnackedMessagesSizeForTesting(), 0UL); - // Set storage value which should fire chrome.storage.onChanged listeners. + // Set storage value which should fire chrome.storage.onChanged listener. ExtensionTestMessageListener extension_event_listener_fired("listener fired"); static constexpr char kScript[] = R"(chrome.storage.local.set({"key" : "value"});)"; @@ -699,19 +717,47 @@ EXPECT_EQ(extension_host->GetUnackedMessagesSizeForTesting(), 0UL); } -// TODO(crbug.com/41493334): Refactor this test into the -// DispatchToEventPage_Acks test since they are so similar. -using PersistentBackgroundPageEventDispatchToSenderApiTest = - EventPageEventDispatchingApiTest; +INSTANTIATE_TEST_SUITE_P(PersistentBackground, + EventDispatchingApiTest, + ::testing::Values(ContextType::kPersistentBackground)); +INSTANTIATE_TEST_SUITE_P(EventPage, + EventDispatchingApiTest, + ::testing::Values(ContextType::kEventPage)); + +// This allows tests to perform web navigations that trigger webRequest API +// events to be sent. +class NavigatingEventDispatchingApiTest : public EventDispatchingApiTest { + public: + NavigatingEventDispatchingApiTest() = default; + + NavigatingEventDispatchingApiTest(const NavigatingEventDispatchingApiTest&) = + delete; + NavigatingEventDispatchingApiTest& operator=( + const NavigatingEventDispatchingApiTest&) = delete; + + void SetUpOnMainThread() override { + ExtensionApiTest::SetUpOnMainThread(); + host_resolver()->AddRule("*", "127.0.0.1"); + ASSERT_TRUE(StartEmbeddedTestServer()); + } + + content::WebContents* web_contents() { + return browser()->tab_strip_model()->GetActiveWebContents(); + } +}; + +using PersistentBackgroundPageDispatchEventToSenderEventApiTest = + NavigatingEventDispatchingApiTest; // Tests that persistent background pages will receive an event message (routed -// through the EventRouter::DispatchToSender() flow) and properly track and +// through the EventRouter::DispatchEventToSender() flow) and properly track and // remove the unacked event message in ExtensionHost. Only persistent background // pages can use the webRequest API so event pages are not tested. -IN_PROC_BROWSER_TEST_F(PersistentBackgroundPageEventDispatchToSenderApiTest, - DispatchToPage_Acks) { +IN_PROC_BROWSER_TEST_F( + PersistentBackgroundPageDispatchEventToSenderEventApiTest, + DispatchToPage_Acks) { // Load an extension with a chrome.webRequest.onBeforeRequest - // (EventRouter::DispatchToSender()) listener and wait for the + // (EventRouter::DispatchEventToSender()) listener and wait for the // chrome.runtime.onInstalled listener to fire. static constexpr char kManifest[] = R"({ @@ -776,20 +822,28 @@ EXPECT_EQ(extension_host->GetUnackedMessagesSizeForTesting(), 0UL); } -// Tests that an event targeted to a content script listener is not recorded -// in unacked event messages in ExtensionHost. -IN_PROC_BROWSER_TEST_F(EventPageEventDispatchingApiTest, +// Tests that an event targeted to a content script listener is not recorded in +// unacked event messages in ExtensionHost (for event pages and persistent +// background pages). EventRouter::DispatchEventToSender() flow is not tested +// since content scripts cannot listen to webRequest events. +IN_PROC_BROWSER_TEST_P(NavigatingEventDispatchingApiTest, DispatchToContentScript_DoesNotRecordMessageForAcking) { + // Load either a persistent background page or a event page script. + static constexpr char kManifestPersistentBackgroundScript[] = + R"("persistent": true)"; + static constexpr char kManifestEventPageBackgroundScript[] = + R"("persistent": false)"; + // Load an extension with a content script that has the only // chrome.storage.onChanged listener. static constexpr char kManifest[] = R"({ - "name": "Event page", + "name": "Background page", "version": "0.1", "manifest_version": 2, "background": { "scripts": ["background.js"], - "persistent": false + %s }, "content_scripts": [{ "matches": ["https://*/*", "http://*/*"], @@ -797,8 +851,14 @@ }], "permissions": ["storage"] })"; + bool persistent_background_extension = + GetParam() == ContextType::kPersistentBackground; + const char* background_script = persistent_background_extension + ? kManifestPersistentBackgroundScript + : kManifestEventPageBackgroundScript; + std::string manifest = base::StringPrintf(kManifest, background_script); TestExtensionDir test_dir; - test_dir.WriteManifest(kManifest); + test_dir.WriteManifest(manifest); constexpr char kContentScriptJs[] = R"( chrome.storage.onChanged.addListener((details) => { @@ -858,8 +918,16 @@ // messages remain. EXPECT_TRUE(content_script_event_listener_fired.WaitUntilSatisfied()); // TODO(crbug.com/1496093): Can we add an observer so that we know that an - // unacked message was not added to map at all? + // unacked message was not added to the map at all? EXPECT_EQ(extension_host->GetUnackedMessagesSizeForTesting(), 0UL); } +INSTANTIATE_TEST_SUITE_P(PersistentBackground, + NavigatingEventDispatchingApiTest, + ::testing::Values(ContextType::kPersistentBackground)); +INSTANTIATE_TEST_SUITE_P(EventPage, + NavigatingEventDispatchingApiTest, + ::testing::Values(ContextType::kEventPage)); + +} // namespace } // namespace extensions
diff --git a/chrome/browser/history_embeddings/OWNERS b/chrome/browser/history_embeddings/OWNERS new file mode 100644 index 0000000..6310b61e --- /dev/null +++ b/chrome/browser/history_embeddings/OWNERS
@@ -0,0 +1 @@ +file://components/history_embeddings/OWNERS
diff --git a/chrome/browser/history_embeddings/history_embeddings_service_browsertest.cc b/chrome/browser/history_embeddings/history_embeddings_service_browsertest.cc new file mode 100644 index 0000000..5d64df6 --- /dev/null +++ b/chrome/browser/history_embeddings/history_embeddings_service_browsertest.cc
@@ -0,0 +1,51 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/history_embeddings/history_embeddings_service.h" + +#include "base/files/scoped_temp_dir.h" +#include "base/test/test_future.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/test/browser_test.h" + +namespace history_embeddings { + +class HistoryEmbeddingsBrowserTest : public InProcessBrowserTest { + public: + void SetUp() override { + CHECK(history_dir_.CreateUniqueTempDir()); + InProcessBrowserTest::SetUp(); + } + + protected: + base::ScopedTempDir history_dir_; +}; + +IN_PROC_BROWSER_TEST_F(HistoryEmbeddingsBrowserTest, BrowserRetrievesPassages) { + auto service = + std::make_unique<HistoryEmbeddingsService>(history_dir_.GetPath()); + + ASSERT_TRUE(embedded_test_server()->Start()); + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), embedded_test_server()->GetURL("/inner_text/test1.html"))); + + base::test::TestFuture<UrlPassages> future; + service->RetrievePassages(*web_contents->GetPrimaryMainFrame(), + future.GetCallback()); + + UrlPassages url_passages = future.Take(); + ASSERT_EQ(url_passages.url.path(), "/inner_text/test1.html"); + + // Note: Currently the passage extraction algorithm does not recurse + // into iframes. If that changes then the passage structure and content + // here will need to change accordingly. + ASSERT_EQ(url_passages.passages.size(), 1u); + ASSERT_EQ(url_passages.passages[0], "A B C D"); +} + +} // namespace history_embeddings
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index f86cda11..33e3b86 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -387,65 +387,40 @@ // Content-Security-Policy, the embed tag is still sized correctly. // Regression test for https://crbug.com/271452. IN_PROC_BROWSER_TEST_P(PDFExtensionTest, CSPDoesNotBlockEmbedStyles) { - // TODO(crbug.com/1445746): Remove this once the test passes for OOPIF PDF. - if (UseOopif()) { - GTEST_SKIP(); - } - const GURL main_url(embedded_test_server()->GetURL("/pdf/test-csp.pdf")); - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url)); - ASSERT_TRUE(GetActiveWebContents()); + content::RenderFrameHost* extension_host = LoadPdfGetExtensionHost(main_url); + ASSERT_TRUE(extension_host); auto* primary_main_frame = GetActiveWebContents()->GetPrimaryMainFrame(); - ASSERT_TRUE(primary_main_frame); - - // Verify the pdf has loaded. - auto* guest_view = GetGuestViewManager()->WaitForSingleGuestViewCreated(); - ASSERT_TRUE(guest_view); - auto* guest_main_frame = guest_view->GetGuestMainFrame(); - EXPECT_NE(primary_main_frame, guest_main_frame); - TestMimeHandlerViewGuest::WaitForGuestLoadStartThenStop(guest_view); // Verify the extension was loaded. const GURL extension_url( "chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/index.html"); - EXPECT_EQ(extension_url, guest_main_frame->GetLastCommittedURL()); + EXPECT_EQ(extension_url, extension_host->GetLastCommittedURL()); EXPECT_EQ(main_url, primary_main_frame->GetLastCommittedURL()); // Verify that the plugin occupies all of the page area. const gfx::Rect embedder_rect = primary_main_frame->GetView()->GetViewBounds(); - const gfx::Rect guest_rect = guest_main_frame->GetView()->GetViewBounds(); - EXPECT_EQ(embedder_rect, guest_rect); + const gfx::Rect extension_rect = extension_host->GetView()->GetViewBounds(); + EXPECT_EQ(embedder_rect, extension_rect); } // This test verifies that when a PDF is served with // Content-Security-Policy: sandbox, this is ignored and the PDF is displayed. // Regression test for https://crbug.com/1187122. IN_PROC_BROWSER_TEST_P(PDFExtensionTest, CSPWithSandboxDoesNotBlockPDF) { - // TODO(crbug.com/1445746): Remove this once the test passes for OOPIF PDF. - if (UseOopif()) { - GTEST_SKIP(); - } - const GURL main_url( embedded_test_server()->GetURL("/pdf/test-csp-sandbox.pdf")); - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url)); - ASSERT_TRUE(GetActiveWebContents()); - auto* primary_main_frame = GetActiveWebContents()->GetPrimaryMainFrame(); - ASSERT_TRUE(primary_main_frame); - - // Verify the pdf has loaded. - auto* guest_view = GetGuestViewManager()->WaitForSingleGuestViewCreated(); - ASSERT_TRUE(guest_view); - EXPECT_NE(primary_main_frame, guest_view->GetGuestMainFrame()); - TestMimeHandlerViewGuest::WaitForGuestLoadStartThenStop(guest_view); + content::RenderFrameHost* extension_host = LoadPdfGetExtensionHost(main_url); + ASSERT_TRUE(extension_host); // Verify the extension was loaded. const GURL extension_url( "chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/index.html"); - EXPECT_EQ(extension_url, - guest_view->GetGuestMainFrame()->GetLastCommittedURL()); - EXPECT_EQ(main_url, primary_main_frame->GetLastCommittedURL()); + EXPECT_EQ(extension_url, extension_host->GetLastCommittedURL()); + EXPECT_EQ( + main_url, + GetActiveWebContents()->GetPrimaryMainFrame()->GetLastCommittedURL()); } // This test verifies that Content-Security-Policy's frame-ancestors 'none' @@ -472,30 +447,35 @@ // Regression test for https://crbug.com/1107535. IN_PROC_BROWSER_TEST_P(PDFExtensionTest, CSPFrameAncestorsOverridesXFrameOptions) { - // TODO(crbug.com/1445746): Remove this once the test passes for OOPIF PDF. - if (UseOopif()) { - GTEST_SKIP(); - } - const GURL main_url( embedded_test_server()->GetURL("/pdf/frame-test-csp-and-xfo.html")); - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url)); - ASSERT_TRUE(GetActiveWebContents()); - auto* primary_main_frame = GetActiveWebContents()->GetPrimaryMainFrame(); - ASSERT_TRUE(primary_main_frame); - // Verify the pdf has loaded. - auto* guest_view = GetGuestViewManager()->WaitForSingleGuestViewCreated(); - ASSERT_TRUE(guest_view); - EXPECT_NE(primary_main_frame, guest_view->GetGuestMainFrame()); - TestMimeHandlerViewGuest::WaitForGuestLoadStartThenStop(guest_view); + content::RenderFrameHost* extension_host; + if (UseOopif()) { + extension_host = LoadPdfInFirstChildGetExtensionHost(main_url); + } else { + // The URL uses an iframe element to embed the PDF, so + // `LoadPdfInFirstChild()` can't be used here. + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url)); + + // Verify the pdf has loaded. + auto* guest_view = GetGuestViewManager()->WaitForSingleGuestViewCreated(); + ASSERT_TRUE(guest_view); + TestMimeHandlerViewGuest::WaitForGuestLoadStartThenStop(guest_view); + extension_host = guest_view->GetGuestMainFrame(); + } + ASSERT_TRUE(extension_host); + + auto* primary_main_frame = GetActiveWebContents()->GetPrimaryMainFrame(); + EXPECT_NE(primary_main_frame, extension_host); // Verify the extension was loaded. const GURL extension_url( "chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/index.html"); - EXPECT_EQ(extension_url, - guest_view->GetGuestMainFrame()->GetLastCommittedURL()); - EXPECT_EQ(main_url, primary_main_frame->GetLastCommittedURL()); + EXPECT_EQ(extension_url, extension_host->GetLastCommittedURL()); + EXPECT_EQ( + main_url, + GetActiveWebContents()->GetPrimaryMainFrame()->GetLastCommittedURL()); } class PDFExtensionLoadTest @@ -829,11 +809,6 @@ // load is handled by MimeHandlerView, and the plugin only gets the response. IN_PROC_BROWSER_TEST_P(PDFExtensionTestWithPartialLoading, PartialRedirectsFailInPlugin) { - // TODO(crbug.com/1445746): Remove this once the test passes for OOPIF PDF. - if (UseOopif()) { - GTEST_SKIP(); - } - // Should match values used by `chrome_pdf::DocumentLoaderImpl`. constexpr size_t kDefaultRequestSize = 65536; constexpr size_t kChunkCloseDistance = 10; @@ -1553,18 +1528,24 @@ } IN_PROC_BROWSER_TEST_P(PDFExtensionIsolatedContentTest, PdfAndHtml) { - // TODO(crbug.com/1445746): Remove this once the test passes for OOPIF PDF. - if (UseOopif()) { - GTEST_SKIP(); - } - content::RenderProcessHost::SetMaxRendererProcessCount(1); // Load a page with an embedded PDF and an HTML iframe, both of the same // origin. - MimeHandlerViewGuest* guest = LoadPdfGetMimeHandlerView( + const GURL main_url( embedded_test_server()->GetURL("/pdf/embed_pdf_and_html.html")); - ASSERT_TRUE(guest); + + if (UseOopif()) { + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url)); + + // The PDF embed is the second child of the HTML page. + content::RenderFrameHost* pdf_embed = + ChildFrameAt(GetActiveWebContents(), 1); + ASSERT_TRUE(GetTestPdfViewerStreamManager(GetActiveWebContents()) + ->WaitUntilPdfLoaded(pdf_embed)); + } else { + ASSERT_TRUE(LoadPdf(main_url)); + } // The PDF plugin frame and the iframe should not share renderer processes // even though they share origins. @@ -1584,11 +1565,6 @@ } IN_PROC_BROWSER_TEST_P(PDFExtensionIsolatedContentTest, DataNavigation) { - // TODO(crbug.com/1445746): Remove this once the test passes for OOPIF PDF. - if (UseOopif()) { - GTEST_SKIP(); - } - content::RenderFrameHost* extension_host = LoadPdfInFirstChildGetExtensionHost( embedded_test_server()->GetURL("/pdf/data_url_rectangles.html")); @@ -1604,11 +1580,6 @@ } IN_PROC_BROWSER_TEST_P(PDFExtensionIsolatedContentTest, HistoryNavigation) { - // TODO(crbug.com/1445746): Remove this once the test passes for OOPIF PDF. - if (UseOopif()) { - GTEST_SKIP(); - } - // Navigating to a PDF should spawn a PDF renderer process. EXPECT_TRUE(LoadPdf(embedded_test_server()->GetURL("/pdf/test.pdf"))); EXPECT_EQ(CountPDFProcesses(), 1); @@ -2699,11 +2670,6 @@ // The plugin document and the mime handler should both use the same background // color. IN_PROC_BROWSER_TEST_P(PDFExtensionTest, BackgroundColor) { - // TODO(crbug.com/1445746): Remove this once the test passes for OOPIF PDF. - if (UseOopif()) { - GTEST_SKIP(); - } - // The background color for plugins is injected when the first response // is intercepted, at which point not all the plugins have loaded. This line // ensures that the PDF plugin has loaded and the right background color is @@ -2723,11 +2689,6 @@ } IN_PROC_BROWSER_TEST_P(PDFExtensionTest, DefaultFocusForEmbeddedPDF) { - // TODO(crbug.com/1445746): Remove this once the test passes for OOPIF PDF. - if (UseOopif()) { - GTEST_SKIP(); - } - content::RenderFrameHost* extension_host = LoadPdfInFirstChildGetExtensionHost( embedded_test_server()->GetURL("/pdf/pdf_embed.html")); @@ -2743,11 +2704,6 @@ } IN_PROC_BROWSER_TEST_P(PDFExtensionTest, DefaultFocusForNonEmbeddedPDF) { - // TODO(crbug.com/1445746): Remove this once the test passes for OOPIF PDF. - if (UseOopif()) { - GTEST_SKIP(); - } - content::RenderFrameHost* extension_host = LoadPdfGetExtensionHost(embedded_test_server()->GetURL("/pdf/test.pdf")); ASSERT_TRUE(extension_host);
diff --git a/chrome/browser/pdf/pdf_extension_test_base.h b/chrome/browser/pdf/pdf_extension_test_base.h index 662cfcc3..6330fdc8 100644 --- a/chrome/browser/pdf/pdf_extension_test_base.h +++ b/chrome/browser/pdf/pdf_extension_test_base.h
@@ -59,7 +59,8 @@ // Same as `LoadPdf()` but loads URLs where the first child of the primary // main frame should be the embedder. This is a common case where an HTML page - // only embeds a single PDF. + // only embeds a single PDF. For GuestView PDF viewer, the embedder must be an + // embed element. testing::AssertionResult LoadPdfInFirstChild(const GURL& url); // Same as LoadPdf(), but also returns a pointer to the `MimeHandlerViewGuest`
diff --git a/chrome/browser/printing/web_api/web_printing_browsertest.cc b/chrome/browser/printing/web_api/web_printing_browsertest.cc index 73d2f2e2..f0b20e97 100644 --- a/chrome/browser/printing/web_api/web_printing_browsertest.cc +++ b/chrome/browser/printing/web_api/web_printing_browsertest.cc
@@ -21,6 +21,15 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/features_generated.h" +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "base/test/mock_callback.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/printing/print_job.h" +#include "chrome/browser/printing/print_job_manager.h" +#include "printing/print_settings.h" +#include "printing/printed_document.h" +#endif + #if BUILDFLAG(IS_CHROMEOS_LACROS) #include "chrome/browser/printing/local_printer_utils_chromeos.h" #include "chrome/test/chromeos/printing/mock_local_printer_chromeos.h" @@ -54,7 +63,21 @@ const pdfBlob = new Blob([pdf], {type: 'application/pdf'}); const printers = await navigator.printing.getPrinters(); - const printJob = await printers[0].printJob("Title", { data: pdfBlob }, {}); + const printJob = await printers[0].printJob("Title", { data: pdfBlob }, { + mediaCol: { + mediaSize: { + xDimension: 21000, + yDimension: 29700, + } + }, + printColorMode: "color", + multipleDocumentHandling: "separate-documents-collated-copies", + printerResolution: { + crossFeedDirectionResolution: 300, + feedDirectionResolution: 400, + units: "dots-per-inch", + }, + }); const printJobComplete = new Promise((resolve, reject) => { printJob.onjobstatechange = () => { if (printJob.attributes().jobState === $1) { @@ -70,6 +93,13 @@ using testing::_; using testing::AtMost; +#if BUILDFLAG(IS_CHROMEOS_ASH) +using testing::AllOf; +using testing::Eq; +using testing::Field; +using testing::Property; +#endif + #if BUILDFLAG(IS_CHROMEOS_LACROS) using testing::DoAll; using testing::InSequence; @@ -101,6 +131,26 @@ (override)); }; +#if BUILDFLAG(IS_CHROMEOS_ASH) +auto ValidatePrintSettings() { + // These are synced with the `kPrintScriptWithJobStatePlaceholder` script. + return AllOf( + // copies: + Property(&PrintSettings::copies, Eq(1)), + // mediaCol: + Property(&PrintSettings::requested_media, + Field(&PrintSettings::RequestedMedia::size_microns, + Eq(gfx::Size(210000, 297000)))), + // printColorMode: + Property(&PrintSettings::color, Eq(mojom::ColorModel::kColorModeColor)), + Property(&PrintSettings::title, Eq(u"Title")), + // multipleDocumentHandling: + Property(&PrintSettings::collate, Eq(true)), + // printerResolution: + Property(&PrintSettings::dpi_size, Eq(gfx::Size(300, 400)))); +} +#endif + } // namespace class WebPrintingBrowserTestBase @@ -295,6 +345,35 @@ }, "documentFormatDefault": "application/pdf", "documentFormatSupported": [ "application/pdf" ], + "mediaColDefault": { + "mediaSize": { + "xDimension": 21000, + "yDimension": 29700, + }, + "mediaSizeName": "iso_a4_210x297mm", + }, + "mediaColDatabase": [{ + "mediaSize": { + "xDimension": 21000, + "yDimension": 29700, + }, + "mediaSizeName": "iso_a4_210x297mm", + }, { + "mediaSize": { + "xDimension": 21590, + "yDimension": 27940, + }, + "mediaSizeName": "na_letter_8.5x11in", + }, { + "mediaSize": { + "xDimension": 20000, + "yDimension": { + "from": 25000, + "to": 30000, + }, + }, + "mediaSizeName": "om_200000x250000um_200x250mm", + }], "multipleDocumentHandlingDefault": "separate-documents-uncollated-copies", "multipleDocumentHandlingSupported": [ "separate-documents-uncollated-copies", @@ -339,6 +418,16 @@ IN_PROC_BROWSER_TEST_F(WebPrintingBrowserTest, Print) { #if BUILDFLAG(IS_CHROMEOS_ASH) + // Set up a matcher to validate correctness of `PrintSettings`. + base::MockRepeatingCallback<void(PrintJob*, PrintedDocument*, int)> + doc_done_cb; + EXPECT_CALL( + doc_done_cb, + Run(_, Property(&PrintedDocument::settings, ValidatePrintSettings()), _)); + auto subscription = + g_browser_process->print_job_manager()->AddDocDoneCallback( + doc_done_cb.Get()); + AddPrinterWithSemanticCaps(kId, kName, extensions::ConstructPrinterCapabilities()); #elif BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/printing/web_api/web_printing_mojom_traits.cc b/chrome/browser/printing/web_api/web_printing_mojom_traits.cc index f493f66..3f8c1c00 100644 --- a/chrome/browser/printing/web_api/web_printing_mojom_traits.cc +++ b/chrome/browser/printing/web_api/web_printing_mojom_traits.cc
@@ -9,6 +9,7 @@ #include "base/strings/utf_string_conversions.h" #include "mojo/public/cpp/bindings/type_converter.h" #include "printing/mojom/print.mojom-shared.h" +#include "printing/units.h" #include "third_party/blink/public/mojom/printing/web_printing.mojom.h" namespace mojo { @@ -48,6 +49,27 @@ } } +bool InferRequestedMedia( + blink::mojom::WebPrintJobTemplateAttributesDataView data, + printing::PrintSettings& settings) { + blink::mojom::WebPrintingMediaCollectionRequestedDataView media_col; + data.GetMediaColDataView(&media_col); + if (media_col.is_null()) { + // media-col is an optional field. + return true; + } + gfx::Size media_size; + if (!media_col.ReadMediaSize(&media_size)) { + return false; + } + // The incoming size is specified in hundredths of millimeters (PWG units) + // whereas the printing subsystem operates on microns. + settings.set_requested_media( + {.size_microns = {media_size.width() * printing::kMicronsPerPwgUnit, + media_size.height() * printing::kMicronsPerPwgUnit}}); + return true; +} + } // namespace // static @@ -208,6 +230,9 @@ break; } } + if (!InferRequestedMedia(data, *settings)) { + return false; + } if (auto mdh = data.multiple_document_handling()) { switch (*mdh) { case MultipleDocumentHandling::kSeparateDocumentsCollatedCopies:
diff --git a/chrome/browser/printing/web_api/web_printing_mojom_traits.h b/chrome/browser/printing/web_api/web_printing_mojom_traits.h index 73e9ca6..d44f95c 100644 --- a/chrome/browser/printing/web_api/web_printing_mojom_traits.h +++ b/chrome/browser/printing/web_api/web_printing_mojom_traits.h
@@ -68,6 +68,10 @@ static uint32_t copies(const std::unique_ptr<printing::PrintSettings>& ptr) { NOTREACHED_NORETURN(); } + static const blink::mojom::WebPrintingMediaCollectionRequestedPtr& media_col( + const std::unique_ptr<printing::PrintSettings>& ptr) { + NOTREACHED_NORETURN(); + } static const std::optional<blink::mojom::WebPrintingMultipleDocumentHandling>& multiple_document_handling( const std::unique_ptr<printing::PrintSettings>& ptr) {
diff --git a/chrome/browser/printing/web_api/web_printing_service_chromeos.cc b/chrome/browser/printing/web_api/web_printing_service_chromeos.cc index acec0c10..ec268e0 100644 --- a/chrome/browser/printing/web_api/web_printing_service_chromeos.cc +++ b/chrome/browser/printing/web_api/web_printing_service_chromeos.cc
@@ -48,9 +48,41 @@ return color_model != mojom::ColorModel::kUnknownColorModel; } -bool ValidatePrintJobTemplateAttributesAgainstPrinterAttributes( +bool ValidateMediaCol( const PrintSettings& pjt_attributes, const PrinterSemanticCapsAndDefaults& printer_attributes) { + // media-size / media-size-name: + const auto& media = pjt_attributes.requested_media(); + if (media.IsDefault()) { + // Means nothing has actually been requested. + return true; + } + const auto& papers = printer_attributes.papers; + // Validate that the requested paper is supported by the printer. + if (!base::ranges::any_of(papers, [&](const auto& paper) { + return paper.IsSizeWithinBounds(media.size_microns); + })) { + return false; + } + return true; +} + +void UpdatePrintJobTemplateAttributesWithPrinterDefaults( + PrintSettings& pjt_attributes, + const PrinterSemanticCapsAndDefaults& printer_attributes) { + if (!IsDuplexModeKnown(pjt_attributes.duplex_mode())) { + pjt_attributes.set_duplex_mode(printer_attributes.duplex_default); + } + if (!IsColorModelKnown(pjt_attributes.color())) { + pjt_attributes.set_color(printer_attributes.color_default + ? mojom::ColorModel::kColorModeColor + : mojom::ColorModel::kColorModeMonochrome); + } +} + +bool ValidateAttributesAndUpdateIfNecessary( + PrintSettings& pjt_attributes, + const PrinterSemanticCapsAndDefaults& printer_attributes) { if (pjt_attributes.copies() < 1 || pjt_attributes.copies() > printer_attributes.copies_max) { return false; @@ -77,22 +109,15 @@ !base::Contains(printer_attributes.dpis, pjt_attributes.dpi_size())) { return false; } + if (!ValidateMediaCol(pjt_attributes, printer_attributes)) { + return false; + } + // Update selected fields to printer defaults if they're not specified. + UpdatePrintJobTemplateAttributesWithPrinterDefaults(pjt_attributes, + printer_attributes); return true; } -void UpdatePrintJobTemplateAttributesWithPrinterDefaults( - PrintSettings* pjt_attributes, - const PrinterSemanticCapsAndDefaults& printer_attributes) { - if (!IsDuplexModeKnown(pjt_attributes->duplex_mode())) { - pjt_attributes->set_duplex_mode(printer_attributes.duplex_default); - } - if (!IsColorModelKnown(pjt_attributes->color())) { - pjt_attributes->set_color(printer_attributes.color_default - ? mojom::ColorModel::kColorModeColor - : mojom::ColorModel::kColorModeMonochrome); - } -} - blink::mojom::WebPrinterAttributesPtr MergePrinterAttributesAndStatus( blink::mojom::WebPrinterAttributesPtr printer_attributes, std::unique_ptr<PrinterStatus> printer_status) { @@ -260,15 +285,12 @@ return; } - if (!ValidatePrintJobTemplateAttributesAgainstPrinterAttributes( - *pjt_attributes, *printer_attributes)) { + if (!ValidateAttributesAndUpdateIfNecessary(*pjt_attributes, + *printer_attributes)) { std::move(callback).Run(blink::mojom::WebPrintResult::NewError( blink::mojom::WebPrintError::kPrintJobTemplateAttributesMismatch)); return; } - // Update selected fields to printer defaults if they're not specified. - UpdatePrintJobTemplateAttributesWithPrinterDefaults(pjt_attributes.get(), - *printer_attributes); pdf_flattener_->ReadAndFlattenPdf( std::move(document),
diff --git a/chrome/browser/printing/web_api/web_printing_type_converters.cc b/chrome/browser/printing/web_api/web_printing_type_converters.cc index 7278ff1e..427b07a 100644 --- a/chrome/browser/printing/web_api/web_printing_type_converters.cc +++ b/chrome/browser/printing/web_api/web_printing_type_converters.cc
@@ -7,10 +7,57 @@ #include <optional> #include "base/containers/contains.h" +#include "chrome/common/printing/print_media_l10n.h" #include "mojo/public/cpp/bindings/message.h" #include "printing/backend/print_backend.h" +#include "printing/units.h" #include "third_party/blink/public/mojom/printing/web_printing.mojom.h" +namespace { + +using MediaCollection = blink::mojom::WebPrintingMediaCollection; +using MediaCollectionPtr = blink::mojom::WebPrintingMediaCollectionPtr; +using Paper = printing::PrinterSemanticCapsAndDefaults::Paper; + +using MediaSize = blink::mojom::WebPrintingMediaSize; +using MediaSizeDimension = blink::mojom::WebPrintingMediaSizeDimension; +using Range = blink::mojom::WebPrintingRange; + +} // namespace + +namespace mojo { + +template <> +struct TypeConverter<MediaCollectionPtr, Paper> { + static MediaCollectionPtr Convert(const Paper& paper) { + // The printing subsystem operates on microns, whereas the spec-compliant + // `media_size` must be represented in hundredths of millimeters (PWG + // units). + auto media_size = MediaSize::New(); + if (paper.SupportsCustomSize()) { + media_size->y_dimension = MediaSizeDimension::NewRange( + Range::New(paper.size_um().height() / printing::kMicronsPerPwgUnit, + paper.max_height_um() / printing::kMicronsPerPwgUnit)); + } else { + media_size->y_dimension = MediaSizeDimension::NewValue( + paper.size_um().height() / printing::kMicronsPerPwgUnit); + } + // `Paper` struct doesn't provide information about variable width + // (moreover, papers with variable width are silently discarded by + // ChromeOS). Hence `x_dimension` is always a single value. + media_size->x_dimension = MediaSizeDimension::NewValue( + paper.size_um().width() / printing::kMicronsPerPwgUnit); + + auto media_col = MediaCollection::New(); + media_col->media_size = std::move(media_size); + media_col->media_size_name = + printing::LocalizePaperDisplayName(paper.size_um()).vendor_id; + return media_col; + } +}; + +} // namespace mojo + namespace printing { namespace { @@ -38,6 +85,14 @@ blink::mojom::WebPrintingRange::New(1, caps.copies_max); } +void ProcessMediaCollection(const PrinterSemanticCapsAndDefaults& caps, + blink::mojom::WebPrinterAttributes* attributes) { + attributes->media_col_default = + mojo::ConvertTo<MediaCollectionPtr>(caps.default_paper); + attributes->media_col_database = + mojo::ConvertTo<std::vector<MediaCollectionPtr>>(caps.papers); +} + void ProcessMultipleDocumentHandling( const PrinterSemanticCapsAndDefaults& caps, blink::mojom::WebPrinterAttributes* attributes) { @@ -122,6 +177,7 @@ auto attributes = blink::mojom::WebPrinterAttributes::New(); printing::ProcessCopies(capabilities, attributes.get()); + printing::ProcessMediaCollection(capabilities, attributes.get()); printing::ProcessMultipleDocumentHandling(capabilities, attributes.get()); printing::ProcessOrientationRequested(capabilities, attributes.get()); printing::ProcessPrinterResolution(capabilities, attributes.get());
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudIPHController.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudIPHController.java index 15d6dc6..c1957b9 100644 --- a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudIPHController.java +++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudIPHController.java
@@ -86,8 +86,8 @@ new IPHCommandBuilder( mToolbarMenuButton.getContext().getResources(), FeatureConstants.READ_ALOUD_APP_MENU_FEATURE, - R.string.menu_listen_to_this_page, - R.string.menu_listen_to_this_page) + R.string.menu_listen_to_this_page_iph, + R.string.menu_listen_to_this_page_iph) .setAnchorView(mToolbarMenuButton) .setOnShowCallback(() -> turnOnHighlightForMenuItem(R.id.readaloud_menu_id)) .setOnDismissCallback(this::turnOffHighlightForMenuItem)
diff --git a/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc b/chrome/browser/renderer_context_menu/read_write_card_observer.cc similarity index 79% rename from chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc rename to chrome/browser/renderer_context_menu/read_write_card_observer.cc index 4089adc63..177e352 100644 --- a/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc +++ b/chrome/browser/renderer_context_menu/read_write_card_observer.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/renderer_context_menu/quick_answers_menu_observer.h" +#include "chrome/browser/renderer_context_menu/read_write_card_observer.h" #include <utility> #include <vector> @@ -22,14 +22,13 @@ } // namespace -QuickAnswersMenuObserver::QuickAnswersMenuObserver( - RenderViewContextMenuProxy* proxy, - Profile* profile) +ReadWriteCardObserver::ReadWriteCardObserver(RenderViewContextMenuProxy* proxy, + Profile* profile) : proxy_(proxy), profile_(profile) {} -QuickAnswersMenuObserver::~QuickAnswersMenuObserver() = default; +ReadWriteCardObserver::~ReadWriteCardObserver() = default; -void QuickAnswersMenuObserver::OnContextMenuShown( +void ReadWriteCardObserver::OnContextMenuShown( const content::ContextMenuParams& params, const gfx::Rect& bounds_in_screen) { chromeos::ReadWriteCardsManager* cards_manager = @@ -38,11 +37,11 @@ cards_manager->FetchController( params, proxy_->GetBrowserContext(), - base::BindOnce(&QuickAnswersMenuObserver::OnFetchControllers, + base::BindOnce(&ReadWriteCardObserver::OnFetchControllers, weak_factory_.GetWeakPtr(), params, bounds_in_screen)); } -void QuickAnswersMenuObserver::OnContextMenuViewBoundsChanged( +void ReadWriteCardObserver::OnContextMenuViewBoundsChanged( const gfx::Rect& bounds_in_screen) { for (auto controller : read_write_card_controllers_) { if (!controller) { @@ -55,7 +54,7 @@ } } -void QuickAnswersMenuObserver::OnMenuClosed() { +void ReadWriteCardObserver::OnMenuClosed() { for (auto controller : read_write_card_controllers_) { if (!controller) { continue; @@ -68,11 +67,11 @@ is_other_command_executed_ = false; } -void QuickAnswersMenuObserver::CommandWillBeExecuted(int command_id) { +void ReadWriteCardObserver::CommandWillBeExecuted(int command_id) { is_other_command_executed_ = true; } -void QuickAnswersMenuObserver::OnTextSurroundingSelectionAvailable( +void ReadWriteCardObserver::OnTextSurroundingSelectionAvailable( const std::u16string& selected_text, const std::u16string& surrounding_text, uint32_t start_offset, @@ -88,7 +87,7 @@ } } -void QuickAnswersMenuObserver::OnFetchControllers( +void ReadWriteCardObserver::OnFetchControllers( const content::ContextMenuParams& params, const gfx::Rect& bounds_in_screen, std::vector<base::WeakPtr<chromeos::ReadWriteCardController>> controllers) { @@ -116,7 +115,7 @@ if (focused_frame) { focused_frame->RequestTextSurroundingSelection( base::BindOnce( - &QuickAnswersMenuObserver::OnTextSurroundingSelectionAvailable, + &ReadWriteCardObserver::OnTextSurroundingSelectionAvailable, weak_factory_.GetWeakPtr(), params.selection_text), kMaxSurroundingTextLength); }
diff --git a/chrome/browser/renderer_context_menu/quick_answers_menu_observer.h b/chrome/browser/renderer_context_menu/read_write_card_observer.h similarity index 69% rename from chrome/browser/renderer_context_menu/quick_answers_menu_observer.h rename to chrome/browser/renderer_context_menu/read_write_card_observer.h index f427b1ec..9d13b2c 100644 --- a/chrome/browser/renderer_context_menu/quick_answers_menu_observer.h +++ b/chrome/browser/renderer_context_menu/read_write_card_observer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_RENDERER_CONTEXT_MENU_QUICK_ANSWERS_MENU_OBSERVER_H_ -#define CHROME_BROWSER_RENDERER_CONTEXT_MENU_QUICK_ANSWERS_MENU_OBSERVER_H_ +#ifndef CHROME_BROWSER_RENDERER_CONTEXT_MENU_READ_WRITE_CARD_OBSERVER_H_ +#define CHROME_BROWSER_RENDERER_CONTEXT_MENU_READ_WRITE_CARD_OBSERVER_H_ #include <memory> #include <string> @@ -21,14 +21,15 @@ class ReadWriteCardController; } // namespace chromeos -// A class that implements the quick answers menu. -class QuickAnswersMenuObserver : public RenderViewContextMenuObserver { +// A class that observes context menu actions and notify all the associated +// `ReadWriteCardController` about the events. +class ReadWriteCardObserver : public RenderViewContextMenuObserver { public: - QuickAnswersMenuObserver(const QuickAnswersMenuObserver&) = delete; - QuickAnswersMenuObserver& operator=(const QuickAnswersMenuObserver&) = delete; + ReadWriteCardObserver(const ReadWriteCardObserver&) = delete; + ReadWriteCardObserver& operator=(const ReadWriteCardObserver&) = delete; - QuickAnswersMenuObserver(RenderViewContextMenuProxy* proxy, Profile* profile); - ~QuickAnswersMenuObserver() override; + ReadWriteCardObserver(RenderViewContextMenuProxy* proxy, Profile* profile); + ~ReadWriteCardObserver() override; // RenderViewContextMenuObserver implementation. void CommandWillBeExecuted(int command_id) override; @@ -39,7 +40,7 @@ void OnMenuClosed() override; private: - friend class QuickAnswersMenuObserverTest; + friend class ReadWriteCardObserverTest; void OnTextSurroundingSelectionAvailable( const std::u16string& selected_text, @@ -67,7 +68,7 @@ std::vector<raw_ptr<chromeos::ReadWriteCardController>> read_write_card_controllers_; - base::WeakPtrFactory<QuickAnswersMenuObserver> weak_factory_{this}; + base::WeakPtrFactory<ReadWriteCardObserver> weak_factory_{this}; }; -#endif // CHROME_BROWSER_RENDERER_CONTEXT_MENU_QUICK_ANSWERS_MENU_OBSERVER_H_ +#endif // CHROME_BROWSER_RENDERER_CONTEXT_MENU_READ_WRITE_CARD_OBSERVER_H_
diff --git a/chrome/browser/renderer_context_menu/quick_answers_menu_observer_unittest.cc b/chrome/browser/renderer_context_menu/read_write_card_observer_unittest.cc similarity index 84% rename from chrome/browser/renderer_context_menu/quick_answers_menu_observer_unittest.cc rename to chrome/browser/renderer_context_menu/read_write_card_observer_unittest.cc index 5e318de..a97d0888 100644 --- a/chrome/browser/renderer_context_menu/quick_answers_menu_observer_unittest.cc +++ b/chrome/browser/renderer_context_menu/read_write_card_observer_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/renderer_context_menu/quick_answers_menu_observer.h" +#include "chrome/browser/renderer_context_menu/read_write_card_observer.h" #include <cstddef> #include <memory> @@ -73,22 +73,22 @@ } // namespace -class QuickAnswersMenuObserverTest : public ChromeRenderViewHostTestHarness { +class ReadWriteCardObserverTest : public ChromeRenderViewHostTestHarness { public: - QuickAnswersMenuObserverTest() = default; + ReadWriteCardObserverTest() = default; - QuickAnswersMenuObserverTest(const QuickAnswersMenuObserverTest&) = delete; - QuickAnswersMenuObserverTest& operator=(const QuickAnswersMenuObserverTest&) = + ReadWriteCardObserverTest(const ReadWriteCardObserverTest&) = delete; + ReadWriteCardObserverTest& operator=(const ReadWriteCardObserverTest&) = delete; - ~QuickAnswersMenuObserverTest() override = default; + ~ReadWriteCardObserverTest() override = default; void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); context_menu_ = CreateContextMenu(web_contents()); - observer_ = std::make_unique<QuickAnswersMenuObserver>(context_menu_.get(), - profile()); + observer_ = + std::make_unique<ReadWriteCardObserver>(context_menu_.get(), profile()); auto controllers = InitControllers(); @@ -110,7 +110,7 @@ protected: std::vector<std::unique_ptr<TestReadWriteCardController>> controllers_; - std::unique_ptr<QuickAnswersMenuObserver> observer_; + std::unique_ptr<ReadWriteCardObserver> observer_; private: std::vector<base::WeakPtr<chromeos::ReadWriteCardController>> @@ -132,7 +132,7 @@ // Make sure that all controllers are fetched into the class after // `OnFetchControllers`. -TEST_F(QuickAnswersMenuObserverTest, FetchController) { +TEST_F(ReadWriteCardObserverTest, FetchController) { EXPECT_EQ(controllers_.size(), GetReadWriteCardControllers().size()); EXPECT_FALSE(controllers_.empty()); @@ -141,14 +141,14 @@ } } -TEST_F(QuickAnswersMenuObserverTest, BoundsChanged) { +TEST_F(ReadWriteCardObserverTest, BoundsChanged) { observer_->OnContextMenuViewBoundsChanged(/*bounds_in_screen=*/gfx::Rect()); for (auto& controller : controllers_) { EXPECT_TRUE(controller->on_anchor_bounds_changed_called()); } } -TEST_F(QuickAnswersMenuObserverTest, OnMenuClosed) { +TEST_F(ReadWriteCardObserverTest, OnMenuClosed) { observer_->OnMenuClosed(); for (auto& controller : controllers_) { EXPECT_TRUE(controller->on_dismiss_called());
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index aae767a..93466423 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -286,6 +286,7 @@ #if BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES) #include "chrome/browser/lens/region_search/lens_region_search_controller.h" +#include "chrome/browser/ui/lens/lens_overlay_controller.h" #include "chrome/browser/ui/lens/lens_side_panel_helper.h" #include "chrome/grit/theme_resources.h" #include "ui/base/resource/resource_bundle.h" @@ -300,7 +301,7 @@ #include "chrome/browser/chromeos/arc/start_smart_selection_action_menu.h" #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h" #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.h" -#include "chrome/browser/renderer_context_menu/quick_answers_menu_observer.h" +#include "chrome/browser/renderer_context_menu/read_write_card_observer.h" #include "chromeos/constants/chromeos_features.h" #include "chromeos/ui/clipboard_history/clipboard_history_submenu_model.h" #include "chromeos/ui/clipboard_history/clipboard_history_util.h" @@ -1323,10 +1324,10 @@ menu_model_.RemoveItemAt(0); } - // Always add Quick Answers view last, as it is rendered next to the context + // Always add read write cards UI last, as it is rendered next to the context // menu, meaning that each menu item added/removed in this function will cause // it to visibly jump on the screen (see b/173569669). - AppendQuickAnswersItems(); + AppendReadWriteCardItems(); if (base::FeatureList::IsEnabled( autofill::features::kAutofillPopupDoesNotOverlapWithContextMenu)) { @@ -1892,15 +1893,15 @@ #endif } -void RenderViewContextMenu::AppendQuickAnswersItems() { +void RenderViewContextMenu::AppendReadWriteCardItems() { #if BUILDFLAG(IS_CHROMEOS) - if (!quick_answers_menu_observer_) { - quick_answers_menu_observer_ = - std::make_unique<QuickAnswersMenuObserver>(this, GetProfile()); + if (!read_write_card_observer_) { + read_write_card_observer_ = + std::make_unique<ReadWriteCardObserver>(this, GetProfile()); } - observers_.AddObserver(quick_answers_menu_observer_.get()); - quick_answers_menu_observer_->InitMenu(params_); + observers_.AddObserver(read_write_card_observer_.get()); + read_write_card_observer_->InitMenu(params_); #endif } @@ -4273,6 +4274,15 @@ return; } + if (is_google_default_search_provider && + lens::features::IsLensOverlayEnabled()) { + browser->tab_strip_model() + ->GetActiveTab() + ->lens_overlay_controller() + ->ShowUI(); + return; + } + // We don't use `source_web_contents_` here because it doesn't work with the // PDF reader. WebContents* web_contents =
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.h b/chrome/browser/renderer_context_menu/render_view_context_menu.h index b49ccaa5..e83fec15 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.h +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.h
@@ -63,7 +63,7 @@ class LinkToTextMenuObserver; class PrintPreviewContextMenuObserver; class Profile; -class QuickAnswersMenuObserver; +class ReadWriteCardObserver; class SpellingMenuObserver; class SpellingOptionsSubMenuObserver; #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) @@ -283,7 +283,7 @@ void AppendOpenWithLinkItems(); void AppendSmartSelectionActionItems(); void AppendOpenInWebAppLinkItems(); - void AppendQuickAnswersItems(); + void AppendReadWriteCardItems(); void AppendImageItems(); void AppendAudioItems(); void AppendCanvasItems(); @@ -499,8 +499,8 @@ // An observer that handles smart text selection action items. std::unique_ptr<RenderViewContextMenuObserver> start_smart_selection_action_menu_observer_; - // An observer that generate Quick answers queries. - std::unique_ptr<QuickAnswersMenuObserver> quick_answers_menu_observer_; + // An observer that populates events to read write cards. + std::unique_ptr<ReadWriteCardObserver> read_write_card_observer_; // A submenu model to contain clipboard history item descriptors. Used only if // the clipboard history refresh feature is enabled.
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc index 9e8177d7..6b13041 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -171,6 +171,8 @@ #endif #if BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES) +#include "base/test/run_until.h" +#include "chrome/browser/ui/lens/lens_overlay_controller.h" #include "chrome/browser/ui/lens/lens_side_panel_helper.h" #include "ui/events/test/event_generator.h" #endif @@ -2644,6 +2646,57 @@ EXPECT_EQ(new_tab_content, expected_content); } +class LensOverlayBrowserTest : public SearchByRegionBrowserBaseTest { + protected: + void SetUp() override { + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeatures({lens::features::kLensOverlay}, {}); + + // This does not use SearchByRegionBrowserBaseTest::SetUp because that + // function does its own conflicting initialization of a FeatureList. + InProcessBrowserTest::SetUp(); + } + + void OpenContextMenuAndClickRegionSearchEntrypoint( + ContextMenuNotificationObserver::MenuShownCallback callback) { + // |menu_observer_| will cause the search lens for image menu item to be + // clicked. + menu_observer_ = std::make_unique<ContextMenuNotificationObserver>( + IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH, ui::EF_MOUSE_BUTTON, + std::move(callback)); + RightClickToOpenContextMenu(); + } +}; + +IN_PROC_BROWSER_TEST_F(LensOverlayBrowserTest, + RegionSearchContextMenuOpensLensOverlay) { + // State should start in off. + auto* controller = + browser()->tab_strip_model()->GetActiveTab()->lens_overlay_controller(); + ASSERT_EQ(controller->state(), LensOverlayController::State::kOff); + + OpenContextMenuAndClickRegionSearchEntrypoint(base::NullCallback()); + + // Clicking the region search entrypoint should eventually result in overlay + // state. + ASSERT_TRUE(base::test::RunUntil([&]() { + return controller->state() == LensOverlayController::State::kOverlay; + })); +} + +IN_PROC_BROWSER_TEST_F(LensOverlayBrowserTest, + RegionSearchContextMenuDoesNotOpenRegionSearch) { + OpenContextMenuAndClickRegionSearchEntrypoint( + // Callback that will be called after the context menu item is clicked. + base::BindLambdaForTesting([&](RenderViewContextMenu* menu) { + // Verify the normal region search flow does not activate + lens::LensRegionSearchController* controller = + menu->GetLensRegionSearchControllerForTesting(); + ASSERT_EQ(controller, nullptr); + })); + base::RunLoop().RunUntilIdle(); +} + #endif // BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES) #if BUILDFLAG(ENABLE_PDF)
diff --git a/chrome/browser/resources/ash/settings/os_printing_page/cups_printers.html b/chrome/browser/resources/ash/settings/os_printing_page/cups_printers.html index cefa5e9..a77ce66 100644 --- a/chrome/browser/resources/ash/settings/os_printing_page/cups_printers.html +++ b/chrome/browser/resources/ash/settings/os_printing_page/cups_printers.html
@@ -17,7 +17,7 @@ padding: 20px; } - #addManualPrinterButtonRevamp { + #addManualPrinterButton { background: none; } @@ -66,7 +66,7 @@ pointer-events: none; } - #nearbyPrintersRevamp { + #nearbyPrinters { display: flex; } @@ -120,12 +120,12 @@ padding-inline-start: 20px; } - #addPrinterSectionRevamp { + #addPrinterSection { height: 64px; padding-inline: 0; } - #addPrinterSectionRevampContainer { + #addPrinterSectionContainer { padding-inline-start: 10px; padding-top: 8px; } @@ -245,10 +245,10 @@ active-printer="{{activePrinter}}" printers-count="{{nearbyPrinterCount_}}"> </settings-cups-nearby-printers> - <div id="addPrinterSectionRevamp" class="list-frame add-printer-section"> - <div id="addPrinterSectionRevampContainer" + <div id="addPrinterSection" class="list-frame add-printer-section"> + <div id="addPrinterSectionContainer" class="layout horizontal center custom-list-item-top"> - <cr-button id="addManualPrinterButtonRevamp" + <cr-button id="addManualPrinterButton" class="prefix-icon" on-click="onAddPrinterClick_" disabled="[[!addPrinterButtonActive_(hasActiveNetworkConnection, prefs.native_printing.user_native_printers_allowed.value)]]"
diff --git a/chrome/browser/resources/ash/settings/os_printing_page/cups_printers.ts b/chrome/browser/resources/ash/settings/os_printing_page/cups_printers.ts index 2f54a375..953c2ef 100644 --- a/chrome/browser/resources/ash/settings/os_printing_page/cups_printers.ts +++ b/chrome/browser/resources/ash/settings/os_printing_page/cups_printers.ts
@@ -471,7 +471,7 @@ private onAddPrinterDialogClose_(): void { const icon = this.shadowRoot!.querySelector<CrIconButtonElement>( - '#addManualPrinterButtonRevamp'); + '#addManualPrinterButton'); assert(icon); focusWithoutInk(icon); }
diff --git a/chrome/browser/resources/ash/settings/os_settings_routes.ts b/chrome/browser/resources/ash/settings/os_settings_routes.ts index fde3ec4..5a7271b 100644 --- a/chrome/browser/resources/ash/settings/os_settings_routes.ts +++ b/chrome/browser/resources/ash/settings/os_settings_routes.ts
@@ -321,10 +321,11 @@ if (!isGuest()) { r.OS_PEOPLE = createSection( r.BASIC, routesMojom.PEOPLE_SECTION_PATH, Section.kPeople); - r.ACCOUNT_MANAGER = createSubpage( - r.OS_PEOPLE, routesMojom.MY_ACCOUNTS_SUBPAGE_PATH, Subpage.kMyAccounts); if (!isRevampWayfindingEnabled()) { + r.ACCOUNT_MANAGER = createSubpage( + r.OS_PEOPLE, routesMojom.MY_ACCOUNTS_SUBPAGE_PATH, + Subpage.kMyAccounts); // TODO(b/305747266) : Disambiguate the names for OS_SYNC and SYNC. r.OS_SYNC = createSubpage( r.OS_PEOPLE, routesMojom.SYNC_SUBPAGE_PATH, Subpage.kSync);
diff --git a/chrome/browser/resources/new_tab_page/app.html b/chrome/browser/resources/new_tab_page/app.html index 3026d95..d343309 100644 --- a/chrome/browser/resources/new_tab_page/app.html +++ b/chrome/browser/resources/new_tab_page/app.html
@@ -338,6 +338,56 @@ } } + :host([wallpaper-search-button-animation-enabled_]) + #wallpaperSearchButtonContainer { + animation: 750ms forwards grow; + opacity: 0; + right: 0px; + transform-origin: right; + } + + @keyframes grow { + from { + opacity: 0; + right: 0px; + transform: scale(0.8); + } + to { + opacity: 100%; + right: 40px; + transform: scale(1); + } + } + + :host([wallpaper-search-button-animation-enabled_]) + #wallpaperSearchIcon { + animation: 2.5s 350ms spin; + } + + @keyframes spin { + from { + transform:rotate(0deg); + } + to { + transform:rotate(720deg); + } + } + + :host([wallpaper-search-button-animation-enabled_]) + #wallpaperSearchText { + animation: 500ms forwards 300ms show; + opacity: 0; + } + + @keyframes show { + from { + opacity: 0; + } + to { + opacity: 100%; + } + } + #themeAttribution { align-self: flex-start; bottom: 16px; @@ -527,7 +577,8 @@ aria-pressed="[[showWallpaperSearch_]]"> <div id="wallpaperSearchIcon" class="customize-icon" slot="prefix-icon"></div> - <div class="customize-text" hidden$="[[showWallpaperSearch_]]"> + <div id="wallpaperSearchText" class="customize-text" + hidden$="[[showWallpaperSearch_]]"> $i18n{wallpaperSearchButton} </div> </cr-button>
diff --git a/chrome/browser/resources/new_tab_page/app.ts b/chrome/browser/resources/new_tab_page/app.ts index 2d817611..67d889e 100644 --- a/chrome/browser/resources/new_tab_page/app.ts +++ b/chrome/browser/resources/new_tab_page/app.ts
@@ -335,6 +335,13 @@ value: document.documentElement.scrollTop <= 0, }, + wallpaperSearchButtonAnimationEnabled_: { + type: Boolean, + value: () => + loadTimeData.getBoolean('wallpaperSearchButtonAnimationEnabled'), + reflectToAttribute: true, + }, + wallpaperSearchButtonEnabled_: { type: Boolean, value: () => loadTimeData.getBoolean('wallpaperSearchButtonEnabled'), @@ -382,6 +389,7 @@ private promoAndModulesLoaded_: boolean; private lazyRender_: boolean; private scrolledToTop_: boolean; + private wallpaperSearchButtonAnimationEnabled_: boolean; private wallpaperSearchButtonEnabled_: boolean; private callbackRouter_: PageCallbackRouter;
diff --git a/chrome/browser/resources/side_panel/read_anything/app.ts b/chrome/browser/resources/side_panel/read_anything/app.ts index a9cf8a3..ec664dc 100644 --- a/chrome/browser/resources/side_panel/read_anything/app.ts +++ b/chrome/browser/resources/side_panel/read_anything/app.ts
@@ -1286,14 +1286,16 @@ if (this.chromeRefresh2023Enabled_ && (colorSuffix === '')) { return 'var(--color-sys-state-hover-on-subtle)'; } - return `var(--color-current-read-aloud-highlight${colorSuffix})`; + return `var(--color-read-anything-current-read-aloud-highlight${ + colorSuffix})`; } getPreviousHighlightColorVar(colorSuffix: string) { if (this.chromeRefresh2023Enabled_ && (colorSuffix === '')) { return 'var(--color-sys-on-surface-secondary)'; } - return `var(--color-previous-read-aloud-highlight${colorSuffix})`; + return `var(--color-read-anything-previous-read-aloud-highlight${ + colorSuffix})`; } getBackgroundColorVar(colorSuffix: string) {
diff --git a/chrome/browser/resources/tab_search/tab_organization_group.html b/chrome/browser/resources/tab_search/tab_organization_group.html index bf9b926..07bb8d2b 100644 --- a/chrome/browser/resources/tab_search/tab_organization_group.html +++ b/chrome/browser/resources/tab_search/tab_organization_group.html
@@ -139,6 +139,7 @@ </iron-selector> <template is="dom-if" if="[[!multiTabOrganization]]"> <tab-organization-results-actions + show-refresh="[[refreshButtonEnabled_]]" is-last-organization="[[isLastOrganization]]" on-create-group-click="onCreateGroupClick_" on-reject-click="onRejectGroupClick_">
diff --git a/chrome/browser/resources/tab_search/tab_organization_group.ts b/chrome/browser/resources/tab_search/tab_organization_group.ts index 76ddd68..c1032fb 100644 --- a/chrome/browser/resources/tab_search/tab_organization_group.ts +++ b/chrome/browser/resources/tab_search/tab_organization_group.ts
@@ -53,6 +53,12 @@ value: 0, }, + refreshButtonEnabled_: { + type: Boolean, + value: () => + loadTimeData.getBoolean('tabOrganizationRefreshButtonEnabled'), + }, + showInput_: Boolean, tabDatas_: { @@ -70,6 +76,7 @@ organizationId: number; private lastFocusedIndex_: number; + private refreshButtonEnabled_: boolean; private showInput_: boolean; private tabDatas_: TabData[];
diff --git a/chrome/browser/resources/tab_search/tab_organization_page.html b/chrome/browser/resources/tab_search/tab_organization_page.html index 1b150789..f89bd1e 100644 --- a/chrome/browser/resources/tab_search/tab_organization_page.html +++ b/chrome/browser/resources/tab_search/tab_organization_page.html
@@ -70,7 +70,9 @@ multi-tab-organization="[[multiTabOrganization_]]" available-height="[[availableHeight_]]" on-reject-click="onRejectClick_" + on-reject-all-groups-click="onRejectAllGroupsClick_" on-create-group-click="onCreateGroupClick_" + on-create-all-groups-click="onCreateAllGroupsClick_" on-remove-tab="onRemoveTab_" on-learn-more-click="onLearnMoreClick_" on-feedback="onFeedback_">
diff --git a/chrome/browser/resources/tab_search/tab_organization_page.ts b/chrome/browser/resources/tab_search/tab_organization_page.ts index a0819fa..bcb86aa 100644 --- a/chrome/browser/resources/tab_search/tab_organization_page.ts +++ b/chrome/browser/resources/tab_search/tab_organization_page.ts
@@ -246,6 +246,10 @@ this.session_!.sessionId, event.detail.organizationId); } + private onRejectAllGroupsClick_() { + this.apiProxy_.rejectSession(this.session_!.sessionId); + } + private onCreateGroupClick_( event: CustomEvent<{organizationId: number, name: string, tabs: Tab[]}>) { this.apiProxy_.acceptTabOrganization( @@ -253,6 +257,16 @@ event.detail.name, event.detail.tabs); } + private onCreateAllGroupsClick_(event: CustomEvent<{ + organizations: Array<{organizationId: number, name: string, tabs: Tab[]}>, + }>) { + event.detail.organizations.forEach((organization) => { + this.apiProxy_.acceptTabOrganization( + this.session_!.sessionId, organization.organizationId, + organization.name, organization.tabs); + }); + } + private onCheckNow_() { this.apiProxy_.restartSession(); }
diff --git a/chrome/browser/resources/tab_search/tab_organization_results.html b/chrome/browser/resources/tab_search/tab_organization_results.html index 2ad83b0..6ce6acfd3d 100644 --- a/chrome/browser/resources/tab_search/tab_organization_results.html +++ b/chrome/browser/resources/tab_search/tab_organization_results.html
@@ -49,7 +49,7 @@ </template> </div> <template is="dom-if" if="[[multiTabOrganization]]"> - <tab-organization-results-actions + <tab-organization-results-actions show-refresh multiple-organizations="[[hasMultipleOrganizations_(session)]]" on-create-group-click="onCreateAllGroupsClick_" on-reject-click="onRejectAllGroupsClick_">
diff --git a/chrome/browser/resources/tab_search/tab_organization_results.ts b/chrome/browser/resources/tab_search/tab_organization_results.ts index 54863c3..e9058ea 100644 --- a/chrome/browser/resources/tab_search/tab_organization_results.ts +++ b/chrome/browser/resources/tab_search/tab_organization_results.ts
@@ -17,6 +17,7 @@ import type {IronSelectorElement} from 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import type {TabOrganizationGroupElement} from './tab_organization_group.js'; import {getTemplate} from './tab_organization_results.html.js'; import type {TabOrganization, TabOrganizationSession} from './tab_search.mojom-webui.js'; @@ -123,13 +124,31 @@ private onCreateAllGroupsClick_(event: CustomEvent) { event.stopPropagation(); event.preventDefault(); - // TODO(b/324942857): Implement + + const groups = + [...this.shadowRoot!.querySelectorAll('tab-organization-group')]; + const organizations = groups.map((group: TabOrganizationGroupElement) => { + return { + organizationId: group.organizationId, + name: group.name, + tabs: group.tabs, + }; + }); + + this.dispatchEvent(new CustomEvent('create-all-groups-click', { + bubbles: true, + composed: true, + detail: {organizations}, + })); } private onRejectAllGroupsClick_(event: CustomEvent) { event.stopPropagation(); event.preventDefault(); - // TODO(b/324944497): Implement + this.dispatchEvent(new CustomEvent('reject-all-groups-click', { + bubbles: true, + composed: true, + })); } private onLearnMoreClick_() {
diff --git a/chrome/browser/resources/tab_search/tab_organization_results_actions.html b/chrome/browser/resources/tab_search/tab_organization_results_actions.html index b098ba19..d0b82ed 100644 --- a/chrome/browser/resources/tab_search/tab_organization_results_actions.html +++ b/chrome/browser/resources/tab_search/tab_organization_results_actions.html
@@ -11,12 +11,14 @@ </style> <div class="button-row"> - <template is="dom-if" if="[[showRefresh_]]"> - <cr-button class="tonal-button" on-click="onRejectGroupClick_"> + <template is="dom-if" if="[[showRefresh]]"> + <cr-button id="refreshButton" class="tonal-button" + on-click="onRejectGroupClick_"> [[getRefreshButtonText_(isLastOrganization, multipleOrganizations)]] </cr-button> </template> - <cr-button class="action-button" on-click="onCreateGroupClick_"> + <cr-button id="createButton" class="action-button" + on-click="onCreateGroupClick_"> [[getCreateButtonText_(multipleOrganizations)]] </cr-button> </div>
diff --git a/chrome/browser/resources/tab_search/tab_organization_results_actions.ts b/chrome/browser/resources/tab_search/tab_organization_results_actions.ts index fc006be..14b34404 100644 --- a/chrome/browser/resources/tab_search/tab_organization_results_actions.ts +++ b/chrome/browser/resources/tab_search/tab_organization_results_actions.ts
@@ -2,6 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** + * @fileoverview 'tab-organization-results-actions' is a row with actions that + * can be taken on a tab organization suggestion. It is agnostic as to what + * that suggestion is, and can be used to suggest one or multiple groups. + */ + import 'chrome://resources/cr_elements/cr_button/cr_button.js'; import './strings.m.js'; @@ -19,19 +25,13 @@ return { isLastOrganization: Boolean, multipleOrganizations: Boolean, - - showRefresh_: { - type: Boolean, - value: () => - loadTimeData.getBoolean('tabOrganizationRefreshButtonEnabled'), - }, + showRefresh: Boolean, }; } isLastOrganization: boolean; multipleOrganizations: boolean; - - private showRefresh_: boolean; + showRefresh: boolean; static get template() { return getTemplate();
diff --git a/chrome/browser/resources/tab_search/tab_search_api_proxy.ts b/chrome/browser/resources/tab_search/tab_search_api_proxy.ts index f98597c..77834016 100644 --- a/chrome/browser/resources/tab_search/tab_search_api_proxy.ts +++ b/chrome/browser/resources/tab_search/tab_search_api_proxy.ts
@@ -34,6 +34,8 @@ requestTabOrganization(): void; + rejectSession(sessionId: number): void; + restartSession(): void; switchToTab(info: SwitchToTabInfo): void; @@ -118,6 +120,10 @@ this.handler.requestTabOrganization(); } + rejectSession(sessionId: number) { + this.handler.rejectSession(sessionId); + } + restartSession() { this.handler.restartSession(); }
diff --git a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.cc b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.cc index f005cd7..2c04e9c 100644 --- a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.cc +++ b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.cc
@@ -109,11 +109,12 @@ void ChromeEnterpriseRealTimeUrlLookupService::GetAccessToken( const GURL& url, RTLookupResponseCallback response_callback, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) { + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + SessionID tab_id) { token_fetcher_->Start(base::BindOnce( &ChromeEnterpriseRealTimeUrlLookupService::OnGetAccessToken, weak_factory_.GetWeakPtr(), url, std::move(response_callback), - std::move(callback_task_runner), base::TimeTicks::Now())); + std::move(callback_task_runner), base::TimeTicks::Now(), tab_id)); } void ChromeEnterpriseRealTimeUrlLookupService::OnGetAccessToken( @@ -121,10 +122,11 @@ RTLookupResponseCallback response_callback, scoped_refptr<base::SequencedTaskRunner> callback_task_runner, base::TimeTicks get_token_start_time, + SessionID tab_id, const std::string& access_token) { SendRequest(url, access_token, std::move(response_callback), std::move(callback_task_runner), - /* is_sampled_report */ false); + /* is_sampled_report */ false, tab_id); } std::optional<std::string>
diff --git a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.h b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.h index 12752c6..2237e1f6 100644 --- a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.h +++ b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.h
@@ -72,7 +72,8 @@ void GetAccessToken( const GURL& url, RTLookupResponseCallback response_callback, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) override; + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + SessionID tab_id) override; // Called when the access token is obtained from |token_fetcher_|. void OnGetAccessToken( @@ -80,6 +81,7 @@ RTLookupResponseCallback response_callback, scoped_refptr<base::SequencedTaskRunner> callback_task_runner, base::TimeTicks get_token_start_time, + SessionID tab_id, const std::string& access_token); std::optional<std::string> GetDMTokenString() const override;
diff --git a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_unittest.cc b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_unittest.cc index 12dde47..85778d7 100644 --- a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_unittest.cc
@@ -62,6 +62,11 @@ event_outermost_main_frame_id, int user_gesture_count_limit, ReferrerChain* out_referrer_chain)); + MOCK_METHOD4(IdentifyReferrerChainByEventURL, + AttributionResult(const GURL& event_url, + SessionID event_tab_id, + int user_gesture_count_limit, + ReferrerChain* out_referrer_chain)); MOCK_METHOD3(IdentifyReferrerChainByPendingEventURL, AttributionResult(const GURL& event_url, int user_gesture_count_limit, @@ -240,7 +245,8 @@ request_callback; base::MockCallback<RTLookupResponseCallback> response_callback; enterprise_rt_service()->StartLookup(url, response_callback.Get(), - content::GetIOThreadTaskRunner({})); + content::GetIOThreadTaskRunner({}), + SessionID::InvalidValue()); test_url_loader_factory_.SetInterceptor(request_callback.Get()); EXPECT_CALL(request_callback, Run(_)).Times(0); @@ -266,7 +272,8 @@ base::MockCallback<RTLookupResponseCallback> response_callback; enterprise_rt_service()->StartLookup(url, response_callback.Get(), - content::GetIOThreadTaskRunner({})); + content::GetIOThreadTaskRunner({}), + SessionID::InvalidValue()); EXPECT_CALL(response_callback, Run(/* is_rt_lookup_successful */ true, /* is_cached_response */ false, _));
diff --git a/chrome/browser/safe_browsing/threat_details_unittest.cc b/chrome/browser/safe_browsing/threat_details_unittest.cc index c827245e1..ff2906b2 100644 --- a/chrome/browser/safe_browsing/threat_details_unittest.cc +++ b/chrome/browser/safe_browsing/threat_details_unittest.cc
@@ -229,6 +229,11 @@ outermost_event_main_frame_id, int user_gesture_count_limit, ReferrerChain* out_referrer_chain)); + MOCK_METHOD4(IdentifyReferrerChainByEventURL, + AttributionResult(const GURL& event_url, + SessionID event_tab_id, + int user_gesture_count_limit, + ReferrerChain* out_referrer_chain)); MOCK_METHOD3(IdentifyReferrerChainByPendingEventURL, AttributionResult(const GURL& event_url, int user_gesture_count_limit,
diff --git a/chrome/browser/tabmodel/internal/android/java/src/org/chromium/chrome/browser/tabmodel/TabWindowManagerImpl.java b/chrome/browser/tabmodel/internal/android/java/src/org/chromium/chrome/browser/tabmodel/TabWindowManagerImpl.java index 4eb6fd9..c02b5ad 100644 --- a/chrome/browser/tabmodel/internal/android/java/src/org/chromium/chrome/browser/tabmodel/TabWindowManagerImpl.java +++ b/chrome/browser/tabmodel/internal/android/java/src/org/chromium/chrome/browser/tabmodel/TabWindowManagerImpl.java
@@ -207,6 +207,8 @@ + newActivity + " new activity task id: " + newActivity.getTaskId() + + " new activity is finishing? " + + newActivity.isFinishing() + " activity at requested index: " + activityAtRequestedIndex; if (activityAtRequestedIndex == null) {
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index eb2d8f0..34209257 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2525,6 +2525,7 @@ "../ash/app_list/search/util/manatee.h", "../ash/app_list/search/util/mrfu_cache.cc", "../ash/app_list/search/util/mrfu_cache.h", + "../ash/app_list/search/util/persistent_proto.cc", "../ash/app_list/search/util/persistent_proto.h", "../ash/app_list/search/util/score_normalizer.cc", "../ash/app_list/search/util/score_normalizer.h",
diff --git a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java index 894b81690..3906beb 100644 --- a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java +++ b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java
@@ -48,7 +48,6 @@ private final @NonNull Activity mActivity; private final @NonNull TabSupplierObserver mTabSupplierObserver; private final ObserverList<EdgeToEdgePadAdjuster> mPadAdjusters = new ObserverList<>(); - private final ObserverList<ChangeObserver> mEdgeChangeObservers = new ObserverList<>(); private final @NonNull TabObserver mTabObserver; /** Multiplier to convert from pixels to DPs. */ @@ -144,16 +143,6 @@ } @Override - public void registerObserver(ChangeObserver changeObserver) { - mEdgeChangeObservers.addObserver(changeObserver); - } - - @Override - public void unregisterObserver(ChangeObserver changeObserver) { - mEdgeChangeObservers.removeObserver(changeObserver); - } - - @Override public int getBottomInset() { return mSystemInsets == null || !isToEdge() ? 0 @@ -185,8 +174,7 @@ } /** - * Conditionally draws the given View ToEdge or ToNormal based on {@link - * EdgeToEdgeUtils#shouldDrawToEdge(Tab)} + * Conditionally draws the given View ToEdge or ToNormal based on {@link #shouldDrawToEdge(Tab)} * * @param viewId The ID of the Root UI View. * @param webContents The {@link WebContents} to notify of inset env() changes. @@ -197,8 +185,8 @@ } /** - * Conditionally draws the given View ToEdge or ToNormal based on {@link - * EdgeToEdgeUtils#shouldDrawToEdge(Tab, int)}. + * Conditionally draws the given View ToEdge or ToNormal based on {@link #shouldDrawToEdge(Tab, + * int)}. * * @param viewId The ID of the Root UI View. * @param value A new {@link WebContentsObserver.ViewportFitType} value being applied now. @@ -291,9 +279,6 @@ for (var adjuster : mPadAdjusters) { adjuster.adjustToEdge(toEdge, mSystemInsets.bottom); } - for (var observer : mEdgeChangeObservers) { - observer.onToEdgeChange(isToEdge() ? mSystemInsets.bottom : 0); - } // We only make the Nav Bar transparent because it's the only thing we want to draw // underneath. @@ -370,10 +355,6 @@ mIsActivityToEdge = toEdge; } - public @Nullable ChangeObserver getAnyChangeObserverForTesting() { - return mEdgeChangeObservers.isEmpty() ? null : mEdgeChangeObservers.iterator().next(); - } - void setSystemInsetsForTesting(Insets systemInsetsForTesting) { mSystemInsets = systemInsetsForTesting; }
diff --git a/chrome/browser/ui/android/edge_to_edge/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeSupplier.java b/chrome/browser/ui/android/edge_to_edge/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeSupplier.java index 9773b32d..e989761 100644 --- a/chrome/browser/ui/android/edge_to_edge/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeSupplier.java +++ b/chrome/browser/ui/android/edge_to_edge/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeSupplier.java
@@ -4,36 +4,9 @@ package org.chromium.chrome.browser.ui.edge_to_edge; -import androidx.annotation.Px; - /** A supplier notifying of whether edge to edge is on and the value of the bottom inset. */ public interface EdgeToEdgeSupplier { - - /** - * Notifies that a change has occurred that may require an update, and supplies the new bottom - * inset in pixels. - */ - interface ChangeObserver { - - /** - * Notifies that a change has been made in the bottom inset and supplies the new inset. - * - * @param bottomInset The new bottom inset. - */ - void onToEdgeChange(@Px int bottomInset); - } - - /** Registers an automatic adjuster of padding for a view. See {@link EdgeToEdgePadAdjuster}. */ void registerAdjuster(EdgeToEdgePadAdjuster adjuster); void unregisterAdjuster(EdgeToEdgePadAdjuster adjuster); - - /** - * Registers an observer to be called any time the system changes ToEdge or back. - * - * @param changeObserver a {@link ChangeObserver} that provides the new bottom inset. - */ - void registerObserver(ChangeObserver changeObserver); - - void unregisterObserver(ChangeObserver changeObserver); }
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 1afcb77a..6268e66e 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -2517,6 +2517,10 @@ Listen to this page </message> + <message name="IDS_MENU_LISTEN_TO_THIS_PAGE_IPH" desc="The in-product-help message that encourages users to use the Listen to this Page feature in the app menu"> + You can listen to this page + </message> + <message name="IDS_MENU_PRINT" desc="Menu item for printing the current page. [CHAR_LIMIT=27]"> Print… </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_LISTEN_TO_THIS_PAGE_IPH.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_LISTEN_TO_THIS_PAGE_IPH.png.sha1 new file mode 100644 index 0000000..d7ed7e4 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_LISTEN_TO_THIS_PAGE_IPH.png.sha1
@@ -0,0 +1 @@ +b76351f397799d4eeccb1d4440177cf9da18d65f \ No newline at end of file
diff --git a/chrome/browser/ui/android/toolbar/BUILD.gn b/chrome/browser/ui/android/toolbar/BUILD.gn index 79dec1b..6f79c8f 100644 --- a/chrome/browser/ui/android/toolbar/BUILD.gn +++ b/chrome/browser/ui/android/toolbar/BUILD.gn
@@ -144,7 +144,6 @@ "//chrome/browser/tab_group:java", "//chrome/browser/tabmodel:java", "//chrome/browser/ui/android/appmenu:java", - "//chrome/browser/ui/android/edge_to_edge:java", "//chrome/browser/ui/android/favicon:java", "//chrome/browser/ui/android/favicon:java_resources", "//chrome/browser/ui/android/layouts:java", @@ -315,7 +314,6 @@ "java/src/org/chromium/chrome/browser/toolbar/adaptive/OptionalNewTabButtonControllerUnitTest.java", "java/src/org/chromium/chrome/browser/toolbar/adaptive/TranslateToolbarButtonControllerUnitTest.java", "java/src/org/chromium/chrome/browser/toolbar/adaptive/settings/AdaptiveToolbarSettingsFragmentTest.java", - "java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsMediatorTest.java", "java/src/org/chromium/chrome/browser/toolbar/home_button/HomeButtonCoordinatorTest.java", "java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressMediatorTest.java", "java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinatorTest.java", @@ -357,8 +355,6 @@ "//chrome/browser/tab:java", "//chrome/browser/tabmodel:java", "//chrome/browser/ui/android/appmenu:java", - "//chrome/browser/ui/android/edge_to_edge:java", - "//chrome/browser/ui/android/edge_to_edge/internal:java", "//chrome/browser/ui/android/layouts:java", "//chrome/browser/ui/android/omnibox:java", "//chrome/browser/ui/android/omnibox:java_resources",
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java index 18d04a7..1cc3d6d 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java
@@ -20,7 +20,6 @@ import org.chromium.chrome.browser.tab.TabObscuringHandler; import org.chromium.chrome.browser.toolbar.R; import org.chromium.chrome.browser.toolbar.bottom.BottomControlsViewBinder.ViewHolder; -import org.chromium.chrome.browser.ui.edge_to_edge.EdgeToEdgeController; import org.chromium.components.browser_ui.widget.gesture.BackPressHandler; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.modelutil.PropertyModel; @@ -49,15 +48,13 @@ /** * Build the coordinator that manages the bottom controls. - * * @param activity Activity instance to use. * @param windowAndroid A {@link WindowAndroid} for watching keyboard visibility events. * @param layoutManager A {@link LayoutManager} to attach overlays to. * @param resourceManager A {@link ResourceManager} for loading textures into the compositor. - * @param controlsSizer A {@link BrowserControlsSizer} to update the bottom controls height for - * the renderer. + * @param controlsSizer A {@link BrowserControlsSizer} to update the bottom controls + * height for the renderer. * @param fullscreenManager A {@link FullscreenManager} to listen for fullscreen changes. - * @param edgeToEdgeControllerSupplier A supplier to control drawing to the edge of the screen. * @param root The parent {@link ViewGroup} for the bottom controls. * @param contentDelegate Delegate for bottom controls UI operations. * @param tabObscuringHandler Delegate object handling obscuring views. @@ -72,7 +69,6 @@ ResourceManager resourceManager, BrowserControlsSizer controlsSizer, FullscreenManager fullscreenManager, - ObservableSupplier<EdgeToEdgeController> edgeToEdgeControllerSupplier, ScrollingBottomViewResourceFrameLayout root, BottomControlsContentDelegate contentDelegate, TabObscuringHandler tabObscuringHandler, @@ -91,10 +87,7 @@ View container = root.findViewById(R.id.bottom_container_slot); ViewGroup.LayoutParams params = container.getLayoutParams(); - - int bottomControlsHeightRes = - root.getResources().getDimensionPixelOffset(bottomControlsHeightId); - params.height = bottomControlsHeightRes; + params.height = root.getResources().getDimensionPixelOffset(bottomControlsHeightId); mMediator = new BottomControlsMediator( windowAndroid, @@ -102,9 +95,9 @@ controlsSizer, fullscreenManager, tabObscuringHandler, - bottomControlsHeightRes, - overlayPanelVisibilitySupplier, - edgeToEdgeControllerSupplier); + root.getResources().getDimensionPixelOffset(bottomControlsHeightId), + overlayPanelVisibilitySupplier); + resourceManager .getDynamicResourceLoader() .registerResource(root.getId(), root.getResourceAdapter());
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsMediator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsMediator.java index dc95539d..17f5645 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsMediator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsMediator.java
@@ -4,8 +4,6 @@ package org.chromium.chrome.browser.toolbar.bottom; -import androidx.annotation.Nullable; - import org.chromium.base.CallbackController; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.chrome.browser.browser_controls.BrowserControlsSizer; @@ -15,8 +13,6 @@ import org.chromium.chrome.browser.layouts.LayoutStateProvider.LayoutStateObserver; import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.tab.TabObscuringHandler; -import org.chromium.chrome.browser.ui.edge_to_edge.EdgeToEdgeController; -import org.chromium.chrome.browser.ui.edge_to_edge.EdgeToEdgeSupplier.ChangeObserver; import org.chromium.ui.KeyboardVisibilityDelegate; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.modelutil.PropertyModel; @@ -31,8 +27,6 @@ KeyboardVisibilityDelegate.KeyboardVisibilityListener, LayoutStateObserver, TabObscuringHandler.Observer { - private static final String TAG = "BotControlsMediator"; - /** The model for the bottom controls component that holds all of its view state. */ private final PropertyModel mModel; @@ -46,8 +40,6 @@ private final CallbackController mCallbackController; - private final ObservableSupplier<EdgeToEdgeController> mEdgeToEdgeControllerSupplier; - /** The height of the bottom bar in pixels, not including the top shadow. */ private int mBottomControlsHeight; @@ -68,23 +60,17 @@ private LayoutStateProvider mLayoutStateProvider; - @Nullable private ChangeObserver mEdgeToEdgeChangeObserver; - private int mBottomControlsOriginalHeight; - /** * Build a new mediator that handles events from outside the bottom controls component. - * * @param windowAndroid A {@link WindowAndroid} for watching keyboard visibility events. * @param model The {@link BottomControlsProperties} that holds all the view state for the - * bottom controls component. + * bottom controls component. * @param controlsSizer The {@link BrowserControlsSizer} to manipulate browser controls. * @param fullscreenManager A {@link FullscreenManager} for events related to the browser - * controls. + * controls. * @param tabObscuringHandler Delegate object handling obscuring views. * @param bottomControlsHeight The height of the bottom bar in pixels. * @param overlayPanelVisibilitySupplier Notifies overlay panel visibility event. - * @param edgeToEdgeControllerSupplier Supplies an {@link EdgeToEdgeController} to adjust the - * height of the bottom controls when drawing all the way to the edge of the screen. */ BottomControlsMediator( WindowAndroid windowAndroid, @@ -93,8 +79,7 @@ FullscreenManager fullscreenManager, TabObscuringHandler tabObscuringHandler, int bottomControlsHeight, - ObservableSupplier<Boolean> overlayPanelVisibilitySupplier, - ObservableSupplier<EdgeToEdgeController> edgeToEdgeControllerSupplier) { + ObservableSupplier<Boolean> overlayPanelVisibilitySupplier) { mModel = model; mFullscreenManager = fullscreenManager; @@ -115,36 +100,6 @@ // Watch for keyboard events so we can hide the bottom toolbar when the keyboard is showing. mWindowAndroid = windowAndroid; mWindowAndroid.getKeyboardDelegate().addKeyboardVisibilityListener(this); - - mEdgeToEdgeControllerSupplier = edgeToEdgeControllerSupplier; - if (mEdgeToEdgeControllerSupplier.get() != null) { - mBottomControlsOriginalHeight = bottomControlsHeight; - mEdgeToEdgeChangeObserver = - (bottomInset) -> { - // TODO(https://crbug.com/327274751) handle coordination between ReadAloud - // and this class. - int adjustedHeight = mBottomControlsOriginalHeight + bottomInset; - if (adjustedHeight != mBrowserControlsSizer.getBottomControlsHeight()) { - mBrowserControlsSizer.setBottomControlsHeight( - adjustedHeight, - mBrowserControlsSizer.getBottomControlsMinHeight()); - updateBottomControlsOffset(adjustedHeight); - } - if (adjustedHeight - != mModel.get(BottomControlsProperties.ANDROID_VIEW_HEIGHT)) { - mModel.set( - BottomControlsProperties.ANDROID_VIEW_HEIGHT, adjustedHeight); - } - }; - mEdgeToEdgeControllerSupplier.get().registerObserver(mEdgeToEdgeChangeObserver); - } - } - - private void updateBottomControlsOffset(int bottomControlsYOffset) { - // TODO(https://crbug.com/41483234) Find a better way to update bottom controls compositor - // view when the height changes. - final int unused = 0; - onControlsOffsetChanged(unused, unused, bottomControlsYOffset, 0, false); } void setLayoutStateProvider(LayoutStateProvider layoutStateProvider) { @@ -167,10 +122,6 @@ mLayoutStateProvider.removeObserver(this); mLayoutStateProvider = null; } - if (mEdgeToEdgeControllerSupplier.get() != null && mEdgeToEdgeChangeObserver != null) { - mEdgeToEdgeControllerSupplier.get().unregisterObserver(mEdgeToEdgeChangeObserver); - mEdgeToEdgeChangeObserver = null; - } mTabObscuringHandler.removeObserver(this); } @@ -253,8 +204,4 @@ public void updateObscured(boolean obscureTabContent, boolean obscureToolbar) { mModel.set(BottomControlsProperties.IS_OBSCURED, obscureToolbar); } - - ChangeObserver getEdgeToEdgeChangeObserverForTesting() { - return mEdgeToEdgeChangeObserver; - } }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsMediatorTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsMediatorTest.java deleted file mode 100644 index 941be81b..0000000 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsMediatorTest.java +++ /dev/null
@@ -1,175 +0,0 @@ -// Copyright 2024 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.toolbar.bottom; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; - -import static org.chromium.chrome.browser.toolbar.bottom.BottomControlsProperties.ANDROID_VIEW_HEIGHT; - -import android.app.Activity; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.Robolectric; -import org.robolectric.annotation.Config; - -import org.chromium.base.supplier.ObservableSupplier; -import org.chromium.base.supplier.ObservableSupplierImpl; -import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.base.test.util.Features; -import org.chromium.base.test.util.Features.DisableFeatures; -import org.chromium.base.test.util.Features.EnableFeatures; -import org.chromium.chrome.browser.browser_controls.BrowserControlsSizer; -import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; -import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.browser.fullscreen.FullscreenManager; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabObscuringHandler; -import org.chromium.chrome.browser.ui.edge_to_edge.EdgeToEdgeController; -import org.chromium.chrome.browser.ui.edge_to_edge.EdgeToEdgeControllerImpl; -import org.chromium.chrome.browser.ui.edge_to_edge.EdgeToEdgeSupplier.ChangeObserver; -import org.chromium.ui.KeyboardVisibilityDelegate; -import org.chromium.ui.base.TestActivity; -import org.chromium.ui.base.WindowAndroid; -import org.chromium.ui.modelutil.PropertyModel; - -/** Unit tests for {@link BottomControlsMediator}. */ -@RunWith(BaseRobolectricTestRunner.class) -@Config(manifest = Config.NONE) -@DisableFeatures({ChromeFeatureList.TOTALLY_EDGE_TO_EDGE}) -public class BottomControlsMediatorTest { - @Rule public TestRule mProcessor = new Features.JUnitProcessor(); - - private static final int DEFAULT_HEIGHT = 80; - private static final int DEFAULT_INSET = 56; - @Mock BrowserControlsSizer mBrowserControlsSizer; - @Mock BrowserControlsStateProvider mBrowserControlsStateProvider; - @Mock WindowAndroid mWindowAndroid; - @Mock TabObscuringHandler mTabObscuringHandler; - @Mock ObservableSupplier<Boolean> mOverlayPanelVisibilitySupplier; - @Mock EdgeToEdgeController mEdgeToEdgeController; - @Mock FullscreenManager mFullscreenManager; - @Mock KeyboardVisibilityDelegate mKeyboardDelegate; - - private ObservableSupplierImpl<EdgeToEdgeController> mEdgeToEdgeControllerSupplier; - private ObservableSupplierImpl<Tab> mTabObservableSupplier = new ObservableSupplierImpl(); - - private PropertyModel mModel; - private BottomControlsMediator mMediator; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - doReturn(mKeyboardDelegate).when(mWindowAndroid).getKeyboardDelegate(); - mModel = - new PropertyModel.Builder(BottomControlsProperties.ALL_KEYS) - .with(BottomControlsProperties.ANDROID_VIEW_VISIBLE, false) - .with(BottomControlsProperties.COMPOSITED_VIEW_VISIBLE, false) - .build(); - mEdgeToEdgeControllerSupplier = new ObservableSupplierImpl(mEdgeToEdgeController); - mMediator = - new BottomControlsMediator( - mWindowAndroid, - mModel, - mBrowserControlsSizer, - mFullscreenManager, - mTabObscuringHandler, - DEFAULT_HEIGHT, - mOverlayPanelVisibilitySupplier, - mEdgeToEdgeControllerSupplier); - } - - @Test - public void testNoEdgeToEdge() { - BottomControlsMediator plainMediator = - new BottomControlsMediator( - mWindowAndroid, - mModel, - mBrowserControlsSizer, - mFullscreenManager, - mTabObscuringHandler, - DEFAULT_HEIGHT, - mOverlayPanelVisibilitySupplier, - new ObservableSupplierImpl(null)); - assertNull(plainMediator.getEdgeToEdgeChangeObserverForTesting()); - } - - @Test - public void testEdgeToEdge_simple() { - assertNotNull(mMediator.getEdgeToEdgeChangeObserverForTesting()); - verify(mEdgeToEdgeController).registerObserver(any()); - } - - @Test - public void testEdgeToEdge_ToNormal() { - ChangeObserver changeObserver = mMediator.getEdgeToEdgeChangeObserverForTesting(); - changeObserver.onToEdgeChange(0); - assertEquals(DEFAULT_HEIGHT, mModel.get(ANDROID_VIEW_HEIGHT)); - } - - @Test - public void testEdgeToEdge_ToEdge() { - ChangeObserver changeObserver = mMediator.getEdgeToEdgeChangeObserverForTesting(); - changeObserver.onToEdgeChange(DEFAULT_INSET); - assertEquals(DEFAULT_HEIGHT + DEFAULT_INSET, mModel.get(ANDROID_VIEW_HEIGHT)); - } - - @Test - public void testEdgeToEdge_ObserverDestroyed() { - // Set up a mediator with a live EdgeToEdgeController. - Activity activity = Robolectric.buildActivity(TestActivity.class).setup().get(); - EdgeToEdgeControllerImpl liveEdgeToEdgeController = - new EdgeToEdgeControllerImpl( - activity, mTabObservableSupplier, null, mBrowserControlsStateProvider); - BottomControlsMediator plainMediator = - new BottomControlsMediator( - mWindowAndroid, - mModel, - mBrowserControlsSizer, - mFullscreenManager, - mTabObscuringHandler, - DEFAULT_HEIGHT, - mOverlayPanelVisibilitySupplier, - new ObservableSupplierImpl(liveEdgeToEdgeController)); - assertNotNull(liveEdgeToEdgeController.getAnyChangeObserverForTesting()); - plainMediator.destroy(); - assertNull(liveEdgeToEdgeController.getAnyChangeObserverForTesting()); - } - - @Test - @EnableFeatures(ChromeFeatureList.DRAW_NATIVE_EDGE_TO_EDGE) - public void testEdgeToEdge_ObserverCalled() { - // Set up a mediator with a live EdgeToEdgeController. - Activity activity = Robolectric.buildActivity(TestActivity.class).setup().get(); - EdgeToEdgeControllerImpl liveEdgeToEdgeController = - new EdgeToEdgeControllerImpl( - activity, mTabObservableSupplier, null, mBrowserControlsStateProvider); - new BottomControlsMediator( - mWindowAndroid, - mModel, - mBrowserControlsSizer, - mFullscreenManager, - mTabObscuringHandler, - DEFAULT_HEIGHT, - mOverlayPanelVisibilitySupplier, - new ObservableSupplierImpl(liveEdgeToEdgeController)); - assertNotNull(liveEdgeToEdgeController.getAnyChangeObserverForTesting()); - liveEdgeToEdgeController.setToEdgeForTesting(false); - int toNormalHeight = mModel.get(ANDROID_VIEW_HEIGHT); - // Go to a native page which will go ToEdge due to our enabled Feature for this test case. - mTabObservableSupplier.set(null); - assertEquals(toNormalHeight, mModel.get(ANDROID_VIEW_HEIGHT)); - } -}
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsProperties.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsProperties.java index 409b138a..b670159 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsProperties.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsProperties.java
@@ -10,8 +10,9 @@ import org.chromium.ui.modelutil.PropertyModel.WritableIntPropertyKey; class BottomControlsProperties { - /** The height of the Android View in px. */ - static final WritableIntPropertyKey ANDROID_VIEW_HEIGHT = new WritableIntPropertyKey(); + /** The height of the bottom control container (view which includes the top shadow) in px. */ + static final WritableIntPropertyKey BOTTOM_CONTROLS_CONTAINER_HEIGHT_PX = + new WritableIntPropertyKey(); /** The Y offset of the view in px. */ static final WritableIntPropertyKey Y_OFFSET = new WritableIntPropertyKey(); @@ -35,7 +36,7 @@ static final PropertyKey[] ALL_KEYS = new PropertyKey[] { - ANDROID_VIEW_HEIGHT, + BOTTOM_CONTROLS_CONTAINER_HEIGHT_PX, Y_OFFSET, ANDROID_VIEW_TRANSLATE_Y, ANDROID_VIEW_VISIBLE,
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsViewBinder.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsViewBinder.java index 75ca1cd..c01ae7a 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsViewBinder.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsViewBinder.java
@@ -34,10 +34,10 @@ } static void bind(PropertyModel model, ViewHolder view, PropertyKey propertyKey) { - if (BottomControlsProperties.ANDROID_VIEW_HEIGHT == propertyKey) { - View bottomControlsView = view.root.findViewById(R.id.bottom_container_slot); - bottomControlsView.getLayoutParams().height = - model.get(BottomControlsProperties.ANDROID_VIEW_HEIGHT); + if (BottomControlsProperties.BOTTOM_CONTROLS_CONTAINER_HEIGHT_PX == propertyKey) { + View bottomControlsWrapper = view.root.findViewById(R.id.bottom_controls_wrapper); + bottomControlsWrapper.getLayoutParams().height = + model.get(BottomControlsProperties.BOTTOM_CONTROLS_CONTAINER_HEIGHT_PX); } else if (BottomControlsProperties.Y_OFFSET == propertyKey) { view.sceneLayer.setYOffset(model.get(BottomControlsProperties.Y_OFFSET)); } else if (BottomControlsProperties.ANDROID_VIEW_TRANSLATE_Y == propertyKey) {
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java index e0afc4d..d291fdfc 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
@@ -147,7 +147,8 @@ private Drawable getTempTabStripDrawable(boolean incognito) { Drawable bgdColor = new ColorDrawable( - TabUiThemeUtil.getTabStripBackgroundColor(getContext(), incognito)); + TabUiThemeUtil.getTabStripBackgroundColor( + getContext(), incognito, /* isActivityFocused= */ true)); Drawable bdgTabImage = ResourcesCompat.getDrawable( getContext().getResources(),
diff --git a/chrome/browser/ui/autofill/autofill_context_menu_manager.cc b/chrome/browser/ui/autofill/autofill_context_menu_manager.cc index 05edda6b..e60d14f2 100644 --- a/chrome/browser/ui/autofill/autofill_context_menu_manager.cc +++ b/chrome/browser/ui/autofill/autofill_context_menu_manager.cc
@@ -352,27 +352,30 @@ void AutofillContextMenuManager::LogManualFallbackContextMenuEntryAccepted( BrowserAutofillManager& manager, const FillingProduct filling_product) { - if (filling_product == FillingProduct::kAddress) { auto& driver = static_cast<ContentAutofillDriver&>(manager.driver()); AutofillField* field = GetAutofillField(manager, driver.GetFrameToken()); - const bool is_address_field = - field && IsAddressType(field->Type().GetStorableType()); - if (is_address_field) { - // Address manual fallback was triggered from a classified address field. - manager.GetAutocompleteUnrecognizedFallbackEventLogger() - .ContextMenuEntryAccepted( - /*address_field_has_ac_unrecognized=*/field - ->ShouldSuppressSuggestionsAndFillingByDefault()); - } else { + if (filling_product == FillingProduct::kAddress) { + const bool is_address_field = + field && IsAddressType(field->Type().GetStorableType()); + if (is_address_field) { + // Address manual fallback was triggered from a classified address + // field. + manager.GetAutocompleteUnrecognizedFallbackEventLogger() + .ContextMenuEntryAccepted( + /*address_field_has_ac_unrecognized=*/field + ->ShouldSuppressSuggestionsAndFillingByDefault()); + } else { + manager.GetManualFallbackEventLogger().ContextMenuEntryAccepted( + FillingProduct::kAddress); + } + } else if (filling_product == FillingProduct::kCreditCard && + !(field && + field->Type().group() == FieldTypeGroup::kCreditCard)) { + // Only log payments manual fallback when triggered from a field that is + // not classified as payments. manager.GetManualFallbackEventLogger().ContextMenuEntryAccepted( - FillingProduct::kAddress); + FillingProduct::kCreditCard); } - } else if (filling_product == FillingProduct::kCreditCard) { - // Only log payments manual fallback when triggered from a field that is - // not classified as payments. - manager.GetManualFallbackEventLogger().ContextMenuEntryAccepted( - FillingProduct::kCreditCard); - } } void AutofillContextMenuManager::LogManualFallbackContextMenuEntryShown(
diff --git a/chrome/browser/ui/autofill/autofill_context_menu_manager_browsertest.cc b/chrome/browser/ui/autofill/autofill_context_menu_manager_browsertest.cc index 76a6dbfb..47c0cd9a 100644 --- a/chrome/browser/ui/autofill/autofill_context_menu_manager_browsertest.cc +++ b/chrome/browser/ui/autofill/autofill_context_menu_manager_browsertest.cc
@@ -676,7 +676,6 @@ .is_field_unclassified = true, .test_name = "UnclassifiedField_Payments_NotAccepted", }, - { .manual_fallback_option = AutofillSuggestionTriggerSource::kManualFallbackAddress,
diff --git a/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl.cc b/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl.cc index 8a0ad31..c2a8c4d 100644 --- a/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl.cc +++ b/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl.cc
@@ -95,7 +95,7 @@ } AutofillBubbleBase* -VirtualCardEnrollBubbleControllerImpl::GetVirtualCardEnrollBubbleView() const { +VirtualCardEnrollBubbleControllerImpl::GetVirtualCardBubbleView() const { return bubble_view(); } @@ -111,6 +111,10 @@ return enrollment_status_ == EnrollmentStatus::kPaymentsServerRequestInFlight; } +bool VirtualCardEnrollBubbleControllerImpl::IsEnrollmentComplete() const { + return enrollment_status_ == EnrollmentStatus::kCompleted; +} + void VirtualCardEnrollBubbleControllerImpl::ShowConfirmationBubbleView( bool is_vcn_enrolled) { HideIconAndBubble(); @@ -366,6 +370,13 @@ // sure further OnVisibilityChanged() don't trigger opening the bubble because // we don't want to re-show it every time the web contents become visible. bubble_state_ = BubbleState::kShowingIcon; + + // Metrics for showing virtual card enroll bubble are logged once when + // enrollment is offered, do not log the same metrics again while showing + // confirmation bubble. + if (enrollment_status_ == EnrollmentStatus::kCompleted) { + return; + } #endif // BUILDFLAG(IS_ANDROID) // If the dialog is to be shown again because user clicked on links, do not
diff --git a/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl.h b/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl.h index 78cb96fd..eae63d4 100644 --- a/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl.h +++ b/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl.h
@@ -54,11 +54,12 @@ const VirtualCardEnrollUiModel& GetUiModel() const override; VirtualCardEnrollmentBubbleSource GetVirtualCardEnrollmentBubbleSource() const override; - AutofillBubbleBase* GetVirtualCardEnrollBubbleView() const override; + AutofillBubbleBase* GetVirtualCardBubbleView() const override; #if !BUILDFLAG(IS_ANDROID) void HideIconAndBubble() override; bool IsEnrollmentInProgress() const override; + bool IsEnrollmentComplete() const override; virtual void ShowConfirmationBubbleView(bool is_vcn_enrolled); #endif
diff --git a/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl_test_api.h b/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl_test_api.h index b0f822b2..d297029 100644 --- a/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl_test_api.h +++ b/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl_test_api.h
@@ -26,14 +26,14 @@ bubble_shown_closure_for_testing; } + void SetFields(const VirtualCardEnrollmentFields& fields) { + controller_->ui_model_.enrollment_fields = fields; + } + #if BUILDFLAG(IS_ANDROID) bool DidShowBottomSheet() { return !!controller_->autofill_vcn_enroll_bottom_sheet_bridge_; } - - void SetFields(const VirtualCardEnrollmentFields& fields) { - controller_->ui_model_.enrollment_fields = fields; - } #else VirtualCardEnrollBubbleControllerImpl::EnrollmentStatus GetEnrollmentStatus() {
diff --git a/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl_unittest.cc b/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl_unittest.cc index e0f92df..27294d5 100644 --- a/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl_unittest.cc +++ b/chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl_unittest.cc
@@ -172,7 +172,7 @@ } AutofillBubbleBase* GetBubbleViews() { - return controller()->GetVirtualCardEnrollBubbleView(); + return controller()->GetVirtualCardBubbleView(); } const VirtualCardEnrollmentFields& virtual_card_enrollment_fields() const {
diff --git a/chrome/browser/ui/color/chrome_color_id.h b/chrome/browser/ui/color/chrome_color_id.h index 86443a5d..7ac8ab2c 100644 --- a/chrome/browser/ui/color/chrome_color_id.h +++ b/chrome/browser/ui/color/chrome_color_id.h
@@ -406,6 +406,16 @@ E_CPONLY(kColorReadAnythingBackgroundDark) \ E_CPONLY(kColorReadAnythingBackgroundLight) \ E_CPONLY(kColorReadAnythingBackgroundYellow) \ + E_CPONLY(kColorReadAnythingCurrentReadAloudHighlight) \ + E_CPONLY(kColorReadAnythingCurrentReadAloudHighlightBlue) \ + E_CPONLY(kColorReadAnythingCurrentReadAloudHighlightDark) \ + E_CPONLY(kColorReadAnythingCurrentReadAloudHighlightLight) \ + E_CPONLY(kColorReadAnythingCurrentReadAloudHighlightYellow) \ + E_CPONLY(kColorReadAnythingFocusRingBackground) \ + E_CPONLY(kColorReadAnythingFocusRingBackgroundBlue) \ + E_CPONLY(kColorReadAnythingFocusRingBackgroundDark) \ + E_CPONLY(kColorReadAnythingFocusRingBackgroundLight) \ + E_CPONLY(kColorReadAnythingFocusRingBackgroundYellow) \ E_CPONLY(kColorReadAnythingForeground) \ E_CPONLY(kColorReadAnythingForegroundBlue) \ E_CPONLY(kColorReadAnythingForegroundDark) \ @@ -441,21 +451,11 @@ E_CPONLY(kColorReadAnythingLinkVisitedDark) \ E_CPONLY(kColorReadAnythingLinkVisitedLight) \ E_CPONLY(kColorReadAnythingLinkVisitedYellow) \ - E_CPONLY(kColorReadAnythingFocusRingBackground) \ - E_CPONLY(kColorReadAnythingFocusRingBackgroundBlue) \ - E_CPONLY(kColorReadAnythingFocusRingBackgroundDark) \ - E_CPONLY(kColorReadAnythingFocusRingBackgroundLight) \ - E_CPONLY(kColorReadAnythingFocusRingBackgroundYellow) \ - E_CPONLY(kColorCurrentReadAloudHighlight) \ - E_CPONLY(kColorCurrentReadAloudHighlightBlue) \ - E_CPONLY(kColorCurrentReadAloudHighlightDark) \ - E_CPONLY(kColorCurrentReadAloudHighlightLight) \ - E_CPONLY(kColorCurrentReadAloudHighlightYellow) \ - E_CPONLY(kColorPreviousReadAloudHighlight) \ - E_CPONLY(kColorPreviousReadAloudHighlightBlue) \ - E_CPONLY(kColorPreviousReadAloudHighlightDark) \ - E_CPONLY(kColorPreviousReadAloudHighlightLight) \ - E_CPONLY(kColorPreviousReadAloudHighlightYellow) \ + E_CPONLY(kColorReadAnythingPreviousReadAloudHighlight) \ + E_CPONLY(kColorReadAnythingPreviousReadAloudHighlightBlue) \ + E_CPONLY(kColorReadAnythingPreviousReadAloudHighlightDark) \ + E_CPONLY(kColorReadAnythingPreviousReadAloudHighlightLight) \ + E_CPONLY(kColorReadAnythingPreviousReadAloudHighlightYellow) \ /* Realbox colors. */ \ E_CPONLY(kColorRealboxAnswerIconBackground) \ E_CPONLY(kColorRealboxAnswerIconForeground) \
diff --git a/chrome/browser/ui/color/chrome_color_mixer.cc b/chrome/browser/ui/color/chrome_color_mixer.cc index 16b2e742..2dffc89 100644 --- a/chrome/browser/ui/color/chrome_color_mixer.cc +++ b/chrome/browser/ui/color/chrome_color_mixer.cc
@@ -765,6 +765,17 @@ // The Read Anything themes need to be hard coded because they do not // change with the chrome theme, which is the purpose of the Read Anything // feature. + mixer[kColorReadAnythingCurrentReadAloudHighlight] = { + dark_mode ? kColorReadAnythingCurrentReadAloudHighlightDark + : kColorReadAnythingCurrentReadAloudHighlightLight}; + mixer[kColorReadAnythingCurrentReadAloudHighlightDark] = { + SkColorSetARGB(25, 253, 252, 251)}; + mixer[kColorReadAnythingCurrentReadAloudHighlightLight] = { + SkColorSetARGB(15, 31, 31, 31)}; + mixer[kColorReadAnythingCurrentReadAloudHighlightBlue] = { + SkColorSetARGB(15, 31, 31, 31)}; + mixer[kColorReadAnythingCurrentReadAloudHighlightYellow] = { + SkColorSetARGB(15, 31, 31, 31)}; mixer[kColorReadAnythingForeground] = { dark_mode ? kColorReadAnythingForegroundDark : kColorReadAnythingForegroundLight}; @@ -772,23 +783,17 @@ mixer[kColorReadAnythingForegroundDark] = {SkColorSetRGB(227, 227, 227)}; mixer[kColorReadAnythingForegroundLight] = {SkColorSetRGB(31, 31, 31)}; mixer[kColorReadAnythingForegroundYellow] = {SkColorSetRGB(31, 31, 31)}; - mixer[kColorCurrentReadAloudHighlight] = { - dark_mode ? kColorCurrentReadAloudHighlightDark - : kColorCurrentReadAloudHighlightLight}; - mixer[kColorCurrentReadAloudHighlightDark] = { - SkColorSetARGB(25, 253, 252, 251)}; - mixer[kColorCurrentReadAloudHighlightLight] = { - SkColorSetARGB(15, 31, 31, 31)}; - mixer[kColorCurrentReadAloudHighlightBlue] = {SkColorSetARGB(15, 31, 31, 31)}; - mixer[kColorCurrentReadAloudHighlightYellow] = { - SkColorSetARGB(15, 31, 31, 31)}; - mixer[kColorPreviousReadAloudHighlight] = { - dark_mode ? kColorPreviousReadAloudHighlightDark - : kColorPreviousReadAloudHighlightLight}; - mixer[kColorPreviousReadAloudHighlightDark] = {SkColorSetRGB(199, 199, 199)}; - mixer[kColorPreviousReadAloudHighlightLight] = {SkColorSetRGB(71, 71, 71)}; - mixer[kColorPreviousReadAloudHighlightBlue] = {SkColorSetRGB(71, 71, 71)}; - mixer[kColorPreviousReadAloudHighlightYellow] = {SkColorSetRGB(71, 71, 71)}; + mixer[kColorReadAnythingPreviousReadAloudHighlight] = { + dark_mode ? kColorReadAnythingPreviousReadAloudHighlightDark + : kColorReadAnythingPreviousReadAloudHighlightLight}; + mixer[kColorReadAnythingPreviousReadAloudHighlightDark] = { + SkColorSetRGB(199, 199, 199)}; + mixer[kColorReadAnythingPreviousReadAloudHighlightLight] = { + SkColorSetRGB(71, 71, 71)}; + mixer[kColorReadAnythingPreviousReadAloudHighlightBlue] = { + SkColorSetRGB(71, 71, 71)}; + mixer[kColorReadAnythingPreviousReadAloudHighlightYellow] = { + SkColorSetRGB(71, 71, 71)}; mixer[kColorReadAnythingSeparator] = {dark_mode ? kColorReadAnythingSeparatorDark : kColorReadAnythingSeparatorLight};
diff --git a/chrome/browser/ui/color/material_chrome_color_mixer.cc b/chrome/browser/ui/color/material_chrome_color_mixer.cc index 7668f21b..9ba0003 100644 --- a/chrome/browser/ui/color/material_chrome_color_mixer.cc +++ b/chrome/browser/ui/color/material_chrome_color_mixer.cc
@@ -114,9 +114,11 @@ mixer[kColorSidePanelBackground] = {ui::kColorSysBaseContainer}; // Read Anything (in the side panel) colors. + mixer[kColorReadAnythingCurrentReadAloudHighlight] = { + ui::kColorSysStateHoverOnSubtle}; mixer[kColorReadAnythingForeground] = {ui::kColorSysOnSurface}; - mixer[kColorCurrentReadAloudHighlight] = {ui::kColorSysStateHoverOnSubtle}; - mixer[kColorPreviousReadAloudHighlight] = {ui::kColorSysOnSurfaceSecondary}; + mixer[kColorReadAnythingPreviousReadAloudHighlight] = { + ui::kColorSysOnSurfaceSecondary}; // Tab Group Dialog colors. mixer[kColorTabGroupDialogIconEnabled] = {ui::kColorSysOnSurfaceSubtle};
diff --git a/chrome/browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc b/chrome/browser/ui/quick_answers/quick_answers_controller_browsertest.cc similarity index 81% rename from chrome/browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc rename to chrome/browser/ui/quick_answers/quick_answers_controller_browsertest.cc index fb7cc04..67abaa5a 100644 --- a/chrome/browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc +++ b/chrome/browser/ui/quick_answers/quick_answers_controller_browsertest.cc
@@ -10,11 +10,11 @@ namespace { -using QuickAnswersMenuObserverTest = quick_answers::QuickAnswersBrowserTestBase; +using QuickAnswersControllerTest = quick_answers::QuickAnswersBrowserTestBase; } // namespace -IN_PROC_BROWSER_TEST_F(QuickAnswersMenuObserverTest, FeatureIneligible) { +IN_PROC_BROWSER_TEST_F(QuickAnswersControllerTest, FeatureIneligible) { QuickAnswersState::Get()->set_eligibility_for_testing(false); ShowMenuParams params; @@ -27,7 +27,7 @@ controller()->GetVisibilityForTesting()); } -IN_PROC_BROWSER_TEST_F(QuickAnswersMenuObserverTest, PasswordField) { +IN_PROC_BROWSER_TEST_F(QuickAnswersControllerTest, PasswordField) { QuickAnswersState::Get()->set_eligibility_for_testing(true); ShowMenuParams params; @@ -42,7 +42,7 @@ controller()->GetVisibilityForTesting()); } -IN_PROC_BROWSER_TEST_F(QuickAnswersMenuObserverTest, NoSelectedText) { +IN_PROC_BROWSER_TEST_F(QuickAnswersControllerTest, NoSelectedText) { QuickAnswersState::Get()->set_eligibility_for_testing(true); ShowMenu(ShowMenuParams()); @@ -52,7 +52,7 @@ controller()->GetVisibilityForTesting()); } -IN_PROC_BROWSER_TEST_F(QuickAnswersMenuObserverTest, QuickAnswersPending) { +IN_PROC_BROWSER_TEST_F(QuickAnswersControllerTest, QuickAnswersPending) { QuickAnswersState::Get()->set_eligibility_for_testing(true); ShowMenuParams params;
diff --git a/chrome/browser/ui/views/autofill/payments/dialog_view_ids.h b/chrome/browser/ui/views/autofill/payments/dialog_view_ids.h index c1f2a3fb..3eb7c7d2 100644 --- a/chrome/browser/ui/views/autofill/payments/dialog_view_ids.h +++ b/chrome/browser/ui/views/autofill/payments/dialog_view_ids.h
@@ -65,6 +65,8 @@ // The following are views::Label objects. EXPIRATION_DATE_LABEL, // Appears during save offer bubble NICKNAME_LABEL, // Appears during manage saved IBAN bubble. + DESCRIPTION_LABEL, // Appears during save card and virtual card enroll + // confirmation bubble. // The following are views::StyledLabel objects. SETTINGS_LABEL, // Appears in the mandatory reauth opt-in confirmation @@ -72,7 +74,9 @@ // The following are views::Throbber objects. LOADING_THROBBER, // Appears during server card upload in save card offer - // bubble. + // bubble and during ongoing enrollment in virtual card + // enroll bubble. + }; } // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_and_virtual_card_enroll_confirmation_bubble_views.cc b/chrome/browser/ui/views/autofill/payments/save_card_and_virtual_card_enroll_confirmation_bubble_views.cc index 5fda0a9..877d31d 100644 --- a/chrome/browser/ui/views/autofill/payments/save_card_and_virtual_card_enroll_confirmation_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/payments/save_card_and_virtual_card_enroll_confirmation_bubble_views.cc
@@ -6,7 +6,11 @@ #include <utility> +#include "chrome/app/vector_icons/vector_icons.h" +#include "chrome/browser/ui/views/accessibility/theme_tracking_non_accessible_image_view.h" +#include "chrome/browser/ui/views/autofill/payments/dialog_view_ids.h" #include "chrome/browser/ui/views/autofill/payments/payments_view_util.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "ui/base/ui_base_types.h" namespace autofill { @@ -21,8 +25,13 @@ : LocationBarBubbleDelegateView(anchor_view, web_contents), controller_hide_callback_(std::move(controller_hide_callback)), ui_params_(std::move(ui_params)) { - SetButtons(ui::DIALOG_BUTTON_NONE); - SetShowCloseButton(true); + if (ui_params_.is_success) { + SetButtons(ui::DIALOG_BUTTON_NONE); + SetShowCloseButton(true); + } else { + SetButtons(ui::DIALOG_BUTTON_OK); + SetButtonLabel(ui::DIALOG_BUTTON_OK, ui_params_.failure_button_text); + } set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_BUBBLE_PREFERRED_WIDTH)); } @@ -35,6 +44,29 @@ } } +void SaveCardAndVirtualCardEnrollConfirmationBubbleViews::AddedToWidget() { + if (ui_params_.is_success) { + auto image_view = std::make_unique<ThemeTrackingNonAccessibleImageView>( + ui::ImageModel::FromVectorIcon(kSaveCardAndVcnSuccessConfirmationIcon), + ui::ImageModel::FromVectorIcon( + kSaveCardAndVcnSuccessConfirmationDarkIcon), + base::BindRepeating(&views::BubbleDialogDelegate::GetBackgroundColor, + base::Unretained(this))); + image_view->SetBorder( + views::CreateEmptyBorder(ChromeLayoutProvider::Get() + ->GetInsetsMetric(views::INSETS_DIALOG) + .set_bottom(0))); + GetBubbleFrameView()->SetHeaderView(std::move(image_view)); + } + GetBubbleFrameView()->SetTitleView(CreateTitleView( + GetWindowTitle(), TitleWithIconAndSeparatorView::Icon::GOOGLE_PAY)); +} + +std::u16string +SaveCardAndVirtualCardEnrollConfirmationBubbleViews::GetWindowTitle() const { + return ui_params_.title_text; +} + void SaveCardAndVirtualCardEnrollConfirmationBubbleViews::WindowClosing() { if (!controller_hide_callback_.is_null()) { std::move(controller_hide_callback_) @@ -42,6 +74,20 @@ } } +void SaveCardAndVirtualCardEnrollConfirmationBubbleViews::Init() { + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); + set_margins(ChromeLayoutProvider::Get()->GetDialogInsetsForContentType( + views::DialogContentType::kText, views::DialogContentType::kText)); + auto description = std::make_unique<views::Label>( + ui_params_.description_text, views::style::CONTEXT_DIALOG_BODY_TEXT, + views::style::STYLE_SECONDARY); + description->SetID(DialogViewId::DESCRIPTION_LABEL); + description->SetHorizontalAlignment(gfx::ALIGN_LEFT); + description->SetMultiLine(true); + AddChildView(std::move(description)); +} + SaveCardAndVirtualCardEnrollConfirmationBubbleViews:: ~SaveCardAndVirtualCardEnrollConfirmationBubbleViews() = default;
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_and_virtual_card_enroll_confirmation_bubble_views.h b/chrome/browser/ui/views/autofill/payments/save_card_and_virtual_card_enroll_confirmation_bubble_views.h index f0ad4aa1..ae69fde 100644 --- a/chrome/browser/ui/views/autofill/payments/save_card_and_virtual_card_enroll_confirmation_bubble_views.h +++ b/chrome/browser/ui/views/autofill/payments/save_card_and_virtual_card_enroll_confirmation_bubble_views.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_SAVE_CARD_AND_VIRTUAL_CARD_ENROLL_CONFIRMATION_BUBBLE_VIEWS_H_ #define CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_SAVE_CARD_AND_VIRTUAL_CARD_ENROLL_CONFIRMATION_BUBBLE_VIEWS_H_ -#include "base/gtest_prod_util.h" #include "chrome/browser/ui/autofill/autofill_bubble_base.h" #include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h" #include "components/autofill/core/browser/ui/payments/payments_bubble_closed_reasons.h" @@ -35,18 +34,15 @@ void Hide() override; // LocationBarBubbleDelegateView: + void AddedToWidget() override; + std::u16string GetWindowTitle() const override; void WindowClosing() override; private: ~SaveCardAndVirtualCardEnrollConfirmationBubbleViews() override; - // TODO(crbug.com/1499264): FRIEND_TEST is only temporary and should be - // removed after the UI elements are actually implemented into the view and - // can be tested. - FRIEND_TEST_ALL_PREFIXES(SaveCardConfirmationBubbleViewsInteractiveUiTest, - ShowSuccessBubbleViewThenHideBubbleView); - FRIEND_TEST_ALL_PREFIXES(SaveCardConfirmationBubbleViewsInteractiveUiTest, - ShowFailureBubbleViewThenHideBubbleView); + // LocationBarBubbleDelegateView: + void Init() override; base::OnceCallback<void(PaymentsBubbleClosedReason)> controller_hide_callback_;
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_and_virtual_card_enroll_confirmation_bubble_views_interactive_uitest.cc b/chrome/browser/ui/views/autofill/payments/save_card_and_virtual_card_enroll_confirmation_bubble_views_interactive_uitest.cc index a7a6ecf..1ad532c7 100644 --- a/chrome/browser/ui/views/autofill/payments/save_card_and_virtual_card_enroll_confirmation_bubble_views_interactive_uitest.cc +++ b/chrome/browser/ui/views/autofill/payments/save_card_and_virtual_card_enroll_confirmation_bubble_views_interactive_uitest.cc
@@ -3,10 +3,14 @@ // found in the LICENSE file. #include "chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h" + +#include "chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl_test_api.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/views/autofill/payments/dialog_view_ids.h" #include "chrome/browser/ui/views/autofill/payments/save_card_and_virtual_card_enroll_confirmation_bubble_views.h" #include "chrome/browser/ui/views/autofill/payments/save_card_bubble_views.h" #include "chrome/browser/ui/views/autofill/payments/save_payment_icon_view.h" +#include "chrome/browser/ui/views/autofill/payments/virtual_card_enroll_icon_view.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/toolbar_button_provider.h" #include "chrome/test/base/in_process_browser_test.h" @@ -38,7 +42,7 @@ CHECK(save_card_controller); } - SaveCardBubbleControllerImpl* Controller() { + SaveCardBubbleControllerImpl* GetController() { if (!browser() || !browser()->tab_strip_model() || !browser()->tab_strip_model()->GetActiveWebContents()) { return nullptr; @@ -50,7 +54,7 @@ SaveCardAndVirtualCardEnrollConfirmationBubbleViews* BubbleView() { return static_cast<SaveCardAndVirtualCardEnrollConfirmationBubbleViews*>( - Controller()->GetPaymentBubbleView()); + GetController()->GetPaymentBubbleView()); } SavePaymentIconView* IconView() { @@ -64,7 +68,7 @@ } void ShowBubble(bool card_saved) { - Controller()->ShowConfirmationBubbleView(card_saved); + GetController()->ShowConfirmationBubbleView(card_saved); } void HideBubble(views::Widget::ClosedReason closed_reason) { @@ -83,19 +87,27 @@ IN_PROC_BROWSER_TEST_F(SaveCardConfirmationBubbleViewsInteractiveUiTest, ShowSuccessBubbleViewThenHideBubbleView) { ShowBubble(/*card_saved=*/true); - EXPECT_NE(BubbleView(), nullptr); - EXPECT_TRUE(IconView()->GetVisible()); - SaveCardAndVirtualCardEnrollConfirmationUiParams ui_params = - BubbleView()->ui_params_; - EXPECT_TRUE(ui_params.is_success); - EXPECT_EQ(ui_params.title_text, + EXPECT_NE(BubbleView(), nullptr); + + EXPECT_TRUE(BubbleView()->ShouldShowCloseButton()); + EXPECT_TRUE(BubbleView() + ->GetBubbleFrameView() + ->GetHeaderViewForTesting() + ->GetVisible()); + EXPECT_NE(BubbleView()->GetBubbleFrameView()->title(), nullptr); + EXPECT_EQ(BubbleView()->GetWindowTitle(), l10n_util::GetStringUTF16( IDS_AUTOFILL_SAVE_CARD_CONFIRMATION_SUCCESS_TITLE_TEXT)); - EXPECT_EQ(ui_params.description_text, + EXPECT_TRUE( + BubbleView()->GetViewByID(DialogViewId::DESCRIPTION_LABEL)->GetVisible()); + EXPECT_EQ(static_cast<views::Label*>( + BubbleView()->GetViewByID(DialogViewId::DESCRIPTION_LABEL)) + ->GetText(), l10n_util::GetStringUTF16( IDS_AUTOFILL_SAVE_CARD_CONFIRMATION_SUCCESS_DESCRIPTION_TEXT)); - EXPECT_TRUE(ui_params.failure_button_text.empty()); + EXPECT_EQ(BubbleView()->GetDialogButtons(), ui::DIALOG_BUTTON_NONE); + EXPECT_TRUE(IconView()->GetVisible()); HideBubble(views::Widget::ClosedReason::kLostFocus); EXPECT_EQ(BubbleView(), nullptr); @@ -105,26 +117,160 @@ IN_PROC_BROWSER_TEST_F(SaveCardConfirmationBubbleViewsInteractiveUiTest, ShowFailureBubbleViewThenHideBubbleView) { ShowBubble(/*card_saved=*/false); - EXPECT_NE(BubbleView(), nullptr); - EXPECT_TRUE(IconView()->GetVisible()); - SaveCardAndVirtualCardEnrollConfirmationUiParams ui_params = - BubbleView()->ui_params_; - EXPECT_FALSE(ui_params.is_success); - EXPECT_EQ(ui_params.title_text, + EXPECT_NE(BubbleView(), nullptr); + EXPECT_FALSE(BubbleView()->ShouldShowCloseButton()); + EXPECT_EQ(BubbleView()->GetBubbleFrameView()->GetHeaderViewForTesting(), + nullptr); + EXPECT_NE(BubbleView()->GetBubbleFrameView()->title(), nullptr); + EXPECT_EQ(BubbleView()->GetWindowTitle(), l10n_util::GetStringUTF16( IDS_AUTOFILL_SAVE_CARD_CONFIRMATION_FAILURE_TITLE_TEXT)); - EXPECT_EQ(ui_params.description_text, + EXPECT_TRUE( + BubbleView()->GetViewByID(DialogViewId::DESCRIPTION_LABEL)->GetVisible()); + EXPECT_EQ(static_cast<views::Label*>( + BubbleView()->GetViewByID(DialogViewId::DESCRIPTION_LABEL)) + ->GetText(), l10n_util::GetStringUTF16( IDS_AUTOFILL_SAVE_CARD_CONFIRMATION_FAILURE_DESCRIPTION_TEXT)); + EXPECT_EQ(BubbleView()->GetDialogButtons(), ui::DIALOG_BUTTON_OK); EXPECT_EQ( - ui_params.failure_button_text, + BubbleView()->GetDialogButtonLabel(ui::DIALOG_BUTTON_OK), l10n_util::GetStringUTF16( IDS_AUTOFILL_SAVE_CARD_AND_VIRTUAL_CARD_ENROLL_CONFIRMATION_FAILURE_BUTTON_TEXT)); + EXPECT_TRUE(IconView()->GetVisible()); HideBubble(views::Widget::ClosedReason::kLostFocus); EXPECT_EQ(BubbleView(), nullptr); EXPECT_FALSE(IconView()->GetVisible()); } +class VirtualCardEnrollConfirmationBubbleViewsInteractiveUiTest + : public InProcessBrowserTest { + public: + VirtualCardEnrollConfirmationBubbleViewsInteractiveUiTest() = default; + ~VirtualCardEnrollConfirmationBubbleViewsInteractiveUiTest() override = + default; + VirtualCardEnrollConfirmationBubbleViewsInteractiveUiTest( + const VirtualCardEnrollConfirmationBubbleViewsInteractiveUiTest&) = + delete; + VirtualCardEnrollConfirmationBubbleViewsInteractiveUiTest& operator=( + const VirtualCardEnrollConfirmationBubbleViewsInteractiveUiTest&) = + delete; + + // InProcessBrowserTest: + void SetUpOnMainThread() override { + VirtualCardEnrollBubbleControllerImpl* virtual_card_enroll_controller = + static_cast<VirtualCardEnrollBubbleControllerImpl*>( + VirtualCardEnrollBubbleControllerImpl::GetOrCreate( + browser()->tab_strip_model()->GetActiveWebContents())); + CHECK(virtual_card_enroll_controller); + } + + VirtualCardEnrollBubbleControllerImpl* GetController() { + if (!browser() || !browser()->tab_strip_model() || + !browser()->tab_strip_model()->GetActiveWebContents()) { + return nullptr; + } + + return VirtualCardEnrollBubbleControllerImpl::FromWebContents( + browser()->tab_strip_model()->GetActiveWebContents()); + } + + SaveCardAndVirtualCardEnrollConfirmationBubbleViews* BubbleView() { + return static_cast<SaveCardAndVirtualCardEnrollConfirmationBubbleViews*>( + GetController()->GetVirtualCardBubbleView()); + } + + VirtualCardEnrollIconView* IconView() { + BrowserView* browser_view = + BrowserView::GetBrowserViewForBrowser(browser()); + PageActionIconView* icon = + browser_view->toolbar_button_provider()->GetPageActionIconView( + PageActionIconType::kVirtualCardEnroll); + CHECK(icon); + return static_cast<VirtualCardEnrollIconView*>(icon); + } + + void ShowBubble(bool is_vcn_enrolled) { + GetController()->ShowConfirmationBubbleView(is_vcn_enrolled); + } + + private: + test::AutofillBrowserTestEnvironment autofill_test_environment_; + base::test::ScopedFeatureList feature_list_{ + features::kAutofillEnableVcnEnrollLoadingAndConfirmation}; +}; + +IN_PROC_BROWSER_TEST_F( + VirtualCardEnrollConfirmationBubbleViewsInteractiveUiTest, + ShowSuccessBubbleViewThenHideBubbleView) { + ShowBubble(/*is_vcn_enrolled=*/true); + + EXPECT_NE(BubbleView(), nullptr); + EXPECT_TRUE(BubbleView()->ShouldShowCloseButton()); + EXPECT_TRUE(BubbleView() + ->GetBubbleFrameView() + ->GetHeaderViewForTesting() + ->GetVisible()); + EXPECT_NE(BubbleView()->GetBubbleFrameView()->title(), nullptr); + EXPECT_EQ( + BubbleView()->GetWindowTitle(), + l10n_util::GetStringUTF16( + IDS_AUTOFILL_VIRTUAL_CARD_ENROLL_CONFIRMATION_SUCCESS_TITLE_TEXT)); + EXPECT_TRUE( + BubbleView()->GetViewByID(DialogViewId::DESCRIPTION_LABEL)->GetVisible()); + EXPECT_EQ( + static_cast<views::Label*>( + BubbleView()->GetViewByID(DialogViewId::DESCRIPTION_LABEL)) + ->GetText(), + l10n_util::GetStringUTF16( + IDS_AUTOFILL_VIRTUAL_CARD_ENROLL_CONFIRMATION_SUCCESS_DESCRIPTION_TEXT)); + EXPECT_EQ(BubbleView()->GetDialogButtons(), ui::DIALOG_BUTTON_NONE); + EXPECT_TRUE(IconView()->GetVisible()); + + GetController()->HideIconAndBubble(); + EXPECT_EQ(BubbleView(), nullptr); + EXPECT_FALSE(IconView()->GetVisible()); +} + +IN_PROC_BROWSER_TEST_F( + VirtualCardEnrollConfirmationBubbleViewsInteractiveUiTest, + ShowFailureBubbleViewThenHideBubbleView) { + CreditCard card = test::GetCreditCard(); + VirtualCardEnrollmentFields enrollment_fields; + enrollment_fields.credit_card = card; + test_api(GetController()).SetFields(enrollment_fields); + ShowBubble(/*is_vcn_enrolled=*/false); + + EXPECT_NE(BubbleView(), nullptr); + EXPECT_FALSE(BubbleView()->ShouldShowCloseButton()); + EXPECT_EQ(BubbleView()->GetBubbleFrameView()->GetHeaderViewForTesting(), + nullptr); + EXPECT_NE(BubbleView()->GetBubbleFrameView()->title(), nullptr); + EXPECT_EQ( + BubbleView()->GetWindowTitle(), + l10n_util::GetStringUTF16( + IDS_AUTOFILL_VIRTUAL_CARD_ENROLL_CONFIRMATION_FAILURE_TITLE_TEXT)); + EXPECT_TRUE( + BubbleView()->GetViewByID(DialogViewId::DESCRIPTION_LABEL)->GetVisible()); + EXPECT_EQ( + static_cast<views::Label*>( + BubbleView()->GetViewByID(DialogViewId::DESCRIPTION_LABEL)) + ->GetText(), + l10n_util::GetStringFUTF16( + IDS_AUTOFILL_VIRTUAL_CARD_ENROLL_CONFIRMATION_FAILURE_DESCRIPTION_TEXT, + card.NetworkAndLastFourDigits())); + EXPECT_EQ(BubbleView()->GetDialogButtons(), ui::DIALOG_BUTTON_OK); + EXPECT_EQ( + BubbleView()->GetDialogButtonLabel(ui::DIALOG_BUTTON_OK), + l10n_util::GetStringUTF16( + IDS_AUTOFILL_SAVE_CARD_AND_VIRTUAL_CARD_ENROLL_CONFIRMATION_FAILURE_BUTTON_TEXT)); + EXPECT_TRUE(IconView()->GetVisible()); + + GetController()->HideIconAndBubble(); + EXPECT_EQ(BubbleView(), nullptr); + EXPECT_FALSE(IconView()->GetVisible()); +} + } // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/payments/virtual_card_enroll_bubble_views_interactive_uitest.cc b/chrome/browser/ui/views/autofill/payments/virtual_card_enroll_bubble_views_interactive_uitest.cc index 2e0cb61..0843bba 100644 --- a/chrome/browser/ui/views/autofill/payments/virtual_card_enroll_bubble_views_interactive_uitest.cc +++ b/chrome/browser/ui/views/autofill/payments/virtual_card_enroll_bubble_views_interactive_uitest.cc
@@ -132,7 +132,7 @@ } return static_cast<VirtualCardEnrollBubbleViews*>( - controller->GetVirtualCardEnrollBubbleView()); + controller->GetVirtualCardBubbleView()); } void ClickLearnMoreLink() { GetBubbleViews()->LearnMoreLinkClicked(); }
diff --git a/chrome/browser/ui/views/autofill/payments/virtual_card_enroll_icon_view.cc b/chrome/browser/ui/views/autofill/payments/virtual_card_enroll_icon_view.cc index 35648f4fb..0d9a0a4 100644 --- a/chrome/browser/ui/views/autofill/payments/virtual_card_enroll_icon_view.cc +++ b/chrome/browser/ui/views/autofill/payments/virtual_card_enroll_icon_view.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/ui/browser_command_controller.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/view_ids.h" +#include "chrome/browser/ui/views/autofill/payments/save_card_and_virtual_card_enroll_confirmation_bubble_views.h" #include "chrome/browser/ui/views/autofill/payments/virtual_card_enroll_bubble_views.h" #include "chrome/grit/generated_resources.h" #include "components/autofill/core/browser/ui/payments/virtual_card_enroll_bubble_controller.h" @@ -45,8 +46,19 @@ return nullptr; } + // Checking controller's `enrollment_status_` is `kCompleted` ensures that + // the bubble view returned is of the type + // `SaveCardAndVirtualCardEnrollConfirmationBubbleViews` since controller + // hides the `VirtualCardEnrollBubbleViews` once the enrollment completes to + // show the confirmation bubble. + if (controller->IsEnrollmentComplete()) { + return static_cast< + autofill::SaveCardAndVirtualCardEnrollConfirmationBubbleViews*>( + controller->GetVirtualCardBubbleView()); + } + return static_cast<autofill::VirtualCardEnrollBubbleViews*>( - controller->GetVirtualCardEnrollBubbleView()); + controller->GetVirtualCardBubbleView()); } void VirtualCardEnrollIconView::UpdateImpl() {
diff --git a/chrome/browser/ui/views/webauthn/sheet_view_factory.cc b/chrome/browser/ui/views/webauthn/sheet_view_factory.cc index abd54f3c..6cda02b 100644 --- a/chrome/browser/ui/views/webauthn/sheet_view_factory.cc +++ b/chrome/browser/ui/views/webauthn/sheet_view_factory.cc
@@ -337,13 +337,15 @@ sheet_view = std::make_unique<AuthenticatorGpmPinSheetView>( std::make_unique<AuthenticatorGPMPinSheetModel>( dialog_model, kPinDigitCount, - AuthenticatorGPMPinSheetModel::Mode::kPinCreate)); + AuthenticatorGPMPinSheetModel::Mode::kPinCreate, + dialog_model->gpm_pin_error())); break; case Step::kGPMEnterPin: sheet_view = std::make_unique<AuthenticatorGpmPinSheetView>( std::make_unique<AuthenticatorGPMPinSheetModel>( dialog_model, kPinDigitCount, - AuthenticatorGPMPinSheetModel::Mode::kPinEntry)); + AuthenticatorGPMPinSheetModel::Mode::kPinEntry, + dialog_model->gpm_pin_error())); break; case Step::kNotStarted: case Step::kConditionalMediation:
diff --git a/chrome/browser/ui/webauthn/sheet_models.cc b/chrome/browser/ui/webauthn/sheet_models.cc index fbde0a3..9631aea 100644 --- a/chrome/browser/ui/webauthn/sheet_models.cc +++ b/chrome/browser/ui/webauthn/sheet_models.cc
@@ -1585,11 +1585,13 @@ AuthenticatorGPMPinSheetModel::AuthenticatorGPMPinSheetModel( AuthenticatorRequestDialogModel* dialog_model, int pin_digits_count, - Mode mode) + Mode mode, + AuthenticatorRequestDialogModel::GpmPinError error) : AuthenticatorSheetModelBase(dialog_model, OtherMechanismButtonVisibility::kHidden), pin_digits_count_(pin_digits_count), - mode_(mode) { + mode_(mode), + error_(error) { // TODO(rgod): Add correct illustration. vector_illustrations_.emplace(kPasskeyHeaderIcon, kPasskeyHeaderDarkIcon); } @@ -1628,6 +1630,15 @@ } } +std::u16string AuthenticatorGPMPinSheetModel::GetError() const { + switch (error_) { + case AuthenticatorRequestDialogModel::GpmPinError::kNone: + return std::u16string(); + case AuthenticatorRequestDialogModel::GpmPinError::kWrongPin: + return u"Wrong PIN (UNTRANSLATED)"; + } +} + bool AuthenticatorGPMPinSheetModel::IsAcceptButtonVisible() const { return true; }
diff --git a/chrome/browser/ui/webauthn/sheet_models.h b/chrome/browser/ui/webauthn/sheet_models.h index d561931..1f22f49 100644 --- a/chrome/browser/ui/webauthn/sheet_models.h +++ b/chrome/browser/ui/webauthn/sheet_models.h
@@ -688,7 +688,8 @@ explicit AuthenticatorGPMPinSheetModel( AuthenticatorRequestDialogModel* dialog_model, int pin_digits_count, - Mode mode); + Mode mode, + AuthenticatorRequestDialogModel::GpmPinError error); ~AuthenticatorGPMPinSheetModel() override; int pin_digits_count() const; @@ -700,6 +701,7 @@ // AuthenticatorSheetModelBase: std::u16string GetStepTitle() const override; std::u16string GetStepDescription() const override; + std::u16string GetError() const override; bool IsAcceptButtonEnabled() const override; bool IsAcceptButtonVisible() const override; std::u16string GetAcceptButtonLabel() const override; @@ -708,6 +710,7 @@ std::u16string pin_; const int pin_digits_count_; const Mode mode_; + const AuthenticatorRequestDialogModel::GpmPinError error_; }; #endif // CHROME_BROWSER_UI_WEBAUTHN_SHEET_MODELS_H_
diff --git a/chrome/browser/ui/webui/downloads/downloads.mojom b/chrome/browser/ui/webui/downloads/downloads.mojom index 8c882e1..861a51d 100644 --- a/chrome/browser/ui/webui/downloads/downloads.mojom +++ b/chrome/browser/ui/webui/downloads/downloads.mojom
@@ -145,6 +145,7 @@ Cancel(string id); ClearAll(); OpenDownloadsFolderRequiringGesture(); + OpenEsbSettings(); // Opens this download with the given |id| while it is being scanned by Safe // Browsing. This completes the scan early. This requires a user gesture on
diff --git a/chrome/browser/ui/webui/downloads/downloads_dom_handler.cc b/chrome/browser/ui/webui/downloads/downloads_dom_handler.cc index 64272499..d6be3fac 100644 --- a/chrome/browser/ui/webui/downloads/downloads_dom_handler.cc +++ b/chrome/browser/ui/webui/downloads/downloads_dom_handler.cc
@@ -40,6 +40,7 @@ #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/hats/trust_safety_sentiment_service.h" #include "chrome/browser/ui/hats/trust_safety_sentiment_service_factory.h" #include "chrome/browser/ui/webui/downloads/downloads.mojom.h" @@ -51,6 +52,7 @@ #include "components/prefs/pref_service.h" #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" +#include "components/safe_browsing/core/common/safebrowsing_referral_methods.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/download_item_utils.h" #include "content/public/browser/download_manager.h" @@ -776,3 +778,13 @@ downloads.push_back(file); RemoveDownloads(downloads); } + +void DownloadsDOMHandler::OpenEsbSettings() { + Browser* browser = chrome::FindBrowserWithTab(GetWebUIWebContents()); + if (!browser) { + return; + } + chrome::ShowSafeBrowsingEnhancedProtectionWithIph( + browser, + safe_browsing::SafeBrowsingSettingReferralMethod::kDownloadPageRowPromo); +}
diff --git a/chrome/browser/ui/webui/downloads/downloads_dom_handler.h b/chrome/browser/ui/webui/downloads/downloads_dom_handler.h index ca99647..f8c1b5b 100644 --- a/chrome/browser/ui/webui/downloads/downloads_dom_handler.h +++ b/chrome/browser/ui/webui/downloads/downloads_dom_handler.h
@@ -74,6 +74,7 @@ void ReviewDangerousRequiringGesture(const std::string& id) override; void DeepScan(const std::string& id) override; void BypassDeepScanRequiringGesture(const std::string& id) override; + void OpenEsbSettings() override; protected: // These methods are for mocking so that most of this class does not actually
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc index 4bb30889..2f57dcaa 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -678,10 +678,15 @@ profile_->GetPrefs()->IsManagedPreference(prefs::kNtpModulesVisible)); source->AddBoolean("customizeChromeEnabled", customize_chrome::IsSidePanelEnabled()); - source->AddBoolean( - "wallpaperSearchButtonEnabled", + bool wallpaper_search_button_enabled = base::FeatureList::IsEnabled(ntp_features::kNtpWallpaperSearchButton) && - customize_chrome::IsWallpaperSearchEnabledForProfile(profile_)); + customize_chrome::IsWallpaperSearchEnabledForProfile(profile_); + source->AddBoolean("wallpaperSearchButtonEnabled", + wallpaper_search_button_enabled); + source->AddBoolean("wallpaperSearchButtonAnimationEnabled", + wallpaper_search_button_enabled && + base::FeatureList::IsEnabled( + ntp_features::kNtpWallpaperSearchButtonAnimation)); content::URLDataSource::Add(profile_, std::make_unique<SanitizedImageSource>(profile_));
diff --git a/chrome/browser/ui/webui/tab_search/tab_search.mojom b/chrome/browser/ui/webui/tab_search/tab_search.mojom index b961f16b..c639bbdc 100644 --- a/chrome/browser/ui/webui/tab_search/tab_search.mojom +++ b/chrome/browser/ui/webui/tab_search/tab_search.mojom
@@ -230,6 +230,9 @@ // Remove the tab from the tab organization. RemoveTabFromOrganization(int32 session_id, int32 organization_id, Tab tab); + // Reject all tab organizations in the current session. + RejectSession(int32 session_id); + // Clear the current tab organization session state and start a new request. RestartSession();
diff --git a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc index 595a28b..a0cf4701 100644 --- a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc +++ b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc
@@ -484,6 +484,27 @@ } } +void TabSearchPageHandler::RejectSession(int32_t session_id) { + Browser* browser = chrome::FindLastActive(); + if (!browser || !organization_service_) { + return; + } + + TabOrganizationSession* session = + organization_service_->GetSessionForBrowser(browser); + if (!session || session->session_id() != session_id) { + return; + } + + for (const std::unique_ptr<TabOrganization>& organization : + session->tab_organizations()) { + organization->Reject(); + } + + organization_service_->ResetSessionForBrowser( + browser, TabOrganizationEntryPoint::kTabSearch, nullptr); +} + void TabSearchPageHandler::RestartSession() { Browser* browser = chrome::FindLastActive(); if (!browser) {
diff --git a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.h b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.h index a226651..0672952 100644 --- a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.h +++ b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.h
@@ -86,6 +86,7 @@ void RemoveTabFromOrganization(int32_t session_id, int32_t organization_id, tab_search::mojom::TabPtr tab) override; + void RejectSession(int32_t session_id) override; void RestartSession() override; void SaveRecentlyClosedExpandedPref(bool expanded) override; void SetTabIndex(int32_t index) override;
diff --git a/chrome/browser/ui/webui/webui_util.cc b/chrome/browser/ui/webui/webui_util.cc index 71a6909e..89e864a 100644 --- a/chrome/browser/ui/webui/webui_util.cc +++ b/chrome/browser/ui/webui/webui_util.cc
@@ -58,7 +58,7 @@ if (scheme == content::kChromeUIScheme) { source->OverrideContentSecurityPolicy( network::mojom::CSPDirectiveName::ConnectSrc, - "connect-src chrome://resources 'self';"); + "connect-src chrome://resources chrome://theme 'self';"); source->OverrideContentSecurityPolicy( network::mojom::CSPDirectiveName::ImgSrc, "img-src chrome://resources chrome://theme chrome://image "
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.cc b/chrome/browser/webauthn/authenticator_request_dialog_model.cc index cd2692a..e69d8bc 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model.cc +++ b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
@@ -1269,7 +1269,7 @@ current_step() == Step::kGPMEnterPin); // TODO(enclave): For kGPMCreatePin - upload pin and handle passkey creation. // TODO(enclave): For kGPMEnterPin - verify pin and handle sign-in or setting - // up biometrics (if available). + // up biometrics (if available) or setting `gpm_pin_error_`. } void AuthenticatorRequestDialogModel::AddAuthenticator(
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.h b/chrome/browser/webauthn/authenticator_request_dialog_model.h index f1b63cc..be14ac81 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model.h +++ b/chrome/browser/webauthn/authenticator_request_dialog_model.h
@@ -286,6 +286,12 @@ kReady, }; + // Possible error states during GPM pin entry / creation. + enum class GpmPinError { + kNone, + kWrongPin, + }; + explicit AuthenticatorRequestDialogModel( content::RenderFrameHost* render_frame_host); @@ -728,6 +734,8 @@ void set_allow_icloud_keychain(bool); void set_should_create_in_icloud_keychain(bool); + GpmPinError gpm_pin_error() const { return gpm_pin_error_; } + #if BUILDFLAG(IS_MAC) void RecordMacOsStartedHistogram(); void RecordMacOsSuccessHistogram(device::FidoRequestType, @@ -982,6 +990,9 @@ // Records the state of the primary account for the profile, if any. AccountState account_state_ = AccountState::kNone; + // Records the error during GPM pin entry / creation, if any. + GpmPinError gpm_pin_error_ = GpmPinError::kNone; + #if BUILDFLAG(IS_MAC) // did_record_macos_start_histogram_ is set to true if a histogram record of // starting the current request was made. Any later successful completion will
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index b2513ad1e..0917b71 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1709229418-1d63095880705d541bde82fa1879afffe3b9eb1d-b0a7a7040e49ebde707133bb7b28d1df2acbe3f5.profdata +chrome-android32-main-1709251103-e8d56921b9676e3c8c28dd83222f6d9af53ff132-3c4dd528ce3d74fc6fbb5168d0d0578f495ae3ac.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 3eabcec..d93ed7fe 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1709236759-a0e0102010e726c3ec9aa26f7a40a2917c462929-cb4b55eca6f33658d7073a2cc65fe5357f6b9ffb.profdata +chrome-mac-arm-main-1709243983-50785a75cb830e0f2240fd1b19b319a71af9aaab-d13c4884812124f4acaa95b49bf2d9031dc14546.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 47a1cc5..773e267 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1709218648-e2b52b52f25d190f3daa56cd2651973155f54f21-e8dfc1f2e3fadb8df821082483dd7e98f14dd2e9.profdata +chrome-win32-main-1709240374-c1fa17f359931ac60670f45b775a845e91cf471b-a24027fc5f6980ae3924b10ebafca851e62c9b14.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 49525b9..76dc689c 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1709218648-0864b8c6975aadc135a9a765319061552d647627-e8dfc1f2e3fadb8df821082483dd7e98f14dd2e9.profdata +chrome-win64-main-1709240374-555542797fa7ce9ea2319c141916825658cb036a-a24027fc5f6980ae3924b10ebafca851e62c9b14.profdata
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn index dde8502..9a4608e2 100644 --- a/chrome/renderer/BUILD.gn +++ b/chrome/renderer/BUILD.gn
@@ -333,6 +333,8 @@ "extensions/api/accessibility_private_hooks_delegate.h", "extensions/api/app_hooks_delegate.cc", "extensions/api/app_hooks_delegate.h", + "extensions/api/chrome_extensions_renderer_api_provider.cc", + "extensions/api/chrome_extensions_renderer_api_provider.h", "extensions/api/extension_hooks_delegate.cc", "extensions/api/extension_hooks_delegate.h", "extensions/api/identity_hooks_delegate.cc",
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 086c1d1..5e6f1d9f 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -202,6 +202,7 @@ #if BUILDFLAG(ENABLE_EXTENSIONS) #include "chrome/common/controlled_frame/controlled_frame.h" #include "chrome/common/initialize_extensions_client.h" +#include "chrome/renderer/extensions/api/chrome_extensions_renderer_api_provider.h" #include "chrome/renderer/extensions/chrome_extensions_renderer_client.h" #include "extensions/common/constants.h" #include "extensions/common/context_data.h" @@ -444,6 +445,8 @@ chrome_extensions_renderer_client->AddAPIProvider( std::make_unique< controlled_frame::ControlledFrameExtensionsRendererAPIProvider>()); + chrome_extensions_renderer_client->AddAPIProvider( + std::make_unique<extensions::ChromeExtensionsRendererAPIProvider>()); chrome_extensions_renderer_client->RenderThreadStarted(); WebSecurityPolicy::RegisterURLSchemeAsExtension( WebString::FromASCII(extensions::kExtensionScheme));
diff --git a/chrome/renderer/controlled_frame/controlled_frame_extensions_renderer_api_provider.cc b/chrome/renderer/controlled_frame/controlled_frame_extensions_renderer_api_provider.cc index 6a9c30f..2064871 100644 --- a/chrome/renderer/controlled_frame/controlled_frame_extensions_renderer_api_provider.cc +++ b/chrome/renderer/controlled_frame/controlled_frame_extensions_renderer_api_provider.cc
@@ -12,10 +12,10 @@ namespace controlled_frame { -void ControlledFrameExtensionsRendererAPIProvider:: - EnableCustomElementAllowlist() { - blink::WebCustomElement::AddEmbedderCustomElementName("controlledframe"); -} +void ControlledFrameExtensionsRendererAPIProvider::RegisterNativeHandlers( + extensions::ModuleSystem* module_system, + extensions::NativeExtensionBindingsSystem* bindings_system, + extensions::ScriptContext* context) {} void ControlledFrameExtensionsRendererAPIProvider::PopulateSourceMap( extensions::ResourceBundleSourceMap* source_map) { @@ -28,6 +28,11 @@ IDR_CONTROLLED_FRAME_API_METHODS_JS); } +void ControlledFrameExtensionsRendererAPIProvider:: + EnableCustomElementAllowlist() { + blink::WebCustomElement::AddEmbedderCustomElementName("controlledframe"); +} + bool ControlledFrameExtensionsRendererAPIProvider::RequireWebViewModules( extensions::ScriptContext* context) { if (context->GetAvailability("controlledFrameInternal").is_available()) {
diff --git a/chrome/renderer/controlled_frame/controlled_frame_extensions_renderer_api_provider.h b/chrome/renderer/controlled_frame/controlled_frame_extensions_renderer_api_provider.h index fd15b49..9cb7eef7 100644 --- a/chrome/renderer/controlled_frame/controlled_frame_extensions_renderer_api_provider.h +++ b/chrome/renderer/controlled_frame/controlled_frame_extensions_renderer_api_provider.h
@@ -28,9 +28,13 @@ ControlledFrameExtensionsRendererAPIProvider& operator=( const ControlledFrameExtensionsRendererAPIProvider&) = delete; - void EnableCustomElementAllowlist() override; + void RegisterNativeHandlers( + extensions::ModuleSystem* module_system, + extensions::NativeExtensionBindingsSystem* bindings_system, + extensions::ScriptContext* context) override; void PopulateSourceMap( extensions::ResourceBundleSourceMap* source_map) override; + void EnableCustomElementAllowlist() override; bool RequireWebViewModules(extensions::ScriptContext* context) override; };
diff --git a/chrome/renderer/extensions/api/chrome_extensions_renderer_api_provider.cc b/chrome/renderer/extensions/api/chrome_extensions_renderer_api_provider.cc new file mode 100644 index 0000000..a2e605e --- /dev/null +++ b/chrome/renderer/extensions/api/chrome_extensions_renderer_api_provider.cc
@@ -0,0 +1,187 @@ +// Copyright 2024 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/renderer/extensions/api/chrome_extensions_renderer_api_provider.h" + +#include "build/chromeos_buildflags.h" +#include "chrome/grit/renderer_resources.h" +#include "chrome/renderer/extensions/api/media_galleries_custom_bindings.h" +#include "chrome/renderer/extensions/api/notifications_native_handler.h" +#include "chrome/renderer/extensions/api/page_capture_custom_bindings.h" +#include "chrome/renderer/extensions/api/sync_file_system_custom_bindings.h" +#include "extensions/renderer/bindings/api_bindings_system.h" +#include "extensions/renderer/lazy_background_page_native_handler.h" +#include "extensions/renderer/module_system.h" +#include "extensions/renderer/native_extension_bindings_system.h" +#include "extensions/renderer/native_handler.h" +#include "extensions/renderer/resource_bundle_source_map.h" + +#if BUILDFLAG(IS_CHROMEOS) +#include "chrome/renderer/extensions/api/file_browser_handler_custom_bindings.h" +#include "chrome/renderer/extensions/api/platform_keys_natives.h" +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/renderer/extensions/api/file_manager_private_custom_bindings.h" +#endif + +namespace extensions { + +void ChromeExtensionsRendererAPIProvider::RegisterNativeHandlers( + ModuleSystem* module_system, + NativeExtensionBindingsSystem* bindings_system, + ScriptContext* context) { + module_system->RegisterNativeHandler( + "sync_file_system", + std::make_unique<SyncFileSystemCustomBindings>(context)); +#if BUILDFLAG(IS_CHROMEOS) + module_system->RegisterNativeHandler( + "file_browser_handler", + std::make_unique<FileBrowserHandlerCustomBindings>(context)); + module_system->RegisterNativeHandler( + "platform_keys_natives", std::make_unique<PlatformKeysNatives>(context)); +#endif // BUILDFLAG(IS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) + module_system->RegisterNativeHandler( + "file_manager_private", + std::make_unique<FileManagerPrivateCustomBindings>(context)); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + module_system->RegisterNativeHandler( + "notifications_private", + std::make_unique<NotificationsNativeHandler>(context)); + module_system->RegisterNativeHandler( + "mediaGalleries", + std::make_unique<MediaGalleriesCustomBindings>(context)); + module_system->RegisterNativeHandler( + "page_capture", std::make_unique<PageCaptureCustomBindings>( + context, bindings_system->GetIPCMessageSender())); + + // The following are native handlers that are defined in //extensions, but + // are only used for APIs defined in Chrome. + // TODO(devlin): We should clean this up. If an API is defined in Chrome, + // there's no reason to have its native handlers residing and being compiled + // in //extensions. + module_system->RegisterNativeHandler( + "lazy_background_page", + std::make_unique<LazyBackgroundPageNativeHandler>(context)); +} + +void ChromeExtensionsRendererAPIProvider::PopulateSourceMap( + ResourceBundleSourceMap* source_map) { + // Custom bindings. + source_map->RegisterSource("action", IDR_ACTION_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("browserAction", + IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("declarativeContent", + IDR_DECLARATIVE_CONTENT_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("desktopCapture", + IDR_DESKTOP_CAPTURE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("developerPrivate", + IDR_DEVELOPER_PRIVATE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("downloads", IDR_DOWNLOADS_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("gcm", IDR_GCM_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("identity", IDR_IDENTITY_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("imageWriterPrivate", + IDR_IMAGE_WRITER_PRIVATE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("input.ime", IDR_INPUT_IME_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("mediaGalleries", + IDR_MEDIA_GALLERIES_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("notifications", + IDR_NOTIFICATIONS_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("omnibox", IDR_OMNIBOX_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("pageAction", IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("pageCapture", + IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("syncFileSystem", + IDR_SYNC_FILE_SYSTEM_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("systemIndicator", + IDR_SYSTEM_INDICATOR_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("tabCapture", IDR_TAB_CAPTURE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("tts", IDR_TTS_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("ttsEngine", IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS); + +#if BUILDFLAG(IS_CHROMEOS) + source_map->RegisterSource("certificateProvider", + IDR_CERTIFICATE_PROVIDER_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("enterprise.platformKeys", + IDR_ENTERPRISE_PLATFORM_KEYS_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("enterprise.platformKeys.CryptoKey", + IDR_ENTERPRISE_PLATFORM_KEYS_CRYPTO_KEY_JS); + source_map->RegisterSource("enterprise.platformKeys.SubtleCrypto", + IDR_ENTERPRISE_PLATFORM_KEYS_SUBTLE_CRYPTO_JS); + source_map->RegisterSource("enterprise.platformKeys.Token", + IDR_ENTERPRISE_PLATFORM_KEYS_TOKEN_JS); + source_map->RegisterSource("fileBrowserHandler", + IDR_FILE_BROWSER_HANDLER_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("fileSystemProvider", + IDR_FILE_SYSTEM_PROVIDER_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("platformKeys", + IDR_PLATFORM_KEYS_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("platformKeys.getCryptoKeyUtil", + IDR_PLATFORM_KEYS_GET_CRYPTO_KEY_UTIL_JS); + source_map->RegisterSource("platformKeys.Key", IDR_PLATFORM_KEYS_KEY_JS); + source_map->RegisterSource("platformKeys.SubtleCrypto", + IDR_PLATFORM_KEYS_SUBTLE_CRYPTO_JS); + source_map->RegisterSource("platformKeys.utils", IDR_PLATFORM_KEYS_UTILS_JS); + + // Remote Apps. + source_map->RegisterSource("chromeos.remote_apps.mojom-lite", + IDR_REMOTE_APPS_MOJOM_LITE_JS); + source_map->RegisterSource("chromeos.remote_apps", + IDR_REMOTE_APPS_BINDINGS_JS); + source_map->RegisterSource("url/mojom/url.mojom-lite", + IDR_MOJO_URL_MOJOM_LITE_JS); +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + source_map->RegisterSource("fileManagerPrivate", + IDR_FILE_MANAGER_PRIVATE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("terminalPrivate", + IDR_TERMINAL_PRIVATE_CUSTOM_BINDINGS_JS); + + // IME service on Chrome OS. + source_map->RegisterSource("ash.ime.mojom.ime_service.mojom", + IDR_IME_SERVICE_MOJOM_JS); + source_map->RegisterSource("ash.ime.mojom.input_engine.mojom", + IDR_IME_SERVICE_INPUT_ENGINE_MOJOM_JS); + source_map->RegisterSource("ash.ime.mojom.input_method.mojom", + IDR_IME_SERVICE_INPUT_METHOD_MOJOM_JS); + source_map->RegisterSource("ash.ime.mojom.input_method_host.mojom", + IDR_IME_SERVICE_INPUT_METHOD_HOST_MOJOM_JS); + source_map->RegisterSource("chromeos.ime.service", + IDR_IME_SERVICE_BINDINGS_JS); + + source_map->RegisterSource("chromeos.tts.mojom.google_tts_stream.mojom", + IDR_GOOGLE_TTS_STREAM_MOJOM_JS); + source_map->RegisterSource("chromeos.tts.google_stream", + IDR_GOOGLE_TTS_STREAM_BINDINGS_JS); + + source_map->RegisterSource("ash.enhanced_network_tts.mojom-lite", + IDR_ENHANCED_NETWORK_TTS_MOJOM_LITE_JS); + source_map->RegisterSource("ash.enhanced_network_tts", + IDR_ENHANCED_NETWORK_TTS_BINDINGS_JS); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + source_map->RegisterSource( + "webrtcDesktopCapturePrivate", + IDR_WEBRTC_DESKTOP_CAPTURE_PRIVATE_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("webrtcLoggingPrivate", + IDR_WEBRTC_LOGGING_PRIVATE_CUSTOM_BINDINGS_JS); + + // Platform app sources that are not API-specific.. + source_map->RegisterSource("chromeWebViewElement", + IDR_CHROME_WEB_VIEW_ELEMENT_JS); + source_map->RegisterSource("chromeWebViewInternal", + IDR_CHROME_WEB_VIEW_INTERNAL_CUSTOM_BINDINGS_JS); + source_map->RegisterSource("chromeWebView", IDR_CHROME_WEB_VIEW_JS); +} + +void ChromeExtensionsRendererAPIProvider::EnableCustomElementAllowlist() {} + +bool ChromeExtensionsRendererAPIProvider::RequireWebViewModules( + ScriptContext* context) { + return false; +} + +} // namespace extensions
diff --git a/chrome/renderer/extensions/api/chrome_extensions_renderer_api_provider.h b/chrome/renderer/extensions/api/chrome_extensions_renderer_api_provider.h new file mode 100644 index 0000000..4263ba6 --- /dev/null +++ b/chrome/renderer/extensions/api/chrome_extensions_renderer_api_provider.h
@@ -0,0 +1,36 @@ +// Copyright 2024 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_RENDERER_EXTENSIONS_API_CHROME_EXTENSIONS_RENDERER_API_PROVIDER_H_ +#define CHROME_RENDERER_EXTENSIONS_API_CHROME_EXTENSIONS_RENDERER_API_PROVIDER_H_ + +#include "extensions/renderer/extensions_renderer_api_provider.h" + +namespace extensions { +class ResourceBundleSourceMap; +class ScriptContext; + +// Provides capabilities for extension APIs defined at the //chrome layer. +class ChromeExtensionsRendererAPIProvider + : public ExtensionsRendererAPIProvider { + public: + ChromeExtensionsRendererAPIProvider() = default; + ChromeExtensionsRendererAPIProvider( + const ChromeExtensionsRendererAPIProvider&) = delete; + ChromeExtensionsRendererAPIProvider& operator=( + const ChromeExtensionsRendererAPIProvider&) = delete; + ~ChromeExtensionsRendererAPIProvider() override = default; + + // ExtensionsRendererAPIProvider: + void RegisterNativeHandlers(ModuleSystem* module_system, + NativeExtensionBindingsSystem* bindings_system, + ScriptContext* context) override; + void PopulateSourceMap(ResourceBundleSourceMap* source_map) override; + void EnableCustomElementAllowlist() override; + bool RequireWebViewModules(ScriptContext* context) override; +}; + +} // namespace extensions + +#endif // CHROME_RENDERER_EXTENSIONS_API_CHROME_EXTENSIONS_RENDERER_API_PROVIDER_H_
diff --git a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc index 969b2ee..9dc7f0b29 100644 --- a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc +++ b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
@@ -12,7 +12,6 @@ #include "chrome/common/channel_info.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/crash_keys.h" -#include "chrome/grit/renderer_resources.h" #include "chrome/renderer/extensions/api/app_hooks_delegate.h" #include "chrome/renderer/extensions/api/extension_hooks_delegate.h" #include "chrome/renderer/extensions/api/identity_hooks_delegate.h" @@ -35,7 +34,6 @@ #include "extensions/renderer/lazy_background_page_native_handler.h" #include "extensions/renderer/native_extension_bindings_system.h" #include "extensions/renderer/native_handler.h" -#include "extensions/renderer/resource_bundle_source_map.h" #include "extensions/renderer/script_context.h" #include "media/media_buildflags.h" #include "printing/buildflags/buildflags.h" @@ -61,162 +59,6 @@ ChromeExtensionsDispatcherDelegate::~ChromeExtensionsDispatcherDelegate() {} -void ChromeExtensionsDispatcherDelegate::RegisterNativeHandlers( - extensions::Dispatcher* dispatcher, - extensions::ModuleSystem* module_system, - extensions::NativeExtensionBindingsSystem* bindings_system, - extensions::ScriptContext* context) { - module_system->RegisterNativeHandler( - "sync_file_system", - std::unique_ptr<NativeHandler>( - new extensions::SyncFileSystemCustomBindings(context))); -#if BUILDFLAG(IS_CHROMEOS) - module_system->RegisterNativeHandler( - "file_browser_handler", - std::make_unique<extensions::FileBrowserHandlerCustomBindings>(context)); - module_system->RegisterNativeHandler( - "platform_keys_natives", - std::make_unique<extensions::PlatformKeysNatives>(context)); -#endif // BUILDFLAG(IS_CHROMEOS) -#if BUILDFLAG(IS_CHROMEOS_ASH) - module_system->RegisterNativeHandler( - "file_manager_private", - std::unique_ptr<NativeHandler>( - new extensions::FileManagerPrivateCustomBindings(context))); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) - module_system->RegisterNativeHandler( - "notifications_private", - std::unique_ptr<NativeHandler>( - new extensions::NotificationsNativeHandler(context))); - module_system->RegisterNativeHandler( - "mediaGalleries", - std::unique_ptr<NativeHandler>( - new extensions::MediaGalleriesCustomBindings(context))); - module_system->RegisterNativeHandler( - "page_capture", std::make_unique<extensions::PageCaptureCustomBindings>( - context, bindings_system->GetIPCMessageSender())); - - // The following are native handlers that are defined in //extensions, but - // are only used for APIs defined in Chrome. - // TODO(devlin): We should clean this up. If an API is defined in Chrome, - // there's no reason to have its native handlers residing and being compiled - // in //extensions. - module_system->RegisterNativeHandler( - "lazy_background_page", - std::unique_ptr<NativeHandler>( - new extensions::LazyBackgroundPageNativeHandler(context))); -} - -void ChromeExtensionsDispatcherDelegate::PopulateSourceMap( - extensions::ResourceBundleSourceMap* source_map) { - // Custom bindings. - source_map->RegisterSource("action", IDR_ACTION_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("browserAction", - IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("declarativeContent", - IDR_DECLARATIVE_CONTENT_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("desktopCapture", - IDR_DESKTOP_CAPTURE_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("developerPrivate", - IDR_DEVELOPER_PRIVATE_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("downloads", IDR_DOWNLOADS_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("gcm", IDR_GCM_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("identity", IDR_IDENTITY_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("imageWriterPrivate", - IDR_IMAGE_WRITER_PRIVATE_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("input.ime", IDR_INPUT_IME_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("mediaGalleries", - IDR_MEDIA_GALLERIES_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("notifications", - IDR_NOTIFICATIONS_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("omnibox", IDR_OMNIBOX_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("pageAction", IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("pageCapture", - IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("syncFileSystem", - IDR_SYNC_FILE_SYSTEM_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("systemIndicator", - IDR_SYSTEM_INDICATOR_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("tabCapture", IDR_TAB_CAPTURE_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("tts", IDR_TTS_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("ttsEngine", IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS); - -#if BUILDFLAG(IS_CHROMEOS) - source_map->RegisterSource("certificateProvider", - IDR_CERTIFICATE_PROVIDER_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("enterprise.platformKeys", - IDR_ENTERPRISE_PLATFORM_KEYS_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("enterprise.platformKeys.CryptoKey", - IDR_ENTERPRISE_PLATFORM_KEYS_CRYPTO_KEY_JS); - source_map->RegisterSource("enterprise.platformKeys.SubtleCrypto", - IDR_ENTERPRISE_PLATFORM_KEYS_SUBTLE_CRYPTO_JS); - source_map->RegisterSource("enterprise.platformKeys.Token", - IDR_ENTERPRISE_PLATFORM_KEYS_TOKEN_JS); - source_map->RegisterSource("fileBrowserHandler", - IDR_FILE_BROWSER_HANDLER_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("fileSystemProvider", - IDR_FILE_SYSTEM_PROVIDER_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("platformKeys", - IDR_PLATFORM_KEYS_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("platformKeys.getCryptoKeyUtil", - IDR_PLATFORM_KEYS_GET_CRYPTO_KEY_UTIL_JS); - source_map->RegisterSource("platformKeys.Key", IDR_PLATFORM_KEYS_KEY_JS); - source_map->RegisterSource("platformKeys.SubtleCrypto", - IDR_PLATFORM_KEYS_SUBTLE_CRYPTO_JS); - source_map->RegisterSource("platformKeys.utils", IDR_PLATFORM_KEYS_UTILS_JS); - - // Remote Apps. - source_map->RegisterSource("chromeos.remote_apps.mojom-lite", - IDR_REMOTE_APPS_MOJOM_LITE_JS); - source_map->RegisterSource("chromeos.remote_apps", - IDR_REMOTE_APPS_BINDINGS_JS); - source_map->RegisterSource("url/mojom/url.mojom-lite", - IDR_MOJO_URL_MOJOM_LITE_JS); -#endif - -#if BUILDFLAG(IS_CHROMEOS_ASH) - source_map->RegisterSource("fileManagerPrivate", - IDR_FILE_MANAGER_PRIVATE_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("terminalPrivate", - IDR_TERMINAL_PRIVATE_CUSTOM_BINDINGS_JS); - - // IME service on Chrome OS. - source_map->RegisterSource("ash.ime.mojom.ime_service.mojom", - IDR_IME_SERVICE_MOJOM_JS); - source_map->RegisterSource("ash.ime.mojom.input_engine.mojom", - IDR_IME_SERVICE_INPUT_ENGINE_MOJOM_JS); - source_map->RegisterSource("ash.ime.mojom.input_method.mojom", - IDR_IME_SERVICE_INPUT_METHOD_MOJOM_JS); - source_map->RegisterSource("ash.ime.mojom.input_method_host.mojom", - IDR_IME_SERVICE_INPUT_METHOD_HOST_MOJOM_JS); - source_map->RegisterSource("chromeos.ime.service", - IDR_IME_SERVICE_BINDINGS_JS); - - source_map->RegisterSource("chromeos.tts.mojom.google_tts_stream.mojom", - IDR_GOOGLE_TTS_STREAM_MOJOM_JS); - source_map->RegisterSource("chromeos.tts.google_stream", - IDR_GOOGLE_TTS_STREAM_BINDINGS_JS); - - source_map->RegisterSource("ash.enhanced_network_tts.mojom-lite", - IDR_ENHANCED_NETWORK_TTS_MOJOM_LITE_JS); - source_map->RegisterSource("ash.enhanced_network_tts", - IDR_ENHANCED_NETWORK_TTS_BINDINGS_JS); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) - - source_map->RegisterSource( - "webrtcDesktopCapturePrivate", - IDR_WEBRTC_DESKTOP_CAPTURE_PRIVATE_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("webrtcLoggingPrivate", - IDR_WEBRTC_LOGGING_PRIVATE_CUSTOM_BINDINGS_JS); - - // Platform app sources that are not API-specific.. - source_map->RegisterSource("chromeWebViewElement", - IDR_CHROME_WEB_VIEW_ELEMENT_JS); - source_map->RegisterSource("chromeWebViewInternal", - IDR_CHROME_WEB_VIEW_INTERNAL_CUSTOM_BINDINGS_JS); - source_map->RegisterSource("chromeWebView", IDR_CHROME_WEB_VIEW_JS); -} - void ChromeExtensionsDispatcherDelegate::RequireWebViewModules( extensions::ScriptContext* context) { DCHECK(context->GetAvailability("webViewInternal").is_available());
diff --git a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h index a939f33..a0560d3 100644 --- a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h +++ b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h
@@ -21,13 +21,6 @@ private: // extensions::DispatcherDelegate implementation. - void RegisterNativeHandlers( - extensions::Dispatcher* dispatcher, - extensions::ModuleSystem* module_system, - extensions::NativeExtensionBindingsSystem* bindings_system, - extensions::ScriptContext* context) override; - void PopulateSourceMap( - extensions::ResourceBundleSourceMap* source_map) override; void RequireWebViewModules(extensions::ScriptContext* context) override; void OnActiveExtensionsUpdated( const std::set<std::string>& extensions_ids) override;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 0e038a6..585049f 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1830,6 +1830,7 @@ "//components/history/content/browser", "//components/history/core/common", "//components/history_clusters/core:core", + "//components/history_embeddings", "//components/image_fetcher/core", "//components/infobars/content", "//components/invalidation/impl", @@ -2096,7 +2097,6 @@ "//components/policy/proto", "//testing:test_scripts_shared", "//testing/buildbot/filters:browser_tests_filters", - "//testing/buildbot/filters:cr23_pixel_browser_tests_filters", "//testing/buildbot/filters:linux_trusty_rel_browser_tests_filters", "//third_party/mesa_headers", "//third_party/private_membership:private_membership_proto", @@ -2317,6 +2317,7 @@ "../browser/history/history_browsertest.cc", "../browser/history/redirect_browsertest.cc", "../browser/history_clusters/history_clusters_metrics_browsertest.cc", + "../browser/history_embeddings/history_embeddings_service_browsertest.cc", "../browser/icon_loader_browsertest.cc", "../browser/icon_transcoder/svg_icon_transcoder_browsertest.cc", "../browser/idle/idle_browsertest.cc", @@ -4816,7 +4817,6 @@ "../browser/policy/login_policy_test_base_browsertest.cc", "../browser/policy/restricted_mgs_policy_provider_ash_browsertest.cc", "../browser/process_singleton_browsertest.cc", - "../browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc", "../browser/sessions/session_restore_browsertest_chromeos.cc", "../browser/signin/chromeos_mirror_account_consistency_browsertest.cc", "../browser/speech/extension_api/tts_extension_api_ash_browsertest.cc", @@ -4884,6 +4884,7 @@ "../browser/ui/quick_answers/quick_answers_browsertest.cc", "../browser/ui/quick_answers/quick_answers_browsertest_base.cc", "../browser/ui/quick_answers/quick_answers_browsertest_base.h", + "../browser/ui/quick_answers/quick_answers_controller_browsertest.cc", "../browser/ui/settings_window_manager_browsertest_chromeos.cc", "../browser/ui/views/apps/app_dialog/app_dialog_view_browsertest.cc", "../browser/ui/views/apps/app_dialog/app_uninstall_dialog_view_browsertest.cc", @@ -8335,7 +8336,7 @@ "../browser/performance_manager/policies/oom_score_policy_chromeos_unittest.cc", "../browser/performance_manager/policies/report_page_processes_policy_unittest.cc", "../browser/policy/system_features_disable_list_policy_handler_unittest.cc", - "../browser/renderer_context_menu/quick_answers_menu_observer_unittest.cc", + "../browser/renderer_context_menu/read_write_card_observer_unittest.cc", "../browser/speech/tts_crosapi_util_unittest.cc", "../browser/ui/webui/certificate_provisioning_ui_handler_unittest.cc", "../browser/usb/usb_pinned_notification_unittest.cc",
diff --git a/chrome/test/data/webui/chromeos/print_preview_cros/fake_print_preview_page_handler_test.ts b/chrome/test/data/webui/chromeos/print_preview_cros/fake_print_preview_page_handler_test.ts index 323010b..182363b1 100644 --- a/chrome/test/data/webui/chromeos/print_preview_cros/fake_print_preview_page_handler_test.ts +++ b/chrome/test/data/webui/chromeos/print_preview_cros/fake_print_preview_page_handler_test.ts
@@ -7,6 +7,7 @@ import {FAKE_PRINT_REQUEST_FAILURE_INVALID_SETTINGS_ERROR, FAKE_PRINT_REQUEST_SUCCESSFUL, FakePrintPreviewPageHandler} from 'chrome://os-print/js/fakes/fake_print_preview_page_handler.js'; import {assert} from 'chrome://resources/js/assert.js'; import {assertEquals} from 'chrome://webui-test/chromeos/chai_assert.js'; +import {MockController} from 'chrome://webui-test/chromeos/mock_controller.m.js'; suite('PrintPreviewCrosApp', () => { let printPreviewPageHandler: FakePrintPreviewPageHandler; @@ -46,4 +47,37 @@ printPreviewPageHandler.cancel(); assertEquals(1, printPreviewPageHandler.getCallCount('cancel')); }); + + // Verify the fake PrintPreviewPageHandler method uses 0ms delay resolve + // method by default. + test('default delay is 0ms', async () => { + const mockController = new MockController(); + const methods = printPreviewPageHandler.getMethodsForTesting(); + const resolveNoDelay = + mockController.createFunctionMock(methods, 'resolveMethodWithDelay'); + const delay = 0; + resolveNoDelay.addExpectation('print', delay); + await printPreviewPageHandler.print(); + + mockController.verifyMocks(); + mockController.reset(); + }); + + // Verify the fake PrintPreviewPageHandler use resolve method with delay when + // a delay is configured. + test( + 'uses delayed resolver when testDelayMs is greater than zero', + async () => { + const mockController = new MockController(); + const methods = printPreviewPageHandler.getMethodsForTesting(); + const resolveWithDelay = mockController.createFunctionMock( + methods, 'resolveMethodWithDelay'); + const delay = 1; + resolveWithDelay.addExpectation('print', delay); + printPreviewPageHandler.useTestDelay(delay); + await printPreviewPageHandler.print(); + + mockController.verifyMocks(); + mockController.reset(); + }); });
diff --git a/chrome/test/data/webui/chromeos/print_preview_cros/print_ticket_manager_test.ts b/chrome/test/data/webui/chromeos/print_preview_cros/print_ticket_manager_test.ts index 30d866d..8d37dfd1 100644 --- a/chrome/test/data/webui/chromeos/print_preview_cros/print_ticket_manager_test.ts +++ b/chrome/test/data/webui/chromeos/print_preview_cros/print_ticket_manager_test.ts
@@ -4,22 +4,31 @@ import 'chrome://os-print/js/data/print_ticket_manager.js'; -import {PrintTicketManager} from 'chrome://os-print/js/data/print_ticket_manager.js'; +import {PRINT_REQUEST_FINISHED_EVENT, PRINT_REQUEST_STARTED_EVENT, PrintTicketManager} from 'chrome://os-print/js/data/print_ticket_manager.js'; import {FakePrintPreviewPageHandler} from 'chrome://os-print/js/fakes/fake_print_preview_page_handler.js'; import {setPrintPreviewPageHandlerForTesting} from 'chrome://os-print/js/utils/mojo_data_providers.js'; -import {assertEquals, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js'; +import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js'; +import {MockTimer} from 'chrome://webui-test/mock_timer.js'; +import {eventToPromise} from 'chrome://webui-test/test_util.js'; suite('PrintTicketManager', () => { let printPreviewPageHandler: FakePrintPreviewPageHandler; + let mockTimer: MockTimer; setup(() => { PrintTicketManager.resetInstanceForTesting(); // Setup fakes for testing. + mockTimer = new MockTimer(); + mockTimer.install(); printPreviewPageHandler = new FakePrintPreviewPageHandler(); setPrintPreviewPageHandlerForTesting(printPreviewPageHandler); }); + teardown(() => { + mockTimer.uninstall(); + }); + test('is a singleton', () => { const instance1 = PrintTicketManager.getInstance(); const instance2 = PrintTicketManager.getInstance(); @@ -49,4 +58,117 @@ instance.cancelPrintRequest(); assertEquals(1, printPreviewPageHandler.getCallCount(method)); }); + + // Verify PRINT_REQUEST_STARTED_EVENT is dispatched when sentPrintRequest is + // called and PRINT_REQUEST_FINISHED_EVENT is called when + // PrintPreviewPageHandler.print resolves. + test( + 'PRINT_REQUEST_STARTED_EVENT and PRINT_REQUEST_FINISHED_EVENT are ' + + ' invoked when sentPrintRequest called', + async () => { + const delay = 1; + printPreviewPageHandler.useTestDelay(delay); + const instance = PrintTicketManager.getInstance(); + let startCount = 0; + instance.addEventListener(PRINT_REQUEST_STARTED_EVENT, () => { + ++startCount; + }); + let finishCount = 0; + instance.addEventListener(PRINT_REQUEST_FINISHED_EVENT, () => { + ++finishCount; + }); + const startEvent = + eventToPromise(PRINT_REQUEST_STARTED_EVENT, instance); + const finishEvent = + eventToPromise(PRINT_REQUEST_FINISHED_EVENT, instance); + + assertEquals(0, startCount, 'Start should have zero calls'); + assertEquals(0, finishCount, 'Finish should have zero calls'); + + instance.sendPrintRequest(); + + await startEvent; + + assertEquals(1, startCount, 'Start should have one call'); + assertEquals(0, finishCount, 'Finish should have zero calls'); + + // Advance time by test delay to trigger method resolver. + mockTimer.tick(delay); + await finishEvent; + + assertEquals(1, startCount, 'Start should have one call'); + assertEquals(1, finishCount, 'Finish should have one call'); + }); + + // Verify isPrintRequestInProgress is false until sentPrintRequest is called + // and returns to false when PrintPreviewPageHandler.print resolves. + test( + 'isPrintRequestInProgress updates based on sendPrintRequest progress', + async () => { + const delay = 1; + printPreviewPageHandler.useTestDelay(delay); + const instance = PrintTicketManager.getInstance(); + const startEvent = + eventToPromise(PRINT_REQUEST_STARTED_EVENT, instance); + const finishEvent = + eventToPromise(PRINT_REQUEST_FINISHED_EVENT, instance); + + assertFalse(instance.isPrintRequestInProgress(), 'Request not started'); + + instance.sendPrintRequest(); + + await startEvent; + + assertTrue(instance.isPrintRequestInProgress(), 'Request started'); + + mockTimer.tick(delay); + await finishEvent; + + assertFalse(instance.isPrintRequestInProgress(), 'Request finished'); + }); + + // Verify PrintTicketManger ensures that PrintPreviewPageHandler.print is only + // called if print request is not in progress. + test('ensure only one print request triggered at a time', async () => { + const delay = 1; + printPreviewPageHandler.useTestDelay(delay); + const instance = PrintTicketManager.getInstance(); + const startEvent = eventToPromise(PRINT_REQUEST_STARTED_EVENT, instance); + const finishEvent = eventToPromise(PRINT_REQUEST_FINISHED_EVENT, instance); + + const method = 'print'; + let expectedCallCount = 0; + assertEquals( + expectedCallCount, printPreviewPageHandler.getCallCount(method), + 'No request sent'); + assertFalse(instance.isPrintRequestInProgress(), 'Request not started'); + + instance.sendPrintRequest(); + + // After calling `sendPrintRequest` the call count should increment. + ++expectedCallCount; + await startEvent; + + assertEquals( + expectedCallCount, printPreviewPageHandler.getCallCount(method), + 'One request sent'); + assertTrue(instance.isPrintRequestInProgress(), 'Request started'); + + // While request is in progress additional `sendPrintRequest` should not + // call `PrintPreviewPageHandler.print`. + instance.sendPrintRequest(); + instance.sendPrintRequest(); + instance.sendPrintRequest(); + assertEquals( + expectedCallCount, printPreviewPageHandler.getCallCount(method), + 'One request sent'); + + mockTimer.tick(delay); + await finishEvent; + + assertEquals( + expectedCallCount, printPreviewPageHandler.getCallCount(method), + 'One request sent'); + assertFalse(instance.isPrintRequestInProgress(), 'Request finished'); + }); });
diff --git a/chrome/test/data/webui/chromeos/print_preview_cros/summary_panel_controller_test.ts b/chrome/test/data/webui/chromeos/print_preview_cros/summary_panel_controller_test.ts index d7e1bfb4..7c37f6c 100644 --- a/chrome/test/data/webui/chromeos/print_preview_cros/summary_panel_controller_test.ts +++ b/chrome/test/data/webui/chromeos/print_preview_cros/summary_panel_controller_test.ts
@@ -4,25 +4,37 @@ import 'chrome://os-print/js/summary_panel.js'; -import {PrintTicketManager} from 'chrome://os-print/js/data/print_ticket_manager.js'; +import {PRINT_REQUEST_FINISHED_EVENT, PRINT_REQUEST_STARTED_EVENT, PrintTicketManager} from 'chrome://os-print/js/data/print_ticket_manager.js'; +import {FakePrintPreviewPageHandler} from 'chrome://os-print/js/fakes/fake_print_preview_page_handler.js'; import {SummaryPanelController} from 'chrome://os-print/js/summary_panel_controller.js'; +import {setPrintPreviewPageHandlerForTesting} from 'chrome://os-print/js/utils/mojo_data_providers.js'; import {assert} from 'chrome://resources/js/assert.js'; -import {assertEquals, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js'; +import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js'; import {MockController} from 'chrome://webui-test/chromeos/mock_controller.m.js'; +import {eventToPromise} from 'chrome://webui-test/test_util.js'; suite('SummaryPanelController', () => { let controller: SummaryPanelController|null = null; let mockController: MockController; + let printPreviewPageHandler: FakePrintPreviewPageHandler; + let printTicketManger: PrintTicketManager; setup(() => { mockController = new MockController(); + PrintTicketManager.resetInstanceForTesting(); + // Setup fakes. + printPreviewPageHandler = new FakePrintPreviewPageHandler(); + setPrintPreviewPageHandlerForTesting(printPreviewPageHandler); + printTicketManger = PrintTicketManager.getInstance(); + controller = new SummaryPanelController(); assertTrue(!!controller); }); teardown(() => { mockController.reset(); + PrintTicketManager.resetInstanceForTesting(); controller = null; }); @@ -67,4 +79,60 @@ controller!.handleCancelClicked(); mockController.verifyMocks(); }); + + // Verify handler called when PRINT_REQUEST_STARTED_EVENT triggered. + test('PRINT_REQUEST_STARTED_EVENT calls onPrintRequestStarted', async () => { + assert(controller); + const handlerFn = + mockController.createFunctionMock(controller, 'onPrintRequestStarted'); + const testEvent = new CustomEvent<void>( + PRINT_REQUEST_STARTED_EVENT, {bubbles: true, composed: true}); + const startRequest = + eventToPromise(PRINT_REQUEST_STARTED_EVENT, printTicketManger); + handlerFn.addExpectation(testEvent); + + printTicketManger.dispatchEvent(testEvent); + await startRequest; + + mockController.verifyMocks(); + }); + + // Verify handler called when PRINT_REQUEST_FINISHED_EVENT triggered. + test( + 'PRINT_REQUEST_FINISHED_EVENT calls onPrintRequestFinished', async () => { + assert(controller); + const handlerFn = mockController.createFunctionMock( + controller, 'onPrintRequestFinished'); + const testEvent = new CustomEvent<void>( + PRINT_REQUEST_FINISHED_EVENT, {bubbles: true, composed: true}); + const finishRequest = + eventToPromise(PRINT_REQUEST_FINISHED_EVENT, printTicketManger); + handlerFn.addExpectation(testEvent); + + printTicketManger.dispatchEvent(testEvent); + await finishRequest; + + mockController.verifyMocks(); + }); + + // Verify shouldDisablePrintButton is true when print request is in progress. + test( + 'shouldDisablePrintButton true while print request is in progress', + () => { + const printRequestInProgressFn = mockController.createFunctionMock( + printTicketManger, 'isPrintRequestInProgress'); + printRequestInProgressFn.returnValue = true; + assertTrue(controller!.shouldDisablePrintButton()); + }); + + // Verify shouldDisablePrintButton is false when print request is not in + // progress. + test( + 'shouldDisablePrintButton true while print request is in progress', + () => { + const printRequestInProgressFn = mockController.createFunctionMock( + printTicketManger, 'isPrintRequestInProgress'); + printRequestInProgressFn.returnValue = false; + assertFalse(controller!.shouldDisablePrintButton()); + }); });
diff --git a/chrome/test/data/webui/chromeos/print_preview_cros/summary_panel_test.ts b/chrome/test/data/webui/chromeos/print_preview_cros/summary_panel_test.ts index 68f8dec..6b6d33b7b 100644 --- a/chrome/test/data/webui/chromeos/print_preview_cros/summary_panel_test.ts +++ b/chrome/test/data/webui/chromeos/print_preview_cros/summary_panel_test.ts
@@ -4,14 +4,18 @@ import 'chrome://os-print/js/summary_panel.js'; +import {PrintTicketManager} from 'chrome://os-print/js/data/print_ticket_manager.js'; +import {FakePrintPreviewPageHandler} from 'chrome://os-print/js/fakes/fake_print_preview_page_handler.js'; import {SummaryPanelElement} from 'chrome://os-print/js/summary_panel.js'; -import {SHEETS_USED_CHANGED_EVENT, SummaryPanelController} from 'chrome://os-print/js/summary_panel_controller.js'; +import {PRINT_BUTTON_DISABLED_CHANGED_EVENT, SHEETS_USED_CHANGED_EVENT, SummaryPanelController} from 'chrome://os-print/js/summary_panel_controller.js'; +import {setPrintPreviewPageHandlerForTesting} from 'chrome://os-print/js/utils/mojo_data_providers.js'; import {strictQuery} from 'chrome://resources/ash/common/typescript_utils/strict_query.js'; import {Button} from 'chrome://resources/cros_components/button/button.js'; import {assert} from 'chrome://resources/js/assert.js'; -import {assertEquals, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js'; +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js'; import {MockController} from 'chrome://webui-test/chromeos/mock_controller.m.js'; -import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; +import {MockTimer} from 'chrome://webui-test/mock_timer.js'; import {eventToPromise, isChildVisible, isVisible} from 'chrome://webui-test/test_util.js'; suite('SummaryPanel', () => { @@ -22,10 +26,18 @@ let element: SummaryPanelElement|null = null; let controller: SummaryPanelController|null = null; let mockController: MockController|null = null; + let printPreviewPageHandler: FakePrintPreviewPageHandler; + let mockTimer: MockTimer; setup(async () => { document.body.innerHTML = window.trustedTypes!.emptyHTML; + // Configure mocks and fakes. mockController = new MockController(); + mockTimer = new MockTimer(); + mockTimer.install(); + PrintTicketManager.resetInstanceForTesting(); + printPreviewPageHandler = new FakePrintPreviewPageHandler(); + setPrintPreviewPageHandlerForTesting(printPreviewPageHandler); element = document.createElement(SummaryPanelElement.is) as SummaryPanelElement; assertTrue(!!element); @@ -37,10 +49,11 @@ // CrOS components are async and require flushTasks before they are // available. - await flushTasks(); + flush(); }); teardown(() => { + mockTimer.uninstall(); if (element) { element.remove(); } @@ -48,6 +61,7 @@ controller = null; mockController?.reset(); mockController = null; + PrintTicketManager.resetInstanceForTesting(); }); // Sets sheets used in controller and wait for UI to update. @@ -57,7 +71,7 @@ eventToPromise(SHEETS_USED_CHANGED_EVENT, controller); controller.setSheetsUsedForTesting(sheetsUsed); await sheetsUsedEvent; - await flushTasks(); + flush(); } // Verify the summary-panel element can be rendered, contains print, cancel, @@ -150,4 +164,42 @@ // Verify controller is listening to click event. mockController.verifyMocks(); }); + + // Verify print button disabled when print button clicked and re-enabled when + // PrintPreviewPageHandler.print resolves. + test('Print button disabled while print request in progress', async () => { + assert(controller); + const printDisabledEvent1 = + eventToPromise(PRINT_BUTTON_DISABLED_CHANGED_EVENT, controller); + const delay = 10; + printPreviewPageHandler.useTestDelay(delay); + + const printButton = + strictQuery<Button>(printButtonSelector, element!.shadowRoot, Button); + assertFalse( + printButton.disabled, 'Print should be enabled before request sent'); + + printButton.click(); + await printDisabledEvent1; + + const printTicketManger = PrintTicketManager.getInstance(); + assertTrue( + printTicketManger.isPrintRequestInProgress(), + 'Print request in progress'); + assertTrue( + printButton.disabled, + 'Print should be disabled while request in progress'); + + const printDisabledEvent2 = + eventToPromise(PRINT_BUTTON_DISABLED_CHANGED_EVENT, controller); + mockTimer.tick(delay); + await printDisabledEvent2; + + assertFalse( + printTicketManger.isPrintRequestInProgress(), + 'Print request is complete'); + assertFalse( + printButton.disabled, + 'Print should be enabled after request completes'); + }); });
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.ts index 9adae58..f9a59bb9 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.ts +++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.ts
@@ -597,8 +597,8 @@ const viewContainer = viewElement.shadowRoot!.querySelector('#container') as HTMLDivElement; - // The icon name is 'overview' in keyToIconNameMap. - const regex = /^(search|launcher) alt shift overview$/; + // The icon label is 'show windows'. + const regex = /^(search|launcher) alt shift show windows$/; assertTrue(!!viewContainer.ariaLabel); assertTrue(regex.test(viewContainer.ariaLabel)); });
diff --git a/chrome/test/data/webui/downloads/test_support.ts b/chrome/test/data/webui/downloads/test_support.ts index b232eabb..4ef6fd9 100644 --- a/chrome/test/data/webui/downloads/test_support.ts +++ b/chrome/test/data/webui/downloads/test_support.ts
@@ -85,6 +85,7 @@ reviewDangerousRequiringGesture(_id: string) {} deepScan(_id: string) {} bypassDeepScanRequiringGesture(_id: string) {} + openEsbSettings() {} } export class TestIconLoader extends TestBrowserProxy implements IconLoader {
diff --git a/chrome/test/data/webui/new_tab_page/app_test.ts b/chrome/test/data/webui/new_tab_page/app_test.ts index f2c49b29..524c3b3 100644 --- a/chrome/test/data/webui/new_tab_page/app_test.ts +++ b/chrome/test/data/webui/new_tab_page/app_test.ts
@@ -1175,6 +1175,7 @@ suiteSetup(() => { loadTimeData.overrideValues({ wallpaperSearchButtonEnabled: true, + wallpaperSearchButtonAnimationEnabled: true, }); }); @@ -1183,6 +1184,18 @@ assertTrue(!!app.shadowRoot!.querySelector('#wallpaperSearchButton')); }); + test('button has animation if the flag is enabled', () => { + assertNotStyle( + $$(app, '#wallpaperSearchButtonContainer')!, 'animation-name', + 'none'); + assertNotStyle( + $$(app, '#wallpaperSearchButton .customize-icon')!, + 'animation-name', 'none'); + assertNotStyle( + $$(app, '#wallpaperSearchButton .customize-text')!, + 'animation-name', 'none'); + }); + ([ ['#customizeButton', NtpElement.CUSTOMIZE_BUTTON], ['#wallpaperSearchButton', NtpElement.WALLPAPER_SEARCH_BUTTON], @@ -1358,5 +1371,25 @@ $$<HTMLElement>(app, '#customizeButtonContainer')!.offsetWidth); }); }); + + suite('AnimationDisabled', () => { + suiteSetup(() => { + loadTimeData.overrideValues({ + wallpaperSearchButtonAnimationEnabled: false, + }); + }); + + test('button has no animation if the flag is disabled', () => { + assertStyle( + $$(app, '#wallpaperSearchButtonContainer')!, 'animation-name', + 'none'); + assertStyle( + $$(app, '#wallpaperSearchButton .customize-icon')!, + 'animation-name', 'none'); + assertStyle( + $$(app, '#wallpaperSearchButton .customize-text')!, + 'animation-name', 'none'); + }); + }); }); });
diff --git a/chrome/test/data/webui/settings/chromeos/os_printing_page/cups_printer_landing_page_test.ts b/chrome/test/data/webui/settings/chromeos/os_printing_page/cups_printer_landing_page_test.ts index 504faea7..0d7590d7 100644 --- a/chrome/test/data/webui/settings/chromeos/os_printing_page/cups_printer_landing_page_test.ts +++ b/chrome/test/data/webui/settings/chromeos/os_printing_page/cups_printer_landing_page_test.ts
@@ -1389,11 +1389,11 @@ // connected to a network. assertTrue(!!page.shadowRoot!.querySelector('#cloudOffIcon')); assertTrue(!!page.shadowRoot!.querySelector('#connectionMessage')); - const addManualPrinterButtonRevamp = + const addManualPrinterButton = page.shadowRoot!.querySelector<HTMLButtonElement>( - '#addManualPrinterButtonRevamp'); - assertTrue(!!addManualPrinterButtonRevamp); - assertTrue(addManualPrinterButtonRevamp.disabled); + '#addManualPrinterButton'); + assertTrue(!!addManualPrinterButton); + assertTrue(addManualPrinterButton.disabled); }); test('checkNetworkConnection', async () => { @@ -1407,11 +1407,11 @@ // connected. assertTrue(!!page.shadowRoot!.querySelector('#cloudOffIcon')); assertTrue(!!page.shadowRoot!.querySelector('#connectionMessage')); - const addManualPrinterButtonRevamp = + const addManualPrinterButton = page.shadowRoot!.querySelector<HTMLButtonElement>( - '#addManualPrinterButtonRevamp'); - assertTrue(!!addManualPrinterButtonRevamp); - assertTrue(addManualPrinterButtonRevamp.disabled); + '#addManualPrinterButton'); + assertTrue(!!addManualPrinterButton); + assertTrue(addManualPrinterButton.disabled); // Simulate connecting to a network with connectivity. wifi1.connectionState = ConnectionStateType.kOnline; page.onActiveNetworksChanged([wifi1]);
diff --git a/chrome/test/data/webui/settings/chromeos/os_printing_page/cups_printer_page_test.ts b/chrome/test/data/webui/settings/chromeos/os_printing_page/cups_printer_page_test.ts index b648e035..9b0ffee 100644 --- a/chrome/test/data/webui/settings/chromeos/os_printing_page/cups_printer_page_test.ts +++ b/chrome/test/data/webui/settings/chromeos/os_printing_page/cups_printer_page_test.ts
@@ -160,7 +160,7 @@ await flushTasks(); const icon = page.shadowRoot!.querySelector<HTMLButtonElement>( - '#addManualPrinterButtonRevamp'); + '#addManualPrinterButton'); assertTrue(!!icon); icon.click(); assertEquals(
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.cc b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.cc index a87d605..e4182f8d 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.cc +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.cc
@@ -1750,18 +1750,23 @@ RunSettingsTest("os_people_page/account_manager_settings_card_test.js"); } -class OSSettingsPeopleTestLacrosOnlyDisabled : public OSSettingsMochaTest { +class OSSettingsMochaTestRevampAndLacrosOnlyDisabled + : public OSSettingsMochaTest { protected: - OSSettingsPeopleTestLacrosOnlyDisabled() { - scoped_feature_list_.InitAndDisableFeature( - ash::standalone_browser::features::kLacrosOnly); + OSSettingsMochaTestRevampAndLacrosOnlyDisabled() { + scoped_feature_list_.InitWithFeatures( + /*enabled=*/{}, + /*disabled=*/{ + ash::standalone_browser::features::kLacrosOnly, + ash::features::kOsSettingsRevampWayfinding, + }); } private: base::test::ScopedFeatureList scoped_feature_list_; }; -IN_PROC_BROWSER_TEST_F(OSSettingsPeopleTestLacrosOnlyDisabled, +IN_PROC_BROWSER_TEST_F(OSSettingsMochaTestRevampAndLacrosOnlyDisabled, OsPeoplePageAccountManagerSubpage) { RunSettingsTest("os_people_page/account_manager_subpage_test.js"); }
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index dec9555..079bb38a 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -36,6 +36,10 @@ 'ash::standalone_browser::features::kLacrosOnly', 'ash::standalone_browser::features::kLacrosProfileMigrationForceOff', ], + disabled: [ + // The account manager subpage does not exist under the revamp. + 'ash::features::kOsSettingsRevampWayfinding', + ], }, ], ].forEach(test => registerTest(...test));
diff --git a/chrome/test/data/webui/tab_search/tab_organization_page_test.ts b/chrome/test/data/webui/tab_search/tab_organization_page_test.ts index 579d0e8..0bbdfe773f 100644 --- a/chrome/test/data/webui/tab_search/tab_organization_page_test.ts +++ b/chrome/test/data/webui/tab_search/tab_organization_page_test.ts
@@ -100,6 +100,42 @@ override); } + function createMultiOrganizationSession( + count: number, override: Partial<TabOrganizationSession> = {}) { + const organizations: Object[] = []; + for (let i = 0; i < count; i++) { + organizations.push( + { + organizationId: i, + name: stringToMojoString16('Organization ' + i), + tabs: [ + createTab({ + title: 'Tab 1 Organization ' + i, + url: {url: 'https://tab-1.com/'}, + }), + createTab({ + title: 'Tab 2 Organization ' + i, + url: {url: 'https://tab-2.com/'}, + }), + createTab({ + title: 'Tab 3 Organization ' + i, + url: {url: 'https://tab-3.com/'}, + }), + ], + }, + ); + } + + return Object.assign( + { + sessionId: 1, + state: TabOrganizationState.kSuccess, + organizations: organizations, + error: TabOrganizationError.kNone, + }, + override); + } + test('Organize tabs starts request', async () => { await tabOrganizationPageSetup(); assertEquals(0, testApiProxy.getCallCount('requestTabOrganization')); @@ -264,7 +300,7 @@ assertFalse(focusableElement2.matches(':focus')); }); - test('Create group accepts organization', async () => { + test('Single organization create group accepts organization', async () => { await tabOrganizationPageSetup(); testApiProxy.getCallbackRouterRemote().tabOrganizationSessionUpdated( @@ -288,6 +324,39 @@ assertEquals(1, testApiProxy.getCallCount('acceptTabOrganization')); }); + test( + 'Multi organization create groups accepts all organizations', + async () => { + loadTimeData.overrideValues({ + multiTabOrganizationEnabled: true, + }); + + await tabOrganizationPageSetup(); + + const organizationCount = 3; + testApiProxy.getCallbackRouterRemote().tabOrganizationSessionUpdated( + createMultiOrganizationSession(organizationCount)); + await flushTasks(); + + assertEquals(0, testApiProxy.getCallCount('acceptTabOrganization')); + + const results = tabOrganizationPage.shadowRoot!.querySelector( + 'tab-organization-results'); + assertTrue(!!results); + const actions = results.shadowRoot!.querySelector( + 'tab-organization-results-actions'); + assertTrue(!!actions); + const createGroupsButton = + actions.shadowRoot!.querySelector<HTMLElement>('#createButton'); + assertTrue(!!createGroupsButton); + createGroupsButton.click(); + await flushTasks(); + + assertEquals( + organizationCount, + testApiProxy.getCallCount('acceptTabOrganization')); + }); + test('Group cancel button rejects organization', async () => { loadTimeData.overrideValues({ multiTabOrganizationEnabled: true, @@ -315,7 +384,7 @@ assertEquals(1, testApiProxy.getCallCount('rejectTabOrganization')); }); - test('Refresh rejects organization', async () => { + test('Single organization refresh rejects organization', async () => { const rejectFinalSuggestion = 'Clear'; loadTimeData.overrideValues({ @@ -349,6 +418,34 @@ assertEquals(1, testApiProxy.getCallCount('rejectTabOrganization')); }); + test('Multi organization refresh rejects session', async () => { + loadTimeData.overrideValues({ + multiTabOrganizationEnabled: true, + }); + + await tabOrganizationPageSetup(); + + testApiProxy.getCallbackRouterRemote().tabOrganizationSessionUpdated( + createSession({state: TabOrganizationState.kSuccess})); + await flushTasks(); + + assertEquals(0, testApiProxy.getCallCount('rejectSession')); + + const results = tabOrganizationPage.shadowRoot!.querySelector( + 'tab-organization-results'); + assertTrue(!!results); + const actions = + results.shadowRoot!.querySelector('tab-organization-results-actions'); + assertTrue(!!actions); + const refreshButton = + actions.shadowRoot!.querySelector<HTMLElement>('#refreshButton'); + assertTrue(!!refreshButton); + refreshButton.click(); + await flushTasks(); + + assertEquals(1, testApiProxy.getCallCount('rejectSession')); + }); + test( 'Refresh button has different label for multiple suggestions', async () => { @@ -362,34 +459,10 @@ await tabOrganizationPageSetup(); - const multiOrganizationSession = { - sessionId: 1, - state: TabOrganizationState.kSuccess, - organizations: [ - { - organizationId: 1, - name: stringToMojoString16('foo'), - tabs: [ - createTab({title: 'Tab 1', url: {url: 'https://tab-1.com/'}}), - createTab({title: 'Tab 2', url: {url: 'https://tab-2.com/'}}), - createTab({title: 'Tab 3', url: {url: 'https://tab-3.com/'}}), - ], - }, - { - organizationId: 2, - name: stringToMojoString16('bar'), - tabs: [ - createTab({title: 'Tab 4', url: {url: 'https://tab-4.com/'}}), - createTab({title: 'Tab 5', url: {url: 'https://tab-5.com/'}}), - createTab({title: 'Tab 6', url: {url: 'https://tab-6.com/'}}), - ], - }, - ], - error: TabOrganizationError.kNone, - }; + testApiProxy.getCallbackRouterRemote().tabOrganizationSessionUpdated( - multiOrganizationSession); + createMultiOrganizationSession(2)); await flushTasks(); const results = tabOrganizationPage.shadowRoot!.querySelector(
diff --git a/chrome/test/data/webui/tab_search/test_tab_search_api_proxy.ts b/chrome/test/data/webui/tab_search/test_tab_search_api_proxy.ts index 9609b68..36be767 100644 --- a/chrome/test/data/webui/tab_search/test_tab_search_api_proxy.ts +++ b/chrome/test/data/webui/tab_search/test_tab_search_api_proxy.ts
@@ -23,6 +23,7 @@ 'openRecentlyClosedEntry', 'requestTabOrganization', 'removeTabFromOrganization', + 'rejectSession', 'restartSession', 'switchToTab', 'saveRecentlyClosedExpandedPref', @@ -84,6 +85,10 @@ 'removeTabFromOrganization', sessionId, organizationId, tab); } + rejectSession() { + this.methodCalled('rejectSession'); + } + restartSession() { this.methodCalled('restartSession'); }
diff --git a/chrome/updater/net/network_fetcher_win.cc b/chrome/updater/net/network_fetcher_win.cc index 7ae4a9e2..9b44987a 100644 --- a/chrome/updater/net/network_fetcher_win.cc +++ b/chrome/updater/net/network_fetcher_win.cc
@@ -43,7 +43,7 @@ policy_service_proxy_configuration) { if (policy_service_proxy_configuration) { return base::MakeRefCounted<winhttp::ProxyConfiguration>(winhttp::ProxyInfo{ - policy_service_proxy_configuration->proxy_auto_detect.value_or(true), + policy_service_proxy_configuration->proxy_auto_detect, base::SysUTF8ToWide( policy_service_proxy_configuration->proxy_pac_url.value_or("")), base::SysUTF8ToWide( @@ -192,6 +192,9 @@ ScopedImpersonation impersonate; if (IsSystemInstall()) { HResultOr<ScopedKernelHANDLE> token = GetLoggedOnUserToken(); + VLOG_IF(2, !token.has_value()) + << __func__ << ": GetLoggedOnUserToken failed: " << std::hex + << token.error(); if (token.has_value()) { const HRESULT hr = impersonate.Impersonate(token.value().get()); VLOG(2)
diff --git a/chrome/updater/policy/service.cc b/chrome/updater/policy/service.cc index ad7604f..7e393301 100644 --- a/chrome/updater/policy/service.cc +++ b/chrome/updater/policy/service.cc
@@ -710,6 +710,8 @@ } } else if (proxy_mode.policy().compare(kProxyModeAutoDetect) == 0) { policy_service_proxy_configuration.proxy_auto_detect = true; + } else { + is_policy_config_valid = false; } if (!is_policy_config_valid) {
diff --git a/chrome/updater/policy/service.h b/chrome/updater/policy/service.h index 0f68715b..bd2d6c1 100644 --- a/chrome/updater/policy/service.h +++ b/chrome/updater/policy/service.h
@@ -199,7 +199,10 @@ static std::optional<PolicyServiceProxyConfiguration> Get( scoped_refptr<PolicyService> policy_service); - std::optional<bool> proxy_auto_detect; + // Note `Get()` returns a nullopt when there's no proxy policies. Otherwise + // `proxy_auto_detect` must have a value, and is only set to true when the + // policy chooses "auto-detect". + bool proxy_auto_detect = false; std::optional<std::string> proxy_pac_url; std::optional<std::string> proxy_url; };
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 40f6092..80dc386f 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -15790.0.0 \ No newline at end of file +15803.0.0 \ No newline at end of file
diff --git a/clank b/clank index 5ac8fb2..eadffcd 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 5ac8fb250ea25c91a12158f768d4f5c03976f15e +Subproject commit eadffcd4b5ec79ec69e29f75c6695edf9c69aff1
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index 8e165954..1dc84c1 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -87,9 +87,7 @@ // Returns true if the scheme given by |url| is one for which autofill is // allowed to activate. By default this only returns true for HTTP and HTTPS. bool HasAllowedScheme(const GURL& url) { - return url.SchemeIsHTTPOrHTTPS() || - base::FeatureList::IsEnabled( - features::test::kAutofillAllowNonHttpActivation); + return url.SchemeIsHTTPOrHTTPS(); } std::string ServerTypesToString(const AutofillField* field) {
diff --git a/components/autofill/core/browser/ui/payments/virtual_card_enroll_bubble_controller.h b/components/autofill/core/browser/ui/payments/virtual_card_enroll_bubble_controller.h index 22f859a9..c819661b 100644 --- a/components/autofill/core/browser/ui/payments/virtual_card_enroll_bubble_controller.h +++ b/components/autofill/core/browser/ui/payments/virtual_card_enroll_bubble_controller.h
@@ -44,9 +44,9 @@ virtual VirtualCardEnrollmentBubbleSource GetVirtualCardEnrollmentBubbleSource() const = 0; - // Returns the currently active virtual card enroll bubble view. Can be - // nullptr if no bubble is visible. - virtual AutofillBubbleBase* GetVirtualCardEnrollBubbleView() const = 0; + // Returns the currently active virtual card enroll or confirmation bubble + // view. Can be nullptr if no bubble is visible. + virtual AutofillBubbleBase* GetVirtualCardBubbleView() const = 0; #if !BUILDFLAG(IS_ANDROID) // Hides the bubble and icon if it is showing. @@ -55,6 +55,9 @@ // Returns true if bubble is already accepted and the virtual card enrollment // process is in progress. virtual bool IsEnrollmentInProgress() const = 0; + + // Returns true if server request for virtual card enrollment is complete. + virtual bool IsEnrollmentComplete() const = 0; #endif // Virtual card enroll button takes card information to enroll into a VCN.
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index a4d3ba1..ffd5124 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -677,13 +677,6 @@ namespace test { -// Controls whether autofill activates on non-HTTP(S) pages. Useful for -// automated tests with data URLS in cases where it's too difficult to use the -// embedded test server. Generally avoid using. -BASE_FEATURE(kAutofillAllowNonHttpActivation, - "AutofillAllowNonHttpActivation", - base::FEATURE_DISABLED_BY_DEFAULT); - // Testing tool that collects metrics during a run of the captured site tests // and dumps the collected metrics into a specified output directory. // For each test, a file named {test-name}.txt is created. It contains all the
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h index aec4638b..5c4b3fc 100644 --- a/components/autofill/core/common/autofill_features.h +++ b/components/autofill/core/common/autofill_features.h
@@ -236,8 +236,6 @@ namespace test { COMPONENT_EXPORT(AUTOFILL) -BASE_DECLARE_FEATURE(kAutofillAllowNonHttpActivation); -COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillCapturedSiteTestsMetricsScraper); COMPONENT_EXPORT(AUTOFILL) extern const base::FeatureParam<std::string>
diff --git a/components/history/core/browser/sync/history_sync_bridge.cc b/components/history/core/browser/sync/history_sync_bridge.cc index 9b6c772..128d582 100644 --- a/components/history/core/browser/sync/history_sync_bridge.cc +++ b/components/history/core/browser/sync/history_sync_bridge.cc
@@ -175,6 +175,11 @@ // Definitionally, any visit from Sync is known to sync. row.is_known_to_sync = true; + // Transfer app_id if present. + if (specifics.has_app_id()) { + row.app_id = specifics.app_id(); + } + // Reconstruct the page transition - first get the core type. int page_transition = syncer::FromSyncPageTransition( specifics.page_transition().core_transition()); @@ -300,7 +305,8 @@ const GURL& referrer_url, const std::vector<GURL>& favicon_urls, int64_t local_cluster_id, - std::vector<VisitID>* included_visit_ids) { + std::vector<VisitID>* included_visit_ids, + std::optional<std::string> app_id) { DCHECK(!local_cache_guid.empty()); DCHECK(!redirect_visits.empty()); @@ -442,6 +448,9 @@ } history->set_originator_cluster_id(local_cluster_id); + if (app_id) { + history->set_app_id(*app_id); + } // The entity name is used for debugging purposes; choose something that's a // decent tradeoff between "unique" and "readable". @@ -1064,9 +1073,10 @@ // should be the same (except potentially in unit tests). int64_t local_cluster_id = history_backend_->GetClusterIdContainingVisit( redirect_visits.front().visit_id); - entities.push_back(MakeEntityData( - GetLocalCacheGuid(), annotated_visits, chain_middle_trimmed, - referrer_url, favicon_urls, local_cluster_id, included_visit_ids)); + entities.push_back(MakeEntityData(GetLocalCacheGuid(), annotated_visits, + chain_middle_trimmed, referrer_url, + favicon_urls, local_cluster_id, + included_visit_ids, final_visit.app_id)); } return entities;
diff --git a/components/history/core/browser/sync/history_sync_bridge_unittest.cc b/components/history/core/browser/sync/history_sync_bridge_unittest.cc index eb35f53..ae61d15 100644 --- a/components/history/core/browser/sync/history_sync_bridge_unittest.cc +++ b/components/history/core/browser/sync/history_sync_bridge_unittest.cc
@@ -34,6 +34,9 @@ namespace history { +const std::string kTestAppId = "org.chromium.dino.stegosaurus"; +const std::string kTestAppId2 = "org.chromium.dino.velociraptor"; + namespace { using testing::_; @@ -48,6 +51,7 @@ const std::string& originator_cache_guid, const std::vector<GURL>& urls, const std::vector<VisitID>& originator_visit_ids = {}, + std::optional<std::string> app_id = std::nullopt, const bool has_url_keyed_image = false, const std::vector<VisitContentModelAnnotations::Category>& categories = {}, const std::vector<std::string>& related_searches = {}) { @@ -67,6 +71,9 @@ sync_pb::SyncEnums_PageTransitionRedirectType_SERVER_REDIRECT); } } + if (app_id) { + specifics.set_app_id(*app_id); + } specifics.set_has_url_keyed_image(has_url_keyed_image); for (const auto& category : categories) { auto* category_to_sync = specifics.add_categories(); @@ -83,12 +90,13 @@ const std::string& originator_cache_guid, const GURL& url, VisitID originator_visit_id = 0, + std::optional<std::string> app_id = std::nullopt, const bool has_url_keyed_image = false, const std::vector<VisitContentModelAnnotations::Category>& categories = {}, const std::vector<std::string>& related_searches = {}) { return CreateSpecifics(visit_time, originator_cache_guid, std::vector{url}, - std::vector{originator_visit_id}, has_url_keyed_image, - categories, related_searches); + std::vector{originator_visit_id}, app_id, + has_url_keyed_image, categories, related_searches); } syncer::EntityData SpecificsToEntityData( @@ -293,7 +301,8 @@ std::pair<URLRow, VisitRow> AddVisitToBackendAndAdvanceClock( const GURL& url, ui::PageTransition transition, - VisitID referring_visit = kInvalidVisitID) { + VisitID referring_visit = kInvalidVisitID, + std::optional<std::string> app_id = std::nullopt) { // After grabbing the visit time, advance the mock time so that the next // visit will get a unique time. base::Time visit_time = base::Time::Now(); @@ -316,6 +325,7 @@ ui::PageTransitionFromInt(transition | ui::PAGE_TRANSITION_CHAIN_START | ui::PAGE_TRANSITION_CHAIN_END); visit_row.referring_visit = referring_visit; + visit_row.app_id = app_id; visit_row.visit_id = backend()->AddVisit(visit_row); return {url_row, visit_row}; @@ -475,11 +485,13 @@ const std::vector<std::string> related_searches( {related_search_1, related_search_2}); - AddVisitToBackendAndAdvanceClock(local_url, ui::PAGE_TRANSITION_LINK); + AddVisitToBackendAndAdvanceClock(local_url, ui::PAGE_TRANSITION_LINK, + /*referring_visit=*/kInvalidVisitID, + kTestAppId); sync_pb::HistorySpecifics remote_entity = CreateSpecifics( base::Time::Now() - base::Minutes(1), remote_cache_guid, remote_url, {}, - has_url_keyed_image, categories, related_searches); + kTestAppId2, has_url_keyed_image, categories, related_searches); ApplyInitialSyncChanges({remote_entity}); @@ -494,6 +506,9 @@ EXPECT_EQ(backend()->GetVisits()[1].url_id, backend()->GetURLs()[1].id()); EXPECT_EQ(backend()->GetVisits()[1].originator_cache_guid, remote_cache_guid); EXPECT_TRUE(backend()->GetVisits()[1].is_known_to_sync); + EXPECT_EQ(backend()->GetVisits()[0].app_id, kTestAppId); + EXPECT_EQ(backend()->GetVisits()[1].app_id, kTestAppId2); + // Check that the remote visit's annotation info got synced. // NOTE: Annotation info is present on the last remote visit. const std::vector<AnnotatedVisit> annotated_visits = @@ -531,25 +546,29 @@ TEST_F(HistorySyncBridgeTest, MergesRemoteChanges) { const GURL remote_url("https://remote.com"); - sync_pb::HistorySpecifics remote_entity = CreateSpecifics( - base::Time::Now() - base::Minutes(1), "remote_cache_guid", remote_url); + sync_pb::HistorySpecifics remote_entity = + CreateSpecifics(base::Time::Now() - base::Minutes(1), "remote_cache_guid", + remote_url, {}, kTestAppId); // Start Sync the first time, so the remote data gets written to the local DB. ApplyInitialSyncChanges({remote_entity}); ASSERT_EQ(backend()->GetURLs().size(), 1u); ASSERT_EQ(backend()->GetVisits().size(), 1u); ASSERT_EQ(backend()->GetVisits()[0].visit_duration, base::TimeDelta()); + ASSERT_EQ(backend()->GetVisits()[0].app_id, kTestAppId); // Stop Sync, then start it again so the same data gets downloaded again. ApplyDisableSyncChanges(); // ...but the data has been updated in the meantime. remote_entity.set_visit_duration_micros(1000); + remote_entity.set_app_id(kTestAppId2); ApplyInitialSyncChanges({remote_entity}); // The entries in the local DB should have been updated (*not* duplicated). ASSERT_EQ(backend()->GetURLs().size(), 1u); ASSERT_EQ(backend()->GetVisits().size(), 1u); EXPECT_EQ(backend()->GetVisits()[0].visit_duration, base::Microseconds(1000)); + ASSERT_EQ(backend()->GetVisits()[0].app_id, kTestAppId2); } TEST_F(HistorySyncBridgeTest, DoesNotApplyUnsyncableRemoteChanges) {
diff --git a/components/history_embeddings/BUILD.gn b/components/history_embeddings/BUILD.gn index c86e19fd..292a52d2 100644 --- a/components/history_embeddings/BUILD.gn +++ b/components/history_embeddings/BUILD.gn
@@ -21,6 +21,10 @@ "//components/history_embeddings/proto:history_embeddings_proto", "//components/keyed_service/core", "//components/os_crypt/sync", + "//content/public/browser", + "//content/public/common", + "//mojo/public/cpp/bindings", + "//services/service_manager", "//sql", "//third_party/zlib/google:compression_utils", "//url",
diff --git a/components/history_embeddings/DEPS b/components/history_embeddings/DEPS index 22121a38..6237e997 100644 --- a/components/history_embeddings/DEPS +++ b/components/history_embeddings/DEPS
@@ -1,7 +1,11 @@ include_rules = [ "+components/keyed_service/core", "+components/os_crypt/sync", + "+content/public/browser", + "+mojo/public/cpp/bindings", + "+services/service_manager/public/cpp", "+sql", + "+third_party/blink/public", "+third_party/zlib", "+url", ]
diff --git a/components/history_embeddings/history_embeddings_features.cc b/components/history_embeddings/history_embeddings_features.cc index e6391c2..8a5cac0e 100644 --- a/components/history_embeddings/history_embeddings_features.cc +++ b/components/history_embeddings/history_embeddings_features.cc
@@ -12,4 +12,9 @@ "HistoryEmbeddings", base::FEATURE_DISABLED_BY_DEFAULT); +const base::FeatureParam<int> kPassageExtractionMaxWordsPerAggregatePassage( + &kHistoryEmbeddings, + "PassageExtractionMaxWordsPerAggregatePassage", + 200); + } // namespace history_embeddings
diff --git a/components/history_embeddings/history_embeddings_features.h b/components/history_embeddings/history_embeddings_features.h index e5a1f25b..22f614d 100644 --- a/components/history_embeddings/history_embeddings_features.h +++ b/components/history_embeddings/history_embeddings_features.h
@@ -6,11 +6,18 @@ #define COMPONENTS_HISTORY_EMBEDDINGS_HISTORY_EMBEDDINGS_FEATURES_H_ #include "base/feature_list.h" +#include "base/metrics/field_trial_params.h" namespace history_embeddings { BASE_DECLARE_FEATURE(kHistoryEmbeddings); +// Specifies the `max_words_per_aggregate_passage` parameter for the +// DocumentChunker passage extraction algorithm. A passage from a single +// node can exceed this maximum, but aggregation keeps within the limit. +extern const base::FeatureParam<int> + kPassageExtractionMaxWordsPerAggregatePassage; + } // namespace history_embeddings #endif // COMPONENTS_HISTORY_EMBEDDINGS_HISTORY_EMBEDDINGS_FEATURES_H_
diff --git a/components/history_embeddings/history_embeddings_service.cc b/components/history_embeddings/history_embeddings_service.cc index 4dba6e37..1ce6560e 100644 --- a/components/history_embeddings/history_embeddings_service.cc +++ b/components/history_embeddings/history_embeddings_service.cc
@@ -4,18 +4,63 @@ #include "components/history_embeddings/history_embeddings_service.h" +#include <numeric> + #include "base/feature_list.h" #include "base/files/file_path.h" #include "base/functional/bind.h" +#include "base/metrics/histogram_functions.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" +#include "base/time/time.h" #include "components/history_embeddings/history_embeddings_features.h" #include "components/history_embeddings/sql_database.h" +#include "mojo/public/cpp/bindings/callback_helpers.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/mojom/content_extraction/inner_text.mojom.h" namespace history_embeddings { +UrlPassages::UrlPassages() = default; +UrlPassages::~UrlPassages() = default; +UrlPassages::UrlPassages(UrlPassages&&) = default; +UrlPassages& UrlPassages::operator=(UrlPassages&&) = default; + +void OnGotInnerText(mojo::Remote<blink::mojom::InnerTextAgent> remote, + base::TimeTicks start_time, + GURL url, + base::OnceCallback<void(UrlPassages)> callback, + blink::mojom::InnerTextFramePtr mojo_frame) { + const base::TimeDelta extraction_time = base::TimeTicks::Now() - start_time; + UrlPassages url_passages; + url_passages.url = std::move(url); + if (mojo_frame) { + for (const auto& segment : mojo_frame->segments) { + if (segment->is_text()) { + url_passages.passages.push_back(segment->get_text()); + } + } + base::UmaHistogramTimes("History.Embeddings.Passages.ExtractionTime", + extraction_time); + } + const size_t total_text_size = + std::reduce(url_passages.passages.cbegin(), url_passages.passages.cend(), + 0u, [](size_t acc, const std::string& passage) { + return acc + passage.size(); + }); + base::UmaHistogramCounts1000("History.Embeddings.Passages.PassageCount", + url_passages.passages.size()); + base::UmaHistogramCounts10M("History.Embeddings.Passages.TotalTextSize", + total_text_size); + std::move(callback).Run(std::move(url_passages)); +} + +//////////////////////////////////////////////////////////////////////////////// + HistoryEmbeddingsService::HistoryEmbeddingsService( - const base::FilePath& storage_dir) { + const base::FilePath& storage_dir) + : weak_ptr_factory_(this) { if (!base::FeatureList::IsEnabled(kHistoryEmbeddings)) { // If the feature flag is disabled, skip initialization. Note we don't also // check the pref here, because the pref can change at runtime. @@ -31,8 +76,35 @@ HistoryEmbeddingsService::~HistoryEmbeddingsService() = default; +void HistoryEmbeddingsService::RetrievePassages(content::RenderFrameHost& host, + PassagesCallback callback) { + const base::TimeTicks start_time = base::TimeTicks::Now(); + mojo::Remote<blink::mojom::InnerTextAgent> agent; + host.GetRemoteInterfaces()->GetInterface(agent.BindNewPipeAndPassReceiver()); + auto params = blink::mojom::InnerTextParams::New(); + params->max_words_per_aggregate_passage = + std::max(0, kPassageExtractionMaxWordsPerAggregatePassage.Get()); + auto* agent_ptr = agent.get(); + agent_ptr->GetInnerText( + std::move(params), + mojo::WrapCallbackWithDefaultInvokeIfNotRun( + base::BindOnce( + &OnGotInnerText, std::move(agent), start_time, + host.GetLastCommittedURL(), + base::BindOnce(&HistoryEmbeddingsService::OnPassagesRetrieved, + weak_ptr_factory_.GetWeakPtr(), + std::move(callback))), + nullptr)); +} + void HistoryEmbeddingsService::Shutdown() { database_.Reset(); } +void HistoryEmbeddingsService::OnPassagesRetrieved(PassagesCallback callback, + UrlPassages url_passages) { + // TODO(orinj): Store in database. For now just notify callback for testing. + std::move(callback).Run(std::move(url_passages)); +} + } // namespace history_embeddings
diff --git a/components/history_embeddings/history_embeddings_service.h b/components/history_embeddings/history_embeddings_service.h index fe24576b..ea4796f6 100644 --- a/components/history_embeddings/history_embeddings_service.h +++ b/components/history_embeddings/history_embeddings_service.h
@@ -5,13 +5,34 @@ #ifndef COMPONENTS_HISTORY_EMBEDDINGS_HISTORY_EMBEDDINGS_SERVICE_H_ #define COMPONENTS_HISTORY_EMBEDDINGS_HISTORY_EMBEDDINGS_SERVICE_H_ +#include <string> +#include <vector> + #include "base/files/file_path.h" +#include "base/functional/callback.h" +#include "base/memory/weak_ptr.h" #include "base/threading/sequence_bound.h" #include "components/history_embeddings/sql_database.h" #include "components/keyed_service/core/keyed_service.h" +#include "content/public/browser/render_frame_host.h" +#include "url/gurl.h" namespace history_embeddings { +struct UrlPassages { + UrlPassages(); + ~UrlPassages(); + UrlPassages(const UrlPassages&) = delete; + UrlPassages& operator=(const UrlPassages&) = delete; + UrlPassages(UrlPassages&&); + UrlPassages& operator=(UrlPassages&&); + + GURL url; + std::vector<std::string> passages; +}; + +using PassagesCallback = base::OnceCallback<void(UrlPassages)>; + class HistoryEmbeddingsService : public KeyedService { public: // `storage_dir` will generally be the Profile directory. @@ -20,13 +41,24 @@ HistoryEmbeddingsService& operator=(const HistoryEmbeddingsService&) = delete; ~HistoryEmbeddingsService() override; + // Initiate async passage extraction from given host's main frame. + // When extraction completes, the passages will be stored in the database + // and then given to the callback. + void RetrievePassages(content::RenderFrameHost& host, + PassagesCallback callback); + // KeyedService: void Shutdown() override; private: + // Called indirectly via RetrievePassages when passage extraction completes. + void OnPassagesRetrieved(PassagesCallback callback, UrlPassages passages); + // The underlying SQL database, bound to a separate storage sequence. // This will be null if the feature flag is disabled. base::SequenceBound<SqlDatabase> database_; + + base::WeakPtrFactory<HistoryEmbeddingsService> weak_ptr_factory_; }; } // namespace history_embeddings
diff --git a/components/lens/lens_features.cc b/components/lens/lens_features.cc index 16df1ca..255dde51 100644 --- a/components/lens/lens_features.cc +++ b/components/lens/lens_features.cc
@@ -175,5 +175,9 @@ return kShouldIssueProcessPrewarmingForLens.Get(); } +bool IsLensOverlayEnabled() { + return base::FeatureList::IsEnabled(kLensOverlay); +} + } // namespace features } // namespace lens
diff --git a/components/lens/lens_features.h b/components/lens/lens_features.h index c1bbfed..66e3b0c 100644 --- a/components/lens/lens_features.h +++ b/components/lens/lens_features.h
@@ -195,6 +195,10 @@ // is shown. COMPONENT_EXPORT(LENS_FEATURES) extern bool GetShouldIssueProcessPrewarmingForLens(); + +// Returns whether to the Lens overlay is enabled +COMPONENT_EXPORT(LENS_FEATURES) +extern bool IsLensOverlayEnabled(); } // namespace features } // namespace lens
diff --git a/components/optimization_guide/core/optimization_guide_features.cc b/components/optimization_guide/core/optimization_guide_features.cc index 75b56bc..970dc242 100644 --- a/components/optimization_guide/core/optimization_guide_features.cc +++ b/components/optimization_guide/core/optimization_guide_features.cc
@@ -403,23 +403,39 @@ } bool IsModelQualityLoggingEnabledForFeature( - proto::ModelExecutionFeature feature_name) { + proto::ModelExecutionFeature feature) { if (!IsModelQualityLoggingEnabled()) { return false; } - // Disable logging for test features. - if (feature_name == + // Always disable logging for test features. + if (feature == proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_UNSPECIFIED || - feature_name == - proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_TEST) { + feature == proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_TEST) { return false; } + bool default_logging_enabled = false; + switch (feature) { + case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_COMPOSE: + case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_TAB_ORGANIZATION: + case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_WALLPAPER_SEARCH: + // Enable logging when you have approvals. For new features please + // consult with components/optimization_guide/core/model_quality/OWNERS to + // discuss if you need logging or not for your feature. + default_logging_enabled = true; + break; + case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_UNSPECIFIED: + case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_TEST: + // Logging disabled. + NOTREACHED(); + break; + } + std::string param_name = - base::ToLowerASCII(proto::ModelExecutionFeature_Name(feature_name)); + base::ToLowerASCII(proto::ModelExecutionFeature_Name(feature)); return GetFieldTrialParamByFeatureAsBool(kModelQualityLogging, param_name, - true); + default_logging_enabled); } bool IsRemoteFetchingEnabled() {
diff --git a/components/optimization_guide/core/optimization_guide_features_unittest.cc b/components/optimization_guide/core/optimization_guide_features_unittest.cc index b61f1eb..dceccfe 100644 --- a/components/optimization_guide/core/optimization_guide_features_unittest.cc +++ b/components/optimization_guide/core/optimization_guide_features_unittest.cc
@@ -95,6 +95,25 @@ proto::MODEL_EXECUTION_FEATURE_UNSPECIFIED)); } +TEST(OptimizationGuideFeaturesTest, + ModelQualityLoggingAlwaysDisabledForTestAndUnspecifiedFeatures) { + base::test::ScopedFeatureList scoped_feature_list; + + scoped_feature_list.InitAndEnableFeatureWithParameters( + features::kModelQualityLogging, + {{"model_execution_feature_test", "true"}, + {"model_execution_feature_unspecified", "true"}}); + + EXPECT_TRUE(features::IsModelQualityLoggingEnabled()); + + // Test and Unspecified features should have logging always disabled not + // allowed to be controlled via finch. + EXPECT_FALSE(features::IsModelQualityLoggingEnabledForFeature( + proto::MODEL_EXECUTION_FEATURE_TEST)); + EXPECT_FALSE(features::IsModelQualityLoggingEnabledForFeature( + proto::MODEL_EXECUTION_FEATURE_UNSPECIFIED)); +} + TEST(OptimizationGuideFeaturesTest, ComposeModelQualityLoggingDisabled) { base::test::ScopedFeatureList scoped_feature_list;
diff --git a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.h b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.h index 25672be..945b01f 100644 --- a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.h +++ b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.h
@@ -74,6 +74,10 @@ // immersive fullscreen session. - (BOOL)immersiveFullscreen; +// The sheet parent that should be used. In immersive fullscreen the preferred +// sheet parent is the root window (the browser window). +- (NSWindow*)preferredSheetParent; + // Identifier for the NativeWidgetMac from which this window was created. This // may be used to look up the NativeWidgetMacNSWindowHost in the browser process // or the NativeWidgetNSWindowBridge in a display process.
diff --git a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm index 568f0c2..eca5cea 100644 --- a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm +++ b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm
@@ -840,6 +840,10 @@ return NO; } +- (NSWindow*)preferredSheetParent { + return [self immersiveFullscreen] ? [self rootWindow] : self; +} + #ifndef NDEBUG - (NSString*)debugDescription { if (!self.title.length) {
diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm index 3f4ac8e..5535f9c5 100644 --- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm +++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
@@ -1790,6 +1790,10 @@ host_->OnVisibilityChanged(window_visible_); NSWindow* parent_window = parent_->ns_window(); + if (NativeWidgetMacNSWindow* parent_widget_window = + base::apple::ObjCCast<NativeWidgetMacNSWindow>(parent_window)) { + parent_window = [parent_widget_window preferredSheetParent]; + } DCHECK(parent_window); NSWindow* __weak weak_window = window_;
diff --git a/components/remote_cocoa/app_shim/select_file_dialog_bridge.mm b/components/remote_cocoa/app_shim/select_file_dialog_bridge.mm index 824cfaa..a1a6a83 100644 --- a/components/remote_cocoa/app_shim/select_file_dialog_bridge.mm +++ b/components/remote_cocoa/app_shim/select_file_dialog_bridge.mm
@@ -412,18 +412,12 @@ auto ended_callback = base::BindRepeating( &SelectFileDialogBridge::OnPanelEnded, weak_factory_.GetWeakPtr()); - // If the owning_window_ widget is currently in an immersive fullscreen - // session, add then remove the panel as a child. Otherwise the following - // -beginSheetModalForWindow:completionHandler: call will place the panel - // z-order behind the owning widget. See http://crbug/40282144. - NativeWidgetMacNSWindow* owning_window_widget = - base::apple::ObjCCast<NativeWidgetMacNSWindow>(owning_window_); - if (owning_window_widget && [owning_window_widget immersiveFullscreen]) { - [owning_window_ addChildWindow:panel_ ordered:NSWindowAbove]; - [owning_window_ removeChildWindow:panel_]; + NSWindow* sheet_parent = owning_window_; + if (NativeWidgetMacNSWindow* sheet_parent_widget_window = + base::apple::ObjCCast<NativeWidgetMacNSWindow>(sheet_parent)) { + sheet_parent = [sheet_parent_widget_window preferredSheetParent]; } - - [panel_ beginSheetModalForWindow:owning_window_ + [panel_ beginSheetModalForWindow:sheet_parent completionHandler:^(NSInteger result) { ended_callback.Run(result != NSModalResponseOK); }];
diff --git a/components/safe_browsing/content/browser/BUILD.gn b/components/safe_browsing/content/browser/BUILD.gn index 418baef..8b9f1a9 100644 --- a/components/safe_browsing/content/browser/BUILD.gn +++ b/components/safe_browsing/content/browser/BUILD.gn
@@ -127,6 +127,7 @@ "//components/security_interstitials/content:security_interstitial_page", "//components/security_interstitials/core", "//components/security_interstitials/core:unsafe_resource", + "//components/sessions", "//components/signin/public/identity_manager", "//components/unified_consent", "//components/version_info",
diff --git a/components/safe_browsing/content/browser/async_check_tracker_unittest.cc b/components/safe_browsing/content/browser/async_check_tracker_unittest.cc index cc4d0b2..5562a27 100644 --- a/components/safe_browsing/content/browser/async_check_tracker_unittest.cc +++ b/components/safe_browsing/content/browser/async_check_tracker_unittest.cc
@@ -120,7 +120,7 @@ /*hash_realtime_service=*/nullptr, /*hash_realtime_selection=*/ hash_realtime_utils::HashRealTimeSelection::kNone, - /*is_async_check=*/true); + /*is_async_check=*/true, SessionID::InvalidValue()); checker->AddUrlInRedirectChainForTesting(url_); tracker_->TransferUrlChecker(std::move(checker)); }
diff --git a/components/safe_browsing/content/browser/browser_url_loader_throttle.cc b/components/safe_browsing/content/browser/browser_url_loader_throttle.cc index f1779883..3d78b15b 100644 --- a/components/safe_browsing/content/browser/browser_url_loader_throttle.cc +++ b/components/safe_browsing/content/browser/browser_url_loader_throttle.cc
@@ -20,6 +20,7 @@ #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/utils.h" #include "components/safe_browsing/core/common/web_ui_constants.h" +#include "components/sessions/content/session_tab_helper.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" #include "content/public/common/url_constants.h" @@ -139,6 +140,9 @@ url_lookup_service_metric_suffix_ = url_real_time_lookup_enabled_ ? url_lookup_service_->GetMetricSuffix() : kNoRealTimeURLLookupService; + content::WebContents* web_contents = web_contents_getter_.Run(); + tab_id_ = web_contents ? sessions::SessionTabHelper::IdForTab(web_contents) + : SessionID::InvalidValue(); skip_check_checker_ = std::make_unique<SkipCheckCheckerOnSB>( delegate_getter_, frame_tree_node_id); } @@ -223,7 +227,7 @@ /*hash_realtime_service=*/nullptr, /*hash_realtime_selection=*/ hash_realtime_utils::HashRealTimeSelection::kNone, - /*is_async_check=*/false); + /*is_async_check=*/false, SessionID::InvalidValue()); async_sb_checker_ = std::make_unique<UrlCheckerOnSB>( delegate_getter_, frame_tree_node_id_, navigation_id_, web_contents_getter_, @@ -233,7 +237,7 @@ url_real_time_lookup_enabled_, can_check_db, can_check_high_confidence_allowlist, url_lookup_service_metric_suffix_, url_lookup_service_, hash_realtime_service_, hash_realtime_selection_, - /*is_async_check=*/true); + /*is_async_check=*/true, tab_id_); if (on_sync_sb_checker_created_callback_for_testing_) { std::move(on_sync_sb_checker_created_callback_for_testing_).Run(); } @@ -250,7 +254,7 @@ url_real_time_lookup_enabled_, can_check_db, can_check_high_confidence_allowlist, url_lookup_service_metric_suffix_, url_lookup_service_, hash_realtime_service_, hash_realtime_selection_, - /*is_async_check=*/false); + /*is_async_check=*/false, tab_id_); if (on_sync_sb_checker_created_callback_for_testing_) { std::move(on_sync_sb_checker_created_callback_for_testing_).Run(); }
diff --git a/components/safe_browsing/content/browser/browser_url_loader_throttle.h b/components/safe_browsing/content/browser/browser_url_loader_throttle.h index 2124cc8..7e8d5238 100644 --- a/components/safe_browsing/content/browser/browser_url_loader_throttle.h +++ b/components/safe_browsing/content/browser/browser_url_loader_throttle.h
@@ -213,6 +213,7 @@ std::optional<int64_t> navigation_id_; UrlCheckerOnSB::GetDelegateCallback delegate_getter_; base::RepeatingCallback<content::WebContents*()> web_contents_getter_; + SessionID tab_id_ = SessionID::InvalidValue(); // Checkers used to perform Safe Browsing checks. |sync_sb_checker_| may defer // the URL loader. |async_sb_checker_| doesn't defer the URL loader and may
diff --git a/components/safe_browsing/content/browser/browser_url_loader_throttle_unittest.cc b/components/safe_browsing/content/browser/browser_url_loader_throttle_unittest.cc index 71bde29..e25d802b 100644 --- a/components/safe_browsing/content/browser/browser_url_loader_throttle_unittest.cc +++ b/components/safe_browsing/content/browser/browser_url_loader_throttle_unittest.cc
@@ -124,10 +124,12 @@ void StartLookup( const GURL& url, RTLookupResponseCallback response_callback, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) override {} + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + SessionID tab_id) override {} void SendSampledRequest( const GURL& url, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) override {} + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + SessionID tab_id) override {} private: GURL GetRealTimeLookupUrl() const override { return GURL(); } @@ -140,7 +142,8 @@ void GetAccessToken( const GURL& url, RTLookupResponseCallback response_callback, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) override {} + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + SessionID tab_id) override {} std::optional<std::string> GetDMTokenString() const override { return std::nullopt; } @@ -201,7 +204,8 @@ url_lookup_service_on_ui, hash_realtime_service_on_ui, hash_realtime_selection, - is_async_check) {} + is_async_check, + SessionID::InvalidValue()) {} // Returns the CallbackInfo that was previously added in |AddCallbackInfo|. // It will crash if |AddCallbackInfo| was not called.
diff --git a/components/safe_browsing/content/browser/mojo_safe_browsing_impl.cc b/components/safe_browsing/content/browser/mojo_safe_browsing_impl.cc index 87e8393..5a98b7d8 100644 --- a/components/safe_browsing/content/browser/mojo_safe_browsing_impl.cc +++ b/components/safe_browsing/content/browser/mojo_safe_browsing_impl.cc
@@ -173,7 +173,7 @@ /*hash_realtime_service_on_ui=*/nullptr, /*hash_realtime_selection=*/ hash_realtime_utils::HashRealTimeSelection::kNone, - /*is_async_check=*/false); + /*is_async_check=*/false, SessionID::InvalidValue()); auto weak_impl = checker_impl->WeakPtr(); checker_impl->CheckUrl(
diff --git a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc index 2d33ed8..6bc94fe3 100644 --- a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc +++ b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc
@@ -564,6 +564,17 @@ } SafeBrowsingNavigationObserverManager::AttributionResult +SafeBrowsingNavigationObserverManager::IdentifyReferrerChainByEventURL( + const GURL& event_url, + SessionID event_tab_id, + int user_gesture_count_limit, + ReferrerChain* out_referrer_chain) { + return IdentifyReferrerChainByEventURL( + event_url, event_tab_id, content::GlobalRenderFrameHostId(), + user_gesture_count_limit, out_referrer_chain); +} + +SafeBrowsingNavigationObserverManager::AttributionResult SafeBrowsingNavigationObserverManager::IdentifyReferrerChainByPendingEventURL( const GURL& event_url, int user_gesture_count_limit,
diff --git a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h index 0000d3b..d260e395 100644 --- a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h +++ b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h
@@ -269,6 +269,15 @@ int user_gesture_count_limit, ReferrerChain* out_referrer_chain) override; + // Helper function to |IdentifyReferrerChainByEventURL| above in cases where + // |event_outermost_main_frame_id| is not available. That value will default + // to |content::GlobalRenderFrameHostId()|. + AttributionResult IdentifyReferrerChainByEventURL( + const GURL& event_url, + SessionID event_tab_id, // Invalid if tab id is unknown or not available. + int user_gesture_count_limit, + ReferrerChain* out_referrer_chain) override; + // Based on the |event_url|, traces back the observed PendingNavigationEvents // and NavigationEvents in navigation_event_list_ to identify the sequence of // navigations leading to the |event_url|, with the coverage limited to
diff --git a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_unittest.cc b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_unittest.cc index 5ff5b75d..b0594e3 100644 --- a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_unittest.cc +++ b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_unittest.cc
@@ -371,6 +371,54 @@ events.NavigationEventsSize() - 1)); } +TEST_F(SBNavigationObserverTest, TestBasicReferrerChain) { + base::Time now = base::Time::Now(); + base::Time one_second_ago = base::Time::FromSecondsSinceUnixEpoch( + now.InSecondsFSinceUnixEpoch() - 1.0); + base::Time two_seconds_ago = base::Time::FromSecondsSinceUnixEpoch( + now.InSecondsFSinceUnixEpoch() - 2.0); + + std::unique_ptr<NavigationEvent> first_navigation = + std::make_unique<NavigationEvent>(); + first_navigation->original_request_url = GURL("http://A.com"); + first_navigation->last_updated = two_seconds_ago; + first_navigation->navigation_initiation = + ReferrerChainEntry::BROWSER_INITIATED; + navigation_event_list()->RecordNavigationEvent(std::move(first_navigation)); + + std::unique_ptr<NavigationEvent> second_navigation = + std::make_unique<NavigationEvent>(); + second_navigation->source_url = GURL("http://A.com"); + second_navigation->original_request_url = GURL("http://B.com"); + second_navigation->last_updated = one_second_ago; + second_navigation->navigation_initiation = + ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE; + navigation_event_list()->RecordNavigationEvent(std::move(second_navigation)); + + std::unique_ptr<NavigationEvent> third_navigation = + std::make_unique<NavigationEvent>(); + third_navigation->source_url = GURL("http://B.com"); + third_navigation->original_request_url = GURL("http://C.com"); + third_navigation->last_updated = now; + third_navigation->navigation_initiation = + ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE; + navigation_event_list()->RecordNavigationEvent(std::move(third_navigation)); + + ASSERT_EQ(3U, navigation_event_list()->NavigationEventsSize()); + + ReferrerChain referrer_chain; + navigation_observer_manager_->IdentifyReferrerChainByEventURL( + GURL("http://C.com/"), SessionID::InvalidValue(), + content::GlobalRenderFrameHostId(), 10, &referrer_chain); + ASSERT_EQ(3, referrer_chain.size()); + + ReferrerChain referrer_chain_without_render_frame_host; + navigation_observer_manager_->IdentifyReferrerChainByEventURL( + GURL("http://C.com/"), SessionID::InvalidValue(), 10, + &referrer_chain_without_render_frame_host); + ASSERT_EQ(3, referrer_chain_without_render_frame_host.size()); +} + TEST_F(SBNavigationObserverTest, BasicNavigationAndCommit) { // Navigation in current tab. NavigateAndCommit(GURL("http://foo/1"), ui::PAGE_TRANSITION_AUTO_BOOKMARK);
diff --git a/components/safe_browsing/content/browser/url_checker_on_sb.cc b/components/safe_browsing/content/browser/url_checker_on_sb.cc index d17f8a17..56dd2023 100644 --- a/components/safe_browsing/content/browser/url_checker_on_sb.cc +++ b/components/safe_browsing/content/browser/url_checker_on_sb.cc
@@ -67,7 +67,8 @@ base::WeakPtr<RealTimeUrlLookupServiceBase> url_lookup_service, base::WeakPtr<HashRealTimeService> hash_realtime_service, hash_realtime_utils::HashRealTimeSelection hash_realtime_selection, - bool is_async_check) + bool is_async_check, + SessionID tab_id) : delegate_getter_(std::move(delegate_getter)), frame_tree_node_id_(frame_tree_node_id), navigation_id_(navigation_id), @@ -81,8 +82,8 @@ hash_realtime_service_(hash_realtime_service), hash_realtime_selection_(hash_realtime_selection), creation_time_(base::TimeTicks::Now()), - is_async_check_(is_async_check) { -} + is_async_check_(is_async_check), + tab_id_(tab_id) {} UrlCheckerOnSB::~UrlCheckerOnSB() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -107,7 +108,7 @@ can_check_db_, can_check_high_confidence_allowlist_, url_lookup_service_metric_suffix_, content::GetUIThreadTaskRunner({}), url_lookup_service_, hash_realtime_service_, hash_realtime_selection_, - is_async_check_); + is_async_check_, tab_id_); } CheckUrl(params.url, params.method);
diff --git a/components/safe_browsing/content/browser/url_checker_on_sb.h b/components/safe_browsing/content/browser/url_checker_on_sb.h index 1fa3322..7370d437 100644 --- a/components/safe_browsing/content/browser/url_checker_on_sb.h +++ b/components/safe_browsing/content/browser/url_checker_on_sb.h
@@ -91,7 +91,8 @@ base::WeakPtr<RealTimeUrlLookupServiceBase> url_lookup_service, base::WeakPtr<HashRealTimeService> hash_realtime_service, hash_realtime_utils::HashRealTimeSelection hash_realtime_selection, - bool is_async_check); + bool is_async_check, + SessionID tab_id); ~UrlCheckerOnSB(); @@ -163,6 +164,7 @@ hash_realtime_utils::HashRealTimeSelection::kNone; base::TimeTicks creation_time_; bool is_async_check_ = false; + SessionID tab_id_; base::WeakPtrFactory<UrlCheckerOnSB> weak_factory_{this}; };
diff --git a/components/safe_browsing/content/browser/web_api_handshake_checker.cc b/components/safe_browsing/content/browser/web_api_handshake_checker.cc index 491d2d0..33e55da 100644 --- a/components/safe_browsing/content/browser/web_api_handshake_checker.cc +++ b/components/safe_browsing/content/browser/web_api_handshake_checker.cc
@@ -78,7 +78,7 @@ /*hash_realtime_service_on_ui=*/nullptr, /*hash_realtime_selection=*/ hash_realtime_utils::HashRealTimeSelection::kNone, - /*is_async_check=*/false); + /*is_async_check=*/false, SessionID::InvalidValue()); url_checker_->CheckUrl( url, "GET", base::BindOnce(&WebApiHandshakeChecker::CheckerOnSB::OnCheckUrlResult,
diff --git a/components/safe_browsing/core/browser/BUILD.gn b/components/safe_browsing/core/browser/BUILD.gn index 03797a43..2d78c9dfb 100644 --- a/components/safe_browsing/core/browser/BUILD.gn +++ b/components/safe_browsing/core/browser/BUILD.gn
@@ -50,6 +50,7 @@ "//components/safe_browsing/core/common/proto:csd_proto", "//components/safe_browsing/core/common/proto:realtimeapi_proto", "//components/security_interstitials/core:unsafe_resource", + "//components/sessions:session_id", "//components/unified_consent", "//components/version_info", "//net", @@ -91,6 +92,7 @@ "//components/safe_browsing/core/common", "//components/safe_browsing/core/common/proto:csd_proto", "//components/security_interstitials/core:unsafe_resource", + "//components/sessions:session_id", "//net/traffic_annotation:test_support", "//services/network/public/cpp", "//services/network/public/mojom",
diff --git a/components/safe_browsing/core/browser/realtime/BUILD.gn b/components/safe_browsing/core/browser/realtime/BUILD.gn index 2daca16..36afaed 100644 --- a/components/safe_browsing/core/browser/realtime/BUILD.gn +++ b/components/safe_browsing/core/browser/realtime/BUILD.gn
@@ -74,6 +74,7 @@ "//components/safe_browsing/core/common:safe_browsing_prefs", "//components/safe_browsing/core/common/proto:csd_proto", "//components/safe_browsing/core/common/proto:realtimeapi_proto", + "//components/sessions:session_id", "//services/network/public/cpp:cpp", "//url:url", ]
diff --git a/components/safe_browsing/core/browser/realtime/url_lookup_service.cc b/components/safe_browsing/core/browser/realtime/url_lookup_service.cc index f152e7b..7f946af 100644 --- a/components/safe_browsing/core/browser/realtime/url_lookup_service.cc +++ b/components/safe_browsing/core/browser/realtime/url_lookup_service.cc
@@ -79,11 +79,12 @@ void RealTimeUrlLookupService::GetAccessToken( const GURL& url, RTLookupResponseCallback response_callback, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) { + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + SessionID tab_id) { token_fetcher_->Start(base::BindOnce( &RealTimeUrlLookupService::OnGetAccessToken, weak_factory_.GetWeakPtr(), url, std::move(response_callback), std::move(callback_task_runner), - base::TimeTicks::Now())); + base::TimeTicks::Now(), tab_id)); } void RealTimeUrlLookupService::OnPrefChanged() { @@ -97,6 +98,7 @@ RTLookupResponseCallback response_callback, scoped_refptr<base::SequencedTaskRunner> callback_task_runner, base::TimeTicks get_token_start_time, + SessionID tab_id, const std::string& access_token) { if (shutting_down_) return; @@ -107,7 +109,7 @@ !access_token.empty()); SendRequest(url, access_token, std::move(response_callback), std::move(callback_task_runner), - /* is_sampled_report */ false); + /* is_sampled_report */ false, tab_id); } void RealTimeUrlLookupService::OnResponseUnauthorized(
diff --git a/components/safe_browsing/core/browser/realtime/url_lookup_service.h b/components/safe_browsing/core/browser/realtime/url_lookup_service.h index 70ef129e..247f211 100644 --- a/components/safe_browsing/core/browser/realtime/url_lookup_service.h +++ b/components/safe_browsing/core/browser/realtime/url_lookup_service.h
@@ -101,7 +101,8 @@ void GetAccessToken( const GURL& url, RTLookupResponseCallback response_callback, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) override; + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + SessionID tab_id) override; std::optional<std::string> GetDMTokenString() const override; bool ShouldIncludeCredentials() const override; void OnResponseUnauthorized(const std::string& invalid_access_token) override; @@ -121,6 +122,7 @@ RTLookupResponseCallback response_callback, scoped_refptr<base::SequencedTaskRunner> callback_task_runner, base::TimeTicks get_token_start_time, + SessionID tab_id, const std::string& access_token); // Unowned object used for getting preference settings.
diff --git a/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc b/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc index 40c8e5f..6aff3aad6 100644 --- a/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc +++ b/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc
@@ -296,20 +296,23 @@ void RealTimeUrlLookupServiceBase::SendSampledRequest( const GURL& url, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) { + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + SessionID tab_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(url.is_valid()); SendRequest(url, /* access_token_string */ std::string(), /* response_callback */ base::NullCallback(), - std::move(callback_task_runner), /* is_sampled_report */ true); + std::move(callback_task_runner), /* is_sampled_report */ true, + tab_id); } void RealTimeUrlLookupServiceBase::StartLookup( const GURL& url, RTLookupResponseCallback response_callback, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) { + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + SessionID tab_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(url.is_valid()); @@ -336,12 +339,12 @@ if (CanPerformFullURLLookupWithToken()) { GetAccessToken(url, std::move(response_callback), - std::move(callback_task_runner)); + std::move(callback_task_runner), tab_id); } else { SendRequest(url, /* access_token_string */ std::string(), std::move(response_callback), std::move(callback_task_runner), - /* is_sampled_report */ false); + /* is_sampled_report */ false, tab_id); } } @@ -350,10 +353,11 @@ const std::string& access_token_string, RTLookupResponseCallback response_callback, scoped_refptr<base::SequencedTaskRunner> callback_task_runner, - bool is_sampled_report) { + bool is_sampled_report, + SessionID tab_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); std::unique_ptr<RTLookupRequest> request = - FillRequestProto(url, is_sampled_report); + FillRequestProto(url, is_sampled_report, tab_id); RecordRequestPopulationWithAndWithoutSuffix( "SafeBrowsing.RT.Request.UserPopulation", GetMetricSuffix(), request->population().user_population()); @@ -534,7 +538,8 @@ std::unique_ptr<RTLookupRequest> RealTimeUrlLookupServiceBase::FillRequestProto( const GURL& url, - bool is_sampled_report) { + bool is_sampled_report, + SessionID tab_id) { auto request = std::make_unique<RTLookupRequest>(); request->set_url(SanitizeURL(url).spec()); request->set_lookup_type(RTLookupRequest::NAVIGATION); @@ -550,9 +555,28 @@ *request->mutable_population() = get_user_population_callback_.Run(); if (referrer_chain_provider_) { - referrer_chain_provider_->IdentifyReferrerChainByPendingEventURL( - SanitizeURL(url), GetReferrerUserGestureLimit(), - request->mutable_referrer_chain()); + ReferrerChainProvider::AttributionResult attribution_result = + referrer_chain_provider_->IdentifyReferrerChainByPendingEventURL( + SanitizeURL(url), GetReferrerUserGestureLimit(), + request->mutable_referrer_chain()); + // The navigation event may not be found for various reasons. One + // possibility is that with async checks, the event URL may no longer be + // pending if the page has already loaded. If the navigation event is not + // found, try to fetch the referrer chain as a regular event URL rather than + // a pending one. + if (attribution_result == ReferrerChainProvider::AttributionResult:: + NAVIGATION_EVENT_NOT_FOUND && + base::FeatureList::IsEnabled( + safe_browsing::kSafeBrowsingAsyncRealTimeCheck)) { + CHECK(request->referrer_chain().empty()); + referrer_chain_provider_->IdentifyReferrerChainByEventURL( + SanitizeURL(url), tab_id, GetReferrerUserGestureLimit(), + request->mutable_referrer_chain()); + + RecordBooleanWithAndWithoutSuffix( + "SafeBrowsing.RT.EventUrlReferrerChainFetchSucceeded", + GetMetricSuffix(), !request->referrer_chain().empty()); + } SanitizeReferrerChainEntries(request->mutable_referrer_chain(), GetMinAllowedTimestampForReferrerChains(), /*should_remove_subresource_url=*/
diff --git a/components/safe_browsing/core/browser/realtime/url_lookup_service_base.h b/components/safe_browsing/core/browser/realtime/url_lookup_service_base.h index c526a1a1..4a03f36 100644 --- a/components/safe_browsing/core/browser/realtime/url_lookup_service_base.h +++ b/components/safe_browsing/core/browser/realtime/url_lookup_service_base.h
@@ -22,6 +22,7 @@ #include "components/safe_browsing/core/browser/utils/backoff_operator.h" #include "components/safe_browsing/core/common/proto/csd.pb.h" #include "components/safe_browsing/core/common/proto/realtimeapi.pb.h" +#include "components/sessions/core/session_id.h" #include "url/gurl.h" namespace net { @@ -107,13 +108,15 @@ virtual void StartLookup( const GURL& url, RTLookupResponseCallback response_callback, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner); + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + SessionID tab_id); // Similar to the function StartLookup above, // but to send Protego sampled request specifically. virtual void SendSampledRequest( const GURL& url, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner); + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + SessionID tab_id); // Helper function to return a weak pointer. base::WeakPtr<RealTimeUrlLookupServiceBase> GetWeakPtr(); @@ -159,7 +162,8 @@ const std::string& access_token_string, RTLookupResponseCallback response_callback, scoped_refptr<base::SequencedTaskRunner> callback_task_runner, - bool is_sampled_report); + bool is_sampled_report, + SessionID tab_id); private: using PendingRTLookupRequests = @@ -193,7 +197,8 @@ virtual void GetAccessToken( const GURL& url, RTLookupResponseCallback response_callback, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) = 0; + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + SessionID tab_id) = 0; // Called when the response from the server is unauthorized, so child classes // can add extra handling when this happens. @@ -264,9 +269,9 @@ std::unique_ptr<std::string> response_body); // Fills in fields in |RTLookupRequest|. - std::unique_ptr<RTLookupRequest> FillRequestProto( - const GURL& url, - bool is_sampled_report); + std::unique_ptr<RTLookupRequest> FillRequestProto(const GURL& url, + bool is_sampled_report, + SessionID tab_id); // Logs |request| and |oauth_token| on any open // chrome://safe-browsing pages. Returns a token that can be passed
diff --git a/components/safe_browsing/core/browser/realtime/url_lookup_service_unittest.cc b/components/safe_browsing/core/browser/realtime/url_lookup_service_unittest.cc index 8ed7b962..739bbd6 100644 --- a/components/safe_browsing/core/browser/realtime/url_lookup_service_unittest.cc +++ b/components/safe_browsing/core/browser/realtime/url_lookup_service_unittest.cc
@@ -62,6 +62,11 @@ event_outermost_main_frame_id, int user_gesture_count_limit, ReferrerChain* out_referrer_chain)); + MOCK_METHOD4(IdentifyReferrerChainByEventURL, + AttributionResult(const GURL& event_url, + SessionID event_tab_id, + int user_gesture_count_limit, + ReferrerChain* out_referrer_chain)); MOCK_METHOD3(IdentifyReferrerChainByPendingEventURL, AttributionResult(const GURL& event_url, int user_gesture_count_limit, @@ -181,7 +186,8 @@ std::unique_ptr<RTLookupRequest> FillRequestProto( const GURL& url, bool is_sampled_report) { - return rt_service_->FillRequestProto(url, is_sampled_report); + return rt_service_->FillRequestProto(url, is_sampled_report, + SessionID::InvalidValue()); } std::unique_ptr<RTLookupResponse> GetCachedRealTimeUrlVerdict( const GURL& url) { @@ -333,7 +339,8 @@ EXPECT_CALL(response_callback, Run(/* is_rt_lookup_successful */ false, /* is_cached_response */ false, _)); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); task_environment_.RunUntilIdle(); } @@ -488,7 +495,8 @@ base::MockCallback<RTLookupResponseCallback> response_callback; rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); EXPECT_CALL(response_callback, Run(/* is_rt_lookup_successful */ true, /* is_cached_response */ true, _)); @@ -515,7 +523,8 @@ RTLookupResponse::ThreatInfo::COVERING_MATCH); rt_service()->StartLookup(url, base::DoNothing(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); FulfillAccessTokenRequest("access_token_string"); task_environment_.RunUntilIdle(); @@ -539,7 +548,8 @@ RTLookupResponse::ThreatInfo::COVERING_MATCH); rt_service()->StartLookup(url, base::DoNothing(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); task_environment_.RunUntilIdle(); @@ -563,7 +573,8 @@ task_environment_.RunUntilIdle(); rt_service()->StartLookup(url, base::DoNothing(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); task_environment_.RunUntilIdle(); @@ -588,7 +599,8 @@ task_environment_.RunUntilIdle(); rt_service()->StartLookup(url, base::DoNothing(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); task_environment_.RunUntilIdle(); @@ -611,7 +623,8 @@ RTLookupResponse::ThreatInfo::COVERING_MATCH); rt_service()->StartLookup(url, base::DoNothing(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); FulfillAccessTokenRequest("access_token_string"); task_environment_.RunUntilIdle(); @@ -635,7 +648,8 @@ RTLookupResponse::ThreatInfo::COVERING_MATCH); rt_service()->StartLookup(url, base::DoNothing(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); FulfillAccessTokenRequest("access_token_string"); task_environment_.RunUntilIdle(); @@ -678,7 +692,8 @@ test_url_loader_factory_.SetInterceptor(interceptor.GetCallback()); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); EXPECT_TRUE(raw_token_fetcher()->WasStartCalled()); FulfillAccessTokenRequest("access_token_string"); @@ -722,7 +737,8 @@ test_url_loader_factory_.SetInterceptor(interceptor.GetCallback()); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); EXPECT_TRUE(raw_token_fetcher()->WasStartCalled()); // Token fetcher returns empty string when the token is unavailable. @@ -758,7 +774,8 @@ test_url_loader_factory_.SetInterceptor(interceptor.GetCallback()); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); task_environment_.RunUntilIdle(); @@ -784,7 +801,8 @@ /* is_cached_response */ false, _)); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); FulfillAccessTokenRequest("invalid_token_string"); EXPECT_CALL(*raw_token_fetcher(), @@ -805,7 +823,8 @@ /* is_cached_response */ false, _)); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); FulfillAccessTokenRequest("invalid_token_string"); EXPECT_CALL(*raw_token_fetcher(), OnInvalidAccessToken(_)).Times(0); @@ -839,10 +858,15 @@ url, /*user_gesture_count_limit=*/2, _)) .WillOnce(DoAll(SetArgPointee<2>(returned_referrer_chain), Return(ReferrerChainProvider::SUCCESS))); + EXPECT_CALL(*referrer_chain_provider_, + IdentifyReferrerChainByEventURL( + url, _, /*user_gesture_count_limit=*/2, _)) + .Times(0); base::MockCallback<RTLookupResponseCallback> response_callback; EXPECT_CALL(response_callback, Run(/* is_rt_lookup_successful */ true, /* is_cached_response */ false, _)); + bool request_validated; MustRunInterceptor interceptor( base::BindLambdaForTesting([&](const network::ResourceRequest& request) { RTLookupRequest request_proto; @@ -854,13 +878,16 @@ EXPECT_EQ(kTestUrl, request_proto.referrer_chain().Get(0).url()); EXPECT_EQ(kTestReferrerUrl, request_proto.referrer_chain().Get(1).url()); + request_validated = true; })); test_url_loader_factory_.SetInterceptor(interceptor.GetCallback()); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); task_environment_.RunUntilIdle(); + EXPECT_TRUE(request_validated); } TEST_F(RealTimeUrlLookupServiceTest, @@ -890,7 +917,12 @@ url, /*user_gesture_count_limit=*/2, _)) .WillOnce(DoAll(SetArgPointee<2>(returned_referrer_chain), Return(ReferrerChainProvider::SUCCESS))); + EXPECT_CALL(*referrer_chain_provider_, + IdentifyReferrerChainByEventURL( + url, _, /*user_gesture_count_limit=*/2, _)) + .Times(0); + bool request_validated; base::MockCallback<RTLookupResponseCallback> response_callback; MustRunInterceptor interceptor( base::BindLambdaForTesting([&](const network::ResourceRequest& request) { @@ -923,6 +955,8 @@ EXPECT_FALSE(request_proto.referrer_chain() .Get(1) .is_subframe_referrer_url_removed()); + + request_validated = true; })); test_url_loader_factory_.SetInterceptor(interceptor.GetCallback()); @@ -930,9 +964,11 @@ /* is_cached_response */ false, _)); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); task_environment_.RunUntilIdle(); + EXPECT_TRUE(request_validated); } TEST_F(RealTimeUrlLookupServiceTest, @@ -965,7 +1001,12 @@ url, /*user_gesture_count_limit=*/2, _)) .WillOnce(DoAll(SetArgPointee<2>(returned_referrer_chain), Return(ReferrerChainProvider::SUCCESS))); + EXPECT_CALL(*referrer_chain_provider_, + IdentifyReferrerChainByEventURL( + url, _, /*user_gesture_count_limit=*/2, _)) + .Times(0); + bool request_validated; base::MockCallback<RTLookupResponseCallback> response_callback; MustRunInterceptor interceptor( base::BindLambdaForTesting([&](const network::ResourceRequest& request) { @@ -992,6 +1033,8 @@ request_proto.referrer_chain().Get(1).url()); EXPECT_FALSE( request_proto.referrer_chain().Get(1).is_subframe_url_removed()); + + request_validated = true; })); test_url_loader_factory_.SetInterceptor(interceptor.GetCallback()); @@ -999,9 +1042,11 @@ /* is_cached_response */ false, _)); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); task_environment_.RunUntilIdle(); + EXPECT_TRUE(request_validated); } TEST_F(RealTimeUrlLookupServiceTest, @@ -1034,11 +1079,16 @@ url, /*user_gesture_count_limit=*/2, _)) .WillOnce(DoAll(SetArgPointee<2>(returned_referrer_chain), Return(ReferrerChainProvider::SUCCESS))); + EXPECT_CALL(*referrer_chain_provider_, + IdentifyReferrerChainByEventURL( + url, _, /*user_gesture_count_limit=*/2, _)) + .Times(0); base::MockCallback<RTLookupResponseCallback> response_callback; EXPECT_CALL(response_callback, Run(/* is_rt_lookup_successful */ true, /* is_cached_response */ false, _)); + bool request_validated; MustRunInterceptor interceptor( base::BindLambdaForTesting([&](const network::ResourceRequest& request) { RTLookupRequest request_proto; @@ -1070,13 +1120,122 @@ request_proto.referrer_chain().Get(1).is_subframe_url_removed()); EXPECT_FALSE( request_proto.referrer_chain().Get(1).is_url_removed_by_policy()); + + request_validated = true; })); test_url_loader_factory_.SetInterceptor(interceptor.GetCallback()); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); task_environment_.RunUntilIdle(); + EXPECT_TRUE(request_validated); +} + +// Tests that when a call to IdentifyReferrerChainByPendingEventURL does not +// identify the referrer chain, the service falls back to +// IdentifyReferrerChainByEventURL. +TEST_F(RealTimeUrlLookupServiceTest, + TestReferrerChain_FallbackToEventUrlReferrerChain) { + base::HistogramTester histogram_tester; + EnableRealTimeUrlLookup({kSafeBrowsingAsyncRealTimeCheck}, {}); + GURL url(kTestUrl); + SetUpRTLookupResponse(RTLookupResponse::ThreatInfo::DANGEROUS, + RTLookupResponse::ThreatInfo::SOCIAL_ENGINEERING, 60, + "example.test/", + RTLookupResponse::ThreatInfo::COVERING_MATCH); + ReferrerChain returned_referrer_chain; + double navigation_time_msec = + base::Time::Now().InMillisecondsSinceUnixEpoch(); + returned_referrer_chain.Add()->Swap( + CreateReferrerChainEntry(kTestUrl, /*main_frame_url=*/"", + /*referrer_url=*/"", + /*referrer_main_frame_url=*/"", + navigation_time_msec) + .get()); + returned_referrer_chain.Add()->Swap( + CreateReferrerChainEntry(kTestReferrerUrl, /*main_frame_url=*/"", + /*referrer_url=*/"", + /*referrer_main_frame_url=*/"", + navigation_time_msec) + .get()); + EXPECT_CALL(*referrer_chain_provider_, + IdentifyReferrerChainByPendingEventURL( + url, /*user_gesture_count_limit=*/2, _)) + .WillOnce(Return(ReferrerChainProvider::NAVIGATION_EVENT_NOT_FOUND)); + EXPECT_CALL(*referrer_chain_provider_, + IdentifyReferrerChainByEventURL( + url, _, /*user_gesture_count_limit=*/2, _)) + .WillOnce(DoAll(SetArgPointee<3>(returned_referrer_chain), + Return(ReferrerChainProvider::SUCCESS))); + + base::MockCallback<RTLookupResponseCallback> response_callback; + EXPECT_CALL(response_callback, Run(/* is_rt_lookup_successful */ true, + /* is_cached_response */ false, _)); + bool request_validated; + MustRunInterceptor interceptor( + base::BindLambdaForTesting([&](const network::ResourceRequest& request) { + RTLookupRequest request_proto; + ASSERT_TRUE(GetRequestProto(request, &request_proto)); + // Check referrer chain is attached. + EXPECT_EQ(2, request_proto.referrer_chain().size()); + EXPECT_EQ(kTestUrl, request_proto.referrer_chain().Get(0).url()); + EXPECT_EQ(kTestReferrerUrl, + request_proto.referrer_chain().Get(1).url()); + request_validated = true; + })); + test_url_loader_factory_.SetInterceptor(interceptor.GetCallback()); + + rt_service()->StartLookup(url, response_callback.Get(), + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); + task_environment_.RunUntilIdle(); + EXPECT_TRUE(request_validated); + + histogram_tester.ExpectUniqueSample( + "SafeBrowsing.RT.EventUrlReferrerChainFetchSucceeded", + /*sample=*/true, + /*expected_bucket_count=*/1); +} + +TEST_F( + RealTimeUrlLookupServiceTest, + TestReferrerChain_NoFallbackToEventUrlReferrerChain_AsyncChecksDisabled) { + EnableRealTimeUrlLookup({}, {kSafeBrowsingAsyncRealTimeCheck}); + GURL url(kTestUrl); + SetUpRTLookupResponse(RTLookupResponse::ThreatInfo::DANGEROUS, + RTLookupResponse::ThreatInfo::SOCIAL_ENGINEERING, 60, + "example.test/", + RTLookupResponse::ThreatInfo::COVERING_MATCH); + EXPECT_CALL(*referrer_chain_provider_, + IdentifyReferrerChainByPendingEventURL( + url, /*user_gesture_count_limit=*/2, _)) + .WillOnce(Return(ReferrerChainProvider::NAVIGATION_EVENT_NOT_FOUND)); + EXPECT_CALL(*referrer_chain_provider_, + IdentifyReferrerChainByEventURL( + url, _, /*user_gesture_count_limit=*/2, _)) + .Times(0); + + base::MockCallback<RTLookupResponseCallback> response_callback; + EXPECT_CALL(response_callback, Run(/* is_rt_lookup_successful */ true, + /* is_cached_response */ false, _)); + bool request_validated; + MustRunInterceptor interceptor( + base::BindLambdaForTesting([&](const network::ResourceRequest& request) { + RTLookupRequest request_proto; + ASSERT_TRUE(GetRequestProto(request, &request_proto)); + // Check no referrer chain is attached. + EXPECT_TRUE(request_proto.referrer_chain().empty()); + request_validated = true; + })); + test_url_loader_factory_.SetInterceptor(interceptor.GetCallback()); + + rt_service()->StartLookup(url, response_callback.Get(), + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); + task_environment_.RunUntilIdle(); + EXPECT_TRUE(request_validated); } TEST_F(RealTimeUrlLookupServiceTest, TestShutdown_CallbackNotPostedOnShutdown) { @@ -1093,7 +1252,8 @@ EXPECT_CALL(response_callback, Run(_, _, _)).Times(0); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); rt_service()->Shutdown(); @@ -1134,7 +1294,8 @@ EXPECT_CALL(response_callback, Run(_, _, _)).Times(0); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); rt_service()->Shutdown(); @@ -1159,7 +1320,8 @@ test_url_loader_factory_.SetInterceptor(interceptor.GetCallback()); rt_service()->SendSampledRequest( - url, base::SequencedTaskRunner::GetCurrentDefault()); + url, base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); rt_service()->Shutdown(); task_environment_.RunUntilIdle(); @@ -1190,7 +1352,8 @@ EXPECT_CALL(response_callback, Run(/* is_rt_lookup_successful */ !make_fail, /* is_cached_response */ false, _)); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); task_environment_.RunUntilIdle(); }; auto perform_failing_lookup = [perform_lookup]() { perform_lookup(true); }; @@ -1240,7 +1403,8 @@ EXPECT_CALL(response_callback, Run(/* is_rt_lookup_successful */ false, /* is_cached_response */ false, _)); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); task_environment_.RunUntilIdle(); }; @@ -1280,7 +1444,8 @@ /* is_cached_response */ true, _)); test_url_loader_factory_.SetInterceptor(request_callback.Get()); rt_service()->StartLookup(cached_url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); task_environment_.RunUntilIdle(); } @@ -1305,7 +1470,8 @@ /* is_cached_response */ false, _)); test_url_loader_factory_.SetInterceptor(request_callback.Get()); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); task_environment_.RunUntilIdle(); } @@ -1325,7 +1491,8 @@ EXPECT_CALL(response_callback, Run(/* is_rt_lookup_successful */ false, /* is_cached_response */ false, _)); rt_service()->StartLookup(url, response_callback.Get(), - base::SequencedTaskRunner::GetCurrentDefault()); + base::SequencedTaskRunner::GetCurrentDefault(), + SessionID::InvalidValue()); task_environment_.RunUntilIdle(); };
diff --git a/components/safe_browsing/core/browser/referrer_chain_provider.h b/components/safe_browsing/core/browser/referrer_chain_provider.h index fa50d9e7..d35ca11 100644 --- a/components/safe_browsing/core/browser/referrer_chain_provider.h +++ b/components/safe_browsing/core/browser/referrer_chain_provider.h
@@ -46,6 +46,12 @@ int user_gesture_count_limit, ReferrerChain* out_referrer_chain) = 0; + virtual AttributionResult IdentifyReferrerChainByEventURL( + const GURL& event_url, + SessionID event_tab_id, + int user_gesture_count_limit, + ReferrerChain* out_referrer_chain) = 0; + virtual AttributionResult IdentifyReferrerChainByPendingEventURL( const GURL& event_url, int user_gesture_count_limit,
diff --git a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc index bb031353..70cb27ff 100644 --- a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc +++ b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc
@@ -123,7 +123,8 @@ base::WeakPtr<RealTimeUrlLookupServiceBase> url_lookup_service_on_ui, base::WeakPtr<HashRealTimeService> hash_realtime_service_on_ui, HashRealTimeSelection hash_realtime_selection, - bool is_async_check) + bool is_async_check, + SessionID tab_id) : headers_(headers), load_flags_(load_flags), request_destination_(request_destination), @@ -144,7 +145,8 @@ url_lookup_service_on_ui_(url_lookup_service_on_ui), hash_realtime_service_on_ui_(hash_realtime_service_on_ui), hash_realtime_selection_(hash_realtime_selection), - is_async_check_(is_async_check) { + is_async_check_(is_async_check), + tab_id_(tab_id) { DCHECK(url_real_time_lookup_enabled_ || can_check_db_); // This object is used exclusively on the IO thread but may be constructed on @@ -469,7 +471,8 @@ url, url_checker_delegate_->GetThreatTypes(), database_manager_, can_check_db_, can_check_high_confidence_allowlist_, url_lookup_service_metric_suffix_, ui_task_runner_, - url_lookup_service_on_ui_, url_checker_delegate_, web_contents_getter_); + url_lookup_service_on_ui_, url_checker_delegate_, web_contents_getter_, + tab_id_); } else if (!can_check_db_) { return KickOffLookupMechanismResult( SafeBrowsingLookupMechanism::StartCheckResult(
diff --git a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.h b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.h index d57a440c..f00ec13 100644 --- a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.h +++ b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.h
@@ -124,7 +124,8 @@ base::WeakPtr<RealTimeUrlLookupServiceBase> url_lookup_service_on_ui, base::WeakPtr<HashRealTimeService> hash_realtime_service_on_ui, hash_realtime_utils::HashRealTimeSelection hash_realtime_selection, - bool is_async_check); + bool is_async_check, + SessionID tab_id); SafeBrowsingUrlCheckerImpl(const SafeBrowsingUrlCheckerImpl&) = delete; SafeBrowsingUrlCheckerImpl& operator=(const SafeBrowsingUrlCheckerImpl&) = @@ -343,6 +344,10 @@ // If this check allows navigation to commit before it completes. const bool is_async_check_; + // The current tab ID. Used sometimes for identifying the referrer chain for + // URL real-time lookups. Can be |SessionID::InvalidValue()|. + SessionID tab_id_; + base::WeakPtrFactory<SafeBrowsingUrlCheckerImpl> weak_factory_{this}; };
diff --git a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc index e2ffa49..600ca734 100644 --- a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc +++ b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc
@@ -24,6 +24,7 @@ #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/proto/csd.pb.h" #include "components/security_interstitials/core/unsafe_resource.h" +#include "components/sessions/core/session_id.h" #include "net/http/http_request_headers.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -239,7 +240,8 @@ void StartLookup( const GURL& gurl, RTLookupResponseCallback response_callback, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) override { + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + SessionID tab_id) override { std::string url = gurl.spec(); DCHECK(base::Contains(url_details_, url)); auto response = std::make_unique<RTLookupResponse>(); @@ -288,7 +290,8 @@ void SendSampledRequest( const GURL& gurl, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) override {} + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + SessionID tab_id) override {} // |should_complete_lookup| should generally be true, unless you specifically // want to test time-sensitive things like timeouts. Setting it to false will @@ -330,7 +333,8 @@ void GetAccessToken( const GURL& url, RTLookupResponseCallback response_callback, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) override {} + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + SessionID tab_id) override {} std::optional<std::string> GetDMTokenString() const override { return std::nullopt; } @@ -435,7 +439,7 @@ : nullptr, /*hash_realtime_service=*/hash_realtime_service_->GetWeakPtr(), hash_real_time_selection, - /*is_async_check=*/false); + /*is_async_check=*/false, SessionID::InvalidValue()); } protected:
diff --git a/components/safe_browsing/core/browser/url_realtime_mechanism.cc b/components/safe_browsing/core/browser/url_realtime_mechanism.cc index 5dadbaf1..48e635f68 100644 --- a/components/safe_browsing/core/browser/url_realtime_mechanism.cc +++ b/components/safe_browsing/core/browser/url_realtime_mechanism.cc
@@ -45,7 +45,8 @@ scoped_refptr<base::SequencedTaskRunner> ui_task_runner, base::WeakPtr<RealTimeUrlLookupServiceBase> url_lookup_service_on_ui, scoped_refptr<UrlCheckerDelegate> url_checker_delegate, - const base::RepeatingCallback<content::WebContents*()>& web_contents_getter) + const base::RepeatingCallback<content::WebContents*()>& web_contents_getter, + SessionID tab_id) : SafeBrowsingLookupMechanism(url, threat_types, database_manager), can_check_db_(can_check_db), can_check_high_confidence_allowlist_(can_check_high_confidence_allowlist), @@ -53,7 +54,8 @@ ui_task_runner_(ui_task_runner), url_lookup_service_on_ui_(url_lookup_service_on_ui), url_checker_delegate_(url_checker_delegate), - web_contents_getter_(web_contents_getter) {} + web_contents_getter_(web_contents_getter), + tab_id_(tab_id) {} UrlRealTimeMechanism::~UrlRealTimeMechanism() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -94,7 +96,7 @@ FROM_HERE, base::BindOnce(&UrlRealTimeMechanism::MaybeSendSampleRequest, weak_factory_.GetWeakPtr(), url_, - url_lookup_service_on_ui_, + url_lookup_service_on_ui_, tab_id_, base::SequencedTaskRunner::GetCurrentDefault())); // If the URL matches the high-confidence allowlist, still do the hash based // checks. @@ -107,7 +109,7 @@ FROM_HERE, base::BindOnce(&UrlRealTimeMechanism::StartLookupOnUIThread, weak_factory_.GetWeakPtr(), url_, - url_lookup_service_on_ui_, + url_lookup_service_on_ui_, tab_id_, base::SequencedTaskRunner::GetCurrentDefault())); } } @@ -117,6 +119,7 @@ base::WeakPtr<UrlRealTimeMechanism> weak_ptr_on_io, const GURL& url, base::WeakPtr<RealTimeUrlLookupServiceBase> url_lookup_service_on_ui, + SessionID tab_id, scoped_refptr<base::SequencedTaskRunner> io_task_runner) { bool is_lookup_service_found = !!url_lookup_service_on_ui; base::UmaHistogramBoolean("SafeBrowsing.RT.IsLookupServiceFound", @@ -132,13 +135,14 @@ base::BindOnce(&UrlRealTimeMechanism::OnLookupResponse, weak_ptr_on_io); url_lookup_service_on_ui->StartLookup(url, std::move(response_callback), - std::move(io_task_runner)); + std::move(io_task_runner), tab_id); } void UrlRealTimeMechanism::MaybeSendSampleRequest( base::WeakPtr<UrlRealTimeMechanism> weak_ptr_on_io, const GURL& url, base::WeakPtr<RealTimeUrlLookupServiceBase> url_lookup_service_on_ui, + SessionID tab_id, scoped_refptr<base::SequencedTaskRunner> io_task_runner) { bool can_send_protego_sampled_ping = url_lookup_service_on_ui && @@ -150,8 +154,8 @@ bool is_lookup_service_available = !url_lookup_service_on_ui->IsInBackoffMode(); if (is_lookup_service_available) { - url_lookup_service_on_ui->SendSampledRequest(url, - std::move(io_task_runner)); + url_lookup_service_on_ui->SendSampledRequest(url, std::move(io_task_runner), + tab_id); } }
diff --git a/components/safe_browsing/core/browser/url_realtime_mechanism.h b/components/safe_browsing/core/browser/url_realtime_mechanism.h index 1118165..49b2a9d 100644 --- a/components/safe_browsing/core/browser/url_realtime_mechanism.h +++ b/components/safe_browsing/core/browser/url_realtime_mechanism.h
@@ -17,6 +17,7 @@ #include "components/safe_browsing/core/browser/safe_browsing_lookup_mechanism.h" #include "components/safe_browsing/core/browser/url_checker_delegate.h" #include "components/safe_browsing/core/common/proto/realtimeapi.pb.h" +#include "components/sessions/core/session_id.h" #include "url/gurl.h" namespace safe_browsing { @@ -35,7 +36,8 @@ base::WeakPtr<RealTimeUrlLookupServiceBase> url_lookup_service_on_ui, scoped_refptr<UrlCheckerDelegate> url_checker_delegate, const base::RepeatingCallback<content::WebContents*()>& - web_contents_getter); + web_contents_getter, + SessionID tab_id); UrlRealTimeMechanism(const UrlRealTimeMechanism&) = delete; UrlRealTimeMechanism& operator=(const UrlRealTimeMechanism&) = delete; ~UrlRealTimeMechanism() override; @@ -56,6 +58,7 @@ base::WeakPtr<UrlRealTimeMechanism> weak_ptr_on_io, const GURL& url, base::WeakPtr<RealTimeUrlLookupServiceBase> url_lookup_service_on_ui, + SessionID tab_id, scoped_refptr<base::SequencedTaskRunner> io_task_runner); // Checks the eligibility of sending a sampled ping first; @@ -64,6 +67,7 @@ base::WeakPtr<UrlRealTimeMechanism> weak_ptr_on_io, const GURL& url, base::WeakPtr<RealTimeUrlLookupServiceBase> url_lookup_service_on_ui, + SessionID tab_id, scoped_refptr<base::SequencedTaskRunner> io_task_runner); // Called when the |response| from the real-time lookup service is received. @@ -129,6 +133,10 @@ // back to the hash-based checks. std::unique_ptr<DatabaseManagerMechanism> hash_database_mechanism_ = nullptr; + // The current tab ID. Used sometimes for identifying the referrer chain. Can + // be |SessionID::InvalidValue()|. + SessionID tab_id_; + base::WeakPtrFactory<UrlRealTimeMechanism> weak_factory_{this}; };
diff --git a/components/safe_browsing/core/common/safebrowsing_referral_methods.h b/components/safe_browsing/core/common/safebrowsing_referral_methods.h index e4c9591..2a627c8 100644 --- a/components/safe_browsing/core/common/safebrowsing_referral_methods.h +++ b/components/safe_browsing/core/common/safebrowsing_referral_methods.h
@@ -15,7 +15,8 @@ kPromoSlingerReferral = 2, kDownloadBubbleSubpage = 3, kDownloadButtonIphPromo = 4, - kMaxValue = kDownloadButtonIphPromo, + kDownloadPageRowPromo = 5, + kMaxValue = kDownloadPageRowPromo, }; } // namespace safe_browsing
diff --git a/components/sync/protocol/history_specifics.proto b/components/sync/protocol/history_specifics.proto index a2ebdf7..7b90a7a9 100644 --- a/components/sync/protocol/history_specifics.proto +++ b/components/sync/protocol/history_specifics.proto
@@ -145,4 +145,8 @@ // Related search URLs for a Google SRP visit, to provide next steps to user. repeated string related_searches = 25; + + // ID of the app (non-BrApp) this entity was generated for, if any. Only + // visits originating from Android devices may have this set. + optional string app_id = 26; }
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h index aad6bcd8..ff83440 100644 --- a/components/sync/protocol/proto_visitors.h +++ b/components/sync/protocol/proto_visitors.h
@@ -929,6 +929,7 @@ VISIT(has_url_keyed_image); VISIT_REP(categories); VISIT_REP(related_searches); + VISIT(app_id); } VISIT_PROTO_FIELDS(
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn index e26ae1e..954c87a 100644 --- a/components/viz/common/BUILD.gn +++ b/components/viz/common/BUILD.gn
@@ -219,6 +219,7 @@ "resources/bitmap_allocation.h", "resources/platform_color.h", "resources/release_callback.h", + "resources/resource_id.cc", "resources/resource_id.h", "resources/return_callback.h", "resources/returned_resource.cc",
diff --git a/components/viz/common/quads/compositor_frame_metadata.h b/components/viz/common/quads/compositor_frame_metadata.h index fb78a5d..fbc373c7 100644 --- a/components/viz/common/quads/compositor_frame_metadata.h +++ b/components/viz/common/quads/compositor_frame_metadata.h
@@ -7,6 +7,7 @@ #include <stdint.h> +#include <limits> #include <memory> #include <optional> #include <vector> @@ -35,10 +36,14 @@ namespace viz { -// A frame token value of 0 indicates an invalid or local frame token. A +// A frame token value of 0 indicates an invalid token. +inline constexpr uint32_t kInvalidFrameToken = 0; + +// A frame token value of `kLocalFrameToken` indicates a local frame token. A // local frame token is used inside viz when it creates its own CompositorFrame // for a surface. -inline constexpr uint32_t kInvalidOrLocalFrameToken = 0; +inline constexpr uint32_t kLocalFrameToken = + std::numeric_limits<uint32_t>::max(); // Compares two frame tokens, handling cases where the token wraps around the // 32-bit max value. @@ -51,7 +56,11 @@ class VIZ_COMMON_EXPORT FrameTokenGenerator { public: inline uint32_t operator++() { - if (++frame_token_ == kInvalidOrLocalFrameToken) { + ++frame_token_; + if (frame_token_ == kLocalFrameToken) { + ++frame_token_; + } + if (frame_token_ == kInvalidFrameToken) { ++frame_token_; } return frame_token_; @@ -60,7 +69,7 @@ inline uint32_t operator*() const { return frame_token_; } private: - uint32_t frame_token_ = kInvalidOrLocalFrameToken; + uint32_t frame_token_ = kInvalidFrameToken; }; class VIZ_COMMON_EXPORT CompositorFrameMetadata { @@ -143,7 +152,7 @@ // after the 32-bit max value. // TODO(crbug.com/850386): A custom type would be better to avoid incorrect // comparisons. - uint32_t frame_token = kInvalidOrLocalFrameToken; + uint32_t frame_token = kInvalidFrameToken; // Once the display compositor processes a frame with // |send_frame_token_to_embedder| flag turned on, the |frame_token| for the
diff --git a/components/viz/common/resources/resource_id.cc b/components/viz/common/resources/resource_id.cc new file mode 100644 index 0000000..0bb5d95 --- /dev/null +++ b/components/viz/common/resources/resource_id.cc
@@ -0,0 +1,49 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/viz/common/resources/resource_id.h" + +namespace viz { + +ReservedResourceIdTracker::ReservedResourceIdTracker() = default; +ReservedResourceIdTracker::~ReservedResourceIdTracker() = default; + +ResourceId ReservedResourceIdTracker::AllocId(int initial_ref_count) { + // Check we can allocate an ID. + CHECK_LT(id_ref_counts_.size(), kNumReservedResourceIds); + + // Find the next available ID. This is guaranteed to terminate because we + // checked there is at least one available ID. + while (id_ref_counts_.contains(ResourceId(next_id_))) { + if (next_id_ == std::numeric_limits<uint32_t>::max()) { + next_id_ = kVizReservedRangeStartId.GetUnsafeValue(); + } else { + ++next_id_; + } + } + DCHECK_GE(next_id_, kVizReservedRangeStartId.GetUnsafeValue()); + auto id = ResourceId(next_id_); + id_ref_counts_[id] = initial_ref_count; + return id; +} + +void ReservedResourceIdTracker::RefId(ResourceId id, int count) { + auto iter = id_ref_counts_.find(id); + CHECK(iter != id_ref_counts_.end()); + iter->second += count; +} + +bool ReservedResourceIdTracker::UnrefId(ResourceId id, int count) { + auto iter = id_ref_counts_.find(id); + CHECK(iter != id_ref_counts_.end()); + CHECK_GE(iter->second, count); + iter->second -= count; + if (iter->second == 0) { + id_ref_counts_.erase(iter); + return true; + } + return false; +} + +} // namespace viz
diff --git a/components/viz/common/resources/resource_id.h b/components/viz/common/resources/resource_id.h index ab76cb4..6ded665 100644 --- a/components/viz/common/resources/resource_id.h +++ b/components/viz/common/resources/resource_id.h
@@ -9,10 +9,13 @@ #include <functional> #include <limits> +#include <map> #include "base/check_op.h" +#include "base/containers/contains.h" #include "base/containers/flat_set.h" #include "base/types/id_type.h" +#include "components/viz/common/viz_common_export.h" namespace viz { @@ -22,11 +25,12 @@ // ResourceIdGenerator below, since it will skip generating reserved ids. using ResourceId = base::IdTypeU32<ResourceIdTypeMarker>; using ResourceIdSet = base::flat_set<ResourceId>; -constexpr ResourceId kInvalidResourceId(0); -constexpr ResourceId kVizReservedRangeStartId( - std::numeric_limits<uint32_t>::max() - 3000u); +inline constexpr ResourceId kInvalidResourceId(0); +inline constexpr uint32_t kNumReservedResourceIds = 3000u; +inline constexpr ResourceId kVizReservedRangeStartId( + std::numeric_limits<uint32_t>::max() - kNumReservedResourceIds); -class ResourceIdGenerator { +class VIZ_COMMON_EXPORT ResourceIdGenerator { public: explicit ResourceIdGenerator(uint32_t start_id) : start_id_(start_id), next_id_(start_id) { @@ -52,12 +56,37 @@ uint32_t next_id_ = 1u; }; -struct ResourceIdHasher { +struct VIZ_COMMON_EXPORT ResourceIdHasher { size_t operator()(const ResourceId& resource_id) const { return std::hash<uint32_t>()(resource_id.GetUnsafeValue()); } }; +// ReservedResourceIdTracker is used for keeping track of refcounts on viz +// reserved resources and allocating unused resource IDs. Since the resource ID +// space for reserved resources is much smaller than the client resource ID +// space, we keep track of which resource IDs are used individually, so we can +// allocate resource IDs that are no longer used and avoid reusing IDs that are +// still in use. +class VIZ_COMMON_EXPORT ReservedResourceIdTracker { + public: + ReservedResourceIdTracker(); + ~ReservedResourceIdTracker(); + + [[nodiscard]] ResourceId AllocId(int initial_ref_count); + void RefId(ResourceId id, int count); + + // Unrefs the given `id`. Returns true if there are no more refs to this + // resource id. + bool UnrefId(ResourceId id, int count); + + void set_next_id_for_test(uint32_t next_id) { next_id_ = next_id; } + + private: + uint32_t next_id_ = kVizReservedRangeStartId.GetUnsafeValue(); + std::map<ResourceId, int> id_ref_counts_; +}; + } // namespace viz #endif // COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_ID_H_
diff --git a/components/viz/service/display/display_unittest.cc b/components/viz/service/display/display_unittest.cc index 96bae9f1..670ce81 100644 --- a/components/viz/service/display/display_unittest.cc +++ b/components/viz/service/display/display_unittest.cc
@@ -3629,8 +3629,8 @@ display_->Resize(display_size); const gfx::Size sub_surface_size(32, 32); - uint32_t frame_token_1 = kInvalidOrLocalFrameToken; - uint32_t frame_token_2 = kInvalidOrLocalFrameToken; + uint32_t frame_token_1 = kInvalidFrameToken; + uint32_t frame_token_2 = kInvalidFrameToken; { CompositorFrame frame = CompositorFrameBuilder()
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc index eaec952..b79c86f 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -25,6 +25,7 @@ #include "components/viz/common/features.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/common/quads/compositor_frame.h" +#include "components/viz/common/quads/compositor_frame_metadata.h" #include "components/viz/common/quads/compositor_render_pass.h" #include "components/viz/common/resources/bitmap_allocation.h" #include "components/viz/common/surfaces/surface_info.h" @@ -392,24 +393,30 @@ base::TimeTicks draw_start_timestamp, const gfx::SwapTimings& swap_timings, const gfx::PresentationFeedback& feedback) { - DidPresentCompositorFrame(frame_token, draw_start_timestamp, swap_timings, - feedback); + // If the frame was submitted locally (from inside viz), do not tell the + // client about it, since the client did not send it. + if (frame_token != kLocalFrameToken) { + DidPresentCompositorFrame(frame_token, draw_start_timestamp, swap_timings, + feedback); + } } void CompositorFrameSinkSupport::RefResources( const std::vector<TransferableResource>& resources) { - if (surface_animation_manager_) - surface_animation_manager_->RefResources(resources); + if (reserved_resource_delegate_) { + reserved_resource_delegate_->RefResources(resources); + } surface_resource_holder_.RefResources(resources); } void CompositorFrameSinkSupport::UnrefResources( std::vector<ReturnedResource> resources) { - // |surface_animation_manager_| allocates ResourceIds in a different range + // `ReservedResourceDelegate` allocates ResourceIds in a different range // than the client so it can process returned resources before // |surface_resource_holder_|. - if (surface_animation_manager_) - surface_animation_manager_->UnrefResources(resources); + if (reserved_resource_delegate_) { + reserved_resource_delegate_->UnrefResources(resources); + } surface_resource_holder_.UnrefResources(std::move(resources)); } @@ -441,6 +448,9 @@ void CompositorFrameSinkSupport::ReceiveFromChild( const std::vector<TransferableResource>& resources) { + if (reserved_resource_delegate_) { + reserved_resource_delegate_->ReceiveFromChild(resources); + } surface_resource_holder_.ReceiveFromChild(resources); } @@ -576,6 +586,26 @@ } } +void CompositorFrameSinkSupport::SetSurfaceAnimationManager( + std::unique_ptr<SurfaceAnimationManager> surface_animation_manager) { + // We only support one of SurfaceAnimationManager or a custom + // `ReservedResourceDelegate` for the lifetime of a CFSS. If we are setting + // `surface_animation_manager_`, then either there is no current one and it + // and `reserved_resource_delegate_` should be nullptr, or we are setting a + // new one and the previous values should be equal. + CHECK_EQ(surface_animation_manager_.get(), reserved_resource_delegate_); + reserved_resource_delegate_ = surface_animation_manager.get(); + surface_animation_manager_ = std::move(surface_animation_manager); +} + +std::unique_ptr<SurfaceAnimationManager> +CompositorFrameSinkSupport::TakeSurfaceAnimationManager() { + // See comment in `SetSurfaceAnimationManager` about this CHECK. + CHECK_EQ(surface_animation_manager_.get(), reserved_resource_delegate_); + reserved_resource_delegate_ = nullptr; + return std::move(surface_animation_manager_); +} + base::TimeDelta CompositorFrameSinkSupport::GetPreferredFrameInterval( mojom::CompositorFrameSinkType* type) const { if (type) @@ -974,7 +1004,8 @@ base::TimeTicks draw_start_timestamp, const gfx::SwapTimings& swap_timings, const gfx::PresentationFeedback& feedback) { - CHECK_NE(frame_token, kInvalidOrLocalFrameToken); + CHECK_NE(frame_token, kInvalidFrameToken); + CHECK_NE(frame_token, kLocalFrameToken); DCHECK((feedback.flags & gfx::PresentationFeedback::kFailure) || (!draw_start_timestamp.is_null() && !swap_timings.is_null())); @@ -1496,11 +1527,11 @@ // Initialize this before creating the SurfaceAnimationManager since the // save operation may execute synchronously. in_flight_save_sequence_id_ = directive.sequence_id(); - surface_animation_manager_ = SurfaceAnimationManager::CreateWithSave( + SetSurfaceAnimationManager(SurfaceAnimationManager::CreateWithSave( directive, surface, frame_sink_manager_->shared_bitmap_manager(), base::BindOnce(&CompositorFrameSinkSupport:: OnCompositorFrameTransitionDirectiveProcessed, - base::Unretained(this))); + base::Unretained(this)))); break; case CompositorFrameTransitionDirective::Type::kAnimateRenderer: // The save operation must have been executed before we see an animate @@ -1518,9 +1549,9 @@ << directive.navigation_id(); } - surface_animation_manager_ = + SetSurfaceAnimationManager( frame_sink_manager_->TakeSurfaceAnimationManager( - directive.navigation_id()); + directive.navigation_id())); } if (surface_animation_manager_) @@ -1530,7 +1561,7 @@ break; case CompositorFrameTransitionDirective::Type::kRelease: - surface_animation_manager_.reset(); + SetSurfaceAnimationManager(nullptr); // This `surface_animation_manager_` could correspond to an in-flight // save, reset the tracking here. @@ -1568,7 +1599,7 @@ // SurfaceAnimationManager for this |navigation_id|. Should never happen // but handled safely because its untrusted input from the renderer. frame_sink_manager_->CacheSurfaceAnimationManager( - directive.navigation_id(), std::move(surface_animation_manager_)); + directive.navigation_id(), TakeSurfaceAnimationManager()); } in_flight_save_sequence_id_ = 0; @@ -1632,6 +1663,14 @@ return surface_animation_manager_.get(); } +void CompositorFrameSinkSupport::SetReservedResourceDelegate( + ReservedResourceDelegate* delegate) { + // We only support a custom `ReservedResourceDelegate` on root CFSS. So make + // sure `surface_animation_manager_` is not set. + CHECK(!surface_animation_manager_); + reserved_resource_delegate_ = delegate; +} + void CompositorFrameSinkSupport::DestroySelf() { // SUBTLE: We explicitly copy `frame_sink_id_` because // DestroyCompositorFrameSink takes the FrameSinkId by reference and may
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.h b/components/viz/service/frame_sinks/compositor_frame_sink_support.h index 2ab23f7..d61eb30 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.h +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.h
@@ -273,6 +273,8 @@ return frame_sink_type_; } + void SetReservedResourceDelegate(ReservedResourceDelegate* delegate); + private: friend class CompositorFrameSinkSupportTest; friend class DisplayTest; @@ -356,6 +358,10 @@ base::flat_set<base::PlatformThreadId> thread_ids, bool passed_verification); + void SetSurfaceAnimationManager( + std::unique_ptr<SurfaceAnimationManager> surface_animation_manager); + std::unique_ptr<SurfaceAnimationManager> TakeSurfaceAnimationManager(); + const raw_ptr<mojom::CompositorFrameSinkClient> client_; const raw_ptr<FrameSinkManagerImpl> frame_sink_manager_; @@ -508,6 +514,12 @@ // frames may be produced by Surfaces managed by distinct // CompositorFrameSinks. std::unique_ptr<SurfaceAnimationManager> surface_animation_manager_; + + // This is used for any viz side resources that are managed by viz. These + // resources must use the reserved resource range defined by + // `kVizReservedRangeStartId`. + raw_ptr<ReservedResourceDelegate> reserved_resource_delegate_ = nullptr; + // The sequence ID for the save directive pending copy. uint32_t in_flight_save_sequence_id_ = 0;
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc index fc8cd6e3..df87632 100644 --- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc +++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
@@ -288,7 +288,7 @@ CompositorFrame frame; auto& metadata = frame.metadata; - metadata.frame_token = kInvalidOrLocalFrameToken; + metadata.frame_token = kLocalFrameToken; // The given `surface_id` may be newer than `current_surface_id`, so use the // one we actually have.
diff --git a/components/viz/service/frame_sinks/surface_resource_holder.cc b/components/viz/service/frame_sinks/surface_resource_holder.cc index d47ff53..fc44a25 100644 --- a/components/viz/service/frame_sinks/surface_resource_holder.cc +++ b/components/viz/service/frame_sinks/surface_resource_holder.cc
@@ -4,11 +4,15 @@ #include "components/viz/service/frame_sinks/surface_resource_holder.h" +#include <utility> + #include "base/check.h" #include "components/viz/service/frame_sinks/surface_resource_holder_client.h" namespace viz { +ReservedResourceDelegate::~ReservedResourceDelegate() = default; + SurfaceResourceHolder::SurfaceResourceHolder( SurfaceResourceHolderClient* client) : client_(client) {} @@ -22,6 +26,16 @@ void SurfaceResourceHolder::ReceiveFromChild( const std::vector<TransferableResource>& resources) { for (const auto& resource : resources) { + // We don't handle reserved resources here. CompositorFrames from clients + // can never contain reserved ResourceIds, but viz can pretend to submit + // frames from the client (see + // `CompositorFrameSinkSupport::SubmitCompositorFrameLocally`), e.g. for + // frame eviction purposes. Those CompositorFrames may contain reserved + // resources, so ignore them here. + if (resource.id >= kVizReservedRangeStartId) { + continue; + } + ResourceRefs& ref = resource_id_info_map_[resource.id]; ref.refs_holding_resource_alive++; ref.refs_received_from_child++;
diff --git a/components/viz/service/frame_sinks/surface_resource_holder.h b/components/viz/service/frame_sinks/surface_resource_holder.h index 1eb14669..0a480a43 100644 --- a/components/viz/service/frame_sinks/surface_resource_holder.h +++ b/components/viz/service/frame_sinks/surface_resource_holder.h
@@ -17,6 +17,21 @@ namespace viz { class SurfaceResourceHolderClient; +// ReservedResourceDelegate is an interface for tracking the lifetime of +// resources. Code which submits resources that are managed fully on the viz +// side (with resource IDs >= kVizReservedRangeStartId) should implement this. +class ReservedResourceDelegate { + public: + virtual ~ReservedResourceDelegate(); + + virtual void ReceiveFromChild( + const std::vector<TransferableResource>& resources) = 0; + virtual void RefResources( + const std::vector<TransferableResource>& resources) = 0; + virtual void UnrefResources( + const std::vector<ReturnedResource>& resources) = 0; +}; + // A SurfaceResourceHolder manages the lifetime of resources submitted by a // particular SurfaceFactory. Each resource is held by the service until // it is no longer referenced by any pending frames or by any
diff --git a/components/viz/service/surfaces/surface.cc b/components/viz/service/surfaces/surface.cc index c430a718..b455c746a 100644 --- a/components/viz/service/surfaces/surface.cc +++ b/components/viz/service/surfaces/surface.cc
@@ -76,7 +76,7 @@ base::TimeTicks draw_start_timestamp, const gfx::SwapTimings& swap_timings, const gfx::PresentationFeedback& feedback) { - if (surface_client_ && frame_token_ != kInvalidOrLocalFrameToken) { + if (surface_client_) { surface_client_->OnSurfacePresented(frame_token_, draw_start_timestamp, swap_timings, feedback); }
diff --git a/components/viz/service/surfaces/surface_unittest.cc b/components/viz/service/surfaces/surface_unittest.cc index 1e85538..4fd0c52 100644 --- a/components/viz/service/surfaces/surface_unittest.cc +++ b/components/viz/service/surfaces/surface_unittest.cc
@@ -81,7 +81,7 @@ if (BeginFrameAcksEnabled()) { support->SetWantsBeginFrameAcks(); } - uint32_t frame_token = kInvalidOrLocalFrameToken; + uint32_t frame_token = kInvalidFrameToken; { CompositorFrame frame = CompositorFrameBuilder() @@ -89,7 +89,7 @@ .SetBeginFrameSourceId(kBeginFrameSourceId) .Build(); frame_token = frame.metadata.frame_token; - ASSERT_NE(frame_token, kInvalidOrLocalFrameToken); + ASSERT_NE(frame_token, kInvalidFrameToken); EXPECT_CALL(client, DidReceiveCompositorFrameAck(testing::_)) .Times(BeginFrameAcksEnabled() ? 0 : 1); support->SubmitCompositorFrame(local_surface_id, std::move(frame));
diff --git a/components/viz/service/transitions/DEPS b/components/viz/service/transitions/DEPS index 5009321..902363c5 100644 --- a/components/viz/service/transitions/DEPS +++ b/components/viz/service/transitions/DEPS
@@ -2,6 +2,7 @@ include_rules = [ "+components/viz/service/display/shared_bitmap_manager.h", + "+components/viz/service/frame_sinks", "+components/viz/service/surfaces", "+gpu/command_buffer/common", ]
diff --git a/components/viz/service/transitions/surface_animation_manager.cc b/components/viz/service/transitions/surface_animation_manager.cc index 5e21393..c50ba22 100644 --- a/components/viz/service/transitions/surface_animation_manager.cc +++ b/components/viz/service/transitions/surface_animation_manager.cc
@@ -179,6 +179,12 @@ empty_resource_ids_.clear(); } +void SurfaceAnimationManager::ReceiveFromChild( + const std::vector<TransferableResource>& resources) { + // We don't do anything here, because resources are initially reffed via + // `ImportResources`. +} + void SurfaceAnimationManager::RefResources( const std::vector<TransferableResource>& resources) { if (transferable_resource_tracker_.is_empty())
diff --git a/components/viz/service/transitions/surface_animation_manager.h b/components/viz/service/transitions/surface_animation_manager.h index c3cecb8..f2a857b 100644 --- a/components/viz/service/transitions/surface_animation_manager.h +++ b/components/viz/service/transitions/surface_animation_manager.h
@@ -17,6 +17,7 @@ #include "components/viz/common/quads/compositor_render_pass_draw_quad.h" #include "components/viz/common/resources/resource_id.h" #include "components/viz/service/display/shared_bitmap_manager.h" +#include "components/viz/service/frame_sinks/surface_resource_holder.h" #include "components/viz/service/surfaces/surface_saved_frame.h" #include "components/viz/service/transitions/transferable_resource_tracker.h" #include "components/viz/service/viz_service_export.h" @@ -36,7 +37,8 @@ // // This class is owned by CompositorFrameSinkSupport but can be moved between // CompositorFrameSinkSupports for transitions between 2 renderer CC instances. -class VIZ_SERVICE_EXPORT SurfaceAnimationManager { +class VIZ_SERVICE_EXPORT SurfaceAnimationManager + : public ReservedResourceDelegate { public: using TransitionDirectiveCompleteCallback = base::OnceCallback<void(const CompositorFrameTransitionDirective&)>; @@ -47,13 +49,16 @@ SharedBitmapManager* shared_bitmap_manager, TransitionDirectiveCompleteCallback sequence_id_finished_callback); - ~SurfaceAnimationManager(); + ~SurfaceAnimationManager() override; void Animate(); - // Resource ref count management. - void RefResources(const std::vector<TransferableResource>& resources); - void UnrefResources(const std::vector<ReturnedResource>& resources); + // ReservedResourceDelegate: + void ReceiveFromChild( + const std::vector<TransferableResource>& resources) override; + void RefResources( + const std::vector<TransferableResource>& resources) override; + void UnrefResources(const std::vector<ReturnedResource>& resources) override; // Replaced ViewTransitionElementResourceIds with corresponding ResourceIds if // necessary.
diff --git a/components/viz/service/transitions/transferable_resource_tracker.cc b/components/viz/service/transitions/transferable_resource_tracker.cc index e852b483..203610ed 100644 --- a/components/viz/service/transitions/transferable_resource_tracker.cc +++ b/components/viz/service/transitions/transferable_resource_tracker.cc
@@ -23,9 +23,7 @@ TransferableResourceTracker::TransferableResourceTracker( SharedBitmapManager* shared_bitmap_manager) - : starting_id_(kVizReservedRangeStartId.GetUnsafeValue()), - next_id_(kVizReservedRangeStartId.GetUnsafeValue()), - shared_bitmap_manager_(shared_bitmap_manager) {} + : shared_bitmap_manager_(shared_bitmap_manager) {} TransferableResourceTracker::~TransferableResourceTracker() = default; @@ -112,7 +110,7 @@ } } - resource.id = GetNextAvailableResourceId(); + resource.id = id_tracker_.AllocId(/*initial_ref_count=*/1); DCHECK(!base::Contains(managed_resources_, resource.id)); managed_resources_.emplace( resource.id, @@ -133,39 +131,15 @@ void TransferableResourceTracker::RefResource(ResourceId id) { DCHECK(base::Contains(managed_resources_, id)); - ++managed_resources_[id].ref_count; + id_tracker_.RefId(id, /*count=*/1); } void TransferableResourceTracker::UnrefResource(ResourceId id, int count) { DCHECK(base::Contains(managed_resources_, id)); - DCHECK_LE(count, managed_resources_[id].ref_count); - managed_resources_[id].ref_count -= count; - if (managed_resources_[id].ref_count == 0) + + if (id_tracker_.UnrefId(id, count)) { managed_resources_.erase(id); -} - -ResourceId TransferableResourceTracker::GetNextAvailableResourceId() { - uint32_t result = next_id_; - - // Since we're working with a limit range of resources, it is a lot more - // likely that we will loop back to the starting id after running out of - // resource ids. This loop ensures that `next_id_` is set to a value that is - // not `result` and is also available in that it's currently tracked by - // `managed_resources_`. Note that if we end up looping twice, we fail with a - // CHECK since we don't have any available resources for this request. - bool looped = false; - while (next_id_ == result || - base::Contains(managed_resources_, ResourceId(next_id_))) { - if (next_id_ == std::numeric_limits<uint32_t>::max()) { - CHECK(!looped); - next_id_ = starting_id_; - looped = true; - } else { - ++next_id_; - } } - DCHECK_GE(result, kVizReservedRangeStartId.GetUnsafeValue()); - return ResourceId(result); } TransferableResourceTracker::TransferableResourceHolder:: @@ -175,9 +149,7 @@ TransferableResourceTracker::TransferableResourceHolder:: TransferableResourceHolder(const TransferableResource& resource, ResourceReleaseCallback release_callback) - : resource(resource), - release_callback(std::move(release_callback)), - ref_count(1u) {} + : resource(resource), release_callback(std::move(release_callback)) {} TransferableResourceTracker::TransferableResourceHolder:: ~TransferableResourceHolder() {
diff --git a/components/viz/service/transitions/transferable_resource_tracker.h b/components/viz/service/transitions/transferable_resource_tracker.h index 8af36c0..ff86954 100644 --- a/components/viz/service/transitions/transferable_resource_tracker.h +++ b/components/viz/service/transitions/transferable_resource_tracker.h
@@ -89,8 +89,6 @@ private: friend class TransferableResourceTrackerTest; - ResourceId GetNextAvailableResourceId(); - PositionedResource ImportResource( SurfaceSavedFrame::OutputCopyResult output_copy); @@ -98,9 +96,6 @@ uint32_t>::value, "ResourceId underlying type should be uint32_t"); - const uint32_t starting_id_; - uint32_t next_id_; - const raw_ptr<SharedBitmapManager> shared_bitmap_manager_; struct TransferableResourceHolder { @@ -116,9 +111,10 @@ TransferableResource resource; ResourceReleaseCallback release_callback; - int ref_count = 0; }; + ReservedResourceIdTracker id_tracker_; + std::map<ResourceId, TransferableResourceHolder> managed_resources_; };
diff --git a/components/viz/service/transitions/transferable_resource_tracker_unittest.cc b/components/viz/service/transitions/transferable_resource_tracker_unittest.cc index bc70416..a7e9be24 100644 --- a/components/viz/service/transitions/transferable_resource_tracker_unittest.cc +++ b/components/viz/service/transitions/transferable_resource_tracker_unittest.cc
@@ -34,7 +34,7 @@ class TransferableResourceTrackerTest : public testing::Test { public: void SetNextId(TransferableResourceTracker* tracker, uint32_t id) { - tracker->next_id_ = id; + tracker->id_tracker_.set_next_id_for_test(id); } // Returns if there is a SharedBitmap in SharedBitmapManager for |resource|. @@ -85,6 +85,7 @@ SetNextId(&tracker, next_id); ResourceId last_id = kInvalidResourceId; + std::vector<TransferableResourceTracker::ResourceFrame> frames; for (int i = 0; i < 10; ++i) { auto frame = tracker.ImportResources(CreateFrameWithResult()); ASSERT_EQ(frame.shared.size(), 1u); @@ -94,8 +95,11 @@ EXPECT_GE(resource->resource.id, kVizReservedRangeStartId); EXPECT_NE(resource->resource.id, last_id); last_id = resource->resource.id; + frames.push_back(std::move(frame)); + } + for (auto& frame : frames) { tracker.ReturnFrame(frame); - EXPECT_FALSE(HasBitmapResource(resource->resource)); + EXPECT_FALSE(HasBitmapResource(frame.shared.at(0)->resource)); } } @@ -131,6 +135,7 @@ SetNextId(&tracker, next_id); ResourceId last_id = kInvalidResourceId; + std::vector<TransferableResourceTracker::ResourceFrame> frames; for (int i = 0; i < 10; ++i) { auto frame = tracker.ImportResources(CreateFrameWithResult()); ASSERT_EQ(frame.shared.size(), 1u); @@ -141,8 +146,11 @@ EXPECT_NE(new_resource->resource.id, last_id); EXPECT_NE(new_resource->resource.id, resource->resource.id); last_id = new_resource->resource.id; + frames.push_back(std::move(frame)); + } + for (auto& frame : frames) { tracker.ReturnFrame(frame); - EXPECT_FALSE(HasBitmapResource(new_resource->resource)); + EXPECT_FALSE(HasBitmapResource(frame.shared.at(0)->resource)); } }
diff --git a/components/viz/test/fake_host_frame_sink_client.h b/components/viz/test/fake_host_frame_sink_client.h index 4ca2a27..827b842 100644 --- a/components/viz/test/fake_host_frame_sink_client.h +++ b/components/viz/test/fake_host_frame_sink_client.h
@@ -29,7 +29,7 @@ uint32_t last_frame_token_seen() const { return last_frame_token_seen_; } private: - uint32_t last_frame_token_seen_ = kInvalidOrLocalFrameToken; + uint32_t last_frame_token_seen_ = kInvalidFrameToken; }; } // namespace viz
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 9480a24..79e2564 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -2780,6 +2780,8 @@ "child_process_launcher_helper_win.cc", "device_posture/device_posture_platform_provider_win.cc", "device_posture/device_posture_platform_provider_win.h", + "device_posture/device_posture_registry_watcher_win.cc", + "device_posture/device_posture_registry_watcher_win.h", "font_access/font_enumeration_data_source_win.cc", "font_access/font_enumeration_data_source_win.h", "installedapp/installed_app_provider_impl_win.cc",
diff --git a/content/browser/blob_storage/blob_url_browsertest.cc b/content/browser/blob_storage/blob_url_browsertest.cc index 8102a9d..66c45bb 100644 --- a/content/browser/blob_storage/blob_url_browsertest.cc +++ b/content/browser/blob_storage/blob_url_browsertest.cc
@@ -3,8 +3,6 @@ // found in the LICENSE file. #include "base/strings/pattern.h" -#include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/common/content_switches.h" @@ -175,91 +173,4 @@ EXPECT_FALSE(base::MatchPattern(window_location, "*spoof*")); } -enum class PartitionedBlobUrlBrowserTestTestCase { - kSupportPartitionedBlobUrlDisabled, - kSupportPartitionedBlobUrlEnabled, -}; - -class PartitionedBlobUrlBrowserTestP - : public BlobUrlBrowserTest, - public testing::WithParamInterface< - PartitionedBlobUrlBrowserTestTestCase> { - public: - PartitionedBlobUrlBrowserTestP() { - scoped_feature_list_.InitWithFeatureState( - net::features::kSupportPartitionedBlobUrl, - GetParam() == PartitionedBlobUrlBrowserTestTestCase:: - kSupportPartitionedBlobUrlEnabled); - } - - private: - base::test::ScopedFeatureList scoped_feature_list_; -}; - -IN_PROC_BROWSER_TEST_P(PartitionedBlobUrlBrowserTestP, - BlobUrlStoreRegisterMetrics) { - GURL main_url(embedded_test_server()->GetURL("chromium.org", "/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), main_url)); - - base::HistogramTester histogram_tester; - - EXPECT_TRUE(ExecJs(shell(), "URL.createObjectURL(new Blob(['foo']))")); - - FetchHistogramsFromChildProcesses(); - - if (base::FeatureList::IsEnabled(net::features::kSupportPartitionedBlobUrl)) { - histogram_tester.ExpectTotalCount( - "Storage.Blob.RegisterURLTimeWithPartitioningSupport.Frame", 1); - } else { - histogram_tester.ExpectTotalCount( - "Storage.Blob.RegisterURLTimeWithoutPartitioningSupport", 1); - } -} - -IN_PROC_BROWSER_TEST_P(PartitionedBlobUrlBrowserTestP, - BlobUrlStoreRegisterMetricsWorker) { - GURL main_url(embedded_test_server()->GetURL("chromium.org", "/title1.html")); - EXPECT_TRUE(NavigateToURL(shell(), main_url)); - - base::HistogramTester histogram_tester; - - EXPECT_TRUE(ExecJs(shell(), R"( - function workerCode() { - URL.createObjectURL(new Blob(['foo'])); - postMessage(true); - } - var workerBlob = new Blob( - [workerCode.toString() + ';workerCode();'], - {type: 'application/javascript'}); - new Promise((resolve) => { - var w = new Worker(URL.createObjectURL(workerBlob)); - w.onmessage = (e) => { - w.terminate(); - resolve(); - }; - });)")); - - FetchHistogramsFromChildProcesses(); - - // We expect two PublicURLManager::RegisterURL calls, one from the frame when - // it creates the worker and another when the worker creates a blob URL. - if (base::FeatureList::IsEnabled(net::features::kSupportPartitionedBlobUrl)) { - histogram_tester.ExpectTotalCount( - "Storage.Blob.RegisterURLTimeWithPartitioningSupport.Frame", 1); - histogram_tester.ExpectTotalCount( - "Storage.Blob.RegisterURLTimeWithPartitioningSupport.Worker", 1); - } else { - histogram_tester.ExpectTotalCount( - "Storage.Blob.RegisterURLTimeWithoutPartitioningSupport", 2); - } -} - -INSTANTIATE_TEST_SUITE_P( - PartitionedBlobUrlBrowserTest, - PartitionedBlobUrlBrowserTestP, - ::testing::Values(PartitionedBlobUrlBrowserTestTestCase:: - kSupportPartitionedBlobUrlDisabled, - PartitionedBlobUrlBrowserTestTestCase:: - kSupportPartitionedBlobUrlEnabled)); - } // namespace content
diff --git a/content/browser/device_posture/device_posture_platform_provider_win.cc b/content/browser/device_posture/device_posture_platform_provider_win.cc index dca66d8..718aa6b7 100644 --- a/content/browser/device_posture/device_posture_platform_provider_win.cc +++ b/content/browser/device_posture/device_posture_platform_provider_win.cc
@@ -4,190 +4,36 @@ #include "content/browser/device_posture/device_posture_platform_provider_win.h" -#include <optional> - -#include "base/containers/contains.h" -#include "base/containers/fixed_flat_map.h" -#include "base/json/json_reader.h" -#include "base/strings/string_split.h" -#include "base/strings/utf_string_conversions.h" - -using blink::mojom::DevicePostureType; - -namespace { -// The full specification of the registry is located over here -// https://github.com/foldable-devices/foldable-windows-registry-specification -// This approach is a stop gap solution until Windows gains proper APIs. -// -// TODO(darktears): When Windows gains the APIs we should update this code. -// https://crbug.com/1465934 -// -// FOLED stands for Foldable OLED. -constexpr wchar_t kFoledRegKeyPath[] = L"Software\\Intel\\Foled"; - -// On Windows the platform returns [left][fold][right] and so far we support -// only one display feature in Chromium. -constexpr int kFirstFoldInSegmentsArray = 1; - -} // namespace +#include "content/browser/device_posture/device_posture_registry_watcher_win.h" namespace content { -DevicePosturePlatformProviderWin::DevicePosturePlatformProviderWin() { - base::win::RegKey registry_key(HKEY_CURRENT_USER, kFoledRegKeyPath, - KEY_QUERY_VALUE); - if (registry_key.Valid()) { - ComputeFoldableState(registry_key, /*notify_changes=*/false); - } -} +DevicePosturePlatformProviderWin::DevicePosturePlatformProviderWin() = default; DevicePosturePlatformProviderWin::~DevicePosturePlatformProviderWin() = default; void DevicePosturePlatformProviderWin::StartListening() { - if (registry_key_) { + if (registry_watcher_observation_.IsObserving()) { return; } - - registry_key_.emplace(HKEY_CURRENT_USER, kFoledRegKeyPath, - KEY_NOTIFY | KEY_QUERY_VALUE); - if (registry_key_->Valid()) { - // Start watching the registry for changes. - registry_key_->StartWatching( - base::BindOnce(&DevicePosturePlatformProviderWin::OnRegistryKeyChanged, - base::Unretained(this))); - } + registry_watcher_observation_.Observe( + DevicePostureRegistryWatcherWin::GetInstance()); } void DevicePosturePlatformProviderWin::StopListening() { - registry_key_ = std::nullopt; + registry_watcher_observation_.Reset(); } -std::optional<DevicePostureType> DevicePosturePlatformProviderWin::ParsePosture( - std::string_view posture_state) { - static constexpr auto kPostureStateToPostureType = - base::MakeFixedFlatMap<std::string_view, DevicePostureType>( - {{"MODE_HANDHELD", DevicePostureType::kFolded}, - {"MODE_DUAL_ANGLE", DevicePostureType::kFolded}, - {"MODE_LAPTOP_KB", DevicePostureType::kContinuous}, - {"MODE_LAYFLAT_LANDSCAPE", - DevicePostureType::kContinuous}, - {"MODE_LAYFLAT_PORTRAIT", - DevicePostureType::kContinuous}, - {"MODE_TABLETOP", DevicePostureType::kContinuous}}); - if (auto* iter = kPostureStateToPostureType.find(posture_state); - iter != kPostureStateToPostureType.end()) { - return iter->second; - } - DVLOG(1) << "Could not parse the posture data: " << posture_state; - return std::nullopt; +void DevicePosturePlatformProviderWin::UpdateDevicePosture( + const blink::mojom::DevicePostureType& posture) { + current_posture_ = posture; + NotifyDevicePostureChanged(current_posture_); } -void DevicePosturePlatformProviderWin::ComputeFoldableState( - const base::win::RegKey& registry_key, - bool notify_changes) { - CHECK(registry_key.Valid()); - - std::wstring postureData; - if (registry_key.ReadValue(L"PostureData", &postureData) != ERROR_SUCCESS) { - return; - } - - std::optional<base::Value::Dict> dict = - base::JSONReader::ReadDict(base::WideToUTF8(postureData)); - if (!dict) { - DVLOG(1) << "Could not read the foldable status."; - return; - } - const std::string* posture_state = dict->FindString("PostureState"); - if (!posture_state) { - return; - } - - const DevicePostureType old_posture = current_posture_; - std::optional<DevicePostureType> posture = ParsePosture(*posture_state); - - if (posture) { - current_posture_ = posture.value(); - if (old_posture != current_posture_ && notify_changes) { - NotifyDevicePostureChanged(current_posture_); - } - } - - base::Value::List* viewport_segments = dict->FindList("Rectangles"); - if (!viewport_segments) { - DVLOG(1) << "Could not parse the viewport segments data."; - return; - } - - std::optional<std::vector<gfx::Rect>> segments = - ParseViewportSegments(*viewport_segments); - if (!segments) { - return; - } - - // If there is not enough segments then the display feature is empty. - if (segments->size() < 2) { - current_display_feature_bounds_ = gfx::Rect(); - } else { - // We want the first fold segment of the segment array. - current_display_feature_bounds_ = segments->at(kFirstFoldInSegmentsArray); - } - - if (notify_changes) { - NotifyDisplayFeatureBoundsChanged(current_display_feature_bounds_); - } -} - -std::optional<std::vector<gfx::Rect>> -DevicePosturePlatformProviderWin::ParseViewportSegments( - const base::Value::List& viewport_segments) { - if (viewport_segments.empty()) { - return std::nullopt; - } - - // Check if the list is correctly constructed. It should be a multiple of - // |left side|fold|right side| or 1. - if (viewport_segments.size() != 1 && viewport_segments.size() % 3 != 0) { - DVLOG(1) << "Could not parse the viewport segments data."; - return std::nullopt; - } - - std::vector<gfx::Rect> segments; - for (const auto& segment : viewport_segments) { - const std::string* segment_string = segment.GetIfString(); - if (!segment_string) { - DVLOG(1) << "Could not parse the viewport segments data"; - return std::nullopt; - } - auto rectangle_dimensions = base::SplitStringPiece( - *segment_string, ",", base::WhitespaceHandling::TRIM_WHITESPACE, - base::SplitResult::SPLIT_WANT_NONEMPTY); - if (rectangle_dimensions.size() != 4) { - DVLOG(1) << "Could not parse the viewport segments data: " - << *segment_string; - return std::nullopt; - } - int x, y, width, height; - if (!base::StringToInt(rectangle_dimensions[0], &x) || - !base::StringToInt(rectangle_dimensions[1], &y) || - !base::StringToInt(rectangle_dimensions[2], &width) || - !base::StringToInt(rectangle_dimensions[3], &height)) { - DVLOG(1) << "Could not parse the viewport segments data: " - << *segment_string; - return std::nullopt; - } - segments.emplace_back(x, y, width, height); - } - return segments; -} - -void DevicePosturePlatformProviderWin::OnRegistryKeyChanged() { - // |OnRegistryKeyChanged| is removed as an observer when the ChangeCallback is - // called, so we need to re-register. - registry_key_->StartWatching( - base::BindOnce(&DevicePosturePlatformProviderWin::OnRegistryKeyChanged, - base::Unretained(this))); - ComputeFoldableState(registry_key_.value(), /*notify_changes=*/true); +void DevicePosturePlatformProviderWin::UpdateDisplayFeatureBounds( + const gfx::Rect& display_feature_bounds) { + current_display_feature_bounds_ = display_feature_bounds; + NotifyDisplayFeatureBoundsChanged(current_display_feature_bounds_); } } // namespace content
diff --git a/content/browser/device_posture/device_posture_platform_provider_win.h b/content/browser/device_posture/device_posture_platform_provider_win.h index 2aa60d1d..d48b896 100644 --- a/content/browser/device_posture/device_posture_platform_provider_win.h +++ b/content/browser/device_posture/device_posture_platform_provider_win.h
@@ -5,19 +5,16 @@ #ifndef CONTENT_BROWSER_DEVICE_POSTURE_DEVICE_POSTURE_PLATFORM_PROVIDER_WIN_H_ #define CONTENT_BROWSER_DEVICE_POSTURE_DEVICE_POSTURE_PLATFORM_PROVIDER_WIN_H_ -#include <optional> -#include <string_view> -#include <vector> - -#include "base/strings/string_piece.h" -#include "base/values.h" -#include "base/win/registry.h" +#include "base/observer_list_types.h" +#include "base/scoped_observation.h" #include "content/browser/device_posture/device_posture_platform_provider.h" -#include "content/common/content_export.h" namespace content { -class DevicePosturePlatformProviderWin : public DevicePosturePlatformProvider { +class DevicePostureRegistryWatcherWin; + +class DevicePosturePlatformProviderWin : public DevicePosturePlatformProvider, + public base::CheckedObserver { public: DevicePosturePlatformProviderWin(); ~DevicePosturePlatformProviderWin() override; @@ -27,22 +24,16 @@ DevicePosturePlatformProviderWin& operator=( const DevicePosturePlatformProviderWin&) = delete; - private: - friend class DevicePosturePlatformProviderWinTest; + void UpdateDevicePosture(const blink::mojom::DevicePostureType& posture); + void UpdateDisplayFeatureBounds(const gfx::Rect& display_feature_bounds); + private: void StartListening() override; void StopListening() override; - void OnRegistryKeyChanged(); - void ComputeFoldableState(const base::win::RegKey& registry_key, - bool notify_changes); - CONTENT_EXPORT static std::optional<std::vector<gfx::Rect>> - ParseViewportSegments(const base::Value::List& viewport_segments); - CONTENT_EXPORT static std::optional<blink::mojom::DevicePostureType> - ParsePosture(std::string_view posture_state); - // This member is used to watch the registry after StartListening is called. - // It will be destroyed when calling StopListening. - std::optional<base::win::RegKey> registry_key_; + base::ScopedObservation<DevicePostureRegistryWatcherWin, + DevicePosturePlatformProviderWin> + registry_watcher_observation_{this}; }; } // namespace content
diff --git a/content/browser/device_posture/device_posture_registry_watcher_win.cc b/content/browser/device_posture/device_posture_registry_watcher_win.cc new file mode 100644 index 0000000..c0ed83d9 --- /dev/null +++ b/content/browser/device_posture/device_posture_registry_watcher_win.cc
@@ -0,0 +1,213 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +#include "content/browser/device_posture/device_posture_registry_watcher_win.h" + +#include <optional> + +#include "base/containers/contains.h" +#include "base/containers/fixed_flat_map.h" +#include "base/json/json_reader.h" +#include "base/strings/string_split.h" +#include "base/strings/utf_string_conversions.h" + +using blink::mojom::DevicePostureType; + +namespace { +// The full specification of the registry is located over here +// https://github.com/foldable-devices/foldable-windows-registry-specification +// This approach is a stop gap solution until Windows gains proper APIs. +// +// TODO(1465934): When Windows gains the APIs we should update this code. +// +// FOLED stands for Foldable OLED. +constexpr wchar_t kFoledRegKeyPath[] = L"Software\\Intel\\Foled"; + +// On Windows the platform returns [left][fold][right] and so far we support +// only one display feature in Chromium. +constexpr int kFirstFoldInSegmentsArray = 1; + +} // namespace + +namespace content { +// static +DevicePostureRegistryWatcherWin* +DevicePostureRegistryWatcherWin::GetInstance() { + static base::NoDestructor<DevicePostureRegistryWatcherWin> instance; + return instance.get(); +} + +DevicePostureRegistryWatcherWin::DevicePostureRegistryWatcherWin() { + base::win::RegKey registry_key(HKEY_CURRENT_USER, kFoledRegKeyPath, + KEY_QUERY_VALUE); + if (registry_key.Valid()) { + ComputeFoldableState(registry_key, /*notify_changes=*/false); + } +} + +DevicePostureRegistryWatcherWin::~DevicePostureRegistryWatcherWin() = default; + +void DevicePostureRegistryWatcherWin::AddObserver( + DevicePosturePlatformProviderWin* observer) { + if (!observer) { + return; + } + + DCHECK(!observers_.HasObserver(observer)); + if (observers_.empty()) { + DCHECK(!registry_key_); + registry_key_.emplace(HKEY_CURRENT_USER, kFoledRegKeyPath, + KEY_NOTIFY | KEY_QUERY_VALUE); + if (registry_key_->Valid()) { + // Start watching the registry for changes. + registry_key_->StartWatching( + base::BindOnce(&DevicePostureRegistryWatcherWin::OnRegistryKeyChanged, + base::Unretained(this))); + } + } + + observers_.AddObserver(observer); + // Inform the observer with the current state. + observer->UpdateDevicePosture(current_posture_); + observer->UpdateDisplayFeatureBounds(current_display_feature_bounds_); +} + +void DevicePostureRegistryWatcherWin::RemoveObserver( + DevicePosturePlatformProviderWin* observer) { + observers_.RemoveObserver(observer); + if (observers_.empty()) { + registry_key_ = std::nullopt; + } +} + +std::optional<DevicePostureType> DevicePostureRegistryWatcherWin::ParsePosture( + std::string_view posture_state) { + static constexpr auto kPostureStateToPostureType = + base::MakeFixedFlatMap<std::string_view, DevicePostureType>( + {{"MODE_HANDHELD", DevicePostureType::kFolded}, + {"MODE_DUAL_ANGLE", DevicePostureType::kFolded}, + {"MODE_LAPTOP_KB", DevicePostureType::kContinuous}, + {"MODE_LAYFLAT_LANDSCAPE", DevicePostureType::kContinuous}, + {"MODE_LAYFLAT_PORTRAIT", DevicePostureType::kContinuous}, + {"MODE_TABLETOP", DevicePostureType::kContinuous}}); + if (auto* iter = kPostureStateToPostureType.find(posture_state); + iter != kPostureStateToPostureType.end()) { + return iter->second; + } + DVLOG(1) << "Could not parse the posture data: " << posture_state; + return std::nullopt; +} + +void DevicePostureRegistryWatcherWin::ComputeFoldableState( + const base::win::RegKey& registry_key, + bool notify_changes) { + CHECK(registry_key.Valid()); + + std::wstring posture_data; + if (registry_key.ReadValue(L"PostureData", &posture_data) != ERROR_SUCCESS) { + return; + } + + std::optional<base::Value::Dict> dict = + base::JSONReader::ReadDict(base::WideToUTF8(posture_data)); + if (!dict) { + DVLOG(1) << "Could not read the foldable status."; + return; + } + const std::string* posture_state = dict->FindString("PostureState"); + if (!posture_state) { + return; + } + + const DevicePostureType old_posture = current_posture_; + std::optional<DevicePostureType> posture = ParsePosture(*posture_state); + + if (posture) { + current_posture_ = posture.value(); + if (old_posture != current_posture_ && notify_changes) { + for (DevicePosturePlatformProviderWin& observer : observers_) { + observer.UpdateDevicePosture(current_posture_); + } + } + } + + base::Value::List* viewport_segments = dict->FindList("Rectangles"); + if (!viewport_segments) { + DVLOG(1) << "Could not parse the viewport segments data."; + return; + } + + std::optional<std::vector<gfx::Rect>> segments = + ParseViewportSegments(*viewport_segments); + if (!segments) { + return; + } + + // If there is not enough segments then the display feature is empty. + if (segments->size() < 2) { + current_display_feature_bounds_ = gfx::Rect(); + } else { + // We want the first fold segment of the segment array. + current_display_feature_bounds_ = segments->at(kFirstFoldInSegmentsArray); + } + + if (notify_changes) { + for (DevicePosturePlatformProviderWin& observer : observers_) { + observer.UpdateDisplayFeatureBounds(current_display_feature_bounds_); + } + } +} + +std::optional<std::vector<gfx::Rect>> +DevicePostureRegistryWatcherWin::ParseViewportSegments( + const base::Value::List& viewport_segments) { + if (viewport_segments.empty()) { + return std::nullopt; + } + + // Check if the list is correctly constructed. It should be a multiple of + // |left side|fold|right side| or 1. + if (viewport_segments.size() != 1 && viewport_segments.size() % 3 != 0) { + DVLOG(1) << "Could not parse the viewport segments data."; + return std::nullopt; + } + + std::vector<gfx::Rect> segments; + for (const auto& segment : viewport_segments) { + const std::string* segment_string = segment.GetIfString(); + if (!segment_string) { + DVLOG(1) << "Could not parse the viewport segments data"; + return std::nullopt; + } + auto rectangle_dimensions = base::SplitStringPiece( + *segment_string, ",", base::WhitespaceHandling::TRIM_WHITESPACE, + base::SplitResult::SPLIT_WANT_NONEMPTY); + if (rectangle_dimensions.size() != 4) { + DVLOG(1) << "Could not parse the viewport segments data: " + << *segment_string; + return std::nullopt; + } + int x, y, width, height; + if (!base::StringToInt(rectangle_dimensions[0], &x) || + !base::StringToInt(rectangle_dimensions[1], &y) || + !base::StringToInt(rectangle_dimensions[2], &width) || + !base::StringToInt(rectangle_dimensions[3], &height)) { + DVLOG(1) << "Could not parse the viewport segments data: " + << *segment_string; + return std::nullopt; + } + segments.emplace_back(x, y, width, height); + } + return segments; +} + +void DevicePostureRegistryWatcherWin::OnRegistryKeyChanged() { + // |OnRegistryKeyChanged| is removed as an observer when the ChangeCallback is + // called, so we need to re-register. + registry_key_->StartWatching( + base::BindOnce(&DevicePostureRegistryWatcherWin::OnRegistryKeyChanged, + base::Unretained(this))); + ComputeFoldableState(registry_key_.value(), /*notify_changes=*/true); +} + +} // namespace content
diff --git a/content/browser/device_posture/device_posture_registry_watcher_win.h b/content/browser/device_posture/device_posture_registry_watcher_win.h new file mode 100644 index 0000000..b2ffecb --- /dev/null +++ b/content/browser/device_posture/device_posture_registry_watcher_win.h
@@ -0,0 +1,64 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_DEVICE_POSTURE_DEVICE_POSTURE_REGISTRY_WATCHER_WIN_H_ +#define CONTENT_BROWSER_DEVICE_POSTURE_DEVICE_POSTURE_REGISTRY_WATCHER_WIN_H_ + +#include <optional> +#include <string_view> +#include <vector> + +#include "base/no_destructor.h" +#include "base/observer_list.h" +#include "base/strings/string_piece.h" +#include "base/values.h" +#include "base/win/registry.h" +#include "content/browser/device_posture/device_posture_platform_provider_win.h" +#include "content/common/content_export.h" + +namespace content { + +// This is a singleton class that will fetch and monitor the registry to get +// posture and display feature information. +class DevicePostureRegistryWatcherWin { + public: + static DevicePostureRegistryWatcherWin* GetInstance(); + + void AddObserver(DevicePosturePlatformProviderWin* observer); + void RemoveObserver(DevicePosturePlatformProviderWin* observer); + + DevicePostureRegistryWatcherWin(const DevicePostureRegistryWatcherWin&) = + delete; + DevicePostureRegistryWatcherWin& operator=( + const DevicePostureRegistryWatcherWin&) = delete; + + private: + friend class DevicePostureRegistryWatcherWinTest; + friend class base::NoDestructor<DevicePostureRegistryWatcherWin>; + + DevicePostureRegistryWatcherWin(); + ~DevicePostureRegistryWatcherWin(); + + void OnRegistryKeyChanged(); + void ComputeFoldableState(const base::win::RegKey& registry_key, + bool notify_changes); + CONTENT_EXPORT static std::optional<std::vector<gfx::Rect>> + ParseViewportSegments(const base::Value::List& viewport_segments); + CONTENT_EXPORT static std::optional<blink::mojom::DevicePostureType> + ParsePosture(std::string_view posture_state); + + base::ObserverList<DevicePosturePlatformProviderWin> observers_; + + blink::mojom::DevicePostureType current_posture_ = + blink::mojom::DevicePostureType::kContinuous; + gfx::Rect current_display_feature_bounds_; + + // This member is used to watch the registry after StartListening is called. + // It will be destroyed when calling StopListening. + std::optional<base::win::RegKey> registry_key_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_DEVICE_POSTURE_DEVICE_POSTURE_REGISTRY_WATCHER_WIN_H_
diff --git a/content/browser/device_posture/device_posture_platform_provider_win_unittest.cc b/content/browser/device_posture/device_posture_registry_watcher_win_unittest.cc similarity index 88% rename from content/browser/device_posture/device_posture_platform_provider_win_unittest.cc rename to content/browser/device_posture/device_posture_registry_watcher_win_unittest.cc index 1a74a684..774bf38 100644 --- a/content/browser/device_posture/device_posture_platform_provider_win_unittest.cc +++ b/content/browser/device_posture/device_posture_registry_watcher_win_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/device_posture/device_posture_platform_provider_win.h" +#include "content/browser/device_posture/device_posture_registry_watcher_win.h" #include <string_view> @@ -12,31 +12,31 @@ namespace content { -class DevicePosturePlatformProviderWinTest : public testing::Test { +class DevicePostureRegistryWatcherWinTest : public testing::Test { protected: - DevicePosturePlatformProviderWinTest() = default; + DevicePostureRegistryWatcherWinTest() = default; - ~DevicePosturePlatformProviderWinTest() override = default; + ~DevicePostureRegistryWatcherWinTest() override = default; static std::optional<std::vector<gfx::Rect>> ParseViewportSegments( const base::Value::List& viewport_segments) { - return DevicePosturePlatformProviderWin::ParseViewportSegments( + return DevicePostureRegistryWatcherWin::ParseViewportSegments( viewport_segments); } static std::optional<blink::mojom::DevicePostureType> ParsePosture( std::string_view posture_state) { - return DevicePosturePlatformProviderWin::ParsePosture(posture_state); + return DevicePostureRegistryWatcherWin::ParsePosture(posture_state); } }; -TEST_F(DevicePosturePlatformProviderWinTest, InvalidPostureData) { +TEST_F(DevicePostureRegistryWatcherWinTest, InvalidPostureData) { EXPECT_FALSE(ParsePosture("")); EXPECT_FALSE(ParsePosture("test")); EXPECT_FALSE(ParsePosture(" LAPTOP")); } -TEST_F(DevicePosturePlatformProviderWinTest, ValidPostureData) { +TEST_F(DevicePostureRegistryWatcherWinTest, ValidPostureData) { EXPECT_EQ(ParsePosture("MODE_HANDHELD"), blink::mojom::DevicePostureType::kFolded); EXPECT_EQ(ParsePosture("MODE_DUAL_ANGLE"), @@ -51,7 +51,7 @@ blink::mojom::DevicePostureType::kContinuous); } -TEST_F(DevicePosturePlatformProviderWinTest, InvalidViewportSegmentsData) { +TEST_F(DevicePostureRegistryWatcherWinTest, InvalidViewportSegmentsData) { base::Value::List list; std::optional<std::vector<gfx::Rect>> result_viewport_segments = ParseViewportSegments(list); @@ -149,7 +149,7 @@ EXPECT_FALSE(ParseViewportSegments(list)); } -TEST_F(DevicePosturePlatformProviderWinTest, ValidViewportSegmentsData) { +TEST_F(DevicePostureRegistryWatcherWinTest, ValidViewportSegmentsData) { std::optional<std::vector<gfx::Rect>> result_viewport_segments; base::Value::List list = base::test::ParseJsonList(R"([ "132, 123, 123, 123"
diff --git a/content/browser/indexed_db/indexed_db_bucket_context.cc b/content/browser/indexed_db/indexed_db_bucket_context.cc index 3f9a7b4..7da02df 100644 --- a/content/browser/indexed_db/indexed_db_bucket_context.cc +++ b/content/browser/indexed_db/indexed_db_bucket_context.cc
@@ -595,7 +595,7 @@ } int64_t IndexedDBBucketContext::GetInMemorySize() { - return backing_store_->GetInMemorySize(); + return backing_store_ ? backing_store_->GetInMemorySize() : 0; } void IndexedDBBucketContext::ReportOutstandingBlobs(bool blobs_outstanding) { @@ -979,6 +979,10 @@ // TODO(jsbell): Sort by name? std::vector<storage::mojom::IdbDatabaseMetadataPtr> database_list; + if (backing_store_ && backing_store_->in_memory()) { + info->size = GetInMemorySize(); + } + for (const auto& [name, db] : databases_) { storage::mojom::IdbDatabaseMetadataPtr db_info = storage::mojom::IdbDatabaseMetadata::New();
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc index a64e482..3b013f5 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.cc +++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -70,6 +70,25 @@ #include "third_party/zlib/google/zip.h" #include "url/origin.h" +// Invokes a given method on an IndexedDBBucketContext, synchronously or +// asynchronously depending on the state of the kIndexedDBShardBackingStores +// flag. This is a transitional helper and should be replaced by SequenceBound +// when the feature is enabled by default. +#define CALL_BUCKET_METHOD(bucket_id, method, ...) \ + { \ + auto iter = bucket_contexts_.find(bucket_id); \ + if (iter != bucket_contexts_.end()) { \ + auto bucket_closure = \ + base::BindOnce(&IndexedDBBucketContext::method, \ + base::Unretained(iter->second.get()), __VA_ARGS__); \ + if (ShardingEnabled()) { \ + IDBTaskRunner()->PostTask(FROM_HERE, std::move(bucket_closure)); \ + } else { \ + std::move(bucket_closure).Run(); \ + } \ + } \ + } + namespace content { using blink::StorageKey; @@ -77,6 +96,10 @@ namespace { +bool ShardingEnabled() { + return base::FeatureList::IsEnabled(features::kIndexedDBShardBackingStores); +} + bool IsAllowedPath(const std::vector<base::FilePath>& allowed_paths, const base::FilePath& candidate_path) { for (const base::FilePath& allowed_path : allowed_paths) { @@ -253,9 +276,17 @@ DCHECK(IDBTaskRunner()->RunsTasksInCurrentSequence()); DCHECK_EQ(bucket_locator.type, blink::mojom::StorageType::kTemporary); DCHECK(!callback.is_null()); - ForceClose(bucket_locator.id, - storage::mojom::ForceCloseReason::FORCE_CLOSE_DELETE_ORIGIN, - base::DoNothing()); + ForceClose( + bucket_locator.id, + storage::mojom::ForceCloseReason::FORCE_CLOSE_DELETE_ORIGIN, + base::BindOnce(&IndexedDBContextImpl::DidForceCloseForDeleteBucketData, + weak_factory_.GetWeakPtr(), bucket_locator, + std::move(callback))); +} + +void IndexedDBContextImpl::DidForceCloseForDeleteBucketData( + const storage::BucketLocator& bucket_locator, + DeleteBucketDataCallback callback) { if (in_memory()) { bucket_set_.erase(bucket_locator); bucket_size_map_.erase(bucket_locator); @@ -283,13 +314,21 @@ storage::mojom::ForceCloseReason reason, base::OnceClosure closure) { auto it = bucket_contexts_.find(bucket_id); - if (it != bucket_contexts_.end()) { - it->second->ForceClose( - /*doom=*/reason == - storage::mojom::ForceCloseReason::FORCE_CLOSE_DELETE_ORIGIN); + if (it == bucket_contexts_.end()) { + std::move(closure).Run(); + return; } - - std::move(closure).Run(); + auto bucket_closure = base::BindOnce( + &IndexedDBBucketContext::ForceClose, base::Unretained(it->second.get()), + /*doom=*/reason == + storage::mojom::ForceCloseReason::FORCE_CLOSE_DELETE_ORIGIN); + if (ShardingEnabled()) { + IDBTaskRunner()->PostTaskAndReply(FROM_HERE, std::move(bucket_closure), + std::move(closure)); + } else { + std::move(bucket_closure).Run(); + std::move(closure).Run(); + } } void IndexedDBContextImpl::DownloadBucketData( @@ -375,7 +414,11 @@ storage::mojom::IdbBucketMetadata::New(); info->bucket_locator = bucket_locator; info->name = bucket_info.name; - info->size = static_cast<double>(GetBucketDiskUsage(bucket_locator)); + if (!in_memory()) { + // Size for in-memory DBs will be filled in + // `IndexedDBBucketContext::FillInMetadata()`. + info->size = static_cast<double>(GetBucketDiskUsage(bucket_locator)); + } info->last_modified = GetBucketLastModified(bucket_locator); if (!in_memory()) { @@ -494,9 +537,9 @@ const std::string& key, const std::string& value, base::OnceClosure callback) { - bucket_contexts_.find(bucket_locator.id) - ->second->WriteToIndexedDBForTesting(key, value, // IN-TEST - std::move(callback)); + DCHECK(base::Contains(bucket_contexts_, bucket_locator.id)); + CALL_BUCKET_METHOD(bucket_locator.id, WriteToIndexedDBForTesting, key, value, + std::move(callback)); } void IndexedDBContextImpl::GetPathForBlobForTesting( @@ -511,13 +554,22 @@ void IndexedDBContextImpl::CompactBackingStoreForTesting( const BucketLocator& bucket_locator, base::OnceClosure callback) { - bucket_contexts_.find(bucket_locator.id) - ->second->CompactBackingStoreForTesting(); // IN-TEST - std::move(callback).Run(); + auto it = bucket_contexts_.find(bucket_locator.id); + IDBTaskRunner()->PostTaskAndReply( + FROM_HERE, + base::BindOnce(&IndexedDBBucketContext::CompactBackingStoreForTesting, + base::Unretained(it->second.get())), + std::move(callback)); } void IndexedDBContextImpl::GetUsageForTesting( GetUsageForTestingCallback callback) { + if (in_memory()) { + DCHECK_EQ(1U, bucket_contexts_.size()); + GetInMemorySize(bucket_contexts_.begin()->first, std::move(callback)); + return; + } + int64_t total_size = 0; for (const BucketLocator& bucket : bucket_set_) { total_size += GetBucketDiskUsage(bucket); @@ -549,6 +601,7 @@ int64_t IndexedDBContextImpl::GetBucketDiskUsage( const BucketLocator& bucket_locator) { DCHECK(IDBTaskRunner()->RunsTasksInCurrentSequence()); + DCHECK(!in_memory()); if (!LookUpBucket(bucket_locator.id)) return 0; @@ -650,9 +703,13 @@ // other callbacks) so that `ForceClose()` below doesn't mutate // `bucket_contexts_` while it's being iterated. weak_factory_.InvalidateWeakPtrs(); - for (const auto& [locator, context] : bucket_contexts_) { - context->ForceClose(/*doom=*/false); + for (auto& [bucket_id, context] : bucket_contexts_) { + CALL_BUCKET_METHOD(bucket_id, ForceClose, /*doom=*/false); + if (ShardingEnabled()) { + IDBTaskRunner()->DeleteSoon(FROM_HERE, std::move(context)); + } } + bucket_contexts_.clear(); } @@ -684,12 +741,13 @@ } if (delete_bucket) { - auto it = bucket_contexts_.find(bucket_locator.id); - if (it != bucket_contexts_.end()) { - it->second->ForceClose(false); - } - base::ranges::for_each(GetStoragePaths(bucket_locator), - &base::DeletePathRecursively); + ForceClose(bucket_locator.id, {}, + base::BindOnce( + [](std::vector<base::FilePath> paths) { + base::ranges::for_each(paths, + &base::DeletePathRecursively); + }, + GetStoragePaths(bucket_locator))); } } } @@ -732,9 +790,7 @@ int64_t IndexedDBContextImpl::ReadUsageFromDisk( const BucketLocator& bucket_locator, bool write_in_progress) const { - if (in_memory()) { - return GetInMemorySize(bucket_locator); - } + DCHECK(!in_memory()); #if BUILDFLAG(IS_WIN) // Touch all files in the LevelDB directory to update directory entry @@ -918,13 +974,22 @@ } } -int64_t IndexedDBContextImpl::GetInMemorySize( - const BucketLocator& bucket_locator) const { - auto it = bucket_contexts_.find(bucket_locator.id); +void IndexedDBContextImpl::GetInMemorySize( + storage::BucketId bucket_id, + base::OnceCallback<void(int64_t)> on_got_size) const { + auto it = bucket_contexts_.find(bucket_id); if (it == bucket_contexts_.end()) { - return 0; + std::move(on_got_size).Run(0); + return; } - return it->second->GetInMemorySize(); + auto bucket_closure = base::BindOnce(&IndexedDBBucketContext::GetInMemorySize, + base::Unretained(it->second.get())); + if (ShardingEnabled()) { + IDBTaskRunner()->PostTaskAndReplyWithResult( + FROM_HERE, std::move(bucket_closure), std::move(on_got_size)); + } else { + std::move(on_got_size).Run(std::move(bucket_closure).Run()); + } } std::vector<storage::BucketId> @@ -953,7 +1018,19 @@ if (it == bucket_contexts_.end()) { std::move(result).Run(std::move(info)); } else { - it->second->FillInMetadata(std::move(info), std::move(result)); + CALL_BUCKET_METHOD(info->bucket_locator.id, FillInMetadata, std::move(info), + std::move(result)); + } +} + +void IndexedDBContextImpl::DestroyBucketContext(storage::BucketId bucket_id) { + if (ShardingEnabled()) { + auto it = bucket_contexts_.find(bucket_id); + CHECK(it != bucket_contexts_.end()); + IDBTaskRunner()->DeleteSoon(FROM_HERE, std::move(it->second)); + bucket_contexts_.erase(it); + } else { + bucket_contexts_.erase(bucket_id); } } @@ -968,14 +1045,9 @@ const BucketLocator bucket_locator = bucket.ToBucketLocator(); IndexedDBBucketContext::Delegate bucket_delegate; - bucket_delegate.on_ready_for_destruction = base::BindRepeating( - [](base::WeakPtr<IndexedDBContextImpl> context, - const BucketLocator& bucket_locator) { - if (context) { - context->bucket_contexts_.erase(bucket_locator.id); - } - }, - weak_factory_.GetWeakPtr(), bucket_locator); + bucket_delegate.on_ready_for_destruction = + base::BindOnce(&IndexedDBContextImpl::DestroyBucketContext, + weak_factory_.GetWeakPtr(), bucket_locator.id); bucket_delegate.on_content_changed = base::BindRepeating( base::BindRepeating(&IndexedDBContextImpl::NotifyIndexedDBContentChanged, weak_factory_.GetWeakPtr(), bucket_locator)); @@ -985,7 +1057,7 @@ bucket_delegate.for_each_bucket_context = base::BindRepeating( &IndexedDBContextImpl::ForEachBucketContext, weak_factory_.GetWeakPtr()); - if (base::FeatureList::IsEnabled(features::kIndexedDBShardBackingStores)) { + if (ShardingEnabled()) { bucket_delegate.on_ready_for_destruction = base::BindPostTask( idb_task_runner_, std::move(bucket_delegate.on_ready_for_destruction)); bucket_delegate.on_receiver_bounced = base::BindPostTask( @@ -1023,8 +1095,8 @@ it = bucket_contexts_.emplace(bucket_locator.id, std::move(bucket_context)) .first; if (pending_failure_injector_) { - it->second->BindMockFailureSingletonForTesting( // IN-TEST - std::move(pending_failure_injector_)); + CALL_BUCKET_METHOD(bucket_locator.id, BindMockFailureSingletonForTesting, + std::move(pending_failure_injector_)); } bucket_set_.insert(bucket_locator); return *it->second; @@ -1033,7 +1105,11 @@ void IndexedDBContextImpl::GetBucketUsage(const BucketLocator& bucket, GetBucketUsageCallback callback) { DCHECK_EQ(bucket.type, blink::mojom::StorageType::kTemporary); - std::move(callback).Run(GetBucketDiskUsage(bucket)); + if (in_memory()) { + GetInMemorySize(bucket.id, std::move(callback)); + } else { + std::move(callback).Run(GetBucketDiskUsage(bucket)); + } } void IndexedDBContextImpl::GetStorageKeysForType(
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h index dc276a3..6f5c1e3 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.h +++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -219,6 +219,10 @@ // third-party-context IDB files are stored. std::map<storage::BucketId, base::FilePath> FindIndexedDBFiles() const; + void DidForceCloseForDeleteBucketData( + const storage::BucketLocator& bucket_locator, + DeleteBucketDataCallback callback); + void OnBucketInfoReady( GetAllBucketsDetailsCallback callback, std::vector<storage::QuotaErrorOr<storage::BucketInfo>> bucket_infos); @@ -227,7 +231,8 @@ void ForEachBucketContext(IndexedDBBucketContext::InstanceClosure callback); // Calculates in-memory/incognito usage for usage reporting. - int64_t GetInMemorySize(const storage::BucketLocator& bucket_locator) const; + void GetInMemorySize(storage::BucketId bucket_id, + base::OnceCallback<void(int64_t)> on_got_size) const; std::vector<storage::BucketId> GetOpenBucketIdsForTesting() const; @@ -262,6 +267,8 @@ const std::u16string& database_name, const std::u16string& object_store_name); + void DestroyBucketContext(storage::BucketId id); + std::optional<storage::BucketLocator> LookUpBucket( storage::BucketId bucket_id);
diff --git a/content/browser/media/system_media_controls_notifier.h b/content/browser/media/system_media_controls_notifier.h index 2ad0481c..da467ac 100644 --- a/content/browser/media/system_media_controls_notifier.h +++ b/content/browser/media/system_media_controls_notifier.h
@@ -58,6 +58,8 @@ void MediaControllerImageChanged( ::media_session::mojom::MediaSessionImageType type, const SkBitmap& bitmap) override; + // There's no chapter images in the system media tray view, so we don't need + // to implement this method. void MediaControllerChapterImageChanged(int chapter_index, const SkBitmap& bitmap) override {}
diff --git a/content/browser/media/web_app_system_media_controls_browsertest.cc b/content/browser/media/web_app_system_media_controls_browsertest.cc index 60d7226..6a3efebd 100644 --- a/content/browser/media/web_app_system_media_controls_browsertest.cc +++ b/content/browser/media/web_app_system_media_controls_browsertest.cc
@@ -207,13 +207,8 @@ base::test::ScopedFeatureList feature_list_; }; -#if BUILDFLAG(IS_WIN) && defined(ADDRESS_SANITIZER) -#define MAYBE_SimpleOneBrowserTest DISABLED_SimpleOneBrowserTest -#else -#define MAYBE_SimpleOneBrowserTest SimpleOneBrowserTest -#endif IN_PROC_BROWSER_TEST_F(WebAppSystemMediaControlsBrowserTest, - MAYBE_SimpleOneBrowserTest) { + SimpleOneBrowserTest) { GURL http_url(https_server()->GetURL("/media/session/media-session.html")); EXPECT_TRUE(NavigateToURL(shell(), http_url)); @@ -222,6 +217,9 @@ // Check video is playing. EXPECT_TRUE(IsPlaying(shell(), "long-video-loop")); + bool is_for_pwa = WaitForStartWatchingMediaKey(); + EXPECT_FALSE(is_for_pwa); + // Hit pause via simulating SMTC pause. MediaKeysListenerManagerImpl* media_keys_listener_manager_impl = BrowserMainLoop::GetInstance()->media_keys_listener_manager();
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index fd4f8af0..96b47ec 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -5767,7 +5767,7 @@ can_store_old_page_in_bfcache /* persisted */); } -bool NavigationRequest::ShouldDispatchPageConcealEvent() const { +bool NavigationRequest::ShouldDispatchPageSwapEvent() const { if (early_render_frame_host_swap_type_ != EarlyRenderFrameHostSwapType::kNone) { return false; @@ -5777,11 +5777,11 @@ return false; } - if (!base::FeatureList::IsEnabled(blink::features::kPageConcealEvent)) { + if (!base::FeatureList::IsEnabled(blink::features::kPageSwapEvent)) { return false; } - return !did_fire_page_conceal_; + return !did_fire_page_swap_; } void NavigationRequest::CommitNavigation() { @@ -5809,10 +5809,10 @@ DCHECK(!blink::IsRendererDebugURL(common_params_->url)); AddOldPageInfoToCommitParamsIfNeeded(); - if (ShouldDispatchPageConcealEvent()) { + if (ShouldDispatchPageSwapEvent()) { frame_tree_node_->current_frame_host() ->GetAssociatedLocalFrame() - ->DispatchPageConceal(WillDispatchPageConceal()); + ->DispatchPageSwap(WillDispatchPageSwap()); } url::Origin origin_to_commit = GetOriginToCommit().value(); @@ -10316,13 +10316,12 @@ return loader_.get() != nullptr; } -blink::mojom::PageConcealEventParamsPtr -NavigationRequest::WillDispatchPageConceal() { - CHECK(ShouldDispatchPageConcealEvent()); +blink::mojom::PageSwapEventParamsPtr NavigationRequest::WillDispatchPageSwap() { + CHECK(ShouldDispatchPageSwapEvent()); - did_fire_page_conceal_ = true; + did_fire_page_swap_ = true; - // The `pageconceal` event is fired on the old Document to provide information + // The `pageswap` event is fired on the old Document to provide information // about the new Document. The information shared must be restricted to // same-origin Documents. const bool is_same_origin = @@ -10336,24 +10335,24 @@ CHECK(!frame_tree_node_->current_origin().opaque()); - auto page_conceal_event_params = blink::mojom::PageConcealEventParams::New(); - page_conceal_event_params->url = common_params_->url; + auto page_swap_event_params = blink::mojom::PageSwapEventParams::New(); + page_swap_event_params->url = common_params_->url; switch (common_params_->navigation_type) { case blink::mojom::NavigationType::RELOAD: case blink::mojom::NavigationType::RELOAD_BYPASSING_CACHE: - page_conceal_event_params->navigation_type = + page_swap_event_params->navigation_type = blink::mojom::NavigationTypeForNavigationApi::kReload; break; case blink::mojom::NavigationType::HISTORY_DIFFERENT_DOCUMENT: - page_conceal_event_params->navigation_type = + page_swap_event_params->navigation_type = blink::mojom::NavigationTypeForNavigationApi::kTraverse; - page_conceal_event_params->page_state = commit_params_->page_state; + page_swap_event_params->page_state = commit_params_->page_state; break; case blink::mojom::NavigationType::DIFFERENT_DOCUMENT: - page_conceal_event_params->navigation_type = + page_swap_event_params->navigation_type = common_params_->should_replace_current_entry ? blink::mojom::NavigationTypeForNavigationApi::kReplace : blink::mojom::NavigationTypeForNavigationApi::kPush; @@ -10367,10 +10366,10 @@ case blink::mojom::NavigationType::HISTORY_SAME_DOCUMENT: case blink::mojom::NavigationType::SAME_DOCUMENT: NOTREACHED_NORETURN() - << "Same-document navigations shouldn't fire pageconceal"; + << "Same-document navigations shouldn't fire pageswap"; } - return page_conceal_event_params; + return page_swap_event_params; } void NavigationRequest::MaybeRecordTraceEventsAndHistograms() {
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h index 920d1aa..92fb7f6 100644 --- a/content/browser/renderer_host/navigation_request.h +++ b/content/browser/renderer_host/navigation_request.h
@@ -1323,13 +1323,13 @@ bool HasLoader() const; // Notifies that an IPC will be sent to the old Document's renderer to - // dispatch the `pageconceal` event. Returns the parameters which should be + // dispatch the `pageswap` event. Returns the parameters which should be // used for the event if this is a same-origin navigation. - blink::mojom::PageConcealEventParamsPtr WillDispatchPageConceal(); + blink::mojom::PageSwapEventParamsPtr WillDispatchPageSwap(); - // Returns true if this navigation is eligible for dispatching a `pageconceal` + // Returns true if this navigation is eligible for dispatching a `pageswap` // event on the old Document and the event has not been dispatched already. - bool ShouldDispatchPageConcealEvent() const; + bool ShouldDispatchPageSwapEvent() const; private: friend class NavigationRequestTest; @@ -2852,12 +2852,12 @@ // value is available. std::optional<url::Origin> tentative_data_origin_to_commit_; - // `pageconceal` can be fired at different stages of the navigation lifecycle: + // `pageswap` can be fired at different stages of the navigation lifecycle: // - ready to commit if this navigation is associated with a ViewTransition. // - unload old document if there is no ViewTransition opt-in. - // This tracks whether the pageconceal event has been fired for this + // This tracks whether the pageswap event has been fired for this // navigation. - bool did_fire_page_conceal_ = false; + bool did_fire_page_swap_ = false; base::WeakPtrFactory<NavigationRequest> weak_factory_{this}; };
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc index 8b25c53..621dee9 100644 --- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -7791,7 +7791,7 @@ /*ignore_outstanding_network_request=*/false); enabled_features.push_back( {blink::features::kViewTransitionOnNavigation, {{}}}); - enabled_features.push_back({blink::features::kPageConcealEvent, {{}}}); + enabled_features.push_back({blink::features::kPageSwapEvent, {{}}}); enabled_features.push_back( {features::kInvalidateLocalSurfaceIdPreCommit, {{}}}); scoped_feature_list_.InitWithFeaturesAndParameters(
diff --git a/content/browser/renderer_host/render_widget_host_view_ios.mm b/content/browser/renderer_host/render_widget_host_view_ios.mm index c443a7f..57ecf421 100644 --- a/content/browser/renderer_host/render_widget_host_view_ios.mm +++ b/content/browser/renderer_host/render_widget_host_view_ios.mm
@@ -10,6 +10,7 @@ #include "base/command_line.h" #include "base/strings/sys_string_conversions.h" +#include "build/ios_buildflags.h" #include "components/viz/common/features.h" #include "components/viz/common/surfaces/frame_sink_id_allocator.h" #include "content/browser/renderer_host/browser_compositor_ios.h" @@ -52,7 +53,13 @@ gfx::Size(980, 735); bool IsTesting() { +#if BUILDFLAG(IS_IOS_APP_EXTENSION) + // This class shouldn't really be build with extension anyways. + // Fix the build to avoid building browser code in extensions. + return false; +#else return [[UIApplication sharedApplication] isRunningTests]; +#endif } gfx::Rect GetDefaultSizeForTesting() {
diff --git a/content/browser/renderer_host/view_transition_commit_deferring_condition.cc b/content/browser/renderer_host/view_transition_commit_deferring_condition.cc index 9112f40..60b6a98 100644 --- a/content/browser/renderer_host/view_transition_commit_deferring_condition.cc +++ b/content/browser/renderer_host/view_transition_commit_deferring_condition.cc
@@ -39,7 +39,7 @@ if (!navigation_request.IsInPrimaryMainFrame()) return nullptr; - if (!navigation_request.ShouldDispatchPageConcealEvent()) { + if (!navigation_request.ShouldDispatchPageSwapEvent()) { return nullptr; } @@ -89,16 +89,16 @@ auto* render_frame_host = navigation_request->frame_tree_node()->current_frame_host(); - blink::mojom::PageConcealEventParamsPtr page_conceal_event_params = - navigation_request->WillDispatchPageConceal(); - CHECK(page_conceal_event_params); + blink::mojom::PageSwapEventParamsPtr page_swap_event_params = + navigation_request->WillDispatchPageSwap(); + CHECK(page_swap_event_params); // TODO(crbug.com/1372584): Implement a timeout, to avoid blocking the // navigation for too long. CHECK(render_frame_host->IsRenderFrameLive()); render_frame_host->GetAssociatedLocalFrame() ->SnapshotDocumentForViewTransition( - std::move(page_conceal_event_params), + std::move(page_swap_event_params), base::BindOnce(&OnSnapshotAck, std::move(resume), navigation_request->GetWeakPtr())); return Result::kDefer;
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 6da8fc7..da232cd 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -242,8 +242,7 @@ raw_ref(blink::features::kSharedStorageAPIM118), kSetOnlyIfOverridden}, {wf::EnableSharedStorageAPIM123, - raw_ref(blink::features::kSharedStorageAPIM123), - kSetOnlyIfOverridden}, + raw_ref(blink::features::kSharedStorageAPIM123), kDefault}, {wf::EnableFedCmMultipleIdentityProviders, raw_ref(features::kFedCmMultipleIdentityProviders), kDefault}, {wf::EnableFedCmDisconnect, raw_ref(features::kFedCmDisconnect),
diff --git a/content/public/test/fake_local_frame.cc b/content/public/test/fake_local_frame.cc index 2aeef86..1cbf984 100644 --- a/content/public/test/fake_local_frame.cc +++ b/content/public/test/fake_local_frame.cc
@@ -202,11 +202,10 @@ bool is_browser_initiated) {} void FakeLocalFrame::SnapshotDocumentForViewTransition( - blink::mojom::PageConcealEventParamsPtr, + blink::mojom::PageSwapEventParamsPtr, SnapshotDocumentForViewTransitionCallback callback) {} -void FakeLocalFrame::DispatchPageConceal( - blink::mojom::PageConcealEventParamsPtr) {} +void FakeLocalFrame::DispatchPageSwap(blink::mojom::PageSwapEventParamsPtr) {} void FakeLocalFrame::AddResourceTimingEntryForFailedSubframeNavigation( const ::blink::FrameToken& subframe_token,
diff --git a/content/public/test/fake_local_frame.h b/content/public/test/fake_local_frame.h index 6401523..481a36c 100644 --- a/content/public/test/fake_local_frame.h +++ b/content/public/test/fake_local_frame.h
@@ -154,9 +154,9 @@ const std::string& page_state, bool is_browser_initiated) override; void SnapshotDocumentForViewTransition( - blink::mojom::PageConcealEventParamsPtr, + blink::mojom::PageSwapEventParamsPtr, SnapshotDocumentForViewTransitionCallback callback) override; - void DispatchPageConceal(blink::mojom::PageConcealEventParamsPtr) override; + void DispatchPageSwap(blink::mojom::PageSwapEventParamsPtr) override; void AddResourceTimingEntryForFailedSubframeNavigation( const ::blink::FrameToken& subframe_token, const GURL& initial_url,
diff --git a/content/shell/app/ios/BUILD.gn b/content/shell/app/ios/BUILD.gn index 7684e84..97a9a397 100644 --- a/content/shell/app/ios/BUILD.gn +++ b/content/shell/app/ios/BUILD.gn
@@ -25,6 +25,8 @@ sources = [ "../shell_main.cc" ] + ldflags = [ "-Wl,--ignore-auto-link-option=CoreAudioTypes" ] + deps = [ "//content/app/ios/appex:content_process", "//content/public/app",
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 2815030..0dad112 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -3202,7 +3202,7 @@ sources += [ "../browser/accessibility/browser_accessibility_manager_win_unittest.cc", "../browser/accessibility/browser_accessibility_win_unittest.cc", - "../browser/device_posture/device_posture_platform_provider_win_unittest.cc", + "../browser/device_posture/device_posture_registry_watcher_win_unittest.cc", "../browser/renderer_host/direct_manipulation_test_helper_win.cc", "../browser/renderer_host/direct_manipulation_test_helper_win.h", "../browser/renderer_host/direct_manipulation_win_unittest.cc",
diff --git a/content/web_test/common/web_test.mojom b/content/web_test/common/web_test.mojom index 40be113..3b6650d1 100644 --- a/content/web_test/common/web_test.mojom +++ b/content/web_test/common/web_test.mojom
@@ -4,6 +4,7 @@ module content.mojom; +import "mojo/public/mojom/base/byte_string.mojom"; import "mojo/public/mojom/base/file_path.mojom"; import "mojo/public/mojom/base/string16.mojom"; import "mojo/public/mojom/base/values.mojom"; @@ -44,8 +45,9 @@ // Audio dump. array<uint8>? audio; - // Layout dump. - string? layout; + // Layout dump. A ByteString rather than a string because the layout dump can + // be supplied by the test and may contain non-UTF8 encoded text. + mojo_base.mojom.ByteString? layout; // Image dump. skia.mojom.BitmapN32? pixels;
diff --git a/docs/unsafe_buffers.md b/docs/unsafe_buffers.md new file mode 100644 index 0000000..de80e6d --- /dev/null +++ b/docs/unsafe_buffers.md
@@ -0,0 +1,39 @@ +# Preventing OOB through Unsafe Buffers errors (aka Spanification) + +Out-of-bounds (OOB) security bugs commonly happen through pointers +which have no bounds checks associated with them. We prevent such +bugs by always using containers. + +Most pointers are unowned references into an array (or vector) +and the most appropriate replacement for the pointer is +base::span. + +When a file or directory is known to pass compilation with +`-Wunsafe-buffer-usage`,it should be added to the +[`//build/config/unsafe_buffers_paths.txt`](../build/config/unsafe_buffers_paths.txt) +file to enable compiler errors if unsafe pointer usage is added to +the file later. + +# Functions with array pointer parameters + +Functions that receive a pointer into an array may read +or write out of bounds of the pointer if given a pointer that +is incorrectly sized. Such functions should be marked with the +UNSAFE_BUFFER_USAGE attribute macro. + +The same is true for functions that accept an iterator instead +of a range type. Some examples of each are memcpy() and +std::copy(). + +Calling such functions is unsafe and should generally be avoided. +Instead, replace such functions with an API built on base::span +or other range types which prevents any chance of OOB memory +access. For instance, replace `memcpy()`, `std::copy()` and +`std::ranges::copy()` with `base::span::copy_from()`. And +replace `memset()` with `std::ranges::fill()`. + +# Writing unsafe data structures with pointers + +TODO: Write about `UNSAFE_BUFFERS()` for rare exceptions where +the correctness of pointer bounds can be fully explained and +encapsulated, such as within a data structure.
diff --git a/docs/website b/docs/website index 7918c58..f2eab19 160000 --- a/docs/website +++ b/docs/website
@@ -1 +1 @@ -Subproject commit 7918c586771aed5e170cb5ce33fdfc38f6203063 +Subproject commit f2eab19faaecbab4992d4633704136e5778faabc
diff --git a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc index c6b35b7..0fa7721c 100644 --- a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc +++ b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc
@@ -71,16 +71,6 @@ UMA_HISTOGRAM_ENUMERATION(kLoadRulesetResultHistogram, result); } -// Whether the `extension` has the permission to use the declarativeNetRequest -// API. -bool HasAPIPermission(const Extension& extension) { - const PermissionsData* permissions = extension.permissions_data(); - return permissions->HasAPIPermission( - mojom::APIPermissionID::kDeclarativeNetRequest) || - permissions->HasAPIPermission( - mojom::APIPermissionID::kDeclarativeNetRequestWithHostAccess); -} - // Returns whether the extension's allocation should be released. This would // return true for cases where we expect the extension to be unloaded for a // while or if the extension directory's contents changed in a reload. @@ -141,7 +131,7 @@ HostPermissionsAlwaysRequired GetHostPermissionsAlwaysRequired( const Extension& extension) { - DCHECK(HasAPIPermission(extension)); + DCHECK(HasAnyDNRPermission(extension)); const PermissionsData* permissions = extension.permissions_data(); if (permissions->HasAPIPermission( @@ -461,8 +451,9 @@ const Extension* extension, bool is_update, const std::string& old_name) { - if (!HasAPIPermission(*extension)) + if (!HasAnyDNRPermission(*extension)) { return; + } if (!is_update || Manifest::IsUnpackedLocation(extension->location())) return; @@ -481,8 +472,9 @@ const Extension* extension) { DCHECK_EQ(context_, browser_context); - if (!HasAPIPermission(*extension)) + if (!HasAnyDNRPermission(*extension)) { return; + } LoadRequestData load_data(extension->id(), extension->version()); int expected_ruleset_checksum; @@ -554,8 +546,9 @@ UnloadedExtensionReason reason) { DCHECK_EQ(context_, browser_context); - if (!HasAPIPermission(*extension)) + if (!HasAnyDNRPermission(*extension)) { return; + } // If the extension is unloaded for any reason other than an update, the // unused rule allocation should not be kept for this extension the next @@ -585,8 +578,9 @@ UninstallReason reason) { DCHECK_EQ(context_, browser_context); - if (!HasAPIPermission(*extension)) + if (!HasAnyDNRPermission(*extension)) { return; + } session_rules_.erase(extension->id());
diff --git a/extensions/browser/api/declarative_net_request/utils.cc b/extensions/browser/api/declarative_net_request/utils.cc index 7d9e53f..af9c7aed 100644 --- a/extensions/browser/api/declarative_net_request/utils.cc +++ b/extensions/browser/api/declarative_net_request/utils.cc
@@ -488,6 +488,14 @@ return enabled_static_rule_count; } +bool HasAnyDNRPermission(const Extension& extension) { + const PermissionsData* permissions = extension.permissions_data(); + return permissions->HasAPIPermission( + mojom::APIPermissionID::kDeclarativeNetRequest) || + permissions->HasAPIPermission( + mojom::APIPermissionID::kDeclarativeNetRequestWithHostAccess); +} + bool HasDNRFeedbackPermission(const Extension* extension, const std::optional<int>& tab_id) { const PermissionsData* permissions_data = extension->permissions_data();
diff --git a/extensions/browser/api/declarative_net_request/utils.h b/extensions/browser/api/declarative_net_request/utils.h index d98de5f0..1f0893c7 100644 --- a/extensions/browser/api/declarative_net_request/utils.h +++ b/extensions/browser/api/declarative_net_request/utils.h
@@ -19,6 +19,7 @@ #include "extensions/browser/api/web_request/web_request_resource_type.h" #include "extensions/common/api/declarative_net_request.h" #include "extensions/common/api/declarative_net_request/constants.h" +#include "extensions/common/extension.h" #include "third_party/re2/src/re2/re2.h" namespace base { @@ -169,6 +170,10 @@ // |composite_matcher|. size_t GetEnabledStaticRuleCount(const CompositeMatcher* composite_matcher); +// Whether the `extension` has the permission to use the declarativeNetRequest +// API. +bool HasAnyDNRPermission(const Extension& extension); + // Returns true if |extension| has the declarativeNetRequestFeedback permission // for the specified |tab_id|. If |tab_is| is omitted, then non-tab specific // permissions are checked.
diff --git a/extensions/browser/api/web_request/extension_web_request_event_router.cc b/extensions/browser/api/web_request/extension_web_request_event_router.cc index 90ba672..7b99af2d 100644 --- a/extensions/browser/api/web_request/extension_web_request_event_router.cc +++ b/extensions/browser/api/web_request/extension_web_request_event_router.cc
@@ -33,6 +33,7 @@ #include "extensions/browser/api/web_request/web_request_time_tracker.h" #include "extensions/browser/api_activity_monitor.h" #include "extensions/browser/event_router.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/process_map.h" #include "extensions/common/api/web_request/web_request_activity_log_constants.h"
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc index baab943..f031257 100644 --- a/extensions/browser/api/web_request/web_request_api.cc +++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -28,6 +28,7 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/url_constants.h" +#include "extensions/browser/api/declarative_net_request/utils.h" #include "extensions/browser/api/web_request/extension_web_request_event_router.h" #include "extensions/browser/api/web_request/web_request_api_constants.h" #include "extensions/browser/api/web_request/web_request_api_helpers.h" @@ -240,6 +241,13 @@ request_id.request_id, std::move(callback)); } +void WebRequestAPI::ProxySet::OnDNRExtensionUnloaded( + const Extension* extension) { + for (const auto& proxy : proxies_) { + proxy->OnDNRExtensionUnloaded(extension); + } +} + WebRequestAPI::RequestIDGenerator::RequestIDGenerator() = default; WebRequestAPI::RequestIDGenerator::~RequestIDGenerator() = default; @@ -630,6 +638,10 @@ --web_request_extension_count_; UpdateMayHaveProxies(); } + + if (declarative_net_request::HasAnyDNRPermission(*extension)) { + proxies_->OnDNRExtensionUnloaded(extension); + } } void WebRequestAPI::UpdateActiveListener(
diff --git a/extensions/browser/api/web_request/web_request_api.h b/extensions/browser/api/web_request/web_request_api.h index ff85a72..ec5cc7c 100644 --- a/extensions/browser/api/web_request/web_request_api.h +++ b/extensions/browser/api/web_request/web_request_api.h
@@ -95,6 +95,11 @@ scoped_refptr<net::HttpResponseHeaders> response_headers, int32_t request_id, AuthRequestCallback callback); + + // Called when an extension that can execute declarativeNetRequest actions + // is unloaded, so orphaned DNR actions on current requests can be cleaned + // up. + virtual void OnDNRExtensionUnloaded(const Extension* extension) = 0; }; // A ProxySet is a set of proxies used by WebRequestAPI: It holds Proxy @@ -134,6 +139,8 @@ const content::GlobalRequestID& request_id, AuthRequestCallback callback); + void OnDNRExtensionUnloaded(const Extension* extension); + private: // Although these members are initialized on the UI thread, we expect at // least one memory barrier before actually calling Generate in the IO
diff --git a/extensions/browser/api/web_request/web_request_api_helpers.cc b/extensions/browser/api/web_request/web_request_api_helpers.cc index 08b8e37..89ea7a3 100644 --- a/extensions/browser/api/web_request/web_request_api_helpers.cc +++ b/extensions/browser/api/web_request/web_request_api_helpers.cc
@@ -38,7 +38,6 @@ #include "extensions/browser/api/extensions_api_client.h" #include "extensions/browser/api/web_request/web_request_api_constants.h" #include "extensions/browser/api/web_request/web_request_info.h" -#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/extensions_browser_client.h" #include "extensions/common/api/declarative_net_request.h"
diff --git a/extensions/browser/api/web_request/web_request_info.cc b/extensions/browser/api/web_request/web_request_info.cc index 3c4ba5f..c1296e13 100644 --- a/extensions/browser/api/web_request/web_request_info.cc +++ b/extensions/browser/api/web_request/web_request_info.cc
@@ -257,4 +257,15 @@ response_from_cache = response.was_fetched_via_cache; } +void WebRequestInfo::EraseDNRActionsForExtension( + const ExtensionId& extension_id) { + if (dnr_actions.has_value()) { + std::erase_if( + *dnr_actions, + [extension_id](declarative_net_request::RequestAction& action) { + return action.extension_id == extension_id; + }); + } +} + } // namespace extensions
diff --git a/extensions/browser/api/web_request/web_request_info.h b/extensions/browser/api/web_request/web_request_info.h index bcca020..c9e9c1d 100644 --- a/extensions/browser/api/web_request/web_request_info.h +++ b/extensions/browser/api/web_request/web_request_info.h
@@ -94,6 +94,10 @@ void AddResponseInfoFromResourceResponse( const network::mojom::URLResponseHead& response); + // Erases all actions in `dnr_actions` that are associated with the given + // `extension_id`. + void EraseDNRActionsForExtension(const ExtensionId& extension_id); + // A unique identifier for this request. const uint64_t id;
diff --git a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc index cece63a..0a5a1a9 100644 --- a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc +++ b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
@@ -1326,6 +1326,7 @@ std::move(callback_pair.second).Run(net::OK); } + void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnRequestError( const network::URLLoaderCompletionStatus& status, State state) { @@ -1434,6 +1435,13 @@ return status; } +void WebRequestProxyingURLLoaderFactory::InProgressRequest:: + EraseDNRActionsForExtension(const ExtensionId& extension_id) { + if (info_) { + info_->EraseDNRActionsForExtension(extension_id); + } +} + WebRequestProxyingURLLoaderFactory::WebRequestProxyingURLLoaderFactory( content::BrowserContext* browser_context, int render_process_id, @@ -1619,6 +1627,13 @@ std::move(callback)); } +void WebRequestProxyingURLLoaderFactory::OnDNRExtensionUnloaded( + const Extension* extension) { + for (auto& request : requests_) { + request.second->EraseDNRActionsForExtension(extension->id()); + } +} + WebRequestProxyingURLLoaderFactory::~WebRequestProxyingURLLoaderFactory() = default;
diff --git a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h index fd423c5..f88e9e9 100644 --- a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h +++ b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h
@@ -139,6 +139,10 @@ const net::IPEndPoint& endpoint, OnHeadersReceivedCallback callback) override; + // Erases all DNR actions in `info_` that are associated with + // `extension_id`. + void EraseDNRActionsForExtension(const ExtensionId& extension_id); + private: // The state of an InProgressRequest. This is reported via UMA and UKM // at the end of the request, so do not change enum values. @@ -348,6 +352,7 @@ scoped_refptr<net::HttpResponseHeaders> response_headers, int32_t request_id, WebRequestAPI::AuthRequestCallback callback) override; + void OnDNRExtensionUnloaded(const Extension* extension) override; content::ContentBrowserClient::URLLoaderFactoryType loader_factory_type() const {
diff --git a/extensions/browser/api/web_request/web_request_proxying_websocket.cc b/extensions/browser/api/web_request/web_request_proxying_websocket.cc index 3270bc9..75ab6bd 100644 --- a/extensions/browser/api/web_request/web_request_proxying_websocket.cc +++ b/extensions/browser/api/web_request/web_request_proxying_websocket.cc
@@ -285,6 +285,11 @@ ContinueToHeadersReceived(); } +void WebRequestProxyingWebSocket::OnDNRExtensionUnloaded( + const Extension* extension) { + info_.EraseDNRActionsForExtension(extension->id()); +} + void WebRequestProxyingWebSocket::StartProxying( WebSocketFactory factory, const GURL& url,
diff --git a/extensions/browser/api/web_request/web_request_proxying_websocket.h b/extensions/browser/api/web_request/web_request_proxying_websocket.h index 301757a4..c8b4d1c 100644 --- a/extensions/browser/api/web_request/web_request_proxying_websocket.h +++ b/extensions/browser/api/web_request/web_request_proxying_websocket.h
@@ -88,6 +88,9 @@ const net::IPEndPoint& endpoint, OnHeadersReceivedCallback callback) override; + // WebRequestAPI::Proxy: + void OnDNRExtensionUnloaded(const Extension* extension) override; + static void StartProxying( WebSocketFactory factory, const GURL& url,
diff --git a/extensions/browser/api/web_request/web_request_proxying_webtransport.cc b/extensions/browser/api/web_request/web_request_proxying_webtransport.cc index 8c3d7873..0263e4b 100644 --- a/extensions/browser/api/web_request/web_request_proxying_webtransport.cc +++ b/extensions/browser/api/web_request/web_request_proxying_webtransport.cc
@@ -238,6 +238,11 @@ } private: + // WebRequestAPI::Proxy: + void OnDNRExtensionUnloaded(const Extension* extension) override { + info_.EraseDNRActionsForExtension(extension->id()); + } + mojo::PendingRemote<WebTransportHandshakeClient> handshake_client_; // Weak reference to the ProxySet. This is safe as `proxies_` owns this // object.
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index 72722cc..ee72282 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -1474,15 +1474,16 @@ "automationInternal", std::make_unique<AutomationInternalCustomBindings>( context, bindings_system)); - delegate_->RegisterNativeHandlers(this, module_system, bindings_system, - context); + for (const auto& api_provider : api_providers_) { + api_provider->RegisterNativeHandlers(module_system, bindings_system, + context); + } } void Dispatcher::PopulateSourceMap() { const std::vector<JsResourceInfo> resources = GetJsResources(); for (const auto& resource : resources) source_map_.RegisterSource(resource.name, resource.id); - delegate_->PopulateSourceMap(&source_map_); for (const auto& api_provider : api_providers_) { api_provider->PopulateSourceMap(&source_map_); }
diff --git a/extensions/renderer/dispatcher_delegate.h b/extensions/renderer/dispatcher_delegate.h index 2ee9b7b..9b52227 100644 --- a/extensions/renderer/dispatcher_delegate.h +++ b/extensions/renderer/dispatcher_delegate.h
@@ -10,9 +10,7 @@ namespace extensions { class Dispatcher; -class ModuleSystem; class NativeExtensionBindingsSystem; -class ResourceBundleSourceMap; class ScriptContext; // Base class and default implementation for an extensions::Dispacher delegate. @@ -22,16 +20,6 @@ public: virtual ~DispatcherDelegate() {} - // Includes additional native handlers in a ScriptContext's ModuleSystem. - virtual void RegisterNativeHandlers( - Dispatcher* dispatcher, - ModuleSystem* module_system, - NativeExtensionBindingsSystem* bindings_system, - ScriptContext* context) {} - - // Includes additional source resources into the resource map. - virtual void PopulateSourceMap(ResourceBundleSourceMap* source_map) {} - // Requires modules for defining <webview> within an extension context's // module system. virtual void RequireWebViewModules(ScriptContext* context);
diff --git a/extensions/renderer/extensions_renderer_api_provider.h b/extensions/renderer/extensions_renderer_api_provider.h index 9894492d..f57c10f9c 100644 --- a/extensions/renderer/extensions_renderer_api_provider.h +++ b/extensions/renderer/extensions_renderer_api_provider.h
@@ -7,6 +7,8 @@ namespace extensions { +class ModuleSystem; +class NativeExtensionBindingsSystem; class ScriptContext; class ResourceBundleSourceMap; @@ -18,13 +20,21 @@ public: virtual ~ExtensionsRendererAPIProvider() = default; - // Blink maintains an allowlist for custom element names. This method - // provides the delegate the ability to add more names to that allowlist. - virtual void EnableCustomElementAllowlist() = 0; + // Registers any native handlers to provide additional functionality for + // native bindings. Called each time a new ScriptContext is created, since + // native handlers are per-context. + virtual void RegisterNativeHandlers( + ModuleSystem* module_system, + NativeExtensionBindingsSystem* bindings_system, + ScriptContext* context) = 0; // Includes additional source resources into the resource map. virtual void PopulateSourceMap(ResourceBundleSourceMap* source_map) = 0; + // Blink maintains an allowlist for custom element names. This method + // provides the delegate the ability to add more names to that allowlist. + virtual void EnableCustomElementAllowlist() = 0; + // Requires modules for defining WebView APIs within a ScriptContext's // ModuleSystem. virtual bool RequireWebViewModules(ScriptContext* context) = 0;
diff --git a/infra/config/generated/testing/mixins.pyl b/infra/config/generated/testing/mixins.pyl index 5c1b91b..220ad86 100644 --- a/infra/config/generated/testing/mixins.pyl +++ b/infra/config/generated/testing/mixins.pyl
@@ -247,11 +247,6 @@ }, }, }, - 'chrome-refresh-2023': { - 'args': [ - '--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh', - ], - }, 'chrome-swarming-pool': { 'swarming': { 'dimensions': {
diff --git a/infra/config/generated/testing/test_suites.pyl b/infra/config/generated/testing/test_suites.pyl index 1856283..60cf421 100644 --- a/infra/config/generated/testing/test_suites.pyl +++ b/infra/config/generated/testing/test_suites.pyl
@@ -621,7 +621,7 @@ 'chromeos_js_code_coverage_browser_tests': { 'test': 'browser_tests', 'swarming': { - 'shards': 20, + 'shards': 32, }, }, }, @@ -1718,145 +1718,6 @@ }, }, - 'cr23_linux_gtests': { - 'cr23_browser_tests': { - 'test': 'browser_tests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/cr23.linux.cr23_browser_tests.filter', - ], - 'ci_only': True, - 'swarming': { - 'shards': 20, - }, - }, - 'cr23_interactive_ui_tests': { - 'test': 'interactive_ui_tests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/cr23.linux.cr23_interactive_ui_tests.filter', - ], - 'ci_only': True, - 'swarming': { - 'shards': 10, - }, - }, - 'cr23_views_unittests': { - 'test': 'views_unittests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'ci_only': True, - }, - }, - - 'cr23_mac_gtests': { - 'cr23_browser_tests': { - 'test': 'browser_tests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/cr23.mac.cr23_browser_tests.filter', - ], - 'ci_only': True, - 'swarming': { - 'shards': 20, - }, - }, - 'cr23_interactive_ui_tests': { - 'test': 'interactive_ui_tests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/cr23.mac.cr23_interactive_ui_tests.filter', - ], - 'ci_only': True, - 'swarming': { - 'shards': 10, - }, - }, - 'cr23_views_unittests': { - 'test': 'views_unittests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'ci_only': True, - }, - }, - - 'cr23_pixel_browser_tests_gtests': { - 'cr23_pixel_browser_tests': { - 'test': 'browser_tests', - 'mixins': [ - 'skia_gold_test', - 'chrome-refresh-2023', - ], - 'args': [ - '--browser-ui-tests-verify-pixels', - '--enable-pixel-output-in-tests', - '--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter;../../testing/buildbot/filters/cr23.win.cr23_browser_tests.filter', - '--test-launcher-jobs=1', - ], - 'swarming': { - 'shards': 3, - }, - }, - 'cr23_pixel_interactive_ui_tests': { - 'test': 'interactive_ui_tests', - 'mixins': [ - 'skia_gold_test', - 'chrome-refresh-2023', - ], - 'args': [ - '--browser-ui-tests-verify-pixels', - '--enable-pixel-output-in-tests', - '--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter;../../testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter', - ], - }, - }, - - 'cr23_win_gtests': { - 'cr23_browser_tests': { - 'test': 'browser_tests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/cr23.win.cr23_browser_tests.filter', - ], - 'ci_only': True, - 'swarming': { - 'shards': 20, - }, - }, - 'cr23_interactive_ui_tests': { - 'test': 'interactive_ui_tests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter', - ], - 'ci_only': True, - 'swarming': { - 'shards': 10, - }, - }, - 'cr23_views_unittests': { - 'test': 'views_unittests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'ci_only': True, - }, - }, - 'cronet_gtests': { 'cronet_sample_test_apk': {}, 'cronet_smoketests_apk': {}, @@ -6051,22 +5912,6 @@ 'vr_platform_specific_chromium_gtests', ], - 'chromium_linux_gtests_once': [ - 'aura_gtests', - 'chromium_gtests', - 'chromium_gtests_for_devices_with_graphical_output', - 'chromium_gtests_for_linux_and_chromeos_only', - 'chromium_gtests_for_linux_and_mac_only', - 'chromium_gtests_for_linux_only', - 'chromium_gtests_for_win_and_linux_only', - 'cr23_linux_gtests', - 'linux_flavor_specific_chromium_gtests', - 'linux_specific_xr_gtests', - 'non_android_and_cast_and_chromeos_chromium_gtests', - 'non_android_chromium_gtests_no_nacl', - 'vr_platform_specific_chromium_gtests', - ], - 'chromium_linux_rel_isolated_scripts': [ 'chromedriver_py_tests_isolated_scripts', 'chromium_web_tests_high_dpi_isolated_scripts', @@ -6121,15 +5966,6 @@ 'non_android_chromium_gtests_no_nacl', ], - 'chromium_mac_gtests_no_nacl_once': [ - 'chromium_gtests', - 'chromium_gtests_for_devices_with_graphical_output', - 'cr23_mac_gtests', - 'mac_specific_chromium_gtests', - 'non_android_and_cast_and_chromeos_chromium_gtests', - 'non_android_chromium_gtests_no_nacl', - ], - 'chromium_mac_rel_isolated_scripts': [ 'chromedriver_py_tests_isolated_scripts', 'components_perftests_isolated_scripts', @@ -6167,7 +6003,6 @@ 'chromium_gtests', 'chromium_gtests_for_devices_with_graphical_output', 'chromium_gtests_for_win_and_linux_only', - 'cr23_pixel_browser_tests_gtests', 'fieldtrial_browser_tests', 'non_android_and_cast_and_chromeos_chromium_gtests', 'non_android_chromium_gtests_no_nacl', @@ -6181,22 +6016,6 @@ 'chromium_gtests_for_windows_multiscreen', ], - 'chromium_win10_gtests_once': [ - 'aura_gtests', - 'chromium_gtests', - 'chromium_gtests_for_devices_with_graphical_output', - 'chromium_gtests_for_win_and_linux_only', - 'cr23_pixel_browser_tests_gtests', - 'cr23_win_gtests', - 'fieldtrial_browser_tests', - 'non_android_and_cast_and_chromeos_chromium_gtests', - 'non_android_chromium_gtests_no_nacl', - 'non_android_chromium_gtests_skia_gold', - 'pixel_browser_tests_gtests', - 'vr_platform_specific_chromium_gtests', - 'win_specific_chromium_gtests', - ], - 'chromium_win_dbg_isolated_scripts': [ 'chromedriver_py_tests_isolated_scripts', 'components_perftests_isolated_scripts',
diff --git a/infra/config/generated/testing/variants.pyl b/infra/config/generated/testing/variants.pyl index b216ae7..8f96eb02 100644 --- a/infra/config/generated/testing/variants.pyl +++ b/infra/config/generated/testing/variants.pyl
@@ -323,16 +323,16 @@ }, 'LACROS_VERSION_SKEW_DEV': { 'identifier': 'Lacros version skew testing ash dev', - 'description': 'Run with ash-chrome version 123.0.6312.11', + 'description': 'Run with ash-chrome version 123.0.6312.18', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.11/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.18/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v123.0.6312.11', - 'revision': 'version:123.0.6312.11', + 'location': 'lacros_version_skew_tests_v123.0.6312.18', + 'revision': 'version:123.0.6312.18', }, ], },
diff --git a/infra/config/targets/basic_suites.star b/infra/config/targets/basic_suites.star index 942d35c..29fd5878 100644 --- a/infra/config/targets/basic_suites.star +++ b/infra/config/targets/basic_suites.star
@@ -631,7 +631,7 @@ tests = { "chromeos_js_code_coverage_browser_tests": targets.legacy_test_config( swarming = targets.swarming( - shards = 20, + shards = 32, ), ), }, @@ -1625,109 +1625,6 @@ }, ) -# TODO(crbug.com/1444855): Delete the cr23_{linux,mac,win}_gtest suites -# after the ChromeRefresh2023 is fully rolled out. -targets.legacy_basic_suite( - name = "cr23_linux_gtests", - tests = { - "cr23_browser_tests": targets.legacy_test_config( - args = [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.linux.cr23_browser_tests.filter", - ], - ci_only = True, - swarming = targets.swarming( - shards = 20, - ), - ), - "cr23_interactive_ui_tests": targets.legacy_test_config( - args = [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.linux.cr23_interactive_ui_tests.filter", - ], - ci_only = True, - swarming = targets.swarming( - shards = 10, - ), - ), - "cr23_views_unittests": targets.legacy_test_config( - ci_only = True, - ), - }, -) - -targets.legacy_basic_suite( - name = "cr23_mac_gtests", - tests = { - "cr23_browser_tests": targets.legacy_test_config( - args = [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.mac.cr23_browser_tests.filter", - ], - ci_only = True, - swarming = targets.swarming( - shards = 20, - ), - ), - "cr23_interactive_ui_tests": targets.legacy_test_config( - args = [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.mac.cr23_interactive_ui_tests.filter", - ], - ci_only = True, - swarming = targets.swarming( - shards = 10, - ), - ), - "cr23_views_unittests": targets.legacy_test_config( - ci_only = True, - ), - }, -) - -targets.legacy_basic_suite( - name = "cr23_pixel_browser_tests_gtests", - tests = { - "cr23_pixel_browser_tests": targets.legacy_test_config( - args = [ - "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter;../../testing/buildbot/filters/cr23.win.cr23_browser_tests.filter", - "--test-launcher-jobs=1", - ], - swarming = targets.swarming( - shards = 3, - ), - ), - "cr23_pixel_interactive_ui_tests": targets.legacy_test_config( - args = [ - "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter;../../testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter", - ], - ), - }, -) - -targets.legacy_basic_suite( - name = "cr23_win_gtests", - tests = { - "cr23_browser_tests": targets.legacy_test_config( - args = [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.win.cr23_browser_tests.filter", - ], - ci_only = True, - swarming = targets.swarming( - shards = 20, - ), - ), - "cr23_interactive_ui_tests": targets.legacy_test_config( - args = [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter", - ], - ci_only = True, - swarming = targets.swarming( - shards = 10, - ), - ), - "cr23_views_unittests": targets.legacy_test_config( - ci_only = True, - ), - }, -) - targets.legacy_basic_suite( name = "cronet_gtests", tests = {
diff --git a/infra/config/targets/compound_suites.star b/infra/config/targets/compound_suites.star index b29d016..8b94342 100644 --- a/infra/config/targets/compound_suites.star +++ b/infra/config/targets/compound_suites.star
@@ -299,8 +299,7 @@ ) # When changing something here, change chromium_linux_and_gl_gtests, -# chromium_linux_and_gl_and_vulkan_gtests, and -# chromium_linux_rel_gtests_once in the same way. +# chromium_linux_and_gl_and_vulkan_gtests in the same way. targets.legacy_compound_suite( name = "chromium_linux_gtests", basic_suites = [ @@ -319,32 +318,6 @@ ], ) -# TODO(crbug.com/1444855): This set should match chromium_linux_gtests, -# except that it also runs tests that we can afford to run only once on -# Linux machines (for now, this is just the cr23_linux_gtests). -# -# Delete this test suite after the ChromeRefresh2023 is fully rolled out -# (assuming no other test suites are being run only once) and make sure -# any bots go back to using chromium_linux_gtests. -targets.legacy_compound_suite( - name = "chromium_linux_gtests_once", - basic_suites = [ - "aura_gtests", - "chromium_gtests", - "chromium_gtests_for_devices_with_graphical_output", - "chromium_gtests_for_linux_and_chromeos_only", - "chromium_gtests_for_linux_and_mac_only", - "chromium_gtests_for_linux_only", - "chromium_gtests_for_win_and_linux_only", - "cr23_linux_gtests", - "linux_flavor_specific_chromium_gtests", - "linux_specific_xr_gtests", - "non_android_and_cast_and_chromeos_chromium_gtests", - "non_android_chromium_gtests_no_nacl", - "vr_platform_specific_chromium_gtests", - ], -) - targets.legacy_compound_suite( name = "chromium_linux_rel_isolated_scripts", basic_suites = [ @@ -409,7 +382,6 @@ ], ) -# When changing something here, change # chromium_mac_gtests_no_nacl_once in the same way. # TODO(b/303417958): This no_nacl suite is identical to the normal suite, since # NaCl has been disabled on Mac. Replace this by the normal suite. @@ -425,26 +397,6 @@ ], ) -# TODO(crbug.com/1444855): This set should match -# chromium_mac_gtests_no_nacl, except that it also runs tests that we can -# only afford to run once on Mac machines (for now, this is just the -# cr23_mac_gtests). -# -# Delete this test suite after the ChromeRefresh2023 is fully rolled out -# and make sure any bots go back to using -# chromium_mac_gtests_no_nacl_no_nocompile. -targets.legacy_compound_suite( - name = "chromium_mac_gtests_no_nacl_once", - basic_suites = [ - "chromium_gtests", - "chromium_gtests_for_devices_with_graphical_output", - "cr23_mac_gtests", - "mac_specific_chromium_gtests", - "non_android_and_cast_and_chromeos_chromium_gtests", - "non_android_chromium_gtests_no_nacl", - ], -) - targets.legacy_compound_suite( name = "chromium_mac_rel_isolated_scripts", basic_suites = [ @@ -506,7 +458,6 @@ "chromium_gtests", "chromium_gtests_for_devices_with_graphical_output", "chromium_gtests_for_win_and_linux_only", - "cr23_pixel_browser_tests_gtests", "fieldtrial_browser_tests", "non_android_and_cast_and_chromeos_chromium_gtests", "non_android_chromium_gtests_no_nacl", @@ -524,31 +475,6 @@ ], ) -# TODO(crbug.com/1444855): This set should match chromium_win10_gtests, -# except that it also runs tests that we can afford to run only once -# on Windows machines (for now this is just the cr23_win_gtests). -# -# Delete this test suite after the ChromeRefresh2023 is fully rolled out -# and make sure any bots go back to using chromium_win10_gtests. -targets.legacy_compound_suite( - name = "chromium_win10_gtests_once", - basic_suites = [ - "aura_gtests", - "chromium_gtests", - "chromium_gtests_for_devices_with_graphical_output", - "chromium_gtests_for_win_and_linux_only", - "cr23_pixel_browser_tests_gtests", - "cr23_win_gtests", - "fieldtrial_browser_tests", - "non_android_and_cast_and_chromeos_chromium_gtests", - "non_android_chromium_gtests_no_nacl", - "non_android_chromium_gtests_skia_gold", - "pixel_browser_tests_gtests", - "vr_platform_specific_chromium_gtests", - "win_specific_chromium_gtests", - ], -) - targets.legacy_compound_suite( name = "chromium_win_dbg_isolated_scripts", basic_suites = [
diff --git a/infra/config/targets/lacros-version-skew-variants.json b/infra/config/targets/lacros-version-skew-variants.json index 2c32d4f..b5438eb 100644 --- a/infra/config/targets/lacros-version-skew-variants.json +++ b/infra/config/targets/lacros-version-skew-variants.json
@@ -17,16 +17,16 @@ }, "LACROS_VERSION_SKEW_DEV": { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.11/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.18/test_ash_chrome" ], - "description": "Run with ash-chrome version 123.0.6312.11", + "description": "Run with ash-chrome version 123.0.6312.18", "identifier": "Lacros version skew testing ash dev", "swarming": { "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v123.0.6312.11", - "revision": "version:123.0.6312.11" + "location": "lacros_version_skew_tests_v123.0.6312.18", + "revision": "version:123.0.6312.18" } ] }
diff --git a/infra/config/targets/mixins.star b/infra/config/targets/mixins.star index 239bc2b2..d2cb8de 100644 --- a/infra/config/targets/mixins.star +++ b/infra/config/targets/mixins.star
@@ -296,15 +296,6 @@ ) targets.mixin( - name = "chrome-refresh-2023", - args = [ - # All features to be launched under CR2023. - # See go/chrome-cr2023-testing-on-bots - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh", - ], -) - -targets.mixin( name = "chrome-swarming-pool", swarming = targets.swarming( dimensions = {
diff --git a/infra/config/targets/tests.star b/infra/config/targets/tests.star index 255447f..d80d73e 100644 --- a/infra/config/targets/tests.star +++ b/infra/config/targets/tests.star
@@ -733,56 +733,6 @@ ) targets.tests.gtest_test( - name = "cr23_browser_tests", - mixins = [ - "chrome-refresh-2023", - ], - binary = "browser_tests", -) - -targets.tests.gtest_test( - name = "cr23_interactive_ui_tests", - mixins = [ - "chrome-refresh-2023", - ], - binary = "interactive_ui_tests", -) - -targets.tests.gtest_test( - name = "cr23_pixel_browser_tests", - mixins = [ - "skia_gold_test", - "chrome-refresh-2023", - ], - args = [ - "--browser-ui-tests-verify-pixels", - "--enable-pixel-output-in-tests", - ], - binary = "browser_tests", -) - -targets.tests.gtest_test( - name = "cr23_pixel_interactive_ui_tests", - mixins = [ - "skia_gold_test", - "chrome-refresh-2023", - ], - args = [ - "--browser-ui-tests-verify-pixels", - "--enable-pixel-output-in-tests", - ], - binary = "interactive_ui_tests", -) - -targets.tests.gtest_test( - name = "cr23_views_unittests", - mixins = [ - "chrome-refresh-2023", - ], - binary = "views_unittests", -) - -targets.tests.gtest_test( name = "crashpad_tests", )
diff --git a/internal b/internal index ee061f4..9f3d71f 160000 --- a/internal +++ b/internal
@@ -1 +1 @@ -Subproject commit ee061f481382201645e2569b5cfb8bc70f5685ef +Subproject commit 9f3d71f2b078ed96b1334c3921e47d2a2735a9c5
diff --git a/ios/components/security_interstitials/DEPS b/ios/components/security_interstitials/DEPS index 86229b8..7498868 100644 --- a/ios/components/security_interstitials/DEPS +++ b/ios/components/security_interstitials/DEPS
@@ -6,6 +6,7 @@ "+components/safe_browsing/core/common", "+components/safe_browsing/ios", "+components/security_interstitials/core", + "+components/sessions/core", "+components/sync_preferences", "+components/keyed_service/core", "+components/keyed_service/ios",
diff --git a/ios/components/security_interstitials/safe_browsing/BUILD.gn b/ios/components/security_interstitials/safe_browsing/BUILD.gn index cccba60..d743685 100644 --- a/ios/components/security_interstitials/safe_browsing/BUILD.gn +++ b/ios/components/security_interstitials/safe_browsing/BUILD.gn
@@ -41,6 +41,7 @@ "//components/safe_browsing/ios/browser:allow_list", "//components/safe_browsing/ios/browser/password_protection", "//components/security_interstitials/core:unsafe_resource", + "//components/sessions:session_id", "//ios/components/cookie_util", "//ios/components/security_interstitials/safe_browsing:util", "//ios/net",
diff --git a/ios/components/security_interstitials/safe_browsing/fake_safe_browsing_service.mm b/ios/components/security_interstitials/safe_browsing/fake_safe_browsing_service.mm index 495263a9..dc21973 100644 --- a/ios/components/security_interstitials/safe_browsing/fake_safe_browsing_service.mm +++ b/ios/components/security_interstitials/safe_browsing/fake_safe_browsing_service.mm
@@ -44,7 +44,8 @@ /*url_lookup_service_on_ui=*/nullptr, /*hash_realtime_service_on_ui=*/nullptr, safe_browsing::hash_realtime_utils::HashRealTimeSelection::kNone, - /*is_async_check=*/false) {} + /*is_async_check=*/false, + SessionID::InvalidValue()) {} ~FakeSafeBrowsingUrlCheckerImpl() override = default; // SafeBrowsingUrlCheckerImpl:
diff --git a/ios/components/security_interstitials/safe_browsing/safe_browsing_service_impl.mm b/ios/components/security_interstitials/safe_browsing/safe_browsing_service_impl.mm index 22f9edd..37ab0c54 100644 --- a/ios/components/security_interstitials/safe_browsing/safe_browsing_service_impl.mm +++ b/ios/components/security_interstitials/safe_browsing/safe_browsing_service_impl.mm
@@ -17,6 +17,7 @@ #import "components/safe_browsing/core/browser/url_checker_delegate.h" #import "components/safe_browsing/core/common/features.h" #import "components/safe_browsing/core/common/safebrowsing_constants.h" +#import "components/sessions/core/session_id.h" #import "ios/components/cookie_util/cookie_util.h" #import "ios/components/security_interstitials/safe_browsing/safe_browsing_client.h" #import "ios/components/security_interstitials/safe_browsing/url_checker_delegate_impl.h" @@ -176,12 +177,11 @@ security_interstitials::UnsafeResource::kNoFrameTreeNodeId, /*navigation_id=*/std::nullopt, can_perform_full_url_lookup, /*can_check_db=*/true, /*can_check_high_confidence_allowlist=*/true, - /*url_lookup_service_metric_suffix=*/"", - web::GetUIThreadTaskRunner({}), + /*url_lookup_service_metric_suffix=*/"", web::GetUIThreadTaskRunner({}), url_lookup_service ? url_lookup_service->GetWeakPtr() : nullptr, hash_real_time_service ? hash_real_time_service->GetWeakPtr() : nullptr, hash_real_time_selection, - /*is_async_check=*/false); + /*is_async_check=*/false, SessionID::InvalidValue()); } bool SafeBrowsingServiceImpl::CanCheckUrl(const GURL& url) const {
diff --git a/media/audio/audio_output_device_unittest.cc b/media/audio/audio_output_device_unittest.cc index 11ed572..3fb0e0e1 100644 --- a/media/audio/audio_output_device_unittest.cc +++ b/media/audio/audio_output_device_unittest.cc
@@ -293,22 +293,29 @@ StopAudioDevice(); } -// TODO(crbug.com/327577325) Re-enable this test -TEST_F(AudioOutputDeviceTest, DISABLED_ErrorFiredForSocketClose) { +TEST_F(AudioOutputDeviceTest, ErrorFiredForSocketClose) { StartAudioDevice(); CallOnStreamCreated(); + // Lock used to ensure Render() completes before CloseBrowserSocket() starts. + base::Lock send_lock_; + base::RunLoop run_loop; EXPECT_CALL(callback_, Render(_, _, _, _)) - .WillOnce(DoAll(base::test::RunClosure(base::BindLambdaForTesting( - [&]() { CloseBrowserSocket(); })), + .WillOnce(DoAll(base::test::RunClosure(base::BindLambdaForTesting([&]() { + base::AutoLock lock(send_lock_); + CloseBrowserSocket(); + })), Return(0))) .WillRepeatedly(Return(0)); EXPECT_CALL(callback_, OnRenderError()) .WillOnce(base::test::RunClosure(run_loop.QuitWhenIdleClosure())); - Render(); + { + base::AutoLock lock(send_lock_); + Render(); + } run_loop.Run(); StopAudioDevice();
diff --git a/printing/test_printing_context.cc b/printing/test_printing_context.cc index 2b6202d..0d09e99 100644 --- a/printing/test_printing_context.cc +++ b/printing/test_printing_context.cc
@@ -160,7 +160,22 @@ std::unique_ptr<PrintSettings> existing_settings = std::move(settings_); settings_ = std::make_unique<PrintSettings>(*found->second); settings_->set_copies(existing_settings->copies()); - settings_->set_dpi(existing_settings->dpi()); + // Client-supplied settings take priority over default device settings; try to + // transfer the non-empty ones. + if (existing_settings->color() != mojom::ColorModel::kUnknownColorModel) { + settings_->set_color(existing_settings->color()); + } + settings_->set_collate(existing_settings->collate()); + if (!existing_settings->dpi_size().IsEmpty()) { + settings_->set_dpi_xy(existing_settings->dpi_horizontal(), + existing_settings->dpi_vertical()); + } + if (!existing_settings->title().empty()) { + settings_->set_title(existing_settings->title()); + } + if (!existing_settings->requested_media().IsDefault()) { + settings_->set_requested_media(existing_settings->requested_media()); + } #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) for (const auto& item : existing_settings->advanced_settings()) settings_->advanced_settings().emplace(item.first, item.second.Clone());
diff --git a/testing/buildbot/chromium.cft.json b/testing/buildbot/chromium.cft.json index 3b5d2bec..b44cdcf 100644 --- a/testing/buildbot/chromium.cft.json +++ b/testing/buildbot/chromium.cft.json
@@ -5834,34 +5834,6 @@ "test_id_prefix": "ninja://courgette:courgette_unittests/" }, { - "args": [ - "--browser-ui-tests-verify-pixels", - "--enable-pixel-output-in-tests", - "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter;../../testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter", - "--git-revision=${got_revision}", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_pixel_interactive_ui_tests", - "precommit_args": [ - "--gerrit-issue=${patch_issue}", - "--gerrit-patchset=${patch_set}", - "--buildbucket-id=${buildbucket_build_id}" - ], - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Windows-10-19045" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" - }, - { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 66e1909..c4e041c 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5407,9 +5407,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_v123.0.6312.11/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.18/test_ash_chrome" ], - "description": "Run with ash-chrome version 123.0.6312.11", + "description": "Run with ash-chrome version 123.0.6312.18", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5419,8 +5419,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v123.0.6312.11", - "revision": "version:123.0.6312.11" + "location": "lacros_version_skew_tests_v123.0.6312.18", + "revision": "version:123.0.6312.18" } ], "dimensions": { @@ -5563,9 +5563,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.11/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.18/test_ash_chrome" ], - "description": "Run with ash-chrome version 123.0.6312.11", + "description": "Run with ash-chrome version 123.0.6312.18", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5575,8 +5575,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v123.0.6312.11", - "revision": "version:123.0.6312.11" + "location": "lacros_version_skew_tests_v123.0.6312.18", + "revision": "version:123.0.6312.18" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index 3d0db5c..04cba4c 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -8329,7 +8329,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 20 + "shards": 32 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/" @@ -20342,9 +20342,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_v123.0.6312.11/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.18/test_ash_chrome" ], - "description": "Run with ash-chrome version 123.0.6312.11", + "description": "Run with ash-chrome version 123.0.6312.18", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -20354,8 +20354,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v123.0.6312.11", - "revision": "version:123.0.6312.11" + "location": "lacros_version_skew_tests_v123.0.6312.18", + "revision": "version:123.0.6312.18" } ], "dimensions": { @@ -20492,9 +20492,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.11/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.18/test_ash_chrome" ], - "description": "Run with ash-chrome version 123.0.6312.11", + "description": "Run with ash-chrome version 123.0.6312.18", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -20504,8 +20504,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v123.0.6312.11", - "revision": "version:123.0.6312.11" + "location": "lacros_version_skew_tests_v123.0.6312.18", + "revision": "version:123.0.6312.18" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index e8dc81a..e8fc9c2 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -40010,9 +40010,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_v123.0.6312.11/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.18/test_ash_chrome" ], - "description": "Run with ash-chrome version 123.0.6312.11", + "description": "Run with ash-chrome version 123.0.6312.18", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -40021,8 +40021,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v123.0.6312.11", - "revision": "version:123.0.6312.11" + "location": "lacros_version_skew_tests_v123.0.6312.18", + "revision": "version:123.0.6312.18" } ], "dimensions": { @@ -40160,9 +40160,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.11/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.18/test_ash_chrome" ], - "description": "Run with ash-chrome version 123.0.6312.11", + "description": "Run with ash-chrome version 123.0.6312.18", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -40171,8 +40171,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v123.0.6312.11", - "revision": "version:123.0.6312.11" + "location": "lacros_version_skew_tests_v123.0.6312.18", + "revision": "version:123.0.6312.18" } ], "dimensions": { @@ -41510,9 +41510,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_v123.0.6312.11/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.18/test_ash_chrome" ], - "description": "Run with ash-chrome version 123.0.6312.11", + "description": "Run with ash-chrome version 123.0.6312.18", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -41522,8 +41522,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v123.0.6312.11", - "revision": "version:123.0.6312.11" + "location": "lacros_version_skew_tests_v123.0.6312.18", + "revision": "version:123.0.6312.18" } ], "dimensions": { @@ -41666,9 +41666,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.11/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.18/test_ash_chrome" ], - "description": "Run with ash-chrome version 123.0.6312.11", + "description": "Run with ash-chrome version 123.0.6312.18", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -41678,8 +41678,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v123.0.6312.11", - "revision": "version:123.0.6312.11" + "location": "lacros_version_skew_tests_v123.0.6312.18", + "revision": "version:123.0.6312.18" } ], "dimensions": { @@ -42990,9 +42990,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_v123.0.6312.11/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.18/test_ash_chrome" ], - "description": "Run with ash-chrome version 123.0.6312.11", + "description": "Run with ash-chrome version 123.0.6312.18", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43001,8 +43001,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v123.0.6312.11", - "revision": "version:123.0.6312.11" + "location": "lacros_version_skew_tests_v123.0.6312.18", + "revision": "version:123.0.6312.18" } ], "dimensions": { @@ -43140,9 +43140,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.11/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.18/test_ash_chrome" ], - "description": "Run with ash-chrome version 123.0.6312.11", + "description": "Run with ash-chrome version 123.0.6312.18", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43151,8 +43151,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v123.0.6312.11", - "revision": "version:123.0.6312.11" + "location": "lacros_version_skew_tests_v123.0.6312.18", + "revision": "version:123.0.6312.18" } ], "dimensions": { @@ -49067,68 +49067,6 @@ "test_id_prefix": "ninja://courgette:courgette_unittests/" }, { - "args": [ - "--browser-ui-tests-verify-pixels", - "--enable-pixel-output-in-tests", - "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter;../../testing/buildbot/filters/cr23.win.cr23_browser_tests.filter", - "--test-launcher-jobs=1", - "--git-revision=${got_revision}", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_pixel_browser_tests", - "precommit_args": [ - "--gerrit-issue=${patch_issue}", - "--gerrit-patchset=${patch_set}", - "--buildbucket-id=${buildbucket_build_id}" - ], - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Windows-10-19045", - "pool": "chromium.tests.no-external-ip" - }, - "expiration": 43200, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ - "--browser-ui-tests-verify-pixels", - "--enable-pixel-output-in-tests", - "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter;../../testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter", - "--git-revision=${got_revision}", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_pixel_interactive_ui_tests", - "precommit_args": [ - "--gerrit-issue=${patch_issue}", - "--gerrit-patchset=${patch_set}", - "--buildbucket-id=${buildbucket_build_id}" - ], - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Windows-10-19045", - "pool": "chromium.tests.no-external-ip" - }, - "expiration": 43200, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" - }, - { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index 7142a85..9e63977 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -1261,67 +1261,6 @@ "test_id_prefix": "ninja://content/test:content_unittests/" }, { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.linux.cr23_browser_tests.filter", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "ci_only": true, - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_browser_tests", - "swarming": { - "dimensions": { - "os": "Ubuntu-22.04" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 20 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.linux.cr23_interactive_ui_tests.filter", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "ci_only": true, - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_interactive_ui_tests", - "swarming": { - "dimensions": { - "os": "Ubuntu-22.04" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 10 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" - }, - { - "args": [ - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "ci_only": true, - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_views_unittests", - "swarming": { - "dimensions": { - "os": "Ubuntu-22.04" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "views_unittests", - "test_id_prefix": "ninja://ui/views:views_unittests/" - }, - { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index 603c20c6..78cbab9b 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -5120,70 +5120,6 @@ "test_id_prefix": "ninja://content/test:content_unittests/" }, { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.mac.cr23_browser_tests.filter", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "ci_only": true, - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_browser_tests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Mac-13" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 20 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.mac.cr23_interactive_ui_tests.filter", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "ci_only": true, - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_interactive_ui_tests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Mac-13" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 10 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" - }, - { - "args": [ - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "ci_only": true, - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_views_unittests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Mac-13" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "views_unittests", - "test_id_prefix": "ninja://ui/views:views_unittests/" - }, - { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5687,6 +5623,22 @@ "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, + "name": "openscreen_unittests", + "swarming": { + "dimensions": { + "cpu": "x86-64", + "os": "Mac-13" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "openscreen_unittests", + "test_id_prefix": "ninja://chrome/browser/media/router:openscreen_unittests/" + }, + { + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, "name": "pdf_unittests", "swarming": { "dimensions": {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 8d80c96..5cb05e5 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -16376,12 +16376,12 @@ { "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_v123.0.6312.11/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.18/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 123.0.6312.11", + "description": "Run with ash-chrome version 123.0.6312.18", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16391,8 +16391,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v123.0.6312.11", - "revision": "version:123.0.6312.11" + "location": "lacros_version_skew_tests_v123.0.6312.18", + "revision": "version:123.0.6312.18" } ], "dimensions": { @@ -16552,12 +16552,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.11/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.18/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 123.0.6312.11", + "description": "Run with ash-chrome version 123.0.6312.18", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16567,8 +16567,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v123.0.6312.11", - "revision": "version:123.0.6312.11" + "location": "lacros_version_skew_tests_v123.0.6312.18", + "revision": "version:123.0.6312.18" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json index 046e08a..a3e90d086 100644 --- a/testing/buildbot/chromium.win.json +++ b/testing/buildbot/chromium.win.json
@@ -577,128 +577,6 @@ "test_id_prefix": "ninja://courgette:courgette_unittests/" }, { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.win.cr23_browser_tests.filter", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "ci_only": true, - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_browser_tests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Windows-10-19045" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 20 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "ci_only": true, - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_interactive_ui_tests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Windows-10-19045" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 10 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" - }, - { - "args": [ - "--browser-ui-tests-verify-pixels", - "--enable-pixel-output-in-tests", - "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter;../../testing/buildbot/filters/cr23.win.cr23_browser_tests.filter", - "--test-launcher-jobs=1", - "--git-revision=${got_revision}", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_pixel_browser_tests", - "precommit_args": [ - "--gerrit-issue=${patch_issue}", - "--gerrit-patchset=${patch_set}", - "--buildbucket-id=${buildbucket_build_id}" - ], - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Windows-10-19045" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ - "--browser-ui-tests-verify-pixels", - "--enable-pixel-output-in-tests", - "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter;../../testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter", - "--git-revision=${got_revision}", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_pixel_interactive_ui_tests", - "precommit_args": [ - "--gerrit-issue=${patch_issue}", - "--gerrit-patchset=${patch_set}", - "--buildbucket-id=${buildbucket_build_id}" - ], - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Windows-10-19045" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" - }, - { - "args": [ - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "ci_only": true, - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_views_unittests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Windows-10-19045" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "views_unittests", - "test_id_prefix": "ninja://ui/views:views_unittests/" - }, - { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4364,34 +4242,6 @@ "test_id_prefix": "ninja://courgette:courgette_unittests/" }, { - "args": [ - "--browser-ui-tests-verify-pixels", - "--enable-pixel-output-in-tests", - "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter;../../testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter", - "--git-revision=${got_revision}", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_pixel_interactive_ui_tests", - "precommit_args": [ - "--gerrit-issue=${patch_issue}", - "--gerrit-patchset=${patch_set}", - "--buildbucket-id=${buildbucket_build_id}" - ], - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Windows-11-22000" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" - }, - { "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -8041,34 +7891,6 @@ "test_id_prefix": "ninja://courgette:courgette_unittests/" }, { - "args": [ - "--browser-ui-tests-verify-pixels", - "--enable-pixel-output-in-tests", - "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter;../../testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter", - "--git-revision=${got_revision}", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_pixel_interactive_ui_tests", - "precommit_args": [ - "--gerrit-issue=${patch_issue}", - "--gerrit-patchset=${patch_set}", - "--buildbucket-id=${buildbucket_build_id}" - ], - "swarming": { - "dimensions": { - "cpu": "arm64", - "os": "Windows-11", - "screen_scaling_percent": "100" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" - }, - { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" },
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index 1df98acb..b723b35 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -56,12 +56,6 @@ data = [ "//testing/buildbot/filters/cft.blink_web_tests.filter" ] } -source_set("cr23_pixel_browser_tests_filters") { - testonly = true - - data = [ "//testing/buildbot/filters/win.win-rel-cft.cr23_pixel_browser_tests.filter" ] -} - source_set("browser_tests_filters") { testonly = true @@ -71,9 +65,6 @@ "//testing/buildbot/filters/chromeos.msan.browser_tests.oobe_negative.filter", "//testing/buildbot/filters/chromeos.msan.browser_tests.oobe_positive.filter", "//testing/buildbot/filters/code_coverage.browser_tests.filter", - "//testing/buildbot/filters/cr23.linux.cr23_browser_tests.filter", - "//testing/buildbot/filters/cr23.mac.cr23_browser_tests.filter", - "//testing/buildbot/filters/cr23.win.cr23_browser_tests.filter", "//testing/buildbot/filters/fuchsia.browser_tests.filter", "//testing/buildbot/filters/linux-chromeos.browser_tests.pixel_tests.filter", "//testing/buildbot/filters/linux-chromeos.browser_tests.require_lacros.filter", @@ -349,9 +340,6 @@ data = [ "//testing/buildbot/filters/accessibility-linux.interactive_ui_tests.filter", - "//testing/buildbot/filters/cr23.linux.cr23_interactive_ui_tests.filter", - "//testing/buildbot/filters/cr23.mac.cr23_interactive_ui_tests.filter", - "//testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter", "//testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", "//testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", "//testing/buildbot/filters/linux.linux-rel-cft.interactive_ui_tests.filter",
diff --git a/testing/buildbot/filters/cr23.linux.cr23_browser_tests.filter b/testing/buildbot/filters/cr23.linux.cr23_browser_tests.filter deleted file mode 100644 index 0009af06..0000000 --- a/testing/buildbot/filters/cr23.linux.cr23_browser_tests.filter +++ /dev/null
@@ -1 +0,0 @@ -# cr23_browser_tests that are expected to fail on linux bots:
diff --git a/testing/buildbot/filters/cr23.linux.cr23_interactive_ui_tests.filter b/testing/buildbot/filters/cr23.linux.cr23_interactive_ui_tests.filter deleted file mode 100644 index 89b6c43..0000000 --- a/testing/buildbot/filters/cr23.linux.cr23_interactive_ui_tests.filter +++ /dev/null
@@ -1,5 +0,0 @@ -# cr23_interactive_ui_tests that are expected to fail on linux bots: --PermissionsFlowInteractiveUITest.CameraActivityIndicatorTest --PermissionsFlowInteractiveUITest.CameraAndMicrophoneActivityIndicatorTest --PermissionsFlowInteractiveUITest.MicrophoneActivityIndicatorTest --PriceTrackingIconViewInteractiveTest.EnablePriceTrackOnPress
diff --git a/testing/buildbot/filters/cr23.mac.cr23_browser_tests.filter b/testing/buildbot/filters/cr23.mac.cr23_browser_tests.filter deleted file mode 100644 index 9951351..0000000 --- a/testing/buildbot/filters/cr23.mac.cr23_browser_tests.filter +++ /dev/null
@@ -1 +0,0 @@ -# cr23_browser_tests that are expected to fail on mac bots:
diff --git a/testing/buildbot/filters/cr23.mac.cr23_interactive_ui_tests.filter b/testing/buildbot/filters/cr23.mac.cr23_interactive_ui_tests.filter deleted file mode 100644 index 765cb5f..0000000 --- a/testing/buildbot/filters/cr23.mac.cr23_interactive_ui_tests.filter +++ /dev/null
@@ -1,8 +0,0 @@ -# cr23_interactive_ui_tests that are expected to fail on mac bots: --PermissionsFlowInteractiveUITest.CameraActivityIndicatorTest --PermissionsFlowInteractiveUITest.CameraAndMicrophoneActivityIndicatorTest --PermissionsFlowInteractiveUITest.MicrophoneActivityIndicatorTest --PriceTrackingIconViewInteractiveTest.EnablePriceTrackOnPress - -# This may be a flaky failure unrelated to the cr23 code paths. --SitePerProcessInteractivePDFTest.ContextMenuPositionForEmbeddedPDFInCrossOriginFrame
diff --git a/testing/buildbot/filters/cr23.win.cr23_browser_tests.filter b/testing/buildbot/filters/cr23.win.cr23_browser_tests.filter deleted file mode 100644 index 4607693..0000000 --- a/testing/buildbot/filters/cr23.win.cr23_browser_tests.filter +++ /dev/null
@@ -1 +0,0 @@ -# cr23_browser_tests that are expected to fail on win bots:
diff --git a/testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter b/testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter deleted file mode 100644 index 4a9ea9d..0000000 --- a/testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter +++ /dev/null
@@ -1,5 +0,0 @@ -# cr2023_interactive_ui_tests that are expected to fail on win bots: --PermissionsFlowInteractiveUITest.CameraActivityIndicatorTest --PermissionsFlowInteractiveUITest.CameraAndMicrophoneActivityIndicatorTest --PermissionsFlowInteractiveUITest.MicrophoneActivityIndicatorTest --PriceTrackingIconViewInteractiveTest.EnablePriceTrackOnPress
diff --git a/testing/buildbot/filters/win.win-rel-cft.cr23_pixel_browser_tests.filter b/testing/buildbot/filters/win.win-rel-cft.cr23_pixel_browser_tests.filter deleted file mode 100644 index 7685f8f..0000000 --- a/testing/buildbot/filters/win.win-rel-cft.cr23_pixel_browser_tests.filter +++ /dev/null
@@ -1,9 +0,0 @@ -# https://ci.chromium.org/ui/p/chromium/builders/try/win-rel-cft/185 --All/PasswordGenerationPopupViewBrowsertest.* --All/PopupViewViewsBrowsertest* --InfoBarUiTest.* --InteractionTestUtilBrowserTest.CompareScreenshot_WebPage - -# https://ci.chromium.org/ui/p/chromium/builders/ci/win-rel-cft/3427/ --PageInfoBubbleViewCookiesSubpageBrowserTest.* --PageInfoBubbleViewDialogBrowserTest.*
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index 5c1b91b..220ad86 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -247,11 +247,6 @@ }, }, }, - 'chrome-refresh-2023': { - 'args': [ - '--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape,IPH_DesktopCustomizeChromeRefresh', - ], - }, 'chrome-swarming-pool': { 'swarming': { 'dimensions': {
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 281d0c6..622e241 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -2366,25 +2366,6 @@ 'Android FYI Release (Pixel 2)', ], }, - 'cr23_pixel_browser_tests': { - # This target should be removed from any CI only builders. Developers can - # intentionally make UI changes. Without running pixel tests on CQ, those - # cls will get wrongly reverted by sheriffs. - # When we switch CQ builders(e.g. use Win11 to replace Win10), we also - # need to update this field. - 'remove_from': [ - 'Win11 Tests x64', - 'win-rel-cft', - 'win11-arm64-rel-tests', - ], - 'modifications': { - 'win-rel-cft': { - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/win.win-rel-cft.cr23_pixel_browser_tests.filter', - ], - }, - }, - }, 'crashpad_tests': { 'remove_from': [ 'linux-win_cross-rel', # https://crbug.com/762167
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 1856283..60cf421 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -621,7 +621,7 @@ 'chromeos_js_code_coverage_browser_tests': { 'test': 'browser_tests', 'swarming': { - 'shards': 20, + 'shards': 32, }, }, }, @@ -1718,145 +1718,6 @@ }, }, - 'cr23_linux_gtests': { - 'cr23_browser_tests': { - 'test': 'browser_tests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/cr23.linux.cr23_browser_tests.filter', - ], - 'ci_only': True, - 'swarming': { - 'shards': 20, - }, - }, - 'cr23_interactive_ui_tests': { - 'test': 'interactive_ui_tests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/cr23.linux.cr23_interactive_ui_tests.filter', - ], - 'ci_only': True, - 'swarming': { - 'shards': 10, - }, - }, - 'cr23_views_unittests': { - 'test': 'views_unittests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'ci_only': True, - }, - }, - - 'cr23_mac_gtests': { - 'cr23_browser_tests': { - 'test': 'browser_tests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/cr23.mac.cr23_browser_tests.filter', - ], - 'ci_only': True, - 'swarming': { - 'shards': 20, - }, - }, - 'cr23_interactive_ui_tests': { - 'test': 'interactive_ui_tests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/cr23.mac.cr23_interactive_ui_tests.filter', - ], - 'ci_only': True, - 'swarming': { - 'shards': 10, - }, - }, - 'cr23_views_unittests': { - 'test': 'views_unittests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'ci_only': True, - }, - }, - - 'cr23_pixel_browser_tests_gtests': { - 'cr23_pixel_browser_tests': { - 'test': 'browser_tests', - 'mixins': [ - 'skia_gold_test', - 'chrome-refresh-2023', - ], - 'args': [ - '--browser-ui-tests-verify-pixels', - '--enable-pixel-output-in-tests', - '--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter;../../testing/buildbot/filters/cr23.win.cr23_browser_tests.filter', - '--test-launcher-jobs=1', - ], - 'swarming': { - 'shards': 3, - }, - }, - 'cr23_pixel_interactive_ui_tests': { - 'test': 'interactive_ui_tests', - 'mixins': [ - 'skia_gold_test', - 'chrome-refresh-2023', - ], - 'args': [ - '--browser-ui-tests-verify-pixels', - '--enable-pixel-output-in-tests', - '--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter;../../testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter', - ], - }, - }, - - 'cr23_win_gtests': { - 'cr23_browser_tests': { - 'test': 'browser_tests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/cr23.win.cr23_browser_tests.filter', - ], - 'ci_only': True, - 'swarming': { - 'shards': 20, - }, - }, - 'cr23_interactive_ui_tests': { - 'test': 'interactive_ui_tests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter', - ], - 'ci_only': True, - 'swarming': { - 'shards': 10, - }, - }, - 'cr23_views_unittests': { - 'test': 'views_unittests', - 'mixins': [ - 'chrome-refresh-2023', - ], - 'ci_only': True, - }, - }, - 'cronet_gtests': { 'cronet_sample_test_apk': {}, 'cronet_smoketests_apk': {}, @@ -6051,22 +5912,6 @@ 'vr_platform_specific_chromium_gtests', ], - 'chromium_linux_gtests_once': [ - 'aura_gtests', - 'chromium_gtests', - 'chromium_gtests_for_devices_with_graphical_output', - 'chromium_gtests_for_linux_and_chromeos_only', - 'chromium_gtests_for_linux_and_mac_only', - 'chromium_gtests_for_linux_only', - 'chromium_gtests_for_win_and_linux_only', - 'cr23_linux_gtests', - 'linux_flavor_specific_chromium_gtests', - 'linux_specific_xr_gtests', - 'non_android_and_cast_and_chromeos_chromium_gtests', - 'non_android_chromium_gtests_no_nacl', - 'vr_platform_specific_chromium_gtests', - ], - 'chromium_linux_rel_isolated_scripts': [ 'chromedriver_py_tests_isolated_scripts', 'chromium_web_tests_high_dpi_isolated_scripts', @@ -6121,15 +5966,6 @@ 'non_android_chromium_gtests_no_nacl', ], - 'chromium_mac_gtests_no_nacl_once': [ - 'chromium_gtests', - 'chromium_gtests_for_devices_with_graphical_output', - 'cr23_mac_gtests', - 'mac_specific_chromium_gtests', - 'non_android_and_cast_and_chromeos_chromium_gtests', - 'non_android_chromium_gtests_no_nacl', - ], - 'chromium_mac_rel_isolated_scripts': [ 'chromedriver_py_tests_isolated_scripts', 'components_perftests_isolated_scripts', @@ -6167,7 +6003,6 @@ 'chromium_gtests', 'chromium_gtests_for_devices_with_graphical_output', 'chromium_gtests_for_win_and_linux_only', - 'cr23_pixel_browser_tests_gtests', 'fieldtrial_browser_tests', 'non_android_and_cast_and_chromeos_chromium_gtests', 'non_android_chromium_gtests_no_nacl', @@ -6181,22 +6016,6 @@ 'chromium_gtests_for_windows_multiscreen', ], - 'chromium_win10_gtests_once': [ - 'aura_gtests', - 'chromium_gtests', - 'chromium_gtests_for_devices_with_graphical_output', - 'chromium_gtests_for_win_and_linux_only', - 'cr23_pixel_browser_tests_gtests', - 'cr23_win_gtests', - 'fieldtrial_browser_tests', - 'non_android_and_cast_and_chromeos_chromium_gtests', - 'non_android_chromium_gtests_no_nacl', - 'non_android_chromium_gtests_skia_gold', - 'pixel_browser_tests_gtests', - 'vr_platform_specific_chromium_gtests', - 'win_specific_chromium_gtests', - ], - 'chromium_win_dbg_isolated_scripts': [ 'chromedriver_py_tests_isolated_scripts', 'components_perftests_isolated_scripts',
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index b216ae7..8f96eb02 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -323,16 +323,16 @@ }, 'LACROS_VERSION_SKEW_DEV': { 'identifier': 'Lacros version skew testing ash dev', - 'description': 'Run with ash-chrome version 123.0.6312.11', + 'description': 'Run with ash-chrome version 123.0.6312.18', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.11/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v123.0.6312.18/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v123.0.6312.11', - 'revision': 'version:123.0.6312.11', + 'location': 'lacros_version_skew_tests_v123.0.6312.18', + 'revision': 'version:123.0.6312.18', }, ], },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 3b5a303..c0d2f53 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -4754,10 +4754,7 @@ 'linux-jammy', ], 'test_suites': { - # TODO(crbug.com/1444855): Switch this back to - # 'chromium_linux_gtests' after the ChromeRefresh2023 - # is fully rolled out. - 'gtest_tests': 'chromium_linux_gtests_once', + 'gtest_tests': 'chromium_linux_gtests', 'isolated_scripts': 'chromium_linux_rel_isolated_scripts_once', }, }, @@ -4877,10 +4874,7 @@ 'isolate_profile_data', ], 'test_suites': { - # TODO(crbug.com/1444855): Switch this back to - # 'chromium_mac_gtests_no_nacl' after the ChromeRefresh2023 is fully - # rolled out. - 'gtest_tests': 'chromium_mac_gtests_no_nacl_once', + 'gtest_tests': 'chromium_mac_gtests_no_nacl', 'isolated_scripts': 'chromium_mac_rel_isolated_scripts_once', }, }, @@ -6127,10 +6121,7 @@ 'isolate_profile_data', ], 'test_suites': { - # TODO(crbug.com/1444855): Switch this back to - # 'chromium_win10_gtests' after the - # ChromeRefresh2023 is fully rolled out. - 'gtest_tests': 'chromium_win10_gtests_once', + 'gtest_tests': 'chromium_win10_gtests', 'isolated_scripts': 'chromium_win_rel_isolated_scripts_once', }, },
diff --git a/testing/libfuzzer/reproducing.md b/testing/libfuzzer/reproducing.md index c9bc1e4..34436ea 100644 --- a/testing/libfuzzer/reproducing.md +++ b/testing/libfuzzer/reproducing.md
@@ -46,7 +46,7 @@ ClusterFuzz: ``` -export ASAN_OPTIONS=redzone=256:print_summary=1:handle_sigill=1:allocator_release_to_os_interval_ms=500:print_suppressions=0:strict_memcmp=1:allow_user_segv_handler=0:use_sigaltstack=1:handle_sigfpe=1:handle_sigbus=1:detect_stack_use_after_return=0:alloc_dealloc_mismatch=0:detect_leaks=0:print_scariness=1:allocator_may_return_null=1:handle_abort=1:check_malloc_usable_size=0:detect_container_overflow=0:quarantine_size_mb=256:detect_odr_violation=0:symbolize=1:handle_segv=1:fast_unwind_on_fatal=1 +export ASAN_OPTIONS=redzone=256:print_summary=1:handle_sigill=1:allocator_release_to_os_interval_ms=500:print_suppressions=0:strict_memcmp=1:allow_user_segv_handler=0:use_sigaltstack=1:handle_sigfpe=1:handle_sigbus=1:detect_stack_use_after_return=0:alloc_dealloc_mismatch=0:detect_leaks=0:print_scariness=1:allocator_may_return_null=1:handle_abort=1:check_malloc_usable_size=0:detect_container_overflow=0:quarantine_size_mb=256:detect_odr_violation=0:symbolize=1:handle_segv=1:fast_unwind_on_fatal=0 ``` 5. Run the fuzz target:
diff --git a/third_party/angle b/third_party/angle index 69f5e9ca..1ceddbf 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit 69f5e9ca60cd6adfecd9eb8c969beeec30a4813d +Subproject commit 1ceddbf6977926d674c0c5a78b398f684d0052b1
diff --git a/third_party/blink/perf_tests/accessibility/location-changes-css-animation.html b/third_party/blink/perf_tests/accessibility/location-changes-css-animation.html new file mode 100644 index 0000000..1797f4e --- /dev/null +++ b/third_party/blink/perf_tests/accessibility/location-changes-css-animation.html
@@ -0,0 +1,114 @@ +<!DOCTYPE html> +<html> +<body> +<script src="../resources/runner.js"></script> + +<style> + .root { + width: 100%; + padding: 5px; + position: absolute; + transform: translate(0,0); + transition: transform 2s; + } + .child { + border: 1px solid black; + height: 10px; + width: 10px; + margin: -1px; + display: inline-block; + } + + #root1.end { + transform: translateX(500px); + } + + #root2.end { + transform: translateY(500px); + } +</style> + +<div id="container"></div> + +<script> +let isDone = false; +let startTime; + +function runTest() { + if (startTime) { + PerfTestRunner.measureValueAsync(PerfTestRunner.now() - startTime); + PerfTestRunner.addRunTestEndMarker(); + } + + if (!document.querySelector('#root1')) { + generateAllContent(); + } + + if (!isDone) { + PerfTestRunner.addRunTestStartMarker(); + startTime = PerfTestRunner.now(); + + setTimeout(animateRoots, 0); + setTimeout(runTest, 2500); + } +} + +function animateRoots() { + document.querySelector('#root1').classList.toggle('end'); + document.querySelector('#root2').classList.toggle('end'); +} + +function generateAllContent() { + const root1 = container.appendChild(document.createElement('div')); + root1.id = 'root1'; + root1.className = 'root'; + + const root2 = container.appendChild(document.createElement('div')); + root2.id = 'root2'; + root2.className = 'root'; + + for (let i = 0; i < 17; i++) { + const child1 = generateNodes(100, "blue"); + root1.appendChild(child1); + const child2 = generateNodes(100, "green"); + root2.appendChild(child2); + } +} + +// Recursively add layers of descendants. +function generateNodes(depth, color) { + if (depth === 0) + return; + + const node = document.createElement("div"); + node.className = "child"; + node.style.backgroundColor = color; + node.setAttribute("tabindex", 0); + depth--; + const child = generateNodes(depth, color); + if(child) { + node.appendChild(child); + } + return node; +} + +PerfTestRunner.startMeasureValuesAsync({ + description: 'Test accessibility performance when animating many nodes', + unit: 'ms', + done: function () { + isDone = true; + }, + run: function() { + runTest(); + }, + iterationCount: 6, + tracingCategories: 'accessibility', + traceEventsToMeasure: [ + 'BrowserAccessibilityManager::OnAccessibilityEvents', + 'ProcessDeferredAccessibilityEvents', + 'RenderAccessibilityImpl::SendPendingAccessibilityEvents', + ] +}); +</script> + +</html>
diff --git a/third_party/blink/perf_tests/accessibility/location-changes-js-animation.html b/third_party/blink/perf_tests/accessibility/location-changes-js-animation.html new file mode 100644 index 0000000..b972719 --- /dev/null +++ b/third_party/blink/perf_tests/accessibility/location-changes-js-animation.html
@@ -0,0 +1,108 @@ +<!DOCTYPE html> +<html> +<body> +<script src="../resources/runner.js"></script> + +<style> + .root { + width: 100%; + padding: 5px; + position: absolute; + } + .child { + border: 1px solid black; + height: 10px; + width: 10px; + margin: -1px; + display: inline-block; + } +</style> + +<div id="container"></div> + +<script> +let isDone = false; +let startTime; +let animateTimes; + +function runTest() { + if (startTime) { + PerfTestRunner.measureValueAsync(PerfTestRunner.now() - startTime); + PerfTestRunner.addRunTestEndMarker(); + } + if (!isDone) { + PerfTestRunner.addRunTestStartMarker(); + startTime = PerfTestRunner.now(); + + container.innerHTML = ''; + + generateAllContent(); + + animateTimes = 0; + animateRoots(); + setTimeout(runTest, 2500); + } +} + +function animateRoots() { + if (++ animateTimes < 500) { + document.querySelector('#root1').style.top = animateTimes +'px'; + document.querySelector('#root2').style.left = animateTimes +'px'; + requestAnimationFrame(animateRoots); + } +} + +function generateAllContent() { + const root1 = container.appendChild(document.createElement('div')); + root1.id = 'root1'; + root1.className = 'root'; + + const root2 = container.appendChild(document.createElement('div')); + root2.id = 'root2'; + root2.className = 'root'; + + for (let i = 0; i < 17; i++) { + const child1 = generateNodes(100, "blue"); + root1.appendChild(child1); + const child2 = generateNodes(100, "green"); + root2.appendChild(child2); + } +} + +// Recursively add layers of descendants. +function generateNodes(depth, color) { + if (depth === 0) + return; + + const node = document.createElement("div"); + node.className = "child"; + node.style.backgroundColor = color; + node.setAttribute("tabindex", 0); + depth--; + const child = generateNodes(depth, color); + if(child) { + node.appendChild(child); + } + return node; +} + +PerfTestRunner.startMeasureValuesAsync({ + description: 'Test accessibility performance when animating many nodes', + unit: 'ms', + done: function () { + isDone = true; + }, + run: function() { + runTest(); + }, + iterationCount: 6, + tracingCategories: 'accessibility', + traceEventsToMeasure: [ + 'BrowserAccessibilityManager::OnAccessibilityEvents', + 'ProcessDeferredAccessibilityEvents', + 'RenderAccessibilityImpl::SendPendingAccessibilityEvents', + ] +}); +</script> + +</html>
diff --git a/third_party/blink/perf_tests/accessibility/location-changes-scrolling.html b/third_party/blink/perf_tests/accessibility/location-changes-scrolling.html new file mode 100644 index 0000000..b2005498 --- /dev/null +++ b/third_party/blink/perf_tests/accessibility/location-changes-scrolling.html
@@ -0,0 +1,95 @@ +<!DOCTYPE html> +<html> +<body> +<script src="../resources/runner.js"></script> + +<table id="testElement"> + <tr> + <th>Sender</th> + <td>Message</td> + </tr> +</table> + +<script> +var isDone = false; +var startTime; + +// Before the test starts, add 2000 rows to the table, something like a +// message board with lots of replies on a long thread. + +let table = document.getElementById('testElement'); +for (let i = 0; i < 2000; i++) { + let tr = document.createElement('tr'); + table.appendChild(tr); + let sender = document.createElement('td'); + sender.innerHTML = 'user' + Math.floor(10000*Math.random()); + tr.appendChild(sender); + let message = document.createElement('td'); + message.innerHTML = '<div>Message content ' + + Math.floor(10000*Math.random()) + '</div>'; + let link = document.createElement('a'); + link.href = '#'; + link.id = 'link' + i; + link.innerHTML = 'Reply'; + message.appendChild(link); + tr.appendChild(message); +} + +function runTest() { + if (startTime) { + PerfTestRunner.measureValueAsync(PerfTestRunner.now() - startTime); + PerfTestRunner.addRunTestEndMarker(); + } + if (!isDone) { + PerfTestRunner.addRunTestStartMarker(); + startTime = PerfTestRunner.now(); + + let scrollTimes = 0; + + let scrollInProcess = false; + let scroll = () => { + if(scrollInProcess) return; + scrollInProcess = true; + + if(scrollTimes == 5) { + return runTest(); + } + + requestAnimationFrame(() => { + scrollTimes ++; + window.scrollBy({ + top: 600, + behavior: 'smooth' + }); + document.addEventListener("scrollend", () => { + console.log("scrolling again!"); + scrollInProcess = false; + setTimeout(scroll, 500); + }, { once: true }); + }); + }; + + scroll(); + } + } + +PerfTestRunner.startMeasureValuesAsync({ + description: 'Test accessibility performance when scrolling some divs', + unit: 'ms', + done: function () { + isDone = true; + }, + run: function() { + runTest(); + }, + iterationCount: 6, + tracingCategories: 'accessibility', + traceEventsToMeasure: [ + 'BrowserAccessibilityManager::OnAccessibilityEvents', + 'ProcessDeferredAccessibilityEvents', + 'RenderAccessibilityImpl::SendPendingAccessibilityEvents', + ] +}); +</script> + +</html>
diff --git a/third_party/blink/public/mojom/frame/frame.mojom b/third_party/blink/public/mojom/frame/frame.mojom index 1653899..8dd981e7 100644 --- a/third_party/blink/public/mojom/frame/frame.mojom +++ b/third_party/blink/public/mojom/frame/frame.mojom
@@ -1088,17 +1088,17 @@ // Requests a one-time snapshot of the document state for a ViewTransition. // See https://drafts.csswg.org/css-view-transitions-1/ for details. SnapshotDocumentForViewTransition( - PageConcealEventParams page_conceal_event_params) => ( + PageSwapEventParams page_swap_event_params) => ( blink.mojom.ViewTransitionState view_transition_state); - // Dispatches a `pageconceal` event on the previous Document before the + // Dispatches a `pageswap` event on the previous Document before the // navigation is committed. This API is used for navigations which don't have // a ViewTransition. // For ViewTransition the event must be dispatched before snapshotting the old // Document with a `ViewTransition` object passed to script. So the dispatch // is done as a part of the `SnapshotDocumentForViewTransition` API above. - DispatchPageConceal( - PageConcealEventParams? page_conceal_event_params); + DispatchPageSwap( + PageSwapEventParams? page_swap_event_params); // Allows the browser to add a resource timing entry for a subframe // navigation that has failed before committing - a non-ok object navigation
diff --git a/third_party/blink/public/mojom/navigation/navigation_params.mojom b/third_party/blink/public/mojom/navigation/navigation_params.mojom index d817b65f..cc0e0f81 100644 --- a/third_party/blink/public/mojom/navigation/navigation_params.mojom +++ b/third_party/blink/public/mojom/navigation/navigation_params.mojom
@@ -625,9 +625,9 @@ string? cookie_deprecation_label; }; -// Parameters used to dispatch the `pageconceal` event on the old Document for +// Parameters used to dispatch the `pageswap` event on the old Document for // a navigation. Only generated for same-origin navigations. -struct PageConcealEventParams { +struct PageSwapEventParams { // The URL of the destination page. url.mojom.Url url;
diff --git a/third_party/blink/public/mojom/printing/web_printing.mojom b/third_party/blink/public/mojom/printing/web_printing.mojom index 57ee518c..5a1b193 100644 --- a/third_party/blink/public/mojom/printing/web_printing.mojom +++ b/third_party/blink/public/mojom/printing/web_printing.mojom
@@ -92,11 +92,47 @@ uint32 to; }; +union WebPrintingMediaSizeDimension { + WebPrintingRange range; + uint32 value; +}; + +// Each media size dimension can be either a fixed value or a range. +// Examples from the IPP spec: +// +// /* ISO A4 transparency only from manual feed */ +// media-size={ +// x-dimension=21000 +// y-dimension=29700 +// } +// +// /* Custom sizes from 3x5 to 8.5x14 inches */ +// media-size={ +// x-dimension=7620-21590 +// y-dimension=12700-35560 +// } +// +// Dimensions are specified in PWG units (hundredths of millimeters). +struct WebPrintingMediaSize { + WebPrintingMediaSizeDimension x_dimension; + WebPrintingMediaSizeDimension y_dimension; +}; + +// Represents the media-col entry of printer attributes. See §6.3.1 in +// in https://ftp.pwg.org/pub/pwg/candidates/cs-ippjobext21-20230210-5100.7.pdf +struct WebPrintingMediaCollection { + WebPrintingMediaSize media_size; + string media_size_name; +}; + // Detailed description of a single printer. struct WebPrinterAttributes { uint32 copies_default; WebPrintingRange copies_supported; + WebPrintingMediaCollection media_col_default; + array<WebPrintingMediaCollection> media_col_database; + WebPrintingMultipleDocumentHandling multiple_document_handling_default; array<WebPrintingMultipleDocumentHandling> multiple_document_handling_supported; @@ -117,10 +153,20 @@ array<WebPrintingSides> sides_supported; }; +// Represents the requested media-col entry for a print job. Note that this +// struct slightly differs from WebPrintingMediaCollection and thus is defined +// separately: +// * `media_size` dimensions are defined as values instead of ranges; +// * `media_size_name` is omitted (callers are supposed to pass `media_size`). +struct WebPrintingMediaCollectionRequested { + gfx.mojom.Size media_size; +}; + struct WebPrintJobTemplateAttributes { string job_name; uint32 copies; + WebPrintingMediaCollectionRequested? media_col; WebPrintingMultipleDocumentHandling? multiple_document_handling; WebPrintingOrientationRequested? orientation_requested; gfx.mojom.Size? printer_resolution;
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni index fd197ad5..0b7defe0 100644 --- a/third_party/blink/renderer/bindings/generated_in_core.gni +++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -1289,8 +1289,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_default_controller.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_default_reader.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_default_reader.h", - "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_page_conceal_event.cc", - "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_page_conceal_event.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_page_swap_event.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_page_swap_event.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_page_reveal_event.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_page_reveal_event.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_report.cc",
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni index e9aea78c..be03fb1 100644 --- a/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -3147,7 +3147,19 @@ # current_os = "linux" and target_os = "android". Using target_os is necessary as # we need to compile in the same way as would happen when current_os = "android". if (target_os != "android") { + generated_union_sources_in_modules += [ + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_unsignedlong_webprintingrange.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_unsignedlong_webprintingrange.h", + ] generated_dictionary_sources_in_modules += [ + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_printing_media_size.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_printing_media_size.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_printing_media_size_requested.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_printing_media_size_requested.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_printing_media_collection.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_printing_media_collection.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_printing_media_collection_requested.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_printing_media_collection_requested.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_printing_range.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_printing_range.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_printing_resolution.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_core.gni b/third_party/blink/renderer/bindings/idl_in_core.gni index b479355..af2c87a8 100644 --- a/third_party/blink/renderer/bindings/idl_in_core.gni +++ b/third_party/blink/renderer/bindings/idl_in_core.gni
@@ -739,7 +739,7 @@ "//third_party/blink/renderer/core/url_pattern/url_pattern_init.idl", "//third_party/blink/renderer/core/url_pattern/url_pattern_options.idl", "//third_party/blink/renderer/core/url_pattern/url_pattern_result.idl", - "//third_party/blink/renderer/core/view_transition/page_conceal_event.idl", + "//third_party/blink/renderer/core/view_transition/page_swap_event.idl", "//third_party/blink/renderer/core/view_transition/page_reveal_event.idl", "//third_party/blink/renderer/core/view_transition/view_transition.idl", "//third_party/blink/renderer/core/view_transition/view_transition_callback.idl",
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl index cbf461412..85c3331 100644 --- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl +++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
@@ -17,6 +17,13 @@ {% if property.style_builder_declare %} {% if property.style_builder_generate_inherit %} void {{class_name}}::ApplyInherit(StyleResolverState& state) const { + {% if property.affected_by_zoom %} + if (RuntimeEnabledFeatures::StandardizedBrowserZoomEnabled()) { + if (ApplyParentValueIfZoomChanged(state)) { + return; + } + } + {% endif %} {{(caller(property) ~ '}')}} {% endif %} {% endif %}
diff --git a/third_party/blink/renderer/core/accessibility/ax_object_cache.h b/third_party/blink/renderer/core/accessibility/ax_object_cache.h index 61e95857..b1f2b60a 100644 --- a/third_party/blink/renderer/core/accessibility/ax_object_cache.h +++ b/third_party/blink/renderer/core/accessibility/ax_object_cache.h
@@ -48,6 +48,7 @@ namespace blink { class AbstractInlineTextBox; +class AriaNotification; class AriaNotificationOptions; class AXObject; class AccessibleNode; @@ -164,11 +165,16 @@ virtual void HandleAttributeChanged(const QualifiedName& attr_name, AccessibleNode*) = 0; - // Handle notifications from the `ariaNotify` API. + // Handles a notification from the `ariaNotify` API. virtual void HandleAriaNotification(const Node*, const String&, const AriaNotificationOptions*) = 0; + // Retrieves the `AriaNotification` (if any) for a given `AXObject`. + // Note that ownership of such notification will be removed from this object. + virtual std::unique_ptr<AriaNotification> RetrieveAriaNotification( + const AXObject*) = 0; + // Called when a HTMLFrameOwnerElement (such as an iframe element) changes the // embedding token of its child frame. virtual void EmbeddingTokenChanged(HTMLFrameOwnerElement*) = 0;
diff --git a/third_party/blink/renderer/core/css/build.gni b/third_party/blink/renderer/core/css/build.gni index 81688f1..0b5a0e1 100644 --- a/third_party/blink/renderer/core/css/build.gni +++ b/third_party/blink/renderer/core/css/build.gni
@@ -589,6 +589,7 @@ "properties/css_property_ref.h", "properties/css_unresolved_property.cc", "properties/css_unresolved_property.h", + "properties/longhand.cc", "properties/longhand.h", "properties/longhands/custom_property.cc", "properties/longhands/custom_property.h", @@ -816,6 +817,7 @@ "media_query_set_test.cc", "media_values_test.cc", "mock_css_paint_image_generator.h", + "page_rule_collector_test.cc", "parser/at_rule_descriptor_parser_test.cc", "parser/container_query_parser_test.cc", "parser/css_lazy_parsing_test.cc",
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5 index 609c800..cba24adf 100644 --- a/third_party/blink/renderer/core/css/css_properties.json5 +++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -744,6 +744,21 @@ default: false, valid_type: "bool", }, + + // - affected_by_zoom: true + // + // Whether or not the computed value of this property is affected by + // the effective zoom factor. Generally, all computed values that contain + // a blink::Length are affected by zoom. + // + // Setting this flag to 'true' will change the inheritance behavior + // (Longhand::ApplyInherit) to effectively "rezoom" the inherited value. + // + // https://github.com/w3c/csswg-drafts/issues/9397 + affected_by_zoom: { + default: false, + valid_type: "bool", + }, }, // Members in the data objects should appear in the same order as in the @@ -3342,6 +3357,7 @@ valid_for_first_line: true, valid_for_cue: true, valid_for_marker: true, + affected_by_zoom: true, }, { name: "list-style-image", @@ -6387,6 +6403,7 @@ supports_incremental_style: true, valid_for_formatted_text: true, valid_for_position_fallback: true, + affected_by_zoom: true, }, { name: "will-change",
diff --git a/third_party/blink/renderer/core/css/css_test_helpers.cc b/third_party/blink/renderer/core/css/css_test_helpers.cc index a3911827..d336b32 100644 --- a/third_party/blink/renderer/core/css/css_test_helpers.cc +++ b/third_party/blink/renderer/core/css/css_test_helpers.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/css/css_test_helpers.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_css_style_sheet_init.h" #include "third_party/blink/renderer/bindings/core/v8/v8_property_definition.h" #include "third_party/blink/renderer/core/css/css_custom_ident_value.h" #include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" @@ -72,6 +73,16 @@ document, NullURL(), TextPosition::MinimumPosition(), UTF8Encoding()); } +RuleSet* CreateRuleSet(Document& document, String text) { + DummyExceptionStateForTesting exception_state; + auto* init = CSSStyleSheetInit::Create(); + auto* media_query_evaluator = + MakeGarbageCollected<MediaQueryEvaluator>(document.GetFrame()); + auto* sheet = CSSStyleSheet::Create(document, init, exception_state); + sheet->replaceSync(text, exception_state); + return &sheet->Contents()->EnsureRuleSet(*media_query_evaluator); +} + PropertyRegistration* CreatePropertyRegistration(const String& name, String syntax, const CSSValue* initial_value,
diff --git a/third_party/blink/renderer/core/css/css_test_helpers.h b/third_party/blink/renderer/core/css/css_test_helpers.h index 5681358..f65e8a0 100644 --- a/third_party/blink/renderer/core/css/css_test_helpers.h +++ b/third_party/blink/renderer/core/css/css_test_helpers.h
@@ -51,6 +51,7 @@ }; CSSStyleSheet* CreateStyleSheet(Document& document); +RuleSet* CreateRuleSet(Document& document, String text); // Create a PropertyRegistration with the given name. An initial value must // be provided when the syntax is not "*".
diff --git a/third_party/blink/renderer/core/css/element_rule_collector_test.cc b/third_party/blink/renderer/core/css/element_rule_collector_test.cc index 93958eda..f5c5b87 100644 --- a/third_party/blink/renderer/core/css/element_rule_collector_test.cc +++ b/third_party/blink/renderer/core/css/element_rule_collector_test.cc
@@ -78,7 +78,7 @@ MatchRequest request(rule_set, scope); collector.CollectMatchingRules(request); - collector.SortAndTransferMatchedRules(CascadeOrigin::kNone, + collector.SortAndTransferMatchedRules(CascadeOrigin::kAuthor, /*is_vtt_embedded_style=*/false, /*tracker=*/nullptr);
diff --git a/third_party/blink/renderer/core/css/page_rule_collector.cc b/third_party/blink/renderer/core/css/page_rule_collector.cc index 5ecb46b..76c9049 100644 --- a/third_party/blink/renderer/core/css/page_rule_collector.cc +++ b/third_party/blink/renderer/core/css/page_rule_collector.cc
@@ -66,6 +66,8 @@ result_(match_result) {} void PageRuleCollector::MatchPageRules(RuleSet* rules, + CascadeOrigin origin, + TreeScope* tree_scope, const CascadeLayerMap* layer_map) { if (!rules) { return; @@ -89,9 +91,13 @@ return r1->Selector()->Specificity() < r2->Selector()->Specificity(); }); + if (origin == CascadeOrigin::kAuthor) { + CHECK(tree_scope); + result_.BeginAddingAuthorRulesForTreeScope(*tree_scope); + } + for (unsigned i = 0; i < matched_page_rules.size(); i++) { - result_.AddMatchedProperties(&matched_page_rules[i]->Properties(), - CascadeOrigin::kNone); + result_.AddMatchedProperties(&matched_page_rules[i]->Properties(), origin); } }
diff --git a/third_party/blink/renderer/core/css/page_rule_collector.h b/third_party/blink/renderer/core/css/page_rule_collector.h index 0464c69..84073b5f 100644 --- a/third_party/blink/renderer/core/css/page_rule_collector.h +++ b/third_party/blink/renderer/core/css/page_rule_collector.h
@@ -23,6 +23,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PAGE_RULE_COLLECTOR_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PAGE_RULE_COLLECTOR_H_ +#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/css/resolver/match_result.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -31,7 +32,7 @@ class CascadeLayerMap; class StyleRulePage; -class PageRuleCollector { +class CORE_EXPORT PageRuleCollector { STACK_ALLOCATED(); public: @@ -40,7 +41,12 @@ const AtomicString& page_name, MatchResult&); - void MatchPageRules(RuleSet* rules, const CascadeLayerMap* layer_map); + // TreeScope is required for CascadeOrigin::kAuthor, + // and ignored for other origins. + void MatchPageRules(RuleSet* rules, + CascadeOrigin, + TreeScope*, + const CascadeLayerMap* layer_map); const MatchResult& MatchedResult() { return result_; } private:
diff --git a/third_party/blink/renderer/core/css/page_rule_collector_test.cc b/third_party/blink/renderer/core/css/page_rule_collector_test.cc new file mode 100644 index 0000000..2e3785fe --- /dev/null +++ b/third_party/blink/renderer/core/css/page_rule_collector_test.cc
@@ -0,0 +1,76 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/css/page_rule_collector.h" + +#include <optional> + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/css/css_test_helpers.h" +#include "third_party/blink/renderer/core/css/media_query_evaluator.h" +#include "third_party/blink/renderer/core/css/resolver/style_cascade.h" +#include "third_party/blink/renderer/core/css/resolver/style_resolver.h" +#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/style/computed_style.h" +#include "third_party/blink/renderer/core/testing/page_test_base.h" + +namespace blink { + +class PageRuleCollectorTest : public PageTestBase { + public: + const ComputedStyle* ComputePageStyle(String ua_sheet_string, + String author_sheet_string) { + RuleSet* ua_ruleset = + css_test_helpers::CreateRuleSet(GetDocument(), ua_sheet_string); + RuleSet* author_ruleset = + css_test_helpers::CreateRuleSet(GetDocument(), author_sheet_string); + + const ComputedStyle& initial_style = + GetDocument().GetStyleResolver().InitialStyle(); + Element* root_element = GetDocument().documentElement(); + + StyleResolverState state(GetDocument(), *root_element); + state.CreateNewStyle(initial_style, initial_style); + + STACK_UNINITIALIZED StyleCascade cascade(state); + + PageRuleCollector collector(&initial_style, /* page_index */ 0, + /* page_name */ AtomicString("page"), + cascade.MutableMatchResult()); + + collector.MatchPageRules(ua_ruleset, CascadeOrigin::kUserAgent, + nullptr /* tree_scope */, nullptr /* layer_map */); + + collector.MatchPageRules(author_ruleset, CascadeOrigin::kAuthor, + &GetDocument() /* tree_scope */, + nullptr /* layer_map */); + + cascade.Apply(); + + return state.TakeStyle(); + } +}; + +TEST_F(PageRuleCollectorTest, UserAgent) { + String ua_sheet_string = "@page { margin: 1px; }"; + String author_sheet_string = "@page { margin: 2px; }"; + + const ComputedStyle* style = + ComputePageStyle(ua_sheet_string, author_sheet_string); + + EXPECT_EQ(Length::Fixed(2), style->MarginLeft()); +} + +TEST_F(PageRuleCollectorTest, UserAgentImportant) { + String ua_sheet_string = "@page { margin: 1px !important; }"; + String author_sheet_string = "@page { margin: 2px; }"; + + const ComputedStyle* style = + ComputePageStyle(ua_sheet_string, author_sheet_string); + + EXPECT_EQ(Length::Fixed(1), style->MarginLeft()); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhand.cc b/third_party/blink/renderer/core/css/properties/longhand.cc new file mode 100644 index 0000000..432a0ed --- /dev/null +++ b/third_party/blink/renderer/core/css/properties/longhand.cc
@@ -0,0 +1,30 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/css/properties/longhand.h" + +#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" + +namespace blink { + +void Longhand::ApplyParentValue(StyleResolverState& state) const { + // Creating the (computed) CSSValue involves unzooming using the parent's + // effective zoom. + const CSSValue* parent_computed_value = + ComputedStyleUtils::ComputedPropertyValue(*this, *state.ParentStyle()); + CHECK(parent_computed_value); + // Applying the CSSValue involves zooming using our effective zoom. + ApplyValue(state, *parent_computed_value, ValueMode::kNormal); +} + +bool Longhand::ApplyParentValueIfZoomChanged(StyleResolverState& state) const { + if (state.ParentStyle()->EffectiveZoom() != + state.StyleBuilder().EffectiveZoom()) { + ApplyParentValue(state); + return true; + } + return false; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhand.h b/third_party/blink/renderer/core/css/properties/longhand.h index 79e12be..08c1846 100644 --- a/third_party/blink/renderer/core/css/properties/longhand.h +++ b/third_party/blink/renderer/core/css/properties/longhand.h
@@ -57,6 +57,15 @@ protected: constexpr Longhand(CSSPropertyID id, Flags flags, char repetition_separator) : CSSProperty(id, flags | kLonghand, repetition_separator) {} + // Applies the computed CSSValue of the parent style using ApplyValue. + // This generally achieves the same as ApplyInherit, but effectively + // "rezooms" the value. + // + // https://github.com/w3c/csswg-drafts/issues/9397 + void ApplyParentValue(StyleResolverState&) const; + // If our zoom is different from the parent zoom, calls ApplyParentValue + // and returns true. Otherwise does nothing and returns false. + bool ApplyParentValueIfZoomChanged(StyleResolverState&) const; }; template <>
diff --git a/third_party/blink/renderer/core/css/resolver/cascade_expansion_test.cc b/third_party/blink/renderer/core/css/resolver/cascade_expansion_test.cc index cbf9b3a..1fb94a9c 100644 --- a/third_party/blink/renderer/core/css/resolver/cascade_expansion_test.cc +++ b/third_party/blink/renderer/core/css/resolver/cascade_expansion_test.cc
@@ -653,8 +653,9 @@ auto* set = ParseDeclarationBlock("left:1px"); MatchResult result; + result.BeginAddingAuthorRulesForTreeScope(GetDocument()); for (wtf_size_t i = 0; i < max + 3; ++i) { - result.AddMatchedProperties(set, CascadeOrigin::kNone); + result.AddMatchedProperties(set, CascadeOrigin::kAuthor); } ASSERT_EQ(max + 3u, result.GetMatchedProperties().size()); @@ -685,14 +686,15 @@ } MatchResult result; + result.BeginAddingAuthorRulesForTreeScope(GetDocument()); result.AddMatchedProperties( ImmutableCSSPropertyValueSet::Create(declarations.data(), max + 1, kHTMLStandardMode), - CascadeOrigin::kNone); + CascadeOrigin::kAuthor); result.AddMatchedProperties( ImmutableCSSPropertyValueSet::Create(declarations.data(), max + 2, kHTMLStandardMode), - CascadeOrigin::kNone); + CascadeOrigin::kAuthor); EXPECT_GT(ExpansionAt(result, 0).size(), 0u); EXPECT_EQ(ExpansionAt(result, 1).size(), 0u);
diff --git a/third_party/blink/renderer/core/css/resolver/match_result.cc b/third_party/blink/renderer/core/css/resolver/match_result.cc index 5f536c1b..bb1d7fda 100644 --- a/third_party/blink/renderer/core/css/resolver/match_result.cc +++ b/third_party/blink/renderer/core/css/resolver/match_result.cc
@@ -52,6 +52,7 @@ const CSSPropertyValueSet* properties, CascadeOrigin origin, const AddMatchedPropertiesOptions& options) { + CHECK_NE(origin, CascadeOrigin::kNone); matched_properties_.Grow(matched_properties_.size() + 1); MatchedProperties& new_properties = matched_properties_.back(); new_properties.properties = const_cast<CSSPropertyValueSet*>(properties);
diff --git a/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.cc b/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.cc index 2251b1de..e58f319 100644 --- a/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.cc
@@ -314,7 +314,8 @@ // Currently, only @page rules in the document scope apply. DCHECK(scope_->RootNode().IsDocumentNode()); for (auto [sheet, rule_set] : active_style_sheets_) { - collector.MatchPageRules(rule_set.Get(), GetCascadeLayerMap()); + collector.MatchPageRules(rule_set.Get(), CascadeOrigin::kAuthor, scope_, + GetCascadeLayerMap()); } }
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade.cc b/third_party/blink/renderer/core/css/resolver/style_cascade.cc index 5844b7e..3fa154d 100644 --- a/third_party/blink/renderer/core/css/resolver/style_cascade.cc +++ b/third_party/blink/renderer/core/css/resolver/style_cascade.cc
@@ -331,10 +331,14 @@ for (CSSPropertyID id : map_.NativeBitset()) { CSSPropertyName name(id); CascadePriority priority = map_.At(name); - DCHECK(priority.HasOrigin()); if (IsInterpolation(priority)) { continue; } + if (!priority.HasOrigin()) { + // Declarations added for explicit defaults (AddExplicitDefaults) + // should not be observable. + continue; + } const CSSValue* cascaded = ValueAt(match_result_, priority.GetPosition()); DCHECK(cascaded); result.Set(name, cascaded); @@ -384,6 +388,8 @@ } void StyleCascade::AnalyzeMatchResult() { + AddExplicitDefaults(); + int index = 0; for (const MatchedProperties& properties : match_result_.GetMatchedProperties()) { @@ -452,6 +458,40 @@ } } +// The implicit defaulting behavior of inherited properties is to take +// the value of the parent style [1]. However, we never reach +// Longhand::ApplyInherit for implicit defaults, which is needed to adjust +// Lengths with premultiplied zoom. Therefore, all inherited properties +// are instead explicitly defaulted [2] when the effective zoom has changed +// versus the parent zoom. +// +// [1] https://drafts.csswg.org/css-cascade/#defaulting +// [2] https://drafts.csswg.org/css-cascade/#defaulting-keywords +void StyleCascade::AddExplicitDefaults() { + if (RuntimeEnabledFeatures::StandardizedBrowserZoomEnabled() && + effective_zoom_changed_) { + // TODO(crbug.com/40946858): Generate a list from json5. + // + // At a glance, these inherited properties can contain lengths: + // + // -webkit-border-horizontal-spacing + // -webkit-border-vertical-spacing + // -webkit-text-stroke-width + // letter-spacing + // line-height + // list-style-image + // stroke-dashoffset + // stroke-width + // text-indent + // text-shadow + // text-underline-offset + // word-spacing + // + // (And maybe more). + map_.Add(CSSPropertyID::kLineHeight, CascadePriority(CascadeOrigin::kNone)); + } +} + void StyleCascade::Reanalyze() { map_.Reset(); generation_ = 0; @@ -471,6 +511,12 @@ // values on ComputedStyle. auto direction = state_.StyleBuilder().Direction(); auto writing_mode = state_.StyleBuilder().GetWritingMode(); + // Similarly, we assume that the effective zoom of this element + // is the same as the parent's effective zoom. If it isn't, + // we re-cascade with explicit defaults inserted at CascadeOrigin::kNone. + // + // See also StyleCascade::AddExplicitDefaults. + float effective_zoom = state_.StyleBuilder().EffectiveZoom(); if (map_.NativeBitset().Has(CSSPropertyID::kDirection)) { LookupAndApply(GetCSSPropertyDirection(), resolver); @@ -478,13 +524,26 @@ if (map_.NativeBitset().Has(CSSPropertyID::kWritingMode)) { LookupAndApply(GetCSSPropertyWritingMode(), resolver); } + if (map_.NativeBitset().Has(CSSPropertyID::kZoom)) { + LookupAndApply(GetCSSPropertyZoom(), resolver); + } + + bool reanalyze = false; if (depends_on_cascade_affecting_property_) { if (direction != state_.StyleBuilder().Direction() || writing_mode != state_.StyleBuilder().GetWritingMode()) { - Reanalyze(); + reanalyze = true; } } + if (effective_zoom != state_.StyleBuilder().EffectiveZoom()) { + effective_zoom_changed_ = true; + reanalyze = true; + } + + if (reanalyze) { + Reanalyze(); + } } void StyleCascade::ApplyHighPriority(CascadeResolver& resolver) { @@ -741,9 +800,13 @@ *priority = CascadePriority(*priority, resolver.generation_); DCHECK(!property.IsSurrogate()); DCHECK(priority->GetOrigin() < CascadeOrigin::kAnimation); - const CSSValue* value = ValueAt(match_result_, priority->GetPosition()); - DCHECK(value); CascadeOrigin origin = priority->GetOrigin(); + // Values at CascadeOrigin::kNone are used for explicit defaulting, + // see StyleCascade::AddExplicitDefaults. + const CSSValue* value = (origin == CascadeOrigin::kNone) + ? cssvalue::CSSUnsetValue::Create() + : ValueAt(match_result_, priority->GetPosition()); + DCHECK(value); value = Resolve(property, *value, *priority, origin, resolver); DCHECK(IsA<CustomProperty>(property) || !value->IsUnparsedDeclaration()); DCHECK(!value->IsPendingSubstitutionValue());
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade.h b/third_party/blink/renderer/core/css/resolver/style_cascade.h index 8b91255..f7889b6 100644 --- a/third_party/blink/renderer/core/css/resolver/style_cascade.h +++ b/third_party/blink/renderer/core/css/resolver/style_cascade.h
@@ -178,6 +178,7 @@ void AnalyzeIfNeeded(); void AnalyzeMatchResult(); void AnalyzeInterpolations(); + void AddExplicitDefaults(); // Clears the CascadeMap and other state, and analyzes the MatchResult/ // interpolations again. @@ -541,6 +542,8 @@ // computed value of the property affects how e.g. margin-inline-start // (and other css-logical properties) cascade. bool depends_on_cascade_affecting_property_ = false; + // See comment in StyleCascade::AddExplicitDefaults (.cc file). + bool effective_zoom_changed_ = false; // If true, invisible rules will be added to the cascade, setting // `has_invisible_rules_` to true whenever such rules are actually seen. // Otherwise, invisible rules are silently ignored.
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 687df3f..1421284d 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
@@ -197,8 +197,12 @@ *CSSPropertyName::From(GetDocument().GetExecutionContext(), name)); } + CascadePriority* FindPriority(CSSPropertyName name) { + return cascade_.map_.Find(name); + } + CascadePriority GetPriority(CSSPropertyName name) { - CascadePriority* c = cascade_.map_.Find(name); + CascadePriority* c = FindPriority(name); return c ? *c : CascadePriority(); } @@ -2713,6 +2717,33 @@ EXPECT_EQ(2.0f, cascade.TakeStyle()->EffectiveZoom()); } +TEST_F(StyleCascadeTest, ZoomExplicitDefault) { + ScopedStandardizedBrowserZoomForTest scoped_feature(true); + + TestCascade cascade(GetDocument()); + cascade.Add("zoom:200%"); + cascade.Apply(); + + // Since the zoom changed, there should be an explicit entry + // in the cascade map with CascadeOrigin::kNone. + CascadePriority* priority = + cascade.FindPriority(CSSPropertyName(CSSPropertyID::kLineHeight)); + ASSERT_TRUE(priority); + EXPECT_EQ(CascadeOrigin::kNone, priority->GetOrigin()); +} + +TEST_F(StyleCascadeTest, ZoomNoExplicitDefault) { + ScopedStandardizedBrowserZoomForTest scoped_feature(true); + + TestCascade cascade(GetDocument()); + cascade.Apply(); + + // Since the zoom did not change, there should not be an entry in the map. + CascadePriority* priority = + cascade.FindPriority(CSSPropertyName(CSSPropertyID::kLineHeight)); + EXPECT_FALSE(priority); +} + TEST_F(StyleCascadeTest, WritingModeCascadeOrder) { TestCascade cascade(GetDocument()); cascade.Add("writing-mode", "vertical-lr"); @@ -3693,6 +3724,24 @@ EXPECT_EQ("-5s", CssTextAt(map, "animation-delay")); } +TEST_F(StyleCascadeTest, GetCascadedValuesWithExplicitDefaults) { + ScopedStandardizedBrowserZoomForTest scoped_feature(true); + + TestCascade cascade(GetDocument()); + cascade.Add("top:100px"); + cascade.Add("zoom:200%"); // Causes explicit defaults. + cascade.Apply(); + + // Any explicit defaults (StyleCascade::AddExplicitDefaults) should not + // be visible via GetCascadedValues. + + auto map = cascade.GetCascadedValues(); + EXPECT_EQ(2u, map.size()); + + EXPECT_EQ("100px", CssTextAt(map, "top")); + EXPECT_EQ("200%", CssTextAt(map, "zoom")); +} + TEST_F(StyleCascadeTest, StaticResolveNoVar) { // We don't need this object, but it's an easy way of setting // up a StyleResolverState.
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 a0ab107..3f8760b 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -1784,6 +1784,7 @@ collector.MatchPageRules( CSSDefaultStyleSheets::Instance().DefaultPrintStyle(), + CascadeOrigin::kUserAgent, nullptr /* tree_scope */, nullptr /* layer_map */); if (ScopedStyleResolver* scoped_resolver = @@ -3064,8 +3065,11 @@ // Use StyleCascade to apply inheritance in the correct order. STACK_UNINITIALIZED StyleCascade cascade(state); - cascade.MutableMatchResult().AddMatchedProperties( - css_property_value_set, CascadeOrigin::kNone, {.is_inline_style = true}); + cascade.MutableMatchResult().BeginAddingAuthorRulesForTreeScope( + GetDocument()); + cascade.MutableMatchResult().AddMatchedProperties(css_property_value_set, + CascadeOrigin::kAuthor, + {.is_inline_style = true}); cascade.Apply(); StyleAdjuster::AdjustComputedStyle(state, nullptr);
diff --git a/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc b/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc index 38d1617..20e47e95 100644 --- a/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc +++ b/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc
@@ -318,13 +318,17 @@ if (end_style->ShouldPreserveBreaks() && start == end && end.OffsetInContainerNode() < static_cast<int>(To<Text>(end.ComputeContainerNode())->length())) { - int end_offset = end.OffsetInContainerNode(); - // TODO(yosin) We should use |PositionMoveType::CodePoint| for - // |previousPositionOf()|. - if (!IsNewLineAtPosition( - PreviousPositionOf(end, PositionMoveType::kCodeUnit)) && - IsNewLineAtPosition(end)) - end = Position(end.ComputeContainerNode(), end_offset + 1); + if (!RuntimeEnabledFeatures:: + NoIncreasingEndOffsetOnSplittingTextNodesEnabled()) { + int end_offset = end.OffsetInContainerNode(); + // TODO(yosin) We should use |PositionMoveType::CodePoint| for + // |previousPositionOf()|. + if (!IsNewLineAtPosition( + PreviousPositionOf(end, PositionMoveType::kCodeUnit)) && + IsNewLineAtPosition(end)) { + end = Position(end.ComputeContainerNode(), end_offset + 1); + } + } if (is_end_and_end_of_last_paragraph_on_same_node && end.OffsetInContainerNode() >= end_of_last_paragraph.OffsetInContainerNode())
diff --git a/third_party/blink/renderer/core/events/event_type_names.json5 b/third_party/blink/renderer/core/events/event_type_names.json5 index 5af1129..c9eaf4c 100644 --- a/third_party/blink/renderer/core/events/event_type_names.json5 +++ b/third_party/blink/renderer/core/events/event_type_names.json5
@@ -257,8 +257,8 @@ "reading", "readingerror", "readystatechange", - "pageconceal", "pagereveal", + "pageswap", "reflectionchange", "rejectionhandled", "release",
diff --git a/third_party/blink/renderer/core/fileapi/public_url_manager.cc b/third_party/blink/renderer/core/fileapi/public_url_manager.cc index db633aa5..7f7ed2a8 100644 --- a/third_party/blink/renderer/core/fileapi/public_url_manager.cc +++ b/third_party/blink/renderer/core/fileapi/public_url_manager.cc
@@ -27,9 +27,7 @@ #include "third_party/blink/renderer/core/fileapi/public_url_manager.h" #include "base/feature_list.h" -#include "base/metrics/histogram_functions.h" #include "base/notreached.h" -#include "base/strings/strcat.h" #include "base/types/pass_key.h" #include "base/unguessable_token.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -67,16 +65,6 @@ } // namespace -// Execution context names corresponding to the entries from -// `ExecutionContextIdForHistogram` in public_url_manager.h. -const char* const kExecutionContextNamesForHistograms[]{ - "Frame", - "Worker", -}; -static_assert(std::size(kExecutionContextNamesForHistograms) == - static_cast<size_t>(ExecutionContextIdForHistogram::kMaxValue) + - 1); - PublicURLManager::PublicURLManager(ExecutionContext* execution_context) : ExecutionContextLifecycleObserver(execution_context), frame_url_store_(execution_context), @@ -89,7 +77,6 @@ return; } - execution_context_type_ = ExecutionContextIdForHistogram::kFrame; frame->GetRemoteNavigationAssociatedInterfaces()->GetInterface( frame_url_store_.BindNewEndpointAndPassReceiver( execution_context->GetTaskRunner(TaskType::kFileReading))); @@ -101,7 +88,6 @@ return; } - execution_context_type_ = ExecutionContextIdForHistogram::kWorker; worker_global_scope->GetBrowserInterfaceBroker().GetInterface( worker_url_store_.BindNewPipeAndPassReceiver( execution_context->GetTaskRunner(TaskType::kFileReading))); @@ -153,9 +139,6 @@ : ExecutionContextLifecycleObserver(execution_context), frame_url_store_(execution_context), worker_url_store_(execution_context) { - if (base::FeatureList::IsEnabled(net::features::kSupportPartitionedBlobUrl)) { - execution_context_type_ = ExecutionContextIdForHistogram::kFrame; - } frame_url_store_.Bind( std::move(frame_url_store_remote), execution_context->GetTaskRunner(TaskType::kFileReading)); @@ -200,31 +183,9 @@ } } - base::ElapsedTimer register_timer; GetBlobURLStore().Register(std::move(blob_remote), url, GetExecutionContext()->GetAgentClusterID(), top_level_site); - const base::TimeDelta register_url_time = register_timer.Elapsed(); - - if (base::FeatureList::IsEnabled( - net::features::kSupportPartitionedBlobUrl)) { - // This holds because `execution_context_type_` will always be set for - // Window, SharedWorker, and DedicatedWorker contexts, which are the only - // ones where URL.CreateObjectURL is exposed (per the IDL). - CHECK(execution_context_type_.has_value()); - - const char* context_type_ = - kExecutionContextNamesForHistograms[static_cast<int>( - *execution_context_type_)]; - base::UmaHistogramCustomTimes( - base::StrCat({"Storage.Blob.RegisterURLTimeWithPartitioningSupport.", - context_type_}), - register_url_time, base::Milliseconds(1), base::Seconds(60), 50); - } else { - base::UmaHistogramCustomTimes( - "Storage.Blob.RegisterURLTimeWithoutPartitioningSupport", - register_url_time, base::Milliseconds(1), base::Seconds(60), 50); - } mojo_urls_.insert(url_string); registrable->CloneMojoBlob(std::move(blob_receiver));
diff --git a/third_party/blink/renderer/core/fileapi/public_url_manager.h b/third_party/blink/renderer/core/fileapi/public_url_manager.h index d4c80fdf..153a303 100644 --- a/third_party/blink/renderer/core/fileapi/public_url_manager.h +++ b/third_party/blink/renderer/core/fileapi/public_url_manager.h
@@ -48,17 +48,6 @@ class URLRegistry; class URLRegistrable; -// Execution context ids for usage in metrics. Entries should not be renumbered -// and numeric values should never be reused. Please keep in sync with -// "BlobURLExecutionContextId" in -// src/tools/metrics/histograms/metadata/histogram_suffixes_list.xml and with -// `kExecutionContextNamesForHistograms` in public_url_manager.cc. -enum class ExecutionContextIdForHistogram { - kFrame = 0, - kWorker = 1, - kMaxValue = kWorker -}; - class CORE_EXPORT PublicURLManager final : public GarbageCollected<PublicURLManager>, public ExecutionContextLifecycleObserver { @@ -106,11 +95,6 @@ URLToRegistryMap url_to_registry_; HashSet<URLString> mojo_urls_; - // Records which execution context type instantiated this PublicURLManager, - // for collecting metrics. This is only set when the SupportPartitionedBlobUrl - // feature is enabled, and is only set for frame or worker execution contexts. - std::optional<ExecutionContextIdForHistogram> execution_context_type_; - bool is_stopped_ = false; // For a frame context or from a main thread worklet context, a
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h index 8fc0c52..54401bc6 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.h +++ b/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -373,7 +373,7 @@ DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange, kOrientationchange) - DEFINE_ATTRIBUTE_EVENT_LISTENER(pageconceal, kPageconceal) + DEFINE_ATTRIBUTE_EVENT_LISTENER(pageswap, kPageswap) DEFINE_ATTRIBUTE_EVENT_LISTENER(pagereveal, kPagereveal)
diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc index 44fb3b3..3d57ede 100644 --- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc +++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
@@ -69,7 +69,7 @@ #include "third_party/blink/renderer/core/paint/timing/paint_timing.h" #include "third_party/blink/renderer/core/script/classic_script.h" #include "third_party/blink/renderer/core/timing/dom_window_performance.h" -#include "third_party/blink/renderer/core/view_transition/page_conceal_event.h" +#include "third_party/blink/renderer/core/view_transition/page_swap_event.h" #include "third_party/blink/renderer/core/view_transition/view_transition_supplement.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_timing_utils.h" #include "third_party/blink/renderer/platform/widget/frame_widget.h" @@ -1348,17 +1348,17 @@ } void LocalFrameMojoHandler::SnapshotDocumentForViewTransition( - mojom::blink::PageConcealEventParamsPtr params, + mojom::blink::PageSwapEventParamsPtr params, SnapshotDocumentForViewTransitionCallback callback) { ViewTransitionSupplement::SnapshotDocumentForNavigation( *frame_->GetDocument(), std::move(params), std::move(callback)); } -void LocalFrameMojoHandler::DispatchPageConceal( - mojom::blink::PageConcealEventParamsPtr params) { - auto* page_conceal_event = MakeGarbageCollected<PageConcealEvent>( +void LocalFrameMojoHandler::DispatchPageSwap( + mojom::blink::PageSwapEventParamsPtr params) { + auto* page_swap_event = MakeGarbageCollected<PageSwapEvent>( *frame_->GetDocument(), std::move(params), nullptr); - frame_->GetDocument()->domWindow()->DispatchEvent(*page_conceal_event); + frame_->GetDocument()->domWindow()->DispatchEvent(*page_swap_event); } void LocalFrameMojoHandler::DispatchBeforeUnload(
diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h index 5d38d56..ab3748f 100644 --- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h +++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h
@@ -211,9 +211,9 @@ const std::string& page_state, bool is_browser_initiated) final; void SnapshotDocumentForViewTransition( - mojom::blink::PageConcealEventParamsPtr, + mojom::blink::PageSwapEventParamsPtr, SnapshotDocumentForViewTransitionCallback callback) final; - void DispatchPageConceal(mojom::blink::PageConcealEventParamsPtr) final; + void DispatchPageSwap(mojom::blink::PageSwapEventParamsPtr) final; void AddResourceTimingEntryForFailedSubframeNavigation( const FrameToken& subframe_token,
diff --git a/third_party/blink/renderer/core/frame/window.idl b/third_party/blink/renderer/core/frame/window.idl index 1bdff0e..4e342b9 100644 --- a/third_party/blink/renderer/core/frame/window.idl +++ b/third_party/blink/renderer/core/frame/window.idl
@@ -172,8 +172,8 @@ // 90 is when rotated counter clockwise. [HighEntropy=Direct, MeasureAs=WindowOrientation, RuntimeEnabled=OrientationEvent] readonly attribute long orientation; - // Event handler attribute for the pageconceal event. - [RuntimeEnabled=PageConcealEvent] attribute EventHandler onpageconceal; + // Event handler attribute for the pageswap event. + [RuntimeEnabled=PageSwapEvent] attribute EventHandler onpageswap; // Event handler attribute for the pagereveal event. // https://drafts.csswg.org/css-view-transitions-2/#reveal-event
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 58fe300..5db666f 100644 --- a/third_party/blink/renderer/core/style/computed_style_test.cc +++ b/third_party/blink/renderer/core/style/computed_style_test.cc
@@ -880,19 +880,21 @@ auto* light_declaration = ParseDeclarationBlock("color-scheme:light"); StyleCascade cascade1(state); + cascade1.MutableMatchResult().BeginAddingAuthorRulesForTreeScope(document); cascade1.MutableMatchResult().AddMatchedProperties(color_declaration, - CascadeOrigin::kNone); + CascadeOrigin::kAuthor); cascade1.MutableMatchResult().AddMatchedProperties(dark_declaration, - CascadeOrigin::kNone); + CascadeOrigin::kAuthor); cascade1.Apply(); const ComputedStyle* style = state.StyleBuilder().CloneStyle(); EXPECT_EQ(Color::kWhite, style->VisitedDependentColor(GetCSSPropertyColor())); StyleCascade cascade2(state); + cascade2.MutableMatchResult().BeginAddingAuthorRulesForTreeScope(document); cascade2.MutableMatchResult().AddMatchedProperties(color_declaration, - CascadeOrigin::kNone); + CascadeOrigin::kAuthor); cascade2.MutableMatchResult().AddMatchedProperties(light_declaration, - CascadeOrigin::kNone); + CascadeOrigin::kAuthor); cascade2.Apply(); style = state.StyleBuilder().CloneStyle(); EXPECT_EQ(Color::kBlack, style->VisitedDependentColor(GetCSSPropertyColor())); @@ -922,20 +924,22 @@ auto* light_declaration = ParseDeclarationBlock("color-scheme:light"); StyleCascade cascade1(state); + cascade1.MutableMatchResult().BeginAddingAuthorRulesForTreeScope(document); cascade1.MutableMatchResult().AddMatchedProperties(bgimage_declaration, - CascadeOrigin::kNone); + CascadeOrigin::kAuthor); cascade1.MutableMatchResult().AddMatchedProperties(dark_declaration, - CascadeOrigin::kNone); + CascadeOrigin::kAuthor); cascade1.Apply(); EXPECT_TRUE(state.TakeStyle()->HasBackgroundImage()); state.SetStyle(*initial); StyleCascade cascade2(state); + cascade2.MutableMatchResult().BeginAddingAuthorRulesForTreeScope(document); cascade2.MutableMatchResult().AddMatchedProperties(bgimage_declaration, - CascadeOrigin::kNone); + CascadeOrigin::kAuthor); cascade2.MutableMatchResult().AddMatchedProperties(light_declaration, - CascadeOrigin::kNone); + CascadeOrigin::kAuthor); cascade2.Apply(); EXPECT_FALSE(state.TakeStyle()->HasBackgroundImage()); }
diff --git a/third_party/blink/renderer/core/view_transition/build.gni b/third_party/blink/renderer/core/view_transition/build.gni index f7073f6..e7f4bcc 100644 --- a/third_party/blink/renderer/core/view_transition/build.gni +++ b/third_party/blink/renderer/core/view_transition/build.gni
@@ -5,10 +5,10 @@ blink_core_sources_view_transition = [ "dom_view_transition.cc", "dom_view_transition.h", - "page_conceal_event.cc", - "page_conceal_event.h", "page_reveal_event.cc", "page_reveal_event.h", + "page_swap_event.cc", + "page_swap_event.h", "view_transition.cc", "view_transition.h", "view_transition_content_element.cc",
diff --git a/third_party/blink/renderer/core/view_transition/page_conceal_event.cc b/third_party/blink/renderer/core/view_transition/page_swap_event.cc similarity index 76% rename from third_party/blink/renderer/core/view_transition/page_conceal_event.cc rename to third_party/blink/renderer/core/view_transition/page_swap_event.cc index dfcc1e0..9df3b41f 100644 --- a/third_party/blink/renderer/core/view_transition/page_conceal_event.cc +++ b/third_party/blink/renderer/core/view_transition/page_swap_event.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 "third_party/blink/renderer/core/view_transition/page_conceal_event.h" +#include "third_party/blink/renderer/core/view_transition/page_swap_event.h" #include "third_party/blink/public/common/page_state/page_state.h" #include "third_party/blink/renderer/core/event_interface_names.h" @@ -38,25 +38,25 @@ } // namespace -PageConcealEvent::PageConcealEvent( +PageSwapEvent::PageSwapEvent( Document& document, - mojom::blink::PageConcealEventParamsPtr page_conceal_event_params, + mojom::blink::PageSwapEventParamsPtr page_swap_event_params, DOMViewTransition* view_transition) - : Event(event_type_names::kPageconceal, Bubbles::kNo, Cancelable::kNo), + : Event(event_type_names::kPageswap, Bubbles::kNo, Cancelable::kNo), dom_view_transition_(view_transition) { - CHECK(RuntimeEnabledFeatures::PageConcealEventEnabled()); + CHECK(RuntimeEnabledFeatures::PageSwapEventEnabled()); CHECK(!view_transition || RuntimeEnabledFeatures::ViewTransitionOnNavigationEnabled()); - CHECK(!view_transition || page_conceal_event_params); + CHECK(!view_transition || page_swap_event_params); - if (page_conceal_event_params) { + if (page_swap_event_params) { NavigationApi* navigation = document.domWindow()->navigation(); // The current entry could be null for the initial about:blank Document, a // detached window, or an opaque origin. We shouldn't be creating the // activation info for the first 2 cases: - // 1. We don't fire `pageconceal` on the initial about:blank Document. - // 2. We shouldn't be firing `pageconceal` for detached windows. The event + // 1. We don't fire `pageswap` on the initial about:blank Document. + // 2. We shouldn't be firing `pageswap` for detached windows. The event // only fires when navigating away from a Document and there shouldn't be // navigations in a detached window, i.e., a disconnected iframe. // 3. The activation info is only provided for same-origin navigations. An @@ -65,7 +65,7 @@ CHECK(from); NavigationHistoryEntry* entry = nullptr; - switch (page_conceal_event_params->navigation_type) { + switch (page_swap_event_params->navigation_type) { case mojom::blink::NavigationTypeForNavigationApi::kReload: entry = from; break; @@ -74,7 +74,7 @@ // rare race conditions. Member<HistoryItem> destination_item = HistoryItem::Create(PageState::CreateFromEncodedData( - page_conceal_event_params->page_state)); + page_swap_event_params->page_state)); entry = navigation->GetExistingEntryFor( destination_item->GetNavigationApiKey(), destination_item->GetNavigationApiId()); @@ -85,34 +85,34 @@ document.domWindow(), /*key=*/WTF::CreateCanonicalUUIDString(), /*id=*/WTF::CreateCanonicalUUIDString(), - /*url=*/page_conceal_event_params->url, + /*url=*/page_swap_event_params->url, /*document_sequence_number=*/0, /*state=*/nullptr); } activation_ = MakeGarbageCollected<NavigationActivation>(); activation_->Update( - entry, from, TypeToString(page_conceal_event_params->navigation_type)); + entry, from, TypeToString(page_swap_event_params->navigation_type)); } } -PageConcealEvent::~PageConcealEvent() = default; +PageSwapEvent::~PageSwapEvent() = default; -const AtomicString& PageConcealEvent::InterfaceName() const { - return event_interface_names::kPageConcealEvent; +const AtomicString& PageSwapEvent::InterfaceName() const { + return event_interface_names::kPageSwapEvent; } -void PageConcealEvent::Trace(Visitor* visitor) const { +void PageSwapEvent::Trace(Visitor* visitor) const { visitor->Trace(activation_); visitor->Trace(dom_view_transition_); Event::Trace(visitor); } -DOMViewTransition* PageConcealEvent::viewTransition() const { +DOMViewTransition* PageSwapEvent::viewTransition() const { return dom_view_transition_.Get(); } -NavigationActivation* PageConcealEvent::activation() const { +NavigationActivation* PageSwapEvent::activation() const { return activation_.Get(); }
diff --git a/third_party/blink/renderer/core/view_transition/page_conceal_event.h b/third_party/blink/renderer/core/view_transition/page_swap_event.h similarity index 69% rename from third_party/blink/renderer/core/view_transition/page_conceal_event.h rename to third_party/blink/renderer/core/view_transition/page_swap_event.h index c0b785cb..77f4ec68 100644 --- a/third_party/blink/renderer/core/view_transition/page_conceal_event.h +++ b/third_party/blink/renderer/core/view_transition/page_swap_event.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_VIEW_TRANSITION_PAGE_CONCEAL_EVENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_VIEW_TRANSITION_PAGE_CONCEAL_EVENT_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_VIEW_TRANSITION_PAGE_SWAP_EVENT_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_VIEW_TRANSITION_PAGE_SWAP_EVENT_H_ #include "third_party/blink/public/mojom/navigation/navigation_params.mojom-blink.h" #include "third_party/blink/renderer/core/dom/events/event.h" @@ -16,17 +16,17 @@ class DOMViewTransition; class NavigationActivation; -// Implementation for the pageconceal event. Fired before the Document is hidden +// Implementation for the pageswap event. Fired before the Document is hidden // and unloaded or placed in the BFCache. // TODO(khushalsagar): Update spec link once it's settled. -class PageConcealEvent final : public Event { +class PageSwapEvent final : public Event { DEFINE_WRAPPERTYPEINFO(); public: - PageConcealEvent(Document&, - mojom::blink::PageConcealEventParamsPtr, + PageSwapEvent(Document&, + mojom::blink::PageSwapEventParamsPtr, DOMViewTransition*); - ~PageConcealEvent() override; + ~PageSwapEvent() override; const AtomicString& InterfaceName() const override; @@ -41,12 +41,12 @@ }; template <> -struct DowncastTraits<PageConcealEvent> { +struct DowncastTraits<PageSwapEvent> { static bool AllowFrom(const Event& event) { - return event.type() == event_type_names::kPageconceal; + return event.type() == event_type_names::kPageswap; } }; } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_VIEW_TRANSITION_PAGE_CONCEAL_EVENT_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_VIEW_TRANSITION_PAGE_SWAP_EVENT_H_
diff --git a/third_party/blink/renderer/core/view_transition/page_conceal_event.idl b/third_party/blink/renderer/core/view_transition/page_swap_event.idl similarity index 81% rename from third_party/blink/renderer/core/view_transition/page_conceal_event.idl rename to third_party/blink/renderer/core/view_transition/page_swap_event.idl index 3f484f9..b4e21a9 100644 --- a/third_party/blink/renderer/core/view_transition/page_conceal_event.idl +++ b/third_party/blink/renderer/core/view_transition/page_swap_event.idl
@@ -4,8 +4,8 @@ [ Exposed=Window, - RuntimeEnabled=PageConcealEvent -] interface PageConcealEvent : Event { + RuntimeEnabled=PageSwapEvent +] interface PageSwapEvent : Event { [RuntimeEnabled=ViewTransitionOnNavigation] readonly attribute ViewTransition? viewTransition; readonly attribute NavigationActivation? activation; };
diff --git a/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc b/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc index 153f545..2dc25499 100644 --- a/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc +++ b/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc
@@ -15,7 +15,7 @@ #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/view_transition/dom_view_transition.h" -#include "third_party/blink/renderer/core/view_transition/page_conceal_event.h" +#include "third_party/blink/renderer/core/view_transition/page_swap_event.h" #include "third_party/blink/renderer/core/view_transition/view_transition.h" #include "third_party/blink/renderer/core/view_transition/view_transition_utils.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" @@ -209,7 +209,7 @@ // static void ViewTransitionSupplement::SnapshotDocumentForNavigation( Document& document, - mojom::blink::PageConcealEventParamsPtr params, + mojom::blink::PageSwapEventParamsPtr params, ViewTransition::ViewTransitionStateCallback callback) { DCHECK(RuntimeEnabledFeatures::ViewTransitionOnNavigationEnabled()); auto* supplement = From(document); @@ -218,7 +218,7 @@ void ViewTransitionSupplement::StartTransition( Document& document, - mojom::blink::PageConcealEventParamsPtr params, + mojom::blink::PageSwapEventParamsPtr params, ViewTransition::ViewTransitionStateCallback callback) { if (transition_) { // We should skip a transition if one exists, regardless of how it was @@ -230,9 +230,9 @@ transition_ = ViewTransition::CreateForSnapshotForNavigation( &document, std::move(callback), this); - auto* page_conceal_event = MakeGarbageCollected<PageConcealEvent>( + auto* page_swap_event = MakeGarbageCollected<PageSwapEvent>( document, std::move(params), transition_->GetScriptDelegate()); - document.domWindow()->DispatchEvent(*page_conceal_event); + document.domWindow()->DispatchEvent(*page_swap_event); } // static
diff --git a/third_party/blink/renderer/core/view_transition/view_transition_supplement.h b/third_party/blink/renderer/core/view_transition/view_transition_supplement.h index 88aabafa..a94319d 100644 --- a/third_party/blink/renderer/core/view_transition/view_transition_supplement.h +++ b/third_party/blink/renderer/core/view_transition/view_transition_supplement.h
@@ -53,7 +53,7 @@ // |ViewTransitionStateCallback|. static void SnapshotDocumentForNavigation( Document&, - mojom::blink::PageConcealEventParamsPtr, + mojom::blink::PageSwapEventParamsPtr, ViewTransition::ViewTransitionStateCallback); // Creates a ViewTransition using cached state from the previous Document @@ -123,7 +123,7 @@ const std::optional<Vector<String>>& types, ExceptionState& exception_state); void StartTransition(Document& document, - mojom::blink::PageConcealEventParamsPtr, + mojom::blink::PageSwapEventParamsPtr, ViewTransition::ViewTransitionStateCallback callback); void StartTransition(Document& document, ViewTransitionState transition_state);
diff --git a/third_party/blink/renderer/core/view_transition/view_transition_test.cc b/third_party/blink/renderer/core/view_transition/view_transition_test.cc index ff77149d..e26fb3c 100644 --- a/third_party/blink/renderer/core/view_transition/view_transition_test.cc +++ b/third_party/blink/renderer/core/view_transition/view_transition_test.cc
@@ -1312,12 +1312,12 @@ ScriptState* script_state = v8_scope.GetScriptState(); ExceptionState& exception_state = v8_scope.GetExceptionState(); - auto page_conceal_params = mojom::blink::PageConcealEventParams::New(); - page_conceal_params->url = KURL("http://test.com"); - page_conceal_params->navigation_type = + auto page_swap_params = mojom::blink::PageSwapEventParams::New(); + page_swap_params->url = KURL("http://test.com"); + page_swap_params->navigation_type = mojom::blink::NavigationTypeForNavigationApi::kPush; ViewTransitionSupplement::SnapshotDocumentForNavigation( - GetDocument(), std::move(page_conceal_params), + GetDocument(), std::move(page_swap_params), base::BindOnce([](const ViewTransitionState&) {})); ASSERT_TRUE(ViewTransitionSupplement::From(GetDocument())->GetTransition());
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index 8d23f1a..e92f115 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -104,9 +104,8 @@ #include "third_party/blink/renderer/core/svg/svg_element.h" #include "third_party/blink/renderer/core/svg/svg_g_element.h" #include "third_party/blink/renderer/core/svg/svg_style_element.h" +#include "third_party/blink/renderer/modules/accessibility/aria_notification.h" #include "third_party/blink/renderer/modules/accessibility/ax_enums.h" -#include "ui/accessibility/ax_tree_id.h" -#include "ui/accessibility/ax_tree_source.h" #if DCHECK_IS_ON() #include "third_party/blink/renderer/modules/accessibility/ax_debug_utils.h" #endif @@ -133,6 +132,8 @@ #include "ui/accessibility/ax_enums.mojom-blink-forward.h" #include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/ax_role_properties.h" +#include "ui/accessibility/ax_tree_id.h" +#include "ui/accessibility/ax_tree_source.h" #include "ui/events/keycodes/dom/dom_code.h" #include "ui/events/keycodes/dom/keycode_converter.h" #include "ui/gfx/geometry/transform.h" @@ -1304,6 +1305,32 @@ return element->ExistingAccessibleNode(); } +namespace { + +void SerializeAriaNotificationAttributes(const AriaNotification& notification, + ui::AXNodeData* node_data) { + DCHECK(node_data); + + TruncateAndAddStringAttribute( + node_data, + ax::mojom::blink::StringAttribute::kAriaNotificationAnnouncement, + notification.Announcement()); + + TruncateAndAddStringAttribute( + node_data, ax::mojom::blink::StringAttribute::kAriaNotificationId, + notification.NotificationId()); + + node_data->AddIntAttribute( + ax::mojom::blink::IntAttribute::kAriaNotificationInterrupt, + static_cast<int32_t>(notification.Interrupt())); + + node_data->AddIntAttribute( + ax::mojom::blink::IntAttribute::kAriaNotificationPriority, + static_cast<int32_t>(notification.Priority())); +} + +} // namespace + void AXObject::Serialize(ui::AXNodeData* node_data, ui::AXMode accessibility_mode) { // Reduce redundant ancestor chain walking for display lock computations. @@ -1403,6 +1430,10 @@ SerializeOtherScreenReaderAttributes(node_data); + if (auto notification = AXObjectCache().RetrieveAriaNotification(this)) { + SerializeAriaNotificationAttributes(*notification, node_data); + } + // Return early. The following attributes are unnecessary for ignored nodes. // Exception: focusable ignored nodes are fully serialized, so that reasonable // verbalizations can be made if they actually receive focus.
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc index 0772305..7a0a056c 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -97,6 +97,7 @@ #include "third_party/blink/renderer/core/style/content_data.h" #include "third_party/blink/renderer/core/svg/svg_graphics_element.h" #include "third_party/blink/renderer/core/svg/svg_style_element.h" +#include "third_party/blink/renderer/modules/accessibility/aria_notification.h" #include "third_party/blink/renderer/modules/accessibility/ax_image_map_link.h" #include "third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h" #include "third_party/blink/renderer/modules/accessibility/ax_layout_object.h" @@ -3931,6 +3932,12 @@ } } +std::unique_ptr<AriaNotification> AXObjectCacheImpl::RetrieveAriaNotification( + const AXObject* obj) { + DCHECK(obj); + return aria_notifications_.Take(obj->AXObjectID()); +} + void AXObjectCacheImpl::UpdateTableRoleWithCleanLayout(Node* table) { if (AXObject* ax_table = Get(table)) { if (ax_table->RoleValue() == ax::mojom::blink::Role::kLayoutTable &&
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h index 478956d..35ca6e1 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -39,14 +39,12 @@ #include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h" #include "third_party/blink/public/mojom/render_accessibility.mojom-blink.h" #include "third_party/blink/public/web/web_ax_enums.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_aria_notification_options.h" #include "third_party/blink/renderer/core/accessibility/ax_object_cache_base.h" #include "third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h" #include "third_party/blink/renderer/core/aom/computed_accessible_node.h" #include "third_party/blink/renderer/core/editing/commands/selection_for_undo_step.h" #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" -#include "third_party/blink/renderer/modules/accessibility/aria_notification.h" #include "third_party/blink/renderer/modules/accessibility/ax_object.h" #include "third_party/blink/renderer/modules/accessibility/blink_ax_tree_source.h" #include "third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h" @@ -287,6 +285,9 @@ const String&, const AriaNotificationOptions*) override; + std::unique_ptr<AriaNotification> RetrieveAriaNotification( + const AXObject*) override; + void SetCanvasObjectBounds(HTMLCanvasElement*, Element*, const PhysicalRect&) override;
diff --git a/third_party/blink/renderer/modules/ml/ml_context.idl b/third_party/blink/renderer/modules/ml/ml_context.idl index 4dbdeb8..9fa5cb84 100644 --- a/third_party/blink/renderer/modules/ml/ml_context.idl +++ b/third_party/blink/renderer/modules/ml/ml_context.idl
@@ -27,8 +27,7 @@ [ RuntimeEnabled=MachineLearningNeuralNetwork, CallWith=ScriptState, - RaisesException, - Exposed=(Window, DedicatedWorker) + RaisesException ] Promise<MLComputeResult> compute( MLGraph graph, MLNamedArrayBufferViews inputs, MLNamedArrayBufferViews outputs); };
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl index 72ef2d2..6528c46 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl
@@ -318,7 +318,6 @@ [ CallWith=ScriptState, - RaisesException, - Exposed=(Window, DedicatedWorker) + RaisesException ] Promise<MLGraph> build(MLNamedOperands outputs); };
diff --git a/third_party/blink/renderer/modules/printing/web_printer.cc b/third_party/blink/renderer/modules/printing/web_printer.cc index 3704ed1..8c02c72 100644 --- a/third_party/blink/renderer/modules/printing/web_printer.cc +++ b/third_party/blink/renderer/modules/printing/web_printer.cc
@@ -3,12 +3,15 @@ // found in the LICENSE file. #include "third_party/blink/renderer/modules/printing/web_printer.h" +#include <limits> #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_print_document_description.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_print_job_template_attributes.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_printer_attributes.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_web_printing_media_collection_requested.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_web_printing_media_size_requested.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_printing_resolution.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/fileapi/blob.h" @@ -25,6 +28,10 @@ constexpr char kPrinterUnreachableError[] = "Unable to connect to the printer."; +bool IsPositiveInt32(uint32_t value) { + return value > 0 && value <= std::numeric_limits<int32_t>::max(); +} + bool ValidatePrintJobTemplateAttributes( const WebPrintJobTemplateAttributes* pjt_attributes, ExceptionState& exception_state) { @@ -49,8 +56,20 @@ return false; } } + if (pjt_attributes->hasMediaCol()) { + const auto& media_col = *pjt_attributes->mediaCol(); + const auto& media_size = *media_col.mediaSize(); + if (!IsPositiveInt32(media_size.yDimension()) || + !IsPositiveInt32(media_size.xDimension())) { + exception_state.ThrowTypeError( + "Both `xDimension` and `yDimension` must be positive integer " + "values."); + return false; + } + } return true; } + } // namespace WebPrinter::WebPrinter(ExecutionContext* execution_context,
diff --git a/third_party/blink/renderer/modules/printing/web_printer_attributes.idl b/third_party/blink/renderer/modules/printing/web_printer_attributes.idl index e41291e7..3093d7391e 100644 --- a/third_party/blink/renderer/modules/printing/web_printer_attributes.idl +++ b/third_party/blink/renderer/modules/printing/web_printer_attributes.idl
@@ -17,9 +17,31 @@ required Blob data; }; +typedef (WebPrintingRange or unsigned long) WebPrintingMediaSizeDimension; + +dictionary WebPrintingMediaSize { + WebPrintingMediaSizeDimension yDimension; + WebPrintingMediaSizeDimension xDimension; +}; + +dictionary WebPrintingMediaCollection { + DOMString mediaSizeName; + WebPrintingMediaSize mediaSize; +}; + +dictionary WebPrintingMediaSizeRequested { + required unsigned long yDimension; + required unsigned long xDimension; +}; + +dictionary WebPrintingMediaCollectionRequested { + required WebPrintingMediaSizeRequested mediaSize; +}; + dictionary WebPrintJobTemplateAttributes { unsigned long copies; + WebPrintingMediaCollectionRequested mediaCol; WebPrintingMultipleDocumentHandling multipleDocumentHandling; WebPrintingOrientationRequested orientationRequested; WebPrintingResolution printerResolution; @@ -34,6 +56,9 @@ unsigned long copiesDefault; WebPrintingRange copiesSupported; + WebPrintingMediaCollection mediaColDefault; + sequence<WebPrintingMediaCollection> mediaColDatabase; + WebPrintingMimeMediaType documentFormatDefault; sequence<WebPrintingMimeMediaType> documentFormatSupported;
diff --git a/third_party/blink/renderer/modules/printing/web_printing_type_converters.cc b/third_party/blink/renderer/modules/printing/web_printing_type_converters.cc index 80ebff4..9536894 100644 --- a/third_party/blink/renderer/modules/printing/web_printing_type_converters.cc +++ b/third_party/blink/renderer/modules/printing/web_printing_type_converters.cc
@@ -5,10 +5,15 @@ #include "third_party/blink/renderer/modules/printing/web_printing_type_converters.h" #include "third_party/blink/public/mojom/printing/web_printing.mojom-blink.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_union_unsignedlong_webprintingrange.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_print_color_mode.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_print_job_template_attributes.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_printer_attributes.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_printer_state.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_web_printing_media_collection.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_web_printing_media_collection_requested.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_web_printing_media_size.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_web_printing_media_size_requested.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_printing_mime_media_type.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_printing_multiple_document_handling.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_printing_orientation_requested.h" @@ -20,10 +25,27 @@ #include "third_party/blink/renderer/platform/resolution_units.h" namespace { +// copies: +using BlinkRange = blink::WebPrintingRange; +using MojomRangePtr = blink::mojom::blink::WebPrintingRangePtr; + // sides: using V8Sides = blink::V8WebPrintingSides; using MojomSides = blink::mojom::blink::WebPrintingSides; +// media-col: +using BlinkMediaCollection = blink::WebPrintingMediaCollection; +using BlinkMediaCollectionRequested = + blink::WebPrintingMediaCollectionRequested; +using V8MediaSizeDimension = blink::V8UnionUnsignedLongOrWebPrintingRange; +using MojomMediaCollection = blink::mojom::blink::WebPrintingMediaCollection; +using MojomMediaCollectionRequested = + blink::mojom::blink::WebPrintingMediaCollectionRequested; +using MojomMediaCollectionRequestedPtr = + blink::mojom::blink::WebPrintingMediaCollectionRequestedPtr; +using MojomMediaSizeDimensionPtr = + blink::mojom::blink::WebPrintingMediaSizeDimensionPtr; + // multiple-document-handling: using V8MultipleDocumentHandling = blink::V8WebPrintingMultipleDocumentHandling; using MojomMultipleDocumentHandling = @@ -140,6 +162,58 @@ }; template <> +struct TypeConverter<BlinkRange*, MojomRangePtr> { + static BlinkRange* Convert(const MojomRangePtr& range_in) { + auto* range = blink::MakeGarbageCollected<BlinkRange>(); + range->setFrom(range_in->from); + range->setTo(range_in->to); + return range; + } +}; + +template <> +struct TypeConverter<V8MediaSizeDimension*, MojomMediaSizeDimensionPtr> { + static V8MediaSizeDimension* Convert( + const MojomMediaSizeDimensionPtr& dimension) { + return dimension->is_range() + ? blink::MakeGarbageCollected<V8MediaSizeDimension>( + mojo::ConvertTo<BlinkRange*>(dimension->get_range())) + : blink::MakeGarbageCollected<V8MediaSizeDimension>( + dimension->get_value()); + } +}; + +template <> +struct TypeConverter<BlinkMediaCollection*, MojomMediaCollection*> { + static BlinkMediaCollection* Convert( + const MojomMediaCollection* media_col_in) { + auto* media_col = blink::MakeGarbageCollected<BlinkMediaCollection>(); + media_col->setMediaSizeName(media_col_in->media_size_name); + auto* media_size = + blink::MakeGarbageCollected<blink::WebPrintingMediaSize>(); + media_size->setYDimension(mojo::ConvertTo<V8MediaSizeDimension*>( + media_col_in->media_size->y_dimension)); + media_size->setXDimension(mojo::ConvertTo<V8MediaSizeDimension*>( + media_col_in->media_size->x_dimension)); + media_col->setMediaSize(media_size); + return media_col; + } +}; + +template <> +struct TypeConverter<MojomMediaCollectionRequestedPtr, + BlinkMediaCollectionRequested*> { + static MojomMediaCollectionRequestedPtr Convert( + const BlinkMediaCollectionRequested* media_col_in) { + auto media_col = MojomMediaCollectionRequested::New(); + media_col->media_size = { + base::checked_cast<int32_t>(media_col_in->mediaSize()->xDimension()), + base::checked_cast<int32_t>(media_col_in->mediaSize()->yDimension())}; + return media_col; + } +}; + +template <> struct TypeConverter<gfx::Size, blink::WebPrintingResolution*> { static gfx::Size Convert( const blink::WebPrintingResolution* printer_resolution) { @@ -313,10 +387,8 @@ void ProcessCopies(const mojom::blink::WebPrinterAttributes& new_attributes, WebPrinterAttributes* current_attributes) { current_attributes->setCopiesDefault(new_attributes.copies_default); - auto* copies_range = WebPrintingRange::Create(); - copies_range->setFrom(new_attributes.copies_supported->from); - copies_range->setTo(new_attributes.copies_supported->to); - current_attributes->setCopiesSupported(copies_range); + current_attributes->setCopiesSupported( + mojo::ConvertTo<BlinkRange*>(new_attributes.copies_supported)); } void ProcessDocumentFormat( @@ -328,6 +400,16 @@ V8WebPrintingMimeMediaType::Enum::kApplicationPdf)}); } +void ProcessMediaCollection( + const mojom::blink::WebPrinterAttributes& new_attributes, + WebPrinterAttributes* current_attributes) { + current_attributes->setMediaColDefault( + mojo::ConvertTo<BlinkMediaCollection*>(new_attributes.media_col_default)); + current_attributes->setMediaColDatabase( + mojo::ConvertTo<HeapVector<Member<BlinkMediaCollection>>>( + new_attributes.media_col_database)); +} + void ProcessMultipleDocumentHandling( const mojom::blink::WebPrinterAttributes& new_attributes, WebPrinterAttributes* current_attributes) { @@ -398,6 +480,7 @@ blink::ProcessCopies(*printer_attributes, attributes); blink::ProcessDocumentFormat(*printer_attributes, attributes); + blink::ProcessMediaCollection(*printer_attributes, attributes); blink::ProcessMultipleDocumentHandling(*printer_attributes, attributes); blink::ProcessOrientationRequested(*printer_attributes, attributes); blink::ProcessPrinterResolution(*printer_attributes, attributes); @@ -421,6 +504,10 @@ auto attributes = blink::mojom::blink::WebPrintJobTemplateAttributes::New(); attributes->copies = pjt_attributes->getCopiesOr(1); + if (pjt_attributes->hasMediaCol()) { + attributes->media_col = mojo::ConvertTo<MojomMediaCollectionRequestedPtr>( + pjt_attributes->mediaCol()); + } if (pjt_attributes->hasMultipleDocumentHandling()) { attributes->multiple_document_handling = mojo::ConvertTo<MojomMultipleDocumentHandling>(
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 24538e4..582a01d9a 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -2467,6 +2467,12 @@ name: "NoIdleEncodingForWebTests", status: "test", }, + // Doesn't increase the end offset on getting the range for a new line + // character. See https://crbug.com/326888905 + { + name: "NoIncreasingEndOffsetOnSplittingTextNodes", + status: "stable", + }, // Makes enter/leave Mouse and Pointer Events non-composed as per // corresponding specifications. { @@ -2716,11 +2722,6 @@ name: "OverscrollCustomization", status: "experimental", }, - { - name: "PageConcealEvent", - status: "experimental", - implied_by: ["ViewTransitionOnNavigation"], - }, // The following are developer opt-outs and opt-ins for page freezing. If // neither is specified then heuristics will be applied to determine whether // the page is eligible. @@ -2750,6 +2751,11 @@ implied_by: ["ViewTransitionOnNavigation"], }, { + name: "PageSwapEvent", + status: "experimental", + implied_by: ["ViewTransitionOnNavigation"], + }, + { name: "PaintUnderInvalidationChecking", settable_from_internals: true, },
diff --git a/third_party/blink/tools/blinkpy/tool/blink_tool.py b/third_party/blink/tools/blinkpy/tool/blink_tool.py index e0ed7f9..e28be99 100644 --- a/third_party/blink/tools/blinkpy/tool/blink_tool.py +++ b/third_party/blink/tools/blinkpy/tool/blink_tool.py
@@ -41,7 +41,6 @@ from blinkpy.common.host import Host from blinkpy.tool.commands.analyze_baselines import AnalyzeBaselines from blinkpy.tool.commands.command import HelpPrintingOptionParser -from blinkpy.tool.commands.flaky_tests import FlakyTests from blinkpy.tool.commands.help_command import HelpCommand from blinkpy.tool.commands.optimize_baselines import OptimizeBaselines from blinkpy.tool.commands.pretty_diff import PrettyDiff @@ -75,7 +74,6 @@ self.commands = [ AnalyzeBaselines(), CrashLog(), - FlakyTests(), OptimizeBaselines(), PrettyDiff(), PrintBaselines(),
diff --git a/third_party/blink/tools/blinkpy/tool/commands/flaky_tests.py b/third_party/blink/tools/blinkpy/tool/commands/flaky_tests.py deleted file mode 100644 index 0670d88..0000000 --- a/third_party/blink/tools/blinkpy/tool/commands/flaky_tests.py +++ /dev/null
@@ -1,127 +0,0 @@ -# Copyright (c) 2011 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -from __future__ import print_function - -import logging - -from blinkpy.web_tests.layout_package.bot_test_expectations import BotTestExpectationsFactory -from blinkpy.web_tests.models.typ_types import Expectation -from blinkpy.web_tests.port.base import Port -from blinkpy.tool.commands.command import Command - -_log = logging.getLogger(__name__) - - -class FlakyTests(Command): - name = 'print-flaky-tests' - help_text = 'Print out flaky tests based on results from the flakiness dashboard' - show_in_main_help = True - - FLAKINESS_DASHBOARD_URL = ( - 'https://test-results.appspot.com/dashboards/flakiness_dashboard.html' - '#testType=blink_web_tests&tests=%s') - - BUG_TEMPLATE = ( - 'https://code.google.com/p/chromium/issues/entry?owner=FILL_ME_IN&status=Assigned&' - 'labels=Pri-1,Cr-Blink,FlakyLayoutTest&summary=XXXXXXX%20is%20flaky&' - 'comment=XXXXXXX%20is%20flaky.%0A%0AIt%20failed%20twice%20and%20then' - '%20passed%20on%20the%203rd%20or%204th%20retry.%20This%20is%20too%20' - 'flaky.%20The%20test%20will%20be%20skipped%20until%20it%27s%20fixed.' - '%20If%20not%20fixed%20in%203%20months,%20it%20will%20be%20deleted%20' - 'or%20perma-skipped.%0A%0AIn%20the%20flakiness%20dashboard,%20the%20' - 'turquoise%20boxes%20are%20runs%20where%20the%20test%20failed%20and%20' - 'then%20passed%20on%20retry.%0A%0Ahttps://test-results.appspot.com' - '/dashboards/flakiness_dashboard.html%23tests=XXXXXXX') - - HEADER = ( - 'Manually add bug numbers for these and then put the lines in web_tests/TestExpectations.\n' - 'Look up the test in the flakiness dashboard first to see if the the platform\n' - 'specifiers should be made more general.\n\n' - 'Bug template:\n%s\n') % BUG_TEMPLATE - - OUTPUT = '%s\n%s\n\nFlakiness dashboard: %s\n' - - def __init__(self): - super(FlakyTests, self).__init__() - # This is sorta silly, but allows for unit testing: - self.expectations_factory = BotTestExpectationsFactory - - def _filter_build_type_specifiers(self, specifiers): - filtered = [] - for specifier in specifiers: - if specifier.lower() not in Port.ALL_BUILD_TYPES: - filtered.append(specifier) - return filtered - - def _collect_expectation_lines(self, builder_names, factory): - exps = [] - for builder_name in builder_names: - - expectations = factory.expectations_for_builder(builder_name) - - # TODO(ojan): We should also skip bots that haven't uploaded recently, - # e.g. if they're >24h stale. - if not expectations: - _log.error("Can't load flakiness data for builder: %s", - builder_name) - continue - - for line in expectations.expectation_lines( - only_consider_very_flaky=True): - # TODO(ojan): Find a way to merge specifiers instead of removing build types. - # We can't just union because some specifiers will change the meaning of others. - # For example, it's not clear how to merge [ Mac Release ] with [ Linux Debug ]. - # But, in theory we should be able to merge [ Mac Release ] and [ Mac Debug ]. - tags = self._filter_build_type_specifiers(line.tags) - exps.append( - Expectation( - tags=tags, results=line.results, test=line.test)) - return exps - - def execute(self, options, args, tool): - factory = self.expectations_factory(tool.builders) - lines = self._collect_expectation_lines( - tool.builders.all_continuous_builder_names(), factory) - lines.sort(key=lambda line: line.test) - - port = tool.port_factory.get() - # Skip any tests which are mentioned in the dashboard but not in our checkout: - fs = tool.filesystem - lines = [ - line for line in lines - if fs.exists(fs.join(port.web_tests_dir(), line.test)) - ] - - test_names = [line.test for line in lines] - flakiness_dashboard_url = self.FLAKINESS_DASHBOARD_URL % \ - ','.join(test_names) - expectations_string = '\n'.join(line.to_string() for line in lines) - - print(self.OUTPUT % - (self.HEADER, expectations_string, flakiness_dashboard_url))
diff --git a/third_party/blink/tools/blinkpy/tool/commands/flaky_tests_unittest.py b/third_party/blink/tools/blinkpy/tool/commands/flaky_tests_unittest.py deleted file mode 100644 index c81ef56..0000000 --- a/third_party/blink/tools/blinkpy/tool/commands/flaky_tests_unittest.py +++ /dev/null
@@ -1,111 +0,0 @@ -# Copyright 2014 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import optparse - -from blinkpy.tool.commands import flaky_tests -from blinkpy.tool.commands.command_test import CommandsTest -from blinkpy.tool.mock_tool import MockBlinkTool -from blinkpy.web_tests.builder_list import BuilderList -from blinkpy.web_tests.layout_package import bot_test_expectations - - -class FakeBotTestExpectations(object): - def expectation_lines(self): - return [] - - -class FakeBotTestExpectationsFactory(object): - FAILURE_MAP = { - 'C': 'CRASH', - 'F': 'FAIL', - 'N': 'NO DATA', - 'P': 'PASS', - 'T': 'TIMEOUT', - 'Y': 'NOTRUN', - 'X': 'SKIP', - 'K': 'LEAK' - } - - def __init__(self, builders): - self.builders = builders - - def _expectations_from_test_data(self, builder, test_data): - test_data[bot_test_expectations.ResultsJSON. - FAILURE_MAP_KEY] = self.FAILURE_MAP - json_dict = { - builder: test_data, - } - results = bot_test_expectations.ResultsJSON(builder, json_dict) - return bot_test_expectations.BotTestExpectations( - results, self.builders, - self.builders.specifiers_for_builder(builder)) - - def expectations_for_builder(self, builder): - if builder == 'foo-builder': - return self._expectations_from_test_data( - builder, { - 'tests': { - 'pass.html': { - 'results': [[2, 'FFFP']], - 'expected': 'PASS' - }, - } - }) - - if builder == 'bar-builder': - return self._expectations_from_test_data( - builder, { - 'tests': { - 'pass.html': { - 'results': [[2, 'TTTP']], - 'expected': 'PASS' - }, - } - }) - - return FakeBotTestExpectations() - - -class FlakyTestsTest(CommandsTest): - @staticmethod - def fake_builders_list(): - return BuilderList({ - 'foo-builder': { - 'port_name': 'dummy-port', - 'specifiers': ['Linux', 'Release'] - }, - 'bar-builder': { - 'port_name': 'dummy-port', - 'specifiers': ['Mac', 'Debug'] - }, - }) - - def test_merge_lines(self): - command = flaky_tests.FlakyTests() - factory = FakeBotTestExpectationsFactory(self.fake_builders_list()) - - lines = command._collect_expectation_lines( - ['foo-builder', 'bar-builder'], factory) - self.assertEqual(len(lines), 2) - self.assertEqual(lines[0].results, set(['FAIL', 'PASS'])) - self.assertEqual(set(lines[0].tags), set(['Linux'])) - self.assertEqual(lines[1].results, set(['TIMEOUT', 'PASS'])) - self.assertEqual(set(lines[1].tags), set(['Mac'])) - - def test_integration(self): - command = flaky_tests.FlakyTests() - tool = MockBlinkTool() - tool.builders = self.fake_builders_list() - command.expectations_factory = FakeBotTestExpectationsFactory - options = optparse.Values({'upload': True}) - expected_stdout = flaky_tests.FlakyTests.OUTPUT % ( - flaky_tests.FlakyTests.HEADER, '', - flaky_tests.FlakyTests.FLAKINESS_DASHBOARD_URL % '') + '\n' - - self.assert_execute_outputs( - command, - options=options, - tool=tool, - expected_stdout=expected_stdout)
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-skia-graphite b/third_party/blink/web_tests/FlagExpectations/enable-skia-graphite index 9583acb..e0daee2 100644 --- a/third_party/blink/web_tests/FlagExpectations/enable-skia-graphite +++ b/third_party/blink/web_tests/FlagExpectations/enable-skia-graphite
@@ -31,6 +31,10 @@ crbug.com/1518086 external/wpt/html/semantics/embedded-content/media-elements/ready-states/autoplay-hidden.optional.html [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 virtual/view-transition-mpa-serialization/external/wpt/css/css-view-transitions/pseudo-with-classes-entry.html [ Failure ] +crbug.com/626703 virtual/view-transition-wide-gamut/external/wpt/css/css-view-transitions/new-and-old-sizes-match.html [ Failure ] +crbug.com/626703 virtual/view-transition/external/wpt/css/css-view-transitions/new-content-container-writing-modes.html [ Failure ] +crbug.com/626703 virtual/view-transition/external/wpt/css/css-view-transitions/pseudo-with-classes-multiple-vt-classes.html [ Failure ] crbug.com/626703 virtual/view-transition-mpa-serialization/external/wpt/css/css-view-transitions/content-with-clip-root.html [ Failure ] crbug.com/626703 virtual/view-transition-mpa-serialization/external/wpt/css/css-view-transitions/pseudo-with-classes-match-multiple-wildcard.html [ Failure ] crbug.com/626703 virtual/view-transition-mpa-serialization/external/wpt/css/css-view-transitions/massive-element-left-of-viewport-partially-onscreen-new.html [ Failure ]
diff --git a/third_party/blink/web_tests/MSANExpectations b/third_party/blink/web_tests/MSANExpectations index 2f7b31c..63d3279 100644 --- a/third_party/blink/web_tests/MSANExpectations +++ b/third_party/blink/web_tests/MSANExpectations
@@ -114,5 +114,3 @@ crbug.com/1457275 [ Linux ] external/wpt/dom/ranges/Range-surroundContents.html [ Skip ] -# Sheriff 2024-02-28 -crbug.com/326356909 [ Linux ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/* [ Crash ]
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index 5cc81f2..91a3a457 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -2117,7 +2117,7 @@ crbug.com/1517744 external/wpt/wai-aria/role/tree-roles.html [ Skip ] # WebNN GPU backend is supported on Win11 by default. -crbug.com/1500120 [ Win10.20h2 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/* [ Skip ] +crbug.com/1500120 [ Win10.20h2 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/* [ Skip ] ######## Unload Deprecation # This is for tests in the "unload-allowed" virtual suite that
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 2dcc653c..61665e4122 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2633,24 +2633,24 @@ # ====== New tests from wpt-importer added here ====== crbug.com/626703 external/wpt/css/css-text-decor/text-shadow/svg-stroke.html [ Failure ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/batch_normalization.https.any.html [ Crash Timeout ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/batch_normalization.https.any.worker.html [ Crash Timeout ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any.html [ Crash Timeout ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any.worker.html [ Crash Timeout ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any.html [ Crash ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any.worker.html [ Crash Timeout ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/gemm.https.any.html [ Crash ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/gemm.https.any.worker.html [ Crash Timeout ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/instance_normalization.https.any.html [ Crash Timeout ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/instance_normalization.https.any.worker.html [ Crash Timeout ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/layer_normalization.https.any.html [ Crash Timeout ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/layer_normalization.https.any.worker.html [ Crash Timeout ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/matmul.https.any.html [ Crash Timeout ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/matmul.https.any.worker.html [ Crash ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.html [ Crash Timeout ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.worker.html [ Crash Timeout ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/reduction.https.any.html [ Crash ] -crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/reduction.https.any.worker.html [ Crash Timeout ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/batch_normalization.https.any.html [ Crash Timeout ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/batch_normalization.https.any.worker.html [ Crash Timeout ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any.html [ Crash Timeout ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any.worker.html [ Crash Timeout ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any.html [ Crash ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any.worker.html [ Crash Timeout ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/gemm.https.any.html [ Crash ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/gemm.https.any.worker.html [ Crash Timeout ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/instance_normalization.https.any.html [ Crash Timeout ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/instance_normalization.https.any.worker.html [ Crash Timeout ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/layer_normalization.https.any.html [ Crash Timeout ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/layer_normalization.https.any.worker.html [ Crash Timeout ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/matmul.https.any.html [ Crash Timeout ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/matmul.https.any.worker.html [ Crash ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.html [ Crash Timeout ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.worker.html [ Crash Timeout ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/reduction.https.any.html [ Crash ] +crbug.com/626703 [ Win11-arm64 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/reduction.https.any.worker.html [ Crash Timeout ] crbug.com/626703 [ Mac12-arm64 ] external/wpt/css/css-pseudo/text-selection.html [ Timeout ] crbug.com/626703 external/wpt/quirks/line-height-preserved-segment-break.html [ Failure ] crbug.com/626703 [ Win11-arm64 ] virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/smooth-scroll-in-load-event.html [ Failure Timeout ] @@ -2697,8 +2697,8 @@ crbug.com/626703 external/wpt/html/rendering/widgets/button-layout/input-type-button-clip.html [ Failure ] crbug.com/626703 external/wpt/css/css-text/text-justify/text-justify-word-separators.html [ Failure ] crbug.com/626703 external/wpt/svg/pservers/reftests/gradient-color-interpolation.svg [ Failure ] -crbug.com/626703 virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/arg_min_max.https.any.html [ Skip Timeout ] -crbug.com/626703 virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/arg_min_max.https.any.worker.html [ Crash ] +crbug.com/626703 virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/arg_min_max.https.any.html [ Skip Timeout ] +crbug.com/626703 virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/arg_min_max.https.any.worker.html [ Crash ] crbug.com/626703 external/wpt/css/css-page/page-orientation-on-landscape-001-print.html [ Failure ] crbug.com/626703 external/wpt/css/css-page/page-orientation-on-portrait-001-print.html [ Failure ] crbug.com/626703 external/wpt/css/css-page/page-orientation-on-square-001-print.html [ Failure ] @@ -2707,7 +2707,7 @@ crbug.com/626703 virtual/backface-visibility-interop/external/wpt/css/css-transforms/transform-box/svgbox-stroke-box-003.html [ Failure ] crbug.com/626703 virtual/backface-visibility-interop/external/wpt/css/css-transforms/transform-box/svgbox-stroke-box-004.html [ Failure ] crbug.com/626703 external/wpt/webnn/conformance_tests/elementwise_logical.https.any.worker.html [ Skip Timeout ] -crbug.com/626703 virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elementwise_logical.https.any.worker.html [ Skip Timeout ] +crbug.com/626703 virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/elementwise_logical.https.any.worker.html [ Skip Timeout ] crbug.com/626703 [ Mac ] external/wpt/pointerevents/pointerevent_after_target_appended.html?mouse [ Timeout ] crbug.com/626703 external/wpt/css/css-nesting/has-nesting.html [ Failure ] crbug.com/626703 [ Release Win11-arm64 ] external/wpt/png/apng/fcTL-blend-source-nearly-transparent.html [ Timeout ] @@ -6879,8 +6879,8 @@ crbug.com/326478175 wpt_internal/dom/about_srcdoc/grandparent_location_aboutsrcdoc.sub.window.html [ Failure Pass Timeout ] # Test infra bug -crbug.com/326459000 virtual/view-transition-on-navigation/wpt_internal/view-transition-on-navigation/pageconceal-push-from-click.html [ Timeout ] -crbug.com/326459000 virtual/pageconceal/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-push-from-click.html [ Timeout ] +crbug.com/326459000 virtual/view-transition-on-navigation/wpt_internal/view-transition-on-navigation/pageswap-push-from-click.html [ Timeout ] +crbug.com/326459000 virtual/pageswap/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-from-click.html [ Timeout ] crbug.com/1467464 http/tests/devtools/network/network-columns-visible.js [ Failure Pass Timeout ] crbug.com/1467464 http/tests/devtools/security/origin-view-ct-compliance.js [ Failure Pass Timeout ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 30cf3f9..edec759 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1401,7 +1401,7 @@ "owners": ["view-transitions-api@chromium.org"], "bases": ["wpt_internal/view-transition-on-navigation"], "exclusive_tests": "ALL", - "args": ["--enable-features=ViewTransitionOnNavigation,PageConcealEvent", + "args": ["--enable-features=ViewTransitionOnNavigation,PageSwapEvent", "--enable-threaded-compositing"], "expires": "May 1, 2024" }, @@ -2566,9 +2566,12 @@ "args": ["--enable-features=GenericSensorExtraClasses"], "expires": "never" }, + "Run the WebNN WPTs with the WebNN service enabled. These are confusingly ", + "named 'gpu' tests however this really means that the WebNN Mojo service ", + "is used instead of the renderer-only implementation built using XNNPACK.", { - "prefix": "webnn-service-enabled", - "platforms": ["Linux", "Win"], + "prefix": "webnn-service-with-gpu", + "platforms": ["Win"], "bases": [ "external/wpt/webnn/conformance_tests/gpu" ], @@ -2577,6 +2580,19 @@ "expires": "Jun 1, 2024", "owners": ["rafael.cintron@microsoft.com", "ningxin.hu@intel.com", "kbr@chromium.org"] }, + "The WebNN service on Linux doesn't use the GPU (for now) and can't run ", + "under MSan so a separate flag configuration is defined here.", + { + "prefix": "webnn-service-without-gpu", + "platforms": ["Linux"], + "bases": [ + "external/wpt/webnn/conformance_tests/gpu" + ], + "exclusive_tests": "ALL", + "args": ["--enable-features=WebMachineLearningNeuralNetwork"], + "expires": "Jun 1, 2024", + "owners": ["rafael.cintron@microsoft.com", "ningxin.hu@intel.com", "kbr@chromium.org"] + }, { "prefix": "unload-allowed", "platforms": ["Linux", "Mac", "Win"], @@ -2734,11 +2750,11 @@ "owners": ["evelynn.kaplan@microsoft.com", "almaher@microsoft.com"] }, { - "prefix": "pageconceal", + "prefix": "pageswap", "platforms": ["Linux", "Mac", "Win"], "exclusive_tests": "ALL", - "bases": ["external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal"], - "args": ["--enable-features=PageConcealEvent"], + "bases": ["external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap"], + "args": ["--enable-features=PageSwapEvent"], "expires": "June 1, 2024", "owners": ["khushalsagar@chromium.org", "vmpstr@chromium.org"] },
diff --git a/third_party/blink/web_tests/editing/execCommand/indent/indent_pre_with_new_lines.html b/third_party/blink/web_tests/editing/execCommand/indent/indent_pre_with_new_lines.html new file mode 100644 index 0000000..77a9300 --- /dev/null +++ b/third_party/blink/web_tests/editing/execCommand/indent/indent_pre_with_new_lines.html
@@ -0,0 +1,19 @@ +<!doctype html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../../assert_selection.js"></script> +<div id="log"></div> +<script> +test(() => { + assert_selection( + '<div contenteditable style="white-space: pre">^\nHello|</div>', + 'indent', + '<div contenteditable style="white-space: pre"><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">^\nHello|</blockquote></div>'); +}, 'Indent a block that preserves white spaces. The block has texts started with a new line.'); +test(() => { + assert_selection( + '<div contenteditable style="white-space: pre">^\n<div>Hello|</div></div>', + 'indent', + '<div contenteditable style="white-space: pre"><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">^\n<div>Hello|</div></blockquote></div>'); +}, 'Indent a block that preserves white spaces. The block has a new line text and a div.'); +</script>
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 64720ab..dc929ad 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
@@ -260306,7 +260306,7 @@ ] ], "canvas-filter-object-turbulence.html": [ - "b5b494825e7a714be3326cd052078c9b5c780a92", + "fe87d37930123e3e1113b14b620fdc5a0de08edf", [ null, [ @@ -260315,7 +260315,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 16 + ], + [ + 0, + 1000 + ] + ] + ] + ] + } ] ], "idl-conversions": { @@ -276560,7 +276576,22 @@ ], {} ] - ] + ], + "errors": { + "unknown-ancillary-error-recovery.html": [ + "df37153fd76026be581c4da33f9df0fd60e2c05b", + [ + null, + [ + [ + "/png/errors/unknown-ancillary-error-recovery-ref.html", + "==" + ] + ], + {} + ] + ] + } }, "preload": { "preload-in-data-doc.html": [ @@ -316750,7 +316781,7 @@ [] ], "highlight-pseudo-computed-expected.txt": [ - "34d8abea11982a5784f3ebf4fb0b42d9b67537cd", + "a5f58429dcaebab1c37a653544fc478c052575a8", [] ], "painting": { @@ -338786,7 +338817,7 @@ [] ], "getComputedStyle-pseudo-with-argument-expected.txt": [ - "8ca2b6411e71068844959637a3014128b868b431", + "07f3a7b88c141486ea6873c825a20dfbecfb8362", [] ], "getComputedStyle-width-scroll.tentative-expected.txt": [ @@ -376692,6 +376723,22 @@ "de7629453d91d09551fdfcbe51c90cda494e6fcf", [] ], + "errors": { + "support": { + "invalid-unknown-ancillary.png": [ + "21373a5a5aff91c2755cdc9a7f381da29658850c", + [] + ], + "no-invalid-chunks.png": [ + "6605d479854ba0d9e772b105f1b276b7c842a306", + [] + ] + }, + "unknown-ancillary-error-recovery-ref.html": [ + "cfa2cbb6f14cc95cb5930dab38fa3fb11bda49bd", + [] + ] + }, "support": { "cICP-and-iCCP.png": [ "71d88defc12b18b29d2c2dd4303e4bfb15d1a4c0", @@ -442497,6 +442544,29 @@ ] ] }, + "reading-order": { + "reading-order-items-computed.html": [ + "a8280337665d7779f59dac55d342d8224d262b94", + [ + null, + {} + ] + ], + "reading-order-items-invalid.html": [ + "eff5846e316cafce44f3c876c6a1ad9056a2d939", + [ + null, + {} + ] + ], + "reading-order-items-valid.html": [ + "d1ac7de64eb869dc585680f5bdde06839453c448", + [ + null, + {} + ] + ] + }, "textarea-display.html": [ "44634e3c3bdb7187f14c24b922d098ee273f995d", [ @@ -603872,6 +603942,15 @@ } }, "private-aggregation": { + "protected-audience-auction-report-buyers-debug-mode-surface.https.html": [ + "ddc2b6a3723071d7b0f21b0f17757a1f1c59e1c8", + [ + null, + { + "timeout": "long" + } + ] + ], "protected-audience-surface-failure.https.html": [ "b512afc25dbe99441a0c57638e7b11e2e0681f36", [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-viewport/line-height-ref.html b/third_party/blink/web_tests/external/wpt/css/css-viewport/line-height-ref.html new file mode 100644 index 0000000..c755392 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-viewport/line-height-ref.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<style>CSS zoom applies to line-height when specified and inherited</style> +<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-viewport/"> +<div style="line-height: 12px; font-size: 12px"> + Double-spaced<br>12px font text +</div> + +<hr> + +<div style="line-height: 24px; font-size: 24px;"> + Double-spaced<br>12px font zoomed text +</div> + +<hr> + +<div style="line-height: 12px; font-size: 12px"> + <div style="line-height: 24px; font-size: 24px"> + Double-spaced<br>12px font zoomed inherited text + </div> +</div> + +<hr>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-viewport/line-height.html b/third_party/blink/web_tests/external/wpt/css/css-viewport/line-height.html new file mode 100644 index 0000000..fa333be3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-viewport/line-height.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<style>CSS zoom applies to line-height when specified and inherited</style> +<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-viewport/"> +<link rel="match" href="line-height-ref.html"> +<div style="line-height: 12px; font-size: 12px"> + Double-spaced<br>12px font text +</div> + +<hr> + +<div style="line-height: 12px; font-size: 12px; zoom: 2"> + Double-spaced<br>12px font zoomed text +</div> + +<hr> + +<div style="line-height: 12px; font-size: 12px"> + <div style="zoom:2"> + Double-spaced<br>12px font zoomed inherited text + </div> +</div> + +<hr>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-viewport/width-ref.html b/third_party/blink/web_tests/external/wpt/css/css-viewport/width-ref.html new file mode 100644 index 0000000..5d2755f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-viewport/width-ref.html
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<style>CSS zoom applies to width when specified and inherited</style> +<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-viewport/"> +<style> + #parent { + width: 100px; + background: red; + } + #child-zoomed { + width: inherit; + background: lime; + width: 200px; + height: 200px; + } + #child { + width: 200px; + height: 200px; + background: green; + } +</style> +<p>You should see two squares below. One lime, and one green.</p> +<div id="parent"> + <div id="child-zoomed"></div> + <div id="child"></div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-viewport/width.html b/third_party/blink/web_tests/external/wpt/css/css-viewport/width.html new file mode 100644 index 0000000..b6d9753 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-viewport/width.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<style>CSS zoom applies to width when specified and inherited</style> +<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-viewport/"> +<link rel="match" href="width-ref.html"> +<style> + #parent { + width: 100px; + background: red; + } + #child-zoomed { + zoom: 2; + width: inherit; + background: lime; + height: 100px; + } + #child { + width: 200px; + height: 200px; + background: green; + } +</style> +<p>You should see two squares below. One lime, and one green.</p> +<div id="parent"> + <div id="child-zoomed"></div> + <div id="child"></div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-cross-origin.sub.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-cross-origin.sub.html similarity index 83% rename from third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-cross-origin.sub.html rename to third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-cross-origin.sub.html index bcc8a9f8..44479cf0 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-cross-origin.sub.html +++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-cross-origin.sub.html
@@ -1,5 +1,5 @@ <!DOCTYPE HTML> -<title>Tests pageconceal for cross-origin navigations</title> +<title>Tests pageswap for cross-origin navigations</title> <link rel="author" title="Khushal Sagar" href="mailto:khushalsagar@chromium.org"> <link rel="help" href="https://html.spec.whatwg.org/"> <script src="/resources/testharness.js"></script> @@ -7,7 +7,7 @@ <script src="/resources/testdriver.js"></script> <script src="/resources/testdriver-vendor.js"></script> <script> -const expectedUrl = "http://{{hosts[][www]}}:{{ports[http][0]}}/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-cross-origin.sub.html?new"; +const expectedUrl = "http://{{hosts[][www]}}:{{ports[http][0]}}/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-cross-origin.sub.html?new"; const params = new URLSearchParams(location.search); // The page the popup navigates to. @@ -21,7 +21,7 @@ if (is_test_page) { const expectedUrl = location.href + "?new"; - const expectedEvents = ["pageconceal", "pagehide"]; + const expectedEvents = ["pageswap", "pagehide"]; promise_test(async t => { let popup; @@ -40,15 +40,15 @@ } })); }); - }, `pageconceal on navigation from script`); + }, `pageswap on navigation from script`); } else if (is_popup_page) { onload = () => { requestAnimationFrame(() => requestAnimationFrame(() => { location.href = expectedUrl; })); - onpageconceal = (e) => { - window.opener.events.push("pageconceal"); + onpageswap = (e) => { + window.opener.events.push("pageswap"); if (e.activation != null) window.opener.events.push("activation"); if (e.viewTransition != null)
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-iframe.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-iframe.html similarity index 77% rename from third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-iframe.html rename to third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-iframe.html index 4202cf0..05ca1a9 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-iframe.html +++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-iframe.html
@@ -1,5 +1,5 @@ <!DOCTYPE HTML> -<title>Tests pageconceal dispatch on iframe Documents</title> +<title>Tests pageswap dispatch on iframe Documents</title> <link rel="author" title="Khushal Sagar" href="mailto:khushalsagar@chromium.org"> <link rel="help" href="https://html.spec.whatwg.org/"> <script src="/resources/testharness.js"></script> @@ -12,18 +12,18 @@ function runTest(frame) { let frameWindow = frame.contentWindow; - let pageconcealfired = false; + let pageswapfired = false; let expectedUrl = frameWindow.location.href + '?new'; - frameWindow.onpageconceal = (e) => { - assert_equals(e.activation.entry.url, expectedUrl, 'activation url incorrect in pageconceal'); - assert_equals(e.activation.navigationType, "push", 'navigation type incorrect in pageconceal'); - assert_equals(e.activation.from, frameWindow.navigation.currentEntry, 'from entry incorrect in pageconceal'); + frameWindow.onpageswap = (e) => { + assert_equals(e.activation.entry.url, expectedUrl, 'activation url incorrect in pageswap'); + assert_equals(e.activation.navigationType, "push", 'navigation type incorrect in pageswap'); + assert_equals(e.activation.from, frameWindow.navigation.currentEntry, 'from entry incorrect in pageswap'); assert_false(e.activation.entry.sameDocument, 'new entry must be cross-document'); - pageconcealfired = true; + pageswapfired = true; } frameWindow.onpagehide = (e) => { - assert_true(pageconcealfired, 'pageconceal not fired'); + assert_true(pageswapfired, 'pageswap not fired'); done(); }
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-push-from-click.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-from-click.html similarity index 85% rename from third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-push-from-click.html rename to third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-from-click.html index a2a6eb9..936158c 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-push-from-click.html +++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-from-click.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>pageconceal navigationactivation for push navigations from user click</title> +<title>pageswap navigationactivation for push navigations from user click</title> <link rel="help" href="https://html.spec.whatwg.org/"> <link rel="author" href="mailto:khushalsagar@chromium.org"> <script src="/resources/testharness.js"></script> @@ -21,7 +21,7 @@ if (is_test_page) { const expectedUrl = location.href + "?new"; - const expectedEvents = ["pageconceal", expectedUrl, "push","from", "pagehide"]; + const expectedEvents = ["pageswap", expectedUrl, "push","from", "pagehide"]; promise_test(async t => { let popup; @@ -51,10 +51,10 @@ } })); }); - }, `pageconceal on navigation from user click`); + }, `pageswap on navigation from user click`); } else if (is_popup_page) { - onpageconceal = (e) => { - window.opener.events.push("pageconceal"); + onpageswap = (e) => { + window.opener.events.push("pageswap"); if (e.viewTransition != null) window.opener.events.push("transition"); window.opener.events.push(e.activation.entry.url); @@ -70,5 +70,5 @@ } </script> <body> - <a id="nav_link" href='/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-push-from-click.html?new'>Click me</a> + <a id="nav_link" href='/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-from-click.html?new'>Click me</a> </body>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-push-navigation-hidden-document.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation-hidden-document.html similarity index 87% rename from third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-push-navigation-hidden-document.html rename to third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation-hidden-document.html index fdff57c..0a69923 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-push-navigation-hidden-document.html +++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation-hidden-document.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>Tests pageconceal dispatch on hidden Documents</title> +<title>Tests pageswap dispatch on hidden Documents</title> <link rel="author" title="Khushal Sagar" href="mailto:khushalsagar@chromium.org"> <link rel="author" href="mailto:khushalsagar@chromium.org"> <script src="/resources/testharness.js"></script> @@ -21,7 +21,7 @@ if (is_test_page) { const expectedUrl = location.href + "?new"; - const expectedEvents = ["pageconceal", expectedUrl, "push","from", "pagehide"]; + const expectedEvents = ["pageswap", expectedUrl, "push","from", "pagehide"]; promise_test(async t => { let popup; @@ -40,7 +40,7 @@ } })); }); - }, `pageconceal on navigation from script`); + }, `pageswap on navigation from script`); } else if (is_popup_page) { onload = async () => { await test_driver.minimize_window(); @@ -50,8 +50,8 @@ location.href = location.href.split('?')[0] + '?new'; }; - onpageconceal = (e) => { - window.opener.events.push("pageconceal"); + onpageswap = (e) => { + window.opener.events.push("pageswap"); if (e.viewTransition != null) window.opener.events.push("transition"); window.opener.events.push(e.activation.entry.url);
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-push-navigation.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation.html similarity index 86% rename from third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-push-navigation.html rename to third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation.html index 57e12d9e..4542d7cae 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-push-navigation.html +++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>pageconceal navigationactivation for push navigations</title> +<title>pageswap navigationactivation for push navigations</title> <link rel="help" href="https://html.spec.whatwg.org/"> <link rel="author" href="mailto:khushalsagar@chromium.org"> <script src="/resources/testharness.js"></script> @@ -19,7 +19,7 @@ if (is_test_page) { const expectedUrl = location.href + "?new"; - const expectedEvents = ["pageconceal", expectedUrl, "push","from", "pagehide"]; + const expectedEvents = ["pageswap", expectedUrl, "push","from", "pagehide"]; promise_test(async t => { let popup; @@ -38,15 +38,15 @@ } })); }); - }, `pageconceal on navigation from script`); + }, `pageswap on navigation from script`); } else if (is_popup_page) { onload = () => { requestAnimationFrame(() => requestAnimationFrame(() => { location.href = location.href.split('?')[0] + '?new'; })); - onpageconceal = (e) => { - window.opener.events.push("pageconceal"); + onpageswap = (e) => { + window.opener.events.push("pageswap"); if (e.viewTransition != null) window.opener.events.push("transition"); window.opener.events.push(e.activation.entry.url);
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-push-with-redirect.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-redirect.html similarity index 80% rename from third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-push-with-redirect.html rename to third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-redirect.html index 9ad5ee7..8252fff8 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-push-with-redirect.html +++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-redirect.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>pageconceal navigationactivation for push navigations with a same-origin redirect</title> +<title>pageswap navigationactivation for push navigations with a same-origin redirect</title> <link rel="help" href="https://html.spec.whatwg.org/"> <link rel="author" href="mailto:khushalsagar@chromium.org"> <script src="/resources/testharness.js"></script> @@ -19,7 +19,7 @@ if (is_test_page) { const expectedUrl = location.href + "?new"; - const expectedEvents = ["pageconceal", expectedUrl, "push","from", "pagehide"]; + const expectedEvents = ["pageswap", expectedUrl, "push","from", "pagehide"]; promise_test(async t => { let popup; @@ -38,15 +38,15 @@ } })); }); - }, `pageconceal on navigation with same-origin redirect`); + }, `pageswap on navigation with same-origin redirect`); } else if (is_popup_page) { onload = () => { requestAnimationFrame(() => requestAnimationFrame(() => { - location.href = "/common/redirect.py?location=/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-push-with-redirect.html?new"; + location.href = "/common/redirect.py?location=/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-redirect.html?new"; })); - onpageconceal = (e) => { - window.opener.events.push("pageconceal"); + onpageswap = (e) => { + window.opener.events.push("pageswap"); if (e.viewTransition != null) window.opener.events.push("transition"); window.opener.events.push(e.activation.entry.url);
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-reload-navigation.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-reload-navigation.html similarity index 86% rename from third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-reload-navigation.html rename to third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-reload-navigation.html index 0dd135c..f7539eb 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-reload-navigation.html +++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-reload-navigation.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>pageconceal navigationactivation for replace navigations</title> +<title>pageswap navigationactivation for replace navigations</title> <link rel="help" href="https://html.spec.whatwg.org/"> <link rel="author" href="mailto:khushalsagar@chromium.org"> <script src="/resources/testharness.js"></script> @@ -17,7 +17,7 @@ if (is_test_page) { const expectedUrl = location.href.split('?')[0] + "?popup"; - const expectedEvents = ["pageconceal", "entry", "reload","from", "pagehide"]; + const expectedEvents = ["pageswap", "entry", "reload","from", "pagehide"]; promise_test(async t => { let popup; @@ -37,7 +37,7 @@ } })); }); - }, `pageconceal on replace navigation from script`); + }, `pageswap on replace navigation from script`); } else if (is_popup_page) { onload = () => { requestAnimationFrame(() => requestAnimationFrame(() => { @@ -45,8 +45,8 @@ location.reload(); })); - onpageconceal = (e) => { - window.opener.events.push("pageconceal"); + onpageswap = (e) => { + window.opener.events.push("pageswap"); if (e.viewTransition != null) window.opener.events.push("transition"); if (e.activation.entry == navigation.currentEntry)
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-replace-navigation.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-navigation.html similarity index 85% rename from third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-replace-navigation.html rename to third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-navigation.html index 012439a..f6b3f74 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-replace-navigation.html +++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-navigation.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>pageconceal navigationactivation for replace navigations</title> +<title>pageswap navigationactivation for replace navigations</title> <link rel="help" href="https://html.spec.whatwg.org/"> <link rel="author" href="mailto:khushalsagar@chromium.org"> <script src="/resources/testharness.js"></script> @@ -19,7 +19,7 @@ if (is_test_page) { const expectedUrl = location.href.split('?')[0] + "?new"; - const expectedEvents = ["pageconceal", expectedUrl, "replace","from", "pagehide"]; + const expectedEvents = ["pageswap", expectedUrl, "replace","from", "pagehide"]; promise_test(async t => { let popup; @@ -38,15 +38,15 @@ } })); }); - }, `pageconceal on replace navigation from script`); + }, `pageswap on replace navigation from script`); } else if (is_popup_page) { onload = () => { requestAnimationFrame(() => requestAnimationFrame(() => { location.replace(location.href.split('?')[0] + '?new'); })); - onpageconceal = (e) => { - window.opener.events.push("pageconceal"); + onpageswap = (e) => { + window.opener.events.push("pageswap"); if (e.viewTransition != null) window.opener.events.push("transition"); window.opener.events.push(e.activation.entry.url);
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-traverse-navigation-no-bfcache.https.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-no-bfcache.https.html similarity index 88% rename from third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-traverse-navigation-no-bfcache.https.html rename to third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-no-bfcache.https.html index c34c443b..9e8c0e1 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageconceal/pageconceal-traverse-navigation-no-bfcache.https.html +++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-no-bfcache.https.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>pageconceal navigationactivation for traverse navigations</title> +<title>pageswap navigationactivation for traverse navigations</title> <link rel="help" href="https://html.spec.whatwg.org/"> <link rel="author" href="mailto:khushalsagar@chromium.org"> <script src="/resources/testharness.js"></script> @@ -18,7 +18,7 @@ // The test page which opens a popup for the navigation sequence. if (is_test_page) { const expectedUrl = location.href.split('?')[0] + "?popup"; - const expectedEvents = ["pageconceal", expectedUrl, "traverse","from", "pagehide"]; + const expectedEvents = ["pageswap", expectedUrl, "traverse","from", "pagehide"]; promise_test(async t => { let popup; @@ -37,7 +37,7 @@ } })); }); - }, `pageconceal on traverse navigation from script`); + }, `pageswap on traverse navigation from script`); } else if (is_initial_page_first_navigation) { // The popup page which the user navigates back to. onload = async () => { @@ -57,8 +57,8 @@ })); }; - onpageconceal = (e) => { - window.opener.events.push("pageconceal"); + onpageswap = (e) => { + window.opener.events.push("pageswap"); if (e.viewTransition != null) window.opener.events.push("transition"); window.opener.events.push(e.activation.entry.url);
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html index ff0eebe..ea5600b0 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html
@@ -1,28 +1,28 @@ <body> <svg style="display:none">> <filter id="base"> - <feTurbulence baseFrequency="0.025"/> + <feTurbulence baseFrequency="0.03125"/> </filter> <filter id="base2d"> - <feTurbulence baseFrequency="0.025, 0.1"/> + <feTurbulence baseFrequency="0.03125, 0.125"/> </filter> <filter id="highFrequency"> - <feTurbulence baseFrequency="0.05"/> + <feTurbulence baseFrequency="0.0625"/> </filter> <filter id="seed"> - <feTurbulence baseFrequency="0.025" seed="100"/> + <feTurbulence baseFrequency="0.03125" seed="100"/> </filter> <filter id="numOctaves"> - <feTurbulence baseFrequency="0.025" numOctaves="2"/> + <feTurbulence baseFrequency="0.03125" numOctaves="2"/> </filter> <filter id="empty"> <feTurbulence/> </filter> <filter id="fractalNoise"> - <feTurbulence baseFrequency="0.025" type="fractalNoise"/> + <feTurbulence baseFrequency="0.03125" type="fractalNoise"/> </filter> <filter id="stitchTiles"> - <feTurbulence baseFrequency="0.025" stitchTiles="noStitch"/> + <feTurbulence baseFrequency="0.03125" stitchTiles="noStitch"/> </filter> </body> <script> @@ -34,4 +34,4 @@ ctx.filter = `url(#${tc.id})`; ctx.fillRect(0, 0, 1, 1); } -</script> \ No newline at end of file +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html index fe87d37..eb0803e4 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html
@@ -1,19 +1,18 @@ <head> <link rel="match" href="canvas-filter-object-blur-expected.html"> - <meta name=fuzzy content="maxDifference=0-16; totalPixels=0-1000"> </head> <body> </body> <script> const testCases = [ - {baseFrequency: 0.025}, - {baseFrequency: [0.025, 0.1]}, - {baseFrequency: 0.05}, - {baseFrequency: 0.025, seed: 100}, - {baseFrequency: 0.025, numOctaves: 2}, + {baseFrequency: 0.03125}, + {baseFrequency: [0.03125, 0.125]}, + {baseFrequency: 0.0625}, + {baseFrequency: 0.03125, seed: 100}, + {baseFrequency: 0.03125, numOctaves: 2}, {}, - {baseFrequency: 0.025, type: "fractalNoise"}, - {baseFrequency: 0.025, stitchTiles: "stitch"}, + {baseFrequency: 0.03125, type: "fractalNoise"}, + {baseFrequency: 0.03125, stitchTiles: "stitch"}, ] for (tc of testCases) {
diff --git a/third_party/blink/web_tests/external/wpt/png/errors/support/invalid-unknown-ancillary.png b/third_party/blink/web_tests/external/wpt/png/errors/support/invalid-unknown-ancillary.png new file mode 100644 index 0000000..21373a5a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/png/errors/support/invalid-unknown-ancillary.png Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/png/errors/support/no-invalid-chunks.png b/third_party/blink/web_tests/external/wpt/png/errors/support/no-invalid-chunks.png new file mode 100644 index 0000000..6605d47 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/png/errors/support/no-invalid-chunks.png Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/png/errors/unknown-ancillary-error-recovery-ref.html b/third_party/blink/web_tests/external/wpt/png/errors/unknown-ancillary-error-recovery-ref.html new file mode 100644 index 0000000..cfa2cbb6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/png/errors/unknown-ancillary-error-recovery-ref.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<meta charset="utf-8"> +<title>PNG Third Edition: Decoder error recovery, invalid ancillary</title> +<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org"> +<style> + .test { + width: 32px; + height: 32px; + background-color: green; + } +</style> +<body> + <p>Test passes if you see a rainbow square, and not a red one.</p> + <div class="test"><img src="support/no-invalid-chunks.png" alt=""></div> +</body> +</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/png/errors/unknown-ancillary-error-recovery.html b/third_party/blink/web_tests/external/wpt/png/errors/unknown-ancillary-error-recovery.html new file mode 100644 index 0000000..df37153 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/png/errors/unknown-ancillary-error-recovery.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<meta charset="utf-8"> +<title>PNG Third Edition: Decoder error recovery, invalid ancillary</title> +<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org"> +<link rel="help" href="https://www.w3.org/TR/png-3/#13Decoders.Errors"> +<link rel="help" href="https://github.com/w3c/PNG-spec/issues/320"> +<link rel="match" href="unknown-ancillary-error-recovery-ref.html"> +<meta name="assert" content="Encountering an unknown ancillary chunk is never an error. The chunk can simply be ignored."> +<style> + .test { + width: 32px; + height: 32px; + background-color: red; + } +</style> +<body> + <p>Test passes if you see a rainbow square, and not a red one.</p> + <div class="test"><img src="support/invalid-unknown-ancillary.png" alt=""></div> +</body> +</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt index 4c92b68..147c50e 100644 --- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt +++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
@@ -183,10 +183,10 @@ PASS oldChildWindow.onoffline is newChildWindow.onoffline PASS oldChildWindow.ononline is newChildWindow.ononline PASS oldChildWindow.onoverscroll is newChildWindow.onoverscroll -PASS oldChildWindow.onpageconceal is newChildWindow.onpageconceal PASS oldChildWindow.onpagehide is newChildWindow.onpagehide PASS oldChildWindow.onpagereveal is newChildWindow.onpagereveal PASS oldChildWindow.onpageshow is newChildWindow.onpageshow +PASS oldChildWindow.onpageswap is newChildWindow.onpageswap PASS oldChildWindow.onpause is newChildWindow.onpause PASS oldChildWindow.onplay is newChildWindow.onplay PASS oldChildWindow.onplaying is newChildWindow.onplaying
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt index 4176fe4..79771b6 100644 --- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt +++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt
@@ -127,10 +127,10 @@ PASS childWindow.onoffline is null PASS childWindow.ononline is null PASS childWindow.onoverscroll is null -PASS childWindow.onpageconceal is null PASS childWindow.onpagehide is null PASS childWindow.onpagereveal is null PASS childWindow.onpageshow is null +PASS childWindow.onpageswap is null PASS childWindow.onpause is null PASS childWindow.onplay is null PASS childWindow.onplaying is null
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt index c929a19c..51545f5e 100644 --- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt +++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt
@@ -127,10 +127,10 @@ PASS childWindow.onoffline is null PASS childWindow.ononline is null PASS childWindow.onoverscroll is null -PASS childWindow.onpageconceal is null PASS childWindow.onpagehide is null PASS childWindow.onpagereveal is null PASS childWindow.onpageshow is null +PASS childWindow.onpageswap is null PASS childWindow.onpause is null PASS childWindow.onplay is null PASS childWindow.onplaying is null
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/arg_min_max.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/arg_min_max.https.any-expected.txt similarity index 100% copy from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/arg_min_max.https.any.worker-expected.txt copy to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/arg_min_max.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/arg_min_max.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/arg_min_max.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/arg_min_max.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/arg_min_max.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/batch_normalization.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/batch_normalization.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/batch_normalization.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/batch_normalization.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/batch_normalization.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/batch_normalization.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/batch_normalization.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/batch_normalization.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/cast.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/cast.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/cast.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/cast.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/cast.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/cast.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/cast.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/cast.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/clamp.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/clamp.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/clamp.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/clamp.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/clamp.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/clamp.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/clamp.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/clamp.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/concat.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/concat.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/concat.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/concat.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/concat.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/concat.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/concat.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/concat.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/constant.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/constant.https.any-expected.txt similarity index 100% copy from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/constant.https.any-expected.txt copy to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/constant.https.any-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/constant.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/constant.https.any.worker-expected.txt similarity index 100% copy from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/constant.https.any.worker-expected.txt copy to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/constant.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elementwise_logical.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/elementwise_logical.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elementwise_logical.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/elementwise_logical.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elementwise_logical.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/elementwise_logical.https.any.worker-expected.txt similarity index 100% copy from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elementwise_logical.https.any-expected.txt copy to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/elementwise_logical.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elementwise_unary.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/elementwise_unary.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elementwise_unary.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/elementwise_unary.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elementwise_unary.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/elementwise_unary.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elementwise_unary.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/elementwise_unary.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elu.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/elu.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elu.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/elu.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elu.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/elu.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elu.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/elu.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/expand.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/expand.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/expand.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/expand.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/expand.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/expand.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/expand.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/expand.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/gather.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/gather.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/gather.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/gather.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/gather.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/gather.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/gather.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/gather.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/gemm.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/gemm.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/gemm.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/gemm.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/gemm.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/gemm.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/gemm.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/gemm.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/hard_sigmoid.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/hard_sigmoid.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/hard_sigmoid.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/hard_sigmoid.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/hard_sigmoid.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/hard_sigmoid.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/hard_sigmoid.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/hard_sigmoid.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/hard_swish.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/hard_swish.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/hard_swish.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/hard_swish.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/hard_swish.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/hard_swish.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/hard_swish.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/hard_swish.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/instance_normalization.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/instance_normalization.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/instance_normalization.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/instance_normalization.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/instance_normalization.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/instance_normalization.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/instance_normalization.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/instance_normalization.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/layer_normalization.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/layer_normalization.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/layer_normalization.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/layer_normalization.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/layer_normalization.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/layer_normalization.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/layer_normalization.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/layer_normalization.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/leaky_relu.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/leaky_relu.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/leaky_relu.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/leaky_relu.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/leaky_relu.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/leaky_relu.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/leaky_relu.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/leaky_relu.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/linear.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/linear.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/linear.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/linear.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/linear.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/linear.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/linear.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/linear.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/matmul.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/matmul.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/matmul.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/matmul.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/matmul.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/matmul.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/matmul.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/matmul.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pad.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/pad.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pad.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/pad.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pad.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/pad.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pad.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/pad.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pooling.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/pooling.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pooling.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/pooling.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/prelu.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/prelu.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/prelu.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/prelu.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/prelu.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/prelu.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/prelu.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/prelu.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/reduction.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/reduction.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/reduction.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/reduction.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/reduction.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/reduction.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/reduction.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/reduction.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/relu.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/relu.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/relu.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/relu.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/relu.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/relu.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/relu.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/relu.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/reshape.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/reshape.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/reshape.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/reshape.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/reshape.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/reshape.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/reshape.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/reshape.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/sigmoid.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/sigmoid.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/sigmoid.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/sigmoid.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/sigmoid.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/sigmoid.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/sigmoid.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/sigmoid.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/slice.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/slice.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/slice.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/slice.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/slice.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/slice.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/slice.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/slice.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softmax.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/softmax.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softmax.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/softmax.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softmax.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/softmax.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softmax.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/softmax.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softplus.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/softplus.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softplus.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/softplus.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softplus.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/softplus.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softplus.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/softplus.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softsign.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/softsign.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softsign.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/softsign.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softsign.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/softsign.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softsign.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/softsign.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/split.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/split.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/split.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/split.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/split.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/split.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/split.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/split.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/tanh.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/tanh.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/tanh.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/tanh.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/tanh.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/tanh.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/tanh.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/tanh.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/transpose.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/transpose.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/transpose.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/transpose.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/transpose.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/transpose.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/transpose.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/transpose.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/triangular.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/triangular.https.any-expected.txt similarity index 100% copy from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/triangular.https.any-expected.txt copy to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/triangular.https.any-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/triangular.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/triangular.https.any.worker-expected.txt similarity index 100% copy from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/triangular.https.any.worker-expected.txt copy to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/triangular.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/where.https.any-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/where.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/where.https.any-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/where.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/where.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/where.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/linux/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/where.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/linux/virtual/webnn-service-without-gpu/external/wpt/webnn/conformance_tests/gpu/where.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/mac-mac12/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/smooth-scroll-in-load-event-expected.txt b/third_party/blink/web_tests/platform/mac-mac12/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/smooth-scroll-in-load-event-expected.txt new file mode 100644 index 0000000..2709251 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac12/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/smooth-scroll-in-load-event-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] Smooth scroll in load event handler + assert_equals: Final value of scrollLeft expected 800 but got 0 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/smooth-scroll-in-load-event-expected.txt b/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/smooth-scroll-in-load-event-expected.txt new file mode 100644 index 0000000..2709251 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/smooth-scroll-in-load-event-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] Smooth scroll in load event handler + assert_equals: Final value of scrollLeft expected 800 but got 0 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/cast.https.any-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/smooth-scroll-in-load-event-expected.txt similarity index 100% copy from third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/cast.https.any-expected.txt copy to third_party/blink/web_tests/platform/mac/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/smooth-scroll-in-load-event-expected.txt
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pooling.https.any-expected.txt b/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/pooling.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pooling.https.any-expected.txt rename to third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/pooling.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/cast.https.any-expected.txt b/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/cast.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/cast.https.any-expected.txt rename to third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/cast.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/cast.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/cast.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/cast.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/cast.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/constant.https.any-expected.txt b/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/constant.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/constant.https.any-expected.txt rename to third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/constant.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/constant.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/constant.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/constant.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/constant.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/conv2d.https.any-expected.txt b/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/conv2d.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/conv2d.https.any-expected.txt rename to third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/conv2d.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/conv2d.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/conv2d.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/conv2d.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/conv2d.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/pooling.https.any-expected.txt b/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/pooling.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/pooling.https.any-expected.txt rename to third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/pooling.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/pooling.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/pooling.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/pooling.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/pooling.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/triangular.https.any-expected.txt b/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/triangular.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/triangular.https.any-expected.txt rename to third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/triangular.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/triangular.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/triangular.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-enabled/external/wpt/webnn/gpu/triangular.https.any.worker-expected.txt rename to third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/gpu/triangular.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/virtual/pageconceal/README.md b/third_party/blink/web_tests/virtual/pageconceal/README.md deleted file mode 100644 index ccaa9522..0000000 --- a/third_party/blink/web_tests/virtual/pageconceal/README.md +++ /dev/null
@@ -1 +0,0 @@ -This is a suite to run tests which dispatch a pageconceal event.
diff --git a/third_party/blink/web_tests/virtual/pageswap/README.md b/third_party/blink/web_tests/virtual/pageswap/README.md new file mode 100644 index 0000000..d4119d5 --- /dev/null +++ b/third_party/blink/web_tests/virtual/pageswap/README.md
@@ -0,0 +1 @@ +This is a suite to run tests which dispatch a pageswap event.
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/README.md b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/README.md similarity index 75% copy from third_party/blink/web_tests/virtual/webnn-service-enabled/README.md copy to third_party/blink/web_tests/virtual/webnn-service-with-gpu/README.md index 358a6dc..2d9b8af95 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-enabled/README.md +++ b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/README.md
@@ -1 +1,2 @@ # This suite runs tests with --enable-features=WebMachineLearningNeuralNetwork +# and --use-gpu-in-tests.
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/cast.https.any-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/cast.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/cast.https.any-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/cast.https.any-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/cast.https.any.worker-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/cast.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/cast.https.any.worker-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/cast.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/constant.https.any-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/constant.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/constant.https.any-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/constant.https.any-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/constant.https.any.worker-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/constant.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/constant.https.any.worker-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/constant.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any.worker-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any.worker-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/conv2d.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any.worker-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any.worker-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/conv_transpose2d.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elu.https.any-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/elu.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elu.https.any-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/elu.https.any-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elu.https.any.worker-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/elu.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/elu.https.any.worker-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/elu.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/matmul.https.any-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/matmul.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/matmul.https.any-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/matmul.https.any-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/matmul.https.any.worker-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/matmul.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/matmul.https.any.worker-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/matmul.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pooling.https.any-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/pooling.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pooling.https.any-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/pooling.https.any-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.worker-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.worker-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/pooling.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softplus.https.any-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/softplus.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softplus.https.any-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/softplus.https.any-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softplus.https.any.worker-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/softplus.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/softplus.https.any.worker-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/softplus.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/squeeze.https.any-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/squeeze.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/squeeze.https.any-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/squeeze.https.any-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/squeeze.https.any.worker-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/squeeze.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/squeeze.https.any.worker-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/squeeze.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/triangular.https.any-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/triangular.https.any-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/triangular.https.any-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/triangular.https.any-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/triangular.https.any.worker-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/triangular.https.any.worker-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/conformance_tests/gpu/triangular.https.any.worker-expected.txt rename to third_party/blink/web_tests/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gpu/triangular.https.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/README.md b/third_party/blink/web_tests/virtual/webnn-service-without-gpu/README.md similarity index 79% rename from third_party/blink/web_tests/virtual/webnn-service-enabled/README.md rename to third_party/blink/web_tests/virtual/webnn-service-without-gpu/README.md index 358a6dc..3daffa39 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-enabled/README.md +++ b/third_party/blink/web_tests/virtual/webnn-service-without-gpu/README.md
@@ -1 +1 @@ -# This suite runs tests with --enable-features=WebMachineLearningNeuralNetwork +# This suite runs tests with --enable-features=WebMachineLearningNeuralNetwork.
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 3d1e05b1..1cbfa6dd 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
@@ -6974,13 +6974,13 @@ getter deltaX getter deltaY method constructor -interface PageConcealEvent : Event - attribute @@toStringTag - getter activation - method constructor interface PageRevealEvent : Event attribute @@toStringTag method constructor +interface PageSwapEvent : Event + attribute @@toStringTag + getter activation + method constructor interface PageTransitionEvent : Event attribute @@toStringTag getter persisted @@ -9418,6 +9418,7 @@ method append method clear method constructor + method createWorklet method delete method run method selectURL @@ -9426,6 +9427,8 @@ attribute @@toStringTag method addModule method constructor + method run + method selectURL interface SharedWorker : EventTarget attribute @@toStringTag getter onerror @@ -12722,10 +12725,10 @@ getter onoffline getter ononline getter onoverscroll - getter onpageconceal getter onpagehide getter onpagereveal getter onpageshow + getter onpageswap getter onpause getter onplay getter onplaying @@ -12954,10 +12957,10 @@ setter onoffline setter ononline setter onoverscroll - setter onpageconceal setter onpagehide setter onpagereveal setter onpageshow + setter onpageswap setter onpause setter onplay setter onplaying
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-fired-before-old-state-capture-ref.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-fired-before-old-state-capture-ref.html similarity index 80% rename from third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-fired-before-old-state-capture-ref.html rename to third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-fired-before-old-state-capture-ref.html index 495fb6dd..bda3330 100644 --- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-fired-before-old-state-capture-ref.html +++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-fired-before-old-state-capture-ref.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>View transitions: Test pageconceal fires before document capture (ref)</title> +<title>View transitions: Test pageswap fires before document capture (ref)</title> <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> <link rel="author" href="mailto:khushalsagar@chromium.org"> <style>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-fired-before-old-state-capture.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-fired-before-old-state-capture.html similarity index 87% rename from third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-fired-before-old-state-capture.html rename to third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-fired-before-old-state-capture.html index 3b3e5390..8ce791b 100644 --- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-fired-before-old-state-capture.html +++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-fired-before-old-state-capture.html
@@ -1,9 +1,9 @@ <!DOCTYPE html> <html class="reftest-wait"> -<title>View transitions: Test pageconceal fires before document capture</title> +<title>View transitions: Test pageswap fires before document capture</title> <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> <link rel="author" href="mailto:khushalsagar@chromium.org"> -<link rel="match" href="pageconceal-fired-before-old-state-capture-ref.html"> +<link rel="match" href="pageswap-fired-before-old-state-capture-ref.html"> <script src="/common/reftest-wait.js"></script> <script> const params = new URLSearchParams(location.search); @@ -18,7 +18,7 @@ }); }); } else { - addEventListener('pageconceal', e => { + addEventListener('pageswap', e => { document.documentElement.classList.add('oldPage'); });
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-push-from-click.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-push-from-click.html similarity index 85% rename from third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-push-from-click.html rename to third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-push-from-click.html index f9abf559..3705039 100644 --- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-push-from-click.html +++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-push-from-click.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>View transitions: pageconceal navigationactivation for push navigations from user click</title> +<title>View transitions: pageswap navigationactivation for push navigations from user click</title> <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> <link rel="author" href="mailto:khushalsagar@chromium.org"> <script src="/resources/testharness.js"></script> @@ -27,7 +27,7 @@ if (is_test_page) { const expectedUrl = location.href + "?new"; - const expectedEvents = ["pageconceal", "transition", expectedUrl, "push","from", "pagehide"]; + const expectedEvents = ["pageswap", "transition", expectedUrl, "push","from", "pagehide"]; promise_test(async t => { let popup; @@ -57,10 +57,10 @@ } })); }); - }, `pageconceal on navigation from user click`); + }, `pageswap on navigation from user click`); } else if (is_popup_page) { - onpageconceal = (e) => { - window.opener.events.push("pageconceal"); + onpageswap = (e) => { + window.opener.events.push("pageswap"); if (e.viewTransition != null) window.opener.events.push("transition"); window.opener.events.push(e.activation.entry.url); @@ -76,5 +76,5 @@ } </script> <body> - <a id="nav_link" href='/wpt_internal/view-transition-on-navigation/pageconceal-push-from-click.html?new'>Click me</a> + <a id="nav_link" href='/wpt_internal/view-transition-on-navigation/pageswap-push-from-click.html?new'>Click me</a> </body>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-push-navigation.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-push-navigation.html similarity index 85% rename from third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-push-navigation.html rename to third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-push-navigation.html index 623b9ab..50a43e70 100644 --- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-push-navigation.html +++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-push-navigation.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>View transitions: pageconceal navigationactivation for push navigations</title> +<title>View transitions: pageswap navigationactivation for push navigations</title> <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> <link rel="author" href="mailto:khushalsagar@chromium.org"> <script src="/resources/testharness.js"></script> @@ -24,7 +24,7 @@ if (is_test_page) { const expectedUrl = location.href + "?new"; - const expectedEvents = ["pageconceal", "transition", expectedUrl, "push","from", "pagehide"]; + const expectedEvents = ["pageswap", "transition", expectedUrl, "push","from", "pagehide"]; promise_test(async t => { let popup; @@ -43,15 +43,15 @@ } })); }); - }, `pageconceal on navigation from script`); + }, `pageswap on navigation from script`); } else if (is_popup_page) { onload = () => { requestAnimationFrame(() => requestAnimationFrame(() => { location.href = location.href.split('?')[0] + '?new'; })); - onpageconceal = (e) => { - window.opener.events.push("pageconceal"); + onpageswap = (e) => { + window.opener.events.push("pageswap"); if (e.viewTransition != null) window.opener.events.push("transition"); window.opener.events.push(e.activation.entry.url);
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-push-with-redirect.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-push-with-redirect.html similarity index 81% rename from third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-push-with-redirect.html rename to third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-push-with-redirect.html index 54d39f1..bc14886 100644 --- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-push-with-redirect.html +++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-push-with-redirect.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>View transitions: pageconceal navigationactivation for push navigations with a same-origin redirect</title> +<title>View transitions: pageswap navigationactivation for push navigations with a same-origin redirect</title> <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> <link rel="author" href="mailto:khushalsagar@chromium.org"> <script src="/resources/testharness.js"></script> @@ -24,7 +24,7 @@ if (is_test_page) { const expectedUrl = location.href + "?new"; - const expectedEvents = ["pageconceal", "transition", expectedUrl, "push","from", "pagehide"]; + const expectedEvents = ["pageswap", "transition", expectedUrl, "push","from", "pagehide"]; promise_test(async t => { let popup; @@ -43,15 +43,15 @@ } })); }); - }, `pageconceal on navigation with same-origin redirect`); + }, `pageswap on navigation with same-origin redirect`); } else if (is_popup_page) { onload = () => { requestAnimationFrame(() => requestAnimationFrame(() => { - location.href = "/common/redirect.py?location=/wpt_internal/view-transition-on-navigation/pageconceal-push-with-redirect.html?new"; + location.href = "/common/redirect.py?location=/wpt_internal/view-transition-on-navigation/pageswap-push-with-redirect.html?new"; })); - onpageconceal = (e) => { - window.opener.events.push("pageconceal"); + onpageswap = (e) => { + window.opener.events.push("pageswap"); if (e.viewTransition != null) window.opener.events.push("transition"); window.opener.events.push(e.activation.entry.url);
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-replace-navigation.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-replace-navigation.html similarity index 85% rename from third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-replace-navigation.html rename to third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-replace-navigation.html index 9d29140..18f63454 100644 --- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-replace-navigation.html +++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-replace-navigation.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>View transitions: pageconceal navigationactivation for replace navigations</title> +<title>View transitions: pageswap navigationactivation for replace navigations</title> <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> <link rel="author" href="mailto:khushalsagar@chromium.org"> <script src="/resources/testharness.js"></script> @@ -24,7 +24,7 @@ if (is_test_page) { const expectedUrl = location.href.split('?')[0] + "?new"; - const expectedEvents = ["pageconceal", "transition", expectedUrl, "replace","from", "pagehide"]; + const expectedEvents = ["pageswap", "transition", expectedUrl, "replace","from", "pagehide"]; promise_test(async t => { let popup; @@ -43,15 +43,15 @@ } })); }); - }, `pageconceal on replace navigation from script`); + }, `pageswap on replace navigation from script`); } else if (is_popup_page) { onload = () => { requestAnimationFrame(() => requestAnimationFrame(() => { location.replace(location.href.split('?')[0] + '?new'); })); - onpageconceal = (e) => { - window.opener.events.push("pageconceal"); + onpageswap = (e) => { + window.opener.events.push("pageswap"); if (e.viewTransition != null) window.opener.events.push("transition"); window.opener.events.push(e.activation.entry.url);
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-skip-transition.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-skip-transition.html similarity index 90% rename from third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-skip-transition.html rename to third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-skip-transition.html index 4ad4582..bfeee782 100644 --- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-skip-transition.html +++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-skip-transition.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>View transitions: skipTransition() in pageconceal aborts the transition</title> +<title>View transitions: skipTransition() in pageswap aborts the transition</title> <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> <link rel="author" href="mailto:khushalsagar@chromium.org"> <script src="/resources/testharness.js"></script> @@ -21,7 +21,7 @@ location.replace(location.href + '?new'); })); }; - onpageconceal = (e) => { + onpageswap = (e) => { assert_not_equals(e.viewTransition, null); e.viewTransition.skipTransition(); };
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-traverse-navigation-no-bfcache.https.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-traverse-navigation-no-bfcache.https.html similarity index 88% rename from third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-traverse-navigation-no-bfcache.https.html rename to third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-traverse-navigation-no-bfcache.https.html index 1d173b5..9137dc4 100644 --- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageconceal-traverse-navigation-no-bfcache.https.html +++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pageswap-traverse-navigation-no-bfcache.https.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>View transitions: pageconceal navigationactivation for traverse navigations</title> +<title>View transitions: pageswap navigationactivation for traverse navigations</title> <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> <link rel="author" href="mailto:khushalsagar@chromium.org"> <script src="/resources/testharness.js"></script> @@ -28,7 +28,7 @@ // The test page which opens a popup for the navigation sequence. if (is_test_page) { const expectedUrl = location.href.split('?')[0] + "?popup"; - const expectedEvents = ["pageconceal", "transition", expectedUrl, "traverse","from", "pagehide"]; + const expectedEvents = ["pageswap", "transition", expectedUrl, "traverse","from", "pagehide"]; promise_test(async t => { let popup; @@ -47,7 +47,7 @@ } })); }); - }, `pageconceal on traverse navigation from script`); + }, `pageswap on traverse navigation from script`); } else if (is_initial_page_first_navigation) { // The popup page which the user navigates back to. onload = async () => { @@ -67,8 +67,8 @@ })); }; - onpageconceal = (e) => { - window.opener.events.push("pageconceal"); + onpageswap = (e) => { + window.opener.events.push("pageswap"); if (e.viewTransition != null) window.opener.events.push("transition"); window.opener.events.push(e.activation.entry.url);
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/prerender-removed-during-navigation.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/prerender-removed-during-navigation.html index cd19213..d261b0d 100644 --- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/prerender-removed-during-navigation.html +++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/prerender-removed-during-navigation.html
@@ -71,7 +71,7 @@ await ready_to_activate; - onpageconceal = () => { + onpageswap = () => { prerender_script.remove(); }
diff --git a/third_party/chromium-variations b/third_party/chromium-variations index 32e2e5c..2f49c50 160000 --- a/third_party/chromium-variations +++ b/third_party/chromium-variations
@@ -1 +1 @@ -Subproject commit 32e2e5c8d0343434cf154f2b928775c2d95ad8c5 +Subproject commit 2f49c50b79ab7a6ee16f324656f0185a44fa50a6
diff --git a/third_party/depot_tools b/third_party/depot_tools index 1ac3eb7..fbb0301 160000 --- a/third_party/depot_tools +++ b/third_party/depot_tools
@@ -1 +1 @@ -Subproject commit 1ac3eb7b9844751478c7bdae4614f4d1e8b9b0f8 +Subproject commit fbb0301f1f70813fb62e1f64e05410b730c8417e
diff --git a/third_party/googletest/src b/third_party/googletest/src index 76bb2af..dda72ef 160000 --- a/third_party/googletest/src +++ b/third_party/googletest/src
@@ -1 +1 @@ -Subproject commit 76bb2afb8b522d24496ad1c757a49784fbfa2e42 +Subproject commit dda72ef32181edbfcd32a8c52b4740cd8061ab6f
diff --git a/third_party/openscreen/src b/third_party/openscreen/src index ab2e341..614d391 160000 --- a/third_party/openscreen/src +++ b/third_party/openscreen/src
@@ -1 +1 @@ -Subproject commit ab2e34151f1f147f3dd56f73cdf3ea5c6ad2d0a5 +Subproject commit 614d391f2236a5035b6e7be8d0278db63bddbce0
diff --git a/third_party/webrtc b/third_party/webrtc index e5ac106..ede7529 160000 --- a/third_party/webrtc +++ b/third_party/webrtc
@@ -1 +1 @@ -Subproject commit e5ac106a357e2a1a088b732f0232d470de42f0cb +Subproject commit ede75295d43032370f24bd4295693972ad27aaf0
diff --git a/tools/cast3p/runtime.version b/tools/cast3p/runtime.version index f44b66d..be896b60 100644 --- a/tools/cast3p/runtime.version +++ b/tools/cast3p/runtime.version
@@ -1 +1 @@ -400152 +404550
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml index cef7682..4571f88 100644 --- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -3737,6 +3737,8 @@ <suffix name="Enterprise" label="Records metrics for enterprise real time URL lookup service."/> <affected-histogram name="SafeBrowsing.RT.BackoffState"/> + <affected-histogram + name="SafeBrowsing.RT.EventUrlReferrerChainFetchSucceeded"/> <affected-histogram name="SafeBrowsing.RT.GetCache.Time"/> <affected-histogram name="SafeBrowsing.RT.GetCacheResult"/> <affected-histogram name="SafeBrowsing.RT.HasTokenInRequest"/>
diff --git a/tools/metrics/histograms/metadata/history/OWNERS b/tools/metrics/histograms/metadata/history/OWNERS index 8b39852..ec1d00ac 100644 --- a/tools/metrics/histograms/metadata/history/OWNERS +++ b/tools/metrics/histograms/metadata/history/OWNERS
@@ -13,3 +13,7 @@ # For History.* histograms sophiechang@chromium.org + +# For History.Embeddings.* histograms +tommycli@chromium.org +orinj@chromium.org
diff --git a/tools/metrics/histograms/metadata/history/histograms.xml b/tools/metrics/histograms/metadata/history/histograms.xml index e3f0470..d75e33a 100644 --- a/tools/metrics/histograms/metadata/history/histograms.xml +++ b/tools/metrics/histograms/metadata/history/histograms.xml
@@ -1834,6 +1834,38 @@ </summary> </histogram> +<histogram name="History.Embeddings.Passages.ExtractionTime" units="ms" + expires_after="2024-12-31"> + <owner>orinj@chromium.org</owner> + <owner>tommycli@chromium.org</owner> + <summary> + Round trip request and response time for a single passage extraction. The + clock starts just before the browser requests passages from a renderer, and + stops just after results are received. Logged each time passages are + successfully retrieved from a RenderFrameHost. + </summary> +</histogram> + +<histogram name="History.Embeddings.Passages.PassageCount" units="passages" + expires_after="2024-12-31"> + <owner>orinj@chromium.org</owner> + <owner>tommycli@chromium.org</owner> + <summary> + Number of passages retrieved from a single page passage extraction. Logged + each time passages are retrieved from a RenderFrameHost. + </summary> +</histogram> + +<histogram name="History.Embeddings.Passages.TotalTextSize" units="bytes" + expires_after="2024-12-31"> + <owner>orinj@chromium.org</owner> + <owner>tommycli@chromium.org</owner> + <summary> + The sum of passage text sizes for all passages retrieved from an extraction. + Logged each time passages are retrieved from a RenderFrameHost. + </summary> +</histogram> + <histogram name="History.FaviconDatabaseSizeMB" units="MB" expires_after="M130"> <owner>rogerm@chromium.org</owner> <owner>sky@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index 33dd7ff0..465a5b7 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -2076,6 +2076,18 @@ </summary> </histogram> +<histogram name="SafeBrowsing.RT.EventUrlReferrerChainFetchSucceeded" + enum="BooleanSuccess" expires_after="2024-08-21"> + <owner>thefrog@chromium.org</owner> + <owner>chrome-counter-abuse-alerts@google.com</owner> + <summary> + Logged when fetching the referrer chain for a pending event URL is not able + to find a matching navigation event, so the referrer chain is fetched for + non-pending event URLs instead as a fallback. Logs true if the fallback + fetch returns a non-empty chain. + </summary> +</histogram> + <histogram name="SafeBrowsing.RT.GetCache.FallbackThreatType" enum="SBThreatType" expires_after="2025-01-22"> <owner>xinghuilu@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/storage/histograms.xml b/tools/metrics/histograms/metadata/storage/histograms.xml index 89cbe5d..1ec2e5b 100644 --- a/tools/metrics/histograms/metadata/storage/histograms.xml +++ b/tools/metrics/histograms/metadata/storage/histograms.xml
@@ -335,35 +335,6 @@ </summary> </histogram> -<histogram name="Storage.Blob.RegisterURLTimeWithoutPartitioningSupport" - units="ms" expires_after="2024-02-20"> - <owner>awillia@chromium.org</owner> - <owner>chrome-owp-storage@chromium.org</owner> - <summary> - Recorded when the PublicURLManager::RegisterURL method calls the per-process - BlobURLStore::Register mojo interface method. The value recorded is the time - taken for the call to complete. This histogram is only logged when the - SupportPartitionedBlobUrl feature is disabled. - </summary> -</histogram> - -<histogram name="Storage.Blob.RegisterURLTimeWithPartitioningSupport.{Type}" - units="ms" expires_after="2024-06-30"> - <owner>awillia@chromium.org</owner> - <owner>chrome-owp-storage@chromium.org</owner> - <summary> - Recorded when the PublicURLManager::RegisterURL method calls the - BlobURLStore::Register mojo interface method. The value recorded is the time - taken for the call to complete. This variation of the histogram records - results from {Type}. This histogram is only logged when the - SupportPartitionedBlobUrl feature is enabled. - </summary> - <token key="Type"> - <variant name="Frame" summary="frame execution contexts"/> - <variant name="Worker" summary="worker execution contexts"/> - </token> -</histogram> - <histogram name="Storage.Buckets.BucketCount" units="buckets" expires_after="2024-04-01"> <owner>estade@chromium.org</owner>
diff --git a/tools/metrics/structured/gen_validator.py b/tools/metrics/structured/gen_validator.py index 35ca55450..4ef4445 100755 --- a/tools/metrics/structured/gen_validator.py +++ b/tools/metrics/structured/gen_validator.py
@@ -28,7 +28,7 @@ if args.cros_input is not None: cros_structured = model.Model( open(args.cros_input, encoding='utf-8').read(), 'cros') - structured = model.MergeModels(structured, cros_structured) + structured = model.merge_models(structured, cros_structured) codegen.ValidatorHeaderTemplate( args.output, 'structured_metrics_validator.h').write_file()
diff --git a/tools/metrics/structured/sync/model.py b/tools/metrics/structured/sync/model.py index fae9f8b9..835303d9 100644 --- a/tools/metrics/structured/sync/model.py +++ b/tools/metrics/structured/sync/model.py
@@ -107,7 +107,8 @@ </structured-metrics>""" -def MergeModels(primary: Model, other: Model) -> Model: +def merge_models(primary: Model, other: Model) -> Model: + """Merges two models into one.""" primary.projects += [ p for p in other.projects if not re.match('Test', p.name) ]
diff --git a/tools/perf/contrib/shared_storage/shared_storage.py b/tools/perf/contrib/shared_storage/shared_storage.py index 7420768..f657f120 100644 --- a/tools/perf/contrib/shared_storage/shared_storage.py +++ b/tools/perf/contrib/shared_storage/shared_storage.py
@@ -14,8 +14,6 @@ from telemetry.timeline import chrome_trace_category_filter from telemetry.web_perf import timeline_based_measurement -from py_utils import xvfb - # Features to enable via command line. _ENABLED_FEATURES = [ 'SharedStorageAPI:ExposeDebugMessageForSettingsStatus/true', @@ -91,8 +89,8 @@ logging.warning('The maximum allowed number of iterations is 10. ' + 'Increase pageset_repeat instead.') cls.iterations = _MAX_NUM_ITERATIONS - if args.xvfb and xvfb.ShouldStartXvfb(): - cls.xvfb_process = xvfb.StartXvfb() + if args.xvfb and utils.ShouldStartXvfb(): + cls.xvfb_process = utils.StartXvfb() def SetExtraBrowserOptions(self, options): # `options` is an instance of `browser_options.BrowserOptions`.
diff --git a/tools/perf/contrib/shared_storage/utils/__init__.py b/tools/perf/contrib/shared_storage/utils/__init__.py index 823762d..6aef145 100644 --- a/tools/perf/contrib/shared_storage/utils/__init__.py +++ b/tools/perf/contrib/shared_storage/utils/__init__.py
@@ -15,6 +15,8 @@ 'JsonDump', 'MovePreviousExpectedHistogramsFile', 'ProcessResults', + 'ShouldStartXvfb', + 'StartXvfb', ] from .file_util import (CleanUpRunPathFile, EnsureDataDir, @@ -25,4 +27,5 @@ GetSharedStorageIteratorHistograms, GetSharedStorageUmaHistograms) from .process_results import ProcessResults +from .xvfb import ShouldStartXvfb, StartXvfb from .util import GetNonePlaceholder, JsonDump
diff --git a/tools/perf/contrib/shared_storage/utils/xvfb.py b/tools/perf/contrib/shared_storage/utils/xvfb.py new file mode 100644 index 0000000..092c10ac --- /dev/null +++ b/tools/perf/contrib/shared_storage/utils/xvfb.py
@@ -0,0 +1,47 @@ +# Copyright 2024 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os +import logging +import subprocess +import platform +import time + + +def _GetLockFilePath(server_num): + return "/tmp/.X11-unix/X{}".format(server_num) + + +def ShouldStartXvfb(): + # TODO(crbug.com/973847): Note that you can locally change this to return + # False to diagnose timeouts for dev server tests. + return platform.system() == 'Linux' + + +def StartXvfb(): + # Get a number of an available server. + server_num = 99 + while os.path.exists(_GetLockFilePath(server_num)): + server_num += 1 + + display = ':{}'.format(server_num) + xvfb_command = ['Xvfb', display, '-screen', '0', '1024x769x24', '-ac'] + xvfb_process = subprocess.Popen(xvfb_command, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + time.sleep(0.2) + returncode = xvfb_process.poll() + if returncode is None: + os.environ['DISPLAY'] = display + + # Use print instead of logging to ensure that the recommendation to remove + # the lock file is displayed regardless of verbosity settings. + print('Started Xvfb on display %s.' % display) + print('If test fails to exit cleanly, it is recommended that you manually' + ' remove the file "%s".\n' % _GetLockFilePath(server_num)) + else: + logging.error('Xvfb did not start, returncode: %s, stdout:\n%s', returncode, + xvfb_process.stdout.read()) + xvfb_process = None + return xvfb_process
diff --git a/tools/perf/page_sets/rendering/motionmark.py b/tools/perf/page_sets/rendering/motionmark.py index df88e5f..afdbfca 100644 --- a/tools/perf/page_sets/rendering/motionmark.py +++ b/tools/perf/page_sets/rendering/motionmark.py
@@ -257,16 +257,12 @@ def RunPageInteractions(self, action_runner): with action_runner.CreateInteraction('Filter'): - action_runner.Wait(2) action_runner.WaitForJavaScriptCondition( 'window.benchmarkRunnerClient.results._results') - # Navigate to about:blank to stop rendering frames and let the device - # cool down while the trace data for the story is processed. - action_runner.Navigate('about:blank') - @classmethod - def GetFixed2SecondsUrl(cls, suite_name, test_name, complexity): + def GetFixed2SecondsUrl(cls, suite_name, test_name, complexity, + test_interval): # Strip unwanted characters from names for ch in [' ', '.', ',']: suite_name = suite_name.replace(ch, '') @@ -278,65 +274,68 @@ '?suite-name=%s' '&test-name=%s' '&complexity=%d' - '&test-interval=2' - '&warmup-length=100' - '&warmup-frame-count=10' + '&test-interval=%d' + '&warmup-length=0' + '&warmup-frame-count=0' '&first-frame-minimum-length=0' '&display=minimal' '&tiles=big' '&controller=fixed' '&system-frame-rate=60' '&frame-rate=60' - '&time-measurement=performance') % (suite_name, test_name, complexity) + '&time-measurement=performance') % (suite_name, test_name, complexity, + test_interval) #Numbers for complexity based on MotionMark score for chrome build without PGO +#TODO(vmiura): Update names from fixed_2_seconds to match the new durations. class MotionMarkFixed2SecondsMultiply(MotionMarkFixed2SecondsPage): BASE_NAME = 'motionmark_fixed_2_seconds_multiply' URL = MotionMarkFixed2SecondsPage.GetFixed2SecondsUrl('MotionMark', - 'Multiply', 1396) + 'Multiply', 1396, 5) class MotionMarkFixed2SecondsCanvasArcs(MotionMarkFixed2SecondsPage): BASE_NAME = 'motionmark_fixed_2_seconds_canvas_arcs' URL = MotionMarkFixed2SecondsPage.GetFixed2SecondsUrl('MotionMark', - 'Canvas Arcs', 6194) + 'Canvas Arcs', 6194, 5) class MotionMarkFixed2SecondsLeaves(MotionMarkFixed2SecondsPage): BASE_NAME = 'motionmark_fixed_2_seconds_leaves' URL = MotionMarkFixed2SecondsPage.GetFixed2SecondsUrl('MotionMark', 'Leaves', - 1377) + 1377, 5) class MotionMarkFixed2SecondsPaths(MotionMarkFixed2SecondsPage): BASE_NAME = 'motionmark_fixed_2_seconds_paths' URL = MotionMarkFixed2SecondsPage.GetFixed2SecondsUrl('MotionMark', 'Paths', - 29172) + 29172, 5) class MotionMarkFixed2SecondsCanvasLines(MotionMarkFixed2SecondsPage): BASE_NAME = 'motionmark_fixed_2_seconds_canvas_lines' URL = MotionMarkFixed2SecondsPage.GetFixed2SecondsUrl('MotionMark', - 'Canvas Lines', 16520) + 'Canvas Lines', 16520, + 5) class MotionMarkFixed2SecondsImages(MotionMarkFixed2SecondsPage): BASE_NAME = 'motionmark_fixed_2_seconds_images' URL = MotionMarkFixed2SecondsPage.GetFixed2SecondsUrl('MotionMark', 'Images', - 200) + 200, 5) class MotionMarkFixed2SecondsDesign(MotionMarkFixed2SecondsPage): BASE_NAME = 'motionmark_fixed_2_seconds_design' URL = MotionMarkFixed2SecondsPage.GetFixed2SecondsUrl('MotionMark', 'Design', - 213) + 213, 5) class MotionMarkFixed2SecondsSuits(MotionMarkFixed2SecondsPage): BASE_NAME = 'motionmark_fixed_2_seconds_suits' URL = MotionMarkFixed2SecondsPage.GetFixed2SecondsUrl('MotionMark', 'Suits', - 1299) + 1299, 5) @benchmark.Info(emails=['chrome-skia-graphite@google.com'],
diff --git a/tools/perf/process_perf_results.pydeps b/tools/perf/process_perf_results.pydeps index 1983fb12..a9906b7 100644 --- a/tools/perf/process_perf_results.pydeps +++ b/tools/perf/process_perf_results.pydeps
@@ -39,7 +39,6 @@ ../../third_party/catapult/common/py_utils/py_utils/tempfile_ext.py ../../third_party/catapult/common/py_utils/py_utils/ts_proxy_server.py ../../third_party/catapult/common/py_utils/py_utils/webpagereplay_go_server.py -../../third_party/catapult/common/py_utils/py_utils/xvfb.py ../../third_party/catapult/common/py_vulcanize/py_vulcanize/__init__.py ../../third_party/catapult/common/py_vulcanize/py_vulcanize/generate.py ../../third_party/catapult/common/py_vulcanize/py_vulcanize/html_generation_controller.py @@ -563,6 +562,7 @@ contrib/shared_storage/utils/histogram_list.py contrib/shared_storage/utils/process_results.py contrib/shared_storage/utils/util.py +contrib/shared_storage/utils/xvfb.py contrib/system_health_scroll_jank/__init__.py contrib/system_health_scroll_jank/janky_story_set.py contrib/system_health_scroll_jank/system_health_scroll_jank.py
diff --git a/tools/utr/recipe.py b/tools/utr/recipe.py index df887ba..54d5872 100644 --- a/tools/utr/recipe.py +++ b/tools/utr/recipe.py
@@ -75,7 +75,8 @@ # Add UTR recipe props. Its schema is located at: # https://chromium.googlesource.com/chromium/tools/build/+/HEAD/recipes/recipes/chromium/universal_test_runner.proto input_props = builder_props.copy() - input_props['checkout_path'] = str(_SRC_DIR.parent) + input_props['checkout_path'] = str(_SRC_DIR) + input_props['$recipe_engine/path'] = {'cache_dir': str(_SRC_DIR.parent)} input_props['test_names'] = tests if build_dir: input_props['build_dir'] = build_dir
diff --git a/tools/utr/recipe_test.py b/tools/utr/recipe_test.py index d363764..45c028a 100755 --- a/tools/utr/recipe_test.py +++ b/tools/utr/recipe_test.py
@@ -27,14 +27,16 @@ def testProps(self): runner = recipe.LegacyRunner(self.tmp_dir, {}, 'some-bucket', - 'some-builder', [], False, False) + 'some-builder', 'swarming-server', [], False, + False) self.assertEqual( runner._input_props['$recipe_engine/buildbucket']['build']['builder'] ['builder'], 'some-builder') def testRun(self): runner = recipe.LegacyRunner(self.tmp_dir, {}, 'some-bucket', - 'some-builder', [], False, False) + 'some-builder', 'swarming-server', [], False, + False) self.subp_mock.returncode = 123 with mock.patch('subprocess.Popen', return_value=self.subp_mock): exit_code, _ = runner.run_recipe() @@ -42,7 +44,8 @@ def testJson(self): runner = recipe.LegacyRunner(self.tmp_dir, {}, 'some-bucket', - 'some-builder', [], False, False) + 'some-builder', 'swarming-server', [], False, + False) with mock.patch('tempfile.TemporaryDirectory', return_value=self.tmp_dir): with mock.patch('subprocess.Popen', return_value=self.subp_mock): # Missing json file
diff --git a/ui/base/cocoa/text_services_context_menu.mm b/ui/base/cocoa/text_services_context_menu.mm index edd094b..31b6ca6 100644 --- a/ui/base/cocoa/text_services_context_menu.mm +++ b/ui/base/cocoa/text_services_context_menu.mm
@@ -70,19 +70,20 @@ namespace ui { -// When running on an OS release earlier than macOS 14, do this as well, for two -// reasons: +// When running on an OS release earlier than macOS 14, or running on macOS 14.4 +// and later, do this as well, for two reasons: // // 1. Interoperability with the other parts of the system that use this same // speech synthesizer. // // 2. Working around a bug in `AVSpeechSynthesizer` which does not provide the // correct voice when a specific voice is chosen in the system accessibility -// settings (see https://crbug.com/1484940#c9, FB13197951). +// settings (see https://crbug.com/40072850#comment10, FB13197951). // -// However, for macOS 14, directly use the deprecated NSSpeechSynthesizer class, -// as there is a bug with the NSApplication provided methods that causes -// occasional hiccups in the audio (see https://crbug.com/1489906, FB13261400). +// However, for macOS 14.0 through 14.3, directly use the deprecated +// NSSpeechSynthesizer class, as there is a bug with the NSApplication provided +// methods that causes occasional hiccups in the audio (see +// https://crbug.com/40074199, FB13261400). #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" @@ -117,7 +118,8 @@ #pragma clang diagnostic pop void TextServicesContextMenu::SpeakText(const std::u16string& text) { - if (base::mac::MacOSVersion() >= 14'00'00) { + int version = base::mac::MacOSVersion(); + if (version >= 14'00'00 && version < 14'04'00) { FB13261400Workaround::SpeakText(text); } else { [NSApp speakString:base::SysUTF16ToNSString(text)]; @@ -125,7 +127,8 @@ } void TextServicesContextMenu::StopSpeaking() { - if (base::mac::MacOSVersion() >= 14'00'00) { + int version = base::mac::MacOSVersion(); + if (version >= 14'00'00 && version < 14'04'00) { FB13261400Workaround::StopSpeaking(); } else { [NSApp stopSpeaking:nil]; @@ -133,7 +136,8 @@ } bool TextServicesContextMenu::IsSpeaking() { - if (base::mac::MacOSVersion() >= 14'00'00) { + int version = base::mac::MacOSVersion(); + if (version >= 14'00'00 && version < 14'04'00) { return FB13261400Workaround::IsSpeaking(); } else { return [NSApp isSpeaking];
diff --git a/v8 b/v8 index 4089389..68087ab 160000 --- a/v8 +++ b/v8
@@ -1 +1 @@ -Subproject commit 408938972fdca848d564d0bd80139df8a90e53a5 +Subproject commit 68087ab41a76501a5364273a52cd395f0e7033b3