1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file.
4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#ifndef COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_USAGE_STATS_H_
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_USAGE_STATS_H_
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/callback.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/message_loop/message_loop_proxy.h"
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/prefs/pref_member.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/threading/thread_checker.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/data_reduction_proxy/browser/data_reduction_proxy_params.h"
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/data_reduction_proxy/common/data_reduction_proxy_headers.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/base/host_port_pair.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/base/network_change_notifier.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/url_request/url_request.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace net {
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass HttpResponseHeaders;
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass ProxyConfig;
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class ProxyServer;
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace data_reduction_proxy {
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass DataReductionProxyUsageStats
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : public net::NetworkChangeNotifier::NetworkChangeObserver {
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Records a data reduction proxy bypass event as a "BlockType" if
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // |bypass_all| is true and as a "BypassType" otherwise. Records the event as
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // "Primary" if |is_primary| is true and "Fallback" otherwise.
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  static void RecordDataReductionProxyBypassInfo(
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      bool is_primary,
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      bool bypass_all,
356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      const net::ProxyServer& proxy_server,
366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      DataReductionProxyBypassType bypass_type);
376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // For the given response |headers| that are expected to include the data
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // reduction proxy via header, records response code UMA if the data reduction
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // proxy via header is not present.
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static void DetectAndRecordMissingViaHeaderResponseCode(
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      bool is_primary,
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const net::HttpResponseHeaders* headers);
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // MessageLoopProxy instance is owned by io_thread. |params| outlives
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // this class instance.
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DataReductionProxyUsageStats(
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      DataReductionProxyParams* params,
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const scoped_refptr<base::MessageLoopProxy>& ui_thread_proxy);
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~DataReductionProxyUsageStats();
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Sets the callback to be called on the UI thread when the unavailability
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // status has changed.
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void set_unavailable_callback(
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      const base::Callback<void(bool)>& unavailable_callback) {
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    unavailable_callback_ = unavailable_callback;
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Callback intended to be called from |ChromeNetworkDelegate| when a
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // request completes. This method is used to gather usage stats.
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnUrlRequestCompleted(const net::URLRequest* request, bool started);
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Records the last bypass reason to |bypass_type_| and sets
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // |triggering_request_| to true. A triggering request is the first request to
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // cause the current bypass.
666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void SetBypassType(DataReductionProxyBypassType type);
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Records all the data reduction proxy bytes-related histograms for the
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // completed URLRequest |request|.
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void RecordBytesHistograms(
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      net::URLRequest* request,
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const BooleanPrefMember& data_reduction_proxy_enabled,
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const net::ProxyConfig& data_reduction_proxy_config);
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Called by |ChromeNetworkDelegate| when a proxy is put into the bad proxy
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // list. Used to track when the data reduction proxy falls back.
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnProxyFallback(const net::ProxyServer& bypassed_proxy,
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       int net_error);
796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  friend class DataReductionProxyUsageStatsTest;
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FRIEND_TEST_ALL_PREFIXES(DataReductionProxyUsageStatsTest,
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           RecordMissingViaHeaderBytes);
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  enum BypassedBytesType {
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NOT_BYPASSED = 0,         /* Not bypassed. */
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    SSL,                      /* Bypass due to SSL. */
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LOCAL_BYPASS_RULES,       /* Bypass due to client-side bypass rules. */
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    MANAGED_PROXY_CONFIG,     /* Bypass due to managed config. */
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    AUDIO_VIDEO,              /* Audio/Video bypass. */
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    TRIGGERING_REQUEST,       /* Triggering request bypass. */
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NETWORK_ERROR,            /* Network error. */
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    BYPASSED_BYTES_TYPE_MAX   /* This must always be last.*/
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  };
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Given |data_reduction_proxy_enabled|, a |request|, and the
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |data_reduction_proxy_config| records the number of bypassed bytes for that
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |request| into UMAs based on bypass type. |data_reduction_proxy_enabled|
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // tells us the state of the kDataReductionProxyEnabled preference.
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void RecordBypassedBytesHistograms(
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      net::URLRequest* request,
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const BooleanPrefMember& data_reduction_proxy_enabled,
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const net::ProxyConfig& data_reduction_proxy_config);
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Records UMA of the number of response bytes of responses that are expected
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // to have the data reduction proxy via header, but where the data reduction
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // proxy via header is not present.
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void RecordMissingViaHeaderBytes(net::URLRequest* request);
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // NetworkChangeNotifier::NetworkChangeObserver:
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void OnNetworkChanged(
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      net::NetworkChangeNotifier::ConnectionType type) OVERRIDE;
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Called when request counts change. Resets counts if they exceed thresholds,
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // and calls MaybeNotifyUnavailability otherwise.
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnRequestCountChanged();
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Clears request counts unconditionally.
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void ClearRequestCounts();
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Checks if the availability status of the data reduction proxy has changed,
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // and notifies the UIThread via NotifyUnavailabilityOnUIThread if so. The
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // data reduction proxy is considered unavailable if and only if no requests
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // went through the proxy but some eligible requests were service by other
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // routes.
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void NotifyUnavailabilityIfChanged();
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void NotifyUnavailabilityOnUIThread(bool unavailable);
1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DataReductionProxyParams* data_reduction_proxy_params_;
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The last reason for bypass as determined by
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // MaybeBypassProxyAndPrepareToRetry
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DataReductionProxyBypassType last_bypass_type_;
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // True if the last request triggered the current bypass.
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool triggering_request_;
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const scoped_refptr<base::MessageLoopProxy> ui_thread_proxy_;
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The following 2 fields are used to determine if data reduction proxy is
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // unreachable. We keep a count of requests which should go through
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // data request proxy, as well as those which actually do. The proxy is
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // unreachable if no successful requests are made through it despite a
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // non-zero number of requests being eligible.
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Count of successful requests through the data reduction proxy.
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  unsigned long successful_requests_through_proxy_count_;
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Count of network errors encountered when connecting to a data reduction
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // proxy.
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  unsigned long proxy_net_errors_count_;
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Whether or not the data reduction proxy is unavailable.
1516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  bool unavailable_;
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::ThreadChecker thread_checker_;
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void RecordBypassedBytes(
1566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      DataReductionProxyBypassType bypass_type,
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      BypassedBytesType bypassed_bytes_type,
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      int64 content_length);
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Called when the unavailability status has changed. Runs on the UI thread.
1616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::Callback<void(bool)> unavailable_callback_;
1626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(DataReductionProxyUsageStats);
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace data_reduction_proxy
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif  // COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_USAGE_STATS_H_
169