diff --git a/DEPS b/DEPS index 86f57d3..f53ee14 100644 --- a/DEPS +++ b/DEPS
@@ -313,7 +313,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': '7056b58bd3f5af3896df93abd40a24e7fb713edc', + 'src_internal_revision': '878ff7e60356f58c1ce23f1b7b4d520e3b4c17ed', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. @@ -321,11 +321,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': 'c94b446f73cf3fb1c72ceb12eb1461a5130acb35', + 'v8_revision': '83887edd7e3e261ca55a1c48173921f874530371', # 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': '24dabdbbeee213d7a1fd01a70cddacc1949d3b26', + 'angle_revision': '5b7763f9d427e98d9be0319fc4c9ef645de63cb7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -333,7 +333,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'cdc2dda5a9576ca869b1a3d7c2104edb45187319', + 'pdfium_revision': '6943be26ed4071a12bef21c27ff0f590d82ccbc9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -388,7 +388,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '897e3d48d8fdc6057befd6d8251a6671d748c8b8', + 'catapult_revision': '171b75b883c5d97e4daac2e0ab8a94f78645ef6c', # 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. @@ -448,7 +448,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '68e066a008e8097a8c7a77b27a1bef813ed69b5a', + 'dawn_revision': '8b28afe0df83ce011f2d92588d5770f6cf2f466a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -504,7 +504,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'libunwind_revision': '9ebf30f2a4f88d37644327ba0eb445d0aba05c02', + 'libunwind_revision': '7b1593d5caacf5d07faa5ef8535733ab51ad9bc8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -848,7 +848,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '73c35de43ab85aa40f061a65515a0f1351b020a3', + '51992b448e50bca8ddb234cb03f8fda5b445fe77', 'condition': 'checkout_android and checkout_src_internal', }, @@ -1284,7 +1284,7 @@ # For Linux and Chromium OS. 'src/third_party/cros_system_api': { - 'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + '8a208829b3b80c26c66dec5a18ba2bcb64c69bee', + 'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + '6600b606a8df2fe2b57caf436cc12083ff4beb4f', 'condition': 'checkout_linux', }, @@ -1298,7 +1298,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '0b943400a45966122a123c27f4f290ab309d893a', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'a51863b2f82626587641543b60f249431c48d1ec', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1782,7 +1782,7 @@ Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '09a4f3ec842a8932341b195c5b01e141c8a16eb7', 'src/third_party/openscreen/src': - Var('chromium_git') + '/openscreen' + '@' + 'd0b32cadd6ddc94646047ee93aff43db2470f9c0', + Var('chromium_git') + '/openscreen' + '@' + 'f3cb605aacaa61ea878363434572f67b68a6c8ed', 'src/third_party/openxr/src': { 'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + '58a00cf85c39ad5ec4dc43a769624e420c06179a', @@ -4146,7 +4146,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - 'a96082a751e2643f6253853554b37ce6234ffeae', + '9fb0acc762ca7bef8428faf4278d1691a05a6401', 'condition': 'checkout_ios and checkout_src_internal', }, @@ -4225,7 +4225,7 @@ }, 'src/third_party/ml': { - 'url': Var('chrome_git') + '/chrome/third_party/ml.git' + '@' + '9797a0977fd4de5ca4398943e6a6a61fc3ac5180', + 'url': Var('chrome_git') + '/chrome/third_party/ml.git' + '@' + '338d9a5d1281e4e6059e36c7c2696ef2e6184174', 'condition': 'checkout_third_party_ml', },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 8d5d547c..67a2569 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -7214,3 +7214,35 @@ "pointers>", ) return [output_api.PresubmitPromptWarning(message)] + +def CheckInlineConstexprDefinitionsInHeaders(input_api, output_api): + """Checks that non-static constexpr definitions in headers are inline.""" + # In a properly formatted file, constexpr definitions inside classes or + # structs will have additional whitespace at the beginning of the line. + # The pattern looks for variables initialized as constexpr kVar = ...; or + # constexpr kVar{...}; + # The pattern does not match expressions that have braces in kVar to avoid + # matching constexpr functions. + pattern = input_api.re.compile(r'^constexpr (?!inline )[^\(\)]*[={]') + attribute_pattern = input_api.re.compile(r'(\[\[[a-zA-Z_:]+\]\]|[A-Z]+[A-Z_]+) ') + problems = [] + for f in input_api.AffectedFiles(): + if not _IsCPlusPlusHeaderFile(input_api, f.LocalPath()): + continue + + for line_number, line in f.ChangedContents(): + line = attribute_pattern.sub('', line) + if pattern.search(line): + problems.append( + f"{f.LocalPath()}: {line_number}\n {line}") + + if problems: + return [ + output_api.PresubmitPromptWarning( + 'Consider inlining constexpr variable definitions in headers ' + 'outside of classes to avoid unnecessary copies of the ' + 'constant. See https://abseil.io/tips/168 for more details.', + problems) + ] + else: + return []
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py index 6db23638..fb6ab873 100755 --- a/PRESUBMIT_test.py +++ b/PRESUBMIT_test.py
@@ -5242,6 +5242,149 @@ mock_output_api) self.assertEqual(len(msgs), 0) +class CheckInlineConstexprDefinitionsInHeadersTest(unittest.TestCase): + def testNoInlineConstexprInHeaderFile(self): + """Tests that non-inlined constexpr variables in headers fail the test.""" + input_api = MockInputApi() + input_api.files = [ + MockAffectedFile('src/constants.h', ['constexpr int kVersion = 5;']) + ] + warnings = PRESUBMIT.CheckInlineConstexprDefinitionsInHeaders(input_api, MockOutputApi()) + self.assertEqual(1, len(warnings)) + + def testNoInlineConstexprInHeaderFileInitializedFromFunction(self): + """Tests that non-inlined constexpr header variables that are initialized from a function fail.""" + input_api = MockInputApi() + input_api.files = [ + MockAffectedFile('src/constants.h', ['constexpr int kVersion = GetVersion();']) + ] + warnings = PRESUBMIT.CheckInlineConstexprDefinitionsInHeaders(input_api, MockOutputApi()) + self.assertEqual(1, len(warnings)) + + def testNoInlineConstexprInHeaderFileInitializedWithExpression(self): + """Tests that non-inlined constexpr header variables initialized with an expression fail.""" + input_api = MockInputApi() + input_api.files = [ + MockAffectedFile('src/constants.h', ['constexpr int kVersion = (4 + 5)*3;']) + ] + warnings = PRESUBMIT.CheckInlineConstexprDefinitionsInHeaders(input_api, MockOutputApi()) + self.assertEqual(1, len(warnings)) + + def testNoInlineConstexprInHeaderFileBraceInitialized(self): + """Tests that non-inlined constexpr header variables that are brace-initialized fail.""" + input_api = MockInputApi() + input_api.files = [ + MockAffectedFile('src/constants.h', ['constexpr int kVersion{5};']) + ] + warnings = PRESUBMIT.CheckInlineConstexprDefinitionsInHeaders(input_api, MockOutputApi()) + self.assertEqual(1, len(warnings)) + + def testNoInlineConstexprInHeaderWithAttribute(self): + """Tests that non-inlined constexpr header variables that have compiler attributes fail.""" + input_api = MockInputApi() + input_api.files = [ + MockAffectedFile('src/constants.h', ['constexpr [[maybe_unused]] int kVersion{5};']) + ] + warnings = PRESUBMIT.CheckInlineConstexprDefinitionsInHeaders(input_api, MockOutputApi()) + self.assertEqual(1, len(warnings)) + + def testInlineConstexprInHeaderWithAttribute(self): + """Tests that inlined constexpr header variables that have compiler attributes pass.""" + input_api = MockInputApi() + input_api.files = [ + MockAffectedFile('src/constants.h', ['inline constexpr [[maybe_unused]] int kVersion{5};']), + MockAffectedFile('src/constants.h', ['constexpr inline [[maybe_unused]] int kVersion{5};']), + MockAffectedFile('src/constants.h', ['inline constexpr [[maybe_unused]] inline int kVersion{5};']) + ] + warnings = PRESUBMIT.CheckInlineConstexprDefinitionsInHeaders(input_api, MockOutputApi()) + self.assertEqual(0, len(warnings)) + + def testNoInlineConstexprInHeaderFileMultipleLines(self): + """Tests that non-inlined constexpr header variable definitions spanning multiple lines fail.""" + input_api = MockInputApi() + lines = ['constexpr char kLongName =', + ' "This is a very long name of something.";' + ] + input_api.files = [MockAffectedFile('src/constants.h', lines)] + warnings = PRESUBMIT.CheckInlineConstexprDefinitionsInHeaders(input_api, MockOutputApi()) + self.assertEqual(1, len(warnings)) + + def testNoInlineConstexprInCCFile(self): + """Tests that non-inlined constexpr variables in .cc files pass the test.""" + input_api = MockInputApi() + input_api.files = [ + MockAffectedFile('src/implementation.cc', ['constexpr int kVersion = 5;']) + ] + warnings = PRESUBMIT.CheckInlineConstexprDefinitionsInHeaders(input_api, MockOutputApi()) + self.assertEqual(0, len(warnings)) + + def testInlineConstexprInHeaderFile(self): + """Tests that inlined constexpr variables in header files pass the test.""" + input_api = MockInputApi() + input_api.files = [ + MockAffectedFile('src/constants.h', ['constexpr inline int kX = 5;']), + MockAffectedFile('src/version.h', ['inline constexpr float kY = 5.0f;']) + ] + warnings = PRESUBMIT.CheckInlineConstexprDefinitionsInHeaders(input_api, MockOutputApi()) + self.assertEqual(0, len(warnings)) + + def testConstexprStandaloneFunctionInHeaderFile(self): + """Tests that non-inlined constexpr functions in headers pass the test.""" + input_api = MockInputApi() + input_api.files = [ + MockAffectedFile('src/helpers.h', ['constexpr int GetVersion();']) + ] + warnings = PRESUBMIT.CheckInlineConstexprDefinitionsInHeaders(input_api, MockOutputApi()) + self.assertEqual(0, len(warnings)) + + def testConstexprWithAbseilAttributeInHeader(self): + """Tests that non-inlined constexpr variables with Abseil-type prefixes in headers fail.""" + input_api = MockInputApi() + input_api.files = [ + MockAffectedFile('src/helpers.h', ['ABSL_FOOFOO constexpr int i = 5;']) + ] + warnings = PRESUBMIT.CheckInlineConstexprDefinitionsInHeaders(input_api, MockOutputApi()) + self.assertEqual(1, len(warnings)) + + def testInlineConstexprWithAbseilAttributeInHeader(self): + """Tests that inlined constexpr variables with Abseil-type prefixes in headers pass.""" + input_api = MockInputApi() + input_api.files = [ + MockAffectedFile('src/helpers.h', ['constexpr ABSL_FOO inline int i = 5;']) + ] + warnings = PRESUBMIT.CheckInlineConstexprDefinitionsInHeaders(input_api, MockOutputApi()) + self.assertEqual(0, len(warnings)) + + def testConstexprWithClangAttributeInHeader(self): + """Tests that non-inlined constexpr variables with attributes with colons in headers fail.""" + input_api = MockInputApi() + input_api.files = [ + MockAffectedFile('src/helpers.h', ['[[clang::someattribute]] constexpr int i = 5;']) + ] + warnings = PRESUBMIT.CheckInlineConstexprDefinitionsInHeaders(input_api, MockOutputApi()) + self.assertEqual(1, len(warnings)) + + def testInlineConstexprWithClangAttributeInHeader(self): + """Tests that inlined constexpr variables with attributes with colons in headers pass.""" + input_api = MockInputApi() + input_api.files = [ + MockAffectedFile('src/helpers.h', ['constexpr [[clang::someattribute]] inline int i = 5;']) + ] + warnings = PRESUBMIT.CheckInlineConstexprDefinitionsInHeaders(input_api, MockOutputApi()) + self.assertEqual(0, len(warnings)) + + def testNoExplicitInlineConstexprInsideClassInHeaderFile(self): + """Tests that non-inlined constexpr class members pass the test.""" + input_api = MockInputApi() + lines = ['class SomeClass {', + ' public:', + ' static constexpr kVersion = 5;', + '};'] + input_api.files = [ + MockAffectedFile('src/class.h', lines) + ] + warnings = PRESUBMIT.CheckInlineConstexprDefinitionsInHeaders(input_api, MockOutputApi()) + self.assertEqual(0, len(warnings)) if __name__ == '__main__': unittest.main()
diff --git a/ash/app_list/app_list_test_api.cc b/ash/app_list/app_list_test_api.cc index ce2f6755..b73a28cd 100644 --- a/ash/app_list/app_list_test_api.cc +++ b/ash/app_list/app_list_test_api.cc
@@ -34,6 +34,7 @@ #include "ash/app_list/views/recent_apps_view.h" #include "ash/app_list/views/scrollable_apps_grid_view.h" #include "ash/app_list/views/search_box_view.h" +#include "ash/constants/ash_pref_names.h" #include "ash/public/cpp/accelerators.h" #include "ash/shell.h" #include "base/functional/callback.h" @@ -565,6 +566,15 @@ AppListNudgeController::SetReorderNudgeDisabledForTest(disable); } +void AppListTestApi::DisableSearchNotifier(bool disable) { + auto* prefs = + Shell::Get()->session_controller()->GetLastActiveUserPrefService(); + ScopedDictPrefUpdate pref_update(prefs, + ash::prefs::kImageSearchPrivacyNotice); + // Accept the notifier to disable it. + pref_update->Set("accepted", disable); +} + void AppListTestApi::SetContinueSectionPrivacyNoticeAccepted() { AppListNudgeController::SetPrivacyNoticeAcceptedForTest(true); }
diff --git a/ash/app_list/views/app_list_item_view.cc b/ash/app_list/views/app_list_item_view.cc index e253e00..222bcda 100644 --- a/ash/app_list/views/app_list_item_view.cc +++ b/ash/app_list/views/app_list_item_view.cc
@@ -1296,8 +1296,18 @@ void AppListItemView::OnMouseReleased(const ui::MouseEvent& event) { auto weak_this = weak_ptr_factory_.GetWeakPtr(); - // Triggers the button's click handler callback, which might delete `this`. - Button::OnMouseReleased(event); + // Reset all states if we are already dragging, and avoid triggering a button + // mouse release event. + if (ui_state_ == UI_STATE_DRAGGING && + drag_state_ == DragState::kInitialized) { + SetMouseDragging(false); + drag_state_ = DragState::kNone; + return; + } else { + // Triggers the button's click handler callback, which might delete `this`. + Button::OnMouseReleased(event); + } + if (!weak_this) { return; }
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index 22e0ff6..fcd6a5c 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -262,6 +262,36 @@ } // namespace +class CheckBoxMenuItemView : public views::MenuItemView { + public: + CheckBoxMenuItemView(views::MenuItemView* parent, + int command, + AppListViewDelegate* view_delegate) + : views::MenuItemView(parent, + command, + views::MenuItemView::Type::kNormal), + view_delegate_(view_delegate) {} + + CheckBoxMenuItemView(const CheckBoxMenuItemView&) = delete; + CheckBoxMenuItemView& operator=(const CheckBoxMenuItemView&) = delete; + + ~CheckBoxMenuItemView() override = default; + + void GetAccessibleNodeData(ui::AXNodeData* node_data) override { + views::MenuItemView::GetAccessibleNodeData(node_data); + // Set the role of the toggleable menu items to checkbox. + node_data->role = ax::mojom::Role::kMenuItemCheckBox; + node_data->SetCheckedState( + view_delegate_->IsCategoryEnabled( + static_cast<AppListSearchControlCategory>(GetCommand())) + ? ax::mojom::CheckedState::kTrue + : ax::mojom::CheckedState::kFalse); + } + + private: + raw_ptr<AppListViewDelegate> view_delegate_ = nullptr; +}; + class FilterMenuAdapter : public views::MenuModelAdapter { public: FilterMenuAdapter(ui::SimpleMenuModel* menu_model, @@ -276,6 +306,33 @@ ~FilterMenuAdapter() override = default; + // Override AppendMenuItem to use customized MenuItemView. + views::MenuItemView* AppendMenuItem(views::MenuItemView* menu, + ui::MenuModel* model, + size_t model_index) override { + if (!menu->HasSubmenu()) { + menu->CreateSubmenu(); + } + + if (model->GetTypeAt(model_index) == ui::MenuModel::TYPE_TITLE) { + return menu->AppendTitle(model->GetLabelAt(model_index)); + } + + auto menu_item_view = std::make_unique<CheckBoxMenuItemView>( + menu, model->GetCommandIdAt(model_index), view_delegate_); + menu_item_view->SetTitle(model->GetLabelAt(model_index)); + menu_item_view->SetIcon(model->GetIconAt(model_index)); + menu_item_view->SetAccessibleName(model->GetAccessibleNameAt(model_index)); + + const ui::ElementIdentifier element_id = + model->GetElementIdentifierAt(model_index); + if (element_id) { + menu_item_view->SetProperty(views::kElementIdentifierKey, element_id); + } + + return menu->GetSubmenu()->AddChildView(std::move(menu_item_view)); + } + // views::MenuDelegate bool ShouldExecuteCommandWithoutClosingMenu(int id, const ui::Event& e) override {
diff --git a/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc b/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc index 7dd2042e..6ed20747 100644 --- a/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc +++ b/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
@@ -236,6 +236,34 @@ EXPECT_TRUE(testApi.close_button()->GetEnabled()); } +// Test that the close button is disabled when `is_close_button_enabled` is +// `false`. +TEST_F(FrameCaptionButtonContainerViewTest, CloseButtonIsDisabled) { + FrameCaptionButtonContainerView container( + CreateTestWidget(MAXIMIZE_ALLOWED, MINIMIZE_ALLOWED, + CLOSE_BUTTON_VISIBLE), + false /*=is_close_button_enabled*/); + InitContainer(&container); + views::test::RunScheduledLayout(&container); + FrameCaptionButtonContainerView::TestApi testApi(&container); + EXPECT_TRUE(testApi.close_button()->GetVisible()); + EXPECT_FALSE(testApi.close_button()->GetEnabled()); +} + +// Test that the close button is enabled when `is_close_button_enabled` is +// `true`. +TEST_F(FrameCaptionButtonContainerViewTest, CloseButtonIsEnabled) { + FrameCaptionButtonContainerView container( + CreateTestWidget(MAXIMIZE_ALLOWED, MINIMIZE_ALLOWED, + CLOSE_BUTTON_VISIBLE), + true /*=is_close_button_enabled*/); + InitContainer(&container); + views::test::RunScheduledLayout(&container); + FrameCaptionButtonContainerView::TestApi testApi(&container); + EXPECT_TRUE(testApi.close_button()->GetVisible()); + EXPECT_TRUE(testApi.close_button()->GetEnabled()); +} + // Test that the close button is not visible when // |ShouldShowCloseButton()| returns false. TEST_F(FrameCaptionButtonContainerViewTest, ShouldShowCloseButtonFalse) {
diff --git a/ash/frame/non_client_frame_view_ash_unittest.cc b/ash/frame/non_client_frame_view_ash_unittest.cc index 4281682..e03aee6 100644 --- a/ash/frame/non_client_frame_view_ash_unittest.cc +++ b/ash/frame/non_client_frame_view_ash_unittest.cc
@@ -609,19 +609,22 @@ FrameCaptionButtonContainerView::TestApi test_api( header_view->caption_button_container()); - // CLOSE button is always enabled. - EXPECT_TRUE(test_api.close_button()); EXPECT_FALSE(test_api.close_button()->GetVisible()); - EXPECT_TRUE(test_api.close_button()->GetEnabled()); + EXPECT_FALSE(test_api.minimize_button()->GetVisible()); + EXPECT_FALSE(test_api.size_button()->GetVisible()); + EXPECT_FALSE(test_api.menu_button()->GetVisible()); + // Close button model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_CLOSE, true); non_client_frame_view->SizeConstraintsChanged(); widget->LayoutRootViewIfNecessary(); EXPECT_TRUE(test_api.close_button()->GetVisible()); + EXPECT_FALSE(test_api.close_button()->GetEnabled()); - EXPECT_FALSE(test_api.minimize_button()->GetVisible()); - EXPECT_FALSE(test_api.size_button()->GetVisible()); - EXPECT_FALSE(test_api.menu_button()->GetVisible()); + model_ptr->SetEnabled(views::CAPTION_BUTTON_ICON_CLOSE, true); + non_client_frame_view->SizeConstraintsChanged(); + widget->LayoutRootViewIfNecessary(); + EXPECT_TRUE(test_api.close_button()->GetEnabled()); // Back button model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_BACK, true);
diff --git a/ash/game_dashboard/game_dashboard_button.cc b/ash/game_dashboard/game_dashboard_button.cc index 7d445fc..8d3aaad 100644 --- a/ash/game_dashboard/game_dashboard_button.cc +++ b/ash/game_dashboard/game_dashboard_button.cc
@@ -17,8 +17,11 @@ #include "chromeos/strings/grit/chromeos_strings.h" #include "chromeos/ui/frame/frame_header.h" #include "chromeos/ui/vector_icons/vector_icons.h" +#include "third_party/skia/include/core/SkColor.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/color/color_id.h" +#include "ui/color/color_provider.h" #include "ui/compositor/layer.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/rounded_corners_f.h" @@ -43,6 +46,29 @@ constexpr gfx::Insets kGamepadIconMargins = gfx::Insets::TLBR(0, 0, 0, 8); constexpr gfx::Insets kDropdownArrowMargins = gfx::Insets::TLBR(0, 6, 0, 0); +// 30% opacity for disabled state. +constexpr SkAlpha kAlphaForDisabled = + base::saturated_cast<SkAlpha>(std::numeric_limits<SkAlpha>::max() * 0.3); + +ui::ColorId GetBackgroundEnabledColorId(bool is_recording) { + return is_recording ? cros_tokens::kCrosSysSystemNegativeContainer + : cros_tokens::kCrosSysHighlightShape; +} + +ui::ColorId GetIconAndLabelEnabledColorId(bool is_recording) { + return is_recording ? cros_tokens::kCrosSysSystemOnNegativeContainer + : cros_tokens::kCrosSysOnPrimaryContainer; +} + +SkColor GetColor(ui::ColorProvider* color_provider, + ui::ColorId color_id, + bool is_enabled) { + DCHECK(color_provider); + + SkColor color = color_provider->GetColor(color_id); + return is_enabled ? color : SkColorSetA(color, kAlphaForDisabled); +} + } // namespace GameDashboardButton::GameDashboardButton(PressedCallback callback) @@ -68,8 +94,6 @@ // Add the dropdown icon view. dropdown_icon_view_ = AddChildView(std::make_unique<views::ImageView>()); dropdown_icon_view_->SetProperty(views::kMarginsKey, kDropdownArrowMargins); - - UpdateViews(); } GameDashboardButton::~GameDashboardButton() = default; @@ -103,40 +127,60 @@ IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_RECORDING, duration)); } +void GameDashboardButton::AddedToWidget() { + views::Button::AddedToWidget(); + UpdateViews(); +} + void GameDashboardButton::ChildPreferredSizeChanged(views::View* child) { PreferredSizeChanged(); } +void GameDashboardButton::OnThemeChanged() { + views::View::OnThemeChanged(); + // No need to update the theme before this view is added to the widget. + if (GetWidget()) { + UpdateViews(); + } +} + +void GameDashboardButton::StateChanged(ButtonState old_state) { + UpdateViews(); +} + void GameDashboardButton::UpdateDropDownArrow() { DCHECK(dropdown_icon_view_); const gfx::VectorIcon& dropdown_icon = toggled_ ? kGdDropUpArrowIcon : kGdDropDownArrowIcon; - const auto icon_color = is_recording_ - ? cros_tokens::kCrosSysSystemOnNegativeContainer - : cros_tokens::kCrosSysOnPrimaryContainer; + const SkColor icon_color = + GetColor(GetColorProvider(), GetIconAndLabelEnabledColorId(is_recording_), + GetEnabled()); dropdown_icon_view_->SetImage( ui::ImageModel::FromVectorIcon(dropdown_icon, icon_color, kIconHeight)); } void GameDashboardButton::UpdateViews() { - ui::ColorId container_color; - ui::ColorId icon_and_label_color; - if (is_recording_) { - container_color = cros_tokens::kCrosSysSystemNegativeContainer; - icon_and_label_color = cros_tokens::kCrosSysSystemOnNegativeContainer; - // Don't update `title_view_` because it will be updated by - // `UpdateRecordingDuration()`. - } else { - container_color = cros_tokens::kCrosSysHighlightShape; - icon_and_label_color = cros_tokens::kCrosSysOnPrimaryContainer; + DCHECK(GetWidget()); + + // Don't update `title_view_` because it will be updated by + // `UpdateRecordingDuration()`. + if (!is_recording_) { SetTitle(l10n_util::GetStringUTF16( IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_TITLE)); } - SetBackground(views::CreateThemedSolidBackground(container_color)); + auto* color_provider = GetColorProvider(); + DCHECK(color_provider); + + const bool enabled = GetEnabled(); + SetBackground(views::CreateSolidBackground(GetColor( + color_provider, GetBackgroundEnabledColorId(is_recording_), enabled))); + + const SkColor icon_and_label_color = GetColor( + color_provider, GetIconAndLabelEnabledColorId(is_recording_), enabled); gamepad_icon_view_->SetImage(ui::ImageModel::FromVectorIcon( chromeos::kGameDashboardGamepadIcon, icon_and_label_color, kIconHeight)); - title_view_->SetEnabledColorId(icon_and_label_color); + title_view_->SetEnabledColor(icon_and_label_color); UpdateDropDownArrow(); }
diff --git a/ash/game_dashboard/game_dashboard_button.h b/ash/game_dashboard/game_dashboard_button.h index e037dac6..c9c7b50 100644 --- a/ash/game_dashboard/game_dashboard_button.h +++ b/ash/game_dashboard/game_dashboard_button.h
@@ -68,7 +68,12 @@ void UpdateRecordingDuration(const std::u16string& duration); // views::View: + void AddedToWidget() override; void ChildPreferredSizeChanged(views::View* child) override; + void OnThemeChanged() override; + + // views::Button: + void StateChanged(ButtonState old_state) override; private: friend class GameDashboardContextTestApi; @@ -83,7 +88,7 @@ // Updates all the views in the button. If `is_recording_` is true, the // UI is updated to show the 'Recording' button, indicating that there's an // active video recording session. Otherwise, it will show the 'Default' - // button. + // button. Make sure this is called after this view is added to a widget. void UpdateViews(); // Sets the `title_view` and the tooltip text to `title_text`.
diff --git a/ash/game_dashboard/game_dashboard_context.cc b/ash/game_dashboard/game_dashboard_context.cc index b02e4ab..9b5b9b64 100644 --- a/ash/game_dashboard/game_dashboard_context.cc +++ b/ash/game_dashboard/game_dashboard_context.cc
@@ -294,11 +294,13 @@ auto game_dashboard_button = std::make_unique<GameDashboardButton>( base::BindRepeating(&GameDashboardContext::OnGameDashboardButtonPressed, weak_ptr_factory_.GetWeakPtr())); - game_dashboard_button->AddObserver(this); DCHECK(!game_dashboard_button_); game_dashboard_button_ = game_dashboard_button.get(); game_dashboard_button_widget_ = CreateTransientChildWidget( game_window_, "GameDashboardButton", std::move(game_dashboard_button)); + // Add observer after `game_dashboard_button_widget_` is created because the + // observation is to update `game_dashboard_button_widget_` bounds. + game_dashboard_button_->AddObserver(this); game_dashboard_button_input_monitor_ = std::make_unique<GameDashboardButtonInputMonitor>(this); game_dashboard_button_widget_->GetContentsView()->AddPreTargetHandler(
diff --git a/ash/public/cpp/test/app_list_test_api.h b/ash/public/cpp/test/app_list_test_api.h index ca03b88..c971d0e 100644 --- a/ash/public/cpp/test/app_list_test_api.h +++ b/ash/public/cpp/test/app_list_test_api.h
@@ -152,6 +152,10 @@ // Enables/Disables the app list nudge for testing. void DisableAppListNudge(bool disable); + // Enables/Disables the search notifier which shows the privacy notice in + // launcher search for testing. + void DisableSearchNotifier(bool disable); + // Marks continue section privacy notice as accepted. void SetContinueSectionPrivacyNoticeAccepted();
diff --git a/ash/quick_pair/ui/ui_broker_impl_unittest.cc b/ash/quick_pair/ui/ui_broker_impl_unittest.cc index 37fc7c0..5f3588f 100644 --- a/ash/quick_pair/ui/ui_broker_impl_unittest.cc +++ b/ash/quick_pair/ui/ui_broker_impl_unittest.cc
@@ -21,7 +21,6 @@ constexpr char kTestDeviceAddress[] = "11:12:13:14:15:16"; constexpr char kValidModelId[] = "718c17"; -const std::string kUserEmail = "test@test.test"; class FakeFastPairPresenter : public ash::quick_pair::FastPairPresenter { public:
diff --git a/ash/system/focus_mode/focus_mode_detailed_view_unittest.cc b/ash/system/focus_mode/focus_mode_detailed_view_unittest.cc index 5f7ce313..044339b3 100644 --- a/ash/system/focus_mode/focus_mode_detailed_view_unittest.cc +++ b/ash/system/focus_mode/focus_mode_detailed_view_unittest.cc
@@ -67,6 +67,12 @@ widget_->SetContentsView(std::move(focus_mode_detailed_view)); } + void SetInactiveSessionDuration(SystemTextfield* timer_textfield) { + DCHECK(!FocusModeController::Get()->in_focus_session()); + focus_mode_detailed_view_->SetInactiveSessionDuration(base::Minutes( + focus_mode_util::GetTimerTextfieldInputInMinutes(timer_textfield))); + } + views::Label* GetToggleRowLabel() { return focus_mode_detailed_view_->toggle_view_->text_label(); } @@ -91,11 +97,11 @@ } IconButton* GetTimerSettingIncrementButton() { - return views::AsViewClass<IconButton>(GetTimerSettingView()->children()[3]); + return focus_mode_detailed_view_->timer_increment_button_; } IconButton* GetTimerSettingDecrementButton() { - return views::AsViewClass<IconButton>(GetTimerSettingView()->children()[2]); + return focus_mode_detailed_view_->timer_decrement_button_; } Switch* GetDoNotDisturbToggleButton() { @@ -268,10 +274,16 @@ // - 300, we will not increment further. TEST_F(FocusModeDetailedViewTest, TimerSettingViewIncrements) { SystemTextfield* timer_textfield = GetTimerSettingTextfield(); + IconButton* decrement_button = GetTimerSettingDecrementButton(); IconButton* increment_button = GetTimerSettingIncrementButton(); // Check incrementing 1 through 5. timer_textfield->SetText(u"1"); + SetInactiveSessionDuration(timer_textfield); + + // The `decrement_button` will be disabled only when setting the duration to + // the minimum duration. + EXPECT_FALSE(decrement_button->GetEnabled()); LeftClickOn(increment_button); int expected_next_value = 2; for (int i = 0; i < 3; i++) { @@ -281,6 +293,7 @@ expected_next_value += 1; LeftClickOn(increment_button); } + EXPECT_TRUE(decrement_button->GetEnabled()); // Increment 5 to 10. EXPECT_EQ(u"5", timer_textfield->GetText()); @@ -333,11 +346,18 @@ TEST_F(FocusModeDetailedViewTest, TimerSettingViewDecrements) { SystemTextfield* timer_textfield = GetTimerSettingTextfield(); IconButton* decrement_button = GetTimerSettingDecrementButton(); + IconButton* increment_button = GetTimerSettingIncrementButton(); // Decrement 300 to 285. timer_textfield->SetText(u"300"); + SetInactiveSessionDuration(timer_textfield); + + // The `increment_button` will be disabled only when setting the duration to + // the maximum duration. + EXPECT_FALSE(increment_button->GetEnabled()); LeftClickOn(decrement_button); EXPECT_EQ(u"285", timer_textfield->GetText()); + EXPECT_TRUE(increment_button->GetEnabled()); // Try decrementing 299 to 285, and then continue decrementing to 60. timer_textfield->SetText(u"299");
diff --git a/ash/system/network/network_detailed_view_unittest.cc b/ash/system/network/network_detailed_view_unittest.cc index 22024a5..6a6d4eed 100644 --- a/ash/system/network/network_detailed_view_unittest.cc +++ b/ash/system/network/network_detailed_view_unittest.cc
@@ -34,13 +34,6 @@ } // namespace views namespace ash { -namespace { - -const std::string kNetworkdId = "/network/id"; - -using chromeos::network_config::mojom::NetworkStatePropertiesPtr; - -} // namespace class NetworkDetailedViewTest : public AshTestBase { public:
diff --git a/ash/system/time/calendar_event_list_item_view_jelly.cc b/ash/system/time/calendar_event_list_item_view_jelly.cc index 858ca19..666f298 100644 --- a/ash/system/time/calendar_event_list_item_view_jelly.cc +++ b/ash/system/time/calendar_event_list_item_view_jelly.cc
@@ -237,6 +237,7 @@ } else { formatted_time_text = event_date_formatter_util::GetFormattedInterval(start_time, end_time); + is_current_or_next_event_ = end_time >= base::Time::NowFromSystemTime(); } const auto tooltip_text = l10n_util::GetStringFUTF16( IDS_ASH_CALENDAR_EVENT_ENTRY_TOOL_TIP, base::UTF8ToUTF16(event.summary()),
diff --git a/ash/system/time/calendar_event_list_item_view_jelly.h b/ash/system/time/calendar_event_list_item_view_jelly.h index d43d637..0f84a6a8 100644 --- a/ash/system/time/calendar_event_list_item_view_jelly.h +++ b/ash/system/time/calendar_event_list_item_view_jelly.h
@@ -88,6 +88,8 @@ void OnJoinMeetingButtonPressed(const ui::Event& event); + bool is_current_or_next_event() const { return is_current_or_next_event_; } + private: friend class CalendarViewEventListViewTest; @@ -102,6 +104,10 @@ const GURL video_conference_url_; + // Whether this item which is not an all-day or multi-day event is the current + // or next event. Used for auto scroll in the `CalendarEventListView`. + bool is_current_or_next_event_ = false; + base::WeakPtrFactory<CalendarEventListItemViewJelly> weak_ptr_factory_{this}; };
diff --git a/ash/system/time/calendar_event_list_view.cc b/ash/system/time/calendar_event_list_view.cc index 2792d08..4bf5ae5f 100644 --- a/ash/system/time/calendar_event_list_view.cc +++ b/ash/system/time/calendar_event_list_view.cc
@@ -213,6 +213,44 @@ if (gradient_helper_) { gradient_helper_->UpdateGradientMask(); } + + if (!features::IsCalendarJellyEnabled()) { + return; + } + + const absl::optional<base::Time> selected_date = + calendar_view_controller_->selected_date(); + + // If the selected date is not today, do not auto scroll and reset the + // `scroll_view_` position. Otherwise the previous position will be preserved. + if (!calendar_utils::IsToday(selected_date.value())) { + scroll_view_->ScrollToPosition(scroll_view_->vertical_scroll_bar(), 0); + return; + } + + // Scrolls to the top of `current_or_next_event_view_`. Ignores the multi-day + // events on the top if exists. + if (current_or_next_event_view_) { + auto* multi_day_events_container = + GetViewByID(kEventListMultiDayEventsContainer); + + scroll_view_->ScrollToPosition( + scroll_view_->vertical_scroll_bar(), + (multi_day_events_container + ? multi_day_events_container->GetPreferredSize().height() + + kEventListViewBetweenChildSpacingJelly + : 0) + + (current_or_next_event_view_->GetPreferredSize().height() + + kChildEventListBetweenChildSpacing) * + current_or_next_event_index_); + } else { + // If there's no current or next event because there's no single-day event + // for today or all events have passed, scroll to the end of the list if + // selected date is today. + scroll_view_->ScrollToPosition( + scroll_view_->vertical_scroll_bar(), + scroll_view_->GetVisibleRect().bottom() + kContentInsetsJelly.bottom()); + } } void CalendarEventListView::RequestCloseButtonFocus() { @@ -247,23 +285,33 @@ for (SingleDayEventList::iterator it = events.begin(); it != events.end(); ++it) { const int event_index = std::distance(events.begin(), it) + 1; - container->AddChildView(std::make_unique<CalendarEventListItemViewJelly>( - /*calendar_view_controller=*/calendar_view_controller_, - /*selected_date_params=*/ - SelectedDateParams{ - calendar_view_controller_->selected_date().value(), - calendar_view_controller_->selected_date_midnight(), - calendar_view_controller_->selected_date_midnight_utc()}, /*event=*/ - *it, - /*ui_params=*/ - UIParams{/*round_top_corners=*/it == events.begin(), - /*round_bottom_corners=*/it->id() == events.rbegin()->id(), - /*is_up_next_event_list_item=*/false, - /*show_event_list_dot=*/true, - /*fixed_width=*/0}, - /*event_list_item_index=*/ - EventListItemIndex{/*item_index=*/event_index, - /*total_count_of_events=*/events_size})); + auto* event_list_item_view = container->AddChildView( + std::make_unique<CalendarEventListItemViewJelly>( + /*calendar_view_controller=*/calendar_view_controller_, + /*selected_date_params=*/ + SelectedDateParams{ + calendar_view_controller_->selected_date().value(), + calendar_view_controller_->selected_date_midnight(), + calendar_view_controller_ + ->selected_date_midnight_utc()}, /*event=*/ + *it, + /*ui_params=*/ + UIParams{/*round_top_corners=*/it == events.begin(), + /*round_bottom_corners=*/it->id() == events.rbegin()->id(), + /*is_up_next_event_list_item=*/false, + /*show_event_list_dot=*/true, + /*fixed_width=*/0}, + /*event_list_item_index=*/ + EventListItemIndex{/*item_index=*/event_index, + /*total_count_of_events=*/events_size})); + + // The `current_or_next_event_view_` is the first event that is not an + // all-day or multi-day event, and is the ongoing or the following event. + if (!current_or_next_event_view_ && + event_list_item_view->is_current_or_next_event()) { + current_or_next_event_view_ = event_list_item_view; + current_or_next_event_index_ = event_index - 1; + } } return container; @@ -272,6 +320,11 @@ void CalendarEventListView::UpdateListItems() { content_view_->RemoveAllChildViews(); + // Resets `current_or_next_event_view_` and `current_or_next_event_index_` + // since the `event_list_view_` has been updated. + current_or_next_event_view_ = nullptr; + current_or_next_event_index_ = 0; + if (features::IsCalendarJellyEnabled()) { const auto [multi_day_events, all_other_events] = calendar_view_controller_
diff --git a/ash/system/time/calendar_event_list_view.h b/ash/system/time/calendar_event_list_view.h index 91e7c89..4f622da 100644 --- a/ash/system/time/calendar_event_list_view.h +++ b/ash/system/time/calendar_event_list_view.h
@@ -74,6 +74,12 @@ // `CalendarEventListItemView`. Owned by `CalendarEventListView`. const raw_ptr<views::View, ExperimentalAsh> content_view_; + // The current or the next event in the event list view. + raw_ptr<views::View> current_or_next_event_view_ = nullptr; + + // The index of the current or the next event in the event list view. + int current_or_next_event_index_ = 0; + // views::View: void OnThemeChanged() override;
diff --git a/ash/system/time/calendar_event_list_view_unittest.cc b/ash/system/time/calendar_event_list_view_unittest.cc index f81ed8305..877ad33 100644 --- a/ash/system/time/calendar_event_list_view_unittest.cc +++ b/ash/system/time/calendar_event_list_view_unittest.cc
@@ -22,6 +22,8 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/label.h" +#include "ui/views/controls/scroll_view.h" +#include "ui/views/test/views_test_utils.h" namespace ash { @@ -46,6 +48,28 @@ "id_6", "summary_6", "22 Nov 2021 20:30 GMT", "22 Nov 2021 21:30 GMT")); event_list->InjectItemForTesting(calendar_test_utils::CreateEvent( "id_7", "summary_7", "22 Nov 2021 23:30 GMT", "23 Nov 2021 0:30 GMT")); + event_list->InjectItemForTesting(calendar_test_utils::CreateEvent( + "id_8", "summary_8", "23 Nov 2021 01:30 GMT", "23 Nov 2021 02:30 GMT")); + event_list->InjectItemForTesting(calendar_test_utils::CreateEvent( + "id_9", "summary_9", "23 Nov 2021 02:30 GMT", "23 Nov 2021 03:30 GMT")); + event_list->InjectItemForTesting(calendar_test_utils::CreateEvent( + "id_10", "summary_10", "23 Nov 2021 03:30 GMT", "23 Nov 2021 04:30 GMT")); + event_list->InjectItemForTesting(calendar_test_utils::CreateEvent( + "id_11", "summary_11", "23 Nov 2021 04:30 GMT", "23 Nov 2021 05:30 GMT")); + event_list->InjectItemForTesting(calendar_test_utils::CreateEvent( + "id_12", "summary_12", "23 Nov 2021 05:30 GMT", "23 Nov 2021 06:30 GMT")); + event_list->InjectItemForTesting(calendar_test_utils::CreateEvent( + "id_13", "summary_13", "23 Nov 2021 06:30 GMT", "23 Nov 2021 07:30 GMT")); + event_list->InjectItemForTesting(calendar_test_utils::CreateEvent( + "id_14", "summary_14", "23 Nov 2021 06:30 GMT", "23 Nov 2021 07:30 GMT")); + event_list->InjectItemForTesting(calendar_test_utils::CreateEvent( + "id_15", "summary_15", "23 Nov 2021 07:30 GMT", "23 Nov 2021 08:30 GMT")); + event_list->InjectItemForTesting(calendar_test_utils::CreateEvent( + "id_16", "summary_16", "23 Nov 2021 08:30 GMT", "23 Nov 2021 09:30 GMT")); + event_list->InjectItemForTesting(calendar_test_utils::CreateEvent( + "id_17", "summary_17", "23 Nov 2021 09:30 GMT", "23 Nov 2021 10:30 GMT")); + event_list->InjectItemForTesting(calendar_test_utils::CreateEvent( + "id_18", "summary_18", "23 Nov 2021 10:30 GMT", "23 Nov 2021 11:30 GMT")); return event_list; } @@ -66,11 +90,14 @@ IsCalendarJellyEnabled()); AshTestBase::SetUp(); controller_ = std::make_unique<CalendarViewController>(); + widget_ = CreateFramelessTestWidget(); + widget_->SetFullscreen(true); } void TearDown() override { event_list_view_.reset(); controller_.reset(); + widget_.reset(); AshTestBase::TearDown(); } @@ -83,6 +110,7 @@ controller_->selected_date_ = date; event_list_view_ = std::make_unique<CalendarEventListView>(controller_.get()); + widget_->SetContentsView(event_list_view_.get()); } void RefetchEvents(base::Time start_of_month, @@ -97,6 +125,8 @@ /*row_index=*/0); } + void UpdateEventList() { event_list_view_->UpdateListItems(); } + // The way we send metrics is slightly different for Jelly so we need to // ensure this value is set to true in the controller. void SetEventListIsShowingForMetrics() { @@ -105,7 +135,11 @@ CalendarEventListView* event_list_view() { return event_list_view_.get(); } views::View* content_view() { return event_list_view_->content_view_; } + views::ScrollView* scroll_view() { return event_list_view_->scroll_view_; } CalendarViewController* controller() { return controller_.get(); } + int current_or_next_event_index() { + return event_list_view_->current_or_next_event_index_; + } views::View* GetSameDayEventsContainer() { views::View* container = @@ -149,12 +183,19 @@ bool IsCalendarJellyEnabled() { return GetParam(); } + static base::Time FakeTimeNow() { return fake_time_; } + static void SetFakeNow(base::Time fake_now) { fake_time_ = fake_now; } + private: + std::unique_ptr<views::Widget> widget_; std::unique_ptr<CalendarEventListView> event_list_view_; std::unique_ptr<CalendarViewController> controller_; + static base::Time fake_time_; base::test::ScopedFeatureList scoped_feature_list_; }; +base::Time CalendarViewEventListViewTest::fake_time_; + INSTANTIATE_TEST_SUITE_P(All, CalendarViewEventListViewTest, testing::Bool()); TEST_P(CalendarViewEventListViewTest, ShowEvents) { @@ -279,4 +320,156 @@ EXPECT_EQ(u"summary_0", GetSummary(0)->GetText()); } +TEST_P(CalendarViewEventListViewTest, ScrollToCurrentOrNextEvent) { + if (!features::IsCalendarJellyEnabled()) { + return; + } + + // Sets the timezone to GMT. Otherwise in other timezones events can become + // multi-day events that will be ignored when calculating index. + ash::system::ScopedTimezoneSettings timezone_settings(u"GMT"); + + // Sets today to be a day with many events, so `event_list_view()` is + // scrollable. + base::Time date; + ASSERT_TRUE(base::Time::FromString("23 Nov 2021 08:00 GMT", &date)); + CreateEventListView(date); + + SetSelectedDate(date); + + // Sets the current time to be a time that event id_9 has started. + base::Time current_time; + ASSERT_TRUE(base::Time::FromString("23 Nov 2021 02:40 GMT", ¤t_time)); + SetFakeNow(current_time); + base::subtle::ScopedTimeClockOverrides time_override( + &CalendarViewEventListViewTest::FakeTimeNow, + /*time_ticks_override=*/nullptr, /*thread_ticks_override=*/nullptr); + UpdateEventList(); + views::test::RunScheduledLayout(event_list_view()); + + // The current or next event should be the second event(event id_9). + EXPECT_EQ(1, current_or_next_event_index()); + + // The top of `scroll_view()` visible rect should be the same with the top of + // the current or next event. + auto scroll_view_visible_bounds = scroll_view()->GetVisibleBounds(); + views::View::ConvertRectToScreen(scroll_view(), &scroll_view_visible_bounds); + auto current_item_bounds = + GetHighlightView(current_or_next_event_index())->GetBoundsInScreen(); + EXPECT_EQ(scroll_view_visible_bounds.y(), current_item_bounds.y()); +} + +TEST_P(CalendarViewEventListViewTest, + ScrollToCurrentOrNextEvent_WithMultiDayEvents) { + if (!features::IsCalendarJellyEnabled()) { + return; + } + + // Sets the timezone to HST. The first two events become multi-day events, and + // will be ignored when calculating index. + ash::system::ScopedTimezoneSettings timezone_settings(u"Pacific/Honolulu"); + + // Sets the current time in HST to make today 18 Nov in local time. + base::Time date; + ASSERT_TRUE(base::Time::FromString("18 Nov 2021 8:10 HST", &date)); + CreateEventListView(date); + + SetSelectedDate(date); + + // Sets the current time to be a time that event id_2 has started. + base::Time current_time; + ASSERT_TRUE(base::Time::FromString("18 Nov 2021 11:40 GMT", ¤t_time)); + SetFakeNow(current_time); + base::subtle::ScopedTimeClockOverrides time_override( + &CalendarViewEventListViewTest::FakeTimeNow, + /*time_ticks_override=*/nullptr, /*thread_ticks_override=*/nullptr); + UpdateEventList(); + + // The current or next event should be the first event with id_2 since the + // first two events are multi-day events. + EXPECT_EQ(0, current_or_next_event_index()); + + // The top of `scroll_view()` visible rect should be the same with the top of + // the current or next event. + auto scroll_view_visible_bounds = scroll_view()->GetVisibleBounds(); + views::View::ConvertRectToScreen(scroll_view(), &scroll_view_visible_bounds); + auto current_item_bounds = + GetHighlightView(current_or_next_event_index())->GetBoundsInScreen(); + EXPECT_EQ(scroll_view_visible_bounds.y(), current_item_bounds.y()); +} + +TEST_P(CalendarViewEventListViewTest, + ScrollToCurrentOrNextEvent_PassedDatesStayAtTop) { + if (!features::IsCalendarJellyEnabled()) { + return; + } + + // Sets the timezone to GMT. Otherwise in other timezones events can become + // multi-day events that will be ignored when calculating index. + ash::system::ScopedTimezoneSettings timezone_settings(u"GMT"); + + base::Time date; + ASSERT_TRUE(base::Time::FromString("18 Nov 2021 8:10 GMT", &date)); + CreateEventListView(date); + + SetSelectedDate(date); + + // Sets the current time to be a time that all events for today have passed. + base::Time current_time; + ASSERT_TRUE(base::Time::FromString("19 Nov 2021 11:40 GMT", ¤t_time)); + SetFakeNow(current_time); + base::subtle::ScopedTimeClockOverrides time_override( + &CalendarViewEventListViewTest::FakeTimeNow, + /*time_ticks_override=*/nullptr, /*thread_ticks_override=*/nullptr); + UpdateEventList(); + views::test::RunScheduledLayout(event_list_view()); + + // The current or next event should be the default value. + EXPECT_EQ(0, current_or_next_event_index()); + + // The `scroll_view()` should stay at the top of the list. + auto scroll_view_visible_bounds = scroll_view()->GetVisibleBounds(); + views::View::ConvertRectToScreen(scroll_view(), &scroll_view_visible_bounds); + auto list_top_bounds = + GetHighlightView(current_or_next_event_index())->GetBoundsInScreen(); + EXPECT_EQ(scroll_view_visible_bounds.y(), list_top_bounds.y()); +} + +TEST_P(CalendarViewEventListViewTest, + ScrollToCurrentOrNextEvent_FutureDatesStaysAtTop) { + if (!features::IsCalendarJellyEnabled()) { + return; + } + + // Sets the timezone to GMT. Otherwise in other timezones events can become + // multi-day events that will be ignored when calculating index. + ash::system::ScopedTimezoneSettings timezone_settings(u"GMT"); + + base::Time date; + ASSERT_TRUE(base::Time::FromString("18 Nov 2021 8:10 GMT", &date)); + CreateEventListView(date); + + SetSelectedDate(date); + + // Sets the current time to be a time before today. + base::Time current_time; + ASSERT_TRUE(base::Time::FromString("17 Nov 2021 11:40 GMT", ¤t_time)); + SetFakeNow(current_time); + base::subtle::ScopedTimeClockOverrides time_override( + &CalendarViewEventListViewTest::FakeTimeNow, + /*time_ticks_override=*/nullptr, /*thread_ticks_override=*/nullptr); + UpdateEventList(); + views::test::RunScheduledLayout(event_list_view()); + + // The current or next event should be the first event. + EXPECT_EQ(0, current_or_next_event_index()); + + // The `scroll_view()` should stay at the top of the list. + auto scroll_view_visible_bounds = scroll_view()->GetVisibleBounds(); + views::View::ConvertRectToScreen(scroll_view(), &scroll_view_visible_bounds); + auto first_item_bounds = + GetHighlightView(current_or_next_event_index())->GetBoundsInScreen(); + EXPECT_EQ(scroll_view_visible_bounds.y(), first_item_bounds.y()); +} + } // namespace ash
diff --git a/ash/webui/common/resources/cellular_setup/esim_flow_ui.js b/ash/webui/common/resources/cellular_setup/esim_flow_ui.js index 1a4a4c6..af09d8b 100644 --- a/ash/webui/common/resources/cellular_setup/esim_flow_ui.js +++ b/ash/webui/common/resources/cellular_setup/esim_flow_ui.js
@@ -870,6 +870,10 @@ /** @private */ getLoadingMessage_() { + if (this.smdsSupportEnabled_) { + return this.i18n('profileLoadingPageMessage'); + } + return this.hasHadActiveCellularNetwork_ ? this.i18n('eSimProfileDetectDuringActiveCellularConnectionMessage') : this.i18n('eSimProfileDetectMessage'); @@ -888,6 +892,19 @@ return this.i18n('profileDiscoveryConsentTitle'); } + if (this.smdsSupportEnabled_) { + if (this.selectedESimPageName_ === ESimPageName.PROFILE_DISCOVERY) { + return this.i18n('profileDiscoveryPageTitle'); + } + + if (this.selectedESimPageName_ == ESimPageName.CONFIRMATION_CODE) { + return this.i18n('confimationCodePageTitle'); + } + if (this.selectedESimPageName_ == ESimPageName.PROFILE_LOADING) { + return this.i18n('profileLoadingPageTitle'); + } + } + return ''; },
diff --git a/ash/webui/firmware_update_ui/resources/fake_update_controller.ts b/ash/webui/firmware_update_ui/resources/fake_update_controller.ts index 9f34e6a..2f0d9a5 100644 --- a/ash/webui/firmware_update_ui/resources/fake_update_controller.ts +++ b/ash/webui/firmware_update_ui/resources/fake_update_controller.ts
@@ -4,7 +4,7 @@ import {FakeObservables} from 'chrome://resources/ash/common/fake_observables.js'; import {PromiseResolver} from 'chrome://resources/ash/common/promise_resolver.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {fakeFirmwareUpdates, fakeInstallationProgress, fakeInstallationProgressFailure} from './fake_data.js'; import {FirmwareUpdate, InstallationProgress, UpdateProgressObserverRemote, UpdateProviderInterface, UpdateState} from './firmware_update.mojom-webui.js';
diff --git a/ash/webui/firmware_update_ui/resources/firmware_update_dialog.ts b/ash/webui/firmware_update_ui/resources/firmware_update_dialog.ts index 925b5266..9b0a4c8c 100644 --- a/ash/webui/firmware_update_ui/resources/firmware_update_dialog.ts +++ b/ash/webui/firmware_update_ui/resources/firmware_update_dialog.ts
@@ -13,7 +13,7 @@ import './strings.m.js'; import {I18nMixin, I18nMixinInterface} from 'chrome://resources/cr_elements/i18n_mixin.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {mojoString16ToString} from 'chrome://resources/js/mojo_type_util.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/ash/webui/firmware_update_ui/resources/mojo_interface_provider.ts b/ash/webui/firmware_update_ui/resources/mojo_interface_provider.ts index 4eedbd0..64cbe11 100644 --- a/ash/webui/firmware_update_ui/resources/mojo_interface_provider.ts +++ b/ash/webui/firmware_update_ui/resources/mojo_interface_provider.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {fakeFirmwareUpdates} from './fake_data.js'; import {FakeUpdateController} from './fake_update_controller.js';
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.cc b/ash/wm/tablet_mode/tablet_mode_controller.cc index eff69385b..f6c5e5cc 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller.cc
@@ -145,9 +145,14 @@ // Returns true if the device has an active internal display. bool HasActiveInternalDisplay() { - return display::HasInternalDisplay() && - Shell::Get()->display_manager()->IsActiveDisplayId( - display::Display::InternalDisplayId()); + if (!display::HasInternalDisplay()) { + return false; + } + + display::DisplayManager* display_manager = Shell::Get()->display_manager(); + return display_manager->IsActiveDisplayId( + display::Display::InternalDisplayId()) || + display_manager->IsInUnifiedMode(); } // Returns true if |sequence| has the same properties as the ones we care about
diff --git a/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc b/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc index d579fd6..080c2e0 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc
@@ -173,6 +173,10 @@ bool IsTabletModeStarted() const { return test_api_->IsTabletModeStarted(); } + bool IsInPhysicalTabletState() const { + return test_api_->IsInPhysicalTabletState(); + } + // Attaches a SimpleTestTickClock to the TabletModeController with a non // null value initial value. void AttachTickClockForTest() { @@ -669,6 +673,31 @@ EXPECT_FALSE(AreEventsBlocked()); } +// Tests that tablet mode change events are fired while in unified desktop mode. +TEST_F(TabletModeControllerTest, + TabletModeChangeEventsFiredInUnifiedDesktopMode) { + UpdateDisplay("300x200, 300x200"); + display::test::DisplayManagerTestApi(display_manager()) + .SetFirstDisplayAsInternalDisplay(); + ASSERT_FALSE(IsTabletModeStarted()); + + // Turn on unified desktop mode. + display_manager()->SetUnifiedDesktopEnabled(true); + ASSERT_TRUE(display_manager()->IsInUnifiedMode()); + + // Opening the lid to 270 degrees should start tablet mode. + OpenLidToAngle(270.0f); + EXPECT_TRUE(IsTabletModeStarted()); + EXPECT_TRUE(IsInPhysicalTabletState()); + EXPECT_TRUE(AreEventsBlocked()); + + // Opening the lid to 30 degrees should stop tablet mode. + OpenLidToAngle(30.0f); + EXPECT_FALSE(IsTabletModeStarted()); + EXPECT_FALSE(IsInPhysicalTabletState()); + EXPECT_FALSE(AreEventsBlocked()); +} + // Tests that is a tablet mode signal is received while docked, that maximize // mode is enabled upon exiting docked mode. TEST_F(TabletModeControllerTest, TabletModeAfterExitingDockedMode) {
diff --git a/base/BUILD.gn b/base/BUILD.gn index 32dfbbad..cf178fb3 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -3290,6 +3290,7 @@ "sequence_checker_unittest.cc", "sequence_token_unittest.cc", "state_transitions_unittest.cc", + "std_clamp_unittest.cc", "stl_util_unittest.cc", "strings/abseil_string_number_conversions_unittest.cc", "strings/escape_unittest.cc", @@ -3470,10 +3471,7 @@ } if (use_safe_libcxx) { - sources += [ - "libcpp_hardening_test.cc", - "std_clamp_unittest.cc", - ] + sources += [ "libcpp_hardening_test.cc" ] } defines = []
diff --git a/base/cpu_reduction_experiment.cc b/base/cpu_reduction_experiment.cc index f1584d45..d8291f3 100644 --- a/base/cpu_reduction_experiment.cc +++ b/base/cpu_reduction_experiment.cc
@@ -20,7 +20,7 @@ // Whether to enable a series of optimizations that reduce total CPU // utilization. BASE_FEATURE(kReduceCpuUtilization, - "ReduceCpuUtilization", + "ReduceCpuUtilization2", FEATURE_ENABLED_BY_DEFAULT); class CpuReductionExperimentSubSampler {
diff --git a/base/metrics/persistent_histogram_allocator.cc b/base/metrics/persistent_histogram_allocator.cc index dcf26dc..de2c814 100644 --- a/base/metrics/persistent_histogram_allocator.cc +++ b/base/metrics/persistent_histogram_allocator.cc
@@ -100,6 +100,62 @@ return bucket_count * kBytesPerBucket; } +void MergeSamplesToExistingHistogram( + HistogramBase* existing, + const HistogramBase* histogram, + std::unique_ptr<HistogramSamples> samples) { +#if !BUILDFLAG(IS_NACL) + // If the passed |histogram| does not match with |existing| (i.e. the one + // registered with the global StatisticsRecorder) due to not being the same + // type of histogram or due to specifying different buckets, then unexpected + // things may happen further down the line. This may be indicative that a + // child process is emitting a histogram with different parameters than the + // browser process, for example. + // TODO(crbug/1432981): Remove this. Used to investigate failures when merging + // histograms from an allocator to the global StatisticsRecorder. + bool histograms_match = true; + HistogramType existing_type = existing->GetHistogramType(); + if (histogram->GetHistogramType() != existing_type) { + // Different histogram types. + histograms_match = false; + } else if (existing_type == HistogramType::HISTOGRAM || + existing_type == HistogramType::LINEAR_HISTOGRAM || + existing_type == HistogramType::BOOLEAN_HISTOGRAM || + existing_type == HistogramType::CUSTOM_HISTOGRAM) { + // Only numeric histograms make use of BucketRanges. + const BucketRanges* existing_buckets = + static_cast<const Histogram*>(existing)->bucket_ranges(); + const BucketRanges* histogram_buckets = + static_cast<const Histogram*>(histogram)->bucket_ranges(); + // DCHECK because HasValidChecksum() recomputes the checksum which can be + // expensive to do in a loop. + DCHECK(existing_buckets->HasValidChecksum() && + histogram_buckets->HasValidChecksum()); + + if (existing_buckets->checksum() != histogram_buckets->checksum()) { + // Different buckets. + histograms_match = false; + } + } + + if (!histograms_match) { + // If the histograms do not match, then the call to AddSamples() below might + // trigger a NOTREACHED(). Include the histogram name here for debugging + // purposes. This is not done in GetOrCreateStatisticsRecorderHistogram() + // directly, since that could incorrectly create crash reports for enum + // histograms that have newly appended entries (different bucket max and + // count). + SCOPED_CRASH_KEY_STRING256("PersistentHistogramAllocator", "histogram", + existing->histogram_name()); + existing->AddSamples(*samples); + return; + } +#endif // !BUILDFLAG(IS_NACL) + + // Merge the delta from the passed object to the one in the SR. + existing->AddSamples(*samples); +} + } // namespace PersistentSparseHistogramDataManager::PersistentSparseHistogramDataManager( @@ -462,8 +518,7 @@ return; } - // Merge the delta from the passed object to the one in the SR. - existing->AddSamples(*samples); + MergeSamplesToExistingHistogram(existing, histogram, std::move(samples)); } void PersistentHistogramAllocator::MergeHistogramFinalDeltaToStatisticsRecorder( @@ -485,8 +540,7 @@ return; } - // Merge the delta from the passed object to the one in the SR. - existing->AddSamples(*samples); + MergeSamplesToExistingHistogram(existing, histogram, std::move(samples)); } std::unique_ptr<PersistentSampleMapRecords> @@ -660,47 +714,6 @@ HistogramBase* existing = StatisticsRecorder::FindHistogram(histogram->histogram_name()); if (existing) { -#if !BUILDFLAG(IS_NACL) - // If the passed |histogram| does not match the one registered with the - // global StatisticsRecorder (e.g. not same type of histogram, or they - // specify different buckets), then unexpected things may happen further - // down the line. This may be indicative that a child process is emitting a - // histogram with different parameters than the browser process, for - // example. - // TODO(crbug/1432981): Remove this. Used to investigate failures when - // merging histograms from an allocator to the global StatisticsRecorder. - bool histograms_match = true; - HistogramType existing_type = existing->GetHistogramType(); - if (histogram->GetHistogramType() != existing_type) { - // Different histogram types. - histograms_match = false; - } else if (existing_type == HistogramType::HISTOGRAM || - existing_type == HistogramType::LINEAR_HISTOGRAM || - existing_type == HistogramType::BOOLEAN_HISTOGRAM || - existing_type == HistogramType::CUSTOM_HISTOGRAM) { - // Only numeric histograms make use of BucketRanges. - const BucketRanges* existing_buckets = - static_cast<const Histogram*>(existing)->bucket_ranges(); - const BucketRanges* histogram_buckets = - static_cast<const Histogram*>(histogram)->bucket_ranges(); - // DCHECK because HasValidChecksum() recomputes the checksum which can be - // expensive to do in a loop. - DCHECK(existing_buckets->HasValidChecksum() && - histogram_buckets->HasValidChecksum()); - - if (existing_buckets->checksum() != histogram_buckets->checksum()) { - // Different buckets. - histograms_match = false; - } - } - - if (!histograms_match) { - SCOPED_CRASH_KEY_STRING256("PersistentHistogramAllocator", "histogram", - existing->histogram_name()); - NOTREACHED(); - } -#endif // !BUILDFLAG(IS_NACL) - return existing; }
diff --git a/base/strings/string_piece_unittest.cc b/base/strings/string_piece_unittest.cc index 77a47f8..7685950 100644 --- a/base/strings/string_piece_unittest.cc +++ b/base/strings/string_piece_unittest.cc
@@ -684,7 +684,14 @@ } } -#if defined(_LIBCPP_ENABLE_ASSERTIONS) +// Chromium development assumes StringPiece (which is std::string_view) is +// implemented with an STL that enables hardening checks. We treat bugs that +// trigger one of these conditions as functional rather than security bugs. If +// this test fails on some embedder, it should not be disabled. Instead, the +// embedder should fix their STL or build configuration to enable corresponding +// hardening checks. +// +// See https://chromium.googlesource.com/chromium/src/+/main/docs/security/faq.md#indexing-a-container-out-of-bounds-hits-a-libcpp_verbose_abort_is-this-a-security-bug TEST(StringPieceTest, OutOfBoundsDeath) { { constexpr StringPiece piece; @@ -726,7 +733,6 @@ int length = -1; ASSERT_DEATH_IF_SUPPORTED({ StringPiece piece("hello", length); }, ""); } -#endif // defined(_LIBCPP_ENABLE_ASSERTIONS) TEST(StringPieceTest, ConstexprData) { {
diff --git a/base/tracing/protos/chrome_track_event.proto b/base/tracing/protos/chrome_track_event.proto index 8656e00d..c3c1888 100644 --- a/base/tracing/protos/chrome_track_event.proto +++ b/base/tracing/protos/chrome_track_event.proto
@@ -1424,9 +1424,32 @@ optional int32 num_frames = 2; }; +message ScrollPredictorMetrics { + message EventFrameValue { + optional int64 event_trace_id = 1; + optional float delta_value = 2; + }; + // Data from the previous, current, and next frame used to determine the + // values below as according to the metric doc: + // http://doc/1Y0u0Tq5eUZff75nYUzQVw6JxmbZAW9m64pJidmnGWsY. + optional EventFrameValue prev_event_frame_value = 1; + optional EventFrameValue cur_event_frame_value = 2; + optional EventFrameValue next_event_frame_value = 3; + // This is the amount of delta processed in this frame that was above the + // janky threshold (as defined by + // http://doc/1Y0u0Tq5eUZff75nYUzQVw6JxmbZAW9m64pJidmnGWsY) + optional float janky_value = 4; + // True if we are also missing frames (so multiple frames are being presented + // at once). + optional bool has_missed_vsyncs = 5; + // True if we're moving less than the slow scroll threshold as defined by the + // doc above. + optional bool is_slow_scroll = 6; +}; + message ChromeTrackEvent { // Extension range for Chrome: 1000-1999 - // Next ID: 1055 + // Next ID: 1056 extend TrackEvent { optional ChromeAppState chrome_app_state = 1000; @@ -1542,5 +1565,7 @@ optional CrasUnified chromeos_cras_unified = 1053; optional LibunwindstackUnwinder libunwindstack_unwinder = 1054; + + optional ScrollPredictorMetrics scroll_predictor_metrics = 1055; } }
diff --git a/build/android/fast_local_dev_server.py b/build/android/fast_local_dev_server.py index 282dcf5..a8ac4b0 100755 --- a/build/android/fast_local_dev_server.py +++ b/build/android/fast_local_dev_server.py
@@ -147,6 +147,7 @@ self.cmd = cmd self.stamp_file = stamp_file self._terminated = False + self._replaced = False self._lock = threading.Lock() self._proc: Optional[subprocess.Popen] = None self._thread: Optional[threading.Thread] = None @@ -192,13 +193,14 @@ self._thread.start() return 1 - def terminate(self): + def terminate(self, replaced=False): """Can be called multiple times to cancel and ignore the task's output.""" with self._lock: if self._terminated: return self._terminated = True + self._replaced = replaced # It is safe to access _proc and _thread outside of _lock since they are # only changed by self.start holding _lock when self._terminate is false. # Since we have just set self._terminate to true inside of _lock, we know @@ -230,15 +232,17 @@ that this method does not need locking.""" TaskStats.complete_task() - failed = False + delete_stamp = False if self._terminated: log(f'TERMINATED {self.name}') - # Ignore stdout as it is now outdated. - failed = True + # When tasks are replaced, avoid deleting the stamp file, context: + # https://issuetracker.google.com/301961827. + if not self._replaced: + delete_stamp = True else: log(f'FINISHED {self.name}') if stdout or self._return_code != 0: - failed = True + delete_stamp = True # An extra new line is needed since we want to preserve the previous # _log line. Use a single print so that it is threadsafe. # TODO(wnwen): Improve stdout display by parsing over it and moving the @@ -251,7 +255,7 @@ stdout, ])) - if failed: + if delete_stamp: # Force ninja to consider failed targets as dirty. try: os.unlink(os.path.join(self.cwd, self.stamp_file)) @@ -293,7 +297,7 @@ stamp_file=data['stamp_file']) existing_task = tasks.get(task.key) if existing_task: - existing_task.terminate() + existing_task.terminate(replaced=True) tasks[task.key] = task task_manager.add_task(task) except KeyboardInterrupt:
diff --git a/cc/input/single_scrollbar_animation_controller_thinning.cc b/cc/input/single_scrollbar_animation_controller_thinning.cc index 811a9312..e047e1f 100644 --- a/cc/input/single_scrollbar_animation_controller_thinning.cc +++ b/cc/input/single_scrollbar_animation_controller_thinning.cc
@@ -22,7 +22,8 @@ const ScrollbarPart part) { gfx::RectF rect; if (part == ScrollbarPart::kThumb) { - rect = gfx::RectF(gfx::Rect(scrollbar.ComputeExpandedThumbQuadRect())); + rect = gfx::RectF( + gfx::Rect(scrollbar.ComputeHitTestableExpandedThumbQuadRect())); } else { rect = gfx::RectF(gfx::Rect(scrollbar.bounds())); }
diff --git a/cc/layers/painted_scrollbar_layer_impl.cc b/cc/layers/painted_scrollbar_layer_impl.cc index c7c105a5..a5ccdc3 100644 --- a/cc/layers/painted_scrollbar_layer_impl.cc +++ b/cc/layers/painted_scrollbar_layer_impl.cc
@@ -189,43 +189,60 @@ gfx::Rect PaintedScrollbarLayerImpl::ComputeThumbQuadRect() const { gfx::Rect thumb_rect = ScrollbarLayerImplBase::ComputeThumbQuadRect(); - // Position composited Fluent scrollbar thumb in the center of the track. if (IsFluentScrollbarEnabled()) { - const int track_thickness = - orientation() == ScrollbarOrientation::kHorizontal - ? track_rect_.height() - : track_rect_.width(); - const int thumb_offset = - static_cast<int>((track_thickness - ThumbThickness()) / 2.0f); - - if (orientation() == ScrollbarOrientation::kHorizontal) { - thumb_rect.Offset(0, thumb_offset); - } else { - thumb_rect.Offset( - is_left_side_vertical_scrollbar() ? -thumb_offset : thumb_offset, 0); - } + thumb_rect = CenterFluentScrollbarThumb(thumb_rect); } return thumb_rect; } gfx::Rect PaintedScrollbarLayerImpl::ComputeHitTestableThumbQuadRect() const { - if (!IsFluentScrollbarEnabled()) - return ScrollbarLayerImplBase::ComputeHitTestableThumbQuadRect(); + if (IsFluentScrollbarEnabled()) { + return ExpandFluentScrollbarThumb(ComputeThumbQuadRect()); + } + return ScrollbarLayerImplBase::ComputeHitTestableThumbQuadRect(); +} - // Expand the scrollbar thumb's hit testable rect to be able to capture - // the thumb across the entire width of the track rect. - gfx::Rect thumb_rect = ComputeThumbQuadRect(); +gfx::Rect PaintedScrollbarLayerImpl::ComputeHitTestableExpandedThumbQuadRect() + const { + CHECK(is_overlay_scrollbar()); + if (IsFluentOverlayScrollbarEnabled()) { + return ExpandFluentScrollbarThumb(CenterFluentScrollbarThumb( + ScrollbarLayerImplBase::ComputeHitTestableExpandedThumbQuadRect())); + } + return ScrollbarLayerImplBase::ComputeHitTestableExpandedThumbQuadRect(); +} + +gfx::Rect PaintedScrollbarLayerImpl::CenterFluentScrollbarThumb( + gfx::Rect thumb_rect) const { + CHECK(IsFluentScrollbarEnabled() || IsFluentOverlayScrollbarEnabled()); + const int track_thickness = orientation() == ScrollbarOrientation::kHorizontal + ? track_rect_.height() + : track_rect_.width(); + const int thumb_offset = + static_cast<int>((track_thickness - ThumbThickness()) / 2.0f); + + if (orientation() == ScrollbarOrientation::kHorizontal) { + thumb_rect.Offset(0, thumb_offset); + } else { + thumb_rect.Offset( + is_left_side_vertical_scrollbar() ? -thumb_offset : thumb_offset, 0); + } + return thumb_rect; +} + +gfx::Rect PaintedScrollbarLayerImpl::ExpandFluentScrollbarThumb( + gfx::Rect thumb_rect) const { + CHECK(IsFluentScrollbarEnabled() || IsFluentOverlayScrollbarEnabled()); const gfx::Rect back_track_rect = BackTrackRect(); if (orientation() == ScrollbarOrientation::kHorizontal) { thumb_rect.set_y(back_track_rect.y()); thumb_rect.set_height(back_track_rect.height()); return thumb_rect; - } else { - thumb_rect.set_x(back_track_rect.x()); - thumb_rect.set_width(back_track_rect.width()); - return thumb_rect; } + thumb_rect.set_x(back_track_rect.x()); + thumb_rect.set_width(back_track_rect.width()); + return thumb_rect; } void PaintedScrollbarLayerImpl::SetJumpOnTrackClick(bool jump_on_track_click) {
diff --git a/cc/layers/painted_scrollbar_layer_impl.h b/cc/layers/painted_scrollbar_layer_impl.h index 62485f3..1bc3b350 100644 --- a/cc/layers/painted_scrollbar_layer_impl.h +++ b/cc/layers/painted_scrollbar_layer_impl.h
@@ -47,6 +47,7 @@ gfx::Rect GetEnclosingVisibleRectInTargetSpace() const override; gfx::Rect ComputeThumbQuadRect() const override; gfx::Rect ComputeHitTestableThumbQuadRect() const override; + gfx::Rect ComputeHitTestableExpandedThumbQuadRect() const override; void SetJumpOnTrackClick(bool jump_on_track_click); void SetSupportsDragSnapBack(bool supports_drag_snap_back); @@ -96,6 +97,11 @@ private: const char* LayerTypeAsString() const override; + // Expand the scrollbar thumb's hit testable rect to be able to capture the + // thumb across the entire width of the track rect. + gfx::Rect ExpandFluentScrollbarThumb(gfx::Rect thumb_rect) const; + // Position composited Fluent scrollbar thumb in the center of the track. + gfx::Rect CenterFluentScrollbarThumb(gfx::Rect thumb_rect) const; UIResourceId track_ui_resource_id_; UIResourceId thumb_ui_resource_id_;
diff --git a/cc/layers/painted_scrollbar_layer_impl_unittest.cc b/cc/layers/painted_scrollbar_layer_impl_unittest.cc index d10f548e..7ea3f85 100644 --- a/cc/layers/painted_scrollbar_layer_impl_unittest.cc +++ b/cc/layers/painted_scrollbar_layer_impl_unittest.cc
@@ -158,19 +158,32 @@ bool is_left_side_vertical_scrollbar, const gfx::Rect& track_rect, int thumb_thickness, - int thumb_length) { + int thumb_length, + bool is_overlay = false) { PaintedScrollbarLayerImpl* scrollbar_layer_impl = impl_->AddLayer<PaintedScrollbarLayerImpl>( - orientation, is_left_side_vertical_scrollbar, /*is_overlay=*/false); + orientation, is_left_side_vertical_scrollbar, is_overlay); scrollbar_layer_impl->SetTrackRect(track_rect); scrollbar_layer_impl->SetThumbThickness(thumb_thickness); scrollbar_layer_impl->SetThumbLength(thumb_length); + scrollbar_layer_impl->SetBounds(track_rect.size()); return scrollbar_layer_impl; } std::unique_ptr<LayerTreeImplTestBase> impl_; }; +class PaintedScrollbarLayerImplFluentOverlayTest + : public PaintedScrollbarLayerImplFluentTest { + protected: + void SetUp() override { + LayerTreeSettings settings; + settings.enable_fluent_overlay_scrollbar = true; + settings.enable_fluent_scrollbar = true; + impl_ = std::make_unique<LayerTreeImplTestBase>(settings); + } +}; + TEST_F(PaintedScrollbarLayerImplFluentTest, ComputeThumbQuadRect) { const PaintedScrollbarLayerImpl* scrollbar_layer_impl_vertical = SetUpScrollbarLayerImpl(ScrollbarOrientation::kVertical, false, @@ -218,25 +231,26 @@ // verify that the computed thickness is the width of the track. This prevents // cases where clicking on the margin of the thumb would cause the thumb to not // consider itself clicked/captured. -TEST(PaintedScrollbarLayerImplTest, OverlayFluentThumbHasNoMargin) { - LayerTreeSettings settings; - settings.enable_fluent_overlay_scrollbar = true; +TEST_F(PaintedScrollbarLayerImplFluentOverlayTest, + OverlayFluentThumbHasNoMargin) { { - LayerTreeImplTestBase impl(settings); - ScrollbarOrientation orientation = ScrollbarOrientation::kVertical; - PaintedScrollbarLayerImpl* scrollbar_layer_impl = - impl.AddLayer<PaintedScrollbarLayerImpl>(orientation, false, - /*is_overlay=*/true); - gfx::Rect thumb = scrollbar_layer_impl->ComputeExpandedThumbQuadRect(); + const PaintedScrollbarLayerImpl* scrollbar_layer_impl = + SetUpScrollbarLayerImpl(ScrollbarOrientation::kVertical, + /*is_left_side_vertical_scrollbar=*/false, + gfx::Rect(0, 0, 14, 100), 6, 30, + /*is_overlay=*/true); + gfx::Rect thumb = + scrollbar_layer_impl->ComputeHitTestableExpandedThumbQuadRect(); EXPECT_EQ(scrollbar_layer_impl->bounds().width(), thumb.width()); } { - LayerTreeImplTestBase impl(settings); - ScrollbarOrientation orientation = ScrollbarOrientation::kHorizontal; - PaintedScrollbarLayerImpl* scrollbar_layer_impl = - impl.AddLayer<PaintedScrollbarLayerImpl>(orientation, false, - /*is_overlay=*/true); - gfx::Rect thumb = scrollbar_layer_impl->ComputeExpandedThumbQuadRect(); + const PaintedScrollbarLayerImpl* scrollbar_layer_impl = + SetUpScrollbarLayerImpl(ScrollbarOrientation::kHorizontal, + /*is_left_side_vertical_scrollbar=*/false, + gfx::Rect(0, 0, 100, 14), 6, 30, + /*is_overlay=*/true); + gfx::Rect thumb = + scrollbar_layer_impl->ComputeHitTestableExpandedThumbQuadRect(); EXPECT_EQ(scrollbar_layer_impl->bounds().height(), thumb.height()); } }
diff --git a/cc/layers/scrollbar_layer_impl_base.cc b/cc/layers/scrollbar_layer_impl_base.cc index 3f760f3..ac019e24 100644 --- a/cc/layers/scrollbar_layer_impl_base.cc +++ b/cc/layers/scrollbar_layer_impl_base.cc
@@ -250,7 +250,8 @@ return gfx::ToEnclosingRect(thumb_rect); } -gfx::Rect ScrollbarLayerImplBase::ComputeExpandedThumbQuadRect() const { +gfx::Rect ScrollbarLayerImplBase::ComputeHitTestableExpandedThumbQuadRect() + const { DCHECK(is_overlay_scrollbar()); return ComputeThumbQuadRectWithThumbThicknessScale(1.f); }
diff --git a/cc/layers/scrollbar_layer_impl_base.h b/cc/layers/scrollbar_layer_impl_base.h index c415ae6..d77409b 100644 --- a/cc/layers/scrollbar_layer_impl_base.h +++ b/cc/layers/scrollbar_layer_impl_base.h
@@ -54,7 +54,7 @@ // Thumb quad rect in layer space. virtual gfx::Rect ComputeThumbQuadRect() const; virtual gfx::Rect ComputeHitTestableThumbQuadRect() const; - gfx::Rect ComputeExpandedThumbQuadRect() const; + virtual gfx::Rect ComputeHitTestableExpandedThumbQuadRect() const; float thumb_thickness_scale_factor() { return thumb_thickness_scale_factor_;
diff --git a/cc/metrics/compositor_frame_reporter.cc b/cc/metrics/compositor_frame_reporter.cc index 73683cae..dfb4ca67 100644 --- a/cc/metrics/compositor_frame_reporter.cc +++ b/cc/metrics/compositor_frame_reporter.cc
@@ -1481,7 +1481,8 @@ const auto end_timestamp = viz_breakdown_.presentation_feedback.timestamp; if (global_trackers_.predictor_jank_tracker) { global_trackers_.predictor_jank_tracker->ReportLatestScrollDelta( - total_predicted_delta, end_timestamp, args_.interval); + total_predicted_delta, end_timestamp, args_.interval, + earliest_event->AsScrollUpdate()->trace_id()); } if (global_trackers_.scroll_jank_dropped_frame_tracker) { global_trackers_.scroll_jank_dropped_frame_tracker @@ -1827,7 +1828,6 @@ [](const base::WeakPtr<CompositorFrameReporter>& reporter) { return !reporter; }); - } base::WeakPtr<CompositorFrameReporter> CompositorFrameReporter::GetWeakPtr() {
diff --git a/cc/metrics/predictor_jank_tracker.cc b/cc/metrics/predictor_jank_tracker.cc index b54566e..c1562b1 100644 --- a/cc/metrics/predictor_jank_tracker.cc +++ b/cc/metrics/predictor_jank_tracker.cc
@@ -9,6 +9,9 @@ #include <utility> #include "base/metrics/histogram_macros.h" #include "base/time/time.h" +#include "base/trace_event/trace_event.h" +#include "base/trace_event/typed_macros.h" +#include "base/tracing/protos/chrome_track_event.pbzero.h" namespace cc { namespace { @@ -63,7 +66,8 @@ void PredictorJankTracker::ReportLatestScrollDelta( float next_delta, base::TimeTicks next_presentation_ts, - base::TimeDelta vsync_interval) { + base::TimeDelta vsync_interval, + absl::optional<EventMetrics::TraceId> trace_id) { total_frames_++; float d1 = frame_data_.prev_delta_; float d2 = frame_data_.cur_delta_; @@ -72,7 +76,7 @@ // Verify no scrolling direction change as we can't compare // frames if the user changed their scrolling direction. if (!VerifyFramesSameDirection(d1, d2, d3)) { - StoreLatestFrameData(next_delta, next_presentation_ts); + StoreLatestFrameData(next_delta, next_presentation_ts, trace_id); return; } @@ -99,25 +103,61 @@ ContainsMissedVSync(next_presentation_ts, vsync_interval); if (frame_janky_lower >= janky_threshold) { - ReportJankyFrame(frame_janky_lower - janky_threshold, - contains_missed_vsyncs, slow_scroll); + ReportJankyFrame(next_delta, frame_janky_lower - janky_threshold, + contains_missed_vsyncs, slow_scroll, trace_id); } if (frame_janky_upper >= janky_threshold) { - ReportJankyFrame(frame_janky_upper - janky_threshold, - contains_missed_vsyncs, slow_scroll); + ReportJankyFrame(next_delta, frame_janky_upper - janky_threshold, + contains_missed_vsyncs, slow_scroll, trace_id); } if (total_frames_ >= 50) { ReportJankyFramePercentage(); } - StoreLatestFrameData(next_delta, next_presentation_ts); + StoreLatestFrameData(next_delta, next_presentation_ts, trace_id); } -void PredictorJankTracker::ReportJankyFrame(float janky_value, - bool contains_missed_vsyncs, - bool slow_scroll) { +void PredictorJankTracker::ReportJankyFrame( + float next_delta, + float janky_value, + bool contains_missed_vsyncs, + bool slow_scroll, + absl::optional<EventMetrics::TraceId> trace_id) { janky_frames_++; + TRACE_EVENT_INSTANT( + "input.scrolling", "PredictorJankTracker::ReportJankyFrame", + [&](perfetto::EventContext ctx) { + auto* event = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>(); + auto* scroll_data = event->set_scroll_predictor_metrics(); + { + // prev data. + auto* values = scroll_data->set_prev_event_frame_value(); + if (frame_data_.prev_trace_id_) { + values->set_event_trace_id(frame_data_.prev_trace_id_->value()); + } + values->set_delta_value(frame_data_.prev_delta_); + } + { + // cur data. + auto* values = scroll_data->set_cur_event_frame_value(); + if (frame_data_.cur_trace_id_) { + values->set_event_trace_id(frame_data_.cur_trace_id_->value()); + } + values->set_delta_value(frame_data_.cur_delta_); + } + { + // next data. + auto* values = scroll_data->set_next_event_frame_value(); + if (trace_id) { + values->set_event_trace_id(trace_id->value()); + } + values->set_delta_value(next_delta); + } + scroll_data->set_janky_value(janky_value); + scroll_data->set_has_missed_vsyncs(contains_missed_vsyncs); + scroll_data->set_is_slow_scroll(slow_scroll); + }); if (contains_missed_vsyncs && slow_scroll) { UMA_HISTOGRAM_CUSTOM_COUNTS( "Event.Jank.ScrollUpdate.SlowScroll.MissedVsync." @@ -159,9 +199,12 @@ void PredictorJankTracker::StoreLatestFrameData( float delta, - base::TimeTicks presentation_ts) { + base::TimeTicks presentation_ts, + absl::optional<EventMetrics::TraceId> trace_id) { frame_data_.prev_delta_ = frame_data_.cur_delta_; + frame_data_.prev_trace_id_ = frame_data_.cur_trace_id_; frame_data_.cur_delta_ = delta; + frame_data_.cur_trace_id_ = trace_id; frame_data_.prev_presentation_ts_ = frame_data_.cur_presentation_ts_; frame_data_.cur_presentation_ts_ = presentation_ts; }
diff --git a/cc/metrics/predictor_jank_tracker.h b/cc/metrics/predictor_jank_tracker.h index ece8b2a..1c69c93f 100644 --- a/cc/metrics/predictor_jank_tracker.h +++ b/cc/metrics/predictor_jank_tracker.h
@@ -7,6 +7,8 @@ #include "base/time/time.h" #include "cc/cc_export.h" +#include "cc/metrics/event_metrics.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace cc { @@ -25,7 +27,8 @@ // http://doc/1Y0u0Tq5eUZff75nYUzQVw6JxmbZAW9m64pJidmnGWsY void ReportLatestScrollDelta(float delta, base::TimeTicks presentation_ts, - base::TimeDelta vsync_interval); + base::TimeDelta vsync_interval, + absl::optional<EventMetrics::TraceId> trace_id); // Whenever a new scroll starts, data inside this class will be erased // as it should be comparing neighbouring frames only. @@ -35,11 +38,15 @@ // The metric works by storing a sliding window of the previous two // frames, this function moves the sliding window storing the newer // frame information. - void StoreLatestFrameData(float delta, base::TimeTicks presentation_ts); + void StoreLatestFrameData(float delta, + base::TimeTicks presentation_ts, + absl::optional<EventMetrics::TraceId> trace_id); - void ReportJankyFrame(float janky_value, + void ReportJankyFrame(float next_delta, + float janky_value, bool contains_missed_vsyncs, - bool slow_scroll); + bool slow_scroll, + absl::optional<EventMetrics::TraceId> trace_id); // Finds if a sequence of 3 consecutive frames were presnted in // consecutive vsyncs, or some vsyncs were missed. @@ -51,8 +58,12 @@ struct FrameData { // Delta for the previous frame in pixels. float prev_delta_ = 0; + // The EventLatency event_trace_id value if available. + absl::optional<EventMetrics::TraceId> prev_trace_id_; // Delta for the current frame in pixels. float cur_delta_ = 0; + // The EventLatency event_trace_id value if available. + absl::optional<EventMetrics::TraceId> cur_trace_id_; // Presentation timestamp of the previous frame. base::TimeTicks prev_presentation_ts_;
diff --git a/cc/metrics/predictor_jank_tracker_unittest.cc b/cc/metrics/predictor_jank_tracker_unittest.cc index c3002c5..4bc22eb 100644 --- a/cc/metrics/predictor_jank_tracker_unittest.cc +++ b/cc/metrics/predictor_jank_tracker_unittest.cc
@@ -3,8 +3,13 @@ // found in the LICENSE file. #include "cc/metrics/predictor_jank_tracker.h" + #include <memory> +#include <string> +#include <vector> + #include "base/test/metrics/histogram_tester.h" +#include "base/test/test_trace_processor.h" #include "base/time/time.h" #include "testing/gtest/include/gtest/gtest.h" @@ -15,19 +20,25 @@ PredictorJankTrackerTest() = default; void SetUp() override { + trace_id_ = 0; histogram_tester_ = std::make_unique<base::HistogramTester>(); predictor_jank_tracker_ = std::make_unique<PredictorJankTracker>(); base_presentation_ts_ = base::TimeTicks::Min(); } void MockFrameProduction(double delta, base::TimeTicks presentation_ts) { - predictor_jank_tracker_->ReportLatestScrollDelta(delta, presentation_ts, - vsync_interval); + predictor_jank_tracker_->ReportLatestScrollDelta( + delta, presentation_ts, vsync_interval, + EventMetrics::TraceId(++trace_id_)); } + int64_t trace_id_ = 0; std::unique_ptr<base::HistogramTester> histogram_tester_; std::unique_ptr<PredictorJankTracker> predictor_jank_tracker_; base::TimeTicks base_presentation_ts_; +#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) + ::base::test::TracingEnvironment tracing_environment_; +#endif // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) const char* missed_fast_histogram_name = "Event.Jank.ScrollUpdate.FastScroll.MissedVsync." "FrameAboveJankyThreshold2"; @@ -135,6 +146,44 @@ EXPECT_EQ(histogram_tester_->GetTotalSum(missed_fast_histogram_name), 380); } +#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) +TEST_F(PredictorJankTrackerTest, BasicNonMissedUpperJankCaseWithTracing) { + base::test::TestTraceProcessor ttp; + ttp.StartTrace("input.scrolling"); + // 50 / 10 = 5.0, > janky threshold and should be reporteed. + // No dropped frame as frames are separated by 16ms. + MockFrameProduction(10, base_presentation_ts_); + MockFrameProduction(50, base_presentation_ts_ + base::Milliseconds(16)); + MockFrameProduction(11, base_presentation_ts_ + base::Milliseconds(32)); + + absl::Status status = ttp.StopAndParseTrace(); + ASSERT_TRUE(status.ok()) << status.message(); + std::string query = + R"( + SELECT + EXTRACT_ARG(arg_set_id, + "scroll_predictor_metrics.prev_event_frame_value.delta_value" + ) AS prev_delta, + EXTRACT_ARG(arg_set_id, + "scroll_predictor_metrics.cur_event_frame_value.delta_value" + ) AS cur_delta, + EXTRACT_ARG(arg_set_id, + "scroll_predictor_metrics.next_event_frame_value.delta_value" + ) AS next_delta + FROM + slice + WHERE + name = "PredictorJankTracker::ReportJankyFrame" + )"; + auto result = ttp.RunQuery(query); + ASSERT_TRUE(result.has_value()) << result.error(); + EXPECT_THAT(result.value(), ::testing::ElementsAre( + std::vector<std::string>{ + "prev_delta", "cur_delta", "next_delta"}, + std::vector<std::string>{"10", "50", "11"})); +} + +#endif // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) TEST_F(PredictorJankTrackerTest, NoReportingDirectionChange) { // [50, -100, 50] means the user changed their scrolling direction // and no predictor performance should be reported.
diff --git a/cc/paint/image_transfer_cache_entry.cc b/cc/paint/image_transfer_cache_entry.cc index 5b7e286..a8273f05 100644 --- a/cc/paint/image_transfer_cache_entry.cc +++ b/cc/paint/image_transfer_cache_entry.cc
@@ -252,56 +252,6 @@ return true; } -size_t SafeSizeForTargetColorParams( - const absl::optional<TargetColorParams>& target_color_params) { - // bool for whether or not there are going to be parameters. - size_t target_color_params_size = PaintOpWriter::SerializedSize<bool>(); - if (target_color_params) { - // The target color space. - target_color_params_size += PaintOpWriter::SerializedSize( - target_color_params->color_space.ToSkColorSpace().get()); - target_color_params_size += PaintOpWriter::SerializedSize( - target_color_params->sdr_max_luminance_nits); - target_color_params_size += PaintOpWriter::SerializedSize( - target_color_params->hdr_max_luminance_relative); - } - return target_color_params_size; -} - -void WriteTargetColorParams( - PaintOpWriter& writer, - const absl::optional<TargetColorParams>& target_color_params) { - const bool has_target_color_params = !!target_color_params; - writer.Write(has_target_color_params); - if (target_color_params) { - writer.Write(target_color_params->color_space.ToSkColorSpace().get()); - writer.Write(target_color_params->sdr_max_luminance_nits); - writer.Write(target_color_params->hdr_max_luminance_relative); - } -} - -bool ReadTargetColorParams( - PaintOpReader& reader, - absl::optional<TargetColorParams>& target_color_params) { - bool has_target_color_params = false; - reader.Read(&has_target_color_params); - if (!has_target_color_params) { - target_color_params = absl::nullopt; - return true; - } - - target_color_params = TargetColorParams(); - sk_sp<SkColorSpace> target_color_space; - reader.Read(&target_color_space); - if (!target_color_space) - return false; - - target_color_params->color_space = gfx::ColorSpace(*target_color_space); - reader.Read(&target_color_params->sdr_max_luminance_nits); - reader.Read(&target_color_params->hdr_max_luminance_relative); - return true; -} - sk_sp<SkImage> ReadImage( PaintOpReader& reader, GrDirectContext* gr_context, @@ -527,9 +477,9 @@ const Image& image, bool needs_mips, const absl::optional<gfx::HDRMetadata>& hdr_metadata, - absl::optional<TargetColorParams> target_color_params) + sk_sp<SkColorSpace> target_color_space) : needs_mips_(needs_mips), - target_color_params_(target_color_params), + target_color_space_(target_color_space), id_(GetNextId()), image_(image), hdr_metadata_(hdr_metadata) { @@ -538,17 +488,6 @@ ClientImageTransferCacheEntry::ClientImageTransferCacheEntry( const Image& image, - bool needs_mips, - absl::optional<TargetColorParams> target_color_params) - : needs_mips_(needs_mips), - target_color_params_(target_color_params), - id_(GetNextId()), - image_(image) { - ComputeSize(); -} - -ClientImageTransferCacheEntry::ClientImageTransferCacheEntry( - const Image& image, const Image& gainmap_image, const SkGainmapInfo& gainmap_info, bool needs_mips) @@ -588,7 +527,7 @@ if (hdr_metadata_.has_value()) { writer.Write(hdr_metadata_.value()); } - WriteTargetColorParams(writer, target_color_params_); + writer.Write(target_color_space_.get()); WriteImage(writer, image_); if (has_gainmap) { @@ -610,7 +549,7 @@ if (hdr_metadata_.has_value()) { safe_size += PaintOpWriter::SerializedSize(hdr_metadata_.value()); } - safe_size += SafeSizeForTargetColorParams(target_color_params_); + safe_size += PaintOpWriter::SerializedSize(target_color_space_.get()); safe_size += SafeSizeForImage(image_); if (gainmap_image_) { DCHECK(gainmap_info_); @@ -706,9 +645,12 @@ image_->isTextureBacked() ? gr_context_ : nullptr, image_->isTextureBacked() ? graphite_recorder_ : nullptr); } else if (use_tone_curve_) { + // Images are always rendered as SDR-relative and the output color space + // is SDR itself, image = cache.ApplyToneCurve( - image_, tone_curve_hdr_metadata_, tone_curve_sdr_max_luminance_nits_, - hdr_headroom, image_->isTextureBacked() ? gr_context_ : nullptr, + image_, tone_curve_hdr_metadata_, + gfx::ColorSpace::kDefaultSDRWhiteLevel, hdr_headroom, + image_->isTextureBacked() ? gr_context_ : nullptr, image_->isTextureBacked() ? graphite_recorder_ : nullptr); } if (!image) { @@ -760,9 +702,10 @@ reader.Read(&hdr_metadata_value); tone_curve_hdr_metadata_ = hdr_metadata_value; } - absl::optional<TargetColorParams> target_color_params; - ReadTargetColorParams(reader, target_color_params); - const bool mip_mapped_for_upload = needs_mips && !target_color_params; + sk_sp<SkColorSpace> target_color_space; + reader.Read(&target_color_space); + + const bool mip_mapped_for_upload = needs_mips && !target_color_space; // Deserialize the image. image_ = ReadImage(reader, gr_context, graphite_recorder, @@ -798,20 +741,11 @@ } // Save the tone curve parameters, if they are to be used. - use_tone_curve_ = !has_gainmap_ && target_color_params && - gfx::ColorConversionSkFilterCache::UseToneCurve(image_); - if (use_tone_curve_) { - tone_curve_sdr_max_luminance_nits_ = - target_color_params->sdr_max_luminance_nits; - } + use_tone_curve_ = + !has_gainmap_ && gfx::ColorConversionSkFilterCache::UseToneCurve(image_); // Perform color conversion (if no tone mapping is needed). - if (target_color_params && !NeedsToneMapApplied()) { - auto target_color_space = target_color_params->color_space.ToSkColorSpace(); - if (!target_color_space) { - DLOG(ERROR) << "Invalid target color space."; - return false; - } + if (target_color_space && !NeedsToneMapApplied()) { if (graphite_recorder_) { SkImage::RequiredProperties props{.fMipmapped = needs_mips}; image_ =
diff --git a/cc/paint/image_transfer_cache_entry.h b/cc/paint/image_transfer_cache_entry.h index 18b3f24b..611ff79 100644 --- a/cc/paint/image_transfer_cache_entry.h +++ b/cc/paint/image_transfer_cache_entry.h
@@ -13,7 +13,6 @@ #include "base/atomic_sequence_num.h" #include "base/containers/span.h" #include "base/memory/raw_ptr.h" -#include "cc/paint/target_color_params.h" #include "cc/paint/transfer_cache_entry.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/skia/include/core/SkImageInfo.h" @@ -21,6 +20,8 @@ #include "third_party/skia/include/core/SkYUVAInfo.h" #include "third_party/skia/include/gpu/GrTypes.h" #include "third_party/skia/include/private/SkGainmapInfo.h" +#include "ui/gfx/color_space.h" +#include "ui/gfx/hdr_metadata.h" class GrDirectContext; class SkColorSpace; @@ -81,12 +82,8 @@ ClientImageTransferCacheEntry( const Image& image, bool needs_mips, - absl::optional<TargetColorParams> target_color_params); - ClientImageTransferCacheEntry( - const Image& image, - bool needs_mips, - const absl::optional<gfx::HDRMetadata>& hdr_metadata, - absl::optional<TargetColorParams> target_color_params); + const absl::optional<gfx::HDRMetadata>& hdr_metadata = absl::nullopt, + sk_sp<SkColorSpace> target_color_space = nullptr); ClientImageTransferCacheEntry(const Image& image, const Image& gainmap_image, const SkGainmapInfo& gainmap_info, @@ -109,7 +106,7 @@ void ComputeSize(); const bool needs_mips_ = false; - absl::optional<TargetColorParams> target_color_params_; + sk_sp<SkColorSpace> target_color_space_; const uint32_t id_; uint32_t size_ = 0; static base::AtomicSequenceNumber s_next_id_; @@ -201,7 +198,6 @@ // HDR tonemapping may be done with a tone curve (for global tone mapping). bool use_tone_curve_ = false; absl::optional<gfx::HDRMetadata> tone_curve_hdr_metadata_; - float tone_curve_sdr_max_luminance_nits_; // The value of `size_` is computed during deserialization and never updated // (even if the size of the image changes due to mipmaps being requested).
diff --git a/cc/paint/target_color_params.h b/cc/paint/target_color_params.h index 2bdfb8d..8931fa3f 100644 --- a/cc/paint/target_color_params.h +++ b/cc/paint/target_color_params.h
@@ -35,11 +35,6 @@ // luminance (a non-HDR-capable display will have a value of 1). float hdr_max_luminance_relative = 1.f; - static bool EqualIgnoringHdrHeadroom(const TargetColorParams& a, - const TargetColorParams& b) { - return a.color_space == b.color_space && - a.sdr_max_luminance_nits == b.sdr_max_luminance_nits; - } bool operator==(const TargetColorParams& other) const { return color_space == other.color_space && sdr_max_luminance_nits == other.sdr_max_luminance_nits &&
diff --git a/cc/test/test_options_provider.cc b/cc/test/test_options_provider.cc index 5eec903..2c364b31 100644 --- a/cc/test/test_options_provider.cc +++ b/cc/test/test_options_provider.cc
@@ -111,10 +111,9 @@ SkBitmap::kZeroPixels_AllocFlag); // Create a transfer cache entry for this image. - TargetColorParams target_color_params; ClientImageTransferCacheEntry cache_entry( ClientImageTransferCacheEntry::Image(&bitmap.pixmap()), - false /* needs_mips */, target_color_params); + false /* needs_mips */, absl::nullopt); const uint32_t data_size = cache_entry.SerializedSize(); auto data = PaintOpWriter::AllocateAlignedBuffer<uint8_t>(data_size); if (!cache_entry.Serialize(base::span<uint8_t>(data.get(), data_size))) {
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc index 0223e0f..46e4aa66 100644 --- a/cc/tiles/gpu_image_decode_cache.cc +++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -555,24 +555,20 @@ : frame_key(draw_image.frame_key()), upload_scale_mip_level(mip_level), filter_quality(CalculateDesiredFilterQuality(draw_image)), - target_color_params(draw_image.target_color_params()) { - // TODO(https://crbug.com/1483235): Remove HDR headroom from the cache key, - // since it is not used. - target_color_params.hdr_max_luminance_relative = 1.f; -} + target_color_space(draw_image.target_color_space()) {} bool GpuImageDecodeCache::InUseCacheKey::operator==( const InUseCacheKey& other) const { return frame_key == other.frame_key && upload_scale_mip_level == other.upload_scale_mip_level && filter_quality == other.filter_quality && - target_color_params == other.target_color_params; + target_color_space == other.target_color_space; } size_t GpuImageDecodeCache::InUseCacheKeyHash::operator()( const InUseCacheKey& cache_key) const { return base::HashInts( - cache_key.target_color_params.GetHash(), + cache_key.target_color_space.GetHash(), base::HashInts( cache_key.frame_key.hash(), base::HashInts(cache_key.upload_scale_mip_level, @@ -1093,7 +1089,7 @@ GpuImageDecodeCache::ImageData::ImageData( PaintImage::Id paint_image_id, DecodedDataMode mode, - const TargetColorParams& target_color_params, + const gfx::ColorSpace& target_color_space, PaintFlags::FilterQuality quality, int upload_scale_mip_level, bool needs_mips, @@ -1103,7 +1099,7 @@ ImageInfo image_info[kAuxImageCount]) : paint_image_id(paint_image_id), mode(mode), - target_color_params(target_color_params), + target_color_space(target_color_space), quality(quality), upload_scale_mip_level(upload_scale_mip_level), needs_mips(needs_mips), @@ -2574,51 +2570,44 @@ DCHECK_GT(image_data->decode.ref_count, 0u); DCHECK_GT(image_data->upload.ref_count, 0u); + // Let `target_color_space` be the color space that the image is converted to + // for storage in the cache. If it is nullptr then no conversion is performed, + // and the decoded color space is used. sk_sp<SkColorSpace> target_color_space = SupportsColorSpaceConversion() && draw_image.target_color_space().IsValid() ? draw_image.target_color_space().ToSkColorSpace() : nullptr; - // The value of |decoded_target_colorspace| takes into account the fact - // that we might need to ignore an embedded image color space if |color_type_| - // does not support color space conversions or that color conversion might - // have happened at decode time. - sk_sp<SkColorSpace> decoded_target_colorspace = + // Let `decoded_color_space` be the color space that the decoded image is in. + // This takes into account the fact that we might need to ignore an embedded + // image color space if `color_type_` does not support color space + // conversions or that some color conversion might have happened at decode + // time. + sk_sp<SkColorSpace> decoded_color_space = ColorSpaceForImageDecode(draw_image, image_data->mode); - const bool needs_tone_mapping = NeedsToneMapping( - decoded_target_colorspace, draw_image.paint_image().HasGainmap()); - if (target_color_space && decoded_target_colorspace) { - if (!needs_tone_mapping && - SkColorSpace::Equals(target_color_space.get(), - decoded_target_colorspace.get())) { - target_color_space = nullptr; - } + if (target_color_space && decoded_color_space && + SkColorSpace::Equals(target_color_space.get(), + decoded_color_space.get())) { + target_color_space = nullptr; } - - absl::optional<TargetColorParams> target_color_params; - if (target_color_space) { - target_color_params = draw_image.target_color_params(); - target_color_params->color_space = gfx::ColorSpace(*target_color_space); - } - const absl::optional<gfx::HDRMetadata> hdr_metadata = - draw_image.paint_image().GetHDRMetadata(); - if (image_data->mode == DecodedDataMode::kTransferCache) { DCHECK(use_transfer_cache_); if (image_data->decode.do_hardware_accelerated_decode()) { UploadImageIfNecessary_TransferCache_HardwareDecode( draw_image, image_data, target_color_space); } else { - // Do not color convert YUVA images unless the the color conversion also - // performs tone mapping. - if (image_data->info.yuva.has_value()) { - if (!needs_tone_mapping) { - target_color_params = absl::nullopt; - } + // Do not color convert images that are YUV or need tone mapping. + if (image_data->info.yuva.has_value() || + NeedsToneMapping(decoded_color_space, + draw_image.paint_image().HasGainmap())) { + target_color_space = nullptr; } + const absl::optional<gfx::HDRMetadata> hdr_metadata = + draw_image.paint_image().GetHDRMetadata(); + UploadImageIfNecessary_TransferCache_SoftwareDecode( - draw_image, image_data, decoded_target_colorspace, hdr_metadata, - target_color_params); + draw_image, image_data, decoded_color_space, hdr_metadata, + target_color_space); } } else { // Grab a reference to our decoded image. For the kCpu path, we will use @@ -2629,9 +2618,9 @@ image_data->needs_mips ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo; if (image_data->info.yuva.has_value()) { - UploadImageIfNecessary_GpuCpu_YUVA( - draw_image, image_data, uploaded_image, image_needs_mips, - decoded_target_colorspace, target_color_space); + UploadImageIfNecessary_GpuCpu_YUVA(draw_image, image_data, uploaded_image, + image_needs_mips, decoded_color_space, + target_color_space); } else { UploadImageIfNecessary_GpuCpu_RGBA(draw_image, image_data, uploaded_image, image_needs_mips, target_color_space); @@ -2686,9 +2675,9 @@ void GpuImageDecodeCache::UploadImageIfNecessary_TransferCache_SoftwareDecode( const DrawImage& draw_image, ImageData* image_data, - sk_sp<SkColorSpace> decoded_target_colorspace, + sk_sp<SkColorSpace> decoded_color_space, const absl::optional<gfx::HDRMetadata>& hdr_metadata, - absl::optional<TargetColorParams> target_color_params) { + sk_sp<SkColorSpace> target_color_space) { DCHECK_EQ(image_data->mode, DecodedDataMode::kTransferCache); DCHECK(use_transfer_cache_); DCHECK(!image_data->decode.do_hardware_accelerated_decode()); @@ -2706,7 +2695,7 @@ DCHECK(!info.rgba.has_value()); image[aux_image_index] = ClientImageTransferCacheEntry::Image( image_data->decode.pixmaps(aux_image), info.yuva->yuvaInfo(), - decoded_target_colorspace.get()); + decoded_color_space.get()); } if (info.rgba.has_value()) { DCHECK(!info.yuva.has_value()); @@ -2723,7 +2712,7 @@ image_data->needs_mips) : ClientImageTransferCacheEntry(image[kAuxImageIndexDefault], image_data->needs_mips, hdr_metadata, - target_color_params); + target_color_space); if (!image_entry.IsValid()) return; InsertTransferCacheEntry(image_entry, image_data); @@ -2734,7 +2723,7 @@ ImageData* image_data, sk_sp<SkImage> uploaded_image, skgpu::Mipmapped image_needs_mips, - sk_sp<SkColorSpace> decoded_target_colorspace, + sk_sp<SkColorSpace> decoded_color_space, sk_sp<SkColorSpace> color_space) { DCHECK(!use_transfer_cache_); DCHECK(image_data->info.yuva.has_value()); @@ -2774,7 +2763,7 @@ image_data->info.yuva->yuvaInfo().planeConfig(), image_data->info.yuva->yuvaInfo().subsampling(), image_data->info.yuva->yuvaInfo().yuvColorSpace(), color_space, - decoded_target_colorspace); + decoded_color_space); } // At-raster may have decoded this while we were unlocked. If so, ignore our @@ -3008,7 +2997,7 @@ return base::WrapRefCounted(new ImageData( draw_image.paint_image().stable_id(), mode, - draw_image.target_color_params(), + draw_image.target_color_space(), CalculateDesiredFilterQuality(draw_image), upload_scale_mip_level, needs_mips, is_bitmap_backed, can_do_hardware_accelerated_decode, do_hardware_accelerated_decode, image_info)); @@ -3341,29 +3330,23 @@ // the provided |draw_image|. bool GpuImageDecodeCache::IsCompatible(const ImageData* image_data, const DrawImage& draw_image) const { - bool is_scaled = image_data->upload_scale_mip_level != 0; - bool scale_is_compatible = + const bool is_scaled = image_data->upload_scale_mip_level != 0; + const bool scale_is_compatible = CalculateUploadScaleMipLevel(draw_image, AuxImage::kDefault) >= image_data->upload_scale_mip_level; - bool quality_is_compatible = + const bool quality_is_compatible = CalculateDesiredFilterQuality(draw_image) <= image_data->quality; - sk_sp<SkColorSpace> decoded_target_colorspace = - ColorSpaceForImageDecode(draw_image, image_data->mode); - const bool needs_tone_mapping = NeedsToneMapping( - decoded_target_colorspace, draw_image.paint_image().HasGainmap()); - - bool color_is_compatible = false; - if (!needs_tone_mapping) { - color_is_compatible = image_data->target_color_params.color_space == - draw_image.target_color_space(); - } else { - color_is_compatible = TargetColorParams::EqualIgnoringHdrHeadroom( - image_data->target_color_params, draw_image.target_color_params()); + if (is_scaled && (!scale_is_compatible || !quality_is_compatible)) { + return false; } + + // This is overly pessimistic. If the image is tone mapped or decoded to + // YUV, then the target color space is ignored anyway. + const bool color_is_compatible = + image_data->target_color_space == draw_image.target_color_space(); if (!color_is_compatible) return false; - if (is_scaled && (!scale_is_compatible || !quality_is_compatible)) - return false; + return true; }
diff --git a/cc/tiles/gpu_image_decode_cache.h b/cc/tiles/gpu_image_decode_cache.h index b4c55d8..fab354b 100644 --- a/cc/tiles/gpu_image_decode_cache.h +++ b/cc/tiles/gpu_image_decode_cache.h
@@ -597,7 +597,7 @@ struct ImageData : public base::RefCountedThreadSafe<ImageData> { ImageData(PaintImage::Id paint_image_id, DecodedDataMode mode, - const TargetColorParams& target_color_params, + const gfx::ColorSpace& target_color_space, PaintFlags::FilterQuality quality, int upload_scale_mip_level, bool needs_mips, @@ -628,7 +628,7 @@ const PaintImage::Id paint_image_id; const DecodedDataMode mode; - TargetColorParams target_color_params; + const gfx::ColorSpace target_color_space; PaintFlags::FilterQuality quality; int upload_scale_mip_level; bool needs_mips = false; @@ -682,7 +682,7 @@ PaintImage::FrameKey frame_key; int upload_scale_mip_level; PaintFlags::FilterQuality filter_quality; - TargetColorParams target_color_params; + gfx::ColorSpace target_color_space; }; struct InUseCacheKeyHash { size_t operator()(const InUseCacheKey&) const; @@ -826,8 +826,7 @@ ImageData* image_data, sk_sp<SkColorSpace> decoded_target_colorspace, const absl::optional<gfx::HDRMetadata>& hdr_metadata, - absl::optional<TargetColorParams> target_color_params) - EXCLUSIVE_LOCKS_REQUIRED(lock_); + sk_sp<SkColorSpace> target_color_space) EXCLUSIVE_LOCKS_REQUIRED(lock_); void UploadImageIfNecessary_GpuCpu_YUVA( const DrawImage& draw_image, ImageData* image_data,
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index ba9a0a7..fae22a8 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -912,6 +912,7 @@ void SetUp() override { LayerTreeSettings settings = DefaultSettings(); settings.enable_fluent_overlay_scrollbar = true; + settings.enable_fluent_scrollbar = true; settings.scrollbar_animator = LayerTreeSettings::AURA_OVERLAY; settings.scrollbar_fade_delay = base::Milliseconds(500); settings.scrollbar_fade_duration = base::Milliseconds(300);
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 63eae13..1f566a2 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -1799,6 +1799,7 @@ "//components/policy/android:policy_java_test_support", "//components/power_bookmarks/core:proto_java", "//components/prefs/android:java", + "//components/privacy_sandbox/android:javatests", "//components/profile_metrics:browser_profile_type_enum_java", "//components/query_tiles:java", "//components/query_tiles:test_support_java",
diff --git a/chrome/android/baseline_profiles/profile.txt b/chrome/android/baseline_profiles/profile.txt index e5535253..22e02d73 100644 --- a/chrome/android/baseline_profiles/profile.txt +++ b/chrome/android/baseline_profiles/profile.txt
@@ -6171,8 +6171,8 @@ Lorg/chromium/chrome/browser/tasks/tab_management/TabGridPanelProperties; Lorg/chromium/chrome/browser/tasks/tab_management/TabGridPanelViewBinder$ViewHolder; HSPLorg/chromium/chrome/browser/tasks/tab_management/TabGridPanelViewBinder$ViewHolder;-><init>(Lorg/chromium/chrome/browser/tasks/tab_management/TabGroupUiToolbarView;Landroidx/recyclerview/widget/RecyclerView;Lorg/chromium/chrome/browser/tasks/tab_management/TabGridDialogView;)V -Lorg/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailView; -HSPLorg/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V +Lorg/chromium/chrome/browser/tasks/tab_management/TabThumbnailView; +HSPLorg/chromium/chrome/browser/tasks/tab_management/TabThumbnailView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V Lorg/chromium/chrome/browser/tasks/tab_management/TabGroupUi; Lorg/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator; HSPLorg/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator;-><init>(Landroidx/appcompat/app/AppCompatActivity;Landroid/view/ViewGroup;Lorg/chromium/chrome/browser/tabmodel/IncognitoStateProvider;Lorg/chromium/components/browser_ui/widget/scrim/ScrimCoordinator;Lorg/chromium/base/supplier/ObservableSupplier;Lorg/chromium/components/browser_ui/bottomsheet/BottomSheetController;Lorg/chromium/chrome/browser/init/ActivityLifecycleDispatcherImpl;Lorg/chromium/base/supplier/Supplier;Lorg/chromium/chrome/browser/tabmodel/TabModelSelector;Lorg/chromium/chrome/browser/compositor/layouts/content/TabContentManager;Lorg/chromium/chrome/browser/compositor/CompositorViewHolder;Lorg/chromium/chrome/browser/toolbar/ToolbarManager$$ExternalSyntheticLambda14;Lorg/chromium/chrome/browser/tabmodel/TabCreatorManager;Lorg/chromium/base/supplier/Supplier;Lorg/chromium/base/supplier/OneshotSupplier;)V
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index c2cb0fe..2c4f2ce 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -765,6 +765,7 @@ "java/src/org/chromium/chrome/browser/messages/MessageContainerCoordinator.java", "java/src/org/chromium/chrome/browser/messages/MessageContainerObserver.java", "java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java", + "java/src/org/chromium/chrome/browser/metrics/ExperimentalStartupMetricsTracker.java", "java/src/org/chromium/chrome/browser/metrics/LaunchMetrics.java", "java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java", "java/src/org/chromium/chrome/browser/metrics/VariationsSession.java",
diff --git a/chrome/android/features/start_surface/java/res/layout/single_tab_module_layout.xml b/chrome/android/features/start_surface/java/res/layout/single_tab_module_layout.xml index b3901d6..92c20867 100644 --- a/chrome/android/features/start_surface/java/res/layout/single_tab_module_layout.xml +++ b/chrome/android/features/start_surface/java/res/layout/single_tab_module_layout.xml
@@ -44,7 +44,7 @@ android:layout_height="wrap_content" android:background="@drawable/single_tab_thumbnail_background"> - <org.chromium.chrome.browser.tasks.tab_management.TabGridThumbnailView + <org.chromium.chrome.browser.tasks.tab_management.TabThumbnailView android:id="@+id/tab_thumbnail" android:layout_width="@dimen/single_tab_module_tab_thumbnail_size" android:layout_height="@dimen/single_tab_module_tab_thumbnail_size"
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabView.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabView.java index 265b8ac..4cbe3153 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabView.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabView.java
@@ -17,7 +17,7 @@ import androidx.annotation.Nullable; -import org.chromium.chrome.browser.tasks.tab_management.TabGridThumbnailView; +import org.chromium.chrome.browser.tasks.tab_management.TabThumbnailView; import org.chromium.chrome.start_surface.R; /** View of the tab on the single tab tab switcher. */ @@ -25,8 +25,7 @@ private final Context mContext; private ImageView mFavicon; private TextView mTitle; - @Nullable - private TabGridThumbnailView mTabThumbnail; + @Nullable private TabThumbnailView mTabThumbnail; @Nullable private TextView mUrl;
diff --git a/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml b/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml index eaeadb8..57090be 100644 --- a/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml +++ b/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml
@@ -47,7 +47,7 @@ android:ellipsize="none" android:singleLine="true" android:textAppearance="@style/TextAppearance.TextMediumThick.Primary"/> - <org.chromium.chrome.browser.tasks.tab_management.TabGridThumbnailView + <org.chromium.chrome.browser.tasks.tab_management.TabThumbnailView android:id="@+id/tab_thumbnail" android:layout_width="match_parent" android:layout_height="match_parent"
diff --git a/chrome/android/features/tab_ui/java/res/layout/tab_hover_card_holder.xml b/chrome/android/features/tab_ui/java/res/layout/tab_hover_card_holder.xml index 3acb0b5..317f0b8 100644 --- a/chrome/android/features/tab_ui/java/res/layout/tab_hover_card_holder.xml +++ b/chrome/android/features/tab_ui/java/res/layout/tab_hover_card_holder.xml
@@ -16,8 +16,7 @@ android:orientation="vertical" android:background="@drawable/tab_hover_card_background"> - <!-- TODO (crbug.com/1451925): Rename to TabThumbnailView for generic use. --> - <org.chromium.chrome.browser.tasks.tab_management.TabGridThumbnailView + <org.chromium.chrome.browser.tasks.tab_management.TabThumbnailView android:id="@+id/thumbnail" android:layout_width="match_parent" android:layout_height="@dimen/tab_hover_card_thumbnail_height"
diff --git a/chrome/android/features/tab_ui/java/res/values/attrs.xml b/chrome/android/features/tab_ui/java/res/values/attrs.xml index c015d084..dd220a5 100644 --- a/chrome/android/features/tab_ui/java/res/values/attrs.xml +++ b/chrome/android/features/tab_ui/java/res/values/attrs.xml
@@ -11,7 +11,7 @@ <attr name="elevationTileBase" format="dimension" /> </declare-styleable> - <declare-styleable name="TabGridThumbnailView"> + <declare-styleable name="TabThumbnailView"> <attr name="cornerRadiusTopStart" format="dimension" /> <attr name="cornerRadiusTopEnd" format="dimension" /> <attr name="cornerRadiusBottomStart" format="dimension" />
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java index 1a744ec2c..1ee0853a 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java
@@ -707,10 +707,10 @@ ((TextView) (mAnimationCardView.findViewById(R.id.tab_title))) .setTextColor(((TextView) (view.findViewById(R.id.tab_title))).getTextColors()); - TabGridThumbnailView originalThumbnailView = - (TabGridThumbnailView) view.findViewById(R.id.tab_thumbnail); - TabGridThumbnailView animationThumbnailView = - (TabGridThumbnailView) mAnimationCardView.findViewById(R.id.tab_thumbnail); + TabThumbnailView originalThumbnailView = + (TabThumbnailView) view.findViewById(R.id.tab_thumbnail); + TabThumbnailView animationThumbnailView = + (TabThumbnailView) mAnimationCardView.findViewById(R.id.tab_thumbnail); if (originalThumbnailView.isPlaceholder()) { animationThumbnailView.setImageDrawable(null); } else {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java index 4f371ee..12eb387 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
@@ -258,8 +258,7 @@ } private static void updateThumbnail(ViewLookupCachingFrameLayout view, PropertyModel model) { - TabGridThumbnailView thumbnail = - (TabGridThumbnailView) view.fastFindViewById(R.id.tab_thumbnail); + TabThumbnailView thumbnail = (TabThumbnailView) view.fastFindViewById(R.id.tab_thumbnail); // To GC on hide set a background color and remove the thumbnail. final boolean isSelected = model.get(TabProperties.IS_SELECTED); @@ -344,8 +343,8 @@ ViewLookupCachingFrameLayout rootView, boolean isIncognito, boolean isSelected) { View cardView = rootView.fastFindViewById(R.id.card_view); TextView titleView = (TextView) rootView.fastFindViewById(R.id.tab_title); - TabGridThumbnailView thumbnail = - (TabGridThumbnailView) rootView.fastFindViewById(R.id.tab_thumbnail); + TabThumbnailView thumbnail = + (TabThumbnailView) rootView.fastFindViewById(R.id.tab_thumbnail); ChromeImageView backgroundView = (ChromeImageView) rootView.fastFindViewById(R.id.background_view);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabThumbnailView.java similarity index 93% rename from chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailView.java rename to chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabThumbnailView.java index da4521d6..7e138fc 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailView.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabThumbnailView.java
@@ -37,7 +37,7 @@ * * ShapeableImageView - however, this is inconsistent for hardware/software based draws. * * RoundedCornerImageView - however, this doesn't handle non-Bitmap Drawables well. */ -public class TabGridThumbnailView extends ImageView { +public class TabThumbnailView extends ImageView { private static final boolean SUPPORTS_ANTI_ALIAS_CLIP = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P; @@ -48,7 +48,7 @@ private static Integer sVerticalOffsetPx; /** - * To prevent {@link TabGridThumbnailView#updateImage()} from running during inflation. + * To prevent {@link TabThumbnailView#updateImage()} from running during inflation. */ private boolean mInitialized; @@ -77,11 +77,11 @@ // Realistically this will be set once and never again. private float[] mRadii; - public TabGridThumbnailView(Context context, AttributeSet attrs) { + public TabThumbnailView(Context context, AttributeSet attrs) { this(context, attrs, 0); } - public TabGridThumbnailView(Context context, AttributeSet attrs, int defStyle) { + public TabThumbnailView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); if (sVerticalOffsetPx == null) { @@ -98,15 +98,15 @@ mBackgroundDrawable = new GradientDrawable(); TypedArray a = - getContext().obtainStyledAttributes(attrs, R.styleable.TabGridThumbnailView, 0, 0); + getContext().obtainStyledAttributes(attrs, R.styleable.TabThumbnailView, 0, 0); int radiusTopStart = - a.getDimensionPixelSize(R.styleable.TabGridThumbnailView_cornerRadiusTopStart, 0); + a.getDimensionPixelSize(R.styleable.TabThumbnailView_cornerRadiusTopStart, 0); int radiusTopEnd = - a.getDimensionPixelSize(R.styleable.TabGridThumbnailView_cornerRadiusTopEnd, 0); + a.getDimensionPixelSize(R.styleable.TabThumbnailView_cornerRadiusTopEnd, 0); int radiusBottomStart = a.getDimensionPixelSize( - R.styleable.TabGridThumbnailView_cornerRadiusBottomStart, 0); + R.styleable.TabThumbnailView_cornerRadiusBottomStart, 0); int radiusBottomEnd = - a.getDimensionPixelSize(R.styleable.TabGridThumbnailView_cornerRadiusBottomEnd, 0); + a.getDimensionPixelSize(R.styleable.TabThumbnailView_cornerRadiusBottomEnd, 0); a.recycle(); setRoundedCorners(radiusTopStart, radiusTopEnd, radiusBottomStart, radiusBottomEnd);
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java index b4c3540..b647fef 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java
@@ -438,7 +438,7 @@ public void testThumbnail() { mGridModel.set(TabProperties.GRID_CARD_SIZE, new Size(100, 500)); mGridModel.set(TabProperties.THUMBNAIL_FETCHER, mMockThumbnailProvider); - TabGridThumbnailView thumbnail = mTabGridView.findViewById(R.id.tab_thumbnail); + TabThumbnailView thumbnail = mTabGridView.findViewById(R.id.tab_thumbnail); assertNull("Thumbnail should be set to no drawable.", thumbnail.getDrawable()); assertNotNull("Thumbnail should have a background drawable.", thumbnail.getBackground()); assertTrue("Thumbnail should be set to a place holder.", thumbnail.isPlaceholder()); @@ -460,7 +460,7 @@ @UiThreadTest public void testThumbnailGridCardSize() { mGridModel.set(TabProperties.THUMBNAIL_FETCHER, mMockThumbnailProvider); - TabGridThumbnailView thumbnail = mTabGridView.findViewById(R.id.tab_thumbnail); + TabThumbnailView thumbnail = mTabGridView.findViewById(R.id.tab_thumbnail); assertNull("Thumbnail should be set to no drawable.", thumbnail.getDrawable()); assertNotNull("Thumbnail should have a background drawable.", thumbnail.getBackground()); assertTrue("Thumbnail should be set to a place holder.", thumbnail.isPlaceholder());
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java index 5609e4e..5639158b 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java
@@ -126,7 +126,7 @@ ChromeRenderTestRule.Builder.withPublicCorpus() .setBugComponent(ChromeRenderTestRule.Component.UI_BROWSER_MOBILE_TAB_SWITCHER) .setRevision(8) - .setDescription("TabGridThumbnailView update.") + .setDescription("TabThumbnailView update.") .build(); @Mock
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherAndStartSurfaceLayoutTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherAndStartSurfaceLayoutTest.java index 7007467c..e09e5157 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherAndStartSurfaceLayoutTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherAndStartSurfaceLayoutTest.java
@@ -1503,8 +1503,8 @@ hasAtLeastOneValidViewHolder = true; ViewLookupCachingFrameLayout tabView = (ViewLookupCachingFrameLayout) viewHolder.itemView; - TabGridThumbnailView thumbnail = - (TabGridThumbnailView) tabView.fastFindViewById(R.id.tab_thumbnail); + TabThumbnailView thumbnail = + (TabThumbnailView) tabView.fastFindViewById(R.id.tab_thumbnail); double thumbnailViewRatio = thumbnail.getWidth() * 1.0 / thumbnail.getHeight(); int pixelDelta =
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailViewRenderTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabThumbnailViewRenderTest.java similarity index 86% rename from chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailViewRenderTest.java rename to chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabThumbnailViewRenderTest.java index 73985073..e8db4ed 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailViewRenderTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabThumbnailViewRenderTest.java
@@ -51,12 +51,12 @@ import java.util.List; /** - * Render tests for the UI elements of the {@link TabGridThumbnailView}. + * Render tests for the UI elements of the {@link TabThumbnailView}. */ @RunWith(ParameterizedRunner.class) @ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class) @Batch(Batch.PER_CLASS) -public class TabGridThumbnailViewRenderTest { +public class TabThumbnailViewRenderTest { @ParameterAnnotations.ClassParameter public static List<ParameterSet> sClassParams = new NightModeTestUtils.NightModeParams().getParameters(); @@ -80,10 +80,10 @@ private FrameLayout mContentView; private ViewGroup mTabCard; - private TabGridThumbnailView mTabGridThumbnailView; + private TabThumbnailView mTabThumbnailView; private Bitmap mBitmap; - public TabGridThumbnailViewRenderTest(boolean nightModeEnabled) { + public TabThumbnailViewRenderTest(boolean nightModeEnabled) { NightModeTestUtils.setUpNightModeForBlankUiTestActivity(nightModeEnabled); mRenderTestRule.setNightModeEnabled(nightModeEnabled); } @@ -102,7 +102,7 @@ mTabCard.setVisibility(View.VISIBLE); mContentView.addView(mTabCard); - mTabGridThumbnailView = mContentView.findViewById(R.id.tab_thumbnail); + mTabThumbnailView = mContentView.findViewById(R.id.tab_thumbnail); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); @@ -128,8 +128,8 @@ } private Bitmap createBitmapFourColor() { - final int width = mTabGridThumbnailView.getMeasuredWidth(); - final int height = mTabGridThumbnailView.getMeasuredHeight(); + final int width = mTabThumbnailView.getMeasuredWidth(); + final int height = mTabThumbnailView.getMeasuredHeight(); Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); @@ -165,37 +165,37 @@ public void testPlaceholderDrawable() throws IOException, InterruptedException { TestThreadUtils.runOnUiThreadBlocking(() -> { updateColor(/*isIncognito=*/true, /*isSelected=*/false); - mTabGridThumbnailView.setImageDrawable(null); + mTabThumbnailView.setImageDrawable(null); }); mRenderTestRule.render(mTabCard, "placeholder_incognito_without_thumbnail_deselected"); TestThreadUtils.runOnUiThreadBlocking(() -> { updateColor(/*isIncognito=*/false, /*isSelected=*/false); - mTabGridThumbnailView.setImageDrawable(null); + mTabThumbnailView.setImageDrawable(null); }); mRenderTestRule.render(mTabCard, "placeholder_without_thumbnail_deselected"); TestThreadUtils.runOnUiThreadBlocking(() -> { - mTabGridThumbnailView.setImageBitmap(mBitmap); - mTabGridThumbnailView.setImageMatrix(new Matrix()); + mTabThumbnailView.setImageBitmap(mBitmap); + mTabThumbnailView.setImageMatrix(new Matrix()); }); mRenderTestRule.render(mTabCard, "placeholder_with_thumbnail_deselected"); TestThreadUtils.runOnUiThreadBlocking(() -> { updateColor(/*isIncognito=*/false, /*isSelected=*/true); - mTabGridThumbnailView.setImageDrawable(null); + mTabThumbnailView.setImageDrawable(null); }); mRenderTestRule.render(mTabCard, "placeholder_without_thumbnail_selected"); TestThreadUtils.runOnUiThreadBlocking(() -> { - mTabGridThumbnailView.setImageBitmap(mBitmap); - mTabGridThumbnailView.setImageMatrix(new Matrix()); + mTabThumbnailView.setImageBitmap(mBitmap); + mTabThumbnailView.setImageMatrix(new Matrix()); }); mRenderTestRule.render(mTabCard, "placeholder_with_thumbnail_selected"); TestThreadUtils.runOnUiThreadBlocking(() -> { updateColor(/*isIncognito=*/true, /*isSelected=*/true); - mTabGridThumbnailView.setImageDrawable(null); + mTabThumbnailView.setImageDrawable(null); }); mRenderTestRule.render(mTabCard, "placeholder_incognito_without_thumbnail_selected"); } @@ -209,37 +209,37 @@ testNoPlaceholderDrawable() throws IOException, InterruptedException { TestThreadUtils.runOnUiThreadBlocking(() -> { updateColor(/*isIncognito=*/true, /*isSelected=*/false); - mTabGridThumbnailView.setImageDrawable(null); + mTabThumbnailView.setImageDrawable(null); }); mRenderTestRule.render(mTabCard, "no_placeholder_incognito_without_thumbnail_deselected"); TestThreadUtils.runOnUiThreadBlocking(() -> { updateColor(/*isIncognito=*/false, /*isSelected=*/false); - mTabGridThumbnailView.setImageDrawable(null); + mTabThumbnailView.setImageDrawable(null); }); mRenderTestRule.render(mTabCard, "no_placeholder_without_thumbnail_deselected"); TestThreadUtils.runOnUiThreadBlocking(() -> { - mTabGridThumbnailView.setImageBitmap(mBitmap); - mTabGridThumbnailView.setImageMatrix(new Matrix()); + mTabThumbnailView.setImageBitmap(mBitmap); + mTabThumbnailView.setImageMatrix(new Matrix()); }); mRenderTestRule.render(mTabCard, "no_placeholder_with_thumbnail_deselected"); TestThreadUtils.runOnUiThreadBlocking(() -> { updateColor(/*isIncognito=*/false, /*isSelected=*/true); - mTabGridThumbnailView.setImageDrawable(null); + mTabThumbnailView.setImageDrawable(null); }); mRenderTestRule.render(mTabCard, "no_placeholder_without_thumbnail_selected"); TestThreadUtils.runOnUiThreadBlocking(() -> { - mTabGridThumbnailView.setImageBitmap(mBitmap); - mTabGridThumbnailView.setImageMatrix(new Matrix()); + mTabThumbnailView.setImageBitmap(mBitmap); + mTabThumbnailView.setImageMatrix(new Matrix()); }); mRenderTestRule.render(mTabCard, "no_placeholder_with_thumbnail_selected"); TestThreadUtils.runOnUiThreadBlocking(() -> { updateColor(/*isIncognito=*/true, /*isSelected=*/true); - mTabGridThumbnailView.setImageDrawable(null); + mTabThumbnailView.setImageDrawable(null); }); mRenderTestRule.render(mTabCard, "no_placeholder_incognito_without_thumbnail_selected"); } @@ -251,6 +251,6 @@ cardView.getContext(), isIncognito, isSelected); ViewCompat.setBackgroundTintList(cardView, ColorStateList.valueOf(backgroundColor)); - mTabGridThumbnailView.updateThumbnailPlaceholder(isIncognito, isSelected); + mTabThumbnailView.updateThumbnailPlaceholder(isIncognito, isSelected); } }
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java index aa391e3..24a779600 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java
@@ -609,29 +609,33 @@ public static void waitForThumbnailsToFetch(RecyclerView recyclerView) { assertTrue(recyclerView instanceof TabListRecyclerView); - CriteriaHelper.pollUiThread(() -> { - boolean allFetched = true; - int i = 0; - LinearLayoutManager layoutManager = - (LinearLayoutManager) recyclerView.getLayoutManager(); - for (i = layoutManager.findFirstVisibleItemPosition(); - i <= layoutManager.findLastVisibleItemPosition(); i++) { - View v = layoutManager.findViewByPosition(i); - TabGridThumbnailView thumbnail = v.findViewById(R.id.tab_thumbnail); + CriteriaHelper.pollUiThread( + () -> { + boolean allFetched = true; + int i = 0; + LinearLayoutManager layoutManager = + (LinearLayoutManager) recyclerView.getLayoutManager(); + for (i = layoutManager.findFirstVisibleItemPosition(); + i <= layoutManager.findLastVisibleItemPosition(); + i++) { + View v = layoutManager.findViewByPosition(i); + TabThumbnailView thumbnail = v.findViewById(R.id.tab_thumbnail); - // Some items may not be cards or may not have thumbnails. - if (thumbnail == null) continue; + // Some items may not be cards or may not have thumbnails. + if (thumbnail == null) continue; - if (thumbnail.isPlaceholder() - || !(thumbnail.getDrawable() instanceof BitmapDrawable) - || ((BitmapDrawable) thumbnail.getDrawable()).getBitmap() == null) { - allFetched = false; - break; - } - } - Criteria.checkThat("The thumbnail for card at position " + i + " is missing.", - allFetched, is(true)); - }); + if (thumbnail.isPlaceholder() + || !(thumbnail.getDrawable() instanceof BitmapDrawable) + || ((BitmapDrawable) thumbnail.getDrawable()).getBitmap() == null) { + allFetched = false; + break; + } + } + Criteria.checkThat( + "The thumbnail for card at position " + i + " is missing.", + allFetched, + is(true)); + }); } public static void checkThumbnailsExist(Tab tab) {
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinderUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinderUnitTest.java index 792c17d2..cd29602 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinderUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinderUnitTest.java
@@ -57,8 +57,7 @@ private ViewLookupCachingFrameLayout mViewGroup; @Mock private TabListMediator.ThumbnailFetcher mFetcher; - @Mock - private TabGridThumbnailView mThumbnailView; + @Mock private TabThumbnailView mThumbnailView; @Mock private ImageView mFaviconView; @Captor
diff --git a/chrome/android/features/tab_ui/tab_management_java_sources.gni b/chrome/android/features/tab_ui/tab_management_java_sources.gni index 8f1fcb2..497a5dc 100644 --- a/chrome/android/features/tab_ui/tab_management_java_sources.gni +++ b/chrome/android/features/tab_ui/tab_management_java_sources.gni
@@ -9,12 +9,12 @@ "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/TabAttributeCache.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/CloseAllTabsDialog.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/RecyclerViewPosition.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailView.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUi.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListFaviconProvider.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcher.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java", + "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabThumbnailView.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeProvider.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/UndoGroupSnackbarController.java", @@ -121,7 +121,6 @@ "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java", "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIncognitoReauthPromoTest.java", "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphTest.java", - "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailViewRenderTest.java", "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiTest.java", "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListContainerViewBinderTest.java", "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMenuTest.java", @@ -133,6 +132,7 @@ "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMultiWindowTest.java", "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherTabletTest.java", "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherThumbnailTest.java", + "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabThumbnailViewRenderTest.java", "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TestRecyclerViewSimpleViewBinder.java", ]
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedV2NewTabPageTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedV2NewTabPageTest.java index fdf24353..a6b9609c 100644 --- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedV2NewTabPageTest.java +++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedV2NewTabPageTest.java
@@ -214,6 +214,8 @@ FeatureList.TestValues testValuesOverride = new FeatureList.TestValues(); testValuesOverride.addFeatureFlagOverride( ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID, mEnableScrollableMVT); + testValuesOverride.addFeatureFlagOverride( + ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID, mEnableScrollableMVT); FeatureList.setTestValues(testValuesOverride); mActivityTestRule.startMainActivityWithURL("about:blank");
diff --git a/chrome/android/java/res/layout/autofill_save_card_bottom_sheet.xml b/chrome/android/java/res/layout/autofill_save_card_bottom_sheet.xml index 7ce3da5..146c6399 100644 --- a/chrome/android/java/res/layout/autofill_save_card_bottom_sheet.xml +++ b/chrome/android/java/res/layout/autofill_save_card_bottom_sheet.xml
@@ -17,7 +17,8 @@ android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="@dimen/autofill_bottom_sheet_drag_handlebar_spacing_top" - android:src="@drawable/drag_handlebar" /> + android:src="@drawable/drag_handlebar" + app:tint="@macro/drag_handlebar_color" /> <ScrollView android:id="@+id/autofill_save_card_scroll_view"
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 5dac2cf0..8fac3b8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -116,6 +116,7 @@ import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.locale.LocaleManager; import org.chromium.chrome.browser.metrics.AndroidSessionDurationsServiceState; +import org.chromium.chrome.browser.metrics.ExperimentalStartupMetricsTracker; import org.chromium.chrome.browser.metrics.LaunchMetrics; import org.chromium.chrome.browser.metrics.MainIntentBehaviorMetrics; import org.chromium.chrome.browser.metrics.SimpleStartupForegroundSessionDetector; @@ -409,6 +410,8 @@ // Delegate to handle drag and drop features for tablets. private DragAndDropDelegate mDragDropDelegate; + private ExperimentalStartupMetricsTracker mExperimentalStartupMetricsTracker; + private final IncognitoTabHost mIncognitoTabHost = new IncognitoTabHost() { @Override public boolean hasIncognitoTabs() { @@ -484,6 +487,8 @@ @Override protected void onPreCreate() { super.onPreCreate(); + mExperimentalStartupMetricsTracker = + new ExperimentalStartupMetricsTracker(getTabModelSelectorSupplier()); mMultiInstanceManager = MultiInstanceManager.create(this, getTabModelOrchestratorSupplier(), getMultiWindowModeStateDispatcher(), getLifecycleDispatcher(), getModalDialogManagerSupplier(), this); @@ -1230,6 +1235,7 @@ // Cancel recording cold startup metrics if an overview is shown as they expect a tab to // be the first thing shown after startup. setTrackColdStartupMetrics(false); + mExperimentalStartupMetricsTracker.destroy(); disablePaintPreviewOnRestore(); showOverview(StartSurfaceState.SHOWING_START); mAppLaunchDrawBlocker.onOverviewPageAvailable( @@ -1243,6 +1249,7 @@ // Cancel recording cold startup metrics if an overview is shown as they expect a tab to // be the first thing shown after startup. setTrackColdStartupMetrics(false); + mExperimentalStartupMetricsTracker.destroy(); disablePaintPreviewOnRestore(); showOverview(StartSurfaceState.SHOWING_START); } @@ -2911,6 +2918,11 @@ mDragDropDelegate.destroy(); } + if (mExperimentalStartupMetricsTracker != null) { + mExperimentalStartupMetricsTracker.destroy(); + mExperimentalStartupMetricsTracker = null; + } + super.onDestroyInternal(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java index f77ed6e..0c229875 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -420,7 +420,6 @@ @Override protected void onPreCreate() { - incrementCounter(ChromePreferenceKeys.UMA_ON_PRECREATE_COUNTER); CachedFlagsSafeMode.getInstance().onStartOrResumeCheckpoint(); if (earlyInitializeStartupMetrics()) { mActivityTabStartupMetricsTracker = @@ -441,6 +440,12 @@ } @Override + protected void onPostCreate() { + incrementCounter(ChromePreferenceKeys.UMA_ON_POSTCREATE_COUNTER); + super.onPostCreate(); + } + + @Override protected ActivityWindowAndroid createWindowAndroid() { return new ChromeWindow(/* activity= */ this, mActivityTabProvider, mCompositorViewHolderSupplier, getModalDialogManagerSupplier(),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java index 6374ec7..fa34f92 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
@@ -1985,11 +1985,21 @@ return TabModel.INVALID_TAB_INDEX; } + int getNumLiveTabs() { + int numLiveTabs = 0; + + for (int i = 0; i < mStripTabs.length; i++) { + if (!mStripTabs[i].isDying()) numLiveTabs++; + } + + return numLiveTabs; + } + private List<Animator> computeAndUpdateTabWidth(boolean animate, boolean deferAnimations) { // Remove any queued resize messages. mStripTabEventHandler.removeMessages(MESSAGE_RESIZE); - int numTabs = Math.max(mStripTabs.length, 1); + int numTabs = Math.max(getNumLiveTabs(), 1); // 1. Compute the width of the available space for all tabs. float stripWidth = mWidth - mLeftMargin - mRightMargin;
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 d86e825c..571a686 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
@@ -946,10 +946,12 @@ mModelSelectorButton.setIncognito(mIsIncognito); if (mTabModelSelector != null) { boolean isVisible = mTabModelSelector.getModel(true).getCount() != 0; + + if (isVisible == mModelSelectorButton.isVisible()) return; + mModelSelectorButton.setVisible(isVisible); float endMargin = isVisible ? getModelSelectorButtonWidthWithPadding() : 0.0f; - mNormalHelper.setEndMargin(endMargin, isVisible); mIncognitoHelper.setEndMargin(endMargin, true); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripTabHoverCardView.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripTabHoverCardView.java index af2330ed..3043959 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripTabHoverCardView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripTabHoverCardView.java
@@ -25,8 +25,8 @@ 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.browser.tasks.tab_management.TabGridThumbnailView; import org.chromium.chrome.browser.tasks.tab_management.TabManagementFieldTrial; +import org.chromium.chrome.browser.tasks.tab_management.TabThumbnailView; import org.chromium.chrome.browser.tasks.tab_management.TabUiThemeProvider; import org.chromium.components.embedder_support.util.UrlUtilities; import org.chromium.ui.base.LocalizationUtils; @@ -39,7 +39,7 @@ private TextView mTitleView; private TextView mUrlView; - private TabGridThumbnailView mThumbnailView; + private TabThumbnailView mThumbnailView; private TabModelSelector mTabModelSelector; private TabModelSelectorObserver mTabModelSelectorObserver; private TabContentManager mTabContentManager;
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 1d7b9203..43ac259 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
@@ -303,6 +303,8 @@ boolean willCreate = onCreateInternal(savedInstanceState); if (!willCreate) { onAbortCreate(); + } else { + onPostCreate(); } TraceEvent.end("AsyncInitializationActivity.onCreate()"); } @@ -320,6 +322,14 @@ protected void onAbortCreate() {} /** + * Override to perform operations after the framework successfully calls {@link + * #onCreateInternal}. This method is used in the ChromeActivity derived class to increment the + * "Chrome.UMA.OnPostCreateCounter2" counter for the histogram + * UMA.AndroidPreNative.ChromeActivityCounter2. + */ + protected void onPostCreate() {} + + /** * Called from onCreate() to give derived classes a chance to dispatch the intent using * {@link LaunchIntentDispatcher}. If the method returns anything other than Action.CONTINUE, * the activity is aborted. Default implementation returns Action.CONTINUE.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java index 91ee9fe..3212722 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
@@ -156,6 +156,10 @@ parts.setContentViewAndLoadLibrary(() -> this.onInflationComplete(parts)); } + public boolean isPostInflationStartupComplete() { + return mPostInflationStartupComplete; + } + /** * This is called after the layout inflation has been completed (in the callback sent to {@link * BrowserParts#setContentViewAndLoadLibrary}). This continues the post-inflation pre-native
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java index 4f95c7c..f680357 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java
@@ -132,19 +132,21 @@ public void onPageLoadStarted(Tab tab, GURL url) { // Discard startup navigation measurements when the user interfered and // started the 2nd navigation (in activity lifetime) in parallel. - if (!mIsFirstPageLoadStart) { - mShouldTrackStartupMetrics = false; - } else { + if (mIsFirstPageLoadStart) { mIsFirstPageLoadStart = false; + } else { + mShouldTrackStartupMetrics = false; } } @Override public void onDidFinishNavigationInPrimaryMainFrame( Tab tab, NavigationHandle navigation) { - boolean isTrackedPage = navigation.hasCommitted() - && !navigation.isErrorPage() && !navigation.isSameDocument() - && UrlUtilities.isHttpOrHttps(navigation.getUrl()); + boolean isTrackedPage = + navigation.hasCommitted() + && !navigation.isErrorPage() + && !navigation.isSameDocument() + && UrlUtilities.isHttpOrHttps(navigation.getUrl()); registerFinishNavigation(isTrackedPage); } };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/ExperimentalStartupMetricsTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ExperimentalStartupMetricsTracker.java new file mode 100644 index 0000000..cde0115 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ExperimentalStartupMetricsTracker.java
@@ -0,0 +1,177 @@ +// Copyright 2023 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.metrics; + +import android.os.SystemClock; + +import androidx.annotation.NonNull; + +import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.chrome.browser.base.ColdStartTracker; +import org.chromium.chrome.browser.init.ChromeBrowserInitializer; +import org.chromium.chrome.browser.page_load_metrics.PageLoadMetrics; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabSelectionType; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver; +import org.chromium.components.embedder_support.util.UrlUtilities; +import org.chromium.content_public.browser.NavigationHandle; +import org.chromium.content_public.browser.WebContents; +import org.chromium.url.GURL; + +/** + * Records UMA page load metrics for the first navigation on a cold start. + * + * <p>Uses different cold start heuristics from {@link ActivityTabStartupMetricsTracker}. These + * heuristics are currently experimental. + * + * <p>One pair of histograms is based on {@link ColdStartTracker}. The other heuristic is more + * speculative, it assumes that cold start finishes as soon as post-inflation startup is complete. + */ +public class ExperimentalStartupMetricsTracker { + + private boolean mFirstNavigationCommitted; + + private class TabObserver extends TabModelSelectorTabObserver { + + private boolean mFirstLoadStarted; + + public TabObserver(TabModelSelector selector) { + super(selector); + } + + @Override + public void onShown(Tab tab, @TabSelectionType int type) { + if (tab != null && tab.isNativePage()) { + // Avoid recording metrics when the NTP is shown. + destroy(); + } + } + + @Override + public void onPageLoadStarted(Tab tab, GURL url) { + // Discard startup navigation measurements when the user started another navigation. + if (!mFirstLoadStarted) { + mFirstLoadStarted = true; + } else { + destroy(); + } + } + + @Override + public void onDidFinishNavigationInPrimaryMainFrame( + Tab tab, @NonNull NavigationHandle navigation) { + if (!mShouldTrack || mFirstNavigationCommitted) return; + boolean shouldTrack = + navigation.hasCommitted() + && !navigation.isErrorPage() + && UrlUtilities.isHttpOrHttps(navigation.getUrl()); + if (!shouldTrack) { + // When navigation leads to an error page, download or chrome:// URLs, avoid + // recording both commit and FCP. + destroy(); + } else { + assert !navigation.isSameDocument() : "The first commit cannot be same-document"; + mFirstNavigationCommitted = true; + recordNavigationCommitMetrics(SystemClock.uptimeMillis() - mActivityStartTimeMs); + } + } + } + + private class PageObserver implements PageLoadMetrics.Observer { + private static final long NO_NAVIGATION_ID = -1; + private long mNavigationId = NO_NAVIGATION_ID; + + @Override + public void onNewNavigation( + WebContents webContents, + long navigationId, + boolean isFirstNavigationInWebContents) { + if (mNavigationId != NO_NAVIGATION_ID) return; + mNavigationId = navigationId; + } + + @Override + public void onFirstContentfulPaint( + WebContents webContents, + long navigationId, + long navigationStartMicros, + long firstContentfulPaintMs) { + recordFcpMetricsIfNeeded(navigationId, navigationStartMicros, firstContentfulPaintMs); + destroy(); + } + + private void recordFcpMetricsIfNeeded( + long navigationId, long navigationStartMicros, long firstContentfulPaintMs) { + if (navigationId != mNavigationId || !mShouldTrack || !mFirstNavigationCommitted) { + return; + } + recordFcpMetrics( + navigationStartMicros / 1000 + firstContentfulPaintMs - mActivityStartTimeMs); + } + } + + // The time of the activity onCreate(). All metrics (such as time to first visible content) are + // reported in uptimeMillis relative to this value. + private final long mActivityStartTimeMs; + + private TabModelSelectorTabObserver mTabObserver; + private PageObserver mPageObserver; + private boolean mShouldTrack = true; + private final boolean mCreatedWhileBrowserNotFullyInitialized; + + public ExperimentalStartupMetricsTracker( + ObservableSupplier<TabModelSelector> tabModelSelectorSupplier) { + mActivityStartTimeMs = SystemClock.uptimeMillis(); + mCreatedWhileBrowserNotFullyInitialized = + !ChromeBrowserInitializer.getInstance().isPostInflationStartupComplete(); + tabModelSelectorSupplier.addObserver(this::registerObservers); + } + + private void registerObservers(TabModelSelector tabModelSelector) { + if (!mShouldTrack) return; + mTabObserver = new TabObserver(tabModelSelector); + mPageObserver = new PageObserver(); + PageLoadMetrics.addObserver(mPageObserver, /* supportPrerendering= */ false); + } + + public void destroy() { + mShouldTrack = false; + if (mTabObserver != null) { + mTabObserver.destroy(); + mTabObserver = null; + } + if (mPageObserver != null) { + PageLoadMetrics.removeObserver(mPageObserver); + mPageObserver = null; + } + } + + private void recordHistogram(String name, String suffix, long ms) { + RecordHistogram.recordMediumTimesHistogram( + "Startup.Android.Experimental." + name + ".Tabbed." + suffix, ms); + } + + private void recordNavigationCommitMetrics(long firstCommitMs) { + if (!SimpleStartupForegroundSessionDetector.runningCleanForegroundSession()) return; + if (ColdStartTracker.wasColdOnFirstActivityCreationOrNow()) { + recordHistogram("FirstNavigationCommit", "ColdStartTracker", firstCommitMs); + } + if (mCreatedWhileBrowserNotFullyInitialized) { + recordHistogram("FirstNavigationCommit", "ActivityCreatedWhileInit", firstCommitMs); + } + } + + private void recordFcpMetrics(long firstFcpMs) { + if (!SimpleStartupForegroundSessionDetector.runningCleanForegroundSession()) return; + if (ColdStartTracker.wasColdOnFirstActivityCreationOrNow()) { + recordHistogram("FirstContentfulPaint", "ColdStartTracker", firstFcpMs); + } + if (mCreatedWhileBrowserNotFullyInitialized) { + recordHistogram("FirstContentfulPaint", "ActivityCreatedWhileInit", firstFcpMs); + } + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java index 8487eed5..c28467b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
@@ -171,9 +171,11 @@ syncAndServicesLink.setSummary(buildSyncAndServicesLink()); Preference thirdPartyCookies = findPreference(PREF_THIRD_PARTY_COOKIES); + Preference doNotTrackPref = findPreference(PREF_DO_NOT_TRACK); if (showTrackingProtectionUI()) { if (thirdPartyCookies != null) thirdPartyCookies.setVisible(false); + if (doNotTrackPref != null) doNotTrackPref.setVisible(false); Preference trackingProtection = findPreference(PREF_TRACKING_PROTECTION); trackingProtection.setVisible(true); } else if (thirdPartyCookies != null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS b/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS index 4c541fc7..ab78ed16 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS
@@ -111,7 +111,7 @@ 'TabUtils\.java' : [ "+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java", "+chrome/browser/browser_controls/android/java/src/org/chromium/chrome/browser/browser_controls/BrowserControlsStateProvider.java", - "+chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailView.java", + "+chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabThumbnailView.java", ], 'TabViewManagerImpl\.java': [ "+chrome/browser/browser_controls/android/java/src/org/chromium/chrome/browser/browser_controls/BrowserControlsMarginSupplier.java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtil.java index 1b75e9b..074e175 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtil.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtil.java
@@ -222,7 +222,8 @@ interval = TimeUtils.elapsedRealtimeMillis() - mLastBackPressMsSupplier.get(); } String msg = - "tab %s; control tab %s; back press state %s; layout %s; isFromSS: %s; interval %s"; + "tab %s; control tab %s; back press state %s; layout %s; isFromSS: %s;" + + " interval %s"; boolean isFromSS = tab != null && isTabFromStartSurface(tab); assert false : String.format(msg, tab, controlTab, tab != null && tab.canGoBack(), layoutType, isFromSS, interval); @@ -541,6 +542,20 @@ && !DeviceFormFactor.isNonMultiDisplayContextOnTablet(context); } + // TODO(mschillaci): Remove this was recreate issue is resolved. See crbug.com/1491862. + /** See {@link isStartSurfaceEnabled} */ + @Deprecated + public static boolean isStartSurfaceEnabled_ForToolbarManager(Context context) { + // When creating initial tab, i.e. cold start without restored tabs, we should only show + // StartSurface as the HomePage if Single Pane is enabled, HomePage is not customized, not + // on tablet, accessibility is not enabled or the tab group continuation feature is enabled. + return (!DseNewTabUrlManager.isNewTabSearchEngineUrlAndroidEnabled() + || DseNewTabUrlManager.isDefaultSearchEngineGoogle()) + && StartSurfaceConfiguration.isStartSurfaceFlagEnabled() + && !shouldHideStartSurfaceWithAccessibilityOn_ForToolbarManager(context) + && !DeviceFormFactor.isNonMultiDisplayContextOnTablet(context); + } + /** * @return Whether start surface should be hidden when accessibility is enabled. If it's true, * NTP is shown as homepage. Also, when time threshold is reached, grid tab switcher or @@ -552,6 +567,16 @@ && !(ChromeFeatureList.sStartSurfaceWithAccessibility.isEnabled()); } + // TODO(mschillaci): Remove this when recreate issue is resolved. See crbug.com/1491862. + /** See {@link shouldHideStartSurfaceWithAccessibilityOn} */ + @Deprecated + public static boolean shouldHideStartSurfaceWithAccessibilityOn_ForToolbarManager( + Context context) { + // TODO(crbug.com/1127732): Move this method back to StartSurfaceConfiguration. + return ChromeAccessibilityUtil.get().isAccessibilityEnabledHeavy() + && !(ChromeFeatureList.sStartSurfaceWithAccessibility.isEnabled()); + } + /** * @param tabModelSelector The tab model selector. * @return the total tab count, and works before native initialization. @@ -944,22 +969,23 @@ } public static boolean isScrollableMvtEnabled(Context context) { - boolean isScrollableMvtEnabled = - ChromeFeatureList.isEnabled(ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID); boolean isSurfacePolishEnabled = ChromeFeatureList.sSurfacePolish.isEnabled(); if (!DeviceFormFactor.isNonMultiDisplayContextOnTablet(context)) { // On phones, parameter SURFACE_POLISH_SCROLLABLE_MVT is checked when feature flag - // surface polish is enabled; otherwise, feature flag SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID + // surface polish is enabled; otherwise, feature flag + // SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID // is checked. - return isSurfacePolishEnabled - ? StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.getValue() - : isScrollableMvtEnabled; + return (isSurfacePolishEnabled + && StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.getValue()) + || ChromeFeatureList.isEnabled( + ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID); } // On tablets, only show the scrollable MV tiles on NTP if feature flag surface polish is // enabled. return isSurfacePolishEnabled ? true - : isScrollableMvtEnabled && ChromeFeatureList.sStartSurfaceOnTablet.isEnabled(); + : ChromeFeatureList.isEnabled(ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID) + && ChromeFeatureList.sStartSurfaceOnTablet.isEnabled(); } /**
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 904e7fb..e69f205 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
@@ -598,7 +598,8 @@ mCustomTabThemeColorProvider = new SettableThemeColorProvider(/* context= */ mActivity); mActivityTabProvider = tabProvider; - mIsStartSurfaceEnabled = ReturnToChromeUtil.isStartSurfaceEnabled(mActivity); + mIsStartSurfaceEnabled = + ReturnToChromeUtil.isStartSurfaceEnabled_ForToolbarManager(mActivity); mIsStartSurfaceRefactorEnabled = ReturnToChromeUtil.isStartSurfaceRefactorEnabled(mActivity); @@ -663,7 +664,7 @@ // logo click events are processed in NewTabPageLayout. This callback passed // into TopToolbarCoordinator will only be used for StartSurfaceToolbar, so add // an assertion here. - assert ReturnToChromeUtil.isStartSurfaceEnabled(mActivity); + assert ReturnToChromeUtil.isStartSurfaceEnabled_ForToolbarManager(mActivity); ReturnToChromeUtil.handleLoadUrlFromStartSurface(urlParams, /*isBackground=*/false, /*incognito=*/false, startSurfaceParentTabSupplier.get()); @@ -1112,7 +1113,7 @@ mLocationBarModel.setStartSurfaceState(mStartSurfaceState); if (!mIsStartSurfaceRefactorEnabled) { mStartSurfaceStateObserver = (newState, shouldShowToolbar) -> { - assert ReturnToChromeUtil.isStartSurfaceEnabled(mActivity); + assert ReturnToChromeUtil.isStartSurfaceEnabled_ForToolbarManager(mActivity); mStartSurfaceState = newState; mLocationBarModel.setStartSurfaceState(mStartSurfaceState); mToolbar.updateStartSurfaceToolbarState(newState, shouldShowToolbar, null); @@ -1299,7 +1300,7 @@ && mLayoutStateProvider.getActiveLayoutType() == LayoutType.START_SURFACE) { return false; } else if (mStartSurfaceState == StartSurfaceState.SHOWN_HOMEPAGE - && ReturnToChromeUtil.isStartSurfaceEnabled(mActivity)) { + && mIsStartSurfaceEnabled) { return false; } @@ -1749,10 +1750,14 @@ @Override public void onAccessibilityModeChanged(boolean enabled) { - if (mIsStartSurfaceEnabled != ReturnToChromeUtil.isStartSurfaceEnabled(mActivity) - && !sSkipRecreateForTesting && !mIsCustomTab) { + if (mIsStartSurfaceEnabled + != ReturnToChromeUtil.isStartSurfaceEnabled_ForToolbarManager(mActivity) + && !sSkipRecreateForTesting + && !mIsCustomTab) { // If Start surface is disabled or re-enabled due to the accessibility change, restarts // the activity to create the correct Toolbar from scratch. + // Note: Do not use the |enabled| value passes here, since it may disagree with the + // value from ReturnToChromeUtil. recreateActivityWithTabReparenting(); return; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java index 542f697..416385c0a00 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java
@@ -247,7 +247,6 @@ @SmallTest @Feature({"UiCatalogue"}) @OverrideTrustedCdn - @DisabledTest(message = "Disabled for flakiness! See http://crbug.com/847341") public void testNavigateAway() throws Exception { runTrustedCdnPublisherUrlTest("https://example.com/test", "com.example.test", "example.com", R.drawable.omnibox_https_valid);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java index 41b0dcc..7758a3fc 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java
@@ -69,6 +69,10 @@ "Startup.Android.Cold.TimeToVisibleContent"; private static final String FIRST_COMMIT_OCCURRED_PRE_FOREGROUND_HISTOGRAM = "Startup.Android.Cold.FirstNavigationCommitOccurredPreForeground"; + private static final String FIRST_COMMIT_COLD_START_TRACKER_HISTOGRAM = + "Startup.Android.Experimental.FirstNavigationCommit.Tabbed.ColdStartTracker"; + private static final String FIRST_COMMIT_ACTIVITY_CREATED_WHILE_INIT_HISTOGRAM = + "Startup.Android.Experimental.FirstNavigationCommit.Tabbed.ActivityCreatedWhileInit"; private CustomTabsConnection mConnectionToCleanup; @@ -154,9 +158,18 @@ private void assertHistogramsRecordedAsExpected(int expectedCount, String histogramSuffix) { boolean isTabbedSuffix = histogramSuffix.equals(TABBED_SUFFIX); - // Check that the new first navigation commit is always recorded for the tabbed activity. - Assert.assertEquals(isTabbedSuffix ? expectedCount : 0, + // Check that the new first navigation commit events are recorded for the tabbed activity. + Assert.assertEquals( + isTabbedSuffix ? expectedCount : 0, RecordHistogram.getHistogramTotalCountForTesting(FIRST_COMMIT_HISTOGRAM2)); + Assert.assertEquals( + isTabbedSuffix ? expectedCount : 0, + RecordHistogram.getHistogramTotalCountForTesting( + FIRST_COMMIT_COLD_START_TRACKER_HISTOGRAM)); + Assert.assertEquals( + isTabbedSuffix ? expectedCount : 0, + RecordHistogram.getHistogramTotalCountForTesting( + FIRST_COMMIT_ACTIVITY_CREATED_WHILE_INIT_HISTOGRAM)); int firstCommitSamples = RecordHistogram.getHistogramTotalCountForTesting( FIRST_COMMIT_HISTOGRAM + histogramSuffix);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java index 4c718f08..f7a0f0f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java
@@ -218,6 +218,8 @@ FeatureList.TestValues testValuesOverride = new FeatureList.TestValues(); testValuesOverride.addFeatureFlagOverride( ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID, isScrollableMVTEnabled); + testValuesOverride.addFeatureFlagOverride( + ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID, isScrollableMVTEnabled); FeatureList.setTestValues(testValuesOverride); } @@ -880,12 +882,11 @@ + " is not recorded correctly when click on the menu button."); } - /** - * Test show and click on the single tab card on the {@link NewTabPage} in the tablet. - */ + /** Test show and click on the single tab card on the {@link NewTabPage} in the tablet. */ @Test @MediumTest @Feature({"NewTabPage"}) + @EnableFeatures({ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID}) public void testSingleTabCardShowAndClick() { ChromeTabbedActivity activity = mActivityTestRule.getActivity(); mActivityTestRule.loadUrl(TEST_URL); @@ -1077,10 +1078,11 @@ @Test @MediumTest @Feature({"NewTabPage"}) - @EnableFeatures({ChromeFeatureList.SURFACE_POLISH + "<Study,", - ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID}) - @CommandLineFlags. - Add({"force-fieldtrials=Study/Group", SURFACE_POLISH_PARAMS + "scrollable_mvt/true"}) + @EnableFeatures({ChromeFeatureList.SURFACE_POLISH + "<Study,"}) + @CommandLineFlags.Add({ + "force-fieldtrials=Study/Group", + SURFACE_POLISH_PARAMS + "scrollable_mvt/true" + }) // clang-format off public void test1RowMvtOnNtpAfterPolish() { // clang-format on
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacySettingsFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacySettingsFragmentTest.java index fab8b86..1fd6d3d3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacySettingsFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacySettingsFragmentTest.java
@@ -282,9 +282,10 @@ public void testTrackingProtectionWithSandboxV4() throws IOException { setShowTrackingProtection(true); mSettingsActivityTestRule.startSettingsActivity(); - // Verify that the Tracking Protection row is shown and 3PC is not. + // Verify that the Tracking Protection row is shown and 3PC/DNT is not. onView(withText(R.string.tracking_protection_title)).check(matches(isDisplayed())); onView(withText(R.string.third_party_cookies_link_row_label)).check(doesNotExist()); + onView(withText(R.string.do_not_track_title)).check(doesNotExist()); } @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/MostVisitedTilesLayoutTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/MostVisitedTilesLayoutTest.java index d86ad3f..231b5b08a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/MostVisitedTilesLayoutTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/MostVisitedTilesLayoutTest.java
@@ -167,7 +167,7 @@ MockitoAnnotations.initMocks(this); FeatureList.TestValues testValuesOverride = new FeatureList.TestValues(); testValuesOverride.addFeatureFlagOverride( - ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID, mEnableScrollableMVT); + ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID, mEnableScrollableMVT); FeatureList.setTestValues(testValuesOverride); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupTest.java index 79ca394..bd07bce2 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupTest.java
@@ -104,6 +104,8 @@ FeatureList.TestValues testValuesOverride = new FeatureList.TestValues(); testValuesOverride.addFeatureFlagOverride( ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID, mEnableScrollableMVT); + testValuesOverride.addFeatureFlagOverride( + ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID, mEnableScrollableMVT); FeatureList.setTestValues(testValuesOverride); mTestServer = EmbeddedTestServer.createAndStartServer(
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripTabHoverCardViewUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripTabHoverCardViewUnitTest.java index d1433fd0..46cd4c98 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripTabHoverCardViewUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripTabHoverCardViewUnitTest.java
@@ -53,8 +53,8 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.chrome.browser.tasks.tab_management.TabGridThumbnailView; import org.chromium.chrome.browser.tasks.tab_management.TabManagementFieldTrial; +import org.chromium.chrome.browser.tasks.tab_management.TabThumbnailView; import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.components.browser_ui.styles.ChromeColors; @@ -90,7 +90,7 @@ private static final float STRIP_STACK_HEIGHT = 500.f; private StripTabHoverCardView mTabHoverCardView; - private TabGridThumbnailView mThumbnailView; + private TabThumbnailView mThumbnailView; private TextView mTitleView; private TextView mUrlView; private Context mContext;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabUtilsUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabUtilsUnitTest.java index 4e927f1e..2442355 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabUtilsUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabUtilsUnitTest.java
@@ -36,7 +36,7 @@ import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.TabUtils.UseDesktopUserAgentCaller; -import org.chromium.chrome.browser.tasks.tab_management.TabGridThumbnailView; +import org.chromium.chrome.browser.tasks.tab_management.TabThumbnailView; import org.chromium.chrome.test.AutomotiveContextWrapperTestRule; import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge; import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridgeJni; @@ -328,7 +328,7 @@ int mockImageSize = 100; int mockTargetSize = 50; - TabGridThumbnailView thumbnailView = Mockito.mock(TabGridThumbnailView.class); + TabThumbnailView thumbnailView = Mockito.mock(TabThumbnailView.class); Bitmap bitmap = Bitmap.createBitmap(mockImageSize, mockImageSize, Bitmap.Config.ARGB_8888); bitmap.setDensity(DisplayMetrics.DENSITY_DEFAULT); TabUtils.setBitmapAndUpdateImageMatrix( @@ -346,7 +346,7 @@ int mockImageSize = 100; int mockTargetSize = 50; - TabGridThumbnailView thumbnailView = Mockito.mock(TabGridThumbnailView.class); + TabThumbnailView thumbnailView = Mockito.mock(TabThumbnailView.class); Bitmap bitmap = Bitmap.createBitmap(mockImageSize, mockImageSize, Bitmap.Config.ARGB_8888); bitmap.setDensity(DisplayMetrics.DENSITY_DEFAULT); TabUtils.setBitmapAndUpdateImageMatrix(
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtilUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtilUnitTest.java index fd665a6..249e868 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtilUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtilUnitTest.java
@@ -917,62 +917,18 @@ } @Test - @EnableFeatures({ChromeFeatureList.SURFACE_POLISH, - ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID}) - // clang-format off - public void testIsScrollableMvtEnabled_SurfacePolishEnabled_ScrollableMvtEnabled() { - // clang-format on - Assert.assertTrue(ChromeFeatureList.sSurfacePolish.isEnabled()); - Assert.assertTrue( - ChromeFeatureList.isEnabled(ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID)); - Assert.assertFalse(StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.getValue()); - - // Tests on phones. - // Verifies if feature ChromeFeatureList.SURFACE_POLISH is enabled, feature - // ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID is ignored. Whether to show the - // scrollable MV tiles is determined by the value of - // StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT - Assert.assertFalse(DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext)); - Assert.assertFalse(ReturnToChromeUtil.isScrollableMvtEnabled(mContext)); - - StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.setForTesting(true); - Assert.assertTrue(ReturnToChromeUtil.isScrollableMvtEnabled(mContext)); - - // Tests on tablets. - setupAndVerifyTablets(); - - StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.setForTesting(false); - Assert.assertFalse(StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.getValue()); - // Verifies if feature ChromeFeatureList.SURFACE_POLISH is enabled on tablets, always show - // the scrollable MV tiles. - Assert.assertTrue(ReturnToChromeUtil.isScrollableMvtEnabled(mContext)); - } - - @Test @EnableFeatures({ChromeFeatureList.SURFACE_POLISH}) @DisableFeatures({ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID}) // clang-format off - public void testIsScrollableMvtEnabled_SurfacePolishEnabled_ScrollableMvtDisabled() { + public void testIsScrollableMvtEnabledWhenSurfacePolishEnabled_tablets() { // clang-format on Assert.assertTrue(ChromeFeatureList.sSurfacePolish.isEnabled()); Assert.assertFalse( ChromeFeatureList.isEnabled(ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID)); Assert.assertFalse(StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.getValue()); - - // Tests on phones. - // Verifies if feature ChromeFeatureList.SURFACE_POLISH is enabled, feature - // ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID is ignored. Whether to show the - // scrollable MV tiles is determined by the value of - // StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT - Assert.assertFalse(DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext)); - StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.setForTesting(true); - Assert.assertTrue(ReturnToChromeUtil.isScrollableMvtEnabled(mContext)); - // Tests on tablets. setupAndVerifyTablets(); - StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.setForTesting(false); - Assert.assertFalse(StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.getValue()); // Verifies if feature ChromeFeatureList.SURFACE_POLISH is enabled on tablets, always show // the scrollable MV tiles. Assert.assertTrue(ReturnToChromeUtil.isScrollableMvtEnabled(mContext)); @@ -980,51 +936,41 @@ @Test @DisableFeatures({ChromeFeatureList.SURFACE_POLISH}) - @EnableFeatures({ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID, - ChromeFeatureList.START_SURFACE_ON_TABLET}) + @EnableFeatures({ + ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID, + ChromeFeatureList.START_SURFACE_ON_TABLET + }) // clang-format off - public void testIsScrollableMvtEnabled_SurfacePolishDisabled_ScrollableMvtEnabled() { + public void testIsScrollableMvtEnabled_SurfacePolishDisabled_ScrollableMvtEnabled_tablets() { // clang-format on Assert.assertFalse(ChromeFeatureList.sSurfacePolish.isEnabled()); Assert.assertTrue( ChromeFeatureList.isEnabled(ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID)); Assert.assertFalse(StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.getValue()); - // Tests on phones. - // Verifies if feature ChromeFeatureList.SURFACE_POLISH is disabled, whether to show the - // scrollable MV tiles is determined by the feature flag - // ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID. - Assert.assertFalse(DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext)); - Assert.assertTrue(ReturnToChromeUtil.isScrollableMvtEnabled(mContext)); - // Tests on tablets. setupAndVerifyTablets(); // Verifies if feature ChromeFeatureList.SURFACE_POLISH is disabled on tablets, the - // scrollable MV tiles is only shown when features - // SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID and START_SURFACE_ON_TABLET are both enabled. + // scrollable MV tiles is only shown when both features + // SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID and START_SURFACE_ON_TABLET are enabled. Assert.assertTrue(ReturnToChromeUtil.isScrollableMvtEnabled(mContext)); } @Test - @DisableFeatures({ChromeFeatureList.SURFACE_POLISH, - ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID}) + @DisableFeatures({ + ChromeFeatureList.SURFACE_POLISH, + ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID + }) @EnableFeatures({ChromeFeatureList.START_SURFACE_ON_TABLET}) // clang-format off - public void testIsScrollableMvtEnabled_SurfacePolishDisabled_ScrollableMvtDisabled() { + public void testIsScrollableMvtEnabled_SurfacePolishDisabled_ScrollableMvtDisabled_tablets() { // clang-format on Assert.assertFalse(ChromeFeatureList.sSurfacePolish.isEnabled()); Assert.assertFalse( ChromeFeatureList.isEnabled(ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID)); Assert.assertFalse(StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.getValue()); - // Tests on phones. - // Verifies if feature ChromeFeatureList.SURFACE_POLISH is disabled, whether to show the - // scrollable MV tiles is determined by the feature flag - // ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID. - Assert.assertFalse(DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext)); - Assert.assertFalse(ReturnToChromeUtil.isScrollableMvtEnabled(mContext)); - // Tests on tablets. setupAndVerifyTablets(); @@ -1033,6 +979,72 @@ Assert.assertFalse(ReturnToChromeUtil.isScrollableMvtEnabled(mContext)); } + @Test + @EnableFeatures({ChromeFeatureList.SURFACE_POLISH}) + @DisableFeatures({ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID}) + // clang-format off + public void testIsScrollableMvtEnabledWhenSurfacePolishEnabled_phones() { + // clang-format on + Assert.assertTrue(ChromeFeatureList.sSurfacePolish.isEnabled()); + Assert.assertFalse( + ChromeFeatureList.isEnabled( + ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID)); + Assert.assertFalse(StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.getValue()); + + // Tests on phones. + // Verifies if feature ChromeFeatureList.SURFACE_POLISH is enabled, feature + // ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID is ignored. Whether to show + // the scrollable MV tiles is determined by the value of + // StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT. + Assert.assertFalse(DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext)); + Assert.assertFalse(ReturnToChromeUtil.isScrollableMvtEnabled(mContext)); + + StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.setForTesting(true); + Assert.assertTrue(ReturnToChromeUtil.isScrollableMvtEnabled(mContext)); + } + + @Test + @DisableFeatures({ChromeFeatureList.SURFACE_POLISH}) + @EnableFeatures({ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID}) + // clang-format off + public void testIsScrollableMvtEnabled_SurfacePolishDisabled_ScrollableMvtEnabled_phones() { + // clang-format on + Assert.assertFalse(ChromeFeatureList.sSurfacePolish.isEnabled()); + Assert.assertTrue( + ChromeFeatureList.isEnabled( + ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID)); + Assert.assertFalse(StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.getValue()); + + // Tests on phones. + // Verifies if feature ChromeFeatureList.SURFACE_POLISH is disabled, whether to show the + // scrollable MV tiles depends on feature flag + // ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID. + Assert.assertFalse(DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext)); + Assert.assertTrue(ReturnToChromeUtil.isScrollableMvtEnabled(mContext)); + } + + @Test + @DisableFeatures({ + ChromeFeatureList.SURFACE_POLISH, + ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID + }) + // clang-format off + public void testIsScrollableMvtEnabled_SurfacePolishDisabled_ScrollableMvtDisabled_phones() { + // clang-format on + Assert.assertFalse(ChromeFeatureList.sSurfacePolish.isEnabled()); + Assert.assertFalse( + ChromeFeatureList.isEnabled( + ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID)); + Assert.assertFalse(StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT.getValue()); + + // Tests on phones. + // Verifies if feature ChromeFeatureList.SURFACE_POLISH is disabled, whether to show the + // scrollable MV tiles is determined by the feature flag + // ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID. + Assert.assertFalse(DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext)); + Assert.assertFalse(ReturnToChromeUtil.isScrollableMvtEnabled(mContext)); + } + private void setupAndVerifyTablets() { doReturn(mResources).when(mContext).getResources(); doReturn(DeviceFormFactor.SCREEN_BUCKET_TABLET)
diff --git a/chrome/android/profiles/arm.newest.txt b/chrome/android/profiles/arm.newest.txt index f39c0577..3b89b388 100644 --- a/chrome/android/profiles/arm.newest.txt +++ b/chrome/android/profiles/arm.newest.txt
@@ -1 +1 @@ -chromeos-chrome-arm-120.0.6061.0_rc-r1-merged.afdo.bz2 +chromeos-chrome-arm-120.0.6062.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index a059efa8..6b2fdad 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-120.0.6058.0_rc-r1-merged.afdo.bz2 +chromeos-chrome-amd64-120.0.6062.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 50609f8..a4fad505 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -208,6 +208,18 @@ <message name="IDS_CELLULAR_SETUP_ESIM_PROFILE_DETECT_MESSAGE" desc="Message displayed during loading page in eSIM setup flow when looking for eSIM profiles."> Looking for available profiles... </message> + <message name="IDS_CELLULAR_SETUP_ESIM_PROFILE_LOADING_TITLE" desc="Title message displayed during loading page in eSIM setup flow when looking for eSIM profiles."> + Looking for available eSIM profiles + </message> + <message name="IDS_CELLULAR_SETUP_ESIM_PROFILE_LOADING_MESSAGE" desc="Message displayed during loading page in eSIM setup flow when looking for eSIM profiles."> + This may cause your mobile network to disconnect for a few minutes. + </message> + <message name="IDS_CELLULAR_SETUP_PROFILE_DISCOVERY_PAGE_TITLE" desc="Title message informing user that they can choose a profile from the list below to download."> + Choose an eSIM profile to download + </message> + <message name="IDS_CELLULAR_SETUP_CONFIRMATION_CODE_PAGE_TITLE" desc="Title message informing user that they can enter confirmation code in the text box below."> + Enter confirmation code + </message> <message name="IDS_CELLULAR_SETUP_ESIM_PROFILE_DETECT_DURING_ACTIVE_CELLULAR_CONNECTION_MESSAGE" desc="Message displayed during loading page in eSIM setup flow when looking for eSIM profiles informing the user that cellular setup may disconnect their current cellular network connection."> Looking for available profiles. This may cause your mobile network to disconnect for a few minutes. </message>
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_CONFIRMATION_CODE_PAGE_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_CONFIRMATION_CODE_PAGE_TITLE.png.sha1 new file mode 100644 index 0000000..76ad3d1 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_CONFIRMATION_CODE_PAGE_TITLE.png.sha1
@@ -0,0 +1 @@ +e94e5225ff2ad9ef9c33dcfc27f7f1a91a165428 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_ESIM_PROFILE_LOADING_MESSAGE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_ESIM_PROFILE_LOADING_MESSAGE.png.sha1 new file mode 100644 index 0000000..9c00e6354 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_ESIM_PROFILE_LOADING_MESSAGE.png.sha1
@@ -0,0 +1 @@ +6c2bd264bb7d79386e84016c50f0feafd97423ae \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_ESIM_PROFILE_LOADING_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_ESIM_PROFILE_LOADING_TITLE.png.sha1 new file mode 100644 index 0000000..9c00e6354 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_ESIM_PROFILE_LOADING_TITLE.png.sha1
@@ -0,0 +1 @@ +6c2bd264bb7d79386e84016c50f0feafd97423ae \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_PROFILE_DISCOVERY_PAGE_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_PROFILE_DISCOVERY_PAGE_TITLE.png.sha1 new file mode 100644 index 0000000..3764c57 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_PROFILE_DISCOVERY_PAGE_TITLE.png.sha1
@@ -0,0 +1 @@ +ef8fd12b09c6f81775177277d4b4950015f9540b \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 3fd0879a..05d97b3a 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -1020,14 +1020,11 @@ <message name="IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_TURN_OFF_BODY_TEXT" desc="Body text for the confirmation dialog that spawns when attempting to turn off bulk pinning in Settings: Files: Google Drive."> New files in My Drive will stop syncing automatically to this Chromebook </message> - <message name="IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_TITLE_TEXT" desc="Title text for the dialog that spawns when a user tries to turn on bulk pinning whilst we're still listing files in Settings: Files: Google Drive."> - Checking storage space… - </message> - <message name="IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_BODY_TEXT" desc="Body text for the dialog that spawns when a user tries to turn on bulk pinning whilst we're still listing files in Settings: Files: Google Drive."> - We are in the process of checking storage space… + <message name="IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_TITLE_TEXT" desc="Title text for the dialog that spawns when a user tries to turn on bulk pinning whilst we're still listing files in Settings: Files: Google Drive."> + Scanning is taking longer than expected </message> <message name="IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_ITEMS_FOUND_BODY_TEXT" desc="Body text for the dialog that spawns when a user tries to turn on bulk pinning whilst we're still listing files and we have a known count of listed files in Settings: Files: Google Drive."> - We are in the process of checking storage space. <ph name="ITEMS_FOUND">$1<ex>1,072</ex></ph> items found. + File sync has found <ph name="ITEMS_FOUND">$1<ex>1,072</ex></ph> files so far and is still checking storage space. Try turning on File sync again in a few minutes. </message> <message name="IDS_SETTINGS_GOOGLE_DRIVE_REMOVE_ACCESS_BUTTON_LABEL" desc="Button label indicates that, when pressed, will disconnect the users Google Drive access in Settings: Files: Google Drive"> Remove Drive access
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_BODY_TEXT.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_BODY_TEXT.png.sha1 deleted file mode 100644 index 1cd65c2..0000000 --- a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_BODY_TEXT.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -6d824641cb44b2a5df2f3b2a94cc3ad43a36385b \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_ITEMS_FOUND_BODY_TEXT.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_ITEMS_FOUND_BODY_TEXT.png.sha1 index 46e83d4..3ea8919 100644 --- a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_ITEMS_FOUND_BODY_TEXT.png.sha1 +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_ITEMS_FOUND_BODY_TEXT.png.sha1
@@ -1 +1 @@ -5e1e72b54a21d22cd03a8183054668425b3e69ce \ No newline at end of file +ffd3cfb4101b4ed2cd8480c8c0b3e6bdd8e764c4 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_TITLE_TEXT.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_TITLE_TEXT.png.sha1 index 1cd65c2..3ea8919 100644 --- a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_TITLE_TEXT.png.sha1 +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_TITLE_TEXT.png.sha1
@@ -1 +1 @@ -6d824641cb44b2a5df2f3b2a94cc3ad43a36385b \ No newline at end of file +ffd3cfb4101b4ed2cd8480c8c0b3e6bdd8e764c4 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index d5aa5ae..2d0a341d 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -165,6 +165,7 @@ "app_mode/app_mode_utils.h", "assist_ranker/assist_ranker_service_factory.cc", "assist_ranker/assist_ranker_service_factory.h", + "auth_notification_types.h", "autocomplete/autocomplete_classifier_factory.cc", "autocomplete/autocomplete_classifier_factory.h", "autocomplete/chrome_autocomplete_provider_client.cc", @@ -288,7 +289,6 @@ "chrome_content_browser_client_binder_policies.h", "chrome_content_browser_client_parts.h", "chrome_content_browser_client_receiver_bindings.cc", - "chrome_notification_types.h", "chrome_resource_bundle_helper.cc", "chrome_resource_bundle_helper.h", "client_hints/client_hints_factory.cc", @@ -7945,7 +7945,7 @@ ] deps += [ - "//chrome/common/compose:mojo_bindings", + "//chrome/common/compose", "//components/autofill/core/common", "//components/compose/core/browser", "//components/compose/proto",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 0cf8e3e2..849cb599 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -6019,11 +6019,6 @@ flag_descriptions::kOmniboxOnClobberFocusTypeOnContentDescription, kOsAll, FEATURE_VALUE_TYPE(omnibox::kOmniboxOnClobberFocusTypeOnContent)}, - {"omnibox-fuzzy-url-suggestions", - flag_descriptions::kOmniboxFuzzyUrlSuggestionsName, - flag_descriptions::kOmniboxFuzzyUrlSuggestionsDescription, kOsAll, - FEATURE_VALUE_TYPE(omnibox::kOmniboxFuzzyUrlSuggestions)}, - {"omnibox-report-assisted-query-stats", flag_descriptions::kOmniboxReportAssistedQueryStatsName, flag_descriptions::kOmniboxReportAssistedQueryStatsDescription, kOsAll, @@ -8923,11 +8918,6 @@ flag_descriptions::kFedCmAuthzDescription, kOsDesktop, FEATURE_VALUE_TYPE(features::kFedCmAuthz)}, - {"fedcm-account-auto-selected-flag", - flag_descriptions::kFedCmAccountAutoSelectedFlagName, - flag_descriptions::kFedCmAccountAutoSelectedFlagDescription, kOsAll, - FEATURE_VALUE_TYPE(features::kFedCmAccountAutoSelectedFlag)}, - {"fedcm-error", flag_descriptions::kFedCmErrorName, flag_descriptions::kFedCmErrorDescription, kOsAll, FEATURE_VALUE_TYPE(features::kFedCmError)}, @@ -8936,6 +8926,12 @@ flag_descriptions::kFedCmHostedDomainDescription, kOsAll, FEATURE_VALUE_TYPE(features::kFedCmHostedDomain)}, + {"fedcm-identity-credential-auto-selected-flag", + flag_descriptions::kFedCmIdentityCredentialAutoSelectedFlagName, + flag_descriptions::kFedCmIdentityCredentialAutoSelectedFlagDescription, + kOsAll, + FEATURE_VALUE_TYPE(features::kFedCmIdentityCredentialAutoSelectedFlag)}, + {"fedcm-idp-registration", flag_descriptions::kFedCmIdPRegistrationName, flag_descriptions::kFedCmIdPRegistrationDescription, kOsDesktop, FEATURE_VALUE_TYPE(features::kFedCmIdPRegistration)},
diff --git a/chrome/browser/accessibility/accessibility_extension_api_ash.cc b/chrome/browser/accessibility/accessibility_extension_api_ash.cc index f830eb3..75e13c87 100644 --- a/chrome/browser/accessibility/accessibility_extension_api_ash.cc +++ b/chrome/browser/accessibility/accessibility_extension_api_ash.cc
@@ -345,15 +345,7 @@ const absl::optional<Params> params(Params::Create(args())); EXTENSION_FUNCTION_VALIDATE(params); - // TODO(chrome-a11y-core): we can't open a settings page when you're on the - // signin profile, but maybe we should notify the user and explain why? - Profile* profile = AccessibilityManager::Get()->profile(); - if (!ash::ProfileHelper::IsSigninProfile(profile) && - chromeos::settings::IsOSSettingsSubPage(params->subpage)) { - chrome::SettingsWindowManager::GetInstance()->ShowOSSettings( - profile, params->subpage); - } - + AccessibilityManager::Get()->OpenSettingsSubpage(params->subpage); return RespondNow(NoArguments()); }
diff --git a/chrome/browser/android/customtabs/tab_interaction_recorder_browsertest.cc b/chrome/browser/android/customtabs/tab_interaction_recorder_browsertest.cc index a11372ab..b71b67a0 100644 --- a/chrome/browser/android/customtabs/tab_interaction_recorder_browsertest.cc +++ b/chrome/browser/android/customtabs/tab_interaction_recorder_browsertest.cc
@@ -51,6 +51,8 @@ scoped_feature_list_.InitWithFeaturesAndParameters( content::GetDefaultEnabledBackForwardCacheFeaturesForTesting(), content::GetDefaultDisabledBackForwardCacheFeaturesForTesting()); + // TODO(crbug.com/1491942): This fails with the field trial testing config. + command_line->AppendSwitch("disable-field-trial-config"); } // Helper functions to verify Histogram
diff --git a/chrome/browser/android/metrics/uma_session_stats.cc b/chrome/browser/android/metrics/uma_session_stats.cc index 888dc11..557c076 100644 --- a/chrome/browser/android/metrics/uma_session_stats.cc +++ b/chrome/browser/android/metrics/uma_session_stats.cc
@@ -180,16 +180,17 @@ } void UmaSessionStats::EmitAndResetCounters() { - absl::optional<int> on_precreate_counter = + absl::optional<int> on_postcreate_counter = android::shared_preferences::GetAndClearInt( - "Chrome.UMA.OnPreCreateCounter"); + "Chrome.UMA.OnPostCreateCounter2"); absl::optional<int> on_resume_counter = - android::shared_preferences::GetAndClearInt("Chrome.UMA.OnResumeCounter"); - int on_create_count = std::min(on_precreate_counter.value_or(0), 3); + android::shared_preferences::GetAndClearInt( + "Chrome.UMA.OnResumeCounter2"); + int on_create_count = std::min(on_postcreate_counter.value_or(0), 3); int on_resume_count = std::min(on_resume_counter.value_or(0), 3); ChromeActivityCounter count_code = static_cast<ChromeActivityCounter>(4 * on_create_count + on_resume_count); - UMA_HISTOGRAM_ENUMERATION("UMA.AndroidPreNative.ChromeActivityCounter", + UMA_HISTOGRAM_ENUMERATION("UMA.AndroidPreNative.ChromeActivityCounter2", count_code); } @@ -220,7 +221,7 @@ } bool UmaSessionStats::SessionTimeTracker::BeginForegroundSession() { - // Emit onPreCreate & onResume counters. This is done early in the session + // Emit onPostCreate & onResume counters. This is done early in the session // to ensure that these are captured even if the session is not ended // cleanly. UmaSessionStats::EmitAndResetCounters();
diff --git a/chrome/browser/android/metrics/uma_session_stats.h b/chrome/browser/android/metrics/uma_session_stats.h index 29a07aa6..bc64b8b 100644 --- a/chrome/browser/android/metrics/uma_session_stats.h +++ b/chrome/browser/android/metrics/uma_session_stats.h
@@ -46,9 +46,9 @@ static bool IsBackgroundSessionStartForTesting(); - // Reads counters Chrome.UMA.OnPreCreateCounter and Chrome.UMA.OnResumeCounter - // that are written to in ChromeActivity.java. The counters are - // encoded in an enum histogram, emitted and reset to 0. + // Reads counters Chrome.UMA.OnPostCreateCounter2 and + // Chrome.UMA.OnResumeCounter2 that are written to in ChromeActivity.java. The + // counters are encoded in an enum histogram, emitted and reset to 0. static void EmitAndResetCounters(); private:
diff --git a/chrome/browser/android/omnibox/autocomplete_controller_android.cc b/chrome/browser/android/omnibox/autocomplete_controller_android.cc index 3816fa8..9ebfe5943 100644 --- a/chrome/browser/android/omnibox/autocomplete_controller_android.cc +++ b/chrome/browser/android/omnibox/autocomplete_controller_android.cc
@@ -117,7 +117,6 @@ std::unique_ptr<ChromeAutocompleteProviderClient> client) : profile_{profile}, java_controller_{env, jcontroller.obj()}, - provider_client_{client.get()}, autocomplete_controller_{std::make_unique<AutocompleteController>( std::move(client), AutocompleteClassifier::DefaultOmniboxProviders())} {
diff --git a/chrome/browser/android/omnibox/autocomplete_controller_android.h b/chrome/browser/android/omnibox/autocomplete_controller_android.h index e48174a..248899f 100644 --- a/chrome/browser/android/omnibox/autocomplete_controller_android.h +++ b/chrome/browser/android/omnibox/autocomplete_controller_android.h
@@ -134,11 +134,6 @@ // Guaranteed to be non-null. const base::android::ScopedJavaGlobalRef<jobject> java_controller_; - // Associated AutocompleteProviderClient. - // Guaranteed to be non-null. - const raw_ptr<ChromeAutocompleteProviderClient, DanglingUntriaged> - provider_client_; - // AutocompleteController associated with this client. As this is directly // associated with the |provider_client_| and indirectly with |profile_| // there is exactly one instance per class.
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn index 58a7ee2..83aa7ef 100644 --- a/chrome/browser/ash/BUILD.gn +++ b/chrome/browser/ash/BUILD.gn
@@ -418,6 +418,8 @@ "arc/input_overlay/ui/button_label_list.h", "arc/input_overlay/ui/button_options_menu.cc", "arc/input_overlay/ui/button_options_menu.h", + "arc/input_overlay/ui/delete_edit_shortcut.cc", + "arc/input_overlay/ui/delete_edit_shortcut.h", "arc/input_overlay/ui/edit_finish_view.cc", "arc/input_overlay/ui/edit_finish_view.h", "arc/input_overlay/ui/edit_label.cc",
diff --git a/chrome/browser/ash/accessibility/accessibility_manager.cc b/chrome/browser/ash/accessibility/accessibility_manager.cc index 89c0f1c..a095078 100644 --- a/chrome/browser/ash/accessibility/accessibility_manager.cc +++ b/chrome/browser/ash/accessibility/accessibility_manager.cc
@@ -22,6 +22,7 @@ #include "ash/public/cpp/accessibility_focus_ring_info.h" #include "ash/root_window_controller.h" #include "ash/shell.h" +#include "ash/webui/settings/public/constants/routes_util.h" #include "base/command_line.h" #include "base/containers/flat_map.h" #include "base/files/file_util.h" @@ -56,6 +57,7 @@ #include "chrome/browser/ash/app_mode/kiosk_app_manager.h" #include "chrome/browser/ash/crosapi/browser_manager.h" #include "chrome/browser/ash/policy/enrollment/enrollment_requisition_manager.h" +#include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/api/braille_display_private/stub_braille_controller.h" #include "chrome/browser/extensions/component_loader.h" @@ -64,6 +66,7 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h" #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" +#include "chrome/browser/ui/settings_window_manager_chromeos.h" #include "chrome/browser/ui/singleton_tabs.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/api/accessibility_private.h" @@ -2086,6 +2089,20 @@ return dictation_active_; } +void AccessibilityManager::OpenSettingsSubpage(const std::string& subpage) { + // TODO(chrome-a11y-core): we can't open a settings page when you're on the + // signin profile, but maybe we should notify the user and explain why? + Profile* profile = AccessibilityManager::Get()->profile(); + if (!ash::ProfileHelper::IsSigninProfile(profile) && + chromeos::settings::IsOSSettingsSubPage(subpage)) { + chrome::SettingsWindowManager::GetInstance()->ShowOSSettings(profile, + subpage); + if (open_settings_subpage_observer_for_test_) { + open_settings_subpage_observer_for_test_.Run(); + } + } +} + const std::string AccessibilityManager::GetFocusRingId( ax::mojom::AssistiveTechnologyType at_type, const std::string& focus_ring_name) { @@ -2215,6 +2232,11 @@ screen_darken_observer_for_test_ = observer; } +void AccessibilityManager::SetOpenSettingsSubpageObserverForTest( + base::RepeatingCallback<void()> observer) { + open_settings_subpage_observer_for_test_ = observer; +} + void AccessibilityManager::SetFocusRingObserverForTest( base::RepeatingCallback<void()> observer) { AccessibilityFocusRingController::Get()->SetFocusRingObserverForTesting(
diff --git a/chrome/browser/ash/accessibility/accessibility_manager.h b/chrome/browser/ash/accessibility/accessibility_manager.h index a08d584..811fc33 100644 --- a/chrome/browser/ash/accessibility/accessibility_manager.h +++ b/chrome/browser/ash/accessibility/accessibility_manager.h
@@ -377,6 +377,9 @@ // Sets the bluetooth braille display device address for the current user. void UpdateBluetoothBrailleDisplayAddress(const std::string& address); + // Opens a specified subpage in the ChromeOS Settings app. + void OpenSettingsSubpage(const std::string& subpage); + // Create a focus ring ID from the `at_type` and the name of the ring. const std::string GetFocusRingId(ax::mojom::AssistiveTechnologyType at_type, const std::string& focus_ring_name); @@ -408,6 +411,8 @@ static void SetBrailleControllerForTest( extensions::api::braille_display_private::BrailleController* controller); void SetScreenDarkenObserverForTest(base::RepeatingCallback<void()> observer); + void SetOpenSettingsSubpageObserverForTest( + base::RepeatingCallback<void()> observer); void SetFocusRingObserverForTest(base::RepeatingCallback<void()> observer); // Runs when highlights are set or updated, but not when they are removed. void SetHighlightsObserverForTest(base::RepeatingCallback<void()> observer); @@ -652,6 +657,7 @@ bool ignore_dictation_locale_pref_change_ = false; base::RepeatingCallback<void()> screen_darken_observer_for_test_; + base::RepeatingCallback<void()> open_settings_subpage_observer_for_test_; base::RepeatingCallback<void()> highlights_observer_for_test_; base::RepeatingCallback<void()> select_to_speak_state_observer_for_test_; base::RepeatingCallback<void(const gfx::Rect&)>
diff --git a/chrome/browser/ash/accessibility/service/accessibility_service_client_browsertest.cc b/chrome/browser/ash/accessibility/service/accessibility_service_client_browsertest.cc index 58ee28fc..800aa31 100644 --- a/chrome/browser/ash/accessibility/service/accessibility_service_client_browsertest.cc +++ b/chrome/browser/ash/accessibility/service/accessibility_service_client_browsertest.cc
@@ -887,6 +887,19 @@ waiter.Run(); } +IN_PROC_BROWSER_TEST_F(AccessibilityServiceClientTest, OpenSettingsSubpage) { + auto client = TurnOnAccessibilityService(AssistiveTechnologyType::kChromeVox); + fake_service_->BindAnotherUserInterface(); + + base::RunLoop waiter; + AccessibilityManager::Get()->SetOpenSettingsSubpageObserverForTest( + base::BindLambdaForTesting([&waiter]() { waiter.Quit(); })); + + fake_service_->RequestOpenSettingsSubpage("manageAccessibility/tts"); + + waiter.Run(); +} + IN_PROC_BROWSER_TEST_F(AccessibilityServiceClientTest, SetFocusRings) { auto client = TurnOnAccessibilityService(AssistiveTechnologyType::kSwitchAccess);
diff --git a/chrome/browser/ash/accessibility/service/fake_accessibility_service.cc b/chrome/browser/ash/accessibility/service/fake_accessibility_service.cc index fcd3aa0..a3d7207 100644 --- a/chrome/browser/ash/accessibility/service/fake_accessibility_service.cc +++ b/chrome/browser/ash/accessibility/service/fake_accessibility_service.cc
@@ -206,6 +206,13 @@ } } +void FakeAccessibilityService::RequestOpenSettingsSubpage( + const std::string& subpage) { + for (auto& ux_client : ux_remotes_) { + ux_client->OpenSettingsSubpage(subpage); + } +} + void FakeAccessibilityService::RequestSetFocusRings( std::vector<ax::mojom::FocusRingInfoPtr> focus_rings, ax::mojom::AssistiveTechnologyType at_type) {
diff --git a/chrome/browser/ash/accessibility/service/fake_accessibility_service.h b/chrome/browser/ash/accessibility/service/fake_accessibility_service.h index 2cb1af0..aee8c4a 100644 --- a/chrome/browser/ash/accessibility/service/fake_accessibility_service.h +++ b/chrome/browser/ash/accessibility/service/fake_accessibility_service.h
@@ -140,6 +140,8 @@ void RequestDarkenScreen(bool darken); + void RequestOpenSettingsSubpage(const std::string& subpage); + void RequestSetFocusRings( std::vector<ax::mojom::FocusRingInfoPtr> focus_rings, ax::mojom::AssistiveTechnologyType at_type);
diff --git a/chrome/browser/ash/accessibility/service/user_interface_impl.cc b/chrome/browser/ash/accessibility/service/user_interface_impl.cc index 1ec3ff4..fe02231 100644 --- a/chrome/browser/ash/accessibility/service/user_interface_impl.cc +++ b/chrome/browser/ash/accessibility/service/user_interface_impl.cc
@@ -26,6 +26,10 @@ AccessibilityManager::Get()->SetDarkenScreen(darken); } +void UserInterfaceImpl::OpenSettingsSubpage(const std::string& subpage) { + AccessibilityManager::Get()->OpenSettingsSubpage(subpage); +} + void UserInterfaceImpl::SetFocusRings( std::vector<ax::mojom::FocusRingInfoPtr> focus_rings, ax::mojom::AssistiveTechnologyType at_type) {
diff --git a/chrome/browser/ash/accessibility/service/user_interface_impl.h b/chrome/browser/ash/accessibility/service/user_interface_impl.h index 169ad26..995c026 100644 --- a/chrome/browser/ash/accessibility/service/user_interface_impl.h +++ b/chrome/browser/ash/accessibility/service/user_interface_impl.h
@@ -26,6 +26,7 @@ // ax::mojom::UserInterface: void DarkenScreen(bool enabled) override; + void OpenSettingsSubpage(const std::string& subpage) override; void SetFocusRings(std::vector<ax::mojom::FocusRingInfoPtr> focus_rings, ax::mojom::AssistiveTechnologyType at_type) override; void SetHighlights(const std::vector<gfx::Rect>& rects,
diff --git a/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc b/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc index 8cb93e42..ee8f608 100644 --- a/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc +++ b/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc
@@ -73,11 +73,14 @@ TestSearchProvider(const std::string& prefix, ChromeSearchResult::DisplayType display_type, ChromeSearchResult::Category category, - ChromeSearchResult::ResultType result_type) + ChromeSearchResult::ResultType result_type, + ash::AppListSearchControlCategory control_category) : prefix_(prefix), display_type_(display_type), category_(category), - result_type_(result_type) {} + result_type_(result_type) { + set_control_category(control_category); + } TestSearchProvider(const TestSearchProvider&) = delete; TestSearchProvider& operator=(const TestSearchProvider&) = delete; @@ -143,7 +146,8 @@ std::make_unique<TestSearchProvider>( "app", ChromeSearchResult::DisplayType::kList, ChromeSearchResult::Category::kApps, - ChromeSearchResult::ResultType::kInstalledApp); + ChromeSearchResult::ResultType::kInstalledApp, + ash::AppListSearchControlCategory::kApps); *apps_provider_ptr = apps_provider.get(); search_controller->AddProvider(std::move(apps_provider)); @@ -151,7 +155,8 @@ std::make_unique<TestSearchProvider>( "item", ChromeSearchResult::DisplayType::kList, ChromeSearchResult::Category::kWeb, - ChromeSearchResult::ResultType::kOmnibox); + ChromeSearchResult::ResultType::kOmnibox, + ash::AppListSearchControlCategory::kWeb); *web_provider_ptr = web_provider.get(); search_controller->AddProvider(std::move(web_provider)); @@ -159,7 +164,8 @@ std::make_unique<TestSearchProvider>( "image", ChromeSearchResult::DisplayType::kImage, ChromeSearchResult::Category::kFiles, - ChromeSearchResult::ResultType::kImageSearch); + ChromeSearchResult::ResultType::kImageSearch, + ash::AppListSearchControlCategory::kImages); *image_provider_ptr = image_provider.get(); search_controller->AddProvider(std::move(image_provider)); } @@ -778,6 +784,9 @@ } IN_PROC_BROWSER_TEST_P(SpokenFeedbackAppListSearchTest, LauncherSearch) { + // Disable search notifier to simplify the test. + AppListTestApi().DisableSearchNotifier(true); + EnableChromeVox(); ShowAppList(); @@ -1011,4 +1020,58 @@ sm_.Replay(); } +IN_PROC_BROWSER_TEST_P(SpokenFeedbackAppListSearchTest, SearchCategoryFilter) { + EnableChromeVox(); + ShowAppList(); + + sm_.ExpectSpeechPattern("Search your *"); + sm_.ExpectSpeech("Edit text"); + + sm_.Call([this]() { + apps_provider_->set_best_match_count(2); + apps_provider_->set_count(3); + web_provider_->set_count(4); + SendKeyPress(ui::VKEY_G); + }); + + sm_.ExpectSpeech("G"); + sm_.ExpectSpeech("Displaying 8 results for g"); + + // Move focus to the search notifier. + sm_.Call([this]() { SendKeyPressWithShift(ui::VKEY_TAB); }); + sm_.ExpectSpeechPattern("Try searching *"); + sm_.ExpectSpeech("Continue"); + + // Move focus to the close button. + sm_.Call([this]() { SendKeyPress(ui::VKEY_UP); }); + sm_.ExpectSpeech("Clear searchbox text"); + + // Move focus to the filter button. + sm_.Call([this]() { SendKeyPress(ui::VKEY_UP); }); + sm_.ExpectSpeech("Toggle search result categories"); + + // Open the filter menu. + sm_.Call([this]() { SendKeyPress(ui::VKEY_RETURN); }); + sm_.ExpectSpeech("menu opened"); + + // Move focus to the category options. + sm_.Call([this]() { SendKeyPress(ui::VKEY_DOWN); }); + sm_.ExpectSpeech("Apps"); + sm_.ExpectSpeech("Checked"); + sm_.ExpectSpeech("Your installed apps"); + + sm_.Call([this]() { SendKeyPress(ui::VKEY_DOWN); }); + sm_.ExpectSpeech("Websites"); + sm_.ExpectSpeech("Checked"); + sm_.ExpectSpeech("Websites including pages you've visited and open pages"); + + // Toggle the websites search category. + sm_.Call([this]() { SendKeyPress(ui::VKEY_RETURN); }); + sm_.ExpectSpeech("Websites"); + sm_.ExpectSpeech("Not checked"); + sm_.ExpectSpeech("Websites including pages you've visited and open pages"); + + sm_.Replay(); +} + } // namespace ash
diff --git a/chrome/browser/ash/arc/input_overlay/constants.h b/chrome/browser/ash/arc/input_overlay/constants.h index 7d94d82..1342231 100644 --- a/chrome/browser/ash/arc/input_overlay/constants.h +++ b/chrome/browser/ash/arc/input_overlay/constants.h
@@ -44,6 +44,8 @@ // The offset from the game window content when EditingList is inside of the // game window. constexpr int kEditingListOffsetInsideMainWindow = 24; +// The offset from the action view list item to the editing list border. +constexpr int kEditingListInsideBorderInsets = 16; // Display mode for display overlay. enum class DisplayMode {
diff --git a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc index b4aa1e1..9631c272 100644 --- a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc +++ b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc
@@ -16,8 +16,10 @@ #include "chrome/browser/ash/arc/input_overlay/actions/action.h" #include "chrome/browser/ash/arc/input_overlay/touch_injector.h" #include "chrome/browser/ash/arc/input_overlay/ui/action_view.h" +#include "chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.h" #include "chrome/browser/ash/arc/input_overlay/ui/button_label_list.h" #include "chrome/browser/ash/arc/input_overlay/ui/button_options_menu.h" +#include "chrome/browser/ash/arc/input_overlay/ui/delete_edit_shortcut.h" #include "chrome/browser/ash/arc/input_overlay/ui/edit_finish_view.h" #include "chrome/browser/ash/arc/input_overlay/ui/editing_list.h" #include "chrome/browser/ash/arc/input_overlay/ui/educational_view.h" @@ -52,6 +54,7 @@ constexpr char kEditingList[] = "GameControlsEditingList"; constexpr char kInputMapping[] = "GameControlsInputMapping"; constexpr char kEduationNudge[] = "GameControlsEducationNudge"; +constexpr char kDeleteEditShortcut[] = "DeleteEditShortcut"; std::unique_ptr<views::Widget> CreateTransientWidget( aura::Window* parent_window, @@ -806,6 +809,35 @@ } } +void DisplayOverlayController::AddDeleteEditShortcutWidget( + ActionViewListItem* anchor_view) { + if (delete_edit_shortcut_widget_) { + if (auto* shortcut = views::AsViewClass<DeleteEditShortcut>( + delete_edit_shortcut_widget_->GetContentsView()); + shortcut->anchor_view() != anchor_view) { + shortcut->UpdateAnchorView(anchor_view); + } + return; + } + + delete_edit_shortcut_widget_ = CreateTransientWidget( + touch_injector_->window(), /*widget_name=*/kDeleteEditShortcut, + /*accept_events=*/true, /*is_floating=*/true); + delete_edit_shortcut_widget_->SetContentsView( + std::make_unique<DeleteEditShortcut>(this, anchor_view)); + + auto* window = delete_edit_shortcut_widget_->GetNativeWindow(); + window->parent()->StackChildAtTop(window); + delete_edit_shortcut_widget_->Show(); +} + +void DisplayOverlayController::RemoveDeleteEditShortcutWidget() { + if (delete_edit_shortcut_widget_) { + delete_edit_shortcut_widget_->Close(); + delete_edit_shortcut_widget_.reset(); + } +} + void DisplayOverlayController::MayShowEduNudgeForEditingTip() { if (GetActiveActionsSize() != 1u) { return; @@ -1092,6 +1124,7 @@ // Remove the floating window attached the ActionView. RemoveButtonLabelListWidget(); RemoveButtonOptionsMenuWidget(); + RemoveDeleteEditShortcutWidget(); } else { // Overlay widget is null for test. if (!GetOverlayWidget()) {
diff --git a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h index 8d116166..fcf15b3 100644 --- a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h +++ b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h
@@ -29,6 +29,7 @@ class Action; class ActionEditMenu; +class ActionViewListItem; class ButtonOptionsMenu; class ButtonLabelList; class EditFinishView; @@ -117,6 +118,9 @@ void AddNudgeWidget(views::View* anchor_view, const std::u16string& text); void RemoveNudgeWidget(views::Widget* widget); + void AddDeleteEditShortcutWidget(ActionViewListItem* anchor_view); + void RemoveDeleteEditShortcutWidget(); + // Show education nudge for editing tip. It only shows up for the first new // action after closing `ButtonOptionsMenu`. void MayShowEduNudgeForEditingTip(); @@ -287,6 +291,7 @@ std::unique_ptr<views::Widget> editing_list_widget_; std::unique_ptr<views::Widget> button_options_widget_; std::unique_ptr<views::Widget> button_label_list_widget_; + std::unique_ptr<views::Widget> delete_edit_shortcut_widget_; // Each widget can associate with one education nudge widget. base::flat_map<views::Widget*, std::unique_ptr<views::Widget>> nudge_widgets_;
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_edit_view.cc b/chrome/browser/ash/arc/input_overlay/ui/action_edit_view.cc index 9847f64..5aa57ea 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/action_edit_view.cc +++ b/chrome/browser/ash/arc/input_overlay/ui/action_edit_view.cc
@@ -32,13 +32,16 @@ // TODO(b/279117180): Replace with proper accessible name. SetAccessibleName( l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_GAME_CONTROLS_ALPHA)); - SetUseDefaultFillLayout(true); - auto* container = - AddChildView(std::make_unique<ash::RoundedContainer>(container_type)); - container->SetBorderInsets(gfx::Insets::VH(14, 16)); - container->SetBackground( - views::CreateThemedSolidBackground(cros_tokens::kCrosSysSystemOnBase)); - container->SetLayoutManager(std::make_unique<views::TableLayout>()) + SetBorder(views::CreateEmptyBorder(gfx::Insets::VH(14, 16))); + SetBackground(views::CreateThemedRoundedRectBackground( + cros_tokens::kCrosSysSystemOnBase, + /*top_radius=*/container_type == + ash::RoundedContainer::Behavior::kBottomRounded + ? 0 + : 16, + /*bottom_radius=*/16, + /*for_border_thickness=*/0)); + SetLayoutManager(std::make_unique<views::TableLayout>()) ->AddColumn(/*h_align=*/views::LayoutAlignment::kStart, /*v_align=*/views::LayoutAlignment::kStart, /*horizontal_resize=*/1.0f, @@ -53,8 +56,8 @@ auto title_string = GetActionNameAtIndex(controller_->action_name_list(), action_->name_label_index()); - name_tag_ = container->AddChildView(NameTag::CreateNameTag(title_string)); - labels_view_ = container->AddChildView(EditLabels::CreateEditLabels( + name_tag_ = AddChildView(NameTag::CreateNameTag(title_string)); + labels_view_ = AddChildView(EditLabels::CreateEditLabels( controller_, action_, name_tag_, /*should_update_title=*/true)); }
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.cc b/chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.cc index 61d6954..a107e03 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.cc +++ b/chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.cc
@@ -35,4 +35,8 @@ labels_view_->ShowEduNudgeForEditingTip(); } +void ActionViewListItem::OnMouseEntered(const ui::MouseEvent& event) { + controller_->AddDeleteEditShortcutWidget(this); +} + } // namespace arc::input_overlay
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.h b/chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.h index b7df1c3b..1cc024f 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.h +++ b/chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.h
@@ -32,6 +32,9 @@ // ActionEditView: void ClickCallback() override; + + // views::View: + void OnMouseEntered(const ui::MouseEvent& event) override; }; } // namespace arc::input_overlay
diff --git a/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.cc b/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.cc index 18bc2f4..bfc50844 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.cc +++ b/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.cc
@@ -260,7 +260,9 @@ } void ButtonOptionsMenu::OnActionRemoved(const Action& action) { - DCHECK_EQ(action_, &action); + if (action_ != &action) { + return; + } controller_->RemoveButtonOptionsMenuWidget(); }
diff --git a/chrome/browser/ash/arc/input_overlay/ui/delete_edit_shortcut.cc b/chrome/browser/ash/arc/input_overlay/ui/delete_edit_shortcut.cc new file mode 100644 index 0000000..d3baecc4 --- /dev/null +++ b/chrome/browser/ash/arc/input_overlay/ui/delete_edit_shortcut.cc
@@ -0,0 +1,117 @@ +// Copyright 2023 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/arc/input_overlay/ui/delete_edit_shortcut.h" + +#include "ash/strings/grit/ash_strings.h" +#include "ash/style/icon_button.h" +#include "chrome/app/vector_icons/vector_icons.h" +#include "chrome/browser/ash/arc/input_overlay/actions/action.h" +#include "chrome/browser/ash/arc/input_overlay/constants.h" +#include "chrome/browser/ash/arc/input_overlay/display_overlay_controller.h" +#include "chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.h" +#include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/chromeos/styles/cros_tokens_color_mappings.h" +#include "ui/color/color_provider.h" +#include "ui/views/background.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/view_class_properties.h" + +namespace arc::input_overlay { + +namespace { + +constexpr int kSpaceFromEditingList = 8; + +} // namespace + +DeleteEditShortcut::DeleteEditShortcut(DisplayOverlayController* controller, + ActionViewListItem* anchor_view) + : controller_(controller), anchor_view_(anchor_view) { + Init(); + observation_.Observe(anchor_view); +} + +DeleteEditShortcut::~DeleteEditShortcut() { + observation_.Reset(); +} + +void DeleteEditShortcut::UpdateAnchorView(ActionViewListItem* anchor_view) { + observation_.Reset(); + observation_.Observe(anchor_view); + anchor_view_ = anchor_view; + UpdateWidget(); +} + +void DeleteEditShortcut::VisibilityChanged(views::View* starting_from, + bool is_visible) { + if (is_visible) { + UpdateWidget(); + } +} + +void DeleteEditShortcut::OnMouseExited(const ui::MouseEvent& event) { + views::View::OnMouseExited(event); + if (!IsMouseHovered()) { + controller_->RemoveDeleteEditShortcutWidget(); + } +} + +void DeleteEditShortcut::OnViewRemovedFromWidget(views::View*) { + controller_->RemoveDeleteEditShortcutWidget(); +} + +void DeleteEditShortcut::OnViewBoundsChanged(views::View*) { + controller_->RemoveDeleteEditShortcutWidget(); +} + +void DeleteEditShortcut::Init() { + SetBorder(views::CreateEmptyBorder(gfx::Insets::VH(12, 12))); + SetBackground(views::CreateThemedRoundedRectBackground( + cros_tokens::kCrosSysSystemBaseElevatedOpaque, + /*radius=*/20, + /*for_border_thickness=*/0)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical, + /*inside_border_insets=*/gfx::Insets(), + /*between_child_spacing=*/12)); + + AddChildView(std::make_unique<ash::IconButton>( + base::BindRepeating(&DeleteEditShortcut::OnEditButtonPressed, + base::Unretained(this)), + ash::IconButton::Type::kMedium, &kGameControlsEditPenIcon, + IDS_APP_LIST_FOLDER_NAME_PLACEHOLDER)); + + AddChildView(std::make_unique<ash::IconButton>( + base::BindRepeating(&DeleteEditShortcut::OnDeleteButtonPressed, + base::Unretained(this)), + ash::IconButton::Type::kMedium, &kGameControlsDeleteIcon, + IDS_APP_LIST_FOLDER_NAME_PLACEHOLDER)); +} + +void DeleteEditShortcut::OnEditButtonPressed() { + controller_->AddButtonOptionsMenuWidget(anchor_view_->action()); + controller_->RemoveDeleteEditShortcutWidget(); +} + +void DeleteEditShortcut::OnDeleteButtonPressed() { + controller_->RemoveAction(anchor_view_->action()); +} + +void DeleteEditShortcut::UpdateWidget() { + auto* widget = GetWidget(); + DCHECK(widget); + + auto anchor_point = anchor_view_->GetBoundsInScreen().top_right(); + auto preferred_size = GetPreferredSize(); + anchor_point.Offset(kEditingListInsideBorderInsets + kSpaceFromEditingList, + (anchor_view_->height() - preferred_size.height()) / 2); + widget->SetBounds(gfx::Rect(anchor_point, preferred_size)); + widget->StackAtTop(); +} + +BEGIN_METADATA(DeleteEditShortcut, views::View) +END_METADATA + +} // namespace arc::input_overlay
diff --git a/chrome/browser/ash/arc/input_overlay/ui/delete_edit_shortcut.h b/chrome/browser/ash/arc/input_overlay/ui/delete_edit_shortcut.h new file mode 100644 index 0000000..3dfe7a1 --- /dev/null +++ b/chrome/browser/ash/arc/input_overlay/ui/delete_edit_shortcut.h
@@ -0,0 +1,75 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_UI_DELETE_EDIT_SHORTCUT_H_ +#define CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_UI_DELETE_EDIT_SHORTCUT_H_ + +#include "base/memory/raw_ptr.h" +#include "base/scoped_observation.h" +#include "ui/base/metadata/metadata_header_macros.h" +#include "ui/views/view.h" +#include "ui/views/view_observer.h" + +namespace arc::input_overlay { + +class ActionViewListItem; +class DisplayOverlayController; + +// DeleteEditShortcut displays a shortcut to either edit to the action or delete +// the action. +// +// View looks like this: +// +------+ +// ||icon|| +// |------| +// ||icon|| +// +------+ +class DeleteEditShortcut : public views::View, public views::ViewObserver { + public: + METADATA_HEADER(DeleteEditShortcut); + DeleteEditShortcut(DisplayOverlayController* controller, + ActionViewListItem* anchor_view); + DeleteEditShortcut(const DeleteEditShortcut&) = delete; + DeleteEditShortcut& operator=(const DeleteEditShortcut&) = delete; + ~DeleteEditShortcut() override; + + ActionViewListItem* anchor_view() { return anchor_view_; } + + void UpdateAnchorView(ActionViewListItem* anchor_view); + + // views::View: + void VisibilityChanged(views::View* starting_from, bool is_visible) override; + void OnMouseExited(const ui::MouseEvent& event) override; + + // views::ViewObserver: + void OnViewRemovedFromWidget(views::View*) override; + void OnViewBoundsChanged(views::View*) override; + + private: + friend class EditingListTest; + + class AnchorViewObserver; + + // Build related views. + void Init(); + + // Handle button functions. + void OnEditButtonPressed(); + void OnDeleteButtonPressed(); + + void UpdateWidget(); + + // DisplayOverlayController owns this class, no need to deallocate. + const raw_ptr<DisplayOverlayController> controller_ = nullptr; + raw_ptr<ActionViewListItem> anchor_view_ = nullptr; + + // Watches for the anchor view to be destroyed or removed from its widget. + // Prevents the delete edit shortcut from lingering after its anchor is + // invalid, which can cause strange behavior. + base::ScopedObservation<View, ViewObserver> observation_{this}; +}; + +} // namespace arc::input_overlay + +#endif // CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_UI_DELETE_EDIT_SHORTCUT_H_
diff --git a/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc b/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc index 0088530e..7d38cdc3 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc +++ b/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc
@@ -14,6 +14,7 @@ #include "base/notreached.h" #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ash/arc/input_overlay/actions/action.h" +#include "chrome/browser/ash/arc/input_overlay/constants.h" #include "chrome/browser/ash/arc/input_overlay/display_overlay_controller.h" #include "chrome/browser/ash/arc/input_overlay/touch_injector.h" #include "chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.h" @@ -38,7 +39,6 @@ constexpr int kMainContainerWidth = 296; -constexpr int kInsideBorderInsets = 16; constexpr int kHeaderBottomMargin = 16; // This is associated to the size of `ash::IconButton::Type::kMedium`. constexpr int kIconButtonSize = 32; @@ -110,7 +110,7 @@ void EditingList::Init() { SetBackground(views::CreateThemedRoundedRectBackground( cros_tokens::kCrosSysSystemBaseElevatedOpaque, /*radius=*/24)); - SetBorder(views::CreateEmptyBorder(kInsideBorderInsets)); + SetBorder(views::CreateEmptyBorder(kEditingListInsideBorderInsets)); SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical)) ->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kCenter); @@ -258,6 +258,7 @@ auto* widget = GetWidget(); DCHECK(widget); + controller_->RemoveDeleteEditShortcutWidget(); auto widget_bounds = widget->GetNativeWindow()->GetBoundsInScreen(); widget_bounds.Offset( /*horizontal=*/(event.location() - start_drag_event_pos_).x(), @@ -331,7 +332,7 @@ void EditingList::ClipScrollViewHeight(bool is_outside) { int max_height = controller_->touch_injector()->content_bounds().height() - - 2 * kInsideBorderInsets - kHeaderBottomMargin - + 2 * kEditingListInsideBorderInsets - kHeaderBottomMargin - kIconButtonSize; if (!is_outside) { max_height -= kEditingListOffsetInsideMainWindow;
diff --git a/chrome/browser/ash/arc/input_overlay/ui/editing_list_unittest.cc b/chrome/browser/ash/arc/input_overlay/ui/editing_list_unittest.cc index 1fe1569f..e858379b 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/editing_list_unittest.cc +++ b/chrome/browser/ash/arc/input_overlay/ui/editing_list_unittest.cc
@@ -13,7 +13,9 @@ #include "chrome/browser/ash/arc/input_overlay/test/test_utils.h" #include "chrome/browser/ash/arc/input_overlay/touch_injector.h" #include "chrome/browser/ash/arc/input_overlay/ui/action_view.h" +#include "chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.h" #include "chrome/browser/ash/arc/input_overlay/ui/button_options_menu.h" +#include "chrome/browser/ash/arc/input_overlay/ui/delete_edit_shortcut.h" #include "chrome/browser/ash/arc/input_overlay/ui/input_mapping_view.h" #include "chrome/browser/ash/arc/input_overlay/ui/touch_point.h" #include "ui/aura/window.h" @@ -73,6 +75,21 @@ event_generator->ClickLeftButton(); } + void HoverAtActionViewListItem(int index) { + if (!editing_list_ || editing_list_->is_zero_state_ || index < 0) { + return; + } + views::View* scroll_content = editing_list_->scroll_content_; + DCHECK(scroll_content); + if (index >= static_cast<int>(scroll_content->children().size())) { + return; + } + + auto* event_generator = GetEventGenerator(); + auto view_bounds = scroll_content->children()[index]->GetBoundsInScreen(); + event_generator->MoveMouseTo(view_bounds.CenterPoint()); + } + void MouseDragEditingListBy(int x, int y) { auto* event_generator = GetEventGenerator(); event_generator->MoveMouseTo( @@ -135,6 +152,10 @@ return !!controller_->button_options_widget_; } + bool DeleteEditShortcutExists() { + return !!controller_->delete_edit_shortcut_widget_; + } + bool IsButtonOptionsMenuVisible() { auto* menu_widget = controller_->button_options_widget_.get(); return menu_widget && menu_widget->IsVisible(); @@ -147,6 +168,20 @@ } } + void PressEditButton() { + DCHECK(controller_->delete_edit_shortcut_widget_); + static_cast<DeleteEditShortcut*>( + controller_->delete_edit_shortcut_widget_->GetContentsView()) + ->OnEditButtonPressed(); + } + + void PressDeleteButton() { + DCHECK(controller_->delete_edit_shortcut_widget_); + static_cast<DeleteEditShortcut*>( + controller_->delete_edit_shortcut_widget_->GetContentsView()) + ->OnDeleteButtonPressed(); + } + Action* GetButtonOptionsAction() { auto* menu = controller_->GetButtonOptionsMenu(); if (!menu) { @@ -155,6 +190,13 @@ return menu->action(); } + Action* GetDeleteEditShortcutAction() { + return static_cast<DeleteEditShortcut*>( + controller_->delete_edit_shortcut_widget_->GetContentsView()) + ->anchor_view() + ->action(); + } + views::Widget* GetEducationNudge(views::Widget* widget) { DCHECK(controller_); auto& widgets_map = controller_->nudge_widgets_; @@ -219,6 +261,28 @@ EXPECT_NE(action_1, action_2); } +TEST_F(EditingListTest, TestHoverAtActionViewListItem) { + CheckActions(touch_injector_, /*expect_size=*/3u, /*expect_types=*/ + {ActionType::TAP, ActionType::TAP, ActionType::MOVE}, + /*expect_ids=*/{0, 1, 2}); + HoverAtActionViewListItem(/*index=*/0); + EXPECT_TRUE(DeleteEditShortcutExists()); + auto* action = GetDeleteEditShortcutAction(); + + PressEditButton(); + EXPECT_TRUE(ButtonOptionsMenuExists()); + EXPECT_FALSE(DeleteEditShortcutExists()); + EXPECT_EQ(action, GetButtonOptionsAction()); + PressDoneButtonOnButtonOptionsMenu(); + + HoverAtActionViewListItem(/*index=*/0); + EXPECT_TRUE(DeleteEditShortcutExists()); + PressDeleteButton(); + EXPECT_FALSE(DeleteEditShortcutExists()); + EXPECT_EQ(2u, GetActionListItemsSize()); + EXPECT_EQ(2u, GetActionViewSize()); +} + TEST_F(EditingListTest, TestReposition) { // 1. There is enough space on left and right of the sibling game window // outside.
diff --git a/chrome/browser/ash/login/existing_user_controller.cc b/chrome/browser/ash/login/existing_user_controller.cc index c009d262..60a98ff 100644 --- a/chrome/browser/ash/login/existing_user_controller.cc +++ b/chrome/browser/ash/login/existing_user_controller.cc
@@ -66,9 +66,9 @@ #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/ash/settings/cros_settings.h" #include "chrome/browser/ash/system/device_disabling_manager.h" +#include "chrome/browser/auth_notification_types.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/lifetime/application_lifetime_chromeos.h" #include "chrome/browser/lifetime/browser_shutdown.h" #include "chrome/browser/net/system_network_context_manager.h"
diff --git a/chrome/browser/ash/login/proxy_auth_dialog_browsertest.cc b/chrome/browser/ash/login/proxy_auth_dialog_browsertest.cc index b9cdba4..50693f6 100644 --- a/chrome/browser/ash/login/proxy_auth_dialog_browsertest.cc +++ b/chrome/browser/ash/login/proxy_auth_dialog_browsertest.cc
@@ -11,7 +11,7 @@ #include "chrome/browser/ash/login/test/js_checker.h" #include "chrome/browser/ash/login/test/login_manager_mixin.h" #include "chrome/browser/ash/login/test/oobe_screen_waiter.h" -#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/auth_notification_types.h" #include "chrome/browser/ui/login/login_handler.h" #include "chrome/browser/ui/webui/ash/login/gaia_screen_handler.h" #include "chrome/browser/ui/webui/ash/login/user_creation_screen_handler.h"
diff --git a/chrome/browser/ash/login/quickstart_controller.cc b/chrome/browser/ash/login/quickstart_controller.cc index 7c1e19c..e00e846 100644 --- a/chrome/browser/ash/login/quickstart_controller.cc +++ b/chrome/browser/ash/login/quickstart_controller.cc
@@ -10,9 +10,12 @@ #include "chrome/browser/ash/login/oobe_screen.h" #include "chrome/browser/ash/login/ui/login_display_host.h" #include "chrome/browser/ash/login/wizard_context.h" +#include "chrome/browser/ui/webui/ash/login/consumer_update_screen_handler.h" #include "chrome/browser/ui/webui/ash/login/gaia_screen_handler.h" #include "chrome/browser/ui/webui/ash/login/network_screen_handler.h" +#include "chrome/browser/ui/webui/ash/login/parental_handoff_screen_handler.h" #include "chrome/browser/ui/webui/ash/login/quick_start_screen_handler.h" +#include "chrome/browser/ui/webui/ash/login/user_creation_screen_handler.h" #include "chrome/browser/ui/webui/ash/login/welcome_screen_handler.h" #include "chromeos/ash/components/quick_start/logging.h" #include "chromeos/ash/components/quick_start/quick_start_metrics.h" @@ -33,6 +36,20 @@ return absl::nullopt; } +quick_start_metrics::ScreenName ScreenNameFromOobeScreenId( + OobeScreenId screen_id) { + // TODO(b/298042953): Check Screen IDs for Unicorn account setup flow. + if (screen_id == ConsumerUpdateScreenView::kScreenId) { + // TODO(b/298042953): Update Screen ID when the new OOBE Checking for + // update and determining device configuration screen is added. + return quick_start_metrics::ScreenName:: + kCheckingForUpdateAndDeterminingDeviceConfiguration; + } else if (screen_id == UserCreationView::kScreenId) { + return quick_start_metrics::ScreenName::kChooseChromebookSetup; + } + return quick_start_metrics::ScreenName::kOther; +} + } // namespace QuickStartController::QuickStartController() { @@ -135,6 +152,8 @@ using Step = TargetDeviceBootstrapController::Step; using ErrorCode = TargetDeviceBootstrapController::ErrorCode; + // TODO(b/298042953): Emit ScreenOpened metrics when automatically resuming + // after an update. switch (status.step) { case Step::ADVERTISING_WITH_QR_CODE: { controller_state_ = ControllerState::ADVERTISING; @@ -211,9 +230,13 @@ current_screen_ = current_screen; previous_screen_ = previous_screen; - // Just switched into the quick start screen. if (current_screen_ == QuickStartScreenHandler::kScreenId) { + // Just switched into the quick start screen. The ScreenOpened metrics on + // the Quick Start screen are recorded from OnStatusChanged(). HandleTransitionToQuickStartScreen(); + } else if (IsSetupOngoing()) { + quick_start_metrics::RecordScreenOpened( + ScreenNameFromOobeScreenId(current_screen)); } }
diff --git a/chrome/browser/ash/login/saml/saml_lockscreen_browsertest.cc b/chrome/browser/ash/login/saml/saml_lockscreen_browsertest.cc index 95d55b7..d3d12ac 100644 --- a/chrome/browser/ash/login/saml/saml_lockscreen_browsertest.cc +++ b/chrome/browser/ash/login/saml/saml_lockscreen_browsertest.cc
@@ -24,7 +24,7 @@ #include "chrome/browser/ash/policy/affiliation/affiliation_test_helper.h" #include "chrome/browser/ash/policy/core/device_policy_cros_browser_test.h" #include "chrome/browser/ash/profiles/profile_helper.h" -#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/auth_notification_types.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/login/login_handler.h" #include "chrome/test/base/mixin_based_in_process_browser_test.h"
diff --git a/chrome/browser/ash/login/screens/multidevice_setup_screen.cc b/chrome/browser/ash/login/screens/multidevice_setup_screen.cc index 026bea7..a0ffc9f4 100644 --- a/chrome/browser/ash/login/screens/multidevice_setup_screen.cc +++ b/chrome/browser/ash/login/screens/multidevice_setup_screen.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/ash/multidevice_setup/oobe_completion_tracker_factory.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/webui/ash/login/multidevice_setup_screen_handler.h" +#include "chromeos/ash/components/quick_start/quick_start_metrics.h" #include "chromeos/ash/services/device_sync/public/cpp/device_sync_client.h" #include "chromeos/ash/services/multidevice_setup/public/cpp/multidevice_setup_client.h" #include "chromeos/ash/services/multidevice_setup/public/cpp/oobe_completion_tracker.h" @@ -121,6 +122,8 @@ const std::string& phone_instance_id = context.quick_start_phone_instance_id; if (!phone_instance_id.empty()) { setup_client_->SetQuickStartPhoneInstanceID(phone_instance_id); + quick_start::quick_start_metrics::RecordScreenOpened( + quick_start::quick_start_metrics::ScreenName::kUnifiedSetup); } // Do not skip if potential host exists but none is set yet.
diff --git a/chrome/browser/ash/login/webview_login_browsertest.cc b/chrome/browser/ash/login/webview_login_browsertest.cc index e866d33..09761e85 100644 --- a/chrome/browser/ash/login/webview_login_browsertest.cc +++ b/chrome/browser/ash/login/webview_login_browsertest.cc
@@ -54,9 +54,9 @@ #include "chrome/browser/ash/scoped_test_system_nss_key_slot_mixin.h" #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h" #include "chrome/browser/ash/settings/stub_cros_settings_provider.h" +#include "chrome/browser/auth_notification_types.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ssl/ssl_client_certificate_selector.h" #include "chrome/browser/sync/sync_service_factory.h"
diff --git a/chrome/browser/ash/login/wizard_controller_browsertest.cc b/chrome/browser/ash/login/wizard_controller_browsertest.cc index 4ca8e57..1295ee1 100644 --- a/chrome/browser/ash/login/wizard_controller_browsertest.cc +++ b/chrome/browser/ash/login/wizard_controller_browsertest.cc
@@ -74,9 +74,9 @@ #include "chrome/browser/ash/policy/enrollment/fake_auto_enrollment_client.h" #include "chrome/browser/ash/policy/server_backed_state/server_backed_device_state.h" #include "chrome/browser/ash/policy/server_backed_state/server_backed_state_keys_broker.h" +#include "chrome/browser/auth_notification_types.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/lifetime/browser_shutdown.h" #include "chrome/browser/lifetime/termination_notification.h" #include "chrome/browser/profiles/profile_manager.h"
diff --git a/chrome/browser/ash/net/network_portal_detector_impl.cc b/chrome/browser/ash/net/network_portal_detector_impl.cc index d81393bf..710b8ef2 100644 --- a/chrome/browser/ash/net/network_portal_detector_impl.cc +++ b/chrome/browser/ash/net/network_portal_detector_impl.cc
@@ -14,8 +14,8 @@ #include "base/metrics/histogram_functions.h" #include "base/task/single_thread_task_runner.h" #include "build/branding_buildflags.h" +#include "chrome/browser/auth_notification_types.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/net/system_network_context_manager.h" #include "chromeos/ash/components/dbus/shill/shill_profile_client.h" #include "chromeos/ash/components/login/login_state/login_state.h"
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_test_util.h b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_test_util.h index ada26f0..e2c4efe 100644 --- a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_test_util.h +++ b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_test_util.h
@@ -43,7 +43,6 @@ // Sets whether to continue postprocessing after event observed callback is // called. - // TODO(b/266018440): Create a scoped class to set and unset. static void SetInterruptedAfterEventObserved( FatalCrashEventsObserver& observer, bool interrupted_after_event_observed);
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_unittest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_unittest.cc index 605cda5..28535acb 100644 --- a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_unittest.cc +++ b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_unittest.cc
@@ -41,6 +41,38 @@ using ::ash::cros_healthd::mojom::EventCategoryEnum; using ::ash::cros_healthd::mojom::EventInfo; +// RAII class to interrupt after event is observed. +class ScopedInterruptedAfterEventObserved { + public: + // `observer` must remain alive when this object destructs. + explicit ScopedInterruptedAfterEventObserved( + FatalCrashEventsObserver& observer) + : observer_(&observer) { + FatalCrashEventsObserver::TestEnvironment::SetInterruptedAfterEventObserved( + *observer_, /*interrupted_after_event_observed=*/true); + } + + virtual ~ScopedInterruptedAfterEventObserved() { + FatalCrashEventsObserver::TestEnvironment::SetInterruptedAfterEventObserved( + *observer_, /*interrupted_after_event_observed=*/false); + } + + ScopedInterruptedAfterEventObserved( + const ScopedInterruptedAfterEventObserved&) = delete; + ScopedInterruptedAfterEventObserved& operator=( + const ScopedInterruptedAfterEventObserved&) = delete; + + // The move constructor and assignment are currently unused, but there's + // no reason to not support them as they are standard in scoped classes. + ScopedInterruptedAfterEventObserved(ScopedInterruptedAfterEventObserved&&) = + default; + ScopedInterruptedAfterEventObserved& operator=( + ScopedInterruptedAfterEventObserved&&) = default; + + private: + raw_ptr<FatalCrashEventsObserver> observer_; +}; + // Base class for testing `FatalCrashEventsObserver`. `NoSessionAshTestBase` is // needed here because the observer uses `ash::Shell()` to obtain the user // session type. @@ -653,16 +685,16 @@ base::test::TestFuture<MetricData> result_metric_data; auto fatal_crash_events_observer = CreateAndEnableFatalCrashEventsObserver(&result_metric_data); - // Simulate the thread is interrupted after event observed callback is called. - fatal_crash_test_environment_.SetInterruptedAfterEventObserved( - *fatal_crash_events_observer, /*interrupted_after_event_observed=*/true); - CreateFatalCrashEvent( - /*local_id=*/kLocalId, /*capture_time=*/kCaptureTime, - *fatal_crash_events_observer, &result_metric_data); - // Now back to what production code does (no interruption). - fatal_crash_test_environment_.SetInterruptedAfterEventObserved( - *fatal_crash_events_observer, /*interrupted_after_event_observed=*/false); + { + // Simulate the thread is interrupted after event observed callback is + // called. + ScopedInterruptedAfterEventObserved scoped_interruption( + *fatal_crash_events_observer); + CreateFatalCrashEvent( + /*local_id=*/kLocalId, /*capture_time=*/kCaptureTime, + *fatal_crash_events_observer, &result_metric_data); + } // Always reload to simulate what happens practically, e.g., ash crashes. fatal_crash_events_observer = @@ -693,15 +725,15 @@ *fatal_crash_events_observer, &result_metric_data, /*is_uploaded=*/false); - // Simulate the thread is interrupted after event observed callback is called. - fatal_crash_test_environment_.SetInterruptedAfterEventObserved( - *fatal_crash_events_observer, /*interrupted_after_event_observed=*/true); - CreateFatalCrashEvent(/*local_id=*/kLocalId, /*capture_time=*/kCaptureTime, - *fatal_crash_events_observer, &result_metric_data, - /*is_uploaded=*/true); - // Back to normal. - fatal_crash_test_environment_.SetInterruptedAfterEventObserved( - *fatal_crash_events_observer, /*interrupted_after_event_observed=*/false); + { + // Simulate the thread is interrupted after event observed callback is + // called. + ScopedInterruptedAfterEventObserved scoped_interruption( + *fatal_crash_events_observer); + CreateFatalCrashEvent(/*local_id=*/kLocalId, /*capture_time=*/kCaptureTime, + *fatal_crash_events_observer, &result_metric_data, + /*is_uploaded=*/true); + } // Reload. fatal_crash_events_observer = @@ -1112,17 +1144,18 @@ auto fatal_crash_events_observer = CreateAndEnableFatalCrashEventsObserver(&result_metric_data); - // If required by the test, simulate the thread is interrupted after event - // observed callback is called. - fatal_crash_test_environment_.SetInterruptedAfterEventObserved( - *fatal_crash_events_observer, interrupt_after_event_observed()); + { + // Simulate the thread is interrupted after event observed callback is + // called, if required by the test params. + auto scoped_interruption = + interrupt_after_event_observed() + ? std::make_unique<ScopedInterruptedAfterEventObserved>( + *fatal_crash_events_observer) + : nullptr; - CreateFatalCrashEvent(kCrashReportId, kCreationTime, kOffset, - *fatal_crash_events_observer, &result_metric_data); - - // Now back to what production code does (no interruption). - fatal_crash_test_environment_.SetInterruptedAfterEventObserved( - *fatal_crash_events_observer, /*interrupted_after_event_observed=*/false); + CreateFatalCrashEvent(kCrashReportId, kCreationTime, kOffset, + *fatal_crash_events_observer, &result_metric_data); + } if (reload()) { fatal_crash_events_observer =
diff --git a/chrome/browser/ash/scalable_iph/scalable_iph_browsertest.cc b/chrome/browser/ash/scalable_iph/scalable_iph_browsertest.cc index 0223e95..6ba7204 100644 --- a/chrome/browser/ash/scalable_iph/scalable_iph_browsertest.cc +++ b/chrome/browser/ash/scalable_iph/scalable_iph_browsertest.cc
@@ -740,7 +740,16 @@ testing::Mock::VerifyAndClearExpectations(mock_tracker()); } -IN_PROC_BROWSER_TEST_F(ScalableIphBrowserTest, AppListShown) { +// TODO(crbug.com/1491942): This fails with the field trial testing config. +class ScalableIphBrowserTestNoTestingConfig : public ScalableIphBrowserTest { + public: + void SetUpCommandLine(base::CommandLine* command_line) override { + ScalableIphBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitch("disable-field-trial-config"); + } +}; + +IN_PROC_BROWSER_TEST_F(ScalableIphBrowserTestNoTestingConfig, AppListShown) { EXPECT_CALL(*mock_tracker(), NotifyEvent(scalable_iph::kEventNameAppListShown));
diff --git a/chrome/browser/ash/screenshot_integration_test.cc b/chrome/browser/ash/screenshot_integration_test.cc new file mode 100644 index 0000000..e5306d3 --- /dev/null +++ b/chrome/browser/ash/screenshot_integration_test.cc
@@ -0,0 +1,111 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <string> + +#include "ash/shell.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/run_loop.h" +#include "base/task/single_thread_task_runner.h" +#include "base/test/bind.h" +#include "base/test/scoped_feature_list.h" +#include "base/threading/thread_restrictions.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/test/base/chromeos/crosier/chromeos_integration_test_mixin.h" +#include "chrome/test/base/chromeos/crosier/helper/test_sudo_helper_client.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/mixin_based_in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/test/browser_test.h" +#include "gpu/config/gpu_finch_features.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/display/manager/display_configurator.h" +#include "ui/gfx/color_analysis.h" + +namespace { + +class ScreenshotIntegrationTest : public MixinBasedInProcessBrowserTest, + public testing::WithParamInterface<bool> { + public: + ScreenshotIntegrationTest() { + if (GetParam()) { + feature_list_.InitAndEnableFeature(features::kVulkan); + } else { + feature_list_.InitAndDisableFeature(features::kVulkan); + } + } + + private: + base::test::ScopedFeatureList feature_list_; + ChromeOSIntegrationTestMixin chromeos_integration_test_mixin_{&mixin_host_}; +}; + +INSTANTIATE_TEST_SUITE_P(Vulkan, ScreenshotIntegrationTest, testing::Bool()); + +IN_PROC_BROWSER_TEST_P(ScreenshotIntegrationTest, AverageColor) { + // Ensure the display is powered on, otherwise the screenshot will fail. + base::RunLoop run_loop; + ash::Shell::Get()->display_configurator()->SetDisplayPower( + chromeos::DISPLAY_POWER_ALL_ON, + display::DisplayConfigurator::kSetDisplayPowerForceProbe, + base::BindLambdaForTesting([&](bool success) { + ASSERT_TRUE(success); + run_loop.Quit(); + })); + run_loop.Run(); + + // Maximize the browser window. + ASSERT_TRUE(browser()); + browser()->window()->Maximize(); + + // Load a page with a solid red background. + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), GURL("data:text/html,<body bgcolor=red></body>"))); + + // We don't know when the frame's pixels will be scanned out, so take + // screenshots in a loop until we get a valid one. + SkColor dominant_color; + bool success = false; + for (int i = 0; i < 5; ++i) { + // Sleep for 1 second. + base::RunLoop run_loop2; + base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask( + FROM_HERE, run_loop2.QuitClosure(), base::Seconds(1)); + run_loop2.Run(); + + // Use the command-line screenshot utility to capture the screen. + auto result = + TestSudoHelperClient().RunCommand("screenshot /tmp/screen.png"); + ASSERT_EQ(result.return_code, 0) << result.output; + + // Load the PNG screenshot. + base::ScopedAllowBlockingForTesting allow_blocking; + absl::optional<std::vector<uint8_t>> image_png = + base::ReadFileToBytes(base::FilePath("/tmp/screen.png")); + ASSERT_TRUE(image_png.has_value()); + + // Compute the dominant color. + dominant_color = color_utils::CalculateKMeanColorOfPNG(*image_png); + + // If the color matches the red page background, we're done. + if (dominant_color == SK_ColorRED) { + success = true; + break; + } + + // The screen may not yet have valid pixels yet. + LOG(WARNING) << "Dominant color " << std::hex << dominant_color + << " does not match expected " << SK_ColorRED; + } + EXPECT_TRUE(success) << "Final screenshot had invalid dominant color " + << std::hex << dominant_color; + + // Clean up. + browser()->window()->Close(); +} + +} // namespace
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_integration_browsertest.cc b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_integration_browsertest.cc index b11e2497..38ef18c 100644 --- a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_integration_browsertest.cc +++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_integration_browsertest.cc
@@ -314,6 +314,12 @@ scoped_feature_list_.InitAndDisableFeature(chromeos::features::kJelly); } + // TODO(crbug.com/1491942): This fails with the field trial testing config. + void SetUpCommandLine(base::CommandLine* command_line) override { + PersonalizationAppIntegrationBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitch("disable-field-trial-config"); + } + void SetUp() override { if (IsExperimentalBrowserPixelTestEnabled()) { view_skia_gold_pixel_diff_ =
diff --git a/chrome/browser/chrome_notification_types.h b/chrome/browser/auth_notification_types.h similarity index 74% rename from chrome/browser/chrome_notification_types.h rename to chrome/browser/auth_notification_types.h index 3b6ebdb5..6df8538 100644 --- a/chrome/browser/chrome_notification_types.h +++ b/chrome/browser/auth_notification_types.h
@@ -2,13 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROME_NOTIFICATION_TYPES_H_ -#define CHROME_BROWSER_CHROME_NOTIFICATION_TYPES_H_ +#ifndef CHROME_BROWSER_AUTH_NOTIFICATION_TYPES_H_ +#define CHROME_BROWSER_AUTH_NOTIFICATION_TYPES_H_ -#include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/notification_types.h" -#include "extensions/buildflags/buildflags.h" // ** // ** NOTICE @@ -24,16 +21,12 @@ namespace chrome { enum NotificationType { - NOTIFICATION_CHROME_START = content::NOTIFICATION_CONTENT_END, - - // Authentication ---------------------------------------------------------- - // This is sent when a login prompt is shown. The source is the // Source<NavigationController> for the tab in which the prompt is shown. // Details are a LoginNotificationDetails which provide the LoginHandler // that should be given authentication. // TODO(https://crbug.com/1174785): Remove. - NOTIFICATION_AUTH_NEEDED = NOTIFICATION_CHROME_START, + NOTIFICATION_AUTH_NEEDED = content::NOTIFICATION_CONTENT_END, // This is sent when authentication credentials have been supplied (either // by the user or by an automation service), but before we've actually @@ -52,13 +45,6 @@ // the LoginHandler that should be cancelled. // TODO(https://crbug.com/1174785): Remove. NOTIFICATION_AUTH_CANCELLED, - - // Misc -------------------------------------------------------------------- - // Note:- - // Currently only Content and Chrome define and use notifications. - // Custom notifications not belonging to Content and Chrome should start - // from here. - NOTIFICATION_CHROME_END, }; } // namespace chrome @@ -74,4 +60,4 @@ // ** Callback patterns. // ** -#endif // CHROME_BROWSER_CHROME_NOTIFICATION_TYPES_H_ +#endif // CHROME_BROWSER_AUTH_NOTIFICATION_TYPES_H_
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate_browsertest.cc b/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate_browsertest.cc index 5aa74b52..e6b730b 100644 --- a/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate_browsertest.cc +++ b/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate_browsertest.cc
@@ -244,7 +244,6 @@ void TearDownOnMainThread() override { fake_dlp_client_ = nullptr; - permission_context_.reset(); } // Executes `action` as JavaScript in the context of the opened website. The @@ -289,9 +288,38 @@ ui::SelectFileDialog::SetFactory(std::move(factory)); } + class PermissionContextHandle { + public: + PermissionContextHandle() = default; + + PermissionContextHandle( + content::BrowserContext* browser_context, + std::unique_ptr<TestFileSystemAccessPermissionContext> + permission_context) + : browser_context_(browser_context), + permission_context_(std::move(permission_context)) { + content::SetFileSystemAccessPermissionContext(browser_context_, + permission_context_.get()); + } + + ~PermissionContextHandle() { + if (browser_context_) { + content::SetFileSystemAccessPermissionContext(browser_context_, + nullptr); + } + } + + PermissionContextHandle(PermissionContextHandle&&) = default; + PermissionContextHandle& operator=(PermissionContextHandle&&) = default; + + private: + raw_ptr<content::BrowserContext> browser_context_; + std::unique_ptr<TestFileSystemAccessPermissionContext> permission_context_; + }; + // Setup a delegate to answer directory picker requests with a directory of a // specific file. If `createFile` is set the file is created. - void PrepareDirPicker(bool createFile) { + [[nodiscard]] PermissionContextHandle PrepareDirPicker(bool createFile) { base::FilePath file = tmp_.GetPath().AppendASCII(kTestFileName); if (createFile) { base::ScopedAllowBlockingForTesting allow_blocking; @@ -304,13 +332,13 @@ content::WebContents* const web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - permission_context_ = std::make_unique< + auto permission_context = std::make_unique< testing::NiceMock<TestFileSystemAccessPermissionContext>>( browser()->profile(), embedded_test_server()->GetOrigin(), file.DirName()); - content::SetFileSystemAccessPermissionContext( - web_contents->GetBrowserContext(), permission_context_.get()); + return PermissionContextHandle(web_contents->GetBrowserContext(), + std::move(permission_context)); } protected: @@ -320,7 +348,6 @@ std::unique_ptr<DlpScopedFileAccessDelegate> delegate_; base::ScopedTempDir tmp_; raw_ptr<chromeos::FakeDlpClient> fake_dlp_client_; - std::unique_ptr<TestFileSystemAccessPermissionContext> permission_context_; }; // These tests covers using the File API with dlp files. The parameter @@ -453,7 +480,8 @@ IN_PROC_BROWSER_TEST_F(DlpFileSystemAccessMoveTest, FileSystemAccessMoveProtectedAllow) { - PrepareDirPicker(/*createFile=*/true); + PermissionContextHandle permission_context_handle = + PrepareDirPicker(/*createFile=*/true); DlpScopedFileAccessDelegate::Initialize(base::BindLambdaForTesting( [this]() -> chromeos::DlpClient* { return fake_dlp_client_.get(); })); @@ -523,8 +551,9 @@ auto [isAllowed, directoryPicker, jsId] = GetParam(); fake_dlp_client_->SetFileAccessAllowed(isAllowed); + absl::optional<PermissionContextHandle> permission_context_handle; if (directoryPicker) { - PrepareDirPicker(/*createFile=*/true); + permission_context_handle = PrepareDirPicker(/*createFile=*/true); } else { PrepareFilePicker(/*createFile=*/true); } @@ -576,8 +605,9 @@ ::dlp::AddFilesResponse::default_instance())); fake_dlp_client_->SetAddFilesMock(request.Get()); + absl::optional<PermissionContextHandle> permission_context_handle; if (directoryPicker) { - PrepareDirPicker(/*createFile=*/false); + permission_context_handle = PrepareDirPicker(/*createFile=*/false); } else { PrepareFilePicker(/*createFile=*/false); }
diff --git a/chrome/browser/compose/chrome_compose_client.cc b/chrome/browser/compose/chrome_compose_client.cc index 41d341d..ed3b75c 100644 --- a/chrome/browser/compose/chrome_compose_client.cc +++ b/chrome/browser/compose/chrome_compose_client.cc
@@ -13,9 +13,10 @@ #include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" +#include "chrome/common/compose/type_conversions.h" #include "components/autofill/core/common/form_field_data.h" #include "components/compose/core/browser/compose_manager_impl.h" -#include "components/compose/proto/compose.pb.h" +#include "components/compose/proto/compose_metadata.pb.h" #include "components/optimization_guide/core/optimization_guide_features.h" #include "components/optimization_guide/core/optimization_guide_util.h" #include "content/public/browser/web_contents_user_data.h" @@ -51,7 +52,9 @@ auto* model_executor = GetModelExecutor(); DCHECK(model_executor) << "Unable to acquire model executor."; compose_proto::ComposeRequest request; - request.set_input(input); + request.set_user_input(input); + request.set_tone(ComposeTone(style->tone)); + request.set_length(ComposeLength(style->length)); model_executor->ExecuteModel( optimization_guide::proto::ModelExecutionFeature:: MODEL_EXECUTION_FEATURE_1,
diff --git a/chrome/browser/compose/chrome_compose_client_unittest.cc b/chrome/browser/compose/chrome_compose_client_unittest.cc index 3d4f5017..885c763 100644 --- a/chrome/browser/compose/chrome_compose_client_unittest.cc +++ b/chrome/browser/compose/chrome_compose_client_unittest.cc
@@ -15,7 +15,7 @@ #include "chrome/common/compose/compose.mojom.h" #include "chrome/test/base/browser_with_test_window_test.h" #include "components/compose/core/browser/compose_features.h" -#include "components/compose/proto/compose.pb.h" +#include "components/compose/proto/compose_metadata.pb.h" #include "components/optimization_guide/core/optimization_guide_features.h" #include "components/optimization_guide/core/optimization_guide_model_executor.h" #include "components/optimization_guide/proto/model_execution.pb.h"
diff --git a/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc b/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc index 55ed277a..6fa394d 100644 --- a/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc +++ b/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc
@@ -74,97 +74,6 @@ return true; } -bool GetValue(const base::Value& value, ImpressionEvent* event) { - if (!value.is_dict()) { - return false; - } - - const base::Value::List* impressions = - value.GetDict().FindList("impressions"); - if (!impressions) { - return false; - } - for (const auto& impression : *impressions) { - if (!impression.is_dict()) { - return false; - } - absl::optional<int> id = impression.GetDict().FindInt("id"); - absl::optional<int> type = impression.GetDict().FindInt("type"); - if (!id || !type) { - return false; - } - event->impressions.emplace_back(VisualElementImpression{*id, *type}); - - absl::optional<int> parent = impression.GetDict().FindInt("parent"); - if (parent) { - event->impressions.back().parent = *parent; - } - absl::optional<int> context = impression.GetDict().FindInt("context"); - if (context) { - event->impressions.back().context = *context; - } - } - return true; -} - -bool GetValue(const base::Value& value, ClickEvent* event) { - if (!value.is_dict()) { - return false; - } - - absl::optional<int> veid = value.GetDict().FindInt("veid"); - if (!veid) { - return false; - } - event->veid = *veid; - - absl::optional<int> mouse_button = value.GetDict().FindInt("mouseButton"); - if (mouse_button) { - event->mouse_button = *mouse_button; - } - absl::optional<int> context = value.GetDict().FindInt("context"); - if (context) { - event->context = *context; - } - return true; -} - -bool GetValue(const base::Value& value, ChangeEvent* event) { - if (!value.is_dict()) { - return false; - } - - absl::optional<int> veid = value.GetDict().FindInt("veid"); - if (!veid) { - return false; - } - event->veid = *veid; - - absl::optional<int> context = value.GetDict().FindInt("context"); - if (context) { - event->context = *context; - } - return true; -} - -bool GetValue(const base::Value& value, KeyDownEvent* event) { - if (!value.is_dict()) { - return false; - } - - absl::optional<int> veid = value.GetDict().FindInt("veid"); - if (!veid) { - return false; - } - event->veid = *veid; - - absl::optional<int> context = value.GetDict().FindInt("context"); - if (context) { - event->context = *context; - } - return true; -} - template <typename T> struct StorageTraits { using StorageType = T;
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc index a28c74f0..907efcb2 100644 --- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -29,8 +29,8 @@ #include "base/values.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" +#include "chrome/browser/auth_notification_types.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/devtools/protocol/devtools_protocol_test_support.h" #include "chrome/browser/devtools/url_constants.h" #include "chrome/browser/extensions/active_tab_permission_granter.h"
diff --git a/chrome/browser/file_system_access/file_system_access_tab_helper_browsertest.cc b/chrome/browser/file_system_access/file_system_access_tab_helper_browsertest.cc index 22f9f5b2..64210602 100644 --- a/chrome/browser/file_system_access/file_system_access_tab_helper_browsertest.cc +++ b/chrome/browser/file_system_access/file_system_access_tab_helper_browsertest.cc
@@ -12,6 +12,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" #include "content/public/test/prerender_test_util.h" #include "net/dns/mock_host_resolver.h" #include "testing/gtest/include/gtest/gtest.h" @@ -61,6 +62,10 @@ } void SetUpOnMainThread() override { + // Clear the permission context since setting the testing factory will + // destroy the current context outside of the normal shutdown sequence. + content::SetFileSystemAccessPermissionContext(browser()->profile(), + nullptr); FileSystemAccessPermissionContextFactory::GetInstance() ->SetTestingFactoryAndUse( browser()->profile(),
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index b385bb1..0796f4be 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -4283,11 +4283,6 @@ "expiry_milestone": 110 }, { - "name": "fedcm-account-auto-selected-flag", - "owners": [ "yigu", "web-identity-eng@google.com"], - "expiry_milestone": 125 - }, - { "name": "fedcm-authz", "owners": [ "goto", "web-identity-eng@google.com"], "expiry_milestone": 125 @@ -4303,6 +4298,11 @@ "expiry_milestone": 125 }, { + "name": "fedcm-identity-credential-auto-selected-flag", + "owners": [ "yigu", "web-identity-eng@google.com"], + "expiry_milestone": 125 + }, + { "name": "fedcm-idp-registration", "owners": [ "goto", "web-identity-eng@google.com"], "expiry_milestone": 125 @@ -6096,11 +6096,6 @@ "expiry_milestone": 120 }, { - "name": "omnibox-fuzzy-url-suggestions", - "owners": [ "orinj", "chrome-omnibox-team@google.com" ], - "expiry_milestone": 120 - }, - { "name": "omnibox-gm3-steady-state-background-color", "owners": [ "khalidpeer", "manukh", "chrome-omnibox-team@google.com" ], "expiry_milestone": 120
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 46bbc139..a13d967c 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1604,11 +1604,6 @@ "Enables fractional scroll offsets inside Blink, exposing non-integer " "offsets to web APIs."; -const char kFedCmAccountAutoSelectedFlagName[] = "FedCmAccountAutoSelectedFlag"; -const char kFedCmAccountAutoSelectedFlagDescription[] = - "Allows the browser to share whether an account was auto-selected with " - "developers post user permission to continue with the IdP."; - const char kFedCmAuthzName[] = "FedCmAuthz"; const char kFedCmAuthzDescription[] = "Enables RPs to request authorization for custom IdP scopes."; @@ -1622,6 +1617,13 @@ "Enables RPs to request only FedCM invocations to only show accounts " "matching a given hosted domain."; +const char kFedCmIdentityCredentialAutoSelectedFlagName[] = + "FedCmIdentityCredentialAutoSelectedFlag"; +const char kFedCmIdentityCredentialAutoSelectedFlagDescription[] = + "Allows the browser to share whether an identity credential was " + "auto-selected with developers post user permission to continue with the " + "IdP."; + const char kFedCmIdPRegistrationName[] = "FedCM with IdP Registration support"; const char kFedCmIdPRegistrationDescription[] = "Enables RPs to get identity credentials from registered IdPs."; @@ -2315,10 +2317,6 @@ "If enabled, history URL suggestions from hosts visited often bypass the " "per provider limit."; -const char kOmniboxFuzzyUrlSuggestionsName[] = "Omnibox Fuzzy URL Suggestions"; -const char kOmniboxFuzzyUrlSuggestionsDescription[] = - "Enables URL suggestions for inputs that may contain typos."; - const char kOmniboxGM3SteadyStateBackgroundColorName[] = "Omnibox Steady State Background Color"; const char kOmniboxGM3SteadyStateBackgroundColorDescription[] = @@ -4299,9 +4297,10 @@ const char kShowNtpAtStartupAndroidDescription[] = "Enable showing a NewTabPage at startup after leaving Chrome for a while."; -const char kShowScrollableMVTOnNTPAndroidName[] = "Show scrollable MVT on NTP"; +const char kShowScrollableMVTOnNTPAndroidName[] = + "Show scrollable MVT on NTP on tablets"; const char kShowScrollableMVTOnNTPAndroidDescription[] = - "Enable showing the scrollable most visited tiles on NTP."; + "Enable showing the scrollable most visited tiles on NTP on tablets."; const char kSecurePaymentConfirmationAndroidName[] = "Secure Payment Confirmation on Android";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index b206e61..e5ef60c 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -913,9 +913,6 @@ extern const char kFractionalScrollOffsetsName[]; extern const char kFractionalScrollOffsetsDescription[]; -extern const char kFedCmAccountAutoSelectedFlagName[]; -extern const char kFedCmAccountAutoSelectedFlagDescription[]; - extern const char kFedCmAuthzName[]; extern const char kFedCmAuthzDescription[]; @@ -925,6 +922,9 @@ extern const char kFedCmHostedDomainName[]; extern const char kFedCmHostedDomainDescription[]; +extern const char kFedCmIdentityCredentialAutoSelectedFlagName[]; +extern const char kFedCmIdentityCredentialAutoSelectedFlagDescription[]; + extern const char kFedCmIdPRegistrationName[]; extern const char kFedCmIdPRegistrationDescription[]; @@ -1337,9 +1337,6 @@ extern const char kOmniboxDomainSuggestionsName[]; extern const char kOmniboxDomainSuggestionsDescription[]; -extern const char kOmniboxFuzzyUrlSuggestionsName[]; -extern const char kOmniboxFuzzyUrlSuggestionsDescription[]; - extern const char kOmniboxGM3SteadyStateBackgroundColorName[]; extern const char kOmniboxGM3SteadyStateBackgroundColorDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 1e4aaeb..09814ac0 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -306,6 +306,7 @@ &kSearchEnginesPromoV3, &kShowNtpAtStartupAndroid, &kShowScrollableMVTOnNTPAndroid, + &kShowScrollableMVTOnNtpPhoneAndroid, &kFeedPositionAndroid, &kSearchResumptionModuleAndroid, &kScrollToTLDOptimization, @@ -1011,6 +1012,10 @@ BASE_FEATURE(kShowScrollableMVTOnNTPAndroid, "ShowScrollableMVTOnNTPAndroid", + base::FEATURE_ENABLED_BY_DEFAULT); + +BASE_FEATURE(kShowScrollableMVTOnNtpPhoneAndroid, + "ShowScrollableMVTOnNtpPhoneAndroid", base::FEATURE_DISABLED_BY_DEFAULT); BASE_FEATURE(kShareSheetCustomActionsPolish, @@ -1120,7 +1125,7 @@ BASE_FEATURE(kStartSurfaceOnTablet, "StartSurfaceOnTablet", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kStartSurfaceSpareTab, "StartSurfaceSpareTab",
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index 1aff6813..270608d 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -172,6 +172,7 @@ BASE_DECLARE_FEATURE(kSharingHubLinkToggle); BASE_DECLARE_FEATURE(kShowNtpAtStartupAndroid); BASE_DECLARE_FEATURE(kShowScrollableMVTOnNTPAndroid); +BASE_DECLARE_FEATURE(kShowScrollableMVTOnNtpPhoneAndroid); BASE_DECLARE_FEATURE(kFeedPositionAndroid); BASE_DECLARE_FEATURE(kScrollToTLDOptimization); BASE_DECLARE_FEATURE(kSearchResumptionModuleAndroid);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index f6430cf..0aebb7a 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -431,8 +431,10 @@ public static final String SHARE_SHEET_MIGRATION_ANDROID = "ShareSheetMigrationAndroid"; public static final String SEND_TAB_TO_SELF_V2 = "SendTabToSelfV2"; public static final String SHOPPING_LIST = "ShoppingList"; - public static final String SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID = "ShowScrollableMVTOnNTPAndroid"; public static final String SHOW_NTP_AT_STARTUP_ANDROID = "ShowNtpAtStartupAndroid"; + public static final String SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID = "ShowScrollableMVTOnNTPAndroid"; + public static final String SHOW_SCROLLABLE_MVT_ON_NTP_PHONE_ANDROID = + "ShowScrollableMVTOnNtpPhoneAndroid"; public static final String SMART_SUGGESTION_FOR_LARGE_DOWNLOADS = "SmartSuggestionForLargeDownloads"; public static final String SPARE_TAB = "SpareTab"; @@ -613,7 +615,7 @@ public static final CachedFlag sStartSurfaceDisabledFeedImprovement = new CachedFlag(START_SURFACE_DISABLED_FEED_IMPROVEMENT, false); public static final CachedFlag sStartSurfaceOnTablet = - new CachedFlag(START_SURFACE_ON_TABLET, false); + new CachedFlag(START_SURFACE_ON_TABLET, true); public static final CachedFlag sStartSurfaceRefactor = new CachedFlag(START_SURFACE_REFACTOR, false); public static final CachedFlag sStartSurfaceReturnTime =
diff --git a/chrome/browser/hub/internal/BUILD.gn b/chrome/browser/hub/internal/BUILD.gn index 78306401..4d08168 100644 --- a/chrome/browser/hub/internal/BUILD.gn +++ b/chrome/browser/hub/internal/BUILD.gn
@@ -5,8 +5,8 @@ import("//build/config/android/rules.gni") android_library("java") { + resources_package = "org.chromium.chrome.browser.hub" visibility = [ "//chrome/android:*" ] - sources = [ "android/java/src/org/chromium/chrome/browser/hub/DelegateButtonData.java", "android/java/src/org/chromium/chrome/browser/hub/HubCoordinator.java", @@ -25,8 +25,8 @@ "android/java/src/org/chromium/chrome/browser/hub/PaneManagerImpl.java", "android/java/src/org/chromium/chrome/browser/hub/ResourceButtonData.java", ] - deps = [ + ":java_resources", "//base:base_java", "//chrome/browser/hub:java", "//components/browser_ui/widget/android:java", @@ -37,17 +37,22 @@ ] } +android_resources("java_resources") { + sources = [ "android/res/layout/hub_layout.xml" ] +} + robolectric_library("junit") { resources_package = "org.chromium.chrome.browser.hub" sources = [ "android/java/src/org/chromium/chrome/browser/hub/DelegateButtonDataUnitTest.java", + "android/java/src/org/chromium/chrome/browser/hub/HubCoordinatorUnitTest.java", "android/java/src/org/chromium/chrome/browser/hub/HubManagerImplUnitTest.java", "android/java/src/org/chromium/chrome/browser/hub/PaneManagerImplUnitTest.java", "android/java/src/org/chromium/chrome/browser/hub/ResourceButtonDataUnitTest.java", ] - deps = [ ":java", + ":java_resources", "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support",
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubCoordinator.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubCoordinator.java index 20a8fa9..55bf1df 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubCoordinator.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubCoordinator.java
@@ -4,6 +4,9 @@ package org.chromium.chrome.browser.hub; +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; import android.widget.FrameLayout; /** @@ -13,6 +16,9 @@ */ public class HubCoordinator { private final FrameLayout mContainerView; + private final View mMainHubParent; + private final HubToolbarCoordinator mHubToolbarCoordinator; + private final HubPaneHostCoordinator mHubPaneHostCoordinator; /** * Creates the {@link HubCoordinator}. @@ -20,8 +26,22 @@ * @param containerView The view to attach the Hub to. */ public HubCoordinator(FrameLayout containerView) { + Context context = containerView.getContext(); mContainerView = containerView; + mMainHubParent = LayoutInflater.from(context).inflate(R.layout.hub_layout, null); + mContainerView.addView(mMainHubParent); + + HubToolbarView hubToolbarView = mContainerView.findViewById(R.id.hub_toolbar); + mHubToolbarCoordinator = new HubToolbarCoordinator(hubToolbarView); + + HubPaneHostView hubPaneHostView = mContainerView.findViewById(R.id.hub_pane_host); + mHubPaneHostCoordinator = new HubPaneHostCoordinator(hubPaneHostView); } - public void destroy() {} + /** Removes the hub from the layout tree and cleans up resources. */ + public void destroy() { + mContainerView.removeView(mMainHubParent); + mHubToolbarCoordinator.destroy(); + mHubPaneHostCoordinator.destroy(); + } }
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubCoordinatorUnitTest.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubCoordinatorUnitTest.java new file mode 100644 index 0000000..4f3a1de --- /dev/null +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubCoordinatorUnitTest.java
@@ -0,0 +1,51 @@ +// Copyright 2023 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.hub; + +import android.widget.FrameLayout; + +import androidx.test.ext.junit.rules.ActivityScenarioRule; +import androidx.test.filters.SmallTest; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.ui.base.TestActivity; + +/** Tests for {@link HubCoordinator}. */ +@RunWith(BaseRobolectricTestRunner.class) +public class HubCoordinatorUnitTest { + public @Rule MockitoRule mMockitoRule = MockitoJUnit.rule(); + public @Rule ActivityScenarioRule<TestActivity> mActivityScenarioRule = + new ActivityScenarioRule<>(TestActivity.class); + + private FrameLayout mRootView; + + @Before + public void setUp() { + mActivityScenarioRule.getScenario().onActivity(this::onActivity); + } + + private void onActivity(TestActivity activity) { + mRootView = new FrameLayout(activity); + activity.setContentView(mRootView); + } + + @Test + @SmallTest + public void testCreateAndDestroy() { + HubCoordinator hubCoordinator = new HubCoordinator(mRootView); + mRootView.getChildCount(); + Assert.assertNotEquals(0, mRootView.getChildCount()); + hubCoordinator.destroy(); + Assert.assertEquals(0, mRootView.getChildCount()); + } +}
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubPaneHostCoordinator.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubPaneHostCoordinator.java index fe95c04..a6f8696 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubPaneHostCoordinator.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubPaneHostCoordinator.java
@@ -4,8 +4,6 @@ package org.chromium.chrome.browser.hub; -import android.content.Context; -import android.view.View; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; @@ -13,21 +11,14 @@ /** Sets up the component that holds a single pane at a time in the Hub. */ public class HubPaneHostCoordinator { private final HubPaneHostMediator mMediator; - private final HubPaneHostView mView; /** Eagerly creates the component, but will not be rooted in the view tree yet. */ - public HubPaneHostCoordinator(Context context) { + public HubPaneHostCoordinator(HubPaneHostView hubPaneHostView) { PropertyModel model = new PropertyModel.Builder(HubPaneHostProperties.ALL_KEYS).build(); - mView = new HubPaneHostView(context); - PropertyModelChangeProcessor.create(model, mView, HubPaneHostViewBinder::bind); + PropertyModelChangeProcessor.create(model, hubPaneHostView, HubPaneHostViewBinder::bind); mMediator = new HubPaneHostMediator(model); } - /** Returns the top level view for this component that caller can add to the view tree. */ - public View getView() { - return mView; - } - /** Cleans up observers and resources. */ public void destroy() { mMediator.destroy();
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubPaneHostView.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubPaneHostView.java index 626efe9..1a75ae1 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubPaneHostView.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubPaneHostView.java
@@ -5,13 +5,14 @@ package org.chromium.chrome.browser.hub; import android.content.Context; +import android.util.AttributeSet; import android.view.View; import android.widget.FrameLayout; /** Holds the current pane's {@link View}. */ public class HubPaneHostView extends FrameLayout { - /** Default {@link FrameLayout} constructor. */ - public HubPaneHostView(Context context) { - super(context); + /** Default {@link FrameLayout} constructor called by inflation. */ + public HubPaneHostView(Context context, AttributeSet attributeSet) { + super(context, attributeSet); } }
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarCoordinator.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarCoordinator.java index b2a5aee..46a8df8 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarCoordinator.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarCoordinator.java
@@ -4,8 +4,6 @@ package org.chromium.chrome.browser.hub; -import android.content.Context; -import android.view.View; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; @@ -13,21 +11,14 @@ /** Sets up the component that handles the toolbar of the Hub. */ public class HubToolbarCoordinator { private final HubToolbarMediator mMediator; - private final HubToolbarView mView; /** Eagerly creates the component, but will not be rooted in the view tree yet. */ - public HubToolbarCoordinator(Context context) { + public HubToolbarCoordinator(HubToolbarView hubToolbarView) { PropertyModel model = new PropertyModel.Builder(HubToolbarProperties.ALL_KEYS).build(); - mView = new HubToolbarView(context); - PropertyModelChangeProcessor.create(model, mView, HubToolbarViewBinder::bind); + PropertyModelChangeProcessor.create(model, hubToolbarView, HubToolbarViewBinder::bind); mMediator = new HubToolbarMediator(model); } - /** Returns the top level view for this component that caller can add to the view tree. */ - public View getView() { - return mView; - } - /** Cleans up observers and resources. */ public void destroy() { mMediator.destroy();
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarView.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarView.java index 9a1facf..0f603d6 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarView.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarView.java
@@ -5,12 +5,13 @@ package org.chromium.chrome.browser.hub; import android.content.Context; +import android.util.AttributeSet; import android.widget.LinearLayout; /** Toolbar for the Hub. May contain a single or multiple rows, of which this view is the parent. */ public class HubToolbarView extends LinearLayout { - /** Default {@link LinearLayout} constructor. */ - public HubToolbarView(Context context) { - super(context); + /** Default {@link LinearLayout} constructor called by inflation. */ + public HubToolbarView(Context context, AttributeSet attributeSet) { + super(context, attributeSet); } }
diff --git a/chrome/browser/hub/internal/android/res/layout/hub_layout.xml b/chrome/browser/hub/internal/android/res/layout/hub_layout.xml new file mode 100644 index 0000000..ea901d8f --- /dev/null +++ b/chrome/browser/hub/internal/android/res/layout/hub_layout.xml
@@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright 2023 The Chromium Authors +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <org.chromium.chrome.browser.hub.HubToolbarView + android:id="@+id/hub_toolbar" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + <org.chromium.chrome.browser.hub.HubPaneHostView + android:id="@+id/hub_pane_host" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + +</LinearLayout> \ No newline at end of file
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc index 1566381..1642afd 100644 --- a/chrome/browser/net/profile_network_context_service.cc +++ b/chrome/browser/net/profile_network_context_service.cc
@@ -1017,6 +1017,10 @@ } network_context_params->afp_block_list_experiment_enabled = + (base::FeatureList::IsEnabled( + features:: + kEnableNetworkServiceResourceBlockListIfThirdPartyCookiesBlocked) && + cookie_settings_->ShouldBlockThirdPartyCookies()) || (!profile_->IsOffTheRecord() && base::FeatureList::IsEnabled( features::kEnableNetworkServiceResourceBlockList)) ||
diff --git a/chrome/browser/net/profile_network_context_service_browsertest.cc b/chrome/browser/net/profile_network_context_service_browsertest.cc index 86c8bbaa..b2160b69 100644 --- a/chrome/browser/net/profile_network_context_service_browsertest.cc +++ b/chrome/browser/net/profile_network_context_service_browsertest.cc
@@ -14,6 +14,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/functional/bind.h" #include "base/memory/raw_ptr.h" +#include "base/memory/scoped_refptr.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" @@ -56,6 +57,7 @@ #include "components/privacy_sandbox/privacy_sandbox_features.h" #include "components/privacy_sandbox/privacy_sandbox_settings.h" #include "components/privacy_sandbox/privacy_sandbox_test_util.h" +#include "components/user_prefs/user_prefs.h" #include "content/public/browser/network_service_instance.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/content_features.h" @@ -96,6 +98,12 @@ ~ProfileNetworkContextServiceBrowsertest() override = default; + // TODO(crbug.com/1491942): This fails with the field trial testing config. + void SetUpCommandLine(base::CommandLine* command_line) override { + InProcessBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitch("disable-field-trial-config"); + } + void SetUpOnMainThread() override { EXPECT_TRUE(embedded_test_server()->Start()); loader_factory_ = browser() @@ -868,3 +876,67 @@ EXPECT_TRUE(content::WaitForLoadStop(GetActiveWebContents())); EXPECT_EQ(false, EvalJs(GetActiveWebContents(), command)); } + +class ProfileNetworkContextServiceResourceBlocklistBrowsertest + : public ProfileNetworkContextServiceBrowsertest { + public: + void SetUp() override { + scoped_feature_list_.InitAndEnableFeature( + features:: + kEnableNetworkServiceResourceBlockListIfThirdPartyCookiesBlocked); + ProfileNetworkContextServiceBrowsertest::SetUp(); + } + + content::WebContents* GetActiveWebContents() { + return chrome_test_utils::GetActiveWebContents(this); + } + + PrefService* GetPrefs() { + return user_prefs::UserPrefs::Get( + GetActiveWebContents()->GetBrowserContext()); + } + + protected: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +// Test that with +// kEnableNetworkServiceResourceBlockListIfThirdPartyCookiesBlocked enabled, the +// anti-fingerprinting blocklist is not enabled if third party cookies are +// allowed. +IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceResourceBlocklistBrowsertest, + ThirdPartyCookiesAllowed) { + ProfileNetworkContextService* profile_network_context_service = + ProfileNetworkContextServiceFactory::GetForContext(browser()->profile()); + base::FilePath empty_relative_partition_path; + network::mojom::NetworkContextParams network_context_params; + cert_verifier::mojom::CertVerifierCreationParams + cert_verifier_creation_params; + profile_network_context_service->ConfigureNetworkContextParams( + /*in_memory=*/false, empty_relative_partition_path, + &network_context_params, &cert_verifier_creation_params); + + EXPECT_FALSE(network_context_params.afp_block_list_experiment_enabled); +} + +// Test that with +// kEnableNetworkServiceResourceBlockListIfThirdPartyCookiesBlocked enabled, the +// anti-fingerprinting blocklist is enabled if third party cookies are blocked. +IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceResourceBlocklistBrowsertest, + ThirdPartyCookiesBlocked) { + GetPrefs()->SetInteger( + prefs::kCookieControlsMode, + static_cast<int>(content_settings::CookieControlsMode::kBlockThirdParty)); + + ProfileNetworkContextService* profile_network_context_service = + ProfileNetworkContextServiceFactory::GetForContext(browser()->profile()); + base::FilePath empty_relative_partition_path; + network::mojom::NetworkContextParams network_context_params; + cert_verifier::mojom::CertVerifierCreationParams + cert_verifier_creation_params; + profile_network_context_service->ConfigureNetworkContextParams( + /*in_memory=*/false, empty_relative_partition_path, + &network_context_params, &cert_verifier_creation_params); + + EXPECT_TRUE(network_context_params.afp_block_list_experiment_enabled); +}
diff --git a/chrome/browser/net/proxy_browsertest.cc b/chrome/browser/net/proxy_browsertest.cc index a06498a..434812e3 100644 --- a/chrome/browser/net/proxy_browsertest.cc +++ b/chrome/browser/net/proxy_browsertest.cc
@@ -12,7 +12,7 @@ #include "base/test/bind.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" -#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/auth_notification_types.h" #include "chrome/browser/net/proxy_test_utils.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h"
diff --git a/chrome/browser/net/websocket_browsertest.cc b/chrome/browser/net/websocket_browsertest.cc index 0dd37db..9946df9 100644 --- a/chrome/browser/net/websocket_browsertest.cc +++ b/chrome/browser/net/websocket_browsertest.cc
@@ -19,7 +19,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/bind.h" #include "build/build_config.h" -#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/auth_notification_types.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/login/login_handler.h"
diff --git a/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc b/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc index cc80c5e..9441ac64 100644 --- a/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc +++ b/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc
@@ -222,6 +222,12 @@ } ~PageContentAnnotationsServiceBrowserTest() override = default; + // TODO(crbug.com/1491942): This fails with the field trial testing config. + void SetUpCommandLine(base::CommandLine* command_line) override { + InProcessBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitch("disable-field-trial-config"); + } + void set_load_model_on_startup(bool load_model_on_startup) { load_model_on_startup_ = load_model_on_startup; }
diff --git a/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc b/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc index a0e0606..b43d61d4 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc
@@ -432,6 +432,8 @@ command_line->AppendSwitch( ash::switches::kIgnoreUserProfileMappingForTests); #endif + // TODO(crbug.com/1491942): This fails with the field trial testing config. + command_line->AppendSwitch("disable-field-trial-config"); } void TearDownOnMainThread() override {
diff --git a/chrome/browser/policy/chrome_browser_policy_connector.cc b/chrome/browser/policy/chrome_browser_policy_connector.cc index bf03f3d..63471ea 100644 --- a/chrome/browser/policy/chrome_browser_policy_connector.cc +++ b/chrome/browser/policy/chrome_browser_policy_connector.cc
@@ -330,7 +330,7 @@ base::ThreadPool::CreateSequencedTaskRunner( {base::MayBlock(), base::TaskPriority::BEST_EFFORT}), policy::PolicyLoaderMac::GetManagedPolicyPath(bundle_id), - new MacPreferences(), bundle_id); + std::make_unique<MacPreferences>(), bundle_id); return std::make_unique<AsyncPolicyProvider>(GetSchemaRegistry(), std::move(loader)); #elif BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java index 0782fec..50b5e0e 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -904,9 +904,9 @@ public static final String UI_THEME_SETTING = "ui_theme_setting"; // Diagnostic counters for short sessions; see histogram - // UMA.PreNative.ChromeActivityCounter. - public static final String UMA_ON_PRECREATE_COUNTER = "Chrome.UMA.OnPreCreateCounter"; - public static final String UMA_ON_RESUME_COUNTER = "Chrome.UMA.OnResumeCounter"; + // UMA.PreNative.ChromeActivityCounter2. + public static final String UMA_ON_POSTCREATE_COUNTER = "Chrome.UMA.OnPostCreateCounter2"; + public static final String UMA_ON_RESUME_COUNTER = "Chrome.UMA.OnResumeCounter2"; public static final String VERIFIED_DIGITAL_ASSET_LINKS = "verified_digital_asset_links"; @@ -1105,15 +1105,14 @@ SWAA_STATUS, TABBED_ACTIVITY_LAST_VISIBLE_TIME_MS, TWA_DISCLOSURE_SEEN_PACKAGES, - UMA_ON_PRECREATE_COUNTER, + UMA_ON_POSTCREATE_COUNTER, UMA_ON_RESUME_COUNTER, USB_NOTIFICATION_IDS, USER_ENABLED_DESKTOP_SITE_GLOBAL_SETTING_PREFERENCE_KEY, WEB_FEED_INTRO_LAST_SHOWN_TIME_MS, WEB_FEED_INTRO_WEB_FEED_ID_SHOWN_TIME_MS_PREFIX.pattern(), WEB_FEED_INTRO_WEB_FEED_ID_SHOWN_COUNT_PREFIX.pattern(), - WEB_SIGNIN_ACCOUNT_PICKER_ACTIVE_DISMISSAL_COUNT - ); + WEB_SIGNIN_ACCOUNT_PICKER_ACTIVE_DISMISSAL_COUNT); // clang-format on }
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/DeprecatedChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/DeprecatedChromePreferenceKeys.java index 9f6bc67..ce231c2 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/DeprecatedChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/DeprecatedChromePreferenceKeys.java
@@ -51,6 +51,8 @@ "Chrome.RequestDesktopSiteGlobalSetting.DefaultEnabledShowMessage", "Chrome.RequestDesktopSiteGlobalSetting.OptInMessageShown", "Chrome.SigninPromo.NTPImpressions", + "Chrome.UMA.OnPreCreateCounter", + "Chrome.UMA.OnResumeCounter", "Chrome.VideoTutorials.ShareUrls", "LocaleManager_USR_TYPE", "PersistedNotificationId", @@ -150,8 +152,7 @@ "swap_pixel_format_to_fix_convert_from_translucent", "tab_persistent_store_task_runner_enabled", "webapk_number_of_uninstalls", - "website_settings_filter" - ); + "website_settings_filter"); // clang-format on }
diff --git a/chrome/browser/printing/print_backend_service_manager.cc b/chrome/browser/printing/print_backend_service_manager.cc index 89dd580f..38a5109d 100644 --- a/chrome/browser/printing/print_backend_service_manager.cc +++ b/chrome/browser/printing/print_backend_service_manager.cc
@@ -163,7 +163,7 @@ void PrintBackendServiceManager::UnregisterClient(ClientId id) { // Determine which client type has this ID, and remove it once found. absl::optional<ClientType> client_type; - RemoteId remote_id = GetRemoteIdForPrinterName(kEmptyPrinterName); + absl::optional<RemoteId> remote_id; if (query_clients_.erase(id) != 0) { client_type = ClientType::kQuery; } else if (query_with_ui_clients_.erase(id) != 0) { @@ -189,11 +189,14 @@ << ClientTypeToString(client_type.value()) << ") from print backend service."; + if (!remote_id.has_value()) { + remote_id = GetRemoteIdForPrinterName(kEmptyPrinterName); + } absl::optional<base::TimeDelta> new_timeout = DetermineIdleTimeoutUpdateOnUnregisteredClient(client_type.value(), - remote_id); + remote_id.value()); if (new_timeout.has_value()) - UpdateServiceIdleTimeoutByRemoteId(remote_id, new_timeout.value()); + UpdateServiceIdleTimeoutByRemoteId(remote_id.value(), new_timeout.value()); #if BUILDFLAG(IS_WIN) if (base::FeatureList::IsEnabled(features::kReadPrinterCapabilitiesWithXps) && @@ -639,11 +642,9 @@ return iter->second; } - // No remote yet for this printer so make one. RemoteId is only used within - // browse process management code, so a simple incrementing sequence is - // sufficient. - static uint32_t id_sequence = 0; - return remote_id_map_.insert({printer_name, RemoteId(++id_sequence)}) + // No remote yet for this printer so make one. + return remote_id_map_ + .insert({printer_name, RemoteId(++remote_id_sequence_)}) .first->second; } #endif @@ -807,16 +808,13 @@ // On the first print that will try to use sandboxed service, make note that // so far no drivers have been discovered to require fallback beyond any // predetermined known cases. - static bool first_sandboxed_print = true; - if (first_sandboxed_print) { - first_sandboxed_print = false; + if (first_sandboxed_print_) { + first_sandboxed_print_ = false; base::UmaHistogramBoolean( kPrintBackendRequiresElevatedPrivilegeHistogramName, /*sample=*/false); } - } - if (sandboxed) { return GetServiceFromBundle(remote_id, client_type, /*sandboxed=*/true, sandboxed_remotes_bundles_); }
diff --git a/chrome/browser/printing/print_backend_service_manager.h b/chrome/browser/printing/print_backend_service_manager.h index 9b5d134..d166def 100644 --- a/chrome/browser/printing/print_backend_service_manager.h +++ b/chrome/browser/printing/print_backend_service_manager.h
@@ -689,6 +689,10 @@ RemoteSavedCancelCallbacks sandboxed_saved_cancel_callbacks_; RemoteSavedCancelCallbacks unsandboxed_saved_cancel_callbacks_; + // Gets set to false once there has been at least one attempt to print using + // a sandboxed PrintBackend service. Used for metrics reporting. + bool first_sandboxed_print_ = true; + // Set of printer drivers which require elevated permissions to operate. // It is expected that most print drivers will succeed with the preconfigured // sandbox permissions. Should any drivers be discovered to require more than @@ -703,6 +707,11 @@ base::flat_map<std::string, RemoteId> remote_id_map_; #endif + // Used as base for generating `RemoteId` values. Only used internally + // within browser process management code, so a simple incrementating + // sequence is sufficient. + uint32_t remote_id_sequence_ = 0; + // Crash key is kept at class level so that we can obtain printer driver // information for a prior call should the process be terminated due to Mojo // message response validation.
diff --git a/chrome/browser/privacy_sandbox/tracking_protection_settings_browsertest.cc b/chrome/browser/privacy_sandbox/tracking_protection_settings_browsertest.cc index a277e98..54147d7 100644 --- a/chrome/browser/privacy_sandbox/tracking_protection_settings_browsertest.cc +++ b/chrome/browser/privacy_sandbox/tracking_protection_settings_browsertest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/test/metrics/histogram_tester.h" #include "chrome/browser/privacy_sandbox/tracking_protection_settings_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" @@ -16,6 +17,18 @@ #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" +class TrackingProtectionSettingsMetricsBrowserTest + : public InProcessBrowserTest { + protected: + base::HistogramTester histogram_tester_; +}; + +IN_PROC_BROWSER_TEST_F(TrackingProtectionSettingsMetricsBrowserTest, + RecordsMetricsOnStartup) { + histogram_tester_.ExpectUniqueSample("Settings.TrackingProtection.Enabled", + false, 1); +} + class TrackingProtectionSettingsForEnterpriseBrowserTest : public InProcessBrowserTest, public testing::WithParamInterface<bool> { @@ -41,11 +54,6 @@ } } - privacy_sandbox::TrackingProtectionSettings* tracking_protection_settings() { - return TrackingProtectionSettingsFactory::GetForProfile( - browser()->profile()); - } - protected: testing::NiceMock<policy::MockConfigurationPolicyProvider> policy_provider_; bool enterprise_managed_;
diff --git a/chrome/browser/privacy_sandbox/tracking_protection_settings_factory.cc b/chrome/browser/privacy_sandbox/tracking_protection_settings_factory.cc index 819bc160..945c081 100644 --- a/chrome/browser/privacy_sandbox/tracking_protection_settings_factory.cc +++ b/chrome/browser/privacy_sandbox/tracking_protection_settings_factory.cc
@@ -4,10 +4,14 @@ #include "chrome/browser/privacy_sandbox/tracking_protection_settings_factory.h" +#include "base/metrics/histogram_functions.h" #include "base/no_destructor.h" +#include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/privacy_sandbox/tracking_protection_onboarding_factory.h" #include "chrome/browser/profiles/profile.h" #include "components/keyed_service/core/keyed_service.h" +#include "components/prefs/pref_service.h" +#include "components/privacy_sandbox/tracking_protection_prefs.h" #include "components/privacy_sandbox/tracking_protection_settings.h" TrackingProtectionSettingsFactory* @@ -40,6 +44,23 @@ content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); + bool should_record_metrics = profile->IsRegularProfile(); +#if BUILDFLAG(IS_CHROMEOS_ASH) + should_record_metrics = + should_record_metrics && ash::ProfileHelper::IsUserProfile(profile); +#endif + if (should_record_metrics) { + if (profile->GetPrefs()->GetBoolean( + prefs::kTrackingProtection3pcdEnabled)) { + base::UmaHistogramBoolean("Settings.TrackingProtection.Enabled", true); + base::UmaHistogramBoolean( + "Settings.TrackingProtection.BlockAllThirdParty", + profile->GetPrefs()->GetBoolean(prefs::kBlockAll3pcToggleEnabled)); + } else { + base::UmaHistogramBoolean("Settings.TrackingProtection.Enabled", false); + } + } + return std::make_unique<privacy_sandbox::TrackingProtectionSettings>( profile->GetPrefs(), TrackingProtectionOnboardingFactory::GetForProfile(profile));
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 c53819f5..94b5256 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
@@ -2134,9 +2134,19 @@ IDC_CONTENT_CONTEXT_INSPECTELEMENT})); } +// TODO(crbug.com/1491942): This fails with the field trial testing config. +class ContextMenuFencedFrameTestNoTestingConfig + : public ContextMenuFencedFrameTest { + public: + void SetUpCommandLine(base::CommandLine* command_line) override { + ContextMenuFencedFrameTest::SetUpCommandLine(command_line); + command_line->AppendSwitch("disable-field-trial-config"); + } +}; + // Test that automatic beacons are sent after clicking "Open Link in New Tab" // from a contextual menu inside of a fenced frame. -IN_PROC_BROWSER_TEST_F(ContextMenuFencedFrameTest, +IN_PROC_BROWSER_TEST_F(ContextMenuFencedFrameTestNoTestingConfig, AutomaticBeaconSentAfterContextMenuNavigation) { privacy_sandbox::ScopedPrivacySandboxAttestations scoped_attestations( privacy_sandbox::PrivacySandboxAttestations::CreateForTesting());
diff --git a/chrome/browser/repost_form_warning_browsertest.cc b/chrome/browser/repost_form_warning_browsertest.cc index 727862ab..2cc8fdac 100644 --- a/chrome/browser/repost_form_warning_browsertest.cc +++ b/chrome/browser/repost_form_warning_browsertest.cc
@@ -4,7 +4,7 @@ #include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/auth_notification_types.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/test/test_browser_dialog.h"
diff --git a/chrome/browser/resources/ash/settings/os_about_page/update_warning_dialog.html b/chrome/browser/resources/ash/settings/os_about_page/update_warning_dialog.html index dc6617a..95bec69 100644 --- a/chrome/browser/resources/ash/settings/os_about_page/update_warning_dialog.html +++ b/chrome/browser/resources/ash/settings/os_about_page/update_warning_dialog.html
@@ -1,8 +1,8 @@ <style include="settings-shared"></style> -<cr-dialog id="dialog" close-text="$i18n{close}"> +<cr-dialog id="dialog" close-text="$i18n{close}" show-on-attach> <div slot="title">$i18n{aboutUpdateWarningTitle}</div> <div slot="body"> - <div id="update-warning-message"></div> + [[warningMessage_]] </div> <div slot="button-container"> <cr-button id="cancel" class="cancel-button"
diff --git a/chrome/browser/resources/ash/settings/os_about_page/update_warning_dialog.ts b/chrome/browser/resources/ash/settings/os_about_page/update_warning_dialog.ts index abb41fba..10e39d5b 100644 --- a/chrome/browser/resources/ash/settings/os_about_page/update_warning_dialog.ts +++ b/chrome/browser/resources/ash/settings/os_about_page/update_warning_dialog.ts
@@ -15,8 +15,6 @@ import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {castExists} from '../assert_extras.js'; - import {AboutPageBrowserProxy, AboutPageBrowserProxyImpl, AboutPageUpdateInfo} from './about_page_browser_proxy.js'; import {getTemplate} from './update_warning_dialog.html.js'; @@ -42,7 +40,12 @@ return { updateInfo: { type: Object, - observer: 'updateInfoChanged_', + observer: 'onUpdateInfoChanged_', + }, + + warningMessage_: { + type: String, + value: '', }, }; } @@ -50,6 +53,7 @@ updateInfo?: AboutPageUpdateInfo; private browserProxy_: AboutPageBrowserProxy; + private warningMessage_: string; constructor() { super(); @@ -57,12 +61,6 @@ this.browserProxy_ = AboutPageBrowserProxyImpl.getInstance(); } - override connectedCallback(): void { - super.connectedCallback(); - - this.$.dialog.showModal(); - } - private onCancelClick_(): void { this.$.dialog.close(); } @@ -77,15 +75,13 @@ this.$.dialog.close(); } - private updateInfoChanged_(): void { + private onUpdateInfoChanged_(): void { if (!this.updateInfo || this.updateInfo.size === undefined) { console.warn('ERROR: Update size is undefined'); return; } - const warningMessage = - castExists(this.shadowRoot!.getElementById('update-warning-message')); - warningMessage.innerHTML = this.i18n( + this.warningMessage_ = this.i18n( 'aboutUpdateWarningMessage', // Convert bytes to megabytes Math.floor(Number(this.updateInfo.size) / (1024 * 1024)));
diff --git a/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts b/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts index 4a8d08dc..c345e758 100644 --- a/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts +++ b/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts
@@ -563,11 +563,9 @@ } private getListingFilesDialogBody_(): string { - return this.listedFiles_ > 0n ? - this.i18n( - 'googleDriveFileSyncListingFilesItemsFoundBody', - this.listedFiles_.toLocaleString()) : - this.i18n('googleDriveFileSyncListingFilesBody'); + return this.i18n( + 'googleDriveFileSyncListingFilesItemsFoundBody', + this.listedFiles_.toLocaleString()); } /**
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js index d7c0a28..47faf9e 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js
@@ -3863,13 +3863,7 @@ await mockFeedback.replay(); }); -// TODO(https://crbug.com/1491964): Failing on Linux ChromeOS bots. -GEN('#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)'); -GEN('#define MAYBE_NewWindowWebSpeech DISABLED_NewWindowWebSpeech'); -GEN('#else'); -GEN('#define MAYBE_NewWindowWebSpeech NewWindowWebSpeech'); -GEN('#endif'); -TEST_F('ChromeVoxBackgroundTest', 'MAYBE_NewWindowWebSpeech', function() { +TEST_F('ChromeVoxBackgroundTest', 'NewWindowWebSpeech', function() { this.newCallback(async () => { const speech = []; let onSpeech; @@ -3880,11 +3874,11 @@ } }; - chrome.runtime.openOptionsPage(); + this.runWithLoadedTree('<h1>ChromeVox Rocks</h1><p>We love ChromeVox</p>'); await new Promise(resolve => { onSpeech = textString => { - if (textString === 'ChromeVox Options') { + if (textString === 'ChromeVox Rocks') { resolve(); } }; @@ -3898,8 +3892,8 @@ // Check to ensure there are no duplicate announcements. assertEquals( - speech.indexOf('ChromeVox Options'), - speech.lastIndexOf('ChromeVox Options')); + speech.indexOf('ChromeVox Rocks'), + speech.lastIndexOf('ChromeVox Rocks')); // Ensure there are no announcements about the Tab role. assertTrue(speech.every(text => {
diff --git a/chrome/browser/resources/chromeos/web_app_install/web_app_install_dialog.ts b/chrome/browser/resources/chromeos/web_app_install/web_app_install_dialog.ts index 095bade..2db0bce3 100644 --- a/chrome/browser/resources/chromeos/web_app_install/web_app_install_dialog.ts +++ b/chrome/browser/resources/chromeos/web_app_install/web_app_install_dialog.ts
@@ -6,7 +6,7 @@ import './strings.m.js'; import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js'; -import {assert, assertInstanceof} from 'chrome://resources/js/assert_ts.js'; +import {assert, assertInstanceof} from 'chrome://resources/js/assert.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {getTemplate} from './web_app_install_dialog.html.js';
diff --git a/chrome/browser/resources/compose/app.html b/chrome/browser/resources/compose/app.html index 843e23db..cc0c69c 100644 --- a/chrome/browser/resources/compose/app.html +++ b/chrome/browser/resources/compose/app.html
@@ -39,6 +39,13 @@ padding: 0 20px; } + #loading { + display: flex; + border: solid 1px var(--color-compose-dialog-result-background); + border-radius: 8px; + padding: 16px; + } + #resultContainer { border-radius: 8px; padding: 16px; @@ -113,9 +120,18 @@ <compose-textarea id="textarea" on-value-changed="onTextareaValueChanged_" readonly="[[submitted_]]" - allow-exiting-readonly-mode="[[submitted_]]"> + allow-exiting-readonly-mode="[[!loading_]]"> </compose-textarea> + <div id="loading" hidden="[[!loading_]]"> + <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="43"> + <rect x="0" y="0" width="100%" height="11" rx="4" fill="#D9D9D9"></rect> + <rect x="0" y="16" width="100%" height="10.8333" rx="4" fill="#D9D9D9"> + </rect> + <rect x="0" y="32" width="75%" height="11" rx="4" fill="#D9D9D9"></rect> + </svg> + </div> + <div id="resultContainer" hidden="[[!result_]]"> [[result_]] @@ -124,12 +140,12 @@ <select class="md-select"><option>Menu 2</option></select> <div class="icon-buttons-row"> - <cr-icon-button id="undo" iron-icon="cr:arrow-back" + <cr-icon-button id="undoButton" iron-icon="cr:arrow-back" disabled="[[!undoEnabled_]]" on-click="onUndoClick_"> </cr-icon-button> - <cr-icon-button id="refresh" iron-icon="cr:sync" - on-click="onRefreshClick_"> + <cr-icon-button id="refreshButton" iron-icon="cr:sync" + on-click="onSubmit_"> </cr-icon-button> </div> </div>
diff --git a/chrome/browser/resources/compose/app.ts b/chrome/browser/resources/compose/app.ts index a679864..72da93a3 100644 --- a/chrome/browser/resources/compose/app.ts +++ b/chrome/browser/resources/compose/app.ts
@@ -14,23 +14,15 @@ import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './app.html.js'; -import {Length, StyleModifiers, Tone} from './compose.mojom-webui.js'; +import {Length, Tone} from './compose.mojom-webui.js'; import {ComposeApiProxy, ComposeApiProxyImpl} from './compose_api_proxy.js'; import {ComposeTextareaElement} from './textarea.js'; -// Mock code. -function generateRandomText(): string { - const randomNumber = Math.random() * (200 - 50) + 50; - const result: string[] = []; - for (let i = 0; i < randomNumber; i++) { - result.push('text'); - } - return result.join(' '); -} - export interface ComposeAppElement { $: { insertButton: CrButtonElement, + loading: HTMLElement, + refreshButton: HTMLElement, resultContainer: HTMLElement, submitButton: CrButtonElement, textarea: ComposeTextareaElement, @@ -53,10 +45,22 @@ type: Boolean, value: false, }, + loading_: { + type: Boolean, + value: false, + }, result_: { type: String, value: '', }, + selectedLength_: { + type: Number, + value: Length.kUnset, + }, + selectedTone_: { + type: Number, + value: Tone.kUnset, + }, submitted_: { type: Boolean, value: false, @@ -71,7 +75,10 @@ private apiProxy_: ComposeApiProxy = ComposeApiProxyImpl.getInstance(); private input_: string; private isSubmitEnabled_: boolean; - private result_: string; + private loading_: boolean; + private result_: string|undefined; + private selectedLength_: Length; + private selectedTone_: Tone; private submitted_: boolean; private undoEnabled_: boolean; @@ -80,29 +87,32 @@ ColorChangeUpdater.forDocument().start(); } - private onRefreshClick_() { - this.result_ = generateRandomText(); - } - - private async onSubmit_() { + private onSubmit_() { if (!this.$.textarea.validate()) { return; } this.submitted_ = true; - const styleModifiers: - StyleModifiers = {tone: Tone.kUnset, length: Length.kUnset}; - const composeResult = - await this.apiProxy_.compose(styleModifiers, this.input_); - - // TODO(b/302742291) store the error if any as well. - this.result_ = composeResult.result || 'error'; + this.compose_(); } private onTextareaValueChanged_() { this.input_ = this.$.textarea.value; this.isSubmitEnabled_ = this.$.textarea.validate(); } + + private async compose_() { + this.loading_ = true; + this.result_ = undefined; + const response = await this.apiProxy_.compose( + { + length: this.selectedLength_, + tone: this.selectedTone_, + }, + this.input_); + this.result_ = response.result || 'error'; + this.loading_ = false; + } } declare global {
diff --git a/chrome/browser/resources/compose/textarea.html b/chrome/browser/resources/compose/textarea.html index f77c725..035a1c5 100644 --- a/chrome/browser/resources/compose/textarea.html +++ b/chrome/browser/resources/compose/textarea.html
@@ -55,7 +55,7 @@ #editButtonContainer { --cr-icon-button-icon-size: var(--cr-icon-size); width: var(--cr-icon-size); - height: var(--cr-icon-size); + height: 16px; display: flex; align-items: center; justify-content: center;
diff --git a/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html b/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html index 683a8ae..c7fa7e9 100644 --- a/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html +++ b/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.html
@@ -230,7 +230,7 @@ } </style> <a id="content" href="[[visit.normalizedUrl.url]]" - aria-label$="[[visit.pageTitle]], [[label_]], [[visit.relativeDate]]"> + aria-label$="[[tileLabel_]]"> <div id="image"> <template is="dom-if" if="[[imageUrl_]]" restamp> <img is="cr-auto-img" auto-src="[[imageUrl_.url]]"
diff --git a/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.ts b/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.ts index 4807811..ee50d4b 100644 --- a/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.ts +++ b/chrome/browser/resources/new_tab_page/modules/history_clusters/tile.ts
@@ -70,6 +70,12 @@ computed: `computeHasDiscount_(discount)`, reflectToAttribute: true, }, + + /* The label of the tile in a11y mode. */ + tileLabel_: { + type: String, + computed: `computeTileLabel_(discount, label_)`, + }, }; } @@ -78,6 +84,7 @@ discount: string; hasDiscount: boolean; private imageUrl_: Url|null; + private label_: string; hasImageUrl(): boolean { return !!this.imageUrl_; @@ -120,6 +127,15 @@ } this.imageUrl_ = null; } + + private computeTileLabel_(): string { + const labelTexts = + [this.visit.pageTitle, this.label_, this.visit.relativeDate]; + if (!!this.discount && this.discount.length !== 0) { + labelTexts.push(this.discount); + } + return labelTexts.join(', '); + } } customElements.define(TileModuleElement.is, TileModuleElement);
diff --git a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/visit_tile.html b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/visit_tile.html index 7225090..dbd934b9 100644 --- a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/visit_tile.html +++ b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/visit_tile.html
@@ -186,7 +186,7 @@ } </style> <a id="content" href="[[visit.normalizedUrl.url]]" - aria-label$="[[visit.pageTitle]], [[label_]], [[visit.relativeDate]]"> + aria-label$="[[tileLabel_]]"> <div class="hover-layer"></div> <div id="label-container"> <page-favicon id="icon" url="[[visit.normalizedUrl]]"
diff --git a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/visit_tile.ts b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/visit_tile.ts index ab0402c9..0053410 100644 --- a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/visit_tile.ts +++ b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/visit_tile.ts
@@ -75,6 +75,12 @@ computed: `computeHasDiscount_(discount)`, reflectToAttribute: true, }, + + /* The label of the tile in a11y mode. */ + tileLabel_: { + type: String, + computed: `computeTileLabel_(discount, label_)`, + }, }; } @@ -84,6 +90,7 @@ discount: string; hasDiscount: boolean; private imageUrl_: Url|null; + private label_: string; hasImageUrl(): boolean { return !!this.imageUrl_; @@ -125,6 +132,15 @@ } this.imageUrl_ = null; } + + private computeTileLabel_(): string { + const labelTexts = + [this.visit.pageTitle, this.label_, this.visit.relativeDate]; + if (!!this.discount && this.discount.length !== 0) { + labelTexts.push(this.discount); + } + return labelTexts.join(', '); + } } customElements.define(VisitTileModuleElement.is, VisitTileModuleElement);
diff --git a/chrome/browser/resources/password_manager/password_details_section.ts b/chrome/browser/resources/password_manager/password_details_section.ts index 65dc96c1..274dad4 100644 --- a/chrome/browser/resources/password_manager/password_details_section.ts +++ b/chrome/browser/resources/password_manager/password_details_section.ts
@@ -10,7 +10,7 @@ import './credential_details/passkey_details_card.js'; import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {afterNextRender, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './password_details_section.html.js';
diff --git a/chrome/browser/resources/side_panel/customize_chrome/combobox/customize_chrome_combobox.html b/chrome/browser/resources/side_panel/customize_chrome/combobox/customize_chrome_combobox.html index 0098ec549..d676605 100644 --- a/chrome/browser/resources/side_panel/customize_chrome/combobox/customize_chrome_combobox.html +++ b/chrome/browser/resources/side_panel/customize_chrome/combobox/customize_chrome_combobox.html
@@ -30,8 +30,9 @@ aria-haspopup="listbox" on-click="onInputClick_" on-focusout="onInputFocusout_"> - [[label]] + [[getInputLabel_(label, selectedElement_)]] </button> -<div id="dropdown" role="listbox"> +<div id="dropdown" role="listbox" on-click="onDropdownClick_" + on-pointerdown="onDropdownPointerdown_"> <slot></slot> </div>
diff --git a/chrome/browser/resources/side_panel/customize_chrome/combobox/customize_chrome_combobox.ts b/chrome/browser/resources/side_panel/customize_chrome/combobox/customize_chrome_combobox.ts index 6b1b0c5..3ded63b1 100644 --- a/chrome/browser/resources/side_panel/customize_chrome/combobox/customize_chrome_combobox.ts +++ b/chrome/browser/resources/side_panel/customize_chrome/combobox/customize_chrome_combobox.ts
@@ -12,6 +12,9 @@ /* Selector for keyboard focusable items in the dropdown. */ const HIGHLIGHTABLE_ITEMS_SELECTOR = '[role=group], [role=option]'; +/* Selector for selectable options in the dropdown. */ +const SELECTABLE_ITEMS_SELECTOR = '[role=option]'; + export interface CustomizeChromeCombobox { $: { input: HTMLDivElement, @@ -37,6 +40,7 @@ observer: 'onExpandedChange_', }, label: String, + selectedElement_: Object, }; } @@ -45,6 +49,7 @@ private highlightedElement_: HTMLElement|null = null; label: string; private domObserver_: MutationObserver|null = null; + private selectedElement_: HTMLElement|null = null; override connectedCallback() { super.connectedCallback(); @@ -66,6 +71,14 @@ this.domObserver_ = null; } + private getInputLabel_(): string { + if (this.selectedElement_) { + return this.selectedElement_.textContent!; + } + + return this.label; + } + private highlightElement_(element: HTMLElement|null) { if (this.highlightedElement_) { this.highlightedElement_.removeAttribute('highlighted'); @@ -83,8 +96,29 @@ this.querySelectorAll<HTMLElement>(HIGHLIGHTABLE_ITEMS_SELECTOR)); } + private onDropdownClick_(event: MouseEvent) { + event.preventDefault(); + event.stopPropagation(); + + const selectableTarget = + event.composedPath().find( + target => target instanceof HTMLElement && + target.matches(SELECTABLE_ITEMS_SELECTOR)) as HTMLElement; + if (!selectableTarget) { + return; + } + this.selectItem_(selectableTarget); + this.expanded_ = false; + } + + private onDropdownPointerdown_(e: PointerEvent) { + /* Prevent the dropdown from gaining focus on pointerdown. The input should + * always be the focused element. */ + e.preventDefault(); + } + private onExpandedChange_() { - this.highlightElement_(null); + this.highlightElement_(this.selectedElement_); } private onInputClick_() { @@ -138,6 +172,15 @@ return; } + if (e.key === 'Enter' || e.key === 'Space') { + e.preventDefault(); + e.stopPropagation(); + if (this.selectItem_(this.highlightedElement_)) { + this.expanded_ = false; + } + return; + } + if (!['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(e.key)) { return; } @@ -171,6 +214,24 @@ this.highlightElement_(this.highlightableElements_[index]!); } + + private selectItem_(item: HTMLElement|null): boolean { + if (!item) { + return false; + } + + if (!item.matches(SELECTABLE_ITEMS_SELECTOR)) { + return false; + } + + if (this.selectedElement_) { + this.selectedElement_.removeAttribute('selected'); + } + + item.toggleAttribute('selected', true); + this.selectedElement_ = item; + return true; + } } declare global {
diff --git a/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search_simple.html b/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search_simple.html index c8712c3..ccbe589b 100644 --- a/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search_simple.html +++ b/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search_simple.html
@@ -4,6 +4,10 @@ padding: 0 16px; } + [selected] { + background: green; + } + [highlighted] { background: yellow; }
diff --git a/chrome/browser/task_manager/task_manager_browsertest.cc b/chrome/browser/task_manager/task_manager_browsertest.cc index 3dc9477..b503b71d 100644 --- a/chrome/browser/task_manager/task_manager_browsertest.cc +++ b/chrome/browser/task_manager/task_manager_browsertest.cc
@@ -1876,11 +1876,22 @@ std::make_unique<content::test::FencedFrameTestHelper>(); }; +// TODO(crbug.com/1491942): This fails with the field trial testing config. +class FencedFrameTaskBrowserTestNoTestingConfig + : public FencedFrameTaskBrowserTest { + public: + void SetUpCommandLine(base::CommandLine* command_line) override { + FencedFrameTaskBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitch("disable-field-trial-config"); + } +}; + } // namespace // Testing that the task manager properly displays fenced frame tasks with // re-opening task manager, and with fenced frame navigations. -IN_PROC_BROWSER_TEST_F(FencedFrameTaskBrowserTest, ProperlyShowsTasks) { +IN_PROC_BROWSER_TEST_F(FencedFrameTaskBrowserTestNoTestingConfig, + ProperlyShowsTasks) { ShowTaskManager(); ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index b7cb701c..b9f66ea 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -65,7 +65,6 @@ "autofill/payments/card_unmask_authentication_selection_dialog_controller.h", "autofill/payments/card_unmask_authentication_selection_dialog_controller_impl.cc", "autofill/payments/card_unmask_authentication_selection_dialog_controller_impl.h", - "autofill/payments/card_unmask_otp_input_dialog_controller.h", "autofill/payments/card_unmask_otp_input_dialog_controller_impl.cc", "autofill/payments/card_unmask_otp_input_dialog_controller_impl.h", "autofill/payments/card_unmask_otp_input_dialog_view.h", @@ -744,6 +743,8 @@ if (is_chromeos) { sources += [ + "webui/dlp_internals/dlp_internals_ui.cc", + "webui/dlp_internals/dlp_internals_ui.h", "webui/trusted_vault/trusted_vault_dialog_delegate.cc", "webui/trusted_vault/trusted_vault_dialog_delegate.h", ]
diff --git a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenu.java b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenu.java index 270267e..0d1a6f2 100644 --- a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenu.java +++ b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenu.java
@@ -287,18 +287,29 @@ anchorView.getLocationOnScreen(mTempLocation); int anchorViewOffset = Math.min(Math.abs(mTempLocation[1] - visibleDisplayFrame.top), Math.abs(mTempLocation[1] - visibleDisplayFrame.bottom)); - int popupHeight = setMenuHeight(menuItemIds, heightList, visibleDisplayFrame, sizingPadding, - footerHeight, headerHeight, anchorView, groupDividerResourceId, anchorViewOffset); - int[] popupPosition = getPopupPosition(mTempLocation, mIsByPermanentButton, - mNegativeSoftwareVerticalOffset, mNegativeVerticalOffsetNotTopAnchored, - mCurrentScreenRotation, visibleDisplayFrame, sizingPadding, anchorView, popupWidth, - popupHeight, anchorView.getRootView().getLayoutDirection()); + setMenuHeight( + menuItemIds, + heightList, + visibleDisplayFrame, + sizingPadding, + footerHeight, + headerHeight, + anchorView, + groupDividerResourceId, + anchorViewOffset); + int[] popupPosition = + getPopupPosition( + mTempLocation, + mIsByPermanentButton, + mNegativeSoftwareVerticalOffset, + mCurrentScreenRotation, + visibleDisplayFrame, + sizingPadding, + anchorView, + popupWidth, + anchorView.getRootView().getLayoutDirection()); mPopup.setContentView(contentView); - if (popupHeight + popupPosition[1] > visibleDisplayFrame.height() - anchorViewOffset) { - mPopup.setHeight(visibleDisplayFrame.height() - anchorViewOffset); - } - try { mPopup.showAtLocation(anchorView.getRootView(), Gravity.NO_GRAVITY, popupPosition[0], popupPosition[1]); @@ -337,10 +348,16 @@ } @VisibleForTesting - static int[] getPopupPosition(int[] tempLocation, boolean isByPermanentButton, - int negativeSoftwareVerticalOffset, int negativeVerticalOffsetNotTopAnchored, - int screenRotation, Rect appRect, Rect padding, View anchorView, int popupWidth, - int popupHeight, int viewLayoutDirection) { + static int[] getPopupPosition( + int[] tempLocation, + boolean isByPermanentButton, + int negativeSoftwareVerticalOffset, + int screenRotation, + Rect appRect, + Rect padding, + View anchorView, + int popupWidth, + int viewLayoutDirection) { anchorView.getLocationInWindow(tempLocation); int anchorViewX = tempLocation[0]; int anchorViewY = tempLocation[1]; @@ -521,9 +538,16 @@ if (mAdapter != null) mAdapter.notifyDataSetChanged(); } - private int setMenuHeight(List<Integer> menuItemIds, List<Integer> heightList, - Rect appDimensions, Rect padding, int footerHeight, int headerHeight, View anchorView, - @IdRes int groupDividerResourceId, int anchorViewOffset) { + private void setMenuHeight( + List<Integer> menuItemIds, + List<Integer> heightList, + Rect appDimensions, + Rect padding, + int footerHeight, + int headerHeight, + View anchorView, + @IdRes int groupDividerResourceId, + int anchorViewOffset) { int anchorViewImpactHeight = mIsByPermanentButton ? anchorView.getHeight() : 0; int availableScreenSpace = appDimensions.height() - anchorViewOffset - padding.bottom @@ -546,7 +570,6 @@ menuItemIds, heightList, groupDividerResourceId, availableScreenSpace); menuHeight += footerHeight + headerHeight + padding.top + padding.bottom; mPopup.setHeight(menuHeight); - return menuHeight; } @VisibleForTesting
diff --git a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuPopupPositionTest.java b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuPopupPositionTest.java index de7e15b9..2a4f109 100644 --- a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuPopupPositionTest.java +++ b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuPopupPositionTest.java
@@ -31,12 +31,10 @@ private final int mAppHeight = 1000; private final int mBgPadding = 10; private final int mPopupWidth = 300; - private final int mPopupHeight = 500; private final int mAnchorX = 100; private final int mAnchorY = 300; private final int mAnchorWidth = 40; private final int mNegativeSoftwareVerticalOffset = 25; - private final int mNegativeSoftwareVerticalOffsetNotTopAnchored = 15; private final View mAnchorView = Mockito.mock(View.class); private final Rect mAppRect = new Rect(0, 0, mAppWidth, mAppHeight); private final Rect mBgPaddingRect = new Rect(mBgPadding, mBgPadding, mBgPadding, mBgPadding); @@ -119,9 +117,15 @@ } private int[] getPopupPosition(boolean isByPermanentButton, int rotation, int layoutDirection) { - return AppMenu.getPopupPosition(mTempLocation, isByPermanentButton, - mNegativeSoftwareVerticalOffset, mNegativeSoftwareVerticalOffsetNotTopAnchored, - rotation, mAppRect, mBgPaddingRect, mAnchorView, mPopupWidth, mPopupHeight, + return AppMenu.getPopupPosition( + mTempLocation, + isByPermanentButton, + mNegativeSoftwareVerticalOffset, + rotation, + mAppRect, + mBgPaddingRect, + mAnchorView, + mPopupWidth, layoutDirection); } }
diff --git a/chrome/browser/ui/android/autofill/otp_verification_dialog_view_android.cc b/chrome/browser/ui/android/autofill/otp_verification_dialog_view_android.cc index 173c8a9..86a8916ad 100644 --- a/chrome/browser/ui/android/autofill/otp_verification_dialog_view_android.cc +++ b/chrome/browser/ui/android/autofill/otp_verification_dialog_view_android.cc
@@ -11,7 +11,7 @@ #include "base/android/jni_string.h" #include "base/android/scoped_java_ref.h" #include "chrome/browser/ui/android/autofill/internal/jni_headers/OtpVerificationDialogBridge_jni.h" -#include "chrome/browser/ui/autofill/payments/card_unmask_otp_input_dialog_controller.h" +#include "components/autofill/core/browser/ui/payments/card_unmask_otp_input_dialog_controller.h" #include "content/public/browser/web_contents.h" #include "ui/android/view_android.h" #include "ui/android/window_android.h"
diff --git a/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediatorUnitTest.java b/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediatorUnitTest.java index 9dc15a4..9b85ce2 100644 --- a/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediatorUnitTest.java +++ b/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediatorUnitTest.java
@@ -51,7 +51,6 @@ import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.FeatureList; -import org.chromium.base.test.BaseActivityTestRule; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.device_reauth.ReauthenticatorBridge; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -60,20 +59,14 @@ import org.chromium.components.signin.AccountReauthenticationUtils; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.modelutil.PropertyModel; -import org.chromium.ui.test.util.BlankUiTestActivity; /** Unit tests for the {@link DeviceLockMediator}.*/ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE) @Features.EnableFeatures({ChromeFeatureList.ACCOUNT_REAUTHENTICATION_RECENT_TIME_WINDOW}) public class DeviceLockMediatorUnitTest { - private static final int MOCK_RECENT_TIME_WINDOW = 10; - @Rule public final AccountManagerTestRule mAccountManagerTestRule = new AccountManagerTestRule(); - @Rule - public BaseActivityTestRule<BlankUiTestActivity> mActivityTestRule = - new BaseActivityTestRule<>(BlankUiTestActivity.class); @Mock public Activity mActivity;
diff --git a/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/MissingDeviceLockMediatorUnitTest.java b/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/MissingDeviceLockMediatorUnitTest.java index ecafdaf..a8b32009 100644 --- a/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/MissingDeviceLockMediatorUnitTest.java +++ b/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/MissingDeviceLockMediatorUnitTest.java
@@ -17,7 +17,6 @@ import static org.chromium.chrome.browser.ui.device_lock.MissingDeviceLockProperties.ON_CREATE_DEVICE_LOCK_CLICKED; import static org.chromium.chrome.browser.ui.device_lock.MissingDeviceLockProperties.REMOVE_ALL_LOCAL_DATA_CHECKED; -import android.accounts.Account; import android.app.Activity; import android.app.admin.DevicePolicyManager; import android.content.Intent; @@ -37,10 +36,8 @@ import org.robolectric.annotation.Config; import org.chromium.base.Callback; -import org.chromium.base.test.BaseActivityTestRule; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule; -import org.chromium.ui.test.util.BlankUiTestActivity; /** Unit tests for the {@link DeviceLockMediator}.*/ @RunWith(BaseRobolectricTestRunner.class) @@ -48,15 +45,10 @@ public class MissingDeviceLockMediatorUnitTest { @Rule public final AccountManagerTestRule mAccountManagerTestRule = new AccountManagerTestRule(); - @Rule - public BaseActivityTestRule<BlankUiTestActivity> mActivityTestRule = - new BaseActivityTestRule<>(BlankUiTestActivity.class); @Mock public Activity mActivity; @Mock - public Account mAccount; - @Mock private PackageManager mPackageManager; @Before
diff --git a/chrome/browser/ui/android/omnibox/BUILD.gn b/chrome/browser/ui/android/omnibox/BUILD.gn index e08a75a..6025dcd 100644 --- a/chrome/browser/ui/android/omnibox/BUILD.gn +++ b/chrome/browser/ui/android/omnibox/BUILD.gn
@@ -134,6 +134,7 @@ "java/src/org/chromium/chrome/browser/omnibox/suggestions/header/HeaderViewProperties.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/history_clusters/HistoryClustersProcessor.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesProcessor.java", + "java/src/org/chromium/chrome/browser/omnibox/suggestions/querytiles/QueryTilesProcessor.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/tail/AlignmentManager.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/tail/TailSuggestionProcessor.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/tail/TailSuggestionView.java", @@ -471,6 +472,7 @@ "java/src/org/chromium/chrome/browser/omnibox/suggestions/header/HeaderViewBinderUnitTest.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/history_clusters/HistoryClustersProcessorTest.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesProcessorUnitTest.java", + "java/src/org/chromium/chrome/browser/omnibox/suggestions/querytiles/QueryTilesProcessorUnitTest.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/tail/AlignmentManagerUnitTest.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/tail/TailSuggestionProcessorUnitTest.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/tail/TailSuggestionViewBinderUnitTest.java",
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java index 428c056..d11809ab 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java
@@ -261,6 +261,12 @@ OmniboxSuggestionUiType.DIVIDER_LINE, parent -> new DividerLineView(parent.getContext()), DividerLineViewBinder::bind); + + adapter.registerType( + OmniboxSuggestionUiType.QUERY_TILES, + BaseCarouselSuggestionItemViewBuilder::createView, + BaseCarouselSuggestionViewBinder::bind); + // clang-format on return adapter; }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListBuilder.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListBuilder.java index d03284e..5369394 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListBuilder.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListBuilder.java
@@ -27,6 +27,7 @@ import org.chromium.chrome.browser.omnibox.suggestions.history_clusters.HistoryClustersProcessor; import org.chromium.chrome.browser.omnibox.suggestions.history_clusters.HistoryClustersProcessor.OpenHistoryClustersDelegate; import org.chromium.chrome.browser.omnibox.suggestions.mostvisited.MostVisitedTilesProcessor; +import org.chromium.chrome.browser.omnibox.suggestions.querytiles.QueryTilesProcessor; import org.chromium.chrome.browser.omnibox.suggestions.tail.TailSuggestionProcessor; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.share.ShareDelegate; @@ -103,6 +104,7 @@ context, host, textProvider, mImageSupplier, mBookmarkState)); registerSuggestionProcessor(new TailSuggestionProcessor(context, host)); registerSuggestionProcessor(new MostVisitedTilesProcessor(context, host, mImageSupplier)); + registerSuggestionProcessor(new QueryTilesProcessor(context, host, mImageSupplier)); registerSuggestionProcessor(new BasicSuggestionProcessor( context, host, textProvider, mImageSupplier, mBookmarkState)); }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/PreWarmingRecycledViewPool.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/PreWarmingRecycledViewPool.java index d091ca7c..99336fd 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/PreWarmingRecycledViewPool.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/PreWarmingRecycledViewPool.java
@@ -72,6 +72,7 @@ setMaxRecycledViews(OmniboxSuggestionUiType.TILE_NAVSUGGEST, 1); setMaxRecycledViews(OmniboxSuggestionUiType.PEDAL_SUGGESTION, 3); setMaxRecycledViews(OmniboxSuggestionUiType.DIVIDER_LINE, 1); + setMaxRecycledViews(OmniboxSuggestionUiType.QUERY_TILES, 1); } public void destroy() {
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/carousel/BaseCarouselSuggestionProcessor.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/carousel/BaseCarouselSuggestionProcessor.java index 6dfc29e..0dbf470 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/carousel/BaseCarouselSuggestionProcessor.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/carousel/BaseCarouselSuggestionProcessor.java
@@ -7,6 +7,7 @@ import android.content.Context; import androidx.annotation.CallSuper; +import androidx.annotation.NonNull; import org.chromium.chrome.browser.omnibox.R; import org.chromium.chrome.browser.omnibox.suggestions.SuggestionProcessor; @@ -16,7 +17,7 @@ /** The base processor implementation for the Carousel suggestions. */ public abstract class BaseCarouselSuggestionProcessor implements SuggestionProcessor { - private final Context mContext; + protected final @NonNull Context mContext; private final int mCarouselViewDecorationHeightPx; /**
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesProcessor.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesProcessor.java index 78db17d..64ea39b 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesProcessor.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesProcessor.java
@@ -38,7 +38,6 @@ * SuggestionProcessor for Most Visited URL tiles. */ public class MostVisitedTilesProcessor extends BaseCarouselSuggestionProcessor { - private final @NonNull Context mContext; private final @NonNull SuggestionHost mSuggestionHost; private final @Nullable OmniboxImageSupplier mImageSupplier; private final int mMinCarouselItemViewHeight; @@ -53,7 +52,6 @@ public MostVisitedTilesProcessor(@NonNull Context context, @NonNull SuggestionHost host, @Nullable OmniboxImageSupplier imageSupplier) { super(context); - mContext = context; mSuggestionHost = host; mImageSupplier = imageSupplier; mMinCarouselItemViewHeight =
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/querytiles/QueryTilesProcessor.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/querytiles/QueryTilesProcessor.java new file mode 100644 index 0000000..888902059 --- /dev/null +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/querytiles/QueryTilesProcessor.java
@@ -0,0 +1,71 @@ +// Copyright 2023 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.omnibox.suggestions.querytiles; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.chromium.chrome.browser.omnibox.styles.OmniboxImageSupplier; +import org.chromium.chrome.browser.omnibox.suggestions.SuggestionHost; +import org.chromium.chrome.browser.omnibox.suggestions.carousel.BaseCarouselSuggestionProcessor; +import org.chromium.chrome.browser.omnibox.suggestions.carousel.BaseCarouselSuggestionViewProperties; +import org.chromium.components.omnibox.AutocompleteMatch; +import org.chromium.components.omnibox.OmniboxSuggestionType; +import org.chromium.components.omnibox.suggestions.OmniboxSuggestionUiType; +import org.chromium.ui.modelutil.PropertyModel; + +import java.util.ArrayList; + +/** SuggestionProcessor for Query Tiles. */ +public class QueryTilesProcessor extends BaseCarouselSuggestionProcessor { + private final @NonNull SuggestionHost mSuggestionHost; + private final @Nullable OmniboxImageSupplier mImageSupplier; + + /** + * Constructor. + * + * @param context An Android context. + * @param host SuggestionHost receiving notifications about user actions. + * @param imageSupplier Class retrieving favicons for the MV Tiles. + */ + public QueryTilesProcessor( + @NonNull Context context, + @NonNull SuggestionHost host, + @Nullable OmniboxImageSupplier imageSupplier) { + super(context); + mSuggestionHost = host; + mImageSupplier = imageSupplier; + } + + @Override + public boolean doesProcessSuggestion(AutocompleteMatch match, int matchIndex) { + return match.getType() == OmniboxSuggestionType.TILE_SUGGESTION; + } + + @Override + public int getViewTypeId() { + return OmniboxSuggestionUiType.QUERY_TILES; + } + + @Override + public PropertyModel createModel() { + return new PropertyModel.Builder(BaseCarouselSuggestionViewProperties.ALL_KEYS) + .with(BaseCarouselSuggestionViewProperties.TILES, new ArrayList<>()) + .build(); + } + + @Override + public int getMinimumCarouselItemViewHeight() { + // TODO(crbug/1490333): identify correct height. + return 0; + } + + @Override + public void populateModel(AutocompleteMatch match, PropertyModel model, int matchIndex) { + super.populateModel(match, model, matchIndex); + } +}
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/querytiles/QueryTilesProcessorUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/querytiles/QueryTilesProcessorUnitTest.java new file mode 100644 index 0000000..b9a4685 --- /dev/null +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/querytiles/QueryTilesProcessorUnitTest.java
@@ -0,0 +1,94 @@ +// Copyright 2023 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.omnibox.suggestions.querytiles; + +import static org.junit.Assert.assertEquals; + +import android.content.Context; +import android.view.ContextThemeWrapper; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import org.chromium.base.ContextUtils; +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.omnibox.styles.OmniboxImageSupplier; +import org.chromium.chrome.browser.omnibox.styles.OmniboxResourceProvider; +import org.chromium.chrome.browser.omnibox.suggestions.SuggestionHost; +import org.chromium.chrome.browser.omnibox.suggestions.carousel.BaseCarouselSuggestionViewProperties; +import org.chromium.chrome.browser.omnibox.test.R; +import org.chromium.components.omnibox.AutocompleteMatchBuilder; +import org.chromium.components.omnibox.OmniboxSuggestionType; +import org.chromium.components.omnibox.suggestions.OmniboxSuggestionUiType; +import org.chromium.ui.modelutil.MVCListAdapter.ListItem; +import org.chromium.ui.modelutil.PropertyModel; + +import java.util.List; + +/** Tests for {@link MostVisitedTilesProcessor}. */ +@RunWith(BaseRobolectricTestRunner.class) +public class QueryTilesProcessorUnitTest { + public @Rule MockitoRule mockitoRule = MockitoJUnit.rule(); + + private Context mContext; + private PropertyModel mModel; + private QueryTilesProcessor mProcessor; + private List<ListItem> mTiles; + private @Mock SuggestionHost mSuggestionHost; + private @Mock OmniboxImageSupplier mImageSupplier; + + @Before + public void setUp() { + mContext = + new ContextThemeWrapper( + ContextUtils.getApplicationContext(), R.style.Theme_BrowserUI_DayNight); + mProcessor = new QueryTilesProcessor(mContext, mSuggestionHost, mImageSupplier); + mModel = mProcessor.createModel(); + mTiles = mModel.get(BaseCarouselSuggestionViewProperties.TILES); + OmniboxResourceProvider.disableCachesForTesting(); + } + + @After + public void tearDown() { + OmniboxResourceProvider.reenableCachesForTesting(); + } + + @Test + public void doesProcessSuggestion() { + for (int type = 0; type < OmniboxSuggestionType.NUM_TYPES; type++) { + var match = AutocompleteMatchBuilder.searchWithType(type).build(); + assertEquals( + type == OmniboxSuggestionType.TILE_SUGGESTION, + mProcessor.doesProcessSuggestion(match, 0)); + } + } + + @Test + public void getViewTypeId() { + assertEquals(OmniboxSuggestionUiType.QUERY_TILES, mProcessor.getViewTypeId()); + } + + @Test + public void getMinimumCarouselItemViewHeight() { + assertEquals(0, mProcessor.getMinimumCarouselItemViewHeight()); + } + + @Test + public void populateModel() { + var match = + AutocompleteMatchBuilder.searchWithType(OmniboxSuggestionType.TILE_SUGGESTION) + .build(); + mProcessor.populateModel(match, mModel, 0); + + // Currently expected to do nothing. + assertEquals(0, mTiles.size()); + } +}
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index b67021d..fa95ad6c 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -5691,9 +5691,6 @@ <message name="IDS_SIGNIN_ERROR_DIALOG_GOT_IT_BUTTON" desc="The button text on the error dialog for the user to acknowledge that an error has occurred in their attempt to sign in with an account from an identity provider." translateable="false"> Got it </message> - <message name="IDS_SIGNIN_ERROR_DIALOG_MORE_DETAILS_BUTTON" desc="The button text on the error dialog for the user to get more details about an error that has occurred in their attempt to sign in with an account from an identity provider." translateable="false"> - More details - </message> <message name="IDS_SIGNIN_GENERIC_ERROR_DIALOG_SUMMARY" desc="Summary of generic error upon user failing to sign in with an account from an identity provider." translateable="false"> Can't continue with <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE">%1$s<ex>idp.example</ex></ph> </message> @@ -5731,7 +5728,7 @@ <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE">%1$s<ex>idp.example</ex></ph> isn't available right now. </message> <message name="IDS_SIGNIN_ERROR_DIALOG_MORE_DETAILS_PROMPT" desc="Prompt user to click on the more details button to get more details about an error that has occurred in their attempt to sign in with an account from an identity provider." translateable="false"> - If this issue keeps happening, choose "More details" below to get more information from <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE">%1$s<ex>idp.example</ex></ph>. + If this issue keeps happening, get <ph name="BEGIN_LINK"><link_more_details></ph>more information<ph name="END_LINK"></link_more_details></ph> from <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE">%1$s<ex>idp.example</ex></ph>. </message> <message name="IDS_SIGNIN_ERROR_DIALOG_TRY_OTHER_WAYS_PROMPT" desc="Prompt user to try other ways of signing in after an error has occurred in their attempt to sign in with an account from an identity provider." translateable="false"> If this issue keeps happening, you can try other ways to continue on <ph name="SITE_ETLD_PLUS_ONE">%1$s<ex>rp.example</ex></ph>.
diff --git a/chrome/browser/ui/android/webid/internal/BUILD.gn b/chrome/browser/ui/android/webid/internal/BUILD.gn index 203d4c5..05ca8dd9 100644 --- a/chrome/browser/ui/android/webid/internal/BUILD.gn +++ b/chrome/browser/ui/android/webid/internal/BUILD.gn
@@ -68,7 +68,6 @@ "java/res/layout/account_selection_data_sharing_consent_item.xml", "java/res/layout/account_selection_header_item.xml", "java/res/layout/account_selection_sheet.xml", - "java/res/layout/error_button.xml", "java/res/layout/error_description_text_item.xml", "java/res/layout/error_summary_text_item.xml", "java/res/layout/idp_signin_text_item.xml",
diff --git a/chrome/browser/ui/android/webid/internal/java/res/layout/account_selection_sheet.xml b/chrome/browser/ui/android/webid/internal/java/res/layout/account_selection_sheet.xml index b3375b0..82faacb4 100644 --- a/chrome/browser/ui/android/webid/internal/java/res/layout/account_selection_sheet.xml +++ b/chrome/browser/ui/android/webid/internal/java/res/layout/account_selection_sheet.xml
@@ -32,9 +32,6 @@ <include layout="@layout/idp_signin_text_item" android:id="@+id/idp_signin" android:visibility="gone"/> - <include layout="@layout/account_selection_continue_button" - android:id="@+id/account_selection_continue_btn" - android:visibility="gone"/> <LinearLayout android:id="@+id/error_text" android:layout_width="match_parent" @@ -47,19 +44,9 @@ <include layout="@layout/error_description_text_item" android:id="@+id/error_description"/> </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginEnd="@dimen/account_selection_sheet_horizontal_margin" - android:orientation="horizontal" - android:gravity="end"> - <include layout="@layout/error_button" - android:id="@+id/more_details_btn" - android:visibility="gone"/> - <include layout="@layout/error_button" - android:id="@+id/got_it_btn" - android:visibility="gone"/> - </LinearLayout> + <include layout="@layout/account_selection_continue_button" + android:id="@+id/account_selection_continue_btn" + android:visibility="gone"/> <include layout="@layout/account_selection_data_sharing_consent_item" android:id="@+id/user_data_sharing_consent" android:visibility="gone"/>
diff --git a/chrome/browser/ui/android/webid/internal/java/res/layout/error_button.xml b/chrome/browser/ui/android/webid/internal/java/res/layout/error_button.xml deleted file mode 100644 index 9f816d29..0000000 --- a/chrome/browser/ui/android/webid/internal/java/res/layout/error_button.xml +++ /dev/null
@@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2023 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<org.chromium.ui.widget.ButtonCompat - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:descendantFocusability="blocksDescendants" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - style="@style/OutlinedButton"/>
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionControllerTest.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionControllerTest.java index b5f4fc0..ec95b07 100644 --- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionControllerTest.java +++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionControllerTest.java
@@ -53,7 +53,6 @@ import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.AccountProperties.Avatar; import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.ContinueButtonProperties; import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.DataSharingConsentProperties; -import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.ErrorButtonProperties; import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.ErrorProperties; import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.HeaderProperties.HeaderType; import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.IdpSignInProperties; @@ -328,11 +327,14 @@ // Do not let test inputs be ignored. mMediator.setComponentShowTime(-1000); assertFalse(mMediator.wasDismissed()); - assertNotNull(mModel.get(ItemProperties.CONTINUE_BUTTON) - .get(ContinueButtonProperties.ON_CLICK_LISTENER)); + assertNotNull( + mModel.get(ItemProperties.CONTINUE_BUTTON) + .get(ContinueButtonProperties.PROPERTIES) + .mOnClickListener); mModel.get(ItemProperties.CONTINUE_BUTTON) - .get(ContinueButtonProperties.ON_CLICK_LISTENER) + .get(ContinueButtonProperties.PROPERTIES) + .mOnClickListener .onResult(ANA); verify(mMockDelegate).onAccountSelected(TEST_CONFIG_URL, ANA); assertFalse(mMediator.wasDismissed()); @@ -529,13 +531,16 @@ mModel.get(ItemProperties.IDP_SIGNIN).get(IdpSignInProperties.IDP_FOR_DISPLAY); assertEquals("Incorrect provider ETLD+1", TEST_ETLD_PLUS_ONE_2, idpEtldPlusOne); - assertNotNull(mModel.get(ItemProperties.CONTINUE_BUTTON) - .get(ContinueButtonProperties.ON_CLICK_LISTENER)); + assertNotNull( + mModel.get(ItemProperties.CONTINUE_BUTTON) + .get(ContinueButtonProperties.PROPERTIES) + .mOnClickListener); // Do not let test inputs be ignored. mMediator.setComponentShowTime(-1000); mModel.get(ItemProperties.CONTINUE_BUTTON) - .get(ContinueButtonProperties.ON_CLICK_LISTENER) + .get(ContinueButtonProperties.PROPERTIES) + .mOnClickListener .onResult(null); verify(mMockDelegate, times(++count)).onSignInToIdp(); } @@ -552,7 +557,7 @@ assertEquals(0, mSheetAccountItems.size()); assertEquals(HeaderType.SIGN_IN_ERROR, mModel.get(ItemProperties.HEADER).get(TYPE)); - // For error dialog without an error URL, we expect header + error text + got it button + // For error dialog, we expect header + error text + got it button assertEquals(3, countAllItems()); assertTrue(containsItemOfType(mModel, ItemProperties.ERROR_TEXT)); @@ -564,15 +569,21 @@ errorProperties.mTopFrameForDisplay); assertEquals("Incorrect token error", TOKEN_ERROR_EMPTY_URL, errorProperties.mError); - assertNotNull(mModel.get(ItemProperties.GOT_IT_BUTTON) - .get(ErrorButtonProperties.ON_CLICK_LISTENER)); - assertNull(mModel.get(ItemProperties.MORE_DETAILS_BUTTON)); + assertNotNull( + mModel.get(ItemProperties.CONTINUE_BUTTON) + .get(ContinueButtonProperties.PROPERTIES) + .mOnClickListener); + assertNull( + mModel.get(ItemProperties.ERROR_TEXT) + .get(ErrorProperties.PROPERTIES) + .mMoreDetailsClickRunnable); // Do not let test inputs be ignored. mMediator.setComponentShowTime(-1000); - mModel.get(ItemProperties.GOT_IT_BUTTON) - .get(ErrorButtonProperties.ON_CLICK_LISTENER) - .run(); + mModel.get(ItemProperties.CONTINUE_BUTTON) + .get(ContinueButtonProperties.PROPERTIES) + .mOnClickListener + .onResult(ANA); verify(mMockDelegate, times(++count)) .onDismissed(IdentityRequestDialogDismissReason.GOT_IT_BUTTON); assertTrue(mMediator.wasDismissed()); @@ -590,9 +601,8 @@ assertEquals(0, mSheetAccountItems.size()); assertEquals(HeaderType.SIGN_IN_ERROR, mModel.get(ItemProperties.HEADER).get(TYPE)); - // For error dialog with an error URL, we expect header + error text + got it button + - // more details button - assertEquals(4, countAllItems()); + // For error dialog, we expect header + error text + got it button + assertEquals(3, countAllItems()); assertTrue(containsItemOfType(mModel, ItemProperties.ERROR_TEXT)); ErrorProperties.Properties errorProperties = @@ -603,15 +613,20 @@ errorProperties.mTopFrameForDisplay); assertEquals("Incorrect token error", TOKEN_ERROR, errorProperties.mError); - assertNotNull(mModel.get(ItemProperties.GOT_IT_BUTTON) - .get(ErrorButtonProperties.ON_CLICK_LISTENER)); - assertNotNull(mModel.get(ItemProperties.MORE_DETAILS_BUTTON) - .get(ErrorButtonProperties.ON_CLICK_LISTENER)); + assertNotNull( + mModel.get(ItemProperties.CONTINUE_BUTTON) + .get(ContinueButtonProperties.PROPERTIES) + .mOnClickListener); + assertNotNull( + mModel.get(ItemProperties.ERROR_TEXT) + .get(ErrorProperties.PROPERTIES) + .mMoreDetailsClickRunnable); // Do not let test inputs be ignored. mMediator.setComponentShowTime(-1000); - mModel.get(ItemProperties.MORE_DETAILS_BUTTON) - .get(ErrorButtonProperties.ON_CLICK_LISTENER) + mModel.get(ItemProperties.ERROR_TEXT) + .get(ErrorProperties.PROPERTIES) + .mMoreDetailsClickRunnable .run(); verify(mMockDelegate, times(++count)).onMoreDetails(); verify(mMockDelegate, times(count))
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionMediator.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionMediator.java index 6248be9..69f3e5c 100644 --- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionMediator.java +++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionMediator.java
@@ -16,6 +16,7 @@ import androidx.annotation.Px; import androidx.annotation.VisibleForTesting; +import org.chromium.base.Callback; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; @@ -23,7 +24,6 @@ import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.AccountProperties; import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.ContinueButtonProperties; import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.DataSharingConsentProperties; -import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.ErrorButtonProperties; import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.ErrorProperties; import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.HeaderProperties; import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.HeaderProperties.HeaderType; @@ -441,14 +441,12 @@ updateAccounts(mIdpForDisplay, accounts, areAccountsClickable); updateHeader(); - boolean isContinueButtonVisible = false; - boolean isGotItButtonVisible = false; - boolean isMoreDetailsButtonVisible = false; boolean isDataSharingConsentVisible = false; + Callback<Account> continueButtonCallback = null; if (mHeaderType == HeaderType.SIGN_IN && mSelectedAccount != null) { - isContinueButtonVisible = true; // Only show the user data sharing consent text for sign up. isDataSharingConsentVisible = !mSelectedAccount.isSignIn(); + continueButtonCallback = this::onClickAccountSelected; } if (mHeaderType == HeaderType.VERIFY_AUTO_REAUTHN) { @@ -461,25 +459,20 @@ if (mHeaderType == HeaderType.SIGN_IN_TO_IDP_STATIC) { assert !isDataSharingConsentVisible; assert mSelectedAccount == null; - isContinueButtonVisible = true; + continueButtonCallback = this::onSignInToIdp; } if (mHeaderType == HeaderType.SIGN_IN_ERROR) { assert !isDataSharingConsentVisible; - isContinueButtonVisible = false; - isGotItButtonVisible = true; - isMoreDetailsButtonVisible = !mError.getUrl().isEmpty(); + continueButtonCallback = this::onClickGotItButton; } - mModel.set(ItemProperties.CONTINUE_BUTTON, - isContinueButtonVisible ? createContinueBtnItem(mSelectedAccount, mIdpMetadata) - : null); - mModel.set(ItemProperties.GOT_IT_BUTTON, - isGotItButtonVisible ? createErrorBtnItem(mIdpMetadata, this::onClickGotItButton) - : null); - mModel.set(ItemProperties.MORE_DETAILS_BUTTON, - isMoreDetailsButtonVisible ? createErrorBtnItem(mIdpMetadata, this::onMoreDetails) - : null); + mModel.set( + ItemProperties.CONTINUE_BUTTON, + (continueButtonCallback != null) + ? createContinueBtnItem( + mSelectedAccount, mIdpMetadata, continueButtonCallback) + : null); mModel.set(ItemProperties.DATA_SHARING_CONSENT, isDataSharingConsentVisible ? createDataSharingConsentItem(mIdpForDisplay, mClientMetadata) @@ -594,10 +587,12 @@ onAccountSelected(selectedAccount); } - /** - * Event listener for when the user taps on the got it button of the bottomsheet. - */ - void onClickGotItButton() { + /** Event listener for when the user taps on the got it button of the bottomsheet. */ + void onClickGotItButton(Account account) { + // This method only has an Account to match the type of the event listener. However, it + // should be non-null because an account must have been selected in order to reach an error + // dialog. + assert account != null; if (!shouldInputBeProcessed()) return; onDismissed(IdentityRequestDialogDismissReason.GOT_IT_BUTTON); } @@ -632,22 +627,20 @@ } private PropertyModel createContinueBtnItem( - Account account, IdentityProviderMetadata idpMetadata) { - assert account != null || mHeaderType == HeaderProperties.HeaderType.SIGN_IN_TO_IDP_STATIC; - return new PropertyModel.Builder(ContinueButtonProperties.ALL_KEYS) - .with(ContinueButtonProperties.IDP_METADATA, idpMetadata) - .with(ContinueButtonProperties.ACCOUNT, account) - .with(ContinueButtonProperties.ON_CLICK_LISTENER, - account != null ? this::onClickAccountSelected : this::onSignInToIdp) - .build(); - } + Account account, + IdentityProviderMetadata idpMetadata, + Callback<Account> onClickListener) { + assert account != null + || mHeaderType == HeaderProperties.HeaderType.SIGN_IN_TO_IDP_STATIC + || mHeaderType == HeaderProperties.HeaderType.SIGN_IN_ERROR; - private PropertyModel createErrorBtnItem( - IdentityProviderMetadata idpMetadata, Runnable onClickListener) { - assert mHeaderType == HeaderProperties.HeaderType.SIGN_IN_ERROR; - return new PropertyModel.Builder(ErrorButtonProperties.ALL_KEYS) - .with(ErrorButtonProperties.IDP_METADATA, idpMetadata) - .with(ErrorButtonProperties.ON_CLICK_LISTENER, onClickListener) + ContinueButtonProperties.Properties properties = new ContinueButtonProperties.Properties(); + properties.mAccount = account; + properties.mIdpMetadata = idpMetadata; + properties.mOnClickListener = onClickListener; + properties.mHeaderType = mHeaderType; + return new PropertyModel.Builder(ContinueButtonProperties.ALL_KEYS) + .with(ContinueButtonProperties.PROPERTIES, properties) .build(); } @@ -683,6 +676,8 @@ properties.mIdpForDisplay = idpForDisplay; properties.mTopFrameForDisplay = topFrameForDisplay; properties.mError = error; + properties.mMoreDetailsClickRunnable = + !error.getUrl().isEmpty() ? this::onMoreDetails : null; return new PropertyModel.Builder(ErrorProperties.ALL_KEYS) .with(ErrorProperties.PROPERTIES, properties) .build();
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionProperties.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionProperties.java index 24c76951..077b8c34 100644 --- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionProperties.java +++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionProperties.java
@@ -112,14 +112,17 @@ * sheet. */ static class ContinueButtonProperties { - static final ReadableObjectPropertyKey<Account> ACCOUNT = - new ReadableObjectPropertyKey<>("account"); - static final ReadableObjectPropertyKey<IdentityProviderMetadata> IDP_METADATA = - new ReadableObjectPropertyKey<>("idp_metadata"); - static final ReadableObjectPropertyKey<Callback<Account>> ON_CLICK_LISTENER = - new ReadableObjectPropertyKey<>("on_click_listener"); + static class Properties { + public Account mAccount; + public IdentityProviderMetadata mIdpMetadata; + public Callback<Account> mOnClickListener; + public HeaderProperties.HeaderType mHeaderType; + } - static final PropertyKey[] ALL_KEYS = {ACCOUNT, IDP_METADATA, ON_CLICK_LISTENER}; + static final ReadableObjectPropertyKey<Properties> PROPERTIES = + new ReadableObjectPropertyKey<>("properties"); + + static final PropertyKey[] ALL_KEYS = {PROPERTIES}; private ContinueButtonProperties() {} } @@ -161,6 +164,7 @@ public String mIdpForDisplay; public String mTopFrameForDisplay; public IdentityCredentialTokenError mError; + public Runnable mMoreDetailsClickRunnable; } static final ReadableObjectPropertyKey<Properties> PROPERTIES = @@ -185,13 +189,10 @@ new WritableObjectPropertyKey<>("idp_signin"); static final WritableObjectPropertyKey<PropertyModel> ERROR_TEXT = new WritableObjectPropertyKey<>("error_text"); - static final WritableObjectPropertyKey<PropertyModel> GOT_IT_BUTTON = - new WritableObjectPropertyKey<>("got_it_btn"); - static final WritableObjectPropertyKey<PropertyModel> MORE_DETAILS_BUTTON = - new WritableObjectPropertyKey<>("more_details_btn"); - static final PropertyKey[] ALL_KEYS = {CONTINUE_BUTTON, DATA_SHARING_CONSENT, HEADER, - IDP_SIGNIN, ERROR_TEXT, GOT_IT_BUTTON, MORE_DETAILS_BUTTON}; + static final PropertyKey[] ALL_KEYS = { + CONTINUE_BUTTON, DATA_SHARING_CONSENT, HEADER, IDP_SIGNIN, ERROR_TEXT + }; private ItemProperties() {} }
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java index 112d19a..9b39966 100644 --- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java +++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java
@@ -235,10 +235,15 @@ private static class ErrorText { final String mSummary; - final String mDescription; + final SpannableString mDescription; ErrorText(String summary, String description) { mSummary = summary; + mDescription = new SpannableString(description); + } + + ErrorText(String summary, SpannableString description) { + mSummary = summary; mDescription = description; } } @@ -308,7 +313,16 @@ description += " " + String.format(context.getString( R.string.signin_error_dialog_more_details_prompt, idpForDisplay)); - return new ErrorText(summary, description); + + SpanApplier.SpanInfo moreDetailsSpan = + new SpanApplier.SpanInfo( + "<link_more_details>", + "</link_more_details>", + new NoUnderlineClickableSpan( + context, + (View clickedView) -> properties.mMoreDetailsClickRunnable.run())); + + return new ErrorText(summary, SpanApplier.applySpans(description, moreDetailsSpan)); } /** @@ -343,11 +357,13 @@ static void bindContinueButtonView(PropertyModel model, View view, PropertyKey key) { Context context = view.getContext(); ButtonCompat button = view.findViewById(R.id.account_selection_continue_btn); - if (key == ContinueButtonProperties.IDP_METADATA) { - if (!ColorUtils.inNightMode(context)) { - IdentityProviderMetadata idpMetadata = - model.get(ContinueButtonProperties.IDP_METADATA); + if (key == ContinueButtonProperties.PROPERTIES) { + ContinueButtonProperties.Properties properties = + model.get(ContinueButtonProperties.PROPERTIES); + + IdentityProviderMetadata idpMetadata = properties.mIdpMetadata; + if (!ColorUtils.inNightMode(context)) { Integer backgroundColor = idpMetadata.getBrandBackgroundColor(); if (backgroundColor != null) { button.setButtonColor(ColorStateList.valueOf(backgroundColor)); @@ -363,10 +379,25 @@ button.setTextColor(textColor); } } - } else if (key == ContinueButtonProperties.ACCOUNT) { + + Account account = properties.mAccount; + button.setOnClickListener( + clickedView -> { + properties.mOnClickListener.onResult(account); + }); + String btnText; - Account account = model.get(ContinueButtonProperties.ACCOUNT); - if (account != null) { + HeaderProperties.HeaderType headerType = properties.mHeaderType; + if (headerType == HeaderProperties.HeaderType.SIGN_IN_TO_IDP_STATIC) { + btnText = + String.format( + context.getString( + R.string.idp_signin_status_mismatch_dialog_continue)); + } else if (headerType == HeaderProperties.HeaderType.SIGN_IN_ERROR) { + btnText = + String.format( + context.getString(R.string.signin_error_dialog_got_it_button)); + } else { // Prefers to use given name if it is provided otherwise falls back to using the // name. String givenName = account.getGivenName(); @@ -374,17 +405,10 @@ givenName != null && !givenName.isEmpty() ? givenName : account.getName(); btnText = String.format( context.getString(R.string.account_selection_continue), displayedName); - } else { - btnText = String.format( - context.getString(R.string.idp_signin_status_mismatch_dialog_continue)); } + assert btnText != null; button.setText(btnText); - } else if (key == ContinueButtonProperties.ON_CLICK_LISTENER) { - button.setOnClickListener(clickedView -> { - Account account = model.get(ContinueButtonProperties.ACCOUNT); - model.get(ContinueButtonProperties.ON_CLICK_LISTENER).onResult(account); - }); } else { assert false : "Unhandled update to property:" + key; } @@ -424,31 +448,6 @@ } /** - * Called whenever the got it button on the error dialog is bound to this view. - * @param model The model containing the data for the view. - * @param view The view to be bound. - * @param key The key of the property to be bound. - */ - @SuppressWarnings("checkstyle:SetTextColorAndSetTextSizeCheck") - static void bindGotItButtonView(PropertyModel model, View view, PropertyKey key) { - ButtonCompat button = view.findViewById(R.id.got_it_btn); - bindErrorButtonView(model, view, key, button, R.string.signin_error_dialog_got_it_button); - } - - /** - * Called whenever the more details button on the error dialog is bound to this view. - * @param model The model containing the data for the view. - * @param view The view to be bound. - * @param key The key of the property to be bound. - */ - @SuppressWarnings("checkstyle:SetTextColorAndSetTextSizeCheck") - static void bindMoreDetailsButtonView(PropertyModel model, View view, PropertyKey key) { - ButtonCompat button = view.findViewById(R.id.more_details_btn); - bindErrorButtonView( - model, view, key, button, R.string.signin_error_dialog_more_details_button); - } - - /** * Called whenever non-account views are bound to the bottom sheet. * @param model The model containing the data for the view. * @param view The view to be bound. @@ -473,12 +472,6 @@ } else if (key == ItemProperties.ERROR_TEXT) { itemView = view.findViewById(R.id.error_text); itemBinder = AccountSelectionViewBinder::bindErrorTextView; - } else if (key == ItemProperties.GOT_IT_BUTTON) { - itemView = view.findViewById(R.id.got_it_btn); - itemBinder = AccountSelectionViewBinder::bindGotItButtonView; - } else if (key == ItemProperties.MORE_DETAILS_BUTTON) { - itemView = view.findViewById(R.id.more_details_btn); - itemBinder = AccountSelectionViewBinder::bindMoreDetailsButtonView; } else { assert false : "Unhandled update to property:" + key; return;
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewTest.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewTest.java index 996dd168..680ecbb1 100644 --- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewTest.java +++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewTest.java
@@ -80,6 +80,14 @@ private static final GURL TEST_ERROR_URL = JUnitTestGURLs.URL_1; private static final GURL TEST_EMPTY_ERROR_URL = new GURL(""); + // Android chrome strings may have link tags which needs to be removed before comparing with the + // actual text on the dialog. + private static final String LINK_TAG_REGEX = "<[^>]*>"; + + private static final IdentityProviderMetadata TEST_IDP_METADATA = + new IdentityProviderMetadata( + Color.BLUE, Color.GREEN, "https://icon-url.example", TEST_CONFIG_URL); + private class RpContext { public String mValue; public int mTitleId; @@ -150,9 +158,13 @@ + mResources.getString(R.string.signin_error_dialog_try_other_ways_prompt, TEST_RP_ETLD_PLUS_ONE); } - return initialDescription + " " - + mResources.getString(R.string.signin_error_dialog_more_details_prompt, - TEST_IDP_ETLD_PLUS_ONE); + return initialDescription + + " " + + mResources + .getString( + R.string.signin_error_dialog_more_details_prompt, + TEST_IDP_ETLD_PLUS_ONE) + .replaceAll(LINK_TAG_REGEX, ""); } } @@ -307,7 +319,9 @@ .build())); ShadowLooper.shadowMainLooper().idle(); - mModel.set(ItemProperties.CONTINUE_BUTTON, buildContinueButton(ANA, null)); + mModel.set( + ItemProperties.CONTINUE_BUTTON, + buildContinueButton(ANA, TEST_IDP_METADATA, HeaderType.SIGN_IN)); assertEquals(View.VISIBLE, mContentView.getVisibility()); assertNotNull(getAccounts().getChildAt(0)); @@ -329,7 +343,7 @@ assertTrue(consent.isShown()); String expectedSharingConsentText = mResources.getString(R.string.account_selection_data_sharing_consent, "idp.org"); - expectedSharingConsentText = expectedSharingConsentText.replaceAll("<[^>]*>", ""); + expectedSharingConsentText = expectedSharingConsentText.replaceAll(LINK_TAG_REGEX, ""); // We use toString() here because otherwise getText() returns a // Spanned, which is not equal to the string we get from the resources. assertEquals("Incorrect data sharing consent text", expectedSharingConsentText, @@ -349,7 +363,9 @@ IdentityProviderMetadata idpMetadata = new IdentityProviderMetadata(expectedTextColor, /*brandBackgroundColor*/ Color.GREEN, "https://icon-url.example", TEST_CONFIG_URL); - mModel.set(ItemProperties.CONTINUE_BUTTON, buildContinueButton(ANA, idpMetadata)); + mModel.set( + ItemProperties.CONTINUE_BUTTON, + buildContinueButton(ANA, idpMetadata, HeaderType.SIGN_IN)); assertEquals(View.VISIBLE, mContentView.getVisibility()); @@ -419,7 +435,9 @@ assertEquals("Incorrect IDP sign in mismatch body dialog text", expectedText, idpSignin.getText().toString()); - mModel.set(ItemProperties.CONTINUE_BUTTON, buildContinueButton(null, null)); + mModel.set( + ItemProperties.CONTINUE_BUTTON, + buildContinueButton(null, TEST_IDP_METADATA, HeaderType.SIGN_IN_TO_IDP_STATIC)); ButtonCompat continueButton = mContentView.findViewById(R.id.account_selection_continue_btn); assertTrue(continueButton.isShown()); @@ -498,16 +516,17 @@ } private PropertyModel buildContinueButton( - Account account, IdentityProviderMetadata idpMetadata) { - PropertyModel.Builder modelBuilder = - new PropertyModel.Builder(ContinueButtonProperties.ALL_KEYS) - .with(ContinueButtonProperties.ACCOUNT, account) - .with(ContinueButtonProperties.ON_CLICK_LISTENER, mAccountCallback); - if (idpMetadata != null) { - modelBuilder.with(ContinueButtonProperties.IDP_METADATA, idpMetadata); - } - - return modelBuilder.build(); + Account account, + IdentityProviderMetadata idpMetadata, + HeaderProperties.HeaderType headerType) { + ContinueButtonProperties.Properties properties = new ContinueButtonProperties.Properties(); + properties.mAccount = account; + properties.mIdpMetadata = idpMetadata; + properties.mOnClickListener = mAccountCallback; + properties.mHeaderType = headerType; + return new PropertyModel.Builder(ContinueButtonProperties.ALL_KEYS) + .with(ContinueButtonProperties.PROPERTIES, properties) + .build(); } private PropertyModel buildDataSharingConsentItem(String idpEtldPlusOne) {
diff --git a/chrome/browser/ui/autofill/payments/card_unmask_otp_input_dialog_controller_impl.h b/chrome/browser/ui/autofill/payments/card_unmask_otp_input_dialog_controller_impl.h index 9741b0a..7b83f8ef 100644 --- a/chrome/browser/ui/autofill/payments/card_unmask_otp_input_dialog_controller_impl.h +++ b/chrome/browser/ui/autofill/payments/card_unmask_otp_input_dialog_controller_impl.h
@@ -9,10 +9,10 @@ #include "base/memory/raw_ptr.h" #include "build/build_config.h" -#include "chrome/browser/ui/autofill/payments/card_unmask_otp_input_dialog_controller.h" #include "chrome/browser/ui/autofill/payments/card_unmask_otp_input_dialog_view.h" #include "components/autofill/core/browser/payments/card_unmask_challenge_option.h" #include "components/autofill/core/browser/payments/otp_unmask_delegate.h" +#include "components/autofill/core/browser/ui/payments/card_unmask_otp_input_dialog_controller.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_user_data.h"
diff --git a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc index 97b059a3..4f9dc24 100644 --- a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc +++ b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc
@@ -679,7 +679,8 @@ ASSERT_NE(nullptr, controller()->GetPaymentBubbleView()); EXPECT_EQ(controller()->GetWindowTitle(), u"Save security code?"); EXPECT_EQ(controller()->GetExplanatoryMessage(), - u"For faster checkout, save the CVC for this card to your device"); + u"This card's CVC will be encrypted and saved to your device for " + u"faster checkout"); } TEST_F(SaveCardBubbleControllerImplTest, UploadCardSaveDialogContent) { @@ -710,8 +711,8 @@ ASSERT_NE(nullptr, controller()->GetPaymentBubbleView()); EXPECT_EQ(controller()->GetWindowTitle(), u"Save security code?"); EXPECT_EQ(controller()->GetExplanatoryMessage(), - u"For faster checkout, save the CVC for this card in your " - u"Google Account"); + u"This card's CVC will be encrypted and saved in your Google " + u"Account for faster checkout"); EXPECT_TRUE(controller()->GetLegalMessageLines().empty()); }
diff --git a/chrome/browser/ui/login/login_handler.cc b/chrome/browser/ui/login/login_handler.cc index 1dea8282..680f213 100644 --- a/chrome/browser/ui/login/login_handler.cc +++ b/chrome/browser/ui/login/login_handler.cc
@@ -16,7 +16,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/synchronization/lock.h" #include "build/build_config.h" -#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/auth_notification_types.h" #include "chrome/browser/password_manager/chrome_password_manager_client.h" #include "chrome/browser/preloading/prefetch/no_state_prefetch/chrome_no_state_prefetch_contents_delegate.h" #include "chrome/browser/tab_contents/tab_util.h"
diff --git a/chrome/browser/ui/login/login_handler_browsertest.cc b/chrome/browser/ui/login/login_handler_browsertest.cc index 59f75c7..fc8994f 100644 --- a/chrome/browser/ui/login/login_handler_browsertest.cc +++ b/chrome/browser/ui/login/login_handler_browsertest.cc
@@ -19,8 +19,8 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" +#include "chrome/browser/auth_notification_types.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/net/proxy_test_utils.h" #include "chrome/browser/profiles/profile.h"
diff --git a/chrome/browser/ui/login/login_handler_test_utils.h b/chrome/browser/ui/login/login_handler_test_utils.h index a8841e5..5fb36ab0 100644 --- a/chrome/browser/ui/login/login_handler_test_utils.h +++ b/chrome/browser/ui/login/login_handler_test_utils.h
@@ -7,7 +7,7 @@ #include <list> -#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/auth_notification_types.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/notification_observer.h" #include "content/public/test/test_utils.h"
diff --git a/chrome/browser/ui/views/autofill/payments/card_unmask_otp_input_dialog_views.cc b/chrome/browser/ui/views/autofill/payments/card_unmask_otp_input_dialog_views.cc index 90ff532..9dc8cc6f 100644 --- a/chrome/browser/ui/views/autofill/payments/card_unmask_otp_input_dialog_views.cc +++ b/chrome/browser/ui/views/autofill/payments/card_unmask_otp_input_dialog_views.cc
@@ -8,11 +8,11 @@ #include "base/strings/strcat.h" #include "base/task/single_thread_task_runner.h" -#include "chrome/browser/ui/autofill/payments/card_unmask_otp_input_dialog_controller.h" #include "chrome/browser/ui/autofill/payments/payments_ui_constants.h" #include "chrome/browser/ui/views/autofill/payments/payments_view_util.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/chrome_typography.h" +#include "components/autofill/core/browser/ui/payments/card_unmask_otp_input_dialog_controller.h" #include "components/constrained_window/constrained_window_views.h" #include "content/public/browser/web_contents.h" #include "ui/color/color_id.h"
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc index 5a7514e..be34963 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc
@@ -161,9 +161,13 @@ tab_search_bubble_host_ = tab_search_button->tab_search_bubble_host(); } + const bool is_close_button_enabled = + !(browser->app_controller() && + browser->app_controller()->IsPreventCloseEnabled()); + caption_button_container_ = AddChildView(std::make_unique<chromeos::FrameCaptionButtonContainerView>( - frame(), std::move(tab_search_button))); + frame(), is_close_button_enabled, std::move(tab_search_button))); // Initializing the TabIconView is expensive, so only do it if we need to. if (browser_view()->ShouldShowWindowIcon()) {
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc index 3d1dbcc..4cf2682 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc
@@ -17,12 +17,14 @@ #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/prevent_close_test_base.h" #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" #include "chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_test_utils.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller.h" #include "chrome/browser/ui/views/frame/immersive_mode_tester.h" +#include "chrome/browser/web_applications/web_app_id_constants.h" #include "chrome/test/base/in_process_browser_test.h" #include "chromeos/constants/chromeos_features.h" #include "chromeos/ui/base/window_properties.h" @@ -1246,6 +1248,73 @@ << SkColorGetB(active_frame_color); } +namespace { + +constexpr char kCalculatorAppUrl[] = "https://calculator.apps.chrome/"; + +constexpr char kPreventCloseEnabledForCalculator[] = R"([ + { + "manifest_id": "https://calculator.apps.chrome/", + "run_on_os_login": "run_windowed", + "prevent_close_after_run_on_os_login": true + } +])"; + +} // namespace + +class PreventCloseBrowserNonClientFrameViewChromeOSTest + : public PreventCloseTestBase { + public: + PreventCloseBrowserNonClientFrameViewChromeOSTest() = default; + + PreventCloseBrowserNonClientFrameViewChromeOSTest( + const PreventCloseBrowserNonClientFrameViewChromeOSTest&) = delete; + PreventCloseBrowserNonClientFrameViewChromeOSTest& operator=( + const PreventCloseBrowserNonClientFrameViewChromeOSTest&) = delete; + + ~PreventCloseBrowserNonClientFrameViewChromeOSTest() override = default; + + views::Button* getWindowCloseButton(Browser* browser) { + auto* const browser_view = BrowserView::GetBrowserViewForBrowser(browser); + auto* const frame_view = GetFrameViewChromeOS(browser_view); + + chromeos::FrameCaptionButtonContainerView::TestApi test_api( + frame_view->caption_button_container()); + return test_api.close_button(); + } +}; + +IN_PROC_BROWSER_TEST_F(PreventCloseBrowserNonClientFrameViewChromeOSTest, + CloseButtonIsDisabled) { + InstallPWA(GURL(kCalculatorAppUrl), web_app::kCalculatorAppId); + SetWebAppSettings(kPreventCloseEnabledForCalculator); + + Browser* const browser = + LaunchPWA(web_app::kCalculatorAppId, /*launch_in_window=*/true); + ASSERT_TRUE(browser); + + auto* const close_button = getWindowCloseButton(browser); + ASSERT_TRUE(close_button); + EXPECT_FALSE(close_button->GetEnabled()); + + ClearWebAppSettings(); +} + +IN_PROC_BROWSER_TEST_F(PreventCloseBrowserNonClientFrameViewChromeOSTest, + CloseButtonIsEnabled) { + InstallPWA(GURL(kCalculatorAppUrl), web_app::kCalculatorAppId); + + Browser* const browser = + LaunchPWA(web_app::kCalculatorAppId, /*launch_in_window=*/true); + ASSERT_TRUE(browser); + + auto* const close_button = getWindowCloseButton(browser); + ASSERT_TRUE(close_button); + EXPECT_TRUE(close_button->GetEnabled()); + + ClearWebAppSettings(); +} + #if BUILDFLAG(IS_CHROMEOS_ASH) IN_PROC_BROWSER_TEST_P(BrowserNonClientFrameViewChromeOSTest, ImmersiveModeTopViewInset) {
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc index e2432e52..cd402ea 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc +++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc
@@ -23,6 +23,7 @@ #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/web_contents.h" +#include "cookie_controls_bubble_view_controller.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/ui_base_features.h" #include "ui/views/vector_icons.h" @@ -90,8 +91,20 @@ web_contents_->GetController().SetNeedsReload(); web_contents_->GetController().LoadIfNecessary(); + SwitchToReloadingView(); +} + +void CookieControlsBubbleViewController::SwitchToReloadingView() { bubble_view_->SwitchToReloadingView(); bubble_view_->GetReloadingView()->RequestFocus(); + + // Set a timeout for how long the reloading view is shown for. + base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + &CookieControlsBubbleViewController::OnReloadingViewTimeout, + weak_factory_.GetWeakPtr()), + content_settings::features::kUserBypassUIReloadBubbleTimeout.Get()); } void CookieControlsBubbleViewController::OnFaviconFetched( @@ -218,8 +231,23 @@ void CookieControlsBubbleViewController:: OnFinishedPageReloadWithChangedSettings() { + // TODO: Log a UserMetricsAction here to count completed page reloads once we + // have confidence that this callback is properly scoped. See + // https://crrev.com/c/4925330 for context. controller_observation_.Reset(); bubble_view_->CloseWidget(); + // View destruction is call asynchronously from the bubble being closed, so we + // invalidate the weak pointers here to avoid callbacks happening after + // the bubble is closed and before this class is destroyed. + weak_factory_.InvalidateWeakPtrs(); +} + +void CookieControlsBubbleViewController::OnReloadingViewTimeout() { + base::RecordAction( + base::UserMetricsAction("CookieControls.Bubble.ReloadingTimeout")); + controller_observation_.Reset(); + bubble_view_->CloseWidget(); + weak_factory_.InvalidateWeakPtrs(); } void CookieControlsBubbleViewController::SetCallbacks() {
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h index b847ea8..0ad389c 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h +++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h
@@ -53,6 +53,9 @@ void OnFaviconFetched(const favicon_base::FaviconImageResult& result) const; + void OnReloadingViewTimeout(); + + void SwitchToReloadingView(); void ApplyThirdPartyCookiesAllowedState(base::Time expiration); void ApplyThirdPartyCookiesBlockedState();
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_impl.cc b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_impl.cc index 25c5e64..9559c08 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_impl.cc +++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_impl.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_impl.h" #include <string> +#include "base/metrics/user_metrics.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/views/accessibility/non_accessible_image_view.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" @@ -79,6 +80,8 @@ } void CookieControlsBubbleViewImpl::SwitchToReloadingView() { + base::RecordAction( + base::UserMetricsAction("CookieControls.Bubble.ReloadingShown")); GetReloadingView()->SetVisible(true); GetContentView()->SetVisible(false); SizeToContents();
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc index 4273d18..019b605 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc +++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc
@@ -42,6 +42,9 @@ const char kUMABubbleBlockThirdPartyCookies[] = "CookieControls.Bubble.BlockThirdPartyCookies"; const char kUMABubbleSendFeedback[] = "CookieControls.Bubble.SendFeedback"; +const char kUMABubbleReloadingShown[] = "CookieControls.Bubble.ReloadingShown"; +const char kUMABubbleReloadingTimeout[] = + "CookieControls.Bubble.ReloadingTimeout"; } // namespace class CookieControlsInteractiveUiTest : public InteractiveBrowserTest { @@ -57,7 +60,7 @@ iph_feature_list_.InitAndEnableFeatures(EnabledFeatures(), DisabledFeatures()); https_server()->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES); - https_server()->ServeFilesFromSourceDirectory(GetChromeTestDataDir()); + https_server()->AddDefaultHandlers(GetChromeTestDataDir()); set_open_about_blank_on_browser_launch(true); ASSERT_TRUE(https_server()->InitializeAndListen()); @@ -179,9 +182,17 @@ content_settings::CookieSettings* cookie_settings() { return CookieSettingsFactory::GetForProfile(browser()->profile()).get(); } - GURL third_party_cookie_page_url() { - return https_server()->GetURL("a.test", - "/third_party_partitioned_cookies.html"); + + // If slow is set to true will return a URL for a page that never finishes + // loading. + GURL third_party_cookie_page_url(bool slow = false) { + if (slow) { + return https_server()->GetURL( + "a.test", "/third_party_partitioned_cookies_slow.html"); + } else { + return https_server()->GetURL("a.test", + "/third_party_partitioned_cookies.html"); + } } static base::Time GetReferenceTime() { @@ -441,6 +452,36 @@ WaitForHide(CookieControlsBubbleView::kCookieControlsBubble)); EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleAllowThirdPartyCookies), 1); EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleBlockThirdPartyCookies), 0); + EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleReloadingTimeout), 0); + EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleReloadingShown), 1); +} + +IN_PROC_BROWSER_TEST_F(CookieControlsInteractiveUiTest, ReloadViewTimeout) { + // Test that opening the bubble, then closing it after making a change, + // results in the reload view being displayed and then timing out. + // + // The page loaded in this test will never finish loading, so the timeout + // must be configured shorter than the test timeout. + BlockThirdPartyCookies(); + RunTestSequence( + /*context(),*/ InstrumentTab(kWebContentsElementId), + EnterText(kOmniboxElementId, + base::UTF8ToUTF16( + "https://" + + third_party_cookie_page_url(/*slow=*/true).GetContent())), + Confirm(kOmniboxElementId), + InAnyContext(WaitForShow(kCookieControlsIconElementId)), + PressButton(kCookieControlsIconElementId), + InAnyContext(WaitForShow(CookieControlsBubbleView::kContentView)), + PressButton(CookieControlsContentView::kToggleButton), + PressButton(kLocationIconElementId), + InAnyContext(WaitForShow(CookieControlsBubbleView::kReloadingView)), + WaitForHide(CookieControlsBubbleView::kCookieControlsBubble)); + + EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleAllowThirdPartyCookies), 1); + EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleBlockThirdPartyCookies), 0); + EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleReloadingTimeout), 1); + EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleReloadingShown), 1); } IN_PROC_BROWSER_TEST_F(CookieControlsInteractiveUiTest, @@ -484,6 +525,7 @@ PressButton(kLocationIconElementId), EnsureNotPresent(CookieControlsBubbleView::kReloadingView), WaitForHide(CookieControlsBubbleView::kCookieControlsBubble)); + EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleReloadingTimeout), 0); } IN_PROC_BROWSER_TEST_F(CookieControlsInteractiveUiTest, @@ -527,6 +569,8 @@ PressButton(kLocationIconElementId), InAnyContext(WaitForShow(CookieControlsBubbleView::kReloadingView)), WaitForHide(CookieControlsBubbleView::kCookieControlsBubble)); + EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleReloadingTimeout), 0); + EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleReloadingShown), 1); } IN_PROC_BROWSER_TEST_F(CookieControlsInteractiveUiTest, @@ -571,6 +615,8 @@ PressButton(kLocationIconElementId), EnsureNotPresent(CookieControlsBubbleView::kReloadingView), WaitForHide(CookieControlsBubbleView::kCookieControlsBubble)); + EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleReloadingTimeout), 0); + EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleReloadingShown), 0); } IN_PROC_BROWSER_TEST_F(CookieControlsInteractiveUiTest, NoReloadView) { @@ -590,4 +636,6 @@ EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleAllowThirdPartyCookies), 1); EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleBlockThirdPartyCookies), 1); EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleSendFeedback), 0); + EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleReloadingShown), 0); + EXPECT_EQ(user_actions_.GetActionCount(kUMABubbleReloadingTimeout), 0); }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc b/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc index 24506e1..5d9c4cd 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc
@@ -451,7 +451,7 @@ DISTANCE_OMNIBOX_TWO_LINE_CELL_VERTICAL_PADDING); } const int right_margin = OmniboxFieldTrial::IsActionsUISimplificationEnabled() - ? 11 + ? 7 : OmniboxMatchCellView::kMarginRight; return gfx::Insets::TLBR(vertical_margin, OmniboxMatchCellView::kMarginLeft, vertical_margin, right_margin);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc b/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc index 01f38824..6cc4d77 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc
@@ -335,9 +335,11 @@ } if (OmniboxFieldTrial::IsActionsUISimplificationEnabled() && first_button) { + // Apply a left margin of 4px (rather than zero) in order to make room for + // the focus ring that gets rendered around action chips. first_button->SetProperty( views::kMarginsKey, - gfx::Insets::TLBR(0, 0, 0, + gfx::Insets::TLBR(0, 4, 0, ChromeLayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_BUTTON_HORIZONTAL))); }
diff --git a/chrome/browser/ui/views/performance_controls/high_efficiency_interactive_ui_test.cc b/chrome/browser/ui/views/performance_controls/high_efficiency_interactive_ui_test.cc index ef8555a..62065dd 100644 --- a/chrome/browser/ui/views/performance_controls/high_efficiency_interactive_ui_test.cc +++ b/chrome/browser/ui/views/performance_controls/high_efficiency_interactive_ui_test.cc
@@ -228,7 +228,6 @@ StateChange video_is_playing; video_is_playing.event = kVideoIsPlaying; video_is_playing.where = video; - video_is_playing.type = StateChange::Type::kConditionTrue; video_is_playing.test_function = kMediaIsPlaying; RunTestSequence(
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.cc b/chrome/browser/ui/web_applications/app_browser_controller.cc index a1850498..c4d1219 100644 --- a/chrome/browser/ui/web_applications/app_browser_controller.cc +++ b/chrome/browser/ui/web_applications/app_browser_controller.cc
@@ -24,6 +24,8 @@ #include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/tabs/tab_menu_model_factory.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/common/themes/autogenerated_theme_util.h" @@ -298,6 +300,14 @@ return true; } +bool AppBrowserController::IsPreventCloseEnabled() const { + auto* provider = WebAppProvider::GetForWebApps(browser()->profile()); + if (!provider) { + return false; + } + return provider->registrar_unsafe().IsPreventCloseEnabled(app_id()); +} + #if !BUILDFLAG(IS_CHROMEOS) bool AppBrowserController::HasProfileMenuButton() const { return false;
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.h b/chrome/browser/ui/web_applications/app_browser_controller.h index 7c8a0f6..29cdbcdf 100644 --- a/chrome/browser/ui/web_applications/app_browser_controller.h +++ b/chrome/browser/ui/web_applications/app_browser_controller.h
@@ -213,6 +213,9 @@ // Whether the browser should show the reload button in the toolbar. virtual bool HasReloadButton() const; + // Returns whether prevent close is enabled. + bool IsPreventCloseEnabled() const; + #if !BUILDFLAG(IS_CHROMEOS) // Whether the browser should show the profile menu button in the toolbar. // Not appliccable to ChromeOS, because apps can be installed only for
diff --git a/chrome/browser/ui/webui/ash/cellular_setup/cellular_setup_localized_strings_provider.cc b/chrome/browser/ui/webui/ash/cellular_setup/cellular_setup_localized_strings_provider.cc index facd6945..2bb2e43 100644 --- a/chrome/browser/ui/webui/ash/cellular_setup/cellular_setup_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/ash/cellular_setup/cellular_setup_localized_strings_provider.cc
@@ -101,7 +101,14 @@ {"profileDiscoveryConsentScan", IDS_CELLULAR_SETUP_ESIM_PAGE_PROFILE_DISCOVERY_CONSENT_SCAN}, {"profileDiscoveryConsentCancel", - IDS_CELLULAR_SETUP_ESIM_PAGE_PROFILE_DISCOVERY_CONSENT_CANCEL}}; + IDS_CELLULAR_SETUP_ESIM_PAGE_PROFILE_DISCOVERY_CONSENT_CANCEL}, + {"profileDiscoveryPageTitle", + IDS_CELLULAR_SETUP_PROFILE_DISCOVERY_PAGE_TITLE}, + {"confimationCodePageTitle", + IDS_CELLULAR_SETUP_CONFIRMATION_CODE_PAGE_TITLE}, + {"profileLoadingPageTitle", IDS_CELLULAR_SETUP_ESIM_PROFILE_LOADING_TITLE}, + {"profileLoadingPageMessage", + IDS_CELLULAR_SETUP_ESIM_PROFILE_LOADING_MESSAGE}}; struct NamedBoolean { const char* name;
diff --git a/chrome/browser/ui/webui/ash/lock_screen_reauth/lock_screen_reauth_dialogs.cc b/chrome/browser/ui/webui/ash/lock_screen_reauth/lock_screen_reauth_dialogs.cc index 9ca9f6be..7e348ddc 100644 --- a/chrome/browser/ui/webui/ash/lock_screen_reauth/lock_screen_reauth_dialogs.cc +++ b/chrome/browser/ui/webui/ash/lock_screen_reauth/lock_screen_reauth_dialogs.cc
@@ -18,8 +18,8 @@ #include "chrome/browser/ash/login/profile_auth_data.h" #include "chrome/browser/ash/login/ui/oobe_dialog_size_utils.h" #include "chrome/browser/ash/profiles/profile_helper.h" +#include "chrome/browser/auth_notification_types.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h"
diff --git a/chrome/browser/ui/webui/ash/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/ash/login/gaia_screen_handler.cc index 45bcb56..6422eb2 100644 --- a/chrome/browser/ui/webui/ash/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/ash/login/gaia_screen_handler.cc
@@ -57,12 +57,12 @@ #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/ash/profiles/signin_profile_handler.h" #include "chrome/browser/ash/settings/cros_settings.h" +#include "chrome/browser/auth_notification_types.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/certificate_provider/certificate_provider_service.h" #include "chrome/browser/certificate_provider/certificate_provider_service_factory.h" #include "chrome/browser/certificate_provider/pin_dialog_manager.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/lifetime/browser_shutdown.h" #include "chrome/browser/net/nss_temp_certs_cache_chromeos.h" #include "chrome/browser/net/system_network_context_manager.h"
diff --git a/chrome/browser/ui/webui/ash/settings/pages/files/files_section.cc b/chrome/browser/ui/webui/ash/settings/pages/files/files_section.cc index c32c46e..5121873 100644 --- a/chrome/browser/ui/webui/ash/settings/pages/files/files_section.cc +++ b/chrome/browser/ui/webui/ash/settings/pages/files/files_section.cc
@@ -191,8 +191,6 @@ IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_TURN_OFF_BODY_TEXT}, {"googleDriveFileSyncListingFilesTitle", IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_TITLE_TEXT}, - {"googleDriveFileSyncListingFilesBody", - IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_BODY_TEXT}, {"googleDriveFileSyncListingFilesItemsFoundBody", IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_ITEMS_FOUND_BODY_TEXT}, {"googleDriveNotEnoughSpaceTitle",
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index 7b471b89..122a3d93d 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -201,9 +201,10 @@ #endif #if BUILDFLAG(IS_CHROMEOS) +#include "chrome/browser/ui/webui/dlp_internals/dlp_internals_ui.h" #include "chromeos/crosapi/cpp/gurl_os_handler_utils.h" #include "url/url_util.h" -#endif +#endif // BUILDFLAG(IS_CHROMEOS) #if !BUILDFLAG(IS_CHROMEOS_LACROS) #include "chrome/browser/ui/webui/bluetooth_internals/bluetooth_internals_ui.h" // nogncheck @@ -831,6 +832,11 @@ if (url.host_piece() == chrome::kChromeUIWebAppSettingsHost) return &NewWebUI<WebAppSettingsUI>; #endif +#if BUILDFLAG(IS_CHROMEOS) + if (url.host_piece() == chrome::kChromeUIDlpInternalsHost) { + return &NewWebUI<policy::DlpInternalsUI>; + } +#endif if (IsAboutUI(url)) return &NewWebUI<AboutUI>; @@ -1127,6 +1133,7 @@ GURL(chrome::kChromeUIComponentsUrl), GURL(chrome::kChromeUICreditsURL), GURL(chrome::kChromeUIDeviceLogUrl), + GURL(chrome::kChromeUIDlpInternalsURL), GURL(chrome::kChromeUIExtensionsInternalsURL), GURL(chrome::kChromeUIExtensionsURL), GURL(chrome::kChromeUIFlagsURL),
diff --git a/chrome/browser/ui/webui/dlp_internals/OWNERS b/chrome/browser/ui/webui/dlp_internals/OWNERS new file mode 100644 index 0000000..8557d1b --- /dev/null +++ b/chrome/browser/ui/webui/dlp_internals/OWNERS
@@ -0,0 +1 @@ +file://chrome/browser/chromeos/policy/dlp/OWNERS \ No newline at end of file
diff --git a/chrome/browser/ui/webui/dlp_internals/dlp_internals_ui.cc b/chrome/browser/ui/webui/dlp_internals/dlp_internals_ui.cc new file mode 100644 index 0000000..2e312f794 --- /dev/null +++ b/chrome/browser/ui/webui/dlp_internals/dlp_internals_ui.cc
@@ -0,0 +1,24 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/dlp_internals/dlp_internals_ui.h" + +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/url_constants.h" +#include "content/public/browser/web_ui_data_source.h" + +namespace policy { + +DlpInternalsUI::DlpInternalsUI(content::WebUI* web_ui) + : ui::MojoWebUIController(web_ui) { + Profile* profile = Profile::FromWebUI(web_ui); + content::WebUIDataSource::CreateAndAdd(profile, + chrome::kChromeUIDlpInternalsHost); +} + +WEB_UI_CONTROLLER_TYPE_IMPL(DlpInternalsUI) + +DlpInternalsUI::~DlpInternalsUI() = default; + +} // namespace policy
diff --git a/chrome/browser/ui/webui/dlp_internals/dlp_internals_ui.h b/chrome/browser/ui/webui/dlp_internals/dlp_internals_ui.h new file mode 100644 index 0000000..c5e0610 --- /dev/null +++ b/chrome/browser/ui/webui/dlp_internals/dlp_internals_ui.h
@@ -0,0 +1,28 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_DLP_INTERNALS_DLP_INTERNALS_UI_H_ +#define CHROME_BROWSER_UI_WEBUI_DLP_INTERNALS_DLP_INTERNALS_UI_H_ + +#include "ui/webui/mojo_web_ui_controller.h" + +namespace policy { + +// UI controller for chrome://dlp-internals. +class DlpInternalsUI : public ui::MojoWebUIController { + public: + explicit DlpInternalsUI(content::WebUI* web_ui); + + DlpInternalsUI(const DlpInternalsUI&) = delete; + DlpInternalsUI& operator=(const DlpInternalsUI&) = delete; + + ~DlpInternalsUI() override; + + private: + WEB_UI_CONTROLLER_TYPE_DECL(); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_UI_WEBUI_DLP_INTERNALS_DLP_INTERNALS_UI_H_
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.cc b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.cc index da52e25e7..5546bda 100644 --- a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.cc +++ b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.cc
@@ -235,285 +235,6 @@ } } -void CustomizeChromePageHandler::OnDescriptorsRetrieved( - std::unique_ptr<std::string> response_body) { - if (!response_body) { - // Network errors (i.e. the server did not provide a response). - DVLOG(1) << "Request failed with error: " << simple_url_loader_->NetError(); - std::move(get_descriptors_callback_).Run(nullptr); - return; - } - - std::string response; - response.swap(*response_body); - // The response may start with . Ignore this. - const char kXSSIResponsePreamble[] = ")]}'"; - if (base::StartsWith(response, kXSSIResponsePreamble, - base::CompareCase::SENSITIVE)) { - response = response.substr(strlen(kXSSIResponsePreamble)); - } - data_decoder_->ParseJson( - response, - base::BindOnce(&CustomizeChromePageHandler::OnDescriptorsJsonParsed, - weak_ptr_factory_.GetWeakPtr())); -} - -void CustomizeChromePageHandler::OnDescriptorsJsonParsed( - data_decoder::DataDecoder::ValueOrError result) { - if (!result.has_value() || !result->is_dict()) { - DVLOG(1) << "Parsing JSON failed: " << result.error(); - std::move(get_descriptors_callback_).Run(nullptr); - return; - } - - const base::Value::List* descriptor_a = - result->GetDict().FindList("descriptor_a"); - const base::Value::List* descriptor_b = - result->GetDict().FindList("descriptor_b"); - const base::Value::List* descriptor_c_labels = - result->GetDict().FindList("descriptor_c"); - if (!descriptor_a || !descriptor_b || !descriptor_c_labels) { - DVLOG(1) << "Parsing JSON failed: no valid descriptors."; - std::move(get_descriptors_callback_).Run(nullptr); - return; - } - - std::vector<side_panel::mojom::DescriptorAPtr> mojo_descriptor_a_list; - if (descriptor_a) { - for (const auto& descriptor : *descriptor_a) { - const base::Value::Dict& descriptor_a_dict = descriptor.GetDict(); - auto* category = descriptor_a_dict.FindString("category"); - auto* label_values = descriptor_a_dict.FindList("labels"); - if (!category || !label_values) { - continue; - } - auto mojo_descriptor_a = side_panel::mojom::DescriptorA::New(); - mojo_descriptor_a->category = *category; - std::vector<std::string> labels; - for (const auto& label_value : *label_values) { - labels.push_back(label_value.GetString()); - } - mojo_descriptor_a->labels = std::move(labels); - mojo_descriptor_a_list.push_back(std::move(mojo_descriptor_a)); - } - } - auto mojo_descriptors = side_panel::mojom::Descriptors::New(); - mojo_descriptors->descriptor_a = std::move(mojo_descriptor_a_list); - std::vector<side_panel::mojom::DescriptorBPtr> mojo_descriptor_b_list; - if (descriptor_b) { - for (const auto& descriptor : *descriptor_b) { - const base::Value::Dict& descriptor_b_dict = descriptor.GetDict(); - auto* label = descriptor_b_dict.FindString("label"); - auto* image_path = descriptor_b_dict.FindString("image"); - if (!label || !image_path) { - continue; - } - auto mojo_descriptor_b = side_panel::mojom::DescriptorB::New(); - mojo_descriptor_b->label = *label; - mojo_descriptor_b->image_path = *image_path; - mojo_descriptor_b_list.push_back(std::move(mojo_descriptor_b)); - } - } - mojo_descriptors->descriptor_b = std::move(mojo_descriptor_b_list); - std::vector<std::string> mojo_descriptor_c_labels; - if (descriptor_c_labels) { - for (const auto& label_value : *descriptor_c_labels) { - mojo_descriptor_c_labels.push_back(label_value.GetString()); - } - } - mojo_descriptors->descriptor_c = std::move(mojo_descriptor_c_labels); - std::move(get_descriptors_callback_).Run(std::move(mojo_descriptors)); -} - -void CustomizeChromePageHandler::WallpaperSearchCallback( - SearchWallpaperCallback callback, - optimization_guide::OptimizationGuideModelExecutionResult result) { - if (!result.has_value()) { - return; - } - auto response = optimization_guide::ParsedAnyMetadata< - chrome_intelligence_modelexecution_proto::WallpaperSearchResponse>( - result.value()); - if (response->images_size() < 1) { - return; - } - if (ntp_custom_background_service_) { - ntp_custom_background_service_->SelectLocalBackgroundImage( - response->images(0)); - } - std::move(callback).Run(true); -} - -void CustomizeChromePageHandler::GetDescriptors( - GetDescriptorsCallback callback) { - callback = - mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(callback), nullptr); - if (get_descriptors_callback_) { - return; - } - get_descriptors_callback_ = std::move(callback); - - net::NetworkTrafficAnnotationTag traffic_annotation = - net::DefineNetworkTrafficAnnotation("customize_chrome_page_handler", R"( - semantics { - sender: "Customize Chrome" - description: - "This service downloads different configurations " - "for Customize Chrome." - trigger: - "Opening Customize Chrome on the Desktop NTP, " - "if Google is the default search provider " - "and the user is signed in." - data: "None." - destination: GOOGLE_OWNED_SERVICE - internal { - contacts { - email: "chrome-desktop-ntp@google.com" - } - } - user_data { - type: NONE - } - last_reviewed: "2023-10-10" - } - policy { - cookies_allowed: NO - setting: - "Users can control this feature by signing out or " - "selecting a non-Google default search engine in Chrome " - "settings under 'Search Engine'." - chrome_policy { - DefaultSearchProviderEnabled { - policy_options {mode: MANDATORY} - DefaultSearchProviderEnabled: false - } - } - })"); - - auto resource_request = std::make_unique<network::ResourceRequest>(); - resource_request->url = GURL( - "https://static.corp.google.com/chrome-wallpaper-search/" - "descriptors_en-US.json"); - resource_request->request_initiator = - url::Origin::Create(GURL(chrome::kChromeUINewTabURL)); - simple_url_loader_ = network::SimpleURLLoader::Create( - std::move(resource_request), traffic_annotation); - simple_url_loader_->DownloadToString( - profile_->GetURLLoaderFactory().get(), - base::BindOnce(&CustomizeChromePageHandler::OnDescriptorsRetrieved, - weak_ptr_factory_.GetWeakPtr()), - 1024 * 1024); -} - -void CustomizeChromePageHandler::SearchWallpaper( - const std::string& query, - SearchWallpaperCallback callback) { - callback = - mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(callback), false); - if (!base::FeatureList::IsEnabled( - ntp_features::kCustomizeChromeWallpaperSearch) || - !base::FeatureList::IsEnabled( - optimization_guide::features::kOptimizationGuideModelExecution)) { - return; - } - auto* optimization_guide_keyed_service = - OptimizationGuideKeyedServiceFactory::GetForProfile(profile_); - if (!optimization_guide_keyed_service) { - return; - } - chrome_intelligence_modelexecution_proto::WallpaperSearchRequest request; - request.set_query(query); - optimization_guide_keyed_service->ExecuteModel( - optimization_guide::proto::ModelExecutionFeature:: - MODEL_EXECUTION_FEATURE_WALLPAPER_SEARCH, - request, - base::BindOnce(&CustomizeChromePageHandler::WallpaperSearchCallback, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); -} - -// Save the full sized bitmaps and create a much smaller image version of each -// for sending back to the UI through the callback. Re-encode the bitmap and -// make it base64 for easy reading by the UI. -void CustomizeChromePageHandler::OnWallpaperSearchResultsDecoded( - GetWallpaperSearchResultsCallback callback, - std::vector<SkBitmap> bitmaps) { - std::vector<std::string> thumbnails; - wallpaper_search_results_.clear(); - - for (auto& bitmap : bitmaps) { - SkBitmap small_bitmap = skia::ImageOperations::Resize( - bitmap, skia::ImageOperations::RESIZE_GOOD, 200, 200); - std::vector<unsigned char> encoded; - const bool success = gfx::PNGCodec::EncodeBGRASkBitmap( - small_bitmap, /*discard_transparency=*/false, &encoded); - if (success) { - thumbnails.push_back(base::Base64Encode(encoded)); - wallpaper_search_results_.push_back(bitmap); - } - } - - std::move(callback).Run(thumbnails); -} - -void CustomizeChromePageHandler::OnGotWallpaperSearchResults( - GetWallpaperSearchResultsCallback callback, - optimization_guide::OptimizationGuideModelExecutionResult result) { - if (!result.has_value()) { - return; - } - auto response = optimization_guide::ParsedAnyMetadata< - chrome_intelligence_modelexecution_proto::WallpaperSearchResponse>( - result.value()); - if (response->images().empty()) { - return; - } - auto barrier = base::BarrierCallback<SkBitmap>( - response->images_size(), - base::BindOnce( - &CustomizeChromePageHandler::OnWallpaperSearchResultsDecoded, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); - - // Decode each image that is sent back for security purposes. Switched them - // from gfx::Image to SkBitmap before passing to the barrier callback because - // of some issues with const gfx::Image& and base::BarrierCallback. - for (auto& image : response->images()) { - image_decoder_->DecodeImage( - image, gfx::Size(), nullptr, - base::BindOnce( - [](base::RepeatingCallback<void(SkBitmap)> barrier, - const gfx::Image& image) { - std::move(barrier).Run(image.AsBitmap()); - }, - barrier)); - } -} - -void CustomizeChromePageHandler::GetWallpaperSearchResults( - const std::string& query, - GetWallpaperSearchResultsCallback callback) { - callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun( - std::move(callback), std::vector<std::string>()); - if (!base::FeatureList::IsEnabled( - ntp_features::kCustomizeChromeWallpaperSearch) || - !base::FeatureList::IsEnabled( - optimization_guide::features::kOptimizationGuideModelExecution)) { - return; - } - auto* optimization_guide_keyed_service = - OptimizationGuideKeyedServiceFactory::GetForProfile(profile_); - if (!optimization_guide_keyed_service) { - return; - } - chrome_intelligence_modelexecution_proto::WallpaperSearchRequest request; - request.set_query(query); - optimization_guide_keyed_service->ExecuteModel( - optimization_guide::proto::ModelExecutionFeature:: - MODEL_EXECUTION_FEATURE_WALLPAPER_SEARCH, - request, - base::BindOnce(&CustomizeChromePageHandler::OnGotWallpaperSearchResults, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); -} - void CustomizeChromePageHandler::UpdateTheme() { if (ntp_custom_background_service_) { ntp_custom_background_service_->RefreshBackgroundIfNeeded(); @@ -665,6 +386,286 @@ ScrollToSection(last_requested_section_); } +void CustomizeChromePageHandler::GetDescriptors( + GetDescriptorsCallback callback) { + callback = + mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(callback), nullptr); + if (get_descriptors_callback_) { + return; + } + get_descriptors_callback_ = std::move(callback); + + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("customize_chrome_page_handler", R"( + semantics { + sender: "Customize Chrome" + description: + "This service downloads different configurations " + "for Customize Chrome." + trigger: + "Opening Customize Chrome on the Desktop NTP, " + "if Google is the default search provider " + "and the user is signed in." + data: "None." + destination: GOOGLE_OWNED_SERVICE + internal { + contacts { + email: "chrome-desktop-ntp@google.com" + } + } + user_data { + type: NONE + } + last_reviewed: "2023-10-10" + } + policy { + cookies_allowed: NO + setting: + "Users can control this feature by signing out or " + "selecting a non-Google default search engine in Chrome " + "settings under 'Search Engine'." + chrome_policy { + DefaultSearchProviderEnabled { + policy_options {mode: MANDATORY} + DefaultSearchProviderEnabled: false + } + } + })"); + + auto resource_request = std::make_unique<network::ResourceRequest>(); + resource_request->url = GURL( + "https://static.corp.google.com/chrome-wallpaper-search/" + "descriptors_en-US.json"); + resource_request->request_initiator = + url::Origin::Create(GURL(chrome::kChromeUINewTabURL)); + simple_url_loader_ = network::SimpleURLLoader::Create( + std::move(resource_request), traffic_annotation); + simple_url_loader_->DownloadToString( + profile_->GetURLLoaderFactory().get(), + base::BindOnce(&CustomizeChromePageHandler::OnDescriptorsRetrieved, + weak_ptr_factory_.GetWeakPtr()), + 1024 * 1024); +} + +void CustomizeChromePageHandler::SearchWallpaper( + const std::string& query, + SearchWallpaperCallback callback) { + callback = + mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(callback), false); + if (!base::FeatureList::IsEnabled( + ntp_features::kCustomizeChromeWallpaperSearch) || + !base::FeatureList::IsEnabled( + optimization_guide::features::kOptimizationGuideModelExecution)) { + return; + } + auto* optimization_guide_keyed_service = + OptimizationGuideKeyedServiceFactory::GetForProfile(profile_); + if (!optimization_guide_keyed_service) { + return; + } + chrome_intelligence_modelexecution_proto::WallpaperSearchRequest request; + request.set_query(query); + optimization_guide_keyed_service->ExecuteModel( + optimization_guide::proto::ModelExecutionFeature:: + MODEL_EXECUTION_FEATURE_WALLPAPER_SEARCH, + request, + base::BindOnce(&CustomizeChromePageHandler::WallpaperSearchCallback, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} + +void CustomizeChromePageHandler::GetWallpaperSearchResults( + const std::string& query, + GetWallpaperSearchResultsCallback callback) { + callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun( + std::move(callback), std::vector<std::string>()); + if (!base::FeatureList::IsEnabled( + ntp_features::kCustomizeChromeWallpaperSearch) || + !base::FeatureList::IsEnabled( + optimization_guide::features::kOptimizationGuideModelExecution)) { + return; + } + auto* optimization_guide_keyed_service = + OptimizationGuideKeyedServiceFactory::GetForProfile(profile_); + if (!optimization_guide_keyed_service) { + return; + } + chrome_intelligence_modelexecution_proto::WallpaperSearchRequest request; + request.set_query(query); + optimization_guide_keyed_service->ExecuteModel( + optimization_guide::proto::ModelExecutionFeature:: + MODEL_EXECUTION_FEATURE_WALLPAPER_SEARCH, + request, + base::BindOnce( + &CustomizeChromePageHandler::OnWallpaperSearchResultsRetrieved, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} + +void CustomizeChromePageHandler::OnDescriptorsRetrieved( + std::unique_ptr<std::string> response_body) { + if (!response_body) { + // Network errors (i.e. the server did not provide a response). + DVLOG(1) << "Request failed with error: " << simple_url_loader_->NetError(); + std::move(get_descriptors_callback_).Run(nullptr); + return; + } + + std::string response; + response.swap(*response_body); + // The response may start with . Ignore this. + const char kXSSIResponsePreamble[] = ")]}'"; + if (base::StartsWith(response, kXSSIResponsePreamble, + base::CompareCase::SENSITIVE)) { + response = response.substr(strlen(kXSSIResponsePreamble)); + } + data_decoder_->ParseJson( + response, + base::BindOnce(&CustomizeChromePageHandler::OnDescriptorsJsonParsed, + weak_ptr_factory_.GetWeakPtr())); +} + +void CustomizeChromePageHandler::OnDescriptorsJsonParsed( + data_decoder::DataDecoder::ValueOrError result) { + if (!result.has_value() || !result->is_dict()) { + DVLOG(1) << "Parsing JSON failed: " << result.error(); + std::move(get_descriptors_callback_).Run(nullptr); + return; + } + + const base::Value::List* descriptor_a = + result->GetDict().FindList("descriptor_a"); + const base::Value::List* descriptor_b = + result->GetDict().FindList("descriptor_b"); + const base::Value::List* descriptor_c_labels = + result->GetDict().FindList("descriptor_c"); + if (!descriptor_a || !descriptor_b || !descriptor_c_labels) { + DVLOG(1) << "Parsing JSON failed: no valid descriptors."; + std::move(get_descriptors_callback_).Run(nullptr); + return; + } + + std::vector<side_panel::mojom::DescriptorAPtr> mojo_descriptor_a_list; + if (descriptor_a) { + for (const auto& descriptor : *descriptor_a) { + const base::Value::Dict& descriptor_a_dict = descriptor.GetDict(); + auto* category = descriptor_a_dict.FindString("category"); + auto* label_values = descriptor_a_dict.FindList("labels"); + if (!category || !label_values) { + continue; + } + auto mojo_descriptor_a = side_panel::mojom::DescriptorA::New(); + mojo_descriptor_a->category = *category; + std::vector<std::string> labels; + for (const auto& label_value : *label_values) { + labels.push_back(label_value.GetString()); + } + mojo_descriptor_a->labels = std::move(labels); + mojo_descriptor_a_list.push_back(std::move(mojo_descriptor_a)); + } + } + auto mojo_descriptors = side_panel::mojom::Descriptors::New(); + mojo_descriptors->descriptor_a = std::move(mojo_descriptor_a_list); + std::vector<side_panel::mojom::DescriptorBPtr> mojo_descriptor_b_list; + if (descriptor_b) { + for (const auto& descriptor : *descriptor_b) { + const base::Value::Dict& descriptor_b_dict = descriptor.GetDict(); + auto* label = descriptor_b_dict.FindString("label"); + auto* image_path = descriptor_b_dict.FindString("image"); + if (!label || !image_path) { + continue; + } + auto mojo_descriptor_b = side_panel::mojom::DescriptorB::New(); + mojo_descriptor_b->label = *label; + mojo_descriptor_b->image_path = *image_path; + mojo_descriptor_b_list.push_back(std::move(mojo_descriptor_b)); + } + } + mojo_descriptors->descriptor_b = std::move(mojo_descriptor_b_list); + std::vector<std::string> mojo_descriptor_c_labels; + if (descriptor_c_labels) { + for (const auto& label_value : *descriptor_c_labels) { + mojo_descriptor_c_labels.push_back(label_value.GetString()); + } + } + mojo_descriptors->descriptor_c = std::move(mojo_descriptor_c_labels); + std::move(get_descriptors_callback_).Run(std::move(mojo_descriptors)); +} + +void CustomizeChromePageHandler::WallpaperSearchCallback( + SearchWallpaperCallback callback, + optimization_guide::OptimizationGuideModelExecutionResult result) { + if (!result.has_value()) { + return; + } + auto response = optimization_guide::ParsedAnyMetadata< + chrome_intelligence_modelexecution_proto::WallpaperSearchResponse>( + result.value()); + if (response->images_size() < 1) { + return; + } + if (ntp_custom_background_service_) { + ntp_custom_background_service_->SelectLocalBackgroundImage( + response->images(0)); + } + std::move(callback).Run(true); +} + +void CustomizeChromePageHandler::OnWallpaperSearchResultsRetrieved( + GetWallpaperSearchResultsCallback callback, + optimization_guide::OptimizationGuideModelExecutionResult result) { + if (!result.has_value()) { + return; + } + auto response = optimization_guide::ParsedAnyMetadata< + chrome_intelligence_modelexecution_proto::WallpaperSearchResponse>( + result.value()); + if (response->images().empty()) { + return; + } + auto barrier = base::BarrierCallback<SkBitmap>( + response->images_size(), + base::BindOnce( + &CustomizeChromePageHandler::OnWallpaperSearchResultsDecoded, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + + // Decode each image that is sent back for security purposes. Switched them + // from gfx::Image to SkBitmap before passing to the barrier callback because + // of some issues with const gfx::Image& and base::BarrierCallback. + for (auto& image : response->images()) { + image_decoder_->DecodeImage( + image, gfx::Size(), nullptr, + base::BindOnce( + [](base::RepeatingCallback<void(SkBitmap)> barrier, + const gfx::Image& image) { + std::move(barrier).Run(image.AsBitmap()); + }, + barrier)); + } +} + +// Save the full sized bitmaps and create a much smaller image version of each +// for sending back to the UI through the callback. Re-encode the bitmap and +// make it base64 for easy reading by the UI. +void CustomizeChromePageHandler::OnWallpaperSearchResultsDecoded( + GetWallpaperSearchResultsCallback callback, + std::vector<SkBitmap> bitmaps) { + std::vector<std::string> thumbnails; + wallpaper_search_results_.clear(); + + for (auto& bitmap : bitmaps) { + SkBitmap small_bitmap = skia::ImageOperations::Resize( + bitmap, skia::ImageOperations::RESIZE_GOOD, 200, 200); + std::vector<unsigned char> encoded; + const bool success = gfx::PNGCodec::EncodeBGRASkBitmap( + small_bitmap, /*discard_transparency=*/false, &encoded); + if (success) { + thumbnails.push_back(base::Base64Encode(encoded)); + wallpaper_search_results_.push_back(bitmap); + } + } + + std::move(callback).Run(thumbnails); +} + void CustomizeChromePageHandler::LogEvent(NTPLoggingEventType event) { switch (event) { case NTP_BACKGROUND_UPLOAD_CANCEL:
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.h b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.h index f0e7bc3..25d3394 100644 --- a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.h +++ b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.h
@@ -115,20 +115,20 @@ GetWallpaperSearchResultsCallback callback) override; private: - void LogEvent(NTPLoggingEventType event); - void OnDescriptorsRetrieved(std::unique_ptr<std::string> response_body); void OnDescriptorsJsonParsed(data_decoder::DataDecoder::ValueOrError result); void WallpaperSearchCallback( SearchWallpaperCallback callback, optimization_guide::OptimizationGuideModelExecutionResult result); - void OnGotWallpaperSearchResults( + void OnWallpaperSearchResultsRetrieved( GetWallpaperSearchResultsCallback callback, optimization_guide::OptimizationGuideModelExecutionResult result); void OnWallpaperSearchResultsDecoded( GetWallpaperSearchResultsCallback callback, std::vector<SkBitmap> bitmaps); + void LogEvent(NTPLoggingEventType event); + bool IsCustomLinksEnabled() const; bool IsShortcutsVisible() const;
diff --git a/chrome/browser/util/android/java/src/org/chromium/chrome/browser/util/ChromeAccessibilityUtil.java b/chrome/browser/util/android/java/src/org/chromium/chrome/browser/util/ChromeAccessibilityUtil.java index 0bef074..4d66423 100644 --- a/chrome/browser/util/android/java/src/org/chromium/chrome/browser/util/ChromeAccessibilityUtil.java +++ b/chrome/browser/util/android/java/src/org/chromium/chrome/browser/util/ChromeAccessibilityUtil.java
@@ -30,6 +30,11 @@ return AccessibilityState.isAccessibilityEnabled(); } + @Deprecated + public boolean isAccessibilityEnabledHeavy() { + return AccessibilityState.isAccessibilityEnabledHeavy(); + } + @Override public void setAccessibilityEnabledForTesting(@Nullable Boolean isEnabled) { AccessibilityState.setIsPerformGesturesEnabledForTesting(Boolean.TRUE.equals(isEnabled));
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index e5a687f..18f6c90 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1697111422-491c735f0084fc19f569abdaf9f8ae01eeaac91b.profdata +chrome-android32-main-1697133489-f1629873ad1dff0b5d11778e897bc1a1b183bdeb.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index bf8f6e4..82843d2d 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1697111422-8d15e2e20e3e11c1e46c00d65746d564bda7a377.profdata +chrome-android64-main-1697133489-8481dc05e723a9a46cfb638beb13c52b29d345e2.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 24ded02..143baccb 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1697111422-8f2bb5831c3379c7539fbf02ee820afbc23c128b.profdata +chrome-linux-main-1697133489-62f0b52eb8af38a87e5cb6582a9187cb13b23ada.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 6f80e18..61de0c7 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1697119168-44d695a7b0f1dc52f908532182ecd9801b2953e3.profdata +chrome-mac-arm-main-1697140696-0cda8c995f712ab35df38aebca8076f0eb6632d1.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 84941e1..9fa4975 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1697111422-6b9df0ba0e92ce06dd1ca1f60b6e982d0cb14897.profdata +chrome-mac-main-1697133489-91170e5117657e7eb627d1353ab678801021c8eb.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index 8c82c20..4da5c2d1 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1697111422-b5220fd2cc23957b959f55a4c766233d151186f6.profdata +chrome-win-arm64-main-1697133489-f386570385aada552b18925af611c602dfa14dbd.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 8f507a76..f9efd9cd 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1697111422-1926dbc8117951cfcf85fe32adb74f0eca30191c.profdata +chrome-win32-main-1697133489-d378409cb2f7279e3c504448e8d4943581732706.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 9a18f898..a399f5f 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1697111422-87c92c1f1ca653d32aec8232c972cd66fc167b6b.profdata +chrome-win64-main-1697133489-21852588a6771ae1f017a336061aafc411028b0a.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 75066645..211bfd86 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -432,6 +432,15 @@ "EnableNetworkServiceResourceBlockListInOtrSessions", base::FEATURE_DISABLED_BY_DEFAULT); +// When enabled, resource requests will be evaluated against the Network +// Service's block list if the setting to block all third party cookies is +// enabled. The block list is populated by the MaskedDomainList, so +// "MaskedDomainList" will need to also be enabled for the block list to have +// any contents. +BASE_FEATURE(kEnableNetworkServiceResourceBlockListIfThirdPartyCookiesBlocked, + "EnableNetworkServiceResourceBlockListIfThirdPartyCookiesBlocked", + base::FEATURE_DISABLED_BY_DEFAULT); + // Enable extended descriptions for key settings in Chrome settings. BASE_FEATURE(kExtendedSettingsDescriptions, "ExtendedSettingsDescriptions",
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 50ad2b2c..3297f4f 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -247,6 +247,10 @@ BASE_DECLARE_FEATURE(kEnableNetworkServiceResourceBlockListInOtrSessions); COMPONENT_EXPORT(CHROME_FEATURES) +BASE_DECLARE_FEATURE( + kEnableNetworkServiceResourceBlockListIfThirdPartyCookiesBlocked); + +COMPONENT_EXPORT(CHROME_FEATURES) BASE_DECLARE_FEATURE(kExtendedSettingsDescriptions); #if !BUILDFLAG(IS_ANDROID)
diff --git a/chrome/common/compose/BUILD.gn b/chrome/common/compose/BUILD.gn index e893dd4..5abc752 100644 --- a/chrome/common/compose/BUILD.gn +++ b/chrome/common/compose/BUILD.gn
@@ -6,9 +6,13 @@ import("//third_party/protobuf/proto_library.gni") source_set("compose") { - sources = [] + sources = [ + "type_conversions.cc", + "type_conversions.h", + ] - deps = [ ":mojo_bindings" ] + public_deps = [ ":mojo_bindings" ] + deps = [ "//components/compose/proto:proto" ] } mojom("mojo_bindings") {
diff --git a/chrome/common/compose/DEPS b/chrome/common/compose/DEPS new file mode 100644 index 0000000..9f385dd --- /dev/null +++ b/chrome/common/compose/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + "+components/compose" +] +
diff --git a/chrome/common/compose/type_conversions.cc b/chrome/common/compose/type_conversions.cc new file mode 100644 index 0000000..805373993 --- /dev/null +++ b/chrome/common/compose/type_conversions.cc
@@ -0,0 +1,29 @@ +// Copyright 2023 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/common/compose/type_conversions.h" + +compose_proto::ComposeLength ComposeLength(compose::mojom::Length length) { + switch (length) { + case compose::mojom::Length::kShorter: + return compose_proto::ComposeLength::COMPOSE_SHORTER; + case compose::mojom::Length::kLonger: + return compose_proto::ComposeLength::COMPOSE_LONGER; + case compose::mojom::Length::kUnset: + default: + return compose_proto::ComposeLength::COMPOSE_UNSPECIFIED_LENGTH; + } +} + +compose_proto::ComposeTone ComposeTone(compose::mojom::Tone tone) { + switch (tone) { + case compose::mojom::Tone::kCasual: + return compose_proto::ComposeTone::COMPOSE_INFORMAL; + case compose::mojom::Tone::kFormal: + return compose_proto::ComposeTone::COMPOSE_FORMAL; + case compose::mojom::Tone::kUnset: + default: + return compose_proto::ComposeTone::COMPOSE_UNSPECIFIED_TONE; + } +}
diff --git a/chrome/common/compose/type_conversions.h b/chrome/common/compose/type_conversions.h new file mode 100644 index 0000000..adf1249 --- /dev/null +++ b/chrome/common/compose/type_conversions.h
@@ -0,0 +1,14 @@ +// Copyright 2023 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_COMMON_COMPOSE_TYPE_CONVERSIONS_H_ +#define CHROME_COMMON_COMPOSE_TYPE_CONVERSIONS_H_ + +#include "chrome/common/compose/compose.mojom.h" +#include "components/compose/proto/compose_metadata.pb.h" + +compose_proto::ComposeLength ComposeLength(compose::mojom::Length length); +compose_proto::ComposeTone ComposeTone(compose::mojom::Tone tone); + +#endif // CHROME_COMMON_COMPOSE_TYPE_CONVERSIONS_H_
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index 94eb372f..dbe075da 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -481,6 +481,8 @@ #if BUILDFLAG(IS_CHROMEOS) const char kChromeUIAppDisabledHost[] = "app-disabled"; const char kChromeUIAppDisabledURL[] = "chrome://app-disabled"; +const char kChromeUIDlpInternalsHost[] = "dlp-internals"; +const char kChromeUIDlpInternalsURL[] = "chrome://dlp-internals"; const char kChromeUIGpuURL[] = "chrome://gpu"; const char kChromeUIHistogramsURL[] = "chrome://histograms"; const char kChromeUIKerberosInBrowserHost[] = "kerberos-in-browser"; @@ -832,6 +834,9 @@ #if BUILDFLAG(PLATFORM_CFM) kCfmNetworkSettingsHost, #endif // BUILDFLAG(PLATFORM_CFM) +#if BUILDFLAG(IS_CHROMEOS) + kChromeUIDlpInternalsHost, +#endif // BUILDFLAG(IS_CHROMEOS) }; const size_t kNumberOfChromeHostURLs = std::size(kChromeHostURLs);
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h index cf14a91..c24d2b52b 100644 --- a/chrome/common/webui_url_constants.h +++ b/chrome/common/webui_url_constants.h
@@ -399,6 +399,8 @@ #if BUILDFLAG(IS_CHROMEOS) extern const char kChromeUIAppDisabledHost[]; +extern const char kChromeUIDlpInternalsHost[]; +extern const char kChromeUIDlpInternalsURL[]; extern const char kChromeUIGpuURL[]; extern const char kChromeUIHistogramsURL[]; extern const char kChromeUIKerberosInBrowserHost[];
diff --git a/chrome/renderer/accessibility/read_anything_app_controller.cc b/chrome/renderer/accessibility/read_anything_app_controller.cc index 659dbb3..809fd6d5 100644 --- a/chrome/renderer/accessibility/read_anything_app_controller.cc +++ b/chrome/renderer/accessibility/read_anything_app_controller.cc
@@ -470,8 +470,7 @@ model_.set_requires_distillation(false); - ui::AXSerializableTree* tree = - model_.GetTreeFromId(model_.active_tree_id()).get(); + ui::AXSerializableTree* tree = model_.GetTreeFromId(model_.active_tree_id()); std::unique_ptr<ui::AXTreeSource<const ui::AXNode*>> tree_source( tree->CreateTreeSource()); ui::AXTreeSerializer<const ui::AXNode*, std::vector<const ui::AXNode*>> @@ -526,10 +525,8 @@ // AXNode's language code is BCP 47. Only the base language is needed to // record the metric. - std::string language = model_.GetTreeFromId(model_.active_tree_id()) - .get() - ->root() - ->GetLanguage(); + std::string language = + model_.GetTreeFromId(model_.active_tree_id())->root()->GetLanguage(); if (!language.empty()) { base::UmaHistogramSparse( string_constants::kLanguageHistogramName, @@ -701,8 +698,7 @@ } ui::AXNodeID ReadAnythingAppController::RootId() const { - ui::AXSerializableTree* tree = - model_.GetTreeFromId(model_.active_tree_id()).get(); + ui::AXSerializableTree* tree = model_.GetTreeFromId(model_.active_tree_id()); DCHECK(tree->root()); return tree->root()->id(); }
diff --git a/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc b/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc index dd0efb64..e53d8e4f 100644 --- a/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc +++ b/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc
@@ -1442,15 +1442,11 @@ AccessibilityEventReceived({update_2}); OnAXTreeDistilled({}); - // We want to check that no crash occurs in this case. These node ids and - // offset are incorrect, they should be 2, 3, 0, and 5 (5 is the length of the - // world "Hello"). But because we don't have an AXTreeManager in the test, - // AXSelection::ToUnignoredSelection() exits early without calculating the - // actual ignored selection. - EXPECT_EQ(2, StartNodeId()); - EXPECT_EQ(4, EndNodeId()); - EXPECT_EQ(0, StartOffset()); - EXPECT_EQ(0, EndOffset()); + EXPECT_EQ(0, StartNodeId()); + EXPECT_EQ(0, EndNodeId()); + EXPECT_EQ(-1, StartOffset()); + EXPECT_EQ(-1, EndOffset()); + EXPECT_EQ(false, HasSelection()); } TEST_F(ReadAnythingAppControllerTest, Selection_IsCollapsed) {
diff --git a/chrome/renderer/accessibility/read_anything_app_model.cc b/chrome/renderer/accessibility/read_anything_app_model.cc index 9194f98..a696291 100644 --- a/chrome/renderer/accessibility/read_anything_app_model.cc +++ b/chrome/renderer/accessibility/read_anything_app_model.cc
@@ -308,26 +308,29 @@ base::Contains(display_node_ids_, end_node_id_); } -const std::unique_ptr<ui::AXSerializableTree>& -ReadAnythingAppModel::GetTreeFromId(ui::AXTreeID tree_id) const { +ui::AXSerializableTree* ReadAnythingAppModel::GetTreeFromId( + ui::AXTreeID tree_id) const { DCHECK_NE(tree_id, ui::AXTreeIDUnknown()); DCHECK(ContainsTree(tree_id)); - return trees_.at(tree_id); + return static_cast<ui::AXSerializableTree*>( + tree_managers_.at(tree_id)->ax_tree()); } bool ReadAnythingAppModel::ContainsTree(ui::AXTreeID tree_id) const { - return base::Contains(trees_, tree_id); + return base::Contains(tree_managers_, tree_id); } void ReadAnythingAppModel::AddTree( ui::AXTreeID tree_id, std::unique_ptr<ui::AXSerializableTree> tree) { DCHECK(!ContainsTree(tree_id)); - trees_[tree_id] = std::move(tree); + std::unique_ptr<ui::AXTreeManager> manager = + std::make_unique<ui::AXTreeManager>(std::move(tree)); + tree_managers_[tree_id] = std::move(manager); } void ReadAnythingAppModel::EraseTree(ui::AXTreeID tree_id) { - trees_.erase(tree_id); + tree_managers_.erase(tree_id); // Ensure any pending updates associated with the erased tree are removed. pending_updates_map_.erase(tree_id); @@ -366,8 +369,8 @@ return; } DCHECK_NE(tree_id, ui::AXTreeIDUnknown()); - DCHECK(base::Contains(trees_, tree_id)); - ui::AXSerializableTree* tree = trees_[tree_id].get(); + DCHECK(base::Contains(tree_managers_, tree_id)); + ui::AXSerializableTree* tree = GetTreeFromId(tree_id); CHECK(tree); // Try to merge updates. If the updates are mergeable, MergeAXTreeUpdates will // return true and merge_updates_out will contain the updates. Otherwise, if @@ -426,7 +429,8 @@ void ReadAnythingAppModel::OnAXTreeDestroyed(const ui::AXTreeID& tree_id) { // OnAXTreeDestroyed is called whenever the AXActionHandler in the browser // learns that an AXTree was destroyed. This could be from any tab, not just - // the active one; therefore many tree_ids will not be found in trees_. + // the active one; therefore many tree_ids will not be found in + // tree_managers_. if (!ContainsTree(tree_id)) { return; } @@ -453,7 +457,7 @@ } ui::AXNode* ReadAnythingAppModel::GetAXNode(ui::AXNodeID ax_node_id) const { - ui::AXSerializableTree* tree = GetTreeFromId(active_tree_id_).get(); + ui::AXSerializableTree* tree = GetTreeFromId(active_tree_id_); return tree->GetFromId(ax_node_id); } @@ -514,9 +518,9 @@ return pending_updates_map_; } -std::map<ui::AXTreeID, std::unique_ptr<ui::AXSerializableTree>>* +std::map<ui::AXTreeID, std::unique_ptr<ui::AXTreeManager>>* ReadAnythingAppModel::GetTreesForTesting() { - return &trees_; + return &tree_managers_; } void ReadAnythingAppModel::EraseTreeForTesting(ui::AXTreeID tree_id) {
diff --git a/chrome/renderer/accessibility/read_anything_app_model.h b/chrome/renderer/accessibility/read_anything_app_model.h index 722a70a..cdb01c5 100644 --- a/chrome/renderer/accessibility/read_anything_app_model.h +++ b/chrome/renderer/accessibility/read_anything_app_model.h
@@ -12,6 +12,7 @@ #include "ui/accessibility/ax_event_generator.h" #include "ui/accessibility/ax_node.h" #include "ui/accessibility/ax_selection.h" +#include "ui/accessibility/ax_tree_manager.h" namespace ui { class AXNode; @@ -136,8 +137,7 @@ // clears their selection or selects content inside the distilled content. void ComputeDisplayNodeIdsForDistilledTree(); - const std::unique_ptr<ui::AXSerializableTree>& GetTreeFromId( - ui::AXTreeID tree_id) const; + ui::AXSerializableTree* GetTreeFromId(ui::AXTreeID tree_id) const; void AddTree(ui::AXTreeID tree_id, std::unique_ptr<ui::AXSerializableTree> tree); @@ -156,7 +156,7 @@ std::map<ui::AXTreeID, std::vector<ui::AXTreeUpdate>>& GetPendingUpdatesForTesting(); - std::map<ui::AXTreeID, std::unique_ptr<ui::AXSerializableTree>>* + std::map<ui::AXTreeID, std::unique_ptr<ui::AXTreeManager>>* GetTreesForTesting(); void EraseTreeForTesting(ui::AXTreeID tree_id); @@ -195,8 +195,8 @@ ui::AXNode* GetParentForSelection(ui::AXNode* node); // State. - // AXTrees of web contents in the browser’s tab strip. - std::map<ui::AXTreeID, std::unique_ptr<ui::AXSerializableTree>> trees_; + // Store AXTrees of web contents in the browser's tab strip as AXTreeManagers. + std::map<ui::AXTreeID, std::unique_ptr<ui::AXTreeManager>> tree_managers_; // The AXTreeID of the currently active web contents. ui::AXTreeID active_tree_id_ = ui::AXTreeIDUnknown();
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index bf1b2308..51d17e3 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1035,6 +1035,7 @@ "../browser/ash/featured_integration_test.cc", "../browser/ash/login/lock/lock_screen_integration_test.cc", "../browser/ash/ml_integration_test.cc", + "../browser/ash/screenshot_integration_test.cc", "../browser/ui/ash/app_list/app_list_integration_test.cc", "../browser/ui/ash/quick_settings_integration_test.cc", "../browser/ui/ash/shelf/shelf_integration_test.cc", @@ -1269,6 +1270,9 @@ "//components/webapps/browser:test_support", ] + if (enable_chrome_android_internal) { + data_deps = [ "//clank/build/bot/filters:android_browsertests_filters" ] + } # Add unwind tables in android_browsertests apk to support enabling # sampling profiler. The unwind tables are generated from debug info in the # binary. Removing "default_symbols" and adding symbols config removes the
diff --git a/chrome/test/chromedriver/client/chromedriver.py b/chrome/test/chromedriver/client/chromedriver.py index 1826a95..9bedb6f 100644 --- a/chrome/test/chromedriver/client/chromedriver.py +++ b/chrome/test/chromedriver/client/chromedriver.py
@@ -766,6 +766,9 @@ def ResetCooldown(self): return self.ExecuteCommand(Command.RESET_COOLDOWN, {}) + def RunBounceTrackingMitigations(self): + return self.ExecuteCommand(Command.RUN_BOUNCE_TRACKING_MITIGATIONS, {}) + def GetSessionId(self): if not hasattr(self, '_session_id'): return None
diff --git a/chrome/test/chromedriver/client/command_executor.py b/chrome/test/chromedriver/client/command_executor.py index c13f157..968909a 100644 --- a/chrome/test/chromedriver/client/command_executor.py +++ b/chrome/test/chromedriver/client/command_executor.py
@@ -245,6 +245,9 @@ RESET_COOLDOWN = ( _Method.POST, '/session/:sessionId/fedcm/resetcooldown') + RUN_BOUNCE_TRACKING_MITIGATIONS = ( + _Method.DELETE, + '/session/:sessionId/storage/run_bounce_tracking_mitigations') # Custom Chrome commands. IS_LOADING = (_Method.GET, '/session/:sessionId/is_loading')
diff --git a/chrome/test/chromedriver/server/http_handler.cc b/chrome/test/chromedriver/server/http_handler.cc index 9a0f5bc..9624f58 100644 --- a/chrome/test/chromedriver/server/http_handler.cc +++ b/chrome/test/chromedriver/server/http_handler.cc
@@ -975,6 +975,14 @@ WrapToCommand("ResetCooldown", base::BindRepeating(&ExecuteResetCooldown))), + // Extensions for Navigational Tracking Mitigations: + // https://privacycg.github.io/nav-tracking-mitigations + VendorPrefixedCommandMapping( + kDelete, "session/:sessionId/storage/run_bounce_tracking_mitigations", + WrapToCommand( + "RunBounceTrackingMitigations", + base::BindRepeating(&ExecuteRunBounceTrackingMitigations))), + // Extensions for Custom Handlers API: // https://html.spec.whatwg.org/multipage/system-state.html#rph-automation CommandMapping(
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index a48faed..db8c1fe 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -262,7 +262,10 @@ # These tests are failing on Android # https://bugs.chromium.org/p/chromedriver/issues/detail?id=3560 'ChromeDriverTest.testTakeLargeElementViewportScreenshot', - 'ChromeDriverTest.testTakeLargeElementFullPageScreenshot' + 'ChromeDriverTest.testTakeLargeElementFullPageScreenshot', + # Android does not support command line switches, which are + # currently needed for these tests. + 'NavTrackingMitigationSpecificTest.testRunBounceTrackingMitigations' ] ) _ANDROID_NEGATIVE_FILTER['chrome_stable'] = ( @@ -497,6 +500,13 @@ def GetHttpUrlForFile(file_path): return ChromeDriverBaseTestWithWebServer._http_server.GetUrl() + file_path + @staticmethod + def ReplaceHostName(url, new_host_name): + url_components = urllib.parse.urlparse(url) + return urllib.parse.urlunparse( + url_components._replace( + netloc=('%s:%d' % (new_host_name, url_components.port)))) + class ChromeDriverTestWithCustomCapability(ChromeDriverBaseTestWithWebServer): @@ -4574,12 +4584,6 @@ for fixable technical reasons related to subdomain matching. """ - def ReplaceHostName(self, url, new_host_name): - url_components = urllib.parse.urlparse(url) - return urllib.parse.urlunparse( - url_components._replace( - netloc=('%s:%d' % (new_host_name, url_components.port)))) - def setUp(self): self._driver = self.CreateDriver(chrome_switches=['--site-per-process']) @@ -7015,6 +7019,71 @@ token = self._driver.ExecuteScript("return getResult()") self.assertEqual("token", token) +class NavTrackingMitigationSpecificTest(ChromeDriverBaseTestWithWebServer): + def setUp(self): + global _VENDOR_ID + self._vendor_id = _VENDOR_ID + + self._driver = self.CreateDriver(chrome_switches=[ + '--enable-features="DIPS:delete/true/' + 'triggering_action/stateful_bounce"', + '--test-third-party-cookie-phaseout', + '--host-resolver-rules=MAP * 127.0.0.1' + ]) + + def testRunBounceTrackingMitigations(self): + """Test implementation of bounce tracking mitigations. + """ + initial_url = self.GetHttpUrlForFile('/initial.html') + remote_url = self.ReplaceHostName( + self.GetHttpUrlForFile('/bounce.html'), 'tracker.test') + final_url = self.GetHttpUrlForFile('/final.html') + + self._http_server.SetDataForPath('/initial.html', bytes(""" + <html> + <title>Initial Page</title> + <body> + <a href='%s' id='remote'>Stateful Bouncer\n</a><br> + <a href='%s' id='local'>To Local\n</a> + </body> + </html>""" % (remote_url, final_url), 'utf-8')) + + def StatefullyBounce(request): + return {'Set-Cookie': 'x=y'}, bytes(""" + <html> + <title>Bounce Tracker</title> + <body> + <script> + window.location = '%s'; + </script> + </body> + </html>""" % initial_url, 'utf-8') + self._http_server.SetCallbackForPath('/bounce.html', StatefullyBounce) + self._http_server.SetDataForPath('/final.html', + bytes('<p>DONE!</p>', 'utf-8')) + + self._driver.Load(initial_url) + anchor = self._driver.FindElement('css selector', '#remote') + anchor.Click() + + # Waiting to be redirected back to initial_url by the bounce page. + self.WaitForCondition( + (lambda: 'Initial Page' in self._driver.GetTitle())) + + # A click-started navigation is used to end the active redirect chain. + anchor = self._driver.FindElement('css selector', '#local') + anchor.Click() + + paragraph = self._driver.FindElement('tag name', 'p') + self.assertEqual('DONE!', paragraph.GetText()) + + # The DIPSService can take some time to process and record the terminated + # redirect chain, but there is not an existing signal exposed to notify + # when it has finished. This wait should be sufficient to allow time for it. + self.assertTrue(self.WaitForCondition( + lambda: "tracker.test" in + self._driver.RunBounceTrackingMitigations(), 15)) + # 'Z' in the beginning is to make test executed in the end of suite. class ZChromeStartRetryCountTest(unittest.TestCase):
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc index 5866f03e..a162a97 100644 --- a/chrome/test/chromedriver/window_commands.cc +++ b/chrome/test/chromedriver/window_commands.cc
@@ -2495,6 +2495,46 @@ return Status(kOk); } +Status ExecuteRunBounceTrackingMitigations(Session* session, + WebView* web_view, + const base::Value::Dict& params, + std::unique_ptr<base::Value>* value, + Timeout* timeout) { + // Run command and get result + auto result = std::make_unique<base::Value>(base::Value::Type::DICT); + Status status = web_view->SendCommandAndGetResult( + "Storage.runBounceTrackingMitigations", base::Value::Dict(), &result); + if (status.IsError()) { + return status; + } + + if (result->GetDict().empty()) { + // The result dictionary should only be empty if there is no bounce tracking + // mitigations service (DIPSService) for the current browser context. + return Status( + kUnsupportedOperation, + "current remote end configuration does not support bounce tracking " + "mitigations"); + } + + const base::Value::List* deleted_sites = + result->GetDict().FindList("deletedSites"); + + // create copies of items `deleted_sites` and add them to the output list. + auto site_list = std::make_unique<base::Value>(base::Value::Type::LIST); + for (const base::Value& site : *deleted_sites) { + if (!site.is_string()) { + return Status(kUnknownError, + "DevTools returns a non-string bounce tracker site"); + } + site_list->GetList().Append(site.GetString()); + } + + *value = std::move(site_list); + + return Status(kOk); +} + Status ExecuteSetRPHRegistrationMode(Session* session, WebView* web_view, const base::Value::Dict& params,
diff --git a/chrome/test/chromedriver/window_commands.h b/chrome/test/chromedriver/window_commands.h index 2e4ca1d..908a39f 100644 --- a/chrome/test/chromedriver/window_commands.h +++ b/chrome/test/chromedriver/window_commands.h
@@ -333,6 +333,12 @@ std::unique_ptr<base::Value>* value, Timeout* timeout); +Status ExecuteRunBounceTrackingMitigations(Session* session, + WebView* web_view, + const base::Value::Dict& params, + std::unique_ptr<base::Value>* value, + Timeout* timeout); + Status ExecuteSetRPHRegistrationMode(Session* session, WebView* web_view, const base::Value::Dict& params,
diff --git a/chrome/test/data/pdf/annotations_feature_enabled_test.ts b/chrome/test/data/pdf/annotations_feature_enabled_test.ts index cfffbea..ef53800 100644 --- a/chrome/test/data/pdf/annotations_feature_enabled_test.ts +++ b/chrome/test/data/pdf/annotations_feature_enabled_test.ts
@@ -3,7 +3,7 @@ // found in the LICENSE file. import {AnnotationTool, SaveRequestType, ViewerInkHostElement} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {waitFor} from './test_util.js';
diff --git a/chrome/test/data/pdf/navigator_test.ts b/chrome/test/data/pdf/navigator_test.ts index f242cb9..01a8c50 100644 --- a/chrome/test/data/pdf/navigator_test.ts +++ b/chrome/test/data/pdf/navigator_test.ts
@@ -3,7 +3,7 @@ // found in the LICENSE file. import {NavigatorDelegate, OpenPdfParamsParser, PdfNavigator, WindowOpenDisposition} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js'; -import {assertNotReached} from 'chrome://resources/js/assert_ts.js'; +import {assertNotReached} from 'chrome://resources/js/assert.js'; import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js'; import {getZoomableViewport, MockDocumentDimensions, MockElement, MockSizer, MockViewportChangedCallback} from './test_util.js';
diff --git a/chrome/test/data/third_party_partitioned_cookies_slow.html b/chrome/test/data/third_party_partitioned_cookies_slow.html new file mode 100644 index 0000000..dd9f12da --- /dev/null +++ b/chrome/test/data/third_party_partitioned_cookies_slow.html
@@ -0,0 +1,20 @@ +<html> + <head> + <title>cross-site iframes with partitioned cookies</title> + <script> + function setCookie() { + document.cookie = 'name=Good;'; + console.log("onload"); + } + </script> + </head> +<body onload="setCookie();"> +<!-- This only works if the CrossSiteRedirector is running on the embedded test + server, and the host_resolver is set up to handle b.test and c.test. --> +<iframe src="/cross-site/b.test/partitioned_cookie.html" id="frame1"></iframe> +<iframe src="/cross-site/c.test/mixed_with_partitioned_cookie.html" id="frame2"></iframe> +<iframe src="/cross-site/d.test/set_cookie_header.html" id="frame3"></iframe> +<!-- The frame below will never finish loading. Requires that EmbeddedTestServer + is started with default handlers. --> +<iframe src="/hung-after-headers" /> +</body></html>
diff --git a/chrome/test/data/webui/app_settings/test_app_management_browser_proxy.ts b/chrome/test/data/webui/app_settings/test_app_management_browser_proxy.ts index 8fd2b11d..b082773 100644 --- a/chrome/test/data/webui/app_settings/test_app_management_browser_proxy.ts +++ b/chrome/test/data/webui/app_settings/test_app_management_browser_proxy.ts
@@ -4,7 +4,7 @@ import {App, OptionalBool, PageCallbackRouter, PageHandlerInterface, PageRemote, Permission, RunOnOsLoginMode, WindowMode} from 'chrome://resources/cr_components/app_management/app_management.mojom-webui.js'; import {BrowserProxy} from 'chrome://resources/cr_components/app_management/browser_proxy.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.js'; export class FakePageHandler implements PageHandlerInterface {
diff --git a/chrome/test/data/webui/bluetooth_internals/bluetooth_internals_test.js b/chrome/test/data/webui/bluetooth_internals/bluetooth_internals_test.js index 79e38e40..1a2b1a8 100644 --- a/chrome/test/data/webui/bluetooth_internals/bluetooth_internals_test.js +++ b/chrome/test/data/webui/bluetooth_internals/bluetooth_internals_test.js
@@ -8,7 +8,7 @@ import {dismissSnackbar, getSnackbarStateForTest, showSnackbar} from 'chrome://bluetooth-internals/snackbar.js'; import {UUID} from 'chrome://bluetooth-internals/uuid.mojom-webui.js'; import {ValueDataType} from 'chrome://bluetooth-internals/value_control.js'; -import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js'; +import {assert, assertNotReached} from 'chrome://resources/js/assert.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.js'; import {$} from 'chrome://resources/js/util_ts.js'; import {assertDeepEquals, assertEquals, assertFalse, assertThrows, assertTrue} from 'chrome://webui-test/chai_assert.js';
diff --git a/chrome/test/data/webui/bluetooth_internals/test_utils.js b/chrome/test/data/webui/bluetooth_internals/test_utils.js index 75e256b..1e803afe 100644 --- a/chrome/test/data/webui/bluetooth_internals/test_utils.js +++ b/chrome/test/data/webui/bluetooth_internals/test_utils.js
@@ -5,7 +5,7 @@ import {AdapterReceiver, ConnectResult} from 'chrome://bluetooth-internals/adapter.mojom-webui.js'; import {BluetoothInternalsHandlerReceiver} from 'chrome://bluetooth-internals/bluetooth_internals.mojom-webui.js'; import {DeviceCallbackRouter} from 'chrome://bluetooth-internals/device.mojom-webui.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js'; /**
diff --git a/chrome/test/data/webui/bookmarks/test_timer_proxy.ts b/chrome/test/data/webui/bookmarks/test_timer_proxy.ts index 0de69c1..864f05c 100644 --- a/chrome/test/data/webui/bookmarks/test_timer_proxy.ts +++ b/chrome/test/data/webui/bookmarks/test_timer_proxy.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; // TODO(calamity): Remove TestTimerProxy in favor of MockTimer. export class TestTimerProxy {
diff --git a/chrome/test/data/webui/compose/compose_app_test.ts b/chrome/test/data/webui/compose/compose_app_test.ts index 188c203..769e791 100644 --- a/chrome/test/data/webui/compose/compose_app_test.ts +++ b/chrome/test/data/webui/compose/compose_app_test.ts
@@ -5,27 +5,39 @@ import 'chrome://compose/app.js'; import {ComposeAppElement} from 'chrome://compose/app.js'; -import {ComposeResponse, ComposeStatus, StyleModifiers} from 'chrome://compose/compose.mojom-webui.js'; +import {ComposeResponse, ComposeStatus, Length, StyleModifiers, Tone} from 'chrome://compose/compose.mojom-webui.js'; import {ComposeApiProxy, ComposeApiProxyImpl} from 'chrome://compose/compose_api_proxy.js'; -import {assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; -import {isVisible, whenCheck} from 'chrome://webui-test/test_util.js'; +import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js'; +import {isVisible} from 'chrome://webui-test/test_util.js'; -class TestingApiProxy implements ComposeApiProxy { - constructor() {} +class TestingApiProxy extends TestBrowserProxy implements ComposeApiProxy { + private composeOutput_: string = 'Some output'; - compose(_style: StyleModifiers, _input: string): Promise<ComposeResponse> { + constructor() { + super(['compose']); + } + + compose(style: StyleModifiers, input: string): Promise<ComposeResponse> { + this.methodCalled('compose', {style, input}); return Promise.resolve( - {status: ComposeStatus.kOk, result: 'Here is my output.'}); + {status: ComposeStatus.kOk, result: this.composeOutput_}); + } + + setComposeOutput(output: string) { + this.composeOutput_ = output; } } suite('ComposeApp', () => { let app: ComposeAppElement; + let testProxy: TestingApiProxy; setup(() => { - ComposeApiProxyImpl.setInstance(new TestingApiProxy()); + testProxy = new TestingApiProxy(); + ComposeApiProxyImpl.setInstance(testProxy); document.body.innerHTML = window.trustedTypes!.emptyHTML; app = document.createElement('compose-app'); @@ -34,6 +46,11 @@ return flushTasks(); }); + function mockInput(input: string) { + app.$.textarea.value = input; + app.$.textarea.dispatchEvent(new CustomEvent('value-changed')); + } + test('SubmitsInput', async () => { // Starts off with submit disabled since input is empty. assertTrue(isVisible(app.$.submitButton)); @@ -42,28 +59,50 @@ assertFalse(isVisible(app.$.insertButton)); // Invalid input keeps submit disabled. - app.$.textarea.value = 'Short'; - app.$.textarea.dispatchEvent(new CustomEvent('value-changed')); + mockInput('Short'); assertTrue(app.$.submitButton.disabled); // Inputting valid text enables submit. - app.$.textarea.value = 'Here is my input.'; - app.$.textarea.dispatchEvent(new CustomEvent('value-changed')); + mockInput('Here is my input.'); assertFalse(app.$.submitButton.disabled); // Clicking on submit gets results. app.$.submitButton.click(); + assertTrue(isVisible(app.$.loading)); - // Wait for api proxy promise to resolve. - await flushTasks(); + const args = await testProxy.whenCalled('compose'); + assertEquals(Length.kUnset, args.style.length); + assertEquals(Tone.kUnset, args.style.tone); + assertEquals('Here is my input.', args.input); - const resultContainerVisible = whenCheck(app, () => { - return !app.$.resultContainer.hidden; - }); - await resultContainerVisible; - + assertFalse(isVisible(app.$.loading)); assertFalse(isVisible(app.$.submitButton)); assertTrue(app.$.textarea.readonly); assertTrue(isVisible(app.$.insertButton)); }); + + test('RefreshesResult', async () => { + // Submit the input once so the refresh button shows up. + testProxy.setComposeOutput('Outdated output.'); + mockInput('Input to refresh.'); + app.$.submitButton.click(); + await testProxy.whenCalled('compose'); + testProxy.resetResolver('compose'); + assertTrue(isVisible(app.$.refreshButton)); + + // Click the refresh button and assert compose is called with the same args. + testProxy.setComposeOutput('Refreshed output.'); + app.$.refreshButton.click(); + assertTrue(isVisible(app.$.loading)); + const args = await testProxy.whenCalled('compose'); + assertEquals(Length.kUnset, args.style.length); + assertEquals(Tone.kUnset, args.style.tone); + assertEquals('Input to refresh.', args.input); + + // Verify UI has updated with refreshed results. + assertFalse(isVisible(app.$.loading)); + assertTrue(isVisible(app.$.resultContainer)); + assertTrue( + app.$.resultContainer.textContent!.includes('Refreshed output.')); + }); });
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js index e8c90e7..e560a53 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js
@@ -277,6 +277,10 @@ assertButtonState( /*forwardButtonShouldBeEnabled=*/ false, /*backButtonState=*/ ButtonState.HIDDEN); + assertEquals(eSimPage.header, eSimPage.i18n('profileLoadingPageTitle')); + assertEquals( + profileLoadingPage.loadingMessage, + eSimPage.i18n('profileLoadingPageMessage')); await flushAsync(); } @@ -285,6 +289,7 @@ assertButtonState( /*forwardButtonShouldBeEnabled*/ true, /*backButtonState*/ ButtonState.HIDDEN); + assertEquals(eSimPage.header, eSimPage.i18n('profileDiscoveryPageTitle')); } function assertActivationCodePage( @@ -305,6 +310,7 @@ } assertSelectedPage(ESimPageName.CONFIRMATION_CODE, confirmationCodePage); assertButtonState(forwardButtonShouldBeEnabled, backButtonState); + assertEquals(eSimPage.header, eSimPage.i18n('confimationCodePageTitle')); } test('Error fetching profiles', async function() { @@ -783,36 +789,6 @@ }); }); - test( - 'Show cellular disconnect warning if connected to pSIM network', - async function() { - assertEquals( - profileLoadingPage.loadingMessage, - eSimPage.i18n('eSimProfileDetectMessage')); - - const pSimNetwork = - OncMojo.getDefaultNetworkState(NetworkType.kCellular, 'cellular'); - pSimNetwork.connectionState = ConnectionStateType.kConnected; - networkConfigRemote.addNetworksForTest([pSimNetwork]); - MojoInterfaceProviderImpl.getInstance().remote_ = networkConfigRemote; - await flushAsync(); - - assertEquals( - profileLoadingPage.loadingMessage, - eSimPage.i18n( - 'eSimProfileDetectDuringActiveCellularConnectionMessage')); - - // Disconnect from the network. - networkConfigRemote.removeNetworkForTest(pSimNetwork); - await flushAsync(); - - // The warning should still be showing. - assertEquals( - profileLoadingPage.loadingMessage, - eSimPage.i18n( - 'eSimProfileDetectDuringActiveCellularConnectionMessage')); - }); - test('Show final page with error if no EUICC', async function() { eSimPage.initSubflow(); await assertProfileDiscoveryConsentPageAndContinue();
diff --git a/chrome/test/data/webui/location_internals/location_internals_test.ts b/chrome/test/data/webui/location_internals/location_internals_test.ts index 63b5d927..3469e9ff 100644 --- a/chrome/test/data/webui/location_internals/location_internals_test.ts +++ b/chrome/test/data/webui/location_internals/location_internals_test.ts
@@ -7,7 +7,7 @@ import {BAD_ACCURACY, BAD_ALTITUDE, BAD_HEADING, BAD_LATITUDE_LONGITUDE, BAD_SPEED} from 'chrome://location-internals/geoposition.mojom-webui.js'; import {DIAGNOSE_INFO_VIEW_ID, initializeMojo, REFRESH_FINISH_EVENT, REFRESH_STATUS_ID, REFRESH_STATUS_SUCCESS, REFRESH_STATUS_UNINITIALIZED, WATCH_BUTTON_ID} from 'chrome://location-internals/location_internals.js'; import {LocationInternalsHandler, LocationInternalsHandlerInterface, LocationInternalsHandlerReceiver} from 'chrome://location-internals/location_internals.mojom-webui.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {getRequiredElement} from 'chrome://resources/js/util_ts.js'; import {Time, TimeDelta} from 'chrome://resources/mojo/mojo/public/mojom/base/time.mojom-webui.js'; import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
diff --git a/chrome/test/data/webui/metrics_internals/no_logs_test.ts b/chrome/test/data/webui/metrics_internals/no_logs_test.ts index 4d77087..23df16eb 100644 --- a/chrome/test/data/webui/metrics_internals/no_logs_test.ts +++ b/chrome/test/data/webui/metrics_internals/no_logs_test.ts
@@ -5,7 +5,7 @@ import 'chrome://metrics-internals/app.js'; import {MetricsInternalsAppElement} from 'chrome://metrics-internals/app.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {assertEquals, assertGT, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {getTableRowAsStringArray} from './utils.js';
diff --git a/chrome/test/data/webui/metrics_internals/utils.ts b/chrome/test/data/webui/metrics_internals/utils.ts index 72237c5..53931df 100644 --- a/chrome/test/data/webui/metrics_internals/utils.ts +++ b/chrome/test/data/webui/metrics_internals/utils.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {assertGT} from 'chrome://webui-test/chai_assert.js'; /**
diff --git a/chrome/test/data/webui/metrics_internals/with_log_test.ts b/chrome/test/data/webui/metrics_internals/with_log_test.ts index 418f8d9..c0df04f 100644 --- a/chrome/test/data/webui/metrics_internals/with_log_test.ts +++ b/chrome/test/data/webui/metrics_internals/with_log_test.ts
@@ -6,7 +6,7 @@ import {MetricsInternalsAppElement} from 'chrome://metrics-internals/app.js'; import {getEventsPeekString, sizeToString, timestampToString} from 'chrome://metrics-internals/log_utils.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {assertEquals, assertGT, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {getTableRowAsStringArray} from './utils.js';
diff --git a/chrome/test/data/webui/new_tab_page/middle_slot_promo_test.ts b/chrome/test/data/webui/new_tab_page/middle_slot_promo_test.ts index 300d1071..6f858ab8 100644 --- a/chrome/test/data/webui/new_tab_page/middle_slot_promo_test.ts +++ b/chrome/test/data/webui/new_tab_page/middle_slot_promo_test.ts
@@ -7,7 +7,7 @@ import {MiddleSlotPromoElement, PromoDismissAction} from 'chrome://new-tab-page/lazy_load.js'; import {$$, BrowserCommandProxy, CrAutoImgElement, NewTabPageProxy} from 'chrome://new-tab-page/new_tab_page.js'; import {PageCallbackRouter, PageHandlerRemote, PageRemote, Promo} from 'chrome://new-tab-page/new_tab_page.mojom-webui.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {Command, CommandHandlerRemote} from 'chrome://resources/js/browser_command.mojom-webui.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {assertDeepEquals, assertEquals} from 'chrome://webui-test/chai_assert.js';
diff --git a/chrome/test/data/webui/new_tab_page/modules/history_clusters/module_test.ts b/chrome/test/data/webui/new_tab_page/modules/history_clusters/module_test.ts index 961070d..b42de81f 100644 --- a/chrome/test/data/webui/new_tab_page/modules/history_clusters/module_test.ts +++ b/chrome/test/data/webui/new_tab_page/modules/history_clusters/module_test.ts
@@ -679,6 +679,12 @@ for (const discount of moduleElement.discounts) { assertEquals('', discount); } + const contentElement = + moduleElement.shadowRoot!.querySelector('ntp-history-clusters-tile')! + .shadowRoot!.querySelector('#content')! as HTMLElement; + assertEquals( + contentElement.getAttribute('aria-label'), + 'Test Title 1, foo.com, 1 min ago'); checkInfoDialogContent(moduleElement, 'modulesJourneysInfo'); assertEquals(0, metrics.count(`NewTabPage.HistoryClusters.HasDiscount`)); }); @@ -718,13 +724,34 @@ assertEquals(expectedDiscounts[i], visitTiles[i]!.discount); } assertEquals( + 'https://www.foo.com/1', visitTiles[0]!.visit.normalizedUrl.url); + assertEquals('', visitTiles[0]!.discount); + let contentElement = + visitTiles[0]!.shadowRoot!.querySelector('#content')! as HTMLElement; + assertEquals( + contentElement.getAttribute('aria-label'), + 'Test Title 1, foo.com, 1 min ago'); + + assertEquals( 'https://www.annotated.com/1', visitTiles[1]!.visit.normalizedUrl.url); assertEquals('15% off', visitTiles[1]!.discount); + contentElement = + visitTiles[1]!.shadowRoot!.querySelector('#content')! as HTMLElement; + assertEquals( + contentElement.getAttribute('aria-label'), + 'Test Title 2, annotated.com, 1 min ago, 15% off'); + assertEquals( 'https://www.annotated.com/2', visitTiles[2]!.visit.normalizedUrl.url); assertEquals('$10 off', visitTiles[2]!.discount); + contentElement = + visitTiles[2]!.shadowRoot!.querySelector('#content')! as HTMLElement; + assertEquals( + contentElement.getAttribute('aria-label'), + 'Test Title 3, annotated.com, 1 min ago, $10 off'); + checkInfoDialogContent(moduleElement, 'modulesHistoryWithDiscountInfo'); });
diff --git a/chrome/test/data/webui/new_tab_page/modules/history_clusters/test_support.ts b/chrome/test/data/webui/new_tab_page/modules/history_clusters/test_support.ts index 84ad164..0d1efaa 100644 --- a/chrome/test/data/webui/new_tab_page/modules/history_clusters/test_support.ts +++ b/chrome/test/data/webui/new_tab_page/modules/history_clusters/test_support.ts
@@ -26,7 +26,7 @@ titleMatchPositions: [], urlForDisplayMatchPositions: [], duplicates: [], - relativeDate: '', + relativeDate: '1 min ago', annotations: [], debugInfo: {}, rawVisitData: {
diff --git a/chrome/test/data/webui/new_tab_page/modules/v2/history_clusters/module_test.ts b/chrome/test/data/webui/new_tab_page/modules/v2/history_clusters/module_test.ts index 3e63888..cbe8167 100644 --- a/chrome/test/data/webui/new_tab_page/modules/v2/history_clusters/module_test.ts +++ b/chrome/test/data/webui/new_tab_page/modules/v2/history_clusters/module_test.ts
@@ -399,6 +399,13 @@ for (const discount of moduleElement.discounts) { assertEquals('', discount); } + const contentElement = + moduleElement.shadowRoot! + .querySelector('ntp-history-clusters-visit-tile')!.shadowRoot! + .querySelector('#content')! as HTMLElement; + assertEquals( + contentElement.getAttribute('aria-label'), + 'Test Title 1, foo.com, 1 min ago'); } assertEquals(0, metrics.count(`NewTabPage.HistoryClusters.HasDiscount`)); }); @@ -459,8 +466,19 @@ assertEquals( 'https://www.annotated.com/1', visitTiles[0]!.visit.normalizedUrl.url); + let contentElement = + visitTiles[0]!.shadowRoot!.querySelector('#content')! as HTMLElement; + assertEquals( + contentElement.getAttribute('aria-label'), + 'Test Title 1, annotated.com, 1 min ago, 15% off'); + assertEquals( 'https://www.foo.com/2', visitTiles[1]!.visit.normalizedUrl.url); + contentElement = + visitTiles[1]!.shadowRoot!.querySelector('#content')! as HTMLElement; + assertEquals( + contentElement.getAttribute('aria-label'), + 'Test Title 2, foo.com, 1 min ago'); // Assert Module Two. const expectedDiscountsModuleTwo = ['', '', '$10 off']; @@ -478,9 +496,20 @@ } assertEquals( 'https://www.foo.com/3', visitTiles[0]!.visit.normalizedUrl.url); + contentElement = + visitTiles[0]!.shadowRoot!.querySelector('#content')! as HTMLElement; + assertEquals( + contentElement.getAttribute('aria-label'), + 'Test Title 1, foo.com, 1 min ago'); + assertEquals( 'https://www.annotated.com/2', visitTiles[1]!.visit.normalizedUrl.url); + contentElement = + visitTiles[1]!.shadowRoot!.querySelector('#content')! as HTMLElement; + assertEquals( + contentElement.getAttribute('aria-label'), + 'Test Title 2, annotated.com, 1 min ago, $10 off'); // Assert info dialog. for (const moduleElement of moduleElements) {
diff --git a/chrome/test/data/webui/print_preview/button_strip_interactive_test.ts b/chrome/test/data/webui/print_preview/button_strip_interactive_test.ts index 0a273789..c724753 100644 --- a/chrome/test/data/webui/print_preview/button_strip_interactive_test.ts +++ b/chrome/test/data/webui/print_preview/button_strip_interactive_test.ts
@@ -3,7 +3,7 @@ // found in the LICENSE file. import {Destination, DestinationOrigin, PrintPreviewButtonStripElement, State} from 'chrome://print/print_preview.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {eventToPromise} from 'chrome://webui-test/test_util.js'; suite('ButtonStripInteractiveTest', function() {
diff --git a/chrome/test/data/webui/print_preview/custom_margins_test.ts b/chrome/test/data/webui/print_preview/custom_margins_test.ts index ec86271..42d26492 100644 --- a/chrome/test/data/webui/print_preview/custom_margins_test.ts +++ b/chrome/test/data/webui/print_preview/custom_margins_test.ts
@@ -3,7 +3,7 @@ // found in the LICENSE file. import {CustomMarginsOrientation, Margins, MarginsSetting, MarginsType, MeasurementSystem, MeasurementSystemUnitType, PrintPreviewMarginControlContainerElement, PrintPreviewMarginControlElement, PrintPreviewModelElement, Size, State} from 'chrome://print/print_preview.js'; -import {assertNotReached} from 'chrome://resources/js/assert_ts.js'; +import {assertNotReached} from 'chrome://resources/js/assert.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {fakeDataBind} from 'chrome://webui-test/polymer_test_util.js';
diff --git a/chrome/test/data/webui/print_preview/destination_settings_test.ts b/chrome/test/data/webui/print_preview/destination_settings_test.ts index 8a00fe5..77ef34a2 100644 --- a/chrome/test/data/webui/print_preview/destination_settings_test.ts +++ b/chrome/test/data/webui/print_preview/destination_settings_test.ts
@@ -3,7 +3,7 @@ // found in the LICENSE file. import {Destination, DestinationErrorType, DestinationOrigin, DestinationState, DestinationStoreEventType, Error, GooglePromotedDestinationId, LocalDestinationInfo, makeRecentDestination, NativeLayerImpl, NUM_PERSISTED_DESTINATIONS, PrintPreviewDestinationSettingsElement, RecentDestination, State} from 'chrome://print/print_preview.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {fakeDataBind, waitBeforeNextRender} from 'chrome://webui-test/polymer_test_util.js';
diff --git a/chrome/test/data/webui/print_preview/dpi_settings_test.ts b/chrome/test/data/webui/print_preview/dpi_settings_test.ts index ae21840..5de48a07 100644 --- a/chrome/test/data/webui/print_preview/dpi_settings_test.ts +++ b/chrome/test/data/webui/print_preview/dpi_settings_test.ts
@@ -5,7 +5,7 @@ import 'chrome://print/print_preview.js'; import {LabelledDpiCapability, PrintPreviewDpiSettingsElement} from 'chrome://print/print_preview.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {assertDeepEquals, assertEquals, assertFalse} from 'chrome://webui-test/chai_assert.js'; import {fakeDataBind} from 'chrome://webui-test/polymer_test_util.js';
diff --git a/chrome/test/data/webui/print_preview/invalid_settings_test.ts b/chrome/test/data/webui/print_preview/invalid_settings_test.ts index 73762a81..526d5c7c 100644 --- a/chrome/test/data/webui/print_preview/invalid_settings_test.ts +++ b/chrome/test/data/webui/print_preview/invalid_settings_test.ts
@@ -3,7 +3,7 @@ // found in the LICENSE file. import {CrButtonElement, Destination, MeasurementSystemUnitType, NativeInitialSettings, NativeLayerImpl, PluginProxyImpl, PrintPreviewAppElement, State, whenReady} from 'chrome://print/print_preview.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {waitBeforeNextRender} from 'chrome://webui-test/polymer_test_util.js';
diff --git a/chrome/test/data/webui/print_preview/link_container_test.ts b/chrome/test/data/webui/print_preview/link_container_test.ts index f5308bb3..18c4f4b4 100644 --- a/chrome/test/data/webui/print_preview/link_container_test.ts +++ b/chrome/test/data/webui/print_preview/link_container_test.ts
@@ -4,7 +4,7 @@ import {Destination, DestinationOrigin, PrintPreviewLinkContainerElement} from 'chrome://print/print_preview.js'; // <if expr="is_macosx"> -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; // </if> import {isWindows} from 'chrome://resources/js/platform.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
diff --git a/chrome/test/data/webui/print_preview/native_layer_cros_stub.ts b/chrome/test/data/webui/print_preview/native_layer_cros_stub.ts index fd5a6d2..0591ee6 100644 --- a/chrome/test/data/webui/print_preview/native_layer_cros_stub.ts +++ b/chrome/test/data/webui/print_preview/native_layer_cros_stub.ts
@@ -3,7 +3,7 @@ // found in the LICENSE file. import {LocalDestinationInfo, NativeLayerCros, NativeLayerCrosImpl, PrinterSetupResponse, PrinterStatus, PrinterStatusReason, PrinterStatusSeverity, PrintServersConfig} from 'chrome://print/print_preview.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.js'; import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
diff --git a/chrome/test/data/webui/print_preview/native_layer_stub.ts b/chrome/test/data/webui/print_preview/native_layer_stub.ts index bf0091c..95fd4fb 100644 --- a/chrome/test/data/webui/print_preview/native_layer_stub.ts +++ b/chrome/test/data/webui/print_preview/native_layer_stub.ts
@@ -3,7 +3,7 @@ // found in the LICENSE file. import {CapabilitiesResponse, ExtensionDestinationInfo, GooglePromotedDestinationId, LocalDestinationInfo, NativeInitialSettings, NativeLayer, PageLayoutInfo, PrinterType} from 'chrome://print/print_preview.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {webUIListenerCallback} from 'chrome://resources/js/cr.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.js'; import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
diff --git a/chrome/test/data/webui/print_preview/pdf_toolbar_manager_test.ts b/chrome/test/data/webui/print_preview/pdf_toolbar_manager_test.ts index ab2ea4c..30bba943 100644 --- a/chrome/test/data/webui/print_preview/pdf_toolbar_manager_test.ts +++ b/chrome/test/data/webui/print_preview/pdf_toolbar_manager_test.ts
@@ -3,7 +3,7 @@ // found in the LICENSE file. import {ToolbarManager, ViewerZoomToolbarElement} from 'chrome://print/pdf/pdf_print_wrapper.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; class MockWindow {
diff --git a/chrome/test/data/webui/print_preview/print_preview_test_utils.ts b/chrome/test/data/webui/print_preview/print_preview_test_utils.ts index 1b43e21b..89166cf0 100644 --- a/chrome/test/data/webui/print_preview/print_preview_test_utils.ts +++ b/chrome/test/data/webui/print_preview/print_preview_test_utils.ts
@@ -5,7 +5,7 @@ import {CapabilitiesResponse, Cdd, ColorOption, DEFAULT_MAX_COPIES, Destination, DestinationOrigin, DestinationStore, DpiOption, DuplexOption, ExtensionDestinationInfo, GooglePromotedDestinationId, LocalDestinationInfo, MeasurementSystemUnitType, MediaSizeCapability, MediaSizeOption, MediaTypeOption, NativeInitialSettings, PageOrientationOption, VendorCapabilityValueType} from 'chrome://print/print_preview.js'; import {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.js'; import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {assertEquals} from 'chrome://webui-test/chai_assert.js';
diff --git a/chrome/test/data/webui/print_preview/test_plugin_proxy.ts b/chrome/test/data/webui/print_preview/test_plugin_proxy.ts index 8551abde6..f4f13201 100644 --- a/chrome/test/data/webui/print_preview/test_plugin_proxy.ts +++ b/chrome/test/data/webui/print_preview/test_plugin_proxy.ts
@@ -4,7 +4,7 @@ import {PdfPlugin} from 'chrome://print/pdf/pdf_scripting_api.js'; import {PluginProxy, ViewportChangedCallback} from 'chrome://print/print_preview.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js'; /**
diff --git a/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js b/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js index 073a5dcb..67a27d2 100644 --- a/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js
@@ -59,9 +59,11 @@ * @param {!UpdateStatus} status * @param {{ * progress: number|undefined, - * message: string|undefined - * rollback: bool|undefined - * powerwash: bool|undefined + * message: string|undefined, + * rollback: bool|undefined, + * powerwash: bool|undefined, + * version: string|undefined, + * size: string|undefined, * }} opt_options */ function fireStatusChanged(status, opt_options) { @@ -69,9 +71,11 @@ webUIListenerCallback('update-status-changed', { progress: options.progress === undefined ? 1 : options.progress, message: options.message, - status: status, + status, rollback: options.rollback, powerwash: options.powerwash, + version: options.version, + size: options.size, }); } @@ -268,6 +272,23 @@ assertEquals(expectedMessage, statusMessageEl.textContent); }); + test( + 'Warning dialog is shown when attempting to update over metered network', + async () => { + await initNewPage(); + + fireStatusChanged( + UpdateStatus.NEED_PERMISSION_TO_UPDATE, + {version: '9001.0.0', size: '9999'}); + flush(); + + const warningDialog = + page.shadowRoot.querySelector('settings-update-warning-dialog'); + assertTrue(!!warningDialog); + assertTrue( + warningDialog.$.dialog.open, 'Warning dialog should be open'); + }); + test('NoInternet', function() { assertTrue(page.$.updateStatusMessage.hidden); aboutBrowserProxy.sendStatusNoInternet();
diff --git a/chrome/test/data/webui/side_panel/customize_chrome/combobox_test.ts b/chrome/test/data/webui/side_panel/customize_chrome/combobox_test.ts index ba3e316b..932c158 100644 --- a/chrome/test/data/webui/side_panel/customize_chrome/combobox_test.ts +++ b/chrome/test/data/webui/side_panel/customize_chrome/combobox_test.ts
@@ -104,4 +104,40 @@ assertFalse(isVisible(combobox.$.dropdown)); assertEquals(null, combobox.querySelector('[highlighted]')); }); + + test('SelectsItem', async () => { + const groupA = addGroup(); + const optionA1 = addOption(groupA); + optionA1.innerText = 'I am option 1'; + const optionA2 = addOption(groupA); + optionA2.innerText = 'I am option 2'; + await flushTasks(); + + // Open dropdown, click on first option to select it. + combobox.$.input.click(); + optionA1.dispatchEvent(new Event('click', {composed: true, bubbles: true})); + assertTrue(optionA1.hasAttribute('selected')); + assertFalse(isVisible(combobox.$.dropdown)); + assertTrue(combobox.$.input.textContent!.includes('I am option 1')); + + // Open the dropdown back and arrow key to next option and select it. + combobox.$.input.click(); + combobox.dispatchEvent(new KeyboardEvent('keydown', {key: 'ArrowDown'})); + assertFalse(optionA2.hasAttribute('selected')); + combobox.dispatchEvent(new KeyboardEvent('keydown', {key: 'Enter'})); + assertTrue(optionA2.hasAttribute('selected')); + assertFalse(optionA1.hasAttribute('selected')); + assertTrue(combobox.$.input.textContent!.includes('I am option 2')); + assertFalse(isVisible(combobox.$.dropdown)); + + // Pressing Enter or clicking on an unselectable item should not select it. + combobox.$.input.click(); + combobox.dispatchEvent(new KeyboardEvent('keydown', {key: 'Home'})); + combobox.dispatchEvent(new KeyboardEvent('keydown', {key: 'Enter'})); + assertFalse(groupA.hasAttribute('selected')); + groupA.dispatchEvent(new Event('click', {composed: true, bubbles: true})); + assertFalse(groupA.hasAttribute('selected')); + assertTrue(optionA2.hasAttribute('selected')); + assertTrue(isVisible(combobox.$.dropdown)); + }); });
diff --git a/chrome/test/data/webui/side_panel/read_anything/on_selection_change_nothing_selected_on_loading_screen_selection.js b/chrome/test/data/webui/side_panel/read_anything/on_selection_change_nothing_selected_on_loading_screen_selection.js index dc8f710..c128240 100644 --- a/chrome/test/data/webui/side_panel/read_anything/on_selection_change_nothing_selected_on_loading_screen_selection.js +++ b/chrome/test/data/webui/side_panel/read_anything/on_selection_change_nothing_selected_on_loading_screen_selection.js
@@ -16,11 +16,18 @@ document.querySelector('read-anything-app').shadowRoot; const emptyState = readAnythingApp.getElementById('empty-state-container'); - let selectionChanged = false; - chrome.readingMode.onSelectionChange = - (_anchorNodeId, _anchorOffset, _focusNodeId, _focusOffset) => { - selectionChanged = true; - }; + let result = true; + const assertEquals = (actual, expected) => { + const isEqual = actual === expected; + if (!isEqual) { + console.error( + 'Expected: ' + JSON.stringify(expected) + ', ' + + 'Actual: ' + JSON.stringify(actual)); + } + result = result && isEqual; + return isEqual; + }; + const range = new Range(); range.setStartBefore(emptyState); @@ -31,7 +38,14 @@ return new Promise(resolve => { setTimeout(() => { - resolve(!selectionChanged); + const retrieved_selection = readAnythingApp.getSelection(); + assertEquals(retrieved_selection.rangeCount, 0); + assertEquals(retrieved_selection.anchorNode, null); + assertEquals(retrieved_selection.focusNode, null); + assertEquals(retrieved_selection.anchorOffset, 0); + assertEquals(retrieved_selection.anchorOffset, 0); + assertEquals(retrieved_selection.focusOffset, 0); + resolve(result); }, 1000); }); })();
diff --git a/chrome/test/data/webui/test_browser_proxy.ts b/chrome/test/data/webui/test_browser_proxy.ts index b2b6402..ad60a0c 100644 --- a/chrome/test/data/webui/test_browser_proxy.ts +++ b/chrome/test/data/webui/test_browser_proxy.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.js'; /**
diff --git a/chrome/test/data/webui/test_mock.ts b/chrome/test/data/webui/test_mock.ts index 67f6978..5999595 100644 --- a/chrome/test/data/webui/test_mock.ts +++ b/chrome/test/data/webui/test_mock.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assert} from 'chrome://resources/js/assert.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.js'; type Constructor<T> = new (...args: any[]) => T;
diff --git a/chrome/test/interaction/interactive_browser_test.cc b/chrome/test/interaction/interactive_browser_test.cc index 8ed8dc8..adf70cb6 100644 --- a/chrome/test/interaction/interactive_browser_test.cc +++ b/chrome/test/interaction/interactive_browser_test.cc
@@ -45,29 +45,6 @@ constexpr ui::InteractionSequence::ContextMode kDefaultWebContentsContextMode = ui::InteractionSequence::ContextMode::kAny; -std::string DescribeStateChange( - const WebContentsInteractionTestUtil::StateChange& state_change) { - std::ostringstream oss; - oss << "StateChange{ "; - switch (state_change.type) { - case WebContentsInteractionTestUtil::StateChange::Type::kDoesNotExist: - oss << "does not exist: " << state_change.where << " }"; - break; - case WebContentsInteractionTestUtil::StateChange::Type::kExists: - oss << "exists: " << state_change.where << " }"; - break; - case WebContentsInteractionTestUtil::StateChange::Type:: - kExistsAndConditionTrue: - oss << "exists: " << state_change.where << " and condition true:\n" - << state_change.test_function << "\n}"; - break; - case WebContentsInteractionTestUtil::StateChange::Type::kConditionTrue: - oss << "condition true:\n" << state_change.test_function << "\n}"; - break; - } - return oss.str(); -} - // Matcher that determines whether a particular value is truthy. class IsTruthyMatcher : public testing::MatcherInterface<const base::Value&> { public: @@ -377,14 +354,16 @@ ui::CustomElementEventType event_type = expect_timeout ? state_change.timeout_event : state_change.event; CHECK(event_type); - const auto desc = base::StringPrintf( - "WaitForStateChange( %s, %s )", DescribeStateChange(state_change).c_str(), - expect_timeout ? "true" : "false"); + std::ostringstream desc; + desc << "WaitForStateChange( " << state_change << ", " + << (expect_timeout ? "true" : "false") << " )"; + const bool fail_on_close = !state_change.continue_across_navigation; return Steps( std::move(StepBuilder() - .SetDescription(base::StrCat({desc, ": Queue Event"})) + .SetDescription(base::StrCat({desc.str(), ": Queue Event"})) .SetElementID(webcontents_id) .SetContext(kDefaultWebContentsContextMode) + .SetMustRemainVisible(fail_on_close) .SetStartCallback(base::BindOnce( [](StateChange state_change, ui::TrackedElement* el) { el->AsA<TrackedElementWebContents>() @@ -392,13 +371,15 @@ ->SendEventOnStateChange(state_change); }, state_change))), - std::move(StepBuilder() - .SetDescription(base::StrCat({desc, ": Wait For Event"})) - .SetElementID(webcontents_id) - .SetContext( - ui::InteractionSequence::ContextMode::kFromPreviousStep) - .SetType(ui::InteractionSequence::StepType::kCustomEvent, - event_type))); + std::move( + StepBuilder() + .SetDescription(base::StrCat({desc.str(), ": Wait For Event"})) + .SetElementID(webcontents_id) + .SetContext( + ui::InteractionSequence::ContextMode::kFromPreviousStep) + .SetType(ui::InteractionSequence::StepType::kCustomEvent, + event_type) + .SetMustBeVisibleAtStart(fail_on_close))); } // static
diff --git a/chrome/test/interaction/interactive_browser_test_browsertest.cc b/chrome/test/interaction/interactive_browser_test_browsertest.cc index 6ffb8f8f..2e0ec44 100644 --- a/chrome/test/interaction/interactive_browser_test_browsertest.cc +++ b/chrome/test/interaction/interactive_browser_test_browsertest.cc
@@ -13,6 +13,7 @@ #include "chrome/test/base/test_switches.h" #include "content/public/test/browser_test.h" #include "ui/base/interaction/element_identifier.h" +#include "ui/base/interaction/element_tracker.h" #include "ui/base/interaction/expect_call_in_scope.h" #include "ui/base/interaction/interaction_sequence.h" #include "url/gurl.h" @@ -511,6 +512,53 @@ CheckJsResultAt(kTabId, kText, kElementIsInViewport, true)); } +IN_PROC_BROWSER_TEST_F(InteractiveBrowserTestBrowsertest, + WaitForStateChangeAcrossNavigation) { + DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kTabId); + DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kFoundElementEvent); + const GURL url1 = embedded_test_server()->GetURL(kDocumentWithLinks); + const GURL url2 = embedded_test_server()->GetURL(kDocumentWithNamedElement); + + StateChange state_change; + state_change.type = StateChange::Type::kExists; + state_change.where = {"#select"}; + state_change.continue_across_navigation = true; + state_change.event = kFoundElementEvent; + + RunTestSequence( + InstrumentTab(kTabId), + // This is needed to prevent subsequent navigation from causing the + // previous step to fail due to the element immediately losing visibility. + FlushEvents(), + InParallel(Steps(NavigateWebContents(kTabId, url1), + NavigateWebContents(kTabId, url2)), + WaitForStateChange(kTabId, state_change))); +} + +IN_PROC_BROWSER_TEST_F(InteractiveBrowserTestBrowsertest, + WaitForStateChangeWithConditionAcrossNavigation) { + DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kTabId); + DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kFoundElementEvent); + const GURL url1 = embedded_test_server()->GetURL(kDocumentWithLinks); + const GURL url2 = embedded_test_server()->GetURL(kDocumentWithNamedElement); + + StateChange state_change; + state_change.type = StateChange::Type::kExistsAndConditionTrue; + state_change.where = {"#select option[selected]"}; + state_change.test_function = "(el) => (el.innerText === 'Apple')"; + state_change.continue_across_navigation = true; + state_change.event = kFoundElementEvent; + + RunTestSequence( + InstrumentTab(kTabId), + // This is needed to prevent subsequent navigation from causing the + // previous step to fail due to the element immediately losing visibility. + FlushEvents(), + InParallel(Steps(NavigateWebContents(kTabId, url1), + NavigateWebContents(kTabId, url2)), + WaitForStateChange(kTabId, state_change))); +} + // Parameter for WebUI coverage tests. struct CoverageConfig { // Whether to set the --devtools-code-coverage flag. If it's not set, nothing
diff --git a/chrome/test/interaction/webcontents_interaction_test_util.cc b/chrome/test/interaction/webcontents_interaction_test_util.cc index 48ff5937..84b49ac 100644 --- a/chrome/test/interaction/webcontents_interaction_test_util.cc +++ b/chrome/test/interaction/webcontents_interaction_test_util.cc
@@ -4,6 +4,7 @@ #include "chrome/test/interaction/webcontents_interaction_test_util.h" +#include <algorithm> #include <initializer_list> #include <set> #include <sstream> @@ -18,6 +19,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/weak_auto_reset.h" #include "base/memory/weak_ptr.h" +#include "base/notreached.h" #include "base/scoped_observation.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -77,6 +79,105 @@ on_not_found, on_found); } +// Does `StateChange` validation, including inferring the actual type for +// `Type::kAuto`, and returns the (potentially updated) StateChange. +WebContentsInteractionTestUtil::StateChange ValidateAndInferStateChange( + const WebContentsInteractionTestUtil::StateChange& state_change) { + WebContentsInteractionTestUtil::StateChange configuration = state_change; + + CHECK(configuration.event) << "StateChange missing event - " << configuration; + CHECK(configuration.timeout.has_value() || !configuration.timeout_event) + << "StateChange cannot specify timeout event without timeout - " + << configuration; + + const bool has_function = !configuration.test_function.empty(); + const bool has_where = !configuration.where.empty(); + using Type = WebContentsInteractionTestUtil::StateChange::Type; + switch (configuration.type) { + case Type::kAuto: + if (has_function) { + configuration.type = + has_where ? Type::kExistsAndConditionTrue : Type::kConditionTrue; + } else if (has_where) { + configuration.type = Type::kExists; + } else { + NOTREACHED_NORETURN() + << "Unable to infer StateChange type - " << configuration; + } + break; + case Type::kExists: + CHECK(has_where) << "Expected where to be non-empty - " << configuration; + CHECK(!has_function) << "Expected test function to be empty - " + << configuration; + break; + case Type::kDoesNotExist: + CHECK(has_where) << "Expected where to be non-empty - " << configuration; + CHECK(!has_function) << "Expected test function to be empty - " + << configuration; + break; + case Type::kConditionTrue: + CHECK(!has_where) << "Expected where to be empty - " << configuration; + CHECK(has_function) << "Expected test function to be non-empty - " + << configuration; + break; + case Type::kExistsAndConditionTrue: + CHECK(has_where && has_function) + << "Expected where and function to be non-empty - " << configuration; + } + return configuration; +} + +// Detects the presence of a javascript `function` that takes (el, err) as +// parameters, for backwards-compatibility with older tests that require this. +// +// Expectation is one of: +// ... x, y ... => ... +// ... x, y ... { ... +// +// Functions not in this format will not be recognized as taking an error param. +bool HasErrorParameter(const std::string& function) { + size_t body1 = function.find("=>"); + size_t body2 = function.find('{'); + const size_t body = + (body1 == std::string::npos) + ? body2 + : (body2 == std::string::npos ? body1 : std::min(body1, body2)); + if (body == std::string::npos) { + return false; + } + const size_t comma = function.find(','); + return comma != std::string::npos && comma < body; +} + +// Returns the JS query that must be sent to check a particular state change. +std::string GetStateChangeQuery( + const WebContentsInteractionTestUtil::StateChange& configuration) { + // For `kConditionTrue`, `configuration.test_function` can be used directly + // directly, but for the other options it must be modified. + using Type = WebContentsInteractionTestUtil::StateChange::Type; + switch (configuration.type) { + case Type::kAuto: + NOTREACHED_NORETURN() << "Auto type should already have been inferred."; + case Type::kExists: + return GetExistsQuery( + /* on_not_found = */ "false", + /* on_found = */ "true"); + case Type::kDoesNotExist: + return GetExistsQuery( + /* on_not_found = */ "true", + /* on_found = */ "false"); + case Type::kConditionTrue: + return configuration.test_function; + case Type::kExistsAndConditionTrue: + if (HasErrorParameter(configuration.test_function)) { + return configuration.test_function; + } + const std::string on_found = "(" + configuration.test_function + ")(el)"; + return GetExistsQuery( + /* on_not_found = */ "false", on_found.c_str()); + } +} + // Common execution code for `EvalJsLocal()` and `ExecuteJsLocal()`. // Executes `script` on `host`. void ExecuteScript(content::RenderFrameHost* host, const std::string& script) { @@ -292,25 +393,21 @@ class WebContentsInteractionTestUtil::Poller { public: - Poller(WebContentsInteractionTestUtil* const owner, - const std::string& function, - const DeepQuery& where, - absl::optional<base::TimeDelta> timeout, - base::TimeDelta interval) - : function_(function), - where_(where), - interval_(interval), - timeout_(timeout), + Poller(WebContentsInteractionTestUtil* const owner, StateChange state_change) + : state_change_(std::move(state_change)), + js_query_(GetStateChangeQuery(state_change_)), owner_(owner) {} ~Poller() = default; void StartPolling() { CHECK(!timer_.IsRunning()); - timer_.Start(FROM_HERE, interval_, + timer_.Start(FROM_HERE, state_change_.polling_interval, base::BindRepeating(&Poller::Poll, base::Unretained(this))); } + const StateChange& state_change() const { return state_change_; } + private: void Poll() { // Callback can get called again if Evaluate() below stalls. We don't want @@ -319,48 +416,44 @@ if (is_polling_) return; + // If there is no page loaded, then there is nothing to poll. + if (!owner_->is_page_loaded()) { + CHECK(state_change_.continue_across_navigation) + << "Page discarded waiting for StateChange event " + << state_change_.event; + return; + } + auto weak_ptr = weak_factory_.GetWeakPtr(); base::WeakAutoReset is_polling_auto_reset(weak_ptr, &Poller::is_polling_, true); - base::Value result; - if (where_.empty()) { - result = owner_->Evaluate(function_); - } else if (function_.empty()) { - result = base::Value(owner_->Exists(where_)); - } else { - result = owner_->EvaluateAt(where_, function_); - } + const base::Value result = + state_change_.where.empty() + ? owner_->Evaluate(js_query_) + : owner_->EvaluateAt(state_change_.where, js_query_); // At this point, weak_ptr might be invalid since we could have been deleted // while we were waiting for Evaluate[At]() to complete. if (weak_ptr) { if (IsTruthy(result)) { - owner_->OnPollEvent(this); - } else if (timeout_.has_value() && - elapsed_.Elapsed() > timeout_.value()) { - owner_->OnPollTimeout(this); + owner_->OnPollEvent(this, state_change_.event); + } else if (state_change_.timeout.has_value() && + elapsed_.Elapsed() > state_change_.timeout.value()) { + owner_->OnPollEvent(this, state_change_.timeout_event); } } } const base::ElapsedTimer elapsed_; - const std::string function_; - const DeepQuery where_; - const base::TimeDelta interval_; - const absl::optional<base::TimeDelta> timeout_; + const StateChange state_change_; + const std::string js_query_; const raw_ptr<WebContentsInteractionTestUtil> owner_; base::RepeatingTimer timer_; bool is_polling_ = false; base::WeakPtrFactory<Poller> weak_factory_{this}; }; -struct WebContentsInteractionTestUtil::PollerData { - std::unique_ptr<Poller> poller; - ui::CustomElementEventType event; - ui::CustomElementEventType timeout_event; -}; - // Class that tracks a WebView and its WebContents in a secondary UI. class WebContentsInteractionTestUtil::WebViewData : public views::ViewObserver { public: @@ -749,44 +842,10 @@ void WebContentsInteractionTestUtil::SendEventOnStateChange( const StateChange& configuration) { CHECK(current_element_); - CHECK(!configuration.where.empty() || !configuration.test_function.empty()); - CHECK(configuration.event); - CHECK(configuration.timeout.has_value() || !configuration.timeout_event) - << "Cannot specify timeout event without timeout."; - // Determine the actual query we should use; for kConditionTrue we can use - // configuration.test_function directly, but for the other options we need to - // modify it. - std::string actual_func; - switch (configuration.type) { - case StateChange::Type::kExists: - DCHECK(configuration.test_function.empty()); - actual_func = GetExistsQuery( - /* on_not_found = */ "false", - /* on_found = */ "true"); - break; - case StateChange::Type::kDoesNotExist: - actual_func = GetExistsQuery( - /* on_not_found = */ "true", - /* on_found = */ "false"); - break; - case StateChange::Type::kConditionTrue: - actual_func = configuration.test_function; - break; - case StateChange::Type::kExistsAndConditionTrue: - const std::string on_found = "(" + configuration.test_function + ")(el)"; - actual_func = GetExistsQuery( - /* on_not_found = */ "false", on_found.c_str()); - break; - } - - PollerData poller_data{ - std::make_unique<Poller>(this, actual_func, configuration.where, - configuration.timeout, - configuration.polling_interval), - configuration.event, configuration.timeout_event}; - auto* const poller = poller_data.poller.get(); - pollers_.emplace(poller, std::move(poller_data)); + auto actual_config = ValidateAndInferStateChange(configuration); + const auto& poller = pollers_.emplace_back( + std::make_unique<Poller>(this, std::move(actual_config))); poller->StartPolling(); } @@ -1016,32 +1075,28 @@ void WebContentsInteractionTestUtil::DiscardCurrentElement() { current_element_.reset(); - CHECK(pollers_.empty()) - << "Unexpectedly left page while still waiting for event " - << pollers_.begin()->second.event.GetName(); - pollers_.clear(); + for (const auto& poller : pollers_) { + CHECK(poller->state_change().continue_across_navigation) + << "Unexpectedly left page while still waiting for StateChange event " + << poller->state_change().event; + } } -void WebContentsInteractionTestUtil::OnPollTimeout(Poller* poller) { - CHECK(current_element_); - auto it = pollers_.find(poller); +void WebContentsInteractionTestUtil::OnPollEvent( + Poller* poller, + ui::CustomElementEventType event) { + CHECK(current_element_) + << "StateChange succeeded (or failed) while no page was loaded; " + "this is always an error even if continue_across_navigation is true."; + const auto it = + std::find_if(pollers_.begin(), pollers_.end(), + [poller](const auto& ptr) { return ptr.get() == poller; }); CHECK(it != pollers_.end()); - auto event = it->second.timeout_event; pollers_.erase(it); - CHECK(event) << "SendEventOnStateChange timed out, but no timeout event was " - "specified."; - ui::ElementTracker::GetFrameworkDelegate()->NotifyCustomEvent( - current_element_.get(), event); -} - -void WebContentsInteractionTestUtil::OnPollEvent(Poller* poller) { - CHECK(current_element_); - auto it = pollers_.find(poller); - CHECK(it != pollers_.end()); - auto event = it->second.event; - pollers_.erase(it); - ui::ElementTracker::GetFrameworkDelegate()->NotifyCustomEvent( - current_element_.get(), event); + if (event) { + ui::ElementTracker::GetFrameworkDelegate()->NotifyCustomEvent( + current_element_.get(), event); + } } void WebContentsInteractionTestUtil::StartWatchingWebContents( @@ -1068,3 +1123,40 @@ PrintTo(deep_query, &os); return os; } + +void PrintTo(const WebContentsInteractionTestUtil::StateChange& state_change, + std::ostream* os) { + using Type = WebContentsInteractionTestUtil::StateChange::Type; + *os << "{ "; + switch (state_change.type) { + case Type::kAuto: + *os << "kAuto"; + break; + case Type::kExists: + *os << "kExists"; + break; + case Type::kExistsAndConditionTrue: + *os << "kExistsAndConditionTrue"; + break; + case Type::kConditionTrue: + *os << "kConditionTrue"; + break; + case Type::kDoesNotExist: + *os << "kDoesNotExist"; + break; + } + + *os << ", test_function: \"" << state_change.test_function << "\"" + << ", where: " << state_change.where << ", event: " << state_change.event + << ", continue_across_navigation: " + << (state_change.continue_across_navigation ? "true" : "false") + << ", timeout: " << state_change.timeout.value_or(base::TimeDelta()) + << ", timeout_event: " << state_change.timeout_event << " }"; +} + +extern std::ostream& operator<<( + std::ostream& os, + const WebContentsInteractionTestUtil::StateChange& state_change) { + PrintTo(state_change, &os); + return os; +}
diff --git a/chrome/test/interaction/webcontents_interaction_test_util.h b/chrome/test/interaction/webcontents_interaction_test_util.h index 7afdc07..ec310c86 100644 --- a/chrome/test/interaction/webcontents_interaction_test_util.h +++ b/chrome/test/interaction/webcontents_interaction_test_util.h
@@ -115,22 +115,28 @@ // What type of state change are we watching for? enum class Type { - // Triggers when `test_function`, evaluated at `where`, returns true. - // If `where` does not exist, an error is generated. + // Automatically chooses one of the other types, based on which of + // `test_function` and `where` are set. Will never choose `kDoesNotExist` + // (default). + kAuto, + // Triggers when `test_function` returns true. The `where` field + // should not be set. kConditionTrue, // Triggers when the element specified by `where` exists in the DOM. - // The `test_function` field is ignored. + // The `test_function` field should not be set. kExists, // Triggers when the element specified by `where` exists in the DOM *and* - // `test_function` evaluates to true. + // `test_function` evaluates to true. Both must be set. kExistsAndConditionTrue, // Triggers if/when the element specified by `where` no longer exists. + // The `test_function` field should not be set. kDoesNotExist }; - // By default we want to check `test_function` and assume the element - // exists. - Type type = Type::kConditionTrue; + // By default the type of state change is inferred from the other + // parameters. This may be set explicitly, but it should only be required + // for `kDoesNotExist` as there is no way to infer that option. + Type type = Type::kAuto; // Function to be evaluated every `polling_interval`. Must be able to // execute multiple times successfully. State change is detected when this @@ -159,6 +165,12 @@ // indefinitely (in practice, until the test itself times out). absl::optional<base::TimeDelta> timeout; + // If this is set to `true`, the condition will continue to be polled across + // page navigation. This can be used when the target WebContents may + // transition through one or more intermediate pages before the expected + // condition is met. + bool continue_across_navigation = false; + // The event to fire when `test_script` returns a truthy value. Must be // specified. ui::CustomElementEventType event; @@ -411,7 +423,6 @@ OpenTabSearchMenuAndTestVisibility); class NewTabWatcher; class Poller; - struct PollerData; class WebViewData; WebContentsInteractionTestUtil(content::WebContents* web_contents, @@ -422,8 +433,7 @@ void MaybeCreateElement(bool force = false); void DiscardCurrentElement(); - void OnPollTimeout(Poller* poller); - void OnPollEvent(Poller* poller); + void OnPollEvent(Poller* poller, ui::CustomElementEventType event); void StartWatchingWebContents(content::WebContents* web_contents); @@ -443,7 +453,7 @@ std::unique_ptr<TrackedElementWebContents> current_element_; // List of active event pollers for the current page. - std::map<Poller*, PollerData> pollers_; + std::list<std::unique_ptr<Poller>> pollers_; // Optional object that watches for a new tab to be created, either in a // specific browser or in any browser. @@ -457,4 +467,12 @@ std::ostream& os, const WebContentsInteractionTestUtil::DeepQuery& deep_query); +extern void PrintTo( + const WebContentsInteractionTestUtil::StateChange& state_change, + std::ostream* os); + +extern std::ostream& operator<<( + std::ostream& os, + const WebContentsInteractionTestUtil::StateChange& state_change); + #endif // CHROME_TEST_INTERACTION_WEBCONTENTS_INTERACTION_TEST_UTIL_H_
diff --git a/chrome/test/interaction/webcontents_interaction_test_util_browsertest.cc b/chrome/test/interaction/webcontents_interaction_test_util_browsertest.cc index 4c8d33e..5f0f02d 100644 --- a/chrome/test/interaction/webcontents_interaction_test_util_browsertest.cc +++ b/chrome/test/interaction/webcontents_interaction_test_util_browsertest.cc
@@ -1479,8 +1479,6 @@ // doesn't exist in the document. WebContentsInteractionTestUtil::StateChange state_change; - state_change.type = WebContentsInteractionTestUtil:: - StateChange::Type::kConditionTrue; state_change.where = kQuery; state_change.test_function = kCheckFunction; state_change.event = @@ -2213,6 +2211,57 @@ EXPECT_CALL_IN_SCOPE(completed, Run, sequence->RunSynchronouslyForTesting()); } +IN_PROC_BROWSER_TEST_F(WebContentsInteractionTestUtilTest, + SendEventOnExistsStateChangeContinueAcrossNavigation) { + UNCALLED_MOCK_CALLBACK(ui::InteractionSequence::CompletedCallback, completed); + UNCALLED_MOCK_CALLBACK(ui::InteractionSequence::AbortedCallback, aborted); + + const WebContentsInteractionTestUtil::DeepQuery kQuery{"#ref"}; + auto util = WebContentsInteractionTestUtil::ForExistingTabInBrowser( + browser(), kWebContentsElementId); + const GURL url1 = embedded_test_server()->GetURL(kDocumentWithTitle1URL); + const GURL url2 = embedded_test_server()->GetURL(kDocumentWithLinksURL); + + // Navigate to the first page. + util->LoadPage(url1); + + auto sequence = + ui::InteractionSequence::Builder() + .SetCompletedCallback(completed.Get()) + .SetAbortedCallback(aborted.Get()) + .SetContext(browser()->window()->GetElementContext()) + .AddStep(ui::InteractionSequence::StepBuilder() + .SetType(ui::InteractionSequence::StepType::kShown) + .SetElementID(kWebContentsElementId) + .SetStartCallback(base::BindLambdaForTesting( + [&](ui::InteractionSequence* sequence, + ui::TrackedElement* element) { + // Wait for an element that is only present on the + // second page, to be loaded below. + WebContentsInteractionTestUtil::StateChange change; + change.type = WebContentsInteractionTestUtil:: + StateChange::Type::kExists; + change.where = kQuery; + change.event = kInteractionTestUtilCustomEventType; + change.continue_across_navigation = true; + util->SendEventOnStateChange(change); + + // Navigate to the second page. + util->LoadPage(url2); + })) + .SetMustRemainVisible(false) + .Build()) + .AddStep(ui::InteractionSequence::StepBuilder() + .SetType(ui::InteractionSequence::StepType::kCustomEvent, + kInteractionTestUtilCustomEventType) + .SetElementID(kWebContentsElementId) + .SetMustBeVisibleAtStart(false) + .Build()) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->RunSynchronouslyForTesting()); +} + // This is a regression test for the case where we open a new tab in a way that // causes it not to have a URL; previously, it would not create an element // because navigating_away_from_ was empty.
diff --git a/chromeos/ash/components/local_search_service/public/mojom/BUILD.gn b/chromeos/ash/components/local_search_service/public/mojom/BUILD.gn index bde092f..fb2aa61 100644 --- a/chromeos/ash/components/local_search_service/public/mojom/BUILD.gn +++ b/chromeos/ash/components/local_search_service/public/mojom/BUILD.gn
@@ -16,6 +16,9 @@ webui_module_path = "/" + # Used by the help app UI, which is still using JS + Closure. + use_typescript_sources = false + public_deps = [ "//mojo/public/mojom/base", "//sandbox/policy/mojom",
diff --git a/chromeos/ash/components/multidevice/mojom/BUILD.gn b/chromeos/ash/components/multidevice/mojom/BUILD.gn index 908956c9..aabf769 100644 --- a/chromeos/ash/components/multidevice/mojom/BUILD.gn +++ b/chromeos/ash/components/multidevice/mojom/BUILD.gn
@@ -14,6 +14,10 @@ webui_module_path = "chrome://resources/mojo/chromeos/ash/components/multidevice/mojom" + # Used by ash/webui/common/resources/multidevice_setup, which is still using + # JS + Closure. + use_typescript_sources = false + cpp_typemaps = [ { types = [
diff --git a/chromeos/ash/services/bluetooth_config/public/mojom/BUILD.gn b/chromeos/ash/services/bluetooth_config/public/mojom/BUILD.gn index f8d1f57..311e087b 100644 --- a/chromeos/ash/services/bluetooth_config/public/mojom/BUILD.gn +++ b/chromeos/ash/services/bluetooth_config/public/mojom/BUILD.gn
@@ -14,4 +14,8 @@ "//url/mojom:url_mojom_gurl", ] webui_module_path = "chrome://resources/mojo/chromeos/ash/services/bluetooth_config/public/mojom" + + # Used by ash/webui/common/resources/bluetooth, which is still using JS + + # Closure. + use_typescript_sources = false }
diff --git a/chromeos/ash/services/cellular_setup/public/mojom/BUILD.gn b/chromeos/ash/services/cellular_setup/public/mojom/BUILD.gn index cf554c47..6107ec8a 100644 --- a/chromeos/ash/services/cellular_setup/public/mojom/BUILD.gn +++ b/chromeos/ash/services/cellular_setup/public/mojom/BUILD.gn
@@ -19,4 +19,8 @@ ] webui_module_path = "chrome://resources/mojo/chromeos/ash/services/cellular_setup/public/mojom" + + # Used by ash/webui/common/resources/multidevice_setup, which is still using + # JS + Closure. + use_typescript_sources = false }
diff --git a/chromeos/ash/services/device_sync/public/mojom/BUILD.gn b/chromeos/ash/services/device_sync/public/mojom/BUILD.gn index d3efe888..b567e49 100644 --- a/chromeos/ash/services/device_sync/public/mojom/BUILD.gn +++ b/chromeos/ash/services/device_sync/public/mojom/BUILD.gn
@@ -18,6 +18,10 @@ webui_module_path = "chrome://resources/mojo/chromeos/ash/services/device_sync/public/mojom" + # Used by ash/webui/common/resources/multidevice_setup, which is still using + # JS + Closure. + use_typescript_sources = false + cpp_typemaps = [ { types = [
diff --git a/chromeos/ash/services/multidevice_setup/public/mojom/BUILD.gn b/chromeos/ash/services/multidevice_setup/public/mojom/BUILD.gn index eb2c73b..0b4307e 100644 --- a/chromeos/ash/services/multidevice_setup/public/mojom/BUILD.gn +++ b/chromeos/ash/services/multidevice_setup/public/mojom/BUILD.gn
@@ -13,4 +13,8 @@ public_deps = [ "//chromeos/ash/services/device_sync/public/mojom" ] webui_module_path = "chrome://resources/mojo/chromeos/ash/services/multidevice_setup/public/mojom" + + # Used by ash/webui/common/resources/multidevice_setup, which is still using + # JS + Closure. + use_typescript_sources = false }
diff --git a/chromeos/ash/services/secure_channel/background_eid_generator_unittest.cc b/chromeos/ash/services/secure_channel/background_eid_generator_unittest.cc index 6afa823..03754c0b 100644 --- a/chromeos/ash/services/secure_channel/background_eid_generator_unittest.cc +++ b/chromeos/ash/services/secure_channel/background_eid_generator_unittest.cc
@@ -39,9 +39,6 @@ const std::string kThirdSeed = "thirdSeed"; const std::string kFourthSeed = "fourthSeed"; -const std::string kDeviceId1 = "deviceId1"; -const std::string kDeviceId2 = "deviceId2"; - cryptauth::BeaconSeed CreateBeaconSeed(const std::string& data, const int64_t start_timestamp_ms, const int64_t end_timestamp_ms) { @@ -231,8 +228,8 @@ // Test the case where the account has other devices, but their beacon seeds // don't match the incoming advertisement. |beacon_seeds_[0]| corresponds to -// |kDeviceId1|. Since |kDeviceId1| is not present in the device ids passed to -// IdentifyRemoteDeviceByAdvertisement(), no match is +// |test_remote_devices_[1]|. Since |test_remote_devices_[1]| is not present in +// the device ids passed to IdentifyRemoteDeviceByAdvertisement(), no match is // expected to be found. TEST_F(SecureChannelBackgroundEidGeneratorTest, IdentifyRemoteDeviceByAdvertisement_NoMatchingRemoteDevices) {
diff --git a/chromeos/services/network_config/public/mojom/BUILD.gn b/chromeos/services/network_config/public/mojom/BUILD.gn index ea9950e..3bc4a8f 100644 --- a/chromeos/services/network_config/public/mojom/BUILD.gn +++ b/chromeos/services/network_config/public/mojom/BUILD.gn
@@ -15,6 +15,10 @@ webui_module_path = "chrome://resources/mojo/chromeos/services/network_config/public/mojom" + # Used by ash/webui/common/resources/network_health, which is still using + # JS + Closure. + use_typescript_sources = false + public_deps = [ ":network_types", "//mojo/public/mojom/base",
diff --git a/chromeos/services/network_health/public/mojom/BUILD.gn b/chromeos/services/network_health/public/mojom/BUILD.gn index 0f7c1360..e68684226 100644 --- a/chromeos/services/network_health/public/mojom/BUILD.gn +++ b/chromeos/services/network_health/public/mojom/BUILD.gn
@@ -23,6 +23,10 @@ webui_module_path = "chrome://resources/mojo/chromeos/services/network_health/public/mojom" + + # Used by ash/webui/common/resources/network_health, which is still using + # JS + Closure. + use_typescript_sources = false } }
diff --git a/chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.cc b/chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.cc index a0245acb..ab8c61c 100644 --- a/chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.cc +++ b/chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.cc
@@ -121,7 +121,8 @@ // to determine if each button should be visible and enabled. class DefaultCaptionButtonModel : public CaptionButtonModel { public: - explicit DefaultCaptionButtonModel(views::Widget* frame) : frame_(frame) {} + DefaultCaptionButtonModel(views::Widget* frame, bool is_close_button_enabled) + : frame_(frame), is_close_button_enabled_(is_close_button_enabled) {} DefaultCaptionButtonModel(const DefaultCaptionButtonModel&) = delete; DefaultCaptionButtonModel& operator=(const DefaultCaptionButtonModel&) = delete; @@ -184,21 +185,32 @@ NOTREACHED(); return false; } - bool IsEnabled(views::CaptionButtonIcon type) const override { return true; } + bool IsEnabled(views::CaptionButtonIcon type) const override { + if (type == views::CAPTION_BUTTON_ICON_CLOSE) { + return is_close_button_enabled_; + } + return true; + } bool InZoomMode() const override { return false; } private: raw_ptr<views::Widget> frame_; + + // Configures whether the close button is enabled. + bool is_close_button_enabled_ = true; }; } // namespace FrameCaptionButtonContainerView::FrameCaptionButtonContainerView( views::Widget* frame, + bool is_close_button_enabled, std::unique_ptr<views::FrameCaptionButton> custom_button) : views::AnimationDelegateViews(frame->GetRootView()), frame_(frame), - model_(std::make_unique<DefaultCaptionButtonModel>(frame)) { + model_(std::make_unique<DefaultCaptionButtonModel>( + frame, + is_close_button_enabled)) { SetOrientation(views::BoxLayout::Orientation::kHorizontal); SetCrossAxisAlignment(views::BoxLayout::CrossAxisAlignment::kCenter); SetMainAxisAlignment(views::BoxLayout::MainAxisAlignment::kEnd); @@ -417,6 +429,8 @@ menu_button_->SetEnabled(model_->IsEnabled(views::CAPTION_BUTTON_ICON_MENU)); close_button_->SetVisible( model_->IsVisible(views::CAPTION_BUTTON_ICON_CLOSE)); + close_button_->SetEnabled( + model_->IsEnabled(views::CAPTION_BUTTON_ICON_CLOSE)); } void FrameCaptionButtonContainerView::UpdateButtonsImageAndTooltip() {
diff --git a/chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h b/chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h index 54b2783e..f83b016 100644 --- a/chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h +++ b/chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h
@@ -52,6 +52,7 @@ // left-most caption button (in LTR mode). FrameCaptionButtonContainerView( views::Widget* frame, + bool is_close_button_enabled = true, std::unique_ptr<views::FrameCaptionButton> custom_button = nullptr); FrameCaptionButtonContainerView(const FrameCaptionButtonContainerView&) = delete;
diff --git a/clank b/clank index 73c35de4..51992b44 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 73c35de43ab85aa40f061a65515a0f1351b020a3 +Subproject commit 51992b448e50bca8ddb234cb03f8fda5b445fe77
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index b8a8cca..b1623a1 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -478,6 +478,7 @@ "ui/label_formatter_utils.h", "ui/payments/bubble_show_options.cc", "ui/payments/bubble_show_options.h", + "ui/payments/card_unmask_otp_input_dialog_controller.h", "ui/payments/card_unmask_prompt_controller.h", "ui/payments/card_unmask_prompt_controller_impl.cc", "ui/payments/card_unmask_prompt_controller_impl.h",
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index 0c336e1..847ee196 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -2589,47 +2589,46 @@ if (!ProfileChangesAreOngoing(guid)) return; - const auto& change = ongoing_profile_changes_[guid].front(); + const AutofillProfileDeepChange& change = + ongoing_profile_changes_[guid].front(); if (change.is_ongoing_on_background()) return; - const auto& change_type = change.type(); - const auto* existing_profile = GetProfileByGUID(guid); - const bool profile_exists = (existing_profile != nullptr); - const auto& profile = ongoing_profile_changes_[guid].front().profile(); - + const AutofillProfile* existing_profile = GetProfileByGUID(guid); + const AutofillProfile& profile = change.profile(); DCHECK(guid == profile.guid()); + scoped_refptr<AutofillWebDataService> webdata_service = + database_helper_->GetLocalDatabase(); - if (change_type == AutofillProfileChange::REMOVE) { - if (!profile_exists) { - OnProfileChangeDone(guid); - return; - } - database_helper_->GetLocalDatabase()->RemoveAutofillProfile( - guid, existing_profile->source()); - change.set_is_ongoing_on_background(); - return; + switch (change.type()) { + case AutofillProfileChange::REMOVE: + if (!existing_profile) { + OnProfileChangeDone(guid); + return; + } + webdata_service->RemoveAutofillProfile(guid, existing_profile->source()); + break; + case AutofillProfileChange::ADD: + if (existing_profile || + FindByContents(GetProfileStorage(profile.source()), profile)) { + OnProfileChangeDone(guid); + return; + } + webdata_service->AddAutofillProfile(profile); + break; + case AutofillProfileChange::UPDATE: + if (!existing_profile || + (!change.enforced() && + existing_profile->EqualsForUpdatePurposes(profile))) { + OnProfileChangeDone(guid); + return; + } + webdata_service->UpdateAutofillProfile(profile); + break; + case AutofillProfileChange::EXPIRE: + NOTREACHED_NORETURN(); } - - if (change_type == AutofillProfileChange::ADD) { - const std::vector<std::unique_ptr<AutofillProfile>>& profiles = - GetProfileStorage(profile.source()); - if (profile_exists || FindByContents(profiles, profile)) { - OnProfileChangeDone(guid); - return; - } - database_helper_->GetLocalDatabase()->AddAutofillProfile(profile); - change.set_is_ongoing_on_background(); - return; - } - - if (profile_exists && (change.enforced() || - !existing_profile->EqualsForUpdatePurposes(profile))) { - database_helper_->GetLocalDatabase()->UpdateAutofillProfile(profile); - change.set_is_ongoing_on_background(); - } else { - OnProfileChangeDone(guid); - } + change.set_is_ongoing_on_background(); } bool PersonalDataManager::ProfileChangesAreOngoing(const std::string& guid) {
diff --git a/components/autofill/core/browser/profile_token_quality.cc b/components/autofill/core/browser/profile_token_quality.cc index ff5f175..930a5701 100644 --- a/components/autofill/core/browser/profile_token_quality.cc +++ b/components/autofill/core/browser/profile_token_quality.cc
@@ -27,6 +27,7 @@ #include "components/autofill/core/browser/webdata/autofill_table.h" #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_l10n_util.h" +#include "components/autofill/core/common/autofill_util.h" namespace autofill { @@ -72,71 +73,6 @@ return it->second; } -// Returns true if `a` and `b` differ by Levenshtein distance of at most `k`. -// Edits, inserts and removes each count as one step. -// Runs in O(|a| * k) time and O(k) memory. -bool IsWithinLevenshteinDistance(std::u16string_view a, - std::u16string_view b, - size_t k) { - // If the string's lengths differ by more than `k`, so does their - // Levenshtein distance. - if (a.size() + k < b.size() || a.size() > b.size() + k) { - return false; - } - // The classical Levenshtein distance DP defines dp[i][j] as the edit distance - // of a[:i] and b[:j]. To make this more efficient, one can define dp[i][d] as - // the edit-distance of a[:i] and b[:i + d]. Intuitively, d represents the - // delta between j and i in the former dp. Since the edit-distance is - // restricted by `k`, abs(d) can be bounded by `k`. - // Since dp[i][d] only depends on values from dp[i-1], it is not necessary to - // store the entire 2D table. Instead, this code just stores the d-dimension, - // which represents "the edit-distance with the current prefix of the string, - // for a given delta d". - // Since d is between `-k` and `k`, the implementation shifts the d-index by - // `k`, bringing it in range [0, `2*k`] - - // The algorithm only cares if the Levenshtein distance is at most `k`. Thus, - // any unreachable states and states in which the edit-distance is certainly - // larger than `k` can be set to any value larger than `k`, without affecting - // the result. - const size_t kInfinity = k + 1; - std::vector<size_t> dp(2 * k + 1, kInfinity); - // Initially, `dp[d]` represents the Levenshtein distance of the empty prefix - // of `a` and the j = d - k characters of `b`. Their edit distance is j, since - // j removals are required. States with negative d are not reachable, since - // that corresponds to a negative index into `b`. - std::iota(dp.begin() + k, dp.end(), 0); - for (size_t i = 0; i < a.size(); i++) { - // Right now, `dp` represents the Levenshtein distance when considering the - // first `i` characters (up to index `i-1`) of `a`. After the next loop, - // `dp` will represent the Levenshtein distance when considering the first - // `i+1` characters. - for (size_t d = 0; d <= 2 * k; d++) { - if (i + d < k || i + d >= b.size() + k) { - // `j = i + d - k` is out of range of `b`. - dp[d] = kInfinity; - continue; - } - const size_t j = i + d - k; - // If `a[i] == `b[j]` the Levenshtein distance for `d` remained the same. - if (a[i] != b[j]) { - // (i, j) -> (i-1, j-1), `d` stays the same. - const size_t replace = dp[d]; - // (i, j) -> (i-1, j), `d` increases by 1. - // If the distance between `i` and `j` becomes larger than `k`, their - // edit distance is at least `k + 1`. Same in the `insert` case. - const size_t remove = d != 2 * k ? dp[d + 1] : kInfinity; - // (i, j) -> (i, j-1), `d` decreases by 1. Since `i` stays the same, - // this is intentionally using the dp value updated in the previous - // iteration. - const size_t insert = d != 0 ? dp[d - 1] : kInfinity; - dp[d] = 1 + std::min({replace, remove, insert}); - } - } - } - return dp[b.size() + k - a.size()] <= k; -} - // Computes the `ObservationType` if a field of the given `type` was autofilled // with the `profile`, but the autofilled value was edited to `edited_value` // after filling. @@ -300,14 +236,6 @@ return types; } -// static -bool ProfileTokenQuality::IsWithinLevenshteinDistanceForTesting( - std::u16string_view a, - std::u16string_view b, - size_t k) { - return IsWithinLevenshteinDistance(a, b, k); -} - void ProfileTokenQuality::AddObservation(ServerFieldType type, Observation observation) { CHECK(GetSupportedTypes(*profile_).contains(type));
diff --git a/components/autofill/core/browser/profile_token_quality.h b/components/autofill/core/browser/profile_token_quality.h index 9dc16a1..a043f66 100644 --- a/components/autofill/core/browser/profile_token_quality.h +++ b/components/autofill/core/browser/profile_token_quality.h
@@ -166,11 +166,6 @@ // Resets all observations for the `type`. void ResetObservationsForStoredType(ServerFieldType type); - // Returns true if `a` and `b` are within Levenshtein distance `k`. - static bool IsWithinLevenshteinDistanceForTesting(std::u16string_view a, - std::u16string_view b, - size_t k); - void disable_randomization_for_testing() { diable_randomization_for_testing_ = true; }
diff --git a/components/autofill/core/browser/profile_token_quality_unittest.cc b/components/autofill/core/browser/profile_token_quality_unittest.cc index 777db6c7..5d33dd9 100644 --- a/components/autofill/core/browser/profile_token_quality_unittest.cc +++ b/components/autofill/core/browser/profile_token_quality_unittest.cc
@@ -240,29 +240,6 @@ UnorderedElementsAre(ObservationType::kAccepted)); } -TEST_F(ProfileTokenQualityTest, IsWithinLevenshteinDistance) { - // Checks if the Levenshtein distance between `a` and `b` is exactly `k`, by - // checking that it is <= `k` but not <= `k-1`. - auto has_levenshtein_distance = [](std::u16string_view a, - std::u16string_view b, size_t k) { - return ProfileTokenQuality::IsWithinLevenshteinDistanceForTesting(a, b, - k) && - (k == 0 || - !ProfileTokenQuality::IsWithinLevenshteinDistanceForTesting(a, b, - k - 1)); - }; - - EXPECT_TRUE(has_levenshtein_distance(u"aa", u"aa", 0)); - EXPECT_TRUE(has_levenshtein_distance(u"a", u"aa", 1)); - EXPECT_TRUE(has_levenshtein_distance(u"ab", u"aa", 1)); - EXPECT_TRUE(has_levenshtein_distance(u"aba", u"aa", 1)); - EXPECT_TRUE(has_levenshtein_distance(u"", u"12", 2)); - EXPECT_TRUE(has_levenshtein_distance(u"street", u"str.", 3)); - EXPECT_TRUE(has_levenshtein_distance(u"asdf", u"fdsa", 4)); - EXPECT_TRUE(has_levenshtein_distance(std::u16string(100, 'a'), - std::u16string(200, 'a'), 100)); -} - // Tests that `SaveObservationsForFilledFormForAllSubmittedProfiles()` collects // observations for all profiles that were used to fill the form. TEST_F(ProfileTokenQualityTest,
diff --git a/chrome/browser/ui/autofill/payments/card_unmask_otp_input_dialog_controller.h b/components/autofill/core/browser/ui/payments/card_unmask_otp_input_dialog_controller.h similarity index 88% rename from chrome/browser/ui/autofill/payments/card_unmask_otp_input_dialog_controller.h rename to components/autofill/core/browser/ui/payments/card_unmask_otp_input_dialog_controller.h index c58b87f1..242f042 100644 --- a/chrome/browser/ui/autofill/payments/card_unmask_otp_input_dialog_controller.h +++ b/components/autofill/core/browser/ui/payments/card_unmask_otp_input_dialog_controller.h
@@ -1,9 +1,9 @@ -// Copyright 2021 The Chromium Authors +// Copyright 2023 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_CARD_UNMASK_OTP_INPUT_DIALOG_CONTROLLER_H_ -#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_CARD_UNMASK_OTP_INPUT_DIALOG_CONTROLLER_H_ +#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_UNMASK_OTP_INPUT_DIALOG_CONTROLLER_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_UNMASK_OTP_INPUT_DIALOG_CONTROLLER_H_ #include <string> @@ -74,4 +74,4 @@ } // namespace autofill -#endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_CARD_UNMASK_OTP_INPUT_DIALOG_CONTROLLER_H_ +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_UNMASK_OTP_INPUT_DIALOG_CONTROLLER_H_
diff --git a/components/autofill/core/common/autofill_util.cc b/components/autofill/core/common/autofill_util.cc index fd8e542..d55d62ab 100644 --- a/components/autofill/core/common/autofill_util.cc +++ b/components/autofill/core/common/autofill_util.cc
@@ -4,7 +4,12 @@ #include "components/autofill/core/common/autofill_util.h" +#include <stddef.h> + #include <algorithm> +#include <numeric> +#include <string_view> +#include <vector> #include "base/command_line.h" #include "base/feature_list.h" @@ -132,6 +137,68 @@ return base::ContainsOnlyChars(value, *formatting); } +bool IsWithinLevenshteinDistance(std::u16string_view a, + std::u16string_view b, + size_t k) { + // If the string's lengths differ by more than `k`, so does their + // Levenshtein distance. + if (a.size() + k < b.size() || a.size() > b.size() + k) { + return false; + } + // The classical Levenshtein distance DP defines dp[i][j] as the minimum + // number of insert, remove and replace operation to convert a[:i] to b[:j]. + // To make this more efficient, one can define dp[i][d] as the distance of + // a[:i] and b[:i + d]. Intuitively, d represents the delta between j and i in + // the former dp. Since the Levenshtein distance is restricted by `k`, abs(d) + // can be bounded by `k`. Since dp[i][d] only depends on values from dp[i-1], + // it is not necessary to store the entire 2D table. Instead, this code just + // stores the d-dimension, which represents "the distance with the current + // prefix of the string, for a given delta d". Since d is between `-k` and + // `k`, the implementation shifts the d-index by `k`, bringing it in range + // [0, `2*k`]. + + // The algorithm only cares if the Levenshtein distance is at most `k`. Thus, + // any unreachable states and states in which the distance is certainly larger + // than `k` can be set to any value larger than `k`, without affecting the + // result. + const size_t kInfinity = k + 1; + std::vector<size_t> dp(2 * k + 1, kInfinity); + // Initially, `dp[d]` represents the Levenshtein distance of the empty prefix + // of `a` and the j = d - k characters of `b`. Their distance is j, since j + // removals are required. States with negative d are not reachable, since that + // corresponds to a negative index into `b`. + std::iota(dp.begin() + static_cast<long>(k), dp.end(), 0); + for (size_t i = 0; i < a.size(); i++) { + // Right now, `dp` represents the Levenshtein distance when considering the + // first `i` characters (up to index `i-1`) of `a`. After the next loop, + // `dp` will represent the Levenshtein distance when considering the first + // `i+1` characters. + for (size_t d = 0; d <= 2 * k; d++) { + if (i + d < k || i + d >= b.size() + k) { + // `j = i + d - k` is out of range of `b`. + dp[d] = kInfinity; + continue; + } + const size_t j = i + d - k; + // If `a[i] == `b[j]` the Levenshtein distance for `d` remained the same. + if (a[i] != b[j]) { + // (i, j) -> (i-1, j-1), `d` stays the same. + const size_t replace = dp[d]; + // (i, j) -> (i-1, j), `d` increases by 1. + // If the distance between `i` and `j` becomes larger than `k`, their + // distance is at least `k + 1`. Same in the `insert` case. + const size_t remove = d != 2 * k ? dp[d + 1] : kInfinity; + // (i, j) -> (i, j-1), `d` decreases by 1. Since `i` stays the same, + // this is intentionally using the dp value updated in the previous + // iteration. + const size_t insert = d != 0 ? dp[d - 1] : kInfinity; + dp[d] = 1 + std::min({replace, remove, insert}); + } + } + } + return dp[b.size() + k - a.size()] <= k; +} + bool ShouldAutoselectFirstSuggestionOnArrowDown() { #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || \ BUILDFLAG(IS_CHROMEOS)
diff --git a/components/autofill/core/common/autofill_util.h b/components/autofill/core/common/autofill_util.h index b6a0a36..c641b61 100644 --- a/components/autofill/core/common/autofill_util.h +++ b/components/autofill/core/common/autofill_util.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include <string> +#include <string_view> #include <vector> #include "base/feature_list.h" @@ -62,6 +63,13 @@ // entered by the website and not a real value entered by the user. bool SanitizedFieldIsEmpty(const std::u16string& value); +// Returns true if `a` and `b` differ by Levenshtein distance of at most `k`. +// Edits, inserts and removes each count as one step. +// Runs in O(|a| * k) time and O(k) memory. +bool IsWithinLevenshteinDistance(std::u16string_view a, + std::u16string_view b, + size_t k); + // Returns true if the first suggestion should be autoselected when the autofill // dropdown is shown due to an arrow down event. Enabled on desktop only. bool ShouldAutoselectFirstSuggestionOnArrowDown();
diff --git a/components/autofill/core/common/autofill_util_unittest.cc b/components/autofill/core/common/autofill_util_unittest.cc index 3437f96..c1b271f13 100644 --- a/components/autofill/core/common/autofill_util_unittest.cc +++ b/components/autofill/core/common/autofill_util_unittest.cc
@@ -142,6 +142,26 @@ LowercaseAndTokenizeAttributeStringCase{"foO baR bAz", {"foo", "bar", "baz"}})); +TEST(LevenshteinDistanceTest, IsWithinLevenshteinDistance) { + // Checks if the Levenshtein distance between `a` and `b` is exactly `k`, by + // checking that it is <= `k` but not <= `k-1`. + auto has_levenshtein_distance = [](std::u16string_view a, + std::u16string_view b, size_t k) { + return IsWithinLevenshteinDistance(a, b, k) && + (k == 0 || !IsWithinLevenshteinDistance(a, b, k - 1)); + }; + + EXPECT_TRUE(has_levenshtein_distance(u"aa", u"aa", 0)); + EXPECT_TRUE(has_levenshtein_distance(u"a", u"aa", 1)); + EXPECT_TRUE(has_levenshtein_distance(u"ab", u"aa", 1)); + EXPECT_TRUE(has_levenshtein_distance(u"aba", u"aa", 1)); + EXPECT_TRUE(has_levenshtein_distance(u"", u"12", 2)); + EXPECT_TRUE(has_levenshtein_distance(u"street", u"str.", 3)); + EXPECT_TRUE(has_levenshtein_distance(u"asdf", u"fdsa", 4)); + EXPECT_TRUE(has_levenshtein_distance(std::u16string(100, 'a'), + std::u16string(200, 'a'), 100)); +} + TEST(StripAuthAndParamsTest, StripsAll) { GURL url = GURL("https://login:password@example.com/login/?param=value#ref"); EXPECT_EQ(GURL("https://example.com/login/"), StripAuthAndParams(url));
diff --git a/components/autofill_payments_strings.grdp b/components/autofill_payments_strings.grdp index d5867f5..586ef24 100644 --- a/components/autofill_payments_strings.grdp +++ b/components/autofill_payments_strings.grdp
@@ -129,7 +129,7 @@ Save security code? </message> <message name="IDS_AUTOFILL_SAVE_CVC_PROMPT_EXPLANATION_LOCAL" desc="Explanation text for the Autofill save CVC prompt that offers to save CVC for existing local cards. This prompt is shown if a CVC is detected for an existing local card on form submission."> - For faster checkout, save the CVC for this card to your device + This card's CVC will be encrypted and saved to your device for faster checkout </message> <message name="IDS_AUTOFILL_FIX_FLOW_PROMPT_SAVE_CARD_LABEL" desc="Text to show on the button to save the card to Google when the fix flow dialog is shown after the Autofill save card prompt." formatter_data="android_java"> Save card @@ -215,7 +215,7 @@ Pay faster next time and protect your card with Google’s industry-leading security. </message> <message name="IDS_AUTOFILL_SAVE_CVC_PROMPT_EXPLANATION_UPLOAD" desc="Explanation text for the Autofill save CVC prompt that offers to upload CVC to the Sync server for existing server cards. This prompt is shown if a CVC is detected for an existing server card on form submission."> - For faster checkout, save the CVC for this card in your Google Account + This card's CVC will be encrypted and saved in your Google Account for faster checkout </message> <if expr="is_android">
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_SAVE_CVC_PROMPT_EXPLANATION_LOCAL.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_SAVE_CVC_PROMPT_EXPLANATION_LOCAL.png.sha1 index 3942232ec..905cd89 100644 --- a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_SAVE_CVC_PROMPT_EXPLANATION_LOCAL.png.sha1 +++ b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_SAVE_CVC_PROMPT_EXPLANATION_LOCAL.png.sha1
@@ -1 +1 @@ -5b4fb70e29c1fdb447e5ef2bd6612459c43a2fe5 \ No newline at end of file +83e71cee4576eb542c629625eaea933319011cc7 \ No newline at end of file
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_SAVE_CVC_PROMPT_EXPLANATION_UPLOAD.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_SAVE_CVC_PROMPT_EXPLANATION_UPLOAD.png.sha1 index 5e10360..eb46b2a4 100644 --- a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_SAVE_CVC_PROMPT_EXPLANATION_UPLOAD.png.sha1 +++ b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_SAVE_CVC_PROMPT_EXPLANATION_UPLOAD.png.sha1
@@ -1 +1 @@ -b41a7c2abfe58e837f40d53a639ba34a107a94fe \ No newline at end of file +81ce146fa7f1081fff7e1c09d8e5dd141d3fac7e \ No newline at end of file
diff --git a/components/compose/proto/BUILD.gn b/components/compose/proto/BUILD.gn index 24e8debc..ad42b34 100644 --- a/components/compose/proto/BUILD.gn +++ b/components/compose/proto/BUILD.gn
@@ -6,5 +6,5 @@ proto_library("proto") { proto_in_dir = "//" - sources = [ "compose.proto" ] + sources = [ "compose_metadata.proto" ] }
diff --git a/components/compose/proto/compose.proto b/components/compose/proto/compose.proto deleted file mode 100644 index 71725f4..0000000 --- a/components/compose/proto/compose.proto +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -syntax = "proto3"; -option optimize_for = LITE_RUNTIME; - -package compose_proto; - -message ComposeRequest { - string input = 1; -} - -message ComposeResponse { - string output = 1; -}
diff --git a/components/compose/proto/compose_metadata.proto b/components/compose/proto/compose_metadata.proto new file mode 100644 index 0000000..c0a60d0 --- /dev/null +++ b/components/compose/proto/compose_metadata.proto
@@ -0,0 +1,41 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = "proto3"; + +package compose_proto; + +option optimize_for = LITE_RUNTIME; + +enum ComposeTone { + COMPOSE_UNSPECIFIED_TONE = 0; + COMPOSE_FORMAL = 1; + COMPOSE_INFORMAL = 2; +} +enum ComposeLength { + COMPOSE_UNSPECIFIED_LENGTH = 0; + COMPOSE_SHORTER = 1; + COMPOSE_LONGER = 2; +} +message ComposeRequest { + string user_input = 2; + ComposePageMetadata page_metadata = 3; + ComposeTone tone = 4; + ComposeLength length = 5; + repeated ComposePriorResponse previous_responses = 6; +} +message ComposeResponse { + string output = 1; +} +message ComposePriorResponse { + string response_text = 1; + ComposeTone tone = 2; + ComposeLength length = 3; + bool regenerate_requested_since = 4; +} +message ComposePageMetadata { + string page_url = 1; + string page_title = 2; + string page_inner_text = 3; +}
diff --git a/components/content_settings/core/common/features.cc b/components/content_settings/core/common/features.cc index 2eceade8..0df74d0f 100644 --- a/components/content_settings/core/common/features.cc +++ b/components/content_settings/core/common/features.cc
@@ -70,6 +70,9 @@ const base::FeatureParam<base::TimeDelta> kUserBypassUIReloadTime{ &kUserBypassUI, "reload-time", base::Seconds(30)}; +const base::FeatureParam<base::TimeDelta> kUserBypassUIReloadBubbleTimeout{ + &kUserBypassUI, "reload-bubble-timeout", base::Seconds(5)}; + BASE_FEATURE(kUserBypassFeedback, "UserBypassFeedback", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/components/content_settings/core/common/features.h b/components/content_settings/core/common/features.h index fe6fe7c5..edfbc67 100644 --- a/components/content_settings/core/common/features.h +++ b/components/content_settings/core/common/features.h
@@ -93,6 +93,12 @@ COMPONENT_EXPORT(CONTENT_SETTINGS_FEATURES) extern const base::FeatureParam<base::TimeDelta> kUserBypassUIReloadTime; +// The reloading bubble will be shown until either the page full reloads or this +// timeout is reached. +COMPONENT_EXPORT(CONTENT_SETTINGS_FEATURES) +extern const base::FeatureParam<base::TimeDelta> + kUserBypassUIReloadBubbleTimeout; + // Hide activity indicators if a permission is no longer used. COMPONENT_EXPORT(CONTENT_SETTINGS_FEATURES) BASE_DECLARE_FEATURE(kImprovedSemanticsActivityIndicators);
diff --git a/components/feature_engagement/public/event_constants.cc b/components/feature_engagement/public/event_constants.cc index 5b15a01..72a1ad8 100644 --- a/components/feature_engagement/public/event_constants.cc +++ b/components/feature_engagement/public/event_constants.cc
@@ -107,6 +107,7 @@ const char kShareToolbarItemUsed[] = "share_toolbar_item_used"; const char kDefaultBrowserVideoPromoConditionsMet[] = "default_browser_video_promo_conditions_met"; +const char kLensButtonKeyboardUsed[] = "lens_keyboard_used"; #endif // BUILDFLAG(IS_IOS) #if BUILDFLAG(IS_ANDROID)
diff --git a/components/feature_engagement/public/event_constants.h b/components/feature_engagement/public/event_constants.h index 6672e5b7..ebc87bf3 100644 --- a/components/feature_engagement/public/event_constants.h +++ b/components/feature_engagement/public/event_constants.h
@@ -197,6 +197,9 @@ // eligible to be displayed. extern const char kDefaultBrowserVideoPromoConditionsMet[]; +// The user has triggered the Lens button in the Omnibox keyboard. +extern const char kLensButtonKeyboardUsed[]; + #endif // BUILDFLAG(IS_IOS) // Android.
diff --git a/components/feature_engagement/public/feature_configurations.cc b/components/feature_engagement/public/feature_configurations.cc index f6ab1a0..d3920da 100644 --- a/components/feature_engagement/public/feature_configurations.cc +++ b/components/feature_engagement/public/feature_configurations.cc
@@ -1743,6 +1743,26 @@ return config; } + if (kIPHiOSLensKeyboardFeature.name == feature->name) { + // A config that allows a user education bubble to be shown for the Lens + // button in the omnibox keyboard. Will be shown up to 3 times, but + // opening Lens from the keyboard will prevent the bubble from appearing + // again. + + absl::optional<FeatureConfig> config = FeatureConfig(); + config->valid = true; + config->availability = Comparator(ANY, 0); + config->session_rate = Comparator(EQUAL, 0); + config->trigger = + EventConfig("lens_keyboard_feature_trigger", Comparator(LESS_THAN, 3), + feature_engagement::kMaxStoragePeriod, + feature_engagement::kMaxStoragePeriod); + config->used = EventConfig("lens_keyboard_used", Comparator(EQUAL, 0), + feature_engagement::kMaxStoragePeriod, + feature_engagement::kMaxStoragePeriod); + return config; + } + // iOS Promo Configs are split out into a separate file, so check that too. if (absl::optional<FeatureConfig> ios_promo_feature_config = GetClientSideiOSPromoFeatureConfig(feature)) {
diff --git a/components/feature_engagement/public/feature_constants.cc b/components/feature_engagement/public/feature_constants.cc index 44d546a..7a8d787 100644 --- a/components/feature_engagement/public/feature_constants.cc +++ b/components/feature_engagement/public/feature_constants.cc
@@ -486,6 +486,9 @@ BASE_FEATURE(kIPHiOSDefaultBrowserSettingsBadgeFeature, "IPH_iOSDefaultBrowserSettingsBadge", base::FEATURE_ENABLED_BY_DEFAULT); +BASE_FEATURE(kIPHiOSLensKeyboardFeature, + "IPH_iOSLensKeyboard", + base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kIPHiOSPromoAppStoreFeature, "IPH_iOSPromoAppStore", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/components/feature_engagement/public/feature_constants.h b/components/feature_engagement/public/feature_constants.h index ea3d52e..caa0c4e 100644 --- a/components/feature_engagement/public/feature_constants.h +++ b/components/feature_engagement/public/feature_constants.h
@@ -199,6 +199,7 @@ BASE_DECLARE_FEATURE(kIPHiOSDefaultBrowserBadgeEligibilityFeature); BASE_DECLARE_FEATURE(kIPHiOSDefaultBrowserOverflowMenuBadgeFeature); BASE_DECLARE_FEATURE(kIPHiOSDefaultBrowserSettingsBadgeFeature); +BASE_DECLARE_FEATURE(kIPHiOSLensKeyboardFeature); BASE_DECLARE_FEATURE(kIPHiOSPromoAppStoreFeature); BASE_DECLARE_FEATURE(kIPHiOSPromoWhatsNewFeature); BASE_DECLARE_FEATURE(kIPHiOSPromoPostRestoreFeature);
diff --git a/components/feature_engagement/public/feature_list.cc b/components/feature_engagement/public/feature_list.cc index bd55806..8768481d 100644 --- a/components/feature_engagement/public/feature_list.cc +++ b/components/feature_engagement/public/feature_list.cc
@@ -126,6 +126,7 @@ &kIPHiOSDefaultBrowserBadgeEligibilityFeature, &kIPHiOSDefaultBrowserOverflowMenuBadgeFeature, &kIPHiOSDefaultBrowserSettingsBadgeFeature, + &kIPHiOSLensKeyboardFeature, &kIPHiOSPromoAppStoreFeature, &kIPHiOSPromoWhatsNewFeature, &kIPHiOSPromoPostRestoreFeature,
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h index 85e0035..e27a1e7 100644 --- a/components/feature_engagement/public/feature_list.h +++ b/components/feature_engagement/public/feature_list.h
@@ -237,6 +237,7 @@ DEFINE_VARIATION_PARAM(kIPHiOSDefaultBrowserSettingsBadgeFeature, "IPH_iOSDefaultBrowserSettingsBadge"); DEFINE_VARIATION_PARAM(kIPHiOSPromoAppStoreFeature, "IPH_iOSPromoAppStore"); +DEFINE_VARIATION_PARAM(kIPHiOSLensKeyboardFeature, "IPH_iOSLensKeyboard"); DEFINE_VARIATION_PARAM(kIPHiOSPromoWhatsNewFeature, "IPH_iOSPromoWhatsNew"); DEFINE_VARIATION_PARAM(kIPHiOSPromoPostRestoreFeature, "IPH_iOSPromoPostRestore"); @@ -538,6 +539,7 @@ VARIATION_ENTRY(kIPHiOSDefaultBrowserBadgeEligibilityFeature), VARIATION_ENTRY(kIPHiOSDefaultBrowserOverflowMenuBadgeFeature), VARIATION_ENTRY(kIPHiOSDefaultBrowserSettingsBadgeFeature), + VARIATION_ENTRY(kIPHiOSLensKeyboardFeature), VARIATION_ENTRY(kIPHiOSPromoAppStoreFeature), VARIATION_ENTRY(kIPHiOSPromoWhatsNewFeature), VARIATION_ENTRY(kIPHiOSPromoPostRestoreFeature),
diff --git a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/suggestions/OmniboxSuggestionUiType.java b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/suggestions/OmniboxSuggestionUiType.java index 05dadfc..4f6760b7 100644 --- a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/suggestions/OmniboxSuggestionUiType.java +++ b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/suggestions/OmniboxSuggestionUiType.java
@@ -12,22 +12,28 @@ /** * The different types of view that a suggestion can be. * - * When modifying this list, please also update the - * - OmniboxSuggestionsDropdown#HistogramRecordingRecycledViewPool, - * - OmniboxSuggestionUiType histogram enum - * to reflect the expected/anticipated volume of views that may be reused and appropriate - * histogram details. + * <p>When modifying this list, please also update the - {@link PreWarmingRecycledViewPool}, - + * OmniboxSuggestionUiType histogram enum to reflect the expected/anticipated volume of views that + * may be reused and appropriate histogram details. * - * Please note that the types below are also being recorded in a separate histogram, see: - * - SuggestionsMetrics#recordSuggestionsViewCreatedType() - * - SuggestionsMetrics#recordSuggestionsViewReusedType(). + * <p>Please note that the types below are also being recorded in a separate histogram, see: - + * SuggestionsMetrics#recordSuggestionsViewCreatedType() - + * SuggestionsMetrics#recordSuggestionsViewReusedType(). */ -@IntDef({OmniboxSuggestionUiType.DEFAULT, OmniboxSuggestionUiType.EDIT_URL_SUGGESTION, - OmniboxSuggestionUiType.ANSWER_SUGGESTION, OmniboxSuggestionUiType.ENTITY_SUGGESTION, - OmniboxSuggestionUiType.TAIL_SUGGESTION, OmniboxSuggestionUiType.CLIPBOARD_SUGGESTION, - OmniboxSuggestionUiType.HEADER, OmniboxSuggestionUiType.TILE_NAVSUGGEST, - OmniboxSuggestionUiType.PEDAL_SUGGESTION, OmniboxSuggestionUiType.DIVIDER_LINE, - OmniboxSuggestionUiType.COUNT}) +@IntDef({ + OmniboxSuggestionUiType.DEFAULT, + OmniboxSuggestionUiType.EDIT_URL_SUGGESTION, + OmniboxSuggestionUiType.ANSWER_SUGGESTION, + OmniboxSuggestionUiType.ENTITY_SUGGESTION, + OmniboxSuggestionUiType.TAIL_SUGGESTION, + OmniboxSuggestionUiType.CLIPBOARD_SUGGESTION, + OmniboxSuggestionUiType.HEADER, + OmniboxSuggestionUiType.TILE_NAVSUGGEST, + OmniboxSuggestionUiType.PEDAL_SUGGESTION, + OmniboxSuggestionUiType.DIVIDER_LINE, + OmniboxSuggestionUiType.QUERY_TILES, + OmniboxSuggestionUiType.COUNT +}) @Retention(RetentionPolicy.SOURCE) public @interface OmniboxSuggestionUiType { int DEFAULT = 0; @@ -40,6 +46,7 @@ int TILE_NAVSUGGEST = 7; int PEDAL_SUGGESTION = 8; int DIVIDER_LINE = 9; + int QUERY_TILES = 10; - int COUNT = 10; + int COUNT = 11; }
diff --git a/components/omnibox/browser/autocomplete_classifier.cc b/components/omnibox/browser/autocomplete_classifier.cc index e0b711f..0424725 100644 --- a/components/omnibox/browser/autocomplete_classifier.cc +++ b/components/omnibox/browser/autocomplete_classifier.cc
@@ -77,9 +77,7 @@ AutocompleteProvider::TYPE_HISTORY_URL | AutocompleteProvider::TYPE_SEARCH | AutocompleteProvider::TYPE_SHORTCUTS | - (OmniboxFieldTrial::IsFuzzyUrlSuggestionsEnabled() - ? AutocompleteProvider::TYPE_HISTORY_FUZZY - : 0) | + AutocompleteProvider::TYPE_HISTORY_FUZZY | AutocompleteProvider::TYPE_CALCULATOR; }
diff --git a/components/omnibox/browser/autocomplete_controller.cc b/components/omnibox/browser/autocomplete_controller.cc index 0d6f43b..7716ce4 100644 --- a/components/omnibox/browser/autocomplete_controller.cc +++ b/components/omnibox/browser/autocomplete_controller.cc
@@ -456,13 +456,6 @@ // arithmetic mean. base::TimeTicks start_time = base::TimeTicks::Now(); - // Keep a max-heap of negative relevances to quickly estimate a relevance - // cutoff that can be used to improve counterfactual triggering. - // Prevent memory churn by starting with full size heap, ready for - // first change to be pushed without reallocation. - std::vector<int> relevances(internal_result_.GetDynamicMaxMatches() + 1, 0); - relevances.pop_back(); - for (const auto& provider : providers_) { // Starter Pack engines in keyword mode only run a subset of the providers, // so call `ShouldRunProvider()` to determine which ones should run. @@ -471,20 +464,8 @@ } base::TimeTicks provider_start_time = base::TimeTicks::Now(); - if (history_fuzzy_provider_) { - history_fuzzy_provider_->SetCounterfactualRelevanceHint( - -relevances.front()); - } provider->Start(input_, minimal_changes); - for (const AutocompleteMatch& match : provider->matches()) { - relevances.push_back(-match.relevance); - std::push_heap(relevances.begin(), relevances.end()); - std::pop_heap(relevances.begin(), relevances.end()); - relevances.pop_back(); - DCHECK(std::is_heap(relevances.begin(), relevances.end())); - } - // `UmaHistogramTimes()` uses 1ms - 10s buckets, whereas this uses 1ms - 5s // buckets. // TODO(crbug.com/1340291|manukh): This isn't handled by `metrics_` yet. It
diff --git a/components/omnibox/browser/history_fuzzy_provider.cc b/components/omnibox/browser/history_fuzzy_provider.cc index e02f830..f9879e9f 100644 --- a/components/omnibox/browser/history_fuzzy_provider.cc +++ b/components/omnibox/browser/history_fuzzy_provider.cc
@@ -24,6 +24,7 @@ #include "base/time/time.h" #include "base/trace_event/memory_usage_estimator.h" #include "base/trace_event/trace_event.h" +#include "build/build_config.h" #include "components/history/core/browser/history_database.h" #include "components/history/core/browser/history_db_task.h" #include "components/history/core/browser/history_service.h" @@ -139,13 +140,6 @@ return remaining; } -// Indicates whether to deactivate fuzzy processing due to device performance -// and memory constraints. This prevents loading, updating, and fuzzy search. -bool ShouldBypassForLowEndDevice() { - return OmniboxFieldTrial::kFuzzyUrlSuggestionsLowEndBypass.Get() && - base::SysInfo::IsLowEndDevice(); -} - } // namespace namespace fuzzy { @@ -243,8 +237,6 @@ bool Node::FindCorrections(const std::u16string& text, ToleranceSchedule tolerance_schedule, std::vector<Correction>& corrections) const { - const bool enable_transpose = - OmniboxFieldTrial::kFuzzyUrlSuggestionsTranspose.Get(); DCHECK(corrections.empty()); DCHECK(tolerance_schedule.limit <= Correction::kMaxEdits); @@ -378,7 +370,7 @@ // Transpose. Look ahead cost can be balanced by faster // advancement through input text resulting in shorter search. - if (enable_transpose && text.size() > step.index + 1 && + if (text.size() > step.index + 1 && text[step.index + 1] == entry.first) { const auto it = entry.second->next.find(step_text_char); if (it != entry.second->next.end()) { @@ -471,23 +463,25 @@ HistoryFuzzyProvider::HistoryFuzzyProvider(AutocompleteProviderClient* client) : HistoryProvider(AutocompleteProvider::TYPE_HISTORY_FUZZY, client) { - // Cache tunable parameters so they don't need to be looked up when - // running search and calculating penalties. - min_input_length_ = - OmniboxFieldTrial::kFuzzyUrlSuggestionsMinInputLength.Get(); - penalty_low_ = OmniboxFieldTrial::kFuzzyUrlSuggestionsPenaltyLow.Get(); - penalty_high_ = OmniboxFieldTrial::kFuzzyUrlSuggestionsPenaltyHigh.Get(); - penalty_taper_length_ = - OmniboxFieldTrial::kFuzzyUrlSuggestionsPenaltyTaperLength.Get(); - counterfactual_ = OmniboxFieldTrial::kFuzzyUrlSuggestionsCounterfactual.Get(); - - if (ShouldBypassForLowEndDevice()) { - // Note, this early return will prevent loading from database, which saves - // memory and prevents this provider from working to find fuzzy matches. - // See also the early return in `Start` below; `urls_loaded_event_` never - // signals because the signaling task is never run. - return; - } + // Set up tunable parameters. These can be used to affect fuzzy matching + // behavior and performance. Note, we use different `min_input_length_` values + // depending on desktop versus mobile platforms, determined by experiment. +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) + min_input_length_ = 5; +#else + min_input_length_ = 3; +#endif + // These initial penalty values produce good results for most inputs: + // Using 10% reasonably took a 1334 relevance match down to 1200, + // but was harmful to HQP suggestions: as soon as a '.' was + // appended, a bunch of ~800 navsuggest results overtook a better + // HQP result that was bumped down to ~770. Using 5% lets this + // result compete in the navsuggest range. + penalty_low_ = 5; + penalty_high_ = 5; + // The default value of zero means "no taper", and only the lowest penalty + // will be applied. + penalty_taper_length_ = 0; // In tests, history service is null and doesn't need to be observed. if (client->GetHistoryService()) { @@ -502,10 +496,6 @@ } } -void HistoryFuzzyProvider::SetCounterfactualRelevanceHint(int relevance_hint) { - counterfactual_relevance_hint_ = relevance_hint; -} - void HistoryFuzzyProvider::Start(const AutocompleteInput& input, bool minimal_changes) { TRACE_EVENT0("omnibox", "HistoryFuzzyProvider::Start"); @@ -534,30 +524,6 @@ match.provider = this; } } - - if (!matches_.empty()) { - // This will likely produce some false positives, but the likelihood - // is reduced by only triggering when one of the matches exceeds - // the relevance hint, an estimated cutoff value at which we expect fuzzy - // matches could persist after sorting and culling the full match set. - const bool met_threshold = std::any_of( - matches_.begin(), matches_.end(), [=](const AutocompleteMatch& match) { - return match.relevance > counterfactual_relevance_hint_; - }); - if (met_threshold) { - client()->GetOmniboxTriggeredFeatureService()->FeatureTriggered( - metrics::OmniboxEventProto_Feature_FUZZY_URL_SUGGESTIONS); - } - - // When in the counterfactual group, we do all the work of finding fuzzy - // matches, but do not provide the benefit. To reduce risk of unintended - // consequences downstream (for example showing fewer suggestions than - // normal), the matches are cleared here instead of at end of result - // processing pipeline so they won't interact or dedupe with other matches. - if (counterfactual_) { - matches_.clear(); - } - } } size_t HistoryFuzzyProvider::EstimateMemoryUsage() const { @@ -719,9 +685,6 @@ history::HistoryService* history_service, const history::URLRow& url_row, const history::VisitRow& new_visit) { - if (ShouldBypassForLowEndDevice()) { - return; - } if (root_.TerminalCount() < std::min(OmniboxFieldTrial::MaxNumHQPUrlsIndexedAtStartup(), kMaxTerminalCount)) { @@ -732,9 +695,6 @@ void HistoryFuzzyProvider::OnURLsDeleted( history::HistoryService* history_service, const history::DeletionInfo& deletion_info) { - if (ShouldBypassForLowEndDevice()) { - return; - } // Note, this implementation is conservative in terms of user privacy; it // deletes hosts from the trie if any URL with the given host is deleted. if (deletion_info.IsAllHistory()) {
diff --git a/components/omnibox/browser/history_fuzzy_provider.h b/components/omnibox/browser/history_fuzzy_provider.h index b10793b..d4f1909d 100644 --- a/components/omnibox/browser/history_fuzzy_provider.h +++ b/components/omnibox/browser/history_fuzzy_provider.h
@@ -194,10 +194,6 @@ HistoryFuzzyProvider(const HistoryFuzzyProvider&) = delete; HistoryFuzzyProvider& operator=(const HistoryFuzzyProvider&) = delete; - // Set a relevance hint to improve counterfactual in late-running providers - // where most match relevances are already determined. - void SetCounterfactualRelevanceHint(int relevance_hint); - // HistoryProvider: // AutocompleteProvider. `minimal_changes` is ignored since there is no async // completion performed. @@ -264,13 +260,6 @@ int penalty_high_; size_t penalty_taper_length_; - // Cache counterfactual feature param. - bool counterfactual_; - - // A relevance value below which counterfactual matches are less likely - // to be kept, if they were to be included in the full output match set. - int counterfactual_relevance_hint_{0}; - // Weak pointer factory for callback binding safety. base::WeakPtrFactory<HistoryFuzzyProvider> weak_ptr_factory_{this}; };
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc index 218dab4..7f7bb9b 100644 --- a/components/omnibox/browser/omnibox_field_trial.cc +++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -566,60 +566,6 @@ "ActionsUISimplificationTrimExtra", true); -bool OmniboxFieldTrial::IsFuzzyUrlSuggestionsEnabled() { - return base::FeatureList::IsEnabled(omnibox::kOmniboxFuzzyUrlSuggestions); -} - -const base::FeatureParam<bool> - OmniboxFieldTrial::kFuzzyUrlSuggestionsCounterfactual( - &omnibox::kOmniboxFuzzyUrlSuggestions, - "FuzzyUrlSuggestionsCounterfactual", - false); - -const base::FeatureParam<bool> - OmniboxFieldTrial::kFuzzyUrlSuggestionsLowEndBypass( - &omnibox::kOmniboxFuzzyUrlSuggestions, - "FuzzyUrlSuggestionsLowEndBypass", - false); - -const base::FeatureParam<bool> OmniboxFieldTrial::kFuzzyUrlSuggestionsTranspose( - &omnibox::kOmniboxFuzzyUrlSuggestions, - "FuzzyUrlSuggestionsTranspose", - true); - -const base::FeatureParam<int> - OmniboxFieldTrial::kFuzzyUrlSuggestionsMinInputLength( - &omnibox::kOmniboxFuzzyUrlSuggestions, - "FuzzyUrlSuggestionsMinInputLength", - 3); - -// Note about this default, which produces good results for most inputs: -// Using 10% reasonably took a 1334 relevance match down to 1200, -// but was harmful to HQP suggestions: as soon as a '.' was -// appended, a bunch of ~800 navsuggest results overtook a better -// HQP result that was bumped down to ~770. Using 5% lets this -// result compete in the navsuggest range. -const base::FeatureParam<int> OmniboxFieldTrial::kFuzzyUrlSuggestionsPenaltyLow( - &omnibox::kOmniboxFuzzyUrlSuggestions, - "FuzzyUrlSuggestionsPenaltyLow", - 5); - -// Keeping the default for high penalty equal to preserve current behavior, but -// this is the parameter most likely to need tuning for very short inputs. -const base::FeatureParam<int> - OmniboxFieldTrial::kFuzzyUrlSuggestionsPenaltyHigh( - &omnibox::kOmniboxFuzzyUrlSuggestions, - "FuzzyUrlSuggestionsPenaltyHigh", - 5); - -// The default value of zero means "no taper", and only the lowest penalty -// will be applied. -const base::FeatureParam<int> - OmniboxFieldTrial::kFuzzyUrlSuggestionsPenaltyTaperLength( - &omnibox::kOmniboxFuzzyUrlSuggestions, - "FuzzyUrlSuggestionsPenaltyTaperLength", - 0); - bool OmniboxFieldTrial::IsOnDeviceHeadSuggestEnabledForIncognito() { return base::FeatureList::IsEnabled(omnibox::kOnDeviceHeadProviderIncognito); }
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc index fb70f1e4..62d1596 100644 --- a/components/omnibox/common/omnibox_features.cc +++ b/components/omnibox/common/omnibox_features.cc
@@ -323,11 +323,6 @@ "OmniboxActionsUISimplification", base::FEATURE_DISABLED_BY_DEFAULT); -// Feature used to enable URL suggestions for inputs that may contain typos. -BASE_FEATURE(kOmniboxFuzzyUrlSuggestions, - "OmniboxFuzzyUrlSuggestions", - base::FEATURE_ENABLED_BY_DEFAULT); - // Feature used to synchronize the toolbar's and status bar's color. BASE_FEATURE(kOmniboxMatchToolbarAndStatusBarColor, "OmniboxMatchToolbarAndStatusBarColor",
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h index b907b950..5321f31 100644 --- a/components/omnibox/common/omnibox_features.h +++ b/components/omnibox/common/omnibox_features.h
@@ -86,7 +86,6 @@ BASE_DECLARE_FEATURE(kRichAutocompletion); BASE_DECLARE_FEATURE(kNtpRealboxPedals); BASE_DECLARE_FEATURE(kOmniboxActionsUISimplification); -BASE_DECLARE_FEATURE(kOmniboxFuzzyUrlSuggestions); BASE_DECLARE_FEATURE(kOmniboxMatchToolbarAndStatusBarColor); BASE_DECLARE_FEATURE(kSearchReadyOmniboxAllowQueryEdit); BASE_DECLARE_FEATURE(kSquareSuggestIcons);
diff --git a/components/policy/core/common/policy_loader_mac.h b/components/policy/core/common/policy_loader_mac.h index bdc7197..04c32b5 100644 --- a/components/policy/core/common/policy_loader_mac.h +++ b/components/policy/core/common/policy_loader_mac.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_POLICY_CORE_COMMON_POLICY_LOADER_MAC_H_ #define COMPONENTS_POLICY_CORE_COMMON_POLICY_LOADER_MAC_H_ +#include <memory> #include <string> #include "base/apple/scoped_cftyperef.h" @@ -34,13 +35,13 @@ public: PolicyLoaderMac(scoped_refptr<base::SequencedTaskRunner> task_runner, const base::FilePath& managed_policy_path, - MacPreferences* preferences); + std::unique_ptr<MacPreferences> preferences); // |application_id| will be passed into Mac's Preference Utilities API // instead of the default value of kCFPreferencesCurrentApplication. PolicyLoaderMac(scoped_refptr<base::SequencedTaskRunner> task_runner, const base::FilePath& managed_policy_path, - MacPreferences* preferences, + std::unique_ptr<MacPreferences> preferences, CFStringRef application_id); PolicyLoaderMac(const PolicyLoaderMac&) = delete; PolicyLoaderMac& operator=(const PolicyLoaderMac&) = delete; @@ -76,7 +77,7 @@ const Schema& schema, PolicyMap* policy); - std::unique_ptr<MacPreferences> preferences_; + const std::unique_ptr<MacPreferences> preferences_; // Path to the managed preferences file for the current user, if it could // be found. Updates of this file trigger a policy reload.
diff --git a/components/policy/core/common/policy_loader_mac.mm b/components/policy/core/common/policy_loader_mac.mm index e7b66ff..c75c655 100644 --- a/components/policy/core/common/policy_loader_mac.mm +++ b/components/policy/core/common/policy_loader_mac.mm
@@ -47,19 +47,19 @@ PolicyLoaderMac::PolicyLoaderMac( scoped_refptr<base::SequencedTaskRunner> task_runner, const base::FilePath& managed_policy_path, - MacPreferences* preferences) + std::unique_ptr<MacPreferences> preferences) : PolicyLoaderMac(task_runner, managed_policy_path, - preferences, + std::move(preferences), kCFPreferencesCurrentApplication) {} PolicyLoaderMac::PolicyLoaderMac( scoped_refptr<base::SequencedTaskRunner> task_runner, const base::FilePath& managed_policy_path, - MacPreferences* preferences, + std::unique_ptr<MacPreferences> preferences, CFStringRef application_id) : AsyncPolicyLoader(task_runner, /*periodic_updates=*/true), - preferences_(preferences), + preferences_(std::move(preferences)), managed_policy_path_(managed_policy_path), application_id_(CFStringCreateCopy(kCFAllocatorDefault, application_id)) { }
diff --git a/components/policy/core/common/policy_loader_mac_unittest.cc b/components/policy/core/common/policy_loader_mac_unittest.cc index 911acac..7004e6cb 100644 --- a/components/policy/core/common/policy_loader_mac_unittest.cc +++ b/components/policy/core/common/policy_loader_mac_unittest.cc
@@ -62,7 +62,7 @@ static PolicyProviderTestHarness* Create(); private: - raw_ptr<MockPreferences, AcrossTasksDanglingUntriaged> prefs_; + raw_ptr<MockPreferences, AcrossTasksDanglingUntriaged> prefs_ = nullptr; }; TestHarness::TestHarness() @@ -70,16 +70,17 @@ POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM) {} -TestHarness::~TestHarness() {} +TestHarness::~TestHarness() = default; void TestHarness::SetUp() {} ConfigurationPolicyProvider* TestHarness::CreateProvider( SchemaRegistry* registry, scoped_refptr<base::SequencedTaskRunner> task_runner) { - prefs_ = new MockPreferences(); - std::unique_ptr<AsyncPolicyLoader> loader( - new PolicyLoaderMac(task_runner, base::FilePath(), prefs_)); + auto prefs = std::make_unique<MockPreferences>(); + prefs_ = prefs.get(); + auto loader = std::make_unique<PolicyLoaderMac>(task_runner, base::FilePath(), + std::move(prefs)); return new AsyncPolicyProvider(registry, std::move(loader)); } @@ -96,7 +97,7 @@ int policy_value) { ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name)); ScopedCFTypeRef<CFNumberRef> value( - CFNumberCreate(NULL, kCFNumberIntType, &policy_value)); + CFNumberCreate(nullptr, kCFNumberIntType, &policy_value)); prefs_->AddTestItem(name, value, /*is_forced=*/true, /*is_machine=*/true); } @@ -145,13 +146,15 @@ // Special test cases for some mac preferences details. class PolicyLoaderMacTest : public PolicyTestBase { protected: - PolicyLoaderMacTest() - : prefs_(new MockPreferences()) {} + PolicyLoaderMacTest() = default; void SetUp() override { PolicyTestBase::SetUp(); - std::unique_ptr<AsyncPolicyLoader> loader(new PolicyLoaderMac( - task_environment_.GetMainThreadTaskRunner(), base::FilePath(), prefs_)); + auto prefs = std::make_unique<MockPreferences>(); + prefs_ = prefs.get(); + auto loader = std::make_unique<PolicyLoaderMac>( + task_environment_.GetMainThreadTaskRunner(), base::FilePath(), + std::move(prefs)); provider_ = std::make_unique<AsyncPolicyProvider>(&schema_registry_, std::move(loader)); provider_->Init(&schema_registry_); @@ -162,7 +165,7 @@ PolicyTestBase::TearDown(); } - raw_ptr<MockPreferences, AcrossTasksDanglingUntriaged> prefs_; + raw_ptr<MockPreferences, AcrossTasksDanglingUntriaged> prefs_ = nullptr; std::unique_ptr<AsyncPolicyProvider> provider_; };
diff --git a/components/policy/core/common/policy_service_impl_unittest.cc b/components/policy/core/common/policy_service_impl_unittest.cc index 33c61efd..e2839f6821 100644 --- a/components/policy/core/common/policy_service_impl_unittest.cc +++ b/components/policy/core/common/policy_service_impl_unittest.cc
@@ -43,9 +43,15 @@ const std::string kUrl1 = "example.com"; const std::string kUrl2 = "gmail.com"; const std::string kUrl3 = "google.com"; + +#if !BUILDFLAG(IS_IOS) const std::string kUrl4 = "youtube.com"; +#endif + +#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_IOS) const std::string kAffiliationId1 = "abc"; const std::string kAffiliationId2 = "def"; +#endif // Helper to compare the arguments to an EXPECT_CALL of OnPolicyUpdated() with // their expected values.
diff --git a/components/privacy_sandbox/android/BUILD.gn b/components/privacy_sandbox/android/BUILD.gn index 691bad34..39fb337 100644 --- a/components/privacy_sandbox/android/BUILD.gn +++ b/components/privacy_sandbox/android/BUILD.gn
@@ -30,6 +30,26 @@ ] } +android_library("javatests") { + testonly = true + sources = [ "javatests/src/org/chromium/components/privacy_sandbox/TrackingProtectionSettingsTest.java" ] + deps = [ + ":java", + "//base:base_java", + "//base:base_java_test_support", + "//base:jni_java", + "//components/browser_ui/settings/android:test_support_java", + "//components/browser_ui/site_settings/android:java", + "//content/public/android:content_java", + "//third_party/android_deps:espresso_java", + "//third_party/androidx:androidx_preference_preference_java", + "//third_party/androidx:androidx_test_runner_java", + "//third_party/hamcrest:hamcrest_core_java", + "//third_party/junit", + "//third_party/mockito:mockito_java", + ] +} + android_resources("java_resources") { sources = [ "java/res/xml/tracking_protection_preferences.xml" ] deps = [
diff --git a/components/privacy_sandbox/android/java/res/xml/tracking_protection_preferences.xml b/components/privacy_sandbox/android/java/res/xml/tracking_protection_preferences.xml index 970cdd30..51ba2cf 100644 --- a/components/privacy_sandbox/android/java/res/xml/tracking_protection_preferences.xml +++ b/components/privacy_sandbox/android/java/res/xml/tracking_protection_preferences.xml
@@ -20,8 +20,8 @@ app:allowDividerBelow="false" /> <org.chromium.components.browser_ui.settings.TextMessagePreference + android:key="bullet_point_two" android:title="@string/privacy_sandbox_tracking_protection_bullet_two_title" - android:summary="@string/privacy_sandbox_tracking_protection_bullet_two_description" android:icon="@drawable/ic_domain_verification_24dp" app:allowDividerBelow="false" />
diff --git a/components/privacy_sandbox/android/java/src/org/chromium/components/privacy_sandbox/TrackingProtectionSettings.java b/components/privacy_sandbox/android/java/src/org/chromium/components/privacy_sandbox/TrackingProtectionSettings.java index 839eebe7..de7ec75 100644 --- a/components/privacy_sandbox/android/java/src/org/chromium/components/privacy_sandbox/TrackingProtectionSettings.java +++ b/components/privacy_sandbox/android/java/src/org/chromium/components/privacy_sandbox/TrackingProtectionSettings.java
@@ -10,6 +10,7 @@ import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.style.ForegroundColorSpan; +import android.view.View; import androidx.annotation.ColorInt; import androidx.preference.Preference; @@ -30,6 +31,8 @@ import org.chromium.components.browser_ui.styles.SemanticColorUtils; import org.chromium.components.content_settings.ContentSettingValues; import org.chromium.components.content_settings.ContentSettingsType; +import org.chromium.ui.text.NoUnderlineClickableSpan; +import org.chromium.ui.text.SpanApplier; import org.chromium.ui.widget.Toast; import java.util.ArrayList; @@ -43,6 +46,7 @@ // Must match keys in tracking_protection_preferences.xml. private static final String PREF_BLOCK_ALL_TOGGLE = "block_all_3pcd_toggle"; private static final String PREF_DNT_TOGGLE = "dnt_toggle"; + private static final String PREF_BULLET_TWO = "bullet_point_two"; private static final String ALLOWED_GROUP = "allowed_group"; public static final String ADD_EXCEPTION_KEY = "add_exception"; @@ -59,6 +63,14 @@ SettingsUtils.addPreferencesFromResource(this, R.xml.tracking_protection_preferences); getActivity().setTitle(R.string.privacy_sandbox_tracking_protection_title); + // Format the Learn More link in the second bullet point. + TextMessagePreference bulletTwo = (TextMessagePreference) findPreference(PREF_BULLET_TWO); + bulletTwo.setSummary(SpanApplier.applySpans( + getResources().getString( + R.string.privacy_sandbox_tracking_protection_bullet_two_description), + new SpanApplier.SpanInfo("<link>", "</link>", + new NoUnderlineClickableSpan(getContext(), this::onLearnMoreClicked)))); + ChromeSwitchPreference blockAll3PCookiesSwitch = (ChromeSwitchPreference) findPreference(PREF_BLOCK_ALL_TOGGLE); ChromeSwitchPreference doNotTrackSwitch = @@ -186,4 +198,8 @@ allowedGroup.setTitle(spannable); allowedGroup.setExpanded(mAllowListExpanded); } + + private void onLearnMoreClicked(View view) { + // TODO(b/295926938): Implement. + } }
diff --git a/components/privacy_sandbox/android/javatests/src/org/chromium/components/privacy_sandbox/TrackingProtectionSettingsTest.java b/components/privacy_sandbox/android/javatests/src/org/chromium/components/privacy_sandbox/TrackingProtectionSettingsTest.java new file mode 100644 index 0000000..6d5654ad --- /dev/null +++ b/components/privacy_sandbox/android/javatests/src/org/chromium/components/privacy_sandbox/TrackingProtectionSettingsTest.java
@@ -0,0 +1,84 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.components.privacy_sandbox; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withText; + +import static org.mockito.Mockito.when; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import org.chromium.base.library_loader.LibraryLoader; +import org.chromium.base.library_loader.LibraryProcessType; +import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.base.test.util.Batch; +import org.chromium.base.test.util.JniMocker; +import org.chromium.components.browser_ui.settings.BlankUiTestActivitySettingsTestRule; +import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge; +import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridgeJni; +import org.chromium.content_public.browser.BrowserContextHandle; + +/** + * Tests for TrackingProtectionSettings. + */ +@RunWith(BaseJUnit4ClassRunner.class) +@Batch(Batch.PER_CLASS) +public class TrackingProtectionSettingsTest { + @Rule + public final BlankUiTestActivitySettingsTestRule mSettingsRule = + new BlankUiTestActivitySettingsTestRule(); + + @Rule + public JniMocker mJniMocker = new JniMocker(); + + @Mock + private WebsitePreferenceBridge.Natives mBridgeMock; + + @Mock + private BrowserContextHandle mContextHandleMock; + + @Mock + private TrackingProtectionDelegate mDelegate; + + private TrackingProtectionSettings mFragment; + + @BeforeClass + public static void setupSuite() { + LibraryLoader.getInstance().setLibraryProcessType(LibraryProcessType.PROCESS_BROWSER); + LibraryLoader.getInstance().ensureInitialized(); + } + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mJniMocker.mock(WebsitePreferenceBridgeJni.TEST_HOOKS, mBridgeMock); + mSettingsRule.launchPreference(TrackingProtectionSettings.class, null, (fragment) -> { + ((TrackingProtectionSettings) fragment).setTrackingProtectionDelegate(mDelegate); + }); + mFragment = (TrackingProtectionSettings) mSettingsRule.getPreferenceFragment(); + + when(mDelegate.getBrowserContext()).thenReturn(mContextHandleMock); + } + + @Test + @SmallTest + public void testShowTrackingProtectionUi() { + when(mDelegate.isBlockAll3PCDEnabled()).thenReturn(true); + when(mDelegate.isDoNotTrackEnabled()).thenReturn(true); + onView(withText(R.string.privacy_sandbox_tracking_protection_description)) + .check(matches(isDisplayed())); + } +}
diff --git a/components/privacy_sandbox_strings.grdp b/components/privacy_sandbox_strings.grdp index b7df31a..b6c38e7 100644 --- a/components/privacy_sandbox_strings.grdp +++ b/components/privacy_sandbox_strings.grdp
@@ -2194,7 +2194,7 @@ Most sites should work as expected </message> <message name="IDS_PRIVACY_SANDBOX_TRACKING_PROTECTION_BULLET_TWO_DESCRIPTION" desc="" translateable="false" formatter_data="android_java"> - If a site isn’t working, you can try giving it temporary permission to use third-party cookies. Learn more + If a site isn’t working, you can try giving it temporary permission to use third-party cookies. <ph name="BEGIN_LINK"><link></ph>Learn more<ph name="END_LINK"></link></ph> </message> <message name="IDS_PRIVACY_SANDBOX_TRACKING_PROTECTION_ADVANCED_CATEGORY" desc="" translateable="false" formatter_data="android_java"> Advanced @@ -2203,7 +2203,7 @@ Block all third-party cookies </message> <message name="IDS_TRACKING_PROTECTION_BLOCK_COOKIES_TOGGLE_SUMMARY" desc="" translateable="false" formatter_data="android_java"> - Features on some sites may not work. Learn more + Features on some sites may not work </message> <message name="IDS_TRACKING_PROTECTION_DNT_TOGGLE_TITLE" desc="" translateable="false" formatter_data="android_java"> Send a “Do Not Track” request with your browsing traffic
diff --git a/components/trusted_vault/BUILD.gn b/components/trusted_vault/BUILD.gn index db31088..d54b3c3 100644 --- a/components/trusted_vault/BUILD.gn +++ b/components/trusted_vault/BUILD.gn
@@ -14,6 +14,7 @@ "//base", "//components/keyed_service/core", ] + configs += [ "//build/config/compiler:wexit_time_destructors" ] if (!is_android) { sources += [
diff --git a/components/version_info/BUILD.gn b/components/version_info/BUILD.gn index 236a8e98..3bd0867 100644 --- a/components/version_info/BUILD.gn +++ b/components/version_info/BUILD.gn
@@ -17,7 +17,6 @@ ] deps = [ - "//base", "//base:sanitizer_buildflags", "//build:branding_buildflags", "//build:chromeos_buildflags", @@ -26,6 +25,7 @@ public_deps = [ ":channel", ":generate_version_info", + "//base", ] }
diff --git a/content/browser/attribution_reporting/attribution_aggregatable_report_golden_unittest.cc b/content/browser/attribution_reporting/attribution_aggregatable_report_golden_unittest.cc index 3015f20..ffeb6a4d 100644 --- a/content/browser/attribution_reporting/attribution_aggregatable_report_golden_unittest.cc +++ b/content/browser/attribution_reporting/attribution_aggregatable_report_golden_unittest.cc
@@ -23,6 +23,7 @@ #include "base/time/time.h" #include "components/aggregation_service/features.h" #include "components/attribution_reporting/source_registration_time_config.mojom.h" +#include "components/attribution_reporting/suitable_origin.h" #include "content/browser/aggregation_service/aggregatable_report.h" #include "content/browser/aggregation_service/aggregation_service.h" #include "content/browser/aggregation_service/aggregation_service_features.h" @@ -84,7 +85,12 @@ GetAggregationServiceProcessingUrl(url::Origin::Create( GURL(::aggregation_service::kAggregationServiceCoordinatorAwsCloud .Get()))), - std::move(keyset)); + keyset); + aggregation_service().SetPublicKeysForTesting( + GetAggregationServiceProcessingUrl(url::Origin::Create( + GURL(::aggregation_service::kAggregationServiceCoordinatorGcpCloud + .Get()))), + keyset); absl::optional<std::vector<uint8_t>> private_key = base::Base64Decode(ReadStringFromFile( @@ -323,6 +329,10 @@ TEST_F(AttributionAggregatableReportGoldenLatestVersionTest, VerifyGoldenReport) { + const auto kGcpCoordinatorOrigin = + *attribution_reporting::SuitableOrigin::Deserialize( + ::aggregation_service::kAggregationServiceCoordinatorGcpCloud.Get()); + struct { AttributionReport report; base::StringPiece report_file; @@ -419,6 +429,105 @@ .BuildNullAggregatable(), .report_file = "report_8.json", .cleartext_payloads_file = "report_8_cleartext_payloads.json"}, + {.report = + ReportBuilder(AttributionInfoBuilder().SetDebugKey(456).Build(), + SourceBuilder(base::Time::FromJavaTime(1234483200000)) + .SetDebugKey(123) + .BuildStored()) + .SetAggregatableHistogramContributions( + {AggregatableHistogramContribution(/*key=*/1, /*value=*/2)}) + .SetReportTime(base::Time::FromJavaTime(1234486400000)) + .SetAggregationCoordinatorOrigin(kGcpCoordinatorOrigin) + .BuildAggregatableAttribution(), + .report_file = "report_gcp_1.json", + .cleartext_payloads_file = "report_gcp_1_cleartext_payloads.json"}, + {.report = + ReportBuilder(AttributionInfoBuilder().Build(), + SourceBuilder(base::Time::FromJavaTime(1234483200000)) + .BuildStored()) + .SetAggregatableHistogramContributions( + {AggregatableHistogramContribution(/*key=*/1, /*value=*/2)}) + .SetReportTime(base::Time::FromJavaTime(1234486400000)) + .SetAggregationCoordinatorOrigin(kGcpCoordinatorOrigin) + .BuildAggregatableAttribution(), + .report_file = "report_gcp_2.json", + .cleartext_payloads_file = "report_gcp_2_cleartext_payloads.json"}, + {.report = + ReportBuilder(AttributionInfoBuilder().SetDebugKey(456).Build(), + SourceBuilder(base::Time::FromJavaTime(1234483300000)) + .SetDebugKey(123) + .BuildStored()) + .SetAggregatableHistogramContributions( + {AggregatableHistogramContribution(/*key=*/1, /*value=*/2), + AggregatableHistogramContribution(/*key=*/3, /*value=*/4)}) + .SetReportTime(base::Time::FromJavaTime(1234486500000)) + .SetAggregationCoordinatorOrigin(kGcpCoordinatorOrigin) + .BuildAggregatableAttribution(), + .report_file = "report_gcp_3.json", + .cleartext_payloads_file = "report_gcp_3_cleartext_payloads.json"}, + {.report = + ReportBuilder(AttributionInfoBuilder().Build(), + SourceBuilder(base::Time::FromJavaTime(1234483300000)) + .BuildStored()) + .SetAggregatableHistogramContributions( + {AggregatableHistogramContribution(/*key=*/1, /*value=*/2), + AggregatableHistogramContribution(/*key=*/3, /*value=*/4)}) + .SetReportTime(base::Time::FromJavaTime(1234486500000)) + .SetAggregationCoordinatorOrigin(kGcpCoordinatorOrigin) + .BuildAggregatableAttribution(), + .report_file = "report_gcp_4.json", + .cleartext_payloads_file = "report_gcp_4_cleartext_payloads.json"}, + {.report = + ReportBuilder(AttributionInfoBuilder().SetDebugKey(456).Build(), + SourceBuilder(base::Time::FromJavaTime(1234483400000)) + .SetDebugKey(123) + .BuildStored()) + .SetAggregatableHistogramContributions( + {AggregatableHistogramContribution( + /*key=*/absl::Uint128Max(), /*value=*/1000)}) + .SetReportTime(base::Time::FromJavaTime(1234486600000)) + .SetAggregationCoordinatorOrigin(kGcpCoordinatorOrigin) + .BuildAggregatableAttribution(), + .report_file = "report_gcp_5.json", + .cleartext_payloads_file = "report_gcp_5_cleartext_payloads.json"}, + {.report = + ReportBuilder(AttributionInfoBuilder().Build(), + SourceBuilder(base::Time::FromJavaTime(1234483400000)) + .BuildStored()) + .SetAggregatableHistogramContributions( + {AggregatableHistogramContribution( + /*key=*/absl::Uint128Max(), /*value=*/1000)}) + .SetReportTime(base::Time::FromJavaTime(1234486600000)) + .SetAggregationCoordinatorOrigin(kGcpCoordinatorOrigin) + .BuildAggregatableAttribution(), + .report_file = "report_gcp_6.json", + .cleartext_payloads_file = "report_gcp_6_cleartext_payloads.json"}, + {.report = + ReportBuilder(AttributionInfoBuilder().Build(), + SourceBuilder(base::Time::FromJavaTime(1234483200000)) + .BuildStored()) + .SetAggregatableHistogramContributions( + {AggregatableHistogramContribution(/*key=*/0, /*value=*/1)}) + .SetReportTime(base::Time::FromJavaTime(1234486400000)) + .SetSourceRegistrationTimeConfig( + attribution_reporting::mojom::SourceRegistrationTimeConfig:: + kExclude) + .SetAggregationCoordinatorOrigin(kGcpCoordinatorOrigin) + .BuildAggregatableAttribution(), + .report_file = "report_gcp_7.json", + .cleartext_payloads_file = "report_gcp_7_cleartext_payloads.json"}, + {.report = + ReportBuilder(AttributionInfoBuilder().Build(), + SourceBuilder(base::Time::FromJavaTime(1234483200000)) + .BuildStored()) + .SetReportTime(base::Time::FromJavaTime(1234486400000)) + .SetSourceRegistrationTimeConfig( + attribution_reporting::mojom::SourceRegistrationTimeConfig:: + kExclude) + .SetAggregationCoordinatorOrigin(kGcpCoordinatorOrigin) + .BuildNullAggregatable(), + .report_file = "report_gcp_8.json", + .cleartext_payloads_file = "report_gcp_8_cleartext_payloads.json"}, }; for (auto& test_case : kTestCases) {
diff --git a/content/browser/background_sync/background_sync_service_impl_test_harness.cc b/content/browser/background_sync/background_sync_service_impl_test_harness.cc index f37ca822..607ae582 100644 --- a/content/browser/background_sync/background_sync_service_impl_test_harness.cc +++ b/content/browser/background_sync/background_sync_service_impl_test_harness.cc
@@ -125,6 +125,8 @@ background_sync_test_util::SetIgnoreNetworkChanges(false); mojo::SetDefaultProcessErrorHandler(base::NullCallback()); + + storage_partition_impl_->OnBrowserContextWillBeDestroyed(); } // SetUp helper methods
diff --git a/content/browser/browser_context_impl.cc b/content/browser/browser_context_impl.cc index 3b215303..fffdfa3 100644 --- a/content/browser/browser_context_impl.cc +++ b/content/browser/browser_context_impl.cc
@@ -18,6 +18,7 @@ #include "content/browser/renderer_host/navigation_transitions/navigation_entry_screenshot_cache.h" #include "content/browser/renderer_host/navigation_transitions/navigation_entry_screenshot_manager.h" #include "content/browser/speech/tts_controller_impl.h" +#include "content/browser/storage_partition_impl.h" #include "content/browser/storage_partition_impl_map.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" @@ -48,6 +49,11 @@ partition->GetSharedWorkerService()->Shutdown(); } +void NotifyContextWillBeDestroyed(StoragePartition* partition) { + static_cast<StoragePartitionImpl*>(partition) + ->OnBrowserContextWillBeDestroyed(); +} + void RegisterMediaLearningTask( media::learning::LearningSessionImpl* learning_session, const media::learning::LearningTask& task) { @@ -140,6 +146,9 @@ self_->ForEachLoadedStoragePartition( base::BindRepeating(ShutdownSharedWorkerContext)); + self_->ForEachLoadedStoragePartition( + base::BindRepeating(NotifyContextWillBeDestroyed)); + // Also forcibly release keep alive refcounts on RenderProcessHosts, to ensure // they destruct before the BrowserContext does. for (RenderProcessHost::iterator host_iterator =
diff --git a/content/browser/content_index/content_index_context_impl.h b/content/browser/content_index/content_index_context_impl.h index 566c757..6d5b8b28 100644 --- a/content/browser/content_index/content_index_context_impl.h +++ b/content/browser/content_index/content_index_context_impl.h
@@ -58,7 +58,7 @@ ~ContentIndexContextImpl() override; - raw_ptr<ContentIndexProvider, AcrossTasksDanglingUntriaged> provider_; + raw_ptr<ContentIndexProvider> provider_; ContentIndexDatabase content_index_database_; };
diff --git a/content/browser/content_index/content_index_database.h b/content/browser/content_index/content_index_database.h index bd9a0b07..aa9ce68 100644 --- a/content/browser/content_index/content_index_database.h +++ b/content/browser/content_index/content_index_database.h
@@ -173,7 +173,7 @@ void BlockOrigin(const url::Origin& origin); void UnblockOrigin(const url::Origin& origin); - raw_ptr<ContentIndexProvider, AcrossTasksDanglingUntriaged> provider_; + raw_ptr<ContentIndexProvider> provider_; // A map from origins to how many times it's been blocked. base::flat_map<url::Origin, int> blocked_origins_;
diff --git a/content/browser/cookie_store/cookie_store_manager_unittest.cc b/content/browser/cookie_store/cookie_store_manager_unittest.cc index da33e77b..1e04ef3 100644 --- a/content/browser/cookie_store/cookie_store_manager_unittest.cc +++ b/content/browser/cookie_store/cookie_store_manager_unittest.cc
@@ -442,6 +442,8 @@ worker_test_helper_->ShutdownContext(); task_environment_.RunUntilIdle(); + storage_partition_impl_->OnBrowserContextWillBeDestroyed(); + // Smart pointers are reset manually in destruction order because this is // called by ResetServiceWorkerContext(). example_service_.reset();
diff --git a/content/browser/file_system_access/file_system_access_manager_impl.h b/content/browser/file_system_access/file_system_access_manager_impl.h index 4a9368ab..629be3f 100644 --- a/content/browser/file_system_access/file_system_access_manager_impl.h +++ b/content/browser/file_system_access/file_system_access_manager_impl.h
@@ -578,8 +578,8 @@ const scoped_refptr<ChromeBlobStorageContext> blob_context_; base::SequenceBound<storage::FileSystemOperationRunner> operation_runner_ GUARDED_BY_CONTEXT(sequence_checker_); - raw_ptr<FileSystemAccessPermissionContext, AcrossTasksDanglingUntriaged> - permission_context_ GUARDED_BY_CONTEXT(sequence_checker_); + raw_ptr<FileSystemAccessPermissionContext> permission_context_ + GUARDED_BY_CONTEXT(sequence_checker_); // All the mojo receivers for this FileSystemAccessManager itself. Keeps // track of associated origin and other state as well to not have to rely on
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc index d6d2443..dfc019b 100644 --- a/content/browser/media/session/media_session_impl.cc +++ b/content/browser/media/session/media_session_impl.cc
@@ -1201,6 +1201,8 @@ media_session::mojom::MediaSessionAction::kEnterPictureInPicture)) { DidReceiveAction( media_session::mojom::MediaSessionAction::kEnterPictureInPicture); + uma_helper_.RecordEnterPictureInPicture( + MediaSessionUmaHelper::EnterPictureInPictureType::kRegisteredManual); return; } @@ -1208,6 +1210,8 @@ DCHECK_EQ(normal_players_.size(), 1u); normal_players_.begin()->first.observer->OnEnterPictureInPicture( normal_players_.begin()->first.player_id); + uma_helper_.RecordEnterPictureInPicture( + MediaSessionUmaHelper::EnterPictureInPictureType::kDefaultHandler); } void MediaSessionImpl::ExitPictureInPicture() { @@ -1226,6 +1230,8 @@ DidReceiveAction( media_session::mojom::MediaSessionAction::kEnterPictureInPicture); + uma_helper_.RecordEnterPictureInPicture( + MediaSessionUmaHelper::EnterPictureInPictureType::kRegisteredAutomatic); } void MediaSessionImpl::SetAudioSinkId(const absl::optional<std::string>& id) {
diff --git a/content/browser/media/session/media_session_uma_helper.cc b/content/browser/media/session/media_session_uma_helper.cc index 679650c0..4b5ce9dd 100644 --- a/content/browser/media/session/media_session_uma_helper.cc +++ b/content/browser/media/session/media_session_uma_helper.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/metrics/histogram_base.h" +#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/time/default_tick_clock.h" @@ -25,6 +26,11 @@ UMA_HISTOGRAM_ENUMERATION("Media.Session.Suspended", source); } +void MediaSessionUmaHelper::RecordEnterPictureInPicture( + EnterPictureInPictureType type) const { + base::UmaHistogramEnumeration("Media.Session.EnterPictureInPicture", type); +} + void MediaSessionUmaHelper::OnSessionActive() { current_active_time_ = clock_->NowTicks(); }
diff --git a/content/browser/media/session/media_session_uma_helper.h b/content/browser/media/session/media_session_uma_helper.h index 7b8af57e..719be17 100644 --- a/content/browser/media/session/media_session_uma_helper.h +++ b/content/browser/media/session/media_session_uma_helper.h
@@ -29,11 +29,31 @@ kMaxValue = kSystemTransientDuck, }; + // These values are persisted to logs. Entries should not be renumbered and + // numeric values should never be reused. + enum class EnterPictureInPictureType { + // EnterPictureInPicture was called for the default handler provided by + // MediaSessionImpl. + kDefaultHandler = 0, + + // EnterPictureInPicture was called for an enterpictureinpicture handler + // provided by the website. + kRegisteredManual = 1, + + // EnterAutoPictureInPicture was called for an enterpictureinpicture handler + // provided by the website. + kRegisteredAutomatic = 2, + + kMaxValue = kRegisteredAutomatic, + }; + MediaSessionUmaHelper(); ~MediaSessionUmaHelper(); void RecordSessionSuspended(MediaSessionSuspendedSource source) const; + void RecordEnterPictureInPicture(EnterPictureInPictureType type) const; + void OnSessionActive(); void OnSessionSuspended(); void OnSessionInactive();
diff --git a/content/browser/preloading/prefetch/no_vary_search_helper.h b/content/browser/preloading/prefetch/no_vary_search_helper.h index 11f731f..88270c0 100644 --- a/content/browser/preloading/prefetch/no_vary_search_helper.h +++ b/content/browser/preloading/prefetch/no_vary_search_helper.h
@@ -12,6 +12,7 @@ #include "base/feature_list.h" #include "content/browser/preloading/prefetch/prefetch_container.h" #include "content/common/content_export.h" +#include "content/public/browser/global_routing_id.h" #include "net/http/http_no_vary_search_data.h" #include "services/network/public/cpp/features.h" #include "services/network/public/mojom/no_vary_search.mojom.h" @@ -40,6 +41,40 @@ CONTENT_EXPORT void SetNoVarySearchData( base::WeakPtr<PrefetchContainer> prefetch_container); +// See comments inside `IterateCandidates()` for requirements for `PrefetchKey`. +template <typename PrefetchKey> +class PrefetchKeyTraits; + +template <> +class PrefetchKeyTraits<GURL> { + public: + using PrefetchKey = GURL; + static const GURL& GetURL(const PrefetchKey& key) { return key; } + static PrefetchKey KeyWithNewURL(const PrefetchKey& old_key, + const GURL& new_url) { + return new_url; + } + static bool NonUrlPartIsSame(const PrefetchKey& key1, + const PrefetchKey& key2) { + return true; + } +}; + +template <typename T> +class PrefetchKeyTraits<std::pair<T, GURL>> { + public: + using PrefetchKey = std::pair<T, GURL>; + static const GURL& GetURL(const PrefetchKey& key) { return key.second; } + static PrefetchKey KeyWithNewURL(const PrefetchKey& old_key, + const GURL& new_url) { + return PrefetchKey(old_key.first, new_url); + } + static bool NonUrlPartIsSame(const PrefetchKey& key1, + const PrefetchKey& key2) { + return key1.first == key2.first; + } +}; + // Indicates whether `IterateCandidates` should continue or finish after // `callback` is called. enum class IterateCandidateResult { kContinue, kFinish }; @@ -51,13 +86,14 @@ // - Has a URL with the same non-ref/query part as `url`, // - Has `NoVarySearchData`, AND // - `AreEquivalent()` is true or `check_are_equivalent` is false. -inline void IterateCandidates( - const GURL& url, - const std::map<GURL, base::WeakPtr<PrefetchContainer>>& prefetches, +template <typename PrefetchKey> +void IterateCandidates( + const PrefetchKey& key, + const std::map<PrefetchKey, base::WeakPtr<PrefetchContainer>>& prefetches, base::RepeatingCallback< IterateCandidateResult(base::WeakPtr<PrefetchContainer>)> callback, bool check_are_equivalent = true) { - auto it_exact_match = prefetches.find(url); + auto it_exact_match = prefetches.find(key); if (it_exact_match != prefetches.end() && it_exact_match->second) { if (callback.Run(it_exact_match->second) == IterateCandidateResult::kFinish) { @@ -73,7 +109,8 @@ GURL::Replacements replacements; replacements.ClearRef(); replacements.ClearQuery(); - GURL url_with_no_query = url.ReplaceComponents(replacements); + const GURL& key_url = PrefetchKeyTraits<PrefetchKey>::GetURL(key); + GURL url_with_no_query = key_url.ReplaceComponents(replacements); // `std::map<GURL, ...>` is sorted by lexicographical string order of // the normalized URLs (`GURL::spec_`, i.e. `possibly_invalid_spec()`). @@ -83,10 +120,31 @@ // the URLs starting with `https://example.com/index.html` in lexicographical // order until the URL without the `https://example.com/index.html` prefix is // encountered. - for (auto it = prefetches.lower_bound(url_with_no_query); - it != prefetches.end() && it->first.possibly_invalid_spec().starts_with( - url_with_no_query.possibly_invalid_spec()); - ++it) { + // + // This is possible because URLs with the same prefix are in consecutively + // placed in the `std::map<PrefetchKey, ...>` iteration order. `GURL` and + // `std::pair<T, GURL>` satisfies this requirement and thus corresponding + // `PrefetchKeyTraits` are defined, while e.g. `std::pair<GURL, T>` wouldn't + // work. + // + // The same applies to `std::map<std::pair<DocumentToken, GURL>, ...>`, as + // URLs within the same `DocumentToken` is sorted in the same way. + // An additional check of `DocumentToken` is needed to ensure we still + // iterating URLs within the same `DocumentToken`, which is done in + // `NonUrlPartIsSame()`. + for (auto it = + prefetches.lower_bound(PrefetchKeyTraits<PrefetchKey>::KeyWithNewURL( + key, url_with_no_query)); + it != prefetches.end(); ++it) { + const GURL& prefetch_container_url = + PrefetchKeyTraits<PrefetchKey>::GetURL(it->first); + + if (!PrefetchKeyTraits<PrefetchKey>::NonUrlPartIsSame(key, it->first) || + !prefetch_container_url.possibly_invalid_spec().starts_with( + url_with_no_query.possibly_invalid_spec())) { + break; + } + // `it_exact_match` is already visited above and thus skipped. if (it == it_exact_match) { continue; @@ -103,11 +161,13 @@ // have the same non-ref/query parts. See // `NoVarySearchHelperTest.DoNotPrefixMatch` unit tests for concrete // examples. - if (it->first.ReplaceComponents(replacements) != url_with_no_query) { + if (prefetch_container_url.ReplaceComponents(replacements) != + url_with_no_query) { continue; } if (check_are_equivalent && - !it->second->GetNoVarySearchData()->AreEquivalent(url, it->first)) { + !it->second->GetNoVarySearchData()->AreEquivalent( + key_url, prefetch_container_url)) { continue; } @@ -121,12 +181,13 @@ // - Via exact match, or // - Via No-Vary-Search information if exact match is not found, the feature is // enabled and `SetNoVarySearchData()` is called for such `PrefetchContainer`s. -inline base::WeakPtr<PrefetchContainer> MatchUrl( - const GURL& url, - const std::map<GURL, base::WeakPtr<PrefetchContainer>>& prefetches) { +template <typename PrefetchKey> +base::WeakPtr<PrefetchContainer> MatchUrl( + const PrefetchKey& key, + const std::map<PrefetchKey, base::WeakPtr<PrefetchContainer>>& prefetches) { base::WeakPtr<PrefetchContainer> result = nullptr; IterateCandidates( - url, prefetches, + key, prefetches, base::BindRepeating( [](base::WeakPtr<PrefetchContainer>* result, base::WeakPtr<PrefetchContainer> prefetch_container) { @@ -143,14 +204,15 @@ // Return the (URL,PrefetchContainer) pairs for a specific Url without // query and reference. Allow as input urls with query and/or reference // for ease of use (remove query/reference during lookup). -inline std::vector<std::pair<GURL, base::WeakPtr<PrefetchContainer>>> +template <typename PrefetchKey> +std::vector<std::pair<GURL, base::WeakPtr<PrefetchContainer>>> GetAllForUrlWithoutRefAndQueryForTesting( - const GURL& url, - const std::map<GURL, base::WeakPtr<PrefetchContainer>>& prefetches) { + const PrefetchKey& key, + const std::map<PrefetchKey, base::WeakPtr<PrefetchContainer>>& prefetches) { std::vector<std::pair<GURL, base::WeakPtr<PrefetchContainer>>> result; IterateCandidates( - url, prefetches, + key, prefetches, base::BindRepeating( [](std::vector<std::pair<GURL, base::WeakPtr<PrefetchContainer>>>* result,
diff --git a/content/browser/preloading/prefetch/no_vary_search_helper_unittest.cc b/content/browser/preloading/prefetch/no_vary_search_helper_unittest.cc index 91588435..e4f6a05 100644 --- a/content/browser/preloading/prefetch/no_vary_search_helper_unittest.cc +++ b/content/browser/preloading/prefetch/no_vary_search_helper_unittest.cc
@@ -16,34 +16,89 @@ namespace content { namespace { +network::mojom::URLResponseHeadPtr CreateHead() { + network::mojom::URLResponseHeadPtr head = + network::mojom::URLResponseHead::New(); + head->parsed_headers = network::mojom::ParsedHeaders::New(); + head->parsed_headers->no_vary_search_with_parse_error = + network::mojom::NoVarySearchWithParseError::NewNoVarySearch( + network::mojom::NoVarySearch::New()); + head->parsed_headers->no_vary_search_with_parse_error->get_no_vary_search() + ->vary_on_key_order = true; + return head; +} + class NoVarySearchHelperTester final { public: + explicit NoVarySearchHelperTester(bool use_prefetches_by_key) + : use_prefetches_by_key_(use_prefetches_by_key), + prev_document_token_(base::UnguessableToken::CreateForTesting( + document_token_->GetHighForSerialization(), + document_token_->GetLowForSerialization() - 1)), + next_document_token_(base::UnguessableToken::CreateForTesting( + document_token_->GetHighForSerialization(), + document_token_->GetLowForSerialization() + 1)) {} + PrefetchContainer* AddUrl(const GURL& url, network::mojom::URLResponseHeadPtr head) { auto prefetch_container = - CreatePrefetchContainer(url, std::move(head)); + CreatePrefetchContainer(document_token_, url, std::move(head)); prefetches_[url] = prefetch_container; + prefetches_by_key_[prefetch_container->GetPrefetchContainerKey()] = + prefetch_container; + + // Also add `PrefetchContainer` with different `DocumentToken`s, to test + // that `PrefetchContainer` with different `DocumentToken`s are not + // iterated. + // Ignore all query parameters to make it easier to be matched by mistake. + network::mojom::URLResponseHeadPtr head_for_different_document = + CreateHead(); + head_for_different_document->parsed_headers->no_vary_search_with_parse_error + ->get_no_vary_search() + ->search_variance = + network::mojom::SearchParamsVariance::NewVaryParams({}); + auto next_prefetch_container = CreatePrefetchContainer( + next_document_token_, url, head_for_different_document.Clone()); + prefetches_by_key_[next_prefetch_container->GetPrefetchContainerKey()] = + next_prefetch_container; + auto prev_prefetch_container = CreatePrefetchContainer( + prev_document_token_, url, std::move(head_for_different_document)); + prefetches_by_key_[prev_prefetch_container->GetPrefetchContainerKey()] = + prev_prefetch_container; return prefetch_container.get(); } PrefetchContainer* MatchUrl(const GURL& url) { - return no_vary_search::MatchUrl(url, prefetches_).get(); + if (use_prefetches_by_key_) { + return no_vary_search::MatchUrl( + PrefetchContainer::Key(document_token_, url), + prefetches_by_key_) + .get(); + } else { + return no_vary_search::MatchUrl(url, prefetches_).get(); + } } std::vector<std::pair<GURL, base::WeakPtr<PrefetchContainer>>> GetAllForUrlWithoutRefAndQueryForTesting(const GURL& url) { - return no_vary_search::GetAllForUrlWithoutRefAndQueryForTesting( - url, prefetches_); + if (use_prefetches_by_key_) { + return no_vary_search::GetAllForUrlWithoutRefAndQueryForTesting( + PrefetchContainer::Key(document_token_, url), prefetches_by_key_); + } else { + return no_vary_search::GetAllForUrlWithoutRefAndQueryForTesting( + url, prefetches_); + } } private: base::WeakPtr<PrefetchContainer> CreatePrefetchContainer( + const blink::DocumentToken& document_token, const GURL& url, network::mojom::URLResponseHeadPtr head) { std::unique_ptr<PrefetchContainer> prefetch_container = std::make_unique<PrefetchContainer>( - GlobalRenderFrameHostId(1234, 5678), blink::DocumentToken(), url, + GlobalRenderFrameHostId(1234, 5678), document_token, url, PrefetchType(/*use_prefetch_proxy=*/true, blink::mojom::SpeculationEagerness::kEager), blink::mojom::Referrer(), @@ -62,21 +117,22 @@ std::vector<std::unique_ptr<PrefetchContainer>> owned_prefetches_; std::map<GURL, base::WeakPtr<PrefetchContainer>> prefetches_; + + const bool use_prefetches_by_key_; + + const blink::DocumentToken document_token_{}; + // Different DocumentTokens are prepared so that `prev_document_token_` < + // `document_token_` < `next_document_token_`. + const blink::DocumentToken prev_document_token_; + const blink::DocumentToken next_document_token_; + std::map<PrefetchContainer::Key, base::WeakPtr<PrefetchContainer>> + prefetches_by_key_; }; -network::mojom::URLResponseHeadPtr CreateHead() { - network::mojom::URLResponseHeadPtr head = - network::mojom::URLResponseHead::New(); - head->parsed_headers = network::mojom::ParsedHeaders::New(); - head->parsed_headers->no_vary_search_with_parse_error = - network::mojom::NoVarySearchWithParseError::NewNoVarySearch( - network::mojom::NoVarySearch::New()); - head->parsed_headers->no_vary_search_with_parse_error->get_no_vary_search() - ->vary_on_key_order = true; - return head; -} - -class NoVarySearchHelperTest : public RenderViewHostTestHarness { +// bool `GetParam()` indicates whether `MatchUrl` should operate on +// `prefetches_by_key_`. +class NoVarySearchHelperTest : public RenderViewHostTestHarness, + public ::testing::WithParamInterface<bool> { public: NoVarySearchHelperTest() : RenderViewHostTestHarness( @@ -85,7 +141,7 @@ void SetUp() override { RenderViewHostTestHarness::SetUp(); } }; -TEST_F(NoVarySearchHelperTest, AddAndMatchUrlNonEmptyVaryParams) { +TEST_P(NoVarySearchHelperTest, AddAndMatchUrlNonEmptyVaryParams) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature( network::features::kPrefetchNoVarySearch); @@ -96,7 +152,7 @@ network::mojom::SearchParamsVariance::NewVaryParams({"a"}); std::unique_ptr<NoVarySearchHelperTester> helper = - std::make_unique<NoVarySearchHelperTester>(); + std::make_unique<NoVarySearchHelperTester>(GetParam()); const GURL test_url("https://a.com/index.html?a=2&b=3"); auto* prefetch_container = helper->AddUrl(test_url, std::move(head)); @@ -126,7 +182,7 @@ EXPECT_FALSE(helper->MatchUrl(GURL("https://a.com/index.html?b=4"))); } -TEST_F(NoVarySearchHelperTest, AddAndMatchUrlNonEmptyNoVaryParams) { +TEST_P(NoVarySearchHelperTest, AddAndMatchUrlNonEmptyNoVaryParams) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature( network::features::kPrefetchNoVarySearch); @@ -138,7 +194,7 @@ const GURL test_url = GURL("https://a.com/home.html?a=2&b=3"); std::unique_ptr<NoVarySearchHelperTester> helper = - std::make_unique<NoVarySearchHelperTester>(); + std::make_unique<NoVarySearchHelperTester>(GetParam()); auto* prefetch_container = helper->AddUrl(test_url, std::move(head)); const auto urls_with_no_vary_search = helper->GetAllForUrlWithoutRefAndQueryForTesting(test_url); @@ -167,7 +223,7 @@ EXPECT_FALSE(helper->MatchUrl(GURL("https://a.com/home.html?b=4"))); } -TEST_F(NoVarySearchHelperTest, AddAndMatchUrlEmptyNoVaryParams) { +TEST_P(NoVarySearchHelperTest, AddAndMatchUrlEmptyNoVaryParams) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature( network::features::kPrefetchNoVarySearch); @@ -181,7 +237,7 @@ const GURL test_url = GURL("https://a.com/away.html?a=2&b=3&c=6"); std::unique_ptr<NoVarySearchHelperTester> helper = - std::make_unique<NoVarySearchHelperTester>(); + std::make_unique<NoVarySearchHelperTester>(GetParam()); auto* prefetch_container = helper->AddUrl(test_url, std::move(head)); const auto urls_with_no_vary_search = helper->GetAllForUrlWithoutRefAndQueryForTesting(test_url); @@ -215,7 +271,7 @@ EXPECT_EQ(helper->MatchUrl(test_url), prefetch_container); } -TEST_F(NoVarySearchHelperTest, AddUrlWithoutNoVarySearchTest) { +TEST_P(NoVarySearchHelperTest, AddUrlWithoutNoVarySearchTest) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature( network::features::kPrefetchNoVarySearch); @@ -225,7 +281,7 @@ head->parsed_headers = network::mojom::ParsedHeaders::New(); std::unique_ptr<NoVarySearchHelperTester> helper = - std::make_unique<NoVarySearchHelperTester>(); + std::make_unique<NoVarySearchHelperTester>(GetParam()); GURL test_url("https://a.com/index.html?a=2&b=3"); auto* prefetch_container = helper->AddUrl(test_url, std::move(head)); @@ -236,13 +292,13 @@ EXPECT_EQ(helper->MatchUrl(test_url), prefetch_container); } -TEST_F(NoVarySearchHelperTest, DoNotPrefixMatch) { +TEST_P(NoVarySearchHelperTest, DoNotPrefixMatch) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature( network::features::kPrefetchNoVarySearch); std::unique_ptr<NoVarySearchHelperTester> helper = - std::make_unique<NoVarySearchHelperTester>(); + std::make_unique<NoVarySearchHelperTester>(GetParam()); // `no_match_url_num` and `no_match_url_foo` have the prefix // "https://example.com/index.html" but shouldn't match with @@ -320,5 +376,50 @@ EXPECT_FALSE(helper->MatchUrl(GURL("https://example.com/index.html?a=5"))); } +TEST_P(NoVarySearchHelperTest, DoNotMatchDifferentDocumentToken) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + network::features::kPrefetchNoVarySearch); + + std::unique_ptr<NoVarySearchHelperTester> helper = + std::make_unique<NoVarySearchHelperTester>(GetParam()); + + network::mojom::URLResponseHeadPtr head = CreateHead(); + head->parsed_headers->no_vary_search_with_parse_error->get_no_vary_search() + ->search_variance = + network::mojom::SearchParamsVariance::NewVaryParams({"a"}); + + const GURL url("https://example.com/index.html?a=2&b=3"); + const GURL test_url("https://example.com/index.html?a=2"); + const GURL foo_url("https://example.com/index.html?foo"); + + auto* prefetch_container = helper->AddUrl(url, std::move(head)); + + // Here, `NoVarySearchHelperTester::prefetches_by_key_` have three keys, + // sorted in the order: + // - (prev_document_token_, url) + // - (document_token_, url) + // - (next_document_token_, url) + // Even though the consecutive entries have the same URL, we shouldn't include + // the 1st/3rd ones in the matching results because DocumentToken is + // different. + + EXPECT_EQ(helper->MatchUrl(url), prefetch_container); + EXPECT_EQ(helper->GetAllForUrlWithoutRefAndQueryForTesting(url).size(), 1u); + + EXPECT_EQ(helper->MatchUrl(test_url), prefetch_container); + EXPECT_EQ(helper->GetAllForUrlWithoutRefAndQueryForTesting(test_url).size(), + 1u); + + EXPECT_FALSE(helper->MatchUrl(foo_url)); + EXPECT_EQ(helper->GetAllForUrlWithoutRefAndQueryForTesting(foo_url).size(), + 1u); +} + +INSTANTIATE_TEST_SUITE_P( + /* no prefix */, + NoVarySearchHelperTest, + testing::Bool()); + } // namespace } // namespace content
diff --git a/content/browser/service_worker/service_worker_job_unittest.cc b/content/browser/service_worker/service_worker_job_unittest.cc index d8fde9b..c34bcc7 100644 --- a/content/browser/service_worker/service_worker_job_unittest.cc +++ b/content/browser/service_worker/service_worker_job_unittest.cc
@@ -1741,6 +1741,7 @@ void TearDown() override { // These need to be cleared before `helper_` to avoid dangling pointers. + storage_partition_impl_->OnBrowserContextWillBeDestroyed(); storage_partition_impl_.reset(); update_helper_ = nullptr;
diff --git a/content/browser/service_worker/service_worker_registration_unittest.cc b/content/browser/service_worker/service_worker_registration_unittest.cc index c3e3f7b..a9d3eb2 100644 --- a/content/browser/service_worker/service_worker_registration_unittest.cc +++ b/content/browser/service_worker/service_worker_registration_unittest.cc
@@ -183,6 +183,10 @@ storage_partition_impl_.get()); } + void TearDown() override { + storage_partition_impl_->OnBrowserContextWillBeDestroyed(); + } + ServiceWorkerContextCore* context() { return helper_->context(); } ServiceWorkerRegistry* registry() { return helper_->context()->registry(); }
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index af14b29..3db8ef3 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -16,6 +16,7 @@ #include "base/barrier_closure.h" #include "base/command_line.h" #include "base/containers/contains.h" +#include "base/dcheck_is_on.h" #include "base/feature_list.h" #include "base/files/file_util.h" #include "base/functional/bind.h" @@ -1260,6 +1261,9 @@ deletion_helpers_running_(0) {} StoragePartitionImpl::~StoragePartitionImpl() { +#if DCHECK_IS_ON() + DCHECK(on_browser_context_will_be_destroyed_called_); +#endif browser_context_ = nullptr; if (url_loader_factory_getter_) { @@ -1279,10 +1283,6 @@ std::move(database_tracker))); } - if (GetFileSystemAccessManager()) { - GetFileSystemAccessManager()->Shutdown(); - } - if (GetFileSystemContext()) { GetFileSystemContext()->Shutdown(); } @@ -1307,15 +1307,26 @@ GetBackgroundFetchContext()->Shutdown(); } - if (GetContentIndexContext()) { - GetContentIndexContext()->Shutdown(); - } - if (GetGeneratedCodeCacheContext()) { GetGeneratedCodeCacheContext()->Shutdown(); } } +void StoragePartitionImpl::OnBrowserContextWillBeDestroyed() { +#if DCHECK_IS_ON() + on_browser_context_will_be_destroyed_called_ = true; +#endif + // These hold raw pointers to objects that are about to be destroyed, before + // this object is destroyed. Shut them down now to avoid dangling pointers. + if (GetFileSystemAccessManager()) { + GetFileSystemAccessManager()->Shutdown(); + } + + if (GetContentIndexContext()) { + GetContentIndexContext()->Shutdown(); + } +} + // static std::unique_ptr<StoragePartitionImpl> StoragePartitionImpl::Create( BrowserContext* context,
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h index 5c58239..4e0bbc5a 100644 --- a/content/browser/storage_partition_impl.h +++ b/content/browser/storage_partition_impl.h
@@ -12,6 +12,7 @@ #include <string> #include "base/containers/flat_map.h" +#include "base/dcheck_is_on.h" #include "base/files/file_path.h" #include "base/gtest_prod_util.h" #include "base/memory/raw_ptr.h" @@ -461,6 +462,9 @@ storage::QuotaManagerProxy* GetQuotaManagerProxy(); + // Called by BrowserContextImpl prior to destruction. + void OnBrowserContextWillBeDestroyed(); + class URLLoaderNetworkContext { public: enum class Type { @@ -568,7 +572,9 @@ // of distinguishing different in-memory partitions, but nothing is persisted // on to disk. // - // Initialize() must be called on the StoragePartitionImpl before using it. + // Initialize() must be called on the StoragePartitionImpl before using it, + // and OnBrowserContextWillBeDestroyed() must be called on it prior to + // `context` being destroyed. static std::unique_ptr<StoragePartitionImpl> Create( BrowserContext* context, const StoragePartitionConfig& config, @@ -795,6 +801,10 @@ int next_pending_trust_token_issuance_callback_key_ = 0; +#if DCHECK_IS_ON() + bool on_browser_context_will_be_destroyed_called_ = false; +#endif + base::WeakPtrFactory<StoragePartitionImpl> weak_factory_{this}; };
diff --git a/content/browser/storage_partition_impl_map_unittest.cc b/content/browser/storage_partition_impl_map_unittest.cc index 78a1126..12be184 100644 --- a/content/browser/storage_partition_impl_map_unittest.cc +++ b/content/browser/storage_partition_impl_map_unittest.cc
@@ -67,6 +67,8 @@ appcache_path = partition->GetPath().Append(kAppCacheDirname); task_environment.RunUntilIdle(); + + partition->OnBrowserContextWillBeDestroyed(); } // Create an AppCache directory that would have existed. @@ -84,6 +86,8 @@ // Verify that creating this partition deletes any AppCache directory it may // have had. EXPECT_FALSE(base::PathExists(appcache_path)); + + partition->OnBrowserContextWillBeDestroyed(); } }
diff --git a/content/browser/tracing/background_tracing_manager_impl.cc b/content/browser/tracing/background_tracing_manager_impl.cc index 1df5e94..3b9280d 100644 --- a/content/browser/tracing/background_tracing_manager_impl.cc +++ b/content/browser/tracing/background_tracing_manager_impl.cc
@@ -86,6 +86,9 @@ absl::optional<NewTraceReport> report_to_upload; if (base::FeatureList::IsEnabled(kBackgroundTracingDatabase)) { report_to_upload = database->GetNextReportPendingUpload(); + } else { + // Traces pending upload from previous sessions have timed out. + database->AllPendingUploadSkipped(SkipUploadReason::kUploadTimedOut); } GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(std::move(on_database_created), @@ -657,6 +660,14 @@ std::move(receive_callback) .Run(std::move(trace_report_to_upload_->trace_content), std::move(trace_report_to_upload_->system_profile)); + database_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + [](TraceReportDatabase* trace_database, const base::Token& uuid) { + trace_database->UploadComplete(uuid, base::Time::Now()); + }, + base::Unretained(trace_database_.get()), + trace_report_to_upload_->uuid)); OnFinalizeComplete(absl::nullopt, true); return; }
diff --git a/content/browser/tracing/trace_report/trace_report.mojom b/content/browser/tracing/trace_report/trace_report.mojom index 75865ec..5dff709 100644 --- a/content/browser/tracing/trace_report/trace_report.mojom +++ b/content/browser/tracing/trace_report/trace_report.mojom
@@ -25,6 +25,7 @@ kSizeLimitExceeded = 1, kNotAnonymized = 2, kScenarioQuotaExceeded = 3, + kUploadTimedOut = 4, }; // Information about a single trace to display
diff --git a/content/browser/tracing/trace_report/trace_report_database.cc b/content/browser/tracing/trace_report/trace_report_database.cc index c116d51..310bff18 100644 --- a/content/browser/tracing/trace_report/trace_report_database.cc +++ b/content/browser/tracing/trace_report/trace_report_database.cc
@@ -229,6 +229,30 @@ return update_local_trace.Run(); } +bool TraceReportDatabase::UploadSkipped(const base::Token& uuid, + SkipUploadReason skip_reason) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!is_initialized()) { + return false; + } + + sql::Statement update_local_trace( + database_.GetCachedStatement(SQL_FROM_HERE, + R"sql(UPDATE local_traces + SET state=?, skip_reason=? + WHERE uuid=?)sql")); + + CHECK(update_local_trace.is_valid()); + + update_local_trace.BindInt(0, + static_cast<int>(ReportUploadState::kNotUploaded)); + update_local_trace.BindInt(1, static_cast<int>(skip_reason)); + update_local_trace.BindString(2, uuid.ToString()); + + return update_local_trace.Run(); +} + absl::optional<std::string> TraceReportDatabase::GetTraceContent( const base::Token& uuid) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -350,6 +374,28 @@ return delete_traces_older_than.Run(); } +bool TraceReportDatabase::AllPendingUploadSkipped( + SkipUploadReason skip_reason) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!is_initialized()) { + return false; + } + + sql::Statement statement( + database_.GetCachedStatement(SQL_FROM_HERE, + R"sql(UPDATE local_traces + SET state=?, skip_reason=? + WHERE state=?)sql")); + + statement.BindInt(0, static_cast<int>(ReportUploadState::kNotUploaded)); + statement.BindInt(1, static_cast<int>(skip_reason)); + statement.BindInt(2, static_cast<int>(ReportUploadState::kPending)); + + CHECK(statement.is_valid()); + + return statement.Run(); +} + bool TraceReportDatabase::EnsureTableCreated() { DCHECK(database_.is_open()); @@ -438,9 +484,11 @@ sql::Statement statement(database_.GetCachedStatement(SQL_FROM_HERE, R"sql( SELECT COUNT(uuid) FROM local_traces WHERE scenario_name = ? AND creation_time > ? + AND skip_reason=? )sql")); statement.BindString(0, scenario_name); statement.BindTime(1, since); + statement.BindInt(2, static_cast<int>(SkipUploadReason::kNoSkip)); CHECK(statement.is_valid()); while (statement.Step()) {
diff --git a/content/browser/tracing/trace_report/trace_report_database.h b/content/browser/tracing/trace_report/trace_report_database.h index e0e6fa6d..a22c0ca 100644 --- a/content/browser/tracing/trace_report/trace_report_database.h +++ b/content/browser/tracing/trace_report/trace_report_database.h
@@ -32,6 +32,7 @@ kSizeLimitExceeded = 1, kNotAnonymized = 2, kScenarioQuotaExceeded = 3, + kUploadTimedOut = 4, }; // BaseTraceReport contains common data used to create and display a trace @@ -133,9 +134,12 @@ // Delete all traces older than |age| from today. bool DeleteTracesOlderThan(const base::TimeDelta age); + // Mark all reports that are pending upload as skipped with `skip_reason`. + bool AllPendingUploadSkipped(SkipUploadReason skip_reason); + bool UserRequestedUpload(const base::Token& uuid); bool UploadComplete(const base::Token& uuid, base::Time time); - bool UploadSkipped(const base::Token& uuid); + bool UploadSkipped(const base::Token& uuid, SkipUploadReason skip_reason); // Returns the serialized trace content string if any. absl::optional<std::string> GetTraceContent(const base::Token& uuid);
diff --git a/content/browser/tracing/trace_report/trace_report_database_unittest.cc b/content/browser/tracing/trace_report/trace_report_database_unittest.cc index 8f44614..b5a4c1d4 100644 --- a/content/browser/tracing/trace_report/trace_report_database_unittest.cc +++ b/content/browser/tracing/trace_report/trace_report_database_unittest.cc
@@ -179,6 +179,24 @@ EXPECT_EQ(trace_report_.GetAllReports().size(), 5u); } +TEST_F(TraceReportDatabaseTest, AllPendingUploadSkipped) { + EXPECT_EQ(trace_report_.GetAllReports().size(), 0u); + + ASSERT_TRUE(trace_report_.AddTrace(MakeNewTraceReport())); + ASSERT_TRUE(trace_report_.AddTrace(MakeNewTraceReport())); + EXPECT_EQ(trace_report_.GetAllReports().size(), 2u); + + ASSERT_TRUE( + trace_report_.AllPendingUploadSkipped(SkipUploadReason::kUploadTimedOut)); + + auto all_traces = trace_report_.GetAllReports(); + EXPECT_EQ(all_traces.size(), 2u); + EXPECT_EQ(all_traces[0].upload_state, ReportUploadState::kNotUploaded); + EXPECT_EQ(all_traces[0].skip_reason, SkipUploadReason::kUploadTimedOut); + EXPECT_EQ(all_traces[1].upload_state, ReportUploadState::kNotUploaded); + EXPECT_EQ(all_traces[1].skip_reason, SkipUploadReason::kUploadTimedOut); +} + TEST_F(TraceReportDatabaseTest, UserRequestedUpload) { EXPECT_EQ(trace_report_.GetAllReports().size(), 0u); @@ -234,6 +252,25 @@ EXPECT_FALSE(trace_report_.GetTraceContent(report_uuid)); } +TEST_F(TraceReportDatabaseTest, UploadSkipped) { + EXPECT_EQ(trace_report_.GetAllReports().size(), 0u); + + // Create Report for the local traces database. + NewTraceReport new_report = MakeNewTraceReport(); + const auto report_uuid = new_report.uuid; + + ASSERT_TRUE(trace_report_.AddTrace(new_report)); + EXPECT_EQ(trace_report_.GetAllReports().size(), 1u); + + ASSERT_TRUE(trace_report_.UploadSkipped(report_uuid, + SkipUploadReason::kUploadTimedOut)); + + auto all_traces = trace_report_.GetAllReports(); + EXPECT_EQ(all_traces.size(), 1u); + EXPECT_EQ(all_traces[0].upload_state, ReportUploadState::kNotUploaded); + EXPECT_EQ(all_traces[0].skip_reason, SkipUploadReason::kUploadTimedOut); +} + TEST_F(TraceReportDatabaseTest, GetNextReportPendingUpload) { EXPECT_FALSE(trace_report_.GetNextReportPendingUpload());
diff --git a/content/browser/tracing/trace_report/trace_report_mojom_traits.cc b/content/browser/tracing/trace_report/trace_report_mojom_traits.cc index 999be9d..0a11d8f5 100644 --- a/content/browser/tracing/trace_report/trace_report_mojom_traits.cc +++ b/content/browser/tracing/trace_report/trace_report_mojom_traits.cc
@@ -52,6 +52,8 @@ return SkipUploadReason::kNotAnonymized; case content::SkipUploadReason::kScenarioQuotaExceeded: return SkipUploadReason::kScenarioQuotaExceeded; + case content::SkipUploadReason::kUploadTimedOut: + return SkipUploadReason::kUploadTimedOut; } } @@ -71,7 +73,11 @@ case SkipUploadReason::kScenarioQuotaExceeded: *output = content::SkipUploadReason::kScenarioQuotaExceeded; return true; + case SkipUploadReason::kUploadTimedOut: + *output = content::SkipUploadReason::kUploadTimedOut; + return true; } + return false; } } // namespace mojo
diff --git a/content/browser/web_contents/web_contents_view_android.cc b/content/browser/web_contents/web_contents_view_android.cc index 7488fdd..c51f59fd 100644 --- a/content/browser/web_contents/web_contents_view_android.cc +++ b/content/browser/web_contents/web_contents_view_android.cc
@@ -410,7 +410,9 @@ void WebContentsViewAndroid::UpdateDragOperation( ui::mojom::DragOperation op, bool document_is_handling_drag) { - // Intentional no-op because Android does not have cursor. + // Intentional not storing `op` because Android does not support drag and + // drop cursor yet. + document_is_handling_drag_ = document_is_handling_drag; } bool WebContentsViewAndroid::OnDragEvent(const ui::DragEventAndroid& event) { @@ -430,6 +432,7 @@ case JNI_DragEvent::ACTION_DROP: { DropData drop_data; drop_data.did_originate_from_renderer = false; + drop_data.document_is_handling_drag = document_is_handling_drag_; JNIEnv* env = AttachCurrentThread(); std::u16string drop_content = ConvertJavaStringToUTF16(env, event.GetJavaContent());
diff --git a/content/browser/web_contents/web_contents_view_android.h b/content/browser/web_contents/web_contents_view_android.h index 92ee9318..e2d9cb4 100644 --- a/content/browser/web_contents/web_contents_view_android.h +++ b/content/browser/web_contents/web_contents_view_android.h
@@ -214,6 +214,11 @@ gfx::PointF drag_location_; gfx::PointF drag_screen_location_; + + // Set to true when the document is handling the drag. This means that + // the document has registeted interest in the dropped data and the + // renderer process should pass the data to the document on drop. + bool document_is_handling_drag_ = false; }; } // namespace content
diff --git a/content/browser/web_contents/web_contents_view_ios.h b/content/browser/web_contents/web_contents_view_ios.h index e0642df..c2b03f9 100644 --- a/content/browser/web_contents/web_contents_view_ios.h +++ b/content/browser/web_contents/web_contents_view_ios.h
@@ -50,7 +50,7 @@ void RestoreFocus() override; void FocusThroughTabTraversal(bool reverse) override; DropData* GetDropData() const override; - void CancelDragDropForPortalActivation() override; + void TransferDragSecurityInfo(WebContentsView* view) override; gfx::Rect GetViewBounds() const override; void CreateView(gfx::NativeView context) override; RenderWidgetHostViewBase* CreateViewForWidget(
diff --git a/content/browser/web_contents/web_contents_view_ios.mm b/content/browser/web_contents/web_contents_view_ios.mm index b3880a1..0d4bf98 100644 --- a/content/browser/web_contents/web_contents_view_ios.mm +++ b/content/browser/web_contents/web_contents_view_ios.mm
@@ -154,7 +154,7 @@ return nullptr; } -void WebContentsViewIOS::CancelDragDropForPortalActivation() { +void WebContentsViewIOS::TransferDragSecurityInfo(WebContentsView* view) { NOTIMPLEMENTED(); }
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc index 14066fb..a2e923f 100644 --- a/content/browser/webid/federated_auth_request_impl.cc +++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -107,15 +107,17 @@ } query += "disclosure_text_shown=" + disclosure_text_shown; - if (IsFedCmAccountAutoSelectedFlagEnabled()) { - // Shares with IdP that whether the account was automatically selected. This - // could help developers to better comprehend the token request and segment - // metrics accordingly. - std::string is_account_auto_selected = is_auto_reauthn ? "true" : "false"; + if (IsFedCmIdentityCredentialAutoSelectedFlagEnabled()) { + // Shares with IdP that whether the identity credential was automatically + // selected. This could help developers to better comprehend the token + // request and segment metrics accordingly. + std::string is_identity_credential_auto_selected = + is_auto_reauthn ? "true" : "false"; if (!query.empty()) { query += "&"; } - query += "is_account_auto_selected=" + is_account_auto_selected; + query += "is_identity_credential_auto_selected=" + + is_identity_credential_auto_selected; } if (IsFedCmAuthzEnabled()) { @@ -522,7 +524,7 @@ if (!digital_credential_provider_) { std::move(digital_credential_request_callback_) .Run(RequestTokenStatus::kError, absl::nullopt, "", /*error=*/nullptr, - /*is_account_auto_selected=*/false); + /*is_identity_credential_auto_selected=*/false); return; } @@ -530,11 +532,11 @@ std::move(digital_credential_request_callback_) .Run(RequestTokenStatus::kSuccess, absl::nullopt, response, /*error=*/nullptr, - /*is_account_auto_selected=*/false); + /*is_identity_credential_auto_selected=*/false); } else { std::move(digital_credential_request_callback_) .Run(RequestTokenStatus::kError, absl::nullopt, "", /*error=*/nullptr, - /*is_account_auto_selected=*/false); + /*is_identity_credential_auto_selected=*/false); } } @@ -610,7 +612,7 @@ if (is_multi_idp_input && !IsFedCmMultipleIdentityProvidersEnabled()) { std::move(callback).Run(RequestTokenStatus::kError, absl::nullopt, "", /*error=*/nullptr, - /*is_account_auto_selected=*/false); + /*is_identity_credential_auto_selected=*/false); return; } @@ -621,7 +623,7 @@ // Multi IdP API support. std::move(callback).Run(RequestTokenStatus::kError, absl::nullopt, "", /*error=*/nullptr, - /*is_account_auto_selected=*/false); + /*is_identity_credential_auto_selected=*/false); return; } @@ -631,7 +633,7 @@ // requests. std::move(callback).Run(RequestTokenStatus::kErrorTooManyRequests, absl::nullopt, "", /*error=*/nullptr, - /*is_account_auto_selected=*/false); + /*is_identity_credential_auto_selected=*/false); return; } @@ -644,7 +646,7 @@ if (!digital_credential_provider_) { std::move(digital_credential_request_callback_) .Run(RequestTokenStatus::kError, absl::nullopt, "", /*error=*/nullptr, - /*is_account_auto_selected=*/false); + /*is_identity_credential_auto_selected=*/false); return; } @@ -693,7 +695,7 @@ std::move(callback).Run(RequestTokenStatus::kErrorTooManyRequests, absl::nullopt, "", /*error=*/nullptr, - /*is_account_auto_selected=*/false); + /*is_identity_credential_auto_selected=*/false); return; } @@ -2144,8 +2146,9 @@ } } - bool is_account_auto_selected = - IsFedCmAccountAutoSelectedFlagEnabled() && dialog_type_ == kAutoReauth; + bool is_identity_credential_auto_selected = + IsFedCmIdentityCredentialAutoSelectedFlagEnabled() && + dialog_type_ == kAutoReauth; CleanUp(); @@ -2163,7 +2166,7 @@ FederatedAuthRequestResultToRequestTokenStatus(result); std::move(auth_request_token_callback_) .Run(status, selected_idp_config_url, id_token, std::move(error), - is_account_auto_selected); + is_identity_credential_auto_selected); auth_request_token_callback_.Reset(); } else { base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
diff --git a/content/browser/webid/federated_auth_request_impl_unittest.cc b/content/browser/webid/federated_auth_request_impl_unittest.cc index 907452631..e0967db 100644 --- a/content/browser/webid/federated_auth_request_impl_unittest.cc +++ b/content/browser/webid/federated_auth_request_impl_unittest.cc
@@ -2973,7 +2973,7 @@ checker->SetExpectedTokenPostData( "client_id=" + std::string(kClientId) + "&nonce=" + std::string(kNonce) + "&account_id=" + std::string(kAccountId) + "&disclosure_text_shown=true" + - "&is_account_auto_selected=false"); + "&is_identity_credential_auto_selected=false"); SetNetworkRequestManager(std::move(checker)); RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, @@ -2996,7 +2996,8 @@ checker->SetExpectedTokenPostData( "client_id=" + std::string(kClientId) + "&nonce=" + std::string(kNonce) + "&account_id=" + std::string(kAccountId) + - "&disclosure_text_shown=false" + "&is_account_auto_selected=false"); + "&disclosure_text_shown=false" + + "&is_identity_credential_auto_selected=false"); SetNetworkRequestManager(std::move(checker)); MockConfiguration config = kConfigurationValid; @@ -3013,20 +3014,23 @@ std::unique_ptr<IdpNetworkRequestManagerParamChecker> checker = std::make_unique<IdpNetworkRequestManagerParamChecker>(); - checker->SetExpectedTokenPostData( - "client_id=" + std::string(kClientId) + "&nonce=" + std::string(kNonce) + - "&account_id=account+id&disclosure_text_shown=true&is_account_auto_" - "selected=false"); + checker->SetExpectedTokenPostData("client_id=" + std::string(kClientId) + + "&nonce=" + std::string(kNonce) + + "&account_id=account+id&disclosure_text_" + "shown=true&is_identity_credential_auto_" + "selected=false"); SetNetworkRequestManager(std::move(checker)); RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration); } -// Test that the is_account_auto_selected field is not included in the request -// if the feature is disabled. -TEST_F(FederatedAuthRequestImplTest, AccountAutoSelectedFlagDisabled) { +// Test that the is_identity_credential_auto_selected field is not included in +// the request if the feature is disabled. +TEST_F(FederatedAuthRequestImplTest, + IdentityCredentialAutoSelectedFlagDisabled) { base::test::ScopedFeatureList list; - list.InitAndDisableFeature(features::kFedCmAccountAutoSelectedFlag); + list.InitAndDisableFeature( + features::kFedCmIdentityCredentialAutoSelectedFlag); std::unique_ptr<IdpNetworkRequestManagerParamChecker> checker = std::make_unique<IdpNetworkRequestManagerParamChecker>(); @@ -3039,30 +3043,32 @@ kConfigurationValid); } -// Test that the is_account_auto_selected value in the token post data for -// sign-up case. -TEST_F(FederatedAuthRequestImplTest, AccountAutoSelectedFlagForNewUser) { +// Test that the is_identity_credential_auto_selected value in the token post +// data for sign-up case. +TEST_F(FederatedAuthRequestImplTest, + IdentityCredentialAutoSelectedFlagForNewUser) { base::test::ScopedFeatureList list; - list.InitAndEnableFeature(features::kFedCmAccountAutoSelectedFlag); + list.InitAndEnableFeature(features::kFedCmIdentityCredentialAutoSelectedFlag); std::unique_ptr<IdpNetworkRequestManagerParamChecker> checker = std::make_unique<IdpNetworkRequestManagerParamChecker>(); checker->SetExpectedTokenPostData( "client_id=" + std::string(kClientId) + "&nonce=" + std::string(kNonce) + "&account_id=" + std::string(kAccountId) + "&disclosure_text_shown=true" + - "&is_account_auto_selected=false"); + "&is_identity_credential_auto_selected=false"); SetNetworkRequestManager(std::move(checker)); RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, kConfigurationValid); } -// Test that the is_account_auto_selected value in the token post data for -// returning user with `mediation:required`. -TEST_F(FederatedAuthRequestImplTest, - AccountAutoSelectedFlagForReturningUserWithMediationRequired) { +// Test that the is_identity_credential_auto_selected value in the token post +// data for returning user with `mediation:required`. +TEST_F( + FederatedAuthRequestImplTest, + IdentityCredentialAutoSelectedFlagForReturningUserWithMediationRequired) { base::test::ScopedFeatureList list; - list.InitAndEnableFeature(features::kFedCmAccountAutoSelectedFlag); + list.InitAndEnableFeature(features::kFedCmIdentityCredentialAutoSelectedFlag); // Pretend the sharing permission has been granted for this account. EXPECT_CALL( *test_permission_delegate_, @@ -3076,7 +3082,8 @@ checker->SetExpectedTokenPostData( "client_id=" + std::string(kClientId) + "&nonce=" + std::string(kNonce) + "&account_id=" + std::string(kAccountId) + - "&disclosure_text_shown=false" + "&is_account_auto_selected=false"); + "&disclosure_text_shown=false" + + "&is_identity_credential_auto_selected=false"); SetNetworkRequestManager(std::move(checker)); MockConfiguration config = kConfigurationValid; @@ -3084,12 +3091,13 @@ RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, config); } -// Test that the is_account_auto_selected value in the token post data for -// returning user with `mediation:optional`. -TEST_F(FederatedAuthRequestImplTest, - AccountAutoSelectedFlagForReturningUserWithMediationOptional) { +// Test that the is_identity_credential_auto_selected value in the token post +// data for returning user with `mediation:optional`. +TEST_F( + FederatedAuthRequestImplTest, + IdentityCredentialAutoSelectedFlagForReturningUserWithMediationOptional) { base::test::ScopedFeatureList list; - list.InitAndEnableFeature(features::kFedCmAccountAutoSelectedFlag); + list.InitAndEnableFeature(features::kFedCmIdentityCredentialAutoSelectedFlag); // Pretend the sharing permission has been granted for this account. EXPECT_CALL( *test_permission_delegate_, @@ -3109,7 +3117,8 @@ checker->SetExpectedTokenPostData( "client_id=" + std::string(kClientId) + "&nonce=" + std::string(kNonce) + "&account_id=" + std::string(kAccountId) + - "&disclosure_text_shown=false" + "&is_account_auto_selected=true"); + "&disclosure_text_shown=false" + + "&is_identity_credential_auto_selected=true"); SetNetworkRequestManager(std::move(checker)); MockConfiguration config = kConfigurationValid; @@ -3117,11 +3126,12 @@ RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, config); } -// Test that the is_account_auto_selected value in the token post data for the -// quiet period use case. -TEST_F(FederatedAuthRequestImplTest, AccountAutoSelectedFlagIfInQuietPeriod) { +// Test that the is_identity_credential_auto_selected value in the token post +// data for the quiet period use case. +TEST_F(FederatedAuthRequestImplTest, + IdentityCredentialAutoSelectedFlagIfInQuietPeriod) { base::test::ScopedFeatureList list; - list.InitAndEnableFeature(features::kFedCmAccountAutoSelectedFlag); + list.InitAndEnableFeature(features::kFedCmIdentityCredentialAutoSelectedFlag); // Pretend the sharing permission has been granted for this account. EXPECT_CALL( *test_permission_delegate_, @@ -3146,7 +3156,8 @@ checker->SetExpectedTokenPostData( "client_id=" + std::string(kClientId) + "&nonce=" + std::string(kNonce) + "&account_id=" + std::string(kAccountId) + - "&disclosure_text_shown=false" + "&is_account_auto_selected=false"); + "&disclosure_text_shown=false" + + "&is_identity_credential_auto_selected=false"); SetNetworkRequestManager(std::move(checker)); RequestExpectations expectations = kExpectationSuccess;
diff --git a/content/browser/webid/flags.cc b/content/browser/webid/flags.cc index 88d3d592..94c1fcb 100644 --- a/content/browser/webid/flags.cc +++ b/content/browser/webid/flags.cc
@@ -56,8 +56,9 @@ return base::FeatureList::IsEnabled(features::kWebIdentityMDocs); } -bool IsFedCmAccountAutoSelectedFlagEnabled() { - return base::FeatureList::IsEnabled(features::kFedCmAccountAutoSelectedFlag); +bool IsFedCmIdentityCredentialAutoSelectedFlagEnabled() { + return base::FeatureList::IsEnabled( + features::kFedCmIdentityCredentialAutoSelectedFlag); } bool IsFedCmHostedDomainEnabled() {
diff --git a/content/browser/webid/flags.h b/content/browser/webid/flags.h index 206c4b4..536a891 100644 --- a/content/browser/webid/flags.h +++ b/content/browser/webid/flags.h
@@ -41,8 +41,8 @@ // Whether the Web Identity MDocs API is enabled. bool IsWebIdentityMDocsEnabled(); -// Whether the AccountAutoSelected feature is enabled. -bool IsFedCmAccountAutoSelectedFlagEnabled(); +// Whether the IdentityCredentialAutoSelected feature is enabled. +bool IsFedCmIdentityCredentialAutoSelectedFlagEnabled(); // Whether the HostedDomain feature is enabled. bool IsFedCmHostedDomainEnabled();
diff --git a/content/browser/webid/test/federated_auth_request_request_token_callback_helper.cc b/content/browser/webid/test/federated_auth_request_request_token_callback_helper.cc index 576051c..6fd88a5 100644 --- a/content/browser/webid/test/federated_auth_request_request_token_callback_helper.cc +++ b/content/browser/webid/test/federated_auth_request_request_token_callback_helper.cc
@@ -32,13 +32,13 @@ const absl::optional<GURL>& selected_idp_config_url, const absl::optional<std::string>& token, blink::mojom::TokenErrorPtr error, - bool is_account_auto_selected) { + bool is_identity_credential_auto_selected) { CHECK(!was_called_); status_ = status; selected_idp_config_url_ = selected_idp_config_url; token_ = token; error_ = std::move(error); - is_account_auto_selected_ = is_account_auto_selected; + is_identity_credential_auto_selected_ = is_identity_credential_auto_selected; was_called_ = true; wait_for_callback_loop_.Quit(); }
diff --git a/content/browser/webid/test/federated_auth_request_request_token_callback_helper.h b/content/browser/webid/test/federated_auth_request_request_token_callback_helper.h index 2fd50165..ce11a7c 100644 --- a/content/browser/webid/test/federated_auth_request_request_token_callback_helper.h +++ b/content/browser/webid/test/federated_auth_request_request_token_callback_helper.h
@@ -64,7 +64,7 @@ const absl::optional<GURL>& selected_idp_config_url, const absl::optional<std::string>& token, blink::mojom::TokenErrorPtr error, - bool is_account_auto_selected); + bool is_identity_credential_auto_selected); void Quit(); @@ -74,7 +74,7 @@ absl::optional<GURL> selected_idp_config_url_; absl::optional<std::string> token_; blink::mojom::TokenErrorPtr error_; - bool is_account_auto_selected_{false}; + bool is_identity_credential_auto_selected_{false}; }; } // namespace content
diff --git a/content/browser/webid/webid_browsertest.cc b/content/browser/webid/webid_browsertest.cc index d87fb778..dc15c6c 100644 --- a/content/browser/webid/webid_browsertest.cc +++ b/content/browser/webid/webid_browsertest.cc
@@ -555,6 +555,42 @@ EXPECT_FALSE(*value); } +// Verify that IDP sign-in/out headers work in sync XHR. +IN_PROC_BROWSER_TEST_F(WebIdIdpSigninStatusBrowserTest, + IdpSigninAndOutSyncXhr) { + static constexpr char script[] = R"( + (async () => { + const request = new XMLHttpRequest(); + request.open('GET', '/header/gsign%s', false); + request.send(null); + return request.status; + }) (); + )"; + + GURL url_for_origin = https_server().GetURL(kRpHostName, "/header/"); + url::Origin origin = url::Origin::Create(url_for_origin); + EXPECT_FALSE(sharing_context()->GetIdpSigninStatus(origin).has_value()); + { + base::RunLoop run_loop; + sharing_context()->SetIdpStatusClosureForTesting(run_loop.QuitClosure()); + EXPECT_EQ(200, EvalJs(shell(), base::StringPrintf(script, "in"))); + run_loop.Run(); + } + auto value = sharing_context()->GetIdpSigninStatus(origin); + ASSERT_TRUE(value.has_value()); + EXPECT_TRUE(*value); + + { + base::RunLoop run_loop; + sharing_context()->SetIdpStatusClosureForTesting(run_loop.QuitClosure()); + EXPECT_EQ(200, EvalJs(shell(), base::StringPrintf(script, "out"))); + run_loop.Run(); + } + value = sharing_context()->GetIdpSigninStatus(origin); + ASSERT_TRUE(value.has_value()); + EXPECT_FALSE(*value); +} + // Verify that an IdP can call close to close modal dialog views. IN_PROC_BROWSER_TEST_F(WebIdIdpSigninStatusBrowserTest, IdPClose) { GURL configURL = GURL(BaseIdpUrl()); @@ -761,7 +797,7 @@ content += "nonce=12345&"; content += "account_id=not_real_account&"; content += "disclosure_text_shown=false&"; - content += "is_account_auto_selected=false&"; + content += "is_identity_credential_auto_selected=false&"; // Asserts that the scope, response_type and params parameters // were passed correctly to the id assertion endpoint. content += "scope=name+email+picture&"; @@ -836,7 +872,7 @@ content += "nonce=12345&"; content += "account_id=not_real_account&"; content += "disclosure_text_shown=false&"; - content += "is_account_auto_selected=false&"; + content += "is_identity_credential_auto_selected=false&"; content += "scope=calendar.readonly"; EXPECT_EQ(request.content, content);
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 47cad00..94a8fb9 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -222,8 +222,9 @@ {wf::EnableDocumentPolicyNegotiation, raw_ref(features::kDocumentPolicyNegotiation)}, {wf::EnableFedCm, raw_ref(features::kFedCm), kSetOnlyIfOverridden}, - {wf::EnableFedCmAccountAutoSelectedFlag, - raw_ref(features::kFedCmAccountAutoSelectedFlag), kSetOnlyIfOverridden}, + {wf::EnableFedCmIdentityCredentialAutoSelectedFlag, + raw_ref(features::kFedCmIdentityCredentialAutoSelectedFlag), + kSetOnlyIfOverridden}, {wf::EnableFedCmAuthz, raw_ref(features::kFedCmAuthz), kDefault}, {wf::EnableFedCmError, raw_ref(features::kFedCmError), kDefault}, {wf::EnableFedCmHostedDomain, raw_ref(features::kFedCmHostedDomain),
diff --git a/content/common/webid/identity_url_loader_throttle.cc b/content/common/webid/identity_url_loader_throttle.cc index 84c9f87..12872a75 100644 --- a/content/common/webid/identity_url_loader_throttle.cc +++ b/content/common/webid/identity_url_loader_throttle.cc
@@ -5,8 +5,10 @@ #include "content/common/webid/identity_url_loader_throttle.h" #include "base/containers/contains.h" +#include "base/functional/bind.h" #include "base/metrics/histogram_macros.h" #include "base/strings/string_split.h" +#include "base/task/sequenced_task_runner.h" #include "base/time/time.h" #include "content/common/features.h" #include "content/public/common/content_features.h" @@ -55,7 +57,17 @@ IdentityUrlLoaderThrottle::~IdentityUrlLoaderThrottle() = default; -void IdentityUrlLoaderThrottle::DetachFromCurrentSequence() {} +void IdentityUrlLoaderThrottle::DetachFromCurrentSequence() { + set_idp_status_cb_ = base::BindRepeating( + [](scoped_refptr<base::SequencedTaskRunner> task_runner, + SetIdpStatusCallback original_cb, const url::Origin& origin, + blink::mojom::IdpSigninStatus status) { + task_runner->PostTask( + FROM_HERE, base::BindOnce(std::move(original_cb), origin, status)); + }, + base::SequencedTaskRunner::GetCurrentDefault(), + std::move(set_idp_status_cb_)); +} void IdentityUrlLoaderThrottle::WillStartRequest( network::ResourceRequest* request,
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index a0d3c01..04d7d5d 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -347,10 +347,10 @@ // We enable it here by default to support use in origin trials. BASE_FEATURE(kFedCm, "FedCm", base::FEATURE_ENABLED_BY_DEFAULT); -// Enables usage of the FedCM AccountAutoSelectedFlag feature. ChromeStatus -// entry: https://chromestatus.com/feature/5384360374566912 -BASE_FEATURE(kFedCmAccountAutoSelectedFlag, - "FedCmAccountAutoSelectedFlag", +// Enables usage of the FedCM IdentityCredentialAutoSelectedFlag feature. +// ChromeStatus entry: https://chromestatus.com/feature/5384360374566912 +BASE_FEATURE(kFedCmIdentityCredentialAutoSelectedFlag, + "FedCmIdentityCredentialAutoSelectedFlag", base::FEATURE_ENABLED_BY_DEFAULT); // Enables usage of the FedCM Authz API.
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 270111aa..a10c794 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -89,7 +89,7 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kEnableServiceWorkersForChromeScheme); CONTENT_EXPORT BASE_DECLARE_FEATURE(kEnableServiceWorkersForChromeUntrusted); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCm); -CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmAccountAutoSelectedFlag); +CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmIdentityCredentialAutoSelectedFlag); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmAuthz); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmError); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmHostedDomain);
diff --git a/content/test/content_test_bundle_data.filelist b/content/test/content_test_bundle_data.filelist index d50eb34..4ef59a7 100644 --- a/content/test/content_test_bundle_data.filelist +++ b/content/test/content_test_bundle_data.filelist
@@ -5141,6 +5141,22 @@ data/attribution_reporting/aggregatable_report_goldens/latest/report_7_cleartext_payloads.json data/attribution_reporting/aggregatable_report_goldens/latest/report_8.json data/attribution_reporting/aggregatable_report_goldens/latest/report_8_cleartext_payloads.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_1.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_1_cleartext_payloads.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_2.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_2_cleartext_payloads.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_3.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_3_cleartext_payloads.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_4.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_4_cleartext_payloads.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_5.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_5_cleartext_payloads.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_6.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_6_cleartext_payloads.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_7.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_7_cleartext_payloads.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_8.json +data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_8_cleartext_payloads.json data/attribution_reporting/aggregatable_report_goldens/version_/private_key.txt data/attribution_reporting/aggregatable_report_goldens/version_/public_key.json data/attribution_reporting/aggregatable_report_goldens/version_/report_1.json
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_1.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_1.json new file mode 100644 index 0000000..f352782 --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_1.json
@@ -0,0 +1,11 @@ +{ + "aggregation_coordinator_origin": "https://publickeyservice.msmt.gcp.privacysandboxservices.com", + "aggregation_service_payloads": [ { + "debug_cleartext_payload": "omRkYXRhlKJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAaJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAGlvcGVyYXRpb25paGlzdG9ncmFt", + "key_id": "example_id", + "payload": "fWpWg8lf2AoAZLlp/564iWn+HnKYdKnjXY3Fl7I90yuo9uFArZsMudxNxHbaonIUnu/SmpWUHykFwL+mRSwzhKPvIM1NBcDoKG/05HPhrYuoKX4Ktis9obwcl409Vx1ZIcRqJA8lINdxYuDOEty5KtzDmUX8KDbPEpu+wh4YIhG4uEzRt1zZ7GV0dtb4KbtrrLcvATFAqVPAO0zc9Wi3K1YxgjKJrqXY+C89PABiu8mN8hmQc8OnhGu7cCmLy6hpL+ydeOgoJPB2KrnoPv/U7Hw9ylL1e1ukFDMMyhyr50rTcC7Up3S4K92DrJa1S5BBNF5zMcQ+zwx9Srd6pDd0M61feWxJU5NKo6ZRAaa2QCkqd6sSMXOgY52SZQlwCtByfTlhgo8CX1LGwVQmMm2TNnItySI7WXar857In6NzHACMHKOYEOvURihv6kvEewnCijPwVJx/3yEMLEHhERRner7juG6V8zBC88NcPh5Gj4UQT5MwJegl38xc6L7Jl2KgjUyEBOip2M+kVG80EWbOUKXCDpO1mQ0beJQ15zQE5uvcr30Hu/jyW0dewFUhPAKf568DLy7O2sx6qESLA5NwpRXd62b2E+bndAGuHuajMWrTLtlQNsfrEFblVwEud5znxO43iaG0mSxzJrBUTmDg0Su8dULVOwrZU/3BVJHum8LoEFWppxIsXQSH6JrsO0RkGmlQ3cfy3LuYjOJZlCsbTTfa1HzMKeK0gKhjJkzrN4JRl7mzTVq+PBqdI2A39EjxgxMWu7ZWNJjZ7dlfWgU7HbEd+5TDWpJG6vYYa2DK/K4fQGTJ1cbFZVzIiq/sewUEXHjXsAqoWfockNyRxBbJPHxe4+dfYK9HmAJSC5xrutnDyETU7SH4Ne7SMDv4I3nV84qehoxjzIkBS+bUegindDuG1mSA6oiDwneQDxJ0VfrJmm2eHiin26a78WFqTZ8BhSCd43oFn1WdqJ7mazIaOduiC9OaFqDRErJpiP/EQZN+jK8ybwNRrTlXhqIMjBv1EARlA5tNv+/sxXM8vCyFWao8hgRUrTxCRxfO" + } ], + "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://conversion.test\",\"debug_mode\":\"enabled\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486400\",\"source_registration_time\":\"1234483200\",\"version\":\"0.1\"}", + "source_debug_key": "123", + "trigger_debug_key": "456" +}
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_1_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_1_cleartext_payloads.json new file mode 100644 index 0000000..7bf83a4 --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_1_cleartext_payloads.json
@@ -0,0 +1,3 @@ +[ + "omRkYXRhlKJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAaJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAGlvcGVyYXRpb25paGlzdG9ncmFt" +] \ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_2.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_2.json new file mode 100644 index 0000000..d004bfd --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_2.json
@@ -0,0 +1,8 @@ +{ + "aggregation_coordinator_origin": "https://publickeyservice.msmt.gcp.privacysandboxservices.com", + "aggregation_service_payloads": [ { + "key_id": "example_id", + "payload": "KgkvFUBIbPQYX8T7U/dOqtKtcYVvsO2xRLv4eYt8D2/gWMRXSNYNBsLqwErzkLyr7JOjpafQeNOkuncyOOGg19vmS8JVc/5LalFjKoJAu1byBNDKy6jbisPw9yMFe52ctaJ4i2l3mUBMGROH/V/FYe3ZPdnoXvZL23eb3Eg2ii4g6FiXJAE3oxSRGxgUK3XlwYH1ATPVwSjc9rQPJ88H3GiuJVqTIc+Q/psiBddkC6fSG00UahI42sRV4l0iuf9R9EnChwy1FcFHCzRq4T8t66jhFSxP1kUHwSQMR2toy4g7FZm49F8JBFgxTdUey7fJ1fM/PSyCWu4gP1aY9R/kwh74Yp8tMp/zOGpQUG7UHJHXNmzhpJ+mNaZP0ryb8GuMrMxOsWJ/5N8ajGbFCu8ILOWVkC4eDoCQgfwQRYQKrxMaUlDfqrOrNJNjYvSRTbujtTeAYJCgB94T//3J6G3TCe+/Xx/II6ZOzC6aNylnfPQ0T25mKimuh8Mr5cT2YuXAB1ZL9hXOHJB7xeUAmdFigknwnMubaJsrXRX3L8vadctcg8UfX4a3IXg+0L0WwC5GjHtkA5f6qi2fcV+22XyNVi0ioYl5WQLMQ8rwc0MYtJbHdR/oGncnMwTemAdJrNFvXYIBbz2jtJ5OKhSzxMB3i4dLfNzudWJBBnt1Nwz2SC6eRSkwI+GtJgLa6bslE2B8K7qmz7lP5svxznSbcNzaCrS1CR26GvHSt/bSYPv/MYaTEl2fEsx/dAnkR9N/jquiC2VB79N3vHdCnR0UbhAkBcdHV0ukSbLARhShEEhIuEVLY6L9Ho74AbnCVVU5r9HmNGBrb1DEyecomcYPC3V7Pi05P8cjnQi6Dt+/LuxPXEgZMNxqZ8ZtgT4yqK7dT9+kdgQBoLisRikarJG1yEObpnPdPTAeI04EX10PdXU097DJuynJ9POadvhP3cBMSoMpQc1Kjcb6RaXjjpqNMV/dJGInMLca9STi8aI0cIzXFhUTXWK6sMSSudU+pKZdQ9bmReB4ah5mAjhVyxppasRDpiTw7pWo4BzsFwbH" + } ], + "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://conversion.test\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486400\",\"source_registration_time\":\"1234483200\",\"version\":\"0.1\"}" +}
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_2_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_2_cleartext_payloads.json new file mode 100644 index 0000000..7bf83a4 --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_2_cleartext_payloads.json
@@ -0,0 +1,3 @@ +[ + "omRkYXRhlKJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAaJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAGlvcGVyYXRpb25paGlzdG9ncmFt" +] \ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_3.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_3.json new file mode 100644 index 0000000..cd7b20a5 --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_3.json
@@ -0,0 +1,11 @@ +{ + "aggregation_coordinator_origin": "https://publickeyservice.msmt.gcp.privacysandboxservices.com", + "aggregation_service_payloads": [ { + "debug_cleartext_payload": "omRkYXRhlKJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAaJldmFsdWVEAAAABGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAA6JldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAGlvcGVyYXRpb25paGlzdG9ncmFt", + "key_id": "example_id", + "payload": "IN55GIz1NtrebRzCSuFesnpsiPnrMq9gd983wKW4m1R66J94fAL3XMjd856WpKnVnpcQXDG8OU2Bus9aq0wuYq5sOOpovlK2bo67P+aAEhGCnRnzhZ5R3T9bP69lDruPDMBwb/QXV55uGa4lSvt7rVscfAA6XaC4z6Y5juWpdP1ieqKvxkaAHX7Akp/s7wSqDk7kTVIvXb/z4d0TCW8schjRbcD27ScVsoerLjHeqfJDGZVtDh2vqn0unp+hdTsLkcKzhNbnxxng41Cqu20/JrD+HsQ4F+gZUpbcUUNDpDUXVPFsC9mpl/HRQ0hcmcA+TUsJ8gzvqrmBlxjOlZUOTPnXTmDhz47XTKtBGiisLFwZLZpblu/v6hjS7uz+QgPtFu+oL8c642uiXxlGMVUr8/nzOqBGymaV8lcvImVrUQbGd3fzzB335kuOVTg6wxIPpO4x6TNwVYAA3TbejiBhaY3vrf2Tfa/Zf8pklxe18SnjJ04QSnBeNZebs52XKPU9QZsj3I84sYaOJk9xUtBbMEoLyphR/zFxcm+JaV4DMK3foEer8pr0SxQ14ZkVQNYOusGyItp08WW/voW7Oib1R9BCFIAuViwZy3EWBcGeKQ9iG+ulYIZb1nH7bPINhvAnojf4RKipsDJdCCmAMoNVmvFyH/eGFmR0b7Z6Moy/ufFIvq0FU6AhYX0k9nEdID3G+A+rdGzul9ARFlIad7N1zp0wJp9/gYfPn2zdzFFpDw1/i6f3UN+qGmskSvX1Cc8f9W8LSbY8U6gzWE9V0FoNB/ZSmsFv0La/n6RjSlj1KbDs/cRFIO46FHvb8PsHj2CAHAQm4mog1C7BJXrDmBlckxyMG8aWeBOAN6pR7xRevZyVQqO6/nHcCF06G+X0EyTRFbQ84V7Xk76+mEgJMaC+Xt2VTE3noPeU4+kXWnd1cw/Wjhpf06R6p30c7c46SkFnlQgA7SgSWQjOMrjqbvQDJ5tn7oenloW8UG5DpD2Dcf2jsUmaafQiSNzhLLvYd0VU56KuOKyRLuuL3o+FBGkUy9RGKTGensXMlQhY" + } ], + "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://conversion.test\",\"debug_mode\":\"enabled\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486500\",\"source_registration_time\":\"1234483200\",\"version\":\"0.1\"}", + "source_debug_key": "123", + "trigger_debug_key": "456" +}
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_3_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_3_cleartext_payloads.json new file mode 100644 index 0000000..69c8b88 --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_3_cleartext_payloads.json
@@ -0,0 +1,3 @@ +[ + "omRkYXRhlKJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAaJldmFsdWVEAAAABGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAA6JldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAGlvcGVyYXRpb25paGlzdG9ncmFt" +] \ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_4.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_4.json new file mode 100644 index 0000000..5d7cfb7 --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_4.json
@@ -0,0 +1,8 @@ +{ + "aggregation_coordinator_origin": "https://publickeyservice.msmt.gcp.privacysandboxservices.com", + "aggregation_service_payloads": [ { + "key_id": "example_id", + "payload": "Wyln0B1iq+MFr1c7nfZk+Ld/V3+NS+i/LQsfc/fWpFwWvC+VIpV8oZixL2437WX9dpqlf3pDCuug517u38kgnm08pLREujyenwmJlZvl1gzWcQlmq7zK9zc/gPvGp37dQquV3WtQSBq6o47Rcsc9nixqK1G+MrJbwLuEp4OD1htQtA5oh3lg5QnyMJHI/SZi9ybn43UROw16fNxUG4Kb2wa2RndjNLIW/OiKIXachyP2qgZ7CRM/6m9vWPK2OpRRtAewoySNftHb9dEUPnP5l7hBSd1oU/2cOOh3pc9xok0NvLtOXQBZ4D0Bem/50/736QoZCmts7n/3kfhUvAHh1SjLZoCY1QIAwwpzB2TiwCkUIzo3irM3Aqz/z5CN5HtmK5ijM6AXmF3CjgQG2Ev1nK+oDKmXT3tywZsbAdMJ1dNoNqndnS9rpKItsmLTlqTcWoRH/n8U8saG31u3miIzMCSeF552+F7VFnoBYknIrJtG74uihZnI1J/T12QN6hNy6uiYfTxEgFQq2jx1+7T4tyZruV8f6roAd6F2minzT/7e/9m5DT2OFwYrq1syI4KkRqYTGTfsGjGT2fX9EsQm2zm4z+S+ZwrJLvz+ecCdf+xOnifDvhtKVyAU51iCTB3ENE1slA3GIBcmLffrSU+Q4ctzFm7arOOfF8KhrrrRodASivzaqOw/xC1svolwYpv4epnU3IGq0FPbBKdrbHphxue0EP2v4Te8Vy4E2jNxDCVlW3WZ6ThCzo2Ooi2sVcTVhbWIeaUB9h7GRmMIzZoksLnWeXnNU0M8FGeOTif2OnALkP4G+AmwnLSa/JkqUozxfp1zyDKwQyAfmyGihrB9W/3kbiIGWWE2wjTGE06r7WR0+J2+VYckuTEMivQcTfu4vcrDVXW4N32D1tvaZjOnhhmqWXT0XTiAxSrmbfd5BqlcUP1Rj4L3/2Np0mNfPp0xXAyKocQECiNjzsYGUC222tIARPiNBlk6lPXurNOmvtEq3zdT5I40sKSt4qMhwIbh9C0d7mVY9LFHJRxuNH35kqsDNZHM5MiJrz0A" + } ], + "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://conversion.test\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486500\",\"source_registration_time\":\"1234483200\",\"version\":\"0.1\"}" +}
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_4_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_4_cleartext_payloads.json new file mode 100644 index 0000000..69c8b88 --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_4_cleartext_payloads.json
@@ -0,0 +1,3 @@ +[ + "omRkYXRhlKJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAaJldmFsdWVEAAAABGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAA6JldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAGlvcGVyYXRpb25paGlzdG9ncmFt" +] \ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_5.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_5.json new file mode 100644 index 0000000..dfa11d88 --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_5.json
@@ -0,0 +1,11 @@ +{ + "aggregation_coordinator_origin": "https://publickeyservice.msmt.gcp.privacysandboxservices.com", + "aggregation_service_payloads": [ { + "debug_cleartext_payload": "omRkYXRhlKJldmFsdWVEAAAD6GZidWNrZXRQ/////////////////////6JldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAGlvcGVyYXRpb25paGlzdG9ncmFt", + "key_id": "example_id", + "payload": "7+sSdnUs2HROcHnG4UoiC7m86JzIIXVe57ymYuWadix//+TyBGilyKsbPnZE2gCbq5jNTa8uAZPHdN3485VoDv2g5vEZYJJBofdz3c+5SonoFjgFITvhKi+QCBRHww89U4UGE0I008j3lmA0dozEbqlk6JfOava0biWX6s0dRv9zTV5CYxM5PP7DcjVRkaWt5HaSvXVTiYPJTUidHl5ggUDecTpRBA4QiJJqvdzd3ZjZe8ur15LI+BV0CU/cjPYf46M4BTrJmZ+Lk74GPSfxNSlB1tGjfCdlIl0C1NHWywAKM/VjXh1ageFXIEUJ8075r6ZQokK9AGk1hxZR7VcOFmlj2qfaiPdc9rPBmRpzhD1Ql5zgrDBQsK/k0oLGKB/+m1pAY21zKEVtridMianV9zu6kPvnCuY+yddwKjukGciCPztaahDQAvhrKd6qtQle6Oy5tFaQhoDhFRiq/x0/t925gVs6wrnbuwyQdqKqbv3KdTFoRWRYGCcGNjeETI+1C6yDwkVMmpii4ID3S3umTDd5bcEhRyXzPNK25AfDqz9kWMAvT1xX1jMWPS/Vsv1en/iJmyhtZsQH+YPgL78Ed8LRj79kKFLbo+Gxhvy3n9Mw0an4hl87flWS06MyByb3pmZEYjAiIxTjtTqh8VxP1R+FhktByRWMMwSiHvYdoA7C2I2IixJ77QIWnLE6Q1ViX5RuL+VY6TFikFdpFVHkzLpdzj8yGSVw5sWnLDf6ODUL1huRVzSJxqvwSiq10L0i1bumRt34esBy5SPgDl0okvQAnQZvpeoJ2PsxuVTRRCyFC7EWiKaMhFoDxNZp+xnCOb3S1XKiuycHC3ep84ggLKtZlzRDTebwDx/AwqTai77K9zYLFyvLq18zf0irAvpXoJFC7lqSbs2G7pntl5UqJ3jhhGJM5ezka8qSjRLbAghEiK0ndjrnareAIL8e8PWKBVpkK+YAW3qyKGp9PLhbxShLfgGu7qB8kI+sez80yp5OTrWs2rMLvjuHoFF9ays8HtipC7FM+AQX5UNo6P+tcuFSzaSftTpZQIIt" + } ], + "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://conversion.test\",\"debug_mode\":\"enabled\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486600\",\"source_registration_time\":\"1234483200\",\"version\":\"0.1\"}", + "source_debug_key": "123", + "trigger_debug_key": "456" +}
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_5_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_5_cleartext_payloads.json new file mode 100644 index 0000000..1746e844 --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_5_cleartext_payloads.json
@@ -0,0 +1,3 @@ +[ + "omRkYXRhlKJldmFsdWVEAAAD6GZidWNrZXRQ/////////////////////6JldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAGlvcGVyYXRpb25paGlzdG9ncmFt" +] \ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_6.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_6.json new file mode 100644 index 0000000..7a5b0e9e --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_6.json
@@ -0,0 +1,8 @@ +{ + "aggregation_coordinator_origin": "https://publickeyservice.msmt.gcp.privacysandboxservices.com", + "aggregation_service_payloads": [ { + "key_id": "example_id", + "payload": "F8uZu/YBLODVe39vICj1Jm/vjMN9Zn6WX71mFyA4nk0dyVY7Aha5/fZYUn4TWJRRkU+YVBL7Q3s5uGPrAEr5a5DQE7Kh7jhhOUxVYwgToQUpF5T7nxXrl13wiixD7gN2QuEwI0pCOuQ7PwmNKTF51uwWwJ9KtunJowQOsDTN8JYUJ9VpvURQShYJn2BO9D/mdBWw82NxhZbifA5LtcmZk9ydcjask5bAHH8WRvrWObllkaHX23MLn7Zw6E45rj8U/TD/8+5MvcMYSuDYGscCSVgfrujnVSHvLHTtY0hl2vhUhBv02j9RNqT0rLmy1o6ScXNQ4veI/aOmV7t0C2GY6DX8Yo5UwT5yyuMlvzrJJK1Sp0C7cXB6wZVcB2h3uX3L7i0Bu5d+vFxfObr1E4eHKb3qtgBZ6KC22cFq/Xa12pb0JrRhEhk/mcY6iNED+M2+t5CXSUkHZbJCs7Onx332nldfG6sBJDSJ0PGD+ZyShBIpeQVxMqjc5pimUT71tKagJAvjZdKvdgU/uzbQUiy3In0YWU0dMR9nKkKnJSfhek6SQxY3tlpQicgyl7iQj39CFKZa6FSQ/QHhzJyyi6RJNfPj1hycF3ZoW5pZT5tfUt3qa4J2cl7SAGr8LGHa96Q1g1ZEqp5xDJe/KrI9aWSjJeV9w5RucQ01yv8FfMLVQDb/Nqfo9YVU7Yc1S3l1Hu0io/QS7GCjy0p4p7zulEBbwFfDi5CBY3fx5latUsISpz/VyWheWaYvf4QhRCntBfH3eQDyE/R8CyL39YgLKo3tPpDkxREoyhfDb59UvOQvcDVLkeTiUU71kIrCX1fQUOoDKi3kRC+LO6miCrBnC3j+v9j4h5sODKqZR2xqiJFRxm4PfNp+mxh00hr5w/zH4ko0lbgxoVtqxYaUIa/s27ZGu8neCjyCr2ZelRLfIY9H3PwJLYRbxlHa1C0RTmCZr4lQvSw9ZnGew21+ifPqH+Uf4NMz94M0b8GFTiYtT+INPYqXoIoysB2FWZhKTjP69vthH7BxXYI9ZRCNmOaZe1NibyXEbluGD4cwE6Bg" + } ], + "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://conversion.test\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486600\",\"source_registration_time\":\"1234483200\",\"version\":\"0.1\"}" +}
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_6_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_6_cleartext_payloads.json new file mode 100644 index 0000000..1746e844 --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_6_cleartext_payloads.json
@@ -0,0 +1,3 @@ +[ + "omRkYXRhlKJldmFsdWVEAAAD6GZidWNrZXRQ/////////////////////6JldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAGlvcGVyYXRpb25paGlzdG9ncmFt" +] \ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_7.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_7.json new file mode 100644 index 0000000..2e145538 --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_7.json
@@ -0,0 +1,8 @@ +{ + "aggregation_coordinator_origin": "https://publickeyservice.msmt.gcp.privacysandboxservices.com", + "aggregation_service_payloads": [ { + "key_id": "example_id", + "payload": "hR9Peif1FVr1+QSK6lK5LxAGuJDIOoArZwo8nkcc7UcfLZf0BOy9tUS4A2smDniFyM/3EhZN+3oZQJjDNmiurcDy459pVma3SDFIyLfUbY+m7ekkupW7l34L2pxvE3fo65YvyJ4ypU26Lizw7yauYQOss/vW0hi410FKQG1wrr7dGCioosMPVJT6wiAFqUEwAfiy+7cr4ed+Mv+YWD6HCmtL+/Zszl93CDNjNJXifQapyD6qVpwSatmcgWVkSuUrgbfPqOiyZvUiUy4aLmYFo8vNHhQUFZYqWh0HiiiHeFbrr9re5y6Tb5pRSLTGkPF5+DHYZgtdsiepWPQ4MIIfLgzrp7l/3bDEjHCYm902mIA1LzhXLNb0VGv+0Z2PhZ+hBTfkejMyyeApfCPcZGimXlaoEG8eNgwPoJDWNriJZJQvta1zl2Xhow8opaFjtl991dcscN+AFE/Z+cYJbYYSTh91/+CONxT7kK3KlTdfc1bnep+3YnzMIdg4tnwQ+gukU/Gd7BrC/pA+g7y5ucQkmnwHrV8j3gKB5dkeYyPF5wpSG5sXLS/Q6DoduwTRMjPYr0rMa00kqyTl0IKjG77z18oZ9lGXGAd8LMTRaP4VTWr4Gn7nNyzmG1xqUQkx3Cj4eQIzC+/fM05nXbNmomKf+07OClrXdHYwiYd9fRTwJqzt4H1gZ3cfK+BNh7wQd5WHmGGeg2JVsofmK3RecM2V0QMO/Py0JGSY+lmRRxhHqLdhaDjWzG3GNTgYkWTQGD3nRAFbKJKObe4pYUnl6D68ogG0IKiJkddvEUImMFrvoafSxLraEVTOz0jyLDp4SIvbAT1qQpvPEYbqq2w7C5TBuGCiRWEASPaVsVeOkUgsx/8/b9C0SH/ikfUWQkPbX/4vXQl8YBGfetn0eowKlxd+Hr4cAd6isl9DTOrU5A/Y3GYhqDnZRAIz42Q0v/i5hQ+HoDBt0OVkcnH0Hq5bbE/NG1lM+FJrUTYgOF5i6VYDeszyQvkcC+aQN2XADikzOwavykg1mX1iIW/9Y67+ls5HX8zdAVJw30IwK12X" + } ], + "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://conversion.test\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486400\",\"source_registration_time\":\"0\",\"version\":\"0.1\"}" +}
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_7_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_7_cleartext_payloads.json new file mode 100644 index 0000000..4df1a92f --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_7_cleartext_payloads.json
@@ -0,0 +1,3 @@ +[ + "omRkYXRhlKJldmFsdWVEAAAAAWZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAGlvcGVyYXRpb25paGlzdG9ncmFt" +] \ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_8.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_8.json new file mode 100644 index 0000000..cd31966 --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_8.json
@@ -0,0 +1,10 @@ +{ + "aggregation_coordinator_origin": "https://publickeyservice.msmt.gcp.privacysandboxservices.com", + "aggregation_service_payloads": [ + { + "key_id": "example_id", + "payload": "tMmqsJU1UTaGzNSGdBjRosqjtb7anEOmmjQAqdSZ5UrmRClaxgsYYbrfWgg9pzZtJGPSAUgNGaiaUGJviyr9a5MSxuZMVidKy0u9FB7s6oMGvg8ZyD9O/fIMvtwbGg6PdKYvIo3hvghrXePMBQxXivVpWr/4zX2AGP5dWWGnJdM4RP3qah1INdmSjC2j6rufOqX2fh+X3ZNKOpoL4zP+bwJV/diw4UJQkUcl7a02T049tNNQ75NFfn8+NXYcNsCm8QJ5ZBxURF4jHsaHDAsBzoBu+kFxw6+2gCXp8PWaRVn3wrjSXjs1y/NLCqgpUchpVLVW31ORp9zJLvp+FK8bYe7pPIY+0usk4nLea3ou0Vj9lM5kMNU/bvQdLPBrt3L6Gm+gY+132ZZWKJv+GKzTIWupGYc6+1IX1nayll97DJKYvABuGol5fdz4dQkViZG5RDkPXrIl4yaZLu01NWiyHpEMH/lUvuefsgZ8nd3PzM9VCGcIX8I6lhlmbcDr5U/IQKuJ2joXcihJaLuyIGypkGIF4jPaKhuEhe1BSX5b3B/ufgLtqDAqtbwbkZ9J2PhyN6WosKTXDfbUSqUQhhGMPzOeMHgQeazzYIomqg9oZATV2EiDF7Ykp5/OIhsJOD4uB46KtiSZ57pHaeB+m5GXctgghXIxbl2aFvsk30lziVmcb6oczrtA29/H9DV1JDV8YZKL9U4N2ramopFb/tgQPA6Ke57c0I2lSH4Wed9wlVc57uLzLIC0zDAFYlLCnvM64e0E49vTlvyUEOIu1QMbdqS7W81pDTyc6bHXMY58ynTQh647mczv4n7d5rDC6MT2F00eAoNgccbNILEl41VCn1UHU0AA0YgNrqYHcHsWG73QiCUqApxUW2sYqFyPqxCJMlIixxtcMI14UN5CeGjsmvemapsVquuMj4toFC5cxx4ooKrtigc6wq6+azT+blFxwEdeRBgpu0LPkH8xyx4BCLf+GeVRF/nf5uoUTXUkMOfcUemmwmpI8ra/ef6FNHfgpR7KD76/j3/0w0jmF8+0dWs4ipSnubN93vwo" + } + ], + "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://conversion.test\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486400\",\"source_registration_time\":\"0\",\"version\":\"0.1\"}" +} \ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_8_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_8_cleartext_payloads.json new file mode 100644 index 0000000..8d917f6 --- /dev/null +++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_gcp_8_cleartext_payloads.json
@@ -0,0 +1,3 @@ +[ + "omRkYXRhlKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAGlvcGVyYXRpb25paGlzdG9ncmFt" +] \ No newline at end of file
diff --git a/docs/webui_build_configuration.md b/docs/webui_build_configuration.md index 219aa3e..ac66dbf 100644 --- a/docs/webui_build_configuration.md +++ b/docs/webui_build_configuration.md
@@ -159,7 +159,7 @@ shouldn't be passed to ts_library. All files that aren't imported with an absolute path (e.g. -`import {assert} from 'chrome://resources/js/assert_ts.js'; `) need to exist +`import {assert} from 'chrome://resources/js/assert.js'; `) need to exist inside the TypeScript root directory, at the expected location. For example, if foo.ts in the top level directory contains the import statement `import {Baz} from './bar/baz.js';`, then the folder structure when ts_library
diff --git a/headless/lib/browser/policy/headless_browser_policy_connector.cc b/headless/lib/browser/policy/headless_browser_policy_connector.cc index d69175ce..58783bd 100644 --- a/headless/lib/browser/policy/headless_browser_policy_connector.cc +++ b/headless/lib/browser/policy/headless_browser_policy_connector.cc
@@ -148,7 +148,7 @@ base::ThreadPool::CreateSequencedTaskRunner( {base::MayBlock(), base::TaskPriority::BEST_EFFORT}), policy::PolicyLoaderMac::GetManagedPolicyPath(bundle_id), - new MacPreferences(), bundle_id); + std::make_unique<MacPreferences>(), bundle_id); return std::make_unique<AsyncPolicyProvider>(GetSchemaRegistry(), std::move(loader)); #elif BUILDFLAG(IS_POSIX)
diff --git a/infra/config/generated/builders/ci/lacros-arm-generic-rel-skylab/properties.json b/infra/config/generated/builders/ci/lacros-arm-generic-rel-skylab/properties.json index c8d3311..dc34631 100644 --- a/infra/config/generated/builders/ci/lacros-arm-generic-rel-skylab/properties.json +++ b/infra/config/generated/builders/ci/lacros-arm-generic-rel-skylab/properties.json
@@ -47,6 +47,12 @@ "builder": "lacros-arm-generic-rel-skylab", "project": "chromium" } + ], + "mirroring_builder_group_and_names": [ + { + "builder": "lacros-arm-generic-rel-skylab", + "group": "tryserver.chromium.chromiumos" + } ] } },
diff --git a/infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab/properties.json b/infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab/properties.json index 463dd134..dd0b986c 100644 --- a/infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab/properties.json +++ b/infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab/properties.json
@@ -47,6 +47,12 @@ "builder": "lacros-arm64-generic-rel-skylab", "project": "chromium" } + ], + "mirroring_builder_group_and_names": [ + { + "builder": "lacros-arm64-generic-rel-skylab", + "group": "tryserver.chromium.chromiumos" + } ] } },
diff --git a/infra/config/generated/builders/try/lacros-arm-generic-rel-skylab/properties.json b/infra/config/generated/builders/try/lacros-arm-generic-rel-skylab/properties.json new file mode 100644 index 0000000..a6d862a2 --- /dev/null +++ b/infra/config/generated/builders/try/lacros-arm-generic-rel-skylab/properties.json
@@ -0,0 +1,68 @@ +{ + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "lacros-arm-generic-rel-skylab", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-chromiumos-archive", + "builder_group": "chromium.chromiumos", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb", + "mb_no_luci_auth" + ], + "build_config": "Release", + "config": "chromium", + "target_arch": "arm", + "target_bits": 32, + "target_cros_boards": [ + "arm-generic" + ], + "target_platform": "chromeos" + }, + "legacy_gclient_config": { + "apply_configs": [ + "chromeos", + "checkout_lacros_sdk" + ], + "config": "chromium" + }, + "skylab_upload_location": { + "gs_bucket": "chromium-ci-skylab" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "lacros-arm-generic-rel-skylab", + "project": "chromium" + } + ] + } + }, + "$build/reclient": { + "instance": "rbe-chromium-untrusted", + "jobs": 150, + "metrics_project": "chromium-reclient-metrics", + "scandeps_server": true + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "tryserver.chromium.chromiumos", + "recipe": "chromium_trybot" +} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/lacros-arm64-generic-rel-skylab/properties.json b/infra/config/generated/builders/try/lacros-arm64-generic-rel-skylab/properties.json new file mode 100644 index 0000000..0a6cdd12 --- /dev/null +++ b/infra/config/generated/builders/try/lacros-arm64-generic-rel-skylab/properties.json
@@ -0,0 +1,68 @@ +{ + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "lacros-arm64-generic-rel-skylab", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-chromiumos-archive", + "builder_group": "chromium.chromiumos", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb", + "mb_no_luci_auth" + ], + "build_config": "Release", + "config": "chromium", + "target_arch": "arm", + "target_bits": 64, + "target_cros_boards": [ + "arm64-generic" + ], + "target_platform": "chromeos" + }, + "legacy_gclient_config": { + "apply_configs": [ + "chromeos", + "checkout_lacros_sdk" + ], + "config": "chromium" + }, + "skylab_upload_location": { + "gs_bucket": "chromium-ci-skylab" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "lacros-arm64-generic-rel-skylab", + "project": "chromium" + } + ] + } + }, + "$build/reclient": { + "instance": "rbe-chromium-untrusted", + "jobs": 150, + "metrics_project": "chromium-reclient-metrics", + "scandeps_server": true + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "tryserver.chromium.chromiumos", + "recipe": "chromium_trybot" +} \ No newline at end of file
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index 9985d09..71d4154 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -2928,10 +2928,18 @@ } } builders { + name: "chromium/try/lacros-arm-generic-rel-skylab" + includable_only: true + } + builders { name: "chromium/try/lacros-arm64-generic-rel" includable_only: true } builders { + name: "chromium/try/lacros-arm64-generic-rel-skylab" + includable_only: true + } + builders { name: "chromium/try/layout_test_leak_detection" includable_only: true }
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 84b7d8a..65cbb07e 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -39561,6 +39561,7 @@ use_invocation_timestamp: true } } + description_html: "This builder is mirrored by any of the following try builders:<br/><ul><li><a href=\"https://ci.chromium.org/p/chromium/builders/try/lacros-arm-generic-rel-skylab\">lacros-arm-generic-rel-skylab</a></li></ul>" shadow_builder_adjustments { service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" pool: "luci.chromium.try" @@ -39930,6 +39931,7 @@ use_invocation_timestamp: true } } + description_html: "This builder is mirrored by any of the following try builders:<br/><ul><li><a href=\"https://ci.chromium.org/p/chromium/builders/try/lacros-arm64-generic-rel-skylab\">lacros-arm64-generic-rel-skylab</a></li></ul>" shadow_builder_adjustments { service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" pool: "luci.chromium.try" @@ -80370,6 +80372,98 @@ description_html: "This builder mirrors the following CI builders:<br/><ul><li><a href=\"https://ci.chromium.org/p/chromium/builders/ci/lacros-arm-generic-rel\">lacros-arm-generic-rel</a></li></ul>" } builders { + name: "lacros-arm-generic-rel-skylab" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-22.04" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/lacros-arm-generic-rel-skylab/properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' + '}' + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "chromium_swarming.expose_merge_script_failures" + value: 100 + } + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + description_html: "This builder mirrors the following CI builders:<br/><ul><li><a href=\"https://ci.chromium.org/p/chromium/builders/ci/lacros-arm-generic-rel-skylab\">lacros-arm-generic-rel-skylab</a></li></ul>" + contact_team_email: "chrome-desktop-engprod@google.com" + } + builders { name: "lacros-arm64-generic-rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" @@ -80461,6 +80555,98 @@ description_html: "This builder mirrors the following CI builders:<br/><ul><li><a href=\"https://ci.chromium.org/p/chromium/builders/ci/lacros-arm64-generic-rel\">lacros-arm64-generic-rel</a></li></ul>" } builders { + name: "lacros-arm64-generic-rel-skylab" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-22.04" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/lacros-arm64-generic-rel-skylab/properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "tryserver.chromium.chromiumos",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' + '}' + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "chromium_swarming.expose_merge_script_failures" + value: 100 + } + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + description_html: "This builder mirrors the following CI builders:<br/><ul><li><a href=\"https://ci.chromium.org/p/chromium/builders/ci/lacros-arm64-generic-rel-skylab\">lacros-arm64-generic-rel-skylab</a></li></ul>" + contact_team_email: "chrome-desktop-engprod@google.com" + } + builders { name: "layout_test_leak_detection" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg index afbaae6..0bc792f 100644 --- a/infra/config/generated/luci/luci-milo.cfg +++ b/infra/config/generated/luci/luci-milo.cfg
@@ -3186,9 +3186,15 @@ name: "buildbucket/luci.chromium.try/lacros-arm-generic-rel" } builders { + name: "buildbucket/luci.chromium.try/lacros-arm-generic-rel-skylab" + } + builders { name: "buildbucket/luci.chromium.try/lacros-arm64-generic-rel" } builders { + name: "buildbucket/luci.chromium.try/lacros-arm64-generic-rel-skylab" + } + builders { name: "buildbucket/luci.chromium.try/linux-arm64-castos" } builders { @@ -17950,9 +17956,15 @@ name: "buildbucket/luci.chromium.try/lacros-arm-generic-rel" } builders { + name: "buildbucket/luci.chromium.try/lacros-arm-generic-rel-skylab" + } + builders { name: "buildbucket/luci.chromium.try/lacros-arm64-generic-rel" } builders { + name: "buildbucket/luci.chromium.try/lacros-arm64-generic-rel-skylab" + } + builders { name: "buildbucket/luci.chromium.try/layout_test_leak_detection" } builders { @@ -19080,9 +19092,15 @@ name: "buildbucket/luci.chromium.try/lacros-arm-generic-rel" } builders { + name: "buildbucket/luci.chromium.try/lacros-arm-generic-rel-skylab" + } + builders { name: "buildbucket/luci.chromium.try/lacros-arm64-generic-rel" } builders { + name: "buildbucket/luci.chromium.try/lacros-arm64-generic-rel-skylab" + } + builders { name: "buildbucket/luci.chromium.try/linux-cfm-rel" } builders {
diff --git a/infra/config/generated/testing/test_suites.pyl b/infra/config/generated/testing/test_suites.pyl index d755861..9d75ca04 100644 --- a/infra/config/generated/testing/test_suites.pyl +++ b/infra/config/generated/testing/test_suites.pyl
@@ -4220,7 +4220,7 @@ '--test-launcher-filter-file=../../testing/buildbot/filters/accessibility-linux.browser_tests.filter', ], 'swarming': { - 'shards': 8, + 'shards': 20, }, }, 'content_browsertests': { @@ -4249,7 +4249,7 @@ 'linux_lacros_chrome_browsertests_version_skew': { 'lacros_chrome_browsertests_run_in_series': { 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter', + '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter', ], 'swarming': { 'shards': 2, @@ -4261,7 +4261,7 @@ 'interactive_ui_tests': { 'test': 'interactive_ui_tests', 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter', + '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter', ], 'swarming': { 'shards': 3,
diff --git a/infra/config/generated/testing/variants.pyl b/infra/config/generated/testing/variants.pyl index ac4b64e..a9725b2 100644 --- a/infra/config/generated/testing/variants.pyl +++ b/infra/config/generated/testing/variants.pyl
@@ -70,16 +70,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'identifier': 'Lacros version skew testing ash canary', - 'description': 'Run with ash-chrome version 120.0.6062.0', + 'description': 'Run with ash-chrome version 120.0.6063.0', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6062.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6063.0/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v120.0.6062.0', - 'revision': 'version:120.0.6062.0', + 'location': 'lacros_version_skew_tests_v120.0.6063.0', + 'revision': 'version:120.0.6063.0', }, ], },
diff --git a/infra/config/subprojects/chromium/ci/chromium.chromiumos.star b/infra/config/subprojects/chromium/ci/chromium.chromiumos.star index aeb402d0..49cf1f5 100644 --- a/infra/config/subprojects/chromium/ci/chromium.chromiumos.star +++ b/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
@@ -504,6 +504,7 @@ ci.builder( name = "lacros-arm-generic-rel-skylab", + branch_selector = branches.selector.CROS_BRANCHES, builder_spec = builder_config.builder_spec( gclient_config = builder_config.gclient_config( config = "chromium", @@ -538,6 +539,7 @@ ci.builder( name = "lacros-arm64-generic-rel-skylab", + branch_selector = branches.selector.CROS_BRANCHES, builder_spec = builder_config.builder_spec( gclient_config = builder_config.gclient_config( config = "chromium",
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star index 0e49b10..f61c56b 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
@@ -177,6 +177,16 @@ ) try_.builder( + name = "lacros-arm-generic-rel-skylab", + branch_selector = branches.selector.CROS_BRANCHES, + mirrors = [ + "ci/lacros-arm-generic-rel-skylab", + ], + contact_team_email = "chrome-desktop-engprod@google.com", + main_list_view = "try", +) + +try_.builder( name = "lacros-arm64-generic-rel", branch_selector = branches.selector.CROS_BRANCHES, mirrors = [ @@ -186,6 +196,16 @@ ) try_.builder( + name = "lacros-arm64-generic-rel-skylab", + branch_selector = branches.selector.CROS_BRANCHES, + mirrors = [ + "ci/lacros-arm64-generic-rel-skylab", + ], + contact_team_email = "chrome-desktop-engprod@google.com", + main_list_view = "try", +) + +try_.builder( name = "linux-chromeos-compile-dbg", branch_selector = branches.selector.CROS_BRANCHES, mirrors = [
diff --git a/infra/config/targets/basic_suites.star b/infra/config/targets/basic_suites.star index 0bc537e..91c6afd6d 100644 --- a/infra/config/targets/basic_suites.star +++ b/infra/config/targets/basic_suites.star
@@ -4962,7 +4962,7 @@ "--test-launcher-filter-file=../../testing/buildbot/filters/accessibility-linux.browser_tests.filter", ], swarming = targets.swarming( - shards = 8, + shards = 20, ), ), "content_browsertests": targets.legacy_test_config( @@ -4997,7 +4997,7 @@ tests = { "lacros_chrome_browsertests_run_in_series": targets.legacy_test_config( args = [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", ], swarming = targets.swarming( shards = 2, @@ -5012,7 +5012,7 @@ "interactive_ui_tests": targets.legacy_test_config( test = "interactive_ui_tests", args = [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", ], swarming = targets.swarming( shards = 3,
diff --git a/infra/config/targets/lacros-version-skew-variants.json b/infra/config/targets/lacros-version-skew-variants.json index 3cd7dc8..74d3dd8 100644 --- a/infra/config/targets/lacros-version-skew-variants.json +++ b/infra/config/targets/lacros-version-skew-variants.json
@@ -1,16 +1,16 @@ { "LACROS_VERSION_SKEW_CANARY": { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6062.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6063.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 120.0.6062.0", + "description": "Run with ash-chrome version 120.0.6063.0", "identifier": "Lacros version skew testing ash canary", "swarming": { "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v120.0.6062.0", - "revision": "version:120.0.6062.0" + "location": "lacros_version_skew_tests_v120.0.6063.0", + "revision": "version:120.0.6063.0" } ] }
diff --git a/internal b/internal index 7056b58b..878ff7e 160000 --- a/internal +++ b/internal
@@ -1 +1 @@ -Subproject commit 7056b58bd3f5af3896df93abd40a24e7fb713edc +Subproject commit 878ff7e60356f58c1ce23f1b7b4d520e3b4c17ed
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 02852a9..f375c3e 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1768,6 +1768,9 @@ <message name="IDS_IOS_KEYBOARD_VOICE_SEARCH" desc="Title for the Voice Search keyboard shortcut in the discoverability." meaning="Used as a command title in the iPad command menu."> Voice Search </message> + <message name="IDS_IOS_LENS_KEYBOARD_IPH_TEXT" desc="Text the IPH for the Lens button in the keyboard."> + You can search images and what you see. + </message> <message name="IDS_IOS_MAGIC_STACK_SEE_MORE" desc="The See More button in Magic Stack modules to show a detailed view. [Length: 10em]"> See More </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_LENS_KEYBOARD_IPH_TEXT.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_LENS_KEYBOARD_IPH_TEXT.png.sha1 new file mode 100644 index 0000000..00c609c --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_LENS_KEYBOARD_IPH_TEXT.png.sha1
@@ -0,0 +1 @@ +ca79caca18065ca3783ba10ea932b18d24ce46a8 \ No newline at end of file
diff --git a/ios/chrome/browser/default_browser/model/utils.h b/ios/chrome/browser/default_browser/model/utils.h index 16a49ea..2c5ad06d4 100644 --- a/ios/chrome/browser/default_browser/model/utils.h +++ b/ios/chrome/browser/default_browser/model/utils.h
@@ -347,6 +347,9 @@ // Records given promo stats for "Appear" action into UMA histograms. void RecordPromoStatsToUMAForAppear(PromoStatistics* promo_stats); +// Records stats related to promo display to UMA histograms. +void RecordPromoDisplayStatsToUMA(); + // Logs browser launched for default browser promo trigger criteria experiment // stats to NSUserDefaults. `LogBrowserIndirectlylaunched` and // `LogBrowserLaunched` will have overlap.
diff --git a/ios/chrome/browser/default_browser/model/utils.mm b/ios/chrome/browser/default_browser/model/utils.mm index 757fdbb..8ad6c549a 100644 --- a/ios/chrome/browser/default_browser/model/utils.mm +++ b/ios/chrome/browser/default_browser/model/utils.mm
@@ -1214,6 +1214,18 @@ RecordPromoStatsToUMAForActionString(promo_stats, kAppearAction); } +void RecordPromoDisplayStatsToUMA() { + base::UmaHistogramCounts100( + "IOS.DefaultBrowserPromo.DaysSinceLastPromoInteraction", + NumDaysSincePromoInteraction()); + base::UmaHistogramCounts100( + "IOS.DefaultBrowserPromo.GenericPromoDisplayCount", + GenericPromoInteractionCount()); + base::UmaHistogramCounts100( + "IOS.DefaultBrowserPromo.TailoredPromoDisplayCount", + TailoredPromoInteractionCount()); +} + void LogBrowserLaunched(bool is_cold_start) { if (!IsDefaultBrowserTriggerCriteraExperimentEnabled()) { CleanupStorageForTriggerExperiment();
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 9ad03adc..4156ca2a 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -801,11 +801,6 @@ flag_descriptions::kOmniboxReportSearchboxStatsName, flag_descriptions::kOmniboxReportSearchboxStatsDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(omnibox::kReportSearchboxStats)}, - {"omnibox-fuzzy-url-suggestions", - flag_descriptions::kOmniboxFuzzyUrlSuggestionsName, - flag_descriptions::kOmniboxFuzzyUrlSuggestionsDescription, - flags_ui::kOsIos, - FEATURE_VALUE_TYPE(omnibox::kOmniboxFuzzyUrlSuggestions)}, {"start-surface", flag_descriptions::kStartSurfaceName, flag_descriptions::kStartSurfaceDescription, flags_ui::kOsIos, FEATURE_WITH_PARAMS_VALUE_TYPE(kStartSurface,
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 6a04c668..b23fd42e 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -701,10 +701,6 @@ const char kNTPViewHierarchyRepairDescription[] = "Checks if NTP view hierarchy is broken and fixes it if necessary."; -const char kOmniboxFuzzyUrlSuggestionsName[] = "Omnibox Fuzzy URL Suggestions"; -const char kOmniboxFuzzyUrlSuggestionsDescription[] = - "Enables URL suggestions for inputs that may contain typos."; - const char kOmniboxGroupingFrameworkForZPSName[] = "Omnibox Grouping Framework for ZPS"; const char kOmniboxGroupingFrameworkForZPSDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index 3ddb5e31..2b94a8f 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -615,10 +615,6 @@ extern const char kOmniboxFocusTriggersSRPZeroSuggestName[]; extern const char kOmniboxFocusTriggersSRPZeroSuggestDescription[]; -// Title and description for fuzzy URL suggestions feature. -extern const char kOmniboxFuzzyUrlSuggestionsName[]; -extern const char kOmniboxFuzzyUrlSuggestionsDescription[]; - // Title and description for the flag to enable Omnibox HTTPS upgrades for // schemeless navigations. extern const char kOmniboxHttpsUpgradesName[];
diff --git a/ios/chrome/browser/shared/ui/util/layout_guide_names.h b/ios/chrome/browser/shared/ui/util/layout_guide_names.h index dcdf087..e5d4dd16 100644 --- a/ios/chrome/browser/shared/ui/util/layout_guide_names.h +++ b/ios/chrome/browser/shared/ui/util/layout_guide_names.h
@@ -52,5 +52,8 @@ extern GuideName* const kTabGridBottomToolbarGuide; // A guide that is constrained to match the frame of the first Autofill result. extern GuideName* const kAutofillFirstSuggestionGuide; +// A guide that is constrained to match the frame of the Lens button in the +// omnibox keyboard accessory view. +extern GuideName* const kLensKeyboardButtonGuide; #endif // IOS_CHROME_BROWSER_SHARED_UI_UTIL_LAYOUT_GUIDE_NAMES_H_
diff --git a/ios/chrome/browser/shared/ui/util/layout_guide_names.mm b/ios/chrome/browser/shared/ui/util/layout_guide_names.mm index 25f7e1c..742a51d 100644 --- a/ios/chrome/browser/shared/ui/util/layout_guide_names.mm +++ b/ios/chrome/browser/shared/ui/util/layout_guide_names.mm
@@ -20,3 +20,4 @@ GuideName* const kTabGridBottomToolbarGuide = @"kTabGridBottomToolbarGuide"; GuideName* const kAutofillFirstSuggestionGuide = @"kAutofillFirstSuggestionGuide"; +GuideName* const kLensKeyboardButtonGuide = @"kLensKeyboardButtonGuide";
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm index c3705fd..a5302f1 100644 --- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm +++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -872,9 +872,6 @@ _urlLoadingNotifierBrowserAgent = UrlLoadingNotifierBrowserAgent::FromBrowser(self.browser); - _toolbarCoordinator = - [[ToolbarCoordinator alloc] initWithBrowser:self.browser]; - feature_engagement::Tracker* engagementTracker = feature_engagement::TrackerFactory::GetForBrowserState(browserState); HostContentSettingsMap* settingsMap = @@ -920,6 +917,10 @@ [_dispatcher startDispatchingToTarget:_bubblePresenter forProtocol:@protocol(HelpCommands)]; + _toolbarCoordinator = + [[ToolbarCoordinator alloc] initWithBrowser:self.browser]; + _toolbarCoordinator.bubblePresenter = _bubblePresenter; + _toolbarAccessoryPresenter = [[ToolbarAccessoryPresenter alloc] initWithIsIncognito:browserState->IsOffTheRecord()]; _toolbarAccessoryPresenter.toolbarLayoutGuide =
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.h b/ios/chrome/browser/ui/bubble/bubble_presenter.h index 142be1b..a31ec03 100644 --- a/ios/chrome/browser/ui/bubble/bubble_presenter.h +++ b/ios/chrome/browser/ui/bubble/bubble_presenter.h
@@ -80,6 +80,10 @@ // the item on the current website. - (void)presentPriceNotificationsWhileBrowsingTipBubble; +// Presents a help bubble to inform the user that they can tap the Lens +// button in the omnibox keyboard to search with their camera. +- (void)presentLensKeyboardTipBubble; + @end #endif // IOS_CHROME_BROWSER_UI_BUBBLE_BUBBLE_PRESENTER_H_
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.mm b/ios/chrome/browser/ui/bubble/bubble_presenter.mm index b8adb98..b00b2a6 100644 --- a/ios/chrome/browser/ui/bubble/bubble_presenter.mm +++ b/ios/chrome/browser/ui/bubble/bubble_presenter.mm
@@ -74,6 +74,8 @@ BubbleViewControllerPresenter* whatsNewBubblePresenter; @property(nonatomic, strong) BubbleViewControllerPresenter* priceNotificationsWhileBrowsingBubbleTipPresenter; +@property(nonatomic, strong) + BubbleViewControllerPresenter* lensKeyboardPresenter; @property(nonatomic, assign) WebStateList* webStateList; @property(nonatomic, assign) feature_engagement::Tracker* engagementTracker; @property(nonatomic, assign) HostContentSettingsMap* settingsMap; @@ -147,6 +149,7 @@ [self.followWhileBrowsingBubbleTipPresenter dismissAnimated:NO]; [self.priceNotificationsWhileBrowsingBubbleTipPresenter dismissAnimated:NO]; [self.whatsNewBubblePresenter dismissAnimated:NO]; + [self.lensKeyboardPresenter dismissAnimated:NO]; [self.defaultPageModeTipBubblePresenter dismissAnimated:NO]; } @@ -299,6 +302,32 @@ self.priceNotificationsWhileBrowsingBubbleTipPresenter = presenter; } +- (void)presentLensKeyboardTipBubble { + if (![self canPresentBubbleWithCheckTabScrolledToTop:NO]) { + return; + } + + BubbleArrowDirection arrowDirection = BubbleArrowDirectionDown; + NSString* text = l10n_util::GetNSString(IDS_IOS_LENS_KEYBOARD_IPH_TEXT); + CGPoint lensButtonAnchor = [self anchorPointToGuide:kLensKeyboardButtonGuide + direction:arrowDirection]; + + BubbleViewControllerPresenter* presenter = [self + presentBubbleForFeature:feature_engagement::kIPHiOSLensKeyboardFeature + direction:arrowDirection + alignment:BubbleAlignmentTopOrLeading + text:text + voiceOverAnnouncement:text + anchorPoint:lensButtonAnchor + presentAction:nil + dismissAction:nil]; + if (!presenter) { + return; + } + + self.lensKeyboardPresenter = presenter; +} + #pragma mark - Private // Convenience method that calls -presentBubbleForFeature with default param
diff --git a/ios/chrome/browser/ui/default_promo/default_browser_promo_coordinator.mm b/ios/chrome/browser/ui/default_promo/default_browser_promo_coordinator.mm index 951d322..4bf6b9a 100644 --- a/ios/chrome/browser/ui/default_promo/default_browser_promo_coordinator.mm +++ b/ios/chrome/browser/ui/default_promo/default_browser_promo_coordinator.mm
@@ -137,6 +137,9 @@ // Records that a default browser promo has been shown. - (void)recordDefaultBrowserPromoShown { + // Record the current state before updating the local storage. + RecordPromoDisplayStatsToUMA(); + base::RecordAction( base::UserMetricsAction("IOS.DefaultBrowserFullscreenPromo.Impression")); base::UmaHistogramEnumeration("IOS.DefaultBrowserPromo.Shown",
diff --git a/ios/chrome/browser/ui/default_promo/tailored_promo_coordinator.mm b/ios/chrome/browser/ui/default_promo/tailored_promo_coordinator.mm index 3ee4cd51..20184c1 100644 --- a/ios/chrome/browser/ui/default_promo/tailored_promo_coordinator.mm +++ b/ios/chrome/browser/ui/default_promo/tailored_promo_coordinator.mm
@@ -152,6 +152,9 @@ // Records that a default browser promo has been shown. - (void)recordDefaultBrowserPromoShown { + // Record the current state before updating the local storage. + RecordPromoDisplayStatsToUMA(); + RecordAction( UserMetricsAction("IOS.DefaultBrowserPromo.TailoredFullscreen.Appear")); base::UmaHistogramEnumeration("IOS.DefaultBrowserPromo.Shown",
diff --git a/ios/chrome/browser/ui/default_promo/video_default_browser_promo_coordinator.mm b/ios/chrome/browser/ui/default_promo/video_default_browser_promo_coordinator.mm index 3b5fd2f..5ec89b29 100644 --- a/ios/chrome/browser/ui/default_promo/video_default_browser_promo_coordinator.mm +++ b/ios/chrome/browser/ui/default_promo/video_default_browser_promo_coordinator.mm
@@ -180,6 +180,9 @@ // Records that a default browser promo has been shown. - (void)recordVideoDefaultBrowserPromoShown { + // Record the current state before updating the local storage. + RecordPromoDisplayStatsToUMA(); + LogFullscreenDefaultBrowserPromoDisplayed(); RecordAction(UserMetricsAction("IOS.DefaultBrowserVideoPromo.Appear"));
diff --git a/ios/chrome/browser/ui/lens/BUILD.gn b/ios/chrome/browser/ui/lens/BUILD.gn index a586da14..5e8428cb 100644 --- a/ios/chrome/browser/ui/lens/BUILD.gn +++ b/ios/chrome/browser/ui/lens/BUILD.gn
@@ -13,10 +13,12 @@ ":lens_availability", ":lens_entrypoint", "//base", + "//components/feature_engagement/public", "//components/lens", "//components/prefs", "//components/search_engines", "//ios/chrome/app/strings:ios_strings_grit", + "//ios/chrome/browser/feature_engagement", "//ios/chrome/browser/intents:intents_donation_helper", "//ios/chrome/browser/search_engines:template_url_service_factory", "//ios/chrome/browser/shared/coordinator/chrome_coordinator",
diff --git a/ios/chrome/browser/ui/lens/lens_coordinator.mm b/ios/chrome/browser/ui/lens/lens_coordinator.mm index c8da93f..7d6e780 100644 --- a/ios/chrome/browser/ui/lens/lens_coordinator.mm +++ b/ios/chrome/browser/ui/lens/lens_coordinator.mm
@@ -5,10 +5,14 @@ #import "ios/chrome/browser/ui/lens/lens_coordinator.h" #import "base/strings/sys_string_conversions.h" +#import "components/feature_engagement/public/event_constants.h" +#import "components/feature_engagement/public/feature_constants.h" +#import "components/feature_engagement/public/tracker.h" #import "components/lens/lens_metrics.h" #import "components/prefs/pref_service.h" #import "components/search_engines/template_url.h" #import "components/search_engines/template_url_service.h" +#import "ios/chrome/browser/feature_engagement/tracker_factory.h" #import "ios/chrome/browser/intents/intents_donation_helper.h" #import "ios/chrome/browser/search_engines/template_url_service_factory.h" #import "ios/chrome/browser/shared/model/application_context/application_context.h" @@ -70,6 +74,9 @@ // TemplateURL used to get the search engine. @property(nonatomic, assign) TemplateURLService* templateURLService; +// Feature Engagement Tracker used to handle promo events. +@property(nonatomic, assign) feature_engagement::Tracker* tracker; + @end @implementation LensCoordinator { @@ -121,8 +128,13 @@ base::ScopedObservation<web::WebState, web::WebStateObserver>>( _webStateObserverBridge.get()); - self.templateURLService = ios::TemplateURLServiceFactory::GetForBrowserState( - self.browser->GetBrowserState()); + ChromeBrowserState* browserState = browser->GetBrowserState(); + DCHECK(browserState); + + self.templateURLService = + ios::TemplateURLServiceFactory::GetForBrowserState(browserState); + self.tracker = + feature_engagement::TrackerFactory::GetForBrowserState(browserState); self.loadingWebState = nil; self.lensWebPageLoadTriggeredFromInputSelection = NO; self.transitionAnimator = [[LensModalAnimator alloc] init]; @@ -140,6 +152,7 @@ self.transitionAnimator = nil; self.lensWebPageLoadTriggeredFromInputSelection = NO; self.templateURLService = nil; + self.tracker = nil; _webStateListObservation.reset(); _webStateObservation.reset(); @@ -191,6 +204,15 @@ configuration.ssoService = GetApplicationContext()->GetSSOService(); configuration.entrypoint = entrypoint; + // Mark IPHs as completed. + if (entrypoint == LensEntrypoint::Keyboard) { + feature_engagement::Tracker* featureTracker = self.tracker; + DCHECK(featureTracker); + featureTracker->NotifyEvent( + feature_engagement::events::kLensButtonKeyboardUsed); + featureTracker->Dismissed(feature_engagement::kIPHiOSLensKeyboardFeature); + } + if (!isIncognito) { AuthenticationService* authenticationService = AuthenticationServiceFactory::GetForBrowserState(browserState);
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.h b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.h index a14c975..40830f6 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.h +++ b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.h
@@ -10,6 +10,7 @@ #import "ios/chrome/browser/shared/public/commands/omnibox_commands.h" #import "ios/chrome/browser/ui/location_bar/location_bar_url_loader.h" +@class BubblePresenter; @protocol BrowserCoordinatorCommands; @protocol EditViewAnimatee; @protocol LocationBarAnimatee; @@ -31,6 +32,9 @@ @property(nonatomic, weak) id<OmniboxPopupPresenterDelegate> popupPresenterDelegate; +// Bubble presenter for displaying IPH bubbles relating to the toolbars. +@property(nonatomic, strong) BubblePresenter* bubblePresenter; + // Initializes this Coordinator with its `browser` and a nil base view // controller. - (instancetype)initWithBrowser:(Browser*)browser NS_DESIGNATED_INITIALIZER;
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm index ad49a6e..eb00e88b 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm +++ b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
@@ -192,6 +192,7 @@ self.omniboxCoordinator = [[OmniboxCoordinator alloc] initWithBaseViewController:nil browser:self.browser]; + self.omniboxCoordinator.bubblePresenter = self.bubblePresenter; self.omniboxCoordinator.locationBar = _locationBar.get(); self.omniboxCoordinator.presenterDelegate = self.popupPresenterDelegate; [self.omniboxCoordinator start];
diff --git a/ios/chrome/browser/ui/omnibox/BUILD.gn b/ios/chrome/browser/ui/omnibox/BUILD.gn index 2a30469..d4054f3 100644 --- a/ios/chrome/browser/ui/omnibox/BUILD.gn +++ b/ios/chrome/browser/ui/omnibox/BUILD.gn
@@ -156,6 +156,7 @@ "//ios/chrome/browser/shared/public/features:system_flags", "//ios/chrome/browser/shared/ui/symbols", "//ios/chrome/browser/shared/ui/util", + "//ios/chrome/browser/ui/bubble", "//ios/chrome/browser/ui/default_promo", "//ios/chrome/browser/ui/fullscreen", "//ios/chrome/browser/ui/lens:lens_entrypoint",
diff --git a/ios/chrome/browser/ui/omnibox/DEPS b/ios/chrome/browser/ui/omnibox/DEPS index 291eb167..eb3e284 100644 --- a/ios/chrome/browser/ui/omnibox/DEPS +++ b/ios/chrome/browser/ui/omnibox/DEPS
@@ -6,3 +6,9 @@ "+ios/chrome/browser/ui/ntp/metrics/home_metrics.h", "+ios/chrome/browser/ui/toolbar/public", ] + +specific_include_rules = { + "^omnibox_coordinator.mm": [ + "+ios/chrome/browser/ui/bubble/bubble_presenter.h", + ], +} \ No newline at end of file
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/BUILD.gn b/ios/chrome/browser/ui/omnibox/keyboard_assist/BUILD.gn index bd41bf2..a2d88010 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/BUILD.gn +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/BUILD.gn
@@ -33,6 +33,7 @@ "//ios/chrome/browser/shared/ui/elements", "//ios/chrome/browser/shared/ui/symbols", "//ios/chrome/browser/shared/ui/util", + "//ios/chrome/browser/ui/bubble", "//ios/chrome/browser/ui/lens:lens_availability", "//ios/chrome/browser/ui/lens:lens_entrypoint", "//ios/chrome/browser/ui/location_bar:constants",
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/DEPS b/ios/chrome/browser/ui/omnibox/keyboard_assist/DEPS index 2d9ce501..b2db44f0 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/DEPS +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/DEPS
@@ -1,3 +1,9 @@ include_rules = [ "+ios/chrome/browser/ui/lens", ] + +specific_include_rules = { + "^omnibox_keyboard_accessory_view.mm": [ + "+ios/chrome/browser/ui/bubble/bubble_presenter.h", + ], +}
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.h b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.h index 4b45d038..b07e6567 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.h +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.h
@@ -7,6 +7,7 @@ #import <UIKit/UIKit.h> +@class BubblePresenter; @protocol OmniboxAssistiveKeyboardDelegate; @class OmniboxKeyboardAccessoryView; class TemplateURLService; @@ -27,6 +28,7 @@ UITextField* textField, NSString* dotComTLD, id<OmniboxAssistiveKeyboardDelegate> delegate, - TemplateURLService* templateURLService); + TemplateURLService* templateURLService, + BubblePresenter* bubblePresenter); #endif // IOS_CHROME_BROWSER_UI_OMNIBOX_KEYBOARD_ASSIST_OMNIBOX_ASSISTIVE_KEYBOARD_VIEWS_H_
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.mm b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.mm index 443ba43a..84d3319 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.mm +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.mm
@@ -15,7 +15,8 @@ UITextField* textField, NSString* dotComTLD, id<OmniboxAssistiveKeyboardDelegate> delegate, - TemplateURLService* templateURLService) { + TemplateURLService* templateURLService, + BubblePresenter* bubblePresenter) { DCHECK(dotComTLD); NSArray<NSString*>* buttonTitles = @[ @":", @"-", @"/", dotComTLD ]; @@ -32,7 +33,8 @@ delegate:delegate pasteTarget:textField templateURLService:templateURLService - textField:textField]; + textField:textField + bubblePresenter:bubblePresenter]; [keyboardAccessoryView setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; [textField setInputAccessoryView:keyboardAccessoryView]; return keyboardAccessoryView;
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views_utils.mm b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views_utils.mm index ce94c127..16198796 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views_utils.mm +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views_utils.mm
@@ -6,7 +6,9 @@ #import "ios/chrome/browser/shared/ui/elements/extended_touch_target_button.h" #import "ios/chrome/browser/shared/ui/symbols/symbols.h" +#import "ios/chrome/browser/shared/ui/util/layout_guide_names.h" #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h" +#import "ios/chrome/browser/shared/ui/util/util_swift.h" #import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h" #import "ios/chrome/browser/ui/omnibox/omnibox_ui_features.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" @@ -99,6 +101,8 @@ if (useLens) { // Set up the camera button for Lens. delegate.lensButton = cameraButton; + [delegate.layoutGuideCenter referenceView:cameraButton + underName:kLensKeyboardButtonGuide]; UpdateLensButtonAppearance(cameraButton); [cameraButton addTarget:delegate action:@selector(keyboardAccessoryLensTapped)
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.h b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.h index 01416bf..6e814a34 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.h +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.h
@@ -9,6 +9,7 @@ #import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h" +@class BubblePresenter; class TemplateURLService; // Accessory View above the keyboard. @@ -24,6 +25,7 @@ pasteTarget:(id<UIPasteConfigurationSupporting>)pasteTarget templateURLService:(TemplateURLService*)templateURLService textField:(UITextField*)textField + bubblePresenter:(BubblePresenter*)bubblePresenter NS_DESIGNATED_INITIALIZER; - (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; @@ -35,6 +37,9 @@ // Google is the default search engine. @property(nonatomic, assign) TemplateURLService* templateURLService; +// Bubble presenter for displaying IPH bubbles relating to the NTP. +@property(nonatomic, strong) BubblePresenter* bubblePresenter; + @end #endif // IOS_CHROME_BROWSER_UI_OMNIBOX_KEYBOARD_ASSIST_OMNIBOX_KEYBOARD_ACCESSORY_VIEW_H_
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm index 9da736e..02cb7a72 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm
@@ -12,6 +12,7 @@ #import "ios/chrome/browser/shared/public/features/system_flags.h" #import "ios/chrome/browser/shared/ui/elements/extended_touch_target_button.h" #import "ios/chrome/browser/shared/ui/util/rtl_geometry.h" +#import "ios/chrome/browser/ui/bubble/bubble_presenter.h" #import "ios/chrome/browser/ui/lens/lens_availability.h" #import "ios/chrome/browser/ui/lens/lens_entrypoint.h" #import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.h" @@ -21,6 +22,14 @@ #import "ios/chrome/common/ui/util/constraints_ui_util.h" #import "ios/public/provider/chrome/browser/lens/lens_api.h" +namespace { + +// Delay between the time the view is shown, and the time the Lens button iph +// should be shown. +constexpr base::TimeDelta kLensButtonIPHDelay = base::Seconds(1); + +} // namespace + @interface OmniboxKeyboardAccessoryView () <SearchEngineObserving> @property(nonatomic, retain) NSArray<NSString*>* buttonTitles; @@ -54,7 +63,8 @@ delegate:(id<OmniboxAssistiveKeyboardDelegate>)delegate pasteTarget:(id<UIPasteConfigurationSupporting>)pasteTarget templateURLService:(TemplateURLService*)templateURLService - textField:(UITextField*)textField { + textField:(UITextField*)textField + bubblePresenter:(BubblePresenter*)bubblePresenter { self = [super initWithFrame:CGRectZero inputViewStyle:UIInputViewStyleKeyboard]; if (self) { @@ -65,6 +75,7 @@ self.translatesAutoresizingMaskIntoConstraints = NO; self.allowsSelfSizing = YES; self.templateURLService = templateURLService; + self.bubblePresenter = bubblePresenter; [self addSubviews]; } return self; @@ -236,6 +247,16 @@ lens_availability::CheckAndLogAvailabilityForLensEntryPoint( LensEntrypoint::Keyboard, [self isGoogleSearchEngine:self.templateURLService]); + + UIButton* lensButton = _delegate.lensButton; + if (lensButton) { + __weak __typeof(self) weakSelf = self; + base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask( + FROM_HERE, base::BindOnce(^{ + [weakSelf.bubblePresenter presentLensKeyboardTipBubble]; + }), + kLensButtonIPHDelay); + } } #pragma mark - Setters
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_coordinator.h b/ios/chrome/browser/ui/omnibox/omnibox_coordinator.h index 1e53748..69ae448 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_coordinator.h +++ b/ios/chrome/browser/ui/omnibox/omnibox_coordinator.h
@@ -8,6 +8,7 @@ #import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" class WebLocationBar; +@class BubblePresenter; @protocol EditViewAnimatee; @class OmniboxPopupCoordinator; @class OmniboxTextFieldIOS; @@ -31,6 +32,9 @@ /// Positioner for the popup. Has to be configured before calling `start`. @property(nonatomic, weak) id<OmniboxPopupPresenterDelegate> presenterDelegate; +// Bubble presenter for displaying IPH bubbles relating to the omnibox. +@property(nonatomic, strong) BubblePresenter* bubblePresenter; + // The view controller managed by this coordinator. The parent of this // coordinator is expected to add it to the responder chain. - (UIViewController*)managedViewController;
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm b/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm index 7be8174..03e69246 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm
@@ -31,6 +31,7 @@ #import "ios/chrome/browser/shared/public/commands/omnibox_commands.h" #import "ios/chrome/browser/shared/public/commands/qr_scanner_commands.h" #import "ios/chrome/browser/shared/public/features/features.h" +#import "ios/chrome/browser/ui/bubble/bubble_presenter.h" #import "ios/chrome/browser/ui/location_bar/location_bar_constants.h" #import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h" #import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views.h" @@ -159,7 +160,8 @@ self.browser->GetCommandDispatcher()); self.keyboardDelegate.omniboxTextField = self.textField; self.keyboardAccessoryView = ConfigureAssistiveKeyboardViews( - self.textField, kDotComTLD, self.keyboardDelegate, templateURLService); + self.textField, kDotComTLD, self.keyboardDelegate, templateURLService, + self.bubblePresenter); if (base::FeatureList::IsEnabled(omnibox::kZeroSuggestPrefetching)) { self.zeroSuggestPrefetchHelper = [[ZeroSuggestPrefetchHelper alloc]
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_coordinator.h b/ios/chrome/browser/ui/toolbar/toolbar_coordinator.h index 5135445..9e0b937 100644 --- a/ios/chrome/browser/ui/toolbar/toolbar_coordinator.h +++ b/ios/chrome/browser/ui/toolbar/toolbar_coordinator.h
@@ -13,6 +13,7 @@ #import "ios/chrome/browser/ui/toolbar/public/toolbar_coordinating.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_height_delegate.h" +@class BubblePresenter; @protocol OmniboxPopupPresenterDelegate; @protocol OmniboxFocusDelegate; @protocol SharingPositioner; @@ -34,6 +35,8 @@ popupPresenterDelegate; /// Delegate that handles the toolbars height. @property(nonatomic, weak) id<ToolbarHeightDelegate> toolbarHeightDelegate; +// Bubble presenter for displaying IPH bubbles relating to the toolbars. +@property(nonatomic, strong) BubblePresenter* bubblePresenter; /// Initializes this coordinator with its `browser` and a nil base view /// controller.
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_coordinator.mm b/ios/chrome/browser/ui/toolbar/toolbar_coordinator.mm index eb9d3ff..6fc0fda 100644 --- a/ios/chrome/browser/ui/toolbar/toolbar_coordinator.mm +++ b/ios/chrome/browser/ui/toolbar/toolbar_coordinator.mm
@@ -131,6 +131,7 @@ self.locationBarCoordinator = [[LocationBarCoordinator alloc] initWithBrowser:browser]; self.locationBarCoordinator.delegate = self.omniboxFocusDelegate; + self.locationBarCoordinator.bubblePresenter = self.bubblePresenter; self.locationBarCoordinator.popupPresenterDelegate = self.popupPresenterDelegate; [self.locationBarCoordinator start];
diff --git a/ios_internal b/ios_internal index a96082a..9fb0acc 160000 --- a/ios_internal +++ b/ios_internal
@@ -1 +1 @@ -Subproject commit a96082a751e2643f6253853554b37ce6234ffeae +Subproject commit 9fb0acc762ca7bef8428faf4278d1691a05a6401
diff --git a/media/audio/ios/audio_manager_ios.cc b/media/audio/ios/audio_manager_ios.cc index 1553444..78dcc24 100644 --- a/media/audio/ios/audio_manager_ios.cc +++ b/media/audio/ios/audio_manager_ios.cc
@@ -145,6 +145,19 @@ return true; } +float AudioManagerIOS::GetInputGain() { + return audio_session_manager_->GetInputGain(); +} + +bool AudioManagerIOS::SetInputGain(float volume) { + return audio_session_manager_->SetInputGain(volume); +} + +bool AudioManagerIOS::IsInputMuted() { + return audio_session_manager_->IsInputMuted(); +} + +// private AudioParameters AudioManagerIOS::GetPreferredOutputStreamParameters( const std::string& output_device_id, const AudioParameters& input_params) {
diff --git a/media/audio/ios/audio_manager_ios.h b/media/audio/ios/audio_manager_ios.h index 317eaf0..c51021a0 100644 --- a/media/audio/ios/audio_manager_ios.h +++ b/media/audio/ios/audio_manager_ios.h
@@ -78,6 +78,11 @@ AudioUnitElement element, size_t desired_buffer_size) override; + // Gain + float GetInputGain(); + bool SetInputGain(float volume); + bool IsInputMuted(); + protected: AudioParameters GetPreferredOutputStreamParameters( const std::string& output_device_id,
diff --git a/media/audio/ios/audio_session_manager_ios.h b/media/audio/ios/audio_session_manager_ios.h index 5eed1a9..1ed00e0 100644 --- a/media/audio/ios/audio_session_manager_ios.h +++ b/media/audio/ios/audio_session_manager_ios.h
@@ -24,6 +24,11 @@ std::string GetDefaultInputDeviceID(); int HardwareSampleRate(); + // Gain + float GetInputGain(); + bool SetInputGain(float volume); + bool IsInputMuted(); + private: void GetAudioInputDeviceInfo(media::AudioDeviceNames* device_names); void GetAudioOutputDeviceInfo(media::AudioDeviceNames* device_names);
diff --git a/media/audio/ios/audio_session_manager_ios.mm b/media/audio/ios/audio_session_manager_ios.mm index 471dfe2..f459b4e7 100644 --- a/media/audio/ios/audio_session_manager_ios.mm +++ b/media/audio/ios/audio_session_manager_ios.mm
@@ -4,6 +4,7 @@ #include "media/audio/ios/audio_session_manager_ios.h" +#import <AVFAudio/AVFAudio.h> #import <AVFoundation/AVFoundation.h> #import <Foundation/Foundation.h> @@ -15,7 +16,8 @@ AVAudioSession* audio_session = [AVAudioSession sharedInstance]; NSError* error = nil; - auto options = AVAudioSessionCategoryOptionAllowBluetooth | + auto options = AVAudioSessionCategoryOptionDefaultToSpeaker | + AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionAllowBluetoothA2DP | AVAudioSessionCategoryOptionMixWithOthers; [audio_session setCategory:AVAudioSessionCategoryPlayAndRecord @@ -37,12 +39,34 @@ } } - // Find the desired microphone - for (AVAudioSessionDataSourceDescription* source in builtInMic.dataSources) { - if ([source.orientation isEqual:AVAudioSessionOrientationFront]) { - [builtInMic setPreferredDataSource:source error:nil]; - [audio_session setPreferredInput:builtInMic error:nil]; - break; + [audio_session setPreferredInput:builtInMic error:nil]; + + AVAudioSessionPortDescription* preferredInput = + [audio_session preferredInput]; + if (preferredInput != nil) { + NSArray<AVAudioSessionDataSourceDescription*>* dataSources = + audio_session.preferredInput.dataSources; + AVAudioSessionDataSourceDescription* newDataSource = nil; + for (AVAudioSessionDataSourceDescription* dataSource in dataSources) { + if ([dataSource.orientation isEqual:AVAudioSessionOrientationFront]) { + newDataSource = dataSource; + break; + } + } + + if (newDataSource != nil) { + NSArray<NSString*>* supportedPolarPatterns = + newDataSource.supportedPolarPatterns; + if (supportedPolarPatterns != nil) { + BOOL hasStereo = [supportedPolarPatterns + containsObject:AVAudioSessionPolarPatternStereo]; + if (hasStereo) { + [newDataSource + setPreferredPolarPattern:AVAudioSessionPolarPatternStereo + error:nil]; + } + } + [preferredInput setPreferredDataSource:newDataSource error:nil]; } } @@ -113,6 +137,34 @@ return base::SysNSStringToUTF8([currentInput portName]); } +int AudioSessionManagerIOS::HardwareSampleRate() { + AVAudioSession* audio_session = [AVAudioSession sharedInstance]; + return static_cast<int>(audio_session.sampleRate); +} + +float AudioSessionManagerIOS::GetInputGain() { + AVAudioSession* audio_session = [AVAudioSession sharedInstance]; + return audio_session.inputGain; +} + +bool AudioSessionManagerIOS::SetInputGain(float volume) { + AVAudioSession* audio_session = [AVAudioSession sharedInstance]; + if ([audio_session isInputGainSettable] == YES) { + BOOL success = [audio_session setInputGain:volume error:nil]; + return success; + } + return false; +} + +bool AudioSessionManagerIOS::IsInputMuted() { + if (@available(iOS 17.0, *)) { + AVAudioApplication* audio_application = [AVAudioApplication sharedInstance]; + return audio_application.isInputMuted; + } + return false; +} + +// private void AudioSessionManagerIOS::GetAudioInputDeviceInfo( media::AudioDeviceNames* device_names) { AVAudioSession* audio_session = [AVAudioSession sharedInstance]; @@ -149,9 +201,4 @@ } } -int AudioSessionManagerIOS::HardwareSampleRate() { - AVAudioSession* audio_session = [AVAudioSession sharedInstance]; - return static_cast<int>(audio_session.sampleRate); -} - } // namespace media
diff --git a/media/audio/mac/audio_input_mac.cc b/media/audio/mac/audio_input_mac.cc index a075711..8ef0560 100644 --- a/media/audio/mac/audio_input_mac.cc +++ b/media/audio/mac/audio_input_mac.cc
@@ -168,17 +168,34 @@ } void PCMQueueInAudioInputStream::SetVolume(double volume) { +#if BUILDFLAG(IS_MAC) NOTIMPLEMENTED(); +#else + auto* manager = static_cast<AudioManagerIOS*>(client_); + if (manager) { + manager->SetInputGain(volume); + } +#endif } double PCMQueueInAudioInputStream::GetVolume() { +#if BUILDFLAG(IS_MAC) NOTIMPLEMENTED(); return 1.0; +#else + auto* manager = static_cast<AudioManagerIOS*>(client_); + return manager ? manager->GetInputGain() : 1.0; +#endif } bool PCMQueueInAudioInputStream::IsMuted() { +#if BUILDFLAG(IS_MAC) NOTIMPLEMENTED(); return false; +#else + auto* manager = static_cast<AudioManagerIOS*>(client_); + return manager ? manager->IsInputMuted() : false; +#endif } bool PCMQueueInAudioInputStream::SetAutomaticGainControl(bool enabled) {
diff --git a/media/gpu/test/video_decode_accelerator_perf_tests.cc b/media/gpu/test/video_decode_accelerator_perf_tests.cc index 7e4029f4..75eea55c 100644 --- a/media/gpu/test/video_decode_accelerator_perf_tests.cc +++ b/media/gpu/test/video_decode_accelerator_perf_tests.cc
@@ -6,6 +6,7 @@ #include <numeric> #include <vector> +#include "base/base_switches.h" #include "base/command_line.h" #include "base/files/file_util.h" #include "base/json/json_writer.h" @@ -472,10 +473,12 @@ base::CommandLine::SwitchMap switches = cmd_line->GetSwitches(); for (base::CommandLine::SwitchMap::const_iterator it = switches.begin(); it != switches.end(); ++it) { - if (it->first.find("gtest_") == 0 || // Handled by GoogleTest - it->first == "ozone-platform" || // Handled by Chrome - it->first == "use-gl" || // Handled by Chrome - it->first == "v" || it->first == "vmodule") { // Handled by Chrome + if (it->first.find("gtest_") == 0 || // Handled by GoogleTest + it->first == "ozone-platform" || // Handled by Chrome + it->first == "use-gl" || // Handled by Chrome + // Options below handled by Chrome + it->first == "v" || it->first == "vmodule" || + it->first == "enable-features" || it->first == "disable-features") { continue; } @@ -520,6 +523,20 @@ // video decoder to allow clear HEVC decoding. cmd_line->AppendSwitch("enable-clear-hevc-for-testing"); +#if BUILDFLAG(USE_V4L2_CODEC) + std::unique_ptr<base::FeatureList> feature_list = + std::make_unique<base::FeatureList>(); + feature_list->InitializeFromCommandLine( + cmd_line->GetSwitchValueASCII(switches::kEnableFeatures), + cmd_line->GetSwitchValueASCII(switches::kDisableFeatures)); + if (feature_list->IsFeatureOverridden("V4L2FlatStatelessVideoDecoder")) { + enabled_features.push_back(media::kV4L2FlatStatelessVideoDecoder); + } + if (feature_list->IsFeatureOverridden("V4L2FlatStatefulVideoDecoder")) { + enabled_features.push_back(media::kV4L2FlatStatefulVideoDecoder); + } +#endif + // Set up our test environment. media::test::VideoPlayerTestEnvironment* test_environment = media::test::VideoPlayerTestEnvironment::Create(
diff --git a/net/server/web_socket.cc b/net/server/web_socket.cc index fc3d78d..4bb91c0 100644 --- a/net/server/web_socket.cc +++ b/net/server/web_socket.cc
@@ -121,8 +121,27 @@ int bytes_consumed = 0; result = encoder_->DecodeFrame(frame, &bytes_consumed, message); read_buf->DidConsume(bytes_consumed); - if (result == FRAME_CLOSE) + + if (result == FRAME_CLOSE) { + // The current websocket implementation does not initiate the Close + // handshake before closing the connection. + // Therefore the received Close frame most likely belongs to the client that + // initiated the Closing handshake. + // According to https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.1 + // if an endpoint receives a Close frame and did not previously send a + // Close frame, the endpoint MUST send a Close frame in response. + // It also MAY provide the close reason listed in + // https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1. + // As the closure was initiated by the client the "normal closure" status + // code is appropriate. + std::string code = "\x03\xe8"; // code = 1000; + std::string encoded; + encoder_->EncodeCloseFrame(code, 0, &encoded); + server_->SendRaw(connection_->id(), encoded, *traffic_annotation_); + closed_ = true; + } + if (result == FRAME_PING) { if (!traffic_annotation_) return FRAME_ERROR;
diff --git a/net/server/web_socket_encoder.cc b/net/server/web_socket_encoder.cc index 812ab737..0a363ead 100644 --- a/net/server/web_socket_encoder.cc +++ b/net/server/web_socket_encoder.cc
@@ -340,6 +340,13 @@ EncodeFrameHybi17(frame, masking_key, false, op_code, output); } +void WebSocketEncoder::EncodeCloseFrame(base::StringPiece frame, + int masking_key, + std::string* output) { + constexpr auto op_code = WebSocketFrameHeader::OpCodeEnum::kOpCodeClose; + EncodeFrameHybi17(frame, masking_key, false, op_code, output); +} + void WebSocketEncoder::EncodePongFrame(base::StringPiece frame, int masking_key, std::string* output) {
diff --git a/net/server/web_socket_encoder.h b/net/server/web_socket_encoder.h index 1604a82..58e21d6 100644 --- a/net/server/web_socket_encoder.h +++ b/net/server/web_socket_encoder.h
@@ -47,6 +47,9 @@ void EncodePongFrame(base::StringPiece frame, int masking_key, std::string* output); + void EncodeCloseFrame(base::StringPiece frame, + int masking_key, + std::string* output); bool deflate_enabled() const { return !!deflater_; }
diff --git a/net/server/web_socket_encoder_unittest.cc b/net/server/web_socket_encoder_unittest.cc index 2025645..a875122 100644 --- a/net/server/web_socket_encoder_unittest.cc +++ b/net/server/web_socket_encoder_unittest.cc
@@ -501,4 +501,15 @@ EXPECT_EQ(kOriginalText, encoded.substr(2)); } +TEST_F(WebSocketEncoderCompressionTest, CheckCloseFrameNotCompressed) { + constexpr uint8_t kReserved1Bit = 0x40; + const std::string kOriginalText = "\x03\xe8"; + constexpr int kMask = 0; + std::string encoded; + + server_->EncodeCloseFrame(kOriginalText, kMask, &encoded); + EXPECT_FALSE(encoded[1] & kReserved1Bit); + EXPECT_EQ(kOriginalText, encoded.substr(2)); +} + } // namespace net
diff --git a/remoting/host/input_injector_chromeos.cc b/remoting/host/input_injector_chromeos.cc index a143dbb..af002a6 100644 --- a/remoting/host/input_injector_chromeos.cc +++ b/remoting/host/input_injector_chromeos.cc
@@ -171,6 +171,7 @@ // Ignore events which can't be mapped. if (dom_code != ui::DomCode::NONE) { + VLOG(3) << "Injecting key " << (event.pressed() ? "down" : "up") << " event."; delegate_->InjectKeyEvent(dom_code, event.pressed(), true /* suppress_auto_repeat */); }
diff --git a/remoting/host/input_injector_mac.cc b/remoting/host/input_injector_mac.cc index 063b9a247..c7b0587 100644 --- a/remoting/host/input_injector_mac.cc +++ b/remoting/host/input_injector_mac.cc
@@ -53,6 +53,7 @@ eventRef, unicode.size(), reinterpret_cast<const UniChar*>(unicode.data())); } + VLOG(3) << "Injecting key " << (pressed ? "down" : "up") << " event."; CGEventPost(kCGSessionEventTap, eventRef); } } @@ -256,9 +257,6 @@ int keycode = ui::KeycodeConverter::UsbKeycodeToNativeKeycode(event.usb_keycode()); - VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode() - << " to keycode: " << keycode << std::dec; - // If we couldn't determine the Mac virtual key code then ignore the event. if (keycode == ui::KeycodeConverter::InvalidNativeKeycode()) { return;
diff --git a/remoting/host/input_injector_win.cc b/remoting/host/input_injector_win.cc index 3f5177f..4b4cfce8 100644 --- a/remoting/host/input_injector_win.cc +++ b/remoting/host/input_injector_win.cc
@@ -386,8 +386,6 @@ int scancode = ui::KeycodeConverter::UsbKeycodeToNativeKeycode(event.usb_keycode()); - VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode() - << " to scancode: " << scancode << std::dec; // Ignore events which can't be mapped. if (scancode == ui::KeycodeConverter::InvalidNativeKeycode()) { @@ -418,6 +416,7 @@ } uint32_t flags = KEYEVENTF_SCANCODE | (event.pressed() ? 0 : KEYEVENTF_KEYUP); + VLOG(3) << "Injecting key " << (event.pressed() ? "down" : "up") << " event."; SendKeyboardInput(flags, scancode, 0); }
diff --git a/remoting/host/input_injector_x11.cc b/remoting/host/input_injector_x11.cc index 2a351556..c7de2a8 100644 --- a/remoting/host/input_injector_x11.cc +++ b/remoting/host/input_injector_x11.cc
@@ -154,9 +154,6 @@ int keycode = ui::KeycodeConverter::UsbKeycodeToNativeKeycode(event.usb_keycode()); - VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode() - << " to keycode: " << keycode << std::dec; - // Ignore events which can't be mapped. if (keycode == ui::KeycodeConverter::InvalidNativeKeycode()) { return; @@ -208,6 +205,7 @@ } uint8_t opcode = event.pressed() ? x11::KeyEvent::Press : x11::KeyEvent::Release; + VLOG(3) << "Injecting key " << (event.pressed() ? "down" : "up") << " event."; connection_->xtest().FakeInput({opcode, static_cast<uint8_t>(keycode)}); connection_->Flush(); }
diff --git a/remoting/host/linux/input_injector_wayland.cc b/remoting/host/linux/input_injector_wayland.cc index a57dc20..797d8b3 100644 --- a/remoting/host/linux/input_injector_wayland.cc +++ b/remoting/host/linux/input_injector_wayland.cc
@@ -323,7 +323,7 @@ // Ignore events which can't be mapped. if (keycode == ui::KeycodeConverter::InvalidNativeKeycode()) { - LOG(ERROR) << __func__ << " : Invalid key code: " << keycode; + LOG(ERROR) << __func__ << " : Invalid key code"; return; }
diff --git a/remoting/host/policy_watcher.cc b/remoting/host/policy_watcher.cc index 297c0e8..e4a0f31 100644 --- a/remoting/host/policy_watcher.cc +++ b/remoting/host/policy_watcher.cc
@@ -476,7 +476,7 @@ policy_loader = std::make_unique<policy::PolicyLoaderMac>( file_task_runner, policy::PolicyLoaderMac::GetManagedPolicyPath(bundle_id), - new MacPreferences(), bundle_id); + std::make_unique<MacPreferences>(), bundle_id); #elif BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) policy_loader = std::make_unique<policy::ConfigDirPolicyLoader>( file_task_runner, base::FilePath(policy::kPolicyPath),
diff --git a/services/accessibility/fake_service_client.cc b/services/accessibility/fake_service_client.cc index 777ae05..eb15c50 100644 --- a/services/accessibility/fake_service_client.cc +++ b/services/accessibility/fake_service_client.cc
@@ -112,6 +112,12 @@ } } +void FakeServiceClient::OpenSettingsSubpage(const std::string& subpage) { + if (open_settings_subpage_callback_) { + open_settings_subpage_callback_.Run(subpage); + } +} + void FakeServiceClient::SetFocusRings( std::vector<mojom::FocusRingInfoPtr> focus_rings, mojom::AssistiveTechnologyType at_type) { @@ -161,6 +167,11 @@ darken_screen_callback_ = std::move(callback); } +void FakeServiceClient::SetOpenSettingsSubpageCallback( + base::RepeatingCallback<void(const std::string& subpage)> callback) { + open_settings_subpage_callback_ = std::move(callback); +} + void FakeServiceClient::SetFocusRingsCallback( base::RepeatingCallback<void()> callback) { focus_rings_callback_ = std::move(callback);
diff --git a/services/accessibility/fake_service_client.h b/services/accessibility/fake_service_client.h index 6974985..62281ae 100644 --- a/services/accessibility/fake_service_client.h +++ b/services/accessibility/fake_service_client.h
@@ -64,6 +64,7 @@ // ax::mojom::UserInterface: void DarkenScreen(bool darken) override; + void OpenSettingsSubpage(const std::string& subpage) override; void SetFocusRings(std::vector<ax::mojom::FocusRingInfoPtr> focus_rings, ax::mojom::AssistiveTechnologyType at_type) override; void SetHighlights(const std::vector<gfx::Rect>& rects, @@ -85,6 +86,8 @@ bool UserInterfaceIsBound() const; void SetDarkenScreenCallback( base::RepeatingCallback<void(bool darken)> callback); + void SetOpenSettingsSubpageCallback( + base::RepeatingCallback<void(const std::string& subpage)> callback); void SetFocusRingsCallback(base::RepeatingCallback<void()> callback); const std::vector<ax::mojom::FocusRingInfoPtr>& GetFocusRingsForType( mojom::AssistiveTechnologyType type) const; @@ -109,6 +112,8 @@ mojo::Remote<ax::mojom::TtsUtteranceClient> tts_utterance_client_; base::RepeatingCallback<void(bool darken)> darken_screen_callback_; + base::RepeatingCallback<void(const std::string& subpage)> + open_settings_subpage_callback_; base::RepeatingCallback<void()> focus_rings_callback_; mojo::ReceiverSet<mojom::UserInterface> ux_receivers_; std::map<mojom::AssistiveTechnologyType,
diff --git a/services/accessibility/features/atp_js_api_test.cc b/services/accessibility/features/atp_js_api_test.cc index 5a9dda8..a3ac992 100644 --- a/services/accessibility/features/atp_js_api_test.cc +++ b/services/accessibility/features/atp_js_api_test.cc
@@ -439,6 +439,19 @@ waiter.Run(); } +TEST_F(AccessibilityPrivateJSApiTest, OpenSettingsSubpage) { + base::RunLoop waiter; + client_->SetOpenSettingsSubpageCallback( + base::BindLambdaForTesting([&waiter](const std::string& subpage) { + waiter.Quit(); + ASSERT_EQ(subpage, "manageAccessibility/tts"); + })); + ExecuteJS(R"JS( + chrome.accessibilityPrivate.openSettingsSubpage('manageAccessibility/tts'); + )JS"); + waiter.Run(); +} + TEST_F(AccessibilityPrivateJSApiTest, SetFocusRings) { base::RunLoop waiter; client_->SetFocusRingsCallback(base::BindLambdaForTesting([&waiter, this]() {
diff --git a/services/accessibility/features/javascript/accessibility_private.js b/services/accessibility/features/javascript/accessibility_private.js index 30d8a52..d3d8b851 100644 --- a/services/accessibility/features/javascript/accessibility_private.js +++ b/services/accessibility/features/javascript/accessibility_private.js
@@ -53,6 +53,16 @@ } /** + * Opens a specified ChromeOS settings subpage. For example, to open a page + * with the url 'chrome://settings/manageAccessibility/tts', pass in the + * substring 'manageAccessibility/tts'. + * @param {string} subpage + */ + openSettingsSubpage(subpage) { + this.userInterfaceRemote_.openSettingsSubpage(subpage); + } + + /** * Sets the given accessibility focus rings for this extension. * @param {!Array<!chrome.accessibilityPrivate.FocusRingInfo>} focusRings * Array of focus rings to draw.
diff --git a/services/accessibility/public/mojom/user_interface.mojom b/services/accessibility/public/mojom/user_interface.mojom index 652e41d..386eaf0 100644 --- a/services/accessibility/public/mojom/user_interface.mojom +++ b/services/accessibility/public/mojom/user_interface.mojom
@@ -56,6 +56,11 @@ // undarken screen. DarkenScreen(bool darken); + // Opens a specified ChromeOS settings subpage. For example, to open a page + // with the url 'chrome://settings/manageAccessibility/tts', pass in the + // substring 'manageAccessibility/tts'. + OpenSettingsSubpage(string subpage); + // Sets the given accessibility focus rings for the given `at_type` // or clears them if the list is empty. // TODO(b/293348920): Cleanup after migration: pass a map of id to
diff --git a/services/audio/input_controller_unittest.cc b/services/audio/input_controller_unittest.cc index a75a371c..1c193ea 100644 --- a/services/audio/input_controller_unittest.cc +++ b/services/audio/input_controller_unittest.cc
@@ -61,7 +61,9 @@ kDecreasedTo0, }; +#if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION) const std::string kFifoSizeParameter = "fifo_size"; +#endif } // namespace
diff --git a/services/device/generic_sensor/sensor_provider_impl.cc b/services/device/generic_sensor/sensor_provider_impl.cc index 299fa8e..06a4c67 100644 --- a/services/device/generic_sensor/sensor_provider_impl.cc +++ b/services/device/generic_sensor/sensor_provider_impl.cc
@@ -48,6 +48,10 @@ : provider_(std::move(provider)) { DCHECK(provider_); + // This is used to clean up VirtualSensorProvider instances if they do not + // have any pending requests or connected sensors, as this class has + // DeviceService's lifetime but VirtualSensorProviders are per + // content::WebContents. receivers_.set_disconnect_handler(base::BindRepeating( &SensorProviderImpl::OnReceiverDisconnected, base::Unretained(this))); } @@ -196,15 +200,16 @@ mojom::SensorType type, const SensorReading& reading, UpdateVirtualSensorCallback callback) { - const mojo::ReceiverId receiver_id = receivers_.current_receiver(); + auto virtual_provider_it = + virtual_providers_.find(receivers_.current_receiver()); - if (!base::Contains(virtual_providers_, receiver_id)) { + if (virtual_provider_it == virtual_providers_.end()) { std::move(callback).Run( mojom::UpdateVirtualSensorResult::kSensorTypeNotOverridden); return; } - auto* virtual_provider = virtual_providers_[receiver_id].get(); + auto* virtual_provider = virtual_provider_it->second.get(); if (!virtual_provider->IsOverridingSensor(type)) { std::move(callback).Run( @@ -216,36 +221,37 @@ static_cast<VirtualPlatformSensor*>(virtual_sensor.get()) ->AddReading(reading); } - std::move(callback).Run(mojom::UpdateVirtualSensorResult::kSuccess); } void SensorProviderImpl::RemoveVirtualSensor( mojom::SensorType type, RemoveVirtualSensorCallback callback) { - const mojo::ReceiverId receiver_id = receivers_.current_receiver(); + auto virtual_provider_it = + virtual_providers_.find(receivers_.current_receiver()); - if (!base::Contains(virtual_providers_, receiver_id)) { + if (virtual_provider_it == virtual_providers_.end()) { std::move(callback).Run(); return; } - virtual_providers_[receiver_id]->RemoveSensorOverride(type); + virtual_provider_it->second->RemoveSensorOverride(type); std::move(callback).Run(); } void SensorProviderImpl::GetVirtualSensorInformation( mojom::SensorType type, GetVirtualSensorInformationCallback callback) { - const mojo::ReceiverId receiver_id = receivers_.current_receiver(); + auto virtual_provider_it = + virtual_providers_.find(receivers_.current_receiver()); - if (!base::Contains(virtual_providers_, receiver_id)) { + if (virtual_provider_it == virtual_providers_.end()) { std::move(callback).Run(mojom::GetVirtualSensorInformationResult::NewError( mojom::GetVirtualSensorInformationError::kSensorTypeNotOverridden)); return; } - auto* virtual_provider = virtual_providers_[receiver_id].get(); + auto* virtual_provider = virtual_provider_it->second.get(); if (!virtual_provider->IsOverridingSensor(type)) { std::move(callback).Run(mojom::GetVirtualSensorInformationResult::NewError(
diff --git a/skia/public/mojom/BUILD.gn b/skia/public/mojom/BUILD.gn index fed282f..3efe855 100644 --- a/skia/public/mojom/BUILD.gn +++ b/skia/public/mojom/BUILD.gn
@@ -158,5 +158,10 @@ cpp_typemaps = shared_skia_cpp_typemaps blink_cpp_typemaps = shared_skia_cpp_typemaps + + # Generate TypeScript bindings for WebUI and JavaScript legacy bindings for + # Blink. webui_module_path = "chrome://resources/mojo/skia/public/mojom/" + use_typescript_sources = true + generate_legacy_js_bindings = true }
diff --git a/testing/buildbot/chromium.accessibility.json b/testing/buildbot/chromium.accessibility.json index 51d40a2..855518f 100644 --- a/testing/buildbot/chromium.accessibility.json +++ b/testing/buildbot/chromium.accessibility.json
@@ -49,7 +49,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 8 + "shards": 20 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/" @@ -98,7 +98,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 5 + "shards": 20 }, "test": "blink_web_tests", "test_id_prefix": "ninja://:blink_web_tests/"
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index cd33b2f..aba38f1 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5039,7 +5039,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v118.0.5993.60/test_ash_chrome" ], "description": "Run with ash-chrome version 118.0.5993.60", @@ -5068,10 +5068,10 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6062.0/test_ash_chrome" + "--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_v120.0.6063.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 120.0.6062.0", + "description": "Run with ash-chrome version 120.0.6063.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5081,8 +5081,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v120.0.6062.0", - "revision": "version:120.0.6062.0" + "location": "lacros_version_skew_tests_v120.0.6063.0", + "revision": "version:120.0.6063.0" } ], "dimensions": { @@ -5097,7 +5097,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v119.0.6045.16/test_ash_chrome" ], "description": "Run with ash-chrome version 119.0.6045.16", @@ -5126,7 +5126,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v117.0.5938.157/test_ash_chrome" ], "description": "Run with ash-chrome version 117.0.5938.157", @@ -5189,7 +5189,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--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_v118.0.5993.60/test_ash_chrome" ], "description": "Run with ash-chrome version 118.0.5993.60", @@ -5218,10 +5218,10 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6062.0/test_ash_chrome" + "--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_v120.0.6063.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 120.0.6062.0", + "description": "Run with ash-chrome version 120.0.6063.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5231,8 +5231,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v120.0.6062.0", - "revision": "version:120.0.6062.0" + "location": "lacros_version_skew_tests_v120.0.6063.0", + "revision": "version:120.0.6063.0" } ], "dimensions": { @@ -5247,7 +5247,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--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_v119.0.6045.16/test_ash_chrome" ], "description": "Run with ash-chrome version 119.0.6045.16", @@ -5276,7 +5276,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--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_v117.0.5938.157/test_ash_chrome" ], "description": "Run with ash-chrome version 117.0.5938.157",
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index 0a460656..090076e 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -25419,7 +25419,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v118.0.5993.60/test_ash_chrome" ], "description": "Run with ash-chrome version 118.0.5993.60", @@ -25448,10 +25448,10 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6062.0/test_ash_chrome" + "--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_v120.0.6063.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 120.0.6062.0", + "description": "Run with ash-chrome version 120.0.6063.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25461,8 +25461,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v120.0.6062.0", - "revision": "version:120.0.6062.0" + "location": "lacros_version_skew_tests_v120.0.6063.0", + "revision": "version:120.0.6063.0" } ], "dimensions": { @@ -25477,7 +25477,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v119.0.6045.16/test_ash_chrome" ], "description": "Run with ash-chrome version 119.0.6045.16", @@ -25506,7 +25506,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v117.0.5938.157/test_ash_chrome" ], "description": "Run with ash-chrome version 117.0.5938.157", @@ -25569,7 +25569,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--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_v118.0.5993.60/test_ash_chrome" ], "description": "Run with ash-chrome version 118.0.5993.60", @@ -25598,10 +25598,10 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6062.0/test_ash_chrome" + "--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_v120.0.6063.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 120.0.6062.0", + "description": "Run with ash-chrome version 120.0.6063.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25611,8 +25611,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v120.0.6062.0", - "revision": "version:120.0.6062.0" + "location": "lacros_version_skew_tests_v120.0.6063.0", + "revision": "version:120.0.6063.0" } ], "dimensions": { @@ -25627,7 +25627,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--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_v119.0.6045.16/test_ash_chrome" ], "description": "Run with ash-chrome version 119.0.6045.16", @@ -25656,7 +25656,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--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_v117.0.5938.157/test_ash_chrome" ], "description": "Run with ash-chrome version 117.0.5938.157",
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index efc9975..96ef2ce 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -43487,7 +43487,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v118.0.5993.60/test_ash_chrome" ], "description": "Run with ash-chrome version 118.0.5993.60", @@ -43516,10 +43516,10 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6062.0/test_ash_chrome" + "--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_v120.0.6063.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 120.0.6062.0", + "description": "Run with ash-chrome version 120.0.6063.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43528,8 +43528,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v120.0.6062.0", - "revision": "version:120.0.6062.0" + "location": "lacros_version_skew_tests_v120.0.6063.0", + "revision": "version:120.0.6063.0" } ], "dimensions": { @@ -43545,7 +43545,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v119.0.6045.16/test_ash_chrome" ], "description": "Run with ash-chrome version 119.0.6045.16", @@ -43574,7 +43574,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v117.0.5938.157/test_ash_chrome" ], "description": "Run with ash-chrome version 117.0.5938.157", @@ -43637,7 +43637,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--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_v118.0.5993.60/test_ash_chrome" ], "description": "Run with ash-chrome version 118.0.5993.60", @@ -43666,10 +43666,10 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6062.0/test_ash_chrome" + "--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_v120.0.6063.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 120.0.6062.0", + "description": "Run with ash-chrome version 120.0.6063.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43678,8 +43678,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v120.0.6062.0", - "revision": "version:120.0.6062.0" + "location": "lacros_version_skew_tests_v120.0.6063.0", + "revision": "version:120.0.6063.0" } ], "dimensions": { @@ -43695,7 +43695,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--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_v119.0.6045.16/test_ash_chrome" ], "description": "Run with ash-chrome version 119.0.6045.16", @@ -43724,7 +43724,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--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_v117.0.5938.157/test_ash_chrome" ], "description": "Run with ash-chrome version 117.0.5938.157", @@ -44961,7 +44961,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v118.0.5993.60/test_ash_chrome" ], "description": "Run with ash-chrome version 118.0.5993.60", @@ -44990,10 +44990,10 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6062.0/test_ash_chrome" + "--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_v120.0.6063.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 120.0.6062.0", + "description": "Run with ash-chrome version 120.0.6063.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45002,8 +45002,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v120.0.6062.0", - "revision": "version:120.0.6062.0" + "location": "lacros_version_skew_tests_v120.0.6063.0", + "revision": "version:120.0.6063.0" } ], "dimensions": { @@ -45019,7 +45019,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v119.0.6045.16/test_ash_chrome" ], "description": "Run with ash-chrome version 119.0.6045.16", @@ -45048,7 +45048,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v117.0.5938.157/test_ash_chrome" ], "description": "Run with ash-chrome version 117.0.5938.157", @@ -45111,7 +45111,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--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_v118.0.5993.60/test_ash_chrome" ], "description": "Run with ash-chrome version 118.0.5993.60", @@ -45140,10 +45140,10 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6062.0/test_ash_chrome" + "--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_v120.0.6063.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 120.0.6062.0", + "description": "Run with ash-chrome version 120.0.6063.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45152,8 +45152,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v120.0.6062.0", - "revision": "version:120.0.6062.0" + "location": "lacros_version_skew_tests_v120.0.6063.0", + "revision": "version:120.0.6063.0" } ], "dimensions": { @@ -45169,7 +45169,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--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_v119.0.6045.16/test_ash_chrome" ], "description": "Run with ash-chrome version 119.0.6045.16", @@ -45198,7 +45198,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--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_v117.0.5938.157/test_ash_chrome" ], "description": "Run with ash-chrome version 117.0.5938.157", @@ -45822,7 +45822,7 @@ "gtest_tests": [ { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v118.0.5993.60/test_ash_chrome" ], "description": "Run with ash-chrome version 118.0.5993.60", @@ -45850,10 +45850,10 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6062.0/test_ash_chrome" + "--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_v120.0.6063.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 120.0.6062.0", + "description": "Run with ash-chrome version 120.0.6063.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45862,8 +45862,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v120.0.6062.0", - "revision": "version:120.0.6062.0" + "location": "lacros_version_skew_tests_v120.0.6063.0", + "revision": "version:120.0.6063.0" } ], "dimensions": { @@ -45878,7 +45878,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v119.0.6045.16/test_ash_chrome" ], "description": "Run with ash-chrome version 119.0.6045.16", @@ -45906,7 +45906,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v117.0.5938.157/test_ash_chrome" ], "description": "Run with ash-chrome version 117.0.5938.157",
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 850c415..6cfabf3 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -16331,7 +16331,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v118.0.5993.60/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", @@ -16363,13 +16363,13 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6062.0/test_ash_chrome", + "--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_v120.0.6063.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 120.0.6062.0", + "description": "Run with ash-chrome version 120.0.6063.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16379,8 +16379,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v120.0.6062.0", - "revision": "version:120.0.6062.0" + "location": "lacros_version_skew_tests_v120.0.6063.0", + "revision": "version:120.0.6063.0" } ], "dimensions": { @@ -16395,7 +16395,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v119.0.6045.16/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", @@ -16427,7 +16427,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--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_v117.0.5938.157/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", @@ -16501,7 +16501,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--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_v118.0.5993.60/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", @@ -16533,13 +16533,13 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6062.0/test_ash_chrome", + "--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_v120.0.6063.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 120.0.6062.0", + "description": "Run with ash-chrome version 120.0.6063.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16549,8 +16549,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v120.0.6062.0", - "revision": "version:120.0.6062.0" + "location": "lacros_version_skew_tests_v120.0.6063.0", + "revision": "version:120.0.6063.0" } ], "dimensions": { @@ -16565,7 +16565,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--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_v119.0.6045.16/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", @@ -16597,7 +16597,7 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--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_v117.0.5938.157/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots",
diff --git a/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter b/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter index 5a3c23d5..4a04fe428 100644 --- a/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter +++ b/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter
@@ -2,3 +2,6 @@ # If you need to disable a tests for version skew, use # linux-lacros.lacros_chrome_browsertests.skew.filter. +# TODO(crbug.com/1477409) flaky. +-InputMethodLacrosBrowserTest.ConfirmCompositionWith* +-InputMethodLacrosBrowserTest.DeleteSurroundingText*
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index bcc8080..435a0f6 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -523,6 +523,9 @@ 'args': [ '--flag-specific=force-renderer-accessibility', ], + 'swarming': { + 'shards': 20, + }, }, 'linux-blink-wpt-reset-rel': { 'args': [
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index d755861..9d75ca04 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -4220,7 +4220,7 @@ '--test-launcher-filter-file=../../testing/buildbot/filters/accessibility-linux.browser_tests.filter', ], 'swarming': { - 'shards': 8, + 'shards': 20, }, }, 'content_browsertests': { @@ -4249,7 +4249,7 @@ 'linux_lacros_chrome_browsertests_version_skew': { 'lacros_chrome_browsertests_run_in_series': { 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter', + '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter', ], 'swarming': { 'shards': 2, @@ -4261,7 +4261,7 @@ 'interactive_ui_tests': { 'test': 'interactive_ui_tests', 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter', + '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter', ], 'swarming': { 'shards': 3,
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index ac4b64e..a9725b2 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -70,16 +70,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'identifier': 'Lacros version skew testing ash canary', - 'description': 'Run with ash-chrome version 120.0.6062.0', + 'description': 'Run with ash-chrome version 120.0.6063.0', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6062.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6063.0/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v120.0.6062.0', - 'revision': 'version:120.0.6062.0', + 'location': 'lacros_version_skew_tests_v120.0.6063.0', + 'revision': 'version:120.0.6063.0', }, ], },
diff --git a/testing/libfuzzer/fuzzers/command_buffer_lpm_fuzzer/cmd_buf_lpm_fuzz.h b/testing/libfuzzer/fuzzers/command_buffer_lpm_fuzzer/cmd_buf_lpm_fuzz.h index eb93256..b46b9f7 100644 --- a/testing/libfuzzer/fuzzers/command_buffer_lpm_fuzzer/cmd_buf_lpm_fuzz.h +++ b/testing/libfuzzer/fuzzers/command_buffer_lpm_fuzzer/cmd_buf_lpm_fuzz.h
@@ -113,9 +113,6 @@ wgpu::Queue queue = device.GetQueue(); bool done = false; queue.OnSubmittedWorkDone( -#ifndef WGPU_BREAKING_WORK_DONE_SIGNAL_VALUE_CHANGE - 0u, -#endif // WGPU_BREAKING_WORK_DONE_SIGNAL_VALUE_CHANGE [](WGPUQueueWorkDoneStatus, void* userdata) { *static_cast<bool*>(userdata) = true; },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 012e8ca..33adfb2 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -3621,22 +3621,6 @@ ] } ], - "ChromeStartOnTablet": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "ShowScrollableMVTOnNTPAndroid", - "StartSurfaceOnTablet" - ] - } - ] - } - ], "ChromeStartRefactor": [ { "platforms": [ @@ -10708,6 +10692,7 @@ { "name": "Enabled", "params": { + "ActionsUISimplificationIncludeRealbox": "true", "ActionsUISimplificationTrimExtra": "true" }, "enable_features": [ @@ -10715,8 +10700,29 @@ ] }, { - "name": "Enabled_TrimExtraFalse", + "name": "ExcludeRealbox", "params": { + "ActionsUISimplificationIncludeRealbox": "false", + "ActionsUISimplificationTrimExtra": "true" + }, + "enable_features": [ + "OmniboxActionsUISimplification" + ] + }, + { + "name": "ExcludeRealbox_TrimExtraFalse", + "params": { + "ActionsUISimplificationIncludeRealbox": "false", + "ActionsUISimplificationTrimExtra": "false" + }, + "enable_features": [ + "OmniboxActionsUISimplification" + ] + }, + { + "name": "TrimExtraFalse", + "params": { + "ActionsUISimplificationIncludeRealbox": "true", "ActionsUISimplificationTrimExtra": "false" }, "enable_features": [
diff --git a/third_party/angle b/third_party/angle index 24dabdb..5b7763f 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit 24dabdbbeee213d7a1fd01a70cddacc1949d3b26 +Subproject commit 5b7763f9d427e98d9be0319fc4c9ef645de63cb7
diff --git a/third_party/blink/public/common/fenced_frame/fenced_frame_utils.h b/third_party/blink/public/common/fenced_frame/fenced_frame_utils.h index 88c1693..db97bbe 100644 --- a/third_party/blink/public/common/fenced_frame/fenced_frame_utils.h +++ b/third_party/blink/public/common/fenced_frame/fenced_frame_utils.h
@@ -38,7 +38,7 @@ "Blink.FencedFrame.FailedSandboxLoadInTopLevelFrame"; inline constexpr char kFencedFrameTopNavigationHistogram[] = - "Navigation.TopNavigationFromFencedFrame"; + "Navigation.FencedFrameTopNavigation"; inline constexpr char kAutomaticBeaconOutcomeHistogram[] = "Navigation.AutomaticBeaconOutcome";
diff --git a/third_party/blink/public/mojom/webid/federated_auth_request.mojom b/third_party/blink/public/mojom/webid/federated_auth_request.mojom index 78f1f72..1312fb4 100644 --- a/third_party/blink/public/mojom/webid/federated_auth_request.mojom +++ b/third_party/blink/public/mojom/webid/federated_auth_request.mojom
@@ -186,7 +186,7 @@ url.mojom.Url? selected_identity_provider_config_url, string? token, TokenError? error, - bool is_account_auto_selected); + bool is_identity_credential_auto_selected); // Requests user info to be generated, given an IDP config. // Returns an IdentityUserInfo for each of the user's accounts.
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 6e67f193..2f69b70c 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -971,13 +971,15 @@ if (!frame_->GetDocument()) { return gfx::SizeF(layout_size_); } - if (frame_->GetDocument()->Printing()) { + if (frame_->ShouldUsePrintingLayout()) { if (const LayoutView* layout_view = GetLayoutView()) { return layout_view->DefaultPageAreaSize(); } } gfx::SizeF viewport_size(layout_size_); - viewport_size.Scale(1 / GetFrame().PageZoomFactor()); + if (!frame_->GetDocument()->Printing()) { + viewport_size.Scale(1 / GetFrame().PageZoomFactor()); + } return viewport_size; }
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc index b4a1430..87d85922 100644 --- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc +++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -439,7 +439,7 @@ } bool HTMLCanvasElement::IsPageVisible() { - return GetPage()->IsPageVisible(); + return GetPage() && GetPage()->IsPageVisible(); } CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContextInternal( @@ -521,7 +521,7 @@ CanvasResourceDispatcher::kInvalidPlaceholderCanvasId, Size()); // We don't actually need the begin frame signal when in low latency mode, // but we need to subscribe to it or else dispatching frames will not work. - frame_dispatcher_->SetNeedsBeginFrame(GetPage()->IsPageVisible()); + frame_dispatcher_->SetNeedsBeginFrame(IsPageVisible()); UseCounter::Count(GetDocument(), WebFeature::kHTMLCanvasElementLowLatency); } @@ -1686,16 +1686,13 @@ return context_ && !context_->CreationAttributes().alpha; } -bool HTMLCanvasElement::IsVisible() const { - return GetPage() && GetPage()->IsPageVisible(); -} - bool HTMLCanvasElement::CreateLayer() { DCHECK(!surface_layer_bridge_); LocalFrame* frame = GetDocument().GetFrame(); // We do not design transferControlToOffscreen() for frame-less HTML canvas. - if (!frame) + if (!frame || !frame->GetPage()) { return false; + } surface_layer_bridge_ = std::make_unique<::blink::SurfaceLayerBridge>( frame->GetPage()->GetChromeClient().GetFrameSinkId(frame),
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.h b/third_party/blink/renderer/core/html/canvas/html_canvas_element.h index 058da3e..9996e1c 100644 --- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.h +++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.h
@@ -175,7 +175,6 @@ InsertionNotificationRequest InsertedInto(ContainerNode&) override; bool IsDirty() { return !dirty_rect_.IsEmpty(); } - bool IsVisible() const; void DoDeferredPaintInvalidation();
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index 30bf5f5e..fa8b3db 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -2574,19 +2574,18 @@ PhysicalOffset LayoutBox::OffsetFromContainerInternal( const LayoutObject* o, - bool ignore_scroll_offset) const { + MapCoordinatesFlags mode) const { NOT_DESTROYED(); DCHECK_EQ(o, Container()); - PhysicalOffset offset; - offset += PhysicalLocation(); + PhysicalOffset offset = PhysicalLocation(); - if (IsStickyPositioned()) { + if (IsStickyPositioned() && !(mode & kIgnoreStickyOffset)) { offset += StickyPositionOffset(); } if (o->IsScrollContainer()) - offset += OffsetFromScrollableContainer(o, ignore_scroll_offset); + offset += OffsetFromScrollableContainer(o, mode & kIgnoreScrollOffset); if (NeedsAnchorPositionScrollAdjustment()) { offset += AnchorPositionScrollTranslationOffset();
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h index 3e570e2..9bfaede 100644 --- a/third_party/blink/renderer/core/layout/layout_box.h +++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -1432,7 +1432,7 @@ PhysicalOffset OffsetFromContainerInternal( const LayoutObject*, - bool ignore_scroll_offset) const override; + MapCoordinatesFlags mode) const override; // For atomic inlines, returns its resolved direction in text flow. Not to be // confused with the CSS property 'direction'.
diff --git a/third_party/blink/renderer/core/layout/layout_inline.cc b/third_party/blink/renderer/core/layout/layout_inline.cc index 0a5842a7..b5271ef4 100644 --- a/third_party/blink/renderer/core/layout/layout_inline.cc +++ b/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -813,17 +813,19 @@ PhysicalOffset LayoutInline::OffsetFromContainerInternal( const LayoutObject* container, - bool ignore_scroll_offset) const { + MapCoordinatesFlags mode) const { NOT_DESTROYED(); DCHECK_EQ(container, Container()); PhysicalOffset offset; - if (IsStickyPositioned()) { + if (IsStickyPositioned() && !(mode & kIgnoreStickyOffset)) { offset += StickyPositionOffset(); } - if (container->IsScrollContainer()) - offset += OffsetFromScrollableContainer(container, ignore_scroll_offset); + if (container->IsScrollContainer()) { + offset += + OffsetFromScrollableContainer(container, mode & kIgnoreScrollOffset); + } return offset; }
diff --git a/third_party/blink/renderer/core/layout/layout_inline.h b/third_party/blink/renderer/core/layout/layout_inline.h index 0796cdd7..c484494 100644 --- a/third_party/blink/renderer/core/layout/layout_inline.h +++ b/third_party/blink/renderer/core/layout/layout_inline.h
@@ -233,7 +233,7 @@ PhysicalOffset OffsetFromContainerInternal( const LayoutObject*, - bool ignore_scroll_offset) const final; + MapCoordinatesFlags mode) const final; private: bool AbsoluteTransformDependsOnPoint(const LayoutObject& object) const;
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 4169ebb..459f5bd 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -3339,15 +3339,7 @@ if (!container) return; - PhysicalOffset container_offset = - OffsetFromContainer(container, mode & kIgnoreScrollOffset); - - // TODO(smcgruer): This is inefficient. Instead we should avoid including - // offsetForInFlowPosition in offsetFromContainer when ignoring sticky. - if (mode & kIgnoreStickyOffset && IsStickyPositioned()) { - container_offset -= To<LayoutBoxModelObject>(this)->StickyPositionOffset(); - } - + PhysicalOffset container_offset = OffsetFromContainer(container, mode); if (IsLayoutFlowThread()) { // So far the point has been in flow thread coordinates (i.e. as if // everything in the fragmentation context lived in one tall single column). @@ -3587,18 +3579,18 @@ PhysicalOffset LayoutObject::OffsetFromContainer( const LayoutObject* o, - bool ignore_scroll_offset) const { + MapCoordinatesFlags mode) const { NOT_DESTROYED(); - return OffsetFromContainerInternal(o, ignore_scroll_offset); + return OffsetFromContainerInternal(o, mode); } PhysicalOffset LayoutObject::OffsetFromContainerInternal( const LayoutObject* o, - bool ignore_scroll_offset) const { + MapCoordinatesFlags mode) const { NOT_DESTROYED(); DCHECK_EQ(o, Container()); return o->IsScrollContainer() - ? OffsetFromScrollableContainer(o, ignore_scroll_offset) + ? OffsetFromScrollableContainer(o, mode & kIgnoreScrollOffset) : PhysicalOffset(); }
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index 3e5207ea..18588742 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -2495,7 +2495,7 @@ // Return the offset from the container() layoutObject (excluding transforms // and multicol). PhysicalOffset OffsetFromContainer(const LayoutObject*, - bool ignore_scroll_offset = false) const; + MapCoordinatesFlags = 0) const; // Return the offset from an object from the ancestor. The ancestor need // not be on the containing block chain of |this|. Note that this function // cannot be used when there are transforms between this object and the @@ -3623,7 +3623,7 @@ virtual PhysicalOffset OffsetFromContainerInternal( const LayoutObject*, - bool ignore_scroll_offset) const; + MapCoordinatesFlags mode) const; PhysicalOffset OffsetFromScrollableContainer(const LayoutObject*, bool ignore_scroll_offset) const;
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource_content.cc b/third_party/blink/renderer/core/loader/resource/image_resource_content.cc index 635a661..8a98808 100644 --- a/third_party/blink/renderer/core/loader/resource/image_resource_content.cc +++ b/third_party/blink/renderer/core/loader/resource/image_resource_content.cc
@@ -464,6 +464,10 @@ return UpdateImageResult::kNoDecodeError; if (image_) { + // Mime type could be null, see https://crbug.com/1485926. + if (!image_->MimeType()) { + return UpdateImageResult::kShouldDecodeError; + } const HashSet<String>* unsupported_mime_types = info_->GetUnsupportedImageMimeTypes(); if (unsupported_mime_types &&
diff --git a/third_party/blink/renderer/core/paint/fragment_data_iterator.h b/third_party/blink/renderer/core/paint/fragment_data_iterator.h index c42fba8..56a7a45 100644 --- a/third_party/blink/renderer/core/paint/fragment_data_iterator.h +++ b/third_party/blink/renderer/core/paint/fragment_data_iterator.h
@@ -52,7 +52,7 @@ public: explicit FragmentDataIterator(const LayoutObject& object) : FragmentDataIteratorBase(&object.FirstFragment()) {} - explicit FragmentDataIterator(nullptr_t) + explicit FragmentDataIterator(std::nullptr_t) : FragmentDataIteratorBase(nullptr) {} }; @@ -63,7 +63,7 @@ explicit MutableFragmentDataIterator(const LayoutObject& object) : FragmentDataIteratorBase( &object.GetMutableForPainting().FirstFragment()) {} - explicit MutableFragmentDataIterator(nullptr_t) + explicit MutableFragmentDataIterator(std::nullptr_t) : FragmentDataIteratorBase(nullptr) {} };
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc index 25e1a9d..a1403ce89 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc
@@ -46,7 +46,6 @@ #include "ui/gfx/geometry/rect_f.h" namespace blink { -float const kErrorRange = 0.01; void CanvasPath::closePath() { if (UNLIKELY(IsEmpty())) { @@ -504,17 +503,6 @@ CanonicalizeAngle(&start_angle, &end_angle); float adjusted_end_angle = AdjustEndAngle(start_angle, end_angle, anticlockwise); - - // If the ellipse has a radius of zero and it's closed, this path should be - // ignored from drawing. - if (!path_.HasCurrentPoint() || - (path_.HasCurrentPoint() && path_.CurrentPoint().x() == x && - path_.CurrentPoint().y() == y)) { - if (!radius_x && !radius_y && - abs(adjusted_end_angle - start_angle - kTwoPiFloat) <= kErrorRange) { - return; - } - } if (UNLIKELY(!radius_x || !radius_y || start_angle == adjusted_end_angle)) { // The ellipse is empty but we still need to draw the connecting line to // start point.
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc index 738e9d44..6b2faf6 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -175,7 +175,7 @@ Host()->DiscardResourceProvider(); } - if (canvas() && canvas()->IsVisible()) { + if (canvas() && canvas()->IsPageVisible()) { dispatch_context_lost_event_timer_.StartOneShot(base::TimeDelta(), FROM_HERE); } else {
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc index 7a41479..d17e8a9 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc +++ b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc
@@ -538,7 +538,7 @@ const absl::optional<KURL>& selected_idp_config_url, const WTF::String& token, mojom::blink::TokenErrorPtr error, - bool is_account_auto_selected) { + bool is_identity_credential_auto_selected) { switch (status) { case RequestTokenStatus::kErrorTooManyRequests: { resolver->Reject(MakeGarbageCollected<DOMException>( @@ -571,8 +571,8 @@ return; } case RequestTokenStatus::kSuccess: { - IdentityCredential* credential = - IdentityCredential::Create(token, is_account_auto_selected); + IdentityCredential* credential = IdentityCredential::Create( + token, is_identity_credential_auto_selected); resolver->Resolve(credential); return; }
diff --git a/third_party/blink/renderer/modules/credentialmanagement/identity_credential.cc b/third_party/blink/renderer/modules/credentialmanagement/identity_credential.cc index 279e6fb0..11424d7 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/identity_credential.cc +++ b/third_party/blink/renderer/modules/credentialmanagement/identity_credential.cc
@@ -49,11 +49,13 @@ } // namespace -IdentityCredential* IdentityCredential::Create(const String& token, - bool is_account_auto_selected) { - if (RuntimeEnabledFeatures::FedCmAccountAutoSelectedFlagEnabled()) { - return MakeGarbageCollected<IdentityCredential>(token, - is_account_auto_selected); +IdentityCredential* IdentityCredential::Create( + const String& token, + bool is_identity_credential_auto_selected) { + if (RuntimeEnabledFeatures:: + FedCmIdentityCredentialAutoSelectedFlagEnabled()) { + return MakeGarbageCollected<IdentityCredential>( + token, is_identity_credential_auto_selected); } else { return MakeGarbageCollected<IdentityCredential>(token); } @@ -93,11 +95,13 @@ return true; } -IdentityCredential::IdentityCredential(const String& token, - bool is_account_auto_selected) +IdentityCredential::IdentityCredential( + const String& token, + bool is_identity_credential_auto_selected) : Credential(/* id = */ "", kIdentityCredentialType), token_(token), - is_account_auto_selected_(is_account_auto_selected) {} + is_identity_credential_auto_selected_( + is_identity_credential_auto_selected) {} bool IdentityCredential::IsIdentityCredential() const { return true;
diff --git a/third_party/blink/renderer/modules/credentialmanagement/identity_credential.h b/third_party/blink/renderer/modules/credentialmanagement/identity_credential.h index d00492ed..b8f0032 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/identity_credential.h +++ b/third_party/blink/renderer/modules/credentialmanagement/identity_credential.h
@@ -20,22 +20,23 @@ public: static IdentityCredential* Create(const String& token, - bool is_account_auto_selected); + bool is_identity_credential_auto_selected); static bool IsRejectingPromiseDueToCSP(ContentSecurityPolicy* policy, ScriptPromiseResolver* resolver, const KURL& provider_url); - explicit IdentityCredential(const String& token, - bool is_account_auto_selected = false); + explicit IdentityCredential( + const String& token, + bool is_identity_credential_auto_selected = false); // Credential: bool IsIdentityCredential() const override; // IdentityCredential.idl const String& token() const { return token_; } - const bool& isAccountAutoSelected() const { - return is_account_auto_selected_; + const bool& isIdentityCredentialAutoSelected() const { + return is_identity_credential_auto_selected_; } static ScriptPromise logoutRPs( @@ -44,7 +45,7 @@ private: const String token_; - const bool is_account_auto_selected_{false}; + const bool is_identity_credential_auto_selected_{false}; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/credentialmanagement/identity_credential.idl b/third_party/blink/renderer/modules/credentialmanagement/identity_credential.idl index a0e73e3..c248fa74 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/identity_credential.idl +++ b/third_party/blink/renderer/modules/credentialmanagement/identity_credential.idl
@@ -13,8 +13,8 @@ readonly attribute USVString token; // Whether an account was automatically selected in the FedCM flow. - [RuntimeEnabled=FedCmAccountAutoSelectedFlag] - readonly attribute boolean isAccountAutoSelected; + [RuntimeEnabled=FedCmIdentityCredentialAutoSelectedFlag] + readonly attribute boolean isIdentityCredentialAutoSelected; // Allows IDPs to logout the user out of all of the logged in RPs. [RuntimeEnabled=FedCmIdpSignout, CallWith=ScriptState, MeasureAs=FedCmLogoutRps]
diff --git a/third_party/blink/renderer/modules/credentialmanagement/web_identity_requester.cc b/third_party/blink/renderer/modules/credentialmanagement/web_identity_requester.cc index 63a1db46..3cbae09 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/web_identity_requester.cc +++ b/third_party/blink/renderer/modules/credentialmanagement/web_identity_requester.cc
@@ -23,7 +23,7 @@ const absl::optional<KURL>& selected_idp_config_url, const WTF::String& token, mojom::blink::TokenErrorPtr error, - bool is_account_auto_selected) { + bool is_identity_credential_auto_selected) { for (const auto& provider_resolver_pair : provider_to_resolver_) { KURL provider = provider_resolver_pair.key; ScriptPromiseResolver* resolver = provider_resolver_pair.value; @@ -63,8 +63,8 @@ "Error retrieving a token.", error->code, error->url)); continue; } - IdentityCredential* credential = - IdentityCredential::Create(token, is_account_auto_selected); + IdentityCredential* credential = IdentityCredential::Create( + token, is_identity_credential_auto_selected); resolver->Resolve(credential); continue; } @@ -213,7 +213,7 @@ if (!is_requesting_token_) { OnRequestToken(mojom::blink::RequestTokenStatus::kErrorCanceled, absl::nullopt, "", nullptr, - /*is_account_auto_selected=*/false); + /*is_identity_credential_auto_selected=*/false); return; }
diff --git a/third_party/blink/renderer/modules/credentialmanagement/web_identity_requester.h b/third_party/blink/renderer/modules/credentialmanagement/web_identity_requester.h index cb14e4e..0cde074 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/web_identity_requester.h +++ b/third_party/blink/renderer/modules/credentialmanagement/web_identity_requester.h
@@ -32,7 +32,7 @@ const absl::optional<KURL>& selected_idp_config_url, const WTF::String& token, const mojom::blink::TokenErrorPtr error, - bool is_account_auto_selected); + bool is_identity_credential_auto_selected); // Invoked at most once per token request. void RequestToken();
diff --git a/third_party/blink/renderer/modules/imagecapture/image_capture.cc b/third_party/blink/renderer/modules/imagecapture/image_capture.cc index bb6e8aa5..1382f399 100644 --- a/third_party/blink/renderer/modules/imagecapture/image_capture.cc +++ b/third_party/blink/renderer/modules/imagecapture/image_capture.cc
@@ -501,8 +501,9 @@ bool TrackIsInactive(const MediaStreamTrack& track) { // Spec instructs to return an exception if the Track's readyState() is not - // "live". Also reject if the track is disabled. - return track.readyState() != "live" || !track.enabled(); + // "live". Also reject if the track is disabled or muted. + // TODO(https://crbug.com/1462012): Do not consider muted tracks inactive. + return track.readyState() != "live" || !track.enabled() || track.muted(); } BackgroundBlurMode ParseBackgroundBlur(bool blink_mode) {
diff --git a/third_party/blink/renderer/modules/imagecapture/image_capture_test.cc b/third_party/blink/renderer/modules/imagecapture/image_capture_test.cc index d227dc4..e09d425 100644 --- a/third_party/blink/renderer/modules/imagecapture/image_capture_test.cc +++ b/third_party/blink/renderer/modules/imagecapture/image_capture_test.cc
@@ -661,11 +661,11 @@ EXPECT_CALL(*component_, GetSourceType) .WillRepeatedly(Return(MediaStreamSource::kTypeVideo)); - EXPECT_CALL(*component_, AddSink(_, _, _, _)) - .WillOnce(Invoke([&](WebMediaStreamSink* sink, - const VideoCaptureDeliverFrameCB& callback, - MediaStreamVideoSink::IsSecure is_secure, - MediaStreamVideoSink::UsesAlpha uses_alpha) { + ON_CALL(*component_, AddSink(_, _, _, _)) + .WillByDefault(Invoke([&](WebMediaStreamSink* sink, + const VideoCaptureDeliverFrameCB& callback, + MediaStreamVideoSink::IsSecure is_secure, + MediaStreamVideoSink::UsesAlpha uses_alpha) { platform_track_->AddSink(sink, callback, is_secure, uses_alpha); callback.Run(media::VideoFrame::CreateBlackFrame(gfx::Size(1, 1)), /*estimated_capture_time=*/base::TimeTicks()); @@ -1576,7 +1576,7 @@ EXPECT_TRUE(tester.IsFulfilled()); } -TEST_F(ImageCaptureTest, GrabFrameOfMutedTrackIsFulfilled) { +TEST_F(ImageCaptureTest, GrabFrameOfMutedTrackRejects) { V8TestingScope scope; SetupTrackMocks(scope); track_->SetReadyState("live"); @@ -1587,7 +1587,7 @@ ScriptPromiseTester tester(scope.GetScriptState(), result); tester.WaitUntilSettled(); - EXPECT_TRUE(tester.IsFulfilled()); + EXPECT_TRUE(tester.IsRejected()); } TEST_F(ImageCaptureTest, GrabFrameOfEndedTrackRejects) {
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc index 45d0a1e8..7c6326de 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -1189,6 +1189,8 @@ task_runner_(task_runner), num_gl_errors_to_console_allowed_(kMaxGLErrorsAllowedToConsole), context_type_(context_type), + program_completion_queries_( + base::LRUCache<WebGLProgram*, GLuint>::NO_AUTO_EVICT), number_of_user_allocated_multisampled_renderbuffers_(0) { DCHECK(context_provider); @@ -9003,8 +9005,6 @@ visitor->Trace(texture_units_); visitor->Trace(extensions_); visitor->Trace(make_xr_compatible_resolver_); - visitor->Trace(program_completion_query_list_); - visitor->Trace(program_completion_query_map_); CanvasRenderingContext::Trace(visitor); } @@ -9059,45 +9059,33 @@ void WebGLRenderingContextBase::addProgramCompletionQuery(WebGLProgram* program, GLuint query) { - auto old_query = program_completion_query_map_.find(program); - if (old_query != program_completion_query_map_.end()) { - ContextGL()->DeleteQueriesEXT(1, &old_query->value); - // If this program's been inserted into the map already, then it - // exists in the list, too. Clear it out from there so that its - // new addition doesn't introduce a duplicate. - wtf_size_t old_index = program_completion_query_list_.Find(program); - DCHECK_NE(old_index, WTF::kNotFound); - program_completion_query_list_.EraseAt(old_index); + auto old_query = program_completion_queries_.Get(program); + if (old_query != program_completion_queries_.end()) { + ContextGL()->DeleteQueriesEXT(1, &old_query->second); } - program_completion_query_map_.Set(program, query); - program_completion_query_list_.push_back(program); - if (program_completion_query_map_.size() > kMaxProgramCompletionQueries) { - DCHECK_GT(program_completion_query_list_.size(), 0u); - WebGLProgram* program_to_remove = program_completion_query_list_[0]; - auto program_iter = program_completion_query_map_.find(program_to_remove); - DCHECK_NE(program_iter, program_completion_query_map_.end()); - ContextGL()->DeleteQueriesEXT(1, &program_iter->value); - program_completion_query_map_.erase(program_iter); - program_completion_query_list_.EraseAt(0); + program_completion_queries_.Put(program, query); + if (program_completion_queries_.size() > kMaxProgramCompletionQueries) { + auto oldest = program_completion_queries_.rbegin(); + ContextGL()->DeleteQueriesEXT(1, &oldest->second); + program_completion_queries_.Erase(oldest); } } void WebGLRenderingContextBase::clearProgramCompletionQueries() { - for (auto iter : program_completion_query_map_) { - ContextGL()->DeleteQueriesEXT(1, &iter.value); + for (auto query : program_completion_queries_) { + ContextGL()->DeleteQueriesEXT(1, &query.second); } - program_completion_query_map_.clear(); - program_completion_query_list_.clear(); + program_completion_queries_.Clear(); } bool WebGLRenderingContextBase::checkProgramCompletionQueryAvailable( WebGLProgram* program, bool* completed) { GLuint id = 0; - auto found = program_completion_query_map_.find(program); - if (found != program_completion_query_map_.end()) { - id = found->value; - GLuint available = 0; + auto found = program_completion_queries_.Get(program); + if (found != program_completion_queries_.end()) { + id = found->second; + GLuint available; ContextGL()->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE, &available); if (available) {
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h index 156224f3..771f4dc0 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
@@ -29,6 +29,7 @@ #include <memory> #include "base/check_op.h" +#include "base/containers/lru_cache.h" #include "base/memory/raw_ptr_exclusion.h" #include "base/numerics/checked_math.h" #include "base/task/single_thread_task_runner.h" @@ -57,8 +58,6 @@ #include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h" #include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h" #include "third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h" #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -2001,13 +2000,7 @@ bool checkProgramCompletionQueryAvailable(WebGLProgram* program, bool* completed); static constexpr unsigned int kMaxProgramCompletionQueries = 128u; - - // Support for KHR_parallel_shader_compile. - // - // TODO(crbug.com/1474141): once a HeapLinkedHashMap is available, - // convert these two fields to use that instead. - HeapVector<Member<WebGLProgram>> program_completion_query_list_; - HeapHashMap<Member<WebGLProgram>, GLuint> program_completion_query_map_; + base::LRUCache<WebGLProgram*, GLuint> program_completion_queries_; int number_of_user_allocated_multisampled_renderbuffers_;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 49037966..269acfd 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1623,13 +1623,6 @@ base_feature: "none", }, { - name: "FedCmAccountAutoSelectedFlag", - depends_on: ["FedCm"], - public: true, - status: "test", - base_feature: "none", - }, - { name: "FedCmAuthz", depends_on: ["FedCm"], public: true, @@ -1651,6 +1644,13 @@ base_feature: "none", }, { + name: "FedCmIdentityCredentialAutoSelectedFlag", + depends_on: ["FedCm"], + public: true, + status: "test", + base_feature: "none", + }, + { name: "FedCmIdPRegistration", depends_on: ["FedCm"], public: true,
diff --git a/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer.py b/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer.py index 91efe7c..3d96899c 100644 --- a/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer.py +++ b/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer.py
@@ -217,14 +217,13 @@ # Group ports to write less verbose output. skipped_ports_by_test = collections.defaultdict(list) for port in self._ports: - if self._skips_test(port, nonvirtual_test): - skipped_ports_by_test[nonvirtual_test].append(port) - continue search_path = self._baseline_search_path(port) nonvirtual_locations = [ self.location(path) for path in search_path ] - yield nonvirtual_locations + if not self._skips_test(port, nonvirtual_test): + skipped_ports_by_test[nonvirtual_test].append(port) + yield nonvirtual_locations for virtual_test in virtual_tests: if self._skips_test(port, virtual_test): skipped_ports_by_test[virtual_test].append(port)
diff --git a/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py b/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py index afae23b..6be5020 100644 --- a/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py +++ b/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py
@@ -141,33 +141,37 @@ directory_to_new_results, baseline_dirname='', suffix='txt', - options=None): + options=None, + virtual_suites=None): test_name = 'mock-test.html' baseline_name = 'mock-test-expected.' + suffix + virtual_suites = virtual_suites or [{ + 'prefix': + 'gpu', + 'platforms': ['Linux', 'Mac', 'Win'], + 'bases': [ + 'webexposed', + 'fast/canvas', + 'slow/canvas/mock-test.html', + 'virtual/virtual_empty_bases/', + ], + 'args': ['--foo'], + }, { + 'prefix': + 'virtual_empty_bases', + 'platforms': ['Linux', 'Mac', 'Win'], + 'bases': [], + 'args': ['--foo'], + }, { + 'prefix': + 'stable', + 'platforms': ['Linux', 'Mac', 'Win'], + 'bases': ['webexposed'], + 'args': ['--stable-release-mode'], + }] self.fs.write_text_file( self.finder.path_from_web_tests('VirtualTestSuites'), - json.dumps([{ - 'prefix': - 'gpu', - 'platforms': ['Linux', 'Mac', 'Win'], - 'bases': [ - 'webexposed', - 'fast/canvas', - 'slow/canvas/mock-test.html', - 'virtual/virtual_empty_bases/', - ], - 'args': ['--foo'], - }, { - 'prefix': 'virtual_empty_bases', - 'platforms': ['Linux', 'Mac', 'Win'], - 'bases': [], - 'args': ['--foo'], - }, { - 'prefix': 'stable', - 'platforms': ['Linux', 'Mac', 'Win'], - 'bases': ['webexposed'], - 'args': ['--stable-release-mode'], - }])) + json.dumps(virtual_suites)) self.fs.write_text_file( self.finder.path_from_web_tests('FlagSpecificConfig'), '[{"name": "highdpi", "args": ["--force-device-scale-factor=1.5"]}]' @@ -537,6 +541,37 @@ }, baseline_dirname='virtual/gpu/fast/canvas') + def test_exclusive_virtual_roots(self): + virtual_suites = [{ + 'prefix': 'gpu', + 'platforms': ['Linux', 'Mac', 'Win'], + 'bases': ['fast/canvas'], + 'exclusive_tests': ['fast/canvas'], + 'args': ['--foo'], + }, { + 'prefix': 'not-gpu', + 'platforms': ['Linux', 'Mac', 'Win'], + 'bases': ['fast/canvas'], + 'exclusive_tests': 'ALL', + 'args': ['--bar'], + }] + self._assert_optimization( + { + 'fast/canvas': '1', + 'platform/mac/virtual/gpu/fast/canvas': '1', + 'platform/win/virtual/gpu/fast/canvas': '1', + 'platform/mac/virtual/not-gpu/fast/canvas': '1', + 'platform/win/virtual/not-gpu/fast/canvas': '1', + }, { + 'fast/canvas': '1', + 'platform/mac/virtual/gpu/fast/canvas': None, + 'platform/win/virtual/gpu/fast/canvas': None, + 'platform/mac/virtual/not-gpu/fast/canvas': None, + 'platform/win/virtual/not-gpu/fast/canvas': None, + }, + baseline_dirname='fast/canvas', + virtual_suites=virtual_suites) + def test_all_pass_testharness_at_root(self): self._assert_optimization({'': ALL_PASS_TESTHARNESS_RESULT}, {'': None})
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 69974c14..d184d0b 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -725,21 +725,6 @@ "--disable-threaded-compositing", "--disable-threaded-animation"], "expires": "never" }, - "---------------------- New Base Url Inheritance Behavior -----------------", - "Some wpt tests are specific to the new base-url inheritance behavior,", - "namely that about:blank and about:srcdoc inherit their base urls from", - "their openers, and not their parents, and the inheritance is done using a", - "snapshot taken at the time the frame is navigated. This virtual test suite", - "is for tests that rely on the new behavior to pass.", - { - "prefix": "new-base-url-inheritance-behavior", - "platforms": ["Linux", "Mac", "Win"], - "bases": ["external/wpt/html/infrastructure/urls/base-url"], - "exclusive_tests": "ALL", - "args": ["--enable-features=NewBaseUrlInheritanceBehavior", - "--disable-threaded-compositing", "--disable-threaded-animation"], - "expires": "Sep 10, 2023" - }, "----------------------- origin-keyed agent clusters --------------------", "Origin-keyed agent clusters web platform tests are for the feature at",
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-account-auto-selected-flag.https.html.ini b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-account-auto-selected-flag.https.html.ini deleted file mode 100644 index 6103c4fa..0000000 --- a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-account-auto-selected-flag.https.html.ini +++ /dev/null
@@ -1,6 +0,0 @@ -[fedcm-account-auto-selected-flag.https.html] - expected: - if product == "chrome": [CRASH, ERROR, TIMEOUT] - [Test that the is_account_auto_selected bit is properly sent.] - expected: - if product == "chrome": TIMEOUT
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-basic.https.html b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-basic.https.html index d07c0de..ece63ca 100644 --- a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-basic.https.html +++ b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-basic.https.html
@@ -16,7 +16,7 @@ fedcm_test(async t => { const cred = await fedcm_get_and_select_first_account(t, request_options_with_mediation_required()); assert_equals(cred.token, "token"); - assert_equals(cred.isAccountAutoSelected, false); + assert_equals(cred.isIdentityCredentialAutoSelected, false); }, "Successfully obtaining token should resolve the promise."); </script>
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-account-auto-selected-flag.https.html b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-identity-credential-auto-selected-flag.https.html similarity index 70% rename from third_party/blink/web_tests/external/wpt/credential-management/fedcm-account-auto-selected-flag.https.html rename to third_party/blink/web_tests/external/wpt/credential-management/fedcm-identity-credential-auto-selected-flag.https.html index ac351559..188b6fe 100644 --- a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-account-auto-selected-flag.https.html +++ b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-identity-credential-auto-selected-flag.https.html
@@ -13,17 +13,17 @@ fedcm_get_and_select_first_account} from './support/fedcm-helper.sub.js'; fedcm_test(async t => { - let test_options = request_options_with_mediation_optional("manifest_with_account_auto_selected_flag.json"); + let test_options = request_options_with_mediation_optional("manifest_with_identity_credential_auto_selected_flag.json"); await select_manifest(t, test_options); let cred = await fedcm_get_and_select_first_account(t, test_options); - assert_equals(cred.token, "is_account_auto_selected=false"); + assert_equals(cred.token, "is_identity_credential_auto_selected=false"); - test_options = request_options_with_mediation_optional("manifest_with_account_auto_selected_flag.json"); + test_options = request_options_with_mediation_optional("manifest_with_identity_credential_auto_selected_flag.json"); await select_manifest(t, test_options); cred = await navigator.credentials.get(test_options); - assert_equals(cred.token, "is_account_auto_selected=true"); - assert_equals(cred.isAccountAutoSelected, true); -}, "Test that the is_account_auto_selected bit is properly sent."); + assert_equals(cred.token, "is_identity_credential_auto_selected=true"); + assert_equals(cred.isIdentityCredentialAutoSelected, true); +}, "Test that the is_identity_credential_auto_selected bit is properly sent."); </script>
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-identity-credential-auto-selected-flag.https.html.ini b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-identity-credential-auto-selected-flag.https.html.ini new file mode 100644 index 0000000..559df4d9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-identity-credential-auto-selected-flag.https.html.ini
@@ -0,0 +1,6 @@ +[fedcm-identity-credential-auto-selected-flag.https.html] + expected: + if product == "chrome": [CRASH, ERROR, TIMEOUT] + [Test that the is_identity_credential_auto_selected bit is properly sent.] + expected: + if product == "chrome": TIMEOUT
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-returning-account-auto-reauthn.https.html b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-returning-account-auto-reauthn.https.html index 38c07f0..d075730 100644 --- a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-returning-account-auto-reauthn.https.html +++ b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-returning-account-auto-reauthn.https.html
@@ -29,6 +29,6 @@ // "Jane" is a new user, the second account "John" will be selected. cred = await navigator.credentials.get(test_options); assert_equals(cred.token, "account_id=john_doe"); - assert_equals(cred.isAccountAutoSelected, true); + assert_equals(cred.isIdentityCredentialAutoSelected, true); }, "Test that the returning account from the two accounts will be auto re-authenticated."); </script>
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/manifest_with_account_auto_selected_flag.json b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/manifest_with_identity_credential_auto_selected_flag.json similarity index 60% rename from third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/manifest_with_account_auto_selected_flag.json rename to third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/manifest_with_identity_credential_auto_selected_flag.json index e3f38b79..1499804 100644 --- a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/manifest_with_account_auto_selected_flag.json +++ b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/manifest_with_identity_credential_auto_selected_flag.json
@@ -1,6 +1,6 @@ { "accounts_endpoint": "two_accounts.py", "client_metadata_endpoint": "client_metadata.py", - "id_assertion_endpoint": "token_with_account_auto_selected_flag.py", + "id_assertion_endpoint": "token_with_identity_credential_auto_selected_flag.py", "login_url": "signin.html" }
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_account_auto_selected_flag.py b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_account_auto_selected_flag.py deleted file mode 100644 index 6de26fe..0000000 --- a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_account_auto_selected_flag.py +++ /dev/null
@@ -1,12 +0,0 @@ -import importlib -error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check") - -def main(request, response): - request_error = error_checker.tokenCheck(request) - if (request_error): - return request_error - - response.headers.set(b"Content-Type", b"application/json") - - is_account_auto_selected = request.POST.get(b"is_account_auto_selected") - return "{\"token\": \"is_account_auto_selected=" + is_account_auto_selected.decode("utf-8") + "\"}"
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_identity_credential_auto_selected_flag.py b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_identity_credential_auto_selected_flag.py new file mode 100644 index 0000000..6fa579a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_identity_credential_auto_selected_flag.py
@@ -0,0 +1,12 @@ +import importlib +error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check") + +def main(request, response): + request_error = error_checker.tokenCheck(request) + if (request_error): + return request_error + + response.headers.set(b"Content-Type", b"application/json") + + is_identity_credential_auto_selected = request.POST.get(b"is_identity_credential_auto_selected") + return "{\"token\": \"is_identity_credential_auto_selected=" + is_identity_credential_auto_selected.decode("utf-8") + "\"}"
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-3-ref.html b/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-6-ref.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-3-ref.html rename to third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-6-ref.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-3.html b/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-6.html similarity index 94% rename from third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-3.html rename to third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-6.html index 8d14d5a..d74667c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-3.html +++ b/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-6.html
@@ -4,7 +4,7 @@ <meta charset="utf-8"> <title>CSS Masking: mask-clip: margin-box</title> <link rel="help" href="http://www.w3.org/TR/css-masking-1/#the-mask-clip"> - <link rel="match" href="mask-clip-3-ref.html"> + <link rel="match" href="mask-clip-6-ref.html"> <meta name="assert" content="mask-clip: margin-box should clip to the appropriate box."> <meta content="ahem" name="flags"> <link rel="stylesheet" href="/fonts/ahem.css" />
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-4-ref.html b/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-7-ref.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-4-ref.html rename to third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-7-ref.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-4.html b/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-7.html similarity index 95% rename from third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-4.html rename to third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-7.html index 170b8ec..1c0d8e1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-4.html +++ b/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-7.html
@@ -4,7 +4,7 @@ <meta charset="utf-8"> <title>CSS Masking: mask-clip: no-clip should not clip in the presence of border-radius</title> <link rel="help" href="http://www.w3.org/TR/css-masking-1/#the-mask-clip"> - <link rel="match" href="mask-clip-4-ref.html"> + <link rel="match" href="mask-clip-7-ref.html"> <meta name="assert" content="mask-clip: no-clip with border-radius should not clip."> <meta content="ahem" name="flags"> <link rel="stylesheet" href="/fonts/ahem.css" />
diff --git a/third_party/blink/web_tests/external/wpt/css/printing/media-queries-002-print.html b/third_party/blink/web_tests/external/wpt/css/printing/media-queries-002-print.html new file mode 100644 index 0000000..5f71f3d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/printing/media-queries-002-print.html
@@ -0,0 +1,6 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1491643"> +<link rel="match" href="reference/filled-green-100px-square-print-ref.html"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<iframe src="resources/mq-frame-100px.html" style="display:block; border:none; width:100px; height:100px; background:red;"></iframe>
diff --git a/third_party/blink/web_tests/external/wpt/css/printing/media-queries-003-print-ref.html b/third_party/blink/web_tests/external/wpt/css/printing/media-queries-003-print-ref.html new file mode 100644 index 0000000..99642ca56 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/printing/media-queries-003-print-ref.html
@@ -0,0 +1,7 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<style> + body { margin-right: 108px; } +</style> +<div style="position:absolute; right:0; bottom:0; width:100px; height:100px; background:green;"></div> +There should be a green square in the bottom right corner.
diff --git a/third_party/blink/web_tests/external/wpt/css/printing/media-queries-003-print.html b/third_party/blink/web_tests/external/wpt/css/printing/media-queries-003-print.html new file mode 100644 index 0000000..2c12529 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/printing/media-queries-003-print.html
@@ -0,0 +1,10 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1491643"> +<link rel="match" href="media-queries-003-print-ref.html"> +<frameset cols="*,100" rows="*,100" frameborder="0"> + <frame src="data:text/html,There should be a green square in the bottom right corner."></frame> + <frame src="data:text/html,"></frame> + <frame src="data:text/html,"></frame> + <frame src="resources/mq-frame-100px.html"></frame> +</frameset>
diff --git a/third_party/blink/web_tests/external/wpt/css/printing/reference/filled-green-100px-square-print-ref.html b/third_party/blink/web_tests/external/wpt/css/printing/reference/filled-green-100px-square-print-ref.html new file mode 100644 index 0000000..d4834d1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/printing/reference/filled-green-100px-square-print-ref.html
@@ -0,0 +1,4 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="width:100px; height:100px; background:green;"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/printing/resources/mq-frame-100px.html b/third_party/blink/web_tests/external/wpt/css/printing/resources/mq-frame-100px.html new file mode 100644 index 0000000..ed823c0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/printing/resources/mq-frame-100px.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<style> +body { + margin: 0; +} +div { + background: red; +} +@media (width: 100px) and (height: 100px) { + div { + background: green; + } +} +</style> +<div style="height:100px;"></div>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.stroke.prune.ellipse.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.stroke.prune.ellipse.html deleted file mode 100644 index d5550793..0000000 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.stroke.prune.ellipse.html +++ /dev/null
@@ -1,38 +0,0 @@ -<!DOCTYPE html> -<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>Canvas test: 2d.path.stroke.prune.ellipse</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/html/canvas/resources/canvas-tests.js"></script> -<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> -<body class="show_output"> - -<h1>2d.path.stroke.prune.ellipse</h1> -<p class="desc">Zero-length full ellipse are removed before stroking with miters</p> - - -<p class="output">Actual output:</p> -<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> -<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt=""> -<ul id="d"></ul> -<script> -var t = async_test("Zero-length full ellipse are removed before stroking with miters"); -_addTest(function(canvas, ctx) { - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 100; - ctx.lineCap = 'round'; - ctx.lineJoin = 'round'; - - ctx.beginPath(); - ctx.ellipse(25, 25, 0, 0, 0, 0, 2 * Math.PI); - ctx.stroke(); - - _assertPixel(canvas, 50,25, 0,255,0,255); - -}); -</script> -
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.stroke.prune.ellipse.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.stroke.prune.ellipse.html deleted file mode 100644 index 5eea854..0000000 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.stroke.prune.ellipse.html +++ /dev/null
@@ -1,39 +0,0 @@ -<!DOCTYPE html> -<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>OffscreenCanvas test: 2d.path.stroke.prune.ellipse</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/html/canvas/resources/canvas-tests.js"></script> - -<h1>2d.path.stroke.prune.ellipse</h1> -<p class="desc">Zero-length full ellipse are removed before stroking with miters</p> - - -<script> -var t = async_test("Zero-length full ellipse are removed before stroking with miters"); -var t_pass = t.done.bind(t); -var t_fail = t.step_func(function(reason) { - throw reason; -}); -t.step(function() { - - var canvas = new OffscreenCanvas(100, 50); - var ctx = canvas.getContext('2d'); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 100; - ctx.lineCap = 'round'; - ctx.lineJoin = 'round'; - - ctx.beginPath(); - ctx.ellipse(25, 25, 0, 0, 0, 0, 2 * Math.PI); - ctx.stroke(); - - _assertPixel(canvas, 50,25, 0,255,0,255); - t.done(); - -}); -</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.stroke.prune.ellipse.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.stroke.prune.ellipse.worker.js deleted file mode 100644 index a1fbabd..0000000 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/path-objects/2d.path.stroke.prune.ellipse.worker.js +++ /dev/null
@@ -1,34 +0,0 @@ -// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -// OffscreenCanvas test in a worker:2d.path.stroke.prune.ellipse -// Description:Zero-length full ellipse are removed before stroking with miters -// Note: - -importScripts("/resources/testharness.js"); -importScripts("/html/canvas/resources/canvas-tests.js"); - -var t = async_test("Zero-length full ellipse are removed before stroking with miters"); -var t_pass = t.done.bind(t); -var t_fail = t.step_func(function(reason) { - throw reason; -}); -t.step(function() { - - var canvas = new OffscreenCanvas(100, 50); - var ctx = canvas.getContext('2d'); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 100; - ctx.lineCap = 'round'; - ctx.lineJoin = 'round'; - - ctx.beginPath(); - ctx.ellipse(25, 25, 0, 0, 0, 0, 2 * Math.PI); - ctx.stroke(); - - _assertPixel(canvas, 50,25, 0,255,0,255); - t.done(); -}); -done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/path-objects.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/path-objects.yaml index fab92b9..eec142c 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/path-objects.yaml +++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/path-objects.yaml
@@ -2853,23 +2853,6 @@ @assert pixel 50,25 == 0,255,0,255; expected: green -- name: 2d.path.stroke.prune.ellipse - desc: Zero-length full ellipse are removed before stroking with miters - code: | - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 100; - ctx.lineCap = 'round'; - ctx.lineJoin = 'round'; - - ctx.beginPath(); - ctx.ellipse(25, 25, 0, 0, 0, 0, 2 * Math.PI); - ctx.stroke(); - - @assert pixel 50,25 == 0,255,0,255; - expected: green - name: 2d.path.transformation.basic code: |
diff --git a/third_party/blink/web_tests/fast/scroll-behavior/smooth-scroll/clamp-scroll-offset-if-size-changes-during-animation.html b/third_party/blink/web_tests/fast/scroll-behavior/smooth-scroll/clamp-scroll-offset-if-size-changes-during-animation.html index 8a51c745..18a999c 100644 --- a/third_party/blink/web_tests/fast/scroll-behavior/smooth-scroll/clamp-scroll-offset-if-size-changes-during-animation.html +++ b/third_party/blink/web_tests/fast/scroll-behavior/smooth-scroll/clamp-scroll-offset-if-size-changes-during-animation.html
@@ -1,6 +1,4 @@ <!DOCTYPE html> -<link rel="help" href="https://drafts.csswg.org/css-scroll-snap-1" /> -<link rel="stylesheet" href="resources/simple-snap.css"> <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> <script src="../../../resources/gesture-util.js"></script> @@ -12,17 +10,13 @@ <script> var scroller = document.getElementById("scroller"); -function scrollTop() { - return scroller.scrollTop; -} - promise_test (async () => { - scroller.scrollTo(0, 0); + const scrollendPromise = waitForScrollendEvent(scroller); scroller.scrollTo({top: 1500, behavior: 'smooth'}); scroller.style.height = "1000px"; - await waitForAnimationEnd(scrollTop, 500, 15); - var expected = 2000 - scroller.clientHeight; + await scrollendPromise; + var expected = scroller.scrollHeight - scroller.clientHeight; assert_equals(scroller.scrollTop, expected); }, "Clamps the scroll offset if the scroller's size is changed during animation."); -</script> \ No newline at end of file +</script>
diff --git a/third_party/blink/web_tests/fast/scrolling/fractional-scroll-height-chaining.html b/third_party/blink/web_tests/fast/scrolling/fractional-scroll-height-chaining.html index 5a8e44ec..0fb249d 100644 --- a/third_party/blink/web_tests/fast/scrolling/fractional-scroll-height-chaining.html +++ b/third_party/blink/web_tests/fast/scrolling/fractional-scroll-height-chaining.html
@@ -3,36 +3,57 @@ <script src="../../resources/testharness.js"></script> <script src="../../resources/testharnessreport.js"></script> <script src="../../virtual/percent-based-scrolling/resources/percent-based-util.js"></script> +<script src="../../resources/testdriver.js"></script> +<script src="../../resources/testdriver-actions.js"></script> +<script src="../../resources/testdriver-vendor.js"></script> <style> #scroller { - background-color: #ccc; - margin-top: 20px; - overflow: scroll; + background-color: #ccc; + margin-top: 20px; + overflow: scroll; } #fracheight { - height: 1200.3px; + height: 1200.3px; } </style> -<div id="scroller" onmousewheel=""> +<div id="scroller"> <div id="fracheight"></div> </div> <script> +function accumulateWheelScrollDelta() { + return new Promise((resolve, reject) => { + let scrollAmount = 0; + const scrollendListener = () => { + if (!scrollAmount) { + reject('Expected wheel scroll'); + } else { + resolve(scrollAmount); + } + }; + const wheelListener = (event) => { + scrollAmount += event.deltaY; + }; + document.addEventListener('scrollend', scrollendListener); + document.addEventListener('wheel', wheelListener); + }); +} + promise_test(async () => { await waitForCompositorCommit(); - var scroller_element = document.getElementById("scroller"); - var scroller_center = pointInElement(scroller_element, 50, 50); - await mouseClickOn(50, 50); - await wheelTick(0, 1, scroller_center); - await waitForAnimationEndTimeBased(() => { return window.scrollY }); - - const pixelsToScrollY = pixelsPerTick(); - const { y: expectedScrollY } = calculateExpectedScroll( - document.scrollingElement, 0, pixelsToScrollY - ); - assert_approx_equals(window.scrollY, expectedScrollY, 0.001); + const scroller = document.getElementById("scroller"); + const center = pointInElement(scroller, 50, 50); + // Scroll 1 tick. The actual scroll amount may differ if percent-based + // scrolling is enabled. + const adjustedPixelsPerTick = calculateExpectedScroll( + document.scrollingElement, 0, pixelsPerTick()).y; + const scrollAccumulator = accumulateWheelScrollDelta(); + await wheelScroll(center.x, center.y, 0, adjustedPixelsPerTick); + const scrollDelta = await scrollAccumulator; + assert_approx_equals(window.scrollY, scrollDelta, 0.01); + assert_approx_equals(window.scrollY, adjustedPixelsPerTick, 0.01); }, "Verify that wheel scrolls chain correctly from a fractional-height scroller to its parent."); </script>
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png deleted file mode 100644 index 866c3af9..0000000 --- a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png deleted file mode 100644 index caf265b..0000000 --- a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/inspector-protocol/css/css-style-sheet-events.js b/third_party/blink/web_tests/inspector-protocol/css/css-style-sheet-events.js index 1309226..51d02c33 100644 --- a/third_party/blink/web_tests/inspector-protocol/css/css-style-sheet-events.js +++ b/third_party/blink/web_tests/inspector-protocol/css/css-style-sheet-events.js
@@ -1,5 +1,5 @@ (async function(testRunner) { - var {page, session, dp} = await testRunner.startHTML(` + const {session, dp} = await testRunner.startHTML(` <style> #test { box-sizing: border-box; @@ -13,9 +13,8 @@ await cssHelper.requestDocumentNodeId(); // Add Event - const addEventPromise = dp.CSS.onceStyleSheetAdded(); - await dp.CSS.enable(); - const addEvent = await addEventPromise; + dp.CSS.enable(); + const addEvent = await dp.CSS.onceStyleSheetAdded(); testRunner.log(addEvent, '', [ ...TestRunner.stabilizeNames, 'length' ]); const styleSheetId = addEvent.params.header.styleSheetId; @@ -39,7 +38,9 @@ testRunner.log(addEventAfterChange, '', [ ...TestRunner.stabilizeNames, 'length' ]); // Remove event - await dp.Page.navigate({url: 'about:blank'}); + session.evaluate(` + [...document.head.getElementsByTagName('style')].forEach(item => item.remove()) + `); const removeEvent = await dp.CSS.onceStyleSheetRemoved(); testRunner.log(removeEvent); testRunner.completeTest();
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png deleted file mode 100644 index 6b1299d..0000000 --- a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/platform/mac-mac11/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png deleted file mode 100644 index 6b1299d..0000000 --- a/third_party/blink/web_tests/platform/mac-mac11/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png deleted file mode 100644 index 6b1299d..0000000 --- a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/platform/mac-mac12/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png deleted file mode 100644 index 6b1299d..0000000 --- a/third_party/blink/web_tests/platform/mac-mac12/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png deleted file mode 100644 index 6b1299d..0000000 --- a/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.txt b/third_party/blink/web_tests/platform/win/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.txt deleted file mode 100644 index cb9b046..0000000 --- a/third_party/blink/web_tests/platform/win/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -CONSOLE ERROR: Uncaught ReferenceError: test_driver is not defined -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/platform/win10/virtual/attribution-reporting-debug-mode/wpt_internal/attribution-reporting/source-registration.sub.https_method=a_eligible-expected.txt b/third_party/blink/web_tests/platform/win10/virtual/attribution-reporting-debug-mode/wpt_internal/attribution-reporting/source-registration.sub.https_method=a_eligible-expected.txt deleted file mode 100644 index 5cbe11f..0000000 --- a/third_party/blink/web_tests/platform/win10/virtual/attribution-reporting-debug-mode/wpt_internal/attribution-reporting/source-registration.sub.https_method=a_eligible-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -PASS Source registration succeeds. -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/win10/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/platform/win10/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png deleted file mode 100644 index 1ead4e4..0000000 --- a/third_party/blink/web_tests/platform/win10/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win10/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/platform/win10/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png deleted file mode 100644 index a7d3eb1..0000000 --- a/third_party/blink/web_tests/platform/win10/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/virtual/fenced-frame-mparch/external/wpt/html/anonymous-iframe/fenced-frame.tentative.https.window-expected.txt b/third_party/blink/web_tests/virtual/fenced-frame-mparch/external/wpt/html/anonymous-iframe/fenced-frame.tentative.https.window-expected.txt deleted file mode 100644 index eaeda73..0000000 --- a/third_party/blink/web_tests/virtual/fenced-frame-mparch/external/wpt/html/anonymous-iframe/fenced-frame.tentative.https.window-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL FencedFrame within a credentialless iframe is not credentialless assert_true: Fenced frame cannot be created. expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/virtual/new-base-url-inheritance-behavior/README.md b/third_party/blink/web_tests/virtual/new-base-url-inheritance-behavior/README.md deleted file mode 100644 index b9cc53a..0000000 --- a/third_party/blink/web_tests/virtual/new-base-url-inheritance-behavior/README.md +++ /dev/null
@@ -1,8 +0,0 @@ -Tests for the NewBaseUrlInheritanceBehavior feature. - -This feature changes the manner in which fallback base urls are inherited, -snapshotting them from the frame's opener (at time of creation/navigation) -instead of from the frame's parent. - -Some tests require the feature to be enabled in order to work, and hence -must be run in this virtual test suite to operate as intended.
diff --git a/third_party/blink/web_tests/virtual/new-base-url-inheritance-behavior/external/wpt/html/infrastructure/urls/base-url/README.txt b/third_party/blink/web_tests/virtual/new-base-url-inheritance-behavior/external/wpt/html/infrastructure/urls/base-url/README.txt deleted file mode 100644 index b75eb949..0000000 --- a/third_party/blink/web_tests/virtual/new-base-url-inheritance-behavior/external/wpt/html/infrastructure/urls/base-url/README.txt +++ /dev/null
@@ -1,5 +0,0 @@ -Base url tests for the NewBaseUrlInheritanceBehavior feature. - -This directory is for WPT tests verifying correct inheritance of base urls -with the NewBaseUrlInheritanceBehavior feature enabled. -
diff --git a/third_party/blink/web_tests/platform/win/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/blink/web_tests/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png similarity index 100% rename from third_party/blink/web_tests/platform/win/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png rename to third_party/blink/web_tests/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.txt b/third_party/blink/web_tests/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.txt index 43e5eeed..cb9b046 100644 --- a/third_party/blink/web_tests/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.txt +++ b/third_party/blink/web_tests/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.txt
@@ -1,3 +1,4 @@ +CONSOLE ERROR: Uncaught ReferenceError: test_driver is not defined PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/blink/web_tests/platform/win/virtual/scalefactor150/fast/hidpi/static/popup-menu-appearance-expected.png b/third_party/blink/web_tests/virtual/scalefactor150/fast/hidpi/static/popup-menu-appearance-expected.png similarity index 100% rename from third_party/blink/web_tests/platform/win/virtual/scalefactor150/fast/hidpi/static/popup-menu-appearance-expected.png rename to third_party/blink/web_tests/virtual/scalefactor150/fast/hidpi/static/popup-menu-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/scalefactor150/fast/hidpi/static/popup-menu-with-scrollbar-appearance-expected.png b/third_party/blink/web_tests/virtual/scalefactor150/fast/hidpi/static/popup-menu-with-scrollbar-appearance-expected.png similarity index 100% rename from third_party/blink/web_tests/platform/win/virtual/scalefactor150/fast/hidpi/static/popup-menu-with-scrollbar-appearance-expected.png rename to third_party/blink/web_tests/virtual/scalefactor150/fast/hidpi/static/popup-menu-with-scrollbar-appearance-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png similarity index 100% rename from third_party/blink/web_tests/platform/win/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png rename to third_party/blink/web_tests/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/shared-storage-fenced-frame-mparch/http/tests/inspector-protocol/storage/shared-storage-delete-expected.txt b/third_party/blink/web_tests/virtual/shared-storage-fenced-frame-mparch/http/tests/inspector-protocol/storage/shared-storage-delete-expected.txt deleted file mode 100644 index 4b59107..0000000 --- a/third_party/blink/web_tests/virtual/shared-storage-fenced-frame-mparch/http/tests/inspector-protocol/storage/shared-storage-delete-expected.txt +++ /dev/null
@@ -1,84 +0,0 @@ -Tests shared storage item deletion & clearing via devtools. -Metadata: { - creationTime : <number> - length : 3 - remainingBudget : 12 -} -Entries:[ - [0] : { - key : key0-set-from-document - value : value0 - } - [1] : { - key : key1-set-from-document - value : value1value1 - } - [2] : { - key : key2-set-from-document - value : value2 - } -] -Delete an existing entry via devtools -Delete a non-existing entry via devtools -Metadata: { - creationTime : <number> - length : 2 - remainingBudget : 12 -} -Entries:[ - [0] : { - key : key0-set-from-document - value : value0 - } - [1] : { - key : key1-set-from-document - value : value1value1 - } -] -Clear entries via devtools -undefined -Entries:[ -] -Events: [ - [0] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key0-set-from-document - value : value0 - } - type : documentSet - } - [1] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key1-set-from-document - value : value1 - } - type : documentSet - } - [2] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key1-set-from-document - value : value1 - } - type : documentAppend - } - [3] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key2-set-from-document - value : value2 - } - type : documentSet - } -] -
diff --git a/third_party/blink/web_tests/virtual/shared-storage-fenced-frame-mparch/http/tests/inspector-protocol/storage/shared-storage-expected.txt b/third_party/blink/web_tests/virtual/shared-storage-fenced-frame-mparch/http/tests/inspector-protocol/storage/shared-storage-expected.txt deleted file mode 100644 index e4f33a43..0000000 --- a/third_party/blink/web_tests/virtual/shared-storage-fenced-frame-mparch/http/tests/inspector-protocol/storage/shared-storage-expected.txt +++ /dev/null
@@ -1,246 +0,0 @@ -Tests shared storage event tracking & fetching of entries/metadata. -Metadata: { - creationTime : <number> - length : 4 - remainingBudget : 12 -} -Entries:[ - [0] : { - key : key0-set-from-document - value : value0 - } - [1] : { - key : key0-set-from-worklet - value : value0 - } - [2] : { - key : key1-set-from-document - value : value1value1 - } - [3] : { - key : key1-set-from-worklet - value : value1value1 - } -] -Clear entries -undefined -Entries:[ -] -Events: [ - [0] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key0-set-from-document - value : value0 - } - type : documentSet - } - [1] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key1-set-from-document - value : value1 - } - type : documentSet - } - [2] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key1-set-from-document - value : value1 - } - type : documentAppend - } - [3] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key2-set-from-document - value : value2 - } - type : documentSet - } - [4] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key2-set-from-document - } - type : documentDelete - } - [5] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - scriptSourceUrl : http://127.0.0.1:8000/inspector-protocol/resources/shared-storage-module.js - } - type : documentAddModule - } - [6] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - operationName : test-operation - serializedData : - } - type : documentRun - } - [7] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key0-set-from-worklet - value : value0 - } - type : workletSet - } - [8] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key1-set-from-worklet - value : value1 - } - type : workletSet - } - [9] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key2-set-from-worklet - value : value2 - } - type : workletSet - } - [10] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key1-set-from-worklet - value : value1 - } - type : workletAppend - } - [11] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key2-set-from-worklet - } - type : workletDelete - } - [12] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - } - type : workletLength - } - [13] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - } - type : workletRemainingBudget - } - [14] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - } - type : workletKeys - } - [15] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - } - type : workletEntries - } - [16] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - operationName : test-url-selection-operation - serializedData : - urlsWithMetadata : [ - [0] : { - reportingMetadata : [ - ] - url : https://google.com/ - } - [1] : { - reportingMetadata : [ - ] - url : https://chromium.org/ - } - ] - } - type : documentSelectURL - } - [17] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key0-set-from-worklet - } - type : workletGet - } - [18] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - key : key0-set-from-document - } - type : workletGet - } - [19] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - operationName : clear-operation - serializedData : - } - type : documentRun - } - [20] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - } - type : workletClear - } - [21] : { - accessTime : <number> - mainFrameId : <string> - ownerOrigin : http://127.0.0.1:8000 - params : { - } - type : documentClear - } -] -
diff --git a/third_party/blink/web_tests/virtual/shared-storage-fenced-frame-mparch/http/tests/inspector-protocol/storage/shared-storage-set-expected.txt b/third_party/blink/web_tests/virtual/shared-storage-fenced-frame-mparch/http/tests/inspector-protocol/storage/shared-storage-set-expected.txt deleted file mode 100644 index 9e035fe..0000000 --- a/third_party/blink/web_tests/virtual/shared-storage-fenced-frame-mparch/http/tests/inspector-protocol/storage/shared-storage-set-expected.txt +++ /dev/null
@@ -1,37 +0,0 @@ -Tests shared storage item setting via devtools. -undefined -Entries:[ -] -Set entries via devtools -Metadata: { - creationTime : <number> - length : 6 - remainingBudget : 12 -} -Entries:[ - [0] : { - key : key0-set-from-devtools - value : value0 - } - [1] : { - key : key1-set-from-devtools - value : value1 - } - [2] : { - key : key2-set-from-devtools - value : value2 - } - [3] : { - key : key3-set-from-devtools - value : value3 - } - [4] : { - key : key4-set-from-devtools - value : overridden - } - [5] : { - key : key5-set-from-devtools - value : overridden - } -] -
diff --git a/third_party/blink/web_tests/virtual/shared-storage-fenced-frame-mparch/http/tests/inspector-protocol/storage/shared-storage-tracking-disabled-expected.txt b/third_party/blink/web_tests/virtual/shared-storage-fenced-frame-mparch/http/tests/inspector-protocol/storage/shared-storage-tracking-disabled-expected.txt deleted file mode 100644 index b7175a4..0000000 --- a/third_party/blink/web_tests/virtual/shared-storage-fenced-frame-mparch/http/tests/inspector-protocol/storage/shared-storage-tracking-disabled-expected.txt +++ /dev/null
@@ -1,19 +0,0 @@ -Tests disabling of shared storage event tracking. -Metadata: { - creationTime : <number> - length : 2 - remainingBudget : 12 -} -Entries:[ - [0] : { - key : key0-set-from-document - value : value0 - } - [1] : { - key : key1-set-from-document - value : value1value1 - } -] -Events: [ -] -
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 89ba3896..d26ab316 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
@@ -5248,7 +5248,7 @@ interface IdentityCredential : Credential static method logoutRPs attribute @@toStringTag - getter isAccountAutoSelected + getter isIdentityCredentialAutoSelected getter token method constructor interface IdentityCredentialError : DOMException
diff --git a/third_party/catapult b/third_party/catapult index 897e3d4..171b75b 160000 --- a/third_party/catapult +++ b/third_party/catapult
@@ -1 +1 @@ -Subproject commit 897e3d48d8fdc6057befd6d8251a6671d748c8b8 +Subproject commit 171b75b883c5d97e4daac2e0ab8a94f78645ef6c
diff --git a/third_party/cros_system_api b/third_party/cros_system_api index 8a20882..6600b60 160000 --- a/third_party/cros_system_api +++ b/third_party/cros_system_api
@@ -1 +1 @@ -Subproject commit 8a208829b3b80c26c66dec5a18ba2bcb64c69bee +Subproject commit 6600b606a8df2fe2b57caf436cc12083ff4beb4f
diff --git a/third_party/dawn b/third_party/dawn index 68e066a..8b28afe 160000 --- a/third_party/dawn +++ b/third_party/dawn
@@ -1 +1 @@ -Subproject commit 68e066a008e8097a8c7a77b27a1bef813ed69b5a +Subproject commit 8b28afe0df83ce011f2d92588d5770f6cf2f466a
diff --git a/third_party/depot_tools b/third_party/depot_tools index 0b94340..a51863b 160000 --- a/third_party/depot_tools +++ b/third_party/depot_tools
@@ -1 +1 @@ -Subproject commit 0b943400a45966122a123c27f4f290ab309d893a +Subproject commit a51863b2f82626587641543b60f249431c48d1ec
diff --git a/third_party/libunwind/src b/third_party/libunwind/src index 9ebf30f..7b1593d 160000 --- a/third_party/libunwind/src +++ b/third_party/libunwind/src
@@ -1 +1 @@ -Subproject commit 9ebf30f2a4f88d37644327ba0eb445d0aba05c02 +Subproject commit 7b1593d5caacf5d07faa5ef8535733ab51ad9bc8
diff --git a/third_party/mediapipe/BUILD.gn b/third_party/mediapipe/BUILD.gn index 4a26c554..d01bd98 100644 --- a/third_party/mediapipe/BUILD.gn +++ b/third_party/mediapipe/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("//third_party/flatbuffers/flatbuffer.gni") import("//third_party/protobuf/proto_library.gni") import("//third_party/tflite/features.gni") @@ -11,6 +12,13 @@ mediapipe_build_with_gpu_support = false } +# Generate a buildflag header for compile-time checking of MediaPipe GPU support. +buildflag_header("buildflags") { + header = "buildflags.h" + flags = + [ "MEDIAPIPE_BUILD_WITH_GPU_SUPPORT=$mediapipe_build_with_gpu_support" ] +} + action("stamp_metadata_parser_version") { script = "stamp_metadata_parser_version.py" @@ -422,19 +430,9 @@ sources += [ "src/mediapipe/util/resource_util_apple.cc" ] cflags = [ "-ObjC++" ] } else if (is_android) { - sources += [ - "src/mediapipe/java/com/google/mediapipe/framework/jni/jni_util.cc", - "src/mediapipe/java/com/google/mediapipe/framework/jni/jni_util.h", - "src/mediapipe/util/android/asset_manager_util.cc", - "src/mediapipe/util/android/asset_manager_util.h", - "src/mediapipe/util/android/file/base/file.cc", - "src/mediapipe/util/android/file/base/file.h", - "src/mediapipe/util/android/file/base/filesystem.cc", - "src/mediapipe/util/android/file/base/filesystem.h", - "src/mediapipe/util/android/file/base/helpers.cc", - "src/mediapipe/util/android/file/base/helpers.h", - "src/mediapipe/util/resource_util_android.cc", - ] + # This is by design - our Windows no-op implementation works for Android + # too, and in general we don't need this functionality. + sources += [ "src/mediapipe/util/resource_util_windows.cc" ] } else { sources += [ "src/mediapipe/util/resource_util_default.cc" ] } @@ -633,6 +631,7 @@ tflite_group("mediapipe") { public_deps = [ + ":buildflags", ":mediapipe_flatbuffer_schema", ":mediapipe_proto", ]
diff --git a/third_party/mediapipe/README.chromium b/third_party/mediapipe/README.chromium index 091f8550..ca575db 100644 --- a/third_party/mediapipe/README.chromium +++ b/third_party/mediapipe/README.chromium
@@ -2,7 +2,7 @@ Short Name: mediapipe URL: https://github.com/google/mediapipe Version: 6915a79e288afec408edc4bc3f851613200efb8f -Date: 2023/09/29 +Date: 2023-09-29 License: Apache 2.0 License File: LICENSE Security Critical: Yes @@ -118,3 +118,9 @@ &(const_cast<AnyLite*>(this)->value_)); return any_metadata.Is<T>(); } + +* dont-use-dedicated-context-for-some-calculators.patch - temporary patch that +is only needed when unit-testing with GPU support (not yet official). Will be +removed after MediaPipe w/ GPU is taught how to use Chromium's GL thread and +GL context instead of creating its own. +TODO(https://crbug.com/1492217): remove this patch once it is no longer needed.
diff --git a/third_party/mediapipe/patches/dont-use-dedicated-context-for-some-calculators.patch b/third_party/mediapipe/patches/dont-use-dedicated-context-for-some-calculators.patch new file mode 100644 index 0000000..94b5112 --- /dev/null +++ b/third_party/mediapipe/patches/dont-use-dedicated-context-for-some-calculators.patch
@@ -0,0 +1,27 @@ +From b50be3ef2ad96122ac6c3fb3a54f8a58c7d1c459 Mon Sep 17 00:00:00 2001 +From: Piotr Bialecki <bialpio@chromium.org> +Date: Wed, 11 Oct 2023 13:38:42 -0700 +Subject: [PATCH] MediaPipe: don't use dedicated context for some calculators + +--- + .../mediapipe/src/mediapipe/gpu/gpu_shared_data_internal.cc | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/third_party/mediapipe/src/mediapipe/gpu/gpu_shared_data_internal.cc b/third_party/mediapipe/src/mediapipe/gpu/gpu_shared_data_internal.cc +index b9b9c26f05dfa..1fa8135cc02a0 100644 +--- a/third_party/mediapipe/src/mediapipe/gpu/gpu_shared_data_internal.cc ++++ b/third_party/mediapipe/src/mediapipe/gpu/gpu_shared_data_internal.cc +@@ -129,9 +129,7 @@ absl::Status GpuResources::PrepareGpuNode(CalculatorNode* node) { + #ifndef __EMSCRIPTEN__ + // TODO Allow calculators to request a separate context. + // For now, allow a few calculators to run in their own context. +- bool gets_own_context = (node_type == "ImageFrameToGpuBufferCalculator") || +- (node_type == "GpuBufferToImageFrameCalculator") || +- (node_type == "GlSurfaceSinkCalculator"); ++ bool gets_own_context = false; + + const auto& options = + node->GetCalculatorState().Options<mediapipe::GlContextOptions>(); +-- +2.42.0.609.gbb76f46606-goog +
diff --git a/third_party/mediapipe/src/mediapipe/gpu/gpu_shared_data_internal.cc b/third_party/mediapipe/src/mediapipe/gpu/gpu_shared_data_internal.cc index b9b9c26f..1fa8135 100644 --- a/third_party/mediapipe/src/mediapipe/gpu/gpu_shared_data_internal.cc +++ b/third_party/mediapipe/src/mediapipe/gpu/gpu_shared_data_internal.cc
@@ -129,9 +129,7 @@ #ifndef __EMSCRIPTEN__ // TODO Allow calculators to request a separate context. // For now, allow a few calculators to run in their own context. - bool gets_own_context = (node_type == "ImageFrameToGpuBufferCalculator") || - (node_type == "GpuBufferToImageFrameCalculator") || - (node_type == "GlSurfaceSinkCalculator"); + bool gets_own_context = false; const auto& options = node->GetCalculatorState().Options<mediapipe::GlContextOptions>();
diff --git a/third_party/ml b/third_party/ml index 9797a09..338d9a5 160000 --- a/third_party/ml +++ b/third_party/ml
@@ -1 +1 @@ -Subproject commit 9797a0977fd4de5ca4398943e6a6a61fc3ac5180 +Subproject commit 338d9a5d1281e4e6059e36c7c2696ef2e6184174
diff --git a/third_party/openscreen/src b/third_party/openscreen/src index d0b32ca..f3cb605 160000 --- a/third_party/openscreen/src +++ b/third_party/openscreen/src
@@ -1 +1 @@ -Subproject commit d0b32cadd6ddc94646047ee93aff43db2470f9c0 +Subproject commit f3cb605aacaa61ea878363434572f67b68a6c8ed
diff --git a/third_party/opus/README.chromium b/third_party/opus/README.chromium index 8501358..9f2582f 100644 --- a/third_party/opus/README.chromium +++ b/third_party/opus/README.chromium
@@ -16,7 +16,7 @@ * copy .gitignore from https://git.xiph.org/?p=opus.git;a=tree * set 'x' flags: "chmod 750 win32/genversion.bat" * remove assertion messages in release builds (see crbug/1053572) -* add workaround to ignore some int-overflows when fuzzing (see crbug/1146174) +* add workaround to ignore some int-overflows when fuzzing (see crbug/1146174, crbug/1491812) Opus' own unit tests are located in ./src/tests Additional chromium tests are located in ./tests, and require chromium
diff --git a/third_party/opus/src/silk/x86/NSQ_del_dec_sse4_1.c b/third_party/opus/src/silk/x86/NSQ_del_dec_sse4_1.c index a58a76c..e8960088 100644 --- a/third_party/opus/src/silk/x86/NSQ_del_dec_sse4_1.c +++ b/third_party/opus/src/silk/x86/NSQ_del_dec_sse4_1.c
@@ -671,7 +671,11 @@ /* Update states */ psSS[ 0 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 ); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) + sLF_AR_shp_Q14 = silk_SUB32_ovflw( psSS[ 0 ].Diff_Q14, n_AR_Q14 ); +#else sLF_AR_shp_Q14 = silk_SUB32( psSS[ 0 ].Diff_Q14, n_AR_Q14 ); +#endif psSS[ 0 ].sLTP_shp_Q14 = silk_SUB_SAT32( sLF_AR_shp_Q14, n_LF_Q14 ); psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14; psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14; @@ -691,7 +695,11 @@ /* Update states */ psSS[ 1 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 ); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) + sLF_AR_shp_Q14 = silk_SUB32_ovflw( psSS[ 1 ].Diff_Q14, n_AR_Q14 ); +#else sLF_AR_shp_Q14 = silk_SUB32( psSS[ 1 ].Diff_Q14, n_AR_Q14 ); +#endif psSS[ 1 ].sLTP_shp_Q14 = silk_SUB_SAT32( sLF_AR_shp_Q14, n_LF_Q14 ); psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14; psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14;
diff --git a/third_party/pdfium b/third_party/pdfium index cdc2dda..6943be2 160000 --- a/third_party/pdfium +++ b/third_party/pdfium
@@ -1 +1 @@ -Subproject commit cdc2dda5a9576ca869b1a3d7c2104edb45187319 +Subproject commit 6943be26ed4071a12bef21c27ff0f590d82ccbc9
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 37efa04..98e28f4 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -7785,6 +7785,18 @@ <description>The cookie controls UI was opened.</description> </action> +<action name="CookieControls.Bubble.ReloadingShown"> + <owner>kmg@google.com</owner> + <owner>fmacintosh@google.com</owner> + <description>The reloading bubble is shown.</description> +</action> + +<action name="CookieControls.Bubble.ReloadingTimeout"> + <owner>kmg@google.com</owner> + <owner>fmacintosh@google.com</owner> + <description>The reloading bubble closed after a timeout.</description> +</action> + <action name="CookieControls.Bubble.SendFeedback"> <owner>boujane@google.com</owner> <owner>sauski@google.com</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 9192f4a..7988343 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -63871,6 +63871,8 @@ <int value="-625858826" label="EnableDuplicateDownloadDialog:disabled"/> <int value="-625531491" label="CrOSSuspendToDisk:disabled"/> <int value="-625520587" label="RequestDesktopSiteGlobal:enabled"/> + <int value="-624652131" + label="FedCmIdentityCredentialAutoSelectedFlag:disabled"/> <int value="-624221121" label="CommandLineOnNonRooted:enabled"/> <int value="-623611759" label="TabSelectionEditorV2:enabled"/> <int value="-623364791" label="ClickToCallReceiver:disabled"/> @@ -64098,6 +64100,8 @@ <int value="-514581113" label="OobeSimon:disabled"/> <int value="-514076866" label="MovablePartialScreenshot:disabled"/> <int value="-513967943" label="CryptAuthV2Enrollment:disabled"/> + <int value="-513459348" + label="FedCmIdentityCredentialAutoSelectedFlag:enabled"/> <int value="-513305102" label="LanguagesPreference:enabled"/> <int value="-513066193" label="SyncUSSPasswords:enabled"/> <int value="-512971943" label="disable-one-copy"/> @@ -72172,6 +72176,12 @@ <int value="2" label="Headset Unplugged"/> </enum> +<enum name="MediaSessionEnterPictureInPictureType"> + <int value="0" label="Default Handler"/> + <int value="1" label="Registered Manual"/> + <int value="2" label="Registered Automatic"/> +</enum> + <enum name="MediaSessionSuspendedSource"> <int value="0" label="System Transient"/> <int value="1" label="System Permanent"/> @@ -80112,6 +80122,8 @@ <int value="6" label="HEADER"/> <int value="7" label="TILE_NAVSUGGEST"/> <int value="8" label="PEDAL_SUGGESTION"/> + <int value="9" label="DIVIDER_LINE"/> + <int value="10" label="QUERY_TILES"/> </enum> <enum name="OmniboxSuggestRequests">
diff --git a/tools/metrics/histograms/metadata/content/histograms.xml b/tools/metrics/histograms/metadata/content/histograms.xml index b2e7b82..dad9368a 100644 --- a/tools/metrics/histograms/metadata/content/histograms.xml +++ b/tools/metrics/histograms/metadata/content/histograms.xml
@@ -930,7 +930,7 @@ </histogram> <histogram name="ContentSuggestions.Feed.ContentLifetime.StaleAge" units="ms" - expires_after="2023-11-19"> + expires_after="2024-01-21"> <owner>birnie@google.com</owner> <owner>feed@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml index b58919a..dc944c2 100644 --- a/tools/metrics/histograms/metadata/ios/histograms.xml +++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -547,6 +547,29 @@ </summary> </histogram> +<histogram name="IOS.DefaultBrowserPromo.DaysSinceLastPromoInteraction" + units="count" expires_after="2024-02-04"> + <owner>gayane@google.com</owner> + <owner>bling-get-set-up@google.com</owner> + <summary> + Represents number of days since last default browser promo was displayed + within last 21 days periods. This includes full screen and non-modal promo + and default browser promo in FRE. Recorded before every full screen promo + displayed. + </summary> +</histogram> + +<histogram name="IOS.DefaultBrowserPromo.GenericPromoDisplayCount" + units="count" expires_after="2024-02-04"> + <owner>gayane@google.com</owner> + <owner>bling-get-set-up@google.com</owner> + <summary> + Represents number of generic default browser promos displayed to the user. + This includes all video promo options. Recorded before every full screen + promo displayed. + </summary> +</histogram> + <histogram name="IOS.DefaultBrowserPromo.NonModal.OnScreenTime" units="ms" expires_after="2024-02-04"> <owner>sebsg@chromium.org</owner> @@ -612,6 +635,16 @@ <summary>The default browser promo type shown to the user.</summary> </histogram> +<histogram name="IOS.DefaultBrowserPromo.TailoredPromoDisplayCount" + units="count" expires_after="2024-02-04"> + <owner>gayane@google.com</owner> + <owner>bling-get-set-up@google.com</owner> + <summary> + Represents number of tailored default browser promos displayed to the user. + Recorded before every full screen promo displayed. + </summary> +</histogram> + <histogram name="IOS.DefaultBrowserPromo.{PromoAction}.{PromoStat}" units="count" expires_after="2023-12-01"> <owner>gayane@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml index e47151d..69c3b05 100644 --- a/tools/metrics/histograms/metadata/media/histograms.xml +++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -5201,6 +5201,18 @@ </summary> </histogram> +<histogram name="Media.Session.EnterPictureInPicture" + enum="MediaSessionEnterPictureInPictureType" expires_after="2024-04-30"> + <owner>steimel@chromium.org</owner> + <owner>media-dev-uma@chromium.org</owner> + <summary> + Recorded when EnterPictureInPicture or EnterAutoPictureInPicture is called + on a MediaSessionImpl. Records why picture-in-picture was triggered (whether + it was for the default handler or a website-provided one, and whether the + trigger was manual or automatic). + </summary> +</histogram> + <histogram name="Media.Session.Play" enum="MediaSessionActionSource" expires_after="2024-03-03"> <owner>steimel@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/settings/histograms.xml b/tools/metrics/histograms/metadata/settings/histograms.xml index 705c9ab2..23717aa 100644 --- a/tools/metrics/histograms/metadata/settings/histograms.xml +++ b/tools/metrics/histograms/metadata/settings/histograms.xml
@@ -1092,6 +1092,27 @@ </summary> </histogram> +<histogram name="Settings.TrackingProtection.BlockAllThirdParty" enum="Boolean" + expires_after="2024-09-30"> + <owner>fmacintosh@google.com</owner> + <owner>koilos@google.com</owner> + <summary> + Records the state of the pref that represents whether the user has chosen to + block all third-party cookies on the Tracking Protection settings page. + Logged on startup. + </summary> +</histogram> + +<histogram name="Settings.TrackingProtection.Enabled" enum="BooleanEnabled" + expires_after="2024-09-30"> + <owner>fmacintosh@google.com</owner> + <owner>koilos@google.com</owner> + <summary> + Records the state of the pref that represents whether the user has the new + Tracking Protection prefs and UX. Logged on startup. + </summary> +</histogram> + <histogram name="Settings.TrackingProtection.Redirect" enum="BooleanRedirected" expires_after="2024-12-30"> <owner>fmacintosh@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/startup/histograms.xml b/tools/metrics/histograms/metadata/startup/histograms.xml index c66fffd..668325c1 100644 --- a/tools/metrics/histograms/metadata/startup/histograms.xml +++ b/tools/metrics/histograms/metadata/startup/histograms.xml
@@ -227,16 +227,22 @@ </histogram> <histogram name="Startup.Android.Cold.TimeToFirstVisibleContent2" units="ms" - expires_after="2024-02-04"> + expires_after="never"> +<!-- expires-never: guiding metric (internal: go/chrome-browser-guiding-metrics) --> + <owner>yfriedman@chromium.org</owner> <owner>pasko@chromium.org</owner> <owner>fredmello@chromium.org</owner> + <owner>chrome-analysis-team@google.com</owner> <summary> The time from Chrome tabbed activity creation to the moment the Chrome first appears ready. This metrics has the same semantics as Startup.Android.Cold.TimeToFirstVisibleContent, without the known bug. + + This histogram is of special interest to the chrome-analysis-team@. Do not + change its semantics or retire it without talking to them first. </summary> </histogram> @@ -278,6 +284,55 @@ </summary> </histogram> +<histogram name="Startup.Android.Experimental.{name}.Tabbed.{suffix}" + units="ms" expires_after="2024-08-25"> + <owner>pasko@chromium.org</owner> + <owner>mthiesse@chromium.org</owner> + <owner>yfriedman@chromium.org</owner> + <summary> + The time from activity creation on a cold start to the {name} happening in + this activity. Cold start is determined by whether the {suffix}. + + Recorded only for tabbed activity and on cold starts. Therefore it cannot be + recorded more than once in the application lifetime. + + Similarly to Startup.Android.Cold.TimeToFirstVisibleContent2 omits recording + a sample: + + 1. when the first Activity is a CCT/WebAPK/TWA, + + 2. when an error page is committed, + + 3. for non-http(s) pages, + + 4. for downloads, + + 5. when another activity was shown and hidden before the first navigation + committed, + + 6. when the first navigation was preceded by showing a NTP (New Tab Page). + + For cold start detection based on process creation reason (suffix + .ColdStartTracker) it is recommended to limit analysis of data on the UMA + dashboard to Android P+ because on prior versions the cold start detection + is time-based and therefore less robust. + + TODO(pasko): Rename the suffix when graduating these histograms out of + experimental. The preference is to avoid Java class names in metric names. + </summary> + <token key="name"> + <variant name="FirstContentfulPaint" + summary="first contentful paint (FCP)"/> + <variant name="FirstNavigationCommit" summary="first navigation commit"/> + </token> + <token key="suffix"> + <variant name="ActivityCreatedWhileInit" + summary="activity was created before post-inflation"/> + <variant name="ColdStartTracker" + summary="process creation reason is Activity"/> + </token> +</histogram> + <histogram base="true" name="Startup.Android.FeedContentFirstLoadedTime" units="ms" expires_after="2023-11-12"> <!-- Name completed by histogram_suffixes name="JavaStartMode" -->
diff --git a/tools/metrics/histograms/metadata/uma/histograms.xml b/tools/metrics/histograms/metadata/uma/histograms.xml index 7f2b9c0..eeeefa5 100644 --- a/tools/metrics/histograms/metadata/uma/histograms.xml +++ b/tools/metrics/histograms/metadata/uma/histograms.xml
@@ -90,17 +90,22 @@ </summary> </histogram> -<histogram name="UMA.AndroidPreNative.ChromeActivityCounter" - enum="ChromeActivityCounter" expires_after="2024-04-24"> +<histogram name="UMA.AndroidPreNative.ChromeActivityCounter2" + enum="ChromeActivityCounter" expires_after="2024-10-04"> <owner>gabrielgs@google.com</owner> <owner>src/base/metrics/OWNERS</owner> <summary> - Counts of how many times onPreCreate() and onResume() were called (from the + Counts of how many times onPostCreate() and onResume() were called (from the ChromeActivity class) when a foreground session begins in the native C++ code. The counters are reset when this histogram is emitted. This histogram is a diagnostic tool for understanding Clank short sessions, by capturing some information about the cases where Java code starts up, but native C++ code is never reached. + + This replaces UMA.AndroidPreNative.ChromeActivityCounter, which would + increment the counters to P1R0 on first-run-experience, but would not + advance to native code. This version circumvents the issue by waiting to be + sure that onCreate was not aborted (see AsyncInitializationActivity). </summary> </histogram>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 8fca514..4395c34 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,7 +6,7 @@ }, "win": { "hash": "fa50ded64dec073b47c21db45c18b35fb4908621", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/0bb49ab54dbe55ce5b9dfea3a2ada68b87aecb65/trace_processor_shell.exe" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/58e677929fd423df1885041a1a01c36431872696/trace_processor_shell.exe" }, "linux_arm": { "hash": "bb52a6e014d9272dc4784b1678eee77075df1a86", @@ -22,7 +22,7 @@ }, "linux": { "hash": "943f110d980630f5f6c90ea949d91f5fb91af126", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/0bb49ab54dbe55ce5b9dfea3a2ada68b87aecb65/trace_processor_shell" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/58e677929fd423df1885041a1a01c36431872696/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/accessibility/android/java/src/org/chromium/ui/accessibility/AccessibilityState.java b/ui/accessibility/android/java/src/org/chromium/ui/accessibility/AccessibilityState.java index e92f7b9..ebb5d87 100644 --- a/ui/accessibility/android/java/src/org/chromium/ui/accessibility/AccessibilityState.java +++ b/ui/accessibility/android/java/src/org/chromium/ui/accessibility/AccessibilityState.java
@@ -260,38 +260,52 @@ */ public static boolean isTouchExplorationEnabled() { if (!sInitialized) { - fetchAccessibilityManager(); - return sAccessibilityManager.isTouchExplorationEnabled(); + return isTouchExplorationEnabledHeavy(); } return sState.isTouchExplorationEnabled; } + @Deprecated + public static boolean isTouchExplorationEnabledHeavy() { + fetchAccessibilityManager(); + return sAccessibilityManager.isTouchExplorationEnabled(); + } + public static boolean isPerformGesturesEnabled() { if (!sInitialized) { if (sPreInitCachedValuePerformGesturesEnabled != null) { return sPreInitCachedValuePerformGesturesEnabled; } - fetchAccessibilityManager(); - if (sAccessibilityManager.isEnabled()) { - for (AccessibilityServiceInfo service : - sAccessibilityManager.getEnabledAccessibilityServiceList( - AccessibilityServiceInfo.FEEDBACK_ALL_MASK)) { - if ((service.getCapabilities() - & AccessibilityServiceInfo.CAPABILITY_CAN_PERFORM_GESTURES) - != 0) { - sPreInitCachedValuePerformGesturesEnabled = true; - return true; - } - } - } - sPreInitCachedValuePerformGesturesEnabled = false; - return false; + sPreInitCachedValuePerformGesturesEnabled = isPerformGesturesEnabledHeavy(); + return sPreInitCachedValuePerformGesturesEnabled; } return sState.isPerformGesturesEnabled; } + @Deprecated + public static boolean isPerformGesturesEnabledHeavy() { + // TODO(mschillaci): Remove when recreate issue is resolved. See crbug.com/1491862. + fetchAccessibilityManager(); + if (sAccessibilityManager.isEnabled()) { + for (AccessibilityServiceInfo service : + sAccessibilityManager.getEnabledAccessibilityServiceList( + AccessibilityServiceInfo.FEEDBACK_ALL_MASK)) { + if (0 != (service.getCapabilities() & CAPABILITY_CAN_PERFORM_GESTURES)) { + return true; + } + } + } + return false; + } + + @Deprecated + public static boolean isAccessibilityEnabledHeavy() { + return AccessibilityState.isTouchExplorationEnabledHeavy() + || AccessibilityState.isPerformGesturesEnabledHeavy(); + } + /** * True when at least one accessibility service is enabled on the system. Since a client can * call this after observers are registered, but before the State has been queried for the first
diff --git a/ui/base/metadata/metadata_cache.cc b/ui/base/metadata/metadata_cache.cc index 61d77e6..2a3e20c 100644 --- a/ui/base/metadata/metadata_cache.cc +++ b/ui/base/metadata/metadata_cache.cc
@@ -23,8 +23,8 @@ void MetaDataCache::AddClassMetaData( std::unique_ptr<ClassMetaData> class_data) { - DCHECK(!base::Contains(class_data_cache_, class_data->type_name(), - &ClassMetaData::type_name)); + DCHECK(!base::Contains(class_data_cache_, class_data->GetUniqueName(), + &ClassMetaData::GetUniqueName)); class_data_cache_.push_back(class_data.release()); }
diff --git a/ui/base/metadata/metadata_types.cc b/ui/base/metadata/metadata_types.cc index 8319fce5..42fbbe5a4f 100644 --- a/ui/base/metadata/metadata_types.cc +++ b/ui/base/metadata/metadata_types.cc
@@ -57,8 +57,9 @@ void MetaDataProvider::TriggerChangedCallback(PropertyKey property) { auto entry = property_changed_vectors_.find(property); - if (entry == property_changed_vectors_.end()) + if (entry == property_changed_vectors_.end()) { return; + } PropertyChangedCallbacks* property_changed_callbacks = entry->second.get(); property_changed_callbacks->Notify(); @@ -72,6 +73,13 @@ ClassMetaData::~ClassMetaData() = default; +const std::string& ClassMetaData::GetUniqueName() const { + if (unique_name_.empty()) { + unique_name_ = file_ + ":" + type_name_; + } + return unique_name_; +} + void ClassMetaData::AddMemberData( std::unique_ptr<MemberMetaDataBase> member_data) { members_.push_back(member_data.release()); @@ -80,8 +88,9 @@ MemberMetaDataBase* ClassMetaData::FindMemberData( const std::string& member_name) { for (MemberMetaDataBase* member_data : members_) { - if (member_data->member_name() == member_name) + if (member_data->member_name() == member_name) { return member_data; + } } if (parent_class_meta_data_ != nullptr)
diff --git a/ui/base/metadata/metadata_types.h b/ui/base/metadata/metadata_types.h index 585a0e5c..f43e7c9 100644 --- a/ui/base/metadata/metadata_types.h +++ b/ui/base/metadata/metadata_types.h
@@ -91,6 +91,7 @@ const std::vector<MemberMetaDataBase*>& members() const { return members_; } const std::string& file() const { return file_; } const int& line() const { return line_; } + const std::string& GetUniqueName() const; void AddMemberData(std::unique_ptr<MemberMetaDataBase> member_data); // Lookup the member data entry for a member of this class with a given name. @@ -161,6 +162,7 @@ private: std::string type_name_; + mutable std::string unique_name_; std::vector<MemberMetaDataBase*> members_; raw_ptr<ClassMetaData> parent_class_meta_data_ = nullptr; std::string file_;
diff --git a/ui/webui/resources/js/cr.ts b/ui/webui/resources/js/cr.ts index 2cc13ba7..89841d14 100644 --- a/ui/webui/resources/js/cr.ts +++ b/ui/webui/resources/js/cr.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {assert} from './assert_ts.js'; +import {assert} from './assert.js'; import {PromiseResolver} from './promise_resolver.js'; export interface WebUiListener {
diff --git a/ui/webui/resources/js/custom_element.ts b/ui/webui/resources/js/custom_element.ts index 6dadbd6c..3e99c482 100644 --- a/ui/webui/resources/js/custom_element.ts +++ b/ui/webui/resources/js/custom_element.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {assert} from './assert_ts.js'; +import {assert} from './assert.js'; /** * @fileoverview Base class for Web Components that don't use Polymer.
diff --git a/ui/webui/resources/js/focus_grid.ts b/ui/webui/resources/js/focus_grid.ts index 0cccd16..6104029 100644 --- a/ui/webui/resources/js/focus_grid.ts +++ b/ui/webui/resources/js/focus_grid.ts
@@ -3,7 +3,7 @@ // found in the LICENSE file. // clang-format off -import {assert} from './assert_ts.js'; +import {assert} from './assert.js'; import {FocusRow, FocusRowDelegate} from './focus_row.js'; // clang-format on
diff --git a/ui/webui/resources/js/focus_row.ts b/ui/webui/resources/js/focus_row.ts index dcfb082..ec0d77f8 100644 --- a/ui/webui/resources/js/focus_row.ts +++ b/ui/webui/resources/js/focus_row.ts
@@ -3,7 +3,7 @@ // found in the LICENSE file. // clang-format off -import {assert, assertInstanceof} from './assert_ts.js'; +import {assert, assertInstanceof} from './assert.js'; import {EventTracker} from './event_tracker.js'; import {hasKeyModifiers, isRTL} from './util_ts.js'; // clang-format on
diff --git a/ui/webui/resources/js/focus_without_ink.ts b/ui/webui/resources/js/focus_without_ink.ts index 888f1b3..74e6177 100644 --- a/ui/webui/resources/js/focus_without_ink.ts +++ b/ui/webui/resources/js/focus_without_ink.ts
@@ -3,7 +3,7 @@ // found in the LICENSE file. // clang-format off -import {assert} from './assert_ts.js'; +import {assert} from './assert.js'; import {isIOS} from './platform.js'; // clang-format on
diff --git a/ui/webui/resources/js/load_time_data.ts b/ui/webui/resources/js/load_time_data.ts index a93be464a..23574bae 100644 --- a/ui/webui/resources/js/load_time_data.ts +++ b/ui/webui/resources/js/load_time_data.ts
@@ -14,7 +14,7 @@ * change if the page is re-opened later. */ -import {assert} from './assert_ts.js'; +import {assert} from './assert.js'; interface LoadTimeDataRaw { [key: string]: any;
diff --git a/ui/webui/resources/js/metrics_reporter/metrics_reporter.ts b/ui/webui/resources/js/metrics_reporter/metrics_reporter.ts index 8fe0f9f..926274e 100644 --- a/ui/webui/resources/js/metrics_reporter/metrics_reporter.ts +++ b/ui/webui/resources/js/metrics_reporter/metrics_reporter.ts
@@ -4,7 +4,7 @@ import {TimeDelta} from '//resources/mojo/mojo/public/mojom/base/time.mojom-webui.js'; -import {assert} from '../assert_ts.js'; +import {assert} from '../assert.js'; import {BrowserProxy, BrowserProxyImpl} from './browser_proxy.js';
diff --git a/ui/webui/resources/js/parse_html_subset.ts b/ui/webui/resources/js/parse_html_subset.ts index ae6d9f8..678643c9 100644 --- a/ui/webui/resources/js/parse_html_subset.ts +++ b/ui/webui/resources/js/parse_html_subset.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {assert, assertNotReached} from './assert_ts.js'; +import {assert, assertNotReached} from './assert.js'; export interface SanitizeInnerHtmlOpts { substitutions?: string[];
diff --git a/ui/webui/resources/js/search_highlight_utils.ts b/ui/webui/resources/js/search_highlight_utils.ts index 33302fce..44fa02a6 100644 --- a/ui/webui/resources/js/search_highlight_utils.ts +++ b/ui/webui/resources/js/search_highlight_utils.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {assert} from './assert_ts.js'; +import {assert} from './assert.js'; const WRAPPER_CSS_CLASS: string = 'search-highlight-wrapper';
diff --git a/ui/webui/resources/js/static_types.ts b/ui/webui/resources/js/static_types.ts index 4ff882f..6cc9d36 100644 --- a/ui/webui/resources/js/static_types.ts +++ b/ui/webui/resources/js/static_types.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {assert} from './assert_ts.js'; +import {assert} from './assert.js'; /** * @return Whether the passed tagged template literal is a valid array.
diff --git a/ui/webui/resources/js/util_ts.ts b/ui/webui/resources/js/util_ts.ts index 91eacb08..7e11ed1b 100644 --- a/ui/webui/resources/js/util_ts.ts +++ b/ui/webui/resources/js/util_ts.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {assert} from './assert_ts.js'; +import {assert} from './assert.js'; /** * Alias for document.getElementById. Found elements must be HTMLElements.
diff --git a/ui/webui/resources/mojo/BUILD.gn b/ui/webui/resources/mojo/BUILD.gn index 8af7631..f5e8ada 100644 --- a/ui/webui/resources/mojo/BUILD.gn +++ b/ui/webui/resources/mojo/BUILD.gn
@@ -25,13 +25,13 @@ "mojo/public/mojom/base/token.mojom-webui.js", "mojo/public/mojom/base/unguessable_token.mojom-webui.js", "mojo/public/mojom/base/values.mojom-webui.js", - "skia/public/mojom/skcolor.mojom-webui.js", - "skia/public/mojom/bitmap.mojom-webui.js", - "skia/public/mojom/image_info.mojom-webui.js", "url/mojom/url.mojom-webui.js", ] mojo_ts_files = [ + "skia/public/mojom/skcolor.mojom-webui.ts", + "skia/public/mojom/bitmap.mojom-webui.ts", + "skia/public/mojom/image_info.mojom-webui.ts", "ui/base/mojom/themes.mojom-webui.ts", "ui/base/mojom/window_open_disposition.mojom-webui.ts", "ui/gfx/image/mojom/image.mojom-webui.ts", @@ -81,6 +81,7 @@ out_folder = "$target_gen_dir/preprocessed" in_files = mojo_ts_files deps = [ + "//skia/public/mojom:mojom_ts__generator", "//ui/base/mojom:mojom_ts__generator", "//ui/gfx/geometry/mojom:mojom_ts__generator", "//ui/gfx/image/mojom:mojom_ts__generator", @@ -108,7 +109,6 @@ deps = [ "//mojo/public/mojom/base:base_js__generator", - "//skia/public/mojom:mojom_js__generator", "//url/mojom:url_mojom_gurl_js__generator", ]
diff --git a/v8 b/v8 index c94b446..83887ed 160000 --- a/v8 +++ b/v8
@@ -1 +1 @@ -Subproject commit c94b446f73cf3fb1c72ceb12eb1461a5130acb35 +Subproject commit 83887edd7e3e261ca55a1c48173921f874530371