File: network_change_notifier_delegate_android.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (244 lines) | stat: -rw-r--r-- 10,642 bytes parent folder | download | duplicates (6)
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 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_ANDROID_NETWORK_CHANGE_NOTIFIER_DELEGATE_ANDROID_H_
#define NET_ANDROID_NETWORK_CHANGE_NOTIFIER_DELEGATE_ANDROID_H_

#include <atomic>
#include <map>

#include "base/android/jni_android.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list_threadsafe.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
#include "net/base/net_export.h"
#include "net/base/network_change_notifier.h"
#include "net/base/network_handle.h"

namespace net {

// Delegate used to thread-safely notify NetworkChangeNotifierAndroid whenever a
// network connection change notification is signaled by the Java side (on the
// JNI thread).
// All the methods exposed below must be called exclusively on the JNI thread
// unless otherwise stated (e.g. RegisterObserver()/UnregisterObserver()).
class NET_EXPORT_PRIVATE NetworkChangeNotifierDelegateAndroid {
 public:
  typedef NetworkChangeNotifier::ConnectionCost ConnectionCost;
  typedef NetworkChangeNotifier::ConnectionType ConnectionType;
  typedef NetworkChangeNotifier::ConnectionSubtype ConnectionSubtype;
  typedef NetworkChangeNotifier::NetworkList NetworkList;

  enum class ForceUpdateNetworkState {
    kEnabled,
    kDisabled,
  };
  // Observer interface implemented by NetworkChangeNotifierAndroid which
  // subscribes to network change notifications fired by the delegate (and
  // initiated by the Java side).
  class Observer : public NetworkChangeNotifier::NetworkObserver {
   public:
    ~Observer() override = default;

    // Updates the current connection type.
    virtual void OnConnectionTypeChanged() = 0;

    // Updates the current connection cost.
    virtual void OnConnectionCostChanged() = 0;

    // Updates the current max bandwidth.
    virtual void OnMaxBandwidthChanged(double max_bandwidth_mbps,
                                       ConnectionType connection_type) = 0;

    // Notifies that the default network has gone into a high power mode.
    virtual void OnDefaultNetworkActive() = 0;
  };

  // Initializes native (C++) side of NetworkChangeNotifierAndroid that
  // communicates with Java NetworkChangeNotifier class. The Java
  // NetworkChangeNotifier must have been previously initialized with calls
  // like this:
  //   // Creates global singleton Java NetworkChangeNotifier class instance.
  //   NetworkChangeNotifier.init();
  //   // Creates Java NetworkChangeNotifierAutoDetect class instance.
  //   NetworkChangeNotifier.registerToReceiveNotificationsAlways();
  NetworkChangeNotifierDelegateAndroid();
  explicit NetworkChangeNotifierDelegateAndroid(
      net::NetworkChangeNotifierDelegateAndroid::ForceUpdateNetworkState
          force_update_network_state);
  NetworkChangeNotifierDelegateAndroid(
      const NetworkChangeNotifierDelegateAndroid&) = delete;
  NetworkChangeNotifierDelegateAndroid& operator=(
      const NetworkChangeNotifierDelegateAndroid&) = delete;
  ~NetworkChangeNotifierDelegateAndroid();

  // Called from NetworkChangeNotifier.java on the JNI thread whenever
  // the connection type changes. This updates the current connection type seen
  // by this class and forwards the notification to the observers that
  // subscribed through RegisterObserver().
  void NotifyConnectionTypeChanged(
      JNIEnv* env,
      const base::android::JavaParamRef<jobject>& obj,
      jint new_connection_type,
      jlong default_netid);
  jint GetConnectionType(JNIEnv* env, jobject obj) const;

  // Called from NetworkChangeNotifier.java on the JNI thread whenever
  // the connection cost changes. This updates the current connection cost seen
  // by this class and forwards the notification to the observers that
  // subscribed through RegisterObserver().
  void NotifyConnectionCostChanged(
      JNIEnv* env,
      const base::android::JavaParamRef<jobject>& obj,
      jint new_connection_cost);
  jint GetConnectionCost(JNIEnv* env, jobject obj);

  // Called from NetworkChangeNotifier.java on the JNI thread whenever
  // the connection subtype changes. This updates the current
  // max bandwidth and connection subtype seen by this class and forwards the
  // max bandwidth change to the observers that subscribed through
  // RegisterObserver().
  void NotifyConnectionSubtypeChanged(
      JNIEnv* env,
      const base::android::JavaParamRef<jobject>& obj,
      jint subtype);

  // Called from NetworkChangeNotifier.java on the JNI thread to push
  // down notifications of network connectivity events. These functions in
  // turn:
  //   1) Update |network_map_| and |default_network_|.
  //   2) Push notifications to NetworkChangeNotifier which in turn pushes
  //      notifications to its NetworkObservers. Note that these functions
  //      perform valuable transformations on the signals like deduplicating.
  // For descriptions of what individual calls mean, see
  // NetworkChangeNotifierAutoDetect.Observer functions of the same names.
  void NotifyOfNetworkConnect(JNIEnv* env,
                              const base::android::JavaParamRef<jobject>& obj,
                              jlong net_id,
                              jint connection_type);
  void NotifyOfNetworkSoonToDisconnect(
      JNIEnv* env,
      const base::android::JavaParamRef<jobject>& obj,
      jlong net_id);
  void NotifyOfNetworkDisconnect(
      JNIEnv* env,
      const base::android::JavaParamRef<jobject>& obj,
      jlong net_id);
  void NotifyPurgeActiveNetworkList(
      JNIEnv* env,
      const base::android::JavaParamRef<jobject>& obj,
      const base::android::JavaParamRef<jlongArray>& active_networks);

