Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added search promotion button in omnibox #25409

Merged
merged 1 commit into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/brave_generated_resources.grd
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,10 @@ Or change later at <ph name="SETTINGS_EXTENIONS_LINK">$2<ex>brave://settings/ext
<message name="IDS_ACC_BRAVE_SEARCH_CONVERSION_DISMISS_BUTTON" desc="Announcement when the dismiss button is focused.">
Dismiss Brave search conversion, press Enter to remove this suggestion
</message>
<message name="IDS_BRAVE_SEARCH_CONVERSION_BUTTON_LABEL" desc="The text for the search conversion promotion button">
Switch to Brave Search
</message>

<!-- web Discovery InfoBar -->
<message name="IDS_WEB_DISCOVERY_INFOBAR_MESSAGE" desc="The text for web discovery infobar message">
Help improve <ph name="SEARCH_NAME">$1<ex>Brave Search</ex></ph> by sending anonymous usage data. <ph name="MORE_INFO">$2<ex>More info</ex></ph>
Expand Down
1 change: 1 addition & 0 deletions app/theme/brave_theme_resources.grd
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
<structure type="chrome_scaled_image" name="IDR_BRAVE_SEARCH_CONVERSION_BANNER_GRAPHIC_DARK" file="brave/brave_search_conversion_banner_graphic_dark.png" />
<structure type="chrome_scaled_image" name="IDR_BRAVE_SEARCH_CONVERSION_BANNER_GRAPHIC_DDG" file="brave/brave_search_conversion_banner_graphic_ddg.png" />
<structure type="chrome_scaled_image" name="IDR_BRAVE_SEARCH_CONVERSION_BANNER_GRAPHIC_DDG_DARK" file="brave/brave_search_conversion_banner_graphic_ddg_dark.png" />
<structure type="chrome_scaled_image" name="IDR_BRAVE_SEARCH_CONVERSION_BUTTON_BRAVE_SEARCH_ICON" file="brave/brave_search_conversion_button_brave_search_icon.png" />
<structure type="chrome_scaled_image" name="IDR_BRAVE_SEARCH_LOGO_IN_SEARCH_PROMOTION" file="brave/brave_search_logo_in_search_promotion.png" />
</if>
</structures>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions browser/ui/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,10 @@ source_set("ui") {
"views/frame/vertical_tab_strip_widget_delegate_view.h",
"views/location_bar/brave_location_bar_view.cc",
"views/location_bar/brave_location_bar_view.h",
"views/location_bar/brave_search_conversion/promotion_button_controller.cc",
"views/location_bar/brave_search_conversion/promotion_button_controller.h",
"views/location_bar/brave_search_conversion/promotion_button_view.cc",
"views/location_bar/brave_search_conversion/promotion_button_view.h",
"views/location_bar/brave_star_view.cc",
"views/location_bar/brave_star_view.h",
"views/profiles/brave_avatar_toolbar_button.cc",
Expand Down
11 changes: 10 additions & 1 deletion browser/ui/color/brave_color_id.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,16 @@
E_CPONLY(kColorSearchConversionBannerTypeBackgroundBorderHovered) \
E_CPONLY(kColorSearchConversionBannerTypeBackgroundGradientFrom) \
E_CPONLY(kColorSearchConversionBannerTypeBackgroundGradientTo) \
E_CPONLY(kColorSearchConversionBannerTypeDescText)
E_CPONLY(kColorSearchConversionBannerTypeDescText) \
E_CPONLY(kColorSearchConversionButtonBorder) \
E_CPONLY(kColorSearchConversionButtonBackground) \
E_CPONLY(kColorSearchConversionButtonBackgroundHovered) \
E_CPONLY(kColorSearchConversionButtonText) \
E_CPONLY(kColorSearchConversionButtonCaratRight) \
E_CPONLY(kColorSearchConversionButtonCloseButton) \
E_CPONLY(kColorSearchConversionButtonCloseButtonHovered) \
E_CPONLY(kColorSearchConversionButtonShadow1) \
E_CPONLY(kColorSearchConversionButtonShadow2)

#define BRAVE_SIDEBAR_COLOR_IDS \
E_CPONLY(kColorSidebarAddBubbleBackground) \
Expand Down
20 changes: 20 additions & 0 deletions browser/ui/color/brave_color_mixer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,26 @@ void AddBraveColorMixerForAllThemes(ui::ColorProvider* provider,
// color by their color mixers.
mixer[kColorToolbarButtonActivated] = {SkColorSetRGB(0x7C, 0x91, 0xFF)};
mixer[kColorSidebarButtonPressed] = {kColorToolbarButtonActivated};

// Search conversion button in omnibox.
mixer[kColorSearchConversionButtonText] = {nala::kColorPrimary60};
mixer[kColorSearchConversionButtonBorder] = {nala::kColorPrimary20};
mixer[kColorSearchConversionButtonBackground] = {nala::kColorPrimary10};
mixer[kColorSearchConversionButtonBackgroundHovered] = {
nala::kColorPrimary20};
mixer[kColorSearchConversionButtonText] = {nala::kColorPrimary60};
mixer[kColorSearchConversionButtonCloseButton] = {
ui::AlphaBlend({nala::kColorIconInteractive},
{kColorSearchConversionButtonBackground}, 0.5 * 0xff)};
mixer[kColorSearchConversionButtonCloseButtonHovered] = {
ui::AlphaBlend({nala::kColorIconInteractive},
{kColorSearchConversionButtonBackground}, 0.7 * 0xff)};
mixer[kColorSearchConversionButtonCaratRight] = {
kColorSearchConversionButtonCloseButton};
mixer[kColorSearchConversionButtonShadow1] = {
SkColorSetA(SK_ColorBLACK, 0.05 * 255)};
mixer[kColorSearchConversionButtonShadow2] = {
SkColorSetA(SK_ColorBLACK, 0.1 * 255)};
}

} // namespace
Expand Down
24 changes: 24 additions & 0 deletions browser/ui/views/location_bar/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright (c) 2024 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/.

