Home | History | Annotate | Download | only in bookmarks
      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.
     25 std::string GetEnhancedBookmarksExtensionIdFromFinch() {
     26   return chrome_variations::GetVariationParamValue(kFieldTrialName, "id");
     27 }
     28 
     29 // Returns true if enhanced bookmarks experiment is enabled from Finch.
     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 
     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 
     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 
    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 
    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)
    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 
    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 
    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