  // Called from NetworkActiveNotifier.java on the JNI thread to push down
  // notifications of default network going in to high power mode.
  void NotifyOfDefaultNetworkActive(JNIEnv* env);

  // Registers/unregisters the observer which receives notifications from this
  // delegate. Notifications may be dispatched to the observer from any thread.
  // |observer| must not invoke (Register|Unregister)Observer() when receiving a
  // notification, because it would cause a reentrant lock acquisition.
  // |observer| must unregister itself before
  // ~NetworkChangeNotifierDelegateAndroid().
  void RegisterObserver(Observer* observer);
  void UnregisterObserver(Observer* observer);

  // Called by NetworkChangeNotifierAndroid to report when a
  // DefaultNetworkActiveObserver has been added (or removed) so that the
  // delegate can act on that (possibly enabling or disabling default network
  // active notifications).
  void DefaultNetworkActiveObserverRemoved();
  void DefaultNetworkActiveObserverAdded();

  // These methods are simply implementations of NetworkChangeNotifier APIs of
  // the same name. They can be called from any thread.
  ConnectionCost GetCurrentConnectionCost();
  ConnectionType GetCurrentConnectionType() const;
  void GetCurrentMaxBandwidthAndConnectionType(
      double* max_bandwidth_mbps,
      ConnectionType* connection_type) const;
  ConnectionType GetNetworkConnectionType(handles::NetworkHandle network) const;
  handles::NetworkHandle GetCurrentDefaultNetwork() const;
  void GetCurrentlyConnectedNetworks(NetworkList* network_list) const;
  bool IsDefaultNetworkActive();

  // Can be called from any thread if kStoreConnectionSubtype is enabled,
  // otherwise should be only called from main thread.
  NetworkChangeNotifier::ConnectionSubtype GetCurrentConnectionSubtype() const;

  // Returns true if NetworkCallback failed to register, indicating that
  // network-specific callbacks will not be issued.
  bool RegisterNetworkCallbackFailed() const {
    return register_network_callback_failed_;
  }

  static void EnableNetworkChangeNotifierAutoDetectForTest();

 private:
  friend class BaseNetworkChangeNotifierAndroidTest;

  // Map of active connected networks and their connection type.
  typedef std::map<handles::NetworkHandle, ConnectionType> NetworkMap;

  // Converts a Java long[] into a NetworkMap. Expects long[] to contain
  // repeated instances of: handles::NetworkHandle, ConnectionType
  static void JavaLongArrayToNetworkMap(
      JNIEnv* env,
      const base::android::JavaRef<jlongArray>& long_array,
      NetworkMap* network_map);

  // These can be selectively enabled/disabled as they might be expensive to
  // listen to since they could be fired often.
  void EnableDefaultNetworkActiveNotifications();
  void DisableDefaultNetworkActiveNotifications();

  // Setters that grab appropriate lock.
  void SetCurrentConnectionCost(ConnectionCost connection_cost);
  void SetCurrentConnectionType(ConnectionType connection_type);
  void SetCurrentConnectionSubtype(ConnectionSubtype connection_subtype);
  void SetCurrentMaxBandwidth(double max_bandwidth);
  void SetCurrentDefaultNetwork(handles::NetworkHandle default_network);
  void SetCurrentNetworksAndTypes(NetworkMap network_map);

  // Methods calling the Java side exposed for testing.
  void SetOnline();
  void SetOffline();
  void FakeNetworkConnected(handles::NetworkHandle network,
                            ConnectionType type);
  void FakeNetworkSoonToBeDisconnected(handles::NetworkHandle network);
  void FakeNetworkDisconnected(handles::NetworkHandle network);
  void FakePurgeActiveNetworkList(NetworkList networks);
  void FakeDefaultNetwork(handles::NetworkHandle network, ConnectionType type);
  void FakeConnectionCostChanged(ConnectionCost cost);
  void FakeConnectionSubtypeChanged(ConnectionSubtype subtype);
  void FakeDefaultNetworkActive();

  THREAD_CHECKER(thread_checker_);

  base::Lock observer_lock_;
  raw_ptr<Observer> observer_ GUARDED_BY(observer_lock_) = nullptr;

  const base::android::ScopedJavaGlobalRef<jobject>
      java_network_change_notifier_;
  // True if NetworkCallback failed to register, indicating that
  // network-specific callbacks will not be issued.
  const bool register_network_callback_failed_;
  base::android::ScopedJavaGlobalRef<jobject> java_network_active_notifier_;

  mutable base::Lock connection_lock_;  // Protects the state below.
  ConnectionType connection_type_;
  ConnectionSubtype connection_subtype_;
  ConnectionCost connection_cost_;
  double connection_max_bandwidth_;
  handles::NetworkHandle default_network_;
  NetworkMap network_map_;

  // Used to enable/disable default network active notifications on the Java
  // side.
  std::atomic_int default_network_active_observers_ = 0;
};

}  // namespace net

#endif  // NET_ANDROID_NETWORK_CHANGE_NOTIFIER_DELEGATE_ANDROID_H_