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

Side by Side Diff: components/safe_browsing_db/safe_browsing_prefs.cc

Issue 2869383002: Unify safe_browsing* components [1]: move safe_browsing_prefs* (Closed)
Patch Set: fix win bots Created 3 years, 7 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
(Empty)
1 // Copyright (c) 2016 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 "base/command_line.h"
6 #include "base/logging.h"
7 #include "base/metrics/histogram_macros.h"
8 #include "components/prefs/pref_service.h"
9 #include "components/safe_browsing_db/safe_browsing_prefs.h"
10
11 namespace {
12
13 // Switch value which force the ScoutGroupSelected pref to true.
14 const char kForceScoutGroupValueTrue[] = "true";
15 // Switch value which force the ScoutGroupSelected pref to false.
16 const char kForceScoutGroupValueFalse[] = "false";
17
18 // Name of the Scout Transition UMA metric.
19 const char kScoutTransitionMetricName[] = "SafeBrowsing.Pref.Scout.Transition";
20
21 // Reasons that a state transition for Scout was performed.
22 // These values are written to logs. New enum values can be added, but
23 // existing enums must never be renumbered or deleted and reused.
24 enum ScoutTransitionReason {
25 // Flag forced Scout Group to true
26 FORCE_SCOUT_FLAG_TRUE = 0,
27 // Flag forced Scout Group to false
28 FORCE_SCOUT_FLAG_FALSE = 1,
29 // User in OnlyShowScout group, enters Scout Group
30 ONLY_SHOW_SCOUT_OPT_IN = 2,
31 // User in CanShowScout group, enters Scout Group immediately
32 CAN_SHOW_SCOUT_OPT_IN_SCOUT_GROUP_ON = 3,
33 // User in CanShowScout group, waiting for interstitial to enter Scout Group
34 CAN_SHOW_SCOUT_OPT_IN_WAIT_FOR_INTERSTITIAL = 4,
35 // User in CanShowScout group saw the first interstitial and entered the Scout
36 // Group
37 CAN_SHOW_SCOUT_OPT_IN_SAW_FIRST_INTERSTITIAL = 5,
38 // User in Control group
39 CONTROL = 6,
40 // Rollback: SBER2 on on implies SBER1 can turn on
41 ROLLBACK_SBER2_IMPLIES_SBER1 = 7,
42 // Rollback: SBER2 off so SBER1 must be turned off
43 ROLLBACK_NO_SBER2_SET_SBER1_FALSE = 8,
44 // Rollback: SBER2 absent so SBER1 must be cleared
45 ROLLBACK_NO_SBER2_CLEAR_SBER1 = 9,
46 // New reasons must be added BEFORE MAX_REASONS
47 MAX_REASONS
48 };
49
50 // The Extended Reporting pref that is currently active, used for UMA metrics.
51 // These values are written to logs. New enum values can be added, but
52 // existing enums must never be renumbered or deleted and reused.
53 enum ActiveExtendedReportingPref {
54 SBER1_PREF = 0,
55 SBER2_PREF = 1,
56 // New prefs must be added before MAX_SBER_PREF
57 MAX_SBER_PREF
58 };
59
60 // A histogram for tracking a nullable boolean, which can be false, true or
61 // null. These values are written to logs. New enum values can be added, but
62 // existing enums must never be renumbered or deleted and reused.
63 enum NullableBoolean {
64 NULLABLE_BOOLEAN_FALSE = 0,
65 NULLABLE_BOOLEAN_TRUE = 1,
66 NULLABLE_BOOLEAN_NULL = 2,
67 MAX_NULLABLE_BOOLEAN
68 };
69
70 NullableBoolean GetPrefValueOrNull(const PrefService& prefs,
71 const std::string& pref_name) {
72 if (!prefs.HasPrefPath(pref_name)) {
73 return NULLABLE_BOOLEAN_NULL;
74 }
75 return prefs.GetBoolean(pref_name) ? NULLABLE_BOOLEAN_TRUE
76 : NULLABLE_BOOLEAN_FALSE;
77 }
78
79 // Update the correct UMA metric based on which pref was changed and which UI
80 // the change was made on.
81 void RecordExtendedReportingPrefChanged(
82 const PrefService& prefs,
83 safe_browsing::ExtendedReportingOptInLocation location) {
84 bool pref_value = safe_browsing::IsExtendedReportingEnabled(prefs);
85
86 if (safe_browsing::IsScout(prefs)) {
87 switch (location) {
88 case safe_browsing::SBER_OPTIN_SITE_CHROME_SETTINGS:
89 UMA_HISTOGRAM_BOOLEAN(
90 "SafeBrowsing.Pref.Scout.SetPref.SBER2Pref.ChromeSettings",
91 pref_value);
92 break;
93 case safe_browsing::SBER_OPTIN_SITE_ANDROID_SETTINGS:
94 UMA_HISTOGRAM_BOOLEAN(
95 "SafeBrowsing.Pref.Scout.SetPref.SBER2Pref.AndroidSettings",
96 pref_value);
97 break;
98 case safe_browsing::SBER_OPTIN_SITE_DOWNLOAD_FEEDBACK_POPUP:
99 UMA_HISTOGRAM_BOOLEAN(
100 "SafeBrowsing.Pref.Scout.SetPref.SBER2Pref.DownloadPopup",
101 pref_value);
102 break;
103 case safe_browsing::SBER_OPTIN_SITE_SECURITY_INTERSTITIAL:
104 UMA_HISTOGRAM_BOOLEAN(
105 "SafeBrowsing.Pref.Scout.SetPref.SBER2Pref.SecurityInterstitial",
106 pref_value);
107 break;
108 default:
109 NOTREACHED();
110 }
111 } else {
112 switch (location) {
113 case safe_browsing::SBER_OPTIN_SITE_CHROME_SETTINGS:
114 UMA_HISTOGRAM_BOOLEAN(
115 "SafeBrowsing.Pref.Scout.SetPref.SBER1Pref.ChromeSettings",
116 pref_value);
117 break;
118 case safe_browsing::SBER_OPTIN_SITE_ANDROID_SETTINGS:
119 UMA_HISTOGRAM_BOOLEAN(
120 "SafeBrowsing.Pref.Scout.SetPref.SBER1Pref.AndroidSettings",
121 pref_value);
122 break;
123 case safe_browsing::SBER_OPTIN_SITE_DOWNLOAD_FEEDBACK_POPUP:
124 UMA_HISTOGRAM_BOOLEAN(
125 "SafeBrowsing.Pref.Scout.SetPref.SBER1Pref.DownloadPopup",
126 pref_value);
127 break;
128 case safe_browsing::SBER_OPTIN_SITE_SECURITY_INTERSTITIAL:
129 UMA_HISTOGRAM_BOOLEAN(
130 "SafeBrowsing.Pref.Scout.SetPref.SBER1Pref.SecurityInterstitial",
131 pref_value);
132 break;
133 default:
134 NOTREACHED();
135 }
136 }
137 }
138 } // namespace
139
140 namespace prefs {
141 const char kSafeBrowsingExtendedReportingEnabled[] =
142 "safebrowsing.extended_reporting_enabled";
143 const char kSafeBrowsingScoutReportingEnabled[] =
144 "safebrowsing.scout_reporting_enabled";
145 const char kSafeBrowsingScoutGroupSelected[] =
146 "safebrowsing.scout_group_selected";
147 const char kSafeBrowsingSawInterstitialExtendedReporting[] =
148 "safebrowsing.saw_interstitial_sber1";
149 const char kSafeBrowsingSawInterstitialScoutReporting[] =
150 "safebrowsing.saw_interstitial_sber2";
151 } // namespace prefs
152
153 namespace safe_browsing {
154
155 const char kSwitchForceScoutGroup[] = "force-scout-group";
156
157 const base::Feature kCanShowScoutOptIn{"CanShowScoutOptIn",
158 base::FEATURE_DISABLED_BY_DEFAULT};
159
160 const base::Feature kOnlyShowScoutOptIn{"OnlyShowScoutOptIn",
161 base::FEATURE_DISABLED_BY_DEFAULT};
162
163 std::string ChooseOptInTextPreference(
164 const PrefService& prefs,
165 const std::string& extended_reporting_pref,
166 const std::string& scout_pref) {
167 return IsScout(prefs) ? scout_pref : extended_reporting_pref;
168 }
169
170 int ChooseOptInTextResource(const PrefService& prefs,
171 int extended_reporting_resource,
172 int scout_resource) {
173 return IsScout(prefs) ? scout_resource : extended_reporting_resource;
174 }
175
176 bool ExtendedReportingPrefExists(const PrefService& prefs) {
177 return prefs.HasPrefPath(GetExtendedReportingPrefName(prefs));
178 }
179
180 ExtendedReportingLevel GetExtendedReportingLevel(const PrefService& prefs) {
181 if (!IsExtendedReportingEnabled(prefs)) {
182 return SBER_LEVEL_OFF;
183 } else {
184 return IsScout(prefs) ? SBER_LEVEL_SCOUT : SBER_LEVEL_LEGACY;
185 }
186 }
187
188 const char* GetExtendedReportingPrefName(const PrefService& prefs) {
189 // The Scout pref is active if either of the experiment features are on, and
190 // ScoutGroupSelected is on as well.
191 if ((base::FeatureList::IsEnabled(kCanShowScoutOptIn) ||
192 base::FeatureList::IsEnabled(kOnlyShowScoutOptIn)) &&
193 prefs.GetBoolean(prefs::kSafeBrowsingScoutGroupSelected)) {
194 return prefs::kSafeBrowsingScoutReportingEnabled;
195 }
196
197 // ..otherwise, either no experiment is on (ie: the Control group) or
198 // ScoutGroupSelected is off. So we use the SBER pref instead.
199 return prefs::kSafeBrowsingExtendedReportingEnabled;
200 }
201
202 void InitializeSafeBrowsingPrefs(PrefService* prefs) {
203 // First handle forcing kSafeBrowsingScoutGroupSelected pref via cmd-line.
204 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
205 kSwitchForceScoutGroup)) {
206 std::string switch_value =
207 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
208 kSwitchForceScoutGroup);
209 if (switch_value == kForceScoutGroupValueTrue) {
210 prefs->SetBoolean(prefs::kSafeBrowsingScoutGroupSelected, true);
211 UMA_HISTOGRAM_ENUMERATION(kScoutTransitionMetricName,
212 FORCE_SCOUT_FLAG_TRUE, MAX_REASONS);
213 } else if (switch_value == kForceScoutGroupValueFalse) {
214 prefs->SetBoolean(prefs::kSafeBrowsingScoutGroupSelected, false);
215 UMA_HISTOGRAM_ENUMERATION(kScoutTransitionMetricName,
216 FORCE_SCOUT_FLAG_FALSE, MAX_REASONS);
217 }
218
219 // If the switch is used, don't process the experiment state.
220 return;
221 }
222
223 // Handle the three possible experiment states.
224 if (base::FeatureList::IsEnabled(kOnlyShowScoutOptIn)) {
225 // OnlyShowScoutOptIn immediately turns on ScoutGroupSelected pref.
226 prefs->SetBoolean(prefs::kSafeBrowsingScoutGroupSelected, true);
227 UMA_HISTOGRAM_ENUMERATION(kScoutTransitionMetricName,
228 ONLY_SHOW_SCOUT_OPT_IN, MAX_REASONS);
229 } else if (base::FeatureList::IsEnabled(kCanShowScoutOptIn)) {
230 // CanShowScoutOptIn will only turn on ScoutGroupSelected pref if the legacy
231 // SBER pref is false. Otherwise the legacy SBER pref will stay on and
232 // continue to be used until the next security incident, at which point
233 // the Scout pref will become the active one.
234 if (!prefs->GetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled)) {
235 prefs->SetBoolean(prefs::kSafeBrowsingScoutGroupSelected, true);
236 UMA_HISTOGRAM_ENUMERATION(kScoutTransitionMetricName,
237 CAN_SHOW_SCOUT_OPT_IN_SCOUT_GROUP_ON,
238 MAX_REASONS);
239 } else {
240 UMA_HISTOGRAM_ENUMERATION(kScoutTransitionMetricName,
241 CAN_SHOW_SCOUT_OPT_IN_WAIT_FOR_INTERSTITIAL,
242 MAX_REASONS);
243 }
244 } else {
245 // Both experiment features are off, so this is the Control group. We must
246 // handle the possibility that the user was previously in an experiment
247 // group (above) that was reverted. We want to restore the user to a
248 // reasonable state based on the ScoutGroup and ScoutReporting preferences.
249 UMA_HISTOGRAM_ENUMERATION(kScoutTransitionMetricName, CONTROL, MAX_REASONS);
250 bool transitioned = false;
251 if (prefs->GetBoolean(prefs::kSafeBrowsingScoutReportingEnabled)) {
252 // User opted-in to Scout which is broader than legacy Extended Reporting.
253 // Opt them in to Extended Reporting.
254 prefs->SetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled, true);
255 UMA_HISTOGRAM_ENUMERATION(kScoutTransitionMetricName,
256 ROLLBACK_SBER2_IMPLIES_SBER1, MAX_REASONS);
257 transitioned = true;
258 } else if (prefs->GetBoolean(prefs::kSafeBrowsingScoutGroupSelected)) {
259 // User was in the Scout Group (ie: seeing the Scout opt-in text) but did
260 // NOT opt-in to Scout. Assume this was a conscious choice and remove
261 // their legacy Extended Reporting opt-in as well. The user will have a
262 // chance to evaluate their choice next time they see the opt-in text.
263
264 // We make the Extended Reporting pref mimic the state of the Scout
265 // Reporting pref. So we either Clear it or set it to False.
266 if (prefs->HasPrefPath(prefs::kSafeBrowsingScoutReportingEnabled)) {
267 // Scout Reporting pref was explicitly set to false, so set the SBER
268 // pref to false.
269 prefs->SetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled, false);
270 UMA_HISTOGRAM_ENUMERATION(kScoutTransitionMetricName,
271 ROLLBACK_NO_SBER2_SET_SBER1_FALSE,
272 MAX_REASONS);
273 } else {
274 // Scout Reporting pref is unset, so clear the SBER pref.
275 prefs->ClearPref(prefs::kSafeBrowsingExtendedReportingEnabled);
276 UMA_HISTOGRAM_ENUMERATION(kScoutTransitionMetricName,
277 ROLLBACK_NO_SBER2_CLEAR_SBER1, MAX_REASONS);
278 }
279 transitioned = true;
280 }
281
282 // Also clear both the Scout settings to start over from a clean state and
283 // avoid the above logic from triggering on next restart.
284 prefs->ClearPref(prefs::kSafeBrowsingScoutGroupSelected);
285 prefs->ClearPref(prefs::kSafeBrowsingScoutReportingEnabled);
286
287 // Also forget that the user has seen any interstitials if they're
288 // reverting back to a clean state.
289 if (transitioned) {
290 prefs->ClearPref(prefs::kSafeBrowsingSawInterstitialExtendedReporting);
291 prefs->ClearPref(prefs::kSafeBrowsingSawInterstitialScoutReporting);
292 }
293 }
294 }
295
296 bool IsExtendedReportingEnabled(const PrefService& prefs) {
297 return prefs.GetBoolean(GetExtendedReportingPrefName(prefs));
298 }
299
300 bool IsScout(const PrefService& prefs) {
301 return GetExtendedReportingPrefName(prefs) ==
302 prefs::kSafeBrowsingScoutReportingEnabled;
303 }
304
305 void RecordExtendedReportingMetrics(const PrefService& prefs) {
306 // This metric tracks the extended browsing opt-in based on whichever setting
307 // the user is currently seeing. It tells us whether extended reporting is
308 // happening for this user.
309 UMA_HISTOGRAM_BOOLEAN("SafeBrowsing.Pref.Extended",
310 IsExtendedReportingEnabled(prefs));
311
312 // Track whether this user has ever seen a security interstitial.
313 UMA_HISTOGRAM_BOOLEAN(
314 "SafeBrowsing.Pref.SawInterstitial.SBER1Pref",
315 prefs.GetBoolean(prefs::kSafeBrowsingSawInterstitialExtendedReporting));
316 UMA_HISTOGRAM_BOOLEAN(
317 "SafeBrowsing.Pref.SawInterstitial.SBER2Pref",
318 prefs.GetBoolean(prefs::kSafeBrowsingSawInterstitialScoutReporting));
319
320 // These metrics track the Scout transition.
321 if (prefs.GetBoolean(prefs::kSafeBrowsingScoutGroupSelected)) {
322 // Users in the Scout group: currently seeing the Scout opt-in.
323 UMA_HISTOGRAM_ENUMERATION(
324 "SafeBrowsing.Pref.Scout.ScoutGroup.SBER1Pref",
325 GetPrefValueOrNull(prefs, prefs::kSafeBrowsingExtendedReportingEnabled),
326 MAX_NULLABLE_BOOLEAN);
327 UMA_HISTOGRAM_ENUMERATION(
328 "SafeBrowsing.Pref.Scout.ScoutGroup.SBER2Pref",
329 GetPrefValueOrNull(prefs, prefs::kSafeBrowsingScoutReportingEnabled),
330 MAX_NULLABLE_BOOLEAN);
331 } else {
332 // Users not in the Scout group: currently seeing the SBER opt-in.
333 UMA_HISTOGRAM_ENUMERATION(
334 "SafeBrowsing.Pref.Scout.NoScoutGroup.SBER1Pref",
335 GetPrefValueOrNull(prefs, prefs::kSafeBrowsingExtendedReportingEnabled),
336 MAX_NULLABLE_BOOLEAN);
337 // The following metric is a corner case. User was previously in the
338 // Scout group and was able to opt-in to the Scout pref, but was since
339 // removed from the Scout group (eg: by rolling back a Scout experiment).
340 UMA_HISTOGRAM_ENUMERATION(
341 "SafeBrowsing.Pref.Scout.NoScoutGroup.SBER2Pref",
342 GetPrefValueOrNull(prefs, prefs::kSafeBrowsingScoutReportingEnabled),
343 MAX_NULLABLE_BOOLEAN);
344 }
345 }
346
347 void SetExtendedReportingPrefAndMetric(
348 PrefService* prefs,
349 bool value,
350 ExtendedReportingOptInLocation location) {
351 prefs->SetBoolean(GetExtendedReportingPrefName(*prefs), value);
352 RecordExtendedReportingPrefChanged(*prefs, location);
353 }
354
355 void SetExtendedReportingPref(PrefService* prefs, bool value) {
356 prefs->SetBoolean(GetExtendedReportingPrefName(*prefs), value);
357 }
358
359 void UpdateMetricsAfterSecurityInterstitial(const PrefService& prefs,
360 bool on_show_pref_existed,
361 bool on_show_pref_value) {
362 const ActiveExtendedReportingPref active_pref =
363 IsScout(prefs) ? SBER2_PREF : SBER1_PREF;
364 const bool cur_pref_value = IsExtendedReportingEnabled(prefs);
365
366 if (!on_show_pref_existed) {
367 if (!ExtendedReportingPrefExists(prefs)) {
368 // User seeing pref for the first time, didn't touch the checkbox (left it
369 // unchecked).
370 UMA_HISTOGRAM_ENUMERATION(
371 "SafeBrowsing.Pref.Scout.Decision.First_LeftUnchecked", active_pref,
372 MAX_SBER_PREF);
373 return;
374 }
375
376 // Pref currently exists so user did something to the checkbox
377 if (cur_pref_value) {
378 // User turned the pref on.
379 UMA_HISTOGRAM_ENUMERATION(
380 "SafeBrowsing.Pref.Scout.Decision.First_Enabled", active_pref,
381 MAX_SBER_PREF);
382 return;
383 }
384
385 // Otherwise, user turned the pref off, but because it didn't exist when
386 // the interstitial was first shown, they must have turned it on and then
387 // off before the interstitial was closed.
388 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.Pref.Scout.Decision.First_Disabled",
389 active_pref, MAX_SBER_PREF);
390 return;
391 }
392
393 // At this point, the pref existed when the interstitial was shown so this is
394 // a repeat appearance of the opt-in. Existence can't be removed during an
395 // interstitial so no need to check whether the pref currently exists.
396 if (on_show_pref_value && cur_pref_value) {
397 // User left the pref on.
398 UMA_HISTOGRAM_ENUMERATION(
399 "SafeBrowsing.Pref.Scout.Decision.Repeat_LeftEnabled", active_pref,
400 MAX_SBER_PREF);
401 return;
402 } else if (on_show_pref_value && !cur_pref_value) {
403 // User turned the pref off.
404 UMA_HISTOGRAM_ENUMERATION(
405 "SafeBrowsing.Pref.Scout.Decision.Repeat_Disabled", active_pref,
406 MAX_SBER_PREF);
407 return;
408 } else if (!on_show_pref_value && cur_pref_value) {
409 // User turned the pref on.
410 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.Pref.Scout.Decision.Repeat_Enabled",
411 active_pref, MAX_SBER_PREF);
412 return;
413 } else {
414 // Both on_show and cur values are false - user left the pref off.
415 UMA_HISTOGRAM_ENUMERATION(
416 "SafeBrowsing.Pref.Scout.Decision.Repeat_LeftDisabled", active_pref,
417 MAX_SBER_PREF);
418 return;
419 }
420 }
421
422 void UpdatePrefsBeforeSecurityInterstitial(PrefService* prefs) {
423 // Move the user into the Scout Group if the CanShowScoutOptIn experiment is
424 // enabled and they're not in the group already.
425 if (base::FeatureList::IsEnabled(kCanShowScoutOptIn) &&
426 !prefs->GetBoolean(prefs::kSafeBrowsingScoutGroupSelected)) {
427 prefs->SetBoolean(prefs::kSafeBrowsingScoutGroupSelected, true);
428 UMA_HISTOGRAM_ENUMERATION(kScoutTransitionMetricName,
429 CAN_SHOW_SCOUT_OPT_IN_SAW_FIRST_INTERSTITIAL,
430 MAX_REASONS);
431 }
432
433 // Remember that this user saw an interstitial with the current opt-in text.
434 prefs->SetBoolean(IsScout(*prefs)
435 ? prefs::kSafeBrowsingSawInterstitialScoutReporting
436 : prefs::kSafeBrowsingSawInterstitialExtendedReporting,
437 true);
438 }
439
440 } // namespace safe_browsing
OLDNEW
« no previous file with comments | « components/safe_browsing_db/safe_browsing_prefs.h ('k') | components/safe_browsing_db/safe_browsing_prefs_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698