summaryrefslogtreecommitdiff
path: root/chromium/net/nqe/connectivity_monitor.h
blob: a49445b20bb39d4ac6c0882b689c08b0c94558c5 (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
// Copyright 2020 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.
// Copyright 2020 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 NET_NQE_CONNECTIVITY_MONITOR_H_
#define NET_NQE_CONNECTIVITY_MONITOR_H_

#include <memory>
#include <set>

#include "base/callback.h"
#include "base/cancelable_callback.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "net/base/net_export.h"
#include "net/base/network_change_notifier.h"
#include "net/url_request/url_request.h"

namespace net {

#if defined(OS_ANDROID)
namespace android {
class NetworkActivationRequest;
}
#endif  // defined(OS_ANDROID)

// ConnectivityMonitor is driven by NetworkQualityEstimator and is used to
// monitor progress of active URLRequests. If all active requests fail to make
// progress for a certain time interval, this will log accordingly and may
// report the problem to the operating system as a potential hint to fall back
// onto a more responsive network.
class NET_EXPORT_PRIVATE ConnectivityMonitor
    : public NetworkChangeNotifier::NetworkObserver {
 public:
  // Constructs a new ConnectivityMonitor as below, but with builtin default
  // TimeDelta values.
  explicit ConnectivityMonitor();

  // Constructs a new ConnectivityMonitor which assumes the current network has
  // lost connectivity if it observes no request progress over a duration of at
  // least `inactivity_threshold`. This observation will only occur at most once
  // every `min_observation_interval`.
  ConnectivityMonitor(base::TimeDelta inactivity_threshold,
                      base::TimeDelta min_failure_logging_interval);
  ConnectivityMonitor(const ConnectivityMonitor&) = delete;
  ConnectivityMonitor& operator=(const ConnectivityMonitor&) = delete;
  ~ConnectivityMonitor() override;

  // Registers a new `request` to be tracked by the ConnectivityMonitor. Called
  // just before the request's first header bytes hit the wire.
  void TrackNewRequest(const URLRequest& request);

  // Notifies the ConnectivityMonitor that progress has been made toward
  // `request` completion. This means that some response bytes were received,
  // and for a newly tracked request, the first call to this method signifies
  // receipt of at least the first response header bytes.
  void NotifyRequestProgress(const URLRequest& request);

  // Indicates that `request` has been completed or is about to be destroyed,
  // regardless of success or failure. If `request` was being tracked by this
  // ConnectivityMonitor, it must no longer be tracked after this call.
  void NotifyRequestCompleted(const URLRequest& request);

  // Notifies the monitor of a change in the system's network configuration. As
  // an example, this may be called when an Android device switches its default
  // network from WiFi to mobile data.
  void NotifyConnectionTypeChanged(NetworkChangeNotifier::ConnectionType type);

  size_t num_active_requests_for_testing() const {
    return active_requests_.size();
  }

  // Returns the amount of time since the ConnectivityMonitor first observed the
  // current lapse in connectivity, if any.
  base::Optional<base::TimeDelta> GetTimeSinceLastFailureForTesting();

  // Registers a callback to hook into any time an activity deadline is reached.
  void SetNextDeadlineCallbackForTesting(base::OnceClosure callback);

  // Registers a callback to hook into the code path for OS reporting. Allows
  // tests to effectively observe the OS reporting event.
  void SetReportCallbackForTesting(base::OnceClosure callback);

 private:
  void ScheduleNextActivityDeadline(base::TimeDelta delay);
  void OnActivityDeadlineExceeded();
  void ReportConnectivityFailure();
  void RequestMobileNetworkActivation();

  // NetworkChangeNotifier::NetworkObserver:
  void OnNetworkConnected(
      NetworkChangeNotifier::NetworkHandle network) override;
  void OnNetworkDisconnected(
      NetworkChangeNotifier::NetworkHandle network) override;
  void OnNetworkSoonToDisconnect(
      NetworkChangeNotifier::NetworkHandle network) override;
  void OnNetworkMadeDefault(
      NetworkChangeNotifier::NetworkHandle network) override;

  const base::TimeDelta inactivity_threshold_;
  const base::TimeDelta min_failure_logging_interval_;

  base::OnceClosure next_deadline_callback_for_testing_;
  base::OnceClosure report_callback_for_testing_;

  std::set<const URLRequest*> active_requests_;
  base::CancelableOnceClosure next_activity_deadline_;
  base::Optional<base::TimeTicks> time_last_failure_observed_;

  NetworkChangeNotifier::ConnectionType current_connection_type_;

#if defined(OS_ANDROID)
  std::unique_ptr<android::NetworkActivationRequest> mobile_network_request_;
#endif
};

}  // namespace net

#endif  // NET_NQE_CONNECTIVITY_MONITOR_H_