aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-07-15 01:28:40 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-07-15 01:28:40 +0000
commite056d40da0162b2805c5df079602fbf2da308bbb (patch)
tree14b46d718269544cf078dc96801f5a0f72e6dafb
parente5a2aa76cbd0249ecec3818af74033bebdb0b1ad (diff)
parente23d9b33c8c06ffd1cb464f040736d292c297134 (diff)
downloadsl4a-android12-mainline-conscrypt-release.tar.gz
Snap for 7550844 from e23d9b33c8c06ffd1cb464f040736d292c297134 to mainline-conscrypt-releaseandroid-mainline-12.0.0_r8android-mainline-12.0.0_r25android12-mainline-conscrypt-release
Change-Id: Ie838d4d9910073cd54db950c148253f8ea35be67
-rw-r--r--Android.bp44
-rw-r--r--Common/Android.bp15
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/AndroidFacade.java15
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/CertInstallerHelper.java100
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/ConnectivityConstants.java12
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/ConnectivityEvents.java26
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/ConnectivityManagerFacade.java162
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/VpnFacade.java40
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothHfpClientFacade.java150
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothSocketConnFacade.java16
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/bluetooth/GattClientFacade.java6
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/media/MediaSessionFacade.java14
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/net/IpSecManagerFacade.java6
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/net/SocketFacade.java19
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/telephony/SmsFacade.java2
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyConstants.java31
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyEvents.java49
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java60
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyStateListeners.java40
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyUtils.java73
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/wifi/WifiAwareManagerFacade.java10
-rwxr-xr-xCommon/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java682
-rw-r--r--Common/src/com/googlecode/android_scripting/facade/wifi/WifiRtt2ManagerFacade.java2
-rw-r--r--Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java136
-rw-r--r--Common/src/com/googlecode/android_scripting/rpc/MethodDescriptor.java8
-rw-r--r--InterpreterForAndroid/Android.bp9
-rw-r--r--METADATA3
-rw-r--r--ScriptingLayer/Android.bp9
-rw-r--r--ScriptingLayerForAndroid/Android.bp13
-rw-r--r--ScriptingLayerForAndroid/AndroidManifest.xml36
-rw-r--r--ScriptingLayerForAndroid/jni/Android.bp11
-rw-r--r--ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/ScriptingLayerService.java4
-rw-r--r--ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/TriggerService.java3
-rw-r--r--Utils/Android.bp9
-rw-r--r--Utils/src/com/googlecode/android_scripting/Log.java3
35 files changed, 1417 insertions, 401 deletions
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 00000000..85630370
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,44 @@
+//
+// Copyright (C) 2021 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 {
+ default_applicable_licenses: ["external_sl4a_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+ name: "external_sl4a_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ "SPDX-license-identifier-GPL-2.0",
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+}
diff --git a/Common/Android.bp b/Common/Android.bp
index 6578c143..ad42d294 100644
--- a/Common/Android.bp
+++ b/Common/Android.bp
@@ -14,6 +14,15 @@
// limitations under the License.
//
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_sl4a_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["external_sl4a_license"],
+}
+
java_library {
name: "sl4a.Common",
owner: "google",
@@ -23,19 +32,25 @@ java_library {
"android-common",
"sl4a.Utils",
"junit",
+ "modules-utils-build",
],
sdk_version: "core_platform",
libs: [
"framework-wifi.impl", // allow SL4A to access @hide Wifi APIs
+ "framework-connectivity.impl",
"framework",
"telephony-common",
"ims-common",
+ "bouncycastle-repackaged-unbundled",
],
srcs: [
"src/com/googlecode/android_scripting/**/*.java",
"src/org/apache/commons/codec/**/*.java",
+ ":cellbroadcast-shared-with-sl4a",
+ ":cellbroadcast-util-shared-srcs",
+ ":cellbroadcast-constants-shared-srcs",
],
}
diff --git a/Common/src/com/googlecode/android_scripting/facade/AndroidFacade.java b/Common/src/com/googlecode/android_scripting/facade/AndroidFacade.java
index 87b50cdd..1689c88a 100644
--- a/Common/src/com/googlecode/android_scripting/facade/AndroidFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/AndroidFacade.java
@@ -44,6 +44,8 @@ import android.text.method.PasswordTransformationMethod;
import android.widget.EditText;
import android.widget.Toast;
+import com.android.modules.utils.build.SdkLevel;
+
import com.googlecode.android_scripting.BaseApplication;
import com.googlecode.android_scripting.FileUtils;
import com.googlecode.android_scripting.FutureActivityTaskExecutor;
@@ -600,6 +602,16 @@ public class AndroidFacade extends RpcReceiver {
return Build.VERSION.SDK_INT;
}
+ @Rpc(description = "Returns whether the device is running SDK at least R")
+ public boolean isSdkAtLeastR() {
+ return SdkLevel.isAtLeastR();
+ }
+
+ @Rpc(description = "Returns whether the device is running SDK at least S")
+ public boolean isSdkAtLeastS() {
+ return SdkLevel.isAtLeastS();
+ }
+
@Rpc(description = "Returns the current device time.")
public Long getBuildTime() {
return Build.TIME;
@@ -857,7 +869,8 @@ public class AndroidFacade extends RpcReceiver {
@RpcParameter(name = "message") String message) {
createNotificationChannel();
// This contentIntent is a noop.
- PendingIntent contentIntent = PendingIntent.getService(mService, 0, new Intent(), 0);
+ PendingIntent contentIntent = PendingIntent.getService(mService, 0, new Intent(),
+ PendingIntent.FLAG_IMMUTABLE);
Notification.Builder builder = new Notification.Builder(mService, CHANNEL_ID);
builder.setSmallIcon(mResources.getLogo48())
.setTicker(message)
diff --git a/Common/src/com/googlecode/android_scripting/facade/CertInstallerHelper.java b/Common/src/com/googlecode/android_scripting/facade/CertInstallerHelper.java
index e4c36c13..d3d69c0f 100644
--- a/Common/src/com/googlecode/android_scripting/facade/CertInstallerHelper.java
+++ b/Common/src/com/googlecode/android_scripting/facade/CertInstallerHelper.java
@@ -17,33 +17,31 @@
package com.googlecode.android_scripting.facade;
import android.os.Environment;
-import android.security.Credentials;
-import android.security.KeyStore;
import android.util.Log;
import com.android.internal.net.VpnProfile;
-import com.android.org.bouncycastle.asn1.ASN1InputStream;
-import com.android.org.bouncycastle.asn1.ASN1Sequence;
-import com.android.org.bouncycastle.asn1.DEROctetString;
-import com.android.org.bouncycastle.asn1.x509.BasicConstraints;
-
-import junit.framework.Assert;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.x509.BasicConstraints;
import libcore.io.Streams;
+import junit.framework.Assert;
+
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
+import java.security.KeyStore;
import java.security.KeyStore.PasswordProtection;
import java.security.KeyStore.PrivateKeyEntry;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.UnrecoverableEntryException;
import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
@@ -58,21 +56,27 @@ import java.util.List;
public class CertInstallerHelper {
private static final String TAG = "CertInstallerHelper";
/* Define a password to unlock keystore after it is reset */
- private static final String CERT_STORE_PASSWORD = "password";
- private final int mUid = KeyStore.UID_SELF;
private PrivateKey mUserKey; // private key
private X509Certificate mUserCert; // user certificate
private List<X509Certificate> mCaCerts = new ArrayList<X509Certificate>();
- private KeyStore mKeyStore = KeyStore.getInstance();
+ private final KeyStore mKeyStore;
/**
- * Unlock keystore and set password
+ * Delete all key for caller.
*/
public CertInstallerHelper() {
- for (String key : mKeyStore.list("")) {
- mKeyStore.delete(key, KeyStore.UID_SELF);
+ try {
+ mKeyStore = KeyStore.getInstance("AndroidKeyStore");
+ mKeyStore.load(null);
+ final Enumeration<String> aliases = mKeyStore.aliases();
+ while (aliases.hasMoreElements()) {
+ mKeyStore.deleteEntry(aliases.nextElement());
+ }
+ } catch (KeyStoreException | CertificateException | NoSuchAlgorithmException
+ | IOException e) {
+ Log.e(TAG, "Failed to open and cleanup Keystore.", e);
+ throw new RuntimeException("Failed to open and cleanup Keystore.", e);
}
- mKeyStore.onUserPasswordChanged(CERT_STORE_PASSWORD);
}
private void extractCertificate(String certFile, String password) {
@@ -166,7 +170,7 @@ public class CertInstallerHelper {
/**
* Extract certificate from the given file, and install it to keystore
- * @param name certificate name
+ * @param profile VpnProfile
* @param certFile .p12 file which includes certificates
* @param password password to extract the .p12 file
*/
@@ -174,51 +178,39 @@ public class CertInstallerHelper {
// extract private keys, certificates from the provided file
extractCertificate(certFile, password);
// install certificate to the keystore
- int flags = KeyStore.FLAG_ENCRYPTED;
try {
+ boolean caInstalledWithUserKey = false;
+
if (mUserKey != null) {
Log.v(TAG, "has private key");
- String key = Credentials.USER_PRIVATE_KEY + profile.ipsecUserCert;
- byte[] value = mUserKey.getEncoded();
-
- if (!mKeyStore.importKey(key, value, mUid, flags)) {
- Log.e(TAG, "Failed to install " + key + " as user " + mUid);
- return;
+ if (mUserCert == null) {
+ throw new AssertionError("Must have user cert if user key is installed.");
}
- Log.v(TAG, "install " + key + " as user " + mUid + " is successful");
- }
-
- if (mUserCert != null) {
- String certName = Credentials.USER_CERTIFICATE + profile.ipsecUserCert;
- byte[] certData = Credentials.convertToPem(mUserCert);
-
- if (!mKeyStore.put(certName, certData, mUid, flags)) {
- Log.e(TAG, "Failed to install " + certName + " as user " + mUid);
- return;
+ final List<Certificate> certChain = new ArrayList<Certificate>();
+ certChain.add(mUserCert);
+ if (profile.ipsecUserCert.equals(profile.ipsecCaCert)) {
+ // If the CA certs should be installed under the same alias they have to be
+ // added to the end of the certificate chain.
+ certChain.addAll(mCaCerts);
+ // Make a note that we have installed the CA cert chain along with the
+ // user key and cert.
+ caInstalledWithUserKey = true;
}
- Log.v(TAG, "install " + certName + " as user" + mUid + " is successful.");
+ mKeyStore.setKeyEntry(profile.ipsecUserCert, mUserKey, null,
+ certChain.toArray(new Certificate[0]));
+ Log.v(TAG, "install " + profile.ipsecUserCert + " is successful");
}
- if (!mCaCerts.isEmpty()) {
- String caListName = Credentials.CA_CERTIFICATE + profile.ipsecCaCert;
- X509Certificate[] caCerts = mCaCerts.toArray(new X509Certificate[mCaCerts.size()]);
- byte[] caListData = Credentials.convertToPem(caCerts);
-
- if (!mKeyStore.put(caListName, caListData, mUid, flags)) {
- Log.e(TAG, "Failed to install " + caListName + " as user " + mUid);
- return;
+ if (!(mCaCerts.isEmpty() || caInstalledWithUserKey)) {
+ if (mCaCerts.size() != 1) {
+ throw new AssertionError("Trusted certificate cannot be a cert chain.");
}
- Log.v(TAG, " install " + caListName + " as user " + mUid + " is successful");
+ mKeyStore.setCertificateEntry(profile.ipsecCaCert, mCaCerts.get(0));
+ Log.v(TAG, " install " + profile.ipsecCaCert + " is successful");
}
- } catch (CertificateEncodingException e) {
- Log.e(TAG, "Exception while convert certificates to pem " + e);
+ } catch (KeyStoreException e) {
+ Log.e(TAG, "Exception trying to import certificates. " + e);
throw new AssertionError(e);
- } catch (IOException e) {
- Log.e(TAG, "IOException while convert to pem: " + e);
}
}
-
- public int getUid() {
- return mUid;
- }
}
diff --git a/Common/src/com/googlecode/android_scripting/facade/ConnectivityConstants.java b/Common/src/com/googlecode/android_scripting/facade/ConnectivityConstants.java
index 8e5297ba..867f6245 100644
--- a/Common/src/com/googlecode/android_scripting/facade/ConnectivityConstants.java
+++ b/Common/src/com/googlecode/android_scripting/facade/ConnectivityConstants.java
@@ -66,6 +66,7 @@ public class ConnectivityConstants {
public static final String NETWORK_CALLBACK_EVENT = "networkCallbackEvent";
public static final String MAX_MS_TO_LIVE = "maxMsToLive";
public static final String RSSI = "rssi";
+ public static final String METERED = "metered";
public static final String INTERFACE_NAME = "interfaceName";
public static final String CREATE_TIMESTAMP = "creation_timestamp";
public static final String CURRENT_TIMESTAMP = "current_timestamp";
@@ -78,9 +79,20 @@ public class ConnectivityConstants {
public static final String TetheringFailedCallback = "ConnectivityManagerOnTetheringFailed";
/**
+ * Constants for Meteredness
+ */
+ public static final Integer NET_CAPABILITY_TEMPORARILY_NOT_METERED = 25;
+
+ /**
* Constants for PrivateDnsMode
*/
public static final String PrivateDnsModeOff = "off";
public static final String PrivateDnsModeOpportunistic = "opportunistic";
public static final String PrivateDnsModeStrict = "hostname";
+
+ /**
+ * Constants for NetworkCapabilties/NetworkRequest
+ */
+ public static final String NET_CAPABILITIES_TRANSPORT_TYPE = "TransportType";
+ public static final String NET_CAPABILITIES_CAPABILITIES = "Capability";
}
diff --git a/Common/src/com/googlecode/android_scripting/facade/ConnectivityEvents.java b/Common/src/com/googlecode/android_scripting/facade/ConnectivityEvents.java
index 5c12b7c1..64c6e650 100644
--- a/Common/src/com/googlecode/android_scripting/facade/ConnectivityEvents.java
+++ b/Common/src/com/googlecode/android_scripting/facade/ConnectivityEvents.java
@@ -17,8 +17,8 @@
package com.googlecode.android_scripting.facade;
import android.net.NetworkCapabilities;
-import android.net.wifi.aware.WifiAwareNetworkInfo;
+import com.googlecode.android_scripting.jsonrpc.JsonBuilder;
import com.googlecode.android_scripting.jsonrpc.JsonSerializable;
import org.json.JSONException;
@@ -136,29 +136,7 @@ public class ConnectivityEvents {
*/
public JSONObject toJSON() throws JSONException {
JSONObject json = super.toJSON();
- json.put(ConnectivityConstants.NetworkCallbackContainer.RSSI,
- mNetworkCapabilities.getSignalStrength());
- if (mNetworkCapabilities.getNetworkSpecifier() != null) {
- json.put("network_specifier",
- mNetworkCapabilities.getNetworkSpecifier().toString());
- }
- if (mNetworkCapabilities.getTransportInfo() instanceof WifiAwareNetworkInfo) {
- WifiAwareNetworkInfo anc =
- (WifiAwareNetworkInfo) mNetworkCapabilities.getTransportInfo();
-
- String ipv6 = anc.getPeerIpv6Addr().toString();
- if (ipv6.charAt(0) == '/') {
- ipv6 = ipv6.substring(1);
- }
- json.put("aware_ipv6", ipv6);
- if (anc.getPort() != 0) {
- json.put("aware_port", anc.getPort());
- }
- if (anc.getTransportProtocol() != -1) {
- json.put("aware_transport_protocol", anc.getTransportProtocol());
- }
- }
- return json;
+ return JsonBuilder.buildNetworkCapabilities(json, mNetworkCapabilities);
}
}
diff --git a/Common/src/com/googlecode/android_scripting/facade/ConnectivityManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/ConnectivityManagerFacade.java
index fb66b264..26f00128 100644
--- a/Common/src/com/googlecode/android_scripting/facade/ConnectivityManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/ConnectivityManagerFacade.java
@@ -16,6 +16,8 @@
package com.googlecode.android_scripting.facade;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+
import android.app.Service;
import android.app.usage.NetworkStats;
import android.app.usage.NetworkStats.Bucket;
@@ -32,18 +34,22 @@ import android.net.NetworkInfo;
import android.net.NetworkPolicy;
import android.net.NetworkPolicyManager;
import android.net.NetworkRequest;
+import android.net.NetworkSpecifier;
import android.net.ProxyInfo;
import android.net.RouteInfo;
-import android.net.StringNetworkSpecifier;
import android.net.Uri;
+import android.net.wifi.WifiNetworkSpecifier;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.Settings;
+import com.android.modules.utils.build.SdkLevel;
+
import com.google.common.io.ByteStreams;
import com.googlecode.android_scripting.FileUtils;
import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.facade.wifi.WifiAwareManagerFacade;
+import com.googlecode.android_scripting.facade.wifi.WifiManagerFacade;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.rpc.Rpc;
import com.googlecode.android_scripting.rpc.RpcOptional;
@@ -66,6 +72,7 @@ import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
+import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
@@ -122,7 +129,19 @@ public class ConnectivityManagerFacade extends RpcReceiver {
}
}
- class NetworkCallback extends ConnectivityManager.NetworkCallback {
+ /**
+ * Used to dispatch to a different constructor depending on R or S, since
+ * {@link ConnectivityManager.NetworkCallback#NetworkCallback(int)} was added in S.
+ */
+ private NetworkCallback newNetworkCallback(int events) {
+ if (SdkLevel.isAtLeastS()) {
+ return new NetworkCallback(events);
+ } else {
+ return new NetworkCallback(events, false);
+ }
+ }
+
+ private 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;
@@ -135,23 +154,39 @@ public class ConnectivityManagerFacade extends RpcReceiver {
public static final int EVENT_RESUMED = 1 << 7;
public static final int EVENT_LINK_PROPERTIES_CHANGED = 1 << 8;
public static final int EVENT_BLOCKED_STATUS_CHANGED = 1 << 9;
- 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
- | EVENT_BLOCKED_STATUS_CHANGED;
+ 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
+ | EVENT_BLOCKED_STATUS_CHANGED;
private int mEvents;
public String mId;
private long mCreateTimestamp;
- public NetworkCallback(int events) {
+ /** Called in >= Android S where super(int) does exist. */
+ private NetworkCallback(int events) {
+ super(ConnectivityManager.NetworkCallback.FLAG_INCLUDE_LOCATION_INFO);
+ init(events);
+ }
+
+ /**
+ * Called in <= Android R where super(int) doesn't exist.
+ * @param ignore placeholder argument to differentiate between R and S constructors' method
+ * signatures.
+ */
+ private NetworkCallback(int events, boolean ignore) {
super();
+ init(events);
+ }
+
+ private void init(int events) {
mEvents = events;
mId = this.toString();
mCreateTimestamp = System.currentTimeMillis();
@@ -431,7 +466,7 @@ public class ConnectivityManagerFacade extends RpcReceiver {
builder.setSignalStrength((int) rssi);
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
NetworkRequest networkRequest = builder.build();
- mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL);
+ mNetworkCallback = newNetworkCallback(NetworkCallback.EVENT_ALL);
mManager.registerNetworkCallback(networkRequest, mNetworkCallback);
String key = mNetworkCallback.mId;
mNetworkCallbackMap.put(key, mNetworkCallback);
@@ -446,6 +481,24 @@ public class ConnectivityManagerFacade extends RpcReceiver {
private NetworkRequest buildNetworkRequestFromJson(JSONObject configJson)
throws JSONException {
+ return makeNetworkRequestBuilderFromJson(configJson).build();
+ }
+
+ private NetworkRequest buildWifiAwareNetworkRequestFromJson(JSONObject configJson)
+ throws JSONException {
+ final NetworkRequest.Builder builder = makeNetworkRequestBuilderFromJson(configJson);
+ if (configJson.has("NetworkSpecifier")) {
+ final String strSpecifier = configJson.getString("NetworkSpecifier");
+ Log.d("build NetworkSpecifier" + strSpecifier);
+ final NetworkSpecifier specifier = WifiAwareManagerFacade.getNetworkSpecifier(
+ new JSONObject(strSpecifier));
+ builder.setNetworkSpecifier(specifier);
+ }
+ return builder.build();
+ }
+
+ private NetworkRequest.Builder makeNetworkRequestBuilderFromJson(JSONObject configJson)
+ throws JSONException {
NetworkRequest.Builder builder = new NetworkRequest.Builder();
if (configJson.has("ClearCapabilities")) {
@@ -455,16 +508,19 @@ public class ConnectivityManagerFacade extends RpcReceiver {
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(ConnectivityConstants.NET_CAPABILITIES_TRANSPORT_TYPE)) {
+ Log.d("build TransportType"
+ + configJson.getInt(ConnectivityConstants.NET_CAPABILITIES_TRANSPORT_TYPE));
+ builder.addTransportType(
+ configJson.getInt(ConnectivityConstants.NET_CAPABILITIES_TRANSPORT_TYPE));
}
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");
+ if (configJson.has(ConnectivityConstants.NET_CAPABILITIES_CAPABILITIES)) {
+ JSONArray capabilities =
+ configJson.getJSONArray(ConnectivityConstants.NET_CAPABILITIES_CAPABILITIES);
for (int i = 0; i < capabilities.length(); i++) {
Log.d("build Capability" + capabilities.getInt(i));
builder.addCapability(capabilities.getInt(i));
@@ -482,20 +538,14 @@ public class ConnectivityManagerFacade extends RpcReceiver {
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;
+ return builder;
}
@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);
+ mNetworkCallback = newNetworkCallback(NetworkCallback.EVENT_ALL);
mManager.registerNetworkCallback(networkRequest, mNetworkCallback);
String key = mNetworkCallback.mId;
mNetworkCallbackMap.put(key, mNetworkCallback);
@@ -517,7 +567,7 @@ public class ConnectivityManagerFacade extends RpcReceiver {
@Rpc(description = "register a default network callback")
public String connectivityRegisterDefaultNetworkCallback() {
- mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL);
+ mNetworkCallback = newNetworkCallback(NetworkCallback.EVENT_ALL);
mManager.registerDefaultNetworkCallback(mNetworkCallback);
String key = mNetworkCallback.mId;
mNetworkCallbackMap.put(key, mNetworkCallback);
@@ -528,7 +578,7 @@ public class ConnectivityManagerFacade extends RpcReceiver {
public String connectivityRequestNetwork(@RpcParameter(name = "configJson")
JSONObject configJson) throws JSONException {
NetworkRequest networkRequest = buildNetworkRequestFromJson(configJson);
- mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL);
+ mNetworkCallback = newNetworkCallback(NetworkCallback.EVENT_ALL);
mManager.requestNetwork(networkRequest, mNetworkCallback);
String key = mNetworkCallback.mId;
mNetworkCallbackMap.put(key, mNetworkCallback);
@@ -538,23 +588,42 @@ public class ConnectivityManagerFacade extends RpcReceiver {
@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);
+ NetworkRequest networkRequest = buildWifiAwareNetworkRequestFromJson(configJson);
+ mNetworkCallback = newNetworkCallback(NetworkCallback.EVENT_ALL);
mManager.requestNetwork(networkRequest, mNetworkCallback);
String key = mNetworkCallback.mId;
mNetworkCallbackMap.put(key, mNetworkCallback);
return key;
}
+ /**
+ * Initiates a network request {@link NetworkRequest} using {@link WifiNetworkSpecifier}.
+ *
+ * @param wNs JSONObject Dictionary of wifi network specifier parameters
+ * @param timeoutInMs Timeout for the request. 0 indicates no timeout.
+ * @throws JSONException
+ * @throws GeneralSecurityException
+ */
+ @Rpc(description = "Initiates a network request using the provided network specifier")
+ public String connectivityRequestWifiNetwork(
+ @RpcParameter(name = "wifiNetworkSpecifier") JSONObject wNs,
+ @RpcParameter(name = "timeoutInMS") Integer timeoutInMs)
+ throws JSONException, GeneralSecurityException {
+ NetworkRequest networkRequest = new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_WIFI)
+ .setNetworkSpecifier(WifiManagerFacade.genWifiNetworkSpecifier(wNs))
+ .build();
+ mNetworkCallback = newNetworkCallback(NetworkCallback.EVENT_ALL);
+ if (timeoutInMs != 0) {
+ mManager.requestNetwork(networkRequest, mNetworkCallback, timeoutInMs);
+ } else {
+ 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) {
@@ -598,6 +667,16 @@ public class ConnectivityManagerFacade extends RpcReceiver {
return mManager.getAllNetworkInfo();
}
+ @Rpc(description = "Get connection status information about all network types supported by the device.")
+ public NetworkCapabilities[] connectivityNetworkGetAllCapabilities() {
+ Network[] networks = mManager.getAllNetworks();
+ NetworkCapabilities[] networkCapabilties = new NetworkCapabilities[networks.length];
+ for (int i = 0; i < networks.length; i++) {
+ networkCapabilties[i] = mManager.getNetworkCapabilities(networks[i]);
+ }
+ return networkCapabilties;
+ }
+
@Rpc(description = "Check whether the active network is connected to the Internet.")
public Boolean connectivityNetworkIsConnected() {
NetworkInfo current = mManager.getActiveNetworkInfo();
@@ -1039,5 +1118,8 @@ public class ConnectivityManagerFacade extends RpcReceiver {
@Override
public void shutdown() {
connectivityStopTrackingConnectivityStateChange();
+ for (NetworkCallback networkCallback : mNetworkCallbackMap.values()) {
+ mManager.unregisterNetworkCallback(networkCallback);
+ }
}
}
diff --git a/Common/src/com/googlecode/android_scripting/facade/VpnFacade.java b/Common/src/com/googlecode/android_scripting/facade/VpnFacade.java
index 732cc605..bed8cc82 100644
--- a/Common/src/com/googlecode/android_scripting/facade/VpnFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/VpnFacade.java
@@ -16,50 +16,50 @@
package com.googlecode.android_scripting.facade;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.json.JSONObject;
+import android.app.Service;
+import android.net.VpnManager;
+import android.os.RemoteException;
+import android.security.Credentials;
+import android.security.KeyStore;
+import android.security.LegacyVpnProfileStore;
import com.android.internal.net.LegacyVpnInfo;
import com.android.internal.net.VpnConfig;
import com.android.internal.net.VpnProfile;
import com.android.internal.util.ArrayUtils;
+
import com.google.android.collect.Lists;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.rpc.Rpc;
import com.googlecode.android_scripting.rpc.RpcParameter;
-import android.app.Service;
-import android.content.Context;
-import android.net.IConnectivityManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.security.Credentials;
-import android.security.KeyStore;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.List;
/**
- * Access NFC functions.
+ * Access VPN functions.
*/
public class VpnFacade extends RpcReceiver {
private final Service mService;
- private final IConnectivityManager mConService;
+ private final VpnManager mVpnManager;
private CertInstallerHelper mCertHelper;
public VpnFacade(FacadeManager manager) {
super(manager);
mService = manager.getService();
mCertHelper = new CertInstallerHelper();
- mConService = IConnectivityManager.Stub
- .asInterface(ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
+ mVpnManager = mService.getSystemService(VpnManager.class);
}
static List<VpnProfile> loadVpnProfiles(KeyStore keyStore, int... excludeTypes) {
final ArrayList<VpnProfile> result = Lists.newArrayList();
- for (String key : keyStore.list(Credentials.VPN)) {
- final VpnProfile profile = VpnProfile.decode(key, keyStore.get(Credentials.VPN + key));
+ for (String key : LegacyVpnProfileStore.list(Credentials.VPN)) {
+ final VpnProfile profile = VpnProfile.decode(key,
+ LegacyVpnProfileStore.get(Credentials.VPN + key));
if (profile != null && !ArrayUtils.contains(excludeTypes, profile.type)) {
result.add(profile);
}
@@ -92,17 +92,17 @@ public class VpnFacade extends RpcReceiver {
public void vpnStartLegacyVpn(@RpcParameter(name = "vpnProfile") JSONObject vpnProfile)
throws RemoteException {
VpnProfile profile = genLegacyVpnProfile(vpnProfile);
- mConService.startLegacyVpn(profile);
+ mVpnManager.startLegacyVpn(profile);
}
@Rpc(description = "Stop the current legacy VPN connection.")
public void vpnStopLegacyVpn() throws RemoteException {
- mConService.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, mService.getUserId());
+ mVpnManager.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, mService.getUserId());
}
@Rpc(description = "Get the info object of the currently active legacy VPN connection.")
public LegacyVpnInfo vpnGetLegacyVpnInfo() throws RemoteException {
- return mConService.getLegacyVpnInfo(mService.getUserId());
+ return mVpnManager.getLegacyVpnInfo(mService.getUserId());
}
@Override
diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothHfpClientFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothHfpClientFacade.java
index 17e7b575..8c6f93f8 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothHfpClientFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothHfpClientFacade.java
@@ -28,6 +28,7 @@ import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.facade.FacadeManager;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.rpc.Rpc;
+import com.googlecode.android_scripting.rpc.RpcDefault;
import com.googlecode.android_scripting.rpc.RpcParameter;
import java.util.ArrayList;
@@ -237,27 +238,32 @@ public class BluetoothHfpClientFacade extends RpcReceiver {
return sHfpClientProfile.getAudioState(device);
}
+ private BluetoothDevice getDevice(String deviceStr) {
+ if (sHfpClientProfile == null) return null;
+ BluetoothDevice device;
+ try {
+ device = BluetoothFacade.getDevice(sHfpClientProfile.getConnectedDevices(), deviceStr);
+ } catch (Exception e) {
+ // Do nothing since it is disconnect and this function should force disconnect.
+ Log.e("bluetoothHfpClientConnect getDevice failed " + e);
+ return null;
+ }
+ return device;
+ }
+
/**
- * Start Voice Recognition on remote device
+ * Starts Voice Recognition on remote device
*
* @param deviceStr the Bluetooth MAC address of remote device
- * @return True if command was sent
+ * @return True if command has been issued successfully
*/
@Rpc(description = "Start Remote device Voice Recognition through HFP Client.")
public boolean bluetoothHfpClientStartVoiceRecognition(
@RpcParameter(name = "device",
description = "MAC address of a bluetooth device.")
String deviceStr) {
- if (sHfpClientProfile == null) return false;
- BluetoothDevice device;
- try {
- device = BluetoothFacade.getDevice(
- sHfpClientProfile.getConnectedDevices(), deviceStr);
- } catch (Exception e) {
- // Do nothing since it is disconnect and this function should force disconnect.
- Log.e("bluetoothHfpClientConnect getDevice failed " + e);
- return false;
- }
+ BluetoothDevice device = getDevice(deviceStr);
+ if (device == null) return false;
return sHfpClientProfile.startVoiceRecognition(device);
}
@@ -265,49 +271,89 @@ public class BluetoothHfpClientFacade extends RpcReceiver {
* Stops Voice Recognition in the remote device through Bluetooth HFP client
*
* @param deviceStr the Bluetooth MAC address of remote device
- * @return True if command was sent
+ * @return True if command has been issued successfully
*/
@Rpc(description = "Stops Remote device Voice Recognition through HFP Client.")
public boolean bluetoothHfpClientStopVoiceRecognition(
@RpcParameter(name = "device",
description = "MAC address of a bluetooth device.")
String deviceStr) {
- if (sHfpClientProfile == null) return false;
- BluetoothDevice device;
- try {
- device = BluetoothFacade.getDevice(
- sHfpClientProfile.getConnectedDevices(), deviceStr);
- } catch (Exception e) {
- // Do nothing since it is disconnect
- // and this function should force disconnect.
- Log.e("bluetoothHfpClientConnect getDevice failed " + e);
- return false;
- }
+ BluetoothDevice device = getDevice(deviceStr);
+ if (device == null) return false;
return sHfpClientProfile.stopVoiceRecognition(device);
}
/**
+ * Initiates a connection of audio channel.
+ *
+ * It setup SCO channel with remote connected Handsfree Audio Gateway device.
+ *
+ * @param deviceStr the Bluetooth MAC address of remote device
+ * @return True if command has been issued successfully
+ */
+ @Rpc(description = "Initiates a connection of audio channel.")
+ public boolean bluetoothHfpClientConnectAudio(
+ @RpcParameter(name = "device",
+ description = "MAC address of a bluetooth device.")
+ String deviceStr) {
+ BluetoothDevice device = getDevice(deviceStr);
+ if (device == null) return false;
+ return sHfpClientProfile.connectAudio(device);
+ }
+
+ /**
+ * Dials a call in the remote device through Bluetooth HFP Client
+ *
+ * The last number dial will be placed if the number is an empty string
+ *
+ * @param deviceStr the Bluetooth MAC address of remote device
+ * @param number phone number to dial, the value of null or empty string for last number redial
+ * @return The string of <code>{@link BluetoothHeadsetClientCall} call</code> or null if no
+ * device was not found.
+ */
+ @Rpc(description = "Dials a call in the remote device through HFP Client.")
+ public String bluetoothHfpClientDial(
+ @RpcParameter(name = "device",
+ description = "MAC address of a bluetooth device.") String deviceStr,
+ @RpcParameter(name = "phone_number", description =
+ "phone number to dial, default for last number redial")
+ @RpcDefault("") String number) {
+ BluetoothDevice device = getDevice(deviceStr);
+ if (device == null) return null;
+ return sHfpClientProfile.dial(device, number).toString(true);
+ }
+
+ /**
+ * Disconnects audio channel.
+ *
+ * It tears down the SCO channel from remote AuG device.
+ *
+ * @param deviceStr the Bluetooth MAC address of remote device
+ * @return True if command has been issued successfully
+ */
+ @Rpc(description = "Disconnects audio channel.")
+ public boolean bluetoothHfpClientDisconnectAudio(
+ @RpcParameter(name = "device",
+ description = "MAC address of a bluetooth device.")
+ String deviceStr) {
+ BluetoothDevice device = getDevice(deviceStr);
+ if (device == null) return false;
+ return sHfpClientProfile.disconnectAudio(device);
+ }
+
+ /**
* Accepts a call in the remote device through Bluetooth HFP Client
*
* @param deviceStr the Bluetooth MAC address of remote device
- * @return True if command was sent
+ * @return True if command has been issued successfully
*/
@Rpc(description = "Accepts a call in the remote device through HFP Client.")
public boolean bluetoothHfpClientAcceptCall(
@RpcParameter(name = "device",
description = "MAC address of a bluetooth device.")
String deviceStr) {
- if (sHfpClientProfile == null) return false;
- BluetoothDevice device;
- try {
- device = BluetoothFacade.getDevice(
- sHfpClientProfile.getConnectedDevices(), deviceStr);
- } catch (Exception e) {
- // Do nothing since it is disconnect
- // and this function should force disconnect.
- Log.e("bluetoothHfpClientConnect getDevice failed " + e);
- return false;
- }
+ BluetoothDevice device = getDevice(deviceStr);
+ if (device == null) return false;
return sHfpClientProfile.acceptCall(device, BluetoothHeadsetClient.CALL_ACCEPT_NONE);
}
@@ -315,24 +361,15 @@ public class BluetoothHfpClientFacade extends RpcReceiver {
* Terminates all calls in the remote device through Bluetooth HFP Client
*
* @param deviceStr the Bluetooth MAC address of remote device
- * @return True if command was sent
+ * @return True if command has been issued successfully
*/
@Rpc(description = "Terminates all calls in the remote device through HFP Client.")
public boolean bluetoothHfpClientTerminateAllCalls(
@RpcParameter(name = "device",
description = "MAC address of a bluetooth device.")
String deviceStr) {
- if (sHfpClientProfile == null) return false;
- BluetoothDevice device;
- try {
- device = BluetoothFacade.getDevice(
- sHfpClientProfile.getConnectedDevices(), deviceStr);
- } catch (Exception e) {
- // Do nothing since it is disconnect
- // and this function should force disconnect.
- Log.e("bluetoothHfpClientConnect getDevice failed " + e);
- return false;
- }
+ BluetoothDevice device = getDevice(deviceStr);
+ if (device == null) return false;
return sHfpClientProfile.terminateCall(device, null);
}
@@ -340,28 +377,19 @@ public class BluetoothHfpClientFacade extends RpcReceiver {
* Rejects a call in the remote device through Bluetooth HFP Client
*
* @param deviceStr the Bluetooth MAC address of remote device
- * @return True if command was sent
+ * @return True if command has been issued successfully
*/
@Rpc(description = "Rejects a call in the remote device through HFP Client.")
public boolean bluetoothHfpClientRejectCall(
@RpcParameter(name = "device",
description = "MAC address of a bluetooth device.")
String deviceStr) {
- if (sHfpClientProfile == null) return false;
- BluetoothDevice device;
- try {
- device = BluetoothFacade.getDevice(
- sHfpClientProfile.getConnectedDevices(), deviceStr);
- } catch (Exception e) {
- // Do nothing since it is disconnect
- // and this function should force disconnect.
- Log.e("bluetoothHfpClientConnect getDevice failed " + e);
- return false;
- }
+ BluetoothDevice device = getDevice(deviceStr);
+ if (device == null) return false;
return sHfpClientProfile.rejectCall(device);
}
@Override
public void shutdown() {
}
-}
+} \ No newline at end of file
diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothSocketConnFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothSocketConnFacade.java
index c08fc96a..18ca8588 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothSocketConnFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothSocketConnFacade.java
@@ -33,6 +33,7 @@ import com.googlecode.android_scripting.rpc.RpcParameter;
import org.apache.commons.codec.binary.Base64Codec;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
@@ -555,9 +556,19 @@ public class BluetoothSocketConnFacade extends RpcReceiver {
byte bufIndex = (byte) 0x00FF;
try {
+
+ ByteArrayOutputStream tmp_array = new ByteArrayOutputStream();
for (int i = 0; i < numBuffers; i++) {
// Read one buffer
- byte[] readBuf = conn.readBinary(bufferSize);
+ while (tmp_array.size() < bufferSize) {
+ byte[] tmp_read = conn.readBinary(bufferSize);
+ if (tmp_read.length == 0) {
+ break;
+ }
+ tmp_array.write(tmp_read);
+ }
+ byte[] readBuf = tmp_array.toByteArray();
+ tmp_array.reset();
// Make sure the contents are valid
int nextInChar = 'a';
@@ -587,6 +598,9 @@ public class BluetoothSocketConnFacade extends RpcReceiver {
nextInChar = getNextOutputChar(nextInChar);
}
Log.d("bluetoothConnectionThroughputRead: Buffer Read index=" + i);
+ if (bufferSize < readBuf.length) {
+ tmp_array.write(readBuf, bufferSize, readBuf.length - bufferSize);
+ }
}
long endTesttime = System.currentTimeMillis();
diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattClientFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattClientFacade.java
index f6edde8a..e2286724 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattClientFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattClientFacade.java
@@ -1740,7 +1740,7 @@ public class GattClientFacade extends RpcReceiver {
* @param index the bluetooth gatt index
* @param minConnectionInterval minimum connection interval
* @param maxConnectionInterval maximum connection interval
- * @param slaveLatency maximum slave latency
+ * @param peripheralLatency maximum peripheral latency
* @param supervisionTimeout supervision timeout
* @return boolean True if successful False otherwise.
* @throws Exception
@@ -1750,7 +1750,7 @@ public class GattClientFacade extends RpcReceiver {
@RpcParameter(name = "index") Integer index,
@RpcParameter(name = "minConnectionInterval") Integer minConnectionInterval,
@RpcParameter(name = "maxConnectionInterval") Integer maxConnectionInterval,
- @RpcParameter(name = "slaveLatency") Integer slaveLatency,
+ @RpcParameter(name = "peripheralLatency") Integer peripheralLatency,
@RpcParameter(name = "supervisionTimeout") Integer supervisionTimeout,
@RpcParameter(name = "minConnectionEventLen") Integer minConnectionEventLen,
@RpcParameter(name = "maxConnectionEventLen") Integer maxConnectionEventLen)
@@ -1758,7 +1758,7 @@ public class GattClientFacade extends RpcReceiver {
boolean result = false;
if (mBluetoothGattList.get(index) != null) {
result = mBluetoothGattList.get(index).requestLeConnectionUpdate(
- minConnectionInterval, maxConnectionInterval, slaveLatency, supervisionTimeout,
+ minConnectionInterval, maxConnectionInterval, peripheralLatency, supervisionTimeout,
minConnectionEventLen, maxConnectionEventLen);
} else {
throw new Exception("Invalid index input:" + index);
diff --git a/Common/src/com/googlecode/android_scripting/facade/media/MediaSessionFacade.java b/Common/src/com/googlecode/android_scripting/facade/media/MediaSessionFacade.java
index ad16dc9d..5b4e199b 100644
--- a/Common/src/com/googlecode/android_scripting/facade/media/MediaSessionFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/media/MediaSessionFacade.java
@@ -16,19 +16,15 @@
package com.googlecode.android_scripting.facade.media;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.media.session.MediaController;
import android.media.session.MediaSession;
+import android.media.session.MediaSession.Callback;
import android.media.session.MediaSessionManager;
import android.media.session.MediaSessionManager.OnActiveSessionsChangedListener;
import android.media.session.PlaybackState;
-import android.media.session.MediaSession.Callback;
import android.view.KeyEvent;
import com.googlecode.android_scripting.Log;
@@ -40,6 +36,10 @@ import com.googlecode.android_scripting.rpc.Rpc;
import com.googlecode.android_scripting.rpc.RpcDefault;
import com.googlecode.android_scripting.rpc.RpcParameter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+
/**
* Expose functionalities of MediaSession related classes
* like MediaSession, MediaSessionManager, MediaController.
@@ -146,8 +146,8 @@ public class MediaSessionFacade extends RpcReceiver {
}
KeyEvent keyDown = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
KeyEvent keyUp = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
- mManager.dispatchMediaKeyEvent(keyDown);
- mManager.dispatchMediaKeyEvent(keyUp);
+ mManager.dispatchMediaKeyEvent(keyDown, false);
+ mManager.dispatchMediaKeyEvent(keyUp, false);
}
private MediaController getMediaController(int idx) {
diff --git a/Common/src/com/googlecode/android_scripting/facade/net/IpSecManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/net/IpSecManagerFacade.java
index d0a443f4..a856a1b2 100644
--- a/Common/src/com/googlecode/android_scripting/facade/net/IpSecManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/net/IpSecManagerFacade.java
@@ -18,6 +18,7 @@ package com.googlecode.android_scripting.facade.net;
import android.app.Service;
import android.content.Context;
+import android.net.InetAddresses;
import android.net.IpSecAlgorithm;
import android.net.IpSecManager;
import android.net.IpSecManager.ResourceUnavailableException;
@@ -26,7 +27,6 @@ import android.net.IpSecManager.SpiUnavailableException;
import android.net.IpSecManager.UdpEncapsulationSocket;
import android.net.IpSecTransform;
import android.net.IpSecTransform.Builder;
-import android.net.NetworkUtils;
import com.google.common.io.BaseEncoding;
import com.googlecode.android_scripting.Log;
@@ -315,7 +315,7 @@ public class IpSecManagerFacade extends RpcReceiver {
String addr,
String udpEncapSockId) {
IpSecTransform transform = null;
- InetAddress inetAddr = NetworkUtils.numericToInetAddress(addr);
+ InetAddress inetAddr = InetAddresses.parseNumericAddress(addr);
UdpEncapsulationSocket udpEncapSocket = sUdpEncapHashMap.get(udpEncapSockId);
SecurityParameterIndex spi = sSpiHashMap.get(spiId);
if (spi == null) {
@@ -385,7 +385,7 @@ public class IpSecManagerFacade extends RpcReceiver {
public String ipSecAllocateSecurityParameterIndex(
@RpcParameter(name = "addr") String addr,
@RpcParameter(name = "requestedSpi") @RpcOptional Integer requestedSpi) {
- InetAddress inetAddr = NetworkUtils.numericToInetAddress(addr);
+ InetAddress inetAddr = InetAddresses.parseNumericAddress(addr);
SecurityParameterIndex spi = null;
if (requestedSpi == null) {
spi = allocateSpi(inetAddr);
diff --git a/Common/src/com/googlecode/android_scripting/facade/net/SocketFacade.java b/Common/src/com/googlecode/android_scripting/facade/net/SocketFacade.java
index b57f1fbb..4bcd60c1 100644
--- a/Common/src/com/googlecode/android_scripting/facade/net/SocketFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/net/SocketFacade.java
@@ -16,7 +16,7 @@
package com.googlecode.android_scripting.facade.net;
-import android.net.NetworkUtils;
+import android.net.InetAddresses;
import android.os.ParcelFileDescriptor;
import android.system.ErrnoException;
import android.system.Os;
@@ -157,8 +157,8 @@ public class SocketFacade extends RpcReceiver {
String local,
Integer localPort) {
try {
- InetAddress remoteAddr = NetworkUtils.numericToInetAddress(remote);
- InetAddress localAddr = NetworkUtils.numericToInetAddress(local);
+ InetAddress remoteAddr = InetAddresses.parseNumericAddress(remote);
+ InetAddress localAddr = InetAddresses.parseNumericAddress(local);
Socket socket = new Socket(remoteAddr, remotePort.intValue(), localAddr,
localPort.intValue());
socket.setSoLinger(true, 0);
@@ -209,7 +209,7 @@ public class SocketFacade extends RpcReceiver {
@Rpc(description = "Open TCP server socket and accept connection")
public String openTcpServerSocket(String addr, Integer port) {
try {
- InetAddress localAddr = NetworkUtils.numericToInetAddress(addr);
+ InetAddress localAddr = InetAddresses.parseNumericAddress(addr);
ServerSocket serverSocket = new ServerSocket(port.intValue(), 10, localAddr);
String id = getServerSocketId(serverSocket);
sServerSocketHashMap.put(id, serverSocket);
@@ -402,13 +402,14 @@ public class SocketFacade extends RpcReceiver {
/**
* Open datagram socket using java.net.DatagramSocket
+ *
* @param addr : IP addr to use
* @param port : port to open socket on
* @return Hash key of {@link DatagramSocket}
*/
@Rpc(description = "Open datagram socket")
public String openDatagramSocket(String addr, Integer port) {
- InetAddress localAddr = NetworkUtils.numericToInetAddress(addr);
+ InetAddress localAddr = InetAddresses.parseNumericAddress(addr);
try {
DatagramSocket socket = new DatagramSocket(port.intValue(), localAddr);
socket.setSoTimeout(SOCK_TIMEOUT);
@@ -458,7 +459,7 @@ public class SocketFacade extends RpcReceiver {
Integer port) {
byte[] buf = message.getBytes();
try {
- InetAddress remoteAddr = NetworkUtils.numericToInetAddress(addr);
+ InetAddress remoteAddr = InetAddresses.parseNumericAddress(addr);
DatagramSocket socket = sDatagramSocketHashMap.get(datagramSocketId);
DatagramPacket pkt = new DatagramPacket(buf, buf.length, remoteAddr, port.intValue());
socket.send(pkt);
@@ -505,7 +506,7 @@ public class SocketFacade extends RpcReceiver {
public String openSocket(Integer domain, Integer type, String addr, Integer port) {
try {
FileDescriptor fd = Os.socket(domain, type, 0);
- InetAddress localAddr = NetworkUtils.numericToInetAddress(addr);
+ InetAddress localAddr = InetAddresses.parseNumericAddress(addr);
Os.bind(fd, localAddr, port.intValue());
String id = getFileDescriptorId(fd);
sFileDescriptorHashMap.put(id, fd);
@@ -545,7 +546,7 @@ public class SocketFacade extends RpcReceiver {
public Boolean sendDataOverSocket(
String remoteAddr, Integer remotePort, String message, String id) {
FileDescriptor fd = sFileDescriptorHashMap.get(id);
- InetAddress remote = NetworkUtils.numericToInetAddress(remoteAddr);
+ InetAddress remote = InetAddresses.parseNumericAddress(remoteAddr);
try {
byte [] data = new String(message).getBytes(StandardCharsets.UTF_8);
int bytes = Os.sendto(fd, data, 0, data.length, 0, remote, remotePort.intValue());
@@ -604,7 +605,7 @@ public class SocketFacade extends RpcReceiver {
public Boolean connectSocket(String id, String addr, Integer port) {
FileDescriptor fd = sFileDescriptorHashMap.get(id);
try {
- InetAddress remoteAddr = NetworkUtils.numericToInetAddress(addr);
+ InetAddress remoteAddr = InetAddresses.parseNumericAddress(addr);
Os.connect(fd, remoteAddr, port.intValue());
return true;
} catch (SocketException | ErrnoException e) {
diff --git a/Common/src/com/googlecode/android_scripting/facade/telephony/SmsFacade.java b/Common/src/com/googlecode/android_scripting/facade/telephony/SmsFacade.java
index fa9170a6..1de17161 100644
--- a/Common/src/com/googlecode/android_scripting/facade/telephony/SmsFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/telephony/SmsFacade.java
@@ -741,7 +741,7 @@ public class SmsFacade extends RpcReceiver {
private PendingIntent createBroadcastPendingIntent(String intentAction, Uri messageUri) {
Intent intent = new Intent(intentAction, messageUri);
- return PendingIntent.getBroadcast(mService, 0, intent, 0);
+ return PendingIntent.getBroadcast(mService, 0, intent, PendingIntent.FLAG_MUTABLE);
}
private static String getSmsFailureReason(int resultCode) {
diff --git a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyConstants.java b/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyConstants.java
index ecbec0dd..d5e96335 100644
--- a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyConstants.java
+++ b/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyConstants.java
@@ -188,6 +188,7 @@ public class TelephonyConstants {
public static final String RAT_TD_SCDMA = "TD_SCDMA";
public static final String RAT_GLOBAL = "GLOBAL";
public static final String RAT_LTE_CA = "LTE_CA";
+ public static final String RAT_NR = "NR";
public static final String RAT_UNKNOWN = "UNKNOWN";
/**
@@ -228,6 +229,15 @@ public class TelephonyConstants {
public static final String DATA_STATE_UNKNOWN = "UNKNOWN";
/**
+ * Constant for Override Network Type
+ * **/
+ public static final String OVERRIDE_NETWORK_TYPE_NONE = "NONE";
+ public static final String OVERRIDE_NETWORK_TYPE_LTE_CA = "LTE_CA";
+ public static final String OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO = "LTE_ADVANCED_PRO";
+ public static final String OVERRIDE_NETWORK_TYPE_NR_NSA = "NR_NSA";
+ public static final String OVERRIDE_NETWORK_TYPE_NR_ADVANCED = "NR_MMWAVE";
+
+ /**
* Constant for Telephony Manager Call State
* **/
public static final String TELEPHONY_STATE_RINGING = "RINGING";
@@ -317,6 +327,17 @@ public class TelephonyConstants {
public static final String NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA = "NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA";
public static final String NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = "NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA";
public static final String NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = "NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA";
+ public static final String NETWORK_MODE_NR_LTE_GSM_WCDMA = "NETWORK_MODE_NR_LTE_GSM_WCDMA";
+ public static final String NETWORK_MODE_NR_ONLY = "NETWORK_MODE_NR_ONLY";
+ public static final String NETWORK_MODE_NR_LTE = "NETWORK_MODE_NR_LTE";
+ public static final String NETWORK_MODE_NR_LTE_CDMA_EVDO = "NETWORK_MODE_NR_LTE_CDMA_EVDO";
+ public static final String NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA = "NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA";
+ public static final String NETWORK_MODE_NR_LTE_WCDMA = "NETWORK_MODE_NR_LTE_WCDMA";
+ public static final String NETWORK_MODE_NR_LTE_TDSCDMA = "NETWORK_MODE_NR_LTE_TDSCDMA";
+ public static final String NETWORK_MODE_NR_LTE_TDSCDMA_GSM = "NETWORK_MODE_NR_LTE_TDSCDMA_GSM";
+ public static final String NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA = "NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA";
+ public static final String NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA = "NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA";
+ public static final String NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = "NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA";
public static final String NETWORK_MODE_INVALID = "INVALID";
/**
@@ -373,6 +394,7 @@ public class TelephonyConstants {
public static final String EventPreciseStateChanged = "PreciseStateChanged";
public static final String EventDataConnectionRealTimeInfoChanged = "DataConnectionRealTimeInfoChanged";
public static final String EventDataConnectionStateChanged = "DataConnectionStateChanged";
+ public static final String EventDisplayInfoChanged = "DisplayInfoChanged";
public static final String EventActiveDataSubIdChanged = "ActiveDataSubIdChanged";
public static final String EventServiceStateChanged = "ServiceStateChanged";
public static final String EventSignalStrengthChanged = "SignalStrengthChanged";
@@ -438,6 +460,13 @@ public class TelephonyConstants {
public static final String DATA_CONNECTION_STATE = "dataConnectionState";
}
+ public static class DisplayInfoContainer {
+ public static final String TIME = "time";
+ public static final String NETWORK = "network";
+ public static final String OVERRIDE = "override";
+ public static final String SUBSCRIPTION_ID = "subscriptionId";
+ }
+
public static class ServiceStateContainer {
public static final String VOICE_REG_STATE = "voiceRegState";
public static final String VOICE_NETWORK_TYPE = "voiceNetworkType";
@@ -472,7 +501,7 @@ public class TelephonyConstants {
public static final String IS_DATA_ROAMING_FROM_REGISTRATION =
"isDataRoamingFromRegistration";
public static final String IS_USING_CARRIER_AGGREGATION = "isUsingCarrierAggregation";
- public static final String LTE_EARFCN_RSRP_BOOST = "lteEarfcnRsrpBoost";
+ public static final String LTE_EARFCN_RSRP_BOOST = "LteEarfcnRsrpBoost";
}
public static class MessageWaitingIndicatorContainer {
diff --git a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyEvents.java b/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyEvents.java
index 7021475a..2e394fab 100644
--- a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyEvents.java
+++ b/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyEvents.java
@@ -20,6 +20,7 @@ import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.PhysicalChannelConfig;
import android.telephony.PreciseCallState;
import android.telephony.ServiceState;
+import android.telephony.TelephonyDisplayInfo;
import com.googlecode.android_scripting.jsonrpc.JsonSerializable;
@@ -267,6 +268,52 @@ public class TelephonyEvents {
}
}
+ public static class DisplayInfoChangedEvent implements JsonSerializable {
+ private TelephonyDisplayInfo mDisplayInfoString;
+ private int mSubscriptionId;
+ private String mOverrideDataNetworkType;
+ private String mDataNetworkType;
+
+ DisplayInfoChangedEvent(TelephonyDisplayInfo DisplayInfoString, int subscriptionId) {
+ mDisplayInfoString = DisplayInfoString;
+ mSubscriptionId = subscriptionId;
+ mOverrideDataNetworkType = TelephonyUtils.getDisplayInfoString(
+ DisplayInfoString.getOverrideNetworkType());
+ mDataNetworkType = TelephonyUtils.getNetworkTypeString(
+ DisplayInfoString.getNetworkType());
+ }
+
+ public String getOverrideDataNetworkType() {
+ return mOverrideDataNetworkType;
+ }
+
+ public int getSubscriptionId() {
+ return mSubscriptionId;
+ }
+
+ public String getDataNetworkType() {
+ return mDataNetworkType;
+ }
+
+ public JSONObject toJSON() throws JSONException {
+ JSONObject displayInfoState = new JSONObject();
+
+ displayInfoState.put(
+ TelephonyConstants.DisplayInfoContainer.OVERRIDE,
+ mOverrideDataNetworkType);
+
+ displayInfoState.put(
+ TelephonyConstants.DisplayInfoContainer.NETWORK,
+ mDataNetworkType);
+
+ displayInfoState.put(
+ TelephonyConstants.DisplayInfoContainer.SUBSCRIPTION_ID,
+ mSubscriptionId);
+
+ return displayInfoState;
+ }
+ }
+
public static class PhysicalChannelConfigChangedEvent implements JsonSerializable {
private final List<PhysicalChannelConfig> mConfigs;
@@ -284,7 +331,7 @@ public class TelephonyEvents {
JSONObject cfg = new JSONObject();
cfg.put(
TelephonyConstants.PhysicalChannelConfigContainer.CELL_BANDWIDTH_DOWNLINK,
- c.getCellBandwidthDownlink());
+ c.getCellBandwidthDownlinkKhz());
cfg.put(
TelephonyConstants.PhysicalChannelConfigContainer.CONNECTION_STATUS,
c.getConnectionStatus());
diff --git a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java
index a338402b..e60e5f15 100644
--- a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java
@@ -55,6 +55,8 @@ import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
.DataConnectionStateChangeListener;
import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
+ .DisplayInfoStateChangeListener;
+import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
.ServiceStateChangeListener;
import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
.SignalStrengthChangeListener;
@@ -303,6 +305,28 @@ public class TelephonyManagerFacade extends RpcReceiver {
return true;
}
+ @Rpc(description = "Starts tracking display info change" +
+ "for default subscription ID.")
+ public Boolean telephonyStartTrackingDisplayInfoChange() {
+ return telephonyStartTrackingDisplayInfoChangeForSubscription(
+ SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
+ }
+
+ @Rpc(description = "Starts tracking display info change" +
+ "for specified subscription ID.")
+ public Boolean telephonyStartTrackingDisplayInfoChangeForSubscription(
+ @RpcParameter(name = "subId") Integer subId) {
+ StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
+ if(listener == null) {
+ Log.e("Invalid subscription ID");
+ return false;
+ }
+ mTelephonyManager.createForSubscriptionId(subId).listen(
+ listener.mDisplayInfoStateChangeListener,
+ PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED);
+ return true;
+ }
+
@Rpc(description = "Turn on/off precise listening on fore/background or" +
" ringing calls for default voice subscription ID.")
public Boolean telephonyAdjustPreciseCallStateListenLevel(
@@ -381,6 +405,28 @@ public class TelephonyManagerFacade extends RpcReceiver {
return true;
}
+ @Rpc(description = "Stops tracking display info change " +
+ "for default subscription ID.")
+ public Boolean telephonyStopTrackingDisplayInfoChange() {
+ return telephonyStopTrackingDisplayInfoChangeForSubscription(
+ SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
+ }
+
+ @Rpc(description = "Stops tracking display info change " +
+ "for specified subscription ID.")
+ public Boolean telephonyStopTrackingDisplayInfoChangeForSubscription(
+ @RpcParameter(name = "subId") Integer subId) {
+ StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
+ if(listener == null) {
+ Log.e("Invalid subscription ID");
+ return false;
+ }
+ mTelephonyManager.createForSubscriptionId(subId).listen(
+ listener.mDisplayInfoStateChangeListener,
+ PhoneStateListener.LISTEN_NONE);
+ return true;
+ }
+
@Rpc(description = "Stops tracking call state change " +
"for default voice subscription ID.")
public Boolean telephonyStopTrackingCallStateChange() {
@@ -756,7 +802,12 @@ public class TelephonyManagerFacade extends RpcReceiver {
public boolean telephonySetAlwaysAllowMmsData(
@RpcParameter(name = "subId") Integer subId,
@RpcParameter(name = "alwaysAllow") Boolean alwaysAllow) {
- return mTelephonyManager.createForSubscriptionId(subId).setAlwaysAllowMmsData(alwaysAllow);
+ boolean wasAlwaysAllow = mTelephonyManager.isMobileDataPolicyEnabled(
+ TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED);
+ mTelephonyManager.createForSubscriptionId(subId)
+ .setMobileDataPolicyEnabled(
+ TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED, alwaysAllow);
+ return wasAlwaysAllow == alwaysAllow;
}
/**
@@ -1506,6 +1557,7 @@ public class TelephonyManagerFacade extends RpcReceiver {
public CellInfoChangeListener mCellInfoChangeListener;
public DataConnectionStateChangeListener mDataConnectionStateChangeListener;
public ActiveDataSubIdChangeListener mActiveDataSubIdChangeListener;
+ public DisplayInfoStateChangeListener mDisplayInfoStateChangeListener;
public DataConnectionRealTimeInfoChangeListener mDataConnectionRTInfoChangeListener;
public VoiceMailStateChangeListener mVoiceMailStateChangeListener;
@@ -1520,6 +1572,9 @@ public class TelephonyManagerFacade extends RpcReceiver {
mActiveDataSubIdChangeListener =
new ActiveDataSubIdChangeListener(
mEventFacade, mTelephonyManager, subId, mService.getMainLooper());
+ mDisplayInfoStateChangeListener =
+ new DisplayInfoStateChangeListener(
+ mEventFacade, mTelephonyManager, subId, mService.getMainLooper());
mCallStateChangeListener =
new CallStateChangeListener(mEventFacade, subId, mService.getMainLooper());
mCellInfoChangeListener =
@@ -1545,6 +1600,9 @@ public class TelephonyManagerFacade extends RpcReceiver {
mActiveDataSubIdChangeListener,
PhoneStateListener.LISTEN_NONE);
mTelephonyManager.listen(
+ mDisplayInfoStateChangeListener,
+ PhoneStateListener.LISTEN_NONE);
+ mTelephonyManager.listen(
mCellInfoChangeListener,
PhoneStateListener.LISTEN_NONE);
mTelephonyManager.listen(
diff --git a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyStateListeners.java b/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyStateListeners.java
index e06af17a..b13b66cd 100644
--- a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyStateListeners.java
+++ b/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyStateListeners.java
@@ -24,6 +24,7 @@ import android.telephony.PreciseCallState;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
import com.googlecode.android_scripting.facade.EventFacade;
@@ -217,6 +218,45 @@ public class TelephonyStateListeners {
}
}
+ public static class DisplayInfoStateChangeListener extends PhoneStateListener {
+
+ private final EventFacade mEventFacade;
+ private final TelephonyManager mTelephonyManager;
+ public static final int sListeningStates =
+ PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED;
+ public int subscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+ public DisplayInfoStateChangeListener(EventFacade ef, TelephonyManager tm) {
+ super();
+ mEventFacade = ef;
+ mTelephonyManager = tm;
+ subscriptionId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
+ }
+
+ public DisplayInfoStateChangeListener(EventFacade ef, TelephonyManager tm, int subId) {
+ super();
+ mEventFacade = ef;
+ mTelephonyManager = tm;
+ subscriptionId = subId;
+ }
+
+ public DisplayInfoStateChangeListener(
+ EventFacade ef, TelephonyManager tm, int subId, Looper looper) {
+ super(looper);
+ mEventFacade = ef;
+ mTelephonyManager = tm;
+ subscriptionId = subId;
+ }
+
+ @Override
+ public void onDisplayInfoChanged(TelephonyDisplayInfo mTelephonyDisplayInfo) {
+ mEventFacade.postEvent(
+ TelephonyConstants.EventDisplayInfoChanged,
+ new TelephonyEvents.DisplayInfoChangedEvent(
+ mTelephonyDisplayInfo, subscriptionId));
+ }
+ }
+
public static class ServiceStateChangeListener extends PhoneStateListener {
private final EventFacade mEventFacade;
diff --git a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyUtils.java b/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyUtils.java
index 3b0b4364..7af51cbe 100644
--- a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyUtils.java
+++ b/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyUtils.java
@@ -15,16 +15,20 @@
*/
package com.googlecode.android_scripting.facade.telephony;
-import com.android.ims.ImsConfig;
-import com.android.internal.telephony.RILConstants;
-import com.googlecode.android_scripting.Log;
+
import android.telecom.TelecomManager;
import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.PreciseCallState;
import android.telephony.ServiceState;
+import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
import android.telephony.VoLteServiceState;
+import com.android.ims.ImsConfig;
+import com.android.internal.telephony.RILConstants;
+
+import com.googlecode.android_scripting.Log;
+
/**
* Telephony utility functions
*/
@@ -189,6 +193,23 @@ public class TelephonyUtils {
return TelephonyConstants.DATA_STATE_UNKNOWN;
}
+ public static String getDisplayInfoString(int state) {
+ switch (state) {
+ case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE:
+ return TelephonyConstants.OVERRIDE_NETWORK_TYPE_NONE;
+ case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA:
+ return TelephonyConstants.OVERRIDE_NETWORK_TYPE_LTE_CA;
+ case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO:
+ return TelephonyConstants.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO;
+ case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA:
+ return TelephonyConstants.OVERRIDE_NETWORK_TYPE_NR_NSA;
+ case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED:
+ return TelephonyConstants.OVERRIDE_NETWORK_TYPE_NR_ADVANCED;
+ }
+ Log.d("getDisplayInfoStateString error. int: " + state);
+ return TelephonyConstants.OVERRIDE_NETWORK_TYPE_NONE;
+ }
+
public static int getNetworkModeIntfromString(String networkMode) {
switch (networkMode) {
case TelephonyConstants.NETWORK_MODE_WCDMA_PREF:
@@ -237,6 +258,28 @@ public class TelephonyUtils {
return RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
case TelephonyConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
return RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
+ case TelephonyConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA:
+ return RILConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA;
+ case TelephonyConstants.NETWORK_MODE_NR_ONLY:
+ return RILConstants.NETWORK_MODE_NR_ONLY;
+ case TelephonyConstants.NETWORK_MODE_NR_LTE:
+ return RILConstants.NETWORK_MODE_NR_LTE;
+ case TelephonyConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO:
+ return RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO;
+ case TelephonyConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA:
+ return RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA;
+ case TelephonyConstants.NETWORK_MODE_NR_LTE_WCDMA:
+ return RILConstants.NETWORK_MODE_NR_LTE_WCDMA;
+ case TelephonyConstants.NETWORK_MODE_NR_LTE_TDSCDMA:
+ return RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA;
+ case TelephonyConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM:
+ return RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM;
+ case TelephonyConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA:
+ return RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA;
+ case TelephonyConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA:
+ return RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA;
+ case TelephonyConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+ return RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
}
Log.d("getNetworkModeIntfromString error. String: " + networkMode);
return RILConstants.RIL_ERRNO_INVALID_RESPONSE;
@@ -290,6 +333,28 @@ public class TelephonyUtils {
return TelephonyConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
case RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
return TelephonyConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
+ case RILConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA:
+ return TelephonyConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA;
+ case RILConstants.NETWORK_MODE_NR_ONLY:
+ return TelephonyConstants.NETWORK_MODE_NR_ONLY;
+ case RILConstants.NETWORK_MODE_NR_LTE:
+ return TelephonyConstants.NETWORK_MODE_NR_LTE;
+ case RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO:
+ return TelephonyConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO;
+ case RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA:
+ return TelephonyConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA;
+ case RILConstants.NETWORK_MODE_NR_LTE_WCDMA:
+ return TelephonyConstants.NETWORK_MODE_NR_LTE_WCDMA;
+ case RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA:
+ return TelephonyConstants.NETWORK_MODE_NR_LTE_TDSCDMA;
+ case RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM:
+ return TelephonyConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM;
+ case RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA:
+ return TelephonyConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA;
+ case RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA:
+ return TelephonyConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA;
+ case RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+ return TelephonyConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
}
Log.d("getNetworkModeStringfromInt error. Int: " + networkMode);
return TelephonyConstants.NETWORK_MODE_INVALID;
@@ -335,6 +400,8 @@ public class TelephonyUtils {
return TelephonyConstants.RAT_IDEN;
case TelephonyManager.NETWORK_TYPE_LTE_CA:
return TelephonyConstants.RAT_LTE_CA;
+ case TelephonyManager.NETWORK_TYPE_NR:
+ return TelephonyConstants.RAT_NR;
}
return TelephonyConstants.RAT_UNKNOWN;
}
diff --git a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiAwareManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiAwareManagerFacade.java
index af07b3cb..c690a38e 100644
--- a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiAwareManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiAwareManagerFacade.java
@@ -882,6 +882,16 @@ public class WifiAwareManagerFacade extends RpcReceiver {
mResults.putString("messageAsString", new String(message));
postEvent("WifiAwareSessionOnMessageReceived", mResults);
}
+
+ @Override
+ public void onServiceLost(PeerHandle peerHandle, @WifiAwareManager.DiscoveryLostReasonCode
+ int reason) {
+ Bundle mResults = new Bundle();
+ mResults.putInt("discoverySessionId", mDiscoverySessionId);
+ mResults.putInt("peerId", peerHandle.peerId);
+ mResults.putInt("lostReason", reason);
+ postEvent("WifiAwareSessionOnServiceLost", mResults);
+ }
}
class WifiAwareRangingListener implements RttManager.RttListener {
diff --git a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
index 97b6b0e6..7a69b4bb 100755
--- a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
@@ -16,10 +16,15 @@
package com.googlecode.android_scripting.facade.wifi;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.net.wifi.WifiScanner.WIFI_BAND_24_GHZ;
+import static android.net.wifi.WifiScanner.WIFI_BAND_5_GHZ;
import static com.googlecode.android_scripting.jsonrpc.JsonBuilder.build;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -30,11 +35,13 @@ import android.net.ConnectivityManager.NetworkCallback;
import android.net.DhcpInfo;
import android.net.MacAddress;
import android.net.Network;
+import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.net.Uri;
+import android.net.wifi.CoexUnsafeChannel;
import android.net.wifi.EasyConnectStatusCallback;
import android.net.wifi.ScanResult;
import android.net.wifi.SoftApCapability;
@@ -49,6 +56,7 @@ import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.NetworkRequestMatchCallback;
import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback;
+import android.net.wifi.WifiManager.SubsystemRestartTrackingCallback;
import android.net.wifi.WifiManager.WifiLock;
import android.net.wifi.WifiNetworkSpecifier;
import android.net.wifi.WifiNetworkSuggestion;
@@ -67,8 +75,11 @@ import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils;
import android.util.Base64;
import android.util.SparseArray;
+import android.util.SparseIntArray;
+
import com.android.internal.annotations.GuardedBy;
+import com.android.modules.utils.build.SdkLevel;
import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.facade.EventFacade;
@@ -101,8 +112,8 @@ import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
@@ -133,15 +144,17 @@ public class WifiManagerFacade extends RpcReceiver {
private final WifiScanResultsReceiver mWifiScanResultsReceiver;
private final WifiStateChangeReceiver mStateChangeReceiver;
private final WifiNetworkSuggestionStateChangeReceiver mNetworkSuggestionStateChangeReceiver;
+ private SubsystemRestartTrackingCallbackFacade mSubsystemRestartTrackingCallback = null;
private final HandlerThread mCallbackHandlerThread;
private final Object mCallbackLock = new Object();
- private final Map<NetworkSpecifier, NetworkCallback> mNetworkCallbacks = new HashMap<>();
private boolean mTrackingWifiStateChange;
private boolean mTrackingTetherStateChange;
private boolean mTrackingNetworkSuggestionStateChange;
@GuardedBy("mCallbackLock")
private NetworkRequestUserSelectionCallback mNetworkRequestUserSelectionCallback;
private final SparseArray<SoftApCallbackImp> mSoftapCallbacks;
+ // This is null if SdkLevel is not at least S
+ @Nullable private WifiManager.CoexCallback mCoexCallback;
private final BroadcastReceiver mTetherStateReceiver = new BroadcastReceiver() {
@Override
@@ -208,25 +221,6 @@ public class WifiManagerFacade extends RpcReceiver {
}
};
- private final class NetworkCallbackImpl extends NetworkCallback {
- private static final String EVENT_TAG = mEventType + "NetworkCallback";
-
- @Override
- public void onAvailable(Network network) {
- mEventFacade.postEvent(EVENT_TAG + "OnAvailable", mWifi.getConnectionInfo());
- }
-
- @Override
- public void onUnavailable() {
- mEventFacade.postEvent(EVENT_TAG + "OnUnavailable", null);
- }
-
- @Override
- public void onLost(Network network) {
- mEventFacade.postEvent(EVENT_TAG + "OnLost", null);
- }
- };
-
private static class SoftApCallbackImp implements WifiManager.SoftApCallback {
// A monotonic increasing counter for softap callback ids.
private static int sCount = 0;
@@ -252,21 +246,36 @@ public class WifiManagerFacade extends RpcReceiver {
@Override
public void onConnectedClientsChanged(List<WifiClient> clients) {
- ArrayList<String> macAddresses = new ArrayList<>();
- clients.forEach(x -> macAddresses.add(x.getMacAddress().toString()));
+ ArrayList<MacAddress> macAddresses = new ArrayList<>();
+ clients.forEach(x -> macAddresses.add(x.getMacAddress()));
Bundle msg = new Bundle();
msg.putInt("NumClients", clients.size());
- msg.putStringArrayList("MacAddresses", macAddresses);
+ msg.putParcelableArrayList("MacAddresses", macAddresses);
mEventFacade.postEvent(mEventStr + "OnNumClientsChanged", msg);
mEventFacade.postEvent(mEventStr + "OnConnectedClientsChanged", clients);
}
@Override
+ public void onConnectedClientsChanged(SoftApInfo info, List<WifiClient> clients) {
+ ArrayList<MacAddress> macAddresses = new ArrayList<>();
+ clients.forEach(x -> macAddresses.add(x.getMacAddress()));
+ Bundle msg = new Bundle();
+ msg.putParcelable("Info", info);
+ msg.putParcelableArrayList("ClientsMacAddress", macAddresses);
+ mEventFacade.postEvent(mEventStr + "OnConnectedClientsChangedWithInfo", msg);
+ }
+
+ @Override
public void onInfoChanged(SoftApInfo softApInfo) {
mEventFacade.postEvent(mEventStr + "OnInfoChanged", softApInfo);
}
@Override
+ public void onInfoChanged(List<SoftApInfo> infos) {
+ mEventFacade.postEvent(mEventStr + "OnInfoListChanged", infos);
+ }
+
+ @Override
public void onCapabilityChanged(SoftApCapability softApCapability) {
mEventFacade.postEvent(mEventStr + "OnCapabilityChanged", softApCapability);
}
@@ -280,6 +289,31 @@ public class WifiManagerFacade extends RpcReceiver {
}
};
+ private static class CoexCallbackImpl extends WifiManager.CoexCallback {
+ private final EventFacade mEventFacade;
+ private final String mEventStr;
+
+ CoexCallbackImpl(EventFacade eventFacade) {
+ mEventFacade = eventFacade;
+ mEventStr = mEventType + "CoexCallback";
+ }
+
+ @Override
+ public void onCoexUnsafeChannelsChanged(
+ @NonNull List<CoexUnsafeChannel> unsafeChannels, int restrictions) {
+ Bundle event = new Bundle();
+ try {
+ event.putString("KEY_COEX_UNSAFE_CHANNELS",
+ coexUnsafeChannelsToJson(unsafeChannels).toString());
+ event.putString("KEY_COEX_RESTRICTIONS",
+ coexRestrictionsToJson(restrictions).toString());
+ mEventFacade.postEvent(mEventStr + "#onCoexUnsafeChannelsChanged", event);
+ } catch (JSONException e) {
+ Log.e("Failed to post event for onCoexUnsafeChannelsChanged: " + e);
+ }
+ }
+ };
+
private WifiLock mLock = null;
private boolean mIsConnected = false;
@@ -313,6 +347,9 @@ public class WifiManagerFacade extends RpcReceiver {
mTrackingNetworkSuggestionStateChange = false;
mCallbackHandlerThread.start();
mSoftapCallbacks = new SparseArray<>();
+ if (SdkLevel.isAtLeastS()) {
+ mCoexCallback = new CoexCallbackImpl(mEventFacade);
+ }
}
private void makeLock(int wifiMode) {
@@ -395,6 +432,53 @@ public class WifiManagerFacade extends RpcReceiver {
public class WifiStateChangeReceiver extends BroadcastReceiver {
String mCachedWifiInfo = "";
+ /**
+ * When a peer to peer request is active, WifiManager.getConnectionInfo() returns
+ * the peer to peer connection details. Hence use networking API's to retrieve the
+ * internet connection details.
+ *
+ * But on Android R, we will need to fallback to the legacy getConnectionInfo() API since
+ * WifiInfo doesn't implement TransportInfo.
+ */
+ private WifiInfo getInternetConnectivityWifiInfo() {
+ if (!SdkLevel.isAtLeastS()) {
+ return mWifi.getConnectionInfo();
+ }
+ // TODO (b/156867433): We need a location sensitive synchronous API proposed
+ // in aosp/1629501.
+ final CountDownLatch waitForNetwork = new CountDownLatch(1);
+ final class AnswerBox {
+ public WifiInfo wifiInfo;
+ }
+ final AnswerBox answerBox = new AnswerBox();
+ final NetworkCallback networkCallback =
+ new NetworkCallback(NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) {
+ @Override
+ public void onCapabilitiesChanged(@NonNull Network network,
+ @NonNull NetworkCapabilities networkCapabilities) {
+ answerBox.wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();
+ waitForNetwork.countDown();
+ }
+ };
+ mCm.registerNetworkCallback(
+ new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_WIFI)
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .build(), networkCallback);
+ try {
+ if (!waitForNetwork.await(5, TimeUnit.SECONDS)) {
+ Log.e("Timed out waiting for network to connect");
+ return null;
+ }
+ return answerBox.wifiInfo;
+ } catch (InterruptedException e) {
+ Log.e("Waiting for onAvailable failed", e);
+ return null;
+ } finally {
+ mCm.unregisterNetworkCallback(networkCallback);
+ }
+ }
+
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
@@ -405,7 +489,12 @@ public class WifiManagerFacade extends RpcReceiver {
// If network info is of type wifi, send wifi events.
if (nInfo.getType() == ConnectivityManager.TYPE_WIFI) {
if (nInfo.getDetailedState().equals(DetailedState.CONNECTED)) {
- WifiInfo wInfo = mWifi.getConnectionInfo();
+ WifiInfo wInfo = getInternetConnectivityWifiInfo();
+ if (wInfo == null) {
+ Log.e("Failed to get WifiInfo for internet connection. "
+ + "Not sending wifi network connection event");
+ return;
+ }
String bssid = wInfo.getBSSID();
if (bssid != null && !mCachedWifiInfo.equals(wInfo.toString())) {
Log.d("WifiNetworkConnected");
@@ -519,28 +608,26 @@ public class WifiManagerFacade extends RpcReceiver {
// Check if new security type SAE (WPA3) is present. Default to PSK
if (j.has("security")) {
if (TextUtils.equals(j.getString("security"), "SAE")) {
- config.allowedKeyManagement.set(KeyMgmt.SAE);
- config.requirePmf = true;
+ config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
} else {
- config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
+ config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
}
} else {
- config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
+ config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
}
config.preSharedKey = "\"" + j.getString("password") + "\"";
} else if (j.has("preSharedKey")) {
- config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
config.preSharedKey = j.getString("preSharedKey");
} else {
if (j.has("security")) {
if (TextUtils.equals(j.getString("security"), "OWE")) {
- config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE);
- config.requirePmf = true;
+ config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE);
} else {
- config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
}
} else {
- config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
}
}
if (j.has("BSSID")) {
@@ -557,9 +644,7 @@ public class WifiManagerFacade extends RpcReceiver {
}
if (j.has("wepKeys")) {
// Looks like we only support static WEP.
- config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
- config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
+ config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_WEP);
JSONArray keys = j.getJSONArray("wepKeys");
String[] wepKeys = new String[keys.length()];
for (int i = 0; i < keys.length(); i++) {
@@ -582,7 +667,7 @@ public class WifiManagerFacade extends RpcReceiver {
return config;
}
- private WifiEnterpriseConfig genWifiEnterpriseConfig(JSONObject j) throws JSONException,
+ private static WifiEnterpriseConfig genWifiEnterpriseConfig(JSONObject j) throws JSONException,
GeneralSecurityException {
WifiEnterpriseConfig eConfig = new WifiEnterpriseConfig();
if (j.has(WifiEnterpriseConfig.EAP_KEY)) {
@@ -605,7 +690,11 @@ public class WifiManagerFacade extends RpcReceiver {
Log.v("Client Cert String is " + certStr);
Log.v("Client Key String is " + keyStr);
X509Certificate cert = strToX509Cert(certStr);
- PrivateKey privKey = strToPrivateKey(keyStr);
+ String certAlgo = "RSA";
+ if (j.has("cert_algo")) {
+ certAlgo = j.getString("cert_algo");
+ }
+ PrivateKey privKey = strToPrivateKey(keyStr, certAlgo);
Log.v("Cert is " + cert);
Log.v("Private Key is " + privKey);
eConfig.setClientKeyEntry(privKey, cert);
@@ -649,13 +738,11 @@ public class WifiManagerFacade extends RpcReceiver {
return null;
}
WifiConfiguration config = new WifiConfiguration();
- config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
- config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
+ config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
if (j.has("security")) {
if (TextUtils.equals(j.getString("security"), "SUITE_B_192")) {
- config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192);
- config.requirePmf = true;
+ config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
}
}
@@ -685,7 +772,10 @@ public class WifiManagerFacade extends RpcReceiver {
return config;
}
- private NetworkSpecifier genWifiNetworkSpecifier(JSONObject j) throws JSONException,
+ /**
+ * Generate {@link WifiNetworkSpecifier} from the specified json.
+ */
+ public static NetworkSpecifier genWifiNetworkSpecifier(JSONObject j) throws JSONException,
GeneralSecurityException {
if (j == null) {
return null;
@@ -794,6 +884,11 @@ public class WifiManagerFacade extends RpcReceiver {
}
}
}
+ if (j.has("enhancedMacRandomizationEnabled")
+ && j.getBoolean("enhancedMacRandomizationEnabled")) {
+ builder = builder.setMacRandomizationSetting(
+ WifiNetworkSuggestion.RANDOMIZATION_NON_PERSISTENT);
+ }
return builder.build();
}
@@ -837,22 +932,22 @@ public class WifiManagerFacade extends RpcReceiver {
return info;
}
- private byte[] base64StrToBytes(String input) {
+ private static byte[] base64StrToBytes(String input) {
return Base64.decode(input, Base64.DEFAULT);
}
- private X509Certificate strToX509Cert(String certStr) throws CertificateException {
+ private static X509Certificate strToX509Cert(String certStr) throws CertificateException {
byte[] certBytes = base64StrToBytes(certStr);
InputStream certStream = new ByteArrayInputStream(certBytes);
CertificateFactory cf = CertificateFactory.getInstance("X509");
return (X509Certificate) cf.generateCertificate(certStream);
}
- private PrivateKey strToPrivateKey(String key) throws NoSuchAlgorithmException,
- InvalidKeySpecException {
+ private static PrivateKey strToPrivateKey(String key, String algo)
+ throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] keyBytes = base64StrToBytes(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
- KeyFactory fact = KeyFactory.getInstance("RSA");
+ KeyFactory fact = KeyFactory.getInstance(algo);
PrivateKey priv = fact.generatePrivate(keySpec);
return priv;
}
@@ -1083,6 +1178,27 @@ public class WifiManagerFacade extends RpcReceiver {
}
}
+ private class SubsystemRestartTrackingCallbackFacade extends SubsystemRestartTrackingCallback {
+ private final EventFacade mEventFacade;
+
+ SubsystemRestartTrackingCallbackFacade(EventFacade eventFacade) {
+ super();
+ mEventFacade = eventFacade;
+ }
+
+ @Override
+ public void onSubsystemRestarting() {
+ Log.v("onSubsystemRestarting");
+ mEventFacade.postEvent("WifiSubsystemRestarting", null);
+ }
+
+ @Override
+ public void onSubsystemRestarted() {
+ Log.v("onSubsystemRestarted");
+ mEventFacade.postEvent("WifiSubsystemRestarted", null);
+ }
+ }
+
private OsuProvider buildTestOsuProvider(JSONObject config) {
String osuServiceDescription = "Google Passpoint Test Service";
List<Integer> osuMethodList =
@@ -1233,6 +1349,41 @@ public class WifiManagerFacade extends RpcReceiver {
return mWifi.getConnectionInfo();
}
+ /**
+ * Check if wifi network is temporary disabled.
+ * @param config JSONObject Dictionary of wifi connection parameters.
+ * @return True if network is disabled temporarily, False if not.
+ */
+ @Rpc(description = "Check if network is temporary disabled")
+ public boolean wifiIsNetworkTemporaryDisabledForNetwork(
+ @RpcParameter(name = "config") JSONObject config)
+ throws JSONException, GeneralSecurityException {
+ WifiConfiguration wifiConfig;
+ if (config.has(WifiEnterpriseConfig.EAP_KEY)) {
+ wifiConfig = genWifiConfigWithEnterpriseConfig(config);
+ } else {
+ wifiConfig = genWifiConfig(config);
+ }
+ List<WifiConfiguration> wifiConfigList = wifiGetConfiguredNetworks();
+ for (WifiConfiguration conf : wifiConfigList) {
+ if (conf.getSsidAndSecurityTypeString().equals(
+ wifiConfig.getSsidAndSecurityTypeString())) {
+ Log.d("Found matching config in the configured networks.");
+ return conf.getNetworkSelectionStatus().isNetworkTemporaryDisabled();
+ }
+ }
+ Log.d("Wifi config is not in list of configured wifi networks.");
+ return false;
+ }
+
+ /**
+ * Get wifi standard for wifi connection.
+ */
+ @Rpc(description = "Return connection WiFi standard")
+ public Integer wifiGetConnectionStandard() {
+ return mWifi.getConnectionInfo().getWifiStandard();
+ }
+
@Rpc(description = "Returns wifi activity and energy usage info.")
public WifiActivityEnergyInfo wifiGetControllerActivityEnergyInfo() {
WifiActivityEnergyInfo[] mutable = {null};
@@ -1296,14 +1447,51 @@ public class WifiManagerFacade extends RpcReceiver {
return mWifi.isVerboseLoggingEnabled() ? 1 : 0;
}
+ /**
+ * Query whether or not the device supports concurrency of Station (STA) + multiple access
+ * points (AP) (where the APs bridged together).
+ *
+ * @return true if this device supports concurrency of STA + multiple APs which are bridged
+ * together, false otherwise.
+ */
+ @Rpc(description = "true if this adapter supports STA + bridged Soft AP concurrency.")
+ public Boolean wifiIsStaBridgedApConcurrencySupported() {
+ return mWifi.isStaBridgedApConcurrencySupported();
+ }
+
+ /**
+ * Query whether or not the device supports multiple Access point (AP) which are bridged
+ * together.
+ *
+ * @return true if this device supports concurrency of multiple AP which bridged together,
+ * false otherwise.
+ */
+ @Rpc(description = "true if this adapter supports bridged Soft AP concurrency.")
+ public Boolean wifiIsBridgedApConcurrencySupported() {
+ return mWifi.isBridgedApConcurrencySupported();
+ }
+
@Rpc(description = "true if this adapter supports 5 GHz band.")
public Boolean wifiIs5GHzBandSupported() {
return mWifi.is5GHzBandSupported();
}
- @Rpc(description = "true if this adapter supports multiple simultaneous connections.")
- public Boolean wifiIsAdditionalStaSupported() {
- return mWifi.isAdditionalStaSupported();
+ @Rpc(description = "true if this adapter supports multiple simultaneous connections for"
+ + "local only use-case.")
+ public Boolean wifiIsStaConcurrencyForLocalOnlyConnectionsSupported() {
+ return mWifi.isStaConcurrencyForLocalOnlyConnectionsSupported();
+ }
+
+ @Rpc(description = "true if this adapter supports multiple simultaneous connections for mbb "
+ + "wifi to wifi switching.")
+ public Boolean wifiIsMakeBeforeBreakWifiSwitchingSupported() {
+ return mWifi.isMakeBeforeBreakWifiSwitchingSupported();
+ }
+
+ @Rpc(description = "true if this adapter supports multiple simultaneous connections for "
+ + "restricted connection use-case.")
+ public Boolean wifiIsStaConcurrencyForRestrictedConnectionsSupported() {
+ return mWifi.isStaConcurrencyForRestrictedConnectionsSupported();
}
@Rpc(description = "Return true if WiFi is enabled.")
@@ -1413,6 +1601,17 @@ public class WifiManagerFacade extends RpcReceiver {
public Boolean wifiIsEnhancedOpenSupported() {
return mWifi.isEnhancedOpenSupported();
}
+
+ /**
+ * @return true if this device supports Wi-Fi Device Provisioning Protocol (Easy-connect)
+ * Enrollee Responder mode
+ */
+ @Rpc(description = "Check if Easy Connect (DPP) Enrollee responder mode is supported "
+ + "on this device.")
+ public Boolean wifiIsEasyConnectEnrolleeResponderModeSupported() {
+ return mWifi.isEasyConnectEnrolleeResponderModeSupported();
+ }
+
/**
* @return true if this device supports Wi-Fi Device Provisioning Protocol (Easy-connect)
*/
@@ -1431,6 +1630,16 @@ public class WifiManagerFacade extends RpcReceiver {
makeLock(WifiManager.WIFI_MODE_SCAN_ONLY);
}
+ @Rpc(description = "Acquires a high performance Wifi lock.")
+ public void wifiLockAcquireFullHighPerf() {
+ makeLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF);
+ }
+
+ @Rpc(description = "Acquires a low latency Wifi lock.")
+ public void wifiLockAcquireFullLowLatency() {
+ makeLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY);
+ }
+
@Rpc(description = "Releases a previously acquired Wifi lock.")
public void wifiLockRelease() {
if (mLock != null) {
@@ -1454,6 +1663,30 @@ public class WifiManagerFacade extends RpcReceiver {
return mWifi.removeNetwork(netId);
}
+ private int getApBandFromChannelFrequency(int freq) {
+ if (ScanResult.is24GHz(freq)) {
+ return SoftApConfiguration.BAND_2GHZ;
+ } else if (ScanResult.is5GHz(freq)) {
+ return SoftApConfiguration.BAND_5GHZ;
+ } else if (ScanResult.is6GHz(freq)) {
+ return SoftApConfiguration.BAND_6GHZ;
+ } else if (ScanResult.is60GHz(freq)) {
+ return SoftApConfiguration.BAND_60GHZ;
+ }
+ return -1;
+ }
+
+ private int[] convertJSONArrayToIntArray(JSONArray jArray) throws JSONException {
+ if (jArray == null) {
+ return null;
+ }
+ int[] iArray = new int[jArray.length()];
+ for (int i = 0; i < jArray.length(); i++) {
+ iArray[i] = jArray.getInt(i);
+ }
+ return iArray;
+ }
+
private SoftApConfiguration createSoftApConfiguration(JSONObject configJson)
throws JSONException {
if (configJson == null) {
@@ -1524,10 +1757,48 @@ public class WifiManagerFacade extends RpcReceiver {
for (int j = 0; j < blockedList.length(); j++) {
blockedClientList.add(MacAddress.fromString(blockedList.getString(j)));
}
-
}
+
configBuilder.setAllowedClientList(allowedClientList);
configBuilder.setBlockedClientList(blockedClientList);
+
+ if (SdkLevel.isAtLeastS()) {
+ if (configJson.has("apBands")) {
+ JSONArray jBands = configJson.getJSONArray("apBands");
+ int[] bands = convertJSONArrayToIntArray(jBands);
+ configBuilder.setBands(bands);
+ }
+
+ if (configJson.has("apChannelFrequencies")) {
+ JSONArray jChannelFrequencys = configJson.getJSONArray("apChannelFrequencies");
+ int[] channelFrequencies = convertJSONArrayToIntArray(jChannelFrequencys);
+ SparseIntArray channels = new SparseIntArray();
+ for (int channelFrequency : channelFrequencies) {
+ if (channelFrequency != 0) {
+ channels.put(getApBandFromChannelFrequency(channelFrequency),
+ ScanResult.convertFrequencyMhzToChannelIfSupported(
+ channelFrequency));
+ }
+ }
+ if (channels.size() != 0) {
+ configBuilder.setChannels(channels);
+ }
+ }
+
+ if (configJson.has("MacRandomizationSetting")) {
+ configBuilder.setMacRandomizationSetting(
+ configJson.getInt("MacRandomizationSetting"));
+ }
+
+ if (configJson.has("BridgedModeOpportunisticShutdownEnabled")) {
+ configBuilder.setBridgedModeOpportunisticShutdownEnabled(
+ configJson.getBoolean("BridgedModeOpportunisticShutdownEnabled"));
+ }
+
+ if (configJson.has("Ieee80211axEnabled")) {
+ configBuilder.setIeee80211axEnabled(configJson.getBoolean("Ieee80211axEnabled"));
+ }
+ }
return configBuilder.build();
}
@@ -1684,6 +1955,16 @@ public class WifiManagerFacade extends RpcReceiver {
return enabled;
}
+ @Rpc(description = "Restart the WiFi subsystem.")
+ public void restartWifiSubsystem() {
+ if (mSubsystemRestartTrackingCallback == null) {
+ // one-time registration if needed
+ mSubsystemRestartTrackingCallback = new SubsystemRestartTrackingCallbackFacade(
+ mEventFacade);
+ }
+ mWifi.restartWifiSubsystem();
+ }
+
@Rpc(description = "Toggle Wifi scan always available on and off.", returns = "True if Wifi scan is always available.")
public Boolean wifiToggleScanAlwaysAvailable(
@RpcParameter(name = "enabled") @RpcOptional Boolean enabled)
@@ -1699,91 +1980,6 @@ public class WifiManagerFacade extends RpcReceiver {
mWifi.allowAutojoinGlobal(enable);
}
- private void wifiRequestNetworkWithSpecifierInternal(NetworkSpecifier wns, int timeoutInMs)
- throws GeneralSecurityException {
- NetworkRequest networkRequest = new NetworkRequest.Builder()
- .addTransportType(TRANSPORT_WIFI)
- .setNetworkSpecifier(wns)
- .build();
- NetworkCallback networkCallback = new NetworkCallbackImpl();
- if (timeoutInMs != 0) {
- mCm.requestNetwork(networkRequest, networkCallback,
- new Handler(mCallbackHandlerThread.getLooper()), timeoutInMs);
- } else {
- mCm.requestNetwork(networkRequest, networkCallback,
- new Handler(mCallbackHandlerThread.getLooper()));
- }
- // Store the callback for release later.
- mNetworkCallbacks.put(wns, networkCallback);
- }
-
- /**
- * Initiates a network request {@link NetworkRequest} using {@link WifiNetworkSpecifier}.
- *
- * @param wifiNetworkSpecifier JSONObject Dictionary of wifi network specifier parameters
- * @throws JSONException
- * @throws GeneralSecurityException
- */
- @Rpc(description = "Initiates a network request using the provided network specifier")
- public void wifiRequestNetworkWithSpecifier(
- @RpcParameter(name = "wifiNetworkSpecifier") JSONObject wifiNetworkSpecifier)
- throws JSONException, GeneralSecurityException {
- wifiRequestNetworkWithSpecifierInternal(genWifiNetworkSpecifier(wifiNetworkSpecifier), 0);
- }
-
- /**
- * Initiates a network request {@link NetworkRequest} using {@link WifiNetworkSpecifier}.
- *
- * @param wifiNetworkSpecifier JSONObject Dictionary of wifi network specifier parameters
- * @param timeoutInMs Timeout for the request.
- * @throws JSONException
- * @throws GeneralSecurityException
- */
- @Rpc(description = "Initiates a network request using the provided network specifier")
- public void wifiRequestNetworkWithSpecifierWithTimeout(
- @RpcParameter(name = "wifiNetworkSpecifier") JSONObject wifiNetworkSpecifier,
- @RpcParameter(name = "timeout") Integer timeoutInMs)
- throws JSONException, GeneralSecurityException {
- wifiRequestNetworkWithSpecifierInternal(
- genWifiNetworkSpecifier(wifiNetworkSpecifier), timeoutInMs);
- }
-
- /**
- * Releases network request using {@link WifiNetworkSpecifier}.
- *
- * @throws JSONException
- * @throws GeneralSecurityException
- */
- @Rpc(description = "Releases network request corresponding to the network specifier")
- public void wifiReleaseNetwork(
- @RpcParameter(name = "wifiNetworkSpecifier") JSONObject wifiNetworkSpecifier)
- throws JSONException, GeneralSecurityException {
- NetworkSpecifier wns = genWifiNetworkSpecifier(wifiNetworkSpecifier);
- NetworkCallback networkCallback = mNetworkCallbacks.remove(wns);
- if (networkCallback == null) {
- throw new IllegalArgumentException("network callback is null");
- }
- mCm.unregisterNetworkCallback(networkCallback);
- }
-
- /**
- * Releases all pending network requests.
- *
- * @throws JSONException
- * @throws GeneralSecurityException
- */
- @Rpc(description = "Releases all pending network requests")
- public void wifiReleaseNetworkAll() {
- Iterator<Map.Entry<NetworkSpecifier, NetworkCallback>> it =
- mNetworkCallbacks.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry<NetworkSpecifier, NetworkCallback> entry = it.next();
- NetworkCallback networkCallback = entry.getValue();
- it.remove();
- mCm.unregisterNetworkCallback(networkCallback);
- }
- }
-
/**
* Register network request match callback to simulate the UI flow.
*
@@ -1874,7 +2070,6 @@ public class WifiManagerFacade extends RpcReceiver {
@Override
public void shutdown() {
- wifiReleaseNetworkAll();
wifiLockRelease();
if (mTrackingWifiStateChange == true) {
wifiStopTrackingStateChange();
@@ -1974,6 +2169,36 @@ public class WifiManagerFacade extends RpcReceiver {
Log.d("Posting event: onProgress");
mEventFacade.postEvent(EASY_CONNECT_CALLBACK_TAG, msg);
}
+
+ @Override
+ public void onBootstrapUriGenerated(@NonNull Uri dppUri) {
+ Bundle msg = new Bundle();
+ msg.putString("Type", "onBootstrapUriGenerated");
+ Log.d("onBootstrapUriGenerated uri: " + dppUri.toString());
+ msg.putString("generatedUri", dppUri.toString());
+ Log.d("Posting event: onBootstrapUriGenerated");
+ mEventFacade.postEvent(EASY_CONNECT_CALLBACK_TAG, msg);
+ }
+ }
+
+ private static @WifiManager.EasyConnectCryptographyCurve
+ int getEasyConnectCryptographyCurve(String curve) {
+
+ switch (curve) {
+ case "secp384r1":
+ return WifiManager.EASY_CONNECT_CRYPTOGRAPHY_CURVE_SECP384R1;
+ case "secp521r1":
+ return WifiManager.EASY_CONNECT_CRYPTOGRAPHY_CURVE_SECP521R1;
+ case "brainpoolP256r1":
+ return WifiManager.EASY_CONNECT_CRYPTOGRAPHY_CURVE_BRAINPOOLP256R1;
+ case "brainpoolP384r1":
+ return WifiManager.EASY_CONNECT_CRYPTOGRAPHY_CURVE_BRAINPOOLP384R1;
+ case "brainpoolP512r1":
+ return WifiManager.EASY_CONNECT_CRYPTOGRAPHY_CURVE_BRAINPOOLP512R1;
+ case "prime256v1":
+ default:
+ return WifiManager.EASY_CONNECT_CRYPTOGRAPHY_CURVE_PRIME256V1;
+ }
}
/**
@@ -2017,6 +2242,24 @@ public class WifiManagerFacade extends RpcReceiver {
}
/**
+ * Start Easy Connect (DPP) in Responder-Enrollee role: Receive Wi-Fi configuration from a peer
+ *
+ * @param deviceInfo The device specific info to attach in the generated URI
+ * @param cryptographyCurve Elliptic curve cryptography used to generate DPP
+ * public/private key pair
+ */
+ @Rpc(description = "Easy Connect Responder-Enrollee: Receive Wi-Fi configuration from peer")
+ public void startEasyConnectAsEnrolleeResponder(@RpcParameter(name = "deviceInfo") String
+ deviceInfo, @RpcParameter(name = "cryptographyCurve") String cryptographyCurve) {
+ EasyConnectCallback dppStatusCallback = new EasyConnectCallback();
+
+ // Start Easy Connect
+ mWifi.startEasyConnectAsEnrolleeResponder(deviceInfo,
+ getEasyConnectCryptographyCurve(cryptographyCurve), mService.getMainExecutor(),
+ dppStatusCallback);
+ }
+
+ /**
* Stop Easy Connect (DPP) session
*
*/
@@ -2043,4 +2286,165 @@ public class WifiManagerFacade extends RpcReceiver {
@RpcParameter(name = "enableAutojoin") Boolean enableAutojoin) {
mWifi.allowAutojoinPasspoint(fqdn, enableAutojoin);
}
+
+ private static CoexUnsafeChannel genCoexUnsafeChannel(JSONObject j) throws JSONException {
+ if (j == null || !j.has("band") || !j.has("channel")) {
+ return null;
+ }
+
+ final int band;
+ final String jsonBand = j.getString("band");
+ if (TextUtils.equals(jsonBand, "24_GHZ")) {
+ band = WIFI_BAND_24_GHZ;
+ } else if (TextUtils.equals(jsonBand, "5_GHZ")) {
+ band = WIFI_BAND_5_GHZ;
+ } else {
+ return null;
+ }
+ if (j.has("powerCapDbm")) {
+ return new CoexUnsafeChannel(band, j.getInt("channel"), j.getInt("powerCapDbm"));
+ }
+ return new CoexUnsafeChannel(band, j.getInt("channel"));
+ }
+
+ private static List<CoexUnsafeChannel> genCoexUnsafeChannels(
+ JSONArray jsonCoexUnsafeChannelsArray) throws JSONException {
+ if (jsonCoexUnsafeChannelsArray == null) {
+ return Collections.emptyList();
+ }
+ List<CoexUnsafeChannel> unsafeChannels = new ArrayList<>();
+ for (int i = 0; i < jsonCoexUnsafeChannelsArray.length(); i++) {
+ unsafeChannels.add(
+ genCoexUnsafeChannel(jsonCoexUnsafeChannelsArray.getJSONObject(i)));
+ }
+ return unsafeChannels;
+ }
+
+ private static int genCoexRestrictions(JSONArray jsonCoexRestrictionArray)
+ throws JSONException {
+ if (jsonCoexRestrictionArray == null) {
+ return 0;
+ }
+ int coexRestrictions = 0;
+ for (int i = 0; i < jsonCoexRestrictionArray.length(); i++) {
+ final String jsonRestriction = jsonCoexRestrictionArray.getString(i);
+ if (TextUtils.equals(jsonRestriction, "WIFI_DIRECT")) {
+ coexRestrictions |= WifiManager.COEX_RESTRICTION_WIFI_DIRECT;
+ }
+ if (TextUtils.equals(jsonRestriction, "SOFTAP")) {
+ coexRestrictions |= WifiManager.COEX_RESTRICTION_SOFTAP;
+ }
+ if (TextUtils.equals(jsonRestriction, "WIFI_AWARE")) {
+ coexRestrictions |= WifiManager.COEX_RESTRICTION_WIFI_AWARE;
+ }
+ }
+ return coexRestrictions;
+ }
+
+ /**
+ * Converts a set of {@link CoexUnsafeChannel} to a {@link JSONArray} of {@link JSONObject} of
+ * format:
+ * {
+ * "band": <"24_GHZ" or "5_GHZ">
+ * "channel" : <Channel Number>
+ * (Optional) "powerCapDbm" : <Power Cap in Dbm>
+ * }
+ */
+ private static JSONArray coexUnsafeChannelsToJson(List<CoexUnsafeChannel> unsafeChannels)
+ throws JSONException {
+ final JSONArray jsonCoexUnsafeChannelArray = new JSONArray();
+ for (CoexUnsafeChannel unsafeChannel : unsafeChannels) {
+ final String jsonBand;
+ if (unsafeChannel.getBand() == WIFI_BAND_24_GHZ) {
+ jsonBand = "24_GHZ";
+ } else if (unsafeChannel.getBand() == WIFI_BAND_5_GHZ) {
+ jsonBand = "5_GHZ";
+ } else {
+ continue;
+ }
+ final JSONObject jsonUnsafeChannel = new JSONObject();
+ jsonUnsafeChannel.put("band", jsonBand);
+ jsonUnsafeChannel.put("channel", unsafeChannel.getChannel());
+ final int powerCapDbm = unsafeChannel.getPowerCapDbm();
+ if (powerCapDbm != CoexUnsafeChannel.POWER_CAP_NONE) {
+ jsonUnsafeChannel.put("powerCapDbm", powerCapDbm);
+ }
+ jsonCoexUnsafeChannelArray.put(jsonUnsafeChannel);
+ }
+ return jsonCoexUnsafeChannelArray;
+ }
+
+ /**
+ * Converts a coex restriction bitmask {@link WifiManager#getCoexRestrictions()} to a JSON array
+ * of possible values "WIFI_DIRECT", "SOFTAP", "WIFI_AWARE".
+ */
+ private static JSONArray coexRestrictionsToJson(int coexRestrictions) {
+ final JSONArray jsonCoexRestrictionArray = new JSONArray();
+ if ((coexRestrictions & WifiManager.COEX_RESTRICTION_WIFI_DIRECT) != 0) {
+ jsonCoexRestrictionArray.put("WIFI_DIRECT");
+ }
+ if ((coexRestrictions & WifiManager.COEX_RESTRICTION_SOFTAP) != 0) {
+ jsonCoexRestrictionArray.put("SOFTAP");
+ }
+ if ((coexRestrictions & WifiManager.COEX_RESTRICTION_WIFI_AWARE) != 0) {
+ jsonCoexRestrictionArray.put("WIFI_AWARE");
+ }
+ return jsonCoexRestrictionArray;
+ }
+
+ /**
+ * Returns whether the default coex algorithm is enabled or not
+ *
+ * @return {@code true} if the default coex algorithm is enabled, {@code false} otherwise.
+ */
+ @Rpc(description = "Returns whether the default coex algorithm is enabled or not")
+ public boolean wifiIsDefaultCoexAlgorithmEnabled() {
+ if (!SdkLevel.isAtLeastS()) {
+ return false;
+ }
+ return mWifi.isDefaultCoexAlgorithmEnabled();
+ }
+
+ /**
+ * Sets the active list of unsafe channels to avoid for coex and the restricted Wifi interfaces.
+ *
+ * @param unsafeChannels JSONArray representation of {@link CoexUnsafeChannel}.
+ * See {@link #coexUnsafeChannelsToJson(List)}.
+ * @param restrictions JSONArray representation of coex restrictions.
+ * See {@link #coexRestrictionsToJson(int)}.
+ * @throws JSONException
+ */
+ @Rpc(description = "Set the unsafe channels to avoid for coex")
+ public void wifiSetCoexUnsafeChannels(
+ @RpcParameter(name = "unsafeChannels") JSONArray unsafeChannels,
+ @RpcParameter(name = "restrictions") JSONArray restrictions) throws JSONException {
+ if (!SdkLevel.isAtLeastS()) {
+ return;
+ }
+ mWifi.setCoexUnsafeChannels(
+ genCoexUnsafeChannels(unsafeChannels), genCoexRestrictions(restrictions));
+ }
+
+ /**
+ * Registers a coex callback to start receiving coex update events.
+ */
+ @Rpc(description = "Registers a coex callback to start receiving coex update events")
+ public void wifiRegisterCoexCallback() {
+ if (!SdkLevel.isAtLeastS()) {
+ return;
+ }
+ mWifi.registerCoexCallback(
+ new HandlerExecutor(mCallbackHandlerThread.getThreadHandler()), mCoexCallback);
+ }
+
+ /**
+ * Unregisters the coex callback to stop receiving coex update events.
+ */
+ @Rpc(description = "Unregisters the coex callback to stop receiving coex update events")
+ public void wifiUnregisterCoexCallback() {
+ if (!SdkLevel.isAtLeastS()) {
+ return;
+ }
+ mWifi.unregisterCoexCallback(mCoexCallback);
+ }
}
diff --git a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRtt2ManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRtt2ManagerFacade.java
index 5197896a..7c1cc008 100644
--- a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRtt2ManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRtt2ManagerFacade.java
@@ -79,7 +79,7 @@ public class WifiRtt2ManagerFacade extends RpcReceiver {
@Override
public void shutdown() {
- // empty
+ mService.unregisterReceiver(mStateChangedReceiver);
}
@Rpc(description = "Does the device support the Wi-Fi RTT feature?")
diff --git a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
index a06adbcb..739028ca 100644
--- a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
+++ b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
@@ -36,6 +36,7 @@ import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
+import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.ProxyInfo;
import android.net.RouteInfo;
@@ -49,8 +50,10 @@ import android.net.wifi.WifiClient;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiScanner;
import android.net.wifi.WifiScanner.ScanData;
import android.net.wifi.WpsInfo;
+import android.net.wifi.aware.WifiAwareNetworkInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pGroup;
@@ -83,7 +86,6 @@ import android.telephony.CellSignalStrengthLte;
import android.telephony.CellSignalStrengthTdscdma;
import android.telephony.CellSignalStrengthWcdma;
import android.telephony.ModemActivityInfo;
-import android.telephony.ModemActivityInfo.TransmitPower;
import android.telephony.NeighboringCellInfo;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
@@ -94,12 +96,15 @@ import android.telephony.gsm.GsmCellLocation;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.util.SparseArray;
+import android.util.SparseIntArray;
import com.android.internal.net.LegacyVpnInfo;
+import com.android.modules.utils.build.SdkLevel;
import com.googlecode.android_scripting.ConvertUtils;
import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.event.Event;
+import com.googlecode.android_scripting.facade.ConnectivityConstants;
import com.googlecode.android_scripting.facade.DataUsageController.DataUsageInfo;
import com.googlecode.android_scripting.facade.telephony.InCallServiceImpl;
import com.googlecode.android_scripting.facade.telephony.TelephonyConstants;
@@ -124,6 +129,8 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
public class JsonBuilder {
@@ -238,6 +245,9 @@ public class JsonBuilder {
if (data instanceof Network) {
return buildNetwork((Network) data);
}
+ if (data instanceof NetworkCapabilities) {
+ return buildNetworkCapabilities((NetworkCapabilities) data);
+ }
if (data instanceof NetworkInfo) {
return buildNetworkInfo((NetworkInfo) data);
}
@@ -924,10 +934,52 @@ public class JsonBuilder {
private static Object buildNetwork(Network data) throws JSONException {
JSONObject nw = new JSONObject();
- nw.put("netId", data.netId);
+ nw.put("netId", data.getNetId());
return nw;
}
+ public static JSONObject buildNetworkCapabilities(JSONObject nc, NetworkCapabilities data)
+ throws JSONException {
+ nc.put(ConnectivityConstants.NetworkCallbackContainer.RSSI,
+ data.getSignalStrength());
+ nc.put(ConnectivityConstants.NetworkCallbackContainer.METERED,
+ !data.hasCapability(ConnectivityConstants.NET_CAPABILITY_TEMPORARILY_NOT_METERED));
+ nc.put(ConnectivityConstants.NET_CAPABILITIES_TRANSPORT_TYPE,
+ new JSONArray(data.getTransportTypes()));
+ nc.put(ConnectivityConstants.NET_CAPABILITIES_CAPABILITIES,
+ new JSONArray(data.getCapabilities()));
+
+ if (data.getNetworkSpecifier() != null) {
+ nc.put("network_specifier",
+ data.getNetworkSpecifier().toString());
+ }
+ if (data.getTransportInfo() != null) {
+ nc.put("transport_info",
+ JsonBuilder.build(data.getTransportInfo()));
+ if (data.getTransportInfo() instanceof WifiAwareNetworkInfo) {
+ WifiAwareNetworkInfo anc =
+ (WifiAwareNetworkInfo) data.getTransportInfo();
+
+ String ipv6 = anc.getPeerIpv6Addr().toString();
+ if (ipv6.charAt(0) == '/') {
+ ipv6 = ipv6.substring(1);
+ }
+ nc.put("aware_ipv6", ipv6);
+ if (anc.getPort() != 0) {
+ nc.put("aware_port", anc.getPort());
+ }
+ if (anc.getTransportProtocol() != -1) {
+ nc.put("aware_transport_protocol", anc.getTransportProtocol());
+ }
+ }
+ }
+ return nc;
+ }
+
+ private static Object buildNetworkCapabilities(NetworkCapabilities data) throws JSONException {
+ return buildNetworkCapabilities(new JSONObject(), data);
+ }
+
private static Object buildNetworkInfo(NetworkInfo data)
throws JSONException {
JSONObject info = new JSONObject();
@@ -1056,6 +1108,22 @@ public class JsonBuilder {
return result;
}
+ private static @WifiScanner.WifiBand int apBand2wifiScannerBand(
+ @SoftApConfiguration.BandType int band) {
+ switch(band) {
+ case SoftApConfiguration.BAND_2GHZ:
+ return WifiScanner.WIFI_BAND_24_GHZ;
+ case SoftApConfiguration.BAND_5GHZ:
+ return WifiScanner.WIFI_BAND_5_GHZ;
+ case SoftApConfiguration.BAND_6GHZ:
+ return WifiScanner.WIFI_BAND_6_GHZ;
+ case SoftApConfiguration.BAND_60GHZ:
+ return WifiScanner.WIFI_BAND_60_GHZ;
+ default:
+ return WifiScanner.WIFI_BAND_UNSPECIFIED;
+ }
+ }
+
private static Object buildSoftApConfiguration(SoftApConfiguration data)
throws JSONException {
JSONObject config = new JSONObject();
@@ -1083,6 +1151,26 @@ public class JsonBuilder {
config.put("ClientControlByUserEnabled", data.isClientControlByUserEnabled());
config.put("AllowedClientList", build(data.getAllowedClientList()));
config.put("BlockedClientList", build(data.getBlockedClientList()));
+ if (SdkLevel.isAtLeastS()) {
+ config.put("apBands", buildJSONArray(
+ IntStream.of(data.getBands()).boxed().toArray(Integer[]::new)));
+ SparseIntArray channels = data.getChannels();
+ int[] channelFrequencies = new int[channels.size()];
+ for (int i = 0; i < channels.size(); i++) {
+ int channel = channels.valueAt(i);
+ channelFrequencies[i] = channel == 0 ? 0
+ : ScanResult.convertChannelToFrequencyMhzIfSupported(
+ channel, apBand2wifiScannerBand(channels.keyAt(i)));
+ }
+ if (channelFrequencies.length != 0) {
+ config.put("apChannelFrequencies", build(
+ IntStream.of(channelFrequencies).boxed().toArray(Integer[]::new)));
+ }
+ config.put("MacRandomizationSetting", build(data.getMacRandomizationSetting()));
+ config.put("BridgedModeOpportunisticShutdownEnabled",
+ build(data.isBridgedModeOpportunisticShutdownEnabled()));
+ config.put("Ieee80211axEnabled", build(data.isIeee80211axEnabled()));
+ }
return config;
}
@@ -1221,6 +1309,29 @@ public class JsonBuilder {
SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT));
info.put("wpa3SaeSupported", data.areFeaturesSupported(
SoftApCapability.SOFTAP_FEATURE_WPA3_SAE));
+ info.put("ieee80211axSupported", data.areFeaturesSupported(
+ SoftApCapability.SOFTAP_FEATURE_IEEE80211_AX));
+ info.put("24gSupported", data.areFeaturesSupported(
+ SoftApCapability.SOFTAP_FEATURE_BAND_24G_SUPPORTED));
+ info.put("5gSupported", data.areFeaturesSupported(
+ SoftApCapability.SOFTAP_FEATURE_BAND_5G_SUPPORTED));
+ info.put("6gSupported", data.areFeaturesSupported(
+ SoftApCapability.SOFTAP_FEATURE_BAND_6G_SUPPORTED));
+ info.put("60gSupported", data.areFeaturesSupported(
+ SoftApCapability.SOFTAP_FEATURE_BAND_60G_SUPPORTED));
+ info.put("supported2GHzChannellist", build(
+ IntStream.of(data.getSupportedChannelList(SoftApConfiguration.BAND_2GHZ))
+ .boxed().toArray(Integer[]::new)));
+
+ info.put("supported5GHzChannellist", build(
+ IntStream.of(data.getSupportedChannelList(SoftApConfiguration.BAND_5GHZ))
+ .boxed().toArray(Integer[]::new)));
+ info.put("supported6GHzChannellist", build(
+ IntStream.of(data.getSupportedChannelList(SoftApConfiguration.BAND_6GHZ))
+ .boxed().toArray(Integer[]::new)));
+ info.put("supported60GHzChannellist", build(
+ IntStream.of(data.getSupportedChannelList(SoftApConfiguration.BAND_60GHZ))
+ .boxed().toArray(Integer[]::new)));
return info;
}
@@ -1230,6 +1341,11 @@ public class JsonBuilder {
Log.d("build softAp info.");
info.put("frequency", data.getFrequency());
info.put("bandwidth", data.getBandwidth());
+ info.put("autoShutdownTimeoutMillis", data.getAutoShutdownTimeoutMillis());
+ if (SdkLevel.isAtLeastS()) {
+ info.put("wifiStandard", data.getWifiStandard());
+ info.put("bssid", data.getBssid());
+ }
return info;
}
@@ -1410,16 +1526,14 @@ public class JsonBuilder {
throws JSONException {
JSONObject info = new JSONObject();
- info.put("Timestamp", modemInfo.getTimestamp());
+ info.put("Timestamp", modemInfo.getTimestampMillis());
info.put("SleepTimeMs", modemInfo.getSleepTimeMillis());
info.put("IdleTimeMs", modemInfo.getIdleTimeMillis());
- // convert from int[] to List<Integer> for proper JSON translation
- List<TransmitPower> txPowerIno = modemInfo.getTransmitPowerInfo();
- List<Integer> tmp = new ArrayList<Integer>(txPowerIno.size());
- for (TransmitPower val : txPowerIno) {
- tmp.add(val.getTimeInMillis());
- }
- info.put("TxTimeMs", build(tmp));
+ List<Long> txPowerDurations = IntStream.range(0, 5)
+ .mapToLong(modemInfo::getTransmitDurationMillisAtPowerLevel)
+ .boxed()
+ .collect(Collectors.toList());
+ info.put("TxTimeMs", build(txPowerDurations));
info.put("RxTimeMs", modemInfo.getReceiveTimeMillis());
return info;
}
@@ -1538,7 +1652,7 @@ public class JsonBuilder {
info.put(TelephonyConstants.ServiceStateContainer.IS_USING_CARRIER_AGGREGATION,
ss.isUsingCarrierAggregation());
info.put(TelephonyConstants.ServiceStateContainer.LTE_EARFCN_RSRP_BOOST,
- ss.getLteEarfcnRsrpBoost());
+ ss.getArfcnRsrpBoost());
return info;
}
diff --git a/Common/src/com/googlecode/android_scripting/rpc/MethodDescriptor.java b/Common/src/com/googlecode/android_scripting/rpc/MethodDescriptor.java
index f1a86343..14165748 100644
--- a/Common/src/com/googlecode/android_scripting/rpc/MethodDescriptor.java
+++ b/Common/src/com/googlecode/android_scripting/rpc/MethodDescriptor.java
@@ -26,10 +26,6 @@ import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.jsonrpc.RpcReceiverManager;
import com.googlecode.android_scripting.util.VisibleForTesting;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
@@ -41,6 +37,10 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
/**
* An adapter that wraps {@code Method}.
*/
diff --git a/InterpreterForAndroid/Android.bp b/InterpreterForAndroid/Android.bp
index 452b65d8..1a963b83 100644
--- a/InterpreterForAndroid/Android.bp
+++ b/InterpreterForAndroid/Android.bp
@@ -14,6 +14,15 @@
// limitations under the License.
//
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_sl4a_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["external_sl4a_license"],
+}
+
java_library {
name: "sl4a.InterpreterForAndroid",
owner: "google",
diff --git a/METADATA b/METADATA
new file mode 100644
index 00000000..6d8601bb
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+ license_type: RESTRICTED
+}
diff --git a/ScriptingLayer/Android.bp b/ScriptingLayer/Android.bp
index cf65c2e8..c2967554 100644
--- a/ScriptingLayer/Android.bp
+++ b/ScriptingLayer/Android.bp
@@ -14,6 +14,15 @@
// limitations under the License.
//
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_sl4a_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["external_sl4a_license"],
+}
+
java_library {
name: "sl4a.ScriptingLayer",
owner: "google",
diff --git a/ScriptingLayerForAndroid/Android.bp b/ScriptingLayerForAndroid/Android.bp
index bfe27c92..46797e76 100644
--- a/ScriptingLayerForAndroid/Android.bp
+++ b/ScriptingLayerForAndroid/Android.bp
@@ -14,6 +14,16 @@
// limitations under the License.
//
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_sl4a_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ // SPDX-license-identifier-GPL-2.0
+ default_applicable_licenses: ["external_sl4a_license"],
+}
+
android_test_helper_app {
name: "sl4a",
@@ -56,6 +66,9 @@ android_test_helper_app {
},
jni_libs: ["libcom_googlecode_android_scripting_Exec"],
+
+ min_sdk_version: "30",
+ target_sdk_version: "31",
}
java_import {
diff --git a/ScriptingLayerForAndroid/AndroidManifest.xml b/ScriptingLayerForAndroid/AndroidManifest.xml
index 11db7879..441342ce 100644
--- a/ScriptingLayerForAndroid/AndroidManifest.xml
+++ b/ScriptingLayerForAndroid/AndroidManifest.xml
@@ -117,14 +117,14 @@
<uses-permission android:name="android.permission.WRITE_USER_DICTIONARY" />
<uses-permission android:name="com.android.certinstaller.INSTALL_AS_USER" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
- <uses-permission android:name="com.android.permission.WHITELIST_BLUETOOTH_DEVICE" />
+ <uses-permission android:name="com.android.permission.ALLOWLIST_BLUETOOTH_DEVICE" />
<application
android:icon="@drawable/sl4a_logo_48"
android:label="@string/application_title"
android:name=".Sl4aApplication"
android:theme="@android:style/Theme.DeviceDefault"
android:usesCleartextTraffic="true">
- <activity android:name=".activity.ScriptManager" android:configChanges="keyboardHidden|orientation" android:windowSoftInputMode="adjustResize" android:launchMode="singleTop">
+ <activity android:name=".activity.ScriptManager" android:configChanges="keyboardHidden|orientation" android:windowSoftInputMode="adjustResize" android:launchMode="singleTop" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -134,7 +134,7 @@
</intent-filter>
<meta-data android:name="android.app.searchable" android:resource="@xml/searchable_scripts" />
</activity>
- <activity android:name=".activity.ScriptPicker" android:configChanges="keyboardHidden|orientation" android:label="Scripts">
+ <activity android:name=".activity.ScriptPicker" android:configChanges="keyboardHidden|orientation" android:label="Scripts" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.CREATE_SHORTCUT" />
<category android:name="android.intent.category.DEFAULT" />
@@ -145,31 +145,36 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
- <activity android:name=".activity.InterpreterPicker" android:configChanges="keyboardHidden|orientation" android:label="Interpreters">
+ <activity android:name=".activity.InterpreterPicker" android:configChanges="keyboardHidden|orientation" android:label="Interpreters"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.CREATE_SHORTCUT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
- <activity-alias android:name="LocalePlugin" android:targetActivity=".activity.ScriptPicker" android:label="@string/application_title" android:icon="@drawable/sl4a_logo_32">
+ <activity-alias android:name="LocalePlugin" android:targetActivity=".activity.ScriptPicker" android:label="@string/application_title" android:icon="@drawable/sl4a_logo_32"
+ android:exported="true">
<intent-filter>
<action android:name="com.twofortyfouram.locale.intent.action.EDIT_SETTING" />
</intent-filter>
</activity-alias>
- <receiver android:name=".locale.LocaleReceiver">
+ <receiver android:name=".locale.LocaleReceiver"
+ android:exported="true">
<intent-filter>
<action android:name="com.twofortyfouram.locale.intent.action.FIRE_SETTING" />
</intent-filter>
</receiver>
<activity android:name=".activity.Preferences" android:theme="@android:style/Theme.DeviceDefault.Settings" />
<activity android:name="org.connectbot.ConsoleActivity" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:configChanges="keyboardHidden|orientation" android:windowSoftInputMode="stateAlwaysVisible|adjustResize" android:finishOnTaskLaunch="true" android:launchMode="singleTask" />
- <activity android:name=".activity.ScriptEditor" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:configChanges="keyboardHidden|orientation" android:windowSoftInputMode="stateAlwaysVisible|adjustResize">
+ <activity android:name=".activity.ScriptEditor" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:configChanges="keyboardHidden|orientation" android:windowSoftInputMode="stateAlwaysVisible|adjustResize"
+ android:exported="true">
<intent-filter>
<action android:name="com.googlecode.android_scripting.action.EDIT_SCRIPT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
- <activity android:name=".activity.ApiBrowser" android:configChanges="keyboardHidden|orientation" android:launchMode="singleTop" android:windowSoftInputMode="adjustResize">
+ <activity android:name=".activity.ApiBrowser" android:configChanges="keyboardHidden|orientation" android:launchMode="singleTop" android:windowSoftInputMode="adjustResize"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
@@ -178,7 +183,8 @@
<activity android:name=".activity.ApiPrompt" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:configChanges="keyboardHidden|orientation" />
<activity android:name=".activity.TriggerManager" android:launchMode="singleTask" android:configChanges="keyboardHidden|orientation" />
<activity android:name=".activity.BluetoothDeviceList" android:configChanges="keyboardHidden|orientation" />
- <activity android:name=".activity.ScriptingLayerServiceLauncher" android:taskAffinity="" android:theme="@android:style/Theme.DeviceDefault.NoActionBar.TranslucentDecor">
+ <activity android:name=".activity.ScriptingLayerServiceLauncher" android:taskAffinity="" android:theme="@android:style/Theme.DeviceDefault.NoActionBar.TranslucentDecor"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
@@ -190,7 +196,8 @@
<service android:name=".service.ScriptingLayerService" />
<service android:name=".service.TriggerService" />
<service android:name="com.googlecode.android_scripting.facade.telephony.InCallServiceImpl"
- android:permission="android.permission.BIND_INCALL_SERVICE" >
+ android:permission="android.permission.BIND_INCALL_SERVICE"
+ android:exported="true">
<intent-filter>
<action android:name="android.telecom.InCallService"/>
</intent-filter>
@@ -202,14 +209,16 @@
<action android:name="com.googlecode.android_scripting.service.FacadeService.ACTION_BIND" />
</intent-filter>
</service>
- <service android:name=".facade.bluetooth.media.BluetoothSL4AAudioSrcMBS">
+ <service android:name=".facade.bluetooth.media.BluetoothSL4AAudioSrcMBS"
+ android:exported="true">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
<activity android:name=".activity.InterpreterManager" android:launchMode="singleTask" android:configChanges="keyboardHidden|orientation" />
<activity android:name=".activity.LogcatViewer" android:launchMode="singleTask" android:configChanges="keyboardHidden|orientation" />
- <activity android:name=".activity.ScriptsLiveFolder" android:label="Scripts" android:icon="@drawable/live_folder" android:configChanges="keyboardHidden|orientation">
+ <activity android:name=".activity.ScriptsLiveFolder" android:label="Scripts" android:icon="@drawable/live_folder" android:configChanges="keyboardHidden|orientation"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.CREATE_LIVE_FOLDER" />
<category android:name="android.intent.category.DEFAULT" />
@@ -231,7 +240,8 @@
</provider>
<uses-library android:name="android.test.runner" />
<activity android:name=".activity.ScriptProcessMonitor" android:launchMode="singleTask" android:finishOnTaskLaunch="true" />
- <activity android:configChanges="keyboardHidden|orientation" android:name="org.connectbot.util.ColorsActivity" android:theme="@android:style/Theme.DeviceDefault.Dialog">
+ <activity android:configChanges="keyboardHidden|orientation" android:name="org.connectbot.util.ColorsActivity" android:theme="@android:style/Theme.DeviceDefault.Dialog"
+ android:exported="true">
<intent-filter>
<action android:name="com.googlecode.android_scripting.PICK_TERMINAL_COLORS" />
<category android:name="android.intent.category.DEFAULT" />
diff --git a/ScriptingLayerForAndroid/jni/Android.bp b/ScriptingLayerForAndroid/jni/Android.bp
index cb5e991b..d7f6d7aa 100644
--- a/ScriptingLayerForAndroid/jni/Android.bp
+++ b/ScriptingLayerForAndroid/jni/Android.bp
@@ -14,6 +14,15 @@
// limitations under the License.
//
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_sl4a_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["external_sl4a_license"],
+}
+
cc_library_shared {
name: "libcom_googlecode_android_scripting_Exec",
@@ -25,6 +34,8 @@ cc_library_shared {
"-Wno-unused-parameter",
],
+ header_libs: ["jni_headers"],
+
shared_libs: ["liblog"],
sdk_version: "23",
diff --git a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/ScriptingLayerService.java b/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/ScriptingLayerService.java
index eab396d3..9d5b4cf5 100644
--- a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/ScriptingLayerService.java
+++ b/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/ScriptingLayerService.java
@@ -120,7 +120,9 @@ public class ScriptingLayerService extends ForegroundService {
protected Notification createNotification() {
Intent notificationIntent = new Intent(this, ScriptingLayerService.class);
notificationIntent.setAction(Constants.ACTION_SHOW_RUNNING_SCRIPTS);
- mNotificationPendingIntent = PendingIntent.getService(this, 0, notificationIntent, 0);
+ mNotificationPendingIntent =
+ PendingIntent.getService(this, 0, notificationIntent,
+ PendingIntent.FLAG_IMMUTABLE);
createNotificationChannel();
Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID);
diff --git a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/TriggerService.java b/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/TriggerService.java
index b9115dfc..bf6f235d 100644
--- a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/TriggerService.java
+++ b/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/TriggerService.java
@@ -127,7 +127,8 @@ public class TriggerService extends ForegroundService {
.setWhen(System.currentTimeMillis())
.setContentTitle("SL4A Trigger Service")
.setContentText("Tap to view triggers")
- .setContentIntent(PendingIntent.getActivity(this, 0, notificationIntent, 0));
+ .setContentIntent(PendingIntent.getActivity(this, 0, notificationIntent,
+ PendingIntent.FLAG_IMMUTABLE));
Notification notification = builder.build();
notification.flags = Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT;
return notification;
diff --git a/Utils/Android.bp b/Utils/Android.bp
index d48d3170..51b13255 100644
--- a/Utils/Android.bp
+++ b/Utils/Android.bp
@@ -14,6 +14,15 @@
// limitations under the License.
//
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_sl4a_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["external_sl4a_license"],
+}
+
java_library {
name: "sl4a.Utils",
owner: "google",
diff --git a/Utils/src/com/googlecode/android_scripting/Log.java b/Utils/src/com/googlecode/android_scripting/Log.java
index b3ad6c35..775d67ec 100644
--- a/Utils/src/com/googlecode/android_scripting/Log.java
+++ b/Utils/src/com/googlecode/android_scripting/Log.java
@@ -74,7 +74,8 @@ public class Log {
.setWhen(0)
.setContentTitle(contentTitle)
.setContentText(message)
- .setContentIntent(PendingIntent.getService(context, 0, null, 0));
+ .setContentIntent(PendingIntent.getService(context, 0, null,
+ PendingIntent.FLAG_IMMUTABLE));
Notification note = builder.build();
note.contentView.getLayoutId();
notificationManager.notify(NotificationIdFactory.create(), note);