summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-30 19:41:09 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-30 19:41:09 +0000
commita0e73db0048a7c2a18e3c07e88a4bb4761e8b25d (patch)
treed31e558ffed2163c6c1bf4f9808e1e663897df80
parent1b42e64d59379b4f34960c9e974a74f1c102b065 (diff)
downloadchromium_src-a0e73db0048a7c2a18e3c07e88a4bb4761e8b25d.zip
chromium_src-a0e73db0048a7c2a18e3c07e88a4bb4761e8b25d.tar.gz
chromium_src-a0e73db0048a7c2a18e3c07e88a4bb4761e8b25d.tar.bz2
rAc: better Wallet error messages.
Only the controller-side changes for now. The Views will have to implement the linkification, for now they just show the text with no linkifying. BUG=266130, 266131, 260940 R=isherman@chromium.org Review URL: https://codereview.chromium.org/23495006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@220631 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd10
-rw-r--r--chrome/browser/ui/autofill/account_chooser_model.cc11
-rw-r--r--chrome/browser/ui/autofill/account_chooser_model.h14
-rw-r--r--chrome/browser/ui/autofill/account_chooser_model_unittest.cc2
-rw-r--r--chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc103
-rw-r--r--chrome/browser/ui/autofill/autofill_dialog_controller_impl.h3
-rw-r--r--chrome/browser/ui/autofill/autofill_dialog_types.cc22
-rw-r--r--chrome/browser/ui/autofill/autofill_dialog_types.h19
-rw-r--r--chrome/browser/ui/autofill/autofill_dialog_types_unittest.cc14
9 files changed, 138 insertions, 60 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 4d2495d..31c7e32 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -9945,14 +9945,14 @@ Would you like to start <ph name="CONTROL_PANEL_APPLET_NAME">$1<ex>Add/Remove Pr
<message name="IDS_AUTOFILL_WALLET_BUYER_ACCOUNT_ERROR" desc="Text explaining that the user's Wallet account cannot be used.">
There's something wrong with your Google Wallet account [12].
</message>
- <message name="IDS_AUTOFILL_WALLET_BUYER_COUNTRY_NOT_SUPPORTED" desc="Text explaining that the user's Wallet Buyer Legal Address has a country which is unsupported.">
- lorem ipsum - unsupported buyer bla.
+ <message name="IDS_AUTOFILL_WALLET_BUYER_COUNTRY_NOT_SUPPORTED" desc="Text explaining that the user's Wallet Buyer Legal Address has a country which is unsupported. The text inside the |bars| is link text.">
+ Unfortunately, Google Wallet can only be used at this merchant by buyers with a US address. If you are a US resident, |change your home address| or pay without Google Wallet.
</message>
- <message name="IDS_AUTOFILL_WALLET_UNVERIFIED_KNOW_YOUR_CUSTOMER_STATUS" desc="Text explaining that Google Wallet failed/pending Know Your Customer (KYC) check, and would require user to call Google Wallet.">
- lorem ipsum - kyc.
+ <message name="IDS_AUTOFILL_WALLET_UNVERIFIED_KNOW_YOUR_CUSTOMER_STATUS" desc="Text explaining that Google Wallet failed/pending Know Your Customer (KYC) check. The text inside the |bars| is link text.">
+ We were unable to verify your account information. |Fix this problem|
</message>
<message name="IDS_AUTOFILL_WALLET_UNSUPPORTED_MERCHANT" desc="Text explaining that the merchant is blacklisted for Google Wallet Chrome Payments due to compliance violation.">
- lorem ipsum - unsupported_merchant.
+ Google Wallet is not supported for this merchant.
</message>
<message name="IDS_AUTOFILL_WALLET_SERVICE_UNAVAILABLE_ERROR" desc="Text explaining that Wallet is currently unavailable.">
Google Wallet is currently unavailable [61].
diff --git a/chrome/browser/ui/autofill/account_chooser_model.cc b/chrome/browser/ui/autofill/account_chooser_model.cc
index 3c3bcb0..8980c90 100644
--- a/chrome/browser/ui/autofill/account_chooser_model.cc
+++ b/chrome/browser/ui/autofill/account_chooser_model.cc
@@ -34,6 +34,7 @@ AccountChooserModel::AccountChooserModel(
checked_item_(
prefs->GetBoolean(::prefs::kAutofillDialogPayWithoutWallet) ?
kAutofillItemId : kActiveWalletItemId),
+ had_wallet_error_(false),
metric_logger_(metric_logger),
dialog_type_(dialog_type) {
ReconstructMenuItems();
@@ -73,7 +74,7 @@ bool AccountChooserModel::IsCommandIdChecked(int command_id) const {
bool AccountChooserModel::IsCommandIdEnabled(int command_id) const {
// Currently, _any_ (non-sign-in) error disables _all_ Wallet accounts.
- if (command_id != kAutofillItemId && HadWalletError())
+ if (command_id != kAutofillItemId && had_wallet_error_)
return false;
return true;
@@ -108,17 +109,13 @@ void AccountChooserModel::ExecuteCommand(int command_id, int event_flags) {
delegate_->AccountChoiceChanged();
}
-void AccountChooserModel::SetHadWalletError(const base::string16& message) {
+void AccountChooserModel::SetHadWalletError() {
// Any non-sign-in error disables all Wallet accounts.
- wallet_error_message_ = message;
+ had_wallet_error_ = true;
ClearActiveWalletAccountName();
ExecuteCommand(kAutofillItemId, 0);
}
-bool AccountChooserModel::HadWalletError() const {
- return !wallet_error_message_.empty();
-}
-
void AccountChooserModel::SetHadWalletSigninError() {
ClearActiveWalletAccountName();
ExecuteCommand(kAutofillItemId, 0);
diff --git a/chrome/browser/ui/autofill/account_chooser_model.h b/chrome/browser/ui/autofill/account_chooser_model.h
index fd3f001..723f438 100644
--- a/chrome/browser/ui/autofill/account_chooser_model.h
+++ b/chrome/browser/ui/autofill/account_chooser_model.h
@@ -78,11 +78,8 @@ class AccountChooserModel : public ui::SimpleMenuModel,
}
// Disables all Wallet accounts and switches to the local Autofill data.
- // Should be called when the Wallet server returns an error with the message
- // to be displayed. If |message| is empty the error state will be cleared.
- void SetHadWalletError(const base::string16& message);
-
- bool HadWalletError() const;
+ // Should be called when the Wallet server returns an error.
+ void SetHadWalletError();
// Switches the dialog to the local Autofill data.
// Should be called when the Online Wallet sign-in attempt has failed.
@@ -98,8 +95,6 @@ class AccountChooserModel : public ui::SimpleMenuModel,
// Returns the command id of the current selection.
int checked_item() const { return checked_item_; }
- base::string16 wallet_error_message() const { return wallet_error_message_; }
-
protected:
// Command IDs of the items in this menu; protected for the tests.
// kActiveWalletItemId is the currently active account.
@@ -118,9 +113,8 @@ class AccountChooserModel : public ui::SimpleMenuModel,
// The command id of the currently selected item.
int checked_item_;
- // The message to be displayed if there is a Wallet error. This message is
- // only non-empty if a Wallet error has occurred.
- base::string16 wallet_error_message_;
+ // Whether there has been a Wallet error.
+ bool had_wallet_error_;
// For logging UMA metrics.
const AutofillMetrics& metric_logger_;
diff --git a/chrome/browser/ui/autofill/account_chooser_model_unittest.cc b/chrome/browser/ui/autofill/account_chooser_model_unittest.cc
index f27c1be..be83071 100644
--- a/chrome/browser/ui/autofill/account_chooser_model_unittest.cc
+++ b/chrome/browser/ui/autofill/account_chooser_model_unittest.cc
@@ -100,7 +100,7 @@ TEST_F(AccountChooserModelTest, HandlesError) {
ASSERT_TRUE(model()->IsCommandIdEnabled(
TestAccountChooserModel::kActiveWalletItemId));
- model()->SetHadWalletError(ASCIIToUTF16("Error"));
+ model()->SetHadWalletError();
EXPECT_FALSE(model()->WalletIsSelected());
EXPECT_FALSE(model()->IsCommandIdEnabled(
TestAccountChooserModel::kActiveWalletItemId));
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
index 4508781..f504b83 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
@@ -92,6 +92,11 @@ const char kAddNewItemKey[] = "add-new-item";
const char kManageItemsKey[] = "manage-items";
const char kSameAsBillingKey[] = "same-as-billing";
+// URLs for Wallet error messages.
+const char kBuyerLegalAddressStatusUrl[] =
+ "https://wallet.google.com/manage/settings";
+const char kKnowYourCustomerStatusUrl[] = "https://wallet.google.com/kyc";
+
// Keys for the kAutofillDialogAutofillDefault pref dictionary (do not change
// these values).
const char kGuidPrefKey[] = "guid";
@@ -353,61 +358,103 @@ DialogSection SectionFromLocation(wallet::FormFieldError::Location location) {
return SECTION_MAX;
}
-base::string16 WalletErrorMessage(wallet::WalletClient::ErrorType error_type) {
+scoped_ptr<DialogNotification> GetWalletError(
+ wallet::WalletClient::ErrorType error_type) {
+ base::string16 text;
+ GURL url;
+
switch (error_type) {
- case wallet::WalletClient::BUYER_ACCOUNT_ERROR:
- return l10n_util::GetStringUTF16(IDS_AUTOFILL_WALLET_BUYER_ACCOUNT_ERROR);
+ case wallet::WalletClient::UNVERIFIED_KNOW_YOUR_CUSTOMER_STATUS:
+ text = l10n_util::GetStringUTF16(
+ IDS_AUTOFILL_WALLET_UNVERIFIED_KNOW_YOUR_CUSTOMER_STATUS);
+ url = GURL(kKnowYourCustomerStatusUrl);
+ break;
case wallet::WalletClient::BUYER_LEGAL_ADDRESS_NOT_SUPPORTED:
- return l10n_util::GetStringUTF16(
+ text = l10n_util::GetStringUTF16(
IDS_AUTOFILL_WALLET_BUYER_COUNTRY_NOT_SUPPORTED);
+ url = GURL(kBuyerLegalAddressStatusUrl);
+ break;
+ default:
+ // The notification will not have a link; it's handled in the next
+ // switch statement.
+ break;
+ }
+
+ if (!text.empty()) {
+ scoped_ptr<DialogNotification> notification(new DialogNotification(
+ DialogNotification::WALLET_ERROR,
+ text));
+ notification->set_link_url(url);
+ return notification.Pass();
+ }
+
+ switch (error_type) {
case wallet::WalletClient::UNSUPPORTED_MERCHANT:
- return l10n_util::GetStringUTF16(
+ text = l10n_util::GetStringUTF16(
IDS_AUTOFILL_WALLET_UNSUPPORTED_MERCHANT);
+ break;
case wallet::WalletClient::BAD_REQUEST:
- return l10n_util::GetStringFUTF16(
+ text = l10n_util::GetStringFUTF16(
IDS_AUTOFILL_WALLET_UPGRADE_CHROME_ERROR,
ASCIIToUTF16("71"));
+ break;
case wallet::WalletClient::INVALID_PARAMS:
- return l10n_util::GetStringFUTF16(
+ text = l10n_util::GetStringFUTF16(
IDS_AUTOFILL_WALLET_UPGRADE_CHROME_ERROR,
ASCIIToUTF16("42"));
+ break;
- case wallet::WalletClient::UNVERIFIED_KNOW_YOUR_CUSTOMER_STATUS:
- return l10n_util::GetStringUTF16(
- IDS_AUTOFILL_WALLET_UNVERIFIED_KNOW_YOUR_CUSTOMER_STATUS);
+ case wallet::WalletClient::BUYER_ACCOUNT_ERROR:
+ text = l10n_util::GetStringUTF16(IDS_AUTOFILL_WALLET_BUYER_ACCOUNT_ERROR);
+ break;
case wallet::WalletClient::UNSUPPORTED_API_VERSION:
- return l10n_util::GetStringFUTF16(
+ text = l10n_util::GetStringFUTF16(
IDS_AUTOFILL_WALLET_UPGRADE_CHROME_ERROR,
ASCIIToUTF16("43"));
+ break;
case wallet::WalletClient::SERVICE_UNAVAILABLE:
- return l10n_util::GetStringUTF16(
+ text = l10n_util::GetStringUTF16(
IDS_AUTOFILL_WALLET_SERVICE_UNAVAILABLE_ERROR);
+ break;
case wallet::WalletClient::INTERNAL_ERROR:
- return l10n_util::GetStringFUTF16(IDS_AUTOFILL_WALLET_UNKNOWN_ERROR,
+ text = l10n_util::GetStringFUTF16(IDS_AUTOFILL_WALLET_UNKNOWN_ERROR,
ASCIIToUTF16("62"));
+ break;
case wallet::WalletClient::MALFORMED_RESPONSE:
- return l10n_util::GetStringFUTF16(IDS_AUTOFILL_WALLET_UNKNOWN_ERROR,
+ text = l10n_util::GetStringFUTF16(IDS_AUTOFILL_WALLET_UNKNOWN_ERROR,
ASCIIToUTF16("72"));
+ break;
case wallet::WalletClient::NETWORK_ERROR:
- return l10n_util::GetStringFUTF16(IDS_AUTOFILL_WALLET_UNKNOWN_ERROR,
+ text = l10n_util::GetStringFUTF16(IDS_AUTOFILL_WALLET_UNKNOWN_ERROR,
ASCIIToUTF16("73"));
+ break;
case wallet::WalletClient::UNKNOWN_ERROR:
- return l10n_util::GetStringFUTF16(IDS_AUTOFILL_WALLET_UNKNOWN_ERROR,
+ text = l10n_util::GetStringFUTF16(IDS_AUTOFILL_WALLET_UNKNOWN_ERROR,
ASCIIToUTF16("74"));
+ break;
+
+ default:
+ break;
}
- NOTREACHED();
- return base::string16();
+ DCHECK(!text.empty());
+
+ // The other error types are strings of the form "XXX. You can pay without
+ // wallet."
+ return make_scoped_ptr(new DialogNotification(
+ DialogNotification::WALLET_ERROR,
+ l10n_util::GetStringFUTF16(IDS_AUTOFILL_DIALOG_COMPLETE_WITHOUT_WALLET,
+ text)));
}
gfx::Image GetGeneratedCardImage(const string16& card_number) {
@@ -717,7 +764,7 @@ string16 AutofillDialogControllerImpl::LegalDocumentsText() {
}
DialogSignedInState AutofillDialogControllerImpl::SignedInState() const {
- if (account_chooser_model_.HadWalletError())
+ if (wallet_error_notification_)
return SIGN_IN_DISABLED;
if (signin_helper_ || !wallet_items_)
@@ -1197,7 +1244,7 @@ ui::MenuModel* AutofillDialogControllerImpl::MenuModelForSection(
ui::MenuModel* AutofillDialogControllerImpl::MenuModelForAccountChooser() {
// If there were unrecoverable Wallet errors, or if there are choices other
// than "Pay without the wallet", show the full menu.
- if (account_chooser_model_.HadWalletError() ||
+ if (wallet_error_notification_ ||
account_chooser_model_.HasAccountsToChoose()) {
return &account_chooser_model_;
}
@@ -1832,14 +1879,9 @@ std::vector<DialogNotification> AutofillDialogControllerImpl::
UTF8ToUTF16(source_url_.host()))));
}
- if (account_chooser_model_.HadWalletError()) {
- // TODO(dbeam): figure out a way to dismiss this error after a while.
- notifications.push_back(DialogNotification(
- DialogNotification::WALLET_ERROR,
- l10n_util::GetStringFUTF16(
- IDS_AUTOFILL_DIALOG_COMPLETE_WITHOUT_WALLET,
- account_chooser_model_.wallet_error_message())));
- }
+ // TODO(dbeam): figure out a way to dismiss this error after a while.
+ if (wallet_error_notification_)
+ notifications.push_back(*wallet_error_notification_);
if (IsSubmitPausedOn(wallet::VERIFY_CVV)) {
notifications.push_back(DialogNotification(
@@ -2483,7 +2525,8 @@ void AutofillDialogControllerImpl::DisableWallet(
}
}
SetIsSubmitting(false);
- account_chooser_model_.SetHadWalletError(WalletErrorMessage(error_type));
+ wallet_error_notification_ = GetWalletError(error_type);
+ account_chooser_model_.SetHadWalletError();
}
void AutofillDialogControllerImpl::SuggestionsUpdated() {
@@ -3238,7 +3281,7 @@ void AutofillDialogControllerImpl::FinishSubmit() {
// stop trying to pay with Wallet on future runs of the dialog. On the other
// hand, if there was an error that prevented the user from having the choice
// of using Wallet, leave the pref alone.
- if (!account_chooser_model_.HadWalletError() &&
+ if (!wallet_error_notification_ &&
account_chooser_model_.HasAccountsToChoose()) {
profile_->GetPrefs()->SetBoolean(
::prefs::kAutofillDialogPayWithoutWallet,
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h
index 54fb490..eaefcad 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h
@@ -693,6 +693,9 @@ class AutofillDialogControllerImpl : public AutofillDialogViewDelegate,
// Wallet validation errors. section->type->(error_msg, input_value).
WalletValidationErrors wallet_errors_;
+ // The notification that describes the current wallet error, if any.
+ scoped_ptr<DialogNotification> wallet_error_notification_;
+
// The current state of the Autocheckout flow.
AutocheckoutState autocheckout_state_;
diff --git a/chrome/browser/ui/autofill/autofill_dialog_types.cc b/chrome/browser/ui/autofill/autofill_dialog_types.cc
index ffd0c12..65d0850 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_types.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_types.cc
@@ -5,15 +5,19 @@
#include "chrome/browser/ui/autofill/autofill_dialog_types.h"
#include "base/logging.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
namespace autofill {
-int const kSplashDisplayDurationMs = 1200;
-int const kSplashFadeOutDurationMs = 200;
-int const kSplashFadeInDialogDurationMs = 150;
+const int kSplashDisplayDurationMs = 1200;
+const int kSplashFadeOutDurationMs = 200;
+const int kSplashFadeInDialogDurationMs = 150;
+
+static const base::char16 kRangeSeparator = '|';
DialogNotification::DialogNotification() : type_(NONE) {}
@@ -21,7 +25,17 @@ DialogNotification::DialogNotification(Type type, const string16& display_text)
: type_(type),
display_text_(display_text),
checked_(false),
- interactive_(true) {}
+ interactive_(true) {
+ // If there's a range separated by bars, mark that as the anchor text.
+ std::vector<base::string16> pieces;
+ base::SplitStringDontTrim(display_text, kRangeSeparator, &pieces);
+ if (pieces.size() > 1) {
+ link_range_ = ui::Range(pieces[0].size(), pieces[1].size());
+ display_text_ = JoinString(pieces, string16());
+ }
+}
+
+DialogNotification::~DialogNotification() {}
SkColor DialogNotification::GetBackgroundColor() const {
switch (type_) {
diff --git a/chrome/browser/ui/autofill/autofill_dialog_types.h b/chrome/browser/ui/autofill/autofill_dialog_types.h
index 9b48b0a..914ee75 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_types.h
+++ b/chrome/browser/ui/autofill/autofill_dialog_types.h
@@ -13,9 +13,11 @@
#include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/browser/field_types.h"
#include "third_party/skia/include/core/SkColor.h"
+#include "ui/base/range/range.h"
#include "ui/gfx/font.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/text_constants.h"
+#include "url/gurl.h"
namespace autofill {
@@ -23,12 +25,12 @@ class AutofillField;
// The time (in milliseconds) to show the splash page when the dialog is first
// started.
-extern int const kSplashDisplayDurationMs;
+extern const int kSplashDisplayDurationMs;
// The time (in milliseconds) spend fading out the splash image.
-extern int const kSplashFadeOutDurationMs;
+extern const int kSplashFadeOutDurationMs;
// The time (in milliseconds) spend fading in the dialog (after the splash image
// has been faded out).
-extern int const kSplashFadeInDialogDurationMs;
+extern const int kSplashFadeInDialogDurationMs;
// This struct describes a single input control for the imperative autocomplete
// dialog.
@@ -95,6 +97,7 @@ class DialogNotification {
DialogNotification();
DialogNotification(Type type, const string16& display_text);
+ ~DialogNotification();
// Returns the appropriate background, border, or text color for the view's
// notification area based on |type_|.
@@ -111,6 +114,11 @@ class DialogNotification {
Type type() const { return type_; }
const string16& display_text() const { return display_text_; }
+ void set_link_url(const GURL& link_url) { link_url_ = link_url; }
+ const GURL& link_url() const { return link_url_; }
+
+ const ui::Range& link_range() const { return link_range_; }
+
void set_tooltip_text(const string16& tooltip_text) {
tooltip_text_ = tooltip_text;
}
@@ -126,6 +134,11 @@ class DialogNotification {
Type type_;
string16 display_text_;
+ // If the notification includes a link, these describe the destination and
+ // which part of |display_text_| is the anchor text.
+ GURL link_url_;
+ ui::Range link_range_;
+
// When non-empty, indicates that a tooltip should be shown on the end of
// the notification.
string16 tooltip_text_;
diff --git a/chrome/browser/ui/autofill/autofill_dialog_types_unittest.cc b/chrome/browser/ui/autofill/autofill_dialog_types_unittest.cc
index d024e18..77f480d 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_types_unittest.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_types_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/autofill/autofill_dialog_types.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -17,4 +18,17 @@ TEST(AutofillDialogTypesTest, WarningColorMatches) {
}
#endif
+// Tests for correct parsing of anchor text ranges.
+TEST(AutofillDialogTypesTest, DialogNotificationLink) {
+ base::string16 text(ASCIIToUTF16("Notification without anchor text"));
+ DialogNotification notification(DialogNotification::WALLET_ERROR, text);
+ EXPECT_TRUE(notification.link_range().is_empty());
+
+ text = ASCIIToUTF16("Notification with |anchor text|");
+ notification = DialogNotification(DialogNotification::WALLET_ERROR, text);
+ base::char16 bar = '|';
+ EXPECT_EQ(base::string16::npos, notification.display_text().find(bar));
+ EXPECT_FALSE(notification.link_range().is_empty());
+}
+
} // namespace autofill