1 // Copyright 2019 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 #include "components/autofill_assistant/browser/trigger_context.h"
6 #include "base/strings/string_split.h"
7
8 namespace autofill_assistant {
9
10 // Parameter that allows setting the color of the overlay.
11 const char kOverlayColorParameterName[] = "OVERLAY_COLORS";
12
13 // Parameter that contains the current session username. Should be synced with
14 // |SESSION_USERNAME_PARAMETER| from
15 // .../password_manager/PasswordChangeLauncher.java
16 // TODO(b/151401974): Eliminate duplicate parameter definitions.
17 const char kPasswordChangeUsernameParameterName[] = "PASSWORD_CHANGE_USERNAME";
18
19 // Legacy, remove as soon as possible.
20 // Parameter that contains the path of the lite script that was used to trigger
21 // this flow (may be empty).
22 const char kLiteScriptPathParamaterName[] = "TRIGGER_SCRIPT_USED";
23
24 // Parameter that contains a base64-encoded GetTriggerScriptsResponseProto
25 // message. This allows callers to directly inject trigger scripts, rather than
26 // fetching them from a remote backend.
27 const char kBase64TriggerScriptsResponseProtoParameterName[] =
28 "TRIGGER_SCRIPTS_BASE64";
29
30 // static
CreateEmpty()31 std::unique_ptr<TriggerContext> TriggerContext::CreateEmpty() {
32 return std::make_unique<TriggerContextImpl>();
33 }
34
35 // static
Create(std::map<std::string,std::string> params,const std::string & exp)36 std::unique_ptr<TriggerContext> TriggerContext::Create(
37 std::map<std::string, std::string> params,
38 const std::string& exp) {
39 return std::make_unique<TriggerContextImpl>(params, exp);
40 }
41
42 // static
Merge(std::vector<const TriggerContext * > contexts)43 std::unique_ptr<TriggerContext> TriggerContext::Merge(
44 std::vector<const TriggerContext*> contexts) {
45 return std::make_unique<MergedTriggerContext>(contexts);
46 }
47
TriggerContext()48 TriggerContext::TriggerContext() {}
~TriggerContext()49 TriggerContext::~TriggerContext() {}
50
GetOverlayColors() const51 base::Optional<std::string> TriggerContext::GetOverlayColors() const {
52 return GetParameter(kOverlayColorParameterName);
53 }
54
GetPasswordChangeUsername() const55 base::Optional<std::string> TriggerContext::GetPasswordChangeUsername() const {
56 return GetParameter(kPasswordChangeUsernameParameterName);
57 }
58
WasStartedByLegacyTriggerScript() const59 bool TriggerContext::WasStartedByLegacyTriggerScript() const {
60 return GetParameter(kLiteScriptPathParamaterName).has_value();
61 }
62
63 base::Optional<std::string>
GetBase64TriggerScriptsResponseProto() const64 TriggerContext::GetBase64TriggerScriptsResponseProto() const {
65 return GetParameter(kBase64TriggerScriptsResponseProtoParameterName);
66 }
67
TriggerContextImpl()68 TriggerContextImpl::TriggerContextImpl() {}
69
TriggerContextImpl(std::map<std::string,std::string> parameters,const std::string & experiment_ids)70 TriggerContextImpl::TriggerContextImpl(
71 std::map<std::string, std::string> parameters,
72 const std::string& experiment_ids)
73 : parameters_(std::move(parameters)),
74 experiment_ids_(std::move(experiment_ids)) {}
75
76 TriggerContextImpl::~TriggerContextImpl() = default;
77
GetParameters() const78 std::map<std::string, std::string> TriggerContextImpl::GetParameters() const {
79 return parameters_;
80 }
81
GetParameter(const std::string & name) const82 base::Optional<std::string> TriggerContextImpl::GetParameter(
83 const std::string& name) const {
84 auto iter = parameters_.find(name);
85 if (iter == parameters_.end())
86 return base::nullopt;
87
88 return iter->second;
89 }
90
experiment_ids() const91 std::string TriggerContextImpl::experiment_ids() const {
92 return experiment_ids_;
93 }
94
HasExperimentId(const std::string & experiment_id) const95 bool TriggerContextImpl::HasExperimentId(
96 const std::string& experiment_id) const {
97 std::vector<std::string> experiments = base::SplitString(
98 experiment_ids_, ",", base::WhitespaceHandling::TRIM_WHITESPACE,
99 base::SplitResult::SPLIT_WANT_NONEMPTY);
100 return std::find(experiments.begin(), experiments.end(), experiment_id) !=
101 experiments.end();
102 }
103
is_cct() const104 bool TriggerContextImpl::is_cct() const {
105 return cct_;
106 }
107
is_onboarding_shown() const108 bool TriggerContextImpl::is_onboarding_shown() const {
109 return onboarding_shown_;
110 }
111
is_direct_action() const112 bool TriggerContextImpl::is_direct_action() const {
113 return direct_action_;
114 }
115
get_caller_account_hash() const116 std::string TriggerContextImpl::get_caller_account_hash() const {
117 return caller_account_hash_;
118 }
119
MergedTriggerContext(std::vector<const TriggerContext * > contexts)120 MergedTriggerContext::MergedTriggerContext(
121 std::vector<const TriggerContext*> contexts)
122 : contexts_(contexts) {}
123
~MergedTriggerContext()124 MergedTriggerContext::~MergedTriggerContext() {}
125
GetParameters() const126 std::map<std::string, std::string> MergedTriggerContext::GetParameters() const {
127 std::map<std::string, std::string> merged_parameters;
128 for (const TriggerContext* context : contexts_) {
129 for (const auto& parameter : context->GetParameters()) {
130 merged_parameters.insert(parameter);
131 }
132 }
133 return merged_parameters;
134 }
135
GetParameter(const std::string & name) const136 base::Optional<std::string> MergedTriggerContext::GetParameter(
137 const std::string& name) const {
138 for (const TriggerContext* context : contexts_) {
139 auto opt_value = context->GetParameter(name);
140 if (opt_value)
141 return opt_value;
142 }
143 return base::nullopt;
144 }
145
experiment_ids() const146 std::string MergedTriggerContext::experiment_ids() const {
147 std::string experiment_ids;
148 for (const TriggerContext* context : contexts_) {
149 std::string context_experiment_ids = context->experiment_ids();
150 if (context_experiment_ids.empty())
151 continue;
152
153 if (!experiment_ids.empty())
154 experiment_ids.append(1, ',');
155
156 experiment_ids.append(context->experiment_ids());
157 }
158 return experiment_ids;
159 }
160
HasExperimentId(const std::string & experiment_id) const161 bool MergedTriggerContext::HasExperimentId(
162 const std::string& experiment_id) const {
163 for (const TriggerContext* context : contexts_) {
164 if (context->HasExperimentId(experiment_id)) {
165 return true;
166 }
167 }
168 return false;
169 }
170
is_cct() const171 bool MergedTriggerContext::is_cct() const {
172 for (const TriggerContext* context : contexts_) {
173 if (context->is_cct())
174 return true;
175 }
176 return false;
177 }
178
is_onboarding_shown() const179 bool MergedTriggerContext::is_onboarding_shown() const {
180 for (const TriggerContext* context : contexts_) {
181 if (context->is_onboarding_shown())
182 return true;
183 }
184 return false;
185 }
186
is_direct_action() const187 bool MergedTriggerContext::is_direct_action() const {
188 for (const TriggerContext* context : contexts_) {
189 if (context->is_direct_action())
190 return true;
191 }
192 return false;
193 }
194
get_caller_account_hash() const195 std::string MergedTriggerContext::get_caller_account_hash() const {
196 for (const TriggerContext* context : contexts_) {
197 if (!context->get_caller_account_hash().empty())
198 return context->get_caller_account_hash();
199 }
200 return "";
201 }
202
203 } // namespace autofill_assistant
204