1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_ACCESSORY_SHEET_DATA_H_
6 #define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_ACCESSORY_SHEET_DATA_H_
7 
8 #include <utility>
9 #include <vector>
10 
11 #include "base/optional.h"
12 #include "base/strings/string16.h"
13 #include "base/util/type_safety/strong_alias.h"
14 #include "components/autofill/core/browser/ui/accessory_sheet_enums.h"
15 
16 namespace password_manager {
17 class IsPublicSuffixMatchTag;
18 }  // namespace password_manager
19 
20 namespace autofill {
21 
22 // Represents user data to be shown on the manual fallback UI (e.g. a Profile,
23 // or a Credit Card, or the credentials for a website).
24 class UserInfo {
25  public:
26   // Represents a selectable item, such as the username or a credit card
27   // number.
28   class Field {
29    public:
30     Field(base::string16 display_text,
31           base::string16 a11y_description,
32           bool is_obfuscated,
33           bool selectable);
34     Field(base::string16 display_text,
35           base::string16 a11y_description,
36           std::string id,
37           bool is_obfuscated,
38           bool selectable);
39     Field(const Field& field);
40     Field(Field&& field);
41 
42     ~Field();
43 
44     Field& operator=(const Field& field);
45     Field& operator=(Field&& field);
46 
display_text()47     const base::string16& display_text() const { return display_text_; }
48 
a11y_description()49     const base::string16& a11y_description() const { return a11y_description_; }
50 
id()51     const std::string& id() const { return id_; }
52 
is_obfuscated()53     bool is_obfuscated() const { return is_obfuscated_; }
54 
selectable()55     bool selectable() const { return selectable_; }
56 
57     bool operator==(const UserInfo::Field& field) const;
58 
59    private:
60     base::string16 display_text_;
61     base::string16 a11y_description_;
62     std::string id_;  // Optional, if needed to complete filling.
63     bool is_obfuscated_;
64     bool selectable_;
65   };
66 
67   using IsPslMatch =
68       util::StrongAlias<password_manager::IsPublicSuffixMatchTag, bool>;
69 
70   UserInfo();
71   explicit UserInfo(std::string origin);
72   UserInfo(std::string origin, IsPslMatch is_psl_match);
73   UserInfo(const UserInfo& user_info);
74   UserInfo(UserInfo&& field);
75 
76   ~UserInfo();
77 
78   UserInfo& operator=(const UserInfo& user_info);
79   UserInfo& operator=(UserInfo&& user_info);
80 
add_field(Field field)81   void add_field(Field field) { fields_.push_back(std::move(field)); }
82 
fields()83   const std::vector<Field>& fields() const { return fields_; }
origin()84   const std::string& origin() const { return origin_; }
is_psl_match()85   IsPslMatch is_psl_match() const { return is_psl_match_; }
86 
87   bool operator==(const UserInfo& user_info) const;
88 
89  private:
90   std::string origin_;
91   IsPslMatch is_psl_match_{false};
92   std::vector<Field> fields_;
93 };
94 
95 std::ostream& operator<<(std::ostream& out, const UserInfo::Field& field);
96 std::ostream& operator<<(std::ostream& out, const UserInfo& user_info);
97 
98 // Represents a command below the suggestions, such as "Manage password...".
99 class FooterCommand {
100  public:
101   FooterCommand(base::string16 display_text, autofill::AccessoryAction action);
102   FooterCommand(const FooterCommand& footer_command);
103   FooterCommand(FooterCommand&& footer_command);
104 
105   ~FooterCommand();
106 
107   FooterCommand& operator=(const FooterCommand& footer_command);
108   FooterCommand& operator=(FooterCommand&& footer_command);
109 
display_text()110   const base::string16& display_text() const { return display_text_; }
111 
accessory_action()112   autofill::AccessoryAction accessory_action() const {
113     return accessory_action_;
114   }
115 
116   bool operator==(const FooterCommand& fc) const;
117 
118  private:
119   base::string16 display_text_;
120   autofill::AccessoryAction accessory_action_;
121 };
122 
123 std::ostream& operator<<(std::ostream& out, const FooterCommand& fc);
124 
125 std::ostream& operator<<(std::ostream& out, const AccessoryTabType& type);
126 
127 // Toggle to be displayed above the suggestions. One such toggle can be used,
128 // for example, to turn password saving on for the current origin.
129 class OptionToggle {
130  public:
131   OptionToggle(base::string16 display_text,
132                bool enabled,
133                AccessoryAction accessory_action);
134   OptionToggle(const OptionToggle& option_toggle);
135   OptionToggle(OptionToggle&& option_toggle);
136 
137   ~OptionToggle();
138 
139   OptionToggle& operator=(const OptionToggle& option_toggle);
140   OptionToggle& operator=(OptionToggle&& option_toggle);
141 
display_text()142   const base::string16& display_text() const { return display_text_; }
143 
is_enabled()144   bool is_enabled() const { return enabled_; }
145 
accessory_action()146   AccessoryAction accessory_action() const { return accessory_action_; }
147 
148   bool operator==(const OptionToggle& option_toggle) const;
149 
150  private:
151   base::string16 display_text_;
152   bool enabled_;
153   autofill::AccessoryAction accessory_action_;
154 };
155 
156 // Represents the contents of a bottom sheet tab below the keyboard accessory,
157 // which can correspond to passwords, credit cards, or profiles data.
158 class AccessorySheetData {
159  public:
160   class Builder;
161 
162   AccessorySheetData(AccessoryTabType sheet_type, base::string16 title);
163   AccessorySheetData(AccessoryTabType sheet_type,
164                      base::string16 title,
165                      base::string16 warning);
166   AccessorySheetData(const AccessorySheetData& data);
167   AccessorySheetData(AccessorySheetData&& data);
168 
169   ~AccessorySheetData();
170 
171   AccessorySheetData& operator=(const AccessorySheetData& data);
172   AccessorySheetData& operator=(AccessorySheetData&& data);
173 
title()174   const base::string16& title() const { return title_; }
get_sheet_type()175   AccessoryTabType get_sheet_type() const { return sheet_type_; }
176 
warning()177   const base::string16& warning() const { return warning_; }
set_warning(base::string16 warning)178   void set_warning(base::string16 warning) { warning_ = std::move(warning); }
179 
set_option_toggle(OptionToggle toggle)180   void set_option_toggle(OptionToggle toggle) {
181     option_toggle_ = std::move(toggle);
182   }
option_toggle()183   const base::Optional<OptionToggle>& option_toggle() const {
184     return option_toggle_;
185   }
186 
add_user_info(UserInfo user_info)187   void add_user_info(UserInfo user_info) {
188     user_info_list_.emplace_back(std::move(user_info));
189   }
190 
user_info_list()191   const std::vector<UserInfo>& user_info_list() const {
192     return user_info_list_;
193   }
194 
mutable_user_info_list()195   std::vector<UserInfo>& mutable_user_info_list() { return user_info_list_; }
196 
add_footer_command(FooterCommand footer_command)197   void add_footer_command(FooterCommand footer_command) {
198     footer_commands_.emplace_back(std::move(footer_command));
199   }
200 
footer_commands()201   const std::vector<FooterCommand>& footer_commands() const {
202     return footer_commands_;
203   }
204 
205   bool operator==(const AccessorySheetData& data) const;
206 
207  private:
208   AccessoryTabType sheet_type_;
209   base::string16 title_;
210   base::string16 warning_;
211   base::Optional<OptionToggle> option_toggle_;
212   std::vector<UserInfo> user_info_list_;
213   std::vector<FooterCommand> footer_commands_;
214 };
215 
216 std::ostream& operator<<(std::ostream& out, const AccessorySheetData& data);
217 
218 // Helper class for AccessorySheetData objects creation.
219 //
220 // Example that creates a AccessorySheetData object with two UserInfo objects;
221 // the former has two fields, whereas the latter has three fields:
222 //   AccessorySheetData data = AccessorySheetData::Builder(title)
223 //       .AddUserInfo()
224 //           .AppendField(...)
225 //           .AppendField(...)
226 //       .AddUserInfo()
227 //           .AppendField(...)
228 //           .AppendField(...)
229 //           .AppendField(...)
230 //       .Build();
231 class AccessorySheetData::Builder {
232  public:
233   Builder(AccessoryTabType type, base::string16 title);
234   ~Builder();
235 
236   // Adds a warning string to the accessory sheet.
237   Builder&& SetWarning(base::string16 warning) &&;
238   Builder& SetWarning(base::string16 warning) &;
239 
240   // Sets the option toggle in the accessory sheet.
241   Builder&& SetOptionToggle(base::string16 display_text,
242                             bool enabled,
243                             autofill::AccessoryAction action) &&;
244   Builder& SetOptionToggle(base::string16 display_text,
245                            bool enabled,
246                            autofill::AccessoryAction action) &;
247 
248   // Adds a new UserInfo object to |accessory_sheet_data_|.
249   Builder&& AddUserInfo(
250       std::string origin = std::string(),
251       UserInfo::IsPslMatch is_psl_match = UserInfo::IsPslMatch(false)) &&;
252   Builder& AddUserInfo(
253       std::string origin = std::string(),
254       UserInfo::IsPslMatch is_psl_match = UserInfo::IsPslMatch(false)) &;
255 
256   // Appends a selectable, non-obfuscated field to the last UserInfo object.
257   Builder&& AppendSimpleField(base::string16 text) &&;
258   Builder& AppendSimpleField(base::string16 text) &;
259 
260   // Appends a field to the last UserInfo object.
261   Builder&& AppendField(base::string16 display_text,
262                         base::string16 a11y_description,
263                         bool is_obfuscated,
264                         bool selectable) &&;
265   Builder& AppendField(base::string16 display_text,
266                        base::string16 a11y_description,
267                        bool is_obfuscated,
268                        bool selectable) &;
269 
270   Builder&& AppendField(base::string16 display_text,
271                         base::string16 a11y_description,
272                         std::string id,
273                         bool is_obfuscated,
274                         bool selectable) &&;
275   Builder& AppendField(base::string16 display_text,
276                        base::string16 a11y_description,
277                        std::string id,
278                        bool is_obfuscated,
279                        bool selectable) &;
280 
281   // Appends a new footer command to |accessory_sheet_data_|.
282   Builder&& AppendFooterCommand(base::string16 display_text,
283                                 autofill::AccessoryAction action) &&;
284   Builder& AppendFooterCommand(base::string16 display_text,
285                                autofill::AccessoryAction action) &;
286 
287   // This class returns the constructed AccessorySheetData object. Since this
288   // would render the builder unusable, it's required to destroy the object
289   // afterwards. So if you hold the class in a variable, invoke like this:
290   //   AccessorySheetData::Builder b(title);
291   //   std::move(b).Build();
292   AccessorySheetData&& Build() &&;
293 
294  private:
295   AccessorySheetData accessory_sheet_data_;
296 };
297 
298 }  // namespace autofill
299 
300 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_ACCESSORY_SHEET_DATA_H_
301