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