Skip to content

Commit

Permalink
[ads] Add search result ad clicked InfoBar on desktop & android
Browse files Browse the repository at this point in the history
  • Loading branch information
aseren committed Sep 4, 2024
1 parent eaebaf5 commit 3647090
Show file tree
Hide file tree
Showing 13 changed files with 281 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
BraveInfoBarIdentifier.BRAVE_CONFIRM_P3A_INFOBAR_DELEGATE,
BraveInfoBarIdentifier.SYNC_CANNOT_RUN_INFOBAR,
BraveInfoBarIdentifier.WEB_DISCOVERY_INFOBAR_DELEGATE,
BraveInfoBarIdentifier.BRAVE_SYNC_ACCOUNT_DELETED_INFOBAR
BraveInfoBarIdentifier.BRAVE_SYNC_ACCOUNT_DELETED_INFOBAR,
BraveInfoBarIdentifier.SEARCH_RESULT_AD_CLICKED_INFOBAR_DELEGATE
})
@Retention(RetentionPolicy.SOURCE)
public @interface BraveInfoBarIdentifier {
Expand All @@ -29,4 +30,5 @@
int SYNC_CANNOT_RUN_INFOBAR = 505;
int WEB_DISCOVERY_INFOBAR_DELEGATE = 506;
int BRAVE_SYNC_ACCOUNT_DELETED_INFOBAR = 507;
int SEARCH_RESULT_AD_CLICKED_INFOBAR_DELEGATE = 510;
}
3 changes: 3 additions & 0 deletions app/brave_generated_resources.grd
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,9 @@ Or change later at <ph name="SETTINGS_EXTENIONS_LINK">$2<ex>brave://settings/ext
<message name="IDS_BRAVE_ADS_NOTIFICATION_CLICKED_SAME_AD_MULTIPLE_TIMES_BODY" desc="The notification body to show when a user clicks an ad multiple times">
You don't need to click to earn, but do click if you're interested!
</message>
<message name="IDS_BRAVE_ADS_SEARCH_RESULT_AD_CLICKED_INFOBAR_MESSAGE" desc="The text label of creative search result ad infobar message">
You’ve just clicked on a Brave Search ad. Unlike Big Tech, we measure ad performance anonymously and preserve your privacy.
</message>

<!-- Brave Search -->
<message name="IDS_SETTINGS_WEB_DISCOVERY_LABEL" desc="Description that shows settings for toggle Web Discovery">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* 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/brave_ads/creatives/search_result_ad/creative_search_result_ad_clicked_infobar_delegate.h"

#include <memory>

#include "brave/components/brave_ads/core/public/prefs/pref_names.h"
#include "brave/components/vector_icons/vector_icons.h"
#include "brave/grit/brave_generated_resources.h"
#include "chrome/browser/infobars/confirm_infobar_creator.h"
#include "components/infobars/content/content_infobar_manager.h"
#include "components/infobars/core/infobar.h"
#include "components/prefs/pref_service.h"
#include "components/strings/grit/components_strings.h"
#include "components/vector_icons/vector_icons.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"

namespace brave_ads {

namespace {

constexpr char kLearnMoreUrl[] =
"https://support.brave.com/hc/en-us/articles/360026361072-Brave-Ads-FAQ";

} // namespace

// static
void CreativeSearchResultAdClickedInfoBarDelegate::Create(
content::WebContents* web_contents,
PrefService* prefs) {
CHECK(web_contents);
CHECK(prefs);

infobars::ContentInfoBarManager* infobar_manager =
infobars::ContentInfoBarManager::FromWebContents(web_contents);
if (!infobar_manager) {
return;
}

if (!prefs->GetBoolean(prefs::kShouldShowSearchResultAdClickedInfoBar)) {
return;
}
prefs->SetBoolean(prefs::kShouldShowSearchResultAdClickedInfoBar, false);

infobar_manager->AddInfoBar(
CreateConfirmInfoBar(std::unique_ptr<ConfirmInfoBarDelegate>(
new CreativeSearchResultAdClickedInfoBarDelegate())));
}

CreativeSearchResultAdClickedInfoBarDelegate::
CreativeSearchResultAdClickedInfoBarDelegate() = default;

CreativeSearchResultAdClickedInfoBarDelegate::
~CreativeSearchResultAdClickedInfoBarDelegate() = default;

infobars::InfoBarDelegate::InfoBarIdentifier
CreativeSearchResultAdClickedInfoBarDelegate::GetIdentifier() const {
return SEARCH_RESULT_AD_CLICKED_INFOBAR_DELEGATE;
}

const gfx::VectorIcon&
CreativeSearchResultAdClickedInfoBarDelegate::GetVectorIcon() const {
return kLeoBraveIconMonochromeIcon;
}

std::u16string CreativeSearchResultAdClickedInfoBarDelegate::GetMessageText()
const {
return l10n_util::GetStringUTF16(
IDS_BRAVE_ADS_SEARCH_RESULT_AD_CLICKED_INFOBAR_MESSAGE);
}

int CreativeSearchResultAdClickedInfoBarDelegate::GetButtons() const {
return BUTTON_NONE;
}

std::u16string CreativeSearchResultAdClickedInfoBarDelegate::GetLinkText()
const {
return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
}

GURL CreativeSearchResultAdClickedInfoBarDelegate::GetLinkURL() const {
return GURL(kLearnMoreUrl);
}

} // namespace brave_ads
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* 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/. */

