Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1472)

Side by Side Diff: chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc

Issue 1540423004: Add card details and legal message to Android save credit card infobar. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: components/autofill review. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/autofill/save_card_bubble_controller_impl.h" 5 #include "chrome/browser/ui/autofill/save_card_bubble_controller_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/i18n/message_formatter.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/ui/autofill/save_card_bubble_view.h" 9 #include "chrome/browser/ui/autofill/save_card_bubble_view.h"
13 #include "chrome/browser/ui/browser.h" 10 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_finder.h" 11 #include "chrome/browser/ui/browser_finder.h"
15 #include "chrome/browser/ui/browser_window.h" 12 #include "chrome/browser/ui/browser_window.h"
16 #include "chrome/browser/ui/location_bar/location_bar.h" 13 #include "chrome/browser/ui/location_bar/location_bar.h"
17 #include "components/autofill/core/browser/autofill_metrics.h" 14 #include "components/autofill/core/browser/autofill_metrics.h"
18 #include "components/autofill/core/common/autofill_constants.h" 15 #include "components/autofill/core/common/autofill_constants.h"
19 #include "content/public/browser/navigation_details.h" 16 #include "content/public/browser/navigation_details.h"
20 #include "grit/components_strings.h" 17 #include "grit/components_strings.h"
21 #include "ui/base/l10n/l10n_util.h" 18 #include "ui/base/l10n/l10n_util.h"
22 19
23 DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::SaveCardBubbleControllerImpl); 20 DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::SaveCardBubbleControllerImpl);
24 21
25 namespace autofill { 22 namespace autofill {
26 23
27 namespace { 24 namespace {
28 25
29 // Number of seconds the bubble and icon will survive navigations, starting 26 // Number of seconds the bubble and icon will survive navigations, starting
30 // from when the bubble is shown. 27 // from when the bubble is shown.
31 // TODO(bondd): Share with ManagePasswordsUIController. 28 // TODO(bondd): Share with ManagePasswordsUIController.
32 const int kSurviveNavigationSeconds = 5; 29 const int kSurviveNavigationSeconds = 5;
33 30
34 // Replace "{0}", "{1}", ... in |template_icu| with corresponding strings
35 // from |display_texts|. Sets |out_message| to the resulting string, with
36 // start position of each replacement in |out_offsets|.
37 // Return false on failure. If false is returned then contents of |out_message|
38 // and |out_offsets| are undefined.
39 bool ReplaceTemplatePlaceholders(
40 const base::string16& template_icu,
41 const std::vector<base::string16>& display_texts,
42 base::string16* out_message,
43 std::vector<size_t>* out_offsets) {
44 // Escape "$" -> "$$" for ReplaceStringPlaceholders().
45 //
46 // Edge cases:
47 // 1. Two or more consecutive $ characters will be incorrectly expanded
48 // ("$$" -> "$$$$", which ReplaceStringPlaceholders() then turns into
49 // "$$$").
50 //
51 // 2. "${" will cause false to be returned. "${0}" will expand to "$${0}".
52 // FormatWithNumberedArgs() turns it into "$$$1", which
53 // ReplaceStringPlaceholders() then turns into "$$1" without doing the
54 // parameter replacement. This causes false to be returned because each
55 // parameter is not used exactly once.
56 //
57 // Both of these cases are noted in the header file, and are unlikely to
58 // occur in any actual legal message.
59 base::string16 template_icu_escaped;
60 base::ReplaceChars(template_icu, base::ASCIIToUTF16("$"),
61 base::ASCIIToUTF16("$$"), &template_icu_escaped);
62
63 // Replace "{0}" -> "$1", "{1}" -> "$2", ... to prepare |template_dollars|
64 // for ReplaceStringPlaceholders().
65 base::string16 template_dollars =
66 base::i18n::MessageFormatter::FormatWithNumberedArgs(
67 template_icu_escaped, "$1", "$2", "$3", "$4", "$5", "$6", "$7");
68
69 // FormatWithNumberedArgs() returns an empty string on failure.
70 if (template_dollars.empty() && !template_icu.empty())
71 return false;
72
73 // Replace "$1", "$2", ... with the display text of each parameter.
74 *out_message = base::ReplaceStringPlaceholders(template_dollars,
75 display_texts, out_offsets);
76
77 // Each parameter must be used exactly once. If a parameter is unused or
78 // used more than once then it can't be determined which |offsets| entry
79 // corresponds to which parameter.
80 return out_offsets->size() == display_texts.size();
81 }
82
83 // Parses |line| and sets |out|.
84 // Returns false on failure. |out| is not modified if false is returned.
85 bool ParseLegalMessageLine(const base::DictionaryValue& line,
86 SaveCardBubbleController::LegalMessageLine* out) {
87 SaveCardBubbleController::LegalMessageLine result;
88
89 // |display_texts| elements are the strings that will be substituted for
90 // "{0}", "{1}", etc. in the template string.
91 std::vector<base::string16> display_texts;
92
93 // Process all the template parameters.
94 const base::ListValue* template_parameters = nullptr;
95 if (line.GetList("template_parameter", &template_parameters)) {
96 display_texts.resize(template_parameters->GetSize());
97 result.links.resize(template_parameters->GetSize());
98
99 for (size_t parameter_index = 0;
100 parameter_index < template_parameters->GetSize(); ++parameter_index) {
101 const base::DictionaryValue* single_parameter;
102 std::string url;
103 if (!template_parameters->GetDictionary(parameter_index,
104 &single_parameter) ||
105 !single_parameter->GetString("display_text",
106 &display_texts[parameter_index]) ||
107 !single_parameter->GetString("url", &url)) {
108 return false;
109 }
110 result.links[parameter_index].url = GURL(url);
111 }
112 }
113
114 // Read the template string. It's a small subset of the ICU message format
115 // syntax.
116 base::string16 template_icu;
117 if (!line.GetString("template", &template_icu))
118 return false;
119
120 // Replace the placeholders in |template_icu| with strings from
121 // |display_texts|, and store the start position of each replacement in
122 // |offsets|.
123 std::vector<size_t> offsets;
124 if (!ReplaceTemplatePlaceholders(template_icu, display_texts, &result.text,
125 &offsets)) {
126 return false;
127 }
128
129 // Fill in range values for all links.
130 for (size_t offset_index = 0; offset_index < offsets.size(); ++offset_index) {
131 size_t range_start = offsets[offset_index];
132 result.links[offset_index].range = gfx::Range(
133 range_start, range_start + display_texts[offset_index].size());
134 }
135
136 *out = result;
137 return true;
138 }
139
140 } // namespace 31 } // namespace
141 32
142 SaveCardBubbleControllerImpl::SaveCardBubbleControllerImpl( 33 SaveCardBubbleControllerImpl::SaveCardBubbleControllerImpl(
143 content::WebContents* web_contents) 34 content::WebContents* web_contents)
144 : content::WebContentsObserver(web_contents), 35 : content::WebContentsObserver(web_contents),
145 save_card_bubble_view_(nullptr) { 36 save_card_bubble_view_(nullptr) {
146 DCHECK(web_contents); 37 DCHECK(web_contents);
147 } 38 }
148 39
149 SaveCardBubbleControllerImpl::~SaveCardBubbleControllerImpl() { 40 SaveCardBubbleControllerImpl::~SaveCardBubbleControllerImpl() {
(...skipping 15 matching lines...) Expand all
165 56
166 void SaveCardBubbleControllerImpl::ShowBubbleForUpload( 57 void SaveCardBubbleControllerImpl::ShowBubbleForUpload(
167 const base::Closure& save_card_callback, 58 const base::Closure& save_card_callback,
168 scoped_ptr<base::DictionaryValue> legal_message) { 59 scoped_ptr<base::DictionaryValue> legal_message) {
169 is_uploading_ = true; 60 is_uploading_ = true;
170 is_reshow_ = false; 61 is_reshow_ = false;
171 AutofillMetrics::LogSaveCardPromptMetric( 62 AutofillMetrics::LogSaveCardPromptMetric(
172 AutofillMetrics::SAVE_CARD_PROMPT_SHOW_REQUESTED, is_uploading_, 63 AutofillMetrics::SAVE_CARD_PROMPT_SHOW_REQUESTED, is_uploading_,
173 is_reshow_); 64 is_reshow_);
174 65
175 const base::ListValue* lines = nullptr; 66 if (!LegalMessageLine::Parse(*legal_message, &legal_message_lines_)) {
176 if (legal_message->GetList("line", &lines)) {
177 // Process all lines of the legal message. See comment in header file for
178 // example of valid |legal_message| data.
179 legal_message_lines_.resize(lines->GetSize());
180 for (size_t i = 0; i < lines->GetSize(); ++i) {
181 const base::DictionaryValue* single_line;
182 if (!lines->GetDictionary(i, &single_line) ||
183 !ParseLegalMessageLine(*single_line, &legal_message_lines_[i])) {
184 lines = nullptr;
185 break;
186 }
187 }
188 }
189
190 if (!lines) {
191 AutofillMetrics::LogSaveCardPromptMetric( 67 AutofillMetrics::LogSaveCardPromptMetric(
192 AutofillMetrics::SAVE_CARD_PROMPT_END_INVALID_LEGAL_MESSAGE, 68 AutofillMetrics::SAVE_CARD_PROMPT_END_INVALID_LEGAL_MESSAGE,
193 is_uploading_, is_reshow_); 69 is_uploading_, is_reshow_);
194
195 legal_message_lines_.clear();
196 return; 70 return;
197 } 71 }
198 72
199 save_card_callback_ = save_card_callback; 73 save_card_callback_ = save_card_callback;
200 ShowBubble(); 74 ShowBubble();
201 } 75 }
202 76
203 void SaveCardBubbleControllerImpl::ReshowBubble() { 77 void SaveCardBubbleControllerImpl::ReshowBubble() {
204 is_reshow_ = true; 78 is_reshow_ = true;
205 AutofillMetrics::LogSaveCardPromptMetric( 79 AutofillMetrics::LogSaveCardPromptMetric(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 AutofillMetrics::LogSaveCardPromptMetric( 130 AutofillMetrics::LogSaveCardPromptMetric(
257 AutofillMetrics::SAVE_CARD_PROMPT_DISMISS_CLICK_LEGAL_MESSAGE, 131 AutofillMetrics::SAVE_CARD_PROMPT_DISMISS_CLICK_LEGAL_MESSAGE,
258 is_uploading_, is_reshow_); 132 is_uploading_, is_reshow_);
259 } 133 }
260 134
261 void SaveCardBubbleControllerImpl::OnBubbleClosed() { 135 void SaveCardBubbleControllerImpl::OnBubbleClosed() {
262 save_card_bubble_view_ = nullptr; 136 save_card_bubble_view_ = nullptr;
263 UpdateIcon(); 137 UpdateIcon();
264 } 138 }
265 139
266 const SaveCardBubbleController::LegalMessageLines& 140 const LegalMessageLines& SaveCardBubbleControllerImpl::GetLegalMessageLines()
267 SaveCardBubbleControllerImpl::GetLegalMessageLines() const { 141 const {
268 return legal_message_lines_; 142 return legal_message_lines_;
269 } 143 }
270 144
271 base::TimeDelta SaveCardBubbleControllerImpl::Elapsed() const { 145 base::TimeDelta SaveCardBubbleControllerImpl::Elapsed() const {
272 return timer_->Elapsed(); 146 return timer_->Elapsed();
273 } 147 }
274 148
275 void SaveCardBubbleControllerImpl::DidNavigateMainFrame( 149 void SaveCardBubbleControllerImpl::DidNavigateMainFrame(
276 const content::LoadCommittedDetails& details, 150 const content::LoadCommittedDetails& details,
277 const content::FrameNavigateParams& params) { 151 const content::FrameNavigateParams& params) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 location_bar->UpdateSaveCreditCardIcon(); 209 location_bar->UpdateSaveCreditCardIcon();
336 } 210 }
337 211
338 void SaveCardBubbleControllerImpl::OpenUrl(const GURL& url) { 212 void SaveCardBubbleControllerImpl::OpenUrl(const GURL& url) {
339 web_contents()->OpenURL( 213 web_contents()->OpenURL(
340 content::OpenURLParams(url, content::Referrer(), NEW_FOREGROUND_TAB, 214 content::OpenURLParams(url, content::Referrer(), NEW_FOREGROUND_TAB,
341 ui::PAGE_TRANSITION_LINK, false)); 215 ui::PAGE_TRANSITION_LINK, false));
342 } 216 }
343 217
344 } // namespace autofill 218 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698