From 263959fa7ff096ec7edfafa06217c7d9c809cde1 Mon Sep 17 00:00:00 2001 From: Sangwoo Ko Date: Wed, 4 Mar 2026 06:49:08 +0900 Subject: [PATCH] [Containers] Show PageActionView for partitioned storage tab in location bar (#34248) * Show PageActionView for partitioned storage tab in location bar When the current tab uses a Brave container (partitioned storage), show the page action in the location bar with the container's icon, name, and background color from ContainerModel. - Register kPartitionedStorageActionIconType and enable it in the location bar only when ENABLE_CONTAINERS and the Containers feature are on. - Add PartitionedStoragePageActionController that resolves the tab's container via GetContainerIdForWebContents and ContainerModel, and drives the generic PageActionView (Show/Hide, OverrideImage/Text, etc.); the action is hidden when the tab has no container. --- browser/containers/containers_browsertest.cc | 45 +++++++ .../speedreader/speedreader_browsertest.cc | 1 - browser/ui/BUILD.gn | 2 +- browser/ui/brave_browser_actions.cc | 16 +++ .../page_action/brave_page_action_icon_type.h | 33 ------ .../ui/speedreader/speedreader_tab_helper.cc | 1 - browser/ui/tabs/BUILD.gn | 13 +++ browser/ui/tabs/brave_tab_features.cc | 19 +++ browser/ui/tabs/public/brave_tab_features.h | 11 ++ browser/ui/views/frame/brave_browser_view.cc | 1 - browser/ui/views/page_action/BUILD.gn | 27 +++++ .../brave_page_action_icon_container_view.cc | 1 - ...titioned_storage_page_action_controller.cc | 110 ++++++++++++++++++ ...rtitioned_storage_page_action_controller.h | 44 +++++++ .../ui/page_action/page_action_icon_type.cc | 22 ++++ .../ui/page_action/page_action_icon_type.h | 40 +++++++ .../page_action_icon_controller.cc | 1 - .../page_action_metrics_recorder.h | 30 +++++ .../brave_wayback_machine_browsertest.cc | 1 - ...rowser-ui-actions-chrome_action_id.h.patch | 8 ++ ...er-ui-views-page_action-action_ids.h.patch | 15 +++ ...tion-page_action_metrics_recorder.cc.patch | 40 +++++++ ...n-page_action_properties_provider.cc.patch | 18 +++ .../ui/views/page_action/action_ids.h.toml | 9 ++ .../page_action_metrics_recorder.cc.toml | 24 ++++ .../page_action_properties_provider.cc.toml | 16 +++ test/filters/unit_tests.filter | 7 ++ 27 files changed, 515 insertions(+), 40 deletions(-) delete mode 100644 browser/ui/page_action/brave_page_action_icon_type.h create mode 100644 browser/ui/views/page_action/partitioned_storage_page_action_controller.cc create mode 100644 browser/ui/views/page_action/partitioned_storage_page_action_controller.h create mode 100644 chromium_src/chrome/browser/ui/page_action/page_action_icon_type.cc create mode 100644 chromium_src/chrome/browser/ui/page_action/page_action_icon_type.h create mode 100644 chromium_src/chrome/browser/ui/views/page_action/page_action_metrics_recorder.h create mode 100644 patches/chrome-browser-ui-views-page_action-action_ids.h.patch create mode 100644 patches/chrome-browser-ui-views-page_action-page_action_metrics_recorder.cc.patch create mode 100644 patches/chrome-browser-ui-views-page_action-page_action_properties_provider.cc.patch create mode 100644 rewrite/chrome/browser/ui/views/page_action/action_ids.h.toml create mode 100644 rewrite/chrome/browser/ui/views/page_action/page_action_metrics_recorder.cc.toml create mode 100644 rewrite/chrome/browser/ui/views/page_action/page_action_properties_provider.cc.toml diff --git a/browser/containers/containers_browsertest.cc b/browser/containers/containers_browsertest.cc index e6cf3795492..663107620cc 100644 --- a/browser/containers/containers_browsertest.cc +++ b/browser/containers/containers_browsertest.cc @@ -3,18 +3,22 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at https://mozilla.org/MPL/2.0/. */ +#include "base/test/run_until.h" #include "brave/browser/ui/browser_commands.h" #include "brave/browser/ui/views/tabs/brave_tab.h" #include "brave/components/containers/content/browser/storage_partition_utils.h" #include "brave/components/containers/core/common/features.h" #include "brave/components/containers/core/mojom/containers.mojom.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/actions/chrome_action_id.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views/frame/toolbar_button_provider.h" +#include "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/content_settings/core/browser/host_content_settings_map.h" @@ -29,6 +33,7 @@ #include "third_party/abseil-cpp/absl/strings/str_format.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/views/test/views_test_utils.h" +#include "ui/views/view.h" #include "url/gurl.h" namespace containers { @@ -1046,4 +1051,44 @@ IN_PROC_BROWSER_TEST_F(ContainersBrowserTest, "sw_cookie=persistent_cookie") != std::string::npos); } +IN_PROC_BROWSER_TEST_F(ContainersBrowserTest, + PartitionedStorageActionIconShownOrHiddenPerTab) { + auto* tab_strip_model = browser()->tab_strip_model(); + ASSERT_EQ(1, tab_strip_model->count()); + + IconLabelBubbleView* partitioned_storage_view = + browser()->GetBrowserView().toolbar_button_provider()->GetPageActionView( + kActionShowPartitionedStorage); + ASSERT_NE(nullptr, partitioned_storage_view); + + const GURL url("https://a.test/simple.html"); + + // Tab 0: default (no container) -> icon should be hidden. + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); + + // Open a tab in a container -> icon should be visible on the active tab. + auto container = containers::mojom::Container::New(); + container->id = "test-container"; + container->name = "Test Container"; + container->icon = containers::mojom::Icon::kSocial; + container->background_color = SK_ColorYELLOW; + + brave::OpenUrlInContainer(browser(), url, container); + EXPECT_EQ(2, tab_strip_model->count()); + EXPECT_TRUE(content::WaitForLoadStop(tab_strip_model->GetWebContentsAt(1))); + + EXPECT_TRUE(partitioned_storage_view->GetVisible()) + << "PartitionedStorage icon should be visible on container tab."; + + // Switch to tab 0 (default) -> icon should be hidden. + tab_strip_model->ActivateTabAt(0); + RunScheduledLayouts(); + EXPECT_FALSE(partitioned_storage_view->GetVisible()); + + // Switch back to tab 1 (container) -> icon should be visible. + tab_strip_model->ActivateTabAt(1); + RunScheduledLayouts(); + EXPECT_TRUE(partitioned_storage_view->GetVisible()); +} + } // namespace containers diff --git a/browser/speedreader/speedreader_browsertest.cc b/browser/speedreader/speedreader_browsertest.cc index 037b917cde9..5e15666e9fa 100644 --- a/browser/speedreader/speedreader_browsertest.cc +++ b/browser/speedreader/speedreader_browsertest.cc @@ -21,7 +21,6 @@ #include "brave/browser/speedreader/speedreader_service_factory.h" #include "brave/browser/ui/brave_browser.h" #include "brave/browser/ui/browser_commands.h" -#include "brave/browser/ui/page_action/brave_page_action_icon_type.h" #include "brave/browser/ui/speedreader/speedreader_tab_helper.h" #include "brave/browser/ui/views/frame/brave_browser_view.h" #include "brave/browser/ui/views/frame/split_view/brave_contents_container_view.h" diff --git a/browser/ui/BUILD.gn b/browser/ui/BUILD.gn index 3c329ddca3f..3d366535a8d 100644 --- a/browser/ui/BUILD.gn +++ b/browser/ui/BUILD.gn @@ -277,7 +277,6 @@ source_set("ui") { "content_settings/brave_content_setting_image_models.h", "omnibox/brave_omnibox_client_impl.cc", "omnibox/brave_omnibox_client_impl.h", - "page_action/brave_page_action_icon_type.h", "session_crashed_bubble_brave.cc", "side_panel/ai_chat/ai_chat_side_panel_utils.cc", "side_panel/ai_chat/ai_chat_side_panel_utils.h", @@ -670,6 +669,7 @@ source_set("ui") { "//brave/browser/ui/views:layout_provider", "//brave/browser/ui/views/frame", "//brave/browser/ui/views/location_bar", + "//brave/browser/ui/views/page_action", "//chrome/browser:shell_integration", "//chrome/browser/devtools", "//chrome/browser/enterprise/watermark:watermark_view_lib", diff --git a/browser/ui/brave_browser_actions.cc b/browser/ui/brave_browser_actions.cc index 8014e54de39..a38ea348729 100644 --- a/browser/ui/brave_browser_actions.cc +++ b/browser/ui/brave_browser_actions.cc @@ -5,11 +5,14 @@ #include "brave/browser/ui/brave_browser_actions.h" +#include "base/functional/callback_helpers.h" #include "base/types/to_address.h" #include "brave/components/ai_chat/core/common/buildflags/buildflags.h" +#include "brave/components/containers/buildflags/buildflags.h" #include "brave/components/playlist/core/common/features.h" #include "brave/components/vector_icons/vector_icons.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/actions/chrome_action_id.h" #include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/views/side_panel/side_panel_action_callback.h" #include "chrome/browser/ui/views/side_panel/side_panel_entry_id.h" @@ -23,6 +26,10 @@ #include "brave/components/ai_chat/core/browser/utils.h" #endif +#if BUILDFLAG(ENABLE_CONTAINERS) +#include "brave/components/containers/core/common/features.h" +#endif + namespace { actions::ActionItem::ActionItemBuilder SidePanelAction( @@ -71,4 +78,13 @@ void BraveBrowserActions::InitializeBrowserActions() { .Build()); } #endif + +#if BUILDFLAG(ENABLE_CONTAINERS) + if (base::FeatureList::IsEnabled(containers::features::kContainers)) { + root_action_item_->AddChild(actions::ActionItem::Builder(base::DoNothing()) + .SetActionId(kActionShowPartitionedStorage) + .SetEnabled(true) + .Build()); + } +#endif } diff --git a/browser/ui/page_action/brave_page_action_icon_type.h b/browser/ui/page_action/brave_page_action_icon_type.h deleted file mode 100644 index 450e214154b..00000000000 --- a/browser/ui/page_action/brave_page_action_icon_type.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2023 The Brave Authors. All rights reserved. - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. */ - -#ifndef BRAVE_BROWSER_UI_PAGE_ACTION_BRAVE_PAGE_ACTION_ICON_TYPE_H_ -#define BRAVE_BROWSER_UI_PAGE_ACTION_BRAVE_PAGE_ACTION_ICON_TYPE_H_ - -#include "brave/components/brave_wayback_machine/buildflags/buildflags.h" -#include "brave/components/speedreader/common/buildflags/buildflags.h" -#include "chrome/browser/ui/page_action/page_action_icon_type.h" - -namespace brave { - -#define DECLARE_BRAVE_PAGE_ACTION_ICON_TYPE(NAME, VALUE) \ - constexpr PageActionIconType NAME = static_cast(VALUE) - -// Use negative values so that our values doesn't conflict with upstream values. -DECLARE_BRAVE_PAGE_ACTION_ICON_TYPE(kUndefinedPageActionIconType, -1); -DECLARE_BRAVE_PAGE_ACTION_ICON_TYPE(kPlaylistPageActionIconType, -2); -// -3 was used for Brave Player -#if BUILDFLAG(ENABLE_BRAVE_WAYBACK_MACHINE) -DECLARE_BRAVE_PAGE_ACTION_ICON_TYPE(kWaybackMachineActionIconType, -4); -#endif -#if BUILDFLAG(ENABLE_SPEEDREADER) -DECLARE_BRAVE_PAGE_ACTION_ICON_TYPE(kSpeedreaderPageActionIconType, -5); -#endif - -#undef DECLARE_BRAVE_PAGE_ACTION_ICON_TYPE - -} // namespace brave - -#endif // BRAVE_BROWSER_UI_PAGE_ACTION_BRAVE_PAGE_ACTION_ICON_TYPE_H_ diff --git a/browser/ui/speedreader/speedreader_tab_helper.cc b/browser/ui/speedreader/speedreader_tab_helper.cc index 0e9c22809b4..12e27b25b90 100644 --- a/browser/ui/speedreader/speedreader_tab_helper.cc +++ b/browser/ui/speedreader/speedreader_tab_helper.cc @@ -24,7 +24,6 @@ #include "brave/browser/brave_browser_process.h" #include "brave/browser/speedreader/page_distiller.h" #include "brave/browser/speedreader/speedreader_service_factory.h" -#include "brave/browser/ui/page_action/brave_page_action_icon_type.h" #include "brave/browser/ui/speedreader/speedreader_bubble_view.h" #include "brave/components/speedreader/common/features.h" #include "brave/components/speedreader/speedreader_extended_info_handler.h" diff --git a/browser/ui/tabs/BUILD.gn b/browser/ui/tabs/BUILD.gn index 36db0c5c460..e4134141bf4 100644 --- a/browser/ui/tabs/BUILD.gn +++ b/browser/ui/tabs/BUILD.gn @@ -18,6 +18,11 @@ source_set("tabs_public") { "//brave/components/psst/buildflags", "//chrome/browser/ui/tabs:tabs_public", ] + + deps = [ + "//brave/browser/ui/views/page_action", + "//brave/components/containers/buildflags", + ] } if (!is_android) { @@ -30,6 +35,7 @@ if (!is_android) { ":tabs_public", "//brave/browser/psst", "//brave/browser/ui/side_panel", + "//brave/browser/ui/views/page_action", "//brave/components/psst/browser/content", "//brave/components/psst/common", "//chrome/browser/content_settings:content_settings_factory", @@ -40,6 +46,13 @@ if (!is_android) { if (enable_ai_chat) { deps += [ "//brave/browser/ai_chat" ] } + + if (enable_containers) { + deps += [ + "//brave/components/containers/core/browser", + "//brave/components/containers/core/common:features", + ] + } } # This source set is counterpart to the upstream `tab_strip` source set. diff --git a/browser/ui/tabs/brave_tab_features.cc b/browser/ui/tabs/brave_tab_features.cc index 5a6068dd846..7ec1dcdac03 100644 --- a/browser/ui/tabs/brave_tab_features.cc +++ b/browser/ui/tabs/brave_tab_features.cc @@ -18,6 +18,11 @@ #include "chrome/common/chrome_isolated_world_ids.h" #include "components/tabs/public/tab_interface.h" +#if BUILDFLAG(ENABLE_CONTAINERS) +#include "brave/browser/ui/views/page_action/partitioned_storage_page_action_controller.h" +#include "brave/components/containers/core/common/features.h" +#endif + #if BUILDFLAG(ENABLE_AI_CHAT) #include "brave/browser/ai_chat/ai_chat_utils.h" #include "brave/browser/ai_chat/tab_data_web_contents_observer.h" @@ -64,6 +69,20 @@ void BraveTabFeatures::Init(TabInterface& tab, Profile* profile) { profile->GetPrefs(), ISOLATED_WORLD_ID_BRAVE_INTERNAL); } #endif + +#if BUILDFLAG(ENABLE_CONTAINERS) + if (page_action_controller() && + base::FeatureList::IsEnabled(containers::features::kContainers)) { + // In case of features::kPageActionsMigration is disabled, this controller + // can be null. The feature is enabled by default. So note that we don't + // show the partitioned storage page action when the features is disabled + // by users. + partitioned_storage_page_action_controller_ = + std::make_unique( + tab, *page_action_controller()); + partitioned_storage_page_action_controller_->Init(); + } +#endif } } // namespace tabs diff --git a/browser/ui/tabs/public/brave_tab_features.h b/browser/ui/tabs/public/brave_tab_features.h index 71dca002c34..908970ef401 100644 --- a/browser/ui/tabs/public/brave_tab_features.h +++ b/browser/ui/tabs/public/brave_tab_features.h @@ -9,6 +9,7 @@ #include #include "brave/components/ai_chat/core/common/buildflags/buildflags.h" +#include "brave/components/containers/buildflags/buildflags.h" #include "brave/components/psst/buildflags/buildflags.h" #include "chrome/browser/ui/tabs/public/tab_features.h" @@ -20,6 +21,12 @@ class TabDataWebContentsObserver; } #endif +#if BUILDFLAG(ENABLE_CONTAINERS) +namespace page_actions { +class PartitionedStoragePageActionController; +} +#endif + #if BUILDFLAG(ENABLE_PSST) namespace psst { class PsstTabWebContentsObserver; @@ -51,6 +58,10 @@ class BraveTabFeatures : public TabFeatures { #if BUILDFLAG(ENABLE_PSST) std::unique_ptr psst_web_contents_observer_; #endif +#if BUILDFLAG(ENABLE_CONTAINERS) + std::unique_ptr + partitioned_storage_page_action_controller_; +#endif }; } // namespace tabs diff --git a/browser/ui/views/frame/brave_browser_view.cc b/browser/ui/views/frame/brave_browser_view.cc index c4d41b9876e..efacd2092a4 100644 --- a/browser/ui/views/frame/brave_browser_view.cc +++ b/browser/ui/views/frame/brave_browser_view.cc @@ -23,7 +23,6 @@ #include "brave/browser/ui/color/brave_color_id.h" #include "brave/browser/ui/commands/accelerator_service.h" #include "brave/browser/ui/commands/accelerator_service_factory.h" -#include "brave/browser/ui/page_action/brave_page_action_icon_type.h" #include "brave/browser/ui/page_info/features.h" #include "brave/browser/ui/sidebar/features.h" #include "brave/browser/ui/sidebar/sidebar_controller.h" diff --git a/browser/ui/views/page_action/BUILD.gn b/browser/ui/views/page_action/BUILD.gn index fb9d8407f8a..73989299870 100644 --- a/browser/ui/views/page_action/BUILD.gn +++ b/browser/ui/views/page_action/BUILD.gn @@ -3,6 +3,33 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at https://mozilla.org/MPL/2.0/. +import("//brave/components/containers/buildflags/buildflags.gni") + +source_set("page_action") { + # TODO(https://github.com/brave/brave-browser/issues/52829) + # Other page action icons sources should be added here, not from + # //b/b/ui/BUILD.gn + sources = [] + deps = [] + + if (enable_containers) { + sources += [ + "partitioned_storage_page_action_controller.cc", + "partitioned_storage_page_action_controller.h", + ] + deps += [ + "//brave/browser/ui/containers", + "//brave/components/containers/content/browser", + "//brave/components/containers/core/common:features", + "//chrome/browser/profiles", + "//chrome/browser/ui/actions", + "//chrome/browser/ui/views/page_action", + "//components/tabs:public", + "//components/user_prefs", + ] + } +} + source_set("unit_tests") { testonly = true defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] diff --git a/browser/ui/views/page_action/brave_page_action_icon_container_view.cc b/browser/ui/views/page_action/brave_page_action_icon_container_view.cc index 0d1bc4c3b76..5a05adaf026 100644 --- a/browser/ui/views/page_action/brave_page_action_icon_container_view.cc +++ b/browser/ui/views/page_action/brave_page_action_icon_container_view.cc @@ -8,7 +8,6 @@ #include #include "base/check_is_test.h" -#include "brave/browser/ui/page_action/brave_page_action_icon_type.h" #include "brave/components/brave_wayback_machine/buildflags/buildflags.h" #include "brave/components/playlist/core/common/features.h" #include "brave/components/speedreader/common/buildflags/buildflags.h" diff --git a/browser/ui/views/page_action/partitioned_storage_page_action_controller.cc b/browser/ui/views/page_action/partitioned_storage_page_action_controller.cc new file mode 100644 index 00000000000..159b8003ecd --- /dev/null +++ b/browser/ui/views/page_action/partitioned_storage_page_action_controller.cc @@ -0,0 +1,110 @@ +// Copyright (c) 2026 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +#include "brave/browser/ui/views/page_action/partitioned_storage_page_action_controller.h" + +#include +#include + +#include "base/strings/utf_string_conversions.h" +#include "brave/browser/ui/containers/container_model.h" +#include "brave/components/containers/content/browser/storage_partition_utils.h" +#include "brave/components/containers/core/common/features.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/actions/chrome_action_id.h" +#include "components/user_prefs/user_prefs.h" +#include "content/public/browser/web_contents.h" + +namespace page_actions { + +namespace { + +constexpr float kDefaultScaleFactor = 1.0f; + +std::optional GetContainerModelForWebContents( + content::WebContents* web_contents) { + if (!web_contents) { + return std::nullopt; + } + std::string container_id = + containers::GetContainerIdForWebContents(web_contents); + if (container_id.empty()) { + return std::nullopt; + } + + auto* prefs = user_prefs::UserPrefs::Get(web_contents->GetBrowserContext()); + if (!prefs) { + return std::nullopt; + } + + std::vector models = + containers::GetContainerModelsFromPrefs(*prefs, kDefaultScaleFactor); + auto it = + std::ranges::find(models, container_id, &containers::ContainerModel::id); + if (it != models.end()) { + return containers::ContainerModel(std::move(*it)); + } + + return containers::ContainerModel::CreateForUnknown(container_id, + kDefaultScaleFactor); +} + +} // namespace + +PartitionedStoragePageActionController::PartitionedStoragePageActionController( + tabs::TabInterface& tab, + page_actions::PageActionController& page_action_controller) + : tab_(tab), page_action_controller_(page_action_controller) { + CHECK(base::FeatureList::IsEnabled(containers::features::kContainers)); +} + +PartitionedStoragePageActionController:: + ~PartitionedStoragePageActionController() = default; + +void PartitionedStoragePageActionController::Init() { + did_activate_subscription_ = tab_->RegisterDidActivate( + base::BindRepeating([](PartitionedStoragePageActionController* self, + tabs::TabInterface*) { self->UpdatePageAction(); }, + base::Unretained(this))); + did_become_visible_subscription_ = tab_->RegisterDidBecomeVisible( + base::BindRepeating([](PartitionedStoragePageActionController* self, + tabs::TabInterface*) { self->UpdatePageAction(); }, + base::Unretained(this))); + will_discard_contents_subscription_ = + tab_->RegisterWillDiscardContents(base::BindRepeating( + [](PartitionedStoragePageActionController* self, tabs::TabInterface*, + content::WebContents*, + content::WebContents*) { self->UpdatePageAction(); }, + base::Unretained(this))); + UpdatePageAction(); +} + +void PartitionedStoragePageActionController::UpdatePageAction() { + content::WebContents* web_contents = tab_->GetContents(); + std::optional model = + GetContainerModelForWebContents(web_contents); + if (!model) { + page_action_controller_->Hide(kActionShowPartitionedStorage); + page_action_controller_->ClearOverrideChipColors( + kActionShowPartitionedStorage); + return; + } + + const std::u16string name = base::UTF8ToUTF16(model->name()); + page_action_controller_->Show(kActionShowPartitionedStorage); + page_action_controller_->ShowSuggestionChip(kActionShowPartitionedStorage); + page_action_controller_->SetAlwaysShowLabel(kActionShowPartitionedStorage, + true); + page_action_controller_->OverrideImage(kActionShowPartitionedStorage, + model->icon()); + page_action_controller_->OverrideText(kActionShowPartitionedStorage, name); + page_action_controller_->OverrideAccessibleName(kActionShowPartitionedStorage, + name); + page_action_controller_->OverrideTooltip(kActionShowPartitionedStorage, name); + page_action_controller_->OverrideChipColors( + kActionShowPartitionedStorage, model->background_color(), SK_ColorWHITE); +} + +} // namespace page_actions diff --git a/browser/ui/views/page_action/partitioned_storage_page_action_controller.h b/browser/ui/views/page_action/partitioned_storage_page_action_controller.h new file mode 100644 index 00000000000..54351e58da7 --- /dev/null +++ b/browser/ui/views/page_action/partitioned_storage_page_action_controller.h @@ -0,0 +1,44 @@ +// Copyright (c) 2026 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +#ifndef BRAVE_BROWSER_UI_VIEWS_PAGE_ACTION_PARTITIONED_STORAGE_PAGE_ACTION_CONTROLLER_H_ +#define BRAVE_BROWSER_UI_VIEWS_PAGE_ACTION_PARTITIONED_STORAGE_PAGE_ACTION_CONTROLLER_H_ + +#include "base/callback_list.h" +#include "base/memory/raw_ref.h" +#include "chrome/browser/ui/views/page_action/page_action_controller.h" +#include "components/tabs/public/tab_interface.h" + +namespace page_actions { + +// Drives the Partitioned Storage page action (container indicator): shows the +// action with container icon/name when the tab is in a Brave container, hides +// it otherwise. +class PartitionedStoragePageActionController { + public: + PartitionedStoragePageActionController( + tabs::TabInterface& tab, + page_actions::PageActionController& page_action_controller); + PartitionedStoragePageActionController( + const PartitionedStoragePageActionController&) = delete; + PartitionedStoragePageActionController& operator=( + const PartitionedStoragePageActionController&) = delete; + ~PartitionedStoragePageActionController(); + + void Init(); + + private: + void UpdatePageAction(); + + const raw_ref tab_; + const raw_ref page_action_controller_; + base::CallbackListSubscription did_activate_subscription_; + base::CallbackListSubscription did_become_visible_subscription_; + base::CallbackListSubscription will_discard_contents_subscription_; +}; + +} // namespace page_actions + +#endif // BRAVE_BROWSER_UI_VIEWS_PAGE_ACTION_PARTITIONED_STORAGE_PAGE_ACTION_CONTROLLER_H_ diff --git a/chromium_src/chrome/browser/ui/page_action/page_action_icon_type.cc b/chromium_src/chrome/browser/ui/page_action/page_action_icon_type.cc new file mode 100644 index 00000000000..b3e1b4721e4 --- /dev/null +++ b/chromium_src/chrome/browser/ui/page_action/page_action_icon_type.cc @@ -0,0 +1,22 @@ +// Copyright (c) 2026 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +#include "chrome/browser/ui/page_action/page_action_icon_type.h" + +#define IsPageActionMigrated IsPageActionMigrated_Chromium + +#include + +#undef IsPageActionMigrated + +bool IsPageActionMigrated(PageActionIconType page_action) { + if (page_action == brave::kPartitionedStorageActionIconType) { + // Partitioned Storage (container) page action is based on the new framework + // for page action. + return true; + } + + return IsPageActionMigrated_Chromium(page_action); +} diff --git a/chromium_src/chrome/browser/ui/page_action/page_action_icon_type.h b/chromium_src/chrome/browser/ui/page_action/page_action_icon_type.h new file mode 100644 index 00000000000..8f7d8e762f9 --- /dev/null +++ b/chromium_src/chrome/browser/ui/page_action/page_action_icon_type.h @@ -0,0 +1,40 @@ +// Copyright (c) 2026 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +#ifndef BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_PAGE_ACTION_PAGE_ACTION_ICON_TYPE_H_ +#define BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_PAGE_ACTION_PAGE_ACTION_ICON_TYPE_H_ + +#include // IWYU pragma: export + +// Add a wrapper function to the Chromium implementation to avoid conflicts. +bool IsPageActionMigrated_Chromium(PageActionIconType page_action); + +// Brave specific page action icon types --------------------------------------- +// In order to avoid cyclic depdencies, we define the brave specific page action +// icon types here. + +namespace brave { + +// Use negative values so that our values doesn't conflict with upstream values. +inline constexpr PageActionIconType kUndefinedPageActionIconType = + static_cast(-1); + +inline constexpr PageActionIconType kPlaylistPageActionIconType = + static_cast(-2); + +// -3 was used for Brave Player: which is retired. + +inline constexpr PageActionIconType kWaybackMachineActionIconType = + static_cast(-4); + +inline constexpr PageActionIconType kSpeedreaderPageActionIconType = + static_cast(-5); + +inline constexpr PageActionIconType kPartitionedStorageActionIconType = + static_cast(-6); + +} // namespace brave + +#endif // BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_PAGE_ACTION_PAGE_ACTION_ICON_TYPE_H_ diff --git a/chromium_src/chrome/browser/ui/views/page_action/page_action_icon_controller.cc b/chromium_src/chrome/browser/ui/views/page_action/page_action_icon_controller.cc index 80809d50d00..140a95fc9a1 100644 --- a/chromium_src/chrome/browser/ui/views/page_action/page_action_icon_controller.cc +++ b/chromium_src/chrome/browser/ui/views/page_action/page_action_icon_controller.cc @@ -3,7 +3,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "brave/browser/ui/page_action/brave_page_action_icon_type.h" #include "brave/browser/ui/views/location_bar/brave_star_view.h" #include "brave/components/brave_wayback_machine/buildflags/buildflags.h" #include "brave/components/playlist/core/common/buildflags/buildflags.h" diff --git a/chromium_src/chrome/browser/ui/views/page_action/page_action_metrics_recorder.h b/chromium_src/chrome/browser/ui/views/page_action/page_action_metrics_recorder.h new file mode 100644 index 00000000000..b4da43869d1 --- /dev/null +++ b/chromium_src/chrome/browser/ui/views/page_action/page_action_metrics_recorder.h @@ -0,0 +1,30 @@ +// Copyright (c) 2026 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +#ifndef BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_METRICS_RECORDER_H_ +#define BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_METRICS_RECORDER_H_ + +// Scrubs out histogramming calls +#define RecordIconShown() \ + RecordIconShown() {} \ + void RecordIconShown_Chromium() +#define RecordChipShown() \ + RecordChipShown() {} \ + void RecordChipShown_Chromium() +#define RecordIconClick() \ + RecordIconClick() {} \ + void RecordIconClick_Chromium() +#define RecordChipClick() \ + RecordChipClick() {} \ + void RecordChipClick_Chromium() + +#include // IWYU pragma: export + +#undef RecordChipClick +#undef RecordIconClick +#undef RecordChipShown +#undef RecordIconShown + +#endif // BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_METRICS_RECORDER_H_ diff --git a/components/brave_wayback_machine/brave_wayback_machine_browsertest.cc b/components/brave_wayback_machine/brave_wayback_machine_browsertest.cc index 4131a201be0..ac039d6c209 100644 --- a/components/brave_wayback_machine/brave_wayback_machine_browsertest.cc +++ b/components/brave_wayback_machine/brave_wayback_machine_browsertest.cc @@ -3,7 +3,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "brave/browser/ui/page_action/brave_page_action_icon_type.h" #include "brave/browser/ui/views/page_action/wayback_machine_action_icon_view.h" #include "brave/components/brave_wayback_machine/brave_wayback_machine_tab_helper.h" #include "chrome/browser/ui/browser.h" diff --git a/patches/chrome-browser-ui-actions-chrome_action_id.h.patch b/patches/chrome-browser-ui-actions-chrome_action_id.h.patch index ef0a73b88b7..57ace0cc23e 100644 --- a/patches/chrome-browser-ui-actions-chrome_action_id.h.patch +++ b/patches/chrome-browser-ui-actions-chrome_action_id.h.patch @@ -10,3 +10,11 @@ index faf125bfd6439aa0e4add87c965d5f970d848432..87c3cdd66981596d394fa07c5b36d30e E(kActionSidePanelShowBookmarks, IDC_SHOW_BOOKMARK_SIDE_PANEL) \ E(kActionSidePanelShowComments, IDC_SHOW_COMMENTS_SIDE_PANEL) \ E(kActionSidePanelShowCustomizeChrome) \ +@@ -596,6 +597,7 @@ + E(kActionCopyUrl, IDC_COPY_URL) \ + E(kActionTabGroupsMenu, IDC_SAVED_TAB_GROUPS_MENU) \ + E(kActionTabSearch, IDC_TAB_SEARCH) \ ++ E(kActionShowPartitionedStorage) \ + E(kActionSplitTab, IDC_SPLIT_TAB) \ + + #define CHROME_ACTION_IDS \ diff --git a/patches/chrome-browser-ui-views-page_action-action_ids.h.patch b/patches/chrome-browser-ui-views-page_action-action_ids.h.patch new file mode 100644 index 00000000000..a8446157730 --- /dev/null +++ b/patches/chrome-browser-ui-views-page_action-action_ids.h.patch @@ -0,0 +1,15 @@ +diff --git a/chrome/browser/ui/views/page_action/action_ids.h b/chrome/browser/ui/views/page_action/action_ids.h +index 5d4b2b5c732d3fef65dc9ddea6158580df74f2c6..86a0f58a4b9fd5c6a10e0cb826c5dc892b0e5fa6 100644 +--- a/chrome/browser/ui/views/page_action/action_ids.h ++++ b/chrome/browser/ui/views/page_action/action_ids.h +@@ -14,8 +14,9 @@ namespace page_actions { + // All ActionIds associated with a page action. + // For now, the order of the page actions will be based on their position in + // the array. +-inline constexpr std::array kActionIds = { ++inline constexpr std::array kActionIds = { + kActionAiMode, ++ kActionShowPartitionedStorage, + kActionSidePanelShowLensOverlayResults, + kActionLensOverlayHomework, + kActionShowTranslate, diff --git a/patches/chrome-browser-ui-views-page_action-page_action_metrics_recorder.cc.patch b/patches/chrome-browser-ui-views-page_action-page_action_metrics_recorder.cc.patch new file mode 100644 index 00000000000..ad82f04c379 --- /dev/null +++ b/patches/chrome-browser-ui-views-page_action-page_action_metrics_recorder.cc.patch @@ -0,0 +1,40 @@ +diff --git a/chrome/browser/ui/views/page_action/page_action_metrics_recorder.cc b/chrome/browser/ui/views/page_action/page_action_metrics_recorder.cc +index f5cf8379758e5d7bbbb42761a452f7e279460851..2b6ca4d1c131babea6e43efd4c9ba118659650c8 100644 +--- a/chrome/browser/ui/views/page_action/page_action_metrics_recorder.cc ++++ b/chrome/browser/ui/views/page_action/page_action_metrics_recorder.cc +@@ -105,7 +105,7 @@ bool PageActionPerActionMetricsRecorder::IsNewNavigation() { + return false; + } + +-void PageActionPerActionMetricsRecorder::RecordIconShown() { ++void PageActionPerActionMetricsRecorder::RecordIconShown_Chromium() { + if (current_navigation_metrics_.icon_shown_recorded) { + return; + } +@@ -121,7 +121,7 @@ void PageActionPerActionMetricsRecorder::RecordIconShown() { + page_action_type_); + } + +-void PageActionPerActionMetricsRecorder::RecordChipShown() { ++void PageActionPerActionMetricsRecorder::RecordChipShown_Chromium() { + if (current_navigation_metrics_.chip_shown_recorded) { + return; + } +@@ -153,7 +153,7 @@ void PageActionPerActionMetricsRecorder::RecordClick( + } + } + +-void PageActionPerActionMetricsRecorder::RecordIconClick() { ++void PageActionPerActionMetricsRecorder::RecordIconClick_Chromium() { + base::UmaHistogramEnumeration("PageActionController.Icon.CTR2", + PageActionCTREvent::kClicked); + base::UmaHistogramEnumeration( +@@ -164,7 +164,7 @@ void PageActionPerActionMetricsRecorder::RecordIconClick() { + visible_ephemeral_page_actions_count_callback_.Run(), 20); + } + +-void PageActionPerActionMetricsRecorder::RecordChipClick() { ++void PageActionPerActionMetricsRecorder::RecordChipClick_Chromium() { + base::UmaHistogramEnumeration("PageActionController.Chip.CTR2", + PageActionCTREvent::kClicked); + base::UmaHistogramEnumeration( diff --git a/patches/chrome-browser-ui-views-page_action-page_action_properties_provider.cc.patch b/patches/chrome-browser-ui-views-page_action-page_action_properties_provider.cc.patch new file mode 100644 index 00000000000..d020adbd277 --- /dev/null +++ b/patches/chrome-browser-ui-views-page_action-page_action_properties_provider.cc.patch @@ -0,0 +1,18 @@ +diff --git a/chrome/browser/ui/views/page_action/page_action_properties_provider.cc b/chrome/browser/ui/views/page_action/page_action_properties_provider.cc +index 3dfce9a2c3b183dc7f8d1c83033826e8349be6fb..06e9fe315bc9b1ce89df44a0a257f25850024716 100644 +--- a/chrome/browser/ui/views/page_action/page_action_properties_provider.cc ++++ b/chrome/browser/ui/views/page_action/page_action_properties_provider.cc +@@ -174,6 +174,13 @@ constexpr auto kPageActionProperties = + .type = PageActionIconType::kAutofillAddress, + }, + }, ++ { ++ kActionShowPartitionedStorage, ++ { ++ .histogram_name = "PartitionedStorage", ++ .type = brave::kPartitionedStorageActionIconType, ++ }, ++ }, + { + kActionVirtualCardEnroll, + { diff --git a/rewrite/chrome/browser/ui/views/page_action/action_ids.h.toml b/rewrite/chrome/browser/ui/views/page_action/action_ids.h.toml new file mode 100644 index 00000000000..c9a11b12ddd --- /dev/null +++ b/rewrite/chrome/browser/ui/views/page_action/action_ids.h.toml @@ -0,0 +1,9 @@ +# Copyright (c) 2026 The Brave Authors. All rights reserved. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at https://mozilla.org/MPL/2.0/. + +[[substitution]] +description = 'Increase array length and add kActionShowPartitionedStorage to the array' +re_pattern = '(inline constexpr std::array kActionIds [\s\S]*?kActionAiMode,)' +replace = '\g<1>26\g<2>\n kActionShowPartitionedStorage,' diff --git a/rewrite/chrome/browser/ui/views/page_action/page_action_metrics_recorder.cc.toml b/rewrite/chrome/browser/ui/views/page_action/page_action_metrics_recorder.cc.toml new file mode 100644 index 00000000000..6b9a975feea --- /dev/null +++ b/rewrite/chrome/browser/ui/views/page_action/page_action_metrics_recorder.cc.toml @@ -0,0 +1,24 @@ +# Copyright (c) 2026 The Brave Authors. All rights reserved. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at https://mozilla.org/MPL/2.0/. + +[[substitution]] +description = 'Replaces RecordChipShown with RecordChipShown_Chromium' +re_pattern = '(void PageActionPerActionMetricsRecorder::RecordChipShown)\(\)' +replace = '\1_Chromium()' + +[[substitution]] +description = 'Replaces RecordIconShown with RecordIconShown_Chromium' +re_pattern = '(void PageActionPerActionMetricsRecorder::RecordIconShown)\(\)' +replace = '\1_Chromium()' + +[[substitution]] +description = 'Replaces RecordIconClick with RecordIconClick_Chromium' +re_pattern = '(void PageActionPerActionMetricsRecorder::RecordIconClick)\(\)' +replace = '\1_Chromium()' + +[[substitution]] +description = 'Replaces RecordChipClick with RecordChipClick_Chromium' +re_pattern = '(void PageActionPerActionMetricsRecorder::RecordChipClick)\(\)' +replace = '\1_Chromium()' diff --git a/rewrite/chrome/browser/ui/views/page_action/page_action_properties_provider.cc.toml b/rewrite/chrome/browser/ui/views/page_action/page_action_properties_provider.cc.toml new file mode 100644 index 00000000000..7100bfedfe1 --- /dev/null +++ b/rewrite/chrome/browser/ui/views/page_action/page_action_properties_provider.cc.toml @@ -0,0 +1,16 @@ +# Copyright (c) 2026 The Brave Authors. All rights reserved. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at https://mozilla.org/MPL/2.0/. + +[[substitution]] +description = 'Insert kActionShowPartitionedStorage before kActionVirtualCardEnroll' +pattern = 'kActionVirtualCardEnroll,' +replace = '''kActionShowPartitionedStorage, + { + .histogram_name = "PartitionedStorage", + .type = brave::kPartitionedStorageActionIconType, + }, + }, + { + kActionVirtualCardEnroll,''' diff --git a/test/filters/unit_tests.filter b/test/filters/unit_tests.filter index bd3a1627524..f3789e8d805 100644 --- a/test/filters/unit_tests.filter +++ b/test/filters/unit_tests.filter @@ -783,6 +783,13 @@ -ProtocolHandlersManagerServiceTest.PRE_ProtocolHandlerSanityCheck -ProtocolHandlersManagerServiceTest.ProtocolHandlerSanityCheck +# We added our own page action view but this made metrics code related to the +# page action fails. In order to addressed that we scrubbed out metrics code and +# upstream tests related to it fails +# https://github.com/brave/brave-core/pull/34248 +-PageActionMetricsRecorderTest.* +-PageActionControllerTest.NotifyActionClickedLogsHistogram + # Tests below this point have not been diagnosed or had issues created yet. -AboutFlagsHistogramTest.* -AboutFlagsTest.EveryFlagHasMetadata