blob: 98bfed5a4d532b9d56f8fcddb0137faea989d225 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.googlecode.android_scripting.facade;
import android.app.Service;
import android.app.usage.NetworkStats.Bucket;
import android.app.usage.NetworkStatsManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.PacketKeepalive;
import android.net.ConnectivityManager.PacketKeepaliveCallback;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkPolicy;
import android.net.NetworkPolicyManager;
import android.net.NetworkRequest;
import android.net.StringNetworkSpecifier;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.Settings;
import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.facade.wifi.WifiAwareManagerFacade;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.rpc.Rpc;
import com.googlecode.android_scripting.rpc.RpcOptional;
import com.googlecode.android_scripting.rpc.RpcParameter;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
/**
* Access ConnectivityManager functions.
*/
public class ConnectivityManagerFacade extends RpcReceiver {
public static int AIRPLANE_MODE_OFF = 0;
public static int AIRPLANE_MODE_ON = 1;
public static int DATA_ROAMING_ON = 1;
class ConnectivityReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
Log.e("ConnectivityReceiver received non-connectivity action!");
return;
}
Bundle b = intent.getExtras();
if (b == null) {
Log.e("ConnectivityReceiver failed to receive extras!");
return;
}
int netType =
b.getInt(ConnectivityManager.EXTRA_NETWORK_TYPE,
ConnectivityManager.TYPE_NONE);
if (netType == ConnectivityManager.TYPE_NONE) {
Log.i("ConnectivityReceiver received change to TYPE_NONE.");
return;
}
/*
* Technically there is a race condition here, but retrieving the NetworkInfo from the
* bundle is deprecated. See ConnectivityManager.EXTRA_NETWORK_INFO
*/
for (NetworkInfo info : mManager.getAllNetworkInfo()) {
if (info.getType() == netType) {
mEventFacade.postEvent(ConnectivityConstants.EventConnectivityChanged, info);
}
}
}
}
class PacketKeepaliveReceiver extends PacketKeepaliveCallback {
public static final int EVENT_INVALID = -1;
public static final int EVENT_NONE = 0;
public static final int EVENT_STARTED = 1 << 0;
public static final int EVENT_STOPPED = 1 << 1;
public static final int EVENT_ERROR = 1 << 2;
public static final int EVENT_ALL = EVENT_STARTED |
EVENT_STOPPED |
EVENT_ERROR;
private int mEvents;
public String mId;
public PacketKeepalive mPacketKeepalive;
public PacketKeepaliveReceiver(int events) {
super();
mEvents = events;
mId = this.toString();
}
public void startListeningForEvents(int events) {
mEvents |= events & EVENT_ALL;
}
public void stopListeningForEvents(int events) {
mEvents &= ~(events & EVENT_ALL);
}
@Override
public void onStarted() {
Log.d("PacketKeepaliveCallback on start!");
if ((mEvents & EVENT_STARTED) == EVENT_STARTED) {
mEventFacade.postEvent(
ConnectivityConstants.EventPacketKeepaliveCallback,
new ConnectivityEvents.PacketKeepaliveEvent(
mId,
getPacketKeepaliveReceiverEventString(EVENT_STARTED)));
}
}
@Override
public void onStopped() {
Log.d("PacketKeepaliveCallback on stop!");
if ((mEvents & EVENT_STOPPED) == EVENT_STOPPED) {
mEventFacade.postEvent(
ConnectivityConstants.EventPacketKeepaliveCallback,
new ConnectivityEvents.PacketKeepaliveEvent(
mId,
getPacketKeepaliveReceiverEventString(EVENT_STOPPED)));
}
}
@Override
public void onError(int error) {
Log.d("PacketKeepaliveCallback on error! - code:" + error);
if ((mEvents & EVENT_ERROR) == EVENT_ERROR) {
mEventFacade.postEvent(
ConnectivityConstants.EventPacketKeepaliveCallback,
new ConnectivityEvents.PacketKeepaliveEvent(
mId,
getPacketKeepaliveReceiverEventString(EVENT_ERROR)));
}
}
}
class NetworkCallback extends ConnectivityManager.NetworkCallback {
public static final int EVENT_INVALID = -1;
public static final int EVENT_NONE = 0;
public static final int EVENT_PRECHECK = 1 << 0;
public static final int EVENT_AVAILABLE = 1 << 1;
public static final int EVENT_LOSING = 1 << 2;
public static final int EVENT_LOST = 1 << 3;
public static final int EVENT_UNAVAILABLE = 1 << 4;
public static final int EVENT_CAPABILITIES_CHANGED = 1 << 5;
public static final int EVENT_SUSPENDED = 1 << 6;
public static final int EVENT_RESUMED = 1 << 7;
public static final int EVENT_LINK_PROPERTIES_CHANGED = 1 << 8;
public static final int EVENT_ALL = EVENT_PRECHECK |
EVENT_AVAILABLE |
EVENT_LOSING |
EVENT_LOST |
EVENT_UNAVAILABLE |
EVENT_CAPABILITIES_CHANGED |
EVENT_SUSPENDED |
EVENT_RESUMED |
EVENT_LINK_PROPERTIES_CHANGED;
private int mEvents;
public String mId;
private long mCreateTimestamp;
public NetworkCallback(int events) {
super();
mEvents = events;
mId = this.toString();
mCreateTimestamp = System.currentTimeMillis();
}
public void startListeningForEvents(int events) {
mEvents |= events & EVENT_ALL;
}
public void stopListeningForEvents(int events) {
mEvents &= ~(events & EVENT_ALL);
}
@Override
public void onPreCheck(Network network) {
Log.d("NetworkCallback onPreCheck");
if ((mEvents & EVENT_PRECHECK) == EVENT_PRECHECK) {
mEventFacade.postEvent(
ConnectivityConstants.EventNetworkCallback,
new ConnectivityEvents.NetworkCallbackEventBase(
mId,
getNetworkCallbackEventString(EVENT_PRECHECK), mCreateTimestamp));
}
}
@Override
public void onAvailable(Network network) {
Log.d("NetworkCallback onAvailable");
if ((mEvents & EVENT_AVAILABLE) == EVENT_AVAILABLE) {
mEventFacade.postEvent(
ConnectivityConstants.EventNetworkCallback,
new ConnectivityEvents.NetworkCallbackEventBase(
mId,
getNetworkCallbackEventString(EVENT_AVAILABLE), mCreateTimestamp));
}
}
@Override
public void onLosing(Network network, int maxMsToLive) {
Log.d("NetworkCallback onLosing");
if ((mEvents & EVENT_LOSING) == EVENT_LOSING) {
mEventFacade.postEvent(
ConnectivityConstants.EventNetworkCallback,
new ConnectivityEvents.NetworkCallbackEventOnLosing(
mId,
getNetworkCallbackEventString(EVENT_LOSING), mCreateTimestamp,
maxMsToLive));
}
}
@Override
public void onLost(Network network) {
Log.d("NetworkCallback onLost");
if ((mEvents & EVENT_LOST) == EVENT_LOST) {
mEventFacade.postEvent(
ConnectivityConstants.EventNetworkCallback,
new ConnectivityEvents.NetworkCallbackEventBase(
mId,
getNetworkCallbackEventString(EVENT_LOST), mCreateTimestamp));
}
}
@Override
public void onUnavailable() {
Log.d("NetworkCallback onUnavailable");
if ((mEvents & EVENT_UNAVAILABLE) == EVENT_UNAVAILABLE) {
mEventFacade.postEvent(
ConnectivityConstants.EventNetworkCallback,
new ConnectivityEvents.NetworkCallbackEventBase(
mId,
getNetworkCallbackEventString(EVENT_UNAVAILABLE), mCreateTimestamp));
}
}
@Override
public void onCapabilitiesChanged(Network network,
NetworkCapabilities networkCapabilities) {
Log.d("NetworkCallback onCapabilitiesChanged. RSSI:" +
networkCapabilities.getSignalStrength());
if ((mEvents & EVENT_CAPABILITIES_CHANGED) == EVENT_CAPABILITIES_CHANGED) {
mEventFacade.postEvent(
ConnectivityConstants.EventNetworkCallback,
new ConnectivityEvents.NetworkCallbackEventOnCapabilitiesChanged(
mId,
getNetworkCallbackEventString(EVENT_CAPABILITIES_CHANGED), mCreateTimestamp,
networkCapabilities.getSignalStrength()));
}
}
@Override
public void onNetworkSuspended(Network network) {
Log.d("NetworkCallback onNetworkSuspended");
if ((mEvents & EVENT_SUSPENDED) == EVENT_SUSPENDED) {
mEventFacade.postEvent(
ConnectivityConstants.EventNetworkCallback,
new ConnectivityEvents.NetworkCallbackEventBase(
mId,
getNetworkCallbackEventString(EVENT_SUSPENDED), mCreateTimestamp));
}
}
@Override
public void onLinkPropertiesChanged(Network network,
LinkProperties linkProperties) {
Log.d("NetworkCallback onLinkPropertiesChanged");
if ((mEvents & EVENT_LINK_PROPERTIES_CHANGED) == EVENT_LINK_PROPERTIES_CHANGED) {
mEventFacade.postEvent(
ConnectivityConstants.EventNetworkCallback,
new ConnectivityEvents.NetworkCallbackEventOnLinkPropertiesChanged(mId,
getNetworkCallbackEventString(EVENT_LINK_PROPERTIES_CHANGED),
mCreateTimestamp,
linkProperties.getInterfaceName()));
}
}
@Override
public void onNetworkResumed(Network network) {
Log.d("NetworkCallback onNetworkResumed");
if ((mEvents & EVENT_RESUMED) == EVENT_RESUMED) {
mEventFacade.postEvent(
ConnectivityConstants.EventNetworkCallback,
new ConnectivityEvents.NetworkCallbackEventBase(
mId,
getNetworkCallbackEventString(EVENT_RESUMED), mCreateTimestamp));
}
}
}
private static int getNetworkCallbackEvent(String event) {
switch (event) {
case ConnectivityConstants.NetworkCallbackPreCheck:
return NetworkCallback.EVENT_PRECHECK;
case ConnectivityConstants.NetworkCallbackAvailable:
return NetworkCallback.EVENT_AVAILABLE;
case ConnectivityConstants.NetworkCallbackLosing:
return NetworkCallback.EVENT_LOSING;
case ConnectivityConstants.NetworkCallbackLost:
return NetworkCallback.EVENT_LOST;
case ConnectivityConstants.NetworkCallbackUnavailable:
return NetworkCallback.EVENT_UNAVAILABLE;
case ConnectivityConstants.NetworkCallbackCapabilitiesChanged:
return NetworkCallback.EVENT_CAPABILITIES_CHANGED;
case ConnectivityConstants.NetworkCallbackSuspended:
return NetworkCallback.EVENT_SUSPENDED;
case ConnectivityConstants.NetworkCallbackResumed:
return NetworkCallback.EVENT_RESUMED;
case ConnectivityConstants.NetworkCallbackLinkPropertiesChanged:
return NetworkCallback.EVENT_LINK_PROPERTIES_CHANGED;
}
return NetworkCallback.EVENT_INVALID;
}
private static String getNetworkCallbackEventString(int event) {
switch (event) {
case NetworkCallback.EVENT_PRECHECK:
return ConnectivityConstants.NetworkCallbackPreCheck;
case NetworkCallback.EVENT_AVAILABLE:
return ConnectivityConstants.NetworkCallbackAvailable;
case NetworkCallback.EVENT_LOSING:
return ConnectivityConstants.NetworkCallbackLosing;
case NetworkCallback.EVENT_LOST:
return ConnectivityConstants.NetworkCallbackLost;
case NetworkCallback.EVENT_UNAVAILABLE:
return ConnectivityConstants.NetworkCallbackUnavailable;
case NetworkCallback.EVENT_CAPABILITIES_CHANGED:
return ConnectivityConstants.NetworkCallbackCapabilitiesChanged;
case NetworkCallback.EVENT_SUSPENDED:
return ConnectivityConstants.NetworkCallbackSuspended;
case NetworkCallback.EVENT_RESUMED:
return ConnectivityConstants.NetworkCallbackResumed;
case NetworkCallback.EVENT_LINK_PROPERTIES_CHANGED:
return ConnectivityConstants.NetworkCallbackLinkPropertiesChanged;
}
return ConnectivityConstants.NetworkCallbackInvalid;
}
private static int getPacketKeepaliveReceiverEvent(String event) {
switch (event) {
case ConnectivityConstants.PacketKeepaliveCallbackStarted:
return PacketKeepaliveReceiver.EVENT_STARTED;
case ConnectivityConstants.PacketKeepaliveCallbackStopped:
return PacketKeepaliveReceiver.EVENT_STOPPED;
case ConnectivityConstants.PacketKeepaliveCallbackError:
return PacketKeepaliveReceiver.EVENT_ERROR;
}
return PacketKeepaliveReceiver.EVENT_INVALID;
}
private static String getPacketKeepaliveReceiverEventString(int event) {
switch (event) {
case PacketKeepaliveReceiver.EVENT_STARTED:
return ConnectivityConstants.PacketKeepaliveCallbackStarted;
case PacketKeepaliveReceiver.EVENT_STOPPED:
return ConnectivityConstants.PacketKeepaliveCallbackStopped;
case PacketKeepaliveReceiver.EVENT_ERROR:
return ConnectivityConstants.PacketKeepaliveCallbackError;
}
return ConnectivityConstants.PacketKeepaliveCallbackInvalid;
}
/**
* Callbacks used in ConnectivityManager to confirm tethering has started/failed.
*/
class OnStartTetheringCallback extends ConnectivityManager.OnStartTetheringCallback {
@Override
public void onTetheringStarted() {
mEventFacade.postEvent(ConnectivityConstants.TetheringStartedCallback, null);
}
@Override
public void onTetheringFailed() {
mEventFacade.postEvent(ConnectivityConstants.TetheringFailedCallback, null);
}
}
private final ConnectivityManager mManager;
private NetworkPolicyManager mNetPolicyManager;
private NetworkStatsManager mNetStatsManager;
private final Service mService;
private final Context mContext;
private final ConnectivityReceiver mConnectivityReceiver;
private final EventFacade mEventFacade;
private PacketKeepalive mPacketKeepalive;
private NetworkCallback mNetworkCallback;
private static HashMap<String, PacketKeepaliveReceiver> mPacketKeepaliveReceiverMap =
new HashMap<String, PacketKeepaliveReceiver>();
private static HashMap<String, NetworkCallback> mNetworkCallbackMap =
new HashMap<String, NetworkCallback>();
private boolean mTrackingConnectivityStateChange;
public ConnectivityManagerFacade(FacadeManager manager) {
super(manager);
mService = manager.getService();
mContext = mService.getBaseContext();
mManager = (ConnectivityManager) mService.getSystemService(Context.CONNECTIVITY_SERVICE);
mNetPolicyManager = NetworkPolicyManager.from(mContext);
mNetStatsManager = (NetworkStatsManager)
mService.getSystemService(Context.NETWORK_STATS_SERVICE);
mEventFacade = manager.getReceiver(EventFacade.class);
mConnectivityReceiver = new ConnectivityReceiver();
mTrackingConnectivityStateChange = false;
}
@Rpc(description = "Listen for connectivity changes")
public void connectivityStartTrackingConnectivityStateChange() {
if (!mTrackingConnectivityStateChange) {
mTrackingConnectivityStateChange = true;
mContext.registerReceiver(mConnectivityReceiver,
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
}
@Rpc(description = "start natt keep alive")
public String connectivityStartNattKeepalive(Integer intervalSeconds, String srcAddrString,
Integer srcPort, String dstAddrString) throws UnknownHostException {
try {
Network mNetwork = mManager.getActiveNetwork();
InetAddress srcAddr = InetAddress.getByName(srcAddrString);
InetAddress dstAddr = InetAddress.getByName(dstAddrString);
Log.d("startNattKeepalive srcAddr:" + srcAddr.getHostAddress());
Log.d("startNattKeepalive dstAddr:" + dstAddr.getHostAddress());
Log.d("startNattKeepalive srcPort:" + srcPort);
Log.d("startNattKeepalive intervalSeconds:" + intervalSeconds);
PacketKeepaliveReceiver mPacketKeepaliveReceiver = new PacketKeepaliveReceiver(
PacketKeepaliveReceiver.EVENT_ALL);
mPacketKeepalive = mManager.startNattKeepalive(mNetwork, (int) intervalSeconds,
mPacketKeepaliveReceiver, srcAddr, (int) srcPort, dstAddr);
if (mPacketKeepalive != null) {
mPacketKeepaliveReceiver.mPacketKeepalive = mPacketKeepalive;
String key = mPacketKeepaliveReceiver.mId;
mPacketKeepaliveReceiverMap.put(key, mPacketKeepaliveReceiver);
return key;
} else {
Log.e("startNattKeepalive fail, startNattKeepalive return null");
return null;
}
} catch (UnknownHostException e) {
Log.e("startNattKeepalive UnknownHostException");
return null;
}
}
@Rpc(description = "stop natt keep alive")
public Boolean connectivityStopNattKeepalive(String key) {
PacketKeepaliveReceiver mPacketKeepaliveReceiver =
mPacketKeepaliveReceiverMap.get(key);
if (mPacketKeepaliveReceiver != null) {
mPacketKeepaliveReceiverMap.remove(key);
mPacketKeepaliveReceiver.mPacketKeepalive.stop();
return true;
} else {
return false;
}
}
@Rpc(description = "start listening for NattKeepalive Event")
public Boolean connectivityNattKeepaliveStartListeningForEvent(String key, String eventString) {
PacketKeepaliveReceiver mPacketKeepaliveReceiver =
mPacketKeepaliveReceiverMap.get(key);
if (mPacketKeepaliveReceiver != null) {
int event = getPacketKeepaliveReceiverEvent(eventString);
if (event == PacketKeepaliveReceiver.EVENT_INVALID) {
return false;
}
mPacketKeepaliveReceiver.startListeningForEvents(event);
return true;
} else {
return false;
}
}
@Rpc(description = "stop listening for NattKeepalive Event")
public Boolean connectivityNattKeepaliveStopListeningForEvent(String key, String eventString) {
PacketKeepaliveReceiver mPacketKeepaliveReceiver =
mPacketKeepaliveReceiverMap.get(key);
if (mPacketKeepaliveReceiver != null) {
int event = getPacketKeepaliveReceiverEvent(eventString);
if (event == PacketKeepaliveReceiver.EVENT_INVALID) {
return false;
}
mPacketKeepaliveReceiver.stopListeningForEvents(event);
return true;
} else {
return false;
}
}
@Rpc(description = "start listening for NetworkCallback Event")
public Boolean connectivityNetworkCallbackStartListeningForEvent(String key, String eventString) {
NetworkCallback mNetworkCallback = mNetworkCallbackMap.get(key);
if (mNetworkCallback != null) {
int event = getNetworkCallbackEvent(eventString);
if (event == NetworkCallback.EVENT_INVALID) {
return false;
}
mNetworkCallback.startListeningForEvents(event);
return true;
} else {
return false;
}
}
@Rpc(description = "stop listening for NetworkCallback Event")
public Boolean connectivityNetworkCallbackStopListeningForEvent(String key, String eventString) {
NetworkCallback mNetworkCallback = mNetworkCallbackMap.get(key);
if (mNetworkCallback != null) {
int event = getNetworkCallbackEvent(eventString);
if (event == NetworkCallback.EVENT_INVALID) {
return false;
}
mNetworkCallback.stopListeningForEvents(event);
return true;
} else {
return false;
}
}
@Rpc(description = "Set Rssi Threshold Monitor")
public String connectivitySetRssiThresholdMonitor(Integer rssi) {
Log.d("SL4A:setRssiThresholdMonitor rssi = " + rssi);
NetworkRequest.Builder builder = new NetworkRequest.Builder();
builder.setSignalStrength((int) rssi);
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
NetworkRequest networkRequest = builder.build();
mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL);
mManager.registerNetworkCallback(networkRequest, mNetworkCallback);
String key = mNetworkCallback.mId;
mNetworkCallbackMap.put(key, mNetworkCallback);
return key;
}
@Rpc(description = "Stop Rssi Threshold Monitor")
public Boolean connectivityStopRssiThresholdMonitor(String key) {
Log.d("SL4A:stopRssiThresholdMonitor key = " + key);
return connectivityUnregisterNetworkCallback(key);
}
private NetworkRequest buildNetworkRequestFromJson(JSONObject configJson)
throws JSONException {
NetworkRequest.Builder builder = new NetworkRequest.Builder();
if (configJson.has("ClearCapabilities")) {
/* the 'ClearCapabilities' property does not have a value (that we use). Its presence
is used to clear the capabilities of the constructed network request (which is
constructed with some default capabilities already present). */
Log.d("build ClearCapabilities");
builder.clearCapabilities();
}
if (configJson.has("TransportType")) {
Log.d("build TransportType" + configJson.getInt("TransportType"));
builder.addTransportType(configJson.getInt("TransportType"));
}
if (configJson.has("SignalStrength")) {
Log.d("build SignalStrength" + configJson.getInt("SignalStrength"));
builder.setSignalStrength(configJson.getInt("SignalStrength"));
}
if (configJson.has("Capability")) {
JSONArray capabilities = configJson.getJSONArray("Capability");
for (int i = 0; i < capabilities.length(); i++) {
Log.d("build Capability" + capabilities.getInt(i));
builder.addCapability(capabilities.getInt(i));
}
}
if (configJson.has("LinkUpstreamBandwidthKbps")) {
Log.d("build LinkUpstreamBandwidthKbps" + configJson.getInt(
"LinkUpstreamBandwidthKbps"));
builder.setLinkUpstreamBandwidthKbps(configJson.getInt(
"LinkUpstreamBandwidthKbps"));
}
if (configJson.has("LinkDownstreamBandwidthKbps")) {
Log.d("build LinkDownstreamBandwidthKbps" + configJson.getInt(
"LinkDownstreamBandwidthKbps"));
builder.setLinkDownstreamBandwidthKbps(configJson.getInt(
"LinkDownstreamBandwidthKbps"));
}
if (configJson.has("NetworkSpecifier")) {
Log.d("build NetworkSpecifier" + configJson.getString("NetworkSpecifier"));
builder.setNetworkSpecifier(configJson.getString(
"NetworkSpecifier"));
}
NetworkRequest networkRequest = builder.build();
return networkRequest;
}
@Rpc(description = "register a network callback")
public String connectivityRegisterNetworkCallback(@RpcParameter(name = "configJson")
JSONObject configJson) throws JSONException {
NetworkRequest networkRequest = buildNetworkRequestFromJson(configJson);
mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL);
mManager.registerNetworkCallback(networkRequest, mNetworkCallback);
String key = mNetworkCallback.mId;
mNetworkCallbackMap.put(key, mNetworkCallback);
return key;
}
@Rpc(description = "unregister a network callback")
public Boolean connectivityUnregisterNetworkCallback(@RpcParameter(name = "key")
String key) {
mNetworkCallback = mNetworkCallbackMap.get(key);
if (mNetworkCallback != null) {
mNetworkCallbackMap.remove(key);
mManager.unregisterNetworkCallback(mNetworkCallback);
return true;
} else {
return false;
}
}
@Rpc(description = "request a network")
public String connectivityRequestNetwork(@RpcParameter(name = "configJson")
JSONObject configJson) throws JSONException {
NetworkRequest networkRequest = buildNetworkRequestFromJson(configJson);
mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL);
mManager.requestNetwork(networkRequest, mNetworkCallback);
String key = mNetworkCallback.mId;
mNetworkCallbackMap.put(key, mNetworkCallback);
return key;
}
@Rpc(description = "Request a Wi-Fi Aware network")
public String connectivityRequestWifiAwareNetwork(@RpcParameter(name = "configJson")
JSONObject configJson) throws JSONException {
NetworkRequest networkRequest = buildNetworkRequestFromJson(configJson);
if (networkRequest.networkCapabilities.getNetworkSpecifier() instanceof
StringNetworkSpecifier) {
String ns =
((StringNetworkSpecifier) networkRequest.networkCapabilities
.getNetworkSpecifier()).specifier;
JSONObject j = new JSONObject(ns);
networkRequest.networkCapabilities.setNetworkSpecifier(
WifiAwareManagerFacade.getNetworkSpecifier(j));
}
mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL);
mManager.requestNetwork(networkRequest, mNetworkCallback);
String key = mNetworkCallback.mId;
mNetworkCallbackMap.put(key, mNetworkCallback);
return key;
}
@Rpc(description = "Stop listening for connectivity changes")
public void connectivityStopTrackingConnectivityStateChange() {
if (mTrackingConnectivityStateChange) {
mTrackingConnectivityStateChange = false;
mContext.unregisterReceiver(mConnectivityReceiver);
}
}
@Rpc(description = "Get the extra information about the network state provided by lower network layers.")
public String connectivityNetworkGetActiveConnectionExtraInfo() {
NetworkInfo current = mManager.getActiveNetworkInfo();
if (current == null) {
Log.d("No network is active at the moment.");
return null;
}
return current.getExtraInfo();
}
@Rpc(description = "Return the subtype name of the current network, null if not connected")
public String connectivityNetworkGetActiveConnectionSubtypeName() {
NetworkInfo current = mManager.getActiveNetworkInfo();
if (current == null) {
Log.d("No network is active at the moment.");
return null;
}
return current.getSubtypeName();
}
@Rpc(description = "Return a human-readable name describe the type of the network, e.g. WIFI")
public String connectivityNetworkGetActiveConnectionTypeName() {
NetworkInfo current = mManager.getActiveNetworkInfo();
if (current == null) {
Log.d("No network is active at the moment.");
return null;
}
return current.getTypeName();
}
@Rpc(description = "Get connection status information about all network types supported by the device.")
public NetworkInfo[] connectivityNetworkGetAllInfo() {
return mManager.getAllNetworkInfo();
}
@Rpc(description = "Check whether the active network is connected to the Internet.")
public Boolean connectivityNetworkIsConnected() {
NetworkInfo current = mManager.getActiveNetworkInfo();
if (current == null) {
Log.d("No network is active at the moment.");
return false;
}
return current.isConnected();
}
@Rpc(description = "Checks the airplane mode setting.",
returns = "True if airplane mode is enabled.")
public Boolean connectivityCheckAirplaneMode() {
try {
return Settings.Global.getInt(mService.getContentResolver(),
Settings.Global.AIRPLANE_MODE_ON) == AIRPLANE_MODE_ON;
} catch (Settings.SettingNotFoundException e) {
Log.e("Settings.Global.AIRPLANE_MODE_ON not found!");
return false;
}
}
@Rpc(description = "Toggles airplane mode on and off.",
returns = "True if airplane mode is enabled.")
public void connectivityToggleAirplaneMode(@RpcParameter(name = "enabled")
@RpcOptional
Boolean enabled) {
if (enabled == null) {
enabled = !connectivityCheckAirplaneMode();
}
mManager.setAirplaneMode(enabled);
}
/**
* Check global data roaming setting.
* @return True if roaming is enabled; false otherwise.
*/
@Rpc(description = "Checks data roaming mode setting.",
returns = "True if data roaming mode is enabled.")
public Boolean connectivityCheckDataRoamingMode() {
try {
return Settings.Global.getInt(mService.getContentResolver(),
Settings.Global.DATA_ROAMING) == DATA_ROAMING_ON;
} catch (Settings.SettingNotFoundException e) {
Log.e("Settings.Global.DATA_ROAMING not found!");
return false;
}
}
/**
* Enable or disable data roaming.
* @param roaming 1: Enable data roaming; 0: Disable data roaming.
* @return True for setting roaming mode successfully; false otherwise.
*/
@Rpc(description = "Set Data Roaming Enabled or Disabled")
public boolean connectivitySetDataRoaming(
@RpcParameter(name = "roaming") Integer roaming) {
Log.d("connectivitySetDataRoaming by SubscriptionManager");
return Settings.Global.putInt(mService.getContentResolver(),
Settings.Global.DATA_ROAMING, roaming);
}
@Rpc(description = "Check if tethering supported or not.",
returns = "True if tethering is supported.")
public boolean connectivityIsTetheringSupported() {
return mManager.isTetheringSupported();
}
@Rpc(description = "Call to start tethering with a provisioning check if needed")
public void connectivityStartTethering(@RpcParameter(name = "type") Integer type,
@RpcParameter(name = "showProvisioningUi") Boolean showProvisioningUi) {
Log.d("startTethering for type: " + type + " showProvUi: " + showProvisioningUi);
OnStartTetheringCallback tetherCallback = new OnStartTetheringCallback();
mManager.startTethering(type, showProvisioningUi, tetherCallback);
}
@Rpc(description = "Call to stop tethering")
public void connectivityStopTethering(@RpcParameter(name = "type") Integer type) {
Log.d("stopTethering for type: " + type);
mManager.stopTethering(type);
}
private Enumeration<InetAddress> getInetAddrsForInterface(String ifaceName) {
NetworkInterface iface = null;
try {
iface = NetworkInterface.getByName(ifaceName);
} catch (SocketException e) {
return null;
}
if (iface == null)
return null;
return iface.getInetAddresses();
}
@Rpc(description = "Returns the link local IPv6 address of the interface.")
public String connectivityGetLinkLocalIpv6Address(@RpcParameter(name = "ifaceName")
String ifaceName) {
Inet6Address inet6Address = null;
Enumeration<InetAddress> inetAddresses = getInetAddrsForInterface(ifaceName);
if (inetAddresses == null) {
return null;
}
while (inetAddresses.hasMoreElements()) {
InetAddress addr = inetAddresses.nextElement();
if (addr instanceof Inet6Address) {
if (((Inet6Address) addr).isLinkLocalAddress()) {
inet6Address = (Inet6Address) addr;
break;
}
}
}
if (inet6Address == null) {
return null;
}
return inet6Address.getHostAddress();
}
@Rpc(description = "Return IPv4 address of an interface")
public List<String> connectivityGetIPv4Addresses(
@RpcParameter(name = "ifaceName") String ifaceName) {
Enumeration<InetAddress> inetAddresses
= getInetAddrsForInterface(ifaceName);
if (inetAddresses == null)
return null;
List<String> inetAddrs = new ArrayList<String>();
while (inetAddresses.hasMoreElements()) {
InetAddress addr = inetAddresses.nextElement();
if (addr instanceof Inet4Address) {
Inet4Address inet4Address = (Inet4Address) addr;
inetAddrs.add(inet4Address.getHostAddress());
}
}
return inetAddrs;
}
@Rpc(description = "Return IPv6 addrs of an interface except link local")
public List<String> connectivityGetIPv6Addresses(
@RpcParameter(name = "ifaceName") String ifaceName) {
Enumeration<InetAddress> inetAddresses
= getInetAddrsForInterface(ifaceName);
if (inetAddresses == null)
return null;
List<String> inetAddrs = new ArrayList<String>();
while (inetAddresses.hasMoreElements()) {
InetAddress addr = inetAddresses.nextElement();
if (addr instanceof Inet6Address) {
if (((Inet6Address) addr).isLinkLocalAddress())
continue;
Inet6Address inet6Address = (Inet6Address) addr;
inetAddrs.add(inet6Address.getHostAddress());
}
}
return inetAddrs;
}
@Rpc(description = "Returns active link properties")
public LinkProperties connectivityGetActiveLinkProperties() {
return mManager.getActiveLinkProperties();
}
@Rpc(description = "Factory reset of network policies")
public void connectivityFactoryResetNetworkPolicies(String subscriberId) {
mNetPolicyManager.factoryReset(subscriberId);
}
@Rpc(description = "Set data usage limit for subscription ID")
public void connectivitySetDataUsageLimit(
String subscriberId, String dataLimit) {
NetworkPolicy[] allPolicies = mNetPolicyManager.getNetworkPolicies();
for(int i=0; i<allPolicies.length; i++) {
String subId = allPolicies[i].template.getSubscriberId();
if(subId!=null && subId.equals(subscriberId)) {
allPolicies[i].limitBytes = Long.valueOf(dataLimit);
break;
}
}
mNetPolicyManager.setNetworkPolicies(allPolicies);
}
@Rpc(description = "Get network stats for device")
public long connectivityQuerySummaryForDevice(
String subscriberId, Long startTime, Long endTime)
throws SecurityException, RemoteException {
Bucket bucket = mNetStatsManager.querySummaryForDevice(
ConnectivityManager.TYPE_MOBILE, subscriberId, startTime, endTime);
return bucket.getTxBytes() + bucket.getRxBytes();
}
@Rpc(description = "Returns all interfaces on the android deivce")
public List<NetworkInterface> connectivityGetNetworkInterfaces() {
List<NetworkInterface> interfaces = null;
try {
interfaces = Collections.list(
NetworkInterface.getNetworkInterfaces());
} catch (SocketException e) {
return null;
};
return interfaces;
}
@Override
public void shutdown() {
connectivityStopTrackingConnectivityStateChange();
}
}