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 JNIEnv* env = base::android::AttachCurrentThread();
95 Java_NetworkChangeNotifier_addNativeObserver(
96 env, java_network_change_notifier_, reinterpret_cast<intptr_t>(this));
97 SetCurrentConnectionType(
98 ConvertConnectionType(Java_NetworkChangeNotifier_getCurrentConnectionType(
99 env, java_network_change_notifier_)));
100 SetCurrentConnectionCost(
101 ConvertConnectionCost(Java_NetworkChangeNotifier_getCurrentConnectionCost(
102 env, java_network_change_notifier_)));
103 SetCurrentMaxBandwidth(
104 NetworkChangeNotifierAndroid::GetMaxBandwidthMbpsForConnectionSubtype(
105 GetCurrentConnectionSubtype()));
106 SetCurrentDefaultNetwork(Java_NetworkChangeNotifier_getCurrentDefaultNetId(
107 env, java_network_change_notifier_));
108 NetworkMap network_map;
109 ScopedJavaLocalRef<jlongArray> networks_and_types =
110 Java_NetworkChangeNotifier_getCurrentNetworksAndTypes(
111 env, java_network_change_notifier_);
112 JavaLongArrayToNetworkMap(env, networks_and_types, &network_map);
113 SetCurrentNetworksAndTypes(network_map);
114 java_network_active_notifier_ = Java_NetworkActiveNotifier_build(
115 base::android::AttachCurrentThread(), reinterpret_cast<intptr_t>(this));
116 }
117
~NetworkChangeNotifierDelegateAndroid()118 NetworkChangeNotifierDelegateAndroid::~NetworkChangeNotifierDelegateAndroid() {
119 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
120 DCHECK_EQ(default_network_active_observers_, 0);
121 {
122 base::AutoLock auto_lock(observer_lock_);
123 DCHECK(!observer_);
124 }
125 JNIEnv* env = base::android::AttachCurrentThread();
126 Java_NetworkChangeNotifier_removeNativeObserver(
127 env, java_network_change_notifier_, reinterpret_cast<intptr_t>(this));
128 }
129
130 NetworkChangeNotifier::ConnectionType
GetCurrentConnectionType() const131 NetworkChangeNotifierDelegateAndroid::GetCurrentConnectionType() const {
132 base::AutoLock auto_lock(connection_lock_);
133 return connection_type_;
134 }
135
136 NetworkChangeNotifier::ConnectionCost
GetCurrentConnectionCost()137 NetworkChangeNotifierDelegateAndroid::GetCurrentConnectionCost() {
138 base::AutoLock auto_lock(connection_lock_);
139 return connection_cost_;
140 }
141
142 NetworkChangeNotifier::ConnectionSubtype
GetCurrentConnectionSubtype() const143 NetworkChangeNotifierDelegateAndroid::GetCurrentConnectionSubtype() const {
144 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
145 return ConvertConnectionSubtype(
146 Java_NetworkChangeNotifier_getCurrentConnectionSubtype(
147 base::android::AttachCurrentThread(), java_network_change_notifier_));
148 }
149
150 void NetworkChangeNotifierDelegateAndroid::
GetCurrentMaxBandwidthAndConnectionType(double * max_bandwidth_mbps,ConnectionType * connection_type) const151 GetCurrentMaxBandwidthAndConnectionType(
152 double* max_bandwidth_mbps,
153 ConnectionType* connection_type) const {
154 base::AutoLock auto_lock(connection_lock_);
155 *connection_type = connection_type_;
156 *max_bandwidth_mbps = connection_max_bandwidth_;
157 }
158
159 NetworkChangeNotifier::ConnectionType
GetNetworkConnectionType(handles::NetworkHandle network) const160 NetworkChangeNotifierDelegateAndroid::GetNetworkConnectionType(
161 handles::NetworkHandle network) const {
162 base::AutoLock auto_lock(connection_lock_);
163 auto network_entry = network_map_.find(network);
164 if (network_entry == network_map_.end())
165 return ConnectionType::CONNECTION_UNKNOWN;
166 return network_entry->second;
167 }
168
169 handles::NetworkHandle
GetCurrentDefaultNetwork() const170 NetworkChangeNotifierDelegateAndroid::GetCurrentDefaultNetwork() const {
171 base::AutoLock auto_lock(connection_lock_);
172 return default_network_;
173 }
174
GetCurrentlyConnectedNetworks(NetworkList * network_list) const175 void NetworkChangeNotifierDelegateAndroid::GetCurrentlyConnectedNetworks(
176 NetworkList* network_list) const {
177 network_list->clear();
178 base::AutoLock auto_lock(connection_lock_);
179 for (auto i : network_map_)
180 network_list->push_back(i.first);
181 }
182
IsDefaultNetworkActive()183 bool NetworkChangeNotifierDelegateAndroid::IsDefaultNetworkActive() {
184 JNIEnv* env = base::android::AttachCurrentThread();
185 return Java_NetworkActiveNotifier_isDefaultNetworkActive(
186 env, java_network_active_notifier_);
187 }
188
NotifyConnectionCostChanged(JNIEnv * env,const JavaParamRef<jobject> & obj,jint new_connection_cost)189 void NetworkChangeNotifierDelegateAndroid::NotifyConnectionCostChanged(
190 JNIEnv* env,
191 const JavaParamRef<jobject>& obj,
192 jint new_connection_cost) {
193 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
194 const ConnectionCost actual_connection_cost =
195 ConvertConnectionCost(new_connection_cost);
196 SetCurrentConnectionCost(actual_connection_cost);
197 base::AutoLock auto_lock(observer_lock_);
198 if (observer_)
199 observer_->OnConnectionCostChanged();
200 }
201
NotifyConnectionTypeChanged(JNIEnv * env,const JavaParamRef<jobject> & obj,jint new_connection_type,jlong default_netid)202 void NetworkChangeNotifierDelegateAndroid::NotifyConnectionTypeChanged(
203 JNIEnv* env,
204 const JavaParamRef<jobject>& obj,
205 jint new_connection_type,
206 jlong default_netid) {
207 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
208 const ConnectionType actual_connection_type = ConvertConnectionType(
209 new_connection_type);
210 SetCurrentConnectionType(actual_connection_type);
211 handles::NetworkHandle default_network = default_netid;
212 if (default_network != GetCurrentDefaultNetwork()) {
213 SetCurrentDefaultNetwork(default_network);
214 bool default_exists;
215 {
216 base::AutoLock auto_lock(connection_lock_);
217 // |default_network| may be an invalid value (i.e. -1) in cases where
218 // the device is disconnected or when run on Android versions prior to L,
219 // in which case |default_exists| will correctly be false and no
220 // OnNetworkMadeDefault notification will be sent.
221 default_exists = network_map_.find(default_network) != network_map_.end();
222 }
223 // Android Lollipop had race conditions where CONNECTIVITY_ACTION intents
224 // were sent out before the network was actually made the default.
225 // Delay sending the OnNetworkMadeDefault notification until we are
226 // actually notified that the network connected in NotifyOfNetworkConnect.
227 if (default_exists) {
228 base::AutoLock auto_lock(observer_lock_);
229 if (observer_)
230 observer_->OnNetworkMadeDefault(default_network);
231 }
232 }
233
234 base::AutoLock auto_lock(observer_lock_);
235 if (observer_)
236 observer_->OnConnectionTypeChanged();
237 }
238
GetConnectionType(JNIEnv *,jobject) const239 jint NetworkChangeNotifierDelegateAndroid::GetConnectionType(JNIEnv*,
240 jobject) const {
241 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
242 return GetCurrentConnectionType();
243 }
244
GetConnectionCost(JNIEnv *,jobject)245 jint NetworkChangeNotifierDelegateAndroid::GetConnectionCost(JNIEnv*, jobject) {
246 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
247 return GetCurrentConnectionCost();
248 }
249
NotifyMaxBandwidthChanged(JNIEnv * env,const JavaParamRef<jobject> & obj,jint subtype)250 void NetworkChangeNotifierDelegateAndroid::NotifyMaxBandwidthChanged(
251 JNIEnv* env,
252 const JavaParamRef<jobject>& obj,
253 jint subtype) {
254 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
255 double new_max_bandwidth =
256 NetworkChangeNotifierAndroid::GetMaxBandwidthMbpsForConnectionSubtype(
257 ConvertConnectionSubtype(subtype));
258 SetCurrentMaxBandwidth(new_max_bandwidth);
259 const ConnectionType connection_type = GetCurrentConnectionType();
260 base::AutoLock auto_lock(observer_lock_);
261 if (observer_) {
262 observer_->OnMaxBandwidthChanged(new_max_bandwidth, connection_type);
263 }
264 }
265
NotifyOfNetworkConnect(JNIEnv * env,const JavaParamRef<jobject> & obj,jlong net_id,jint connection_type)266 void NetworkChangeNotifierDelegateAndroid::NotifyOfNetworkConnect(
267 JNIEnv* env,
268 const JavaParamRef<jobject>& obj,
269 jlong net_id,
270 jint connection_type) {
271 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
272 handles::NetworkHandle network = net_id;
273 bool already_exists;
274 bool is_default_network;
275 {
276 base::AutoLock auto_lock(connection_lock_);
277 already_exists = network_map_.find(network) != network_map_.end();
278 network_map_[network] = static_cast<ConnectionType>(connection_type);
279 is_default_network = (network == default_network_);
280 }
281 // Android Lollipop would send many duplicate notifications.
282 // This was later fixed in Android Marshmallow.
283 // Deduplicate them here by avoiding sending duplicate notifications.
284 if (!already_exists) {
285 base::AutoLock auto_lock(observer_lock_);
286 if (observer_) {
287 observer_->OnNetworkConnected(network);
288 if (is_default_network)
289 observer_->OnNetworkMadeDefault(network);
290 }
291 }
292 }
293
NotifyOfNetworkSoonToDisconnect(JNIEnv * env,const JavaParamRef<jobject> & obj,jlong net_id)294 void NetworkChangeNotifierDelegateAndroid::NotifyOfNetworkSoonToDisconnect(
295 JNIEnv* env,
296 const JavaParamRef<jobject>& obj,
297 jlong net_id) {
298 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
299 handles::NetworkHandle network = net_id;
300 {
301 base::AutoLock auto_lock(connection_lock_);
302 if (network_map_.find(network) == network_map_.end())
303 return;
304 }
305 base::AutoLock auto_lock(observer_lock_);
306 if (observer_)
307 observer_->OnNetworkSoonToDisconnect(network);
308 }
309
NotifyOfNetworkDisconnect(JNIEnv * env,const JavaParamRef<jobject> & obj,jlong net_id)310 void NetworkChangeNotifierDelegateAndroid::NotifyOfNetworkDisconnect(
311 JNIEnv* env,
312 const JavaParamRef<jobject>& obj,
313 jlong net_id) {
314 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
315 handles::NetworkHandle network = net_id;
316 {
317 base::AutoLock auto_lock(connection_lock_);
318 if (network == default_network_)
319 default_network_ = handles::kInvalidNetworkHandle;
320 if (network_map_.erase(network) == 0)
321 return;
322 }
323 base::AutoLock auto_lock(observer_lock_);
324 if (observer_)
325 observer_->OnNetworkDisconnected(network);
326 }
327
NotifyPurgeActiveNetworkList(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jlongArray> & active_networks)328 void NetworkChangeNotifierDelegateAndroid::NotifyPurgeActiveNetworkList(
329 JNIEnv* env,
330 const JavaParamRef<jobject>& obj,
331 const JavaParamRef<jlongArray>& active_networks) {
332 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
333 NetworkList active_network_list;
334 base::android::JavaLongArrayToInt64Vector(env, active_networks,
335 &active_network_list);
336 NetworkList disconnected_networks;
337 {
338 base::AutoLock auto_lock(connection_lock_);
339 for (auto i : network_map_) {
340 bool found = false;
341 for (auto j : active_network_list) {
342 if (j == i.first) {
343 found = true;
344 break;
345 }
346 }
347 if (!found) {
348 disconnected_networks.push_back(i.first);
349 }
350 }
351 }
352 for (auto disconnected_network : disconnected_networks)
353 NotifyOfNetworkDisconnect(env, obj, disconnected_network);
354 }
355
NotifyOfDefaultNetworkActive(JNIEnv * env)356 void NetworkChangeNotifierDelegateAndroid::NotifyOfDefaultNetworkActive(
357 JNIEnv* env) {
358 base::AutoLock auto_lock(observer_lock_);
359 if (observer_)
360 observer_->OnDefaultNetworkActive();
361 }
362
RegisterObserver(Observer * observer)363 void NetworkChangeNotifierDelegateAndroid::RegisterObserver(
364 Observer* observer) {
365 base::AutoLock auto_lock(observer_lock_);
366 DCHECK(!observer_);
367 observer_ = observer;
368 }
369
UnregisterObserver(Observer * observer)370 void NetworkChangeNotifierDelegateAndroid::UnregisterObserver(
371 Observer* observer) {
372 base::AutoLock auto_lock(observer_lock_);
373 DCHECK_EQ(observer_, observer);
374 observer_ = nullptr;
375 }
376
DefaultNetworkActiveObserverAdded()377 void NetworkChangeNotifierDelegateAndroid::DefaultNetworkActiveObserverAdded() {
378 if (default_network_active_observers_.fetch_add(1) == 0)
379 EnableDefaultNetworkActiveNotifications();
380 }
381
382 void NetworkChangeNotifierDelegateAndroid::
DefaultNetworkActiveObserverRemoved()383 DefaultNetworkActiveObserverRemoved() {
384 if (default_network_active_observers_.fetch_sub(1) == 1)
385 DisableDefaultNetworkActiveNotifications();
386 }
387
388 void NetworkChangeNotifierDelegateAndroid::
EnableDefaultNetworkActiveNotifications()389 EnableDefaultNetworkActiveNotifications() {
390 JNIEnv* env = base::android::AttachCurrentThread();
391 Java_NetworkActiveNotifier_enableNotifications(env,
392 java_network_active_notifier_);
393 }
394
395 void NetworkChangeNotifierDelegateAndroid::
DisableDefaultNetworkActiveNotifications()396 DisableDefaultNetworkActiveNotifications() {
397 JNIEnv* env = base::android::AttachCurrentThread();
398 Java_NetworkActiveNotifier_disableNotifications(
399 env, java_network_active_notifier_);
400 }
401
SetCurrentConnectionType(ConnectionType new_connection_type)402 void NetworkChangeNotifierDelegateAndroid::SetCurrentConnectionType(
403 ConnectionType new_connection_type) {
404 base::AutoLock auto_lock(connection_lock_);
405 connection_type_ = new_connection_type;
406 }
407
SetCurrentConnectionCost(ConnectionCost new_connection_cost)408 void NetworkChangeNotifierDelegateAndroid::SetCurrentConnectionCost(
409 ConnectionCost new_connection_cost) {
410 base::AutoLock auto_lock(connection_lock_);
411 connection_cost_ = new_connection_cost;
412 }
413
SetCurrentMaxBandwidth(double max_bandwidth)414 void NetworkChangeNotifierDelegateAndroid::SetCurrentMaxBandwidth(
415 double max_bandwidth) {
416 base::AutoLock auto_lock(connection_lock_);
417 connection_max_bandwidth_ = max_bandwidth;
418 }
419
SetCurrentDefaultNetwork(handles::NetworkHandle default_network)420 void NetworkChangeNotifierDelegateAndroid::SetCurrentDefaultNetwork(
421 handles::NetworkHandle default_network) {
422 base::AutoLock auto_lock(connection_lock_);
423 default_network_ = default_network;
424 }
425
SetCurrentNetworksAndTypes(NetworkMap network_map)426 void NetworkChangeNotifierDelegateAndroid::SetCurrentNetworksAndTypes(
427 NetworkMap network_map) {
428 base::AutoLock auto_lock(connection_lock_);
429 network_map_ = network_map;
430 }
431
SetOnline()432 void NetworkChangeNotifierDelegateAndroid::SetOnline() {
433 JNIEnv* env = base::android::AttachCurrentThread();
434 Java_NetworkChangeNotifier_forceConnectivityState(env, true);
435 }
436
SetOffline()437 void NetworkChangeNotifierDelegateAndroid::SetOffline() {
438 JNIEnv* env = base::android::AttachCurrentThread();
439 Java_NetworkChangeNotifier_forceConnectivityState(env, false);
440 }
441
FakeNetworkConnected(handles::NetworkHandle network,ConnectionType type)442 void NetworkChangeNotifierDelegateAndroid::FakeNetworkConnected(
443 handles::NetworkHandle network,
444 ConnectionType type) {
445 JNIEnv* env = base::android::AttachCurrentThread();
446 Java_NetworkChangeNotifier_fakeNetworkConnected(env, network, type);
447 }
448
FakeNetworkSoonToBeDisconnected(handles::NetworkHandle network)449 void NetworkChangeNotifierDelegateAndroid::FakeNetworkSoonToBeDisconnected(
450 handles::NetworkHandle network) {
451 JNIEnv* env = base::android::AttachCurrentThread();
452 Java_NetworkChangeNotifier_fakeNetworkSoonToBeDisconnected(env, network);
453 }
454
FakeNetworkDisconnected(handles::NetworkHandle network)455 void NetworkChangeNotifierDelegateAndroid::FakeNetworkDisconnected(
456 handles::NetworkHandle network) {
457 JNIEnv* env = base::android::AttachCurrentThread();
458 Java_NetworkChangeNotifier_fakeNetworkDisconnected(env, network);
459 }
460
FakePurgeActiveNetworkList(NetworkChangeNotifier::NetworkList networks)461 void NetworkChangeNotifierDelegateAndroid::FakePurgeActiveNetworkList(
462 NetworkChangeNotifier::NetworkList networks) {
463 JNIEnv* env = base::android::AttachCurrentThread();
464 Java_NetworkChangeNotifier_fakePurgeActiveNetworkList(
465 env, base::android::ToJavaLongArray(env, networks));
466 }
467
FakeDefaultNetwork(handles::NetworkHandle network,ConnectionType type)468 void NetworkChangeNotifierDelegateAndroid::FakeDefaultNetwork(
469 handles::NetworkHandle network,
470 ConnectionType type) {
471 JNIEnv* env = base::android::AttachCurrentThread();
472 Java_NetworkChangeNotifier_fakeDefaultNetwork(env, network, type);
473 }
474
FakeConnectionCostChanged(ConnectionCost cost)475 void NetworkChangeNotifierDelegateAndroid::FakeConnectionCostChanged(
476 ConnectionCost cost) {
477 JNIEnv* env = base::android::AttachCurrentThread();
478 Java_NetworkChangeNotifier_fakeConnectionCostChanged(env, cost);
479 }
480
FakeConnectionSubtypeChanged(ConnectionSubtype subtype)481 void NetworkChangeNotifierDelegateAndroid::FakeConnectionSubtypeChanged(
482 ConnectionSubtype subtype) {
483 JNIEnv* env = base::android::AttachCurrentThread();
484 Java_NetworkChangeNotifier_fakeConnectionSubtypeChanged(env, subtype);
485 }
486
FakeDefaultNetworkActive()487 void NetworkChangeNotifierDelegateAndroid::FakeDefaultNetworkActive() {
488 JNIEnv* env = base::android::AttachCurrentThread();
489 Java_NetworkActiveNotifier_fakeDefaultNetworkActive(
490 env, java_network_active_notifier_);
491 }
492
493 void NetworkChangeNotifierDelegateAndroid::
EnableNetworkChangeNotifierAutoDetectForTest()494 EnableNetworkChangeNotifierAutoDetectForTest() {
495 JNIEnv* env = base::android::AttachCurrentThread();
496 Java_NetworkChangeNotifier_setAutoDetectConnectivityState(env, true);
497 }
498
499 } // namespace net
500