[Shields UI] Open page info when Shields detects repeated reloads (#32363)
This commit is contained in:
@@ -18,6 +18,8 @@ source_set("location_bar") {
|
||||
"brave_search_conversion/promotion_button_view.h",
|
||||
"brave_selected_keyword_view_util.cc",
|
||||
"brave_selected_keyword_view_util.h",
|
||||
"brave_shields_page_info_controller.cc",
|
||||
"brave_shields_page_info_controller.h",
|
||||
"brave_star_view.cc",
|
||||
"brave_star_view.h",
|
||||
]
|
||||
@@ -27,6 +29,8 @@ source_set("location_bar") {
|
||||
"//brave/app/theme:brave_theme_resources",
|
||||
"//brave/app/vector_icons",
|
||||
"//brave/browser/ui:brave_tab_prefs",
|
||||
"//brave/browser/ui/page_info",
|
||||
"//brave/browser/ui/views/page_info",
|
||||
"//brave/components/brave_search_conversion",
|
||||
"//brave/components/commander/browser",
|
||||
"//brave/components/commander/common",
|
||||
@@ -43,6 +47,7 @@ source_set("location_bar") {
|
||||
"//chrome/browser/ui/tabs:tab_strip",
|
||||
"//chrome/browser/ui/views/location_bar",
|
||||
"//chrome/browser/ui/views/page_action",
|
||||
"//chrome/browser/ui/views/page_info",
|
||||
"//components/image_fetcher/core",
|
||||
"//components/search_engines",
|
||||
"//components/version_info:channel",
|
||||
|
||||
@@ -14,11 +14,13 @@
|
||||
#include "brave/app/vector_icons/vector_icons.h"
|
||||
#include "brave/browser/themes/brave_theme_service.h"
|
||||
#include "brave/browser/ui/color/brave_color_id.h"
|
||||
#include "brave/browser/ui/page_info/features.h"
|
||||
#include "brave/browser/ui/tabs/brave_tab_prefs.h"
|
||||
#include "brave/browser/ui/views/brave_actions/brave_actions_container.h"
|
||||
#include "brave/browser/ui/views/brave_news/brave_news_action_icon_view.h"
|
||||
#include "brave/browser/ui/views/location_bar/brave_search_conversion/promotion_button_controller.h"
|
||||
#include "brave/browser/ui/views/location_bar/brave_search_conversion/promotion_button_view.h"
|
||||
#include "brave/browser/ui/views/location_bar/brave_shields_page_info_controller.h"
|
||||
#include "brave/browser/ui/views/playlist/playlist_action_icon_view.h"
|
||||
#include "brave/browser/ui/views/toolbar/brave_toolbar_view.h"
|
||||
#include "brave/components/commander/common/buildflags/buildflags.h"
|
||||
@@ -134,6 +136,12 @@ void BraveLocationBarView::Init() {
|
||||
promotion_button_, omnibox_view_, browser());
|
||||
}
|
||||
|
||||
if (page_info::features::IsShowBraveShieldsInPageInfoEnabled()) {
|
||||
shields_page_info_controller_ =
|
||||
std::make_unique<BraveShieldsPageInfoController>(
|
||||
browser_->GetTabStripModel(), location_icon_view());
|
||||
}
|
||||
|
||||
// brave action buttons
|
||||
brave_actions_ = AddChildView(
|
||||
std::make_unique<BraveActionsContainer>(browser_, profile()));
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
class BraveActionsContainer;
|
||||
class BraveActionsContainerTest;
|
||||
class BraveShieldsPageInfoController;
|
||||
class PromotionButtonController;
|
||||
class PromotionButtonView;
|
||||
class PlaylistActionIconView;
|
||||
@@ -135,6 +136,7 @@ class BraveLocationBarView : public LocationBarView {
|
||||
raw_ptr<BraveNewsActionIconView> brave_news_action_icon_view_ = nullptr;
|
||||
std::unique_ptr<PromotionButtonController> promotion_controller_;
|
||||
raw_ptr<PromotionButtonView> promotion_button_ = nullptr;
|
||||
std::unique_ptr<BraveShieldsPageInfoController> shields_page_info_controller_;
|
||||
#if BUILDFLAG(ENABLE_TOR)
|
||||
raw_ptr<OnionLocationView> onion_location_view_ = nullptr;
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/* Copyright (c) 2025 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/location_bar/brave_shields_page_info_controller.h"
|
||||
|
||||
#include "base/check_deref.h"
|
||||
#include "brave/browser/ui/views/page_info/brave_page_info_bubble_view.h"
|
||||
#include "chrome/browser/ui/tabs/tab_strip_model.h"
|
||||
#include "chrome/browser/ui/views/location_bar/location_icon_view.h"
|
||||
#include "chrome/browser/ui/views/page_info/page_info_bubble_specification.h"
|
||||
#include "chrome/browser/ui/views/page_info/page_info_bubble_view.h"
|
||||
#include "content/public/browser/navigation_controller.h"
|
||||
#include "content/public/browser/navigation_entry.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "ui/views/view_utils.h"
|
||||
|
||||
namespace {
|
||||
|
||||
brave_shields::BraveShieldsTabHelper* GetShieldsHelper(
|
||||
content::WebContents* web_contents) {
|
||||
if (!web_contents) {
|
||||
return nullptr;
|
||||
}
|
||||
return brave_shields::BraveShieldsTabHelper::FromWebContents(web_contents);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
BraveShieldsPageInfoController::BraveShieldsPageInfoController(
|
||||
TabStripModel* tab_strip_model,
|
||||
LocationIconView* location_icon_view)
|
||||
: tab_strip_model_(CHECK_DEREF(tab_strip_model)),
|
||||
location_icon_view_(CHECK_DEREF(location_icon_view)) {
|
||||
tab_strip_model_->AddObserver(this);
|
||||
auto* web_contents = tab_strip_model_->GetActiveWebContents();
|
||||
if (auto* shields_helper = GetShieldsHelper(web_contents)) {
|
||||
shields_helper->AddObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
BraveShieldsPageInfoController::~BraveShieldsPageInfoController() {
|
||||
auto* web_contents = tab_strip_model_->GetActiveWebContents();
|
||||
if (auto* shields_helper = GetShieldsHelper(web_contents)) {
|
||||
shields_helper->RemoveObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
void BraveShieldsPageInfoController::OnTabStripModelChanged(
|
||||
TabStripModel* tab_strip_model,
|
||||
const TabStripModelChange& change,
|
||||
const TabStripSelectionChange& selection) {
|
||||
if (selection.active_tab_changed()) {
|
||||
if (auto* shields_helper = GetShieldsHelper(selection.old_contents)) {
|
||||
shields_helper->RemoveObserver(this);
|
||||
}
|
||||
if (auto* shields_helper = GetShieldsHelper(selection.new_contents)) {
|
||||
shields_helper->AddObserver(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BraveShieldsPageInfoController::OnResourcesChanged() {}
|
||||
|
||||
void BraveShieldsPageInfoController::OnRepeatedReloadsDetected() {
|
||||
ShowBubbleForRepeatedReloads();
|
||||
}
|
||||
|
||||
void BraveShieldsPageInfoController::ShowBubbleForRepeatedReloads() {
|
||||
auto* web_contents = tab_strip_model_->GetActiveWebContents();
|
||||
if (!web_contents) {
|
||||
return;
|
||||
}
|
||||
|
||||
content::NavigationEntry* entry =
|
||||
web_contents->GetController().GetVisibleEntry();
|
||||
if (!entry || entry->IsInitialEntry()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<PageInfoBubbleSpecification> specification =
|
||||
PageInfoBubbleSpecification::Builder(
|
||||
&location_icon_view_.get(),
|
||||
location_icon_view_->GetWidget()->GetNativeWindow(), web_contents,
|
||||
entry->GetVirtualURL())
|
||||
.Build();
|
||||
|
||||
views::BubbleDialogDelegateView* bubble =
|
||||
PageInfoBubbleView::CreatePageInfoBubble(std::move(specification));
|
||||
|
||||
auto* page_info_bubble = views::AsViewClass<BravePageInfoBubbleView>(bubble);
|
||||
CHECK(page_info_bubble);
|
||||
page_info_bubble->SetHighlightedButton(&location_icon_view_.get());
|
||||
page_info_bubble->GetWidget()->Show();
|
||||
page_info_bubble->OpenShieldsPageAfterRepeatedReloads();
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/* Copyright (c) 2025 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_LOCATION_BAR_BRAVE_SHIELDS_PAGE_INFO_CONTROLLER_H_
|
||||
#define BRAVE_BROWSER_UI_VIEWS_LOCATION_BAR_BRAVE_SHIELDS_PAGE_INFO_CONTROLLER_H_
|
||||
|
||||
#include "base/memory/raw_ref.h"
|
||||
#include "brave/browser/brave_shields/brave_shields_tab_helper.h"
|
||||
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
|
||||
|
||||
class LocationIconView;
|
||||
class TabStripModel;
|
||||
|
||||
// Controller that listens for Brave Shields events for the current active tab
|
||||
// and opens the Page Info bubble when appropriate.
|
||||
class BraveShieldsPageInfoController
|
||||
: public brave_shields::BraveShieldsTabHelper::Observer,
|
||||
public TabStripModelObserver {
|
||||
public:
|
||||
BraveShieldsPageInfoController(TabStripModel* tab_strip_model,
|
||||
LocationIconView* location_icon_view);
|
||||
|
||||
BraveShieldsPageInfoController(const BraveShieldsPageInfoController&) =
|
||||
delete;
|
||||
BraveShieldsPageInfoController& operator=(
|
||||
const BraveShieldsPageInfoController&) = delete;
|
||||
|
||||
~BraveShieldsPageInfoController() override;
|
||||
|
||||
// TabStripModelObserver:
|
||||
void OnTabStripModelChanged(
|
||||
TabStripModel* tab_strip_model,
|
||||
const TabStripModelChange& change,
|
||||
const TabStripSelectionChange& selection) override;
|
||||
|
||||
// brave_shields::BraveShieldsTabHelper::Observer:
|
||||
void OnResourcesChanged() override;
|
||||
void OnRepeatedReloadsDetected() override;
|
||||
|
||||
private:
|
||||
void ShowBubbleForRepeatedReloads();
|
||||
|
||||
raw_ref<TabStripModel> tab_strip_model_;
|
||||
raw_ref<LocationIconView> location_icon_view_;
|
||||
};
|
||||
|
||||
#endif // BRAVE_BROWSER_UI_VIEWS_LOCATION_BAR_BRAVE_SHIELDS_PAGE_INFO_CONTROLLER_H_
|
||||
@@ -43,6 +43,7 @@ source_set("browser_tests") {
|
||||
deps = [
|
||||
":page_info",
|
||||
"//brave/browser/ui/page_info",
|
||||
"//brave/components/brave_shields/core/common",
|
||||
"//chrome/browser/ui/views/frame",
|
||||
"//chrome/browser/ui/views/location_bar",
|
||||
"//chrome/browser/ui/views/page_info",
|
||||
|
||||
@@ -8,8 +8,10 @@
|
||||
#include "base/test/scoped_feature_list.h"
|
||||
#include "brave/browser/ui/page_info/features.h"
|
||||
#include "brave/browser/ui/views/page_info/brave_page_info_view_ids.h"
|
||||
#include "brave/components/brave_shields/core/common/features.h"
|
||||
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
#include "chrome/browser/ui/browser_commands.h"
|
||||
#include "chrome/browser/ui/views/frame/browser_view.h"
|
||||
#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
|
||||
#include "chrome/browser/ui/views/location_bar/location_icon_view.h"
|
||||
@@ -21,6 +23,7 @@
|
||||
#include "components/content_settings/core/common/content_settings_types.h"
|
||||
#include "components/page_info/page_info.h"
|
||||
#include "content/public/test/browser_test.h"
|
||||
#include "content/public/test/test_navigation_observer.h"
|
||||
#include "ui/events/test/test_event.h"
|
||||
#include "ui/views/controls/button/button.h"
|
||||
#include "ui/views/test/button_test_api.h"
|
||||
@@ -292,3 +295,51 @@ IN_PROC_BROWSER_TEST_F(BravePageInfoBubbleViewFlagDisabledBrowserTest,
|
||||
// Verify that the shields web UI is not visible.
|
||||
EXPECT_FALSE(IsShieldsViewDrawn(bubble_view));
|
||||
}
|
||||
|
||||
class BravePageInfoBubbleViewRepeatedReloadsBrowserTest
|
||||
: public BravePageInfoBubbleViewBrowserTestBase {
|
||||
public:
|
||||
BravePageInfoBubbleViewRepeatedReloadsBrowserTest() {
|
||||
using brave_shields::features::kAdblockOnlyMode;
|
||||
using brave_shields::features::kAdblockOnlyModePromptAfterPageReloadsMax;
|
||||
using brave_shields::features::kAdblockOnlyModePromptAfterPageReloadsMin;
|
||||
|
||||
feature_list_.InitWithFeaturesAndParameters(
|
||||
{{page_info::features::kShowBraveShieldsInPageInfo, {}},
|
||||
{kAdblockOnlyMode,
|
||||
{{kAdblockOnlyModePromptAfterPageReloadsMin.name, "2"},
|
||||
{kAdblockOnlyModePromptAfterPageReloadsMax.name, "3"}}}},
|
||||
{});
|
||||
}
|
||||
|
||||
~BravePageInfoBubbleViewRepeatedReloadsBrowserTest() override = default;
|
||||
|
||||
private:
|
||||
base::test::ScopedFeatureList feature_list_;
|
||||
};
|
||||
|
||||
// Test that the page info bubble is automatically opened and shows the shields
|
||||
// tab after repeated reloads.
|
||||
IN_PROC_BROWSER_TEST_F(BravePageInfoBubbleViewRepeatedReloadsBrowserTest,
|
||||
AutoOpenAfterRepeatedReloads) {
|
||||
GURL test_url = embedded_https_test_server().GetURL("/test.html");
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
|
||||
|
||||
auto reload = [&]() {
|
||||
content::TestNavigationObserver reload_observer(
|
||||
browser()->tab_strip_model()->GetActiveWebContents());
|
||||
chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
|
||||
reload_observer.Wait();
|
||||
};
|
||||
|
||||
// The first reload should not open the bubble.
|
||||
reload();
|
||||
EXPECT_FALSE(GetBubbleView());
|
||||
|
||||
// The second reload should open the bubble with the Shield tab visible.
|
||||
reload();
|
||||
auto* bubble_view = GetBubbleView();
|
||||
ASSERT_TRUE(bubble_view);
|
||||
EXPECT_TRUE(IsShieldsViewDrawn(bubble_view));
|
||||
EXPECT_FALSE(IsSiteSettingsViewDrawn(bubble_view));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user