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_
|