Merge "Extract TimeDetector/TimeZoneDetector interfaces"
diff --git a/apex/sdkextensions/OWNERS b/apex/sdkextensions/OWNERS
index feb2742..a6e5522 100644
--- a/apex/sdkextensions/OWNERS
+++ b/apex/sdkextensions/OWNERS
@@ -1 +1,2 @@
+dariofreni@google.com
hansson@google.com
diff --git a/api/current.txt b/api/current.txt
index c9744c2..c6c9dde 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -29984,7 +29984,9 @@
package android.net.wifi {
public class ScanResult implements android.os.Parcelable {
+ ctor public ScanResult(@NonNull android.net.wifi.ScanResult);
method public int describeContents();
+ method @NonNull public java.util.List<android.net.wifi.ScanResult.InformationElement> getInformationElements();
method public boolean is80211mcResponder();
method public boolean isPasspointNetwork();
method public void writeToParcel(android.os.Parcel, int);
@@ -29994,6 +29996,7 @@
field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1
field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.ScanResult> CREATOR;
field public String SSID;
field public String capabilities;
field public int centerFreq0;
@@ -30006,6 +30009,12 @@
field public CharSequence venueName;
}
+ public static class ScanResult.InformationElement {
+ ctor public ScanResult.InformationElement(@NonNull android.net.wifi.ScanResult.InformationElement);
+ method @NonNull public java.nio.ByteBuffer getBytes();
+ method public int getId();
+ }
+
public enum SupplicantState implements android.os.Parcelable {
method public int describeContents();
method public static boolean isValidState(android.net.wifi.SupplicantState);
@@ -44653,6 +44662,12 @@
field public static final int BAND_7 = 7; // 0x7
field public static final int BAND_8 = 8; // 0x8
field public static final int BAND_9 = 9; // 0x9
+ field public static final int BAND_A = 101; // 0x65
+ field public static final int BAND_B = 102; // 0x66
+ field public static final int BAND_C = 103; // 0x67
+ field public static final int BAND_D = 104; // 0x68
+ field public static final int BAND_E = 105; // 0x69
+ field public static final int BAND_F = 106; // 0x6a
}
public final class AvailableNetworkInfo implements android.os.Parcelable {
@@ -45313,8 +45328,32 @@
public final class PhoneCapability implements android.os.Parcelable {
method public int describeContents();
+ method @NonNull public java.util.List<java.lang.Integer> getBands(int);
+ method @NonNull public java.util.List<java.util.List<java.lang.Long>> getConcurrentFeaturesSupport();
+ method @NonNull public java.util.List<java.lang.String> getLogicalModemUuids();
+ method public int getMaxActiveDedicatedBearers();
+ method public int getMaxActiveInternetData();
+ method public int getMaxActivePsVoice();
+ method public long getPsDataConnectionLingerTimeMillis();
+ method @NonNull public java.util.List<android.telephony.SimSlotCapability> getSimSlotCapabilities();
+ method public long getSupportedRats();
+ method public int getUeCategory(boolean, int);
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhoneCapability> CREATOR;
+ field public static final long MODEM_FEATURE_3GPP2_REG = 1L; // 0x1L
+ field public static final long MODEM_FEATURE_3GPP_REG = 2L; // 0x2L
+ field public static final long MODEM_FEATURE_CDMA2000_EHRPD_REG = 4L; // 0x4L
+ field public static final long MODEM_FEATURE_CSIM = 8192L; // 0x2000L
+ field public static final long MODEM_FEATURE_CS_VOICE_SESSION = 512L; // 0x200L
+ field public static final long MODEM_FEATURE_DEDICATED_BEARER = 2048L; // 0x800L
+ field public static final long MODEM_FEATURE_EUTRAN_REG = 32L; // 0x20L
+ field public static final long MODEM_FEATURE_EUTRA_NR_DUAL_CONNECTIVITY_REG = 128L; // 0x80L
+ field public static final long MODEM_FEATURE_GERAN_REG = 8L; // 0x8L
+ field public static final long MODEM_FEATURE_INTERACTIVE_DATA_SESSION = 1024L; // 0x400L
+ field public static final long MODEM_FEATURE_NETWORK_SCAN = 4096L; // 0x1000L
+ field public static final long MODEM_FEATURE_NGRAN_REG = 64L; // 0x40L
+ field public static final long MODEM_FEATURE_PS_VOICE_REG = 256L; // 0x100L
+ field public static final long MODEM_FEATURE_UTRAN_REG = 16L; // 0x10L
}
public class PhoneNumberFormattingTextWatcher implements android.text.TextWatcher {
@@ -45499,6 +45538,18 @@
field public static final int INVALID = 2147483647; // 0x7fffffff
}
+ public final class SimSlotCapability implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getPhysicalSlotIndex();
+ method public int getSlotType();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SimSlotCapability> CREATOR;
+ field public static final int SLOT_TYPE_EUICC = 3; // 0x3
+ field public static final int SLOT_TYPE_IUICC = 2; // 0x2
+ field public static final int SLOT_TYPE_SOFT_SIM = 4; // 0x4
+ field public static final int SLOT_TYPE_UICC = 1; // 0x1
+ }
+
public final class SmsManager {
method public String createAppSpecificSmsToken(android.app.PendingIntent);
method @Nullable public String createAppSpecificSmsTokenWithPackageInfo(@Nullable String, @NonNull android.app.PendingIntent);
@@ -45845,6 +45896,7 @@
method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public int getNetworkSelectionMode();
method public String getNetworkSpecifier();
method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int getNetworkType();
+ method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.telephony.PhoneCapability getPhoneCapability();
method @Deprecated public int getPhoneCount();
method public int getPhoneType();
method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE}) public int getPreferredOpportunisticDataSubscription();
diff --git a/api/system-current.txt b/api/system-current.txt
index 1ab457e..a92fd51 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -8488,7 +8488,7 @@
}
public class CellBroadcastIntents {
- method public static void sendOrderedBroadcastForBackgroundReceivers(@NonNull android.content.Context, @Nullable android.os.UserHandle, @NonNull android.content.Intent, @Nullable String, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
+ method public static void sendSmsCbReceivedBroadcast(@NonNull android.content.Context, @Nullable android.os.UserHandle, @NonNull android.telephony.SmsCbMessage, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, int);
}
public abstract class CellBroadcastService extends android.app.Service {
diff --git a/core/java/android/telephony/CellBroadcastIntents.java b/core/java/android/telephony/CellBroadcastIntents.java
index 8446253..2e08108 100644
--- a/core/java/android/telephony/CellBroadcastIntents.java
+++ b/core/java/android/telephony/CellBroadcastIntents.java
@@ -16,22 +16,23 @@
package android.telephony;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.app.AppOpsManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
+import android.provider.Telephony;
/**
* A static helper class used to send Intents with prepopulated flags.
* <p>
- * This is intended to be used by the CellBroadcastService and will throw a security exception if
- * used from a UID besides the network stack UID.
+ * This is intended to be used by the CellBroadcastService and does nothing if the caller does not
+ * have permission to broadcast {@link Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION}.
*
* @hide
*/
@@ -39,6 +40,8 @@
public class CellBroadcastIntents {
private static final String LOG_TAG = "CellBroadcastIntents";
+ private static final String EXTRA_MESSAGE = "message";
+
/**
* @hide
*/
@@ -46,50 +49,71 @@
}
/**
- * Returns an intent which can be received by background BroadcastReceivers. This is only
- * intended to be used by the CellBroadcastService and will throw a security exception if called
- * from another UID.
+ * Broadcasts an SMS_CB_RECEIVED_ACTION intent which can be received by background
+ * BroadcastReceivers. This is only intended to be used by the CellBroadcastService and will
+ * do nothing if the caller does not have permission to broadcast
+ * {@link Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION}.
*
* @param context The context from which to send the broadcast
* @param user The user from which to send the broadcast
- * @param intent The Intent to broadcast; all receivers matching this Intent will
- * receive the broadcast.
- * @param receiverPermission String naming a permissions that a receiver must hold in order to
- * receive your broadcast. If null, no permission is required.
- * @param receiverAppOp The app op associated with the broadcast. If null, no appOp is
- * required. If both receiverAppOp and receiverPermission are
- * non-null, a receiver must have both of them to receive the
- * broadcast
+ * @param smsCbMessage The SmsCbMessage to include with the intent
* @param resultReceiver Your own BroadcastReceiver to treat as the final receiver of the
* broadcast.
* @param scheduler A custom Handler with which to schedule the resultReceiver
* callback; if null it will be scheduled in the Context's main
* thread.
* @param initialCode An initial value for the result code. Often Activity.RESULT_OK.
- * @param initialData An initial value for the result data. Often null.
- * @param initialExtras An initial value for the result extras. Often null.
+ * @param slotIndex The slot index to include in the intent
*/
- public static void sendOrderedBroadcastForBackgroundReceivers(@NonNull Context context,
- @Nullable UserHandle user, @NonNull Intent intent, @Nullable String receiverPermission,
- @Nullable String receiverAppOp, @Nullable BroadcastReceiver resultReceiver,
- @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
- @Nullable Bundle initialExtras) {
- int status = context.checkCallingOrSelfPermission(
- "android.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS");
- if (status == PackageManager.PERMISSION_DENIED) {
- throw new SecurityException(
- "Caller does not have permission to send broadcast for background receivers");
- }
- Intent backgroundIntent = new Intent(intent);
+ public static void sendSmsCbReceivedBroadcast(@NonNull Context context,
+ @Nullable UserHandle user, @NonNull SmsCbMessage smsCbMessage,
+ @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler,
+ int initialCode, int slotIndex) {
+ Intent backgroundIntent = new Intent(Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION);
+ backgroundIntent.putExtra(EXTRA_MESSAGE, smsCbMessage);
backgroundIntent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ putPhoneIdAndSubIdExtra(context, backgroundIntent, slotIndex);
+
+ String receiverPermission = Manifest.permission.RECEIVE_SMS;
+ String receiverAppOp = AppOpsManager.OPSTR_RECEIVE_SMS;
if (user != null) {
context.createContextAsUser(user, 0).sendOrderedBroadcast(backgroundIntent,
receiverPermission, receiverAppOp, resultReceiver, scheduler, initialCode,
- initialData, initialExtras);
+ null, null);
} else {
context.sendOrderedBroadcast(backgroundIntent, receiverPermission,
- receiverAppOp, resultReceiver, scheduler, initialCode, initialData,
- initialExtras);
+ receiverAppOp, resultReceiver, scheduler, initialCode, null, null);
+ }
+ }
+
+ /**
+ * Put the phone ID and sub ID into an intent as extras.
+ */
+ private static void putPhoneIdAndSubIdExtra(Context context, Intent intent, int phoneId) {
+ int subId = getSubIdForPhone(context, phoneId);
+ if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ intent.putExtra("subscription", subId);
+ intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
+ }
+ intent.putExtra("phone", phoneId);
+ intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, phoneId);
+ }
+
+ /**
+ * Get the subscription ID for a phone ID, or INVALID_SUBSCRIPTION_ID if the phone does not
+ * have an active sub
+ * @param phoneId the phoneId to use
+ * @return the associated sub id
+ */
+ private static int getSubIdForPhone(Context context, int phoneId) {
+ SubscriptionManager subMan =
+ (SubscriptionManager) context.getSystemService(
+ Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+ int[] subIds = subMan.getSubscriptionIds(phoneId);
+ if (subIds != null) {
+ return subIds[0];
+ } else {
+ return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
}
}
diff --git a/core/java/android/util/CloseGuard.java b/core/java/android/util/CloseGuard.java
index 6ac7696..ba504a3 100644
--- a/core/java/android/util/CloseGuard.java
+++ b/core/java/android/util/CloseGuard.java
@@ -26,7 +26,7 @@
* A simple example: <pre> {@code
* class Foo {
*
- * private final CloseGuard guard = CloseGuard.get();
+ * private final CloseGuard guard = new CloseGuard();
*
* ...
*
@@ -64,7 +64,7 @@
* be deferred. For example: <pre> {@code
* class Bar {
*
- * private final CloseGuard guard = CloseGuard.get();
+ * private final CloseGuard guard = new CloseGuard();
*
* ...
*
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 0c0493b..6960aef 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4700,6 +4700,19 @@
<permission android:name="android.permission.ACCESS_SHARED_LIBRARIES"
android:protectionLevel="signature|installer" />
+ <!-- Allows an app to log compat change usage.
+ @hide <p>Not for use by third-party applications.</p> -->
+ <permission android:name="android.permission.LOG_COMPAT_CHANGE"
+ android:protectionLevel="signature" />
+ <!-- Allows an app to read compat change config.
+ @hide <p>Not for use by third-party applications.</p> -->
+ <permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"
+ android:protectionLevel="signature" />
+ <!-- Allows an app to override compat change config.
+ @hide <p>Not for use by third-party applications.</p> -->
+ <permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"
+ android:protectionLevel="signature" />
+
<!-- Allows input events to be monitored. Very dangerous! @hide -->
<permission android:name="android.permission.MONITOR_INPUT"
android:protectionLevel="signature" />
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index af2569d..14c7795 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -108,6 +108,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
+ <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<uses-permission android:name="android.permission.CREATE_USERS" />
diff --git a/packages/Tethering/src/android/net/dhcp/DhcpServerCallbacks.java b/packages/Tethering/src/android/net/dhcp/DhcpServerCallbacks.java
index 7c413779..9fda125 100644
--- a/packages/Tethering/src/android/net/dhcp/DhcpServerCallbacks.java
+++ b/packages/Tethering/src/android/net/dhcp/DhcpServerCallbacks.java
@@ -28,4 +28,9 @@
public int getInterfaceVersion() {
return IDhcpServerCallbacks.VERSION;
}
+
+ @Override
+ public String getInterfaceHash() {
+ return IDhcpServerCallbacks.HASH;
+ }
}
diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java
index 190d2509..f39e7af 100644
--- a/packages/Tethering/src/android/net/ip/IpServer.java
+++ b/packages/Tethering/src/android/net/ip/IpServer.java
@@ -301,6 +301,11 @@
public int getInterfaceVersion() {
return this.VERSION;
}
+
+ @Override
+ public String getInterfaceHash() {
+ return this.HASH;
+ }
}
private class DhcpServerCallbacksImpl extends DhcpServerCallbacks {
diff --git a/packages/Tethering/src/android/net/util/BaseNetdUnsolicitedEventListener.java b/packages/Tethering/src/android/net/util/BaseNetdUnsolicitedEventListener.java
index 3218c0b..b1ffdb0 100644
--- a/packages/Tethering/src/android/net/util/BaseNetdUnsolicitedEventListener.java
+++ b/packages/Tethering/src/android/net/util/BaseNetdUnsolicitedEventListener.java
@@ -67,4 +67,9 @@
public int getInterfaceVersion() {
return INetdUnsolicitedEventListener.VERSION;
}
+
+ @Override
+ public String getInterfaceHash() {
+ return INetdUnsolicitedEventListener.HASH;
+ }
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 478b87c..e98c370 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2955,6 +2955,11 @@
public int getInterfaceVersion() {
return this.VERSION;
}
+
+ @Override
+ public String getInterfaceHash() {
+ return this.HASH;
+ }
}
private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) {
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 1daed1b..33a82d8 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -734,6 +734,11 @@
public int getInterfaceVersion() {
return INetdUnsolicitedEventListener.VERSION;
}
+
+ @Override
+ public String getInterfaceHash() {
+ return INetdUnsolicitedEventListener.HASH;
+ }
}
//
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 029b7bc..e48169f 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -16,6 +16,11 @@
package com.android.server.compat;
+import static android.Manifest.permission.LOG_COMPAT_CHANGE;
+import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG;
+import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
import android.app.ActivityManager;
import android.app.IActivityManager;
import android.content.Context;
@@ -67,12 +72,14 @@
@Override
public void reportChange(long changeId, ApplicationInfo appInfo) {
+ checkCompatChangeLogPermission();
reportChange(changeId, appInfo.uid,
StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
}
@Override
public void reportChangeByPackageName(long changeId, String packageName, int userId) {
+ checkCompatChangeLogPermission();
ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
if (appInfo == null) {
return;
@@ -82,11 +89,13 @@
@Override
public void reportChangeByUid(long changeId, int uid) {
+ checkCompatChangeLogPermission();
reportChange(changeId, uid, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
}
@Override
public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) {
+ checkCompatChangeReadPermission();
if (mCompatConfig.isChangeEnabled(changeId, appInfo)) {
reportChange(changeId, appInfo.uid,
StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED);
@@ -99,6 +108,7 @@
@Override
public boolean isChangeEnabledByPackageName(long changeId, String packageName, int userId) {
+ checkCompatChangeReadPermission();
ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
if (appInfo == null) {
return true;
@@ -108,6 +118,7 @@
@Override
public boolean isChangeEnabledByUid(long changeId, int uid) {
+ checkCompatChangeReadPermission();
String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
if (packages == null || packages.length == 0) {
return true;
@@ -140,6 +151,7 @@
@Override
public void setOverrides(CompatibilityChangeConfig overrides, String packageName)
throws RemoteException, SecurityException {
+ checkCompatChangeOverridePermission();
mCompatConfig.addOverrides(overrides, packageName);
killPackage(packageName);
}
@@ -147,11 +159,13 @@
@Override
public void setOverridesForTest(CompatibilityChangeConfig overrides, String packageName)
throws RemoteException, SecurityException {
+ checkCompatChangeOverridePermission();
mCompatConfig.addOverrides(overrides, packageName);
}
@Override
public void clearOverrides(String packageName) throws RemoteException, SecurityException {
+ checkCompatChangeOverridePermission();
mCompatConfig.removePackageOverrides(packageName);
killPackage(packageName);
}
@@ -159,12 +173,14 @@
@Override
public void clearOverridesForTest(String packageName)
throws RemoteException, SecurityException {
+ checkCompatChangeOverridePermission();
mCompatConfig.removePackageOverrides(packageName);
}
@Override
public boolean clearOverride(long changeId, String packageName)
throws RemoteException, SecurityException {
+ checkCompatChangeOverridePermission();
boolean existed = mCompatConfig.removeOverride(changeId, packageName);
killPackage(packageName);
return existed;
@@ -172,11 +188,13 @@
@Override
public CompatibilityChangeConfig getAppConfig(ApplicationInfo appInfo) {
+ checkCompatChangeReadPermission();
return mCompatConfig.getAppConfig(appInfo);
}
@Override
public CompatibilityChangeInfo[] listAllChanges() {
+ checkCompatChangeReadPermission();
return mCompatConfig.dumpChanges();
}
@@ -215,6 +233,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ checkCompatChangeReadPermission();
if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;
mCompatConfig.dumpConfig(pw);
}
@@ -276,4 +295,25 @@
Binder.restoreCallingIdentity(identity);
}
}
+
+ private void checkCompatChangeLogPermission() throws SecurityException {
+ if (mContext.checkCallingOrSelfPermission(LOG_COMPAT_CHANGE)
+ != PERMISSION_GRANTED) {
+ throw new SecurityException("Cannot log compat change usage");
+ }
+ }
+
+ private void checkCompatChangeReadPermission() throws SecurityException {
+ if (mContext.checkCallingOrSelfPermission(READ_COMPAT_CHANGE_CONFIG)
+ != PERMISSION_GRANTED) {
+ throw new SecurityException("Cannot read compat change");
+ }
+ }
+
+ private void checkCompatChangeOverridePermission() throws SecurityException {
+ if (mContext.checkCallingOrSelfPermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
+ != PERMISSION_GRANTED) {
+ throw new SecurityException("Cannot override compat change");
+ }
+ }
}
diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
index dbc339b..d15ebe0 100644
--- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
+++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
@@ -310,6 +310,11 @@
return this.VERSION;
}
+ @Override
+ public String getInterfaceHash() {
+ return this.HASH;
+ }
+
private void addWakeupEvent(WakeupEvent event) {
String iface = event.iface;
mWakeupEvents.append(event);
diff --git a/services/net/java/android/net/IpMemoryStore.java b/services/net/java/android/net/IpMemoryStore.java
index 6f91e00..dcefb53 100644
--- a/services/net/java/android/net/IpMemoryStore.java
+++ b/services/net/java/android/net/IpMemoryStore.java
@@ -52,6 +52,11 @@
public int getInterfaceVersion() {
return this.VERSION;
}
+
+ @Override
+ public String getInterfaceHash() {
+ return this.HASH;
+ }
});
}
diff --git a/services/net/java/android/net/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java
index 7f723b1..a3618b4 100644
--- a/services/net/java/android/net/ip/IpClientUtil.java
+++ b/services/net/java/android/net/ip/IpClientUtil.java
@@ -189,6 +189,11 @@
public int getInterfaceVersion() {
return this.VERSION;
}
+
+ @Override
+ public String getInterfaceHash() {
+ return this.HASH;
+ }
}
/**
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 61fe01f..1e623e0 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -65,6 +65,8 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.SUSPEND_APPS"/>
<uses-permission android:name="android.permission.CONTROL_KEYGUARD"/>
+ <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/>
+ <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE"/>
<uses-permission android:name="android.permission.MANAGE_BIND_INSTANT_SERVICE"/>
<uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java
index d325cd8..b1d647f 100644
--- a/telephony/java/android/telephony/AccessNetworkConstants.java
+++ b/telephony/java/android/telephony/AccessNetworkConstants.java
@@ -67,6 +67,22 @@
}
}
+ /**
+ * Access network type
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"RADIO_ACCESS_NETWORK_TYPE_"},
+ value = {
+ AccessNetworkType.UNKNOWN,
+ AccessNetworkType.GERAN,
+ AccessNetworkType.UTRAN,
+ AccessNetworkType.EUTRAN,
+ AccessNetworkType.CDMA2000,
+ AccessNetworkType.IWLAN,
+ AccessNetworkType.NGRAN})
+ public @interface RadioAccessNetworkType {}
+
public static final class AccessNetworkType {
public static final int UNKNOWN = 0;
public static final int GERAN = 1;
@@ -115,11 +131,11 @@
public static final int BAND_ER900 = 14;
/** @hide */
- private GeranBand() {};
+ private GeranBand() {}
}
/**
- * Frenquency bands for UTRAN.
+ * Frequency bands for UTRAN.
* http://www.etsi.org/deliver/etsi_ts/125100_125199/125104/13.03.00_60/ts_125104v130p.pdf
*/
public static final class UtranBand {
@@ -146,12 +162,19 @@
public static final int BAND_25 = 25;
public static final int BAND_26 = 26;
+ /** Frequency bands for TD-SCDMA. Defined in 3GPP TS 25.102, Table 5.2. */
+ public static final int BAND_A = 101;
+ public static final int BAND_B = 102;
+ public static final int BAND_C = 103;
+ public static final int BAND_D = 104;
+ public static final int BAND_E = 105;
+ public static final int BAND_F = 106;
/** @hide */
- private UtranBand() {};
+ private UtranBand() {}
}
/**
- * Frenquency bands for EUTRAN.
+ * Frequency bands for EUTRAN.
* http://www.etsi.org/deliver/etsi_ts/136100_136199/136101/14.03.00_60/ts_136101v140p.pdf
*/
public static final class EutranBand {
@@ -209,7 +232,7 @@
}
/**
- * Frenquency bands for CDMA2000.
+ * Frequency bands for CDMA2000.
* http://www.3gpp2.org/Public_html/Specs/C.S0057-E_v1.0_Bandclass_Specification.pdf
* @hide
*
@@ -240,7 +263,7 @@
public static final int BAND_21 = 22;
/** @hide */
- private CdmaBands() {};
+ private CdmaBands() {}
}
/**
@@ -295,7 +318,7 @@
public static final int BAND_261 = 261;
/** @hide */
- private NgranBands() {};
+ private NgranBands() {}
}
/** @hide */
diff --git a/telephony/java/android/telephony/PhoneCapability.java b/telephony/java/android/telephony/PhoneCapability.java
index 8a75831..90244b3 100644
--- a/telephony/java/android/telephony/PhoneCapability.java
+++ b/telephony/java/android/telephony/PhoneCapability.java
@@ -16,13 +16,20 @@
package android.telephony;
+import android.annotation.LongDef;
import android.annotation.NonNull;
-import android.annotation.SystemApi;
+import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
+import android.telephony.TelephonyManager.NetworkTypeBitMask;
+import com.android.internal.util.CollectionUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -31,68 +38,365 @@
* are shared between those modems defined by list of modem IDs.
*/
public final class PhoneCapability implements Parcelable {
- // Hardcoded default DSDS capability.
+ /** Modem feature indicating 3GPP2 capability. */
+ public static final long MODEM_FEATURE_3GPP2_REG = 1 << 0;
+ /** Modem feature indicating 3GPP capability. */
+ public static final long MODEM_FEATURE_3GPP_REG = 1 << 1;
+ /** Modem feature indicating CDMA 2000 with EHRPD capability. */
+ public static final long MODEM_FEATURE_CDMA2000_EHRPD_REG = 1 << 2;
+ /** Modem feature indicating GSM capability. */
+ public static final long MODEM_FEATURE_GERAN_REG = 1 << 3;
+ /** Modem feature indicating UMTS capability. */
+ public static final long MODEM_FEATURE_UTRAN_REG = 1 << 4;
+ /** Modem feature indicating LTE capability. */
+ public static final long MODEM_FEATURE_EUTRAN_REG = 1 << 5;
+ /** Modem feature indicating 5G capability.*/
+ public static final long MODEM_FEATURE_NGRAN_REG = 1 << 6;
+ /** Modem feature indicating EN-DC capability. */
+ public static final long MODEM_FEATURE_EUTRA_NR_DUAL_CONNECTIVITY_REG = 1 << 7;
+ /** Modem feature indicating VoLTE capability (IMS registered). */
+ public static final long MODEM_FEATURE_PS_VOICE_REG = 1 << 8;
+ /** Modem feature indicating CS voice call capability. */
+ public static final long MODEM_FEATURE_CS_VOICE_SESSION = 1 << 9;
+ /** Modem feature indicating Internet connection capability. */
+ public static final long MODEM_FEATURE_INTERACTIVE_DATA_SESSION = 1 << 10;
+ /**
+ * Modem feature indicating dedicated bearer capability.
+ * For services that require a high level QoS (eg. VoLTE), the network can create
+ * a dedicated bearer with the required QoS on top of an established default bearer.
+ * This will provide a dedicated tunnel for one or more specific traffic types.
+ */
+ public static final long MODEM_FEATURE_DEDICATED_BEARER = 1 << 11;
+ /** Modem feature indicating network scan capability. */
+ public static final long MODEM_FEATURE_NETWORK_SCAN = 1 << 12;
+ /** Modem feature indicating corresponding SIM has CDMA capability. */
+ public static final long MODEM_FEATURE_CSIM = 1 << 13;
+
/** @hide */
+ @LongDef(flag = true, prefix = {"MODEM_FEATURE_" }, value = {
+ MODEM_FEATURE_3GPP2_REG,
+ MODEM_FEATURE_3GPP_REG,
+ MODEM_FEATURE_CDMA2000_EHRPD_REG,
+ MODEM_FEATURE_GERAN_REG,
+ MODEM_FEATURE_UTRAN_REG,
+ MODEM_FEATURE_EUTRAN_REG,
+ MODEM_FEATURE_NGRAN_REG,
+ MODEM_FEATURE_EUTRA_NR_DUAL_CONNECTIVITY_REG,
+ MODEM_FEATURE_PS_VOICE_REG,
+ MODEM_FEATURE_CS_VOICE_SESSION,
+ MODEM_FEATURE_INTERACTIVE_DATA_SESSION,
+ MODEM_FEATURE_DEDICATED_BEARER,
+ MODEM_FEATURE_NETWORK_SCAN,
+ MODEM_FEATURE_CSIM,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ModemFeature {
+ }
+
+ /**
+ * Hardcoded default DSDS capability.
+ * @hide
+ */
public static final PhoneCapability DEFAULT_DSDS_CAPABILITY;
- // Hardcoded default Single SIM single standby capability.
- /** @hide */
+ /**
+ * Hardcoded default Single SIM single standby capability.
+ * @hide
+ */
public static final PhoneCapability DEFAULT_SSSS_CAPABILITY;
static {
- ModemInfo modemInfo1 = new ModemInfo(0, 0, true, true);
- ModemInfo modemInfo2 = new ModemInfo(1, 0, true, true);
+ List<List<Long>> capabilities = new ArrayList<>();
+ List<Long> modem1 = new ArrayList<>();
+ List<Long> modem2 = new ArrayList<>();
+ modem1.add(MODEM_FEATURE_GERAN_REG | MODEM_FEATURE_UTRAN_REG | MODEM_FEATURE_EUTRAN_REG
+ | MODEM_FEATURE_PS_VOICE_REG | MODEM_FEATURE_CS_VOICE_SESSION
+ | MODEM_FEATURE_INTERACTIVE_DATA_SESSION | MODEM_FEATURE_DEDICATED_BEARER);
+ modem2.add(MODEM_FEATURE_GERAN_REG | MODEM_FEATURE_UTRAN_REG | MODEM_FEATURE_EUTRAN_REG
+ | MODEM_FEATURE_PS_VOICE_REG | MODEM_FEATURE_INTERACTIVE_DATA_SESSION
+ | MODEM_FEATURE_DEDICATED_BEARER);
+ capabilities.add(modem1);
+ capabilities.add(modem2);
+ List<String> uuids = new ArrayList<>();
+ uuids.add("com.xxxx.lm0");
+ uuids.add("com.xxxx.lm1");
+ long rats = TelephonyManager.NETWORK_TYPE_BITMASK_GSM
+ | TelephonyManager.NETWORK_TYPE_BITMASK_GPRS
+ | TelephonyManager.NETWORK_TYPE_BITMASK_EDGE
+ | TelephonyManager.NETWORK_TYPE_BITMASK_UMTS
+ | TelephonyManager.NETWORK_TYPE_BITMASK_LTE;
+ DEFAULT_DSDS_CAPABILITY = new PhoneCapability(0, 0, 0, 0, 0, rats, null, null, null, null,
+ uuids, null, capabilities);
- List<ModemInfo> logicalModemList = new ArrayList<>();
- logicalModemList.add(modemInfo1);
- logicalModemList.add(modemInfo2);
- DEFAULT_DSDS_CAPABILITY = new PhoneCapability(1, 1, 0, logicalModemList, false);
-
- logicalModemList = new ArrayList<>();
- logicalModemList.add(modemInfo1);
- DEFAULT_SSSS_CAPABILITY = new PhoneCapability(1, 1, 0, logicalModemList, false);
+ capabilities = new ArrayList<>();
+ capabilities.add(modem1);
+ uuids = new ArrayList<>();
+ uuids.add("com.xxxx.lm0");
+ DEFAULT_SSSS_CAPABILITY = new PhoneCapability(0, 0, 0, 0, 0, rats, null, null, null, null,
+ uuids, null, capabilities);
}
- /** @hide */
- public final int maxActiveVoiceCalls;
- /** @hide */
- public final int maxActiveData;
- /** @hide */
- public final int max5G;
- /** @hide */
- public final boolean validationBeforeSwitchSupported;
- /** @hide */
- public final List<ModemInfo> logicalModemList;
- /** @hide */
- public PhoneCapability(int maxActiveVoiceCalls, int maxActiveData, int max5G,
- List<ModemInfo> logicalModemList, boolean validationBeforeSwitchSupported) {
- this.maxActiveVoiceCalls = maxActiveVoiceCalls;
- this.maxActiveData = maxActiveData;
- this.max5G = max5G;
- // Make sure it's not null.
- this.logicalModemList = logicalModemList == null ? new ArrayList<>() : logicalModemList;
- this.validationBeforeSwitchSupported = validationBeforeSwitchSupported;
+ private final int mUtranUeCategoryDl;
+ private final int mUtranUeCategoryUl;
+ private final int mEutranUeCategoryDl;
+ private final int mEutranUeCategoryUl;
+ private final long mPsDataConnectionLingerTimeMillis;
+ private final @NetworkTypeBitMask long mSupportedRats;
+ private final List<Integer> mGeranBands;
+ private final List<Integer> mUtranBands;
+ private final List<Integer> mEutranBands;
+ private final List<Integer> mNgranBands;
+ private final List<String> mLogicalModemUuids;
+ private final List<SimSlotCapability> mSimSlotCapabilities;
+ private final @ModemFeature List<List<Long>> mConcurrentFeaturesSupport;
+
+ /**
+ * Default constructor to create a PhoneCapability object.
+ * @param utranUeCategoryDl 3GPP UE category for UTRAN downlink.
+ * @param utranUeCategoryUl 3GPP UE category for UTRAN uplink.
+ * @param eutranUeCategoryDl 3GPP UE category for EUTRAN downlink.
+ * @param eutranUeCategoryUl 3GPP UE category for EUTRAN uplink.
+ * @param psDataConnectionLingerTimeMillis length of the grace period to allow a smooth
+ * "handover" between data connections.
+ * @param supportedRats all radio access technologies this phone is capable of supporting.
+ * @param geranBands list of supported {@link AccessNetworkConstants.GeranBand}.
+ * @param utranBands list of supported {@link AccessNetworkConstants.UtranBand}.
+ * @param eutranBands list of supported {@link AccessNetworkConstants.EutranBand}.
+ * @param ngranBands list of supported {@link AccessNetworkConstants.NgranBands}.
+ * @param logicalModemUuids list of logical modem UUIDs, typically of the form
+ * "com.xxxx.lmX", where X is the logical modem ID.
+ * @param simSlotCapabilities list of {@link SimSlotCapability} for the device
+ * @param concurrentFeaturesSupport list of list of concurrently supportable modem feature sets.
+ * @hide
+ */
+ public PhoneCapability(int utranUeCategoryDl, int utranUeCategoryUl, int eutranUeCategoryDl,
+ int eutranUeCategoryUl, long psDataConnectionLingerTimeMillis,
+ @NetworkTypeBitMask long supportedRats, @Nullable List<Integer> geranBands,
+ @Nullable List<Integer> utranBands, @Nullable List<Integer> eutranBands,
+ @Nullable List<Integer> ngranBands, @Nullable List<String> logicalModemUuids,
+ @Nullable List<SimSlotCapability> simSlotCapabilities,
+ @Nullable @ModemFeature List<List<Long>> concurrentFeaturesSupport) {
+ this.mUtranUeCategoryDl = utranUeCategoryDl;
+ this.mUtranUeCategoryUl = utranUeCategoryUl;
+ this.mEutranUeCategoryDl = eutranUeCategoryDl;
+ this.mEutranUeCategoryUl = eutranUeCategoryUl;
+ this.mPsDataConnectionLingerTimeMillis = psDataConnectionLingerTimeMillis;
+ this.mSupportedRats = supportedRats;
+ this.mGeranBands = CollectionUtils.emptyIfNull(geranBands);
+ this.mUtranBands = CollectionUtils.emptyIfNull(utranBands);
+ this.mEutranBands = CollectionUtils.emptyIfNull(eutranBands);
+ this.mNgranBands = CollectionUtils.emptyIfNull(ngranBands);
+ this.mLogicalModemUuids = CollectionUtils.emptyIfNull(logicalModemUuids);
+ this.mSimSlotCapabilities = CollectionUtils.emptyIfNull(simSlotCapabilities);
+ this.mConcurrentFeaturesSupport = CollectionUtils.emptyIfNull(concurrentFeaturesSupport);
+ }
+
+ private PhoneCapability(Parcel in) {
+ mUtranUeCategoryDl = in.readInt();
+ mUtranUeCategoryUl = in.readInt();
+ mEutranUeCategoryDl = in.readInt();
+ mEutranUeCategoryUl = in.readInt();
+ mPsDataConnectionLingerTimeMillis = in.readLong();
+ mSupportedRats = in.readLong();
+ mGeranBands = new ArrayList<>();
+ in.readList(mGeranBands, Integer.class.getClassLoader());
+ mUtranBands = new ArrayList<>();
+ in.readList(mUtranBands, Integer.class.getClassLoader());
+ mEutranBands = new ArrayList<>();
+ in.readList(mEutranBands, Integer.class.getClassLoader());
+ mNgranBands = new ArrayList<>();
+ in.readList(mNgranBands, Integer.class.getClassLoader());
+ mLogicalModemUuids = in.createStringArrayList();
+ mSimSlotCapabilities = in.createTypedArrayList(SimSlotCapability.CREATOR);
+ int length = in.readInt();
+ mConcurrentFeaturesSupport = new ArrayList<>();
+ for (int i = 0; i < length; i++) {
+ ArrayList<Long> feature = new ArrayList<>();
+ in.readList(feature, Long.class.getClassLoader());
+ mConcurrentFeaturesSupport.add(feature);
+ }
+ }
+
+ /**
+ * 3GPP UE category for a given Radio Access Network and direction.
+ *
+ * References are:
+ * TS 25.306 Table 4.1a EUTRAN downlink
+ * TS 25.306 Table 5.1a-2 EUTRAN uplink
+ * TS 25.306 Table 5.1a UTRAN downlink
+ * TS 25.306 Table 5.1g UTRAN uplink
+ *
+ * @param uplink true for uplink direction and false for downlink direction.
+ * @param accessNetworkType accessNetworkType, defined in {@link AccessNetworkType}.
+ * @return the UE category, or -1 if it is not supported.
+ */
+ public int getUeCategory(boolean uplink, @RadioAccessNetworkType int accessNetworkType) {
+ if (uplink) {
+ switch (accessNetworkType) {
+ case AccessNetworkType.UTRAN: return mUtranUeCategoryUl;
+ case AccessNetworkType.EUTRAN: return mEutranUeCategoryUl;
+ default: return -1;
+ }
+ } else {
+ switch (accessNetworkType) {
+ case AccessNetworkType.UTRAN: return mUtranUeCategoryDl;
+ case AccessNetworkType.EUTRAN: return mEutranUeCategoryDl;
+ default: return -1;
+ }
+ }
+ }
+
+ /**
+ * In cellular devices that support a greater number of logical modems than
+ * Internet connections, some devices support a grace period to allow a smooth "handover"
+ * between those connections. If that feature is supported, then this API will provide
+ * the length of that grace period in milliseconds. If it is not supported, the default value
+ * for the grace period is 0.
+ * @return handover linger time in milliseconds, or 0 if it is not supported.
+ */
+ public long getPsDataConnectionLingerTimeMillis() {
+ return mPsDataConnectionLingerTimeMillis;
+ }
+
+ /**
+ * The radio access technologies this device is capable of supporting.
+ * @return a bitfield of all supported network types, defined in {@link TelephonyManager}
+ */
+ public @NetworkTypeBitMask long getSupportedRats() {
+ return mSupportedRats;
+ }
+
+ /**
+ * List of supported cellular bands for the given accessNetworkType.
+ * @param accessNetworkType accessNetworkType, defined in {@link AccessNetworkType}.
+ * @return a list of bands, or an empty list if the access network type is unsupported.
+ */
+ public @NonNull List<Integer> getBands(@RadioAccessNetworkType int accessNetworkType) {
+ switch (accessNetworkType) {
+ case AccessNetworkType.GERAN: return mGeranBands;
+ case AccessNetworkType.UTRAN: return mUtranBands;
+ case AccessNetworkType.EUTRAN: return mEutranBands;
+ case AccessNetworkType.NGRAN: return mNgranBands;
+ default: return new ArrayList<>();
+ }
+ }
+
+ /**
+ * List of logical modem UUIDs, each typically "com.xxxx.lmX", where X is the logical modem ID.
+ * @return a list of modem UUIDs, one for every logical modem the device has.
+ */
+ public @NonNull List<String> getLogicalModemUuids() {
+ return mLogicalModemUuids;
+ }
+
+ /**
+ * List of {@link SimSlotCapability} for the device. The order of SIMs corresponds to the
+ * order of modems in {@link #getLogicalModemUuids}.
+ * @return a list of SIM slot capabilities, one for every SIM slot the device has.
+ */
+ public @NonNull List<SimSlotCapability> getSimSlotCapabilities() {
+ return mSimSlotCapabilities;
+ }
+
+ /**
+ * A List of Lists of concurrently supportable modem feature sets.
+ *
+ * Each entry in the top-level list is an independent configuration across all modems
+ * that describes the capabilities of the device as a whole.
+ *
+ * Each entry in the second-level list is a bitfield of ModemFeatures that describes
+ * the capabilities for a single modem. In the second-level list, the order of the modems
+ * corresponds to order of the UUIDs in {@link #getLogicalModemUuids}.
+ *
+ * For symmetric capabilities that can only be active on one modem at a time, there will be
+ * multiple configurations (equal to the number of modems) that shows it active on each modem.
+ * For asymmetric capabilities that are only available on one of the modems, all configurations
+ * will have that capability on just that one modem.
+ *
+ * The example below shows the concurrentFeaturesSupport for a 3-modem device with
+ * theoretical capabilities SYMMETRIC (available on all modems, but only one at a time) and
+ * ASYMMETRIC (only available on the first modem):
+ * {
+ * Configuration 1: ASYMMETRIC and SYMMETRIC on modem 1, modem 2 empty, modem 3 empty
+ * {(ASYMMETRIC | SYMMETRIC), (), ()},
+ *
+ * Configuration 2: ASYMMETRIC on modem 1, SYMMETRIC on modem 2, modem 3 empty
+ * {(ASYMMETRIC), (SYMMETRIC), ()},
+ *
+ * Configuration 3: ASYMMETRIC on modem 1, modem 2 empty, SYMMETRIC on modem 3
+ * {(ASYMMETRIC), (), (SYMMETRIC)}
+ * }
+ *
+ * @return List of all concurrently supportable modem features.
+ */
+ public @NonNull @ModemFeature List<List<Long>> getConcurrentFeaturesSupport() {
+ return mConcurrentFeaturesSupport;
+ }
+
+ /**
+ * How many modems can simultaneously have PS attached.
+ * @return maximum number of active PS voice connections.
+ */
+ public int getMaxActivePsVoice() {
+ return countFeature(MODEM_FEATURE_PS_VOICE_REG);
+ }
+
+ /**
+ * How many modems can simultaneously support active data connections.
+ * For DSDS, this will be 1, and for DSDA this will be 2.
+ * @return maximum number of active Internet data sessions.
+ */
+ public int getMaxActiveInternetData() {
+ return countFeature(MODEM_FEATURE_INTERACTIVE_DATA_SESSION);
+ }
+
+ /**
+ * How many modems can simultaneously have dedicated bearer capability.
+ * @return maximum number of active dedicated bearers.
+ */
+ public int getMaxActiveDedicatedBearers() {
+ return countFeature(MODEM_FEATURE_DEDICATED_BEARER);
+ }
+
+ /**
+ * Whether the CBRS band 48 is supported or not.
+ * @return true if any RadioAccessNetwork supports CBRS and false if none do.
+ * @hide
+ */
+ public boolean isCbrsSupported() {
+ return mEutranBands.contains(AccessNetworkConstants.EutranBand.BAND_48)
+ || mNgranBands.contains(AccessNetworkConstants.NgranBands.BAND_48);
+ }
+
+ private int countFeature(@ModemFeature long feature) {
+ int count = 0;
+ for (long featureSet : mConcurrentFeaturesSupport.get(0)) {
+ if ((featureSet & feature) != 0) {
+ count++;
+ }
+ }
+ return count;
}
@Override
public String toString() {
- return "maxActiveVoiceCalls=" + maxActiveVoiceCalls + " maxActiveData=" + maxActiveData
- + " max5G=" + max5G + "logicalModemList:"
- + Arrays.toString(logicalModemList.toArray());
- }
-
- private PhoneCapability(Parcel in) {
- maxActiveVoiceCalls = in.readInt();
- maxActiveData = in.readInt();
- max5G = in.readInt();
- validationBeforeSwitchSupported = in.readBoolean();
- logicalModemList = new ArrayList<>();
- in.readList(logicalModemList, ModemInfo.class.getClassLoader());
+ return "utranUeCategoryDl=" + mUtranUeCategoryDl
+ + " utranUeCategoryUl=" + mUtranUeCategoryUl
+ + " eutranUeCategoryDl=" + mEutranUeCategoryDl
+ + " eutranUeCategoryUl=" + mEutranUeCategoryUl
+ + " psDataConnectionLingerTimeMillis=" + mPsDataConnectionLingerTimeMillis
+ + " supportedRats=" + mSupportedRats + " geranBands=" + mGeranBands
+ + " utranBands=" + mUtranBands + " eutranBands=" + mEutranBands
+ + " ngranBands=" + mNgranBands + " logicalModemUuids=" + mLogicalModemUuids
+ + " simSlotCapabilities=" + mSimSlotCapabilities
+ + " concurrentFeaturesSupport=" + mConcurrentFeaturesSupport;
}
@Override
public int hashCode() {
- return Objects.hash(maxActiveVoiceCalls, maxActiveData, max5G, logicalModemList,
- validationBeforeSwitchSupported);
+ return Objects.hash(mUtranUeCategoryDl, mUtranUeCategoryUl, mEutranUeCategoryDl,
+ mEutranUeCategoryUl, mPsDataConnectionLingerTimeMillis, mSupportedRats, mGeranBands,
+ mUtranBands, mEutranBands, mNgranBands, mLogicalModemUuids, mSimSlotCapabilities,
+ mConcurrentFeaturesSupport);
}
@Override
@@ -107,11 +411,19 @@
PhoneCapability s = (PhoneCapability) o;
- return (maxActiveVoiceCalls == s.maxActiveVoiceCalls
- && maxActiveData == s.maxActiveData
- && max5G == s.max5G
- && validationBeforeSwitchSupported == s.validationBeforeSwitchSupported
- && logicalModemList.equals(s.logicalModemList));
+ return (mUtranUeCategoryDl == s.mUtranUeCategoryDl
+ && mUtranUeCategoryUl == s.mUtranUeCategoryUl
+ && mEutranUeCategoryDl == s.mEutranUeCategoryDl
+ && mEutranUeCategoryUl == s.mEutranUeCategoryUl
+ && mPsDataConnectionLingerTimeMillis == s.mPsDataConnectionLingerTimeMillis
+ && mSupportedRats == s.mSupportedRats
+ && mGeranBands.equals(s.mGeranBands)
+ && mUtranBands.equals(s.mUtranBands)
+ && mEutranBands.equals(s.mEutranBands)
+ && mNgranBands.equals(s.mNgranBands)
+ && mLogicalModemUuids.equals(s.mLogicalModemUuids)
+ && mSimSlotCapabilities.equals(s.mSimSlotCapabilities)
+ && mConcurrentFeaturesSupport.equals(s.mConcurrentFeaturesSupport));
}
/**
@@ -125,20 +437,32 @@
* {@link Parcelable#writeToParcel}
*/
public void writeToParcel(@NonNull Parcel dest, @Parcelable.WriteFlags int flags) {
- dest.writeInt(maxActiveVoiceCalls);
- dest.writeInt(maxActiveData);
- dest.writeInt(max5G);
- dest.writeBoolean(validationBeforeSwitchSupported);
- dest.writeList(logicalModemList);
+ dest.writeInt(mUtranUeCategoryDl);
+ dest.writeInt(mUtranUeCategoryUl);
+ dest.writeInt(mEutranUeCategoryDl);
+ dest.writeInt(mEutranUeCategoryUl);
+ dest.writeLong(mPsDataConnectionLingerTimeMillis);
+ dest.writeLong(mSupportedRats);
+ dest.writeList(mGeranBands);
+ dest.writeList(mUtranBands);
+ dest.writeList(mEutranBands);
+ dest.writeList(mNgranBands);
+ dest.writeStringList(mLogicalModemUuids);
+ dest.writeTypedList(mSimSlotCapabilities);
+ dest.writeInt(mConcurrentFeaturesSupport.size());
+ for (List<Long> feature : mConcurrentFeaturesSupport) {
+ dest.writeList(feature);
+ }
}
- public static final @android.annotation.NonNull Parcelable.Creator<PhoneCapability> CREATOR = new Parcelable.Creator() {
- public PhoneCapability createFromParcel(Parcel in) {
- return new PhoneCapability(in);
- }
+ public static final @NonNull Parcelable.Creator<PhoneCapability> CREATOR =
+ new Parcelable.Creator() {
+ public PhoneCapability createFromParcel(Parcel in) {
+ return new PhoneCapability(in);
+ }
- public PhoneCapability[] newArray(int size) {
- return new PhoneCapability[size];
- }
- };
+ public PhoneCapability[] newArray(int size) {
+ return new PhoneCapability[size];
+ }
+ };
}
diff --git a/telephony/java/android/telephony/SimSlotCapability.java b/telephony/java/android/telephony/SimSlotCapability.java
new file mode 100644
index 0000000..3d38d04
--- /dev/null
+++ b/telephony/java/android/telephony/SimSlotCapability.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2019 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 android.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Capabilities for a SIM Slot.
+ */
+public final class SimSlotCapability implements Parcelable {
+ /** Slot type for UICC (removable SIM). */
+ public static final int SLOT_TYPE_UICC = 1;
+ /** Slot type for iUICC/iSIM (integrated SIM). */
+ public static final int SLOT_TYPE_IUICC = 2;
+ /** Slot type for eUICC/eSIM (embedded SIM). */
+ public static final int SLOT_TYPE_EUICC = 3;
+ /** Slot type for soft SIM (no physical SIM). */
+ public static final int SLOT_TYPE_SOFT_SIM = 4;
+
+ /** @hide */
+ @IntDef(prefix = {"SLOT_TYPE_" }, value = {
+ SLOT_TYPE_UICC,
+ SLOT_TYPE_IUICC,
+ SLOT_TYPE_EUICC,
+ SLOT_TYPE_SOFT_SIM,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SlotType {
+ }
+
+ private final int mPhysicalSlotIndex;
+ private final int mSlotType;
+
+ /** @hide */
+ public SimSlotCapability(int physicalSlotId, int slotType) {
+ this.mPhysicalSlotIndex = physicalSlotId;
+ this.mSlotType = slotType;
+ }
+
+ private SimSlotCapability(Parcel in) {
+ mPhysicalSlotIndex = in.readInt();
+ mSlotType = in.readInt();
+ }
+
+ /**
+ * @return physical SIM slot index
+ */
+ public int getPhysicalSlotIndex() {
+ return mPhysicalSlotIndex;
+ }
+
+ /**
+ * @return type of SIM {@link SlotType}
+ */
+ public @SlotType int getSlotType() {
+ return mSlotType;
+ }
+
+ @Override
+ public String toString() {
+ return "mPhysicalSlotIndex=" + mPhysicalSlotIndex + " slotType=" + mSlotType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mPhysicalSlotIndex, mSlotType);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof SimSlotCapability) || hashCode() != o.hashCode()) {
+ return false;
+ }
+
+ if (this == o) {
+ return true;
+ }
+
+ SimSlotCapability s = (SimSlotCapability) o;
+
+ return (mPhysicalSlotIndex == s.mPhysicalSlotIndex && mSlotType == s.mSlotType);
+ }
+
+ /**
+ * {@link Parcelable#describeContents}
+ */
+ public @ContentsFlags int describeContents() {
+ return 0;
+ }
+
+ /**
+ * {@link Parcelable#writeToParcel}
+ */
+ public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) {
+ dest.writeInt(mPhysicalSlotIndex);
+ dest.writeInt(mSlotType);
+ }
+
+ public static final @NonNull Parcelable.Creator<SimSlotCapability> CREATOR =
+ new Parcelable.Creator() {
+ public SimSlotCapability createFromParcel(Parcel in) {
+ return new SimSlotCapability(in);
+ }
+
+ public SimSlotCapability[] newArray(int size) {
+ return new SimSlotCapability[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 3dff079..3ac357a 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1520,6 +1520,24 @@
//
/**
+ * Returns the {@link PhoneCapability} for the device or null if it is not available.
+ * <p>
+ * Requires Permission: READ_PHONE_STATE or that the calling app has
+ * carrier privileges (see {@link #hasCarrierPrivileges}).
+ */
+ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+ @Nullable
+ public PhoneCapability getPhoneCapability() {
+ try {
+ ITelephony telephony = getITelephony();
+ return telephony == null ? null :
+ telephony.getPhoneCapability(getSubId(), getOpPackageName(), getFeatureId());
+ } catch (RemoteException ex) {
+ return null;
+ }
+ }
+
+ /**
* Returns the software version number for the device, for example,
* the IMEI/SV for GSM phones. Return null if the software version is
* not available.
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index f3b467b..1d794cd 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -38,6 +38,7 @@
import android.telephony.ModemActivityInfo;
import android.telephony.NeighboringCellInfo;
import android.telephony.NetworkScanRequest;
+import android.telephony.PhoneCapability;
import android.telephony.PhoneNumberRange;
import android.telephony.RadioAccessFamily;
import android.telephony.ServiceState;
@@ -1830,12 +1831,17 @@
/**
* Return the network selection mode on the subscription with id {@code subId}.
*/
- int getNetworkSelectionMode(int subId);
+ int getNetworkSelectionMode(int subId);
- /**
+ /**
+ * Return the PhoneCapability for the device.
+ */
+ PhoneCapability getPhoneCapability(int subId, String callingPackage, String callingFeatureId);
+
+ /**
* Return true if the device is in emergency sms mode, false otherwise.
*/
- boolean isInEmergencySmsMode();
+ boolean isInEmergencySmsMode();
/**
* Return the modem radio power state for slot index.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
index 42cafd4..5a66e80 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
@@ -66,7 +66,7 @@
@Parameters(name = "{0}-{1}")
public static Collection<Object[]> getParams() {
int[] supportedRotations =
- {Surface.ROTATION_0, Surface.ROTATION_90, Surface.ROTATION_270};
+ {Surface.ROTATION_0, Surface.ROTATION_90};
Collection<Object[]> params = new ArrayList<>();
for (int begin : supportedRotations) {
for (int end : supportedRotations) {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java
index fc6719e..f740af9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java
@@ -25,6 +25,7 @@
import org.junit.Before;
import org.junit.FixMethodOrder;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
@@ -62,6 +63,7 @@
.forAllEntries());
}
+ @Ignore("Flaky")
@Test
public void checkVisibility_imeLayerBecomesInvisible() {
checkResults(result -> LayersTraceSubject.assertThat(result)
@@ -71,6 +73,7 @@
.forAllEntries());
}
+ @Ignore("Flaky")
@Test
public void checkVisibility_imeAppLayerBecomesInvisible() {
checkResults(result -> LayersTraceSubject.assertThat(result)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java
index 8559cb9..37d7c4c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java
@@ -69,7 +69,7 @@
@Parameters(name = "{0}")
public static Collection<Object[]> getParams() {
int[] supportedRotations =
- {Surface.ROTATION_0, Surface.ROTATION_90, Surface.ROTATION_270};
+ {Surface.ROTATION_0, Surface.ROTATION_90};
Collection<Object[]> params = new ArrayList<>();
ArrayList<Intent> testIntents = new ArrayList<>();
@@ -112,7 +112,7 @@
super.runTransition(
changeAppRotation(mIntent, intentId, InstrumentationRegistry.getContext(),
- mUiDevice, mBeginRotation, mEndRotation).repeat(5).build());
+ mUiDevice, mBeginRotation, mEndRotation).build());
}
@Test
diff --git a/tests/PlatformCompatGating/Android.bp b/tests/PlatformCompatGating/Android.bp
index 5e9ef8e..609896e 100644
--- a/tests/PlatformCompatGating/Android.bp
+++ b/tests/PlatformCompatGating/Android.bp
@@ -18,7 +18,6 @@
name: "PlatformCompatGating",
// Only compile source java files in this apk.
srcs: ["src/**/*.java"],
- certificate: "platform",
libs: [
"android.test.runner",
"android.test.base",
diff --git a/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
index 932ec64..c00aa2a 100644
--- a/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
+++ b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
@@ -16,7 +16,9 @@
package android.compat.testing;
+import android.Manifest;
import android.app.Instrumentation;
+import android.app.UiAutomation;
import android.compat.Compatibility;
import android.compat.Compatibility.ChangeConfig;
import android.content.Context;
@@ -83,12 +85,16 @@
@Override
public void evaluate() throws Throwable {
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ UiAutomation uiAutomation = instrumentation.getUiAutomation();
String packageName = instrumentation.getTargetContext().getPackageName();
IPlatformCompat platformCompat = IPlatformCompat.Stub
.asInterface(ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
if (platformCompat == null) {
throw new IllegalStateException("Could not get IPlatformCompat service!");
}
+ uiAutomation.adoptShellPermissionIdentity(
+ Manifest.permission.READ_COMPAT_CHANGE_CONFIG,
+ Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG);
Compatibility.setOverrides(mConfig);
try {
platformCompat.setOverridesForTest(new CompatibilityChangeConfig(mConfig),
@@ -101,6 +107,7 @@
} catch (RemoteException e) {
throw new RuntimeException("Could not call IPlatformCompat binder method!", e);
} finally {
+ uiAutomation.dropShellPermissionIdentity();
Compatibility.clearOverrides();
}
}
diff --git a/wifi/java/android/net/wifi/ScanResult.aidl b/wifi/java/android/net/wifi/ScanResult.aidl
index bb66722..b30689c 100644
--- a/wifi/java/android/net/wifi/ScanResult.aidl
+++ b/wifi/java/android/net/wifi/ScanResult.aidl
@@ -16,4 +16,4 @@
package android.net.wifi;
-parcelable ScanResult;
+@JavaOnlyStableParcelable parcelable ScanResult;
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 2901bd8..2d0942d 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -16,13 +16,16 @@
package android.net.wifi;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
+import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -433,58 +436,100 @@
@UnsupportedAppUsage
public List<String> anqpLines;
- /** information elements from beacon
- * @hide
+ /**
+ * information elements from beacon.
*/
public static class InformationElement {
+ /** @hide */
@UnsupportedAppUsage
public static final int EID_SSID = 0;
+ /** @hide */
@UnsupportedAppUsage
public static final int EID_SUPPORTED_RATES = 1;
+ /** @hide */
@UnsupportedAppUsage
public static final int EID_TIM = 5;
+ /** @hide */
@UnsupportedAppUsage
public static final int EID_BSS_LOAD = 11;
+ /** @hide */
@UnsupportedAppUsage
public static final int EID_ERP = 42;
+ /** @hide */
public static final int EID_HT_CAPABILITIES = 45;
+ /** @hide */
@UnsupportedAppUsage
public static final int EID_RSN = 48;
+ /** @hide */
@UnsupportedAppUsage
public static final int EID_EXTENDED_SUPPORTED_RATES = 50;
+ /** @hide */
@UnsupportedAppUsage
public static final int EID_HT_OPERATION = 61;
+ /** @hide */
@UnsupportedAppUsage
public static final int EID_INTERWORKING = 107;
+ /** @hide */
@UnsupportedAppUsage
public static final int EID_ROAMING_CONSORTIUM = 111;
+ /** @hide */
@UnsupportedAppUsage
public static final int EID_EXTENDED_CAPS = 127;
+ /** @hide */
public static final int EID_VHT_CAPABILITIES = 191;
+ /** @hide */
@UnsupportedAppUsage
public static final int EID_VHT_OPERATION = 192;
+ /** @hide */
@UnsupportedAppUsage
public static final int EID_VSA = 221;
+ /** @hide */
@UnsupportedAppUsage
public int id;
+ /** @hide */
@UnsupportedAppUsage
public byte[] bytes;
+ /** @hide */
public InformationElement() {
}
- public InformationElement(InformationElement rhs) {
+ public InformationElement(@NonNull InformationElement rhs) {
this.id = rhs.id;
this.bytes = rhs.bytes.clone();
}
+
+ /**
+ * The element ID of the information element. Defined in the IEEE 802.11-2016 spec
+ * Table 9-77.
+ */
+ public int getId() {
+ return id;
+ }
+
+ /**
+ * Get the specific content of the information element.
+ */
+ @NonNull
+ public ByteBuffer getBytes() {
+ return ByteBuffer.wrap(bytes).asReadOnlyBuffer();
+ }
}
- /** information elements found in the beacon
+ /**
+ * information elements found in the beacon.
* @hide
*/
@UnsupportedAppUsage
public InformationElement[] informationElements;
+ /**
+ * Get all information elements found in the beacon.
+ */
+ @NonNull
+ public List<InformationElement> getInformationElements() {
+ return Collections.unmodifiableList(Arrays.asList(informationElements));
+ }
/** ANQP response elements.
* @hide
@@ -604,8 +649,8 @@
this.wifiSsid = wifiSsid;
}
- /** copy constructor {@hide} */
- public ScanResult(ScanResult source) {
+ /** copy constructor */
+ public ScanResult(@NonNull ScanResult source) {
if (source != null) {
wifiSsid = source.wifiSsid;
SSID = source.SSID;
@@ -759,9 +804,8 @@
}
}
- /** Implement the Parcelable interface {@hide} */
- @UnsupportedAppUsage
- public static final @android.annotation.NonNull Creator<ScanResult> CREATOR =
+ /** Implement the Parcelable interface */
+ public static final @NonNull Creator<ScanResult> CREATOR =
new Creator<ScanResult>() {
public ScanResult createFromParcel(Parcel in) {
WifiSsid wifiSsid = null;