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