source_set("browser_tests") {
testonly = true
defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]

sources = [ "//brave/browser/ui/views/location_bar/brave_location_bar_view_browsertest.cc" ]

deps = [
"//base",
"//brave/components/brave_search_conversion",
"//chrome/browser",
"//chrome/browser/search_engines",
"//chrome/browser/ui",
"//chrome/common",
"//chrome/test",
"//chrome/test:test_support",
"//components/prefs",
"//ui/base:test_support",
]
}
19 changes: 19 additions & 0 deletions browser/ui/views/location_bar/brave_location_bar_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include "brave/browser/ui/tabs/features.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/playlist/playlist_action_icon_view.h"
#include "brave/browser/ui/views/toolbar/brave_toolbar_view.h"
#include "brave/components/commander/common/buildflags/buildflags.h"
Expand Down Expand Up @@ -125,6 +127,12 @@ void BraveLocationBarView::Init() {
AddChildView(std::make_unique<OnionLocationView>(browser_->profile()));
#endif

if (PromotionButtonController::PromotionEnabled(profile()->GetPrefs())) {
promotion_button_ = AddChildView(std::make_unique<PromotionButtonView>());
promotion_controller_ = std::make_unique<PromotionButtonController>(
promotion_button_, omnibox_view_, browser());
}

// brave action buttons
brave_actions_ = AddChildView(
std::make_unique<BraveActionsContainer>(browser_, profile()));
Expand Down Expand Up @@ -206,6 +214,13 @@ void BraveLocationBarView::OnChanged() {
brave_news_action_icon_view_->Update();
}

if (promotion_controller_) {
const bool show_button =
promotion_controller_->ShouldShowSearchPromotionButton() &&
!ShouldChipOverrideLocationIcon() && !ShouldShowKeywordBubble();
promotion_controller_->Show(show_button);
}

// OnChanged calls Layout
LocationBarView::OnChanged();
}
Expand Down Expand Up @@ -234,6 +249,10 @@ std::vector<views::View*> BraveLocationBarView::GetLeftMostTrailingViews() {
return views;
}

views::View* BraveLocationBarView::GetSearchPromotionButton() const {
return promotion_button_;
}

