summaryrefslogtreecommitdiff
path: root/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
blob: b329f5f1cb3e4fabc5330d3e375f550c299ca01b (plain)
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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
// Copyright 2014 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 COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_SETTINGS_H_
#define COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_SETTINGS_H_

#include <stdint.h>

#include <memory>
#include <string>

#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/threading/thread_checker.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service_observer.h"
#include "components/prefs/pref_member.h"
#include "url/gurl.h"

class PrefService;

namespace base {
class Clock;
}

namespace data_reduction_proxy {

class DataReductionProxyConfig;
class DataReductionProxyEventStore;
class DataReductionProxyIOData;
class DataReductionProxyService;
class DataReductionProxyCompressionStats;

// The header used to request a data reduction proxy pass through. When a
// request is sent to the data reduction proxy with this header, it will respond
// with the original uncompressed response.
extern const char kDataReductionPassThroughHeader[];

// Values of the UMA DataReductionProxy.StartupState histogram.
// This enum must remain synchronized with DataReductionProxyStartupState
// in metrics/histograms/histograms.xml.
enum ProxyStartupState {
  PROXY_NOT_AVAILABLE = 0,
  PROXY_DISABLED,
  PROXY_ENABLED,
  PROXY_STARTUP_STATE_COUNT,
};

// Values of the UMA DataReductionProxy.LoFi.ImplicitOptOutAction histogram.
// This enum must remain synchronized with
// DataReductionProxyLoFiImplicitOptOutAction in
// metrics/histograms/histograms.xml.
enum LoFiImplicitOptOutAction {
  LO_FI_OPT_OUT_ACTION_DISABLED_FOR_SESSION = 0,
  LO_FI_OPT_OUT_ACTION_DISABLED_UNTIL_NEXT_EPOCH,
  LO_FI_OPT_OUT_ACTION_NEXT_EPOCH,
  LO_FI_OPT_OUT_ACTION_INDEX_BOUNDARY,
};

// Values of the UMA DataReductionProxy.EnabledState histogram.
// This enum must remain synchronized with DataReductionProxyEnabledState
// in metrics/histograms/histograms.xml.
enum DataReductionSettingsEnabledAction {
  DATA_REDUCTION_SETTINGS_ACTION_OFF_TO_ON = 0,
  DATA_REDUCTION_SETTINGS_ACTION_ON_TO_OFF,
  DATA_REDUCTION_SETTINGS_ACTION_BOUNDARY,
};

// Central point for configuring the data reduction proxy.
// This object lives on the UI thread and all of its methods are expected to
// be called from there.
class DataReductionProxySettings : public DataReductionProxyServiceObserver {
 public:
  using SyntheticFieldTrialRegistrationCallback =
      base::Callback<bool(base::StringPiece, base::StringPiece)>;

  DataReductionProxySettings();
  virtual ~DataReductionProxySettings();

  // Initializes the Data Reduction Proxy with the name of the preference that
  // controls enabling it, profile prefs and a |DataReductionProxyIOData|. The
  // caller must ensure that all parameters remain alive for the lifetime of
  // the |DataReductionProxySettings| instance.
  void InitDataReductionProxySettings(
      const std::string& data_reduction_proxy_enabled_pref_name,
      PrefService* prefs,
      DataReductionProxyIOData* io_data,
      std::unique_ptr<DataReductionProxyService> data_reduction_proxy_service);

  // Sets the |register_synthetic_field_trial_| callback and runs to register
  // the DataReductionProxyEnabled and the DataReductionProxyLoFiEnabled
  // synthetic field trial.
  void SetCallbackToRegisterSyntheticFieldTrial(
      const SyntheticFieldTrialRegistrationCallback&
          on_data_reduction_proxy_enabled);

  // Returns true if the proxy is enabled.
  bool IsDataReductionProxyEnabled() const;

  // Returns true if the proxy can be used for the given url. This method does
  // not take into account the proxy config or proxy retry list, so it can
  // return true even when the proxy will not be used. Specifically, if
  // another proxy configuration overrides use of data reduction proxy, or
  // if data reduction proxy is in proxy retry list, then data reduction proxy
  // will not be used, but this method will still return true. If this method
  // returns false, then we are guaranteed that data reduction proxy will not be
  // used.
  bool CanUseDataReductionProxy(const GURL& url) const;

  // Returns true if the proxy is managed by an adminstrator's policy.
  bool IsDataReductionProxyManaged();

  // Enables or disables the data reduction proxy.
  void SetDataReductionProxyEnabled(bool enabled);

  // Sets |lo_fi_mode_active_| to true if Lo-Fi is currently active, meaning
  // requests are being sent with "q=low" headers. Set from the IO thread only
  // on main frame requests.
  void SetLoFiModeActiveOnMainFrame(bool lo_fi_mode_active);

  // Increments the number of times the Lo-Fi UI has been shown.
  void IncrementLoFiUIShown();

  // Counts the number of requests to reload the page with images from the Lo-Fi
  // UI. If the user requests the page with images a certain number of times,
  // then Lo-Fi is disabled for the remainder of the session.
  void IncrementLoFiUserRequestsForImages();

  // Records UMA for Lo-Fi implicit opt out actions.
  void RecordLoFiImplicitOptOutAction(
      data_reduction_proxy::LoFiImplicitOptOutAction action) const;

  // Returns the time in microseconds that the last update was made to the
  // daily original and received content lengths.
  int64_t GetDataReductionLastUpdateTime();

  // Clears all data saving statistics.
  void ClearDataSavingStatistics();

  // Returns the difference between the total original size of all HTTP content
  // received from the network and the actual size of the HTTP content received.
  int64_t GetTotalHttpContentLengthSaved();

