1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/android/network_change_notifier_delegate_android.h"
6
7 #include "base/android/build_info.h"
8 #include "base/android/jni_array.h"
9 #include "base/check.h"
10 #include "base/notreached.h"
11 #include "net/android/network_change_notifier_android.h"
12 #include "net/net_jni_headers/NetworkActiveNotifier_jni.h"
13 #include "net/net_jni_headers/NetworkChangeNotifier_jni.h"
14
15 using base::android::JavaParamRef;
16 using base::android::JavaRef;
17 using base::android::ScopedJavaLocalRef;
18
19 namespace net {
20
21 namespace {
22
23 // Converts a Java side connection type (integer) to
24 // the native side NetworkChangeNotifier::ConnectionType.
ConvertConnectionType(jint connection_type)25 NetworkChangeNotifier::ConnectionType ConvertConnectionType(
26 jint connection_type) {
27 switch (connection_type) {
28 case NetworkChangeNotifier::CONNECTION_UNKNOWN:
29 case NetworkChangeNotifier::CONNECTION_ETHERNET:
30 case NetworkChangeNotifier::CONNECTION_WIFI:
31 case NetworkChangeNotifier::CONNECTION_2G:
32 case NetworkChangeNotifier::CONNECTION_3G:
33 case NetworkChangeNotifier::CONNECTION_4G:
34 case NetworkChangeNotifier::CONNECTION_5G:
35 case NetworkChangeNotifier::CONNECTION_NONE:
36 case NetworkChangeNotifier::CONNECTION_BLUETOOTH:
37 break;
38 default:
39 NOTREACHED() << "Unknown connection type received: " << connection_type;
40 return NetworkChangeNotifier::CONNECTION_UNKNOWN;
41 }
42 return static_cast<NetworkChangeNotifier::ConnectionType>(connection_type);
43 }
44
45 // Converts a Java side connection cost (integer) to
46 // the native side NetworkChangeNotifier::ConnectionCost.
ConvertConnectionCost(jint connection_cost)47 NetworkChangeNotifier::ConnectionCost ConvertConnectionCost(
48 jint connection_cost) {
49 switch (connection_cost) {
50 case NetworkChangeNotifier::CONNECTION_COST_UNKNOWN:
51 case NetworkChangeNotifier::CONNECTION_COST_UNMETERED:
52 case NetworkChangeNotifier::CONNECTION_COST_METERED:
53 break;
54 default:
55 NOTREACHED() << "Unknown connection cost received: " << connection_cost;
56 return NetworkChangeNotifier::CONNECTION_COST_UNKNOWN;
57 }
58 return static_cast<NetworkChangeNotifier::ConnectionCost>(connection_cost);
59 }
60
61 // Converts a Java side connection type (integer) to
62 // the native side NetworkChangeNotifier::ConnectionType.
ConvertConnectionSubtype(jint subtype)63 NetworkChangeNotifier::ConnectionSubtype ConvertConnectionSubtype(
64 jint subtype) {
65 DCHECK(subtype >= 0 && subtype <= NetworkChangeNotifier::SUBTYPE_LAST);
66
67 return static_cast<NetworkChangeNotifier::ConnectionSubtype>(subtype);
68 }
69
70 } // namespace
71
72 // static
JavaLongArrayToNetworkMap(JNIEnv * env,const JavaRef<jlongArray> & long_array,NetworkMap * network_map)73 void NetworkChangeNotifierDelegateAndroid::JavaLongArrayToNetworkMap(
74 JNIEnv* env,
75 const JavaRef<jlongArray>& long_array,
76 NetworkMap* network_map) {
77 std::vector<int64_t> int64_list;
78 base::android::JavaLongArrayToInt64Vector(env, long_array, &int64_list);
79 network_map->clear();
80 for (auto i = int64_list.begin(); i != int64_list.end(); ++i) {
81 handles::NetworkHandle network_handle = *i;
82 CHECK(++i != int64_list.end());
83 (*network_map)[network_handle] = static_cast<ConnectionType>(*i);
84 }
85 }
86
NetworkChangeNotifierDelegateAndroid()87 NetworkChangeNotifierDelegateAndroid::NetworkChangeNotifierDelegateAndroid()
88 : java_network_change_notifier_(Java_NetworkChangeNotifier_init(
89 base::android::AttachCurrentThread())),
90 register_network_callback_failed_(
91 Java_NetworkChangeNotifier_registerNetworkCallbackFailed(
92 base::android::AttachCurrentThread(),
93 java_network_change_notifier_)),
94 // TODO(crbug.com/1042122): Remove once Cronet drops Kitkat support.
95 is_default_network_active_api_supported_(
96 base::android::BuildInfo::GetInstance()->sdk_int() >=
97 base::android::SDK_VERSION_LOLLIPOP) {
98 JNIEnv* env = base::android::AttachCurrentThread();
99 Java_NetworkChangeNotifier_addNativeObserver(
100 env, java_network_change_notifier_, reinterpret_cast<intptr_t>(this));
101 SetCurrentConnectionType(
102 ConvertConnectionType(Java_NetworkChangeNotifier_getCurrentConnectionType(
103 env, java_network_change_notifier_)));
104 SetCurrentConnectionCost(
105 ConvertConnectionCost(Java_NetworkChangeNotifier_getCurrentConnectionCost(
106 env, java_network_change_notifier_)));
107 SetCurrentMaxBandwidth(
108 NetworkChangeNotifierAndroid::GetMaxBandwidthMbpsForConnectionSubtype(
109 GetCurrentConnectionSubtype()));
110 SetCurrentDefaultNetwork(Java_NetworkChangeNotifier_getCurrentDefaultNetId(
111 env, java_network_change_notifier_));
112 NetworkMap network_map;
113 ScopedJavaLocalRef<jlongArray> networks_and_types =
114 Java_NetworkChangeNotifier_getCurrentNetworksAndTypes(
115 env, java_network_change_notifier_);
116 JavaLongArrayToNetworkMap(env, networks_and_types, &network_map);
117 SetCurrentNetworksAndTypes(network_map);
118 if (is_default_network_active_api_supported_)
119 java_network_active_notifier_ = Java_NetworkActiveNotifier_build(
120 base::android::AttachCurrentThread(), reinterpret_cast<intptr_t>(this));
121 }
122
~NetworkChangeNotifierDelegateAndroid()123 NetworkChangeNotifierDelegateAndroid::~NetworkChangeNotifierDelegateAndroid() {
124 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
125 DCHECK_EQ(default_network_active_observers_, 0);
126 {
127 base::AutoLock auto_lock(observer_lock_);
128 DCHECK(!observer_);
129 }
130 JNIEnv* env = base::android::AttachCurrentThread();
131 Java_NetworkChangeNotifier_removeNativeObserver(
132 env, java_network_change_notifier_, reinterpret_cast<intptr_t>(this));
133 }
134
135 NetworkChangeNotifier::ConnectionType
GetCurrentConnectionType() const136 NetworkChangeNotifierDelegateAndroid::GetCurrentConnectionType() const {
137 base::AutoLock auto_lock(connection_lock_);
138 return connection_type_;
139 }
140
141 NetworkChangeNotifier::ConnectionCost
GetCurrentConnectionCost()142 NetworkChangeNotifierDelegateAndroid::GetCurrentConnectionCost() {
143 base::AutoLock auto_lock(connection_lock_);
144 return connection_cost_;
145 }
146
147 NetworkChangeNotifier::ConnectionSubtype
GetCurrentConnectionSubtype() const148 NetworkChangeNotifierDelegateAndroid::GetCurrentConnectionSubtype() const {
149 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
150 return ConvertConnectionSubtype(
151 Java_NetworkChangeNotifier_getCurrentConnectionSubtype(
152 base::android::AttachCurrentThread(), java_network_change_notifier_));
153 }
154
155 void NetworkChangeNotifierDelegateAndroid::
GetCurrentMaxBandwidthAndConnectionType(double * max_bandwidth_mbps,ConnectionType * connection_type) const156 GetCurrentMaxBandwidthAndConnectionType(
157 double* max_bandwidth_mbps,
158 ConnectionType* connection_type) const {
159 base::AutoLock auto_lock(connection_lock_);
160 *connection_type = connection_type_;
161 *max_bandwidth_mbps = connection_max_bandwidth_;
162 }
163
164 NetworkChangeNotifier::ConnectionType
GetNetworkConnectionType(handles::NetworkHandle network) const165 NetworkChangeNotifierDelegateAndroid::GetNetworkConnectionType(
166 handles::NetworkHandle network) const {
167 base::AutoLock auto_lock(connection_lock_);
168 auto network_entry = network_map_.find(network);
169 if (network_entry == network_map_.end())
170 return ConnectionType::CONNECTION_UNKNOWN;
171 return network_entry->second;
172 }
173
174 handles::NetworkHandle
GetCurrentDefaultNetwork() const175 NetworkChangeNotifierDelegateAndroid::GetCurrentDefaultNetwork() const {
176 base::AutoLock auto_lock(connection_lock_);
177 return default_network_;
178 }
179
GetCurrentlyConnectedNetworks(NetworkList * network_list) const180 void NetworkChangeNotifierDelegateAndroid::GetCurrentlyConnectedNetworks(
181 NetworkList* network_list) const {
182 network_list->clear();
183 base::AutoLock auto_lock(connection_lock_);
184 for (auto i : network_map_)
185 network_list->push_back(i.first);
186 }
187
IsDefaultNetworkActive()188 bool NetworkChangeNotifierDelegateAndroid::IsDefaultNetworkActive() {
189 // If the API is not available always return true to avoid indefinitely
190 // batching.
191 if (!is_default_network_active_api_supported_)
192 return true;
193 JNIEnv* env = base::android::AttachCurrentThread();
194 return Java_NetworkActiveNotifier_isDefaultNetworkActive(
195 env, java_network_active_notifier_);
196 }
197
NotifyConnectionCostChanged(JNIEnv * env,const JavaParamRef<jobject> & obj,jint new_connection_cost)198 void NetworkChangeNotifierDelegateAndroid::NotifyConnectionCostChanged(
199 JNIEnv* env,
200 const JavaParamRef<jobject>& obj,
201 jint new_connection_cost) {
202 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
203 const ConnectionCost actual_connection_cost =
204 ConvertConnectionCost(new_connection_cost);
205 SetCurrentConnectionCost(actual_connection_cost);
206 base::AutoLock auto_lock(observer_lock_);
207 if (observer_)
208 observer_->OnConnectionCostChanged();
209 }
210
NotifyConnectionTypeChanged(JNIEnv * env,const JavaParamRef<jobject> & obj,jint new_connection_type,jlong default_netid)211 void NetworkChangeNotifierDelegateAndroid::NotifyConnectionTypeChanged(
212 JNIEnv* env,
213 const JavaParamRef<jobject>& obj,
214 jint new_connection_type,
215 jlong default_netid) {
216 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
217 const ConnectionType actual_connection_type = ConvertConnectionType(
218 new_connection_type);
219 SetCurrentConnectionType(actual_connection_type);
220 handles::NetworkHandle default_network = default_netid;
221 if (default_network != GetCurrentDefaultNetwork()) {
222 SetCurrentDefaultNetwork(default_network);
223 bool default_exists;
224 {
225 base::AutoLock auto_lock(connection_lock_);
226 // |default_network| may be an invalid value (i.e. -1) in cases where
227 // the device is disconnected or when run on Android versions prior to L,
228 // in which case |default_exists| will correctly be false and no
229 // OnNetworkMadeDefault notification will be sent.
230 default_exists = network_map_.find(default_network) != network_map_.end();
231 }
232 // Android Lollipop had race conditions where CONNECTIVITY_ACTION intents
233 // were sent out before the network was actually made the default.
234 // Delay sending the OnNetworkMadeDefault notification until we are
235 // actually notified that the network connected in NotifyOfNetworkConnect.
236 if (default_exists) {
237 base::AutoLock auto_lock(observer_lock_);
238 if (observer_)
239 observer_->OnNetworkMadeDefault(default_network);
240 }
241 }
242
243 base::AutoLock auto_lock(observer_lock_);
244 if (observer_)
245 observer_->OnConnectionTypeChanged();
246 }
247
GetConnectionType(JNIEnv *,jobject) const248 jint NetworkChangeNotifierDelegateAndroid::GetConnectionType(JNIEnv*,
249 jobject) const {
250 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
251 return GetCurrentConnectionType();
252 }
253
GetConnectionCost(JNIEnv *,jobject)254 jint NetworkChangeNotifierDelegateAndroid::GetConnectionCost(JNIEnv*, jobject) {
255 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
256 return GetCurrentConnectionCost();
257 }
258
NotifyMaxBandwidthChanged(JNIEnv * env,const JavaParamRef<jobject> & obj,jint subtype)259 void NetworkChangeNotifierDelegateAndroid::NotifyMaxBandwidthChanged(
260 JNIEnv* env,
261 const JavaParamRef<jobject>& obj,
262 jint subtype) {
263 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
264 double new_max_bandwidth =
265 NetworkChangeNotifierAndroid::GetMaxBandwidthMbpsForConnectionSubtype(
266 ConvertConnectionSubtype(subtype));
267 SetCurrentMaxBandwidth(new_max_bandwidth);
268 const ConnectionType connection_type = GetCurrentConnectionType();
269 base::AutoLock auto_lock(observer_lock_);
270 if (observer_) {
271 observer_->OnMaxBandwidthChanged(new_max_bandwidth, connection_type);
272 }
273 }
274
NotifyOfNetworkConnect(JNIEnv * env,const JavaParamRef<jobject> & obj,jlong net_id,jint connection_type)275 void NetworkChangeNotifierDelegateAndroid::NotifyOfNetworkConnect(
276 JNIEnv* env,
277 const JavaParamRef<jobject>& obj,
278 jlong net_id,
279 jint connection_type) {
280 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
281 handles::NetworkHandle network = net_id;
282 bool already_exists;
283 bool is_default_network;
284 {
285 base::AutoLock auto_lock(connection_lock_);
286 already_exists = network_map_.find(network) != network_map_.end();
287 network_map_[network] = static_cast<ConnectionType>(connection_type);
288 is_default_network = (network == default_network_);
289 }
290 // Android Lollipop would send many duplicate notifications.
291 // This was later fixed in Android Marshmallow.
292 // Deduplicate them here by avoiding sending duplicate notifications.
293 if (!already_exists) {
294 base::AutoLock auto_lock(observer_lock_);
295 if (observer_) {
296 observer_->OnNetworkConnected(network);
297 if (is_default_network)
298 observer_->OnNetworkMadeDefault(network);
299 }
300 }
301 }
302
NotifyOfNetworkSoonToDisconnect(JNIEnv * env,const JavaParamRef<jobject> & obj,jlong net_id)303 void NetworkChangeNotifierDelegateAndroid::NotifyOfNetworkSoonToDisconnect(
304 JNIEnv* env,
305 const JavaParamRef<jobject>& obj,
306 jlong net_id) {
307 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
308 handles::NetworkHandle network = net_id;
309 {
310 base::AutoLock auto_lock(connection_lock_);
311 if (network_map_.find(network) == network_map_.end())
312 return;
313 }
314 base::AutoLock auto_lock(observer_lock_);
315 if (observer_)
316 observer_->OnNetworkSoonToDisconnect(network);
317 }
318
NotifyOfNetworkDisconnect(JNIEnv * env,const JavaParamRef<jobject> & obj,jlong net_id)319 void NetworkChangeNotifierDelegateAndroid::NotifyOfNetworkDisconnect(
320 JNIEnv* env,
321 const JavaParamRef<jobject>& obj,
322 jlong net_id) {
323 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
324 handles::NetworkHandle network = net_id;
325 {
326 base::AutoLock auto_lock(connection_lock_);
327 if (network == default_network_)
328 default_network_ = handles::kInvalidNetworkHandle;
329 if (network_map_.erase(network) == 0)
330 return;
331 }
332 base::AutoLock auto_lock(observer_lock_);
333 if (observer_)
334 observer_->OnNetworkDisconnected(network);
335 }
336
NotifyPurgeActiveNetworkList(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jlongArray> & active_networks)337 void NetworkChangeNotifierDelegateAndroid::NotifyPurgeActiveNetworkList(
338 JNIEnv* env,
339 const JavaParamRef<jobject>& obj,
340 const JavaParamRef<jlongArray>& active_networks) {
341 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
342 NetworkList active_network_list;
343 base::android::JavaLongArrayToInt64Vector(env, active_networks,
344 &active_network_list);
345 NetworkList disconnected_networks;
346 {
347 base::AutoLock auto_lock(connection_lock_);
348 for (auto i : network_map_) {
349 bool found = false;
350 for (auto j : active_network_list) {
351 if (j == i.first) {
352 found = true;
353 break;
354 }
355 }
356 if (!found) {
357 disconnected_networks.push_back(i.first);
358 }
359 }
360 }
361 for (auto disconnected_network : disconnected_networks)
362 NotifyOfNetworkDisconnect(env, obj, disconnected_network);
363 }
364
NotifyOfDefaultNetworkActive(JNIEnv * env)365 void NetworkChangeNotifierDelegateAndroid::NotifyOfDefaultNetworkActive(
366 JNIEnv* env) {
367 base::AutoLock auto_lock(observer_lock_);
368 if (observer_)
369 observer_->OnDefaultNetworkActive();
370 }
371
RegisterObserver(Observer * observer)372 void NetworkChangeNotifierDelegateAndroid::RegisterObserver(
373 Observer* observer) {
374 base::AutoLock auto_lock(observer_lock_);
375 DCHECK(!observer_);
376 observer_ = observer;
377 }
378
UnregisterObserver(Observer * observer)379 void NetworkChangeNotifierDelegateAndroid::UnregisterObserver(
380 Observer* observer) {
381 base::AutoLock auto_lock(observer_lock_);
382 DCHECK_EQ(observer_, observer);
383 observer_ = nullptr;
384 }
385
DefaultNetworkActiveObserverAdded()386 void NetworkChangeNotifierDelegateAndroid::DefaultNetworkActiveObserverAdded() {
387 if (!is_default_network_active_api_supported_)
388 return;
389 if (default_network_active_observers_.fetch_add(1) == 0)
390 EnableDefaultNetworkActiveNotifications();
391 }
392
393 void NetworkChangeNotifierDelegateAndroid::
DefaultNetworkActiveObserverRemoved()394 DefaultNetworkActiveObserverRemoved() {
395 if (!is_default_network_active_api_supported_)
396 return;
397 if (default_network_active_observers_.fetch_sub(1) == 1)
398 DisableDefaultNetworkActiveNotifications();
399 }
400
401 void NetworkChangeNotifierDelegateAndroid::
EnableDefaultNetworkActiveNotifications()402 EnableDefaultNetworkActiveNotifications() {
403 if (!is_default_network_active_api_supported_)
404 return;
405 JNIEnv* env = base::android::AttachCurrentThread();
406 Java_NetworkActiveNotifier_enableNotifications(env,
407 java_network_active_notifier_);
408 }
409
410 void NetworkChangeNotifierDelegateAndroid::
DisableDefaultNetworkActiveNotifications()411 DisableDefaultNetworkActiveNotifications() {
412 if (!is_default_network_active_api_supported_)
413 return;
414 JNIEnv* env = base::android::AttachCurrentThread();
415 Java_NetworkActiveNotifier_disableNotifications(
416 env, java_network_active_notifier_);
417 }
418
SetCurrentConnectionType(ConnectionType new_connection_type)419 void NetworkChangeNotifierDelegateAndroid::SetCurrentConnectionType(
420 ConnectionType new_connection_type) {
421 base::AutoLock auto_lock(connection_lock_);
422 connection_type_ = new_connection_type;
423 }
424
SetCurrentConnectionCost(ConnectionCost new_connection_cost)425 void NetworkChangeNotifierDelegateAndroid::SetCurrentConnectionCost(
426 ConnectionCost new_connection_cost) {
427 base::AutoLock auto_lock(connection_lock_);
428 connection_cost_ = new_connection_cost;
429 }
430
SetCurrentMaxBandwidth(double max_bandwidth)431 void NetworkChangeNotifierDelegateAndroid::SetCurrentMaxBandwidth(
432 double max_bandwidth) {
433 base::AutoLock auto_lock(connection_lock_);
434 connection_max_bandwidth_ = max_bandwidth;
435 }
436
SetCurrentDefaultNetwork(handles::NetworkHandle default_network)437 void NetworkChangeNotifierDelegateAndroid::SetCurrentDefaultNetwork(
438 handles::NetworkHandle default_network) {
439 base::AutoLock auto_lock(connection_lock_);
440 default_network_ = default_network;
441 }
442
SetCurrentNetworksAndTypes(NetworkMap network_map)443 void NetworkChangeNotifierDelegateAndroid::SetCurrentNetworksAndTypes(
444 NetworkMap network_map) {
445 base::AutoLock auto_lock(connection_lock_);
446 network_map_ = network_map;
447 }
448
SetOnline()449 void NetworkChangeNotifierDelegateAndroid::SetOnline() {
450 JNIEnv* env = base::android::AttachCurrentThread();
451 Java_NetworkChangeNotifier_forceConnectivityState(env, true);
452 }
453
SetOffline()454 void NetworkChangeNotifierDelegateAndroid::SetOffline() {
455 JNIEnv* env = base::android::AttachCurrentThread();
456 Java_NetworkChangeNotifier_forceConnectivityState(env, false);
457 }
458
FakeNetworkConnected(handles::NetworkHandle network,ConnectionType type)459 void NetworkChangeNotifierDelegateAndroid::FakeNetworkConnected(
460 handles::NetworkHandle network,
461 ConnectionType type) {
462 JNIEnv* env = base::android::AttachCurrentThread();
463 Java_NetworkChangeNotifier_fakeNetworkConnected(env, network, type);
464 }
465
FakeNetworkSoonToBeDisconnected(handles::NetworkHandle network)466 void NetworkChangeNotifierDelegateAndroid::FakeNetworkSoonToBeDisconnected(
467 handles::NetworkHandle network) {
468 JNIEnv* env = base::android::AttachCurrentThread();
469 Java_NetworkChangeNotifier_fakeNetworkSoonToBeDisconnected(env, network);
470 }
471
FakeNetworkDisconnected(handles::NetworkHandle network)472 void NetworkChangeNotifierDelegateAndroid::FakeNetworkDisconnected(
473 handles::NetworkHandle network) {
474 JNIEnv* env = base::android::AttachCurrentThread();
475 Java_NetworkChangeNotifier_fakeNetworkDisconnected(env, network);
476 }
477
FakePurgeActiveNetworkList(NetworkChangeNotifier::NetworkList networks)478 void NetworkChangeNotifierDelegateAndroid::FakePurgeActiveNetworkList(
479 NetworkChangeNotifier::NetworkList networks) {
480 JNIEnv* env = base::android::AttachCurrentThread();
481 Java_NetworkChangeNotifier_fakePurgeActiveNetworkList(
482 env, base::android::ToJavaLongArray(env, networks));
483 }
484
FakeDefaultNetwork(handles::NetworkHandle network,ConnectionType type)485 void NetworkChangeNotifierDelegateAndroid::FakeDefaultNetwork(
486 handles::NetworkHandle network,
487 ConnectionType type) {
488 JNIEnv* env = base::android::AttachCurrentThread();
489 Java_NetworkChangeNotifier_fakeDefaultNetwork(env, network, type);
490 }
491
FakeConnectionCostChanged(ConnectionCost cost)492 void NetworkChangeNotifierDelegateAndroid::FakeConnectionCostChanged(
493 ConnectionCost cost) {
494 JNIEnv* env = base::android::AttachCurrentThread();
495 Java_NetworkChangeNotifier_fakeConnectionCostChanged(env, cost);
496 }
497
FakeConnectionSubtypeChanged(ConnectionSubtype subtype)498 void NetworkChangeNotifierDelegateAndroid::FakeConnectionSubtypeChanged(
499 ConnectionSubtype subtype) {
500 JNIEnv* env = base::android::AttachCurrentThread();
501 Java_NetworkChangeNotifier_fakeConnectionSubtypeChanged(env, subtype);
502 }
503
FakeDefaultNetworkActive()504 void NetworkChangeNotifierDelegateAndroid::FakeDefaultNetworkActive() {
505 if (!is_default_network_active_api_supported_)
506 return;
507 JNIEnv* env = base::android::AttachCurrentThread();
508 Java_NetworkActiveNotifier_fakeDefaultNetworkActive(
509 env, java_network_active_notifier_);
510 }
511
512 void NetworkChangeNotifierDelegateAndroid::
EnableNetworkChangeNotifierAutoDetectForTest()513 EnableNetworkChangeNotifierAutoDetectForTest() {
514 JNIEnv* env = base::android::AttachCurrentThread();
515 Java_NetworkChangeNotifier_setAutoDetectConnectivityState(env, true);
516 }
517
518 } // namespace net
519