Home | History | Annotate | Download | only in variations
      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