Commit 6a43b930 authored by anthonyvd's avatar anthonyvd Committed by Commit bot

[Web Payments] Add data attribution string to dialog

BUG=721126

Review-Url: https://codereview.chromium.org/2876663002
Cr-Commit-Position: refs/heads/master@{#471018}
parent 721d64b5
......@@ -12,10 +12,13 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/payments/ssl_validity_checker.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/region_combobox_model.h"
#include "components/payments/content/payment_request_dialog.h"
#include "components/payments/core/payment_prefs.h"
#include "components/signin/core/browser/signin_manager.h"
#include "content/public/browser/web_contents.h"
#include "third_party/libaddressinput/chromium/chrome_metadata_source.h"
#include "third_party/libaddressinput/chromium/chrome_storage_impl.h"
......@@ -188,4 +191,23 @@ ukm::UkmService* ChromePaymentRequestDelegate::GetUkmService() {
return g_browser_process->ukm_service();
}
std::string ChromePaymentRequestDelegate::GetAuthenticatedEmail() const {
// Check if the profile is authenticated. Guest profiles or incognito
// windows may not have a sign in manager, and are considered not
// authenticated.
Profile* profile =
Profile::FromBrowserContext(web_contents_->GetBrowserContext());
SigninManagerBase* signin_manager =
SigninManagerFactory::GetForProfile(profile);
if (signin_manager && signin_manager->IsAuthenticated())
return signin_manager->GetAuthenticatedAccountInfo().email;
return std::string();
}
PrefService* ChromePaymentRequestDelegate::GetPrefService() {
return Profile::FromBrowserContext(web_contents_->GetBrowserContext())
->GetPrefs();
}
} // namespace payments
......@@ -41,6 +41,8 @@ class ChromePaymentRequestDelegate : public PaymentRequestDelegate {
AddressNormalizer* GetAddressNormalizer() override;
autofill::RegionDataLoader* GetRegionDataLoader() override;
ukm::UkmService* GetUkmService() override;
std::string GetAuthenticatedEmail() const override;
PrefService* GetPrefService() override;
protected:
// Reference to the dialog so that we can satisfy calls to CloseDialog(). This
......
......@@ -90,6 +90,7 @@
#include "components/omnibox/browser/zero_suggest_provider.h"
#include "components/password_manager/core/browser/password_bubble_experiment.h"
#include "components/password_manager/core/browser/password_manager.h"
#include "components/payments/core/payment_prefs.h"
#include "components/policy/core/browser/browser_policy_connector.h"
#include "components/policy/core/browser/url_blacklist_manager.h"
#include "components/policy/core/common/policy_statistics_collector.h"
......@@ -502,6 +503,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
ntp_tiles::MostVisitedSites::RegisterProfilePrefs(registry);
password_bubble_experiment::RegisterPrefs(registry);
password_manager::PasswordManager::RegisterProfilePrefs(registry);
payments::RegisterProfilePrefs(registry);
PrefProxyConfigTrackerImpl::RegisterProfilePrefs(registry);
PrefsTabHelper::RegisterProfilePrefs(registry);
Profile::RegisterProfilePrefs(registry);
......
......@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/views/payments/contact_info_editor_view_controller.h"
#include "chrome/browser/ui/views/payments/credit_card_editor_view_controller.h"
......@@ -26,6 +27,7 @@
#include "components/payments/content/payment_request.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/background.h"
#include "ui/views/controls/label.h"
......@@ -294,6 +296,11 @@ void PaymentRequestDialogView::ShowProcessingSpinner() {
throbber_overlay_.SetVisible(true);
}
Profile* PaymentRequestDialogView::GetProfile() {
return Profile::FromBrowserContext(
request_->web_contents()->GetBrowserContext());
}
void PaymentRequestDialogView::ShowInitialPaymentSheet() {
view_stack_->Push(CreateViewAndInstallController(
base::MakeUnique<PaymentSheetViewController>(
......
......@@ -21,6 +21,8 @@ class AutofillProfile;
class CreditCard;
} // namespace autofill
class Profile;
namespace payments {
class PaymentRequest;
......@@ -150,6 +152,8 @@ class PaymentRequestDialogView : public views::DialogDelegateView,
// a way of closing the dialog.
void ShowProcessingSpinner();
Profile* GetProfile();
ViewStack* view_stack_for_testing() { return view_stack_.get(); }
private:
......
......@@ -15,8 +15,11 @@
#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/browser/ui/views/payments/payment_request_dialog_view.h"
#include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h"
#include "chrome/browser/ui/views/payments/payment_request_row_view.h"
......@@ -28,7 +31,9 @@
#include "components/payments/content/payment_request_state.h"
#include "components/payments/core/currency_formatter.h"
#include "components/payments/core/payment_instrument.h"
#include "components/payments/core/payment_prefs.h"
#include "components/payments/core/strings_util.h"
#include "components/prefs/pref_service.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
......@@ -39,6 +44,7 @@
#include "ui/gfx/range/range.h"
#include "ui/gfx/text_elider.h"
#include "ui/gfx/text_utils.h"
#include "ui/views/border.h"
#include "ui/views/controls/button/md_text_button.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
......@@ -460,6 +466,8 @@ void PaymentSheetViewController::FillContentView(views::View* content_view) {
layout->StartRow(0, 0);
layout->AddView(CreateContactInfoRow().release());
}
layout->StartRow(0, 0);
layout->AddView(CreateDataSourceRow().release());
}
// Adds the product logo to the footer.
......@@ -532,6 +540,15 @@ void PaymentSheetViewController::ButtonPressed(
}
}
void PaymentSheetViewController::StyledLabelLinkClicked(
views::StyledLabel* label,
const gfx::Range& range,
int event_flags) {
// The only thing that can trigger this is the user clicking on the "settings"
// link in the data attribution text.
chrome::ShowSettingsSubPageForProfile(dialog()->GetProfile(), "");
}
void PaymentSheetViewController::UpdatePayButtonState(bool enabled) {
pay_button_->SetEnabled(enabled);
}
......@@ -897,4 +914,70 @@ PaymentSheetViewController::CreateShippingOptionRow() {
}
}
std::unique_ptr<views::View> PaymentSheetViewController::CreateDataSourceRow() {
std::unique_ptr<views::View> content_view = base::MakeUnique<views::View>();
views::BoxLayout* layout = new views::BoxLayout(
views::BoxLayout::kVertical, kPaymentRequestRowHorizontalInsets, 0, 0);
layout->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_START);
layout->set_cross_axis_alignment(
views::BoxLayout::CROSS_AXIS_ALIGNMENT_START);
content_view->SetLayoutManager(layout);
base::string16 data_source;
// If no transaction has been completed so far, choose which string to display
// as a function of the profile's signed in state. Otherwise, always show the
// same string.
bool first_transaction_completed =
dialog()->GetProfile()->GetPrefs()->GetBoolean(
payments::kPaymentsFirstTransactionCompleted);
if (first_transaction_completed) {
data_source =
l10n_util::GetStringUTF16(IDS_PAYMENTS_CARD_AND_ADDRESS_SETTINGS);
} else {
std::string user_email = state()->GetAuthenticatedEmail();
if (!user_email.empty()) {
// Insert the user's email into the format string.
data_source = base::UTF8ToUTF16(base::StringPrintf(
l10n_util::GetStringUTF8(
IDS_PAYMENTS_CARD_AND_ADDRESS_SETTINGS_SIGNED_IN)
.c_str(),
user_email.c_str()));
} else {
data_source = l10n_util::GetStringUTF16(
IDS_PAYMENTS_CARD_AND_ADDRESS_SETTINGS_SIGNED_OUT);
}
}
// The translated string will surround the actual "Settings" substring with
// BEGIN_LINK and END_LINK. Find the beginning of the link range and the
// length of the "settings" part, then remove the BEGIN_LINK and END_LINK
// parts and linkify "settings".
base::string16 begin_tag = base::UTF8ToUTF16("BEGIN_LINK");
base::string16 end_tag = base::UTF8ToUTF16("END_LINK");
size_t link_begin = data_source.find(begin_tag);
DCHECK(link_begin != base::string16::npos);
size_t link_end = data_source.find(end_tag);
DCHECK(link_end != base::string16::npos);
size_t link_length = link_end - link_begin - begin_tag.size();
data_source.erase(link_end, end_tag.size());
data_source.erase(link_begin, begin_tag.size());
std::unique_ptr<views::StyledLabel> data_source_label =
base::MakeUnique<views::StyledLabel>(data_source, this);
data_source_label->SetBorder(views::CreateEmptyBorder(22, 0, 0, 0));
views::StyledLabel::RangeStyleInfo default_style;
default_style.color = data_source_label->GetNativeTheme()->GetSystemColor(
ui::NativeTheme::kColorId_LabelDisabledColor);
data_source_label->SetDefaultStyle(default_style);
data_source_label->AddStyleRange(
gfx::Range(link_begin, link_begin + link_length),
views::StyledLabel::RangeStyleInfo::CreateForLink());
data_source_label->SizeToFit(0);
content_view->AddChildView(data_source_label.release());
return content_view;
}
} // namespace payments
......@@ -11,6 +11,11 @@
#include "chrome/browser/ui/views/payments/payment_request_sheet_controller.h"
#include "components/payments/content/payment_request_spec.h"
#include "components/payments/content/payment_request_state.h"
#include "ui/views/controls/styled_label_listener.h"
namespace views {
class StyledLabel;
}
namespace payments {
......@@ -20,7 +25,8 @@ class PaymentRequestDialogView;
// Payment Request dialog.
class PaymentSheetViewController : public PaymentRequestSheetController,
public PaymentRequestSpec::Observer,
public PaymentRequestState::Observer {
public PaymentRequestState::Observer,
public views::StyledLabelListener {
public:
// Does not take ownership of the arguments, which should outlive this object.
PaymentSheetViewController(PaymentRequestSpec* spec,
......@@ -44,6 +50,11 @@ class PaymentSheetViewController : public PaymentRequestSheetController,
std::unique_ptr<views::View> CreateExtraFooterView() override;
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
// views::StyledLabelListener:
void StyledLabelLinkClicked(views::StyledLabel* label,
const gfx::Range& range,
int event_flags) override;
void UpdatePayButtonState(bool enabled);
std::unique_ptr<views::View> CreateShippingSectionContent();
......@@ -53,6 +64,7 @@ class PaymentSheetViewController : public PaymentRequestSheetController,
std::unique_ptr<views::View> CreateContactInfoSectionContent();
std::unique_ptr<views::Button> CreateContactInfoRow();
std::unique_ptr<views::Button> CreateShippingOptionRow();
std::unique_ptr<views::View> CreateDataSourceRow();
views::Button* pay_button_;
......
......@@ -25,6 +25,7 @@ static_library("content") {
"//components/keyed_service/content",
"//components/payments/core",
"//components/payments/mojom",
"//components/prefs",
"//components/strings:components_strings_grit",
"//content/public/browser",
"//mojo/public/cpp/bindings",
......
......@@ -5,6 +5,7 @@ include_rules = [
"+components/data_use_measurement",
"+components/keyed_service/content",
"+components/link_header_util",
"+components/prefs",
"+components/strings",
"+content/public",
"+mojo/public/cpp",
......
......@@ -13,6 +13,8 @@
#include "components/payments/content/payment_details_validation.h"
#include "components/payments/content/payment_request_web_contents_manager.h"
#include "components/payments/core/can_make_payment_query.h"
#include "components/payments/core/payment_prefs.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
......@@ -165,6 +167,8 @@ void PaymentRequest::Complete(mojom::PaymentComplete result) {
} else {
journey_logger_.RecordJourneyStatsHistograms(
JourneyLogger::COMPLETION_STATUS_COMPLETED);
delegate_->GetPrefService()->SetBoolean(kPaymentsFirstTransactionCompleted,
true);
// When the renderer closes the connection,
// PaymentRequest::OnConnectionTerminated will be called.
client_->OnComplete();
......
......@@ -88,6 +88,10 @@ bool PaymentRequestState::AreRequestedMethodsSupported() const {
return !spec_->supported_card_networks().empty();
}
std::string PaymentRequestState::GetAuthenticatedEmail() const {
return payment_request_delegate_->GetAuthenticatedEmail();
}
void PaymentRequestState::AddObserver(Observer* observer) {
CHECK(observer);
observers_.AddObserver(observer);
......
......@@ -95,6 +95,9 @@ class PaymentRequestState : public PaymentResponseHelper::Delegate,
// false for "https://bobpay.com".
bool AreRequestedMethodsSupported() const;
// Returns authenticated user email, or empty string.
std::string GetAuthenticatedEmail() const;
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
......
......@@ -4,6 +4,8 @@
#include "components/payments/content/payment_response_helper.h"
#include <string>
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_country.h"
......@@ -61,9 +63,9 @@ PaymentResponseHelper::PaymentResponseHelper(
// Start to get the instrument details. Will call back into
// OnInstrumentDetailsReady.
selected_instrument_->InvokePaymentApp(this);
};
}
PaymentResponseHelper::~PaymentResponseHelper(){};
PaymentResponseHelper::~PaymentResponseHelper() {}
// static
mojom::PaymentAddressPtr
......
......@@ -24,6 +24,8 @@ static_library("core") {
"payment_method_data.cc",
"payment_method_data.h",
"payment_options_provider.h",
"payment_prefs.cc",
"payment_prefs.h",
"payment_request_data_util.cc",
"payment_request_data_util.h",
"payment_request_delegate.h",
......@@ -37,6 +39,7 @@ static_library("core") {
"//base",
"//components/autofill/core/browser",
"//components/keyed_service/core",
"//components/pref_registry",
"//components/strings:components_strings_grit",
"//components/ukm",
"//third_party/libphonenumber",
......
......@@ -4,6 +4,7 @@ include_rules = [
"+components/autofill/core",
"+components/keyed_service/core",
"+components/metrics",
"+components/pref_registry",
"+components/strings",
"+components/ukm",
"+third_party/libaddressinput",
......
// Copyright 2017 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 "components/payments/core/payment_prefs.h"
#include "components/pref_registry/pref_registry_syncable.h"
namespace payments {
const char kPaymentsFirstTransactionCompleted[] =
"payments.first_transaction_completed";
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterBooleanPref(kPaymentsFirstTransactionCompleted, false);
}
} // namespace payments
// Copyright 2017 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 COMPONENTS_PAYMENTS_CORE_PAYMENT_PREFS_H_
#define COMPONENTS_PAYMENTS_CORE_PAYMENT_PREFS_H_
namespace user_prefs {
class PrefRegistrySyncable;
}
namespace payments {
// True if the profile has already successfully completed at least one payment
// request transaction.
extern const char kPaymentsFirstTransactionCompleted[];
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
} // namespace payments
#endif // COMPONENTS_PAYMENTS_CORE_PAYMENT_PREFS_H_
......@@ -19,6 +19,8 @@ class PersonalDataManager;
class RegionDataLoader;
} // namespace autofill
class PrefService;
namespace ukm {
class UkmService;
} // namespace ukm
......@@ -74,6 +76,14 @@ class PaymentRequestDelegate {
// Returns a pointer to the UKM service.
virtual ukm::UkmService* GetUkmService() = 0;
// Returns the user's signed-in email address, or empty string if not signed
// in.
virtual std::string GetAuthenticatedEmail() const = 0;
// Gets the pref service for the browser context associated with this
// PaymentRequest.
virtual PrefService* GetPrefService() = 0;
};
} // namespace payments
......
......@@ -77,4 +77,12 @@ void TestPaymentRequestDelegate::CompleteFullCardRequest() {
full_card_request_card_, base::ASCIIToUTF16("123"));
}
std::string TestPaymentRequestDelegate::GetAuthenticatedEmail() const {
return "";
}
PrefService* TestPaymentRequestDelegate::GetPrefService() {
return nullptr;
}
} // namespace payments
......@@ -5,6 +5,8 @@
#ifndef COMPONENTS_PAYMENTS_CORE_TEST_PAYMENT_REQUEST_DELEGATE_H_
#define COMPONENTS_PAYMENTS_CORE_TEST_PAYMENT_REQUEST_DELEGATE_H_
#include <string>
#include "components/payments/core/payment_request_delegate.h"
#include "components/payments/core/test_address_normalizer.h"
......@@ -32,6 +34,8 @@ class TestPaymentRequestDelegate : public PaymentRequestDelegate {
AddressNormalizer* GetAddressNormalizer() override;
autofill::RegionDataLoader* GetRegionDataLoader() override;
ukm::UkmService* GetUkmService() override;
std::string GetAuthenticatedEmail() const override;
PrefService* GetPrefService() override;
TestAddressNormalizer* test_address_normalizer();
void DelayFullCardRequestCompletion();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment