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