OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 package org.webrtc; | |
12 | |
13 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; | |
14 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; | |
15 | |
16 import android.Manifest.permission; | |
17 import android.annotation.SuppressLint; | |
18 import android.content.BroadcastReceiver; | |
19 import android.content.Context; | |
20 import android.content.Intent; | |
21 import android.content.IntentFilter; | |
22 import android.net.ConnectivityManager; | |
23 import android.net.ConnectivityManager.NetworkCallback; | |
24 import android.net.LinkAddress; | |
25 import android.net.LinkProperties; | |
26 import android.net.Network; | |
27 import android.net.NetworkCapabilities; | |
28 import android.net.NetworkInfo; | |
29 import android.net.NetworkRequest; | |
30 import android.net.wifi.WifiInfo; | |
31 import android.net.wifi.WifiManager; | |
32 import android.os.Build; | |
33 import android.telephony.TelephonyManager; | |
34 | |
35 import java.util.ArrayList; | |
36 import java.util.List; | |
37 | |
38 /** | |
39 * Borrowed from Chromium's | |
40 * src/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.jav
a | |
41 * | |
42 * Used by the NetworkMonitor to listen to platform changes in connectivity. | |
43 * Note that use of this class requires that the app have the platform | |
44 * ACCESS_NETWORK_STATE permission. | |
45 */ | |
46 public class NetworkMonitorAutoDetect extends BroadcastReceiver { | |
47 public static enum ConnectionType { | |
48 CONNECTION_UNKNOWN, | |
49 CONNECTION_ETHERNET, | |
50 CONNECTION_WIFI, | |
51 CONNECTION_4G, | |
52 CONNECTION_3G, | |
53 CONNECTION_2G, | |
54 CONNECTION_UNKNOWN_CELLULAR, | |
55 CONNECTION_BLUETOOTH, | |
56 CONNECTION_NONE | |
57 } | |
58 | |
59 public static class IPAddress { | |
60 public final byte[] address; | |
61 public IPAddress(byte[] address) { | |
62 this.address = address; | |
63 } | |
64 } | |
65 | |
66 /** Java version of NetworkMonitor.NetworkInformation */ | |
67 public static class NetworkInformation { | |
68 public final String name; | |
69 public final ConnectionType type; | |
70 public final long handle; | |
71 public final IPAddress[] ipAddresses; | |
72 public NetworkInformation( | |
73 String name, ConnectionType type, long handle, IPAddress[] addresses) { | |
74 this.name = name; | |
75 this.type = type; | |
76 this.handle = handle; | |
77 this.ipAddresses = addresses; | |
78 } | |
79 }; | |
80 | |
81 static class NetworkState { | |
82 private final boolean connected; | |
83 // Defined from ConnectivityManager.TYPE_XXX for non-mobile; for mobile, it
is | |
84 // further divided into 2G, 3G, or 4G from the subtype. | |
85 private final int type; | |
86 // Defined from NetworkInfo.subtype, which is one of the TelephonyManager.NE
TWORK_TYPE_XXXs. | |
87 // Will be useful to find the maximum bandwidth. | |
88 private final int subtype; | |
89 | |
90 public NetworkState(boolean connected, int type, int subtype) { | |
91 this.connected = connected; | |
92 this.type = type; | |
93 this.subtype = subtype; | |
94 } | |
95 | |
96 public boolean isConnected() { | |
97 return connected; | |
98 } | |
99 | |
100 public int getNetworkType() { | |
101 return type; | |
102 } | |
103 | |
104 public int getNetworkSubType() { | |
105 return subtype; | |
106 } | |
107 } | |
108 /** | |
109 * The methods in this class get called when the network changes if the callba
ck | |
110 * is registered with a proper network request. It is only available in Androi
d Lollipop | |
111 * and above. | |
112 */ | |
113 @SuppressLint("NewApi") | |
114 private class SimpleNetworkCallback extends NetworkCallback { | |
115 @Override | |
116 public void onAvailable(Network network) { | |
117 Logging.d(TAG, "Network becomes available: " + network.toString()); | |
118 onNetworkChanged(network); | |
119 } | |
120 | |
121 @Override | |
122 public void onCapabilitiesChanged(Network network, NetworkCapabilities netwo
rkCapabilities) { | |
123 // A capabilities change may indicate the ConnectionType has changed, | |
124 // so forward the new NetworkInformation along to the observer. | |
125 Logging.d(TAG, "capabilities changed: " + networkCapabilities.toString()); | |
126 onNetworkChanged(network); | |
127 } | |
128 | |
129 @Override | |
130 public void onLinkPropertiesChanged(Network network, LinkProperties linkProp
erties) { | |
131 // A link property change may indicate the IP address changes. | |
132 // so forward the new NetworkInformation to the observer. | |
133 Logging.d(TAG, "link properties changed: " + linkProperties.toString()); | |
134 onNetworkChanged(network); | |
135 } | |
136 | |
137 @Override | |
138 public void onLosing(Network network, int maxMsToLive) { | |
139 // Tell the network is going to lose in MaxMsToLive milliseconds. | |
140 // We may use this signal later. | |
141 Logging.d( | |
142 TAG, "Network " + network.toString() + " is about to lose in " + maxMs
ToLive + "ms"); | |
143 } | |
144 | |
145 @Override | |
146 public void onLost(Network network) { | |
147 Logging.d(TAG, "Network " + network.toString() + " is disconnected"); | |
148 observer.onNetworkDisconnect(networkToNetId(network)); | |
149 } | |
150 | |
151 private void onNetworkChanged(Network network) { | |
152 NetworkInformation networkInformation = connectivityManagerDelegate.networ
kToInfo(network); | |
153 if (networkInformation != null) { | |
154 observer.onNetworkConnect(networkInformation); | |
155 } | |
156 } | |
157 } | |
158 | |
159 /** Queries the ConnectivityManager for information about the current connecti
on. */ | |
160 static class ConnectivityManagerDelegate { | |
161 /** | |
162 * Note: In some rare Android systems connectivityManager is null. We hand
le that | |
163 * gracefully below. | |
164 */ | |
165 private final ConnectivityManager connectivityManager; | |
166 | |
167 ConnectivityManagerDelegate(Context context) { | |
168 connectivityManager = | |
169 (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SE
RVICE); | |
170 } | |
171 | |
172 // For testing. | |
173 ConnectivityManagerDelegate() { | |
174 // All the methods below should be overridden. | |
175 connectivityManager = null; | |
176 } | |
177 | |
178 /** | |
179 * Returns connection type and status information about the current | |
180 * default network. | |
181 */ | |
182 NetworkState getNetworkState() { | |
183 if (connectivityManager == null) { | |
184 return new NetworkState(false, -1, -1); | |
185 } | |
186 return getNetworkState(connectivityManager.getActiveNetworkInfo()); | |
187 } | |
188 | |
189 /** | |
190 * Returns connection type and status information about |network|. | |
191 * Only callable on Lollipop and newer releases. | |
192 */ | |
193 @SuppressLint("NewApi") | |
194 NetworkState getNetworkState(Network network) { | |
195 if (connectivityManager == null) { | |
196 return new NetworkState(false, -1, -1); | |
197 } | |
198 return getNetworkState(connectivityManager.getNetworkInfo(network)); | |
199 } | |
200 | |
201 /** | |
202 * Returns connection type and status information gleaned from networkInfo. | |
203 */ | |
204 NetworkState getNetworkState(NetworkInfo networkInfo) { | |
205 if (networkInfo == null || !networkInfo.isConnected()) { | |
206 return new NetworkState(false, -1, -1); | |
207 } | |
208 return new NetworkState(true, networkInfo.getType(), networkInfo.getSubtyp
e()); | |
209 } | |
210 | |
211 /** | |
212 * Returns all connected networks. | |
213 * Only callable on Lollipop and newer releases. | |
214 */ | |
215 @SuppressLint("NewApi") | |
216 Network[] getAllNetworks() { | |
217 if (connectivityManager == null) { | |
218 return new Network[0]; | |
219 } | |
220 return connectivityManager.getAllNetworks(); | |
221 } | |
222 | |
223 List<NetworkInformation> getActiveNetworkList() { | |
224 if (!supportNetworkCallback()) { | |
225 return null; | |
226 } | |
227 ArrayList<NetworkInformation> netInfoList = new ArrayList<NetworkInformati
on>(); | |
228 for (Network network : getAllNetworks()) { | |
229 NetworkInformation info = networkToInfo(network); | |
230 if (info != null) { | |
231 netInfoList.add(info); | |
232 } | |
233 } | |
234 return netInfoList; | |
235 } | |
236 | |
237 /** | |
238 * Returns the NetID of the current default network. Returns | |
239 * INVALID_NET_ID if no current default network connected. | |
240 * Only callable on Lollipop and newer releases. | |
241 */ | |
242 @SuppressLint("NewApi") | |
243 long getDefaultNetId() { | |
244 if (!supportNetworkCallback()) { | |
245 return INVALID_NET_ID; | |
246 } | |
247 // Android Lollipop had no API to get the default network; only an | |
248 // API to return the NetworkInfo for the default network. To | |
249 // determine the default network one can find the network with | |
250 // type matching that of the default network. | |
251 final NetworkInfo defaultNetworkInfo = connectivityManager.getActiveNetwor
kInfo(); | |
252 if (defaultNetworkInfo == null) { | |
253 return INVALID_NET_ID; | |
254 } | |
255 final Network[] networks = getAllNetworks(); | |
256 long defaultNetId = INVALID_NET_ID; | |
257 for (Network network : networks) { | |
258 if (!hasInternetCapability(network)) { | |
259 continue; | |
260 } | |
261 final NetworkInfo networkInfo = connectivityManager.getNetworkInfo(netwo
rk); | |
262 if (networkInfo != null && networkInfo.getType() == defaultNetworkInfo.g
etType()) { | |
263 // There should not be multiple connected networks of the | |
264 // same type. At least as of Android Marshmallow this is | |
265 // not supported. If this becomes supported this assertion | |
266 // may trigger. At that point we could consider using | |
267 // ConnectivityManager.getDefaultNetwork() though this | |
268 // may give confusing results with VPNs and is only | |
269 // available with Android Marshmallow. | |
270 assert defaultNetId == INVALID_NET_ID; | |
271 defaultNetId = networkToNetId(network); | |
272 } | |
273 } | |
274 return defaultNetId; | |
275 } | |
276 | |
277 @SuppressLint("NewApi") | |
278 private NetworkInformation networkToInfo(Network network) { | |
279 LinkProperties linkProperties = connectivityManager.getLinkProperties(netw
ork); | |
280 // getLinkProperties will return null if the network is unknown. | |
281 if (linkProperties == null) { | |
282 Logging.w(TAG, "Detected unknown network: " + network.toString()); | |
283 return null; | |
284 } | |
285 if (linkProperties.getInterfaceName() == null) { | |
286 Logging.w(TAG, "Null interface name for network " + network.toString()); | |
287 return null; | |
288 } | |
289 | |
290 NetworkState networkState = getNetworkState(network); | |
291 if (networkState.connected && networkState.getNetworkType() == Connectivit
yManager.TYPE_VPN) { | |
292 // If a VPN network is in place, we can find the underlying network type
via querying the | |
293 // active network info thanks to | |
294 // https://android.googlesource.com/platform/frameworks/base/+/d6a7980d | |
295 networkState = getNetworkState(); | |
296 } | |
297 ConnectionType connectionType = getConnectionType(networkState); | |
298 if (connectionType == ConnectionType.CONNECTION_NONE) { | |
299 // This may not be an error. The OS may signal a network event with conn
ection type | |
300 // NONE when the network disconnects. | |
301 Logging.d(TAG, "Network " + network.toString() + " is disconnected"); | |
302 return null; | |
303 } | |
304 | |
305 // Some android device may return a CONNECTION_UNKNOWN_CELLULAR or CONNECT
ION_UNKNOWN type, | |
306 // which appears to be usable. Just log them here. | |
307 if (connectionType == ConnectionType.CONNECTION_UNKNOWN | |
308 || connectionType == ConnectionType.CONNECTION_UNKNOWN_CELLULAR) { | |
309 Logging.d(TAG, "Network " + network.toString() + " connection type is "
+ connectionType | |
310 + " because it has type " + networkState.getNetworkType() + " an
d subtype " | |
311 + networkState.getNetworkSubType()); | |
312 } | |
313 | |
314 NetworkInformation networkInformation = | |
315 new NetworkInformation(linkProperties.getInterfaceName(), connectionTy
pe, | |
316 networkToNetId(network), getIPAddresses(linkProperties)); | |
317 return networkInformation; | |
318 } | |
319 | |
320 /** | |
321 * Returns true if {@code network} can provide Internet access. Can be used
to | |
322 * ignore specialized networks (e.g. IMS, FOTA). | |
323 */ | |
324 @SuppressLint("NewApi") | |
325 boolean hasInternetCapability(Network network) { | |
326 if (connectivityManager == null) { | |
327 return false; | |
328 } | |
329 final NetworkCapabilities capabilities = connectivityManager.getNetworkCap
abilities(network); | |
330 return capabilities != null && capabilities.hasCapability(NET_CAPABILITY_I
NTERNET); | |
331 } | |
332 | |
333 /** Only callable on Lollipop and newer releases. */ | |
334 @SuppressLint("NewApi") | |
335 public void registerNetworkCallback(NetworkCallback networkCallback) { | |
336 connectivityManager.registerNetworkCallback( | |
337 new NetworkRequest.Builder().addCapability(NET_CAPABILITY_INTERNET).bu
ild(), | |
338 networkCallback); | |
339 } | |
340 | |
341 /** Only callable on Lollipop and newer releases. */ | |
342 @SuppressLint("NewApi") | |
343 public void requestMobileNetwork(NetworkCallback networkCallback) { | |
344 NetworkRequest.Builder builder = new NetworkRequest.Builder(); | |
345 builder.addCapability(NET_CAPABILITY_INTERNET).addTransportType(TRANSPORT_
CELLULAR); | |
346 connectivityManager.requestNetwork(builder.build(), networkCallback); | |
347 } | |
348 | |
349 @SuppressLint("NewApi") | |
350 IPAddress[] getIPAddresses(LinkProperties linkProperties) { | |
351 IPAddress[] ipAddresses = new IPAddress[linkProperties.getLinkAddresses().
size()]; | |
352 int i = 0; | |
353 for (LinkAddress linkAddress : linkProperties.getLinkAddresses()) { | |
354 ipAddresses[i] = new IPAddress(linkAddress.getAddress().getAddress()); | |
355 ++i; | |
356 } | |
357 return ipAddresses; | |
358 } | |
359 | |
360 @SuppressLint("NewApi") | |
361 public void releaseCallback(NetworkCallback networkCallback) { | |
362 if (supportNetworkCallback()) { | |
363 Logging.d(TAG, "Unregister network callback"); | |
364 connectivityManager.unregisterNetworkCallback(networkCallback); | |
365 } | |
366 } | |
367 | |
368 public boolean supportNetworkCallback() { | |
369 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && connectivi
tyManager != null; | |
370 } | |
371 } | |
372 | |
373 /** Queries the WifiManager for SSID of the current Wifi connection. */ | |
374 static class WifiManagerDelegate { | |
375 private final Context context; | |
376 WifiManagerDelegate(Context context) { | |
377 this.context = context; | |
378 } | |
379 | |
380 // For testing. | |
381 WifiManagerDelegate() { | |
382 // All the methods below should be overridden. | |
383 context = null; | |
384 } | |
385 | |
386 String getWifiSSID() { | |
387 final Intent intent = context.registerReceiver( | |
388 null, new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION)); | |
389 if (intent != null) { | |
390 final WifiInfo wifiInfo = intent.getParcelableExtra(WifiManager.EXTRA_WI
FI_INFO); | |
391 if (wifiInfo != null) { | |
392 final String ssid = wifiInfo.getSSID(); | |
393 if (ssid != null) { | |
394 return ssid; | |
395 } | |
396 } | |
397 } | |
398 return ""; | |
399 } | |
400 } | |
401 | |
402 static final long INVALID_NET_ID = -1; | |
403 private static final String TAG = "NetworkMonitorAutoDetect"; | |
404 | |
405 // Observer for the connection type change. | |
406 private final Observer observer; | |
407 private final IntentFilter intentFilter; | |
408 private final Context context; | |
409 // Used to request mobile network. It does not do anything except for keeping | |
410 // the callback for releasing the request. | |
411 private final NetworkCallback mobileNetworkCallback; | |
412 // Used to receive updates on all networks. | |
413 private final NetworkCallback allNetworkCallback; | |
414 // connectivityManagerDelegate and wifiManagerDelegate are only non-final for
testing. | |
415 private ConnectivityManagerDelegate connectivityManagerDelegate; | |
416 private WifiManagerDelegate wifiManagerDelegate; | |
417 | |
418 private boolean isRegistered; | |
419 private ConnectionType connectionType; | |
420 private String wifiSSID; | |
421 | |
422 /** | |
423 * Observer interface by which observer is notified of network changes. | |
424 */ | |
425 public static interface Observer { | |
426 /** | |
427 * Called when default network changes. | |
428 */ | |
429 public void onConnectionTypeChanged(ConnectionType newConnectionType); | |
430 public void onNetworkConnect(NetworkInformation networkInfo); | |
431 public void onNetworkDisconnect(long networkHandle); | |
432 } | |
433 | |
434 /** | |
435 * Constructs a NetworkMonitorAutoDetect. Should only be called on UI thread. | |
436 */ | |
437 @SuppressLint("NewApi") | |
438 public NetworkMonitorAutoDetect(Observer observer, Context context) { | |
439 this.observer = observer; | |
440 this.context = context; | |
441 connectivityManagerDelegate = new ConnectivityManagerDelegate(context); | |
442 wifiManagerDelegate = new WifiManagerDelegate(context); | |
443 | |
444 final NetworkState networkState = connectivityManagerDelegate.getNetworkStat
e(); | |
445 connectionType = getConnectionType(networkState); | |
446 wifiSSID = getWifiSSID(networkState); | |
447 intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); | |
448 | |
449 registerReceiver(); | |
450 if (connectivityManagerDelegate.supportNetworkCallback()) { | |
451 // On Android 6.0.0, the WRITE_SETTINGS permission is necessary for | |
452 // requestNetwork, so it will fail. This was fixed in Android 6.0.1. | |
453 NetworkCallback tempNetworkCallback = new NetworkCallback(); | |
454 try { | |
455 connectivityManagerDelegate.requestMobileNetwork(tempNetworkCallback); | |
456 } catch (java.lang.SecurityException e) { | |
457 Logging.w(TAG, "Unable to obtain permission to request a cellular networ
k."); | |
458 tempNetworkCallback = null; | |
459 } | |
460 mobileNetworkCallback = tempNetworkCallback; | |
461 allNetworkCallback = new SimpleNetworkCallback(); | |
462 connectivityManagerDelegate.registerNetworkCallback(allNetworkCallback); | |
463 } else { | |
464 mobileNetworkCallback = null; | |
465 allNetworkCallback = null; | |
466 } | |
467 } | |
468 | |
469 /** | |
470 * Allows overriding the ConnectivityManagerDelegate for tests. | |
471 */ | |
472 void setConnectivityManagerDelegateForTests(ConnectivityManagerDelegate delega
te) { | |
473 connectivityManagerDelegate = delegate; | |
474 } | |
475 | |
476 /** | |
477 * Allows overriding the WifiManagerDelegate for tests. | |
478 */ | |
479 void setWifiManagerDelegateForTests(WifiManagerDelegate delegate) { | |
480 wifiManagerDelegate = delegate; | |
481 } | |
482 | |
483 /** | |
484 * Returns whether the object has registered to receive network connectivity i
ntents. | |
485 * Visible for testing. | |
486 */ | |
487 boolean isReceiverRegisteredForTesting() { | |
488 return isRegistered; | |
489 } | |
490 | |
491 List<NetworkInformation> getActiveNetworkList() { | |
492 return connectivityManagerDelegate.getActiveNetworkList(); | |
493 } | |
494 | |
495 public void destroy() { | |
496 if (allNetworkCallback != null) { | |
497 connectivityManagerDelegate.releaseCallback(allNetworkCallback); | |
498 } | |
499 if (mobileNetworkCallback != null) { | |
500 connectivityManagerDelegate.releaseCallback(mobileNetworkCallback); | |
501 } | |
502 unregisterReceiver(); | |
503 } | |
504 | |
505 /** | |
506 * Registers a BroadcastReceiver in the given context. | |
507 */ | |
508 private void registerReceiver() { | |
509 if (isRegistered) | |
510 return; | |
511 | |
512 isRegistered = true; | |
513 context.registerReceiver(this, intentFilter); | |
514 } | |
515 | |
516 /** | |
517 * Unregisters the BroadcastReceiver in the given context. | |
518 */ | |
519 private void unregisterReceiver() { | |
520 if (!isRegistered) | |
521 return; | |
522 | |
523 isRegistered = false; | |
524 context.unregisterReceiver(this); | |
525 } | |
526 | |
527 public NetworkState getCurrentNetworkState() { | |
528 return connectivityManagerDelegate.getNetworkState(); | |
529 } | |
530 | |
531 /** | |
532 * Returns NetID of device's current default connected network used for | |
533 * communication. | |
534 * Only implemented on Lollipop and newer releases, returns INVALID_NET_ID | |
535 * when not implemented. | |
536 */ | |
537 public long getDefaultNetId() { | |
538 return connectivityManagerDelegate.getDefaultNetId(); | |
539 } | |
540 | |
541 public static ConnectionType getConnectionType(NetworkState networkState) { | |
542 if (!networkState.isConnected()) { | |
543 return ConnectionType.CONNECTION_NONE; | |
544 } | |
545 | |
546 switch (networkState.getNetworkType()) { | |
547 case ConnectivityManager.TYPE_ETHERNET: | |
548 return ConnectionType.CONNECTION_ETHERNET; | |
549 case ConnectivityManager.TYPE_WIFI: | |
550 return ConnectionType.CONNECTION_WIFI; | |
551 case ConnectivityManager.TYPE_WIMAX: | |
552 return ConnectionType.CONNECTION_4G; | |
553 case ConnectivityManager.TYPE_BLUETOOTH: | |
554 return ConnectionType.CONNECTION_BLUETOOTH; | |
555 case ConnectivityManager.TYPE_MOBILE: | |
556 // Use information from TelephonyManager to classify the connection. | |
557 switch (networkState.getNetworkSubType()) { | |
558 case TelephonyManager.NETWORK_TYPE_GPRS: | |
559 case TelephonyManager.NETWORK_TYPE_EDGE: | |
560 case TelephonyManager.NETWORK_TYPE_CDMA: | |
561 case TelephonyManager.NETWORK_TYPE_1xRTT: | |
562 case TelephonyManager.NETWORK_TYPE_IDEN: | |
563 return ConnectionType.CONNECTION_2G; | |
564 case TelephonyManager.NETWORK_TYPE_UMTS: | |
565 case TelephonyManager.NETWORK_TYPE_EVDO_0: | |
566 case TelephonyManager.NETWORK_TYPE_EVDO_A: | |
567 case TelephonyManager.NETWORK_TYPE_HSDPA: | |
568 case TelephonyManager.NETWORK_TYPE_HSUPA: | |
569 case TelephonyManager.NETWORK_TYPE_HSPA: | |
570 case TelephonyManager.NETWORK_TYPE_EVDO_B: | |
571 case TelephonyManager.NETWORK_TYPE_EHRPD: | |
572 case TelephonyManager.NETWORK_TYPE_HSPAP: | |
573 return ConnectionType.CONNECTION_3G; | |
574 case TelephonyManager.NETWORK_TYPE_LTE: | |
575 return ConnectionType.CONNECTION_4G; | |
576 default: | |
577 return ConnectionType.CONNECTION_UNKNOWN_CELLULAR; | |
578 } | |
579 default: | |
580 return ConnectionType.CONNECTION_UNKNOWN; | |
581 } | |
582 } | |
583 | |
584 private String getWifiSSID(NetworkState networkState) { | |
585 if (getConnectionType(networkState) != ConnectionType.CONNECTION_WIFI) | |
586 return ""; | |
587 return wifiManagerDelegate.getWifiSSID(); | |
588 } | |
589 | |
590 // BroadcastReceiver | |
591 @Override | |
592 public void onReceive(Context context, Intent intent) { | |
593 final NetworkState networkState = getCurrentNetworkState(); | |
594 if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { | |
595 connectionTypeChanged(networkState); | |
596 } | |
597 } | |
598 | |
599 private void connectionTypeChanged(NetworkState networkState) { | |
600 ConnectionType newConnectionType = getConnectionType(networkState); | |
601 String newWifiSSID = getWifiSSID(networkState); | |
602 if (newConnectionType == connectionType && newWifiSSID.equals(wifiSSID)) | |
603 return; | |
604 | |
605 connectionType = newConnectionType; | |
606 wifiSSID = newWifiSSID; | |
607 Logging.d(TAG, "Network connectivity changed, type is: " + connectionType); | |
608 observer.onConnectionTypeChanged(newConnectionType); | |
609 } | |
610 | |
611 /** | |
612 * Extracts NetID of network on Lollipop and NetworkHandle (which is mungled | |
613 * NetID) on Marshmallow and newer releases. Only available on Lollipop and | |
614 * newer releases. Returns long since getNetworkHandle returns long. | |
615 */ | |
616 @SuppressLint("NewApi") | |
617 private static long networkToNetId(Network network) { | |
618 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | |
619 return network.getNetworkHandle(); | |
620 } | |
621 | |
622 // NOTE(honghaiz): This depends on Android framework implementation details. | |
623 // These details cannot change because Lollipop has been released. | |
624 return Integer.parseInt(network.toString()); | |
625 } | |
626 } | |
OLD | NEW |