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;