1 /* 2 * Copyright (C) 2016 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 package com.googlecode.android_scripting.facade; 18 19 import android.app.Service; 20 import android.content.BroadcastReceiver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 import android.net.ConnectivityManager; 25 import android.net.ConnectivityManager.PacketKeepalive; 26 import android.net.ConnectivityManager.PacketKeepaliveCallback; 27 import android.net.LinkProperties; 28 import android.net.Network; 29 import android.net.NetworkCapabilities; 30 import android.net.NetworkInfo; 31 import android.net.NetworkRequest; 32 import android.os.Bundle; 33 import android.provider.Settings; 34 35 import com.googlecode.android_scripting.Log; 36 import com.googlecode.android_scripting.jsonrpc.RpcReceiver; 37 import com.googlecode.android_scripting.rpc.Rpc; 38 import com.googlecode.android_scripting.rpc.RpcOptional; 39 import com.googlecode.android_scripting.rpc.RpcParameter; 40 41 import org.json.JSONArray; 42 import org.json.JSONException; 43 import org.json.JSONObject; 44 45 import java.net.InetAddress; 46 import java.net.UnknownHostException; 47 import java.util.HashMap; 48 49 /** 50 * Access ConnectivityManager functions. 51 */ 52 public class ConnectivityManagerFacade extends RpcReceiver { 53 54 public static int AIRPLANE_MODE_OFF = 0; 55 public static int AIRPLANE_MODE_ON = 1; 56 57 class ConnectivityReceiver extends BroadcastReceiver { 58 59 @Override 60 public void onReceive(Context context, Intent intent) { 61 String action = intent.getAction(); 62 63 if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 64 Log.e("ConnectivityReceiver received non-connectivity action!"); 65 return; 66 } 67 68 Bundle b = intent.getExtras(); 69 70 if (b == null) { 71 Log.e("ConnectivityReceiver failed to receive extras!"); 72 return; 73 } 74 75 int netType = 76 b.getInt(ConnectivityManager.EXTRA_NETWORK_TYPE, 77 ConnectivityManager.TYPE_NONE); 78 79 if (netType == ConnectivityManager.TYPE_NONE) { 80 Log.i("ConnectivityReceiver received change to TYPE_NONE."); 81 return; 82 } 83 84 /* 85 * Technically there is a race condition here, but retrieving the NetworkInfo from the 86 * bundle is deprecated. See ConnectivityManager.EXTRA_NETWORK_INFO 87 */ 88 for (NetworkInfo info : mManager.getAllNetworkInfo()) { 89 if (info.getType() == netType) { 90 mEventFacade.postEvent(ConnectivityConstants.EventConnectivityChanged, info); 91 } 92 } 93 } 94 } 95 96 class PacketKeepaliveReceiver extends PacketKeepaliveCallback { 97 public static final int EVENT_INVALID = -1; 98 public static final int EVENT_NONE = 0; 99 public static final int EVENT_STARTED = 1 << 0; 100 public static final int EVENT_STOPPED = 1 << 1; 101 public static final int EVENT_ERROR = 1 << 2; 102 public static final int EVENT_ALL = EVENT_STARTED | 103 EVENT_STOPPED | 104 EVENT_ERROR; 105 private int mEvents; 106 public String mId; 107 public PacketKeepalive mPacketKeepalive; 108 109 public PacketKeepaliveReceiver(int events) { 110 super(); 111 mEvents = events; 112 mId = this.toString(); 113 } 114 115 public void startListeningForEvents(int events) { 116 mEvents |= events & EVENT_ALL; 117 } 118 119 public void stopListeningForEvents(int events) { 120 mEvents &= ~(events & EVENT_ALL); 121 } 122 123 @Override 124 public void onStarted() { 125 Log.d("PacketKeepaliveCallback on start!"); 126 if ((mEvents & EVENT_STARTED) == EVENT_STARTED) { 127 mEventFacade.postEvent( 128 ConnectivityConstants.EventPacketKeepaliveCallback, 129 new ConnectivityEvents.PacketKeepaliveEvent( 130 mId, 131 getPacketKeepaliveReceiverEventString(EVENT_STARTED))); 132 } 133 } 134 135 @Override 136 public void onStopped() { 137 Log.d("PacketKeepaliveCallback on stop!"); 138 if ((mEvents & EVENT_STOPPED) == EVENT_STOPPED) { 139 mEventFacade.postEvent( 140 ConnectivityConstants.EventPacketKeepaliveCallback, 141 new ConnectivityEvents.PacketKeepaliveEvent( 142 mId, 143 getPacketKeepaliveReceiverEventString(EVENT_STOPPED))); 144 } 145 } 146 147 @Override 148 public void onError(int error) { 149 Log.d("PacketKeepaliveCallback on error! - code:" + error); 150 if ((mEvents & EVENT_ERROR) == EVENT_ERROR) { 151 mEventFacade.postEvent( 152 ConnectivityConstants.EventPacketKeepaliveCallback, 153 new ConnectivityEvents.PacketKeepaliveEvent( 154 mId, 155 getPacketKeepaliveReceiverEventString(EVENT_ERROR))); 156 } 157 } 158 } 159 160 class NetworkCallback extends ConnectivityManager.NetworkCallback { 161 public static final int EVENT_INVALID = -1; 162 public static final int EVENT_NONE = 0; 163 public static final int EVENT_PRECHECK = 1 << 0; 164 public static final int EVENT_AVAILABLE = 1 << 1; 165 public static final int EVENT_LOSING = 1 << 2; 166 public static final int EVENT_LOST = 1 << 3; 167 public static final int EVENT_UNAVAILABLE = 1 << 4; 168 public static final int EVENT_CAPABILITIES_CHANGED = 1 << 5; 169 public static final int EVENT_SUSPENDED = 1 << 6; 170 public static final int EVENT_RESUMED = 1 << 7; 171 public static final int EVENT_LINK_PROPERTIES_CHANGED = 1 << 8; 172 public static final int EVENT_ALL = EVENT_PRECHECK | 173 EVENT_AVAILABLE | 174 EVENT_LOSING | 175 EVENT_LOST | 176 EVENT_UNAVAILABLE | 177 EVENT_CAPABILITIES_CHANGED | 178 EVENT_SUSPENDED | 179 EVENT_RESUMED | 180 EVENT_LINK_PROPERTIES_CHANGED; 181 182 private int mEvents; 183 public String mId; 184 185 public NetworkCallback(int events) { 186 super(); 187 mEvents = events; 188 mId = this.toString(); 189 } 190 191 public void startListeningForEvents(int events) { 192 mEvents |= events & EVENT_ALL; 193 } 194 195 public void stopListeningForEvents(int events) { 196 mEvents &= ~(events & EVENT_ALL); 197 } 198 199 @Override 200 public void onPreCheck(Network network) { 201 Log.d("NetworkCallback onPreCheck"); 202 if ((mEvents & EVENT_PRECHECK) == EVENT_PRECHECK) { 203 mEventFacade.postEvent( 204 ConnectivityConstants.EventNetworkCallback, 205 new ConnectivityEvents.NetworkCallbackEventBase( 206 mId, 207 getNetworkCallbackEventString(EVENT_PRECHECK))); 208 } 209 } 210 211 @Override 212 public void onAvailable(Network network) { 213 Log.d("NetworkCallback onAvailable"); 214 if ((mEvents & EVENT_AVAILABLE) == EVENT_AVAILABLE) { 215 mEventFacade.postEvent( 216 ConnectivityConstants.EventNetworkCallback, 217 new ConnectivityEvents.NetworkCallbackEventBase( 218 mId, 219 getNetworkCallbackEventString(EVENT_AVAILABLE))); 220 } 221 } 222 223 @Override 224 public void onLosing(Network network, int maxMsToLive) { 225 Log.d("NetworkCallback onLosing"); 226 if ((mEvents & EVENT_LOSING) == EVENT_LOSING) { 227 mEventFacade.postEvent( 228 ConnectivityConstants.EventNetworkCallback, 229 new ConnectivityEvents.NetworkCallbackEventOnLosing( 230 mId, 231 getNetworkCallbackEventString(EVENT_LOSING), 232 maxMsToLive)); 233 } 234 } 235 236 @Override 237 public void onLost(Network network) { 238 Log.d("NetworkCallback onLost"); 239 if ((mEvents & EVENT_LOST) == EVENT_LOST) { 240 mEventFacade.postEvent( 241 ConnectivityConstants.EventNetworkCallback, 242 new ConnectivityEvents.NetworkCallbackEventBase( 243 mId, 244 getNetworkCallbackEventString(EVENT_LOST))); 245 } 246 } 247 248 @Override 249 public void onUnavailable() { 250 Log.d("NetworkCallback onUnavailable"); 251 if ((mEvents & EVENT_UNAVAILABLE) == EVENT_UNAVAILABLE) { 252 mEventFacade.postEvent( 253 ConnectivityConstants.EventNetworkCallback, 254 new ConnectivityEvents.NetworkCallbackEventBase( 255 mId, 256 getNetworkCallbackEventString(EVENT_UNAVAILABLE))); 257 } 258 } 259 260 @Override 261 public void onCapabilitiesChanged(Network network, 262 NetworkCapabilities networkCapabilities) { 263 Log.d("NetworkCallback onCapabilitiesChanged. RSSI:" + 264 networkCapabilities.getSignalStrength()); 265 if ((mEvents & EVENT_CAPABILITIES_CHANGED) == EVENT_CAPABILITIES_CHANGED) { 266 mEventFacade.postEvent( 267 ConnectivityConstants.EventNetworkCallback, 268 new ConnectivityEvents.NetworkCallbackEventOnCapabilitiesChanged( 269 mId, 270 getNetworkCallbackEventString(EVENT_CAPABILITIES_CHANGED), 271 networkCapabilities.getSignalStrength())); 272 } 273 } 274 275 @Override 276 public void onNetworkSuspended(Network network) { 277 Log.d("NetworkCallback onNetworkSuspended"); 278 if ((mEvents & EVENT_SUSPENDED) == EVENT_SUSPENDED) { 279 mEventFacade.postEvent( 280 ConnectivityConstants.EventNetworkCallback, 281 new ConnectivityEvents.NetworkCallbackEventBase( 282 mId, 283 getNetworkCallbackEventString(EVENT_SUSPENDED))); 284 } 285 } 286 287 @Override 288 public void onLinkPropertiesChanged(Network network, 289 LinkProperties linkProperties) { 290 Log.d("NetworkCallback onLinkPropertiesChanged"); 291 if ((mEvents & EVENT_LINK_PROPERTIES_CHANGED) == EVENT_LINK_PROPERTIES_CHANGED) { 292 mEventFacade.postEvent( 293 ConnectivityConstants.EventNetworkCallback, 294 new ConnectivityEvents.NetworkCallbackEventBase( 295 mId, 296 getNetworkCallbackEventString(EVENT_LINK_PROPERTIES_CHANGED))); 297 } 298 } 299 300 @Override 301 public void onNetworkResumed(Network network) { 302 Log.d("NetworkCallback onNetworkResumed"); 303 if ((mEvents & EVENT_RESUMED) == EVENT_RESUMED) { 304 mEventFacade.postEvent( 305 ConnectivityConstants.EventNetworkCallback, 306 new ConnectivityEvents.NetworkCallbackEventBase( 307 mId, 308 getNetworkCallbackEventString(EVENT_RESUMED))); 309 } 310 } 311 } 312 313 private static int getNetworkCallbackEvent(String event) { 314 switch (event) { 315 case ConnectivityConstants.NetworkCallbackPreCheck: 316 return NetworkCallback.EVENT_PRECHECK; 317 case ConnectivityConstants.NetworkCallbackAvailable: 318 return NetworkCallback.EVENT_AVAILABLE; 319 case ConnectivityConstants.NetworkCallbackLosing: 320 return NetworkCallback.EVENT_LOSING; 321 case ConnectivityConstants.NetworkCallbackLost: 322 return NetworkCallback.EVENT_LOST; 323 case ConnectivityConstants.NetworkCallbackUnavailable: 324 return NetworkCallback.EVENT_UNAVAILABLE; 325 case ConnectivityConstants.NetworkCallbackCapabilitiesChanged: 326 return NetworkCallback.EVENT_CAPABILITIES_CHANGED; 327 case ConnectivityConstants.NetworkCallbackSuspended: 328 return NetworkCallback.EVENT_SUSPENDED; 329 case ConnectivityConstants.NetworkCallbackResumed: 330 return NetworkCallback.EVENT_RESUMED; 331 case ConnectivityConstants.NetworkCallbackLinkPropertiesChanged: 332 return NetworkCallback.EVENT_LINK_PROPERTIES_CHANGED; 333 } 334 return NetworkCallback.EVENT_INVALID; 335 } 336 337 private static String getNetworkCallbackEventString(int event) { 338 switch (event) { 339 case NetworkCallback.EVENT_PRECHECK: 340 return ConnectivityConstants.NetworkCallbackPreCheck; 341 case NetworkCallback.EVENT_AVAILABLE: 342 return ConnectivityConstants.NetworkCallbackAvailable; 343 case NetworkCallback.EVENT_LOSING: 344 return ConnectivityConstants.NetworkCallbackLosing; 345 case NetworkCallback.EVENT_LOST: 346 return ConnectivityConstants.NetworkCallbackLost; 347 case NetworkCallback.EVENT_UNAVAILABLE: 348 return ConnectivityConstants.NetworkCallbackUnavailable; 349 case NetworkCallback.EVENT_CAPABILITIES_CHANGED: 350 return ConnectivityConstants.NetworkCallbackCapabilitiesChanged; 351 case NetworkCallback.EVENT_SUSPENDED: 352 return ConnectivityConstants.NetworkCallbackSuspended; 353 case NetworkCallback.EVENT_RESUMED: 354 return ConnectivityConstants.NetworkCallbackResumed; 355 case NetworkCallback.EVENT_LINK_PROPERTIES_CHANGED: 356 return ConnectivityConstants.NetworkCallbackLinkPropertiesChanged; 357 } 358 return ConnectivityConstants.NetworkCallbackInvalid; 359 } 360 361 private static int getPacketKeepaliveReceiverEvent(String event) { 362 switch (event) { 363 case ConnectivityConstants.PacketKeepaliveCallbackStarted: 364 return PacketKeepaliveReceiver.EVENT_STARTED; 365 case ConnectivityConstants.PacketKeepaliveCallbackStopped: 366 return PacketKeepaliveReceiver.EVENT_STOPPED; 367 case ConnectivityConstants.PacketKeepaliveCallbackError: 368 return PacketKeepaliveReceiver.EVENT_ERROR; 369 } 370 return PacketKeepaliveReceiver.EVENT_INVALID; 371 } 372 373 private static String getPacketKeepaliveReceiverEventString(int event) { 374 switch (event) { 375 case PacketKeepaliveReceiver.EVENT_STARTED: 376 return ConnectivityConstants.PacketKeepaliveCallbackStarted; 377 case PacketKeepaliveReceiver.EVENT_STOPPED: 378 return ConnectivityConstants.PacketKeepaliveCallbackStopped; 379 case PacketKeepaliveReceiver.EVENT_ERROR: 380 return ConnectivityConstants.PacketKeepaliveCallbackError; 381 } 382 return ConnectivityConstants.PacketKeepaliveCallbackInvalid; 383 } 384 385 /** 386 * Callbacks used in ConnectivityManager to confirm tethering has started/failed. 387 */ 388 class OnStartTetheringCallback extends ConnectivityManager.OnStartTetheringCallback { 389 @Override 390 public void onTetheringStarted() { 391 mEventFacade.postEvent(ConnectivityConstants.TetheringStartedCallback, null); 392 } 393 394 @Override 395 public void onTetheringFailed() { 396 mEventFacade.postEvent(ConnectivityConstants.TetheringFailedCallback, null); 397 } 398 } 399 400 private final ConnectivityManager mManager; 401 private final Service mService; 402 private final Context mContext; 403 private final ConnectivityReceiver mConnectivityReceiver; 404 private final EventFacade mEventFacade; 405 private PacketKeepalive mPacketKeepalive; 406 private NetworkCallback mNetworkCallback; 407 private static HashMap<String, PacketKeepaliveReceiver> mPacketKeepaliveReceiverMap = 408 new HashMap<String, PacketKeepaliveReceiver>(); 409 private static HashMap<String, NetworkCallback> mNetworkCallbackMap = 410 new HashMap<String, NetworkCallback>(); 411 private boolean mTrackingConnectivityStateChange; 412 413 public ConnectivityManagerFacade(FacadeManager manager) { 414 super(manager); 415 mService = manager.getService(); 416 mContext = mService.getBaseContext(); 417 mManager = (ConnectivityManager) mService.getSystemService(Context.CONNECTIVITY_SERVICE); 418 mEventFacade = manager.getReceiver(EventFacade.class); 419 mConnectivityReceiver = new ConnectivityReceiver(); 420 mTrackingConnectivityStateChange = false; 421 } 422 423 @Rpc(description = "Listen for connectivity changes") 424 public void connectivityStartTrackingConnectivityStateChange() { 425 if (!mTrackingConnectivityStateChange) { 426 mTrackingConnectivityStateChange = true; 427 mContext.registerReceiver(mConnectivityReceiver, 428 new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); 429 } 430 } 431 432 @Rpc(description = "start natt keep alive") 433 public String connectivityStartNattKeepalive(Integer intervalSeconds, String srcAddrString, 434 Integer srcPort, String dstAddrString) throws UnknownHostException { 435 try { 436 Network mNetwork = mManager.getActiveNetwork(); 437 InetAddress srcAddr = InetAddress.getByName(srcAddrString); 438 InetAddress dstAddr = InetAddress.getByName(dstAddrString); 439 Log.d("startNattKeepalive srcAddr:" + srcAddr.getHostAddress()); 440 Log.d("startNattKeepalive dstAddr:" + dstAddr.getHostAddress()); 441 Log.d("startNattKeepalive srcPort:" + srcPort); 442 Log.d("startNattKeepalive intervalSeconds:" + intervalSeconds); 443 PacketKeepaliveReceiver mPacketKeepaliveReceiver = new PacketKeepaliveReceiver( 444 PacketKeepaliveReceiver.EVENT_ALL); 445 mPacketKeepalive = mManager.startNattKeepalive(mNetwork, (int) intervalSeconds, 446 mPacketKeepaliveReceiver, srcAddr, (int) srcPort, dstAddr); 447 if (mPacketKeepalive != null) { 448 mPacketKeepaliveReceiver.mPacketKeepalive = mPacketKeepalive; 449 String key = mPacketKeepaliveReceiver.mId; 450 mPacketKeepaliveReceiverMap.put(key, mPacketKeepaliveReceiver); 451 return key; 452 } else { 453 Log.e("startNattKeepalive fail, startNattKeepalive return null"); 454 return null; 455 } 456 } catch (UnknownHostException e) { 457 Log.e("startNattKeepalive UnknownHostException"); 458 return null; 459 } 460 } 461 462 @Rpc(description = "stop natt keep alive") 463 public Boolean connectivityStopNattKeepalive(String key) { 464 PacketKeepaliveReceiver mPacketKeepaliveReceiver = 465 mPacketKeepaliveReceiverMap.get(key); 466 if (mPacketKeepaliveReceiver != null) { 467 mPacketKeepaliveReceiverMap.remove(key); 468 mPacketKeepaliveReceiver.mPacketKeepalive.stop(); 469 return true; 470 } else { 471 return false; 472 } 473 } 474 475 @Rpc(description = "start listening for NattKeepalive Event") 476 public Boolean connectivityNattKeepaliveStartListeningForEvent(String key, String eventString) { 477 PacketKeepaliveReceiver mPacketKeepaliveReceiver = 478 mPacketKeepaliveReceiverMap.get(key); 479 if (mPacketKeepaliveReceiver != null) { 480 int event = getPacketKeepaliveReceiverEvent(eventString); 481 if (event == PacketKeepaliveReceiver.EVENT_INVALID) { 482 return false; 483 } 484 mPacketKeepaliveReceiver.startListeningForEvents(event); 485 return true; 486 } else { 487 return false; 488 } 489 } 490 491 @Rpc(description = "stop listening for NattKeepalive Event") 492 public Boolean connectivityNattKeepaliveStopListeningForEvent(String key, String eventString) { 493 PacketKeepaliveReceiver mPacketKeepaliveReceiver = 494 mPacketKeepaliveReceiverMap.get(key); 495 if (mPacketKeepaliveReceiver != null) { 496 int event = getPacketKeepaliveReceiverEvent(eventString); 497 if (event == PacketKeepaliveReceiver.EVENT_INVALID) { 498 return false; 499 } 500 mPacketKeepaliveReceiver.stopListeningForEvents(event); 501 return true; 502 } else { 503 return false; 504 } 505 } 506 507 @Rpc(description = "start listening for NetworkCallback Event") 508 public Boolean connectivityNetworkCallbackStartListeningForEvent(String key, String eventString) { 509 NetworkCallback mNetworkCallback = mNetworkCallbackMap.get(key); 510 if (mNetworkCallback != null) { 511 int event = getNetworkCallbackEvent(eventString); 512 if (event == NetworkCallback.EVENT_INVALID) { 513 return false; 514 } 515 mNetworkCallback.startListeningForEvents(event); 516 return true; 517 } else { 518 return false; 519 } 520 } 521 522 @Rpc(description = "stop listening for NetworkCallback Event") 523 public Boolean connectivityNetworkCallbackStopListeningForEvent(String key, String eventString) { 524 NetworkCallback mNetworkCallback = mNetworkCallbackMap.get(key); 525 if (mNetworkCallback != null) { 526 int event = getNetworkCallbackEvent(eventString); 527 if (event == NetworkCallback.EVENT_INVALID) { 528 return false; 529 } 530 mNetworkCallback.stopListeningForEvents(event); 531 return true; 532 } else { 533 return false; 534 } 535 } 536 537 @Rpc(description = "Set Rssi Threshold Monitor") 538 public String connectivitySetRssiThresholdMonitor(Integer rssi) { 539 Log.d("SL4A:setRssiThresholdMonitor rssi = " + rssi); 540 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 541 builder.setSignalStrength((int) rssi); 542 builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); 543 NetworkRequest networkRequest = builder.build(); 544 mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL); 545 mManager.registerNetworkCallback(networkRequest, mNetworkCallback); 546 String key = mNetworkCallback.mId; 547 mNetworkCallbackMap.put(key, mNetworkCallback); 548 return key; 549 } 550 551 @Rpc(description = "Stop Rssi Threshold Monitor") 552 public Boolean connectivityStopRssiThresholdMonitor(String key) { 553 Log.d("SL4A:stopRssiThresholdMonitor key = " + key); 554 return connectivityUnregisterNetworkCallback(key); 555 } 556 557 private NetworkRequest buildNetworkRequestFromJson(JSONObject configJson) 558 throws JSONException { 559 NetworkRequest.Builder builder = new NetworkRequest.Builder(); 560 561 if (configJson.has("TransportType")) { 562 Log.d("build TransportType" + configJson.getInt("TransportType")); 563 builder.addTransportType(configJson.getInt("TransportType")); 564 } 565 if (configJson.has("SignalStrength")) { 566 Log.d("build SignalStrength" + configJson.getInt("SignalStrength")); 567 builder.setSignalStrength(configJson.getInt("SignalStrength")); 568 } 569 if (configJson.has("Capability")) { 570 JSONArray capabilities = configJson.getJSONArray("Capability"); 571 for (int i = 0; i < capabilities.length(); i++) { 572 Log.d("build Capability" + capabilities.getInt(i)); 573 builder.addCapability(capabilities.getInt(i)); 574 } 575 } 576 if (configJson.has("LinkUpstreamBandwidthKbps")) { 577 Log.d("build LinkUpstreamBandwidthKbps" + configJson.getInt( 578 "LinkUpstreamBandwidthKbps")); 579 builder.setLinkUpstreamBandwidthKbps(configJson.getInt( 580 "LinkUpstreamBandwidthKbps")); 581 } 582 if (configJson.has("LinkDownstreamBandwidthKbps")) { 583 Log.d("build LinkDownstreamBandwidthKbps" + configJson.getInt( 584 "LinkDownstreamBandwidthKbps")); 585 builder.setLinkDownstreamBandwidthKbps(configJson.getInt( 586 "LinkDownstreamBandwidthKbps")); 587 } 588 if (configJson.has("NetworkSpecifier")) { 589 Log.d("build NetworkSpecifier" + configJson.getString("NetworkSpecifier")); 590 builder.setNetworkSpecifier(configJson.getString( 591 "NetworkSpecifier")); 592 } 593 NetworkRequest networkRequest = builder.build(); 594 return networkRequest; 595 } 596 597 @Rpc(description = "register a network callback") 598 public String connectivityRegisterNetworkCallback(@RpcParameter(name = "configJson") 599 JSONObject configJson) throws JSONException { 600 NetworkRequest networkRequest = buildNetworkRequestFromJson(configJson); 601 mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL); 602 mManager.registerNetworkCallback(networkRequest, mNetworkCallback); 603 String key = mNetworkCallback.mId; 604 mNetworkCallbackMap.put(key, mNetworkCallback); 605 return key; 606 } 607 608 @Rpc(description = "unregister a network callback") 609 public Boolean connectivityUnregisterNetworkCallback(@RpcParameter(name = "key") 610 String key) { 611 mNetworkCallback = mNetworkCallbackMap.get(key); 612 if (mNetworkCallback != null) { 613 mNetworkCallbackMap.remove(key); 614 mManager.unregisterNetworkCallback(mNetworkCallback); 615 return true; 616 } else { 617 return false; 618 } 619 } 620 621 @Rpc(description = "request a network") 622 public String connectivityRequestNetwork(@RpcParameter(name = "configJson") 623 JSONObject configJson) throws JSONException { 624 NetworkRequest networkRequest = buildNetworkRequestFromJson(configJson); 625 mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL); 626 mManager.requestNetwork(networkRequest, mNetworkCallback); 627 String key = mNetworkCallback.mId; 628 mNetworkCallbackMap.put(key, mNetworkCallback); 629 return key; 630 } 631 632 @Rpc(description = "Stop listening for connectivity changes") 633 public void connectivityStopTrackingConnectivityStateChange() { 634 if (mTrackingConnectivityStateChange) { 635 mTrackingConnectivityStateChange = false; 636 mContext.unregisterReceiver(mConnectivityReceiver); 637 } 638 } 639 640 @Rpc(description = "Get the extra information about the network state provided by lower network layers.") 641 public String connectivityNetworkGetActiveConnectionExtraInfo() { 642 NetworkInfo current = mManager.getActiveNetworkInfo(); 643 if (current == null) { 644 Log.d("No network is active at the moment."); 645 return null; 646 } 647 return current.getExtraInfo(); 648 } 649 650 @Rpc(description = "Return the subtype name of the current network, null if not connected") 651 public String connectivityNetworkGetActiveConnectionSubtypeName() { 652 NetworkInfo current = mManager.getActiveNetworkInfo(); 653 if (current == null) { 654 Log.d("No network is active at the moment."); 655 return null; 656 } 657 return current.getSubtypeName(); 658 } 659 660 @Rpc(description = "Return a human-readable name describe the type of the network, e.g. WIFI") 661 public String connectivityNetworkGetActiveConnectionTypeName() { 662 NetworkInfo current = mManager.getActiveNetworkInfo(); 663 if (current == null) { 664 Log.d("No network is active at the moment."); 665 return null; 666 } 667 return current.getTypeName(); 668 } 669 670 @Rpc(description = "Get connection status information about all network types supported by the device.") 671 public NetworkInfo[] connectivityNetworkGetAllInfo() { 672 return mManager.getAllNetworkInfo(); 673 } 674 675 @Rpc(description = "Check whether the active network is connected to the Internet.") 676 public Boolean connectivityNetworkIsConnected() { 677 NetworkInfo current = mManager.getActiveNetworkInfo(); 678 if (current == null) { 679 Log.d("No network is active at the moment."); 680 return false; 681 } 682 return current.isConnected(); 683 } 684 685 @Rpc(description = "Checks the airplane mode setting.", 686 returns = "True if airplane mode is enabled.") 687 public Boolean connectivityCheckAirplaneMode() { 688 try { 689 return Settings.Global.getInt(mService.getContentResolver(), 690 Settings.Global.AIRPLANE_MODE_ON) == AIRPLANE_MODE_ON; 691 } catch (Settings.SettingNotFoundException e) { 692 Log.e("Settings.Global.AIRPLANE_MODE_ON not found!"); 693 return false; 694 } 695 } 696 697 @Rpc(description = "Toggles airplane mode on and off.", 698 returns = "True if airplane mode is enabled.") 699 public void connectivityToggleAirplaneMode(@RpcParameter(name = "enabled") 700 @RpcOptional 701 Boolean enabled) { 702 if (enabled == null) { 703 enabled = !connectivityCheckAirplaneMode(); 704 } 705 mManager.setAirplaneMode(enabled); 706 } 707 708 @Rpc(description = "Check if tethering supported or not.", 709 returns = "True if tethering is supported.") 710 public boolean connectivityIsTetheringSupported() { 711 return mManager.isTetheringSupported(); 712 } 713 714 @Rpc(description = "Call to start tethering with a provisioning check if needed") 715 public void connectivityStartTethering(@RpcParameter(name = "type") Integer type, 716 @RpcParameter(name = "showProvisioningUi") Boolean showProvisioningUi) { 717 Log.d("startTethering for type: " + type + " showProvUi: " + showProvisioningUi); 718 OnStartTetheringCallback tetherCallback = new OnStartTetheringCallback(); 719 mManager.startTethering(type, showProvisioningUi, tetherCallback); 720 } 721 722 @Rpc(description = "Call to stop tethering") 723 public void connectivityStopTethering(@RpcParameter(name = "type") Integer type) { 724 Log.d("stopTethering for type: " + type); 725 mManager.stopTethering(type); 726 } 727 728 @Override 729 public void shutdown() { 730 connectivityStopTrackingConnectivityStateChange(); 731 } 732 } 733