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