Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / bookmarks / enhanced_bookmarks_features.cc
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/browser/browser_process.h"
14 #include "chrome/browser/flags_storage.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/signin/signin_manager_factory.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/pref_names.h"
19 #include "components/signin/core/browser/signin_manager.h"
20 #include "components/sync_driver/pref_names.h"
21 #include "components/variations/variations_associated_data.h"
22 #include "extensions/common/features/feature.h"
23 #include "extensions/common/features/feature_provider.h"
24 #include "ui/base/device_form_factor.h"
25
26 namespace {
27
28 const char kFieldTrialName[] = "EnhancedBookmarks";
29
30 // Get extension id from Finch EnhancedBookmarks group parameters.
31 std::string GetEnhancedBookmarksExtensionIdFromFinch() {
32   return variations::GetVariationParamValue(kFieldTrialName, "id");
33 }
34
35 // Returns true if enhanced bookmarks experiment is enabled from Finch.
36 bool IsEnhancedBookmarksExperimentEnabledFromFinch() {
37   const std::string ext_id = GetEnhancedBookmarksExtensionIdFromFinch();
38 #if defined(OS_ANDROID)
39   return !ext_id.empty();
40 #else
41   const extensions::FeatureProvider* feature_provider =
42       extensions::FeatureProvider::GetPermissionFeatures();
43   extensions::Feature* feature = feature_provider->GetFeature("metricsPrivate");
44   return feature && feature->IsIdInWhitelist(ext_id);
45 #endif
46 }
47
48 };  // namespace
49
50 bool GetBookmarksExperimentExtensionID(const PrefService* user_prefs,
51                                        std::string* extension_id) {
52   BookmarksExperimentState bookmarks_experiment_state =
53       static_cast<BookmarksExperimentState>(user_prefs->GetInteger(
54           sync_driver::prefs::kEnhancedBookmarksExperimentEnabled));
55   if (bookmarks_experiment_state == BOOKMARKS_EXPERIMENT_ENABLED_FROM_FINCH) {
56     *extension_id = GetEnhancedBookmarksExtensionIdFromFinch();
57     return !extension_id->empty();
58   }
59   if (bookmarks_experiment_state == BOOKMARKS_EXPERIMENT_ENABLED) {
60     *extension_id = user_prefs->GetString(
61         sync_driver::prefs::kEnhancedBookmarksExtensionId);
62     return !extension_id->empty();
63   }
64
65   return false;
66 }
67
68 void UpdateBookmarksExperimentState(
69     PrefService* user_prefs,
70     PrefService* local_state,
71     bool user_signed_in,
72     BookmarksExperimentState experiment_enabled_from_sync) {
73  PrefService* flags_storage = local_state;
74 #if defined(OS_CHROMEOS)
75   // Chrome OS is using user prefs for flags storage.
76   flags_storage = user_prefs;
77 #endif
78
79   BookmarksExperimentState bookmarks_experiment_state_before =
80       static_cast<BookmarksExperimentState>(user_prefs->GetInteger(
81           sync_driver::prefs::kEnhancedBookmarksExperimentEnabled));
82   // If user signed out, clear possible previous state.
83   if (!user_signed_in) {
84     bookmarks_experiment_state_before = BOOKMARKS_EXPERIMENT_NONE;
85     ForceFinchBookmarkExperimentIfNeeded(flags_storage,
86         BOOKMARKS_EXPERIMENT_NONE);
87   }
88
89   // kEnhancedBookmarksExperiment flag could have values "", "1" and "0".
90   // "0" - user opted out.
91   bool opt_out = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
92                      switches::kEnhancedBookmarksExperiment) == "0";
93 #if defined(OS_ANDROID)
94   // Tablets automagically do opt out.
95   opt_out =
96       opt_out || ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET;
97 #endif  // defined(OS_ANDROID)
98
99   BookmarksExperimentState bookmarks_experiment_new_state =
100       BOOKMARKS_EXPERIMENT_NONE;
101
102   if (IsEnhancedBookmarksExperimentEnabledFromFinch() && !user_signed_in) {
103     if (opt_out) {
104       // Experiment enabled but user opted out.
105       bookmarks_experiment_new_state = BOOKMARKS_EXPERIMENT_OPT_OUT_FROM_FINCH;
106     } else {
107       // Experiment enabled.
108       bookmarks_experiment_new_state = BOOKMARKS_EXPERIMENT_ENABLED_FROM_FINCH;
109     }
110   } else if (experiment_enabled_from_sync == BOOKMARKS_EXPERIMENT_ENABLED) {
111     // Experiment enabled from Chrome sync.
112     if (opt_out) {
113       // Experiment enabled but user opted out.
114       bookmarks_experiment_new_state =
115           BOOKMARKS_EXPERIMENT_ENABLED_USER_OPT_OUT;
116     } else {
117       // Experiment enabled.
118       bookmarks_experiment_new_state = BOOKMARKS_EXPERIMENT_ENABLED;
119     }
120   } else if (experiment_enabled_from_sync == BOOKMARKS_EXPERIMENT_NONE) {
121     // Experiment is not enabled from Chrome sync.
122     bookmarks_experiment_new_state = BOOKMARKS_EXPERIMENT_NONE;
123   } else if (bookmarks_experiment_state_before ==
124              BOOKMARKS_EXPERIMENT_ENABLED) {
125     if (opt_out) {
126       // Experiment enabled but user opted out.
127       bookmarks_experiment_new_state =
128           BOOKMARKS_EXPERIMENT_ENABLED_USER_OPT_OUT;
129     } else {
130       bookmarks_experiment_new_state = BOOKMARKS_EXPERIMENT_ENABLED;
131     }
132   } else if (bookmarks_experiment_state_before ==
133              BOOKMARKS_EXPERIMENT_ENABLED_USER_OPT_OUT) {
134     if (opt_out) {
135       bookmarks_experiment_new_state =
136           BOOKMARKS_EXPERIMENT_ENABLED_USER_OPT_OUT;
137     } else {
138       // User opted in again.
139       bookmarks_experiment_new_state = BOOKMARKS_EXPERIMENT_ENABLED;
140     }
141   }
142
143 #if defined(OS_ANDROID)
144   bool opt_in = !opt_out
145       && CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
146           switches::kEnhancedBookmarksExperiment) == "1";
147   if (opt_in && bookmarks_experiment_new_state == BOOKMARKS_EXPERIMENT_NONE)
148     bookmarks_experiment_new_state = BOOKMARKS_EXPERIMENT_ENABLED;
149 #endif
150
151   UMA_HISTOGRAM_ENUMERATION("EnhancedBookmarks.SyncExperimentState",
152                             bookmarks_experiment_new_state,
153                             BOOKMARKS_EXPERIMENT_ENUM_SIZE);
154   user_prefs->SetInteger(
155       sync_driver::prefs::kEnhancedBookmarksExperimentEnabled,
156       bookmarks_experiment_new_state);
157   ForceFinchBookmarkExperimentIfNeeded(flags_storage,
158                                        bookmarks_experiment_new_state);
159 }
160
161 void InitBookmarksExperimentState(Profile* profile) {
162   SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile);
163   bool is_signed_in = signin && signin->IsAuthenticated();
164   UpdateBookmarksExperimentState(
165       profile->GetPrefs(),
166       g_browser_process->local_state(),
167       is_signed_in,
168       BOOKMARKS_EXPERIMENT_ENABLED_FROM_SYNC_UNKNOWN);
169 }
170
171 void ForceFinchBookmarkExperimentIfNeeded(
172     PrefService* flags_storage,
173     BookmarksExperimentState bookmarks_experiment_state) {
174   if (!flags_storage)
175     return;
176   ListPrefUpdate update(flags_storage, prefs::kEnabledLabsExperiments);
177   base::ListValue* experiments_list = update.Get();
178   if (!experiments_list)
179     return;
180   size_t index;
181   if (bookmarks_experiment_state == BOOKMARKS_EXPERIMENT_NONE) {
182     experiments_list->Remove(
183         base::StringValue(switches::kManualEnhancedBookmarks), &index);
184     experiments_list->Remove(
185         base::StringValue(switches::kManualEnhancedBookmarksOptout), &index);
186   } else if (bookmarks_experiment_state == BOOKMARKS_EXPERIMENT_ENABLED) {
187     experiments_list->Remove(
188         base::StringValue(switches::kManualEnhancedBookmarksOptout), &index);
189     experiments_list->AppendIfNotPresent(
190         new base::StringValue(switches::kManualEnhancedBookmarks));
191   } else if (bookmarks_experiment_state ==
192                  BOOKMARKS_EXPERIMENT_ENABLED_USER_OPT_OUT) {
193     experiments_list->Remove(
194         base::StringValue(switches::kManualEnhancedBookmarks), &index);
195     experiments_list->AppendIfNotPresent(
196         new base::StringValue(switches::kManualEnhancedBookmarksOptout));
197   }
198 }
199
200 bool IsEnhancedBookmarksExperimentEnabled(
201     about_flags::FlagsStorage* flags_storage) {
202 #if defined(OS_CHROMEOS)
203   // We are not setting command line flags on Chrome OS to avoid browser restart
204   // but still have flags in flags_storage. So check flags_storage instead.
205   const std::set<std::string> flags = flags_storage->GetFlags();
206   if (flags.find(switches::kManualEnhancedBookmarks) != flags.end())
207     return true;
208   if (flags.find(switches::kManualEnhancedBookmarksOptout) != flags.end())
209     return true;
210 #else
211   CommandLine* command_line = CommandLine::ForCurrentProcess();
212   if (command_line->HasSwitch(switches::kManualEnhancedBookmarks) ||
213       command_line->HasSwitch(switches::kManualEnhancedBookmarksOptout)) {
214     return true;
215   }
216 #endif
217
218   return IsEnhancedBookmarksExperimentEnabledFromFinch();
219 }
220
221 #if defined(OS_ANDROID)
222 bool IsEnhancedBookmarkImageFetchingEnabled(const PrefService* user_prefs) {
223   if (IsEnhancedBookmarksEnabled(user_prefs))
224     return true;
225
226   // Salient images are collected from visited bookmarked pages even if the
227   // enhanced bookmark feature is turned off. This is to have some images
228   // available so that in the future, when the feature is turned on, the user
229   // experience is not a big list of flat colors. However as a precautionary
230   // measure it is possible to disable this collection of images from finch.
231   std::string disable_fetching = variations::GetVariationParamValue(
232       kFieldTrialName, "DisableImagesFetching");
233   return disable_fetching.empty();
234 }
235
236 bool IsEnhancedBookmarksEnabled(const PrefService* user_prefs) {
237   BookmarksExperimentState bookmarks_experiment_state =
238       static_cast<BookmarksExperimentState>(user_prefs->GetInteger(
239           sync_driver::prefs::kEnhancedBookmarksExperimentEnabled));
240   return bookmarks_experiment_state == BOOKMARKS_EXPERIMENT_ENABLED ||
241       bookmarks_experiment_state == BOOKMARKS_EXPERIMENT_ENABLED_FROM_FINCH;
242 }
243 #endif
244
245 bool IsEnableDomDistillerSet() {
246   if (CommandLine::ForCurrentProcess()->
247       HasSwitch(switches::kEnableDomDistiller)) {
248     return true;
249   }
250   if (variations::GetVariationParamValue(
251           kFieldTrialName, "enable-dom-distiller") == "1")
252     return true;
253
254   return false;
255 }
256
257 bool IsEnableSyncArticlesSet() {
258   if (CommandLine::ForCurrentProcess()->
259       HasSwitch(switches::kEnableSyncArticles)) {
260     return true;
261   }
262   if (variations::GetVariationParamValue(
263           kFieldTrialName, "enable-sync-articles") == "1")
264     return true;
265
266   return false;
267 }