1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_METRICS_VARIATIONS_VARIATIONS_SERVICE_H_
#define CHROME_BROWSER_METRICS_VARIATIONS_VARIATIONS_SERVICE_H_
#include <string>
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "chrome/browser/metrics/variations/variations_request_scheduler.h"
#include "chrome/browser/metrics/variations/variations_seed_store.h"
#include "chrome/browser/web_resource/resource_request_allowed_notifier.h"
#include "chrome/common/chrome_version_info.h"
#include "components/variations/variations_seed_simulator.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "url/gurl.h"
#if defined(OS_WIN)
#include "chrome/browser/metrics/variations/variations_registry_syncer_win.h"
#endif
class PrefService;
class PrefRegistrySimple;
namespace base {
class Version;
}
namespace metrics {
class MetricsStateManager;
}
namespace user_prefs {
class PrefRegistrySyncable;
}
namespace variations {
class VariationsSeed;
}
namespace chrome_variations {
// Used to setup field trials based on stored variations seed data, and fetch
// new seed data from the variations server.
class VariationsService
: public net::URLFetcherDelegate,
public ResourceRequestAllowedNotifier::Observer {
public:
class Observer {
public:
// How critical a detected experiment change is. Whether it should be
// handled on a "best-effort" basis or, for a more critical change, if it
// should be given higher priority.
enum Severity {
BEST_EFFORT,
CRITICAL,
};
// Called when the VariationsService detects that there will be significant
// experiment changes on a restart. This notification can then be used to
// update UI (i.e. badging an icon).
virtual void OnExperimentChangesDetected(Severity severity) = 0;
protected:
virtual ~Observer() {}
};
~VariationsService() override;
// Creates field trials based on Variations Seed loaded from local prefs. If
// there is a problem loading the seed data, all trials specified by the seed
// may not be created.
bool CreateTrialsFromSeed();
// Calls FetchVariationsSeed once and repeats this periodically. See
// implementation for details on the period. Must be called after
// |CreateTrialsFromSeed|.
void StartRepeatedVariationsSeedFetch();
// Adds an observer to listen for detected experiment changes.
void AddObserver(Observer* observer);
// Removes a previously-added observer.
void RemoveObserver(Observer* observer);
// Called when the application enters foreground. This may trigger a
// FetchVariationsSeed call.
// TODO(rkaplow): Handle this and the similar event in metrics_service by
// observing an 'OnAppEnterForeground' event instead of requiring the frontend
// code to notify each service individually.
void OnAppEnterForeground();
#if defined(OS_WIN)
// Starts syncing Google Update Variation IDs with the registry.
void StartGoogleUpdateRegistrySync();
#endif
// Exposed for testing.
void SetCreateTrialsFromSeedCalledForTesting(bool called);
// Returns the variations server URL, which can vary if a command-line flag is
// set and/or the variations restrict pref is set in |local_prefs|. Declared
// static for test purposes.
static GURL GetVariationsServerURL(PrefService* local_prefs);
// Exposed for testing.
static std::string GetDefaultVariationsServerURLForTesting();
// Register Variations related prefs in Local State.
static void RegisterPrefs(PrefRegistrySimple* registry);
// Register Variations related prefs in the Profile prefs.
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
// Factory method for creating a VariationsService. Does not take ownership of
// |state_manager|. Caller should ensure that |state_manager| is valid for the
// lifetime of this class.
static scoped_ptr<VariationsService> Create(
PrefService* local_state,
metrics::MetricsStateManager* state_manager);
// Set the PrefService responsible for getting policy-related preferences,
// such as the restrict parameter.
void set_policy_pref_service(PrefService* service) {
DCHECK(service);
policy_pref_service_ = service;
}
// Returns the invalid variations seed signature in base64 format, or an empty
// string if the signature was valid, missing, or if signature verification is
// disabled.
std::string GetInvalidVariationsSeedSignature() const;
protected:
// Starts the fetching process once, where |OnURLFetchComplete| is called with
// the response.
virtual void DoActualFetch();
// Stores the seed to prefs. Set as virtual and protected so that it can be
// overridden by tests.
virtual void StoreSeed(const std::string& seed_data,
const std::string& seed_signature,
const base::Time& date_fetched);
// Creates the VariationsService with the given |local_state| prefs service
// and |state_manager|. This instance will take ownership of |notifier|.
// Does not take ownership of |state_manager|. Caller should ensure that
// |state_manager| is valid for the lifetime of this class. Use the |Create|
// factory method to create a VariationsService.
VariationsService(ResourceRequestAllowedNotifier* notifier,
PrefService* local_state,
metrics::MetricsStateManager* state_manager);
private:
FRIEND_TEST_ALL_PREFIXES(VariationsServiceTest, Observer);
FRIEND_TEST_ALL_PREFIXES(VariationsServiceTest, SeedStoredWhenOKStatus);
FRIEND_TEST_ALL_PREFIXES(VariationsServiceTest, SeedNotStoredWhenNonOKStatus);
FRIEND_TEST_ALL_PREFIXES(VariationsServiceTest, SeedDateUpdatedOn304Status);
// Checks if prerequisites for fetching the Variations seed are met, and if
// so, performs the actual fetch using |DoActualFetch|.
void FetchVariationsSeed();
// Notify any observers of this service based on the simulation |result|.
void NotifyObservers(
const variations::VariationsSeedSimulator::Result& result);
// net::URLFetcherDelegate implementation:
void OnURLFetchComplete(const net::URLFetcher* source) override;
// ResourceRequestAllowedNotifier::Observer implementation:
void OnResourceRequestsAllowed() override;
// Performs a variations seed simulation with the given |seed| and |version|
// and logs the simulation results as histograms.
void PerformSimulationWithVersion(scoped_ptr<variations::VariationsSeed> seed,
const base::Version& version);
// Record the time of the most recent successful fetch.
void RecordLastFetchTime();
// The pref service used to store persist the variations seed.
PrefService* local_state_;
// Used for instantiating entropy providers for variations seed simulation.
// Weak pointer.
metrics::MetricsStateManager* state_manager_;
// Used to obtain policy-related preferences. Depending on the platform, will
// either be Local State or Profile prefs.
PrefService* policy_pref_service_;
VariationsSeedStore seed_store_;
// Contains the scheduler instance that handles timing for requests to the
// server. Initially NULL and instantiated when the initial fetch is
// requested.
scoped_ptr<VariationsRequestScheduler> request_scheduler_;
// Contains the current seed request. Will only have a value while a request
// is pending, and will be reset by |OnURLFetchComplete|.
scoped_ptr<net::URLFetcher> pending_seed_request_;
// The URL to use for querying the Variations server.
GURL variations_server_url_;
// Tracks whether |CreateTrialsFromSeed| has been called, to ensure that
// it gets called prior to |StartRepeatedVariationsSeedFetch|.
bool create_trials_from_seed_called_;
// Tracks whether the initial request to the variations server had completed.
bool initial_request_completed_;
// Helper class used to tell this service if it's allowed to make network
// resource requests.
scoped_ptr<ResourceRequestAllowedNotifier> resource_request_allowed_notifier_;
// The start time of the last seed request. This is used to measure the
// latency of seed requests. Initially zero.
base::TimeTicks last_request_started_time_;
// List of observers of the VariationsService.
ObserverList<Observer> observer_list_;
#if defined(OS_WIN)
// Helper that handles synchronizing Variations with the Registry.
VariationsRegistrySyncer registry_syncer_;
#endif
base::WeakPtrFactory<VariationsService> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(VariationsService);
};
} // namespace chrome_variations
#endif // CHROME_BROWSER_METRICS_VARIATIONS_VARIATIONS_SERVICE_H_
|