Merge "Add  QUERY_ALL_PACKAGES permission to VpnDialogs"
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 3d28bf8..9047df5 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -148,8 +148,8 @@
     args: metalava_framework_docs_args,
     check_api: {
         current: {
-            api_file: "non-updatable-api/current.txt",
-            removed_api_file: "non-updatable-api/removed.txt",
+            api_file: "core/api/current.txt",
+            removed_api_file: "core/api/removed.txt",
         },
         last_released: {
             api_file: ":android-non-updatable.api.public.latest",
@@ -208,8 +208,8 @@
     args: metalava_framework_docs_args + priv_apps,
     check_api: {
         current: {
-            api_file: "non-updatable-api/system-current.txt",
-            removed_api_file: "non-updatable-api/system-removed.txt",
+            api_file: "core/api/system-current.txt",
+            removed_api_file: "core/api/system-removed.txt",
         },
         last_released: {
             api_file: ":android-non-updatable.api.system.latest",
@@ -219,7 +219,7 @@
         api_lint: {
             enabled: true,
             new_since: ":android-non-updatable.api.system.latest",
-            baseline_file: "non-updatable-api/system-lint-baseline.txt",
+            baseline_file: "core/api/system-lint-baseline.txt",
         },
     },
 }
@@ -264,8 +264,8 @@
     args: metalava_framework_docs_args + priv_apps + module_libs,
     check_api: {
         current: {
-            api_file: "non-updatable-api/module-lib-current.txt",
-            removed_api_file: "non-updatable-api/module-lib-removed.txt",
+            api_file: "core/api/module-lib-current.txt",
+            removed_api_file: "core/api/module-lib-removed.txt",
         },
         last_released: {
             api_file: ":android-non-updatable.api.module-lib.latest",
diff --git a/api/current.txt b/api/current.txt
index 19c3138..c2e75cd 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -48321,7 +48321,9 @@
     method @Deprecated public String iccTransmitApduBasicChannel(int, int, int, int, int, String);
     method @Deprecated public String iccTransmitApduLogicalChannel(int, int, int, int, int, int, String);
     method public boolean isConcurrentVoiceAndDataSupported();
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE, "android.permission.READ_PRIVILEGED_PHONE_STATE"}) public boolean isDataConnectionAllowed();
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean isDataEnabled();
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataEnabledForReason(int);
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataRoamingEnabled();
     method public boolean isEmergencyNumber(@NonNull String);
     method public boolean isHearingAidCompatibilitySupported();
@@ -48342,7 +48344,8 @@
     method @Deprecated public String sendEnvelopeWithStatus(String);
     method @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void sendUssdRequest(String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
     method public void sendVisualVoicemailSms(String, int, String, android.app.PendingIntent);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(boolean);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabledForReason(int, boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setForbiddenPlmns(@NonNull java.util.List<java.lang.String>);
     method public boolean setLine1NumberForDisplay(String, String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setNetworkSelectionModeAutomatic();
@@ -48390,6 +48393,10 @@
     field public static final int DATA_CONNECTING = 1; // 0x1
     field public static final int DATA_DISCONNECTED = 0; // 0x0
     field public static final int DATA_DISCONNECTING = 4; // 0x4
+    field public static final int DATA_ENABLED_REASON_CARRIER = 2; // 0x2
+    field public static final int DATA_ENABLED_REASON_POLICY = 1; // 0x1
+    field public static final int DATA_ENABLED_REASON_THERMAL = 3; // 0x3
+    field public static final int DATA_ENABLED_REASON_USER = 0; // 0x0
     field public static final int DATA_SUSPENDED = 3; // 0x3
     field public static final int DATA_UNKNOWN = -1; // 0xffffffff
     field public static final String EXTRA_ACTIVE_SIM_SUPPORTED_COUNT = "android.telephony.extra.ACTIVE_SIM_SUPPORTED_COUNT";
diff --git a/api/system-current.txt b/api/system-current.txt
index 0104ca2..5ea8e43 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -8992,6 +8992,7 @@
     field public static final String NAMESPACE_PACKAGE_MANAGER_SERVICE = "package_manager_service";
     field public static final String NAMESPACE_PERMISSIONS = "permissions";
     field public static final String NAMESPACE_PRIVACY = "privacy";
+    field public static final String NAMESPACE_PROFCOLLECT_NATIVE_BOOT = "profcollect_native_boot";
     field public static final String NAMESPACE_ROLLBACK = "rollback";
     field public static final String NAMESPACE_ROLLBACK_BOOT = "rollback_boot";
     field public static final String NAMESPACE_RUNTIME = "runtime";
@@ -11247,7 +11248,6 @@
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAnyRadioPoweredOn();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApnMetered(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApplicationOnUicc(int);
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataConnectionAllowed();
     method public boolean isDataConnectivityPossible();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled();
@@ -11280,7 +11280,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAllowedNetworkTypes(long);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCallForwarding(@NonNull android.telephony.CallForwardingInfo, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCallWaitingEnabled(boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
diff --git a/api/test-current.txt b/api/test-current.txt
index 93f9e2c..9c51729 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -876,6 +876,14 @@
     field public static final String SAMPLE_RATE = "android.media.audiotrack.sampleRate";
   }
 
+  public abstract class Image implements java.lang.AutoCloseable {
+    ctor protected Image();
+  }
+
+  public abstract static class Image.Plane {
+    ctor protected Image.Plane();
+  }
+
   public final class MediaCas implements java.lang.AutoCloseable {
     method public void forceResourceLost();
   }
diff --git a/non-updatable-api/Android.bp b/core/api/Android.bp
similarity index 100%
rename from non-updatable-api/Android.bp
rename to core/api/Android.bp
diff --git a/non-updatable-api/current.txt b/core/api/current.txt
similarity index 99%
rename from non-updatable-api/current.txt
rename to core/api/current.txt
index 4a44904..ab0aec7 100644
--- a/non-updatable-api/current.txt
+++ b/core/api/current.txt
@@ -46489,7 +46489,9 @@
     method @Deprecated public String iccTransmitApduBasicChannel(int, int, int, int, int, String);
     method @Deprecated public String iccTransmitApduLogicalChannel(int, int, int, int, int, int, String);
     method public boolean isConcurrentVoiceAndDataSupported();
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE, "android.permission.READ_PRIVILEGED_PHONE_STATE"}) public boolean isDataConnectionAllowed();
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean isDataEnabled();
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataEnabledForReason(int);
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataRoamingEnabled();
     method public boolean isEmergencyNumber(@NonNull String);
     method public boolean isHearingAidCompatibilitySupported();
@@ -46510,7 +46512,8 @@
     method @Deprecated public String sendEnvelopeWithStatus(String);
     method @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void sendUssdRequest(String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
     method public void sendVisualVoicemailSms(String, int, String, android.app.PendingIntent);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(boolean);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabledForReason(int, boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setForbiddenPlmns(@NonNull java.util.List<java.lang.String>);
     method public boolean setLine1NumberForDisplay(String, String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setNetworkSelectionModeAutomatic();
@@ -46558,6 +46561,10 @@
     field public static final int DATA_CONNECTING = 1; // 0x1
     field public static final int DATA_DISCONNECTED = 0; // 0x0
     field public static final int DATA_DISCONNECTING = 4; // 0x4
+    field public static final int DATA_ENABLED_REASON_CARRIER = 2; // 0x2
+    field public static final int DATA_ENABLED_REASON_POLICY = 1; // 0x1
+    field public static final int DATA_ENABLED_REASON_THERMAL = 3; // 0x3
+    field public static final int DATA_ENABLED_REASON_USER = 0; // 0x0
     field public static final int DATA_SUSPENDED = 3; // 0x3
     field public static final int DATA_UNKNOWN = -1; // 0xffffffff
     field public static final String EXTRA_ACTIVE_SIM_SUPPORTED_COUNT = "android.telephony.extra.ACTIVE_SIM_SUPPORTED_COUNT";
diff --git a/non-updatable-api/module-lib-current.txt b/core/api/module-lib-current.txt
similarity index 100%
rename from non-updatable-api/module-lib-current.txt
rename to core/api/module-lib-current.txt
diff --git a/non-updatable-api/module-lib-removed.txt b/core/api/module-lib-removed.txt
similarity index 100%
rename from non-updatable-api/module-lib-removed.txt
rename to core/api/module-lib-removed.txt
diff --git a/non-updatable-api/removed.txt b/core/api/removed.txt
similarity index 100%
rename from non-updatable-api/removed.txt
rename to core/api/removed.txt
diff --git a/non-updatable-api/system-current.txt b/core/api/system-current.txt
similarity index 99%
rename from non-updatable-api/system-current.txt
rename to core/api/system-current.txt
index 95fc152..7db113d 100644
--- a/non-updatable-api/system-current.txt
+++ b/core/api/system-current.txt
@@ -7883,6 +7883,7 @@
     field public static final String NAMESPACE_PACKAGE_MANAGER_SERVICE = "package_manager_service";
     field public static final String NAMESPACE_PERMISSIONS = "permissions";
     field public static final String NAMESPACE_PRIVACY = "privacy";
+    field public static final String NAMESPACE_PROFCOLLECT_NATIVE_BOOT = "profcollect_native_boot";
     field public static final String NAMESPACE_ROLLBACK = "rollback";
     field public static final String NAMESPACE_ROLLBACK_BOOT = "rollback_boot";
     field public static final String NAMESPACE_RUNTIME = "runtime";
@@ -10129,7 +10130,6 @@
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAnyRadioPoweredOn();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApnMetered(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApplicationOnUicc(int);
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataConnectionAllowed();
     method public boolean isDataConnectivityPossible();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled();
@@ -10162,7 +10162,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAllowedNetworkTypes(long);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCallForwarding(@NonNull android.telephony.CallForwardingInfo, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCallWaitingEnabled(boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
diff --git a/non-updatable-api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt
similarity index 100%
rename from non-updatable-api/system-lint-baseline.txt
rename to core/api/system-lint-baseline.txt
diff --git a/non-updatable-api/system-removed.txt b/core/api/system-removed.txt
similarity index 100%
rename from non-updatable-api/system-removed.txt
rename to core/api/system-removed.txt
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 69b77a9..0d5bb11 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1111,9 +1111,30 @@
     /** @hide */
     public static final int OP_NO_ISOLATED_STORAGE = AppProtoEnums.APP_OP_NO_ISOLATED_STORAGE;
 
+    /**
+     * Reserved key for 100
+     *
+     * @hide
+     */
+    public static final int OP_RESERVED_100 = 100;
+
+    /**
+     * Reserved key for 101
+     *
+     * @hide
+     */
+    public static final int OP_RESERVED_101 = 101;
+
+    /**
+     * Reserved key for 102
+     *
+     * @hide
+     */
+    public static final int OP_RESERVED_102 = 102;
+
     /** @hide */
     @UnsupportedAppUsage
-    public static final int _NUM_OP = 100;
+    public static final int _NUM_OP = 103;
 
     /** Access to coarse location information. */
     public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -1430,6 +1451,27 @@
      */
     public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage";
 
+    /**
+     * Reserved for 100
+     *
+     * @hide
+     */
+    public static final String OPSTR_RESERVED_100 = "android:opstr_reserved_100";
+
+    /**
+     * Reserved for 101
+     *
+     * @hide
+     */
+    public static final String OPSTR_RESERVED_101 = "android:opstr_reserved_101";
+
+    /**
+     * Reserved for 102
+     *
+     * @hide
+     */
+    public static final String OPSTR_RESERVED_102 = "android:opstr_reserved_102";
+
     /** {@link #sAppOpsToNote} not initialized yet for this op */
     private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
     /** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
@@ -1619,6 +1661,9 @@
             OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, //AUTO_REVOKE_PERMISSIONS_IF_UNUSED
             OP_AUTO_REVOKE_MANAGED_BY_INSTALLER, //OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
             OP_NO_ISOLATED_STORAGE,             // NO_ISOLATED_STORAGE
+            OP_RESERVED_100,                    // OP_RESERVED_100
+            OP_RESERVED_101,                    // OP_RESERVED_101
+            OP_RESERVED_102,                    // OP_RESERVED_102
     };
 
     /**
@@ -1725,6 +1770,9 @@
             OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
             OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER,
             OPSTR_NO_ISOLATED_STORAGE,
+            OPSTR_RESERVED_100,
+            OPSTR_RESERVED_101,
+            OPSTR_RESERVED_102,
     };
 
     /**
@@ -1832,6 +1880,9 @@
             "AUTO_REVOKE_PERMISSIONS_IF_UNUSED",
             "AUTO_REVOKE_MANAGED_BY_INSTALLER",
             "NO_ISOLATED_STORAGE",
+            "RESERVED_100",
+            "RESERVED_101",
+            "RESERVED_102",
     };
 
     /**
@@ -1940,6 +1991,9 @@
             null, // no permission for OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
             null, // no permission for OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
             null, // no permission for OP_NO_ISOLATED_STORAGE
+            null, // OP_RESERVED_100
+            null, // OP_RESERVED_101
+            null, // OP_RESERVED_102
     };
 
     /**
@@ -2048,6 +2102,9 @@
             null, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED
             null, // AUTO_REVOKE_MANAGED_BY_INSTALLER
             null, // NO_ISOLATED_STORAGE
+            null, // OP_RESERVED_100
+            null, // OP_RESERVED_101
+            null, // OP_RESERVED_102
     };
 
     /**
@@ -2155,6 +2212,9 @@
             null, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED
             null, // AUTO_REVOKE_MANAGED_BY_INSTALLER
             null, // NO_ISOLATED_STORAGE
+            null, // OP_RESERVED_100
+            null, // OP_RESERVED_101
+            null, // OP_RESERVED_102
     };
 
     /**
@@ -2261,6 +2321,9 @@
             AppOpsManager.MODE_DEFAULT, // OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
             AppOpsManager.MODE_ALLOWED, // OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
             AppOpsManager.MODE_ERRORED, // OP_NO_ISOLATED_STORAGE
+            AppOpsManager.MODE_ERRORED, // OP_RESERVED_100
+            AppOpsManager.MODE_ERRORED, // OP_RESERVED_101
+            AppOpsManager.MODE_ERRORED, // OP_RESERVED_102
     };
 
     /**
@@ -2371,6 +2434,9 @@
             false, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED
             false, // AUTO_REVOKE_MANAGED_BY_INSTALLER
             true, // NO_ISOLATED_STORAGE
+            false, // OP_RESERVED_100
+            false, // OP_RESERVED_101
+            false, // OP_RESERVED_102
     };
 
     /**
diff --git a/core/java/android/app/backup/OWNERS b/core/java/android/app/backup/OWNERS
index 9c21e8f..7e7710b 100644
--- a/core/java/android/app/backup/OWNERS
+++ b/core/java/android/app/backup/OWNERS
@@ -1,9 +1,4 @@
-alsutton@google.com
-anniemeng@google.com
-brufino@google.com
-bryanmawhinney@google.com
-ctate@google.com
-jorlow@google.com
-nathch@google.com
-rthakohov@google.com
+# Bug component: 656484
+
+include platform/frameworks/base/services/backup:/OWNERS
 
diff --git a/core/java/android/content/pm/OWNERS b/core/java/android/content/pm/OWNERS
new file mode 100644
index 0000000..a16bb4f
--- /dev/null
+++ b/core/java/android/content/pm/OWNERS
@@ -0,0 +1 @@
+per-file PackageParser.java = chiuwinson@google.com
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 0adb66c..a30a652 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -143,8 +143,14 @@
  * <li>All installations must contain a single base APK.
  * </ul>
  *
+ * @deprecated This class is mostly unused and no new changes should be added to it. Use
+ * {@link android.content.pm.parsing.ParsingPackageUtils} and related parsing v2 infrastructure in
+ * the core/services parsing subpackages. Or for a quick parse of a provided APK, use
+ * {@link PackageManager#getPackageArchiveInfo(String, int)}.
+ *
  * @hide
  */
+@Deprecated
 public class PackageParser {
 
     public static final boolean DEBUG_JAR = false;
diff --git a/core/java/android/content/pm/parsing/OWNERS b/core/java/android/content/pm/parsing/OWNERS
new file mode 100644
index 0000000..8049d5c
--- /dev/null
+++ b/core/java/android/content/pm/parsing/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 36137
+
+chiuwinson@google.com
+patb@google.com
+toddke@google.com
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 000cb2a..4d67d46 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -218,6 +218,15 @@
     public static final String NAMESPACE_PACKAGE_MANAGER_SERVICE = "package_manager_service";
 
     /**
+     * Namespace for features related to the Profcollect native Service.
+     * These features are applied at reboot.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_PROFCOLLECT_NATIVE_BOOT = "profcollect_native_boot";
+
+    /**
      * Namespace for Rollback flags that are applied immediately.
      *
      * @hide
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index e4ba87c..f08756a 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -218,6 +218,7 @@
     public static final int KM_ERROR_MISSING_MIN_MAC_LENGTH = -58;
     public static final int KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH = -59;
     public static final int KM_ERROR_CANNOT_ATTEST_IDS = -66;
+    public static final int KM_ERROR_HARDWARE_TYPE_UNAVAILABLE = -68;
     public static final int KM_ERROR_DEVICE_LOCKED = -72;
     public static final int KM_ERROR_UNIMPLEMENTED = -100;
     public static final int KM_ERROR_VERSION_MISMATCH = -101;
@@ -265,6 +266,8 @@
         sErrorCodeToString.put(KM_ERROR_INVALID_MAC_LENGTH,
                 "Invalid MAC or authentication tag length");
         sErrorCodeToString.put(KM_ERROR_CANNOT_ATTEST_IDS, "Unable to attest device ids");
+        sErrorCodeToString.put(KM_ERROR_HARDWARE_TYPE_UNAVAILABLE, "Requested security level "
+                        + "(likely Strongbox) is not available.");
         sErrorCodeToString.put(KM_ERROR_DEVICE_LOCKED, "Device locked");
         sErrorCodeToString.put(KM_ERROR_UNIMPLEMENTED, "Not implemented");
         sErrorCodeToString.put(KM_ERROR_UNKNOWN_ERROR, "Unknown error");
diff --git a/core/proto/android/app/enums.proto b/core/proto/android/app/enums.proto
index bd5cb62..98ba029 100644
--- a/core/proto/android/app/enums.proto
+++ b/core/proto/android/app/enums.proto
@@ -207,4 +207,7 @@
     APP_OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = 97;
     APP_OP_AUTO_REVOKE_MANAGED_BY_INSTALLER = 98;
     APP_OP_NO_ISOLATED_STORAGE = 99;
+    APP_OP_RESERVED_100 = 100;
+    APP_OP_RESERVED_101 = 101;
+    APP_OP_RESERVED_102 = 102;
 }
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 781bb2a..4548f3a 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1671,7 +1671,7 @@
          to be explicitly declared in this resource to be enabled.
              * SDK level 28 makes the following algorithms mandatory : "cbc(aes)", "hmac(md5)",
                "hmac(sha1)", "hmac(sha256)", "hmac(sha384)", "hmac(sha512)", "rfc4106(gcm(aes))"
-             * SDK level 30 makes the following algorithms mandatory : "rfc3686(ctr(aes))",
+             * SDK level 31 makes the following algorithms mandatory : "rfc3686(ctr(aes))",
                "xcbc(aes)", "rfc7539esp(chacha20,poly1305)"
      -->
     <string-array name="config_optionalIpSecAlgorithms" translatable="false">
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index f53a7dc..2162b8a 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -48,18 +48,38 @@
 
     public static final String INSTALL_AS_USER_ACTION = "android.credentials.INSTALL_AS_USER";
 
-    /** Key prefix for CA certificates. */
+    /**
+     * Key prefix for CA certificates.
+     *
+     * @deprecated Keystore no longer supports unstructured blobs. Public certificates are
+     *             stored in typed slots associated with a given alias.
+     */
+    @Deprecated
     public static final String CA_CERTIFICATE = "CACERT_";
 
-    /** Key prefix for user certificates. */
+    /**
+     * Key prefix for user certificates.
+     *
+     * @deprecated Keystore no longer supports unstructured blobs. Public certificates are
+     *             stored in typed slots associated with a given alias.
+     */
+    @Deprecated
     public static final String USER_CERTIFICATE = "USRCERT_";
 
-    /** Key prefix for user private and secret keys. */
+    /**
+     * Key prefix for user private and secret keys.
+     *
+     * @deprecated Keystore no longer uses alias prefixes to discriminate between entry types.
+     */
+    @Deprecated
     public static final String USER_PRIVATE_KEY = "USRPKEY_";
 
-    /** Key prefix for user secret keys.
-     *  @deprecated use {@code USER_PRIVATE_KEY} for this category instead.
+    /**
+     * Key prefix for user secret keys.
+     *
+     * @deprecated use {@code USER_PRIVATE_KEY} for this category instead.
      */
+    @Deprecated
     public static final String USER_SECRET_KEY = "USRSKEY_";
 
     /** Key prefix for VPN. */
@@ -71,7 +91,13 @@
     /** Key prefix for WIFI. */
     public static final String WIFI = "WIFI_";
 
-    /** Key prefix for App Source certificates. */
+    /**
+     * Key prefix for App Source certificates.
+     *
+     * @deprecated This was intended for FS-verity but never used. FS-verity is not
+     *             going to use this constant moving forward.
+     */
+    @Deprecated
     public static final String APP_SOURCE_CERTIFICATE = "FSV_";
 
     /** Key containing suffix of lockdown VPN profile. */
@@ -149,6 +175,7 @@
         pw.close();
         return bao.toByteArray();
     }
+
     /**
      * Convert objects from PEM format, which is used for
      * CA_CERTIFICATE and USER_CERTIFICATE entries.
@@ -166,7 +193,8 @@
             PemObject o;
             while ((o = pr.readPemObject()) != null) {
                 if (o.getType().equals("CERTIFICATE")) {
-                    Certificate c = cf.generateCertificate(new ByteArrayInputStream(o.getContent()));
+                    Certificate c = cf.generateCertificate(
+                            new ByteArrayInputStream(o.getContent()));
                     result.add((X509Certificate) c);
                 } else {
                     throw new IllegalArgumentException("Unknown type " + o.getType());
diff --git a/keystore/java/android/security/KeyPairGeneratorSpec.java b/keystore/java/android/security/KeyPairGeneratorSpec.java
index d5b34c4..1c1c2ee 100644
--- a/keystore/java/android/security/KeyPairGeneratorSpec.java
+++ b/keystore/java/android/security/KeyPairGeneratorSpec.java
@@ -16,9 +16,9 @@
 
 package android.security;
 
-import android.app.KeyguardManager;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.KeyguardManager;
 import android.content.Context;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
@@ -78,8 +78,6 @@
 
     private final Date mEndDate;
 
-    private final int mFlags;
-
     /**
      * Parameter specification for the "{@code AndroidKeyPairGenerator}"
      * instance of the {@link java.security.KeyPairGenerator} API. The
@@ -144,7 +142,6 @@
         mSerialNumber = serialNumber;
         mStartDate = startDate;
         mEndDate = endDate;
-        mFlags = flags;
     }
 
     /**
@@ -229,7 +226,7 @@
      * @hide
      */
     public int getFlags() {
-        return mFlags;
+        return 0;
     }
 
     /**
@@ -243,9 +240,15 @@
      * screen after boot.
      *
      * @see KeyguardManager#isDeviceSecure()
+     *
+     * @deprecated Encryption at rest is on by default. If extra binding to the lockscreen screen
+     *             credential is desired use
+     *             {@link KeyGenParameterSpec.Builder#setUserAuthenticationRequired(boolean)}.
+     *             This flag will be ignored from Android S.
      */
+    @Deprecated
     public boolean isEncryptionRequired() {
-        return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
+        return false;
     }
 
     /**
@@ -292,8 +295,6 @@
 
         private Date mEndDate;
 
-        private int mFlags;
-
         /**
          * Creates a new instance of the {@code Builder} with the given
          * {@code context}. The {@code context} passed in may be used to pop up
@@ -431,10 +432,15 @@
          * secure lock screen after boot.
          *
          * @see KeyguardManager#isDeviceSecure()
+         *
+         * @deprecated Data at rest encryption is enabled by default. If extra binding to the
+         *             lockscreen credential is desired, use
+         *             {@link KeyGenParameterSpec.Builder#setUserAuthenticationRequired(boolean)}.
+         *             This flag will be ignored from Android S.
          */
         @NonNull
+        @Deprecated
         public Builder setEncryptionRequired() {
-            mFlags |= KeyStore.FLAG_ENCRYPTED;
             return this;
         }
 
@@ -455,7 +461,7 @@
                     mSerialNumber,
                     mStartDate,
                     mEndDate,
-                    mFlags);
+                    0);
         }
     }
 }
diff --git a/keystore/java/android/security/KeyStoreParameter.java b/keystore/java/android/security/KeyStoreParameter.java
index 66c87ed..51d29b1 100644
--- a/keystore/java/android/security/KeyStoreParameter.java
+++ b/keystore/java/android/security/KeyStoreParameter.java
@@ -48,18 +48,16 @@
  */
 @Deprecated
 public final class KeyStoreParameter implements ProtectionParameter {
-    private final int mFlags;
 
     private KeyStoreParameter(
             int flags) {
-        mFlags = flags;
     }
 
     /**
      * @hide
      */
     public int getFlags() {
-        return mFlags;
+        return 0;
     }
 
     /**
@@ -74,9 +72,16 @@
      * screen after boot.
      *
      * @see KeyguardManager#isDeviceSecure()
+     *
+     * @deprecated Data at rest encryption is enabled by default. If extra binding to the
+     *             lockscreen credential is desired, use
+     *             {@link android.security.keystore.KeyGenParameterSpec
+     *             .Builder#setUserAuthenticationRequired(boolean)}.
+     *             This flag will be ignored from Android S.
      */
+    @Deprecated
     public boolean isEncryptionRequired() {
-        return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
+        return false;
     }
 
     /**
@@ -100,7 +105,6 @@
      */
     @Deprecated
     public final static class Builder {
-        private int mFlags;
 
         /**
          * Creates a new instance of the {@code Builder} with the given
@@ -126,14 +130,15 @@
          * the user unlocks the secure lock screen after boot.
          *
          * @see KeyguardManager#isDeviceSecure()
+         *
+         * @deprecated Data at rest encryption is enabled by default. If extra binding to the
+         *             lockscreen credential is desired, use
+         *             {@link android.security.keystore.KeyGenParameterSpec
+         *             .Builder#setUserAuthenticationRequired(boolean)}.
+         *             This flag will be ignored from Android S.
          */
         @NonNull
         public Builder setEncryptionRequired(boolean required) {
-            if (required) {
-                mFlags |= KeyStore.FLAG_ENCRYPTED;
-            } else {
-                mFlags &= ~KeyStore.FLAG_ENCRYPTED;
-            }
             return this;
         }
 
@@ -145,8 +150,7 @@
          */
         @NonNull
         public KeyStoreParameter build() {
-            return new KeyStoreParameter(
-                    mFlags);
+            return new KeyStoreParameter(0 /* flags */);
         }
     }
 }
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index 79b8611..610bffe 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -17,6 +17,7 @@
 package android.media;
 
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.graphics.Rect;
 import android.hardware.HardwareBuffer;
@@ -58,6 +59,7 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @TestApi
     protected Image() {
     }
 
@@ -387,6 +389,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @TestApi
         protected Plane() {
         }
 
diff --git a/packages/SettingsProvider/src/android/provider/settings/OWNERS b/packages/SettingsProvider/src/android/provider/settings/OWNERS
index 541dd878..7e7710b 100644
--- a/packages/SettingsProvider/src/android/provider/settings/OWNERS
+++ b/packages/SettingsProvider/src/android/provider/settings/OWNERS
@@ -1,5 +1,4 @@
-# Please reach out to Android B&R when making Settings backup changes
-alsutton@google.com
-nathch@google.com
-rthakohov@google.com
+# Bug component: 656484
+
+include platform/frameworks/base/services/backup:/OWNERS
 
diff --git a/packages/SettingsProvider/test/src/android/provider/OWNERS b/packages/SettingsProvider/test/src/android/provider/OWNERS
index f3241ea..7e7710b 100644
--- a/packages/SettingsProvider/test/src/android/provider/OWNERS
+++ b/packages/SettingsProvider/test/src/android/provider/OWNERS
@@ -1,4 +1,4 @@
-per-file * = *
+# Bug component: 656484
 
-# Please reach out to the Android B&R team for settings backup changes
-per-file SettingsBackupTest.java = alsutton@google.com, nathch@google.com, rthakohov@google.com
+include platform/frameworks/base/services/backup:/OWNERS
+
diff --git a/services/backup/OWNERS b/services/backup/OWNERS
index 7c7e742..3c5268c 100644
--- a/services/backup/OWNERS
+++ b/services/backup/OWNERS
@@ -1,7 +1,6 @@
 # Bug component: 656484
 
 aabhinav@google.com
-alsutton@google.com
 bryanmawhinney@google.com
 jstemmer@google.com
 nathch@google.com
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index a153d41..0ee30f9 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -1589,25 +1589,20 @@
             mWakeLock.setWorkSource(mTmpWorkSource);
         }
 
-        private long delayLocked(long duration) {
+        private void delayLocked(long wakeUpTime) {
             Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "delayLocked");
             try {
-                long durationRemaining = duration;
-                if (duration > 0) {
-                    final long bedtime = duration + SystemClock.uptimeMillis();
-                    do {
-                        try {
-                            this.wait(durationRemaining);
-                        }
-                        catch (InterruptedException e) { }
-                        if (mForceStop) {
-                            break;
-                        }
-                        durationRemaining = bedtime - SystemClock.uptimeMillis();
-                    } while (durationRemaining > 0);
-                    return duration - durationRemaining;
+                long durationRemaining = wakeUpTime - SystemClock.uptimeMillis();
+                while (durationRemaining > 0) {
+                    try {
+                        this.wait(durationRemaining);
+                    }
+                    catch (InterruptedException e) { }
+                    if (mForceStop) {
+                        break;
+                    }
+                    durationRemaining = wakeUpTime - SystemClock.uptimeMillis();
                 }
-                return 0;
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
             }
@@ -1641,7 +1636,8 @@
                     final int repeat = mWaveform.getRepeatIndex();
 
                     int index = 0;
-                    long onDuration = 0;
+                    long nextStepStartTime = SystemClock.uptimeMillis();
+                    long nextVibratorStopTime = 0;
                     while (!mForceStop) {
                         if (index < len) {
                             final int amplitude = amplitudes[index];
@@ -1650,25 +1646,31 @@
                                 continue;
                             }
                             if (amplitude != 0) {
-                                if (onDuration <= 0) {
+                                long now = SystemClock.uptimeMillis();
+                                if (nextVibratorStopTime <= now) {
                                     // Telling the vibrator to start multiple times usually causes
                                     // effects to feel "choppy" because the motor resets at every on
                                     // command.  Instead we figure out how long our next "on" period
                                     // is going to be, tell the motor to stay on for the full
                                     // duration, and then wake up to change the amplitude at the
                                     // appropriate intervals.
-                                    onDuration = getTotalOnDuration(timings, amplitudes, index - 1,
-                                            repeat);
+                                    long onDuration = getTotalOnDuration(
+                                            timings, amplitudes, index - 1, repeat);
                                     doVibratorOn(onDuration, amplitude, mUid, mAttrs);
+                                    nextVibratorStopTime = now + onDuration;
                                 } else {
+                                    // Vibrator is already ON, so just change its amplitude.
                                     doVibratorSetAmplitude(amplitude);
                                 }
                             }
 
-                            long waitTime = delayLocked(duration);
-                            if (amplitude != 0) {
-                                onDuration -= waitTime;
-                            }
+                            // We wait until the time this waveform step was supposed to end,
+                            // calculated from the time it was supposed to start. All start times
+                            // are calculated from the waveform original start time by adding the
+                            // input durations. Any scheduling or processing delay should not affect
+                            // this step's perceived total duration. They will be amortized here.
+                            nextStepStartTime += duration;
+                            delayLocked(nextStepStartTime);
                         } else if (repeat < 0) {
                             break;
                         } else {
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 60e59e3..28afcbb 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -85,6 +85,7 @@
         DeviceConfig.NAMESPACE_INTELLIGENCE_CONTENT_SUGGESTIONS,
         DeviceConfig.NAMESPACE_MEDIA_NATIVE,
         DeviceConfig.NAMESPACE_NETD_NATIVE,
+        DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT,
         DeviceConfig.NAMESPACE_RUNTIME_NATIVE,
         DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT,
         DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 2991339..8be24a6 100755
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -3987,7 +3987,7 @@
     /** @see AudioManager#playSoundEffect(int, float) */
     public void playSoundEffectVolume(int effectType, float volume) {
         // do not try to play the sound effect if the system stream is muted
-        if (isStreamMutedByRingerOrZenMode(STREAM_SYSTEM)) {
+        if (isStreamMute(STREAM_SYSTEM)) {
             return;
         }
 
diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java
index bc3bff1..ff31931 100644
--- a/services/core/java/com/android/server/compat/CompatChange.java
+++ b/services/core/java/com/android/server/compat/CompatChange.java
@@ -18,7 +18,7 @@
 
 import android.annotation.Nullable;
 import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledAfter;
+import android.compat.annotation.EnabledSince;
 import android.content.pm.ApplicationInfo;
 
 import com.android.internal.compat.CompatibilityChangeInfo;
@@ -43,8 +43,8 @@
      * A change ID to be used only in the CTS test for this SystemApi
      */
     @ChangeId
-    @EnabledAfter(targetSdkVersion = 1234) // Needs to be > test APK targetSdkVersion.
-    private static final long CTS_SYSTEM_API_CHANGEID = 149391281; // This is a bug id.
+    @EnabledSince(targetSdkVersion = 1235) // Needs to be > test APK targetSdkVersion.
+    static final long CTS_SYSTEM_API_CHANGEID = 149391281; // This is a bug id.
 
     /**
      * Callback listener for when compat changes are updated for a package.
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 38664fe..2c19a2d 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -375,6 +375,9 @@
         if (change.getLoggingOnly()) {
             return false;
         }
+        if (change.getId() == CompatChange.CTS_SYSTEM_API_CHANGEID) {
+            return false;
+        }
         if (change.getEnableSinceTargetSdk() > 0) {
             if (change.getEnableSinceTargetSdk() < sMinTargetSdk
                     || change.getEnableSinceTargetSdk() > sMaxTargetSdk) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
index 7d76628..66d9f60 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
@@ -123,6 +123,14 @@
                 new RecordStatusInfoValidator(), DEST_DIRECT);
 
         // TODO: Handle messages for the Timer Programming.
+        addValidationInfo(
+                Constants.MESSAGE_CLEAR_ANALOG_TIMER, new AnalogueTimerValidator(), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_CLEAR_EXTERNAL_TIMER, new ExternalTimerValidator(), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_SET_ANALOG_TIMER, new AnalogueTimerValidator(), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_SET_EXTERNAL_TIMER, new ExternalTimerValidator(), DEST_DIRECT);
 
         // Messages for the System Information.
         FixedLengthValidator oneByteValidator = new FixedLengthValidator(1);
@@ -343,6 +351,148 @@
         return true;
     }
 
+    /**
+     * Check if the given value is a valid day of month. A valid value is one which falls within the
+     * range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value day of month
+     * @return true if the day of month is valid
+     */
+    private boolean isValidDayOfMonth(int value) {
+        return isWithinRange(value, 1, 31);
+    }
+
+    /**
+     * Check if the given value is a valid month of year. A valid value is one which falls within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value month of year
+     * @return true if the month of year is valid
+     */
+    private boolean isValidMonthOfYear(int value) {
+        return isWithinRange(value, 1, 12);
+    }
+
+    /**
+     * Check if the given value is a valid hour. A valid value is one which falls within the range
+     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value hour
+     * @return true if the hour is valid
+     */
+    private boolean isValidHour(int value) {
+        return isWithinRange(value, 0, 23);
+    }
+
+    /**
+     * Check if the given value is a valid minute. A valid value is one which falls within the range
+     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value minute
+     * @return true if the minute is valid
+     */
+    private boolean isValidMinute(int value) {
+        return isWithinRange(value, 0, 59);
+    }
+
+    /**
+     * Check if the given value is a valid duration hours. A valid value is one which falls within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value duration hours
+     * @return true if the duration hours is valid
+     */
+    private boolean isValidDurationHours(int value) {
+        return isWithinRange(value, 0, 99);
+    }
+
+    /**
+     * Check if the given value is a valid recording sequence. A valid value is adheres to range
+     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value recording sequence
+     * @return true if the given recording sequence is valid
+     */
+    private boolean isValidRecordingSequence(int value) {
+        value = value & 0xFF;
+        // Validate bit 7 is set to zero
+        if ((value & 0x80) != 0x00) {
+            return false;
+        }
+        // Validate than not more than one bit is set
+        return (Integer.bitCount(value) <= 1);
+    }
+
+    /**
+     * Check if the given value is a valid analogue broadcast type. A valid value is one which falls
+     * within the range description defined in CEC 1.4 Specification : Operand Descriptions (Section
+     * 17)
+     *
+     * @param value analogue broadcast type
+     * @return true if the analogue broadcast type is valid
+     */
+    private boolean isValidAnalogueBroadcastType(int value) {
+        return isWithinRange(value, 0x00, 0x02);
+    }
+
+    /**
+     * Check if the given value is a valid analogue frequency. A valid value is one which falls
+     * within the range description defined in CEC 1.4 Specification : Operand Descriptions (Section
+     * 17)
+     *
+     * @param value analogue frequency
+     * @return true if the analogue frequency is valid
+     */
+    private boolean isValidAnalogueFrequency(int value) {
+        value = value & 0xFFFF;
+        return (value != 0x000 && value != 0xFFFF);
+    }
+
+    /**
+     * Check if the given value is a valid broadcast system. A valid value is one which falls within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value broadcast system
+     * @return true if the broadcast system is valid
+     */
+    private boolean isValidBroadcastSystem(int value) {
+        return isWithinRange(value, 0, 31);
+    }
+
+    /**
+     * Check if the given value is a valid External Plug. A valid value is one which falls within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value External Plug
+     * @return true if the External Plug is valid
+     */
+    private boolean isValidExternalPlug(int value) {
+        return isWithinRange(value, 1, 255);
+    }
+
+    /**
+     * Check if the given value is a valid External Source. A valid value is one which falls within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value External Source Specifier
+     * @return true if the External Source is valid
+     */
+    private boolean isValidExternalSource(byte[] params, int offset) {
+        int externalSourceSpecifier = params[offset];
+        offset = offset + 1;
+        if (externalSourceSpecifier == 0x04) {
+            // External Plug
+            return isValidExternalPlug(params[offset]);
+        } else if (externalSourceSpecifier == 0x05) {
+            // External Physical Address
+            // Validate it contains 2 bytes Physical Address
+            if (params.length - offset >= 2) {
+                return isValidPhysicalAddress(params, offset);
+            }
+        }
+        return false;
+    }
+
     private class PhysicalAddressValidator implements ParameterValidator {
         @Override
         public int isValid(byte[] params) {
@@ -472,4 +622,53 @@
             return toErrorCode(isWithinRange(params[0], mMinValue, mMaxValue));
         }
     }
+
+    /**
+     * Check if the given Analogue Timer message parameters are valid. Valid parameters should
+     * adhere to message description of Analogue Timer defined in CEC 1.4 Specification : Message
+     * Descriptions for Timer Programming Feature (CEC Table 12)
+     */
+    private class AnalogueTimerValidator implements ParameterValidator {
+        @Override
+        public int isValid(byte[] params) {
+            if (params.length < 11) {
+                return ERROR_PARAMETER_SHORT;
+            }
+            return toErrorCode(
+                    isValidDayOfMonth(params[0]) // Day of Month
+                            && isValidMonthOfYear(params[1]) // Month of Year
+                            && isValidHour(params[2]) // Start Time - Hour
+                            && isValidMinute(params[3]) // Start Time - Minute
+                            && isValidDurationHours(params[4]) // Duration - Duration Hours
+                            && isValidMinute(params[5]) // Duration - Minute
+                            && isValidRecordingSequence(params[6]) // Recording Sequence
+                            && isValidAnalogueBroadcastType(params[7]) // Analogue Broadcast Type
+                            && isValidAnalogueFrequency(
+                                    HdmiUtils.twoBytesToInt(params, 8)) // Analogue Frequency
+                            && isValidBroadcastSystem(params[10])); // Broadcast System
+        }
+    }
+
+    /**
+     * Check if the given External Timer message parameters are valid. Valid parameters should
+     * adhere to message description of External Timer defined in CEC 1.4 Specification : Message
+     * Descriptions for Timer Programming Feature (CEC Table 12)
+     */
+    private class ExternalTimerValidator implements ParameterValidator {
+        @Override
+        public int isValid(byte[] params) {
+            if (params.length < 9) {
+                return ERROR_PARAMETER_SHORT;
+            }
+            return toErrorCode(
+                    isValidDayOfMonth(params[0]) // Day of Month
+                            && isValidMonthOfYear(params[1]) // Month of Year
+                            && isValidHour(params[2]) // Start Time - Hour
+                            && isValidMinute(params[3]) // Start Time - Minute
+                            && isValidDurationHours(params[4]) // Duration - Duration Hours
+                            && isValidMinute(params[5]) // Duration - Minute
+                            && isValidRecordingSequence(params[6]) // Recording Sequence
+                            && isValidExternalSource(params, 7)); // External Source
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index ffdcf7e..7d0457b 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -526,8 +526,9 @@
     private final SparseBooleanArray mRestrictBackgroundAllowlistRevokedUids =
             new SparseBooleanArray();
 
+    final Object mMeteredIfacesLock = new Object();
     /** Set of ifaces that are metered. */
-    @GuardedBy("mNetworkPoliciesSecondLock")
+    @GuardedBy("mMeteredIfacesLock")
     private ArraySet<String> mMeteredIfaces = new ArraySet<>();
     /** Set of over-limit templates that have been notified. */
     @GuardedBy("mNetworkPoliciesSecondLock")
@@ -1980,13 +1981,15 @@
         }
 
         // Remove quota from any interfaces that are no longer metered.
-        for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) {
-            final String iface = mMeteredIfaces.valueAt(i);
-            if (!newMeteredIfaces.contains(iface)) {
-                removeInterfaceQuotaAsync(iface);
+        synchronized (mMeteredIfacesLock) {
+            for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) {
+                final String iface = mMeteredIfaces.valueAt(i);
+                if (!newMeteredIfaces.contains(iface)) {
+                    removeInterfaceQuotaAsync(iface);
+                }
             }
+            mMeteredIfaces = newMeteredIfaces;
         }
-        mMeteredIfaces = newMeteredIfaces;
 
         final ContentResolver cr = mContext.getContentResolver();
         final boolean quotaEnabled = Settings.Global.getInt(cr,
@@ -2038,7 +2041,10 @@
             mSubscriptionOpportunisticQuota.put(subId, quotaBytes);
         }
 
-        final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]);
+        final String[] meteredIfaces;
+        synchronized (mMeteredIfacesLock) {
+            meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]);
+        }
         mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget();
 
         mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget();
@@ -3460,7 +3466,10 @@
                 fout.print("Restrict background: "); fout.println(mRestrictBackground);
                 fout.print("Restrict power: "); fout.println(mRestrictPower);
                 fout.print("Device idle: "); fout.println(mDeviceIdleMode);
-                fout.print("Metered ifaces: "); fout.println(mMeteredIfaces);
+                synchronized (mMeteredIfacesLock) {
+                    fout.print("Metered ifaces: ");
+                    fout.println(mMeteredIfaces);
+                }
 
                 fout.println();
                 fout.print("mRestrictBackgroundLowPowerMode: " + mRestrictBackgroundLowPowerMode);
@@ -4656,7 +4665,7 @@
                 }
                 case MSG_LIMIT_REACHED: {
                     final String iface = (String) msg.obj;
-                    synchronized (mNetworkPoliciesSecondLock) {
+                    synchronized (mMeteredIfacesLock) {
                         // fast return if not needed.
                         if (!mMeteredIfaces.contains(iface)) {
                             return true;
@@ -5298,7 +5307,7 @@
                 isBackgroundRestricted = mRestrictBackground;
             }
             final boolean isNetworkMetered;
-            synchronized (mNetworkPoliciesSecondLock) {
+            synchronized (mMeteredIfacesLock) {
                 isNetworkMetered = mMeteredIfaces.contains(ifname);
             }
             final boolean ret = isUidNetworkingBlockedInternal(uid, uidRules, isNetworkMetered,
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 71e7c8a..12c24d4 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -552,7 +552,8 @@
 
         //  schedule periodic pall alarm based on {@link NetworkStatsSettings#getPollInterval()}.
         final PendingIntent pollIntent =
-                PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
+                PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL),
+                        PendingIntent.FLAG_IMMUTABLE);
 
         final long currentRealtime = SystemClock.elapsedRealtime();
         mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
index 4702940..a034643 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
@@ -182,6 +182,70 @@
         assertMessageValidity("40:0A:30").isEqualTo(ERROR_PARAMETER);
     }
 
+    @Test
+    public void isValid_setAnalogueTimer_clearAnalogueTimer() {
+        assertMessageValidity("04:33:0C:08:10:1E:04:30:08:00:13:AD:06").isEqualTo(OK);
+        assertMessageValidity("04:34:04:0C:16:0F:08:37:00:02:EA:60:03:34").isEqualTo(OK);
+
+        assertMessageValidity("0F:33:0C:08:10:1E:04:30:08:00:13:AD:06")
+                .isEqualTo(ERROR_DESTINATION);
+        assertMessageValidity("F0:34:04:0C:16:0F:08:37:00:02:EA:60:03").isEqualTo(ERROR_SOURCE);
+        assertMessageValidity("04:33:0C:08:10:1E:04:30:08:13:AD:06")
+                .isEqualTo(ERROR_PARAMETER_SHORT);
+        // Out of range Day of Month
+        assertMessageValidity("04:34:20:0C:16:0F:08:37:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+        // Out of range Month of Year
+        assertMessageValidity("04:33:0C:00:10:1E:04:30:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Hour
+        assertMessageValidity("04:34:04:0C:18:0F:08:37:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Minute
+        assertMessageValidity("04:33:0C:08:10:50:04:30:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Duration Hours
+        assertMessageValidity("04:34:04:0C:16:0F:64:37:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Minute
+        assertMessageValidity("04:33:0C:08:10:1E:04:64:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("04:34:04:0C:16:0F:08:37:88:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("04:33:0C:08:10:1E:04:30:A2:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+        // Out of range Analogue Broadcast Type
+        assertMessageValidity("04:34:04:0C:16:0F:08:37:00:03:EA:60:03").isEqualTo(ERROR_PARAMETER);
+        // Out of range Analogue Frequency
+        assertMessageValidity("04:33:0C:08:10:1E:04:30:08:00:FF:FF:06").isEqualTo(ERROR_PARAMETER);
+        // Out of range Broadcast System
+        assertMessageValidity("04:34:04:0C:16:0F:08:37:00:02:EA:60:20").isEqualTo(ERROR_PARAMETER);
+    }
+
+    @Test
+    public void isValid_setExternalTimer_clearExternalTimer() {
+        assertMessageValidity("40:A1:0C:08:15:05:04:1E:02:04:20").isEqualTo(OK);
+        assertMessageValidity("40:A2:14:09:12:28:4B:19:10:05:10:00").isEqualTo(OK);
+
+        assertMessageValidity("4F:A1:0C:08:15:05:04:1E:02:04:20").isEqualTo(ERROR_DESTINATION);
+        assertMessageValidity("F4:A2:14:09:12:28:4B:19:10:05:10:00").isEqualTo(ERROR_SOURCE);
+        assertMessageValidity("40:A1:0C:08:15:05:04:1E:02:04").isEqualTo(ERROR_PARAMETER_SHORT);
+        // Out of range Day of Month
+        assertMessageValidity("40:A2:28:09:12:28:4B:19:10:05:10:00").isEqualTo(ERROR_PARAMETER);
+        // Out of range Month of Year
+        assertMessageValidity("40:A1:0C:0F:15:05:04:1E:02:04:20").isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Hour
+        assertMessageValidity("40:A2:14:09:1A:28:4B:19:10:05:10:00").isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Minute
+        assertMessageValidity("40:A1:0C:08:15:48:04:1E:02:04:20").isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Duration Hours
+        assertMessageValidity("40:A2:14:09:12:28:66:19:10:05:10:00").isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Minute
+        assertMessageValidity("40:A1:0C:08:15:05:04:3F:02:04:20").isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("40:A2:14:09:12:28:4B:19:84:05:10:00").isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("40:A1:0C:08:15:05:04:1E:14:04:20").isEqualTo(ERROR_PARAMETER);
+        // Invalid external source specifier
+        assertMessageValidity("40:A2:14:09:12:28:4B:19:10:08:10:00").isEqualTo(ERROR_PARAMETER);
+        // Invalid External PLug
+        assertMessageValidity("04:A1:0C:08:15:05:04:1E:02:04:00").isEqualTo(ERROR_PARAMETER);
+    }
+
     private IntegerSubject assertMessageValidity(String message) {
         return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message)));
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 56c2500..0e327b4 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -9160,8 +9160,10 @@
      * app has carrier privileges (see {@link #hasCarrierPrivileges}).
      *
      * @param enable Whether to enable mobile data.
+     * @deprecated use setDataEnabledForReason with reason DATA_ENABLED_REASON_USER instead.
      *
      */
+    @Deprecated
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public void setDataEnabled(boolean enable) {
@@ -9170,19 +9172,16 @@
 
     /**
      * @hide
-     * @deprecated use {@link #setDataEnabled(boolean)} instead.
+     * @deprecated use {@link #setDataEnabledForReason(int, boolean)} instead.
     */
     @SystemApi
     @Deprecated
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public void setDataEnabled(int subId, boolean enable) {
         try {
-            Log.d(TAG, "setDataEnabled: enabled=" + enable);
-            ITelephony telephony = getITelephony();
-            if (telephony != null)
-                telephony.setUserDataEnabled(subId, enable);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelephony#setUserDataEnabled", e);
+            setDataEnabledForReason(subId, DATA_ENABLED_REASON_USER, enable);
+        } catch (RuntimeException e) {
+            Log.e(TAG, "Error calling setDataEnabledForReason e:" + e);
         }
     }
 
@@ -9390,15 +9389,12 @@
     @Deprecated
     @SystemApi
     public boolean getDataEnabled(int subId) {
-        boolean retVal = false;
         try {
-            ITelephony telephony = getITelephony();
-            if (telephony != null)
-                retVal = telephony.isUserDataEnabled(subId);
-        } catch (RemoteException | NullPointerException e) {
-            Log.e(TAG, "Error calling ITelephony#isUserDataEnabled", e);
+            return isDataEnabledForReason(DATA_ENABLED_REASON_USER);
+        } catch (RuntimeException e) {
+            Log.e(TAG, "Error calling isDataEnabledForReason e:" + e);
         }
-        return retVal;
+        return false;
     }
 
     /**
@@ -10956,19 +10952,18 @@
      *
      * @param enabled control enable or disable carrier data.
      * @see #resetAllCarrierActions()
+     * @deprecated use {@link #setDataEnabledForReason(int, boolean) with
+     * reason {@link #DATA_ENABLED_REASON_CARRIER}} instead.
      * @hide
      */
+    @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public void setCarrierDataEnabled(boolean enabled) {
         try {
-            ITelephony service = getITelephony();
-            if (service != null) {
-                service.carrierActionSetMeteredApnsEnabled(
-                        getSubId(SubscriptionManager.getDefaultDataSubscriptionId()), enabled);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelephony#setCarrierDataEnabled", e);
+            setDataEnabledForReason(DATA_ENABLED_REASON_CARRIER, enabled);
+        } catch (RuntimeException e) {
+            Log.e(TAG, "Error calling setDataEnabledForReason e:" + e);
         }
     }
 
@@ -11054,21 +11049,145 @@
     /**
      * Policy control of data connection. Usually used when data limit is passed.
      * @param enabled True if enabling the data, otherwise disabling.
+     * @deprecated use {@link #setDataEnabledForReason(int, boolean) with
+     * reason {@link #DATA_ENABLED_REASON_POLICY}} instead.
      * @hide
      */
+    @Deprecated
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     public void setPolicyDataEnabled(boolean enabled) {
         try {
+            setDataEnabledForReason(DATA_ENABLED_REASON_POLICY, enabled);
+        } catch (RuntimeException e) {
+            Log.e(TAG, "Error calling setDataEnabledForReason e:" + e);
+        }
+    }
+
+    /** @hide */
+    @IntDef({
+            DATA_ENABLED_REASON_USER,
+            DATA_ENABLED_REASON_POLICY,
+            DATA_ENABLED_REASON_CARRIER,
+            DATA_ENABLED_REASON_THERMAL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DataEnabledReason{}
+
+    /**
+     * To indicate that user enabled or disabled data.
+     */
+    public static final int DATA_ENABLED_REASON_USER = 0;
+
+    /**
+     * To indicate that data control due to policy. Usually used when data limit is passed.
+     * Policy data on/off won't affect user settings but will bypass the
+     * settings and turns off data internally if set to {@code false}.
+     */
+    public static final int DATA_ENABLED_REASON_POLICY = 1;
+
+    /**
+     * To indicate enable or disable carrier data by the system based on carrier signalling or
+     * carrier privileged apps. Carrier data on/off won't affect user settings but will bypass the
+     * settings and turns off data internally if set to {@code false}.
+     */
+    public static final int DATA_ENABLED_REASON_CARRIER = 2;
+
+    /**
+     * To indicate enable or disable data by thermal service.
+     * Thermal data on/off won't affect user settings but will bypass the
+     * settings and turns off data internally if set to {@code false}.
+     */
+    public static final int DATA_ENABLED_REASON_THERMAL = 3;
+
+    /**
+     * Control of data connection and provide the reason triggering the data connection control.
+     * This can be called for following reasons
+     * <ol>
+     * <li>data limit is passed {@link #DATA_ENABLED_REASON_POLICY}
+     * <li>data disabled by carrier {@link #DATA_ENABLED_REASON_CARRIER}
+     * <li>data disabled by user {@link #DATA_ENABLED_REASON_USER}
+     * <li>data disabled due to thermal {@link #DATA_ENABLED_REASON_THERMAL}
+     * </ol>
+     * If any of the reason is off, then it will result in
+     * bypassing user preference and result in data to be turned off.
+     *
+     * <p>If this object has been created with {@link #createForSubscriptionId}, applies
+     *      to the given subId. Otherwise, applies to
+     * {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     *
+     *
+     * @param reason the reason the data enable change is taking place
+     * @param enabled True if enabling the data, otherwise disabling.
+     *
+     * <p>Requires Permission:
+     * The calling app has carrier privileges (see {@link #hasCarrierPrivileges}) if the reason is
+     * {@link #DATA_ENABLED_REASON_USER} or {@link #DATA_ENABLED_REASON_CARRIER} or the call app
+     * has {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} irrespective of
+     * the reason.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     */
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setDataEnabledForReason(@DataEnabledReason int reason, boolean enabled) {
+        setDataEnabledForReason(getSubId(), reason, enabled);
+    }
+
+    private void setDataEnabledForReason(int subId, @DataEnabledReason int reason,
+            boolean enabled) {
+        try {
             ITelephony service = getITelephony();
             if (service != null) {
-                service.setPolicyDataEnabled(enabled, getSubId());
+                service.setDataEnabledForReason(subId, reason, enabled);
+            } else {
+                throw new IllegalStateException("telephony service is null.");
             }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelephony#setPolicyDataEnabled", e);
+        } catch (RemoteException ex) {
+            Log.e(TAG, "Telephony#setDataEnabledForReason RemoteException", ex);
+            ex.rethrowFromSystemServer();
         }
     }
 
     /**
+     * Return whether data is enabled for certain reason .
+     *
+     * If {@link #isDataEnabledForReason} returns false, it means in data enablement for a
+     * specific reason is turned off. If any of the reason is off, then it will result in
+     * bypassing user preference and result in data to be turned off. Call
+     * {@link #isDataConnectionAllowed} in order to know whether
+     * data connection is allowed on the device.
+     *
+     * <p>If this object has been created with {@link #createForSubscriptionId}, applies
+     *      to the given subId. Otherwise, applies to
+     * {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     *
+     * @param reason the reason the data enable change is taking place
+     * @return whether data is enabled for a reason.
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} or
+     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     */
+    @RequiresPermission(anyOf = {android.Manifest.permission.ACCESS_NETWORK_STATE,
+            android.Manifest.permission.READ_PHONE_STATE})
+    public boolean isDataEnabledForReason(@DataEnabledReason int reason) {
+        return isDataEnabledForReason(getSubId(), reason);
+    }
+
+    private boolean isDataEnabledForReason(int subId, @DataEnabledReason int reason) {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                return service.isDataEnabledForReason(subId, reason);
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            Log.e(TAG, "Telephony#isDataEnabledForReason RemoteException", ex);
+            ex.rethrowFromSystemServer();
+        }
+        return false;
+    }
+
+    /**
      * Get Client request stats which will contain statistical information
      * on each request made by client.
      * Callers require either READ_PRIVILEGED_PHONE_STATE or
@@ -11203,10 +11322,14 @@
      *   <LI>And possibly others.</LI>
      * </UL>
      * @return {@code true} if the overall data connection is allowed; {@code false} if not.
-     * @hide
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} or
+     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE} or
+     * android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE
      */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresPermission(anyOf = {android.Manifest.permission.ACCESS_NETWORK_STATE,
+            android.Manifest.permission.READ_PHONE_STATE,
+            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE})
     public boolean isDataConnectionAllowed() {
         boolean retVal = false;
         try {
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index 94407f1..8b6dac8 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -29,12 +29,10 @@
 import android.provider.Settings;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsRcsController;
 import android.telephony.ims.feature.ImsFeature;
-import android.telephony.ims.feature.RcsFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.util.Log;
 
@@ -77,7 +75,7 @@
             "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN";
 
     /**
-     * Receives RCS availability status updates from the ImsService.
+     * Receives RCS Feature availability status updates from the ImsService.
      *
      * @see #isAvailable(int)
      * @see #registerRcsAvailabilityCallback(Executor, AvailabilityCallback)
@@ -101,8 +99,7 @@
 
                 long callingIdentity = Binder.clearCallingIdentity();
                 try {
-                    mExecutor.execute(() -> mLocalCallback.onAvailabilityChanged(
-                            new RcsFeature.RcsImsCapabilities(config)));
+                    mExecutor.execute(() -> mLocalCallback.onAvailabilityChanged(config));
                 } finally {
                     restoreCallingIdentity(callingIdentity);
                 }
@@ -137,7 +134,7 @@
          *
          * @param capabilities The new availability of the capabilities.
          */
-        public void onAvailabilityChanged(@NonNull RcsFeature.RcsImsCapabilities capabilities) {
+        public void onAvailabilityChanged(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
         }
 
         /**@hide*/
@@ -394,7 +391,7 @@
      * @hide
      */
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public boolean isCapable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+    public boolean isCapable(@RcsUceAdapter.RcsImsCapabilityFlag int capability,
             @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) throws ImsException {
         IImsRcsController imsRcsController = getIImsRcsController();
         if (imsRcsController == null) {
@@ -428,7 +425,7 @@
      * @hide
      */
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public boolean isAvailable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability)
+    public boolean isAvailable(@RcsUceAdapter.RcsImsCapabilityFlag int capability)
             throws ImsException {
         IImsRcsController imsRcsController = getIImsRcsController();
         if (imsRcsController == null) {
diff --git a/telephony/java/android/telephony/ims/RcsContactTerminatedReason.aidl b/telephony/java/android/telephony/ims/RcsContactTerminatedReason.aidl
new file mode 100644
index 0000000..cd1ee84
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsContactTerminatedReason.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2020 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.ims;
+
+parcelable RcsContactTerminatedReason;
diff --git a/telephony/java/android/telephony/ims/RcsContactTerminatedReason.java b/telephony/java/android/telephony/ims/RcsContactTerminatedReason.java
new file mode 100644
index 0000000..ee02564
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsContactTerminatedReason.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 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.ims;
+
+import android.annotation.NonNull;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * When the resource for the presence subscribe event has been terminated, the method
+ * SubscribeResponseCallback#onResourceTerminated wil be called with a list of
+ * RcsContactTerminatedReason.
+ * @hide
+ */
+public final class RcsContactTerminatedReason implements Parcelable {
+    private final Uri mContactUri;
+    private final String mReason;
+
+    public RcsContactTerminatedReason(Uri contact, String reason) {
+        mContactUri = contact;
+        mReason = reason;
+    }
+
+    private RcsContactTerminatedReason(Parcel in) {
+        mContactUri = in.readParcelable(Uri.class.getClassLoader());
+        mReason = in.readString();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeParcelable(mContactUri, flags);
+        out.writeString(mReason);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final @NonNull Creator<RcsContactTerminatedReason> CREATOR =
+            new Creator<RcsContactTerminatedReason>() {
+                @Override
+                public RcsContactTerminatedReason createFromParcel(Parcel in) {
+                    return new RcsContactTerminatedReason(in);
+                }
+
+                @Override
+                public RcsContactTerminatedReason[] newArray(int size) {
+                    return new RcsContactTerminatedReason[size];
+                }
+            };
+
+    public Uri getContactUri() {
+        return mContactUri;
+    }
+
+    public String getReason() {
+        return mReason;
+    }
+}
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index 0c88ade..0aeaecc 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -47,6 +47,30 @@
     private static final String TAG = "RcsUceAdapter";
 
     /**
+     * This carrier supports User Capability Exchange as, defined by the framework using
+     * SIP OPTIONS. If set, the RcsFeature should support capability exchange. If not set, this
+     * RcsFeature should not publish capabilities or service capability requests.
+     * @hide
+     */
+    public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1 << 0;
+
+    /**
+     * This carrier supports User Capability Exchange as, defined by the framework using a
+     * presence server. If set, the RcsFeature should support capability exchange. If not set, this
+     * RcsFeature should not publish capabilities or service capability requests.
+     * @hide
+     */
+    public static final int CAPABILITY_TYPE_PRESENCE_UCE = 1 << 1;
+
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "CAPABILITY_TYPE_", value = {
+            CAPABILITY_TYPE_OPTIONS_UCE,
+            CAPABILITY_TYPE_PRESENCE_UCE
+    })
+    public @interface RcsImsCapabilityFlag {}
+
+    /**
      * An unknown error has caused the request to fail.
      * @hide
      */
@@ -106,11 +130,6 @@
      * @hide
      */
     public static final int ERROR_LOST_NETWORK = 12;
-    /**
-     * The request has failed because the same request has already been added to the queue.
-     * @hide
-     */
-    public static final int ERROR_ALREADY_IN_QUEUE = 13;
 
     /**@hide*/
     @Retention(RetentionPolicy.SOURCE)
@@ -125,12 +144,90 @@
             ERROR_REQUEST_TOO_LARGE,
             ERROR_REQUEST_TIMEOUT,
             ERROR_INSUFFICIENT_MEMORY,
-            ERROR_LOST_NETWORK,
-            ERROR_ALREADY_IN_QUEUE
+            ERROR_LOST_NETWORK
     })
     public @interface ErrorCode {}
 
     /**
+     * A capability update has been requested due to the Entity Tag (ETag) expiring.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 0;
+    /**
+     * A capability update has been requested due to moving to LTE with VoPS disabled.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED = 1;
+    /**
+     * A capability update has been requested due to moving to LTE with VoPS enabled.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED = 2;
+    /**
+     * A capability update has been requested due to moving to eHRPD.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 3;
+    /**
+     * A capability update has been requested due to moving to HSPA+.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 4;
+    /**
+     * A capability update has been requested due to moving to 3G.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 5;
+    /**
+     * A capability update has been requested due to moving to 2G.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 6;
+    /**
+     * A capability update has been requested due to moving to WLAN
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN = 7;
+    /**
+     * A capability update has been requested due to moving to IWLAN
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 8;
+    /**
+     * A capability update has been requested but the reason is unknown.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_UNKNOWN = 9;
+    /**
+     * A capability update has been requested due to moving to 5G NR with VoPS disabled.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED = 10;
+    /**
+     * A capability update has been requested due to moving to 5G NR with VoPS enabled.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED = 11;
+
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "ERROR_", value = {
+            CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN,
+            CAPABILITY_UPDATE_TRIGGER_UNKNOWN,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED
+    })
+    public @interface StackPublishTriggerType {}
+
+    /**
      * The last publish has resulted in a "200 OK" response or the device is using SIP OPTIONS for
      * UCE.
      * @hide
@@ -205,7 +302,7 @@
             public void onPublishStateChanged(int publishState) {
                 if (mLocalCallback == null) return;
 
-                long callingIdentity = Binder.clearCallingIdentity();
+                final long callingIdentity = Binder.clearCallingIdentity();
                 try {
                     mExecutor.execute(() -> mLocalCallback.onChanged(publishState));
                 } finally {
@@ -238,38 +335,49 @@
     }
 
     /**
-     * Provides a one-time callback for the response to a UCE request. After this callback is called
-     * by the framework, the reference to this callback will be discarded on the service side.
+     * A callback for the response to a UCE request. The method
+     * {@link CapabilitiesCallback#onCapabilitiesReceived} will be called zero or more times as the
+     * capabilities are received for each requested contact.
+     * <p>
+     * This request will take a varying amount of time depending on if the contacts requested are
+     * cached or if it requires a network query. The timeout time of these requests can vary
+     * depending on the network, however in poor cases it could take up to a minute for a request
+     * to timeout. In that time only a subset of capabilities may have been retrieved.
+     * <p>
+     * After {@link CapabilitiesCallback#onComplete} or {@link CapabilitiesCallback#onError} has
+     * been called, the reference to this callback will be discarded on the service side.
      * @see #requestCapabilities(Executor, List, CapabilitiesCallback)
      * @hide
      */
-    public static class CapabilitiesCallback {
+    public interface CapabilitiesCallback {
 
         /**
-         * Notify this application that the pending capability request has returned successfully.
+         * Notify this application that the pending capability request has returned successfully
+         * for one or more of the requested contacts.
          * @param contactCapabilities List of capabilities associated with each contact requested.
          */
-        public void onCapabilitiesReceived(
-                @NonNull List<RcsContactUceCapability> contactCapabilities) {
+        void onCapabilitiesReceived(@NonNull List<RcsContactUceCapability> contactCapabilities);
 
-        }
+        /**
+         * The pending request has completed successfully due to all requested contacts information
+         * being delivered.
+         */
+        void onComplete();
 
         /**
          * The pending request has resulted in an error and may need to be retried, depending on the
          * error code.
          * @param errorCode The reason for the framework being unable to process the request.
          */
-        public void onError(@ErrorCode int errorCode) {
-
-        }
+        void onError(@ErrorCode int errorCode);
     }
 
     private final Context mContext;
     private final int mSubId;
 
     /**
-     * Not to be instantiated directly, use
-     * {@link ImsRcsManager#getUceAdapter()} to instantiate this manager class.
+     * Not to be instantiated directly, use {@link ImsRcsManager#getUceAdapter()} to instantiate
+     * this manager class.
      * @hide
      */
     RcsUceAdapter(Context context, int subId) {
@@ -280,6 +388,9 @@
     /**
      * Request the User Capability Exchange capabilities for one or more contacts.
      * <p>
+     * This will return the cached capabilities of the contact and will not perform a capability
+     * poll on the network unless there are contacts being queried with stale information.
+     * <p>
      * Be sure to check the availability of this feature using
      * {@link ImsRcsManager#isAvailable(int)} and ensuring
      * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or
@@ -302,7 +413,7 @@
             @NonNull List<Uri> contactNumbers,
             @NonNull CapabilitiesCallback c) throws ImsException {
         if (c == null) {
-            throw new IllegalArgumentException("Must include a non-null AvailabilityCallback.");
+            throw new IllegalArgumentException("Must include a non-null CapabilitiesCallback.");
         }
         if (executor == null) {
             throw new IllegalArgumentException("Must include a non-null Executor.");
@@ -321,7 +432,7 @@
         IRcsUceControllerCallback internalCallback = new IRcsUceControllerCallback.Stub() {
             @Override
             public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) {
-                long callingIdentity = Binder.clearCallingIdentity();
+                final long callingIdentity = Binder.clearCallingIdentity();
                 try {
                     executor.execute(() ->
                             c.onCapabilitiesReceived(contactCapabilities));
@@ -330,8 +441,17 @@
                 }
             }
             @Override
+            public void onComplete() {
+                final long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() -> c.onComplete());
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
+            }
+            @Override
             public void onError(int errorCode) {
-                long callingIdentity = Binder.clearCallingIdentity();
+                final long callingIdentity = Binder.clearCallingIdentity();
                 try {
                     executor.execute(() -> c.onError(errorCode));
                 } finally {
@@ -351,6 +471,88 @@
     }
 
     /**
+     * Ignore the device cache and perform a capability discovery for one contact, also called
+     * "availability fetch."
+     * <p>
+     * This will always perform a query to the network as long as requests are over the carrier
+     * availability fetch throttling threshold. If too many network requests are sent too quickly,
+     * #ERROR_TOO_MANY_REQUESTS will be returned.
+     *
+     * <p>
+     * Be sure to check the availability of this feature using
+     * {@link ImsRcsManager#isAvailable(int)} and ensuring
+     * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or
+     * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} is
+     * enabled or else this operation will fail with
+     * {@link #ERROR_NOT_AVAILABLE} or {@link #ERROR_NOT_ENABLED}.
+     *
+     * @param contactNumber The contact of the capabilities is being requested for.
+     * @param c A one-time callback for when the request for capabilities completes or there is
+     * an error processing the request.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void requestNetworkAvailability(@NonNull @CallbackExecutor Executor executor,
+            @NonNull Uri contactNumber, @NonNull CapabilitiesCallback c) throws ImsException {
+        if (executor == null) {
+            throw new IllegalArgumentException("Must include a non-null Executor.");
+        }
+        if (contactNumber == null) {
+            throw new IllegalArgumentException("Must include non-null contact number.");
+        }
+        if (c == null) {
+            throw new IllegalArgumentException("Must include a non-null CapabilitiesCallback.");
+        }
+
+        IImsRcsController imsRcsController = getIImsRcsController();
+        if (imsRcsController == null) {
+            Log.e(TAG, "requestNetworkAvailability: IImsRcsController is null");
+            throw new ImsException("Cannot find remote IMS service",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+
+        IRcsUceControllerCallback internalCallback = new IRcsUceControllerCallback.Stub() {
+            @Override
+            public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) {
+                final long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() ->
+                            c.onCapabilitiesReceived(contactCapabilities));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
+            }
+            @Override
+            public void onComplete() {
+                final long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() -> c.onComplete());
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
+            }
+            @Override
+            public void onError(int errorCode) {
+                final long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() -> c.onError(errorCode));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
+            }
+        };
+
+        try {
+            imsRcsController.requestNetworkAvailability(mSubId, mContext.getOpPackageName(),
+                    mContext.getAttributionTag(), contactNumber, internalCallback);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling IImsRcsController#requestNetworkAvailability", e);
+            throw new ImsException("Remote IMS Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+    }
+
+    /**
      * Gets the last publish result from the UCE service if the device is using an RCS presence
      * server.
      * @return The last publish result from the UCE service. If the device is using SIP OPTIONS,
diff --git a/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl b/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl
new file mode 100644
index 0000000..a4ffbef
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 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.ims.aidl;
+
+import android.net.Uri;
+import android.telephony.ims.aidl.IOptionsRequestCallback;
+
+import java.util.List;
+
+/**
+ * Listener interface for the ImsService to use to notify the framework of UCE events.
+ * {@hide}
+ */
+oneway interface ICapabilityExchangeEventListener {
+    /**
+     * Trigger the framework to provide a capability update using
+     * {@link RcsCapabilityExchangeImplBase#publishCapabilities}.
+     * <p>
+     * This is typically used when trying to generate an initial PUBLISH for a new
+     * subscription to the network. The device will cache all presence publications
+     * after boot until this method is called the first time.
+     * @param publishTriggerType {@link StackPublishTriggerType} The reason for the
+     * capability update request.
+     * @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is
+     * not currently connected to the framework. This can happen if the
+     * {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the
+     * {@link RcsFeature} has not received the
+     * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare
+     * cases when the Telephony stack has crashed.
+     */
+    void onRequestPublishCapabilities(int publishTriggerType);
+
+    /**
+     * Notify the framework that the device's capabilities have been unpublished from the network.
+     *
+     * @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is not currently
+     * connected to the framework. This can happen if the {@link RcsFeature} is not
+     * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
+     * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
+     * Telephony stack has crashed.
+     */
+    void onUnpublish();
+
+    /**
+     * Inform the framework of a query for this device's UCE capabilities.
+     * <p>
+     * The framework will respond via the
+     * {@link IOptionsRequestCallback#respondToCapabilityRequest} or
+     * {@link IOptionsRequestCallback#respondToCapabilityRequestWithError} method.
+     * @param contactUri The URI associated with the remote contact that is requesting capabilities.
+     * @param remoteCapabilities The remote contact's capability information.
+     * @throws ImsException If this {@link RcsSipOptionsImplBase} instance is not currently
+     * connected to the framework. This can happen if the {@link RcsFeature} is not
+     * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+     * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when
+     * the Telephony stack has crashed.
+     */
+    void onRemoteCapabilityRequest(in Uri contactUri,
+            in List<String> remoteCapabilities,
+            IOptionsRequestCallback cb);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
index 6d25a09..8e84e93 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
@@ -47,6 +47,9 @@
     // ImsUceAdapter specific
     void requestCapabilities(int subId, String callingPackage, String callingFeatureId,
             in List<Uri> contactNumbers, IRcsUceControllerCallback c);
+    void requestNetworkAvailability(int subId, String callingPackage,
+            String callingFeatureId, in Uri contactNumber,
+            IRcsUceControllerCallback c);
     int getUcePublishState(int subId);
     boolean isUceSettingEnabled(int subId, String callingPackage, String callingFeatureId);
     void setUceSettingEnabled(int subId, boolean isEnabled);
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl
index 4b98b79..b47e3c7 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl
@@ -18,8 +18,12 @@
 
 import android.net.Uri;
 import android.telephony.ims.RcsContactUceCapability;
+import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
+import android.telephony.ims.aidl.IOptionsResponseCallback;
+import android.telephony.ims.aidl.IPublishResponseCallback;
 import android.telephony.ims.aidl.IRcsFeatureListener;
+import android.telephony.ims.aidl.ISubscribeResponseCallback;
 import android.telephony.ims.feature.CapabilityChangeRequest;
 
 import java.util.List;
@@ -40,6 +44,12 @@
             IImsCapabilityCallback c);
     oneway void queryCapabilityConfiguration(int capability, int radioTech,
             IImsCapabilityCallback c);
+    // RcsCapabilityExchangeImplBase specific api
+    oneway void setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener);
+    oneway void publishCapabilities(in String pidfXml, IPublishResponseCallback cb);
+    oneway void subscribeForCapabilities(in List<Uri> uris, ISubscribeResponseCallback cb);
+    oneway void sendOptionsCapabilityRequest(in Uri contactUri,
+            in List<String> myCapabilities, IOptionsResponseCallback cb);
     // RcsPresenceExchangeImplBase specific api
     oneway void requestCapabilities(in List<Uri> uris, int operationToken);
     oneway void updateCapabilities(in RcsContactUceCapability capabilities, int operationToken);
@@ -50,4 +60,4 @@
             in RcsContactUceCapability ownCapabilities, int operationToken);
     oneway void respondToCapabilityRequestWithError(in Uri contactUri, int code, in String reason,
             int operationToken);
-}
\ No newline at end of file
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IOptionsRequestCallback.aidl b/telephony/java/android/telephony/ims/aidl/IOptionsRequestCallback.aidl
new file mode 100644
index 0000000..d55670d
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IOptionsRequestCallback.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 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.ims.aidl;
+
+import android.telephony.ims.RcsContactUceCapability;
+
+/**
+ * Interface used by the framework to respond to OPTIONS requests.
+ * {@hide}
+ */
+oneway interface IOptionsRequestCallback {
+    /**
+     * Respond to a remote capability request from the contact specified with the capabilities
+     * of this device.
+     * @param ownCapabilities The capabilities of this device.
+     */
+    void respondToCapabilityRequest(in RcsContactUceCapability ownCapabilities);
+
+    /**
+     * Respond to a remote capability request from the contact specified with the
+     * specified error.
+     * @param contactUri A URI containing the remote contact.
+     * @param code The SIP response code to respond with.
+     * @param reason A non-null String containing the reason associated with the SIP code.
+     */
+    void respondToCapabilityRequestWithError(int code, String reason);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IOptionsResponseCallback.aidl b/telephony/java/android/telephony/ims/aidl/IOptionsResponseCallback.aidl
new file mode 100644
index 0000000..a8c8329
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IOptionsResponseCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 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.ims.aidl;
+
+import java.util.List;
+
+/**
+ * Interface used by the framework to receive the response from the remote user
+ * through {@link RcsCapabilityExchangeImplBase#sendOptionsCapabilityRequest}
+ * {@hide}
+ */
+oneway interface IOptionsResponseCallback {
+    void onCommandError(int code);
+    void onNetworkResponse(int code, String reason, in List<String> theirCaps);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl b/telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl
new file mode 100644
index 0000000..481e7f8
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 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.ims.aidl;
+
+import java.util.List;
+
+/**
+ * Interface used by the framework to receive the response of the publish
+ * request through {@link RcsCapabilityExchangeImplBase#publishCapabilities}
+ * {@hide}
+ */
+oneway interface IPublishResponseCallback {
+    void onCommandError(int code);
+    void onNetworkResponse(int code, String reason);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
index 5975930..0bd3e5e 100644
--- a/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
@@ -25,5 +25,6 @@
  */
 oneway interface IRcsUceControllerCallback {
     void onCapabilitiesReceived(in List<RcsContactUceCapability> contactCapabilities);
+    void onComplete();
     void onError(int errorCode);
 }
diff --git a/telephony/java/android/telephony/ims/aidl/ISubscribeResponseCallback.aidl b/telephony/java/android/telephony/ims/aidl/ISubscribeResponseCallback.aidl
new file mode 100644
index 0000000..4deaba1
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/ISubscribeResponseCallback.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 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.ims.aidl;
+
+import android.net.Uri;
+import android.telephony.ims.RcsContactTerminatedReason;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Interface used by the framework to receive the response of the subscribe
+ * request through {@link RcsCapabilityExchangeImplBase#subscribeForCapabilities}
+ * {@hide}
+ */
+oneway interface ISubscribeResponseCallback {
+    void onCommandError(int code);
+    void onNetworkResponse(int code, in String reason);
+    void onNotifyCapabilitiesUpdate(in List<String> pidfXmls);
+    void onResourceTerminated(in List<RcsContactTerminatedReason> uriTerminatedReason);
+    void onTerminated(in String reason, in String retryAfter);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/RcsOptionsResponseAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/RcsOptionsResponseAidlWrapper.java
new file mode 100644
index 0000000..47a96af
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/RcsOptionsResponseAidlWrapper.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020 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.ims.aidl;
+
+import android.os.RemoteException;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.OptionsResponseCallback;
+
+import java.util.List;
+
+/**
+ * Implementation of the callback OptionsResponseCallback by wrapping the internal AIDL from
+ * telephony.
+ * @hide
+ */
+public class RcsOptionsResponseAidlWrapper implements OptionsResponseCallback {
+
+    private final IOptionsResponseCallback mResponseBinder;
+
+    public RcsOptionsResponseAidlWrapper(IOptionsResponseCallback responseBinder) {
+        mResponseBinder = responseBinder;
+    }
+
+    @Override
+    public void onCommandError(int code) {
+        try {
+            mResponseBinder.onCommandError(code);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
+    public void onNetworkResponse(int code, String reason, List<String> theirCaps)
+            throws ImsException {
+        try {
+            mResponseBinder.onNetworkResponse(code, reason, theirCaps);
+        } catch (RemoteException e) {
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/ims/aidl/RcsPublishResponseAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/RcsPublishResponseAidlWrapper.java
new file mode 100644
index 0000000..22985d0
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/RcsPublishResponseAidlWrapper.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2020 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.ims.aidl;
+
+import android.os.RemoteException;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.PublishResponseCallback;
+
+/**
+ * Implementation of the callback PublishResponseCallback by wrapping the internal AIDL from
+ * telephony.
+ * @hide
+ */
+public class RcsPublishResponseAidlWrapper implements PublishResponseCallback {
+
+    private final IPublishResponseCallback mResponseBinder;
+
+    public RcsPublishResponseAidlWrapper(IPublishResponseCallback responseBinder) {
+        mResponseBinder = responseBinder;
+    }
+
+    @Override
+    public void onCommandError(int code) {
+        try {
+            mResponseBinder.onCommandError(code);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
+    public void onNetworkResponse(int code, String reason) throws ImsException {
+        try {
+            mResponseBinder.onNetworkResponse(code, reason);
+        } catch (RemoteException e) {
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/ims/aidl/RcsSubscribeResponseAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/RcsSubscribeResponseAidlWrapper.java
new file mode 100644
index 0000000..37588ed
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/RcsSubscribeResponseAidlWrapper.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2020 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.ims.aidl;
+
+import android.net.Uri;
+import android.os.RemoteException;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.RcsContactTerminatedReason;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.SubscribeResponseCallback;
+import android.util.Pair;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implementation of the callback OptionsResponseCallback by wrapping the internal AIDL from
+ * telephony.
+ * @hide
+ */
+public class RcsSubscribeResponseAidlWrapper implements SubscribeResponseCallback {
+
+    private final ISubscribeResponseCallback mResponseBinder;
+
+    public RcsSubscribeResponseAidlWrapper(ISubscribeResponseCallback responseBinder) {
+        mResponseBinder = responseBinder;
+    }
+
+    @Override
+    public void onCommandError(int code) {
+        try {
+            mResponseBinder.onCommandError(code);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
+    public void onNetworkResponse(int code, String reason) throws ImsException {
+        try {
+            mResponseBinder.onNetworkResponse(code, reason);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
+    public void onNotifyCapabilitiesUpdate(List<String> pidfXmls) throws ImsException {
+        try {
+            mResponseBinder.onNotifyCapabilitiesUpdate(pidfXmls);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
+    public void onResourceTerminated(List<Pair<Uri, String>> uriTerminatedReason)
+            throws ImsException {
+        try {
+            mResponseBinder.onResourceTerminated(getTerminatedReasonList(uriTerminatedReason));
+        } catch (RemoteException e) {
+        }
+    }
+
+    private List<RcsContactTerminatedReason> getTerminatedReasonList(
+            List<Pair<Uri, String>> uriTerminatedReason) {
+        List<RcsContactTerminatedReason> uriTerminatedReasonList = new ArrayList<>();
+        if (uriTerminatedReason != null) {
+            for (Pair<Uri, String> pair : uriTerminatedReason) {
+                RcsContactTerminatedReason reason =
+                        new RcsContactTerminatedReason(pair.first, pair.second);
+                uriTerminatedReasonList.add(reason);
+            }
+        }
+        return uriTerminatedReasonList;
+    }
+
+    @Override
+    public void onTerminated(String reason, String retryAfter) throws ImsException {
+        try {
+            mResponseBinder.onTerminated(reason, retryAfter);
+        } catch (RemoteException e) {
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
index 87a5094..87a6873 100644
--- a/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
+++ b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
@@ -28,8 +28,8 @@
 import java.util.Set;
 
 /**
- * Request to send to IMS provider, which will try to enable/disable capabilities that are added to
- * the request.
+ * Used by the framework to enable and disable MMTEL and RCS capabilities. See
+ * MmTelFeature#changeEnabledCapabilities and RcsFeature#changeEnabledCapabilities.
  * {@hide}
  */
 @SystemApi
diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java
index b8ae146..5de2ddc 100644
--- a/telephony/java/android/telephony/ims/feature/RcsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java
@@ -23,12 +23,22 @@
 import android.net.Uri;
 import android.os.RemoteException;
 import android.telephony.ims.RcsContactUceCapability;
+import android.telephony.ims.RcsUceAdapter;
+import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsRcsFeature;
+import android.telephony.ims.aidl.IOptionsResponseCallback;
+import android.telephony.ims.aidl.IPublishResponseCallback;
 import android.telephony.ims.aidl.IRcsFeatureListener;
+import android.telephony.ims.aidl.ISubscribeResponseCallback;
+import android.telephony.ims.aidl.RcsOptionsResponseAidlWrapper;
+import android.telephony.ims.aidl.RcsPublishResponseAidlWrapper;
+import android.telephony.ims.aidl.RcsSubscribeResponseAidlWrapper;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
-import android.telephony.ims.stub.RcsPresenceExchangeImplBase;
-import android.telephony.ims.stub.RcsSipOptionsImplBase;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.OptionsResponseCallback;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.PublishResponseCallback;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.SubscribeResponseCallback;
 import android.util.Log;
 
 import com.android.internal.telephony.util.TelephonyUtils;
@@ -64,9 +74,14 @@
             mExecutor = executor;
         }
 
+        /**
+         * @deprecated This method is deprecated. Please call the method
+         * setCapabilityExchangeEventListener instead.
+         */
         @Override
+        @Deprecated
         public void setListener(IRcsFeatureListener listener) {
-            mReference.setListener(listener);
+            Log.w(LOG_TAG, "The method setListener is deprecated");
         }
 
         @Override
@@ -106,44 +121,66 @@
             return executeMethodAsyncForResult(mReference::getFeatureState, "getFeatureState");
         }
 
+        // RcsCapabilityExchangeImplBase specific APIs
+        @Override
+        public void setCapabilityExchangeEventListener(
+                @NonNull ICapabilityExchangeEventListener listener) throws RemoteException {
+            executeMethodAsync(() -> mReference.setCapabilityExchangeEventListener(listener),
+                    "setCapabilityExchangeEventListener");
+        }
+
+        @Override
+        public void publishCapabilities(@NonNull String pidfXml,
+                @NonNull IPublishResponseCallback callback) throws RemoteException {
+            PublishResponseCallback callbackWrapper = new RcsPublishResponseAidlWrapper(callback);
+            executeMethodAsync(() -> mReference.getCapabilityExchangeImplBaseInternal()
+                    .publishCapabilities(pidfXml, callbackWrapper), "publishCapabilities");
+        }
+
+        @Override
+        public void subscribeForCapabilities(@NonNull List<Uri> uris,
+                @NonNull ISubscribeResponseCallback callback) throws RemoteException {
+            SubscribeResponseCallback wrapper = new RcsSubscribeResponseAidlWrapper(callback);
+            executeMethodAsync(() -> mReference.getCapabilityExchangeImplBaseInternal()
+                    .subscribeForCapabilities(uris, wrapper), "subscribeForCapabilities");
+        }
+
+        @Override
+        public void sendOptionsCapabilityRequest(@NonNull Uri contactUri,
+                @NonNull List<String> myCapabilities, @NonNull IOptionsResponseCallback callback)
+                throws RemoteException {
+            OptionsResponseCallback callbackWrapper = new RcsOptionsResponseAidlWrapper(callback);
+            executeMethodAsync(() -> mReference.getCapabilityExchangeImplBaseInternal()
+                    .sendOptionsCapabilityRequest(contactUri, myCapabilities, callbackWrapper),
+                    "sendOptionsCapabilityRequest");
+        }
+
         // RcsPresenceExchangeImplBase specific APIS
         @Override
         public void requestCapabilities(List<Uri> uris, int operationToken) throws RemoteException {
-            executeMethodAsync(() -> mReference.getPresenceExchangeInternal()
-                    .requestCapabilities(uris, operationToken), "requestCapabilities");
+            throw new RemoteException("Unsupported operation: requestCapabilities");
         }
         @Override
         public void updateCapabilities(RcsContactUceCapability capabilities, int operationToken)
                 throws RemoteException {
-            executeMethodAsync(() -> mReference.getPresenceExchangeInternal()
-                            .updateCapabilities(capabilities, operationToken),
-                    "updateCapabilities");
-
+            throw new RemoteException("Unsupported operation: updateCapabilities");
         }
         // RcsSipOptionsImplBase specific APIS
         @Override
         public void sendCapabilityRequest(Uri contactUri, RcsContactUceCapability capabilities,
                 int operationToken) throws RemoteException {
-            executeMethodAsync(() -> mReference.getOptionsExchangeInternal()
-                            .sendCapabilityRequest(contactUri, capabilities, operationToken),
-                    "sendCapabilityRequest");
-
+            throw new RemoteException("Unsupported operation: sendCapabilityRequest");
         }
         @Override
         public void respondToCapabilityRequest(String contactUri,
                 RcsContactUceCapability ownCapabilities, int operationToken)
                 throws RemoteException {
-            executeMethodAsync(() -> mReference.getOptionsExchangeInternal()
-                            .respondToCapabilityRequest(contactUri, ownCapabilities,
-                                    operationToken), "respondToCapabilityRequest");
-
+            throw new RemoteException("Unsupported operation: respondToCapabilityRequest");
         }
         @Override
         public void respondToCapabilityRequestWithError(Uri contactUri, int code, String reason,
                 int operationToken) throws RemoteException {
-            executeMethodAsync(() -> mReference.getOptionsExchangeInternal()
-                            .respondToCapabilityRequestWithError(contactUri, code, reason,
-                                    operationToken), "respondToCapabilityRequestWithError");
+            throw new RemoteException("Unsupported operation: respondToCapabilityRequestWithError");
         }
 
         // Call the methods with a clean calling identity on the executor and wait indefinitely for
@@ -182,8 +219,8 @@
      * Contains the capabilities defined and supported by a {@link RcsFeature} in the
      * form of a bitmask. The capabilities that are used in the RcsFeature are
      * defined as:
-     * {@link RcsImsCapabilityFlag#CAPABILITY_TYPE_OPTIONS_UCE}
-     * {@link RcsImsCapabilityFlag#CAPABILITY_TYPE_PRESENCE_UCE}
+     * {@link RcsUceAdatper.RcsImsCapabilityFlag#CAPABILITY_TYPE_OPTIONS_UCE}
+     * {@link RceUceAdapter.RcsImsCapabilityFlag#CAPABILITY_TYPE_PRESENCE_UCE}
      *
      * The enabled capabilities of this RcsFeature will be set by the framework
      * using {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}.
@@ -223,7 +260,7 @@
          */
         public static final int CAPABILITY_TYPE_PRESENCE_UCE =  1 << 1;
 
-        public RcsImsCapabilities(@RcsImsCapabilityFlag int capabilities) {
+        public RcsImsCapabilities(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
             super(capabilities);
         }
 
@@ -232,25 +269,24 @@
         }
 
         @Override
-        public void addCapabilities(@RcsImsCapabilityFlag int capabilities) {
+        public void addCapabilities(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
             super.addCapabilities(capabilities);
         }
 
         @Override
-        public void removeCapabilities(@RcsImsCapabilityFlag int capabilities) {
+        public void removeCapabilities(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
             super.removeCapabilities(capabilities);
         }
 
         @Override
-        public boolean isCapable(@RcsImsCapabilityFlag int capabilities) {
+        public boolean isCapable(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
             return super.isCapable(capabilities);
         }
     }
 
     private final RcsFeatureBinder mImsRcsBinder;
-    private IRcsFeatureListener mListenerBinder;
-    private RcsPresenceExchangeImplBase mPresExchange;
-    private RcsSipOptionsImplBase mSipOptions;
+    private RcsCapabilityExchangeImplBase mCapabilityExchangeImpl;
+    private ICapabilityExchangeEventListener mCapExchangeEventListener;
 
     /**
      * Create a new RcsFeature.
@@ -314,7 +350,7 @@
      * @hide
      */
     public boolean queryCapabilityConfiguration(
-            @RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+            @RcsUceAdapter.RcsImsCapabilityFlag int capability,
             @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
         // Base Implementation - Override to provide functionality
         return false;
@@ -342,37 +378,22 @@
     }
 
     /**
-     * Retrieve the implementation of SIP OPTIONS for this {@link RcsFeature}.
-     * <p>
-     * Will only be requested by the framework if capability exchange via SIP OPTIONS is
-     * configured as capable during a
+     * Retrieve the implementation of UCE for this {@link RcsFeature}, which can use either
+     * presence or OPTIONS for capability exchange.
+     *
+     * Will only be requested by the framework if capability exchange is configured
+     * as capable during a
      * {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}
      * operation and the RcsFeature sets the status of the capability to true using
      * {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)}.
      *
-     * @return An instance of {@link RcsSipOptionsImplBase} that implements SIP options exchange if
-     * it is supported by the device.
-     * @hide
-     */
-    public @NonNull RcsSipOptionsImplBase getOptionsExchangeImpl() {
-        // Base Implementation, override to implement functionality
-        return new RcsSipOptionsImplBase();
-    }
-
-    /**
-     * Retrieve the implementation of UCE presence for this {@link RcsFeature}.
-     * Will only be requested by the framework if presence exchang is configured as capable during
-     * a {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}
-     * operation and the RcsFeature sets the status of the capability to true using
-     * {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)}.
-     *
-     * @return An instance of {@link RcsPresenceExchangeImplBase} that implements presence
+     * @return An instance of {@link RcsCapabilityExchangeImplBase} that implements presence
      * exchange if it is supported by the device.
      * @hide
      */
-    public @NonNull RcsPresenceExchangeImplBase getPresenceExchangeImpl() {
-        // Base Implementation, override to implement functionality.
-        return new RcsPresenceExchangeImplBase();
+    public @NonNull RcsCapabilityExchangeImplBase createCapabilityExchangeImpl() {
+        // Base Implementation, override to implement functionality
+        return new RcsCapabilityExchangeImplBase();
     }
 
     /**{@inheritDoc}*/
@@ -395,39 +416,20 @@
         return mImsRcsBinder;
     }
 
-    /**@hide*/
-    public IRcsFeatureListener getListener() {
-        synchronized (mLock) {
-            return mListenerBinder;
+    private void setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener) {
+        mCapExchangeEventListener = listener;
+        if (mCapExchangeEventListener != null) {
+            onFeatureReady();
         }
     }
 
-    private void setListener(IRcsFeatureListener listener) {
+    private RcsCapabilityExchangeImplBase getCapabilityExchangeImplBaseInternal() {
         synchronized (mLock) {
-            mListenerBinder = listener;
-            if (mListenerBinder != null) {
-                onFeatureReady();
+            if (mCapabilityExchangeImpl == null) {
+                mCapabilityExchangeImpl = createCapabilityExchangeImpl();
+                mCapabilityExchangeImpl.setEventListener(mCapExchangeEventListener);
             }
-        }
-    }
-
-    private RcsPresenceExchangeImplBase getPresenceExchangeInternal() {
-        synchronized (mLock) {
-            if (mPresExchange == null) {
-                mPresExchange = getPresenceExchangeImpl();
-                mPresExchange.initialize(this);
-            }
-            return mPresExchange;
-        }
-    }
-
-    private RcsSipOptionsImplBase getOptionsExchangeInternal() {
-        synchronized (mLock) {
-            if (mSipOptions == null) {
-                mSipOptions = getOptionsExchangeImpl();
-                mSipOptions.initialize(this);
-            }
-            return mSipOptions;
+            return mCapabilityExchangeImpl;
         }
     }
 }
diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java
index fda295a..0b13efb 100644
--- a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java
+++ b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java
@@ -87,12 +87,8 @@
 
     /** @hide */
     protected final IRcsFeatureListener getListener() throws ImsException {
-        IRcsFeatureListener listener = mFeature.getListener();
-        if (listener == null) {
-            throw new ImsException("Connection to Framework has not been established, wait for "
-                    + "onFeatureReady().", ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
-        }
-        return mFeature.getListener();
+        throw new ImsException("This method is deprecated.",
+                ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
     }
 
     /**
diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
new file mode 100644
index 0000000..b5704bf
--- /dev/null
+++ b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2020 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.ims.stub;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.Uri;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
+import android.util.Log;
+import android.util.Pair;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+
+/**
+ * Base class for different types of Capability exchange.
+ * @hide
+ */
+public class RcsCapabilityExchangeImplBase {
+
+    private static final String LOG_TAG = "RcsCapExchangeImplBase";
+
+    /**
+     * Service is unknown.
+     */
+    public static final int COMMAND_CODE_SERVICE_UNKNOWN = 0;
+
+    /**
+     * The command failed with an unknown error.
+     */
+    public static final int COMMAND_CODE_GENERIC_FAILURE = 1;
+
+    /**
+     * Invalid parameter(s).
+     */
+    public static final int COMMAND_CODE_INVALID_PARAM = 2;
+
+    /**
+     * Fetch error.
+     */
+    public static final int COMMAND_CODE_FETCH_ERROR = 3;
+
+    /**
+     * Request timed out.
+     */
+    public static final int COMMAND_CODE_REQUEST_TIMEOUT = 4;
+
+    /**
+     * Failure due to insufficient memory available.
+     */
+    public static final int COMMAND_CODE_INSUFFICIENT_MEMORY = 5;
+
+    /**
+     * Network connection is lost.
+     * @hide
+     */
+    public static final int COMMAND_CODE_LOST_NETWORK_CONNECTION = 6;
+
+    /**
+     * Requested feature/resource is not supported.
+     * @hide
+     */
+    public static final int COMMAND_CODE_NOT_SUPPORTED = 7;
+
+    /**
+     * Contact or resource is not found.
+     */
+    public static final int COMMAND_CODE_NOT_FOUND = 8;
+
+    /**
+     * Service is not available.
+     */
+    public static final int COMMAND_CODE_SERVICE_UNAVAILABLE = 9;
+
+    /**
+     * Command resulted in no change in state, ignoring.
+     */
+    public static final int COMMAND_CODE_NO_CHANGE = 10;
+
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "COMMAND_CODE_", value = {
+            COMMAND_CODE_SERVICE_UNKNOWN,
+            COMMAND_CODE_GENERIC_FAILURE,
+            COMMAND_CODE_INVALID_PARAM,
+            COMMAND_CODE_FETCH_ERROR,
+            COMMAND_CODE_REQUEST_TIMEOUT,
+            COMMAND_CODE_INSUFFICIENT_MEMORY,
+            COMMAND_CODE_LOST_NETWORK_CONNECTION,
+            COMMAND_CODE_NOT_SUPPORTED,
+            COMMAND_CODE_NOT_FOUND,
+            COMMAND_CODE_SERVICE_UNAVAILABLE,
+            COMMAND_CODE_NO_CHANGE
+    })
+    public @interface CommandCode {}
+
+    /**
+     * Interface used by the framework to receive the response of the publish request.
+     */
+    public interface PublishResponseCallback {
+        /**
+         * Notify the framework that the command associated with this callback has failed.
+         *
+         * @param code The reason why the associated command has failed.
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently connected to the framework. This can happen if the {@link RcsFeature}
+         * is not {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+         * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases
+         * when the Telephony stack has crashed.
+         */
+        void onCommandError(@CommandCode int code) throws ImsException;
+
+
+        /**
+         * Provide the framework with a subsequent network response update to
+         * {@link #publishCapabilities(String, PublishResponseCallback)}.
+         *
+         * @param code The SIP response code sent from the network for the operation
+         * token specified.
+         * @param reason The optional reason response from the network. If the network
+         *  provided no reason with the code, the string should be empty.
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently connected to the framework. This can happen if the {@link RcsFeature}
+         * is not {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+         * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases
+         * when the Telephony stack has crashed.
+         */
+        void onNetworkResponse(@IntRange(from = 100, to = 699) int code,
+                @NonNull String reason) throws ImsException;
+    }
+
+    /**
+     * Interface used by the framework to respond to OPTIONS requests.
+     */
+    public interface OptionsResponseCallback {
+        /**
+         * Notify the framework that the command associated with this callback has failed.
+         *
+         * @param code The reason why the associated command has failed.
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently connected to the framework. This can happen if the
+         * {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the {@link RcsFeature}
+         * has not received the {@link ImsFeature#onFeatureReady()} callback. This may also happen
+         * in rare cases when the Telephony stack has crashed.
+         */
+        void onCommandError(@CommandCode int code) throws ImsException;
+
+        /**
+         * Send the response of a SIP OPTIONS capability exchange to the framework.
+         * @param code The SIP response code that was sent by the network in response
+         * to the request sent by {@link #sendOptionsCapabilityRequest}.
+         * @param reason The optional SIP response reason sent by the network.
+         * If none was sent, this should be an empty string.
+         * @param theirCaps the contact's UCE capabilities associated with the
+         * capability request.
+         * @throws ImsException If this {@link RcsSipOptionsImplBase} instance is not
+         * currently connected to the framework. This can happen if the
+         * {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the
+         * {@link RcsFeature} has not received the
+         * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare
+         * cases when the Telephony stack has crashed.
+         */
+        void onNetworkResponse(int code, @NonNull String reason,
+                @Nullable List<String> theirCaps) throws ImsException;
+    }
+
+    /**
+     * Interface used by the framework to receive the response of the subscribe request.
+     */
+    public interface SubscribeResponseCallback {
+        /**
+         * Notify the framework that the command associated with this callback has failed.
+         *
+         * @param code The reason why the associated command has failed.
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently connected to the framework. This can happen if the
+         * {@link RcsFeature} is not
+         * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+         * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in
+         * rare cases when the Telephony stack has crashed.
+         */
+        void onCommandError(@CommandCode int code) throws ImsException;
+
+        /**
+         * Notify the framework of the response to the SUBSCRIBE request from
+         * {@link #subscribeForCapabilities(List<Uri>, SubscribeResponseCallback)}.
+         *
+         * @param code The SIP response code sent from the network for the operation
+         * token specified.
+         * @param reason The optional reason response from the network. If the network
+         *  provided no reason with the code, the string should be empty.
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently connected to the framework. This can happen if the
+         * {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the
+         * {@link RcsFeature} has not received the {@link ImsFeature#onFeatureReady()} callback.
+         * This may also happen in rare cases when the Telephony stack has crashed.
+         */
+        void onNetworkResponse(@IntRange(from = 100, to = 699) int code,
+                @NonNull String reason) throws ImsException;
+
+        /**
+         * Provides the framework with latest XML PIDF documents included in the
+         * network response for the requested  contacts' capabilities requested by the
+         * Framework  using {@link #requestCapabilities(List, int)}. This should be
+         * called every time a new NOTIFY event is received with new capability
+         * information.
+         *
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently
+         * connected to the framework. This can happen if the {@link RcsFeature} is not
+         * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+         * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in
+         * rare cases when the
+         * Telephony stack has crashed.
+         */
+        void onNotifyCapabilitiesUpdate(@NonNull List<String> pidfXmls) throws ImsException;
+
+        /**
+         * A resource in the resource list for the presence subscribe event has been terminated.
+         * <p>
+         * This allows the framework to know that there will not be any capability information for
+         * a specific contact URI that they subscribed for.
+         */
+        void onResourceTerminated(
+                @NonNull List<Pair<Uri, String>> uriTerminatedReason) throws ImsException;
+
+        /**
+         * The subscription associated with a previous #requestCapabilities operation
+         * has been terminated. This will mostly be due to the subscription expiring,
+         * but may also happen due to an error.
+         * <p>
+         * This allows the framework to know that there will no longer be any
+         * capability updates for the requested operationToken.
+         */
+        void onTerminated(String reason, String retryAfter) throws ImsException;
+    }
+
+
+    private ICapabilityExchangeEventListener mListener;
+
+    /**
+     * Set the event listener to send the request to Framework.
+     */
+    public void setEventListener(ICapabilityExchangeEventListener listener) {
+        mListener = listener;
+    }
+
+    /**
+     * Get the event listener.
+     */
+    public ICapabilityExchangeEventListener getEventListener() {
+        return mListener;
+    }
+
+    /**
+     * The user capabilities of one or multiple contacts have been requested by the framework.
+     * <p>
+     * The response from the network to the SUBSCRIBE request must be sent back to the framework
+     * using {@link #onSubscribeNetworkResponse(int, String, int)}. As NOTIFY requests come in from
+     * the network, the requested contact’s capabilities should be sent back to the framework using
+     * {@link #onSubscribeNotifyRequest} and {@link onSubscribeResourceTerminated}
+     * should be called with the presence information for the contacts specified.
+     * <p>
+     * Once the subscription is terminated, {@link #onSubscriptionTerminated} must be called for
+     * the framework to finish listening for NOTIFY responses.
+     * @param uris A {@link List} of the {@link Uri}s that the framework is requesting the UCE
+     * capabilities for.
+     * @param cb The callback of the subscribe request.
+     */
+    public void subscribeForCapabilities(@NonNull List<Uri> uris,
+            @NonNull SubscribeResponseCallback cb) {
+        // Stub - to be implemented by service
+        Log.w(LOG_TAG, "subscribeForCapabilities called with no implementation.");
+        try {
+            cb.onCommandError(COMMAND_CODE_NOT_SUPPORTED);
+        } catch (ImsException e) {
+            // Do not do anything, this is a stub implementation.
+        }
+    }
+
+    /**
+     * The capabilities of this device have been updated and should be published to the network.
+     * <p>
+     * If this operation succeeds, network response updates should be sent to the framework using
+     * {@link #onNetworkResponse(int, String)}.
+     * @param pidfXml The XML PIDF document containing the capabilities of this device to be sent
+     * to the carrier’s presence server.
+     * @param cb The callback of the publish request
+     */
+    public void publishCapabilities(@NonNull String pidfXml, @NonNull PublishResponseCallback cb) {
+        // Stub - to be implemented by service
+        Log.w(LOG_TAG, "publishCapabilities called with no implementation.");
+        try {
+            cb.onCommandError(COMMAND_CODE_NOT_SUPPORTED);
+        } catch (ImsException e) {
+            // Do not do anything, this is a stub implementation.
+        }
+    }
+
+    /**
+     * Push one's own capabilities to a remote user via the SIP OPTIONS presence exchange mechanism
+     * in order to receive the capabilities of the remote user in response.
+     * <p>
+     * The implementer must call {@link #onNetworkResponse} to send the response of this
+     * query back to the framework.
+     * @param contactUri The URI of the remote user that we wish to get the capabilities of.
+     * @param myCapabilities The capabilities of this device to send to the remote user.
+     * @param callback The callback of this request which is sent from the remote user.
+     */
+    public void sendOptionsCapabilityRequest(@NonNull Uri contactUri,
+            @NonNull List<String> myCapabilities, @NonNull OptionsResponseCallback callback) {
+        // Stub - to be implemented by service
+        Log.w(LOG_TAG, "sendOptionsCapabilityRequest called with no implementation.");
+        try {
+            callback.onCommandError(COMMAND_CODE_NOT_SUPPORTED);
+        } catch (ImsException e) {
+            // Do not do anything, this is a stub implementation.
+        }
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 61c22bb..7945636 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -975,13 +975,6 @@
     boolean setPreferredNetworkType(int subId, int networkType);
 
     /**
-     * User enable/disable Mobile Data.
-     *
-     * @param enable true to turn on, else false
-     */
-    void setUserDataEnabled(int subId, boolean enable);
-
-    /**
      * Get the user enabled state of Mobile Data.
      *
      * TODO: remove and use isUserDataEnabled.
@@ -1002,12 +995,29 @@
     boolean isUserDataEnabled(int subId);
 
     /**
-     * Get the overall enabled state of Mobile Data.
-     *
+     * Check if data is enabled on the device. It can be disabled by
+     * user, carrier, policy or thermal.
      * @return true on enabled
      */
     boolean isDataEnabled(int subId);
 
+    /**
+     * Control of data connection and provide the reason triggering the data connection control.
+     *
+     * @param subId user preferred subId.
+     * @param reason the reason the data enable change is taking place
+     * @param enable true to turn on, else false
+     */
+     void setDataEnabledForReason(int subId, int reason, boolean enable);
+
+    /**
+     * Return whether data is enabled for certain reason
+     * @param subId user preferred subId.       .
+     * @param reason the reason the data enable change is taking place
+     * @return true on enabled
+    */
+    boolean isDataEnabledForReason(int subId, int reason);
+
      /**
      * Checks if manual network selection is allowed.
      *
@@ -1605,15 +1615,6 @@
     int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc);
 
     /**
-     * Action set from carrier signalling broadcast receivers to enable/disable metered apns
-     * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
-     * @param subId the subscription ID that this action applies to.
-     * @param enabled control enable or disable metered apns.
-     * @hide
-     */
-    void carrierActionSetMeteredApnsEnabled(int subId, boolean visible);
-
-    /**
      * Action set from carrier signalling broadcast receivers to enable/disable radio
      * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
      * @param subId the subscription ID that this action applies to.
@@ -1651,14 +1652,6 @@
     void setCallWaitingStatus(int subId, boolean enabled, IIntegerConsumer callback);
 
     /**
-     * Policy control of data connection. Usually used when data limit is passed.
-     * @param enabled True if enabling the data, otherwise disabling.
-     * @param subId Subscription index
-     * @hide
-     */
-    void setPolicyDataEnabled(boolean enabled, int subId);
-
-    /**
      * Get Client request stats which will contain statistical information
      * on each request made by client.
      * @param callingPackage package making the call.
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index d524299..ca7efcd 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -494,6 +494,10 @@
     int RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS = 210;
     int RIL_REQUEST_GET_BARRING_INFO = 211;
     int RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION = 212;
+    int RIL_REQUEST_ALLOCATE_PDU_SESSION_ID = 215;
+    int RIL_REQUEST_RELEASE_PDU_SESSION_ID = 216;
+    int RIL_REQUEST_BEGIN_HANDOVER = 217;
+    int RIL_REQUEST_CANCEL_HANDOVER = 218;
 
     /* Responses begin */
     int RIL_RESPONSE_ACKNOWLEDGEMENT = 800;
diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt
index 5c0283c..b489be2 100644
--- a/wifi/jarjar-rules.txt
+++ b/wifi/jarjar-rules.txt
@@ -36,7 +36,7 @@
 rule android.net.ipmemorystore.NetworkAttributesParcelable* com.android.wifi.x.@0
 rule android.net.ipmemorystore.SameL3NetworkResponseParcelable* com.android.wifi.x.@0
 rule android.net.ipmemorystore.StatusParcelable* com.android.wifi.x.@0
-rule android.net.networkstack.aidl.quirks.IPv6ProvisioningLossQuirk* com.android.wifi.x.@0
+rule android.net.networkstack.aidl.** com.android.wifi.x.@0
 
 # Net utils (includes Network Stack helper classes).
 rule android.net.DhcpResults* com.android.wifi.x.@0