void BraveLocationBarView::RefreshBackground() {
LocationBarView::RefreshBackground();

Expand Down
7 changes: 7 additions & 0 deletions browser/ui/views/location_bar/brave_location_bar_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

class BraveActionsContainer;
class BraveActionsContainerTest;
class PromotionButtonController;
class PromotionButtonView;
class PlaylistActionIconView;
class RewardsBrowserTest;
class SkPath;
Expand Down Expand Up @@ -70,6 +72,7 @@ class BraveLocationBarView : public LocationBarView {
std::vector<views::View*> GetRightMostTrailingViews() override;
// Views that locates at left side of upstream's trailing views.
std::vector<views::View*> GetLeftMostTrailingViews() override;
views::View* GetSearchPromotionButton() const override;
void RefreshBackground() override;
void OnOmniboxBlurred() override;

Expand Down Expand Up @@ -104,6 +107,8 @@ class BraveLocationBarView : public LocationBarView {
playlist::PlaylistBrowserTestWithSitesUsingMediaSource,
MediaShouldBeExtractedFromBackground_DynamicallyAddedMedia);
FRIEND_TEST_ALL_PREFIXES(policy::BraveRewardsPolicyTest, RewardsIconIsHidden);
FRIEND_TEST_ALL_PREFIXES(BraveLocationBarViewBrowserTest,
SearchConversionButtonTest);
friend class ::BraveActionsContainerTest;
friend class ::RewardsBrowserTest;

Expand All @@ -113,6 +118,8 @@ class BraveLocationBarView : public LocationBarView {
std::unique_ptr<ViewShadow> shadow_;
raw_ptr<BraveActionsContainer> brave_actions_ = nullptr;
raw_ptr<BraveNewsActionIconView> brave_news_action_icon_view_ = nullptr;
std::unique_ptr<PromotionButtonController> promotion_controller_;
raw_ptr<PromotionButtonView> promotion_button_ = nullptr;
#if BUILDFLAG(ENABLE_TOR)
raw_ptr<OnionLocationView> onion_location_view_ = nullptr;
#endif
Expand Down
182 changes: 182 additions & 0 deletions browser/ui/views/location_bar/brave_location_bar_view_browsertest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/* Copyright (c) 2024 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_location_bar_view.h"

#include <memory>

#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.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/components/brave_search_conversion/features.h"
#include "brave/components/brave_search_conversion/pref_names.h"
#include "brave/components/search_engines/brave_prepopulated_engines.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/omnibox/omnibox_view_views.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/search_test_utils.h"
#include "components/omnibox/browser/omnibox_edit_model.h"
#include "components/omnibox/browser/omnibox_view.h"
#include "components/search_engines/template_url.h"
#include "components/search_engines/template_url_data_util.h"
#include "components/search_engines/template_url_service.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

class BraveLocationBarViewBrowserTest : public InProcessBrowserTest {
public:
BraveLocationBarViewBrowserTest() {
// Disabled by default.
EXPECT_FALSE(base::FeatureList::IsEnabled(
brave_search_conversion::features::kOmniboxPromotionButton));

features_.InitAndEnableFeature(
brave_search_conversion::features::kOmniboxPromotionButton);
}

BraveLocationBarView* location_bar() {
auto* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
return static_cast<BraveLocationBarView*>(
browser_view->toolbar()->location_bar());
}

OmniboxViewViews* omnibox_view() { return location_bar()->omnibox_view(); }

views::View* promotion_button_view() {
return location_bar()->GetSearchPromotionButton();
}

TemplateURLService* GetTemplateURLService() {
return TemplateURLServiceFactory::GetForProfile(browser()->profile());
}

content::WebContents* web_contents() {
return browser()->tab_strip_model()->GetActiveWebContents();
}

void WaitUntil(base::RepeatingCallback<bool()> condition) {
if (condition.Run()) {
return;
}

base::RepeatingTimer scheduler;
scheduler.Start(FROM_HERE, base::Milliseconds(100),
base::BindLambdaForTesting([this, &condition]() {
if (condition.Run()) {
run_loop_->Quit();
}
}));
Run();
}

void Run() {
run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run();
}

base::test::ScopedFeatureList features_;
std::unique_ptr<base::RunLoop> run_loop_;
};

IN_PROC_BROWSER_TEST_F(BraveLocationBarViewBrowserTest,
SearchConversionButtonTest) {
search_test_utils::WaitForTemplateURLServiceToLoad(GetTemplateURLService());

auto bing_search_data = TemplateURLDataFromPrepopulatedEngine(
TemplateURLPrepopulateData::brave_bing);
TemplateURL bing_template_url(*bing_search_data);

auto brave_search_data = TemplateURLDataFromPrepopulatedEngine(
TemplateURLPrepopulateData::brave_search);
TemplateURL brave_template_url(*brave_search_data);

// Set non brave search as a default provider and type any input.
// Check promotion button is launched.
GetTemplateURLService()->SetUserSelectedDefaultSearchProvider(
&bing_template_url);
location_bar()->FocusLocation(true);
omnibox_view()->SetUserText(u"a");
WaitUntil(base::BindLambdaForTesting(
[&]() { return omnibox_view()->model()->PopupIsOpen(); }));
EXPECT_TRUE(promotion_button_view()->GetVisible());

// Unfocus from the omnibox.
// Omnibox popup is hidden and promotion button will be gone also.
web_contents()->Focus();
WaitUntil(base::BindLambdaForTesting(
[&]() { return !omnibox_view()->model()->PopupIsOpen(); }));
EXPECT_FALSE(promotion_button_view()->GetVisible());

// Set brave search as a default provider and type any input.
GetTemplateURLService()->SetUserSelectedDefaultSearchProvider(
&brave_template_url);

// Check button is not shown with brave search.
location_bar()->FocusLocation(true);
omnibox_view()->SetUserText(u"a");
WaitUntil(base::BindLambdaForTesting(
[&]() { return omnibox_view()->model()->PopupIsOpen(); }));
EXPECT_FALSE(promotion_button_view()->GetVisible());

location_bar()->Revert();
WaitUntil(base::BindLambdaForTesting(
[&]() { return !omnibox_view()->model()->PopupIsOpen(); }));
EXPECT_FALSE(promotion_button_view()->GetVisible());

GetTemplateURLService()->SetUserSelectedDefaultSearchProvider(
&bing_template_url);

// Set dismissed and check button is not shown anymore.
browser()->profile()->GetPrefs()->SetBoolean(
brave_search_conversion::prefs::kDismissed, true);
omnibox_view()->SetUserText(u"a");
WaitUntil(base::BindLambdaForTesting(
[&]() { return omnibox_view()->model()->PopupIsOpen(); }));
EXPECT_FALSE(promotion_button_view()->GetVisible());

location_bar()->Revert();
WaitUntil(base::BindLambdaForTesting(
[&]() { return !omnibox_view()->model()->PopupIsOpen(); }));
EXPECT_FALSE(promotion_button_view()->GetVisible());

constexpr std::u16string search_term = u"a";

// Unset dismissed and simulate promotion button click.
browser()->profile()->GetPrefs()->SetBoolean(
brave_search_conversion::prefs::kDismissed, false);
location_bar()->FocusLocation(true);
omnibox_view()->SetUserText(search_term);
WaitUntil(base::BindLambdaForTesting(
[&]() { return omnibox_view()->model()->PopupIsOpen(); }));
EXPECT_TRUE(promotion_button_view()->GetVisible());

// Check brave search is set as default provider and brave search is loaded in
// active tab.
location_bar()
->promotion_controller_->SetDefaultAndLoadBraveSearchWithCurrentInput();
const TemplateURL* default_provider =
GetTemplateURLService()->GetDefaultSearchProvider();
const auto target_search_url = brave_template_url.GenerateSearchURL(
GetTemplateURLService()->search_terms_data(), search_term);
EXPECT_EQ(brave_template_url.prepopulate_id(),
default_provider->prepopulate_id());
content::WaitForLoadStop(web_contents());
EXPECT_EQ(target_search_url, web_contents()->GetVisibleURL());

// Check dismissed bit is set after user clicks button.
EXPECT_TRUE(browser()->profile()->GetPrefs()->GetBoolean(
brave_search_conversion::prefs::kDismissed));
}
Loading
Loading