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