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