#ifndef BRAVE_BROWSER_BRAVE_ADS_CREATIVES_SEARCH_RESULT_AD_CREATIVE_SEARCH_RESULT_AD_CLICKED_INFOBAR_DELEGATE_H_
#define BRAVE_BROWSER_BRAVE_ADS_CREATIVES_SEARCH_RESULT_AD_CREATIVE_SEARCH_RESULT_AD_CLICKED_INFOBAR_DELEGATE_H_

#include "components/infobars/core/confirm_infobar_delegate.h"

class PrefService;

namespace content {
class WebContents;
} // namespace content

namespace brave_ads {

class CreativeSearchResultAdClickedInfoBarDelegate
: public ConfirmInfoBarDelegate {
public:
CreativeSearchResultAdClickedInfoBarDelegate();
~CreativeSearchResultAdClickedInfoBarDelegate() override;

CreativeSearchResultAdClickedInfoBarDelegate(
const CreativeSearchResultAdClickedInfoBarDelegate&) = delete;
CreativeSearchResultAdClickedInfoBarDelegate& operator=(
const CreativeSearchResultAdClickedInfoBarDelegate&) = delete;

static void Create(content::WebContents* web_contents, PrefService* prefs);

private:
// ConfirmInfoBarDelegate:
infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override;
const gfx::VectorIcon& GetVectorIcon() const override;
std::u16string GetMessageText() const override;
int GetButtons() const override;
std::u16string GetLinkText() const override;
GURL GetLinkURL() const override;
};

} // namespace brave_ads

#endif // BRAVE_BROWSER_BRAVE_ADS_CREATIVES_SEARCH_RESULT_AD_CREATIVE_SEARCH_RESULT_AD_CLICKED_INFOBAR_DELEGATE_H_
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@

#include "brave/browser/brave_ads/creatives/search_result_ad/creative_search_result_ad_tab_helper.h"

#include <utility>

#include "base/check.h"
#include "base/check_is_test.h"
#include "base/functional/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "brave/browser/brave_ads/ads_service_factory.h"
#include "brave/browser/brave_ads/creatives/search_result_ad/creative_search_result_ad_clicked_infobar_delegate.h"
#include "brave/components/brave_ads/browser/ads_service.h"
#include "brave/components/brave_ads/content/browser/creatives/search_result_ad/creative_search_result_ad_handler.h"
#include "brave/components/brave_ads/core/public/ads_feature.h"
Expand Down Expand Up @@ -92,15 +95,15 @@ bool CreativeSearchResultAdTabHelper::ShouldHandleCreativeAdEvents() const {

// If the feature is enabled, we should only trigger creative ad events when
// the user has joined Brave Rewards.
const Profile* const profile =
Profile::FromBrowserContext(web_contents()->GetBrowserContext());
return profile->GetPrefs()->GetBoolean(brave_rewards::prefs::kEnabled);
return GetPrefs()->GetBoolean(brave_rewards::prefs::kEnabled);
}

void CreativeSearchResultAdTabHelper::MaybeTriggerCreativeAdClickedEvent(
const GURL& url) {
const GURL& url,
base::OnceCallback<void(bool success)> callback) {
if (creative_search_result_ad_handler_) {
creative_search_result_ad_handler_->MaybeTriggerCreativeAdClickedEvent(url);
creative_search_result_ad_handler_->MaybeTriggerCreativeAdClickedEvent(
url, std::move(callback));
}
}

Expand All @@ -118,6 +121,22 @@ AdsService* CreativeSearchResultAdTabHelper::GetAdsService() const {
return AdsServiceFactory::GetForProfile(profile);
}

PrefService* CreativeSearchResultAdTabHelper::GetPrefs() const {
Profile* const profile =
Profile::FromBrowserContext(web_contents()->GetBrowserContext());
return profile->GetPrefs();
}

void CreativeSearchResultAdTabHelper::
MaybeTriggerCreativeAdClickedEventCallback(const bool success) {
if (!success) {
return;
}

CreativeSearchResultAdClickedInfoBarDelegate::Create(web_contents(),
GetPrefs());
}

