1 // Copyright (c) 2012 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 #ifndef CHROME_BROWSER_METRICS_VARIATIONS_VARIATIONS_SERVICE_H_ 6 #define CHROME_BROWSER_METRICS_VARIATIONS_VARIATIONS_SERVICE_H_ 7 8 #include <string> 9 10 #include "base/compiler_specific.h" 11 #include "base/gtest_prod_util.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/metrics/field_trial.h" 14 #include "base/time/time.h" 15 #include "chrome/browser/metrics/proto/study.pb.h" 16 #include "chrome/browser/metrics/proto/trials_seed.pb.h" 17 #include "chrome/browser/metrics/variations/variations_request_scheduler.h" 18 #include "chrome/browser/web_resource/resource_request_allowed_notifier.h" 19 #include "chrome/common/chrome_version_info.h" 20 #include "net/url_request/url_fetcher_delegate.h" 21 #include "url/gurl.h" 22 23 #if defined(OS_WIN) 24 #include "chrome/browser/metrics/variations/variations_registry_syncer_win.h" 25 #endif 26 27 class PrefService; 28 class PrefRegistrySimple; 29 30 namespace chrome_variations { 31 32 // Used to setup field trials based on stored variations seed data, and fetch 33 // new seed data from the variations server. 34 class VariationsService 35 : public net::URLFetcherDelegate, 36 public ResourceRequestAllowedNotifier::Observer { 37 public: 38 virtual ~VariationsService(); 39 40 // Creates field trials based on Variations Seed loaded from local prefs. If 41 // there is a problem loading the seed data, all trials specified by the seed 42 // may not be created. 43 bool CreateTrialsFromSeed(); 44 45 // Calls FetchVariationsSeed once and repeats this periodically. See 46 // implementation for details on the period. Must be called after 47 // |CreateTrialsFromSeed|. 48 void StartRepeatedVariationsSeedFetch(); 49 50 // Returns the variations server URL, which can vary if a command-line flag is 51 // set and/or the variations restrict pref is set in |local_prefs|. Declared 52 // static for test purposes. 53 static GURL GetVariationsServerURL(PrefService* local_prefs); 54 55 #if defined(OS_WIN) 56 // Starts syncing Google Update Variation IDs with the registry. 57 void StartGoogleUpdateRegistrySync(); 58 #endif 59 60 // Exposed for testing. 61 void SetCreateTrialsFromSeedCalledForTesting(bool called); 62 63 // Exposed for testing. 64 static std::string GetDefaultVariationsServerURLForTesting(); 65 66 // Register Variations related prefs in Local State. 67 static void RegisterPrefs(PrefRegistrySimple* registry); 68 69 // Factory method for creating a VariationsService. 70 static VariationsService* Create(PrefService* local_state); 71 72 protected: 73 // Starts the fetching process once, where |OnURLFetchComplete| is called with 74 // the response. 75 virtual void DoActualFetch(); 76 77 // This constructor exists for injecting a mock notifier. It is meant for 78 // testing only. This instance will take ownership of |notifier|. 79 VariationsService(ResourceRequestAllowedNotifier* notifier, 80 PrefService* local_state); 81 82 private: 83 FRIEND_TEST_ALL_PREFIXES(VariationsServiceTest, DoNotFetchIfOffline); 84 FRIEND_TEST_ALL_PREFIXES(VariationsServiceTest, DoNotFetchIfOnlineToOnline); 85 FRIEND_TEST_ALL_PREFIXES(VariationsServiceTest, FetchOnReconnect); 86 FRIEND_TEST_ALL_PREFIXES(VariationsServiceTest, LoadSeed); 87 FRIEND_TEST_ALL_PREFIXES(VariationsServiceTest, StoreSeed); 88 FRIEND_TEST_ALL_PREFIXES(VariationsServiceTest, SeedStoredWhenOKStatus); 89 FRIEND_TEST_ALL_PREFIXES(VariationsServiceTest, SeedNotStoredWhenNonOKStatus); 90 91 // Creates the VariationsService with the given |local_state| prefs service. 92 // Use the |Create| factory method to create a VariationsService. 93 explicit VariationsService(PrefService* local_state); 94 95 // Checks if prerequisites for fetching the Variations seed are met, and if 96 // so, performs the actual fetch using |DoActualFetch|. 97 void FetchVariationsSeed(); 98 99 // net::URLFetcherDelegate implementation: 100 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 101 102 // ResourceRequestAllowedNotifier::Observer implementation: 103 virtual void OnResourceRequestsAllowed() OVERRIDE; 104 105 // Store the given seed data to the given local prefs. Note that |seed_data| 106 // is assumed to be the raw serialized protobuf data stored in a string. It 107 // will be Base64Encoded for storage. If the string is invalid or the encoding 108 // fails, the existing prefs are left as is and the function returns false. 109 bool StoreSeedData(const std::string& seed_data, const base::Time& seed_date); 110 111 // Loads the Variations seed data from local state into |seed|. If there is a 112 // problem with loading, the pref value is cleared and false is returned. If 113 // successful, |seed| will contain the loaded data and true is returned. 114 bool LoadTrialsSeedFromPref(TrialsSeed* seed); 115 116 // Record the time of the most recent successful fetch. 117 void RecordLastFetchTime(); 118 119 // The pref service used to store persist the variations seed. 120 PrefService* local_state_; 121 122 // Contains the scheduler instance that handles timing for requests to the 123 // server. Initially NULL and instantiated when the initial fetch is 124 // requested. 125 scoped_ptr<VariationsRequestScheduler> request_scheduler_; 126 127 // Contains the current seed request. Will only have a value while a request 128 // is pending, and will be reset by |OnURLFetchComplete|. 129 scoped_ptr<net::URLFetcher> pending_seed_request_; 130 131 // The URL to use for querying the Variations server. 132 GURL variations_server_url_; 133 134 // Cached serial number from the most recently fetched Variations seed. 135 std::string variations_serial_number_; 136 137 // Tracks whether |CreateTrialsFromSeed| has been called, to ensure that 138 // it gets called prior to |StartRepeatedVariationsSeedFetch|. 139 bool create_trials_from_seed_called_; 140 141 // Tracks whether the initial request to the variations server had completed. 142 bool initial_request_completed_; 143 144 // Helper class used to tell this service if it's allowed to make network 145 // resource requests. 146 scoped_ptr<ResourceRequestAllowedNotifier> resource_request_allowed_notifier_; 147 148 // The start time of the last seed request. This is used to measure the 149 // latency of seed requests. Initially zero. 150 base::TimeTicks last_request_started_time_; 151 152 #if defined(OS_WIN) 153 // Helper that handles synchronizing Variations with the Registry. 154 VariationsRegistrySyncer registry_syncer_; 155 #endif 156 157 DISALLOW_COPY_AND_ASSIGN(VariationsService); 158 }; 159 160 } // namespace chrome_variations 161 162 #endif // CHROME_BROWSER_METRICS_VARIATIONS_VARIATIONS_SERVICE_H_ 163