  // Returns aggregate received and original content lengths over the specified
  // number of days, as well as the time these stats were last updated.
  void GetContentLengths(unsigned int days,
                         int64_t* original_content_length,
                         int64_t* received_content_length,
                         int64_t* last_update_time);

  // Records that the data reduction proxy is unreachable or not.
  void SetUnreachable(bool unreachable);

  // Returns whether the data reduction proxy is unreachable. Returns true
  // if no request has successfully completed through proxy, even though atleast
  // some of them should have.
  bool IsDataReductionProxyUnreachable();

  ContentLengthList GetDailyContentLengths(const char* pref_name);

  // Configures data reduction proxy. |at_startup| is true when this method is
  // called in response to creating or loading a new profile.
  void MaybeActivateDataReductionProxy(bool at_startup);

  // Returns the event store being used. May be null if
  // InitDataReductionProxySettings has not been called.
  DataReductionProxyEventStore* GetEventStore() const;

  // Returns true if the data reduction proxy promo may be shown.
  // This is independent of whether the data reduction proxy is allowed.
  bool PromoAllowed() const {
    return promo_allowed_;
  }

  DataReductionProxyService* data_reduction_proxy_service() {
    return data_reduction_proxy_service_.get();
  }

  // Returns the |DataReductionProxyConfig| being used. May be null if
  // InitDataReductionProxySettings has not been called.
  DataReductionProxyConfig* Config() const {
    return config_;
  }

  // Permits changing the underlying |DataReductionProxyConfig| without running
  // the initialization loop.
  void ResetConfigForTest(DataReductionProxyConfig* config) {
    config_ = config;
  }

 protected:
  void InitPrefMembers();

  void UpdateConfigValues();

  // Virtualized for unit test support.
  virtual PrefService* GetOriginalProfilePrefs();

  // Metrics method. Subclasses should override if they wish to provide
  // alternatives.
  virtual void RecordDataReductionInit() const;

  // Virtualized for mocking. Records UMA specifying whether the proxy was
  // enabled or disabled at startup.
  virtual void RecordStartupState(
      data_reduction_proxy::ProxyStartupState state) const;

 private:
  friend class DataReductionProxySettingsTestBase;
  friend class DataReductionProxySettingsTest;
  friend class DataReductionProxyTestContext;
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestResetDataReductionStatistics);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestIsProxyEnabledOrManaged);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestCanUseDataReductionProxy);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest, TestContentLengths);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestGetDailyContentLengths);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestMaybeActivateDataReductionProxy);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestOnProxyEnabledPrefChange);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestInitDataReductionProxyOn);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestInitDataReductionProxyOff);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           CheckInitMetricsWhenNotAllowed);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestLoFiImplicitOptOutClicksPerSession);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestLoFiImplicitOptOutConsecutiveSessions);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestLoFiImplicitOptOutHistograms);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestLoFiSessionStateHistograms);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestSettingsEnabledStateHistograms);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestDaysSinceEnabled);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestDaysSinceEnabledWithTestClock);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestDaysSinceEnabledExistingUser);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestDaysSinceSavingsCleared);

  // Override of DataReductionProxyService::Observer.
  void OnServiceInitialized() override;

  // Registers the trial "SyntheticDataReductionProxySetting" with the group
  // "Enabled" or "Disabled". Indicates whether the proxy is turned on or not.
  void RegisterDataReductionProxyFieldTrial();

  void OnProxyEnabledPrefChange();

  void ResetDataReductionStatistics();

  // Update IO thread objects in response to UI thread changes.
  void UpdateIOData(bool at_startup);

  // For tests.
  void set_data_reduction_proxy_enabled_pref_name_for_test(
      const std::string& data_reduction_proxy_enabled_pref_name) {
    data_reduction_proxy_enabled_pref_name_ =
        data_reduction_proxy_enabled_pref_name;
  }

  bool unreachable_;

  // A call to MaybeActivateDataReductionProxy may take place before the
  // |data_reduction_proxy_service_| has received a DataReductionProxyIOData
  // pointer. In that case, the operation against the IO objects will not
  // succeed and |deferred_initialization_| will be set to true. When
  // OnServiceInitialized is called, if |deferred_initialization_| is true,
  // IO object calls will be performed at that time.
  bool deferred_initialization_;

  // The following values are cached in order to access the values on the
  // correct thread.
  bool allowed_;
  bool promo_allowed_;

  // The number of requests to reload the page with images from the Lo-Fi
  // UI until Lo-Fi is disabled for the remainder of the session.
  int lo_fi_user_requests_for_images_per_session_;

  // The number of consecutive sessions where Lo-Fi was disabled for
  // Lo-Fi to be disabled until the next implicit opt out epoch, which may be in
  // a later session, or never.
  int lo_fi_consecutive_session_disables_;

  BooleanPrefMember spdy_proxy_auth_enabled_;

  std::unique_ptr<DataReductionProxyService> data_reduction_proxy_service_;

  // The name of the preference that controls enabling and disabling the Data
  // Reduction Proxy.
  std::string data_reduction_proxy_enabled_pref_name_;

  PrefService* prefs_;

  // The caller must ensure that the |config_| outlives this instance.
  DataReductionProxyConfig* config_;

  SyntheticFieldTrialRegistrationCallback register_synthetic_field_trial_;

  // Should not be null.
  std::unique_ptr<base::Clock> clock_;

  base::ThreadChecker thread_checker_;

  DISALLOW_COPY_AND_ASSIGN(DataReductionProxySettings);
};

}  // namespace data_reduction_proxy

#endif  // COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_SETTINGS_H_