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