0

[Offers] Migrate Offer Notification Infobar to a Message

Offers linked to payment methods on merchant sites are currently shown on an infobar. This CL shows the offers on a Message.

Screenshot: https://screenshot.googleplex.com/axzyJjH4NPUuhXZ

Bug: 1323077
Change-Id: I8362f4d770571d2b29b25c82e63e39caf65d0675

Validate-Test-Flakiness: skip
Change-Id: I8362f4d770571d2b29b25c82e63e39caf65d0675
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3655680
Reviewed-by: Siyu An <siyua@chromium.org>
Reviewed-by: Evan Stade <estade@chromium.org>
Commit-Queue: Vishwas Uppoor <vishwasuppoor@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1012077}
This commit is contained in:
Vishwas Uppoor
2022-06-08 18:43:21 +00:00
committed by Chromium LUCI CQ
parent 73aee83b77
commit bcccd565a4
13 changed files with 329 additions and 157 deletions

@@ -864,8 +864,8 @@ static_library("ui") {
"autofill/payments/autofill_snackbar_controller_impl.cc",
"autofill/payments/autofill_snackbar_controller_impl.h",
"autofill/payments/autofill_snackbar_view.h",
"autofill/payments/offer_notification_infobar_controller_impl.cc",
"autofill/payments/offer_notification_infobar_controller_impl.h",
"autofill/payments/offer_notification_controller_android.cc",
"autofill/payments/offer_notification_controller_android.h",
"autofill/payments/virtual_card_enroll_bubble_controller_impl.cc",
"autofill/payments/virtual_card_enroll_bubble_controller_impl.h",
"browser_otr_state_android.cc",

@@ -95,7 +95,7 @@
#include "chrome/browser/ui/android/autofill/card_name_fix_flow_view_android.h"
#include "chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.h"
#include "chrome/browser/ui/android/infobars/autofill_offer_notification_infobar.h"
#include "chrome/browser/ui/autofill/payments/offer_notification_infobar_controller_impl.h"
#include "chrome/browser/ui/autofill/payments/offer_notification_controller_android.h"
#include "components/autofill/core/browser/payments/autofill_credit_card_filling_infobar_delegate_mobile.h"
#include "components/autofill/core/browser/payments/autofill_offer_notification_infobar_delegate_mobile.h"
#include "components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h"
@@ -793,8 +793,9 @@ void ChromeAutofillClient::UpdateOfferNotification(
// it again.
return;
}
std::unique_ptr<OfferNotificationInfoBarControllerImpl> controller =
std::make_unique<OfferNotificationInfoBarControllerImpl>(web_contents());
OfferNotificationControllerAndroid::CreateForWebContents(web_contents());
OfferNotificationControllerAndroid* controller =
OfferNotificationControllerAndroid::FromWebContents(web_contents());
controller->ShowIfNecessary(offer, card);
#else
OfferNotificationBubbleControllerImpl::CreateForWebContents(web_contents());
@@ -807,9 +808,9 @@ void ChromeAutofillClient::UpdateOfferNotification(
void ChromeAutofillClient::DismissOfferNotification() {
#if BUILDFLAG(IS_ANDROID)
std::unique_ptr<OfferNotificationInfoBarControllerImpl> controller =
std::make_unique<OfferNotificationInfoBarControllerImpl>(web_contents());
DCHECK(controller);
OfferNotificationControllerAndroid::CreateForWebContents(web_contents());
OfferNotificationControllerAndroid* controller =
OfferNotificationControllerAndroid::FromWebContents(web_contents());
controller->Dismiss();
#else
OfferNotificationBubbleControllerImpl* controller =

@@ -0,0 +1,117 @@
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/autofill/payments/offer_notification_controller_android.h"
#include <memory>
#include "chrome/browser/android/resource_mapper.h"
#include "chrome/browser/ui/android/infobars/autofill_offer_notification_infobar.h"
#include "components/autofill/core/browser/data_model/autofill_offer_data.h"
#include "components/autofill/core/browser/payments/autofill_offer_notification_infobar_delegate_mobile.h"
#include "components/grit/components_scaled_resources.h"
#include "components/infobars/content/content_infobar_manager.h"
#include "components/infobars/core/infobar.h"
#include "components/messages/android/message_dispatcher_bridge.h"
#include "components/messages/android/message_enums.h"
#include "components/messages/android/messages_feature.h"
#include "components/strings/grit/components_strings.h"
#include "ui/android/window_android.h"
#include "ui/base/l10n/l10n_util.h"
namespace autofill {
OfferNotificationControllerAndroid::OfferNotificationControllerAndroid(
content::WebContents* web_contents)
: content::WebContentsUserData<OfferNotificationControllerAndroid>(
*web_contents) {}
OfferNotificationControllerAndroid::~OfferNotificationControllerAndroid() {
DismissMessage();
}
void OfferNotificationControllerAndroid::ShowIfNecessary(
const AutofillOfferData* offer,
const CreditCard* card) {
DCHECK(offer);
if (!card)
return;
if (messages::IsOfferNotificationMessagesUiEnabled()) {
if (message_) {
// Dismiss the currently-shown message so that the new one can be
// displayed.
DismissMessage();
}
message_ = std::make_unique<messages::MessageWrapper>(
messages::MessageIdentifier::OFFER_NOTIFICATION,
base::BindOnce(&OfferNotificationControllerAndroid::HandleMessageAction,
base::Unretained(this), offer->GetOfferDetailsUrl()),
base::BindOnce(
&OfferNotificationControllerAndroid::HandleMessageDismiss,
base::Unretained(this)));
message_->SetTitle(
l10n_util::GetStringUTF16(IDS_AUTOFILL_OFFERS_MESSAGE_TITLE));
message_->SetDescription(l10n_util::GetStringFUTF16(
IDS_AUTOFILL_OFFERS_MESSAGE_DESCRIPTION_TEXT,
card->CardIdentifierStringForAutofillDisplay()));
message_->SetIconResourceId(
ResourceMapper::MapToJavaDrawableId(IDR_AUTOFILL_GOOGLE_PAY));
message_->DisableIconTint();
message_->SetPrimaryButtonText(l10n_util::GetStringUTF16(
IDS_AUTOFILL_OFFERS_MESSAGE_PRIMARY_BUTTON_TEXT));
messages::MessageDispatcherBridge::Get()->EnqueueMessage(
message_.get(), &GetWebContents(),
messages::MessageScopeType::WEB_CONTENTS,
messages::MessagePriority::kNormal);
} else {
infobars::ContentInfoBarManager::FromWebContents(&GetWebContents())
->AddInfoBar(std::make_unique<AutofillOfferNotificationInfoBar>(
std::make_unique<AutofillOfferNotificationInfoBarDelegateMobile>(
offer->GetOfferDetailsUrl(), *card)));
}
}
void OfferNotificationControllerAndroid::Dismiss() {
if (messages::IsOfferNotificationMessagesUiEnabled()) {
DismissMessage();
} else {
infobars::ContentInfoBarManager* content_infobar_manager =
infobars::ContentInfoBarManager::FromWebContents(&GetWebContents());
if (!content_infobar_manager)
return;
for (size_t i = 0; i < content_infobar_manager->infobar_count(); ++i) {
infobars::InfoBar* infobar = content_infobar_manager->infobar_at(i);
if (infobar->delegate()->GetIdentifier() ==
infobars::InfoBarDelegate::
AUTOFILL_OFFER_NOTIFICATION_INFOBAR_DELEGATE) {
content_infobar_manager->RemoveInfoBar(infobar);
return;
}
}
}
}
void OfferNotificationControllerAndroid::DismissMessage() {
if (message_) {
messages::MessageDispatcherBridge::Get()->DismissMessage(
message_.get(), messages::DismissReason::UNKNOWN);
}
}
void OfferNotificationControllerAndroid::HandleMessageAction(const GURL& url) {
GetWebContents().OpenURL(content::OpenURLParams(
url, content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB,
ui::PAGE_TRANSITION_LINK, false));
}
void OfferNotificationControllerAndroid::HandleMessageDismiss(
messages::DismissReason dismiss_reason) {
message_.reset();
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(OfferNotificationControllerAndroid);
} // namespace autofill

@@ -0,0 +1,57 @@
// Copyright 2022 The Chromium Authors. All rights reserved.
// 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_OFFER_NOTIFICATION_CONTROLLER_ANDROID_H_
#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_OFFER_NOTIFICATION_CONTROLLER_ANDROID_H_
#include "base/memory/raw_ptr.h"
#include "components/autofill/core/browser/data_model/credit_card.h"
#include "components/messages/android/message_wrapper.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_user_data.h"
namespace autofill {
class AutofillOfferData;
// Per-tab controller to control the offer notification infobar / message
// displayed on mobile.
class OfferNotificationControllerAndroid
: public content::WebContentsUserData<OfferNotificationControllerAndroid> {
public:
explicit OfferNotificationControllerAndroid(
content::WebContents* web_contents);
~OfferNotificationControllerAndroid() override;
OfferNotificationControllerAndroid(
const OfferNotificationControllerAndroid&) = delete;
OfferNotificationControllerAndroid& operator=(
const OfferNotificationControllerAndroid&) = delete;
// Show the infobar / message unless it was already shown in the same tab with
// the same origin.
void ShowIfNecessary(const AutofillOfferData* offer, const CreditCard* card);
// Dismiss the infobar / message if it is visible.
void Dismiss();
private:
friend class content::WebContentsUserData<OfferNotificationControllerAndroid>;
// Dismiss the message if it is visible.
void DismissMessage();
// Callbacks for user selection on offer notification message.
void HandleMessageAction(const GURL& url);
void HandleMessageDismiss(messages::DismissReason dismiss_reason);
// Delegate of a toast style popup showing in the top of the screen.
std::unique_ptr<messages::MessageWrapper> message_;
WEB_CONTENTS_USER_DATA_KEY_DECL();
};
} // namespace autofill
#endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_OFFER_NOTIFICATION_CONTROLLER_ANDROID_H_

@@ -3,10 +3,11 @@
// found in the LICENSE file.
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/autofill/autofill_uitest_util.h"
#include "chrome/browser/autofill/personal_data_manager_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/autofill/payments/offer_notification_infobar_controller_impl.h"
#include "chrome/browser/ui/autofill/payments/offer_notification_controller_android.h"
#include "chrome/test/base/android/android_browser_test.h"
#include "chrome/test/base/chrome_test_utils.h"
#include "components/autofill/content/browser/content_autofill_driver.h"
@@ -19,6 +20,9 @@
#include "components/infobars/content/content_infobar_manager.h"
#include "components/infobars/core/infobar.h"
#include "components/infobars/core/infobar_delegate.h"
#include "components/messages/android/message_enums.h"
#include "components/messages/android/messages_feature.h"
#include "components/messages/android/test/messages_test_helper.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
@@ -29,11 +33,11 @@ namespace autofill {
const char kHostName[] = "example.com";
class OfferNotificationInfoBarControllerImplBrowserTest
class OfferNotificationControllerAndroidBrowserTest
: public AndroidBrowserTest {
public:
OfferNotificationInfoBarControllerImplBrowserTest() = default;
~OfferNotificationInfoBarControllerImplBrowserTest() override = default;
OfferNotificationControllerAndroidBrowserTest() = default;
~OfferNotificationControllerAndroidBrowserTest() override = default;
void SetUp() override {
AndroidBrowserTest::SetUp();
@@ -44,30 +48,6 @@ class OfferNotificationInfoBarControllerImplBrowserTest
return chrome_test_utils::GetActiveWebContents(this);
}
infobars::InfoBar* GetInfoBar() {
infobars::ContentInfoBarManager* infobar_manager =
infobars::ContentInfoBarManager::FromWebContents(GetWebContents());
for (size_t i = 0; i < infobar_manager->infobar_count(); ++i) {
infobars::InfoBar* infobar = infobar_manager->infobar_at(i);
if (infobar->delegate()->GetIdentifier() ==
infobars::InfoBarDelegate::
AUTOFILL_OFFER_NOTIFICATION_INFOBAR_DELEGATE) {
return infobar;
}
}
return nullptr;
}
AutofillOfferNotificationInfoBarDelegateMobile* GetInfoBarDelegate(
infobars::InfoBar* infobar) {
return static_cast<AutofillOfferNotificationInfoBarDelegateMobile*>(
infobar->delegate());
}
void ShowOfferNotificationInfoBar(const AutofillOfferData* offer) {
offer_notification_infobar_controller_->ShowIfNecessary(offer, &card_);
}
AutofillOfferData CreateTestCardLinkedOffer(
const std::vector<GURL>& merchant_origins,
const std::vector<int64_t>& eligible_instrument_ids,
@@ -81,19 +61,6 @@ class OfferNotificationInfoBarControllerImplBrowserTest
offer_reward_amount);
}
void VerifyInfoBarShownCount(int count) {
histogram_tester_.ExpectTotalCount(
"Autofill.OfferNotificationInfoBarOffer.CardLinkedOffer", count);
}
void VerifyInfoBarResultMetric(
AutofillMetrics::OfferNotificationInfoBarResultMetric metric,
int count) {
histogram_tester_.ExpectBucketCount(
"Autofill.OfferNotificationInfoBarResult.CardLinkedOffer", metric,
count);
}
GURL GetInitialUrl() {
return embedded_test_server()->GetURL(kHostName, "/empty.html");
}
@@ -104,9 +71,8 @@ class OfferNotificationInfoBarControllerImplBrowserTest
// Wait for Personal Data Manager to be fully loaded to prevent that
// spurious notifications deceive the tests.
WaitForPersonalDataManagerToBeLoaded(GetProfile());
offer_notification_infobar_controller_ =
std::make_unique<OfferNotificationInfoBarControllerImpl>(
GetWebContents());
offer_notification_controller_android_ =
std::make_unique<OfferNotificationControllerAndroid>(GetWebContents());
host_resolver()->AddRule("*", "127.0.0.1");
embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(embedded_test_server()->Start());
@@ -150,17 +116,70 @@ class OfferNotificationInfoBarControllerImplBrowserTest
handler->AddShownNotificationIdForTesting(id);
}
private:
std::unique_ptr<OfferNotificationInfoBarControllerImpl>
offer_notification_infobar_controller_;
// CreditCard that is linked to the offer displayed in the offer notification
// infobar.
protected:
std::unique_ptr<OfferNotificationControllerAndroid>
offer_notification_controller_android_;
// CreditCard that is linked to the offer displayed in the offer notification.
CreditCard card_;
base::HistogramTester histogram_tester_;
base::test::ScopedFeatureList scoped_feature_list_;
private:
PersonalDataManager* personal_data_;
};
IN_PROC_BROWSER_TEST_F(OfferNotificationInfoBarControllerImplBrowserTest,
class OfferNotificationControllerAndroidBrowserTestForInfobar
: public OfferNotificationControllerAndroidBrowserTest {
public:
OfferNotificationControllerAndroidBrowserTestForInfobar() = default;
void SetUp() override {
scoped_feature_list_.InitWithFeatures(
/*enabled_features=*/{},
/*disabled_features=*/{messages::kMessagesForAndroidInfrastructure,
messages::kMessagesForAndroidOfferNotification});
OfferNotificationControllerAndroidBrowserTest::SetUp();
}
infobars::InfoBar* GetInfoBar() {
infobars::ContentInfoBarManager* infobar_manager =
infobars::ContentInfoBarManager::FromWebContents(GetWebContents());
for (size_t i = 0; i < infobar_manager->infobar_count(); ++i) {
infobars::InfoBar* infobar = infobar_manager->infobar_at(i);
if (infobar->delegate()->GetIdentifier() ==
infobars::InfoBarDelegate::
AUTOFILL_OFFER_NOTIFICATION_INFOBAR_DELEGATE) {
return infobar;
}
}
return nullptr;
}
AutofillOfferNotificationInfoBarDelegateMobile* GetInfoBarDelegate(
infobars::InfoBar* infobar) {
return static_cast<AutofillOfferNotificationInfoBarDelegateMobile*>(
infobar->delegate());
}
void ShowOfferNotificationInfoBar(const AutofillOfferData* offer) {
offer_notification_controller_android_->ShowIfNecessary(offer, &card_);
}
void VerifyInfoBarShownCount(int count) {
histogram_tester_.ExpectTotalCount(
"Autofill.OfferNotificationInfoBarOffer.CardLinkedOffer", count);
}
void VerifyInfoBarResultMetric(
AutofillMetrics::OfferNotificationInfoBarResultMetric metric,
int count) {
histogram_tester_.ExpectBucketCount(
"Autofill.OfferNotificationInfoBarResult.CardLinkedOffer", metric,
count);
}
};
IN_PROC_BROWSER_TEST_F(OfferNotificationControllerAndroidBrowserTestForInfobar,
ShowInfobarAndAccept) {
GURL offer_url = GetInitialUrl().DeprecatedGetOriginAsURL();
SetUpOfferDataWithDomains(offer_url);
@@ -181,7 +200,7 @@ IN_PROC_BROWSER_TEST_F(OfferNotificationInfoBarControllerImplBrowserTest,
1);
}
IN_PROC_BROWSER_TEST_F(OfferNotificationInfoBarControllerImplBrowserTest,
IN_PROC_BROWSER_TEST_F(OfferNotificationControllerAndroidBrowserTestForInfobar,
ShowInfobarAndClose) {
GURL offer_url = GetInitialUrl().DeprecatedGetOriginAsURL();
SetUpOfferDataWithDomains(offer_url);
@@ -202,7 +221,7 @@ IN_PROC_BROWSER_TEST_F(OfferNotificationInfoBarControllerImplBrowserTest,
1);
}
IN_PROC_BROWSER_TEST_F(OfferNotificationInfoBarControllerImplBrowserTest,
IN_PROC_BROWSER_TEST_F(OfferNotificationControllerAndroidBrowserTestForInfobar,
CrossTabStatusTracking) {
GURL offer_url = GetInitialUrl().DeprecatedGetOriginAsURL();
int64_t id = SetUpOfferDataWithDomains(offer_url)->GetOfferId();
@@ -219,4 +238,64 @@ IN_PROC_BROWSER_TEST_F(OfferNotificationInfoBarControllerImplBrowserTest,
VerifyInfoBarShownCount(0);
}
class OfferNotificationControllerAndroidBrowserTestForMessagesUi
: public OfferNotificationControllerAndroidBrowserTest {
public:
OfferNotificationControllerAndroidBrowserTestForMessagesUi() = default;
void SetUp() override {
scoped_feature_list_.InitWithFeatures(
/*enabled_features=*/{messages::kMessagesForAndroidInfrastructure,
messages::kMessagesForAndroidOfferNotification},
/*disabled_features=*/{});
OfferNotificationControllerAndroidBrowserTest::SetUp();
}
void VerifyMessageShownCountMetric(int count) {
histogram_tester_.ExpectBucketCount(
"Android.Messages.Enqueued.Visible",
static_cast<int>(messages::MessageIdentifier::OFFER_NOTIFICATION),
count);
}
messages::MessagesTestHelper messages_test_helper_;
};
IN_PROC_BROWSER_TEST_F(
OfferNotificationControllerAndroidBrowserTestForMessagesUi,
MessageShown) {
GURL offer_url = GetInitialUrl().DeprecatedGetOriginAsURL();
SetUpOfferDataWithDomains(offer_url);
ASSERT_TRUE(content::NavigateToURL(GetWebContents(), GetInitialUrl()));
// Verify that the message was shown and logged.
EXPECT_EQ(messages_test_helper_.GetMessageCount(
GetWebContents()->GetTopLevelNativeWindow()),
1);
EXPECT_EQ(
messages_test_helper_.GetMessageIdentifier(
GetWebContents()->GetTopLevelNativeWindow(), /* enqueue index */ 0),
static_cast<int>(messages::MessageIdentifier::OFFER_NOTIFICATION));
VerifyMessageShownCountMetric(1);
}
IN_PROC_BROWSER_TEST_F(
OfferNotificationControllerAndroidBrowserTestForMessagesUi,
CrossTabStatusTracking) {
GURL offer_url = GetInitialUrl().DeprecatedGetOriginAsURL();
int64_t id = SetUpOfferDataWithDomains(offer_url)->GetOfferId();
SetShownOffer(id);
// Navigate to a different URL within the same domain and try to show the
// message.
offer_url = embedded_test_server()->GetURL(kHostName, "/simple_page.html");
ASSERT_TRUE(content::NavigateToURL(GetWebContents(), offer_url));
// Verify that the message was not shown again because it has already been
// marked as shown for this domain.
EXPECT_EQ(messages_test_helper_.GetMessageCount(
GetWebContents()->GetTopLevelNativeWindow()),
0);
VerifyMessageShownCountMetric(0);
}
} // namespace autofill

@@ -1,50 +0,0 @@
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/autofill/payments/offer_notification_infobar_controller_impl.h"
#include "chrome/browser/ui/android/infobars/autofill_offer_notification_infobar.h"
#include "components/autofill/core/browser/data_model/autofill_offer_data.h"
#include "components/autofill/core/browser/payments/autofill_offer_notification_infobar_delegate_mobile.h"
#include "components/infobars/content/content_infobar_manager.h"
#include "components/infobars/core/infobar.h"
#include "ui/android/window_android.h"
namespace autofill {
OfferNotificationInfoBarControllerImpl::OfferNotificationInfoBarControllerImpl(
content::WebContents* contents)
: web_contents_(contents) {}
void OfferNotificationInfoBarControllerImpl::ShowIfNecessary(
const AutofillOfferData* offer,
const CreditCard* card) {
DCHECK(offer);
if (!card)
return;
infobars::ContentInfoBarManager::FromWebContents(web_contents_)
->AddInfoBar(std::make_unique<AutofillOfferNotificationInfoBar>(
std::make_unique<AutofillOfferNotificationInfoBarDelegateMobile>(
offer->GetOfferDetailsUrl(), *card)));
}
void OfferNotificationInfoBarControllerImpl::Dismiss() {
infobars::ContentInfoBarManager* content_infobar_manager =
infobars::ContentInfoBarManager::FromWebContents(web_contents_);
if (!content_infobar_manager)
return;
for (size_t i = 0; i < content_infobar_manager->infobar_count(); ++i) {
infobars::InfoBar* infobar = content_infobar_manager->infobar_at(i);
if (infobar->delegate()->GetIdentifier() ==
infobars::InfoBarDelegate::
AUTOFILL_OFFER_NOTIFICATION_INFOBAR_DELEGATE) {
content_infobar_manager->RemoveInfoBar(infobar);
return;
}
}
}
} // namespace autofill

@@ -1,44 +0,0 @@
// Copyright 2021 The Chromium Authors. All rights reserved.
// 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_OFFER_NOTIFICATION_INFOBAR_CONTROLLER_IMPL_H_
#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_OFFER_NOTIFICATION_INFOBAR_CONTROLLER_IMPL_H_
#include "base/memory/raw_ptr.h"
#include "components/autofill/core/browser/data_model/credit_card.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
namespace autofill {
class AutofillOfferData;
// Per-tab controller to control the offer notification infobar displayed on
// mobile.
class OfferNotificationInfoBarControllerImpl {
public:
explicit OfferNotificationInfoBarControllerImpl(
content::WebContents* contents);
~OfferNotificationInfoBarControllerImpl() = default;
OfferNotificationInfoBarControllerImpl(
const OfferNotificationInfoBarControllerImpl&) = delete;
OfferNotificationInfoBarControllerImpl& operator=(
const OfferNotificationInfoBarControllerImpl&) = delete;
// Show the infobar unless it was already shown in the same tab with the same
// origin.
void ShowIfNecessary(const AutofillOfferData* offer, const CreditCard* card);
// Dismiss the infobar if it is visible.
void Dismiss();
private:
raw_ptr<content::WebContents> web_contents_;
};
} // namespace autofill
#endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_OFFER_NOTIFICATION_INFOBAR_CONTROLLER_IMPL_H_

@@ -853,7 +853,7 @@ if (is_android) {
"../browser/ssl/crlset_browsertest.cc",
"../browser/subresource_filter/subresource_filter_browser_test_harness.cc",
"../browser/subresource_filter/subresource_filter_browser_test_harness.h",
"../browser/ui/autofill/payments/offer_notification_infobar_controller_impl_browsertest.cc",
"../browser/ui/autofill/payments/offer_notification_controller_android_browsertest.cc",
"../browser/ui/webui/policy/policy_ui_browsertest.cc",
"../renderer/autofill/fake_mojo_password_manager_driver.cc",
"../renderer/autofill/fake_mojo_password_manager_driver.h",

@@ -78,7 +78,7 @@ class AutofillOfferManager : public KeyedService,
CreateCardLinkedOffersMap_ReturnsOnlyCardLinkedOffers);
FRIEND_TEST_ALL_PREFIXES(AutofillOfferManagerTest, IsUrlEligible);
friend class OfferNotificationBubbleViewsInteractiveUiTest;
friend class OfferNotificationInfoBarControllerImplBrowserTest;
friend class OfferNotificationControllerAndroidBrowserTest;
// Queries |personal_data_| to reset the elements of
// |eligible_merchant_domains_|

@@ -671,12 +671,21 @@
</message>
</if>
<if expr="is_android">
<message name="IDS_AUTOFILL_OFFERS_REMINDER_DESCRIPTION_TEXT" desc="Secondary explanatory text for the Clank infobar shown on the merchant website when an offer is available to use." formatter_data="android_java">
<message name="IDS_AUTOFILL_OFFERS_REMINDER_DESCRIPTION_TEXT" desc="Secondary explanatory text for the infobar shown on the merchant website when an offer is available to use." formatter_data="android_java">
Pay with <ph name="CARD_DETAIL">%1$s<ex>Visa - 1234</ex></ph> at checkout.
</message>
<message name="IDS_AUTOFILL_OFFERS_REMINDER_DEEP_LINK_TEXT" desc="Text to be linked to take the user to the offer in the Google Pay app." formatter_data="android_java">
See details
</message>
<message name="IDS_AUTOFILL_OFFERS_MESSAGE_TITLE" desc="Title of the message shown on the merchant website when a GPay-activated card linked offer is available to use.">
Google Pay offer available
</message>
<message name="IDS_AUTOFILL_OFFERS_MESSAGE_DESCRIPTION_TEXT" desc="Secondary explanatory text for the message shown on the merchant website when an offer is available to use.">
Check out with <ph name="CARD_DETAIL">$1<ex>Visa - 1234</ex></ph> to use offer
</message>
<message name="IDS_AUTOFILL_OFFERS_MESSAGE_PRIMARY_BUTTON_TEXT" desc="Text for the primary button of the message shown on the merchant website when a GPay-activated card linked offer is available to use.">
Details
</message>
</if>
<if expr="toolkit_views">
<message name="IDS_AUTOFILL_PROMO_CODE_OFFERS_REMINDER_TITLE" desc="Title of the bubble shown on the merchant website when a merchant promo code offer is available to use.">

@@ -0,0 +1 @@
587b54e3577dbb3f64e126b4d7c01c4480bac10e

@@ -0,0 +1 @@
33628376178104d1b7a0adddac1e4bd96995e208

@@ -0,0 +1 @@
1f41b89f1889a8e89497daf7d63ac16bf0113bd2