• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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 "chrome/browser/bookmarks/enhanced_bookmarks_features.h"
6 
7 #include "base/command_line.h"
8 #include "base/metrics/histogram.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/prefs/scoped_user_pref_update.h"
11 #include "base/sha1.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "chrome/common/chrome_switches.h"
14 #include "chrome/common/pref_names.h"
15 #include "components/sync_driver/pref_names.h"
16 #include "components/variations/variations_associated_data.h"
17 #include "extensions/common/features/feature.h"
18 #include "extensions/common/features/feature_provider.h"
19 
20 namespace {
21 
22 const char kFieldTrialName[] = "EnhancedBookmarks";
23 
24 // Get extension id from Finch EnhancedBookmarks group parameters.
GetEnhancedBookmarksExtensionIdFromFinch()25 std::string GetEnhancedBookmarksExtensionIdFromFinch() {
26   return chrome_variations::GetVariationParamValue(kFieldTrialName, "id");
27 }
28 
29 // Returns true if enhanced bookmarks experiment is enabled from Finch.
IsEnhancedBookmarksExperimentEnabledFromFinch()30 bool IsEnhancedBookmarksExperimentEnabledFromFinch() {
31   std::string ext_id = GetEnhancedBookmarksExtensionIdFromFinch();
32   const extensions::FeatureProvider* feature_provider =
33       extensions::FeatureProvider::GetPermissionFeatures();
34   extensions::Feature* feature = feature_provider->GetFeature("metricsPrivate");
35   return feature && feature->IsIdInWhitelist(ext_id);
36 }
37 
38 };  // namespace
39 
GetBookmarksExperimentExtensionID(const PrefService * user_prefs,std::string * extension_id)40 bool GetBookmarksExperimentExtensionID(const PrefService* user_prefs,
41                                        std::string* extension_id) {
42   BookmarksExperimentState bookmarks_experiment_state =
43       static_cast<BookmarksExperimentState>(user_prefs->GetInteger(
44           sync_driver::prefs::kEnhancedBookmarksExperimentEnabled));
45   if (bookmarks_experiment_state == BOOKMARKS_EXPERIMENT_ENABLED_FROM_FINCH) {
46     *extension_id = GetEnhancedBookmarksExtensionIdFromFinch();
47     return !extension_id->empty();
48   }
49   if (bookmarks_experiment_state == BOOKMARKS_EXPERIMENT_ENABLED) {
50     *extension_id = user_prefs->GetString(
51         sync_driver::prefs::kEnhancedBookmarksExtensionId);
52     return !extension_id->empty();
53   }
54 
55   return false;
56 }
57 
UpdateBookmarksExperimentState(PrefService * user_prefs,PrefService * local_state,bool user_signed_in,BookmarksExperimentState experiment_enabled_from_sync)58 void UpdateBookmarksExperimentState(
59     PrefService* user_prefs,
60     PrefService* local_state,
61     bool user_signed_in,
62     BookmarksExperimentState experiment_enabled_from_sync) {
63  PrefService* flags_storage = local_state;
64 #if defined(OS_CHROMEOS)
65   // Chrome OS is using user prefs for flags storage.
66   flags_storage = user_prefs;
67 #endif
68 
69   BookmarksExperimentState bookmarks_experiment_state_before =
70       static_cast<BookmarksExperimentState>(user_prefs->GetInteger(
71           sync_driver::prefs::kEnhancedBookmarksExperimentEnabled));
72   // If user signed out, clear possible previous state.
73   if (!user_signed_in) {
74     bookmarks_experiment_state_before = BOOKMARKS_EXPERIMENT_NONE;
75     ForceFinchBookmarkExperimentIfNeeded(flags_storage,
76         BOOKMARKS_EXPERIMENT_NONE);
77   }
78 
79   // kEnhancedBookmarksExperiment flag could have values "", "1" and "0".
80   // "0" - user opted out.
81   bool opt_out = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
82                      switches::kEnhancedBookmarksExperiment) == "0";
83 
84   BookmarksExperimentState bookmarks_experiment_new_state =
85       BOOKMARKS_EXPERIMENT_NONE;
86 
87   if (IsEnhancedBookmarksExperimentEnabledFromFinch() && !user_signed_in) {
88     if (opt_out) {
89       // Experiment enabled but user opted out.
90       bookmarks_experiment_new_state = BOOKMARKS_EXPERIMENT_OPT_OUT_FROM_FINCH;
91     } else {
92       // Experiment enabled.
93       bookmarks_experiment_new_state = BOOKMARKS_EXPERIMENT_ENABLED_FROM_FINCH;
94     }
95   } else if (experiment_enabled_from_sync == BOOKMARKS_EXPERIMENT_ENABLED) {
96     // Experiment enabled from Chrome sync.
97     if (opt_out) {
98       // Experiment enabled but user opted out.
99       bookmarks_experiment_new_state =
100           BOOKMARKS_EXPERIMENT_ENABLED_USER_OPT_OUT;
101     } else {
102       // Experiment enabled.
103       bookmarks_experiment_new_state = BOOKMARKS_EXPERIMENT_ENABLED;
104     }
105   } else if (experiment_enabled_from_sync == BOOKMARKS_EXPERIMENT_NONE) {
106     // Experiment is not enabled from Chrome sync.
107     bookmarks_experiment_new_state = BOOKMARKS_EXPERIMENT_NONE;
108   } else if (bookmarks_experiment_state_before ==
109              BOOKMARKS_EXPERIMENT_ENABLED) {
110     if (opt_out) {
111       // Experiment enabled but user opted out.
112       bookmarks_experiment_new_state =
113           BOOKMARKS_EXPERIMENT_ENABLED_USER_OPT_OUT;
114     } else {
115       bookmarks_experiment_new_state = BOOKMARKS_EXPERIMENT_ENABLED;
116     }
117   } else if (bookmarks_experiment_state_before ==
118              BOOKMARKS_EXPERIMENT_ENABLED_USER_OPT_OUT) {
119     if (opt_out) {
120       bookmarks_experiment_new_state =
121           BOOKMARKS_EXPERIMENT_ENABLED_USER_OPT_OUT;
122     } else {
123       // User opted in again.
124       bookmarks_experiment_new_state = BOOKMARKS_EXPERIMENT_ENABLED;
125     }
126   }
127 
128   UMA_HISTOGRAM_ENUMERATION("EnhancedBookmarks.SyncExperimentState",
129                             bookmarks_experiment_new_state,
130                             BOOKMARKS_EXPERIMENT_ENUM_SIZE);
131   user_prefs->SetInteger(
132       sync_driver::prefs::kEnhancedBookmarksExperimentEnabled,
133       bookmarks_experiment_new_state);
134   ForceFinchBookmarkExperimentIfNeeded(flags_storage,
135                                        bookmarks_experiment_new_state);
136 }
137 
ForceFinchBookmarkExperimentIfNeeded(PrefService * flags_storage,BookmarksExperimentState bookmarks_experiment_state)138 void ForceFinchBookmarkExperimentIfNeeded(
139     PrefService* flags_storage,
140     BookmarksExperimentState bookmarks_experiment_state) {
141   if (!flags_storage)
142     return;
143   ListPrefUpdate update(flags_storage, prefs::kEnabledLabsExperiments);
144   base::ListValue* experiments_list = update.Get();
145   if (!experiments_list)
146     return;
147   size_t index;
148   if (bookmarks_experiment_state == BOOKMARKS_EXPERIMENT_NONE) {
149     experiments_list->Remove(
150         base::StringValue(switches::kManualEnhancedBookmarks), &index);
151     experiments_list->Remove(
152         base::StringValue(switches::kManualEnhancedBookmarksOptout), &index);
153   } else if (bookmarks_experiment_state == BOOKMARKS_EXPERIMENT_ENABLED) {
154     experiments_list->Remove(
155         base::StringValue(switches::kManualEnhancedBookmarksOptout), &index);
156     experiments_list->AppendIfNotPresent(
157         new base::StringValue(switches::kManualEnhancedBookmarks));
158   } else if (bookmarks_experiment_state ==
159                  BOOKMARKS_EXPERIMENT_ENABLED_USER_OPT_OUT) {
160     experiments_list->Remove(
161         base::StringValue(switches::kManualEnhancedBookmarks), &index);
162     experiments_list->AppendIfNotPresent(
163         new base::StringValue(switches::kManualEnhancedBookmarksOptout));
164   }
165 }
166 
IsEnhancedBookmarksExperimentEnabled()167 bool IsEnhancedBookmarksExperimentEnabled() {
168   CommandLine* command_line = CommandLine::ForCurrentProcess();
169   if (command_line->HasSwitch(switches::kManualEnhancedBookmarks) ||
170       command_line->HasSwitch(switches::kManualEnhancedBookmarksOptout)) {
171     return true;
172   }
173 
174   return IsEnhancedBookmarksExperimentEnabledFromFinch();
175 }
176 
177 #if defined(OS_ANDROID)
IsEnhancedBookmarkImageFetchingEnabled()178 bool IsEnhancedBookmarkImageFetchingEnabled() {
179   if (IsEnhancedBookmarksExperimentEnabled())
180     return true;
181 
182   // Salient images are collected from visited bookmarked pages even if the
183   // enhanced bookmark feature is turned off. This is to have some images
184   // available so that in the future, when the feature is turned on, the user
185   // experience is not a big list of flat colors. However as a precautionary
186   // measure it is possible to disable this collection of images from finch.
187   std::string disable_fetching = chrome_variations::GetVariationParamValue(
188       kFieldTrialName, "DisableImagesFetching");
189   return disable_fetching.empty();
190 }
191 #endif
192 
IsEnableDomDistillerSet()193 bool IsEnableDomDistillerSet() {
194   if (CommandLine::ForCurrentProcess()->
195       HasSwitch(switches::kEnableDomDistiller)) {
196     return true;
197   }
198   if (chrome_variations::GetVariationParamValue(
199           kFieldTrialName, "enable-dom-distiller") == "1")
200     return true;
201 
202   return false;
203 }
204 
IsEnableSyncArticlesSet()205 bool IsEnableSyncArticlesSet() {
206   if (CommandLine::ForCurrentProcess()->
207       HasSwitch(switches::kEnableSyncArticles)) {
208     return true;
209   }
210   if (chrome_variations::GetVariationParamValue(
211           kFieldTrialName, "enable-sync-articles") == "1")
212     return true;
213 
214   return false;
215 }
216