void CreativeSearchResultAdTabHelper::MaybeCreateCreativeSearchResultAdHandler(
content::NavigationHandle* const navigation_handle) {
CHECK(navigation_handle);
Expand Down Expand Up @@ -230,7 +249,10 @@ void CreativeSearchResultAdTabHelper::MaybeHandleCreativeAdClickedEvent(
CHECK(!navigation_handle->GetRedirectChain().empty());
const GURL url = navigation_handle->GetRedirectChain().back();

creative_search_result_ad_tab_helper->MaybeTriggerCreativeAdClickedEvent(url);
creative_search_result_ad_tab_helper->MaybeTriggerCreativeAdClickedEvent(
url, base::BindOnce(&CreativeSearchResultAdTabHelper::
MaybeTriggerCreativeAdClickedEventCallback,
weak_factory_.GetWeakPtr()));
}

void CreativeSearchResultAdTabHelper::DidStartNavigation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "content/public/browser/web_contents_user_data.h"

class GURL;
class PrefService;

namespace brave_ads {

Expand All @@ -39,13 +40,19 @@ class CreativeSearchResultAdTabHelper

bool ShouldHandleCreativeAdEvents() const;

void MaybeTriggerCreativeAdClickedEvent(const GURL& url);
void MaybeTriggerCreativeAdClickedEvent(
const GURL& url,
base::OnceCallback<void(bool success)> callback);

private:
friend class content::WebContentsUserData<CreativeSearchResultAdTabHelper>;

AdsService* GetAdsService() const;

PrefService* GetPrefs() const;

void MaybeTriggerCreativeAdClickedEventCallback(bool success);

void MaybeCreateCreativeSearchResultAdHandler(
content::NavigationHandle* navigation_handle);

Expand Down
3 changes: 3 additions & 0 deletions browser/brave_ads/sources.gni
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ brave_browser_brave_ads_sources = [
"//brave/browser/brave_ads/application_state/notification_helper/notification_helper.h",
"//brave/browser/brave_ads/application_state/notification_helper/notification_helper_impl.cc",
"//brave/browser/brave_ads/application_state/notification_helper/notification_helper_impl.h",
"//brave/browser/brave_ads/creatives/search_result_ad/creative_search_result_ad_clicked_infobar_delegate.cc",
"//brave/browser/brave_ads/creatives/search_result_ad/creative_search_result_ad_clicked_infobar_delegate.h",
"//brave/browser/brave_ads/creatives/search_result_ad/creative_search_result_ad_tab_helper.cc",
"//brave/browser/brave_ads/creatives/search_result_ad/creative_search_result_ad_tab_helper.h",
"//brave/browser/brave_ads/tabs/ads_tab_helper.cc",
Expand All @@ -32,6 +34,7 @@ brave_browser_brave_ads_deps = [
"//brave/components/brave_ads/browser",
"//brave/components/brave_ads/content/browser",
"//brave/components/brave_ads/core",
"//brave/components/vector_icons",
"//chrome/browser/notifications",
"//chrome/browser/profiles",
"//chrome/browser/profiles:profile",
Expand Down
3 changes: 2 additions & 1 deletion chromium_src/components/infobars/core/infobar_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
WEB_DISCOVERY_INFOBAR_DELEGATE = 506, \
BRAVE_SYNC_ACCOUNT_DELETED_INFOBAR = 507, \
BRAVE_REQUEST_OTR_INFOBAR_DELEGATE = 508, \
DEV_CHANNEL_DEPRECATION_INFOBAR_DELEGATE = 509,
DEV_CHANNEL_DEPRECATION_INFOBAR_DELEGATE = 509, \
SEARCH_RESULT_AD_CLICKED_INFOBAR_DELEGATE = 510,

// Deprecated:
// WAYBACK_MACHINE_INFOBAR_DELEGATE = 502
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ void CreativeSearchResultAdHandler::
}

void CreativeSearchResultAdHandler::MaybeTriggerCreativeAdClickedEvent(
const GURL& url) {
const GURL& url,
base::OnceCallback<void(bool success)> callback) {
if (!creative_search_result_ads_) {
// No creative search result ads are present on the web page.
return;
Expand All @@ -100,8 +101,7 @@ void CreativeSearchResultAdHandler::MaybeTriggerCreativeAdClickedEvent(

ads_service_->TriggerSearchResultAdEvent(
creative_search_result_ad->Clone(),
mojom::SearchResultAdEventType::kClicked,
/*intentional*/ base::DoNothing());
mojom::SearchResultAdEventType::kClicked, std::move(callback));
}

///////////////////////////////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ class CreativeSearchResultAdHandler final {
ExtractCreativeAdPlacementIdsFromWebPageCallback callback);

void MaybeTriggerCreativeAdViewedEvent(const std::string& placement_id);
void MaybeTriggerCreativeAdClickedEvent(const GURL& url);
void MaybeTriggerCreativeAdClickedEvent(
const GURL& url,
base::OnceCallback<void(bool success)> callback);

private:
friend class BraveAdsCreativeSearchResultAdHandlerTest;
Expand Down
Loading

0 comments on commit 3647090

Please sign in to comment.