[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:

committed by
Chromium LUCI CQ

parent
73aee83b77
commit
bcccd565a4
chrome
browser
ui
test
components
@@ -864,8 +864,8 @@ static_library("ui") {
|
|||||||
"autofill/payments/autofill_snackbar_controller_impl.cc",
|
"autofill/payments/autofill_snackbar_controller_impl.cc",
|
||||||
"autofill/payments/autofill_snackbar_controller_impl.h",
|
"autofill/payments/autofill_snackbar_controller_impl.h",
|
||||||
"autofill/payments/autofill_snackbar_view.h",
|
"autofill/payments/autofill_snackbar_view.h",
|
||||||
"autofill/payments/offer_notification_infobar_controller_impl.cc",
|
"autofill/payments/offer_notification_controller_android.cc",
|
||||||
"autofill/payments/offer_notification_infobar_controller_impl.h",
|
"autofill/payments/offer_notification_controller_android.h",
|
||||||
"autofill/payments/virtual_card_enroll_bubble_controller_impl.cc",
|
"autofill/payments/virtual_card_enroll_bubble_controller_impl.cc",
|
||||||
"autofill/payments/virtual_card_enroll_bubble_controller_impl.h",
|
"autofill/payments/virtual_card_enroll_bubble_controller_impl.h",
|
||||||
"browser_otr_state_android.cc",
|
"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/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_credit_card_filling_infobar.h"
|
||||||
#include "chrome/browser/ui/android/infobars/autofill_offer_notification_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_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_offer_notification_infobar_delegate_mobile.h"
|
||||||
#include "components/autofill/core/browser/payments/autofill_save_card_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.
|
// it again.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::unique_ptr<OfferNotificationInfoBarControllerImpl> controller =
|
OfferNotificationControllerAndroid::CreateForWebContents(web_contents());
|
||||||
std::make_unique<OfferNotificationInfoBarControllerImpl>(web_contents());
|
OfferNotificationControllerAndroid* controller =
|
||||||
|
OfferNotificationControllerAndroid::FromWebContents(web_contents());
|
||||||
controller->ShowIfNecessary(offer, card);
|
controller->ShowIfNecessary(offer, card);
|
||||||
#else
|
#else
|
||||||
OfferNotificationBubbleControllerImpl::CreateForWebContents(web_contents());
|
OfferNotificationBubbleControllerImpl::CreateForWebContents(web_contents());
|
||||||
@@ -807,9 +808,9 @@ void ChromeAutofillClient::UpdateOfferNotification(
|
|||||||
|
|
||||||
void ChromeAutofillClient::DismissOfferNotification() {
|
void ChromeAutofillClient::DismissOfferNotification() {
|
||||||
#if BUILDFLAG(IS_ANDROID)
|
#if BUILDFLAG(IS_ANDROID)
|
||||||
std::unique_ptr<OfferNotificationInfoBarControllerImpl> controller =
|
OfferNotificationControllerAndroid::CreateForWebContents(web_contents());
|
||||||
std::make_unique<OfferNotificationInfoBarControllerImpl>(web_contents());
|
OfferNotificationControllerAndroid* controller =
|
||||||
DCHECK(controller);
|
OfferNotificationControllerAndroid::FromWebContents(web_contents());
|
||||||
controller->Dismiss();
|
controller->Dismiss();
|
||||||
#else
|
#else
|
||||||
OfferNotificationBubbleControllerImpl* controller =
|
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.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
#include "base/test/metrics/histogram_tester.h"
|
#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/autofill_uitest_util.h"
|
||||||
#include "chrome/browser/autofill/personal_data_manager_factory.h"
|
#include "chrome/browser/autofill/personal_data_manager_factory.h"
|
||||||
#include "chrome/browser/profiles/profile.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/android/android_browser_test.h"
|
||||||
#include "chrome/test/base/chrome_test_utils.h"
|
#include "chrome/test/base/chrome_test_utils.h"
|
||||||
#include "components/autofill/content/browser/content_autofill_driver.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/content/content_infobar_manager.h"
|
||||||
#include "components/infobars/core/infobar.h"
|
#include "components/infobars/core/infobar.h"
|
||||||
#include "components/infobars/core/infobar_delegate.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/browser/web_contents.h"
|
||||||
#include "content/public/test/browser_test.h"
|
#include "content/public/test/browser_test.h"
|
||||||
#include "content/public/test/browser_test_utils.h"
|
#include "content/public/test/browser_test_utils.h"
|
||||||
@@ -29,11 +33,11 @@ namespace autofill {
|
|||||||
|
|
||||||
const char kHostName[] = "example.com";
|
const char kHostName[] = "example.com";
|
||||||
|
|
||||||
class OfferNotificationInfoBarControllerImplBrowserTest
|
class OfferNotificationControllerAndroidBrowserTest
|
||||||
: public AndroidBrowserTest {
|
: public AndroidBrowserTest {
|
||||||
public:
|
public:
|
||||||
OfferNotificationInfoBarControllerImplBrowserTest() = default;
|
OfferNotificationControllerAndroidBrowserTest() = default;
|
||||||
~OfferNotificationInfoBarControllerImplBrowserTest() override = default;
|
~OfferNotificationControllerAndroidBrowserTest() override = default;
|
||||||
|
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
AndroidBrowserTest::SetUp();
|
AndroidBrowserTest::SetUp();
|
||||||
@@ -44,30 +48,6 @@ class OfferNotificationInfoBarControllerImplBrowserTest
|
|||||||
return chrome_test_utils::GetActiveWebContents(this);
|
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(
|
AutofillOfferData CreateTestCardLinkedOffer(
|
||||||
const std::vector<GURL>& merchant_origins,
|
const std::vector<GURL>& merchant_origins,
|
||||||
const std::vector<int64_t>& eligible_instrument_ids,
|
const std::vector<int64_t>& eligible_instrument_ids,
|
||||||
@@ -81,19 +61,6 @@ class OfferNotificationInfoBarControllerImplBrowserTest
|
|||||||
offer_reward_amount);
|
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() {
|
GURL GetInitialUrl() {
|
||||||
return embedded_test_server()->GetURL(kHostName, "/empty.html");
|
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
|
// Wait for Personal Data Manager to be fully loaded to prevent that
|
||||||
// spurious notifications deceive the tests.
|
// spurious notifications deceive the tests.
|
||||||
WaitForPersonalDataManagerToBeLoaded(GetProfile());
|
WaitForPersonalDataManagerToBeLoaded(GetProfile());
|
||||||
offer_notification_infobar_controller_ =
|
offer_notification_controller_android_ =
|
||||||
std::make_unique<OfferNotificationInfoBarControllerImpl>(
|
std::make_unique<OfferNotificationControllerAndroid>(GetWebContents());
|
||||||
GetWebContents());
|
|
||||||
host_resolver()->AddRule("*", "127.0.0.1");
|
host_resolver()->AddRule("*", "127.0.0.1");
|
||||||
embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
|
embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
|
||||||
ASSERT_TRUE(embedded_test_server()->Start());
|
ASSERT_TRUE(embedded_test_server()->Start());
|
||||||
@@ -150,17 +116,70 @@ class OfferNotificationInfoBarControllerImplBrowserTest
|
|||||||
handler->AddShownNotificationIdForTesting(id);
|
handler->AddShownNotificationIdForTesting(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
std::unique_ptr<OfferNotificationInfoBarControllerImpl>
|
std::unique_ptr<OfferNotificationControllerAndroid>
|
||||||
offer_notification_infobar_controller_;
|
offer_notification_controller_android_;
|
||||||
// CreditCard that is linked to the offer displayed in the offer notification
|
// CreditCard that is linked to the offer displayed in the offer notification.
|
||||||
// infobar.
|
|
||||||
CreditCard card_;
|
CreditCard card_;
|
||||||
base::HistogramTester histogram_tester_;
|
base::HistogramTester histogram_tester_;
|
||||||
|
base::test::ScopedFeatureList scoped_feature_list_;
|
||||||
|
|
||||||
|
private:
|
||||||
PersonalDataManager* personal_data_;
|
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) {
|
ShowInfobarAndAccept) {
|
||||||
GURL offer_url = GetInitialUrl().DeprecatedGetOriginAsURL();
|
GURL offer_url = GetInitialUrl().DeprecatedGetOriginAsURL();
|
||||||
SetUpOfferDataWithDomains(offer_url);
|
SetUpOfferDataWithDomains(offer_url);
|
||||||
@@ -181,7 +200,7 @@ IN_PROC_BROWSER_TEST_F(OfferNotificationInfoBarControllerImplBrowserTest,
|
|||||||
1);
|
1);
|
||||||
}
|
}
|
||||||
|
|
||||||
IN_PROC_BROWSER_TEST_F(OfferNotificationInfoBarControllerImplBrowserTest,
|
IN_PROC_BROWSER_TEST_F(OfferNotificationControllerAndroidBrowserTestForInfobar,
|
||||||
ShowInfobarAndClose) {
|
ShowInfobarAndClose) {
|
||||||
GURL offer_url = GetInitialUrl().DeprecatedGetOriginAsURL();
|
GURL offer_url = GetInitialUrl().DeprecatedGetOriginAsURL();
|
||||||
SetUpOfferDataWithDomains(offer_url);
|
SetUpOfferDataWithDomains(offer_url);
|
||||||
@@ -202,7 +221,7 @@ IN_PROC_BROWSER_TEST_F(OfferNotificationInfoBarControllerImplBrowserTest,
|
|||||||
1);
|
1);
|
||||||
}
|
}
|
||||||
|
|
||||||
IN_PROC_BROWSER_TEST_F(OfferNotificationInfoBarControllerImplBrowserTest,
|
IN_PROC_BROWSER_TEST_F(OfferNotificationControllerAndroidBrowserTestForInfobar,
|
||||||
CrossTabStatusTracking) {
|
CrossTabStatusTracking) {
|
||||||
GURL offer_url = GetInitialUrl().DeprecatedGetOriginAsURL();
|
GURL offer_url = GetInitialUrl().DeprecatedGetOriginAsURL();
|
||||||
int64_t id = SetUpOfferDataWithDomains(offer_url)->GetOfferId();
|
int64_t id = SetUpOfferDataWithDomains(offer_url)->GetOfferId();
|
||||||
@@ -219,4 +238,64 @@ IN_PROC_BROWSER_TEST_F(OfferNotificationInfoBarControllerImplBrowserTest,
|
|||||||
VerifyInfoBarShownCount(0);
|
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
|
} // 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/ssl/crlset_browsertest.cc",
|
||||||
"../browser/subresource_filter/subresource_filter_browser_test_harness.cc",
|
"../browser/subresource_filter/subresource_filter_browser_test_harness.cc",
|
||||||
"../browser/subresource_filter/subresource_filter_browser_test_harness.h",
|
"../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",
|
"../browser/ui/webui/policy/policy_ui_browsertest.cc",
|
||||||
"../renderer/autofill/fake_mojo_password_manager_driver.cc",
|
"../renderer/autofill/fake_mojo_password_manager_driver.cc",
|
||||||
"../renderer/autofill/fake_mojo_password_manager_driver.h",
|
"../renderer/autofill/fake_mojo_password_manager_driver.h",
|
||||||
|
@@ -78,7 +78,7 @@ class AutofillOfferManager : public KeyedService,
|
|||||||
CreateCardLinkedOffersMap_ReturnsOnlyCardLinkedOffers);
|
CreateCardLinkedOffersMap_ReturnsOnlyCardLinkedOffers);
|
||||||
FRIEND_TEST_ALL_PREFIXES(AutofillOfferManagerTest, IsUrlEligible);
|
FRIEND_TEST_ALL_PREFIXES(AutofillOfferManagerTest, IsUrlEligible);
|
||||||
friend class OfferNotificationBubbleViewsInteractiveUiTest;
|
friend class OfferNotificationBubbleViewsInteractiveUiTest;
|
||||||
friend class OfferNotificationInfoBarControllerImplBrowserTest;
|
friend class OfferNotificationControllerAndroidBrowserTest;
|
||||||
|
|
||||||
// Queries |personal_data_| to reset the elements of
|
// Queries |personal_data_| to reset the elements of
|
||||||
// |eligible_merchant_domains_|
|
// |eligible_merchant_domains_|
|
||||||
|
@@ -671,12 +671,21 @@
|
|||||||
</message>
|
</message>
|
||||||
</if>
|
</if>
|
||||||
<if expr="is_android">
|
<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.
|
Pay with <ph name="CARD_DETAIL">%1$s<ex>Visa - 1234</ex></ph> at checkout.
|
||||||
</message>
|
</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">
|
<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
|
See details
|
||||||
</message>
|
</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>
|
||||||
<if expr="toolkit_views">
|
<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.">
|
<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.">
|
||||||
|
1
components/autofill_payments_strings_grdp/IDS_AUTOFILL_OFFERS_MESSAGE_DESCRIPTION_TEXT.png.sha1
Normal file
1
components/autofill_payments_strings_grdp/IDS_AUTOFILL_OFFERS_MESSAGE_DESCRIPTION_TEXT.png.sha1
Normal file
@@ -0,0 +1 @@
|
|||||||
|
587b54e3577dbb3f64e126b4d7c01c4480bac10e
|
1
components/autofill_payments_strings_grdp/IDS_AUTOFILL_OFFERS_MESSAGE_PRIMARY_BUTTON_TEXT.png.sha1
Normal file
1
components/autofill_payments_strings_grdp/IDS_AUTOFILL_OFFERS_MESSAGE_PRIMARY_BUTTON_TEXT.png.sha1
Normal file
@@ -0,0 +1 @@
|
|||||||
|
33628376178104d1b7a0adddac1e4bd96995e208
|
@@ -0,0 +1 @@
|
|||||||
|
1f41b89f1889a8e89497daf7d63ac16bf0113bd2
|
Reference in New Issue
Block a user