1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.googlecode.android_scripting.facade; 18 19 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 20 21 import android.app.Service; 22 import android.app.usage.NetworkStats; 23 import android.app.usage.NetworkStats.Bucket; 24 import android.app.usage.NetworkStatsManager; 25 import android.content.BroadcastReceiver; 26 import android.content.Context; 27 import android.content.Intent; 28 import android.content.IntentFilter; 29 import android.net.ConnectivityManager; 30 import android.net.LinkProperties; 31 import android.net.Network; 32 import android.net.NetworkCapabilities; 33 import android.net.NetworkInfo; 34 import android.net.NetworkPolicy; 35 import android.net.NetworkPolicyManager; 36 import android.net.NetworkRequest; 37 import android.net.NetworkSpecifier; 38 import android.net.ProxyInfo; 39 import android.net.RouteInfo; 40 import android.net.Uri; 41 import android.net.wifi.WifiNetworkSpecifier; 42 import android.os.Bundle; 43 import android.os.RemoteException; 44 import android.provider.Settings; 45 import android.telephony.TelephonyManager; 46 47 import com.android.modules.utils.build.SdkLevel; 48 49 import com.google.common.io.ByteStreams; 50 import com.googlecode.android_scripting.FileUtils; 51 import com.googlecode.android_scripting.Log; 52 import com.googlecode.android_scripting.facade.wifi.WifiAwareManagerFacade; 53 import com.googlecode.android_scripting.facade.wifi.WifiManagerFacade; 54 import com.googlecode.android_scripting.jsonrpc.RpcReceiver; 55 import com.googlecode.android_scripting.rpc.Rpc; 56 import com.googlecode.android_scripting.rpc.RpcOptional; 57 import com.googlecode.android_scripting.rpc.RpcParameter; 58 59 import org.json.JSONArray; 60 import org.json.JSONException; 61 import org.json.JSONObject; 62 63 import java.io.BufferedInputStream; 64 import java.io.File; 65 import java.io.FileOutputStream; 66 import java.io.IOException; 67 import java.io.InputStream; 68 import java.io.OutputStream; 69 import java.net.Inet4Address; 70 import java.net.Inet6Address; 71 import java.net.InetAddress; 72 import java.net.NetworkInterface; 73 import java.net.SocketException; 74 import java.net.URL; 75 import java.net.URLConnection; 76 import java.security.GeneralSecurityException; 77 import java.util.ArrayList; 78 import java.util.Collections; 79 import java.util.Enumeration; 80 import java.util.HashMap; 81 import java.util.List; 82 83 /** 84 * Access ConnectivityManager functions. 85 */ 86 public class ConnectivityManagerFacade extends RpcReceiver { 87 88 public static int AIRPLANE_MODE_OFF = 0; 89 public static int AIRPLANE_MODE_ON = 1; 90 public static int DATA_ROAMING_ON = 1; 91 92 private static HashMap<Long, Network> sNetworkHashMap = new HashMap<Long, Network>(); 93 94 class ConnectivityReceiver extends BroadcastReceiver { 95 96 @Override onReceive(Context context, Intent intent)97 public void onReceive(Context context, Intent intent) { 98 String action = intent.getAction(); 99 100 if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 101 Log.e("ConnectivityReceiver received non-connectivity action!"); 102 return; 103 } 104 105 Bundle b = intent.getExtras(); 106 107 if (b == null) { 108 Log.e("ConnectivityReceiver failed to receive extras!"); 109 return; 110 } 111 112 int netType = 113 b.getInt(ConnectivityManager.EXTRA_NETWORK_TYPE, 114 ConnectivityManager.TYPE_NONE); 115 116 if (netType == ConnectivityManager.TYPE_NONE) { 117 Log.i("ConnectivityReceiver received change to TYPE_NONE."); 118 return; 119 } 120 121 /* 122 * Technically there is a race condition here, but retrieving the NetworkInfo from the 123 * bundle is deprecated. See ConnectivityManager.EXTRA_NETWORK_INFO 124 */ 125 for (NetworkInfo info : mManager.getAllNetworkInfo()) { 126 if (info.getType() == netType) { 127 mEventFacade.postEvent(ConnectivityConstants.EventConnectivityChanged, info); 128 } 129 } 130 } 131 } 132 133 /** 134 * Used to dispatch to a different constructor depending on R or S, since 135 * {@link ConnectivityManager.NetworkCallback#NetworkCallback(int)} was added in S. 136 */ newNetworkCallback(int events)137 private NetworkCallback newNetworkCallback(int events) { 138 if (SdkLevel.isAtLeastS()) { 139 return new NetworkCallback(events); 140 } else { 141 return new NetworkCallback(events, false); 142 } 143 } 144 145 private class NetworkCallback extends ConnectivityManager.NetworkCallback { 146 public static final int EVENT_INVALID = -1; 147 public static final int EVENT_NONE = 0; 148 public static final int EVENT_PRECHECK = 1 << 0; 149 public static final int EVENT_AVAILABLE = 1 << 1; 150 public static final int EVENT_LOSING = 1 << 2; 151 public static final int EVENT_LOST = 1 << 3; 152 public static final int EVENT_UNAVAILABLE = 1 << 4; 153 public static final int EVENT_CAPABILITIES_CHANGED = 1 << 5; 154 public static final int EVENT_SUSPENDED = 1 << 6; 155 public static final int EVENT_RESUMED = 1 << 7; 156 public static final int EVENT_LINK_PROPERTIES_CHANGED = 1 << 8; 157 public static final int EVENT_BLOCKED_STATUS_CHANGED = 1 << 9; 158 public static final int EVENT_ALL = 159 EVENT_PRECHECK 160 | EVENT_AVAILABLE 161 | EVENT_LOSING 162 | EVENT_LOST 163 | EVENT_UNAVAILABLE 164 | EVENT_CAPABILITIES_CHANGED 165 | EVENT_SUSPENDED 166 | EVENT_RESUMED 167 | EVENT_LINK_PROPERTIES_CHANGED 168 | EVENT_BLOCKED_STATUS_CHANGED; 169 170 private int mEvents; 171 public String mId; 172 private long mCreateTimestamp; 173 174 /** Called in >= Android S where super(int) does exist. */ NetworkCallback(int events)175 private NetworkCallback(int events) { 176 super(ConnectivityManager.NetworkCallback.FLAG_INCLUDE_LOCATION_INFO); 177 init(events); 178 } 179 180 /** 181 * Called in <= Android R where super(int) doesn't exist. 182 * @param ignore placeholder argument to differentiate between R and S constructors' method 183 * signatures. 184 */ NetworkCallback(int events, boolean ignore)185 private NetworkCallback(int events, boolean ignore) { 186 super(); 187 init(events); 188 } 189 init(int events)190 private void init(int events) { 191 mEvents = events; 192 mId = this.toString(); 193 mCreateTimestamp = System.currentTimeMillis(); 194 } 195 startListeningForEvents(int events)196 public void startListeningForEvents(int events) { 197 mEvents |= events & EVENT_ALL; 198 } 199 stopListeningForEvents(int events)200 public void stopListeningForEvents(int events) { 201 mEvents &= ~(events & EVENT_ALL); 202 } 203 204 @Override onPreCheck(Network network)205 public void onPreCheck(Network network) { 206 Log.d("NetworkCallback onPreCheck"); 207 if ((mEvents & EVENT_PRECHECK) == EVENT_PRECHECK) { 208 mEventFacade.postEvent( 209 ConnectivityConstants.EventNetworkCallback, 210 new ConnectivityEvents.NetworkCallbackEventBase( 211 mId, 212 getNetworkCallbackEventString(EVENT_PRECHECK), mCreateTimestamp)); 213 } 214 } 215 216 @Override onAvailable(Network network)217 public void onAvailable(Network network) { 218 Log.d("NetworkCallback onAvailable"); 219 if ((mEvents & EVENT_AVAILABLE) == EVENT_AVAILABLE) { 220 mEventFacade.postEvent( 221 ConnectivityConstants.EventNetworkCallback, 222 new ConnectivityEvents.NetworkCallbackEventBase( 223 mId, 224 getNetworkCallbackEventString(EVENT_AVAILABLE), mCreateTimestamp)); 225 } 226 } 227 228 @Override onLosing(Network network, int maxMsToLive)229 public void onLosing(Network network, int maxMsToLive) { 230 Log.d("NetworkCallback onLosing"); 231 if ((mEvents & EVENT_LOSING) == EVENT_LOSING) { 232 mEventFacade.postEvent( 233 ConnectivityConstants.EventNetworkCallback, 234 new ConnectivityEvents.NetworkCallbackEventOnLosing( 235 mId, 236 getNetworkCallbackEventString(EVENT_LOSING), mCreateTimestamp, 237 maxMsToLive)); 238 } 239 } 240 241 @Override onLost(Network network)242 public void onLost(Network network) { 243 Log.d("NetworkCallback onLost"); 244 if ((mEvents & EVENT_LOST) == EVENT_LOST) { 245 mEventFacade.postEvent( 246 ConnectivityConstants.EventNetworkCallback, 247 new ConnectivityEvents.NetworkCallbackEventBase( 248 mId, 249 getNetworkCallbackEventString(EVENT_LOST), mCreateTimestamp)); 250 } 251 } 252 253 @Override onUnavailable()254 public void onUnavailable() { 255 Log.d("NetworkCallback onUnavailable"); 256 if ((mEvents & EVENT_UNAVAILABLE) == EVENT_UNAVAILABLE) { 257 mEventFacade.postEvent( 258 ConnectivityConstants.EventNetworkCallback, 259 new ConnectivityEvents.NetworkCallbackEventBase( 260 mId, 261 getNetworkCallbackEventString(EVENT_UNAVAILABLE), mCreateTimestamp)); 262 } 263 } 264 265 @Override onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities)266 public void onCapabilitiesChanged(Network network, 267 NetworkCapabilities networkCapabilities) { 268 Log.d("NetworkCallback onCapabilitiesChanged. RSSI:" + 269 networkCapabilities.getSignalStrength()); 270 if ((mEvents & EVENT_CAPABILITIES_CHANGED) == EVENT_CAPABILITIES_CHANGED) { 271 mEventFacade.postEvent( 272 ConnectivityConstants.EventNetworkCallback, 273 new ConnectivityEvents.NetworkCallbackEventOnCapabilitiesChanged( 274 mId, 275 getNetworkCallbackEventString(EVENT_CAPABILITIES_CHANGED), mCreateTimestamp, 276 networkCapabilities)); 277 } 278 } 279 280 @Override onBlockedStatusChanged(Network network, boolean blocked)281 public void onBlockedStatusChanged(Network network, boolean blocked) { 282 Log.d("NetworkCallback onBlockedStatusChanged"); 283 if ((mEvents & EVENT_BLOCKED_STATUS_CHANGED) == EVENT_BLOCKED_STATUS_CHANGED) { 284 mEventFacade.postEvent( 285 ConnectivityConstants.EventNetworkCallback, 286 new ConnectivityEvents.NetworkCallbackEventBase( 287 mId, 288 getNetworkCallbackEventString(EVENT_BLOCKED_STATUS_CHANGED), 289 mCreateTimestamp)); 290 } 291 } 292 293 @Override onNetworkSuspended(Network network)294 public void onNetworkSuspended(Network network) { 295 Log.d("NetworkCallback onNetworkSuspended"); 296 if ((mEvents & EVENT_SUSPENDED) == EVENT_SUSPENDED) { 297 mEventFacade.postEvent( 298 ConnectivityConstants.EventNetworkCallback, 299 new ConnectivityEvents.NetworkCallbackEventBase( 300 mId, 301 getNetworkCallbackEventString(EVENT_SUSPENDED), mCreateTimestamp)); 302 } 303 } 304 305 @Override onLinkPropertiesChanged(Network network, LinkProperties linkProperties)306 public void onLinkPropertiesChanged(Network network, 307 LinkProperties linkProperties) { 308 Log.d("NetworkCallback onLinkPropertiesChanged"); 309 if ((mEvents & EVENT_LINK_PROPERTIES_CHANGED) == EVENT_LINK_PROPERTIES_CHANGED) { 310 mEventFacade.postEvent( 311 ConnectivityConstants.EventNetworkCallback, 312 new ConnectivityEvents.NetworkCallbackEventOnLinkPropertiesChanged(mId, 313 getNetworkCallbackEventString(EVENT_LINK_PROPERTIES_CHANGED), 314 mCreateTimestamp, 315 linkProperties.getInterfaceName())); 316 } 317 } 318 319 @Override onNetworkResumed(Network network)320 public void onNetworkResumed(Network network) { 321 Log.d("NetworkCallback onNetworkResumed"); 322 if ((mEvents & EVENT_RESUMED) == EVENT_RESUMED) { 323 mEventFacade.postEvent( 324 ConnectivityConstants.EventNetworkCallback, 325 new ConnectivityEvents.NetworkCallbackEventBase( 326 mId, 327 getNetworkCallbackEventString(EVENT_RESUMED), mCreateTimestamp)); 328 } 329 } 330 } 331 getNetworkCallbackEvent(String event)332 private static int getNetworkCallbackEvent(String event) { 333 switch (event) { 334 case ConnectivityConstants.NetworkCallbackPreCheck: 335 return NetworkCallback.EVENT_PRECHECK; 336 case ConnectivityConstants.NetworkCallbackAvailable: 337 return NetworkCallback.EVENT_AVAILABLE; 338 case ConnectivityConstants.NetworkCallbackLosing: 339 return NetworkCallback.EVENT_LOSING; 340 case ConnectivityConstants.NetworkCallbackLost: 341 return NetworkCallback.EVENT_LOST; 342 case ConnectivityConstants.NetworkCallbackUnavailable: 343 return NetworkCallback.EVENT_UNAVAILABLE; 344 case ConnectivityConstants.NetworkCallbackCapabilitiesChanged: 345 return NetworkCallback.EVENT_CAPABILITIES_CHANGED; 346 case ConnectivityConstants.NetworkCallbackSuspended: 347 return NetworkCallback.EVENT_SUSPENDED; 348 case ConnectivityConstants.NetworkCallbackResumed: 349 return NetworkCallback.EVENT_RESUMED; 350 case ConnectivityConstants.NetworkCallbackLinkPropertiesChanged: 351 return NetworkCallback.EVENT_LINK_PROPERTIES_CHANGED; 352 case ConnectivityConstants.NetworkCallbackBlockedStatusChanged: 353 return NetworkCallback.EVENT_BLOCKED_STATUS_CHANGED; 354 } 355 return NetworkCallback.EVENT_INVALID; 356 } 357 getNetworkCallbackEventString(int event)358 private static String getNetworkCallbackEventString(int event) { 359 switch (event) { 360 case NetworkCallback.EVENT_PRECHECK: 361 return ConnectivityConstants.NetworkCallbackPreCheck; 362 case NetworkCallback.EVENT_AVAILABLE: 363 return ConnectivityConstants.NetworkCallbackAvailable; 364 case NetworkCallback.EVENT_LOSING: 365 return ConnectivityConstants.NetworkCallbackLosing; 366 case NetworkCallback.EVENT_LOST: 367 return ConnectivityConstants.NetworkCallbackLost; 368 case NetworkCallback.EVENT_UNAVAILABLE: 369 return ConnectivityConstants.NetworkCallbackUnavailable; 370 case NetworkCallback.EVENT_CAPABILITIES_CHANGED: 371 return ConnectivityConstants.NetworkCallbackCapabilitiesChanged; 372 case NetworkCallback.EVENT_SUSPENDED: 373 return ConnectivityConstants.NetworkCallbackSuspended; 374 case NetworkCallback.EVENT_RESUMED: 375 return ConnectivityConstants.NetworkCallbackResumed; 376 case NetworkCallback.EVENT_LINK_PROPERTIES_CHANGED: 377 return ConnectivityConstants.NetworkCallbackLinkPropertiesChanged; 378 case NetworkCallback.EVENT_BLOCKED_STATUS_CHANGED: 379 return ConnectivityConstants.NetworkCallbackBlockedStatusChanged; 380 } 381 return ConnectivityConstants.NetworkCallbackInvalid; 382 } 383 384 /** 385 * Callbacks used in ConnectivityManager to confirm tethering has started/failed. 386 */ 387 class OnStartTetheringCallback extends ConnectivityManager.OnStartTetheringCallback { 388 @Override onTetheringStarted()389 public void onTetheringStarted() { 390 mEventFacade.postEvent(ConnectivityConstants.TetheringStartedCallback, null); 391 } 392 393 @Override onTetheringFailed()394 public void onTetheringFailed() { 395 mEventFacade.postEvent(ConnectivityConstants.TetheringFailedCallback, null); 396 } 397 } 398 399 private final ConnectivityManager mManager; 400 private NetworkPolicyManager mNetPolicyManager; 401 private NetworkStatsManager mNetStatsManager; 402 private final Service mService; 403 private final Context mContext; 404 private final ConnectivityReceiver mConnectivityReceiver; 405 private final EventFacade mEventFacade; 406 private NetworkCallback mNetworkCallback; 407 private TelephonyManager mTelephonyManager; 408 private static HashMap<String, NetworkCallback> mNetworkCallbackMap = 409 new HashMap<String, NetworkCallback>(); 410 private boolean mTrackingConnectivityStateChange; 411 ConnectivityManagerFacade(FacadeManager manager)412 public ConnectivityManagerFacade(FacadeManager manager) { 413 super(manager); 414 mService = manager.getService(); 415 mContext = mService.getBaseContext(); 416 mManager = (ConnectivityManager) mService.getSystemService(Context.CONNECTIVITY_SERVICE); 417 mNetPolicyManager = NetworkPolicyManager.from(mContext); 418 mNetStatsManager = (NetworkStatsManager) 419 mService.getSystemService(Context.NETWORK_STATS_SERVICE); 420 mEventFacade = manager.getReceiver(EventFacade.class); 421 mConnectivityReceiver = new ConnectivityReceiver(); 422 mTrackingConnectivityStateChange = false; 423 mTelephonyManager = (TelephonyManager) mService.getSystemService(Context.TELEPHONY_SERVICE); 424 } 425 426 @Rpc(description = "Listen for connectivity changes") connectivityStartTrackingConnectivityStateChange()427 public void connectivityStartTrackingConnectivityStateChange() { 428 if (!mTrackingConnectivityStateChange) { 429 mTrackingConnectivityStateChange = true; 430 mContext.registerReceiver(mConnectivityReceiver, 431 new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); 432 } 433 } 434 435 @Rpc(description = "start listening for NetworkCallback Event") connectivityNetworkCallbackStartListeningForEvent(String key, String eventString)436 public Boolean connectivityNetworkCallbackStartListeningForEvent(String key, String eventString) { 437 NetworkCallback mNetworkCallback = mNetworkCallbackMap.get(key); 438 if (mNetworkCallback != null) { 439 int event = getNetworkCallbackEvent(eventString); 440 if (event == NetworkCallback.EVENT_INVALID) { 441 return false; 442 } 443 mNetworkCallback.startListeningForEvents(event); 444 return true; 445 } else { 446 return false; 447 } 448 } 449 450 @Rpc(description = "stop listening for NetworkCallback Event") connectivityNetworkCallbackStopListeningForEvent(String key, String eventString)451 public Boolean connectivityNetworkCallbackStopListeningForEvent(String key, String eventString) { 452 NetworkCallback mNetworkCallback = mNetworkCallbackMap.get(key); 453 if (mNetworkCallback != null) { 454 int event = getNetworkCallbackEvent(eventString); 455 if (event == NetworkCallback.EVENT_INVALID) { 456 return false; 457 } 458 mNetworkCallback.stopListeningForEvents(event); 459 return true; 460 } else { 461 return false; 462 } 463 } 464 465 @Rpc(description = "Set Rssi Threshold Monitor") connectivitySetRssiThresholdMonitor(Integer rssi)466 public String connectivitySetRssiThresholdMonitor(Integer rssi) { 467 Log.d("SL4A:setRssiThresholdMonitor rssi = " + rssi); 468 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 469 builder.setSignalStrength((int) rssi); 470 builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); 471 NetworkRequest networkRequest = builder.build(); 472 mNetworkCallback = newNetworkCallback(NetworkCallback.EVENT_ALL); 473 mManager.registerNetworkCallback(networkRequest, mNetworkCallback); 474 String key = mNetworkCallback.mId; 475 mNetworkCallbackMap.put(key, mNetworkCallback); 476 return key; 477 } 478 479 @Rpc(description = "Stop Rssi Threshold Monitor") connectivityStopRssiThresholdMonitor(String key)480 public Boolean connectivityStopRssiThresholdMonitor(String key) { 481 Log.d("SL4A:stopRssiThresholdMonitor key = " + key); 482 return connectivityUnregisterNetworkCallback(key); 483 } 484 buildNetworkRequestFromJson(JSONObject configJson)485 private NetworkRequest buildNetworkRequestFromJson(JSONObject configJson) 486 throws JSONException { 487 return makeNetworkRequestBuilderFromJson(configJson).build(); 488 } 489 buildWifiAwareNetworkRequestFromJson(JSONObject configJson)490 private NetworkRequest buildWifiAwareNetworkRequestFromJson(JSONObject configJson) 491 throws JSONException { 492 final NetworkRequest.Builder builder = makeNetworkRequestBuilderFromJson(configJson); 493 if (configJson.has("NetworkSpecifier")) { 494 final String strSpecifier = configJson.getString("NetworkSpecifier"); 495 Log.d("build NetworkSpecifier" + strSpecifier); 496 final NetworkSpecifier specifier = WifiAwareManagerFacade.getNetworkSpecifier( 497 new JSONObject(strSpecifier)); 498 builder.setNetworkSpecifier(specifier); 499 } 500 return builder.build(); 501 } 502 makeNetworkRequestBuilderFromJson(JSONObject configJson)503 private NetworkRequest.Builder makeNetworkRequestBuilderFromJson(JSONObject configJson) 504 throws JSONException { 505 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 506 507 if (configJson.has("ClearCapabilities")) { 508 /* the 'ClearCapabilities' property does not have a value (that we use). Its presence 509 is used to clear the capabilities of the constructed network request (which is 510 constructed with some default capabilities already present). */ 511 Log.d("build ClearCapabilities"); 512 builder.clearCapabilities(); 513 } 514 if (configJson.has(ConnectivityConstants.NET_CAPABILITIES_TRANSPORT_TYPE)) { 515 Log.d("build TransportType" 516 + configJson.getInt(ConnectivityConstants.NET_CAPABILITIES_TRANSPORT_TYPE)); 517 builder.addTransportType( 518 configJson.getInt(ConnectivityConstants.NET_CAPABILITIES_TRANSPORT_TYPE)); 519 } 520 if (configJson.has("SignalStrength")) { 521 Log.d("build SignalStrength" + configJson.getInt("SignalStrength")); 522 builder.setSignalStrength(configJson.getInt("SignalStrength")); 523 } 524 if (configJson.has(ConnectivityConstants.NET_CAPABILITIES_CAPABILITIES)) { 525 JSONArray capabilities = 526 configJson.getJSONArray(ConnectivityConstants.NET_CAPABILITIES_CAPABILITIES); 527 for (int i = 0; i < capabilities.length(); i++) { 528 Log.d("build Capability" + capabilities.getInt(i)); 529 builder.addCapability(capabilities.getInt(i)); 530 } 531 } 532 if (configJson.has("LinkUpstreamBandwidthKbps")) { 533 Log.d("build LinkUpstreamBandwidthKbps" + configJson.getInt( 534 "LinkUpstreamBandwidthKbps")); 535 builder.setLinkUpstreamBandwidthKbps(configJson.getInt( 536 "LinkUpstreamBandwidthKbps")); 537 } 538 if (configJson.has("LinkDownstreamBandwidthKbps")) { 539 Log.d("build LinkDownstreamBandwidthKbps" + configJson.getInt( 540 "LinkDownstreamBandwidthKbps")); 541 builder.setLinkDownstreamBandwidthKbps(configJson.getInt( 542 "LinkDownstreamBandwidthKbps")); 543 } 544 return builder; 545 } 546 547 @Rpc(description = "register a network callback") connectivityRegisterNetworkCallback(@pcParametername = "configJson") JSONObject configJson)548 public String connectivityRegisterNetworkCallback(@RpcParameter(name = "configJson") 549 JSONObject configJson) throws JSONException { 550 NetworkRequest networkRequest = buildNetworkRequestFromJson(configJson); 551 mNetworkCallback = newNetworkCallback(NetworkCallback.EVENT_ALL); 552 mManager.registerNetworkCallback(networkRequest, mNetworkCallback); 553 String key = mNetworkCallback.mId; 554 mNetworkCallbackMap.put(key, mNetworkCallback); 555 return key; 556 } 557 558 @Rpc(description = "unregister a network callback") connectivityUnregisterNetworkCallback(@pcParametername = "key") String key)559 public Boolean connectivityUnregisterNetworkCallback(@RpcParameter(name = "key") 560 String key) { 561 mNetworkCallback = mNetworkCallbackMap.get(key); 562 if (mNetworkCallback != null) { 563 mNetworkCallbackMap.remove(key); 564 mManager.unregisterNetworkCallback(mNetworkCallback); 565 return true; 566 } else { 567 return false; 568 } 569 } 570 571 @Rpc(description = "register a default network callback") connectivityRegisterDefaultNetworkCallback()572 public String connectivityRegisterDefaultNetworkCallback() { 573 mNetworkCallback = newNetworkCallback(NetworkCallback.EVENT_ALL); 574 mManager.registerDefaultNetworkCallback(mNetworkCallback); 575 String key = mNetworkCallback.mId; 576 mNetworkCallbackMap.put(key, mNetworkCallback); 577 return key; 578 } 579 580 @Rpc(description = "request a network") connectivityRequestNetwork(@pcParametername = "configJson") JSONObject configJson)581 public String connectivityRequestNetwork(@RpcParameter(name = "configJson") 582 JSONObject configJson) throws JSONException { 583 NetworkRequest networkRequest = buildNetworkRequestFromJson(configJson); 584 mNetworkCallback = newNetworkCallback(NetworkCallback.EVENT_ALL); 585 mManager.requestNetwork(networkRequest, mNetworkCallback); 586 String key = mNetworkCallback.mId; 587 mNetworkCallbackMap.put(key, mNetworkCallback); 588 return key; 589 } 590 591 @Rpc(description = "Request a Wi-Fi Aware network") connectivityRequestWifiAwareNetwork(@pcParametername = "configJson") JSONObject configJson)592 public String connectivityRequestWifiAwareNetwork(@RpcParameter(name = "configJson") 593 JSONObject configJson) throws JSONException { 594 NetworkRequest networkRequest = buildWifiAwareNetworkRequestFromJson(configJson); 595 mNetworkCallback = newNetworkCallback(NetworkCallback.EVENT_ALL); 596 mManager.requestNetwork(networkRequest, mNetworkCallback); 597 String key = mNetworkCallback.mId; 598 mNetworkCallbackMap.put(key, mNetworkCallback); 599 return key; 600 } 601 602 /** 603 * Initiates a network request {@link NetworkRequest} using {@link WifiNetworkSpecifier}. 604 * 605 * @param wNs JSONObject Dictionary of wifi network specifier parameters 606 * @param timeoutInMs Timeout for the request. 0 indicates no timeout. 607 * @throws JSONException 608 * @throws GeneralSecurityException 609 */ 610 @Rpc(description = "Initiates a network request using the provided network specifier") connectivityRequestWifiNetwork( @pcParametername = "wifiNetworkSpecifier") JSONObject wNs, @RpcParameter(name = "timeoutInMS") Integer timeoutInMs)611 public String connectivityRequestWifiNetwork( 612 @RpcParameter(name = "wifiNetworkSpecifier") JSONObject wNs, 613 @RpcParameter(name = "timeoutInMS") Integer timeoutInMs) 614 throws JSONException, GeneralSecurityException { 615 NetworkRequest networkRequest = new NetworkRequest.Builder() 616 .addTransportType(TRANSPORT_WIFI) 617 .setNetworkSpecifier(WifiManagerFacade.genWifiNetworkSpecifier(wNs)) 618 .build(); 619 mNetworkCallback = newNetworkCallback(NetworkCallback.EVENT_ALL); 620 if (timeoutInMs != 0) { 621 mManager.requestNetwork(networkRequest, mNetworkCallback, timeoutInMs); 622 } else { 623 mManager.requestNetwork(networkRequest, mNetworkCallback); 624 } 625 String key = mNetworkCallback.mId; 626 mNetworkCallbackMap.put(key, mNetworkCallback); 627 return key; 628 } 629 630 @Rpc(description = "Stop listening for connectivity changes") connectivityStopTrackingConnectivityStateChange()631 public void connectivityStopTrackingConnectivityStateChange() { 632 if (mTrackingConnectivityStateChange) { 633 mTrackingConnectivityStateChange = false; 634 mContext.unregisterReceiver(mConnectivityReceiver); 635 } 636 } 637 638 @Rpc(description = "Get the extra information about the network state provided by lower network layers.") connectivityNetworkGetActiveConnectionExtraInfo()639 public String connectivityNetworkGetActiveConnectionExtraInfo() { 640 NetworkInfo current = mManager.getActiveNetworkInfo(); 641 if (current == null) { 642 Log.d("No network is active at the moment."); 643 return null; 644 } 645 return current.getExtraInfo(); 646 } 647 648 @Rpc(description = "Return the subtype name of the current network, null if not connected") connectivityNetworkGetActiveConnectionSubtypeName()649 public String connectivityNetworkGetActiveConnectionSubtypeName() { 650 NetworkInfo current = mManager.getActiveNetworkInfo(); 651 if (current == null) { 652 Log.d("No network is active at the moment."); 653 return null; 654 } 655 return current.getSubtypeName(); 656 } 657 658 @Rpc(description = "Return a human-readable name describe the type of the network, e.g. WIFI") connectivityNetworkGetActiveConnectionTypeName()659 public String connectivityNetworkGetActiveConnectionTypeName() { 660 NetworkInfo current = mManager.getActiveNetworkInfo(); 661 if (current == null) { 662 Log.d("No network is active at the moment."); 663 return null; 664 } 665 return current.getTypeName(); 666 } 667 668 @Rpc(description = "Get connection status information about all network types supported by the device.") connectivityNetworkGetAllInfo()669 public NetworkInfo[] connectivityNetworkGetAllInfo() { 670 return mManager.getAllNetworkInfo(); 671 } 672 673 @Rpc(description = "Get connection status information about all network types supported by the device.") connectivityNetworkGetAllCapabilities()674 public NetworkCapabilities[] connectivityNetworkGetAllCapabilities() { 675 Network[] networks = mManager.getAllNetworks(); 676 NetworkCapabilities[] networkCapabilties = new NetworkCapabilities[networks.length]; 677 for (int i = 0; i < networks.length; i++) { 678 networkCapabilties[i] = mManager.getNetworkCapabilities(networks[i]); 679 } 680 return networkCapabilties; 681 } 682 683 @Rpc(description = "Check whether the active network is connected to the Internet.") connectivityNetworkIsConnected()684 public Boolean connectivityNetworkIsConnected() { 685 NetworkInfo current = mManager.getActiveNetworkInfo(); 686 if (current == null) { 687 Log.d("No network is active at the moment."); 688 return false; 689 } 690 return current.isConnected(); 691 } 692 693 @Rpc(description = "Checks the airplane mode setting.", 694 returns = "True if airplane mode is enabled.") connectivityCheckAirplaneMode()695 public Boolean connectivityCheckAirplaneMode() { 696 try { 697 return Settings.Global.getInt(mService.getContentResolver(), 698 Settings.Global.AIRPLANE_MODE_ON) == AIRPLANE_MODE_ON; 699 } catch (Settings.SettingNotFoundException e) { 700 Log.e("Settings.Global.AIRPLANE_MODE_ON not found!"); 701 return false; 702 } 703 } 704 705 @Rpc(description = "Toggles airplane mode on and off.", 706 returns = "True if airplane mode is enabled.") connectivityToggleAirplaneMode(@pcParametername = "enabled") @pcOptional Boolean enabled)707 public void connectivityToggleAirplaneMode(@RpcParameter(name = "enabled") 708 @RpcOptional 709 Boolean enabled) { 710 if (enabled == null) { 711 enabled = !connectivityCheckAirplaneMode(); 712 } 713 mManager.setAirplaneMode(enabled); 714 } 715 716 /** 717 * Check global data roaming setting. 718 * @return True if roaming is enabled; false otherwise. 719 */ 720 @Rpc(description = "Checks data roaming mode setting.", 721 returns = "True if data roaming mode is enabled.") connectivityCheckDataRoamingMode()722 public Boolean connectivityCheckDataRoamingMode() { 723 return mTelephonyManager.isDataRoamingEnabled(); 724 } 725 726 /** 727 * Enable or disable data roaming. 728 * @param roaming 1: Enable data roaming; 0: Disable data roaming. 729 * @return True for setting roaming mode successfully; false otherwise. 730 */ 731 @Rpc(description = "Set Data Roaming Enabled or Disabled") connectivitySetDataRoaming( @pcParametername = "roaming") Integer roaming)732 public boolean connectivitySetDataRoaming( 733 @RpcParameter(name = "roaming") Integer roaming) { 734 Log.d("connectivitySetDataRoaming by SubscriptionManager"); 735 return Settings.Global.putInt(mService.getContentResolver(), 736 Settings.Global.DATA_ROAMING, roaming); 737 } 738 739 @Rpc(description = "Check if tethering supported or not.", 740 returns = "True if tethering is supported.") connectivityIsTetheringSupported()741 public boolean connectivityIsTetheringSupported() { 742 return mManager.isTetheringSupported(); 743 } 744 745 @Rpc(description = "Call to start tethering with a provisioning check if needed") connectivityStartTethering(@pcParametername = "type") Integer type, @RpcParameter(name = "showProvisioningUi") Boolean showProvisioningUi)746 public void connectivityStartTethering(@RpcParameter(name = "type") Integer type, 747 @RpcParameter(name = "showProvisioningUi") Boolean showProvisioningUi) { 748 Log.d("startTethering for type: " + type + " showProvUi: " + showProvisioningUi); 749 OnStartTetheringCallback tetherCallback = new OnStartTetheringCallback(); 750 mManager.startTethering(type, showProvisioningUi, tetherCallback); 751 } 752 753 @Rpc(description = "Call to stop tethering") connectivityStopTethering(@pcParametername = "type") Integer type)754 public void connectivityStopTethering(@RpcParameter(name = "type") Integer type) { 755 Log.d("stopTethering for type: " + type); 756 mManager.stopTethering(type); 757 } 758 getInetAddrsForInterface(String ifaceName)759 private Enumeration<InetAddress> getInetAddrsForInterface(String ifaceName) { 760 NetworkInterface iface = null; 761 try { 762 iface = NetworkInterface.getByName(ifaceName); 763 } catch (SocketException e) { 764 return null; 765 } 766 767 if (iface == null) 768 return null; 769 return iface.getInetAddresses(); 770 } 771 772 @Rpc(description = "Returns the link local IPv6 address of the interface.") connectivityGetLinkLocalIpv6Address(@pcParametername = "ifaceName") String ifaceName)773 public String connectivityGetLinkLocalIpv6Address(@RpcParameter(name = "ifaceName") 774 String ifaceName) { 775 Inet6Address inet6Address = null; 776 Enumeration<InetAddress> inetAddresses = getInetAddrsForInterface(ifaceName); 777 if (inetAddresses == null) { 778 return null; 779 } 780 781 while (inetAddresses.hasMoreElements()) { 782 InetAddress addr = inetAddresses.nextElement(); 783 if (addr instanceof Inet6Address) { 784 if (((Inet6Address) addr).isLinkLocalAddress()) { 785 inet6Address = (Inet6Address) addr; 786 break; 787 } 788 } 789 } 790 791 if (inet6Address == null) { 792 return null; 793 } 794 795 return inet6Address.getHostAddress(); 796 } 797 798 @Rpc(description = "Return IPv4 address of an interface") connectivityGetIPv4Addresses( @pcParametername = "ifaceName") String ifaceName)799 public List<String> connectivityGetIPv4Addresses( 800 @RpcParameter(name = "ifaceName") String ifaceName) { 801 Enumeration<InetAddress> inetAddresses 802 = getInetAddrsForInterface(ifaceName); 803 if (inetAddresses == null) 804 return null; 805 806 List<String> inetAddrs = new ArrayList<String>(); 807 while (inetAddresses.hasMoreElements()) { 808 InetAddress addr = inetAddresses.nextElement(); 809 if (addr instanceof Inet4Address) { 810 Inet4Address inet4Address = (Inet4Address) addr; 811 inetAddrs.add(inet4Address.getHostAddress()); 812 } 813 } 814 815 return inetAddrs; 816 } 817 818 @Rpc(description = "Return IPv6 addrs of an interface except link local") connectivityGetIPv6Addresses( @pcParametername = "ifaceName") String ifaceName)819 public List<String> connectivityGetIPv6Addresses( 820 @RpcParameter(name = "ifaceName") String ifaceName) { 821 Enumeration<InetAddress> inetAddresses 822 = getInetAddrsForInterface(ifaceName); 823 if (inetAddresses == null) 824 return null; 825 826 List<String> inetAddrs = new ArrayList<String>(); 827 while (inetAddresses.hasMoreElements()) { 828 InetAddress addr = inetAddresses.nextElement(); 829 if (addr instanceof Inet6Address) { 830 if (((Inet6Address) addr).isLinkLocalAddress()) 831 continue; 832 Inet6Address inet6Address = (Inet6Address) addr; 833 inetAddrs.add(inet6Address.getHostAddress()); 834 } 835 } 836 837 return inetAddrs; 838 } 839 840 @Rpc(description = "Returns active link properties") connectivityGetActiveLinkProperties()841 public LinkProperties connectivityGetActiveLinkProperties() { 842 return mManager.getActiveLinkProperties(); 843 } 844 845 /** 846 * Get the IPv4 default gateway for the active network. 847 */ 848 @Rpc(description = "Return default gateway of the active network") connectivityGetIPv4DefaultGateway()849 public String connectivityGetIPv4DefaultGateway() { 850 LinkProperties linkProp = mManager.getActiveLinkProperties(); 851 List<RouteInfo> routeInfos = linkProp.getRoutes(); 852 for (RouteInfo routeInfo: routeInfos) { 853 if (routeInfo.isIPv4Default()) { 854 return routeInfo.getGateway().toString().split("/")[1]; 855 } 856 } 857 return null; 858 } 859 860 @Rpc(description = "Returns all IP addresses of the active link") connectivityGetAllAddressesOfActiveLink()861 public List<InetAddress> connectivityGetAllAddressesOfActiveLink() { 862 LinkProperties linkProp = mManager.getActiveLinkProperties(); 863 return linkProp.getAllAddresses(); 864 } 865 866 @Rpc(description = "Check if active link has default IPv6 route") connectivityHasIPv6DefaultRoute()867 public boolean connectivityHasIPv6DefaultRoute() { 868 LinkProperties linkProp = mManager.getActiveLinkProperties(); 869 return linkProp.hasIPv6DefaultRoute(); 870 } 871 872 @Rpc(description = "Factory reset of network policies") connectivityFactoryResetNetworkPolicies(String subscriberId)873 public void connectivityFactoryResetNetworkPolicies(String subscriberId) { 874 mNetPolicyManager.factoryReset(subscriberId); 875 } 876 877 /** 878 * Method to set data warning limit on the device. 879 */ 880 @Rpc(description = "Set data warning limit for subscriber ID") connectivitySetDataWarningLimit(String subscriberId, Long dataLimit)881 public void connectivitySetDataWarningLimit(String subscriberId, Long dataLimit) { 882 NetworkPolicy[] allPolicies = mNetPolicyManager.getNetworkPolicies(); 883 for (int i = 0; i < allPolicies.length; i++) { 884 String subId = allPolicies[i].template.getSubscriberId(); 885 if (subId != null && subId.equals(subscriberId)) { 886 allPolicies[i].warningBytes = dataLimit.longValue(); 887 break; 888 } 889 } 890 mNetPolicyManager.setNetworkPolicies(allPolicies); 891 } 892 893 /** 894 * Method to set data usage limit on the device. 895 */ 896 @Rpc(description = "Set data usage limit for subscriber ID") connectivitySetDataUsageLimit(String subscriberId, Long dataLimit)897 public void connectivitySetDataUsageLimit(String subscriberId, Long dataLimit) { 898 NetworkPolicy[] allPolicies = mNetPolicyManager.getNetworkPolicies(); 899 for (int i = 0; i < allPolicies.length; i++) { 900 String subId = allPolicies[i].template.getSubscriberId(); 901 if (subId != null && subId.equals(subscriberId)) { 902 allPolicies[i].limitBytes = dataLimit.longValue(); 903 break; 904 } 905 } 906 mNetPolicyManager.setNetworkPolicies(allPolicies); 907 } 908 909 /** 910 * Method to get data usage limit on the device. 911 */ 912 @Rpc(description = "Get data usage limit for subscriber ID") connectivityGetDataUsageLimit(String subscriberId)913 public long connectivityGetDataUsageLimit(String subscriberId) { 914 NetworkPolicy[] allPolicies = mNetPolicyManager.getNetworkPolicies(); 915 for (int i = 0; i < allPolicies.length; i++) { 916 String subId = allPolicies[i].template.getSubscriberId(); 917 if (subId != null && subId.equals(subscriberId)) return allPolicies[i].limitBytes; 918 } 919 return -1; 920 } 921 922 /** 923 * Method to get data warning limit on the device 924 */ 925 @Rpc(description = "Get data warning limit for subscriber ID") connectivityGetDataWarningLimit(String subscriberId)926 public long connectivityGetDataWarningLimit(String subscriberId) { 927 NetworkPolicy[] allPolicies = mNetPolicyManager.getNetworkPolicies(); 928 for (int i = 0; i < allPolicies.length; i++) { 929 String subId = allPolicies[i].template.getSubscriberId(); 930 if (subId != null && subId.equals(subscriberId)) return allPolicies[i].warningBytes; 931 } 932 return -1; 933 } 934 935 @Rpc(description = "Get network stats for device") connectivityQuerySummaryForDevice(Integer connType, String subscriberId, Long startTime, Long endTime)936 public long connectivityQuerySummaryForDevice(Integer connType, 937 String subscriberId, Long startTime, Long endTime) 938 throws SecurityException, RemoteException { 939 Bucket bucket = mNetStatsManager.querySummaryForDevice( 940 connType, subscriberId, startTime, endTime); 941 return bucket.getTxBytes() + bucket.getRxBytes(); 942 } 943 944 @Rpc(description = "Get network stats for device - Rx bytes") connectivityQuerySummaryForDeviceRxBytes(Integer connType, String subscriberId, Long startTime, Long endTime)945 public long connectivityQuerySummaryForDeviceRxBytes(Integer connType, 946 String subscriberId, Long startTime, Long endTime) 947 throws SecurityException, RemoteException { 948 Bucket bucket = mNetStatsManager.querySummaryForDevice( 949 connType, subscriberId, startTime, endTime); 950 return bucket.getRxBytes(); 951 } 952 953 @Rpc(description = "Get network stats for UID") connectivityQueryDetailsForUid(Integer connType, String subscriberId, Long startTime, Long endTime, Integer uid)954 public long connectivityQueryDetailsForUid(Integer connType, 955 String subscriberId, Long startTime, Long endTime, Integer uid) 956 throws SecurityException, RemoteException { 957 long totalData = 0; 958 NetworkStats netStats = mNetStatsManager.queryDetailsForUid( 959 connType, subscriberId, startTime, endTime, uid); 960 Bucket bucket = new Bucket(); 961 while(netStats.hasNextBucket() && netStats.getNextBucket(bucket)) { 962 totalData += bucket.getTxBytes() + bucket.getRxBytes(); 963 } 964 netStats.close(); 965 return totalData; 966 } 967 968 @Rpc(description = "Get network stats for UID - Rx bytes") connectivityQueryDetailsForUidRxBytes(Integer connType, String subscriberId, Long startTime, Long endTime, Integer uid)969 public long connectivityQueryDetailsForUidRxBytes(Integer connType, 970 String subscriberId, Long startTime, Long endTime, Integer uid) 971 throws SecurityException, RemoteException { 972 long rxBytes = 0; 973 NetworkStats netStats = mNetStatsManager.queryDetailsForUid( 974 connType, subscriberId, startTime, endTime, uid); 975 Bucket bucket = new Bucket(); 976 while(netStats.hasNextBucket() && netStats.getNextBucket(bucket)) { 977 rxBytes += bucket.getRxBytes(); 978 } 979 netStats.close(); 980 return rxBytes; 981 } 982 983 @Rpc(description = "Returns all interfaces on the android deivce") connectivityGetNetworkInterfaces()984 public List<NetworkInterface> connectivityGetNetworkInterfaces() { 985 List<NetworkInterface> interfaces = null; 986 try { 987 interfaces = Collections.list( 988 NetworkInterface.getNetworkInterfaces()); 989 } catch (SocketException e) { 990 return null; 991 }; 992 993 return interfaces; 994 } 995 996 /** 997 * Get multipath preference for a given network. 998 * @param networkId : network id of wifi or cell network 999 * @return Integer value of multipath preference 1000 */ 1001 @Rpc(description = "Return Multipath preference for a given network") connectivityGetMultipathPreferenceForNetwork(Long networkId)1002 public Integer connectivityGetMultipathPreferenceForNetwork(Long networkId) { 1003 Network network = sNetworkHashMap.get(networkId.longValue()); 1004 return mManager.getMultipathPreference(network); 1005 } 1006 1007 /** 1008 * Return HashMap key for Network object. 1009 * @return long value of Network object key 1010 */ 1011 @Rpc(description = "Return key to active network stored in a hash map") connectivityGetActiveNetwork()1012 public long connectivityGetActiveNetwork() { 1013 Network network = mManager.getActiveNetwork(); 1014 long id = network.getNetworkHandle(); 1015 sNetworkHashMap.put(id, network); 1016 return id; 1017 } 1018 1019 /** 1020 * Get mutlipath preference for active network. 1021 * @return Integer value of multipath preference 1022 */ 1023 @Rpc(description = "Return Multipath preference for active network") connectivityGetMultipathPreference()1024 public Integer connectivityGetMultipathPreference() { 1025 Network network = mManager.getActiveNetwork(); 1026 return mManager.getMultipathPreference(network); 1027 } 1028 1029 /** 1030 * Download file of a given url using Network#openConnection call. 1031 * @param networkId : network id of wifi or cell network 1032 * @param urlString : url in String format 1033 */ 1034 @Rpc(description = "Download file on a given network with Network#openConnection") connectivityNetworkOpenConnection(Long networkId, String urlString)1035 public void connectivityNetworkOpenConnection(Long networkId, String urlString) { 1036 Network network = sNetworkHashMap.get(networkId.longValue()); 1037 try { 1038 URL url = new URL(urlString); 1039 URLConnection urlConnection = network.openConnection(url); 1040 File outFile = FileUtils.getExternalDownload(); 1041 int lastIdx = urlString.lastIndexOf('/'); 1042 String filename = urlString.substring(lastIdx + 1); 1043 Log.d("Using name from url: " + filename); 1044 outFile = new File(outFile, filename); 1045 InputStream in = new BufferedInputStream(urlConnection.getInputStream()); 1046 OutputStream output = new FileOutputStream(outFile); 1047 ByteStreams.copy(in, output); 1048 } catch (IOException e) { 1049 Log.e("Failed to download file: " + e.toString()); 1050 } 1051 } 1052 1053 /** 1054 * Sets the global proxy using the given information. 1055 * 1056 * @param hostname hostname of the proxy 1057 * @param port port set on the proxy server 1058 * @param exclList List of hostnames excluded 1059 */ 1060 @Rpc(description = "Set global proxy") connectivitySetGlobalProxy(String hostname, Integer port, String exclList)1061 public void connectivitySetGlobalProxy(String hostname, Integer port, String exclList) { 1062 ProxyInfo proxyInfo = new ProxyInfo(hostname, port.intValue(), exclList); 1063 mManager.setGlobalProxy(proxyInfo); 1064 } 1065 1066 /** 1067 * Sets the global proxy using a PAC URI. 1068 * 1069 * @param pac PAC URI in string 1070 */ 1071 @Rpc(description = "Set global proxy with proxy autoconfig") connectivitySetGlobalPacProxy(String pac)1072 public void connectivitySetGlobalPacProxy(String pac) { 1073 Uri uri = Uri.parse(pac); 1074 ProxyInfo proxyInfo = new ProxyInfo(uri); 1075 mManager.setGlobalProxy(proxyInfo); 1076 } 1077 1078 /** 1079 * Gets the global proxy settings. 1080 * 1081 * @return ProxyInfo object in dictionary 1082 */ 1083 @Rpc(description = "Get global proxy") connectivityGetGlobalProxy()1084 public ProxyInfo connectivityGetGlobalProxy() { 1085 ProxyInfo proxyInfo = mManager.getGlobalProxy(); 1086 if (proxyInfo == null) return null; 1087 return proxyInfo; 1088 } 1089 1090 /** 1091 * Resets the global proxy settings. 1092 */ 1093 @Rpc(description = "Reset global proxy") connectivityResetGlobalProxy()1094 public void connectivityResetGlobalProxy() { 1095 mManager.setGlobalProxy(null); 1096 } 1097 1098 /** 1099 * Check if active network is metered. 1100 */ 1101 @Rpc(description = "Is active network metered") connectivityIsActiveNetworkMetered()1102 public boolean connectivityIsActiveNetworkMetered() { 1103 return mManager.isActiveNetworkMetered(); 1104 } 1105 1106 /** 1107 * Check if device connected to WiFi network 1108 */ 1109 @Rpc(description = "Is active network WiFi") connectivityIsActiveNetworkWiFi()1110 public boolean connectivityIsActiveNetworkWiFi() { 1111 NetworkInfo mWifi = mManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); 1112 return mWifi.isConnected(); 1113 } 1114 1115 @Override shutdown()1116 public void shutdown() { 1117 connectivityStopTrackingConnectivityStateChange(); 1118 for (NetworkCallback networkCallback : mNetworkCallbackMap.values()) { 1119 mManager.unregisterNetworkCallback(networkCallback); 1120 } 1121 } 1122 } 1123