Merge "Update comments on onApnUnthrottled"
diff --git a/.prebuilt_info/OWNERS b/.prebuilt_info/OWNERS
new file mode 100644
index 0000000..eb8b89b
--- /dev/null
+++ b/.prebuilt_info/OWNERS
@@ -0,0 +1 @@
+per-file prebuilt_info_packages_CtsShim_*.asciipb = file:/packages/CtsShim/OWNERS
diff --git a/Android.bp b/Android.bp
index e79248e..39c8013 100644
--- a/Android.bp
+++ b/Android.bp
@@ -525,7 +525,7 @@
         "android.hardware.vibrator-V1.3-java",
         "android.security.apc-java",
         "android.security.authorization-java",
-        "android.security.usermanager-java",
+        "android.security.maintenance-java",
         "android.security.vpnprofilestore-java",
         "android.system.keystore2-V1-java",
         "android.system.suspend.control.internal-java",
@@ -1130,6 +1130,21 @@
     },
 }
 
+// Build Rust bindings for PermissionController. Needed by keystore2.
+aidl_interface {
+    name: "android.os.permissions_aidl",
+    unstable: true,
+    local_include_dir: "core/java",
+    srcs: [
+        "core/java/android/os/IPermissionController.aidl",
+    ],
+    backend: {
+        rust: {
+            enabled: true,
+        },
+    },
+}
+
 // TODO(b/77285514): remove this once the last few hidl interfaces have been
 // updated to use hwbinder.stubs.
 java_library {
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 2b12da2..4b449ef 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -57,5 +57,65 @@
     {
       "name": "ManagedProfileLifecycleStressTest"
     }
-  ]
+  ],
+ "auto-postsubmit": [
+   // Test tag for automotive targets. These are only running in postsubmit so as to harden the
+   // automotive targets to avoid introducing additional test flake and build time. The plan for
+   // presubmit testing for auto is to augment the existing tests to cover auto use cases as well.
+   // Additionally, this tag is used in targeted test suites to limit resource usage on the test
+   // infra during the hardening phase.
+   // TODO: this tag to be removed once the above is no longer an issue.
+   {
+     "name": "FrameworksUiServicesTests",
+     "options": [
+       {
+         "exclude-annotation": "androidx.test.filters.FlakyTest"
+       }
+     ]
+   },
+   {
+     "name": "ExtServicesUnitTests",
+     "options": [
+       {
+         "exclude-annotation": "androidx.test.filters.FlakyTest"
+       }
+     ]
+   },
+   {
+     "name": "TestablesTests",
+     "options": [
+       {
+         "exclude-annotation": "androidx.test.filters.FlakyTest"
+       }
+     ]
+   },
+   {
+     "name": "FrameworksCoreTests",
+     "options": [
+       {
+         "include-annotation": "android.platform.test.annotations.Presubmit"
+       },
+       {
+         "exclude-annotation": "androidx.test.filters.FlakyTest"
+       },
+       {
+         "exclude-annotation": "org.junit.Ignore"
+       }
+     ]
+   },
+   {
+     "name": "FrameworksServicesTests",
+     "options": [
+       {
+         "include-annotation": "android.platform.test.annotations.Presubmit"
+       },
+       {
+         "exclude-annotation": "androidx.test.filters.FlakyTest"
+       },
+       {
+         "exclude-annotation": "org.junit.Ignore"
+       }
+     ]
+   }
+ ]
 }
diff --git a/core/api/current.txt b/core/api/current.txt
index 28d492c..116ac09 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -40325,29 +40325,29 @@
     field public static final char WILD = 78; // 0x004e 'N'
   }
 
-  public class PhoneStateListener {
-    ctor public PhoneStateListener();
+  @Deprecated public class PhoneStateListener {
+    ctor @Deprecated public PhoneStateListener();
     ctor @Deprecated public PhoneStateListener(@NonNull java.util.concurrent.Executor);
-    method public void onActiveDataSubscriptionIdChanged(int);
-    method public void onBarringInfoChanged(@NonNull android.telephony.BarringInfo);
-    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallDisconnectCauseChanged(int, int);
-    method public void onCallForwardingIndicatorChanged(boolean);
-    method public void onCallStateChanged(int, String);
-    method public void onCellInfoChanged(java.util.List<android.telephony.CellInfo>);
-    method public void onCellLocationChanged(android.telephony.CellLocation);
-    method public void onDataActivity(int);
-    method public void onDataConnectionStateChanged(int);
-    method public void onDataConnectionStateChanged(int, int);
-    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo);
-    method public void onEmergencyNumberListChanged(@NonNull java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>>);
-    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo);
-    method public void onMessageWaitingIndicatorChanged(boolean);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState);
-    method public void onRegistrationFailed(@NonNull android.telephony.CellIdentity, @NonNull String, int, int, int);
-    method public void onServiceStateChanged(android.telephony.ServiceState);
+    method @Deprecated public void onActiveDataSubscriptionIdChanged(int);
+    method @Deprecated public void onBarringInfoChanged(@NonNull android.telephony.BarringInfo);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallDisconnectCauseChanged(int, int);
+    method @Deprecated public void onCallForwardingIndicatorChanged(boolean);
+    method @Deprecated public void onCallStateChanged(int, String);
+    method @Deprecated public void onCellInfoChanged(java.util.List<android.telephony.CellInfo>);
+    method @Deprecated public void onCellLocationChanged(android.telephony.CellLocation);
+    method @Deprecated public void onDataActivity(int);
+    method @Deprecated public void onDataConnectionStateChanged(int);
+    method @Deprecated public void onDataConnectionStateChanged(int, int);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo);
+    method @Deprecated public void onEmergencyNumberListChanged(@NonNull java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>>);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo);
+    method @Deprecated public void onMessageWaitingIndicatorChanged(boolean);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState);
+    method @Deprecated public void onRegistrationFailed(@NonNull android.telephony.CellIdentity, @NonNull String, int, int, int);
+    method @Deprecated public void onServiceStateChanged(android.telephony.ServiceState);
     method @Deprecated public void onSignalStrengthChanged(int);
-    method public void onSignalStrengthsChanged(android.telephony.SignalStrength);
-    method public void onUserMobileDataStateChanged(boolean);
+    method @Deprecated public void onSignalStrengthsChanged(android.telephony.SignalStrength);
+    method @Deprecated public void onUserMobileDataStateChanged(boolean);
     field @Deprecated public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 4194304; // 0x400000
     field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_BARRING_INFO = -2147483648; // 0x80000000
     field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_CALL_DISCONNECT_CAUSES = 33554432; // 0x2000000
@@ -40361,7 +40361,7 @@
     field @Deprecated public static final int LISTEN_EMERGENCY_NUMBER_LIST = 16777216; // 0x1000000
     field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_IMS_CALL_DISCONNECT_CAUSES = 134217728; // 0x8000000
     field @Deprecated public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 4; // 0x4
-    field public static final int LISTEN_NONE = 0; // 0x0
+    field @Deprecated public static final int LISTEN_NONE = 0; // 0x0
     field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 4096; // 0x1000
     field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_REGISTRATION_FAILURE = 1073741824; // 0x40000000
     field @Deprecated public static final int LISTEN_SERVICE_STATE = 1; // 0x1
@@ -40370,94 +40370,6 @@
     field @Deprecated public static final int LISTEN_USER_MOBILE_DATA_STATE = 524288; // 0x80000
   }
 
-  public static interface PhoneStateListener.ActiveDataSubscriptionIdChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onActiveDataSubscriptionIdChanged(int);
-  }
-
-  public static interface PhoneStateListener.AlwaysReportedSignalStrengthChangedListener {
-    method @RequiresPermission("android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH") public void onSignalStrengthsChanged(@NonNull android.telephony.SignalStrength);
-  }
-
-  public static interface PhoneStateListener.BarringInfoChangedListener {
-    method @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void onBarringInfoChanged(@NonNull android.telephony.BarringInfo);
-  }
-
-  public static interface PhoneStateListener.CallDisconnectCauseChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallDisconnectCauseChanged(int, int);
-  }
-
-  public static interface PhoneStateListener.CallForwardingIndicatorChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onCallForwardingIndicatorChanged(boolean);
-  }
-
-  public static interface PhoneStateListener.CallStateChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) public void onCallStateChanged(int, @Nullable String);
-  }
-
-  public static interface PhoneStateListener.CarrierNetworkChangeListener {
-    method public void onCarrierNetworkChange(boolean);
-  }
-
-  public static interface PhoneStateListener.CellInfoChangedListener {
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void onCellInfoChanged(@NonNull java.util.List<android.telephony.CellInfo>);
-  }
-
-  public static interface PhoneStateListener.CellLocationChangedListener {
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void onCellLocationChanged(@NonNull android.telephony.CellLocation);
-  }
-
-  public static interface PhoneStateListener.DataActivationStateChangedListener {
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onDataActivationStateChanged(int);
-  }
-
-  public static interface PhoneStateListener.DataActivityListener {
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onDataActivity(int);
-  }
-
-  public static interface PhoneStateListener.DataConnectionStateChangedListener {
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onDataConnectionStateChanged(int, int);
-  }
-
-  public static interface PhoneStateListener.DisplayInfoChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo);
-  }
-
-  public static interface PhoneStateListener.EmergencyNumberListChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onEmergencyNumberListChanged(@NonNull java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>>);
-  }
-
-  public static interface PhoneStateListener.ImsCallDisconnectCauseChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo);
-  }
-
-  public static interface PhoneStateListener.MessageWaitingIndicatorChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onMessageWaitingIndicatorChanged(boolean);
-  }
-
-  public static interface PhoneStateListener.PhoneCapabilityChangedListener {
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onPhoneCapabilityChanged(@NonNull android.telephony.PhoneCapability);
-  }
-
-  public static interface PhoneStateListener.PreciseDataConnectionStateChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState);
-  }
-
-  public static interface PhoneStateListener.RegistrationFailedListener {
-    method @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void onRegistrationFailed(@NonNull android.telephony.CellIdentity, @NonNull String, int, int, int);
-  }
-
-  public static interface PhoneStateListener.ServiceStateChangedListener {
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onServiceStateChanged(@NonNull android.telephony.ServiceState);
-  }
-
-  public static interface PhoneStateListener.SignalStrengthsChangedListener {
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onSignalStrengthsChanged(@NonNull android.telephony.SignalStrength);
-  }
-
-  public static interface PhoneStateListener.UserMobileDataStateChangedListener {
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onUserMobileDataStateChanged(boolean);
-  }
-
   public final class PhysicalChannelConfig implements android.os.Parcelable {
     method public int describeContents();
     method @IntRange(from=1, to=261) public int getBand();
@@ -40474,7 +40386,7 @@
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field public static final int BAND_UNKNOWN = 0; // 0x0
     field public static final int CELL_BANDWIDTH_UNKNOWN = 0; // 0x0
-    field public static final int CHANNEL_NUMBER_UNKNOWN = -1; // 0xffffffff
+    field public static final int CHANNEL_NUMBER_UNKNOWN = 2147483647; // 0x7fffffff
     field public static final int CONNECTION_PRIMARY_SERVING = 1; // 0x1
     field public static final int CONNECTION_SECONDARY_SERVING = 2; // 0x2
     field public static final int CONNECTION_UNKNOWN = -1; // 0xffffffff
@@ -40929,6 +40841,94 @@
     method public android.telephony.SubscriptionPlan.Builder setTitle(@Nullable CharSequence);
   }
 
+  public class TelephonyCallback {
+    ctor public TelephonyCallback();
+  }
+
+  public static interface TelephonyCallback.ActiveDataSubscriptionIdListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onActiveDataSubscriptionIdChanged(int);
+  }
+
+  public static interface TelephonyCallback.AlwaysReportedSignalStrengthListener {
+    method @RequiresPermission("android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH") public void onSignalStrengthsChanged(@NonNull android.telephony.SignalStrength);
+  }
+
+  public static interface TelephonyCallback.BarringInfoListener {
+    method @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void onBarringInfoChanged(@NonNull android.telephony.BarringInfo);
+  }
+
+  public static interface TelephonyCallback.CallDisconnectCauseListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallDisconnectCauseChanged(int, int);
+  }
+
+  public static interface TelephonyCallback.CallForwardingIndicatorListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onCallForwardingIndicatorChanged(boolean);
+  }
+
+  public static interface TelephonyCallback.CallStateListener {
+    method @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) public void onCallStateChanged(int, @Nullable String);
+  }
+
+  public static interface TelephonyCallback.CarrierNetworkListener {
+    method public void onCarrierNetworkChange(boolean);
+  }
+
+  public static interface TelephonyCallback.CellInfoListener {
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void onCellInfoChanged(@NonNull java.util.List<android.telephony.CellInfo>);
+  }
+
+  public static interface TelephonyCallback.CellLocationListener {
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void onCellLocationChanged(@NonNull android.telephony.CellLocation);
+  }
+
+  public static interface TelephonyCallback.DataActivationStateListener {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onDataActivationStateChanged(int);
+  }
+
+  public static interface TelephonyCallback.DataActivityListener {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onDataActivity(int);
+  }
+
+  public static interface TelephonyCallback.DataConnectionStateListener {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onDataConnectionStateChanged(int, int);
+  }
+
+  public static interface TelephonyCallback.DisplayInfoListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo);
+  }
+
+  public static interface TelephonyCallback.EmergencyNumberListListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onEmergencyNumberListChanged(@NonNull java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>>);
+  }
+
+  public static interface TelephonyCallback.ImsCallDisconnectCauseListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo);
+  }
+
+  public static interface TelephonyCallback.MessageWaitingIndicatorListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onMessageWaitingIndicatorChanged(boolean);
+  }
+
+  public static interface TelephonyCallback.PreciseDataConnectionStateListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState);
+  }
+
+  public static interface TelephonyCallback.RegistrationFailedListener {
+    method @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void onRegistrationFailed(@NonNull android.telephony.CellIdentity, @NonNull String, int, int, int);
+  }
+
+  public static interface TelephonyCallback.ServiceStateListener {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onServiceStateChanged(@NonNull android.telephony.ServiceState);
+  }
+
+  public static interface TelephonyCallback.SignalStrengthsListener {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onSignalStrengthsChanged(@NonNull android.telephony.SignalStrength);
+  }
+
+  public static interface TelephonyCallback.UserMobileDataStateListener {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onUserMobileDataStateChanged(boolean);
+  }
+
   public final class TelephonyDisplayInfo implements android.os.Parcelable {
     method public int describeContents();
     method public int getNetworkType();
@@ -41039,7 +41039,7 @@
     method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle);
     method public boolean isWorldPhone();
     method @Deprecated public void listen(android.telephony.PhoneStateListener, int);
-    method public void registerPhoneStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.PhoneStateListener);
+    method public void registerTelephonyCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyCallback);
     method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestCellInfoUpdate(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
     method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, java.util.concurrent.Executor, android.telephony.TelephonyScanManager.NetworkScanCallback);
     method public void sendDialerSpecialCode(String);
@@ -41063,7 +41063,7 @@
     method @Deprecated public void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
     method @Deprecated public void setVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle, boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void switchMultiSimConfig(int);
-    method public void unregisterPhoneStateListener(@NonNull android.telephony.PhoneStateListener);
+    method public void unregisterTelephonyCallback(@NonNull android.telephony.TelephonyCallback);
     method public void updateAvailableNetworks(@NonNull java.util.List<android.telephony.AvailableNetworkInfo>, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
     field public static final String ACTION_CARRIER_MESSAGING_CLIENT_SERVICE = "android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE";
     field public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE = "android.telephony.action.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE";
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 3529858..6fb9630 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -6,6 +6,10 @@
     method public void setMaxManifestReceiverApiLevel(int);
   }
 
+  public final class PendingIntent implements android.os.Parcelable {
+    method @RequiresPermission("android.permission.GET_INTENT_SENDER_INTENT") public boolean intentFilterEquals(@Nullable android.app.PendingIntent);
+  }
+
 }
 
 package android.app.usage {
@@ -52,10 +56,21 @@
     field @NonNull public final java.util.List<java.lang.String> underlyingIfaces;
   }
 
+  public class VpnManager {
+    field @Deprecated public static final int TYPE_VPN_LEGACY = 3; // 0x3
+    field public static final int TYPE_VPN_NONE = -1; // 0xffffffff
+    field public static final int TYPE_VPN_PLATFORM = 2; // 0x2
+    field public static final int TYPE_VPN_SERVICE = 1; // 0x1
+  }
+
 }
 
 package android.os {
 
+  public final class BatteryStatsManager {
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void reportNetworkInterfaceForTransports(@NonNull String, @NonNull int[]) throws java.lang.RuntimeException;
+  }
+
   public class Binder implements android.os.IBinder {
     method public final void markVintfStability();
   }
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 505ac14..62a5f46 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -9607,51 +9607,16 @@
     method public static boolean isVoiceMailNumber(@NonNull android.content.Context, int, @Nullable String);
   }
 
-  public class PhoneStateListener {
-    method public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes);
+  @Deprecated public class PhoneStateListener {
+    method @Deprecated public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes);
     method @Deprecated public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
-    method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
+    method @Deprecated public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
     method @Deprecated public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber);
-    method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber, int);
-    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState);
-    method public void onRadioPowerStateChanged(int);
-    method public void onSrvccStateChanged(int);
-    method public void onVoiceActivationStateChanged(int);
-    field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED = 23; // 0x17
-    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED = 35; // 0x23
-    field @RequiresPermission("android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH") public static final int EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED = 10; // 0xa
-    field @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static final int EVENT_BARRING_INFO_CHANGED = 32; // 0x20
-    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_CALL_ATTRIBUTES_CHANGED = 27; // 0x1b
-    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_CALL_DISCONNECT_CAUSE_CHANGED = 26; // 0x1a
-    field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_CALL_FORWARDING_INDICATOR_CHANGED = 4; // 0x4
-    field @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) public static final int EVENT_CALL_STATE_CHANGED = 6; // 0x6
-    field public static final int EVENT_CARRIER_NETWORK_CHANGED = 17; // 0x11
-    field @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static final int EVENT_CELL_INFO_CHANGED = 11; // 0xb
-    field @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static final int EVENT_CELL_LOCATION_CHANGED = 5; // 0x5
-    field public static final int EVENT_DATA_ACTIVATION_STATE_CHANGED = 19; // 0x13
-    field public static final int EVENT_DATA_ACTIVITY_CHANGED = 8; // 0x8
-    field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED = 14; // 0xe
-    field public static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 7; // 0x7
-    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_DATA_ENABLED_CHANGED = 34; // 0x22
-    field public static final int EVENT_DISPLAY_INFO_CHANGED = 21; // 0x15
-    field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_EMERGENCY_NUMBER_LIST_CHANGED = 25; // 0x19
-    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED = 28; // 0x1c
-    field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_MESSAGE_WAITING_INDICATOR_CHANGED = 3; // 0x3
-    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_OEM_HOOK_RAW = 15; // 0xf
-    field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int EVENT_OUTGOING_EMERGENCY_CALL = 29; // 0x1d
-    field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int EVENT_OUTGOING_EMERGENCY_SMS = 30; // 0x1e
-    field public static final int EVENT_PHONE_CAPABILITY_CHANGED = 22; // 0x16
-    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 33; // 0x21
-    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_PRECISE_CALL_STATE_CHANGED = 12; // 0xc
-    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED = 13; // 0xd
-    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_RADIO_POWER_STATE_CHANGED = 24; // 0x18
-    field @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static final int EVENT_REGISTRATION_FAILURE = 31; // 0x1f
-    field public static final int EVENT_SERVICE_STATE_CHANGED = 1; // 0x1
-    field public static final int EVENT_SIGNAL_STRENGTHS_CHANGED = 9; // 0x9
-    field public static final int EVENT_SIGNAL_STRENGTH_CHANGED = 2; // 0x2
-    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_SRVCC_STATE_CHANGED = 16; // 0x10
-    field public static final int EVENT_USER_MOBILE_DATA_STATE_CHANGED = 20; // 0x14
-    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_VOICE_ACTIVATION_STATE_CHANGED = 18; // 0x12
+    method @Deprecated public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber, int);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState);
+    method @Deprecated public void onRadioPowerStateChanged(int);
+    method @Deprecated public void onSrvccStateChanged(int);
+    method @Deprecated public void onVoiceActivationStateChanged(int);
     field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000
     field @Deprecated @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
     field @Deprecated @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
@@ -9661,46 +9626,6 @@
     field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000
   }
 
-  public static interface PhoneStateListener.AllowedNetworkTypesChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onAllowedNetworkTypesChanged(@NonNull java.util.Map<java.lang.Integer,java.lang.Long>);
-  }
-
-  public static interface PhoneStateListener.CallAttributesChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes);
-  }
-
-  public static interface PhoneStateListener.DataEnabledChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onDataEnabledChanged(boolean, int);
-  }
-
-  public static interface PhoneStateListener.OutgoingEmergencyCallListener {
-    method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
-  }
-
-  public static interface PhoneStateListener.OutgoingEmergencySmsListener {
-    method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber, int);
-  }
-
-  public static interface PhoneStateListener.PhysicalChannelConfigChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPhysicalChannelConfigChanged(@NonNull java.util.List<android.telephony.PhysicalChannelConfig>);
-  }
-
-  public static interface PhoneStateListener.PreciseCallStateChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState);
-  }
-
-  public static interface PhoneStateListener.RadioPowerStateChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onRadioPowerStateChanged(int);
-  }
-
-  public static interface PhoneStateListener.SrvccStateChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onSrvccStateChanged(int);
-  }
-
-  public static interface PhoneStateListener.VoiceActivationStateChangedListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onVoiceActivationStateChanged(int);
-  }
-
   public final class PinResult implements android.os.Parcelable {
     method public int describeContents();
     method public int getAttemptsRemaining();
@@ -10034,6 +9959,88 @@
     method @Deprecated public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
   }
 
+  public class TelephonyCallback {
+    field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED = 23; // 0x17
+    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED = 35; // 0x23
+    field @RequiresPermission("android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH") public static final int EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED = 10; // 0xa
+    field @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static final int EVENT_BARRING_INFO_CHANGED = 32; // 0x20
+    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_CALL_ATTRIBUTES_CHANGED = 27; // 0x1b
+    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_CALL_DISCONNECT_CAUSE_CHANGED = 26; // 0x1a
+    field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_CALL_FORWARDING_INDICATOR_CHANGED = 4; // 0x4
+    field @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) public static final int EVENT_CALL_STATE_CHANGED = 6; // 0x6
+    field public static final int EVENT_CARRIER_NETWORK_CHANGED = 17; // 0x11
+    field @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static final int EVENT_CELL_INFO_CHANGED = 11; // 0xb
+    field @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static final int EVENT_CELL_LOCATION_CHANGED = 5; // 0x5
+    field public static final int EVENT_DATA_ACTIVATION_STATE_CHANGED = 19; // 0x13
+    field public static final int EVENT_DATA_ACTIVITY_CHANGED = 8; // 0x8
+    field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED = 14; // 0xe
+    field public static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 7; // 0x7
+    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_DATA_ENABLED_CHANGED = 34; // 0x22
+    field public static final int EVENT_DISPLAY_INFO_CHANGED = 21; // 0x15
+    field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_EMERGENCY_NUMBER_LIST_CHANGED = 25; // 0x19
+    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED = 28; // 0x1c
+    field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_MESSAGE_WAITING_INDICATOR_CHANGED = 3; // 0x3
+    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_OEM_HOOK_RAW = 15; // 0xf
+    field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int EVENT_OUTGOING_EMERGENCY_CALL = 29; // 0x1d
+    field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int EVENT_OUTGOING_EMERGENCY_SMS = 30; // 0x1e
+    field public static final int EVENT_PHONE_CAPABILITY_CHANGED = 22; // 0x16
+    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 33; // 0x21
+    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_PRECISE_CALL_STATE_CHANGED = 12; // 0xc
+    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED = 13; // 0xd
+    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_RADIO_POWER_STATE_CHANGED = 24; // 0x18
+    field @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static final int EVENT_REGISTRATION_FAILURE = 31; // 0x1f
+    field public static final int EVENT_SERVICE_STATE_CHANGED = 1; // 0x1
+    field public static final int EVENT_SIGNAL_STRENGTHS_CHANGED = 9; // 0x9
+    field public static final int EVENT_SIGNAL_STRENGTH_CHANGED = 2; // 0x2
+    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_SRVCC_STATE_CHANGED = 16; // 0x10
+    field public static final int EVENT_USER_MOBILE_DATA_STATE_CHANGED = 20; // 0x14
+    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_VOICE_ACTIVATION_STATE_CHANGED = 18; // 0x12
+  }
+
+  public static interface TelephonyCallback.AllowedNetworkTypesListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onAllowedNetworkTypesChanged(@NonNull java.util.Map<java.lang.Integer,java.lang.Long>);
+  }
+
+  public static interface TelephonyCallback.CallAttributesListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes);
+  }
+
+  public static interface TelephonyCallback.DataEnabledListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onDataEnabledChanged(boolean, int);
+  }
+
+  public static interface TelephonyCallback.OutgoingEmergencyCallListener {
+    method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
+  }
+
+  public static interface TelephonyCallback.OutgoingEmergencySmsListener {
+    method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber, int);
+  }
+
+  public static interface TelephonyCallback.PhoneCapabilityListener {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onPhoneCapabilityChanged(@NonNull android.telephony.PhoneCapability);
+  }
+
+  public static interface TelephonyCallback.PhysicalChannelConfigListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPhysicalChannelConfigChanged(@NonNull java.util.List<android.telephony.PhysicalChannelConfig>);
+  }
+
+  public static interface TelephonyCallback.PreciseCallStateListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState);
+  }
+
+  public static interface TelephonyCallback.RadioPowerStateListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onRadioPowerStateChanged(int);
+  }
+
+  public static interface TelephonyCallback.SrvccStateListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onSrvccStateChanged(int);
+  }
+
+  public static interface TelephonyCallback.VoiceActivationStateListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onVoiceActivationStateChanged(int);
+  }
+
   public final class TelephonyHistogram implements android.os.Parcelable {
     ctor public TelephonyHistogram(int, int, int);
     ctor public TelephonyHistogram(android.telephony.TelephonyHistogram);
@@ -10172,7 +10179,7 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult setIccLockEnabled(boolean, @NonNull String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMobileDataPolicyEnabledStatus(int, boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
-    method public int setNrDualConnectivityState(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setNrDualConnectivityState(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean);
@@ -11501,7 +11508,7 @@
     method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) public boolean isRcsVolteSingleRegistrationCapable() throws android.telephony.ims.ImsException;
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerProvisioningChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.Callback) throws android.telephony.ims.ImsException;
-    method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) public void registerRcsProvisioningChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.RcsProvisioningCallback) throws android.telephony.ims.ImsException;
+    method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) public void registerRcsProvisioningCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.RcsProvisioningCallback) throws android.telephony.ims.ImsException;
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningIntValue(int, int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setProvisioningStatusForCapability(int, int, boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
@@ -11509,7 +11516,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setRcsProvisioningStatusForCapability(int, boolean);
     method @RequiresPermission(android.Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION) public void triggerRcsReconfiguration();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
-    method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) public void unregisterRcsProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.RcsProvisioningCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) public void unregisterRcsProvisioningCallback(@NonNull android.telephony.ims.ProvisioningManager.RcsProvisioningCallback);
     field @RequiresPermission(android.Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION) public static final String ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE = "android.telephony.ims.action.RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE";
     field public static final String EXTRA_STATUS = "android.telephony.ims.extra.STATUS";
     field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.ims.extra.SUBSCRIPTION_ID";
@@ -11560,7 +11567,7 @@
     method @NonNull public String getServiceId();
     method @NonNull public String getServiceVersion();
     method @NonNull public String getStatus();
-    method @Nullable public String getTimestamp();
+    method @Nullable public java.time.Instant getTime();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RcsContactPresenceTuple> CREATOR;
     field public static final String SERVICE_ID_CALL_COMPOSER = "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.gsma.callcomposer";
@@ -11587,7 +11594,7 @@
     method @NonNull public android.telephony.ims.RcsContactPresenceTuple.Builder setContactUri(@NonNull android.net.Uri);
     method @NonNull public android.telephony.ims.RcsContactPresenceTuple.Builder setServiceCapabilities(@NonNull android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities);
     method @NonNull public android.telephony.ims.RcsContactPresenceTuple.Builder setServiceDescription(@NonNull String);
-    method @NonNull public android.telephony.ims.RcsContactPresenceTuple.Builder setTimestamp(@NonNull String);
+    method @NonNull public android.telephony.ims.RcsContactPresenceTuple.Builder setTime(@NonNull java.time.Instant);
   }
 
   public static final class RcsContactPresenceTuple.ServiceCapabilities implements android.os.Parcelable {
@@ -11643,7 +11650,7 @@
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getUcePublishState() throws android.telephony.ims.ImsException;
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void removeOnPublishStateChangedListener(@NonNull android.telephony.ims.RcsUceAdapter.OnPublishStateChangedListener) throws android.telephony.ims.ImsException;
     method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, android.Manifest.permission.READ_CONTACTS}) public void requestAvailability(@NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.CapabilitiesCallback) throws android.telephony.ims.ImsException;
-    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, android.Manifest.permission.READ_CONTACTS}) public void requestCapabilities(@NonNull java.util.List<android.net.Uri>, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.CapabilitiesCallback) throws android.telephony.ims.ImsException;
+    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, android.Manifest.permission.READ_CONTACTS}) public void requestCapabilities(@NonNull java.util.Collection<android.net.Uri>, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.CapabilitiesCallback) throws android.telephony.ims.ImsException;
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
     field public static final int CAPABILITY_TYPE_PRESENCE_UCE = 2; // 0x2
     field public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 1; // 0x1
@@ -12120,7 +12127,7 @@
     ctor public RcsCapabilityExchangeImplBase(@NonNull java.util.concurrent.Executor);
     method public void publishCapabilities(@NonNull String, @NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase.PublishResponseCallback);
     method public void sendOptionsCapabilityRequest(@NonNull android.net.Uri, @NonNull java.util.List<java.lang.String>, @NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase.OptionsResponseCallback);
-    method public void subscribeForCapabilities(@NonNull java.util.List<android.net.Uri>, @NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase.SubscribeResponseCallback);
+    method public void subscribeForCapabilities(@NonNull java.util.Collection<android.net.Uri>, @NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase.SubscribeResponseCallback);
     field public static final int COMMAND_CODE_FETCH_ERROR = 3; // 0x3
     field public static final int COMMAND_CODE_GENERIC_FAILURE = 1; // 0x1
     field public static final int COMMAND_CODE_INSUFFICIENT_MEMORY = 5; // 0x5
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 6872141..a0ff97e 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -248,6 +248,10 @@
     method public boolean matchesCallFilter(android.os.Bundle);
   }
 
+  public final class PendingIntent implements android.os.Parcelable {
+    method @RequiresPermission("android.permission.GET_INTENT_SENDER_INTENT") public boolean intentFilterEquals(@Nullable android.app.PendingIntent);
+  }
+
   public final class PictureInPictureParams implements android.os.Parcelable {
     method public java.util.List<android.app.RemoteAction> getActions();
     method public float getAspectRatio();
@@ -1600,6 +1604,10 @@
     method @NonNull public android.telecom.ConnectionRequest.Builder setVideoState(int);
   }
 
+  public abstract class ConnectionService extends android.app.Service {
+    method public void onBindClient(@Nullable android.content.Intent);
+  }
+
 }
 
 package android.telephony {
@@ -1629,10 +1637,10 @@
     method public static void setMinMatchForTest(int);
   }
 
-  public class PhoneStateListener {
-    method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
+  @Deprecated public class PhoneStateListener {
+    method @Deprecated public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
     method @Deprecated public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber);
-    method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber, int);
+    method @Deprecated public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber, int);
   }
 
   public final class PreciseDataConnectionState implements android.os.Parcelable {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b99d5cd..65f2c02 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2770,7 +2770,7 @@
                         memInfo.getTotalPrivateDirty(),
                         memInfo.getTotalPrivateClean(),
                         memInfo.hasSwappedOutPss ? memInfo.getTotalSwappedOutPss() :
-                        memInfo.getTotalSwappedOut(), memInfo.getTotalPss(),
+                        memInfo.getTotalSwappedOut(), memInfo.getTotalRss(),
                         nativeMax+dalvikMax,
                         nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
             }
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 41cac75..c89b53e 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -19,6 +19,9 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.IIntentReceiver;
@@ -1171,6 +1174,30 @@
     }
 
     /**
+     * Comparison operator on two PendingIntent objects, such that true is returned when they
+     * represent {@link Intent}s that are equal as per {@link Intent#filterEquals}.
+     *
+     * @param other The other PendingIntent to compare against.
+     * @return True if action, data, type, class, and categories on two intents are the same.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @TestApi
+    @RequiresPermission(android.Manifest.permission.GET_INTENT_SENDER_INTENT)
+    public boolean intentFilterEquals(@Nullable PendingIntent other) {
+        if (other == null) {
+            return false;
+        }
+        try {
+            return ActivityManager.getService().getIntentForIntentSender(other.mTarget)
+                    .filterEquals(getIntent());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Comparison operator on two PendingIntent objects, such that true
      * is returned then they both represent the same operation from the
      * same package.  This allows you to use {@link #getActivity},
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 53aaae0..16413e1 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -139,7 +139,7 @@
      * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @UnsupportedAppUsage(trackingBug = 181103983)
     public static final String ACTION_CODEC_CONFIG_CHANGED =
             "android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED";
 
@@ -684,7 +684,7 @@
      * @return the current codec status
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @UnsupportedAppUsage(trackingBug = 181103983)
     @Nullable
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public BluetoothCodecStatus getCodecStatus(@NonNull BluetoothDevice device) {
@@ -713,7 +713,7 @@
      * @param codecConfig the codec configuration preference
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @UnsupportedAppUsage(trackingBug = 181103983)
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public void setCodecConfigPreference(@NonNull BluetoothDevice device,
                                          @NonNull BluetoothCodecConfig codecConfig) {
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index a5ece7b..b037261 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -179,21 +179,6 @@
     }
 
     /**
-     * Build a {@link NetworkIdentity} from the given {@link NetworkState} and
-     * {@code subType}, assuming that any mobile networks are using the current IMSI.
-     * The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_*
-     * constants, or {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not.
-     */
-    // TODO: Delete this function after NetworkPolicyManagerService finishes the migration.
-    public static NetworkIdentity buildNetworkIdentity(Context context,
-            NetworkState state, boolean defaultNetwork, @NetworkType int subType) {
-        final NetworkStateSnapshot snapshot = new NetworkStateSnapshot(state.network,
-                state.networkCapabilities, state.linkProperties, state.subscriberId,
-                state.legacyNetworkType);
-        return buildNetworkIdentity(context, snapshot, defaultNetwork, subType);
-    }
-
-    /**
      * Build a {@link NetworkIdentity} from the given {@link NetworkStateSnapshot} and
      * {@code subType}, assuming that any mobile networks are using the current IMSI.
      * The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_*
diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java
index f472ed4..77754d1 100644
--- a/core/java/android/net/VpnManager.java
+++ b/core/java/android/net/VpnManager.java
@@ -16,12 +16,15 @@
 
 package android.net;
 
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
 import static com.android.internal.util.Preconditions.checkNotNull;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.annotation.UserIdInt;
 import android.app.Activity;
 import android.content.ComponentName;
@@ -56,18 +59,21 @@
  */
 public class VpnManager {
     /** Type representing a lack of VPN @hide */
+    @SystemApi(client = MODULE_LIBRARIES)
     public static final int TYPE_VPN_NONE = -1;
 
     /**
      * A VPN created by an app using the {@link VpnService} API.
      * @hide
      */
+    @SystemApi(client = MODULE_LIBRARIES)
     public static final int TYPE_VPN_SERVICE = 1;
 
     /**
      * A VPN created using a {@link VpnManager} API such as {@link #startProvisionedVpnProfile}.
      * @hide
      */
+    @SystemApi(client = MODULE_LIBRARIES)
     public static final int TYPE_VPN_PLATFORM = 2;
 
     /**
@@ -76,6 +82,7 @@
      * @hide
      */
     @Deprecated
+    @SystemApi(client = MODULE_LIBRARIES)
     public static final int TYPE_VPN_LEGACY = 3;
 
     /**
diff --git a/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java b/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
index de086f6..22d7faf 100644
--- a/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
+++ b/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
@@ -19,11 +19,13 @@
 import static android.net.vcn.VcnControlPlaneConfig.CONFIG_TYPE_IKE;
 
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.net.ipsec.ike.IkeSessionParams;
 import android.net.ipsec.ike.TunnelModeChildSessionParams;
+import android.net.vcn.persistablebundleutils.IkeSessionParamsUtils;
+import android.net.vcn.persistablebundleutils.TunnelModeChildSessionParamsUtils;
 import android.os.PersistableBundle;
 import android.util.ArraySet;
+import android.util.Log;
 
 import java.util.Objects;
 
@@ -38,14 +40,11 @@
 public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig {
     private static final String TAG = VcnControlPlaneIkeConfig.class.getSimpleName();
 
-    // STOPSHIP: b/163604823 Make mIkeParams and mChildParams @NonNull when it is supported to
-    // construct mIkeParams and mChildParams from PersistableBundles.
-
     private static final String IKE_PARAMS_KEY = "mIkeParams";
-    @Nullable private final IkeSessionParams mIkeParams;
+    @NonNull private final IkeSessionParams mIkeParams;
 
     private static final String CHILD_PARAMS_KEY = "mChildParams";
-    @Nullable private final TunnelModeChildSessionParams mChildParams;
+    @NonNull private final TunnelModeChildSessionParams mChildParams;
 
     private static final ArraySet<String> BUNDLE_KEY_SET = new ArraySet<>();
 
@@ -80,11 +79,19 @@
         final PersistableBundle ikeParamsBundle = in.getPersistableBundle(IKE_PARAMS_KEY);
         final PersistableBundle childParamsBundle = in.getPersistableBundle(CHILD_PARAMS_KEY);
 
-        // STOPSHIP: b/163604823 Support constructing mIkeParams and mChildParams from
-        // PersistableBundles.
+        Objects.requireNonNull(ikeParamsBundle, "IKE Session Params was null");
+        Objects.requireNonNull(childParamsBundle, "Child Session Params was null");
 
-        mIkeParams = null;
-        mChildParams = null;
+        mIkeParams = IkeSessionParamsUtils.fromPersistableBundle(ikeParamsBundle);
+        mChildParams = TunnelModeChildSessionParamsUtils.fromPersistableBundle(childParamsBundle);
+
+        for (String key : in.keySet()) {
+            if (!BUNDLE_KEY_SET.contains(key)) {
+                Log.w(TAG, "Found an unexpected key in the PersistableBundle: " + key);
+            }
+        }
+
+        validate();
     }
 
     private void validate() {
@@ -101,9 +108,11 @@
     @NonNull
     public PersistableBundle toPersistableBundle() {
         final PersistableBundle result = super.toPersistableBundle();
-
-        // STOPSHIP: b/163604823 Support converting mIkeParams and mChildParams to
-        // PersistableBundles.
+        result.putPersistableBundle(
+                IKE_PARAMS_KEY, IkeSessionParamsUtils.toPersistableBundle(mIkeParams));
+        result.putPersistableBundle(
+                CHILD_PARAMS_KEY,
+                TunnelModeChildSessionParamsUtils.toPersistableBundle(mChildParams));
         return result;
     }
 
@@ -134,10 +143,9 @@
 
         VcnControlPlaneIkeConfig other = (VcnControlPlaneIkeConfig) o;
 
-        // STOPSHIP: b/163604823 Also check mIkeParams and mChildParams when it is supported to
-        // construct mIkeParams and mChildParams from PersistableBundles. They are not checked
-        // now so that VcnGatewayConnectionConfigTest and VcnConfigTest can pass.
-        return super.equals(o);
+        return super.equals(o)
+                && Objects.equals(mIkeParams, other.mIkeParams)
+                && Objects.equals(mChildParams, other.mChildParams);
     }
 
     /** @hide */
diff --git a/core/java/android/net/vcn/persistablebundleutils/CertUtils.java b/core/java/android/net/vcn/persistablebundleutils/CertUtils.java
index b6036b4..35b3186 100644
--- a/core/java/android/net/vcn/persistablebundleutils/CertUtils.java
+++ b/core/java/android/net/vcn/persistablebundleutils/CertUtils.java
@@ -18,18 +18,24 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
 import java.util.Objects;
 
 /**
- * CertUtils provides utility methods for constructing Certificate.
+ * CertUtils provides utility methods for constructing Certificate and PrivateKey.
  *
  * @hide
  */
 public class CertUtils {
     private static final String CERT_TYPE_X509 = "X.509";
+    private static final String PRIVATE_KEY_TYPE_RSA = "RSA";
 
     /** Decodes an ASN.1 DER encoded Certificate */
     public static X509Certificate certificateFromByteArray(byte[] derEncoded) {
@@ -43,4 +49,18 @@
             throw new IllegalArgumentException("Fail to decode certificate", e);
         }
     }
+
+    /** Decodes a PKCS#8 encoded RSA private key */
+    public static RSAPrivateKey privateKeyFromByteArray(byte[] pkcs8Encoded) {
+        Objects.requireNonNull(pkcs8Encoded, "pkcs8Encoded was null");
+        PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(pkcs8Encoded);
+
+        try {
+            KeyFactory keyFactory = KeyFactory.getInstance(PRIVATE_KEY_TYPE_RSA);
+
+            return (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec);
+        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+            throw new IllegalArgumentException("Fail to decode PrivateKey", e);
+        }
+    }
 }
diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java
new file mode 100644
index 0000000..9d3462c
--- /dev/null
+++ b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java
@@ -0,0 +1,513 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.vcn.persistablebundleutils;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.InetAddresses;
+import android.net.eap.EapSessionConfig;
+import android.net.ipsec.ike.IkeSaProposal;
+import android.net.ipsec.ike.IkeSessionParams;
+import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv4PcscfServer;
+import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv6PcscfServer;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignLocalConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeConfigRequest;
+import android.os.PersistableBundle;
+import android.util.ArraySet;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.vcn.util.PersistableBundleUtils;
+
+import java.net.InetAddress;
+import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Abstract utility class to convert IkeSessionParams to/from PersistableBundle.
+ *
+ * @hide
+ */
+@VisibleForTesting(visibility = Visibility.PRIVATE)
+public final class IkeSessionParamsUtils {
+    private static final String SERVER_HOST_NAME_KEY = "SERVER_HOST_NAME_KEY";
+    private static final String SA_PROPOSALS_KEY = "SA_PROPOSALS_KEY";
+    private static final String LOCAL_ID_KEY = "LOCAL_ID_KEY";
+    private static final String REMOTE_ID_KEY = "REMOTE_ID_KEY";
+    private static final String LOCAL_AUTH_KEY = "LOCAL_AUTH_KEY";
+    private static final String REMOTE_AUTH_KEY = "REMOTE_AUTH_KEY";
+    private static final String CONFIG_REQUESTS_KEY = "CONFIG_REQUESTS_KEY";
+    private static final String RETRANS_TIMEOUTS_KEY = "RETRANS_TIMEOUTS_KEY";
+    private static final String HARD_LIFETIME_SEC_KEY = "HARD_LIFETIME_SEC_KEY";
+    private static final String SOFT_LIFETIME_SEC_KEY = "SOFT_LIFETIME_SEC_KEY";
+    private static final String DPD_DELAY_SEC_KEY = "DPD_DELAY_SEC_KEY";
+    private static final String NATT_KEEPALIVE_DELAY_SEC_KEY = "NATT_KEEPALIVE_DELAY_SEC_KEY";
+    private static final String IKE_OPTIONS_KEY = "IKE_OPTIONS_KEY";
+
+    private static final Set<Integer> IKE_OPTIONS = new ArraySet<>();
+
+    static {
+        IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID);
+        IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH);
+        IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_MOBIKE);
+    }
+
+    /** Serializes an IkeSessionParams to a PersistableBundle. */
+    @NonNull
+    public static PersistableBundle toPersistableBundle(@NonNull IkeSessionParams params) {
+        if (params.getConfiguredNetwork() != null || params.getIke3gppExtension() != null) {
+            throw new IllegalStateException(
+                    "Cannot convert a IkeSessionParams with a caller configured network or with"
+                            + " 3GPP extension enabled");
+        }
+
+        final PersistableBundle result = new PersistableBundle();
+
+        result.putString(SERVER_HOST_NAME_KEY, params.getServerHostname());
+
+        final PersistableBundle saProposalBundle =
+                PersistableBundleUtils.fromList(
+                        params.getSaProposals(), IkeSaProposalUtils::toPersistableBundle);
+        result.putPersistableBundle(SA_PROPOSALS_KEY, saProposalBundle);
+
+        result.putPersistableBundle(
+                LOCAL_ID_KEY,
+                IkeIdentificationUtils.toPersistableBundle(params.getLocalIdentification()));
+        result.putPersistableBundle(
+                REMOTE_ID_KEY,
+                IkeIdentificationUtils.toPersistableBundle(params.getRemoteIdentification()));
+
+        result.putPersistableBundle(
+                LOCAL_AUTH_KEY, AuthConfigUtils.toPersistableBundle(params.getLocalAuthConfig()));
+        result.putPersistableBundle(
+                REMOTE_AUTH_KEY, AuthConfigUtils.toPersistableBundle(params.getRemoteAuthConfig()));
+
+        final List<ConfigRequest> reqList = new ArrayList<>();
+        for (IkeConfigRequest req : params.getConfigurationRequests()) {
+            reqList.add(new ConfigRequest(req));
+        }
+        final PersistableBundle configReqListBundle =
+                PersistableBundleUtils.fromList(reqList, ConfigRequest::toPersistableBundle);
+        result.putPersistableBundle(CONFIG_REQUESTS_KEY, configReqListBundle);
+
+        result.putIntArray(RETRANS_TIMEOUTS_KEY, params.getRetransmissionTimeoutsMillis());
+        result.putInt(HARD_LIFETIME_SEC_KEY, params.getHardLifetimeSeconds());
+        result.putInt(SOFT_LIFETIME_SEC_KEY, params.getSoftLifetimeSeconds());
+        result.putInt(DPD_DELAY_SEC_KEY, params.getDpdDelaySeconds());
+        result.putInt(NATT_KEEPALIVE_DELAY_SEC_KEY, params.getNattKeepAliveDelaySeconds());
+
+        final List<Integer> enabledIkeOptions = new ArrayList<>();
+        for (int option : IKE_OPTIONS) {
+            if (params.hasIkeOption(option)) {
+                enabledIkeOptions.add(option);
+            }
+        }
+
+        final int[] optionArray = enabledIkeOptions.stream().mapToInt(i -> i).toArray();
+        result.putIntArray(IKE_OPTIONS_KEY, optionArray);
+
+        return result;
+    }
+
+    /** Constructs an IkeSessionParams by deserializing a PersistableBundle. */
+    @NonNull
+    public static IkeSessionParams fromPersistableBundle(@NonNull PersistableBundle in) {
+        Objects.requireNonNull(in, "PersistableBundle is null");
+
+        final IkeSessionParams.Builder builder = new IkeSessionParams.Builder();
+
+        builder.setServerHostname(in.getString(SERVER_HOST_NAME_KEY));
+
+        PersistableBundle proposalBundle = in.getPersistableBundle(SA_PROPOSALS_KEY);
+        Objects.requireNonNull(in, "SA Proposals was null");
+        List<IkeSaProposal> saProposals =
+                PersistableBundleUtils.toList(
+                        proposalBundle, IkeSaProposalUtils::fromPersistableBundle);
+        for (IkeSaProposal proposal : saProposals) {
+            builder.addSaProposal(proposal);
+        }
+
+        builder.setLocalIdentification(
+                IkeIdentificationUtils.fromPersistableBundle(
+                        in.getPersistableBundle(LOCAL_ID_KEY)));
+        builder.setRemoteIdentification(
+                IkeIdentificationUtils.fromPersistableBundle(
+                        in.getPersistableBundle(REMOTE_ID_KEY)));
+
+        AuthConfigUtils.setBuilderByReadingPersistableBundle(
+                in.getPersistableBundle(LOCAL_AUTH_KEY),
+                in.getPersistableBundle(REMOTE_AUTH_KEY),
+                builder);
+
+        builder.setRetransmissionTimeoutsMillis(in.getIntArray(RETRANS_TIMEOUTS_KEY));
+        builder.setLifetimeSeconds(
+                in.getInt(HARD_LIFETIME_SEC_KEY), in.getInt(SOFT_LIFETIME_SEC_KEY));
+        builder.setDpdDelaySeconds(in.getInt(DPD_DELAY_SEC_KEY));
+        builder.setNattKeepAliveDelaySeconds(in.getInt(NATT_KEEPALIVE_DELAY_SEC_KEY));
+
+        final PersistableBundle configReqListBundle = in.getPersistableBundle(CONFIG_REQUESTS_KEY);
+        Objects.requireNonNull(configReqListBundle, "Config request list was null");
+        final List<ConfigRequest> reqList =
+                PersistableBundleUtils.toList(configReqListBundle, ConfigRequest::new);
+        for (ConfigRequest req : reqList) {
+            switch (req.type) {
+                case ConfigRequest.IPV4_P_CSCF_ADDRESS:
+                    if (req.address == null) {
+                        builder.addPcscfServerRequest(AF_INET);
+                    } else {
+                        builder.addPcscfServerRequest(req.address);
+                    }
+                    break;
+                case ConfigRequest.IPV6_P_CSCF_ADDRESS:
+                    if (req.address == null) {
+                        builder.addPcscfServerRequest(AF_INET6);
+                    } else {
+                        builder.addPcscfServerRequest(req.address);
+                    }
+                    break;
+                default:
+                    throw new IllegalArgumentException(
+                            "Unrecognized config request type: " + req.type);
+            }
+        }
+
+        // Clear IKE Options that are by default enabled
+        for (int option : IKE_OPTIONS) {
+            builder.removeIkeOption(option);
+        }
+
+        final int[] optionArray = in.getIntArray(IKE_OPTIONS_KEY);
+        for (int option : optionArray) {
+            builder.addIkeOption(option);
+        }
+
+        return builder.build();
+    }
+
+    private static final class AuthConfigUtils {
+        private static final int IKE_AUTH_METHOD_PSK = 1;
+        private static final int IKE_AUTH_METHOD_PUB_KEY_SIGNATURE = 2;
+        private static final int IKE_AUTH_METHOD_EAP = 3;
+
+        private static final String AUTH_METHOD_KEY = "AUTH_METHOD_KEY";
+
+        @NonNull
+        public static PersistableBundle toPersistableBundle(@NonNull IkeAuthConfig authConfig) {
+            if (authConfig instanceof IkeAuthPskConfig) {
+                IkeAuthPskConfig config = (IkeAuthPskConfig) authConfig;
+                return IkeAuthPskConfigUtils.toPersistableBundle(
+                        config, createPersistableBundle(IKE_AUTH_METHOD_PSK));
+            } else if (authConfig instanceof IkeAuthDigitalSignLocalConfig) {
+                IkeAuthDigitalSignLocalConfig config = (IkeAuthDigitalSignLocalConfig) authConfig;
+                return IkeAuthDigitalSignConfigUtils.toPersistableBundle(
+                        config, createPersistableBundle(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE));
+            } else if (authConfig instanceof IkeAuthDigitalSignRemoteConfig) {
+                IkeAuthDigitalSignRemoteConfig config = (IkeAuthDigitalSignRemoteConfig) authConfig;
+                return IkeAuthDigitalSignConfigUtils.toPersistableBundle(
+                        config, createPersistableBundle(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE));
+            } else if (authConfig instanceof IkeAuthEapConfig) {
+                IkeAuthEapConfig config = (IkeAuthEapConfig) authConfig;
+                return IkeAuthEapConfigUtils.toPersistableBundle(
+                        config, createPersistableBundle(IKE_AUTH_METHOD_EAP));
+            } else {
+                throw new IllegalStateException("Invalid IkeAuthConfig subclass");
+            }
+        }
+
+        private static PersistableBundle createPersistableBundle(int type) {
+            final PersistableBundle result = new PersistableBundle();
+            result.putInt(AUTH_METHOD_KEY, type);
+            return result;
+        }
+
+        public static void setBuilderByReadingPersistableBundle(
+                @NonNull PersistableBundle localAuthBundle,
+                @NonNull PersistableBundle remoteAuthBundle,
+                @NonNull IkeSessionParams.Builder builder) {
+            Objects.requireNonNull(localAuthBundle, "localAuthBundle was null");
+            Objects.requireNonNull(remoteAuthBundle, "remoteAuthBundle was null");
+
+            final int localMethodType = localAuthBundle.getInt(AUTH_METHOD_KEY);
+            final int remoteMethodType = remoteAuthBundle.getInt(AUTH_METHOD_KEY);
+            switch (localMethodType) {
+                case IKE_AUTH_METHOD_PSK:
+                    if (remoteMethodType != IKE_AUTH_METHOD_PSK) {
+                        throw new IllegalArgumentException(
+                                "Expect remote auth method to be PSK based, but was "
+                                        + remoteMethodType);
+                    }
+                    IkeAuthPskConfigUtils.setBuilderByReadingPersistableBundle(
+                            localAuthBundle, remoteAuthBundle, builder);
+                    return;
+                case IKE_AUTH_METHOD_PUB_KEY_SIGNATURE:
+                    if (remoteMethodType != IKE_AUTH_METHOD_PUB_KEY_SIGNATURE) {
+                        throw new IllegalArgumentException(
+                                "Expect remote auth method to be digital signature based, but was "
+                                        + remoteMethodType);
+                    }
+                    IkeAuthDigitalSignConfigUtils.setBuilderByReadingPersistableBundle(
+                            localAuthBundle, remoteAuthBundle, builder);
+                    return;
+                case IKE_AUTH_METHOD_EAP:
+                    if (remoteMethodType != IKE_AUTH_METHOD_PUB_KEY_SIGNATURE) {
+                        throw new IllegalArgumentException(
+                                "When using EAP for local authentication, expect remote auth"
+                                        + " method to be digital signature based, but was "
+                                        + remoteMethodType);
+                    }
+                    IkeAuthEapConfigUtils.setBuilderByReadingPersistableBundle(
+                            localAuthBundle, remoteAuthBundle, builder);
+                    return;
+                default:
+                    throw new IllegalArgumentException(
+                            "Invalid EAP method type " + localMethodType);
+            }
+        }
+    }
+
+    private static final class IkeAuthPskConfigUtils {
+        private static final String PSK_KEY = "PSK_KEY";
+
+        @NonNull
+        public static PersistableBundle toPersistableBundle(
+                @NonNull IkeAuthPskConfig config, @NonNull PersistableBundle result) {
+            result.putPersistableBundle(
+                    PSK_KEY, PersistableBundleUtils.fromByteArray(config.getPsk()));
+            return result;
+        }
+
+        public static void setBuilderByReadingPersistableBundle(
+                @NonNull PersistableBundle localAuthBundle,
+                @NonNull PersistableBundle remoteAuthBundle,
+                @NonNull IkeSessionParams.Builder builder) {
+            Objects.requireNonNull(localAuthBundle, "localAuthBundle was null");
+            Objects.requireNonNull(remoteAuthBundle, "remoteAuthBundle was null");
+
+            final PersistableBundle localPskBundle = localAuthBundle.getPersistableBundle(PSK_KEY);
+            final PersistableBundle remotePskBundle =
+                    remoteAuthBundle.getPersistableBundle(PSK_KEY);
+            Objects.requireNonNull(localAuthBundle, "Local PSK was null");
+            Objects.requireNonNull(remoteAuthBundle, "Remote PSK was null");
+
+            final byte[] localPsk = PersistableBundleUtils.toByteArray(localPskBundle);
+            final byte[] remotePsk = PersistableBundleUtils.toByteArray(remotePskBundle);
+            if (!Arrays.equals(localPsk, remotePsk)) {
+                throw new IllegalArgumentException("Local PSK and remote PSK are different");
+            }
+            builder.setAuthPsk(localPsk);
+        }
+    }
+
+    private static class IkeAuthDigitalSignConfigUtils {
+        private static final String END_CERT_KEY = "END_CERT_KEY";
+        private static final String INTERMEDIATE_CERTS_KEY = "INTERMEDIATE_CERTS_KEY";
+        private static final String PRIVATE_KEY_KEY = "PRIVATE_KEY_KEY";
+        private static final String TRUST_CERT_KEY = "TRUST_CERT_KEY";
+
+        @NonNull
+        public static PersistableBundle toPersistableBundle(
+                @NonNull IkeAuthDigitalSignLocalConfig config, @NonNull PersistableBundle result) {
+            try {
+                result.putPersistableBundle(
+                        END_CERT_KEY,
+                        PersistableBundleUtils.fromByteArray(
+                                config.getClientEndCertificate().getEncoded()));
+
+                final List<X509Certificate> certList = config.getIntermediateCertificates();
+                final List<byte[]> encodedCertList = new ArrayList<>(certList.size());
+                for (X509Certificate cert : certList) {
+                    encodedCertList.add(cert.getEncoded());
+                }
+
+                final PersistableBundle certsBundle =
+                        PersistableBundleUtils.fromList(
+                                encodedCertList, PersistableBundleUtils::fromByteArray);
+                result.putPersistableBundle(INTERMEDIATE_CERTS_KEY, certsBundle);
+            } catch (CertificateEncodingException e) {
+                throw new IllegalArgumentException("Fail to encode certificate");
+            }
+
+            // TODO: b/170670506 Consider putting PrivateKey in Android KeyStore
+            result.putPersistableBundle(
+                    PRIVATE_KEY_KEY,
+                    PersistableBundleUtils.fromByteArray(config.getPrivateKey().getEncoded()));
+            return result;
+        }
+
+        @NonNull
+        public static PersistableBundle toPersistableBundle(
+                @NonNull IkeAuthDigitalSignRemoteConfig config, @NonNull PersistableBundle result) {
+            try {
+                X509Certificate caCert = config.getRemoteCaCert();
+                if (caCert != null) {
+                    result.putPersistableBundle(
+                            TRUST_CERT_KEY,
+                            PersistableBundleUtils.fromByteArray(caCert.getEncoded()));
+                }
+            } catch (CertificateEncodingException e) {
+                throw new IllegalArgumentException("Fail to encode the certificate");
+            }
+
+            return result;
+        }
+
+        public static void setBuilderByReadingPersistableBundle(
+                @NonNull PersistableBundle localAuthBundle,
+                @NonNull PersistableBundle remoteAuthBundle,
+                @NonNull IkeSessionParams.Builder builder) {
+            Objects.requireNonNull(localAuthBundle, "localAuthBundle was null");
+            Objects.requireNonNull(remoteAuthBundle, "remoteAuthBundle was null");
+
+            // Deserialize localAuth
+            final PersistableBundle endCertBundle =
+                    localAuthBundle.getPersistableBundle(END_CERT_KEY);
+            Objects.requireNonNull(endCertBundle, "End cert was null");
+            final byte[] encodedCert = PersistableBundleUtils.toByteArray(endCertBundle);
+            final X509Certificate endCert = CertUtils.certificateFromByteArray(encodedCert);
+
+            final PersistableBundle certsBundle =
+                    localAuthBundle.getPersistableBundle(INTERMEDIATE_CERTS_KEY);
+            Objects.requireNonNull(certsBundle, "Intermediate certs was null");
+            final List<byte[]> encodedCertList =
+                    PersistableBundleUtils.toList(certsBundle, PersistableBundleUtils::toByteArray);
+            final List<X509Certificate> certList = new ArrayList<>(encodedCertList.size());
+            for (byte[] encoded : encodedCertList) {
+                certList.add(CertUtils.certificateFromByteArray(encoded));
+            }
+
+            final PersistableBundle privateKeyBundle =
+                    localAuthBundle.getPersistableBundle(PRIVATE_KEY_KEY);
+            Objects.requireNonNull(privateKeyBundle, "PrivateKey bundle was null");
+            final PrivateKey privateKey =
+                    CertUtils.privateKeyFromByteArray(
+                            PersistableBundleUtils.toByteArray(privateKeyBundle));
+
+            // Deserialize remoteAuth
+            final PersistableBundle trustCertBundle =
+                    remoteAuthBundle.getPersistableBundle(TRUST_CERT_KEY);
+
+            X509Certificate caCert = null;
+            if (trustCertBundle != null) {
+                final byte[] encodedCaCert = PersistableBundleUtils.toByteArray(trustCertBundle);
+                caCert = CertUtils.certificateFromByteArray(encodedCaCert);
+            }
+
+            builder.setAuthDigitalSignature(caCert, endCert, certList, privateKey);
+        }
+    }
+
+    private static final class IkeAuthEapConfigUtils {
+        private static final String EAP_CONFIG_KEY = "EAP_CONFIG_KEY";
+
+        @NonNull
+        public static PersistableBundle toPersistableBundle(
+                @NonNull IkeAuthEapConfig config, @NonNull PersistableBundle result) {
+            result.putPersistableBundle(
+                    EAP_CONFIG_KEY,
+                    EapSessionConfigUtils.toPersistableBundle(config.getEapConfig()));
+            return result;
+        }
+
+        public static void setBuilderByReadingPersistableBundle(
+                @NonNull PersistableBundle localAuthBundle,
+                @NonNull PersistableBundle remoteAuthBundle,
+                @NonNull IkeSessionParams.Builder builder) {
+            // Deserialize localAuth
+            final PersistableBundle eapBundle =
+                    localAuthBundle.getPersistableBundle(EAP_CONFIG_KEY);
+            Objects.requireNonNull(eapBundle, "EAP Config was null");
+            final EapSessionConfig eapConfig =
+                    EapSessionConfigUtils.fromPersistableBundle(eapBundle);
+
+            // Deserialize remoteAuth
+            final PersistableBundle trustCertBundle =
+                    remoteAuthBundle.getPersistableBundle(
+                            IkeAuthDigitalSignConfigUtils.TRUST_CERT_KEY);
+
+            X509Certificate serverCaCert = null;
+            if (trustCertBundle != null) {
+                final byte[] encodedCaCert = PersistableBundleUtils.toByteArray(trustCertBundle);
+                serverCaCert = CertUtils.certificateFromByteArray(encodedCaCert);
+            }
+            builder.setAuthEap(serverCaCert, eapConfig);
+        }
+    }
+
+    private static final class ConfigRequest {
+        private static final int IPV4_P_CSCF_ADDRESS = 1;
+        private static final int IPV6_P_CSCF_ADDRESS = 2;
+
+        private static final String TYPE_KEY = "type";
+        private static final String ADDRESS_KEY = "address";
+
+        public final int type;
+
+        // Null when it is an empty request
+        @Nullable public final InetAddress address;
+
+        ConfigRequest(IkeConfigRequest config) {
+            if (config instanceof ConfigRequestIpv4PcscfServer) {
+                type = IPV4_P_CSCF_ADDRESS;
+                address = ((ConfigRequestIpv4PcscfServer) config).getAddress();
+            } else if (config instanceof ConfigRequestIpv6PcscfServer) {
+                type = IPV6_P_CSCF_ADDRESS;
+                address = ((ConfigRequestIpv6PcscfServer) config).getAddress();
+            } else {
+                throw new IllegalStateException("Unknown TunnelModeChildConfigRequest");
+            }
+        }
+
+        ConfigRequest(PersistableBundle in) {
+            Objects.requireNonNull(in, "PersistableBundle was null");
+
+            type = in.getInt(TYPE_KEY);
+
+            String addressStr = in.getString(ADDRESS_KEY);
+            if (addressStr == null) {
+                address = null;
+            } else {
+                address = InetAddresses.parseNumericAddress(addressStr);
+            }
+        }
+
+        @NonNull
+        public PersistableBundle toPersistableBundle() {
+            final PersistableBundle result = new PersistableBundle();
+
+            result.putInt(TYPE_KEY, type);
+            if (address != null) {
+                result.putString(ADDRESS_KEY, address.getHostAddress());
+            }
+
+            return result;
+        }
+    }
+}
diff --git a/core/java/android/os/BatteryStatsManager.java b/core/java/android/os/BatteryStatsManager.java
index 258e58d..3f4a218 100644
--- a/core/java/android/os/BatteryStatsManager.java
+++ b/core/java/android/os/BatteryStatsManager.java
@@ -24,6 +24,7 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.content.Context;
+import android.net.NetworkStack;
 import android.os.connectivity.CellularBatteryStats;
 import android.os.connectivity.WifiBatteryStats;
 import android.telephony.DataConnectionRealTimeInfo;
@@ -416,10 +417,31 @@
         }
     }
 
+    /**
+     * Notifies the battery stats of a new interface, and the transport types of the network that
+     * includes that interface.
+     *
+     * @param iface The interface of the network.
+     * @param transportTypes The transport type of the network {@link Transport}.
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
+    public void reportNetworkInterfaceForTransports(@NonNull String iface,
+            @NonNull int[] transportTypes) throws RuntimeException {
+        try {
+            mBatteryStats.noteNetworkInterfaceForTransports(iface, transportTypes);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
     private static int getDataConnectionPowerState(boolean isActive) {
         // TODO: DataConnectionRealTimeInfo is under telephony package but the constants are used
-        // for both Wifi and mobile. It would make more sense to separate the constants to a generic
-        // class or move it to generic package.
+        // for both Wifi and mobile. It would make more sense to separate the constants to a
+        // generic class or move it to generic package.
         return isActive ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
                 : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
     }
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index a4d6c38..0264d23 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1235,9 +1235,9 @@
     }
 
     /**
-     * Creates a directory with name {@code name} under an existing directory {@code baseDir}.
-     * Returns a {@code File} object representing the directory on success, {@code null} on
-     * failure.
+     * Creates a directory with name {@code name} under an existing directory {@code baseDir} if it
+     * doesn't exist already. Returns a {@code File} object representing the directory if it exists
+     * and {@code null} if not.
      *
      * @hide
      */
@@ -1247,13 +1247,23 @@
         return createDir(dir) ? dir : null;
     }
 
-    /** @hide */
+    /**
+     * Ensure the given directory exists, creating it if needed. This method is threadsafe.
+     *
+     * @return false if the directory doesn't exist and couldn't be created
+     *
+     * @hide
+     */
     public static boolean createDir(File dir) {
+        if (dir.mkdir()) {
+            return true;
+        }
+
         if (dir.exists()) {
             return dir.isDirectory();
         }
 
-        return dir.mkdir();
+        return false;
     }
 
     /**
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 6c49b36..d966595 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -54,7 +54,7 @@
 per-file IHwBinder.java = file:platform/system/libhwbinder:/OWNERS
 per-file IHwInterface.java = file:platform/system/libhwbinder:/OWNERS
 
-per-file GraphicsEnvironment.java = chrisforbes@google.com, cnorthrop@google.com, lpy@google.com, timvp@google.com, zzyiwei@google.com
+per-file GraphicsEnvironment.java = file:platform/frameworks/native:/opengl/OWNERS
 
 per-file *Network* = file:/services/core/java/com/android/server/net/OWNERS
 per-file *Power* = file:/services/core/java/com/android/server/power/OWNERS
diff --git a/core/java/android/os/ShellCallback.java b/core/java/android/os/ShellCallback.java
index 632f6c8..be9fb89 100644
--- a/core/java/android/os/ShellCallback.java
+++ b/core/java/android/os/ShellCallback.java
@@ -102,6 +102,10 @@
         }
     }
 
+    public IBinder getShellCallbackBinder() {
+        return mShellCallback.asBinder();
+    }
+
     ShellCallback(Parcel in) {
         mLocal = false;
         mShellCallback = IShellCallback.Stub.asInterface(in.readStrongBinder());
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 769a34e..13871c5 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -1083,7 +1083,8 @@
          *
          * @param primitiveId The primitive to add
          * @param scale The scale to apply to the intensity of the primitive.
-         * @param delay The amount of time in milliseconds to wait before playing this primitive
+         * @param delay The amount of time in milliseconds to wait before playing this primitive,
+         *              starting at the time the previous element in this composition is finished.
          * @return The {@link Composition} object to enable adding multiple primitives in one chain.
          */
         @NonNull
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 18da3a6..0ae5ed7 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -17,10 +17,7 @@
 package android.telephony;
 
 import android.Manifest;
-import android.annotation.CallbackExecutor;
-import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
@@ -32,16 +29,12 @@
 import android.os.HandlerExecutor;
 import android.os.Looper;
 import android.telephony.Annotation.CallState;
-import android.telephony.Annotation.DataActivityType;
 import android.telephony.Annotation.DisconnectCauses;
-import android.telephony.Annotation.NetworkType;
 import android.telephony.Annotation.PreciseDisconnectCauses;
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SimActivationState;
 import android.telephony.Annotation.SrvccState;
-import android.telephony.NetworkRegistrationInfo.Domain;
 import android.telephony.TelephonyManager.DataEnabledReason;
-import android.telephony.TelephonyManager.DataState;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsReasonInfo;
 
@@ -50,8 +43,6 @@
 
 import dalvik.system.VMRuntime;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
 import java.util.List;
 import java.util.Map;
@@ -72,49 +63,15 @@
  * information unless it has the appropriate permissions declared in
  * its manifest file. Where permissions apply, they are noted in the
  * appropriate LISTEN_ flags.
+ *
+ * @deprecated Use {@link TelephonyCallback} instead.
  */
+@Deprecated
 public class PhoneStateListener {
     private static final String LOG_TAG = "PhoneStateListener";
     private static final boolean DBG = false; // STOPSHIP if true
 
     /**
-     * Experiment flag to set the per-pid registration limit for PhoneStateListeners
-     *
-     * Limit on registrations of {@link PhoneStateListener}s on a per-pid
-     * basis. When this limit is exceeded, any calls to {@link TelephonyManager#listen} will fail
-     * with an {@link IllegalStateException}.
-     *
-     * {@link android.os.Process#PHONE_UID}, {@link android.os.Process#SYSTEM_UID}, and the uid that
-     * TelephonyRegistry runs under are exempt from this limit.
-     *
-     * If the value of the flag is less than 1, enforcement of the limit will be disabled.
-     * @hide
-     */
-    public static final String FLAG_PER_PID_REGISTRATION_LIMIT =
-            "phone_state_listener_per_pid_registration_limit";
-
-    /**
-     * Default value for the per-pid registation limit.
-     * See {@link #FLAG_PER_PID_REGISTRATION_LIMIT}.
-     * @hide
-     */
-    public static final int DEFAULT_PER_PID_REGISTRATION_LIMIT = 50;
-
-    /**
-     * This change enables a limit on the number of {@link PhoneStateListener} objects any process
-     * may register via {@link TelephonyManager#listen}. The default limit is 50, which may change
-     * via remote device config updates.
-     *
-     * This limit is enforced via an {@link IllegalStateException} thrown from
-     * {@link TelephonyManager#listen} when the offending process attempts to register one too many
-     * listeners.
-     *
-     * @hide
-     */
-    @ChangeId
-    public static final long PHONE_STATE_LISTENER_LIMIT_CHANGE_ID = 150880553L;
-
-    /**
      * Stop listening for updates.
      *
      * The PhoneStateListener is not tied to any subscription and unregistered for any update.
@@ -126,7 +83,7 @@
      *
      *  @see #onServiceStateChanged
      *  @see ServiceState
-     *  @deprecated Use {@link ServiceStateChangedListener} instead.
+     *  @deprecated Use {@link TelephonyCallback.ServiceStateListener} instead.
      */
     @Deprecated
     public static final int LISTEN_SERVICE_STATE                            = 0x00000001;
@@ -136,7 +93,7 @@
      * {@more}
      *
      * @see #onSignalStrengthChanged
-     * @deprecated Use {@link SignalStrengthsChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.SignalStrengthsListener} instead.
      */
     @Deprecated
     public static final int LISTEN_SIGNAL_STRENGTH                          = 0x00000002;
@@ -152,7 +109,7 @@
      * voicemail icon.
      *
      * @see #onMessageWaitingIndicatorChanged
-     * @deprecated Use {@link MessageWaitingIndicatorChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.MessageWaitingIndicatorListener} instead.
      */
     @Deprecated
     public static final int LISTEN_MESSAGE_WAITING_INDICATOR                = 0x00000004;
@@ -165,7 +122,7 @@
      * {@link TelephonyManager#hasCarrierPrivileges}).
      *
      * @see #onCallForwardingIndicatorChanged
-     * @deprecated Use {@link CallForwardingIndicatorChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.CallForwardingIndicatorListener} instead.
      */
     @Deprecated
     public static final int LISTEN_CALL_FORWARDING_INDICATOR                = 0x00000008;
@@ -183,7 +140,7 @@
      * instead.
      *
      * @see #onCellLocationChanged
-     * @deprecated Use {@link CellLocationChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.CellLocationListener} instead.
      */
     @Deprecated
     public static final int LISTEN_CELL_LOCATION                            = 0x00000010;
@@ -193,7 +150,7 @@
      * {@more}
      *
      * @see #onCallStateChanged
-     * @deprecated Use {@link CallStateChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.CallStateListener} instead.
      */
     @Deprecated
     public static final int LISTEN_CALL_STATE                               = 0x00000020;
@@ -202,7 +159,7 @@
      * Listen for changes to the data connection state (cellular).
      *
      * @see #onDataConnectionStateChanged
-     * @deprecated Use {@link DataConnectionStateChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.DataConnectionStateListener} instead.
      */
     @Deprecated
     public static final int LISTEN_DATA_CONNECTION_STATE                    = 0x00000040;
@@ -215,7 +172,7 @@
      * data-traffic icon.
      *
      * @see #onDataActivity
-     * @deprecated Use {@link DataActivityListener} instead.
+     * @deprecated Use {@link TelephonyCallback.DataActivityListener} instead.
      */
     @Deprecated
     public static final int LISTEN_DATA_ACTIVITY                            = 0x00000080;
@@ -227,7 +184,7 @@
      * icon.
      *
      * @see #onSignalStrengthsChanged
-     * @deprecated Use {@link SignalStrengthsChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.SignalStrengthsListener} instead.
      */
     @Deprecated
     public static final int LISTEN_SIGNAL_STRENGTHS                         = 0x00000100;
@@ -239,7 +196,8 @@
      * @see #onSignalStrengthsChanged
      *
      * @hide
-     * @deprecated Use {@link AlwaysReportedSignalStrengthChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.AlwaysReportedSignalStrengthListener}
+     * instead.
      */
     @Deprecated
     @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
@@ -252,7 +210,7 @@
      * permission.
      *
      * @see #onCellInfoChanged
-     * @deprecated Use {@link CellInfoChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.CellInfoListener} instead.
      */
     @Deprecated
     public static final int LISTEN_CELL_INFO = 0x00000400;
@@ -266,7 +224,7 @@
      * (see {@link TelephonyManager#hasCarrierPrivileges}).
      *
      * @hide
-     * @deprecated Use {@link PreciseCallStateChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.PreciseCallStateListener} instead.
      */
     @Deprecated
     @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
@@ -281,7 +239,7 @@
      * (see {@link TelephonyManager#hasCarrierPrivileges}).
      *
      * @see #onPreciseDataConnectionStateChanged
-     * @deprecated Use {@link PreciseDataConnectionStateChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.PreciseDataConnectionStateListener} instead.
      */
     @Deprecated
     @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
@@ -307,7 +265,7 @@
      *
      * @see #onServiceStateChanged(ServiceState)
      * @hide
-     * @deprecated Use {@link SrvccStateChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.SrvccStateListener} instead.
      */
     @Deprecated
     @SystemApi
@@ -329,7 +287,7 @@
      *
      * @see android.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean)
      * @hide
-     * @deprecated Use {@link CarrierNetworkChangeListener} instead.
+     * @deprecated Use {@link TelephonyCallback.CarrierNetworkListener} instead.
      */
     @Deprecated
     public static final int LISTEN_CARRIER_NETWORK_CHANGE                   = 0x00010000;
@@ -350,7 +308,7 @@
      *
      * @see #onVoiceActivationStateChanged
      * @hide
-     * @deprecated Use {@link VoiceActivationStateChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.VoiceActivationStateListener} instead.
      */
     @Deprecated
     @SystemApi
@@ -370,7 +328,7 @@
      *
      * @see #onDataActivationStateChanged
      * @hide
-     * @deprecated Use {@link DataActivationStateChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.DataActivationStateListener} instead.
      */
     @Deprecated
     public static final int LISTEN_DATA_ACTIVATION_STATE                   = 0x00040000;
@@ -379,7 +337,7 @@
      *  Listen for changes to the user mobile data state
      *
      *  @see #onUserMobileDataStateChanged
-     *  @deprecated Use {@link UserMobileDataStateChangedListener} instead.
+     *  @deprecated Use {@link TelephonyCallback.UserMobileDataStateListener} instead.
      */
     @Deprecated
     public static final int LISTEN_USER_MOBILE_DATA_STATE                  = 0x00080000;
@@ -392,7 +350,7 @@
      *  {@link TelephonyManager#hasCarrierPrivileges}).
      *
      *  @see #onDisplayInfoChanged
-     * @deprecated Use {@link DisplayInfoChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.DisplayInfoListener} instead.
      */
     @Deprecated
     public static final int LISTEN_DISPLAY_INFO_CHANGED = 0x00100000;
@@ -402,7 +360,7 @@
      *
      *  @see #onPhoneCapabilityChanged
      *  @hide
-     *  @deprecated Use {@link PhoneCapabilityChangedListener} instead.
+     *  @deprecated Use {@link TelephonyCallback.PhoneCapabilityListener} instead.
      */
     @Deprecated
     public static final int LISTEN_PHONE_CAPABILITY_CHANGE                 = 0x00200000;
@@ -414,7 +372,7 @@
      *  subscription user selected as default data subscription in DSDS mode.
      *
      *  @see #onActiveDataSubscriptionIdChanged
-     *  @deprecated Use {@link ActiveDataSubscriptionIdChangedListener} instead.
+     *  @deprecated Use {@link TelephonyCallback.ActiveDataSubscriptionIdListener} instead.
      */
     @Deprecated
     public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 0x00400000;
@@ -424,7 +382,7 @@
      *
      *  @see #onRadioPowerStateChanged
      *  @hide
-     *  @deprecated Use {@link RadioPowerStateChangedListener} instead.
+     *  @deprecated Use {@link TelephonyCallback.RadioPowerStateListener} instead.
      */
     @Deprecated
     @SystemApi
@@ -437,7 +395,7 @@
      * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
      * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
      *
-     * @deprecated Use {@link EmergencyNumberListChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.EmergencyNumberListListener} instead.
      */
     @Deprecated
     public static final int LISTEN_EMERGENCY_NUMBER_LIST                   = 0x01000000;
@@ -450,7 +408,7 @@
      * or the calling app has carrier privileges
      * (see {@link TelephonyManager#hasCarrierPrivileges}).
      *
-     * @deprecated Use {@link CallDisconnectCauseChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.CallDisconnectCauseListener} instead.
      */
     @Deprecated
     @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
@@ -465,7 +423,7 @@
      *
      * @see #onCallAttributesChanged
      * @hide
-     * @deprecated Use {@link CallAttributesChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.CallAttributesListener} instead.
      */
     @Deprecated
     @SystemApi
@@ -481,7 +439,7 @@
      * (see {@link TelephonyManager#hasCarrierPrivileges}).
      *
      * @see #onImsCallDisconnectCauseChanged(ImsReasonInfo)
-     * @deprecated Use {@link ImsCallDisconnectCauseChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.ImsCallDisconnectCauseListener} instead.
      */
     @Deprecated
     @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
@@ -492,7 +450,7 @@
      *
      * @see #onOutgoingEmergencyCall
      * @hide
-     * @deprecated Use {@link OutgoingEmergencyCallListener} instead.
+     * @deprecated Use {@link TelephonyCallback.OutgoingEmergencyCallListener} instead.
      */
     @Deprecated
     @SystemApi
@@ -504,7 +462,7 @@
      *
      * @see #onOutgoingEmergencySms
      * @hide
-     * @deprecated Use {@link OutgoingEmergencySmsListener} instead.
+     * @deprecated Use {@link TelephonyCallback.OutgoingEmergencySmsListener} instead.
      */
     @Deprecated
     @SystemApi
@@ -525,7 +483,7 @@
      * of whether the calling app has carrier privileges.
      *
      * @see #onRegistrationFailed
-     * @deprecated Use {@link RegistrationFailedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.RegistrationFailedListener} instead.
      */
     @Deprecated
     @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
@@ -541,539 +499,12 @@
      * of whether the calling app has carrier privileges.
      *
      * @see #onBarringInfoChanged
-     * @deprecated Use {@link BarringInfoChangedListener} instead.
+     * @deprecated Use {@link TelephonyCallback.BarringInfoListener} instead.
      */
     @Deprecated
     @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
     public static final int LISTEN_BARRING_INFO = 0x80000000;
 
-    /**
-     *  Event for changes to the network service state (cellular).
-     *
-     *  @see ServiceStateChangedListener#onServiceStateChanged
-     *  @see ServiceState
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int EVENT_SERVICE_STATE_CHANGED = 1;
-
-    /**
-     * Event for changes to the network signal strength (cellular).
-     *
-     * @see SignalStrengthsChangedListener#onSignalStrengthsChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int EVENT_SIGNAL_STRENGTH_CHANGED = 2;
-
-    /**
-     * Event for changes to the message-waiting indicator.
-     *
-     * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE} or that
-     * the calling app has carrier privileges (see
-     * {@link TelephonyManager#hasCarrierPrivileges}).
-     * <p>
-     * Example: The status bar uses this to determine when to display the
-     * voicemail icon.
-     *
-     * @see MessageWaitingIndicatorChangedListener#onMessageWaitingIndicatorChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-    public static final int EVENT_MESSAGE_WAITING_INDICATOR_CHANGED = 3;
-
-    /**
-     * Event for changes to the call-forwarding indicator.
-     *
-     * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE} or that
-     * the calling app has carrier privileges (see
-     * {@link TelephonyManager#hasCarrierPrivileges}).
-     *
-     * @see CallForwardingIndicatorChangedListener#onCallForwardingIndicatorChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-    public static final int EVENT_CALL_FORWARDING_INDICATOR_CHANGED = 4;
-
-    /**
-     * Event for changes to the device's cell location. Note that
-     * this will result in frequent callbacks to the listener.
-     *
-     * If you need regular location updates but want more control over
-     * the update interval or location precision, you can set up a listener
-     * through the {@link android.location.LocationManager location manager}
-     * instead.
-     *
-     * @see CellLocationChangedListener#onCellLocationChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
-    public static final int EVENT_CELL_LOCATION_CHANGED = 5;
-
-    /**
-     * Event for changes to the device call state.
-     *
-     * @see CallStateChangedListener#onCallStateChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.READ_CALL_LOG)
-    public static final int EVENT_CALL_STATE_CHANGED = 6;
-
-    /**
-     * Event for changes to the data connection state (cellular).
-     *
-     * @see DataConnectionStateChangedListener#onDataConnectionStateChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 7;
-
-    /**
-     * Event for changes to the direction of data traffic on the data
-     * connection (cellular).
-     *
-     * Example: The status bar uses this to display the appropriate
-     * data-traffic icon.
-     *
-     * @see DataActivityListener#onDataActivity
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int EVENT_DATA_ACTIVITY_CHANGED = 8;
-
-    /**
-     * Event for changes to the network signal strengths (cellular).
-     * <p>
-     * Example: The status bar uses this to control the signal-strength
-     * icon.
-     *
-     * @see SignalStrengthsChangedListener#onSignalStrengthsChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int EVENT_SIGNAL_STRENGTHS_CHANGED = 9;
-
-    /**
-     * Event for changes of the network signal strengths (cellular) always reported from modem,
-     * even in some situations such as the screen of the device is off.
-     *
-     * @see AlwaysReportedSignalStrengthChangedListener#onSignalStrengthsChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
-    public static final int EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED = 10;
-
-    /**
-     * Event for changes to observed cell info.
-     *
-     * @see CellInfoChangedListener#onCellInfoChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
-    public static final int EVENT_CELL_INFO_CHANGED = 11;
-
-    /**
-     * Event for {@link android.telephony.Annotation.PreciseCallStates} of ringing,
-     * background and foreground calls.
-     *
-     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
-     * or the calling app has carrier privileges
-     * (see {@link TelephonyManager#hasCarrierPrivileges}).
-     *
-     * @see PreciseCallStateChangedListener#onPreciseCallStateChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
-    public static final int EVENT_PRECISE_CALL_STATE_CHANGED = 12;
-
-    /**
-     * Event for {@link PreciseDataConnectionState} on the data connection (cellular).
-     *
-     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
-     * or the calling app has carrier privileges
-     * (see {@link TelephonyManager#hasCarrierPrivileges}).
-     *
-     * @see PreciseDataConnectionStateChangedListener#onPreciseDataConnectionStateChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
-    public static final int EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED = 13;
-
-    /**
-     * Event for real time info for all data connections (cellular)).
-     *
-     * @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo)
-     *
-     * @deprecated Use {@link TelephonyManager#requestModemActivityInfo}
-     * @hide
-     */
-    @Deprecated
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
-    public static final int EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED = 14;
-
-    /**
-     * Event for OEM hook raw event
-     *
-     * @see #onOemHookRawEvent
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public static final int EVENT_OEM_HOOK_RAW = 15;
-
-    /**
-     * Event for changes to the SRVCC state of the active call.
-     *
-     * @see SrvccStateChangedListener#onSrvccStateChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public static final int EVENT_SRVCC_STATE_CHANGED = 16;
-
-    /**
-     * Event for carrier network changes indicated by a carrier app.
-     *
-     * @see android.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean)
-     * @see CarrierNetworkChangeListener#onCarrierNetworkChange
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int EVENT_CARRIER_NETWORK_CHANGED = 17;
-
-    /**
-     * Event for changes to the sim voice activation state
-     *
-     * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING
-     * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED
-     * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED
-     * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED
-     * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN
-     *
-     * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates voice service has been
-     * fully activated
-     *
-     * @see VoiceActivationStateChangedListener#onVoiceActivationStateChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public static final int EVENT_VOICE_ACTIVATION_STATE_CHANGED = 18;
-
-    /**
-     * Event for changes to the sim data activation state
-     * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING
-     * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED
-     * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED
-     * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED
-     * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN
-     *
-     * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates data service has been
-     * fully activated
-     *
-     * @see DataActivationStateChangedListener#onDataActivationStateChanged
-     * @hide
-     */
-    @SystemApi
-    public static final int EVENT_DATA_ACTIVATION_STATE_CHANGED = 19;
-
-    /**
-     *  Event for changes to the user mobile data state
-     *
-     *  @see UserMobileDataStateChangedListener#onUserMobileDataStateChanged
-     *
-     *  @hide
-     */
-    @SystemApi
-    public static final int EVENT_USER_MOBILE_DATA_STATE_CHANGED = 20;
-
-    /**
-     *  Event for display info changed event.
-     *
-     *  @see DisplayInfoChangedListener#onDisplayInfoChanged
-     *
-     *  @hide
-     */
-    @SystemApi
-    public static final int EVENT_DISPLAY_INFO_CHANGED = 21;
-
-    /**
-     *  Event for changes to the phone capability.
-     *
-     *  @see PhoneCapabilityChangedListener#onPhoneCapabilityChanged
-     *
-     *  @hide
-     */
-    @SystemApi
-    public static final int EVENT_PHONE_CAPABILITY_CHANGED = 22;
-
-    /**
-     *  Event for changes to active data subscription ID. Active data subscription is
-     *  the current subscription used to setup Cellular Internet data. For example,
-     *  it could be the current active opportunistic subscription in use, or the
-     *  subscription user selected as default data subscription in DSDS mode.
-     *
-     *  <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
-     *  app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
-     *
-     *  @see ActiveDataSubscriptionIdChangedListener#onActiveDataSubscriptionIdChanged
-     *
-     *  @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-    public static final int EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED = 23;
-
-    /**
-     *  Event for changes to the radio power state.
-     *
-     *  @see RadioPowerStateChangedListener#onRadioPowerStateChanged
-     *
-     *  @hide
-     */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public static final int EVENT_RADIO_POWER_STATE_CHANGED = 24;
-
-    /**
-     * Event for changes to emergency number list based on all active subscriptions.
-     *
-     * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
-     * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
-     *
-     *  @see EmergencyNumberListChangedListener#onEmergencyNumberListChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-    public static final int EVENT_EMERGENCY_NUMBER_LIST_CHANGED = 25;
-
-    /**
-     * Event for call disconnect causes which contains {@link DisconnectCause} and
-     * {@link PreciseDisconnectCause}.
-     *
-     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
-     * or the calling app has carrier privileges
-     * (see {@link TelephonyManager#hasCarrierPrivileges}).
-     *
-     *  @see CallDisconnectCauseChangedListener#onCallDisconnectCauseChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
-    public static final int EVENT_CALL_DISCONNECT_CAUSE_CHANGED = 26;
-
-    /**
-     * Event for changes to the call attributes of a currently active call.
-     *
-     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
-     * or the calling app has carrier privileges
-     * (see {@link TelephonyManager#hasCarrierPrivileges}).
-     *
-     * @see CallAttributesChangedListener#onCallAttributesChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
-    public static final int EVENT_CALL_ATTRIBUTES_CHANGED = 27;
-
-    /**
-     * Event for IMS call disconnect causes which contains
-     * {@link android.telephony.ims.ImsReasonInfo}
-     *
-     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
-     * or the calling app has carrier privileges
-     * (see {@link TelephonyManager#hasCarrierPrivileges}).
-     *
-     * @see ImsCallDisconnectCauseChangedListener#onImsCallDisconnectCauseChanged(ImsReasonInfo)
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
-    public static final int EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED = 28;
-
-    /**
-     * Event for the emergency number placed from an outgoing call.
-     *
-     * @see OutgoingEmergencyCallListener#onOutgoingEmergencyCall
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
-    public static final int EVENT_OUTGOING_EMERGENCY_CALL = 29;
-
-    /**
-     * Event for the emergency number placed from an outgoing SMS.
-     *
-     * @see OutgoingEmergencySmsListener#onOutgoingEmergencySms
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
-    public static final int EVENT_OUTGOING_EMERGENCY_SMS = 30;
-
-    /**
-     * Event for registration failures.
-     *
-     * Event for indications that a registration procedure has failed in either the CS or PS
-     * domain. This indication does not necessarily indicate a change of service state, which should
-     * be tracked via {@link #EVENT_SERVICE_STATE_CHANGED}.
-     *
-     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or
-     * the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
-     *
-     * <p>Also requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission, regardless
-     * of whether the calling app has carrier privileges.
-     *
-     * @see RegistrationFailedListener#onRegistrationFailed
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(allOf = {
-            Manifest.permission.READ_PRECISE_PHONE_STATE,
-            Manifest.permission.ACCESS_FINE_LOCATION
-    })
-    public static final int EVENT_REGISTRATION_FAILURE = 31;
-
-    /**
-     * Event for Barring Information for the current registered / camped cell.
-     *
-     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or
-     * the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
-     *
-     * <p>Also requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission, regardless
-     * of whether the calling app has carrier privileges.
-     *
-     * @see BarringInfoChangedListener#onBarringInfoChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(allOf = {
-            Manifest.permission.READ_PRECISE_PHONE_STATE,
-            Manifest.permission.ACCESS_FINE_LOCATION
-    })
-    public static final int EVENT_BARRING_INFO_CHANGED = 32;
-
-    /**
-     * Event for changes to the physical channel configuration.
-     *
-     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
-     * or the calling app has carrier privileges
-     * (see {@link TelephonyManager#hasCarrierPrivileges}).
-     *
-     * @see PhysicalChannelConfigChangedListener#onPhysicalChannelConfigChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
-    public static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 33;
-
-    /**
-     * Event for changes to the data enabled.
-     *
-     * Event for indications that the enabled status of current data has changed.
-     *
-     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
-     * or the calling app has carrier privileges
-     * (see {@link TelephonyManager#hasCarrierPrivileges}).
-     *
-     * @see DataEnabledChangedListener#onDataEnabledChanged
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
-    public static final int EVENT_DATA_ENABLED_CHANGED = 34;
-
-    /**
-     * Event for changes to allowed network list based on all active subscriptions.
-     *
-     * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
-     * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
-     *
-     * @hide
-     * @see AllowedNetworkTypesChangedListener#onAllowedNetworkTypesChanged
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public static final int EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED = 35;
-
-    /** @hide */
-    @IntDef(prefix = { "EVENT_" }, value = {
-            EVENT_SERVICE_STATE_CHANGED,
-            EVENT_SIGNAL_STRENGTH_CHANGED,
-            EVENT_MESSAGE_WAITING_INDICATOR_CHANGED,
-            EVENT_CALL_FORWARDING_INDICATOR_CHANGED,
-            EVENT_CELL_LOCATION_CHANGED,
-            EVENT_CALL_STATE_CHANGED,
-            EVENT_DATA_CONNECTION_STATE_CHANGED,
-            EVENT_DATA_ACTIVITY_CHANGED,
-            EVENT_SIGNAL_STRENGTHS_CHANGED,
-            EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED,
-            EVENT_CELL_INFO_CHANGED,
-            EVENT_PRECISE_CALL_STATE_CHANGED,
-            EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED,
-            EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED,
-            EVENT_OEM_HOOK_RAW,
-            EVENT_SRVCC_STATE_CHANGED,
-            EVENT_CARRIER_NETWORK_CHANGED,
-            EVENT_VOICE_ACTIVATION_STATE_CHANGED,
-            EVENT_DATA_ACTIVATION_STATE_CHANGED,
-            EVENT_USER_MOBILE_DATA_STATE_CHANGED,
-            EVENT_DISPLAY_INFO_CHANGED,
-            EVENT_PHONE_CAPABILITY_CHANGED,
-            EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED,
-            EVENT_RADIO_POWER_STATE_CHANGED,
-            EVENT_EMERGENCY_NUMBER_LIST_CHANGED,
-            EVENT_CALL_DISCONNECT_CAUSE_CHANGED,
-            EVENT_CALL_ATTRIBUTES_CHANGED,
-            EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED,
-            EVENT_OUTGOING_EMERGENCY_CALL,
-            EVENT_OUTGOING_EMERGENCY_SMS,
-            EVENT_REGISTRATION_FAILURE,
-            EVENT_BARRING_INFO_CHANGED,
-            EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED,
-            EVENT_DATA_ENABLED_CHANGED,
-            EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface TelephonyEvent {}
-
     /*
      * Subscription used to listen to the phone state changes
      * @hide
@@ -1085,19 +516,16 @@
     /**
      * @hide
      */
-    //TODO: The maxTargetSdk should be S if the build time tool updates it.
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
     @UnsupportedAppUsage(
             maxTargetSdk = Build.VERSION_CODES.R,
-            publicAlternatives = "Use {@code TelephonyManager#registerPhoneStateListener(" +
-                    "Executor, PhoneStateListener)} instead")
-    public IPhoneStateListener callback;
+            publicAlternatives = "Use {@code TelephonyManager#registerTelephonyCallback(" +
+                    "Executor, TelephonyCallback)} instead")
+    public final IPhoneStateListener callback;
 
     /**
      * Create a PhoneStateListener for the Phone with the default subscription.
-     * If this is created for use with deprecated API
-     * {@link TelephonyManager#listen(PhoneStateListener, int)}, then this class requires
-     * Looper.myLooper() not return null.
+     * This class requires Looper.myLooper() not return null.
      */
     public PhoneStateListener() {
         this(null, Looper.myLooper());
@@ -1135,10 +563,7 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     public PhoneStateListener(Integer subId, Looper looper) {
-        if (looper != null) {
-            setExecutor(new HandlerExecutor(new Handler(looper)));
-        }
-        mSubId = subId;
+        this(subId, new HandlerExecutor(new Handler(looper)));
         if (subId != null && VMRuntime.getRuntime().getTargetSdkVersion()
                 >= Build.VERSION_CODES.Q) {
             throw new IllegalArgumentException("PhoneStateListener with subId: "
@@ -1153,779 +578,18 @@
      * The Executor must not be null.
      *
      * @param executor a non-null Executor that will execute callbacks for the PhoneStateListener.
-     * @deprecated Use
-     * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)} instead.
      */
     @Deprecated
     public PhoneStateListener(@NonNull Executor executor) {
-        setExecutor(executor);
-        mSubId = null;
+        this(null, executor);
     }
 
-    private @NonNull Executor mExecutor;
-
-    /**
-     * @hide
-     */
-    public void setExecutor(@NonNull @CallbackExecutor Executor executor) {
-        if (executor == null) {
+    private PhoneStateListener(Integer subId, Executor e) {
+        if (e == null) {
             throw new IllegalArgumentException("PhoneStateListener Executor must be non-null");
         }
-        mExecutor = executor;
-        callback = new IPhoneStateListenerStub(this, mExecutor);
-    }
-
-    /**
-     * @hide
-     */
-    public boolean isExecutorSet() {
-        return mExecutor != null;
-    }
-
-    /**
-     * Interface for service state listener.
-     */
-    public interface ServiceStateChangedListener {
-        /**
-         * Callback invoked when device service state changes on the registered subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         *
-         * The instance of {@link ServiceState} passed as an argument here will have various
-         * levels of location information stripped from it depending on the location permissions
-         * that your app holds.
-         * Only apps holding the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission will
-         * receive all the information in {@link ServiceState}.
-         *
-         * @see ServiceState#STATE_EMERGENCY_ONLY
-         * @see ServiceState#STATE_IN_SERVICE
-         * @see ServiceState#STATE_OUT_OF_SERVICE
-         * @see ServiceState#STATE_POWER_OFF
-         */
-        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-        public void onServiceStateChanged(@NonNull ServiceState serviceState);
-    }
-
-    /**
-     * Interface for message waiting indicator listener.
-     */
-    public interface MessageWaitingIndicatorChangedListener {
-        /**
-         * Callback invoked when the message-waiting indicator changes on the registered
-         * subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         */
-        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-        public void onMessageWaitingIndicatorChanged(boolean mwi);
-    }
-
-    /**
-     * Interface for call-forwarding indicator listener.
-     */
-    public interface CallForwardingIndicatorChangedListener {
-        /**
-         * Callback invoked when the call-forwarding indicator changes on the registered
-         * subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         */
-        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-        public void onCallForwardingIndicatorChanged(boolean cfi);
-    }
-
-    /**
-     * Interface for device cell location listener.
-     */
-    public interface CellLocationChangedListener {
-        /**
-         * Callback invoked when device cell location changes on the registered subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         */
-        @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
-        public void onCellLocationChanged(@NonNull CellLocation location);
-    }
-
-    /**
-     * Interface for call state listener.
-     */
-    public interface CallStateChangedListener {
-        /**
-         * Callback invoked when device call state changes.
-         * <p>
-         * Reports the state of Telephony (mobile) calls on the device for the registered s
-         * ubscription.
-         * <p>
-         * Note: the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to all subIds.
-         * <p>
-         * Note: The state returned here may differ from that returned by
-         * {@link TelephonyManager#getCallState()}. Receivers of this callback should be aware that
-         * calling {@link TelephonyManager#getCallState()} from within this callback may return a
-         * different state than the callback reports.
-         *
-         * @param state call state
-         * @param phoneNumber call phone number. If application does not have
-         * {@link android.Manifest.permission#READ_CALL_LOG} permission or carrier
-         * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an empty string will be
-         * passed as an argument.
-         */
-        @RequiresPermission(android.Manifest.permission.READ_CALL_LOG)
-        public void onCallStateChanged(@CallState int state, @Nullable String phoneNumber);
-    }
-
-    /**
-     * Interface for data connection state listener.
-     */
-    public interface DataConnectionStateChangedListener {
-        /**
-         * Callback invoked when connection state changes on the registered subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         *
-         * @see TelephonyManager#DATA_DISCONNECTED
-         * @see TelephonyManager#DATA_CONNECTING
-         * @see TelephonyManager#DATA_CONNECTED
-         * @see TelephonyManager#DATA_SUSPENDED
-         *
-         * @param state is the current state of data connection.
-         * @param networkType is the current network type of data connection.
-         */
-        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-        public void onDataConnectionStateChanged(@DataState int state,
-                                                 @NetworkType int networkType);
-    }
-
-    /**
-     * Interface for data activity state listener.
-     */
-    public interface DataActivityListener {
-        /**
-         * Callback invoked when data activity state changes on the registered subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         *
-         * @see TelephonyManager#DATA_ACTIVITY_NONE
-         * @see TelephonyManager#DATA_ACTIVITY_IN
-         * @see TelephonyManager#DATA_ACTIVITY_OUT
-         * @see TelephonyManager#DATA_ACTIVITY_INOUT
-         * @see TelephonyManager#DATA_ACTIVITY_DORMANT
-         */
-        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-        public void onDataActivity(@DataActivityType int direction);
-    }
-
-    /**
-     * Interface for network signal strengths listener.
-     */
-    public interface SignalStrengthsChangedListener {
-        /**
-         * Callback invoked when network signal strengths changes on the registered subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         */
-        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-        public void onSignalStrengthsChanged(@NonNull SignalStrength signalStrength);
-    }
-
-    /**
-     * Interface for network signal strengths listener which always reported from modem.
-     */
-    public interface AlwaysReportedSignalStrengthChangedListener {
-        /**
-         * Callback always invoked from modem when network signal strengths changes on the
-         * registered subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         */
-        @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
-        public void onSignalStrengthsChanged(@NonNull SignalStrength signalStrength);
-    }
-
-    /**
-     * Interface for cell info listener.
-     */
-    public interface CellInfoChangedListener {
-        /**
-         * Callback invoked when a observed cell info has changed or new cells have been added
-         * or removed on the registered subscription.
-         * Note, the registration subscription ID s from {@link TelephonyManager} object
-         * which registersPhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         *
-         * @param cellInfo is the list of currently visible cells.
-         */
-        @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
-        public void onCellInfoChanged(@NonNull List<CellInfo> cellInfo);
-    }
-
-    /**
-     * Interface for precise device call state listener.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface PreciseCallStateChangedListener {
-        /**
-         * Callback invoked when precise device call state changes on the registered subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         *
-         * @param callState {@link PreciseCallState}
-         */
-        @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
-        public void onPreciseCallStateChanged(@NonNull PreciseCallState callState);
-    }
-
-    /**
-     * Interface for call disconnect cause listener.
-     */
-    public interface CallDisconnectCauseChangedListener {
-        /**
-         * Callback invoked when call disconnect cause changes on the registered subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         *
-         * @param disconnectCause {@link DisconnectCause}.
-         * @param preciseDisconnectCause {@link PreciseDisconnectCause}.
-         */
-        @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
-        public void onCallDisconnectCauseChanged(@DisconnectCauses int disconnectCause,
-                @PreciseDisconnectCauses int preciseDisconnectCause);
-    }
-
-    /**
-     * Interface for IMS call disconnect cause listener.
-     */
-    public interface ImsCallDisconnectCauseChangedListener {
-        /**
-         * Callback invoked when IMS call disconnect cause changes on the registered subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         *
-         * @param imsReasonInfo {@link ImsReasonInfo} contains details on why IMS call failed.
-         *
-         */
-        @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
-        public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo);
-    }
-
-    /**
-     * Interface for precise data connection state listener.
-     */
-    public interface PreciseDataConnectionStateChangedListener {
-        /**
-         * Callback providing update about the default/internet data connection on the registered
-         * subscription.
-         *
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         *
-         * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
-         * or the calling app has carrier privileges
-         * (see {@link TelephonyManager#hasCarrierPrivileges}).
-         *
-         * @param dataConnectionState {@link PreciseDataConnectionState}
-         */
-        @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
-        public void onPreciseDataConnectionStateChanged(
-                @NonNull PreciseDataConnectionState dataConnectionState);
-    }
-
-    /**
-     * Interface for Single Radio Voice Call Continuity listener.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface SrvccStateChangedListener {
-        /**
-         * Callback invoked when there has been a change in the Single Radio Voice Call Continuity
-         * (SRVCC) state for the currently active call on the registered subscription.
-         *
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         */
-        @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-        public void onSrvccStateChanged(@SrvccState int srvccState);
-    }
-
-    /**
-     * Interface for SIM voice activation state listener.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface VoiceActivationStateChangedListener {
-        /**
-         * Callback invoked when the SIM voice activation state has changed on the registered
-         * subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         *
-         * @param state is the current SIM voice activation state
-         */
-        @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-        public void onVoiceActivationStateChanged(@SimActivationState int state);
-
-    }
-
-    /**
-     * Interface for SIM data activation state listener.
-     */
-    public interface DataActivationStateChangedListener {
-        /**
-         * Callback invoked when the SIM data activation state has changed on the registered
-         * subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         *
-         * @param state is the current SIM data activation state
-         */
-        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-        public void onDataActivationStateChanged(@SimActivationState int state);
-    }
-
-    /**
-     * Interface for user mobile data state listener.
-     */
-    public interface UserMobileDataStateChangedListener {
-        /**
-         * Callback invoked when the user mobile data state has changed on the registered
-         * subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         *
-         * @param enabled indicates whether the current user mobile data state is enabled or
-         *                disabled.
-         */
-        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-        public void onUserMobileDataStateChanged(boolean enabled);
-    }
-
-    /**
-     * Interface for display info listener.
-     */
-    public interface DisplayInfoChangedListener {
-        /**
-         * Callback invoked when the display info has changed on the registered subscription.
-         * <p> The {@link TelephonyDisplayInfo} contains status information shown to the user
-         * based on carrier policy.
-         *
-         * @param telephonyDisplayInfo The display information.
-         */
-        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-        public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo telephonyDisplayInfo);
-    }
-
-    /**
-     * Interface for the current emergency number list listener.
-     */
-    public interface EmergencyNumberListChangedListener {
-        /**
-         * Callback invoked when the current emergency number list has changed on the registered
-         * subscription.
-         *
-         * Note, the registered subscription is associated with {@link TelephonyManager} object
-         * on which
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}
-         * was called.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * given subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         *
-         * @param emergencyNumberList Map associating all active subscriptions on the device with
-         *                            the list of emergency numbers originating from that
-         *                            subscription.
-         *                            If there are no active subscriptions, the map will contain a
-         *                            single entry with
-         *                            {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} as
-         *                            the key and a list of emergency numbers as the value. If no
-         *                            emergency number information is available, the value will be
-         *                            empty.
-         */
-        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-        public void onEmergencyNumberListChanged(
-                @NonNull Map<Integer, List<EmergencyNumber>> emergencyNumberList);
-    }
-
-    /**
-     * Interface for outgoing emergency call listener.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface OutgoingEmergencyCallListener {
-        /**
-         * Callback invoked when an outgoing call is placed to an emergency number.
-         *
-         * This method will be called when an emergency call is placed on any subscription
-         * (including the no-SIM case), regardless of which subscription this listener was
-         * registered on.
-         *
-         * The default implementation of this method calls
-         * {@link #onOutgoingEmergencyCall(EmergencyNumber)} for backwards compatibility purposes.
-         * Do not call {@code super(...)} from within your implementation unless you want
-         * {@link #onOutgoingEmergencyCall(EmergencyNumber)} to be called as well.
-         *
-         * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was
-         *                              placed to.
-         * @param subscriptionId The subscription ID used to place the emergency call. If the
-         *                       emergency call was placed without a valid subscription
-         *                       (e.g. when there are no SIM cards in the device), this will be
-         *                       equal to {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
-         */
-        @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
-        public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber,
-                                     int subscriptionId);
-    }
-
-    /**
-     * Interface for outgoing emergency sms listener.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface OutgoingEmergencySmsListener {
-        /**
-         * Smsback invoked when an outgoing sms is sent to an emergency number.
-         *
-         * This method will be called when an emergency sms is sent on any subscription,
-         * regardless of which subscription this listener was registered on.
-         *
-         * The default implementation of this method calls
-         * {@link #onOutgoingEmergencySms(EmergencyNumber)} for backwards compatibility purposes. Do
-         * not call {@code super(...)} from within your implementation unless you want
-         * {@link #onOutgoingEmergencySms(EmergencyNumber)} to be called as well.
-         *
-         * @param sentEmergencyNumber The {@link EmergencyNumber} the emergency sms was sent to.
-         * @param subscriptionId The subscription ID used to send the emergency sms.
-         */
-        @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
-        public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber,
-                                    int subscriptionId);
-    }
-
-    /**
-     * Interface for phone capability listener.
-     *
-     */
-    public interface PhoneCapabilityChangedListener {
-        /**
-         * Callback invoked when phone capability changes.
-         * Note, this callback triggers regardless of registered subscription.
-         *
-         * @param capability the new phone capability
-         */
-        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-        public void onPhoneCapabilityChanged(@NonNull PhoneCapability capability);
-    }
-
-    /**
-     * Interface for active data subscription ID listener.
-     */
-    public interface ActiveDataSubscriptionIdChangedListener {
-        /**
-         * Callback invoked when active data subscription ID changes.
-         * Note, this callback triggers regardless of registered subscription.
-         *
-         * @param subId current subscription used to setup Cellular Internet data.
-         *              For example, it could be the current active opportunistic subscription
-         *              in use, or the subscription user selected as default data subscription in
-         *              DSDS mode.
-         */
-        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-        public void onActiveDataSubscriptionIdChanged(int subId);
-    }
-
-    /**
-     * Interface for modem radio power state listener.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface RadioPowerStateChangedListener {
-        /**
-         * Callback invoked when modem radio power state changes on the registered subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         *
-         * @param state the modem radio power state
-         */
-        @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-        public void onRadioPowerStateChanged(@RadioPowerState int state);
-    }
-
-    /**
-     * Interface for carrier network listener.
-     */
-    public interface CarrierNetworkChangeListener {
-        /**
-         * Callback invoked when telephony has received notice from a carrier
-         * app that a network action that could result in connectivity loss
-         * has been requested by an app using
-         * {@link android.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean)}
-         *
-         * This is optional and is only used to allow the system to provide alternative UI while
-         * telephony is performing an action that may result in intentional, temporary network
-         * lack of connectivity.
-         *
-         * Note, this callback is pinned to the registered subscription and will be invoked when
-         * the notifying carrier app has carrier privilege rule on the registered
-         * subscription. {@link android.telephony.TelephonyManager#hasCarrierPrivileges}
-         *
-         * @param active If the carrier network change is or shortly will be active,
-         *               {@code true} indicate that showing alternative UI, {@code false} otherwise.
-         */
-        public void onCarrierNetworkChange(boolean active);
-    }
-
-    /**
-     * Interface for registration failures listener.
-     */
-    public interface RegistrationFailedListener {
-        /**
-         * Report that Registration or a Location/Routing/Tracking Area update has failed.
-         *
-         * <p>Indicate whenever a registration procedure, including a location, routing, or tracking
-         * area update fails. This includes procedures that do not necessarily result in a change of
-         * the modem's registration status. If the modem's registration status changes, that is
-         * reflected in the onNetworkStateChanged() and subsequent
-         * get{Voice/Data}RegistrationState().
-         *
-         * <p>Because registration failures are ephemeral, this callback is not sticky.
-         * Registrants will not receive the most recent past value when registering.
-         *
-         * @param cellIdentity the CellIdentity, which must include the globally unique identifier
-         *        for the cell (for example, all components of the CGI or ECGI).
-         * @param chosenPlmn a 5 or 6 digit alphanumeric PLMN (MCC|MNC) among those broadcast by the
-         *         cell that was chosen for the failed registration attempt.
-         * @param domain DOMAIN_CS, DOMAIN_PS or both in case of a combined procedure.
-         * @param causeCode the primary failure cause code of the procedure.
-         *        For GSM/UMTS (MM), values are in TS 24.008 Sec 10.5.95
-         *        For GSM/UMTS (GMM), values are in TS 24.008 Sec 10.5.147
-         *        For LTE (EMM), cause codes are TS 24.301 Sec 9.9.3.9
-         *        For NR (5GMM), cause codes are TS 24.501 Sec 9.11.3.2
-         *        Integer.MAX_VALUE if this value is unused.
-         * @param additionalCauseCode the cause code of any secondary/combined procedure
-         *                            if appropriate. For UMTS, if a combined attach succeeds for
-         *                            PS only, then the GMM cause code shall be included as an
-         *                            additionalCauseCode. For LTE (ESM), cause codes are in
-         *                            TS 24.301 9.9.4.4. Integer.MAX_VALUE if this value is unused.
-         */
-        @RequiresPermission(allOf = {
-                Manifest.permission.READ_PRECISE_PHONE_STATE,
-                Manifest.permission.ACCESS_FINE_LOCATION
-        })
-        public void onRegistrationFailed(@NonNull CellIdentity cellIdentity,
-                                         @NonNull String chosenPlmn, @Domain int domain,
-                                         int causeCode, int additionalCauseCode);
-    }
-
-    /**
-     * Interface for the current allowed network type list listener. This list involves values of
-     * allowed network type for each of reasons.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface AllowedNetworkTypesChangedListener {
-        /**
-         * Callback invoked when the current allowed network type list has changed on the
-         * registered subscription.
-         * Note, the registered subscription is associated with {@link TelephonyManager} object
-         * on which
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}
-         * was called.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * given subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         *
-         * @param allowedNetworkTypesList Map associating all allowed network type reasons
-         * ({@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_USER},
-         * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_POWER}, and
-         * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_CARRIER}) with reason's allowed
-         * network type values.
-         * For example:
-         * map{{TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_USER, long type value},
-         *     {TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_POWER, long type value},
-         *     {TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_CARRIER, long type value}}
-         */
-        @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-        void onAllowedNetworkTypesChanged(
-                @NonNull Map<Integer, Long> allowedNetworkTypesList);
-    }
-
-    /**
-     * Interface for call attributes listener.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface CallAttributesChangedListener {
-        /**
-         * Callback invoked when the call attributes changes on the registered subscription.
-         * Note, the registration subscription ID comes from {@link TelephonyManager} object
-         * which registers PhoneStateListener by
-         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
-         * If this TelephonyManager object was created with
-         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-         * subscription ID. Otherwise, this callback applies to
-         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
-         *
-         * @param callAttributes the call attributes
-         */
-        @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
-        void onCallAttributesChanged(@NonNull CallAttributes callAttributes);
-    }
-
-    /**
-     * Interface for barring information listener.
-     */
-    public interface BarringInfoChangedListener {
-        /**
-         * Report updated barring information for the current camped/registered cell.
-         *
-         * <p>Barring info is provided for all services applicable to the current camped/registered
-         * cell, for the registered PLMN and current access class/access category.
-         *
-         * @param barringInfo for all services on the current cell.
-         * @see android.telephony.BarringInfo
-         */
-        @RequiresPermission(allOf = {
-                Manifest.permission.READ_PRECISE_PHONE_STATE,
-                Manifest.permission.ACCESS_FINE_LOCATION
-        })
-        public void onBarringInfoChanged(@NonNull BarringInfo barringInfo);
-    }
-
-    /**
-     * Interface for current physical channel configuration listener.
-     * @hide
-     */
-    @SystemApi
-    public interface PhysicalChannelConfigChangedListener {
-        /**
-         * Callback invoked when the current physical channel configuration has changed
-         *
-         * @param configs List of the current {@link PhysicalChannelConfig}s
-         */
-        @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
-        public void onPhysicalChannelConfigChanged(@NonNull List<PhysicalChannelConfig> configs);
-    }
-
-    /**
-     * Interface for data enabled listener.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface DataEnabledChangedListener {
-        /**
-         * Callback invoked when the data enabled changes.
-         *
-         * @param enabled {@code true} if data is enabled, otherwise disabled.
-         * @param reason Reason for data enabled/disabled.
-         *               See {@link TelephonyManager.DataEnabledReason}.
-         */
-        @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
-        public void onDataEnabledChanged(boolean enabled,
-                                  @DataEnabledReason int reason);
+        mSubId = subId;
+        callback = new IPhoneStateListenerStub(this, e);
     }
 
     /**
@@ -1946,7 +610,9 @@
      * @see ServiceState#STATE_IN_SERVICE
      * @see ServiceState#STATE_OUT_OF_SERVICE
      * @see ServiceState#STATE_POWER_OFF
+     * @deprecated Use {@link TelephonyCallback.ServiceStateListener} instead.
      */
+    @Deprecated
     public void onServiceStateChanged(ServiceState serviceState) {
         // default implementation empty
     }
@@ -1979,7 +645,10 @@
      * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
      * subId. Otherwise, this callback applies to
      * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+     *
+     * @deprecated Use {@link TelephonyCallback.MessageWaitingIndicatorListener} instead.
      */
+    @Deprecated
     public void onMessageWaitingIndicatorChanged(boolean mwi) {
         // default implementation empty
     }
@@ -1992,7 +661,10 @@
      * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
      * subId. Otherwise, this callback applies to
      * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+     *
+     * @deprecated Use {@link TelephonyCallback.CallForwardingIndicatorListener} instead.
      */
+    @Deprecated
     public void onCallForwardingIndicatorChanged(boolean cfi) {
         // default implementation empty
     }
@@ -2005,7 +677,10 @@
      * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
      * subId. Otherwise, this callback applies to
      * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+     *
+     * @deprecated Use {@link TelephonyCallback.CellLocationListener} instead.
      */
+    @Deprecated
     public void onCellLocationChanged(CellLocation location) {
         // default implementation empty
     }
@@ -2031,7 +706,10 @@
      * {@link android.Manifest.permission#READ_CALL_LOG READ_CALL_LOG} permission or carrier
      * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an empty string will be
      * passed as an argument.
+     *
+     * @deprecated Use {@link TelephonyCallback.CallStateListener} instead.
      */
+    @Deprecated
     public void onCallStateChanged(@CallState int state, String phoneNumber) {
         // default implementation empty
     }
@@ -2049,14 +727,19 @@
      * @see TelephonyManager#DATA_CONNECTING
      * @see TelephonyManager#DATA_CONNECTED
      * @see TelephonyManager#DATA_SUSPENDED
+     * @deprecated Use {@link TelephonyCallback.DataConnectionStateListener} instead.
      */
+    @Deprecated
     public void onDataConnectionStateChanged(int state) {
         // default implementation empty
     }
 
     /**
      * same as above, but with the network type.  Both called.
+     *
+     * @deprecated Use {@link TelephonyCallback.DataConnectionStateListener} instead.
      */
+    @Deprecated
     public void onDataConnectionStateChanged(int state, int networkType) {
         // default implementation empty
     }
@@ -2075,7 +758,9 @@
      * @see TelephonyManager#DATA_ACTIVITY_OUT
      * @see TelephonyManager#DATA_ACTIVITY_INOUT
      * @see TelephonyManager#DATA_ACTIVITY_DORMANT
+     * @deprecated Use {@link TelephonyCallback.DataActivityListener} instead.
      */
+    @Deprecated
     public void onDataActivity(int direction) {
         // default implementation empty
     }
@@ -2088,7 +773,10 @@
      * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
      * subId. Otherwise, this callback applies to
      * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+     *
+     * @deprecated Use {@link TelephonyCallback.SignalStrengthsListener} instead.
      */
+    @Deprecated
     public void onSignalStrengthsChanged(SignalStrength signalStrength) {
         // default implementation empty
     }
@@ -2104,7 +792,9 @@
      * {@link SubscriptionManager#getDefaultSubscriptionId()}.
      *
      * @param cellInfo is the list of currently visible cells.
+     * @deprecated Use {@link TelephonyCallback.CellInfoListener} instead.
      */
+    @Deprecated
     public void onCellInfoChanged(List<CellInfo> cellInfo) {
         // default implementation empty
     }
@@ -2117,11 +807,14 @@
      * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
      * subId. Otherwise, this callback applies to
      * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+     *
      * @param callState {@link PreciseCallState}
      * @hide
+     * @deprecated Use {@link TelephonyCallback.PreciseCallStateListener} instead.
      */
     @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
     @SystemApi
+    @Deprecated
     public void onPreciseCallStateChanged(@NonNull PreciseCallState callState) {
         // default implementation empty
     }
@@ -2137,9 +830,10 @@
      *
      * @param disconnectCause {@link DisconnectCause}.
      * @param preciseDisconnectCause {@link PreciseDisconnectCause}.
-     *
+     * @deprecated Use {@link TelephonyCallback.CallDisconnectCauseListener} instead.
      */
     @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+    @Deprecated
     public void onCallDisconnectCauseChanged(@DisconnectCauses int disconnectCause,
             @PreciseDisconnectCauses int preciseDisconnectCause) {
         // default implementation empty
@@ -2155,9 +849,10 @@
      * {@link SubscriptionManager#getDefaultSubscriptionId()}.
      *
      * @param imsReasonInfo {@link ImsReasonInfo} contains details on why IMS call failed.
-     *
+     * @deprecated Use {@link TelephonyCallback.ImsCallDisconnectCauseListener} instead.
      */
     @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+    @Deprecated
     public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo) {
         // default implementation empty
     }
@@ -2178,8 +873,10 @@
      * (see {@link TelephonyManager#hasCarrierPrivileges}).
      *
      * @param dataConnectionState {@link PreciseDataConnectionState}
+     * @deprecated Use {@link TelephonyCallback.PreciseDataConnectionStateListener} instead.
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @Deprecated
     public void onPreciseDataConnectionStateChanged(
             @NonNull PreciseDataConnectionState dataConnectionState) {
         // default implementation empty
@@ -2195,8 +892,10 @@
      * {@link SubscriptionManager#getDefaultSubscriptionId()}.
      *
      * @hide
+     * @deprecated Use {@link TelephonyManager#requestModemActivityInfo}
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @Deprecated
     public void onDataConnectionRealTimeInfoChanged(
             DataConnectionRealTimeInfo dcRtInfo) {
         // default implementation empty
@@ -2214,11 +913,12 @@
      * {@link SubscriptionManager#getDefaultSubscriptionId()}.
      *
      * @hide
+     * @deprecated Use {@link TelephonyCallback.SrvccStateListener} instead.
      */
     @SystemApi
+    @Deprecated
     public void onSrvccStateChanged(@SrvccState int srvccState) {
         // default implementation empty
-
     }
 
     /**
@@ -2233,8 +933,10 @@
      *
      * @param state is the current SIM voice activation state
      * @hide
+     * @deprecated Use {@link TelephonyCallback.VoiceActivationStateListener} instead.
      */
     @SystemApi
+    @Deprecated
     public void onVoiceActivationStateChanged(@SimActivationState int state) {
         // default implementation empty
     }
@@ -2251,7 +953,9 @@
      *
      * @param state is the current SIM data activation state
      * @hide
+     * @deprecated Use {@link TelephonyCallback.DataActivationStateListener} instead.
      */
+    @Deprecated
     public void onDataActivationStateChanged(@SimActivationState int state) {
         // default implementation empty
     }
@@ -2266,7 +970,9 @@
      * {@link SubscriptionManager#getDefaultSubscriptionId()}.
      *
      * @param enabled indicates whether the current user mobile data state is enabled or disabled.
+     * @deprecated Use {@link TelephonyCallback.UserMobileDataStateListener} instead.
      */
+    @Deprecated
     public void onUserMobileDataStateChanged(boolean enabled) {
         // default implementation empty
     }
@@ -2280,8 +986,10 @@
      * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
      *
      * @param telephonyDisplayInfo The display information.
+     * @deprecated Use {@link TelephonyCallback.DisplayInfoListener} instead.
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @Deprecated
     public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo telephonyDisplayInfo) {
         // default implementation empty
     }
@@ -2304,7 +1012,9 @@
      *                            {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} as
      *                            the key and a list of emergency numbers as the value. If no
      *                            emergency number information is available, the value will be null.
+     * @deprecated Use {@link TelephonyCallback.EmergencyNumberListListener} instead.
      */
+    @Deprecated
     public void onEmergencyNumberListChanged(
             @NonNull Map<Integer, List<EmergencyNumber>> emergencyNumberList) {
         // default implementation empty
@@ -2317,7 +1027,6 @@
      * the no-SIM case), regardless of which subscription this listener was registered on.
      *
      * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was placed to.
-     *
      * @deprecated Use {@link #onOutgoingEmergencyCall(EmergencyNumber, int)}.
      * @hide
      */
@@ -2344,9 +1053,11 @@
      *                       are no SIM cards in the device), this will be equal to
      *                       {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
      * @hide
+     * @deprecated Use {@link TelephonyCallback.OutgoingEmergencyCallListener} instead.
      */
     @SystemApi
     @TestApi
+    @Deprecated
     public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber,
             int subscriptionId) {
         // Default implementation for backwards compatibility
@@ -2361,6 +1072,7 @@
      *
      * @deprecated Use {@link #onOutgoingEmergencySms(EmergencyNumber, int)}.
      * @hide
+     * @deprecated Use {@link TelephonyCallback.OutgoingEmergencySmsListener} instead.
      */
     @SystemApi
     @TestApi
@@ -2383,9 +1095,11 @@
      * @param sentEmergencyNumber The {@link EmergencyNumber} the emergency sms was sent to.
      * @param subscriptionId The subscription ID used to send the emergency sms.
      * @hide
+     * @deprecated Use {@link TelephonyCallback.OutgoingEmergencySmsListener} instead.
      */
     @SystemApi
     @TestApi
+    @Deprecated
     public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber,
             int subscriptionId) {
         // Default implementation for backwards compatibility
@@ -2395,8 +1109,7 @@
     /**
      * Callback invoked when OEM hook raw event is received on the registered subscription.
      * Note, the registration subId comes from {@link TelephonyManager} object which registers
-     * PhoneStateListener by
-     * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+     * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}.
      * If this TelephonyManager object was created with
      * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
      * subId. Otherwise, this callback applies to
@@ -2405,8 +1118,10 @@
      * Requires the READ_PRIVILEGED_PHONE_STATE permission.
      * @param rawData is the byte array of the OEM hook raw data.
      * @hide
+     * @deprecated OEM needs a vendor-extension hal and their apps should use that instead
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @Deprecated
     public void onOemHookRawEvent(byte[] rawData) {
         // default implementation empty
     }
@@ -2417,7 +1132,9 @@
      *
      * @param capability the new phone capability
      * @hide
+     * @deprecated Use {@link TelephonyCallback.PhoneCapabilityListener} instead.
      */
+    @Deprecated
     public void onPhoneCapabilityChanged(@NonNull PhoneCapability capability) {
         // default implementation empty
     }
@@ -2430,7 +1147,9 @@
      * @param subId current subscription used to setup Cellular Internet data.
      *              For example, it could be the current active opportunistic subscription in use,
      *              or the subscription user selected as default data subscription in DSDS mode.
+     * @deprecated Use {@link TelephonyCallback.ActiveDataSubscriptionIdListener} instead.
      */
+    @Deprecated
     public void onActiveDataSubscriptionIdChanged(int subId) {
         // default implementation empty
     }
@@ -2447,8 +1166,10 @@
      * Requires the READ_PRECISE_PHONE_STATE permission.
      * @param callAttributes the call attributes
      * @hide
+     * @deprecated Use {@link TelephonyCallback.CallAttributesListener} instead.
      */
     @SystemApi
+    @Deprecated
     public void onCallAttributesChanged(@NonNull CallAttributes callAttributes) {
         // default implementation empty
     }
@@ -2466,8 +1187,10 @@
      *
      * @param state the modem radio power state
      * @hide
+     * @deprecated Use {@link TelephonyCallback.RadioPowerStateListener} instead.
      */
     @SystemApi
+    @Deprecated
     public void onRadioPowerStateChanged(@RadioPowerState int state) {
         // default implementation empty
     }
@@ -2485,9 +1208,10 @@
      * @param active Whether the carrier network change is or shortly
      *               will be active. This value is true to indicate
      *               showing alternative UI and false to stop.
-     *
      * @hide
+     * @deprecated Use {@link TelephonyCallback.CarrierNetworkListener} instead.
      */
+    @Deprecated
     public void onCarrierNetworkChange(boolean active) {
         // default implementation empty
     }
@@ -2518,7 +1242,9 @@
      *        For UMTS, if a combined attach succeeds for PS only, then the GMM cause code shall be
      *        included as an additionalCauseCode. For LTE (ESM), cause codes are in
      *        TS 24.301 9.9.4.4. Integer.MAX_VALUE if this value is unused.
+     * @deprecated Use {@link TelephonyCallback.RegistrationFailedListener} instead.
      */
+    @Deprecated
     public void onRegistrationFailed(@NonNull CellIdentity cellIdentity, @NonNull String chosenPlmn,
             int domain, int causeCode, int additionalCauseCode) {
         // default implementation empty
@@ -2531,9 +1257,10 @@
      * cell, for the registered PLMN and current access class/access category.
      *
      * @param barringInfo for all services on the current cell.
-     *
      * @see android.telephony.BarringInfo
+     * @deprecated Use {@link TelephonyCallback.BarringInfoListener} instead.
      */
+    @Deprecated
     public void onBarringInfoChanged(@NonNull BarringInfo barringInfo) {
         // default implementation empty
     }
@@ -2829,7 +1556,7 @@
 
             Binder.withCleanCallingIdentity(
                     () -> mExecutor.execute(() -> psl.onRegistrationFailed(
-                                cellIdentity, chosenPlmn, domain, causeCode, additionalCauseCode)));
+                            cellIdentity, chosenPlmn, domain, causeCode, additionalCauseCode)));
             // default implementation empty
         }
 
@@ -2842,33 +1569,15 @@
         }
 
         public void onPhysicalChannelConfigChanged(List<PhysicalChannelConfig> configs) {
-            PhysicalChannelConfigChangedListener listener =
-                    (PhysicalChannelConfigChangedListener) mPhoneStateListenerWeakRef.get();
-            if (listener == null) return;
-
-            Binder.withCleanCallingIdentity(
-                    () -> mExecutor.execute(() -> listener.onPhysicalChannelConfigChanged(
-                            configs)));
+            // default implementation empty
         }
 
         public void onDataEnabledChanged(boolean enabled, @DataEnabledReason int reason) {
-                DataEnabledChangedListener listener =
-                        (DataEnabledChangedListener) mPhoneStateListenerWeakRef.get();
-                if (listener == null) return;
-
-                Binder.withCleanCallingIdentity(
-                        () -> mExecutor.execute(() -> listener.onDataEnabledChanged(
-                                enabled, reason)));
+            // default implementation empty
         }
 
         public void onAllowedNetworkTypesChanged(Map allowedNetworkTypesList) {
-            AllowedNetworkTypesChangedListener listener =
-                    (AllowedNetworkTypesChangedListener) mPhoneStateListenerWeakRef.get();
-            if (listener == null) return;
-
-            Binder.withCleanCallingIdentity(
-                    () -> mExecutor.execute(
-                            () -> listener.onAllowedNetworkTypesChanged(allowedNetworkTypesList)));
+            // default implementation empty
         }
     }
 
diff --git a/core/java/android/telephony/TelephonyCallback.java b/core/java/android/telephony/TelephonyCallback.java
new file mode 100644
index 0000000..a2584cae
--- /dev/null
+++ b/core/java/android/telephony/TelephonyCallback.java
@@ -0,0 +1,1710 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.Manifest;
+import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Binder;
+import android.os.Build;
+import android.telephony.emergency.EmergencyNumber;
+import android.telephony.ims.ImsReasonInfo;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.IPhoneStateListener;
+
+import dalvik.system.VMRuntime;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * A callback class for monitoring changes in specific telephony states
+ * on the device, including service state, signal strength, message
+ * waiting indicator (voicemail), and others.
+ * <p>
+ * To register a callback, use a {@link TelephonyCallback} which implements interfaces regarding
+ * EVENT_*. For example,
+ * FakeServiceStateCallback extends {@link TelephonyCallback} implements
+ * {@link TelephonyCallback.ServiceStateListener}.
+ * <p>
+ * Then override the methods for the state that you wish to receive updates for, and
+ * pass the executor and your TelephonyCallback object to
+ * {@link TelephonyManager#registerTelephonyCallback}.
+ * Methods are called when the state changes, as well as once on initial registration.
+ * <p>
+ * Note that access to some telephony information is
+ * permission-protected. Your application won't receive updates for protected
+ * information unless it has the appropriate permissions declared in
+ * its manifest file. Where permissions apply, they are noted in the
+ * appropriate sub-interfaces.
+ */
+public class TelephonyCallback {
+
+    /**
+     * Experiment flag to set the per-pid registration limit for TelephonyCallback
+     *
+     * Limit on registrations of {@link TelephonyCallback}s on a per-pid basis. When this limit is
+     * exceeded, any calls to {@link TelephonyManager#registerTelephonyCallback} will fail with an
+     * {@link IllegalStateException}.
+     *
+     * {@link android.os.Process#PHONE_UID}, {@link android.os.Process#SYSTEM_UID}, and the uid that
+     * TelephonyRegistry runs under are exempt from this limit.
+     *
+     * If the value of the flag is less than 1, enforcement of the limit will be disabled.
+     * @hide
+     */
+    public static final String FLAG_PER_PID_REGISTRATION_LIMIT =
+            "phone_state_listener_per_pid_registration_limit";
+
+    /**
+     * Default value for the per-pid registration limit.
+     * See {@link #FLAG_PER_PID_REGISTRATION_LIMIT}.
+     * @hide
+     */
+    public static final int DEFAULT_PER_PID_REGISTRATION_LIMIT = 50;
+
+    /**
+     * This change enables a limit on the number of {@link TelephonyCallback} objects any process
+     * may register via {@link TelephonyManager#registerTelephonyCallback}. The default limit is 50,
+     * which may change via remote device config updates.
+     *
+     * This limit is enforced via an {@link IllegalStateException} thrown from
+     * {@link TelephonyManager#registerTelephonyCallback} when the offending process attempts to
+     * register one too many callbacks.
+     *
+     * @hide
+     */
+    @ChangeId
+    public static final long PHONE_STATE_LISTENER_LIMIT_CHANGE_ID = 150880553L;
+
+    /**
+     * Event for changes to the network service state (cellular).
+     *
+     * @hide
+     * @see ServiceStateListener#onServiceStateChanged
+     * @see ServiceState
+     */
+    @SystemApi
+    public static final int EVENT_SERVICE_STATE_CHANGED = 1;
+
+    /**
+     * Event for changes to the network signal strength (cellular).
+     *
+     * @hide
+     * @see SignalStrengthsListener#onSignalStrengthsChanged
+     */
+    @SystemApi
+    public static final int EVENT_SIGNAL_STRENGTH_CHANGED = 2;
+
+    /**
+     * Event for changes to the message-waiting indicator.
+     * <p>
+     * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE} or that
+     * the calling app has carrier privileges (see
+     * {@link TelephonyManager#hasCarrierPrivileges}).
+     * <p>
+     * Example: The status bar uses this to determine when to display the
+     * voicemail icon.
+     *
+     * @hide
+     * @see MessageWaitingIndicatorListener#onMessageWaitingIndicatorChanged
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public static final int EVENT_MESSAGE_WAITING_INDICATOR_CHANGED = 3;
+
+    /**
+     * Event for changes to the call-forwarding indicator.
+     * <p>
+     * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE} or that
+     * the calling app has carrier privileges (see
+     * {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @hide
+     * @see CallForwardingIndicatorListener#onCallForwardingIndicatorChanged
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public static final int EVENT_CALL_FORWARDING_INDICATOR_CHANGED = 4;
+
+    /**
+     * Event for changes to the device's cell location. Note that
+     * this will result in frequent listeners to the listener.
+     * <p>
+     * If you need regular location updates but want more control over
+     * the update interval or location precision, you can set up a callback
+     * through the {@link android.location.LocationManager location manager}
+     * instead.
+     *
+     * @hide
+     * @see CellLocationListener#onCellLocationChanged
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
+    public static final int EVENT_CELL_LOCATION_CHANGED = 5;
+
+    /**
+     * Event for changes to the device call state.
+     *
+     * @hide
+     * @see CallStateListener#onCallStateChanged
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_CALL_LOG)
+    public static final int EVENT_CALL_STATE_CHANGED = 6;
+
+    /**
+     * Event for changes to the data connection state (cellular).
+     *
+     * @hide
+     * @see DataConnectionStateListener#onDataConnectionStateChanged
+     */
+    @SystemApi
+    public static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 7;
+
+    /**
+     * Event for changes to the direction of data traffic on the data
+     * connection (cellular).
+     * <p>
+     * Example: The status bar uses this to display the appropriate
+     * data-traffic icon.
+     *
+     * @hide
+     * @see DataActivityListener#onDataActivity
+     */
+    @SystemApi
+    public static final int EVENT_DATA_ACTIVITY_CHANGED = 8;
+
+    /**
+     * Event for changes to the network signal strengths (cellular).
+     * <p>
+     * Example: The status bar uses this to control the signal-strength
+     * icon.
+     *
+     * @hide
+     * @see SignalStrengthsListener#onSignalStrengthsChanged
+     */
+    @SystemApi
+    public static final int EVENT_SIGNAL_STRENGTHS_CHANGED = 9;
+
+    /**
+     * Event for changes of the network signal strengths (cellular) always reported from modem,
+     * even in some situations such as the screen of the device is off.
+     *
+     * @hide
+     * @see AlwaysReportedSignalStrengthListener#onSignalStrengthsChanged
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
+    public static final int EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED = 10;
+
+    /**
+     * Event for changes to observed cell info.
+     *
+     * @hide
+     * @see CellInfoListener#onCellInfoChanged
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
+    public static final int EVENT_CELL_INFO_CHANGED = 11;
+
+    /**
+     * Event for {@link android.telephony.Annotation.PreciseCallStates} of ringing,
+     * background and foreground calls.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @hide
+     * @see PreciseCallStateListener#onPreciseCallStateChanged
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public static final int EVENT_PRECISE_CALL_STATE_CHANGED = 12;
+
+    /**
+     * Event for {@link PreciseDataConnectionState} on the data connection (cellular).
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @hide
+     * @see PreciseDataConnectionStateListener#onPreciseDataConnectionStateChanged
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public static final int EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED = 13;
+
+    /**
+     * Event for real time info for all data connections (cellular)).
+     *
+     * @hide
+     * @see PhoneStateListener#onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo)
+     * @deprecated Use {@link TelephonyManager#requestModemActivityInfo}
+     */
+    @Deprecated
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public static final int EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED = 14;
+
+    /**
+     * Event for OEM hook raw event
+     *
+     * @hide
+     * @see PhoneStateListener#onOemHookRawEvent
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public static final int EVENT_OEM_HOOK_RAW = 15;
+
+    /**
+     * Event for changes to the SRVCC state of the active call.
+     *
+     * @hide
+     * @see SrvccStateListener#onSrvccStateChanged
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public static final int EVENT_SRVCC_STATE_CHANGED = 16;
+
+    /**
+     * Event for carrier network changes indicated by a carrier app.
+     *
+     * @hide
+     * @see android.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean)
+     * @see CarrierNetworkListener#onCarrierNetworkChange
+     */
+    @SystemApi
+    public static final int EVENT_CARRIER_NETWORK_CHANGED = 17;
+
+    /**
+     * Event for changes to the sim voice activation state
+     *
+     * @hide
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN
+     * <p>
+     * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates voice service has been
+     * fully activated
+     * @see VoiceActivationStateListener#onVoiceActivationStateChanged
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public static final int EVENT_VOICE_ACTIVATION_STATE_CHANGED = 18;
+
+    /**
+     * Event for changes to the sim data activation state
+     *
+     * @hide
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN
+     * <p>
+     * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates data service has been
+     * fully activated
+     * @see DataActivationStateListener#onDataActivationStateChanged
+     */
+    @SystemApi
+    public static final int EVENT_DATA_ACTIVATION_STATE_CHANGED = 19;
+
+    /**
+     * Event for changes to the user mobile data state
+     *
+     * @hide
+     * @see UserMobileDataStateListener#onUserMobileDataStateChanged
+     */
+    @SystemApi
+    public static final int EVENT_USER_MOBILE_DATA_STATE_CHANGED = 20;
+
+    /**
+     * Event for display info changed event.
+     *
+     * @hide
+     * @see DisplayInfoListener#onDisplayInfoChanged
+     */
+    @SystemApi
+    public static final int EVENT_DISPLAY_INFO_CHANGED = 21;
+
+    /**
+     * Event for changes to the phone capability.
+     *
+     * @hide
+     * @see PhoneCapabilityListener#onPhoneCapabilityChanged
+     */
+    @SystemApi
+    public static final int EVENT_PHONE_CAPABILITY_CHANGED = 22;
+
+    /**
+     * Event for changes to active data subscription ID. Active data subscription is
+     * the current subscription used to setup Cellular Internet data. For example,
+     * it could be the current active opportunistic subscription in use, or the
+     * subscription user selected as default data subscription in DSDS mode.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
+     * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @hide
+     * @see ActiveDataSubscriptionIdListener#onActiveDataSubscriptionIdChanged
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public static final int EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED = 23;
+
+    /**
+     * Event for changes to the radio power state.
+     *
+     * @hide
+     * @see RadioPowerStateListener#onRadioPowerStateChanged
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public static final int EVENT_RADIO_POWER_STATE_CHANGED = 24;
+
+    /**
+     * Event for changes to emergency number list based on all active subscriptions.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
+     * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @hide
+     * @see EmergencyNumberListListener#onEmergencyNumberListChanged
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public static final int EVENT_EMERGENCY_NUMBER_LIST_CHANGED = 25;
+
+    /**
+     * Event for call disconnect causes which contains {@link DisconnectCause} and
+     * {@link PreciseDisconnectCause}.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @hide
+     * @see CallDisconnectCauseListener#onCallDisconnectCauseChanged
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public static final int EVENT_CALL_DISCONNECT_CAUSE_CHANGED = 26;
+
+    /**
+     * Event for changes to the call attributes of a currently active call.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @hide
+     * @see CallAttributesListener#onCallAttributesChanged
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public static final int EVENT_CALL_ATTRIBUTES_CHANGED = 27;
+
+    /**
+     * Event for IMS call disconnect causes which contains
+     * {@link android.telephony.ims.ImsReasonInfo}
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @hide
+     * @see ImsCallDisconnectCauseListener#onImsCallDisconnectCauseChanged(ImsReasonInfo)
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public static final int EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED = 28;
+
+    /**
+     * Event for the emergency number placed from an outgoing call.
+     *
+     * @hide
+     * @see OutgoingEmergencyCallListener#onOutgoingEmergencyCall
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
+    public static final int EVENT_OUTGOING_EMERGENCY_CALL = 29;
+
+    /**
+     * Event for the emergency number placed from an outgoing SMS.
+     *
+     * @hide
+     * @see OutgoingEmergencySmsListener#onOutgoingEmergencySms
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
+    public static final int EVENT_OUTGOING_EMERGENCY_SMS = 30;
+
+    /**
+     * Event for registration failures.
+     * <p>
+     * Event for indications that a registration procedure has failed in either the CS or PS
+     * domain. This indication does not necessarily indicate a change of service state, which should
+     * be tracked via {@link #EVENT_SERVICE_STATE_CHANGED}.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or
+     * the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * <p>Also requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission, regardless
+     * of whether the calling app has carrier privileges.
+     *
+     * @hide
+     * @see RegistrationFailedListener#onRegistrationFailed
+     */
+    @SystemApi
+    @RequiresPermission(allOf = {
+            Manifest.permission.READ_PRECISE_PHONE_STATE,
+            Manifest.permission.ACCESS_FINE_LOCATION
+    })
+    public static final int EVENT_REGISTRATION_FAILURE = 31;
+
+    /**
+     * Event for Barring Information for the current registered / camped cell.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or
+     * the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * <p>Also requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission, regardless
+     * of whether the calling app has carrier privileges.
+     *
+     * @hide
+     * @see BarringInfoListener#onBarringInfoChanged
+     */
+    @SystemApi
+    @RequiresPermission(allOf = {
+            Manifest.permission.READ_PRECISE_PHONE_STATE,
+            Manifest.permission.ACCESS_FINE_LOCATION
+    })
+    public static final int EVENT_BARRING_INFO_CHANGED = 32;
+
+    /**
+     * Event for changes to the physical channel configuration.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @hide
+     * @see PhysicalChannelConfigListener#onPhysicalChannelConfigChanged
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 33;
+
+
+    /**
+     * Event for changes to the data enabled.
+     * <p>
+     * Event for indications that the enabled status of current data has changed.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @hide
+     * @see DataEnabledListener#onDataEnabledChanged
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public static final int EVENT_DATA_ENABLED_CHANGED = 34;
+
+    /**
+     * Event for changes to allowed network list based on all active subscriptions.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
+     * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @hide
+     * @see AllowedNetworkTypesListener#onAllowedNetworkTypesChanged
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public static final int EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED = 35;
+
+    /**
+     * @hide
+     */
+    @IntDef(prefix = {"EVENT_"}, value = {
+            EVENT_SERVICE_STATE_CHANGED,
+            EVENT_SIGNAL_STRENGTH_CHANGED,
+            EVENT_MESSAGE_WAITING_INDICATOR_CHANGED,
+            EVENT_CALL_FORWARDING_INDICATOR_CHANGED,
+            EVENT_CELL_LOCATION_CHANGED,
+            EVENT_CALL_STATE_CHANGED,
+            EVENT_DATA_CONNECTION_STATE_CHANGED,
+            EVENT_DATA_ACTIVITY_CHANGED,
+            EVENT_SIGNAL_STRENGTHS_CHANGED,
+            EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED,
+            EVENT_CELL_INFO_CHANGED,
+            EVENT_PRECISE_CALL_STATE_CHANGED,
+            EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED,
+            EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED,
+            EVENT_OEM_HOOK_RAW,
+            EVENT_SRVCC_STATE_CHANGED,
+            EVENT_CARRIER_NETWORK_CHANGED,
+            EVENT_VOICE_ACTIVATION_STATE_CHANGED,
+            EVENT_DATA_ACTIVATION_STATE_CHANGED,
+            EVENT_USER_MOBILE_DATA_STATE_CHANGED,
+            EVENT_DISPLAY_INFO_CHANGED,
+            EVENT_PHONE_CAPABILITY_CHANGED,
+            EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED,
+            EVENT_RADIO_POWER_STATE_CHANGED,
+            EVENT_EMERGENCY_NUMBER_LIST_CHANGED,
+            EVENT_CALL_DISCONNECT_CAUSE_CHANGED,
+            EVENT_CALL_ATTRIBUTES_CHANGED,
+            EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED,
+            EVENT_OUTGOING_EMERGENCY_CALL,
+            EVENT_OUTGOING_EMERGENCY_SMS,
+            EVENT_REGISTRATION_FAILURE,
+            EVENT_BARRING_INFO_CHANGED,
+            EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED,
+            EVENT_DATA_ENABLED_CHANGED,
+            EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TelephonyEvent {
+    }
+
+    /**
+     * @hide
+     */
+    //TODO: The maxTargetSdk should be S if the build time tool updates it.
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    public IPhoneStateListener callback;
+
+    /**
+     * @hide
+     */
+    public void init(@NonNull @CallbackExecutor Executor executor) {
+        if (executor == null) {
+            throw new IllegalArgumentException("TelephonyCallback Executor must be non-null");
+        }
+        callback = new IPhoneStateListenerStub(this, executor);
+    }
+
+    /**
+     * Interface for service state listener.
+     */
+    public interface ServiceStateListener {
+        /**
+         * Callback invoked when device service state changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         * <p>
+         * The instance of {@link ServiceState} passed as an argument here will have various
+         * levels of location information stripped from it depending on the location permissions
+         * that your app holds.
+         * Only apps holding the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission will
+         * receive all the information in {@link ServiceState}.
+         *
+         * @see ServiceState#STATE_EMERGENCY_ONLY
+         * @see ServiceState#STATE_IN_SERVICE
+         * @see ServiceState#STATE_OUT_OF_SERVICE
+         * @see ServiceState#STATE_POWER_OFF
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+        public void onServiceStateChanged(@NonNull ServiceState serviceState);
+    }
+
+    /**
+     * Interface for message waiting indicator listener.
+     */
+    public interface MessageWaitingIndicatorListener {
+        /**
+         * Callback invoked when the message-waiting indicator changes on the registered
+         * subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+        public void onMessageWaitingIndicatorChanged(boolean mwi);
+    }
+
+    /**
+     * Interface for call-forwarding indicator listener.
+     */
+    public interface CallForwardingIndicatorListener {
+        /**
+         * Callback invoked when the call-forwarding indicator changes on the registered
+         * subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+        public void onCallForwardingIndicatorChanged(boolean cfi);
+    }
+
+    /**
+     * Interface for device cell location listener.
+     */
+    public interface CellLocationListener {
+        /**
+         * Callback invoked when device cell location changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         */
+        @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
+        public void onCellLocationChanged(@NonNull CellLocation location);
+    }
+
+    /**
+     * Interface for call state listener.
+     */
+    public interface CallStateListener {
+        /**
+         * Callback invoked when device call state changes.
+         * <p>
+         * Reports the state of Telephony (mobile) calls on the device for the registered
+         * subscription.
+         * <p>
+         * Note: the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         * <p>
+         * Note: The state returned here may differ from that returned by
+         * {@link TelephonyManager#getCallState()}. Receivers of this callback should be aware that
+         * calling {@link TelephonyManager#getCallState()} from within this callback may return a
+         * different state than the callback reports.
+         *
+         * @param state       call state
+         * @param phoneNumber call phone number. If application does not have
+         *                    {@link android.Manifest.permission#READ_CALL_LOG} permission or
+         *                    carrier
+         *                    privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an
+         *                    empty string will be
+         *                    passed as an argument.
+         */
+        @RequiresPermission(android.Manifest.permission.READ_CALL_LOG)
+        public void onCallStateChanged(@Annotation.CallState int state,
+            @Nullable String phoneNumber);
+    }
+
+    /**
+     * Interface for data connection state listener.
+     */
+    public interface DataConnectionStateListener {
+        /**
+         * Callback invoked when connection state changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param state       is the current state of data connection.
+         * @param networkType is the current network type of data connection.
+         * @see TelephonyManager#DATA_DISCONNECTED
+         * @see TelephonyManager#DATA_CONNECTING
+         * @see TelephonyManager#DATA_CONNECTED
+         * @see TelephonyManager#DATA_SUSPENDED
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+        public void onDataConnectionStateChanged(@TelephonyManager.DataState int state,
+            @Annotation.NetworkType int networkType);
+    }
+
+    /**
+     * Interface for data activity state listener.
+     */
+    public interface DataActivityListener {
+        /**
+         * Callback invoked when data activity state changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @see TelephonyManager#DATA_ACTIVITY_NONE
+         * @see TelephonyManager#DATA_ACTIVITY_IN
+         * @see TelephonyManager#DATA_ACTIVITY_OUT
+         * @see TelephonyManager#DATA_ACTIVITY_INOUT
+         * @see TelephonyManager#DATA_ACTIVITY_DORMANT
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+        public void onDataActivity(@Annotation.DataActivityType int direction);
+    }
+
+    /**
+     * Interface for network signal strengths listener.
+     */
+    public interface SignalStrengthsListener {
+        /**
+         * Callback invoked when network signal strengths changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+        public void onSignalStrengthsChanged(@NonNull SignalStrength signalStrength);
+    }
+
+    /**
+     * Interface for network signal strengths callback which always reported from modem.
+     */
+    public interface AlwaysReportedSignalStrengthListener {
+        /**
+         * Callback always invoked from modem when network signal strengths changes on the
+         * registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         */
+        @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
+        public void onSignalStrengthsChanged(@NonNull SignalStrength signalStrength);
+    }
+
+    /**
+     * Interface for cell info listener.
+     */
+    public interface CellInfoListener {
+        /**
+         * Callback invoked when a observed cell info has changed or new cells have been added
+         * or removed on the registered subscription.
+         * Note, the registration subscription ID s from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param cellInfo is the list of currently visible cells.
+         */
+        @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
+        public void onCellInfoChanged(@NonNull List<CellInfo> cellInfo);
+    }
+
+    /**
+     * Interface for precise device call state listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface PreciseCallStateListener {
+        /**
+         * Callback invoked when precise device call state changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param callState {@link PreciseCallState}
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+        public void onPreciseCallStateChanged(@NonNull PreciseCallState callState);
+    }
+
+    /**
+     * Interface for call disconnect cause listener.
+     */
+    public interface CallDisconnectCauseListener {
+        /**
+         * Callback invoked when call disconnect cause changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param disconnectCause        {@link DisconnectCause}.
+         * @param preciseDisconnectCause {@link PreciseDisconnectCause}.
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+        public void onCallDisconnectCauseChanged(@Annotation.DisconnectCauses int disconnectCause,
+            @Annotation.PreciseDisconnectCauses int preciseDisconnectCause);
+    }
+
+    /**
+     * Interface for IMS call disconnect cause listener.
+     */
+    public interface ImsCallDisconnectCauseListener {
+        /**
+         * Callback invoked when IMS call disconnect cause changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param imsReasonInfo {@link ImsReasonInfo} contains details on why IMS call failed.
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+        public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo);
+    }
+
+    /**
+     * Interface for precise data connection state listener.
+     */
+    public interface PreciseDataConnectionStateListener {
+        /**
+         * Callback providing update about the default/internet data connection on the registered
+         * subscription.
+         * <p>
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+         * or the calling app has carrier privileges
+         * (see {@link TelephonyManager#hasCarrierPrivileges}).
+         *
+         * @param dataConnectionState {@link PreciseDataConnectionState}
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+        public void onPreciseDataConnectionStateChanged(
+            @NonNull PreciseDataConnectionState dataConnectionState);
+    }
+
+    /**
+     * Interface for Single Radio Voice Call Continuity listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface SrvccStateListener {
+        /**
+         * Callback invoked when there has been a change in the Single Radio Voice Call Continuity
+         * (SRVCC) state for the currently active call on the registered subscription.
+         * <p>
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         */
+        @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+        public void onSrvccStateChanged(@Annotation.SrvccState int srvccState);
+    }
+
+    /**
+     * Interface for SIM voice activation state listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface VoiceActivationStateListener {
+        /**
+         * Callback invoked when the SIM voice activation state has changed on the registered
+         * subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param state is the current SIM voice activation state
+         */
+        @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+        public void onVoiceActivationStateChanged(@Annotation.SimActivationState int state);
+
+    }
+
+    /**
+     * Interface for SIM data activation state listener.
+     */
+    public interface DataActivationStateListener {
+        /**
+         * Callback invoked when the SIM data activation state has changed on the registered
+         * subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param state is the current SIM data activation state
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+        public void onDataActivationStateChanged(@Annotation.SimActivationState int state);
+    }
+
+    /**
+     * Interface for user mobile data state listener.
+     */
+    public interface UserMobileDataStateListener {
+        /**
+         * Callback invoked when the user mobile data state has changed on the registered
+         * subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param enabled indicates whether the current user mobile data state is enabled or
+         *                disabled.
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+        public void onUserMobileDataStateChanged(boolean enabled);
+    }
+
+    /**
+     * Interface for display info listener.
+     */
+    public interface DisplayInfoListener {
+        /**
+         * Callback invoked when the display info has changed on the registered subscription.
+         * <p> The {@link TelephonyDisplayInfo} contains status information shown to the user
+         * based on carrier policy.
+         *
+         * @param telephonyDisplayInfo The display information.
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+        public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo telephonyDisplayInfo);
+    }
+
+    /**
+     * Interface for the current emergency number list listener.
+     */
+    public interface EmergencyNumberListListener {
+        /**
+         * Callback invoked when the current emergency number list has changed on the registered
+         * subscription.
+         * <p>
+         * Note, the registered subscription is associated with {@link TelephonyManager} object
+         * on which
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}
+         * was called.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * given subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param emergencyNumberList Map associating all active subscriptions on the device with
+         *                            the list of emergency numbers originating from that
+         *                            subscription.
+         *                            If there are no active subscriptions, the map will contain a
+         *                            single entry with
+         *                            {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} as
+         *                            the key and a list of emergency numbers as the value. If no
+         *                            emergency number information is available, the value will be
+         *                            empty.
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+        public void onEmergencyNumberListChanged(
+            @NonNull Map<Integer, List<EmergencyNumber>> emergencyNumberList);
+    }
+
+    /**
+     * Interface for outgoing emergency call listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface OutgoingEmergencyCallListener {
+        /**
+         * Callback invoked when an outgoing call is placed to an emergency number.
+         * <p>
+         * This method will be called when an emergency call is placed on any subscription
+         * (including the no-SIM case), regardless of which subscription this callback was
+         * registered on.
+         * <p>
+         *
+         * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was
+         *                              placed to.
+         * @param subscriptionId        The subscription ID used to place the emergency call. If the
+         *                              emergency call was placed without a valid subscription
+         *                              (e.g. when there are no SIM cards in the device), this
+         *                              will be
+         *                              equal to
+         *                              {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
+         */
+        @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
+        public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber,
+            int subscriptionId);
+    }
+
+    /**
+     * Interface for outgoing emergency sms listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface OutgoingEmergencySmsListener {
+        /**
+         * Smsback invoked when an outgoing sms is sent to an emergency number.
+         * <p>
+         * This method will be called when an emergency sms is sent on any subscription,
+         * regardless of which subscription this callback was registered on.
+         *
+         * @param sentEmergencyNumber The {@link EmergencyNumber} the emergency sms was sent to.
+         * @param subscriptionId      The subscription ID used to send the emergency sms.
+         */
+        @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
+        public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber,
+            int subscriptionId);
+    }
+
+    /**
+     * Interface for phone capability listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface PhoneCapabilityListener {
+        /**
+         * Callback invoked when phone capability changes.
+         * Note, this callback triggers regardless of registered subscription.
+         *
+         * @param capability the new phone capability
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+        public void onPhoneCapabilityChanged(@NonNull PhoneCapability capability);
+    }
+
+    /**
+     * Interface for active data subscription ID listener.
+     */
+    public interface ActiveDataSubscriptionIdListener {
+        /**
+         * Callback invoked when active data subscription ID changes.
+         * Note, this callback triggers regardless of registered subscription.
+         *
+         * @param subId current subscription used to setup Cellular Internet data.
+         *              For example, it could be the current active opportunistic subscription
+         *              in use, or the subscription user selected as default data subscription in
+         *              DSDS mode.
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+        public void onActiveDataSubscriptionIdChanged(int subId);
+    }
+
+    /**
+     * Interface for modem radio power state listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface RadioPowerStateListener {
+        /**
+         * Callback invoked when modem radio power state changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param state the modem radio power state
+         */
+        @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+        public void onRadioPowerStateChanged(@Annotation.RadioPowerState int state);
+    }
+
+    /**
+     * Interface for carrier network listener.
+     */
+    public interface CarrierNetworkListener {
+        /**
+         * Callback invoked when telephony has received notice from a carrier
+         * app that a network action that could result in connectivity loss
+         * has been requested by an app using
+         * {@link android.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean)}
+         * <p>
+         * This is optional and is only used to allow the system to provide alternative UI while
+         * telephony is performing an action that may result in intentional, temporary network
+         * lack of connectivity.
+         * <p>
+         * Note, this callback is pinned to the registered subscription and will be invoked when
+         * the notifying carrier app has carrier privilege rule on the registered
+         * subscription. {@link android.telephony.TelephonyManager#hasCarrierPrivileges}
+         *
+         * @param active If the carrier network change is or shortly will be active,
+         *               {@code true} indicate that showing alternative UI, {@code false} otherwise.
+         */
+        public void onCarrierNetworkChange(boolean active);
+    }
+
+    /**
+     * Interface for registration failures listener.
+     */
+    public interface RegistrationFailedListener {
+        /**
+         * Report that Registration or a Location/Routing/Tracking Area update has failed.
+         *
+         * <p>Indicate whenever a registration procedure, including a location, routing, or tracking
+         * area update fails. This includes procedures that do not necessarily result in a change of
+         * the modem's registration status. If the modem's registration status changes, that is
+         * reflected in the onNetworkStateChanged() and subsequent
+         * get{Voice/Data}RegistrationState().
+         *
+         * <p>Because registration failures are ephemeral, this callback is not sticky.
+         * Registrants will not receive the most recent past value when registering.
+         *
+         * @param cellIdentity        the CellIdentity, which must include the globally unique
+         *                            identifier
+         *                            for the cell (for example, all components of the CGI or ECGI).
+         * @param chosenPlmn          a 5 or 6 digit alphanumeric PLMN (MCC|MNC) among those
+         *                            broadcast by the
+         *                            cell that was chosen for the failed registration attempt.
+         * @param domain              DOMAIN_CS, DOMAIN_PS or both in case of a combined procedure.
+         * @param causeCode           the primary failure cause code of the procedure.
+         *                            For GSM/UMTS (MM), values are in TS 24.008 Sec 10.5.95
+         *                            For GSM/UMTS (GMM), values are in TS 24.008 Sec 10.5.147
+         *                            For LTE (EMM), cause codes are TS 24.301 Sec 9.9.3.9
+         *                            For NR (5GMM), cause codes are TS 24.501 Sec 9.11.3.2
+         *                            Integer.MAX_VALUE if this value is unused.
+         * @param additionalCauseCode the cause code of any secondary/combined procedure
+         *                            if appropriate. For UMTS, if a combined attach succeeds for
+         *                            PS only, then the GMM cause code shall be included as an
+         *                            additionalCauseCode. For LTE (ESM), cause codes are in
+         *                            TS 24.301 9.9.4.4. Integer.MAX_VALUE if this value is unused.
+         */
+        @RequiresPermission(allOf = {
+                Manifest.permission.READ_PRECISE_PHONE_STATE,
+                Manifest.permission.ACCESS_FINE_LOCATION
+        })
+        public void onRegistrationFailed(@NonNull CellIdentity cellIdentity,
+            @NonNull String chosenPlmn, @NetworkRegistrationInfo.Domain int domain, int causeCode,
+            int additionalCauseCode);
+    }
+
+    /**
+     * Interface for the current allowed network type list listener. This list involves values of
+     * allowed network type for each of reasons.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface AllowedNetworkTypesListener {
+        /**
+         * Callback invoked when the current allowed network type list has changed on the
+         * registered subscription.
+         * Note, the registered subscription is associated with {@link TelephonyManager} object
+         * on which
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}
+         * was called.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * given subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param allowedNetworkTypesList Map associating all allowed network type reasons
+         * ({@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_USER},
+         * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_POWER},
+         * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_CARRIER}, and
+         * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G}) with reason's allowed
+         * network type values.
+         * For example:
+         * map{{TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_USER, long type value},
+         *     {TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_POWER, long type value},
+         *     {TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_CARRIER, long type value},
+         *     {TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G, long type value}}
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+        void onAllowedNetworkTypesChanged(@NonNull Map<Integer, Long> allowedNetworkTypesList);
+    }
+
+    /**
+     * Interface for call attributes listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface CallAttributesListener {
+        /**
+         * Callback invoked when the call attributes changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers TelephonyCallback by
+         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param callAttributes the call attributes
+         */
+        @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
+        void onCallAttributesChanged(@NonNull CallAttributes callAttributes);
+    }
+
+    /**
+     * Interface for barring information listener.
+     */
+    public interface BarringInfoListener {
+        /**
+         * Report updated barring information for the current camped/registered cell.
+         *
+         * <p>Barring info is provided for all services applicable to the current camped/registered
+         * cell, for the registered PLMN and current access class/access category.
+         *
+         * @param barringInfo for all services on the current cell.
+         * @see android.telephony.BarringInfo
+         */
+        @RequiresPermission(allOf = {
+                Manifest.permission.READ_PRECISE_PHONE_STATE,
+                Manifest.permission.ACCESS_FINE_LOCATION
+        })
+        public void onBarringInfoChanged(@NonNull BarringInfo barringInfo);
+    }
+
+    /**
+     * Interface for current physical channel configuration listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface PhysicalChannelConfigListener {
+        /**
+         * Callback invoked when the current physical channel configuration has changed
+         *
+         * @param configs List of the current {@link PhysicalChannelConfig}s
+         */
+        @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
+        public void onPhysicalChannelConfigChanged(@NonNull List<PhysicalChannelConfig> configs);
+    }
+
+    /**
+     * Interface for data enabled listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface DataEnabledListener {
+        /**
+         * Callback invoked when the data enabled changes.
+         *
+         * @param enabled {@code true} if data is enabled, otherwise disabled.
+         * @param reason  Reason for data enabled/disabled.
+         *                See {@link TelephonyManager.DataEnabledReason}.
+         */
+        @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
+        public void onDataEnabledChanged(boolean enabled,
+            @TelephonyManager.DataEnabledReason int reason);
+    }
+
+
+    /**
+     * The callback methods need to be called on the handler thread where
+     * this object was created.  If the binder did that for us it'd be nice.
+     * <p>
+     * Using a static class and weak reference here to avoid memory leak caused by the
+     * IPhoneState.Stub callback retaining references to the outside TelephonyCallback:
+     * even caller has been destroyed and "un-registered" the TelephonyCallback, it is still not
+     * eligible for GC given the references coming from:
+     * Native Stack --> TelephonyCallback --> Context (Activity).
+     * memory of caller's context will be collected after GC from service side get triggered
+     */
+    private static class IPhoneStateListenerStub extends IPhoneStateListener.Stub {
+        private WeakReference<TelephonyCallback> mTelephonyCallbackWeakRef;
+        private Executor mExecutor;
+
+        IPhoneStateListenerStub(TelephonyCallback telephonyCallback, Executor executor) {
+            mTelephonyCallbackWeakRef = new WeakReference<TelephonyCallback>(telephonyCallback);
+            mExecutor = executor;
+        }
+
+        public void onServiceStateChanged(ServiceState serviceState) {
+            ServiceStateListener listener = (ServiceStateListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onServiceStateChanged(serviceState)));
+        }
+
+        public void onSignalStrengthChanged(int asu) {
+            // default implementation empty
+        }
+
+        public void onMessageWaitingIndicatorChanged(boolean mwi) {
+            MessageWaitingIndicatorListener listener =
+                    (MessageWaitingIndicatorListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onMessageWaitingIndicatorChanged(mwi)));
+        }
+
+        public void onCallForwardingIndicatorChanged(boolean cfi) {
+            CallForwardingIndicatorListener listener =
+                    (CallForwardingIndicatorListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onCallForwardingIndicatorChanged(cfi)));
+        }
+
+        public void onCellLocationChanged(CellIdentity cellIdentity) {
+            // There is no system/public API to create an CellIdentity in system server,
+            // so the server pass a null to indicate an empty initial location.
+            CellLocation location =
+                    cellIdentity == null ? CellLocation.getEmpty() : cellIdentity.asCellLocation();
+            CellLocationListener listener = (CellLocationListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onCellLocationChanged(location)));
+        }
+
+        public void onCallStateChanged(int state, String incomingNumber) {
+            CallStateListener listener = (CallStateListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onCallStateChanged(state,
+                            incomingNumber)));
+        }
+
+        public void onDataConnectionStateChanged(int state, int networkType) {
+            DataConnectionStateListener listener =
+                    (DataConnectionStateListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            if (state == TelephonyManager.DATA_DISCONNECTING
+                    && VMRuntime.getRuntime().getTargetSdkVersion() < Build.VERSION_CODES.R) {
+                Binder.withCleanCallingIdentity(
+                        () -> mExecutor.execute(() ->
+                                listener.onDataConnectionStateChanged(
+                                        TelephonyManager.DATA_CONNECTED, networkType)));
+            } else {
+                Binder.withCleanCallingIdentity(
+                        () -> mExecutor.execute(() ->
+                                listener.onDataConnectionStateChanged(state, networkType)));
+            }
+        }
+
+        public void onDataActivity(int direction) {
+            DataActivityListener listener = (DataActivityListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onDataActivity(direction)));
+        }
+
+        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+            SignalStrengthsListener listener =
+                    (SignalStrengthsListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onSignalStrengthsChanged(
+                            signalStrength)));
+        }
+
+        public void onCellInfoChanged(List<CellInfo> cellInfo) {
+            CellInfoListener listener = (CellInfoListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onCellInfoChanged(cellInfo)));
+        }
+
+        public void onPreciseCallStateChanged(PreciseCallState callState) {
+            PreciseCallStateListener listener =
+                    (PreciseCallStateListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onPreciseCallStateChanged(callState)));
+        }
+
+        public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) {
+            CallDisconnectCauseListener listener =
+                    (CallDisconnectCauseListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onCallDisconnectCauseChanged(
+                            disconnectCause, preciseDisconnectCause)));
+        }
+
+        public void onPreciseDataConnectionStateChanged(
+                PreciseDataConnectionState dataConnectionState) {
+            PreciseDataConnectionStateListener listener =
+                    (PreciseDataConnectionStateListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(
+                            () -> listener.onPreciseDataConnectionStateChanged(
+                                    dataConnectionState)));
+        }
+
+        public void onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo dcRtInfo) {
+            // default implementation empty
+        }
+
+        public void onSrvccStateChanged(int state) {
+            SrvccStateListener listener = (SrvccStateListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onSrvccStateChanged(state)));
+        }
+
+        public void onVoiceActivationStateChanged(int activationState) {
+            VoiceActivationStateListener listener =
+                    (VoiceActivationStateListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(
+                            () -> listener.onVoiceActivationStateChanged(activationState)));
+        }
+
+        public void onDataActivationStateChanged(int activationState) {
+            DataActivationStateListener listener =
+                    (DataActivationStateListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(
+                            () -> listener.onDataActivationStateChanged(activationState)));
+        }
+
+        public void onUserMobileDataStateChanged(boolean enabled) {
+            UserMobileDataStateListener listener =
+                    (UserMobileDataStateListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(
+                            () -> listener.onUserMobileDataStateChanged(enabled)));
+        }
+
+        public void onDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo) {
+            DisplayInfoListener listener = (DisplayInfoListener)mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(
+                            () -> listener.onDisplayInfoChanged(telephonyDisplayInfo)));
+        }
+
+        public void onOemHookRawEvent(byte[] rawData) {
+            // default implementation empty
+        }
+
+        public void onCarrierNetworkChange(boolean active) {
+            CarrierNetworkListener listener =
+                    (CarrierNetworkListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onCarrierNetworkChange(active)));
+        }
+
+        public void onEmergencyNumberListChanged(Map emergencyNumberList) {
+            EmergencyNumberListListener listener =
+                    (EmergencyNumberListListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(
+                            () -> listener.onEmergencyNumberListChanged(emergencyNumberList)));
+        }
+
+        public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber,
+            int subscriptionId) {
+            OutgoingEmergencyCallListener listener =
+                    (OutgoingEmergencyCallListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(
+                            () -> listener.onOutgoingEmergencyCall(placedEmergencyNumber,
+                                    subscriptionId)));
+        }
+
+        public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber,
+            int subscriptionId) {
+            OutgoingEmergencySmsListener listener =
+                    (OutgoingEmergencySmsListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(
+                            () -> listener.onOutgoingEmergencySms(sentEmergencyNumber,
+                                    subscriptionId)));
+        }
+
+        public void onPhoneCapabilityChanged(PhoneCapability capability) {
+            PhoneCapabilityListener listener =
+                    (PhoneCapabilityListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onPhoneCapabilityChanged(capability)));
+        }
+
+        public void onRadioPowerStateChanged(@Annotation.RadioPowerState int state) {
+            RadioPowerStateListener listener =
+                    (RadioPowerStateListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onRadioPowerStateChanged(state)));
+        }
+
+        public void onCallAttributesChanged(CallAttributes callAttributes) {
+            CallAttributesListener listener =
+                    (CallAttributesListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onCallAttributesChanged(
+                            callAttributes)));
+        }
+
+        public void onActiveDataSubIdChanged(int subId) {
+            ActiveDataSubscriptionIdListener listener =
+                    (ActiveDataSubscriptionIdListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onActiveDataSubscriptionIdChanged(
+                            subId)));
+        }
+
+        public void onImsCallDisconnectCauseChanged(ImsReasonInfo disconnectCause) {
+            ImsCallDisconnectCauseListener listener =
+                    (ImsCallDisconnectCauseListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(
+                            () -> listener.onImsCallDisconnectCauseChanged(disconnectCause)));
+        }
+
+        public void onRegistrationFailed(@NonNull CellIdentity cellIdentity,
+            @NonNull String chosenPlmn, int domain, int causeCode, int additionalCauseCode) {
+            RegistrationFailedListener listener =
+                    (RegistrationFailedListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onRegistrationFailed(
+                            cellIdentity, chosenPlmn, domain, causeCode, additionalCauseCode)));
+            // default implementation empty
+        }
+
+        public void onBarringInfoChanged(BarringInfo barringInfo) {
+            BarringInfoListener listener = (BarringInfoListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onBarringInfoChanged(barringInfo)));
+        }
+
+        public void onPhysicalChannelConfigChanged(List<PhysicalChannelConfig> configs) {
+            PhysicalChannelConfigListener listener =
+                    (PhysicalChannelConfigListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onPhysicalChannelConfigChanged(
+                            configs)));
+        }
+
+        public void onDataEnabledChanged(boolean enabled,
+            @TelephonyManager.DataEnabledReason int reason) {
+            DataEnabledListener listener =
+                    (DataEnabledListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> listener.onDataEnabledChanged(
+                            enabled, reason)));
+        }
+
+        public void onAllowedNetworkTypesChanged(Map allowedNetworkTypesList) {
+            AllowedNetworkTypesListener listener =
+                    (AllowedNetworkTypesListener) mTelephonyCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(
+                            () -> listener.onAllowedNetworkTypesChanged(allowedNetworkTypesList)));
+        }
+    }
+}
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 8c51651..15d1a59 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -209,7 +209,7 @@
     }
 
     /**
-     * To check the SDK version for {@link #listenWithEventList}.
+     * To check the SDK version for {@link #listenFromListener}.
      */
     @ChangeId
     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.P)
@@ -221,24 +221,49 @@
      * @param pkg Package name
      * @param featureId Feature ID
      * @param listener Listener providing callback
-     * @param events List events
+     * @param events Events
      * @param notifyNow Whether to notify instantly
      */
-    public void listenWithEventList(int subId, @NonNull String pkg, @NonNull String featureId,
-            @NonNull PhoneStateListener listener, @NonNull int[] events, boolean notifyNow) {
+    public void listenFromListener(int subId, @NonNull String pkg, @NonNull String featureId,
+            @NonNull PhoneStateListener listener, @NonNull int events, boolean notifyNow) {
+        if (listener == null) {
+            throw new IllegalStateException("telephony service is null.");
+        }
+
         try {
+            int[] eventsList = getEventsFromBitmask(events).stream().mapToInt(i -> i).toArray();
             // subId from PhoneStateListener is deprecated Q on forward, use the subId from
             // TelephonyManager instance. Keep using subId from PhoneStateListener for pre-Q.
             if (Compatibility.isChangeEnabled(LISTEN_CODE_CHANGE)) {
                 // Since mSubId in PhoneStateListener is deprecated from Q on forward, this is
                 // the only place to set mSubId and its for "informational" only.
-                listener.mSubId = (events.length == 0)
+                listener.mSubId = (eventsList.length == 0)
                         ? SubscriptionManager.INVALID_SUBSCRIPTION_ID : subId;
             } else if (listener.mSubId != null) {
                 subId = listener.mSubId;
             }
             sRegistry.listenWithEventList(
-                    subId, pkg, featureId, listener.callback, events, notifyNow);
+                    subId, pkg, featureId, listener.callback, eventsList, notifyNow);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Listen for incoming subscriptions
+     * @param subId Subscription ID
+     * @param pkg Package name
+     * @param featureId Feature ID
+     * @param telephonyCallback Listener providing callback
+     * @param events List events
+     * @param notifyNow Whether to notify instantly
+     */
+    private void listenFromCallback(int subId, @NonNull String pkg, @NonNull String featureId,
+            @NonNull TelephonyCallback telephonyCallback, @NonNull int[] events,
+            boolean notifyNow) {
+        try {
+            sRegistry.listenWithEventList(
+                    subId, pkg, featureId, telephonyCallback.callback, events, notifyNow);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -802,11 +827,11 @@
     /**
      * Notify emergency number list changed on certain subscription.
      *
-     * @param subId for which emergency number list changed.
      * @param slotIndex for which emergency number list changed. Can be derived from subId except
      * when subId is invalid.
+     * @param subId for which emergency number list changed.
      */
-    public void notifyAllowedNetworkTypesChanged(int subId, int slotIndex,
+    public void notifyAllowedNetworkTypesChanged(int slotIndex, int subId,
             Map<Integer, Long> allowedNetworkTypeList) {
         try {
             sRegistry.notifyAllowedNetworkTypesChanged(slotIndex, subId, allowedNetworkTypeList);
@@ -815,136 +840,137 @@
         }
     }
 
-    public @NonNull Set<Integer> getEventsFromListener(@NonNull PhoneStateListener listener) {
+    public @NonNull Set<Integer> getEventsFromCallback(
+            @NonNull TelephonyCallback telephonyCallback) {
 
         Set<Integer> eventList = new ArraySet<>();
 
-        if (listener instanceof PhoneStateListener.ServiceStateChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_SERVICE_STATE_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.ServiceStateListener) {
+            eventList.add(TelephonyCallback.EVENT_SERVICE_STATE_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.MessageWaitingIndicatorChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.MessageWaitingIndicatorListener) {
+            eventList.add(TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.CallForwardingIndicatorChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.CallForwardingIndicatorListener) {
+            eventList.add(TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.CellLocationChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_CELL_LOCATION_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.CellLocationListener) {
+            eventList.add(TelephonyCallback.EVENT_CELL_LOCATION_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.CallStateChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_CALL_STATE_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.CallStateListener) {
+            eventList.add(TelephonyCallback.EVENT_CALL_STATE_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.DataConnectionStateChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.DataConnectionStateListener) {
+            eventList.add(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.DataActivityListener) {
-            eventList.add(PhoneStateListener.EVENT_DATA_ACTIVITY_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.DataActivityListener) {
+            eventList.add(TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.SignalStrengthsChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.SignalStrengthsListener) {
+            eventList.add(TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.AlwaysReportedSignalStrengthChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.AlwaysReportedSignalStrengthListener) {
+            eventList.add(TelephonyCallback.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.CellInfoChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_CELL_INFO_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.CellInfoListener) {
+            eventList.add(TelephonyCallback.EVENT_CELL_INFO_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.PreciseCallStateChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.PreciseCallStateListener) {
+            eventList.add(TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.CallDisconnectCauseChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_CALL_DISCONNECT_CAUSE_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.CallDisconnectCauseListener) {
+            eventList.add(TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.ImsCallDisconnectCauseChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.ImsCallDisconnectCauseListener) {
+            eventList.add(TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.PreciseDataConnectionStateChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.PreciseDataConnectionStateListener) {
+            eventList.add(TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.SrvccStateChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_SRVCC_STATE_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.SrvccStateListener) {
+            eventList.add(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.VoiceActivationStateChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.VoiceActivationStateListener) {
+            eventList.add(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.DataActivationStateChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_DATA_ACTIVATION_STATE_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.DataActivationStateListener) {
+            eventList.add(TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.UserMobileDataStateChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.UserMobileDataStateListener) {
+            eventList.add(TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.DisplayInfoChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.DisplayInfoListener) {
+            eventList.add(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.EmergencyNumberListChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.EmergencyNumberListListener) {
+            eventList.add(TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.OutgoingEmergencyCallListener) {
-            eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_CALL);
+        if (telephonyCallback instanceof TelephonyCallback.OutgoingEmergencyCallListener) {
+            eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_CALL);
         }
 
-        if (listener instanceof PhoneStateListener.OutgoingEmergencySmsListener) {
-            eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_SMS);
+        if (telephonyCallback instanceof TelephonyCallback.OutgoingEmergencySmsListener) {
+            eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_SMS);
         }
 
-        if (listener instanceof PhoneStateListener.PhoneCapabilityChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_PHONE_CAPABILITY_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.PhoneCapabilityListener) {
+            eventList.add(TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.ActiveDataSubscriptionIdChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.ActiveDataSubscriptionIdListener) {
+            eventList.add(TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.RadioPowerStateChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.RadioPowerStateListener) {
+            eventList.add(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.CarrierNetworkChangeListener) {
-            eventList.add(PhoneStateListener.EVENT_CARRIER_NETWORK_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.CarrierNetworkListener) {
+            eventList.add(TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.RegistrationFailedListener) {
-            eventList.add(PhoneStateListener.EVENT_REGISTRATION_FAILURE);
+        if (telephonyCallback instanceof TelephonyCallback.RegistrationFailedListener) {
+            eventList.add(TelephonyCallback.EVENT_REGISTRATION_FAILURE);
         }
 
-        if (listener instanceof PhoneStateListener.CallAttributesChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.CallAttributesListener) {
+            eventList.add(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.BarringInfoChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_BARRING_INFO_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.BarringInfoListener) {
+            eventList.add(TelephonyCallback.EVENT_BARRING_INFO_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.PhysicalChannelConfigChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.PhysicalChannelConfigListener) {
+            eventList.add(TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.DataEnabledChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_DATA_ENABLED_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.DataEnabledListener) {
+            eventList.add(TelephonyCallback.EVENT_DATA_ENABLED_CHANGED);
         }
 
-        if (listener instanceof PhoneStateListener.AllowedNetworkTypesChangedListener) {
-            eventList.add(PhoneStateListener.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED);
+        if (telephonyCallback instanceof TelephonyCallback.AllowedNetworkTypesListener) {
+            eventList.add(TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED);
         }
 
         return eventList;
@@ -955,200 +981,183 @@
         Set<Integer> eventList = new ArraySet<>();
 
         if ((eventMask & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
-            eventList.add(PhoneStateListener.EVENT_SERVICE_STATE_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_SERVICE_STATE_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
-            eventList.add(PhoneStateListener.EVENT_SIGNAL_STRENGTH_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_SIGNAL_STRENGTH_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
-            eventList.add(PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
-            eventList.add(PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
-            eventList.add(PhoneStateListener.EVENT_CELL_LOCATION_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_CELL_LOCATION_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
-            eventList.add(PhoneStateListener.EVENT_CALL_STATE_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_CALL_STATE_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
-            eventList.add(PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
-            eventList.add(PhoneStateListener.EVENT_DATA_ACTIVITY_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
-            eventList.add(PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) != 0) {
-            eventList.add(PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
-            eventList.add(PhoneStateListener.EVENT_CELL_INFO_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_CELL_INFO_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
-            eventList.add(PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
-            eventList.add(PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO) != 0) {
-            eventList.add(PhoneStateListener.EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) {
-            eventList.add(PhoneStateListener.EVENT_OEM_HOOK_RAW);
+            eventList.add(TelephonyCallback.EVENT_OEM_HOOK_RAW);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) != 0) {
-            eventList.add(PhoneStateListener.EVENT_SRVCC_STATE_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE) != 0) {
-            eventList.add(PhoneStateListener.EVENT_CARRIER_NETWORK_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) != 0) {
-            eventList.add(PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE) != 0) {
-            eventList.add(PhoneStateListener.EVENT_DATA_ACTIVATION_STATE_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE) != 0) {
-            eventList.add(PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED) != 0) {
-            eventList.add(PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE) != 0) {
-            eventList.add(PhoneStateListener.EVENT_PHONE_CAPABILITY_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE) != 0) {
-            eventList.add(PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED) != 0) {
-            eventList.add(PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST) != 0) {
-            eventList.add(PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES) != 0) {
-            eventList.add(PhoneStateListener.EVENT_CALL_DISCONNECT_CAUSE_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED) != 0) {
-            eventList.add(PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES) != 0) {
-            eventList.add(PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL) != 0) {
-            eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_CALL);
+            eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_CALL);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS) != 0) {
-            eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_SMS);
+            eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_SMS);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_REGISTRATION_FAILURE) != 0) {
-            eventList.add(PhoneStateListener.EVENT_REGISTRATION_FAILURE);
+            eventList.add(TelephonyCallback.EVENT_REGISTRATION_FAILURE);
         }
 
         if ((eventMask & PhoneStateListener.LISTEN_BARRING_INFO) != 0) {
-            eventList.add(PhoneStateListener.EVENT_BARRING_INFO_CHANGED);
+            eventList.add(TelephonyCallback.EVENT_BARRING_INFO_CHANGED);
         }
         return eventList;
 
     }
 
     /**
-     * Registers a listener object to receive notification of changes
-     * in specified telephony states.
+     * Registers a callback object to receive notification of changes in specified telephony states.
      * <p>
-     * To register a listener, pass a {@link PhoneStateListener} which implements
+     * To register a callback, pass a {@link TelephonyCallback} which implements
      * interfaces of events. For example,
-     * FakeServiceStateChangedListener extends {@link PhoneStateListener} implements
-     * {@link PhoneStateListener.ServiceStateChangedListener}.
+     * FakeServiceStateCallback extends {@link TelephonyCallback} implements
+     * {@link TelephonyCallback.ServiceStateListener}.
      *
      * At registration, and when a specified telephony state changes, the telephony manager invokes
-     * the appropriate callback method on the listener object and passes the current (updated)
+     * the appropriate callback method on the callback object and passes the current (updated)
      * values.
      * <p>
      *
      * If this TelephonyManager object has been created with
      * {@link TelephonyManager#createForSubscriptionId}, applies to the given subId.
      * Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}.
-     * To listen events for multiple subIds, pass a separate listener object to
+     * To register events for multiple subIds, pass a separate callback object to
      * each TelephonyManager object created with {@link TelephonyManager#createForSubscriptionId}.
      *
      * Note: if you call this method while in the middle of a binder transaction, you <b>must</b>
      * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A
      * {@link SecurityException} will be thrown otherwise.
      *
-     * This API should be used sparingly -- large numbers of listeners will cause system
-     * instability. If a process has registered too many listeners without unregistering them, it
-     * may encounter an {@link IllegalStateException} when trying to register more listeners.
+     * This API should be used sparingly -- large numbers of callbacks will cause system
+     * instability. If a process has registered too many callbacks without unregistering them, it
+     * may encounter an {@link IllegalStateException} when trying to register more callbacks.
      *
-     * @param listener The {@link PhoneStateListener} object to register.
+     * @param callback The {@link TelephonyCallback} object to register.
      */
-    public void registerPhoneStateListener(@NonNull @CallbackExecutor Executor executor, int subId,
-            String pkgName, String attributionTag, @NonNull PhoneStateListener listener,
+    public void registerTelephonyCallback(@NonNull @CallbackExecutor Executor executor,
+            int subId, String pkgName, String attributionTag, @NonNull TelephonyCallback callback,
             boolean notifyNow) {
-        listener.setExecutor(executor);
-        registerPhoneStateListener(subId, pkgName, attributionTag, listener,
-                getEventsFromListener(listener), notifyNow);
-    }
-
-    public void registerPhoneStateListenerWithEvents(int subId, String pkgName,
-            String attributionTag, @NonNull PhoneStateListener listener, int events,
-            boolean notifyNow) {
-        registerPhoneStateListener(
-                subId, pkgName, attributionTag, listener, getEventsFromBitmask(events), notifyNow);
-    }
-
-    private void registerPhoneStateListener(int subId,
-            String pkgName, String attributionTag, @NonNull PhoneStateListener listener,
-            @NonNull Set<Integer> events, boolean notifyNow) {
-        if (listener == null) {
+        if (callback == null) {
             throw new IllegalStateException("telephony service is null.");
         }
-
-        listenWithEventList(subId, pkgName, attributionTag, listener,
-                events.stream().mapToInt(i -> i).toArray(), notifyNow);
+        callback.init(executor);
+        listenFromCallback(subId, pkgName, attributionTag, callback,
+                getEventsFromCallback(callback).stream().mapToInt(i -> i).toArray(), notifyNow);
     }
 
     /**
-     * Unregister an existing {@link PhoneStateListener}.
+     * Unregister an existing {@link TelephonyCallback}.
      *
-     * @param listener The {@link PhoneStateListener} object to unregister.
+     * @param callback The {@link TelephonyCallback} object to unregister.
      */
-    public void unregisterPhoneStateListener(int subId, String pkgName, String attributionTag,
-                                             @NonNull PhoneStateListener listener,
-                                             boolean notifyNow) {
-        listenWithEventList(subId, pkgName, attributionTag, listener, new int[0], notifyNow);
+    public void unregisterTelephonyCallback(int subId, String pkgName, String attributionTag,
+            @NonNull TelephonyCallback callback, boolean notifyNow) {
+        listenFromCallback(subId, pkgName, attributionTag, callback, new int[0], notifyNow);
     }
 }
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 10f6c61..96818fa 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -67,7 +67,7 @@
  * <p>Content capture provides real-time, continuous capture of application activity, display and
  * events to an intelligence service that is provided by the Android system. The intelligence
  * service then uses that info to mediate and speed user journey through different apps. For
- * example, when the user receives a restaurant address in a chat app and switchs to a map app
+ * example, when the user receives a restaurant address in a chat app and switches to a map app
  * to search for that restaurant, the intelligence service could offer an autofill dialog to
  * let the user automatically select its address.
  *
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index fe87b64..c220428 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -648,8 +648,6 @@
      */
     private static void performSystemServerDexOpt(String classPath) {
         final String[] classPathElements = classPath.split(":");
-        final IInstalld installd = IInstalld.Stub
-                .asInterface(ServiceManager.getService("installd"));
         final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
 
         String classPathForElement = "";
@@ -686,6 +684,10 @@
                 final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
                 final String seInfo = null;
                 final int targetSdkVersion = 0;  // SystemServer targets the system's SDK version
+                // Wait for installd to be made available
+                IInstalld installd = IInstalld.Stub.asInterface(
+                        ServiceManager.waitForService("installd"));
+
                 try {
                     installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
                             instructionSet, dexoptNeeded, outputPath, dexFlags, systemServerFilter,
diff --git a/core/java/com/android/internal/util/LocationPermissionChecker.java b/core/java/com/android/internal/util/LocationPermissionChecker.java
index c583d5a..d67bd7a 100644
--- a/core/java/com/android/internal/util/LocationPermissionChecker.java
+++ b/core/java/com/android/internal/util/LocationPermissionChecker.java
@@ -226,7 +226,7 @@
     }
 
     private boolean isTargetSdkLessThan(String packageName, int versionCode, int callingUid) {
-        long ident = Binder.clearCallingIdentity();
+        final long ident = Binder.clearCallingIdentity();
         try {
             if (mContext.getPackageManager().getApplicationInfoAsUser(
                     packageName, 0,
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 0e3db46..f379ba0 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -902,7 +902,7 @@
             continue;
         }
 
-        if (!AppendDmaBufInfo(pid, &dmabufs, false)) {
+        if (!ReadDmaBufMapRefs(pid, &dmabufs)) {
             LOG(ERROR) << "Failed to read maps for pid " << pid;
         }
     }
diff --git a/core/proto/android/app/OWNERS b/core/proto/android/app/OWNERS
index 296abd1..cc479e6 100644
--- a/core/proto/android/app/OWNERS
+++ b/core/proto/android/app/OWNERS
@@ -1 +1 @@
-per-file location_time_zone_manager.proto = nfuller@google.com, mingaleev@google.com
+per-file location_time_zone_manager.proto, time_zone_detector.proto = nfuller@google.com, mingaleev@google.com
diff --git a/core/proto/android/app/location_time_zone_manager.proto b/core/proto/android/app/location_time_zone_manager.proto
index f44d549..891e9fc 100644
--- a/core/proto/android/app/location_time_zone_manager.proto
+++ b/core/proto/android/app/location_time_zone_manager.proto
@@ -17,6 +17,7 @@
 syntax = "proto2";
 package android.app.time;
 
+import "frameworks/base/core/proto/android/app/time_zone_detector.proto";
 import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
@@ -31,15 +32,6 @@
   repeated TimeZoneProviderStateProto secondary_provider_states = 3;
 }
 
-// Represents a GeolocationTimeZoneSuggestion that can be / has been passed to the time zone
-// detector.
-message GeolocationTimeZoneSuggestionProto {
-  option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
-  repeated string zone_ids = 1;
-  repeated string debug_info = 2;
-}
-
 // The state tracked for a LocationTimeZoneProvider.
 message TimeZoneProviderStateProto {
   option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/app/time_zone_detector.proto b/core/proto/android/app/time_zone_detector.proto
new file mode 100644
index 0000000..b33ca1d
--- /dev/null
+++ b/core/proto/android/app/time_zone_detector.proto
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package android.app.time;
+
+import "frameworks/base/core/proto/android/privacy.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "TimeZoneDetectorProto";
+
+// Represents a GeolocationTimeZoneSuggestion that can be / has been passed to the time zone
+// detector.
+message GeolocationTimeZoneSuggestionProto {
+  option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  repeated string zone_ids = 1;
+  repeated string debug_info = 2;
+}
+
+/*
+ * An obfuscated and simplified time zone suggestion for metrics use.
+ *
+ * The suggestion's time zone IDs (which relate to location) are obfuscated by
+ * mapping them to an ordinal. When the ordinal is assigned consistently across
+ * several objects (i.e. so the same time zone ID is always mapped to the same
+ * ordinal), this allows comparisons between those objects. For example, we can
+ * answer "did these two suggestions agree?", "does the suggestion match the
+ * device's current time zone?", without leaking knowledge of location. Ordinals
+ * are also significantly more compact than full IANA TZDB IDs, albeit highly
+ * unstable and of limited use.
+ */
+message MetricsTimeZoneSuggestion {
+  option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  enum Type {
+    CERTAIN = 1;
+    UNCERTAIN = 2;
+  }
+  optional Type type = 1;
+
+  // The ordinals for time zone(s) in the suggestion. Always empty for
+  // UNCERTAIN, and can be empty for CERTAIN, for example when the device is in
+  // a disputed area / on an ocean.
+  repeated uint32 time_zone_ordinals = 2;
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
index 2c1bbf0..aa2eb63 100644
--- a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
@@ -232,7 +232,7 @@
         assertThat(entry3.handlerClassName).isEqualTo(
                 "com.android.internal.os.LooperStatsTest$TestHandlerSecond");
         assertThat(entry3.messageName).startsWith(
-                "com.android.internal.os.LooperStatsTest-$$ExternalSyntheticLambda");
+                "com.android.internal.os.LooperStatsTest$$ExternalSyntheticLambda4");
         assertThat(entry3.messageCount).isEqualTo(1);
         assertThat(entry3.recordedMessageCount).isEqualTo(1);
         assertThat(entry3.exceptionCount).isEqualTo(0);
diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
index ed789f0..5501569 100644
--- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java
+++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
@@ -20,7 +20,7 @@
 import android.annotation.Nullable;
 import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
-import android.security.usermanager.IKeystoreUserManager;
+import android.security.maintenance.IKeystoreMaintenance;
 import android.system.keystore2.Domain;
 import android.system.keystore2.ResponseCode;
 import android.util.Log;
@@ -34,9 +34,9 @@
 
     public static final int SYSTEM_ERROR = ResponseCode.SYSTEM_ERROR;
 
-    private static IKeystoreUserManager getService() {
-        return IKeystoreUserManager.Stub.asInterface(
-                ServiceManager.checkService("android.security.usermanager"));
+    private static IKeystoreMaintenance getService() {
+        return IKeystoreMaintenance.Stub.asInterface(
+                ServiceManager.checkService("android.security.maintenance"));
     }
 
     /**
diff --git a/keystore/java/android/security/keystore/AttestationUtils.java b/keystore/java/android/security/keystore/AttestationUtils.java
index f1eea82..11c3689 100644
--- a/keystore/java/android/security/keystore/AttestationUtils.java
+++ b/keystore/java/android/security/keystore/AttestationUtils.java
@@ -23,7 +23,6 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.Build;
-import android.security.KeyStore;
 import android.security.keymaster.KeymasterArguments;
 import android.security.keymaster.KeymasterCertificateChain;
 import android.security.keymaster.KeymasterDefs;
@@ -34,9 +33,14 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.nio.charset.StandardCharsets;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.SecureRandom;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.security.spec.ECGenParameterSpec;
 import java.util.Collection;
+import java.util.Random;
 import java.util.Set;
 
 /**
@@ -256,24 +260,49 @@
     @NonNull public static X509Certificate[] attestDeviceIds(Context context,
             @NonNull int[] idTypes, @NonNull byte[] attestationChallenge) throws
             DeviceIdAttestationException {
-        final KeymasterArguments attestArgs = prepareAttestationArgumentsForDeviceId(
-                context, idTypes, attestationChallenge);
+        String keystoreAlias = generateRandomAlias();
+        KeyGenParameterSpec.Builder builder =
+                new KeyGenParameterSpec.Builder(keystoreAlias, KeyProperties.PURPOSE_SIGN)
+                        .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
+                        .setDigests(KeyProperties.DIGEST_SHA256)
+                        .setAttestationChallenge(attestationChallenge);
 
-        // Perform attestation.
-        final KeymasterCertificateChain outChain = new KeymasterCertificateChain();
-        final int errorCode = KeyStore.getInstance().attestDeviceIds(attestArgs, outChain);
-        if (errorCode != KeyStore.NO_ERROR) {
-            throw new DeviceIdAttestationException("Unable to perform attestation",
-                    KeyStore.getKeyStoreException(errorCode));
+        if (idTypes != null) {
+            builder.setAttestationIds(idTypes);
+            builder.setDevicePropertiesAttestationIncluded(true);
         }
 
         try {
-            return parseCertificateChain(outChain);
-        } catch (KeyAttestationException e) {
-            throw new DeviceIdAttestationException(e.getMessage(), e);
+            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
+                    KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
+            keyPairGenerator.initialize(builder.build());
+            keyPairGenerator.generateKeyPair();
+
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+
+            X509Certificate[] certificateChain =
+                    (X509Certificate[]) keyStore.getCertificateChain(keystoreAlias);
+
+            keyStore.deleteEntry(keystoreAlias);
+
+            return certificateChain;
+        } catch (Exception e) {
+            throw new DeviceIdAttestationException("Unable to perform attestation", e);
         }
     }
 
+    private static String generateRandomAlias() {
+        Random random = new SecureRandom();
+        StringBuilder builder = new StringBuilder();
+        // Pick random uppercase letters, A-Z.  20 of them gives us ~94 bits of entropy, which
+        // should prevent any conflicts with app-selected aliases, even for very unlucky users.
+        for (int i = 0; i < 20; ++i) {
+            builder.append(random.nextInt(26) + 'A');
+        }
+        return builder.toString();
+    }
+
     /**
      * Returns true if the attestation chain provided is a valid key attestation chain.
      * @hide
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 72735a7..5cb2c3b 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -467,8 +467,8 @@
      *
      * @return The numeric namespace as configured in the keystore2_key_contexts files of Android's
      *         SEPolicy.
-     *         TODO b/171806779 link to public Keystore 2.0 documentation.
-     *              See bug for more details for now.
+     *         See <a href="https://source.android.com/security/keystore#access-control">
+     *             Keystore 2.0 access control</a>
      * @hide
      */
     @SystemApi
@@ -1042,9 +1042,9 @@
          * keys between system and vendor components, e.g., WIFI settings and WPA supplicant.
          *
          * @param namespace Numeric SELinux namespace as configured in keystore2_key_contexts
-         *                  of Android's SEPolicy.
-         *                  TODO b/171806779 link to public Keystore 2.0 documentation.
-         *                       See bug for more details for now.
+         *         of Android's SEPolicy.
+         *         See <a href="https://source.android.com/security/keystore#access-control">
+         *             Keystore 2.0 access control</a>
          * @return this Builder object.
          *
          * @hide
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
index d36695b..fa852e3 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
@@ -340,11 +340,11 @@
      * @param keyStore The keystore2 backend.
      * @param alias The alias of the key in the Keystore database.
      * @param namespace The a Keystore namespace. This is used by system api only to request
-     *                  Android system specific keystore namespace, which can be configured
-     *                  in the device's SEPolicy. Third party apps and most system components
-     *                  set this parameter to -1 to indicate their application specific namespace.
-     *                  TODO b/171806779 link to public Keystore 2.0 documentation.
-     *                       See bug for more details for now.
+     *         Android system specific keystore namespace, which can be configured
+     *         in the device's SEPolicy. Third party apps and most system components
+     *         set this parameter to -1 to indicate their application specific namespace.
+     *         See <a href="https://source.android.com/security/keystore#access-control">
+     *             Keystore 2.0 access control</a>
      * @hide
      **/
     @NonNull
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index a6dc9ce..45ed317 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -2905,10 +2905,14 @@
         ResultReceiver wrappedListener = new ResultReceiver(null) {
             @Override
             protected void onReceiveResult(int resultCode, Bundle resultData) {
-                Binder.withCleanCallingIdentity(() ->
-                            executor.execute(() -> {
-                                listener.onTetheringEntitlementResult(resultCode);
-                            }));
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() -> {
+                        listener.onTetheringEntitlementResult(resultCode);
+                    });
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             }
         };
 
diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
index ab58f1b..c82cd3b 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
@@ -1866,7 +1866,7 @@
                 final ArraySet<T> result = new ArraySet<>(size);
                 for (int i = 0; i < size; i++) {
                     final T value = in.readParcelable(loader);
-                    result.append(value);
+                    result.add(value);
                 }
                 return result;
             }
diff --git a/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java b/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java
index 43fffd7..739ddad 100644
--- a/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java
+++ b/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java
@@ -30,8 +30,8 @@
 import android.net.Uri;
 import android.os.Handler;
 import android.provider.Settings;
-import android.telephony.PhoneStateListener;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyManager;
 import android.util.Log;
 
@@ -92,8 +92,8 @@
     }
 
     @VisibleForTesting
-    protected class ActiveDataSubscriptionIdChangedListener extends PhoneStateListener
-            implements PhoneStateListener.ActiveDataSubscriptionIdChangedListener {
+    protected class ActiveDataSubscriptionIdListener extends TelephonyCallback
+            implements TelephonyCallback.ActiveDataSubscriptionIdListener {
         @Override
         public void onActiveDataSubscriptionIdChanged(int subId) {
             mActiveSubId = subId;
@@ -121,8 +121,8 @@
             }
         };
 
-        ctx.getSystemService(TelephonyManager.class).registerPhoneStateListener(
-                new HandlerExecutor(handler), new ActiveDataSubscriptionIdChangedListener());
+        ctx.getSystemService(TelephonyManager.class).registerTelephonyCallback(
+                new HandlerExecutor(handler), new ActiveDataSubscriptionIdListener());
 
         updateAvoidBadWifi();
         updateMeteredMultipathPreference();
diff --git a/packages/CtsShim/OWNERS b/packages/CtsShim/OWNERS
new file mode 100644
index 0000000..ba9f2b9
--- /dev/null
+++ b/packages/CtsShim/OWNERS
@@ -0,0 +1,2 @@
+ioffe@google.com
+toddke@google.com
\ No newline at end of file
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
index 4ef5e2b..59ea9f0 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
@@ -320,7 +320,7 @@
         }
     }
 
-    private void installScratch() throws IOException, InterruptedException {
+    private void installScratch() throws IOException {
         final long scratchSize = mDynSystem.suggestScratchSize();
         Thread thread = new Thread() {
             @Override
@@ -347,7 +347,11 @@
                 publishProgress(progress);
             }
 
-            Thread.sleep(100);
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                // Ignore the error.
+            }
         }
 
         if (mInstallationSession == null) {
@@ -361,7 +365,7 @@
         }
     }
 
-    private void installUserdata() throws IOException, InterruptedException {
+    private void installUserdata() throws IOException {
         Thread thread = new Thread(() -> {
             mInstallationSession = mDynSystem.createPartition("userdata", mUserdataSize, false);
         });
@@ -383,7 +387,11 @@
                 publishProgress(progress);
             }
 
-            Thread.sleep(100);
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                // Ignore the error.
+            }
         }
 
         if (mInstallationSession == null) {
@@ -397,8 +405,7 @@
         }
     }
 
-    private void installImages()
-            throws IOException, InterruptedException, ImageValidationException {
+    private void installImages() throws IOException, ImageValidationException {
         if (mStream != null) {
             if (mIsZip) {
                 installStreamingZipUpdate();
@@ -410,14 +417,12 @@
         }
     }
 
-    private void installStreamingGzUpdate()
-            throws IOException, InterruptedException, ImageValidationException {
+    private void installStreamingGzUpdate() throws IOException, ImageValidationException {
         Log.d(TAG, "To install a streaming GZ update");
         installImage("system", mSystemSize, new GZIPInputStream(mStream));
     }
 
-    private void installStreamingZipUpdate()
-            throws IOException, InterruptedException, ImageValidationException {
+    private void installStreamingZipUpdate() throws IOException, ImageValidationException {
         Log.d(TAG, "To install a streaming ZIP update");
 
         ZipInputStream zis = new ZipInputStream(mStream);
@@ -432,8 +437,7 @@
         }
     }
 
-    private void installLocalZipUpdate()
-            throws IOException, InterruptedException, ImageValidationException {
+    private void installLocalZipUpdate() throws IOException, ImageValidationException {
         Log.d(TAG, "To install a local ZIP update");
 
         Enumeration<? extends ZipEntry> entries = mZipFile.entries();
@@ -449,7 +453,7 @@
     }
 
     private boolean installImageFromAnEntry(ZipEntry entry, InputStream is)
-            throws IOException, InterruptedException, ImageValidationException {
+            throws IOException, ImageValidationException {
         String name = entry.getName();
 
         Log.d(TAG, "ZipEntry: " + name);
@@ -473,7 +477,7 @@
     }
 
     private void installImage(String partitionName, long uncompressedSize, InputStream is)
-            throws IOException, InterruptedException, ImageValidationException {
+            throws IOException, ImageValidationException {
 
         SparseInputStream sis = new SparseInputStream(new BufferedInputStream(is));
 
@@ -504,7 +508,11 @@
                 return;
             }
 
-            Thread.sleep(100);
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                // Ignore the error.
+            }
         }
 
         if (mInstallationSession == null) {
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index dc1ce82..3fed29a 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -285,6 +285,9 @@
     <!-- Permission needed for CTS test - MusicRecognitionManagerTest -->
     <uses-permission android:name="android.permission.MANAGE_MUSIC_RECOGNITION" />
 
+    <!-- Permission needed for CTS test - CtsVoiceRecognitionTestCases -->
+    <uses-permission android:name="android.permission.MANAGE_SPEECH_RECOGNITION" />
+
     <!-- Permissions required to test ambient display. -->
     <uses-permission android:name="android.permission.READ_DREAM_STATE"/>
     <uses-permission android:name="android.permission.WRITE_DREAM_STATE"/>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 49be648..1486826 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -25,11 +25,11 @@
 import android.telephony.Annotation;
 import android.telephony.CellSignalStrength;
 import android.telephony.CellSignalStrengthCdma;
-import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
 import android.text.Html;
@@ -63,7 +63,7 @@
     private final String mNetworkNameSeparator;
     private final ContentObserver mObserver;
     @VisibleForTesting
-    final PhoneStateListener mPhoneStateListener;
+    final MobileTelephonyCallback mTelephonyCallback;
     // Save entire info for logging, we only use the id.
     final SubscriptionInfo mSubscriptionInfo;
 
@@ -83,6 +83,7 @@
     private Config mConfig;
     @VisibleForTesting
     boolean mInflateSignalStrengths = false;
+    final Handler mHandler;
 
     // TODO: Reduce number of vars passed in, if we have the NetworkController, probably don't
     // need listener lists anymore.
@@ -98,7 +99,8 @@
         mPhone = phone;
         mDefaults = defaults;
         mSubscriptionInfo = info;
-        mPhoneStateListener = new MobilePhoneStateListener((new Handler(receiverLooper))::post);
+        mHandler = new Handler(receiverLooper);
+        mTelephonyCallback = new MobileTelephonyCallback();
         mNetworkNameSeparator = getTextIfExists(R.string.status_bar_network_name_separator)
                 .toString();
         mNetworkNameDefault = getTextIfExists(
@@ -157,15 +159,7 @@
      * Start listening for phone state changes.
      */
     public void registerListener() {
-        mPhone.listen(mPhoneStateListener,
-                PhoneStateListener.LISTEN_SERVICE_STATE
-                        | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
-                        | PhoneStateListener.LISTEN_CALL_STATE
-                        | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
-                        | PhoneStateListener.LISTEN_DATA_ACTIVITY
-                        | PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE
-                        | PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE
-                        | PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED);
+        mPhone.registerTelephonyCallback(mHandler::post, mTelephonyCallback);
         mContext.getContentResolver().registerContentObserver(Global.getUriFor(Global.MOBILE_DATA),
                 true, mObserver);
         mContext.getContentResolver().registerContentObserver(Global.getUriFor(
@@ -177,7 +171,7 @@
      * Stop listening for phone state changes.
      */
     public void unregisterListener() {
-        mPhone.listen(mPhoneStateListener, 0);
+        mPhone.unregisterTelephonyCallback(mTelephonyCallback);
         mContext.getContentResolver().unregisterContentObserver(mObserver);
     }
 
@@ -622,11 +616,15 @@
         pw.println("  isDataDisabled=" + isDataDisabled() + ",");
     }
 
-    class MobilePhoneStateListener extends PhoneStateListener {
-        public MobilePhoneStateListener(Executor executor) {
-            super(executor);
-        }
-
+    class MobileTelephonyCallback extends TelephonyCallback implements
+            TelephonyCallback.SignalStrengthsListener,
+            TelephonyCallback.ServiceStateListener,
+            TelephonyCallback.DataConnectionStateListener,
+            TelephonyCallback.DataActivityListener,
+            TelephonyCallback.CarrierNetworkListener,
+            TelephonyCallback.ActiveDataSubscriptionIdListener,
+            TelephonyCallback.DisplayInfoListener
+    {
         @Override
         public void onSignalStrengthsChanged(SignalStrength signalStrength) {
             if (DEBUG) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 9a7400e..3a84e31 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -47,11 +47,11 @@
 import android.provider.Settings.Global;
 import android.telephony.CellSignalStrength;
 import android.telephony.NetworkRegistrationInfo;
-import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
 import android.testing.TestableLooper;
@@ -95,7 +95,6 @@
 
     protected NetworkControllerImpl mNetworkController;
     protected MobileSignalController mMobileSignalController;
-    protected PhoneStateListener mPhoneStateListener;
     protected SignalStrength mSignalStrength;
     protected ServiceState mServiceState;
     protected TelephonyDisplayInfo mTelephonyDisplayInfo;
@@ -211,8 +210,6 @@
         setDefaultSubId(mSubId);
         setSubscriptions(mSubId);
         mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId);
-        mPhoneStateListener = mMobileSignalController.mPhoneStateListener;
-
         ArgumentCaptor<ConnectivityManager.NetworkCallback> callbackArg =
             ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
         verify(mMockCm, atLeastOnce())
@@ -340,18 +337,15 @@
 
     private void updateSignalStrength() {
         Log.d(TAG, "Sending Signal Strength: " + mSignalStrength);
-        mPhoneStateListener.onSignalStrengthsChanged(mSignalStrength);
+        mMobileSignalController.mTelephonyCallback
+                .onSignalStrengthsChanged(mSignalStrength);
     }
 
     protected void updateServiceState() {
         Log.d(TAG, "Sending Service State: " + mServiceState);
-        mPhoneStateListener.onServiceStateChanged(mServiceState);
-        mPhoneStateListener.onDisplayInfoChanged(mTelephonyDisplayInfo);
-    }
-
-    public void updateCallState(int state) {
-        // Inputs not currently used in NetworkControllerImpl.
-        mPhoneStateListener.onCallStateChanged(state, "0123456789");
+        mMobileSignalController.mTelephonyCallback.onServiceStateChanged(mServiceState);
+        mMobileSignalController.mTelephonyCallback
+                .onDisplayInfoChanged(mTelephonyDisplayInfo);
     }
 
     public void updateDataConnectionState(int dataState, int dataNetType) {
@@ -363,16 +357,17 @@
         when(mServiceState.getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN))
                 .thenReturn(fakeRegInfo);
         when(mTelephonyDisplayInfo.getNetworkType()).thenReturn(dataNetType);
-        mPhoneStateListener.onDataConnectionStateChanged(dataState, dataNetType);
+        mMobileSignalController.mTelephonyCallback
+                .onDataConnectionStateChanged(dataState, dataNetType);
     }
 
     public void updateDataActivity(int dataActivity) {
-        mPhoneStateListener.onDataActivity(dataActivity);
+        mMobileSignalController.mTelephonyCallback.onDataActivity(dataActivity);
     }
 
     public void setCarrierNetworkChange(boolean enable) {
         Log.d(TAG, "setCarrierNetworkChange(" + enable + ")");
-        mPhoneStateListener.onCarrierNetworkChange(enable);
+        mMobileSignalController.mTelephonyCallback.onCarrierNetworkChange(enable);
     }
 
     protected void verifyHasNoSims(boolean hasNoSimsVisible) {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2c9837d..78853c7 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -175,6 +175,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.sysprop.NetworkProperties;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -189,7 +190,6 @@
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.IBatteryStats;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.LocationPermissionChecker;
@@ -201,7 +201,6 @@
 import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
 import com.android.net.module.util.NetworkCapabilitiesUtils;
 import com.android.net.module.util.PermissionUtils;
-import com.android.server.am.BatteryStatsService;
 import com.android.server.connectivity.AutodestructReference;
 import com.android.server.connectivity.DnsManager;
 import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
@@ -217,7 +216,6 @@
 import com.android.server.connectivity.ProxyTracker;
 import com.android.server.connectivity.QosCallbackTracker;
 import com.android.server.net.NetworkPolicyManagerInternal;
-import com.android.server.utils.PriorityDump;
 
 import libcore.io.IoUtils;
 
@@ -884,27 +882,59 @@
     }
     private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this);
 
+    final LocalPriorityDump mPriorityDumper = new LocalPriorityDump();
     /**
      * Helper class which parses out priority arguments and dumps sections according to their
      * priority. If priority arguments are omitted, function calls the legacy dump command.
      */
-    private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
-        @Override
-        public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
-            doDump(fd, pw, new String[] {DIAG_ARG}, asProto);
-            doDump(fd, pw, new String[] {SHORT_ARG}, asProto);
+    private class LocalPriorityDump {
+        private static final String PRIORITY_ARG = "--dump-priority";
+        private static final String PRIORITY_ARG_HIGH = "HIGH";
+        private static final String PRIORITY_ARG_NORMAL = "NORMAL";
+
+        LocalPriorityDump() {}
+
+        private void dumpHigh(FileDescriptor fd, PrintWriter pw) {
+            doDump(fd, pw, new String[] {DIAG_ARG});
+            doDump(fd, pw, new String[] {SHORT_ARG});
         }
 
-        @Override
-        public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
-            doDump(fd, pw, args, asProto);
+        private void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) {
+            doDump(fd, pw, args);
         }
 
-        @Override
-        public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
-           doDump(fd, pw, args, asProto);
+        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            if (args == null) {
+                dumpNormal(fd, pw, args);
+                return;
+            }
+
+            String priority = null;
+            for (int argIndex = 0; argIndex < args.length; argIndex++) {
+                if (args[argIndex].equals(PRIORITY_ARG) && argIndex + 1 < args.length) {
+                    argIndex++;
+                    priority = args[argIndex];
+                }
+            }
+
+            if (PRIORITY_ARG_HIGH.equals(priority)) {
+                dumpHigh(fd, pw);
+            } else if (PRIORITY_ARG_NORMAL.equals(priority)) {
+                dumpNormal(fd, pw, args);
+            } else {
+                // ConnectivityService publishes binder service using publishBinderService() with
+                // no priority assigned will be treated as NORMAL priority. Dumpsys does not send
+                // "--dump-priority" arguments to the service. Thus, dump both NORMAL and HIGH to
+                // align the legacy design.
+                // TODO: Integrate into signal dump.
+                dumpNormal(fd, pw, args);
+                pw.println();
+                pw.println("DUMP OF SERVICE HIGH connectivity");
+                pw.println();
+                dumpHigh(fd, pw);
+            }
         }
-    };
+    }
 
     /**
      * Keeps track of the number of requests made under different uids.
@@ -1035,8 +1065,18 @@
             return new MultinetworkPolicyTracker(c, h, r);
         }
 
-        public IBatteryStats getBatteryStatsService() {
-            return BatteryStatsService.getService();
+        /**
+         * @see BatteryStatsManager
+         */
+        public void reportNetworkInterfaceForTransports(Context context, String iface,
+                int[] transportTypes) {
+            final BatteryStatsManager batteryStats =
+                    context.getSystemService(BatteryStatsManager.class);
+            batteryStats.reportNetworkInterfaceForTransports(iface, transportTypes);
+        }
+
+        public boolean getCellular464XlatEnabled() {
+            return NetworkProperties.isCellular464XlatEnabled().orElse(true);
         }
     }
 
@@ -1236,8 +1276,7 @@
                 new NetworkInfo(TYPE_NONE, 0, "", ""),
                 new LinkProperties(), new NetworkCapabilities(), 0, mContext,
                 null, new NetworkAgentConfig(), this, null,
-                null, 0, INVALID_UID,
-                mQosCallbackTracker);
+                null, 0, INVALID_UID, mQosCallbackTracker, mDeps);
     }
 
     private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
@@ -1479,11 +1518,11 @@
         // but only exists if an app asks about them or requests them. Ensure the requesting app
         // gets the type it asks for.
         filtered.setType(type);
-        final DetailedState state = isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)
-                ? DetailedState.BLOCKED
-                : filtered.getDetailedState();
-        filtered.setDetailedState(getLegacyLockdownState(state),
-                "" /* reason */, null /* extraInfo */);
+        if (isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)) {
+            filtered.setDetailedState(DetailedState.BLOCKED, null /* reason */,
+                    null /* extraInfo */);
+        }
+        filterForLegacyLockdown(filtered);
         return filtered;
     }
 
@@ -1559,8 +1598,8 @@
         final DetailedState state = isNetworkWithCapabilitiesBlocked(nc, uid, false)
                 ? DetailedState.BLOCKED
                 : DetailedState.DISCONNECTED;
-        info.setDetailedState(getLegacyLockdownState(state),
-                "" /* reason */, null /* extraInfo */);
+        info.setDetailedState(state, null /* reason */, null /* extraInfo */);
+        filterForLegacyLockdown(info);
         return info;
     }
 
@@ -2354,9 +2393,7 @@
         mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService");
     }
 
-    // Public because it's used by mLockdownTracker.
-    public void sendConnectedBroadcast(NetworkInfo info) {
-        PermissionUtils.enforceNetworkStackPermission(mContext);
+    private void sendConnectedBroadcast(NetworkInfo info) {
         sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
     }
 
@@ -2593,7 +2630,7 @@
     @Override
     protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
             @Nullable String[] args) {
-        PriorityDump.dump(mPriorityDumper, fd, writer, args);
+        mPriorityDumper.dump(fd, writer, args);
     }
 
     private boolean checkDumpPermission(Context context, String tag, PrintWriter pw) {
@@ -2608,10 +2645,9 @@
         }
     }
 
-    private void doDump(FileDescriptor fd, PrintWriter writer, String[] args, boolean asProto) {
+    private void doDump(FileDescriptor fd, PrintWriter writer, String[] args) {
         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
         if (!checkDumpPermission(mContext, TAG, pw)) return;
-        if (asProto) return;
 
         if (CollectionUtils.contains(args, DIAG_ARG)) {
             dumpNetworkDiagnostics(pw);
@@ -3604,11 +3640,10 @@
     // pendingIntent => NetworkRequestInfo map.
     // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo.
     private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) {
-        Intent intent = pendingIntent.getIntent();
         for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) {
             PendingIntent existingPendingIntent = entry.getValue().mPendingIntent;
             if (existingPendingIntent != null &&
-                    existingPendingIntent.getIntent().filterEquals(intent)) {
+                    existingPendingIntent.intentFilterEquals(pendingIntent)) {
                 return entry.getValue();
             }
         }
@@ -3651,6 +3686,13 @@
                     }
                 }
             }
+            // If this NRI has a satisfier already, it is replacing an older request that
+            // has been removed. Track it.
+            final NetworkRequest activeRequest = nri.getActiveRequest();
+            if (null != activeRequest) {
+                // If there is an active request, then for sure there is a satisfier.
+                nri.getSatisfier().addRequest(activeRequest);
+            }
         }
 
         rematchAllNetworksAndRequests();
@@ -4996,8 +5038,8 @@
         // The legacy lockdown VPN always uses the default network.
         // If the VPN's underlying network is no longer the current default network, it means that
         // the default network has just switched, and the VPN is about to disconnect.
-        // Report that the VPN is not connected, so when the state of NetworkInfo objects
-        // overwritten by getLegacyLockdownState will be set to CONNECTING and not CONNECTED.
+        // Report that the VPN is not connected, so the state of NetworkInfo objects overwritten
+        // by filterForLegacyLockdown will be set to CONNECTING and not CONNECTED.
         final NetworkAgentInfo defaultNetwork = getDefaultNetwork();
         if (defaultNetwork == null || !defaultNetwork.network.equals(underlying[0])) {
             return null;
@@ -5006,6 +5048,9 @@
         return nai;
     };
 
+    // TODO: move all callers to filterForLegacyLockdown and delete this method.
+    // This likely requires making sendLegacyNetworkBroadcast take a NetworkInfo object instead of
+    // just a DetailedState object.
     private DetailedState getLegacyLockdownState(DetailedState origState) {
         if (origState != DetailedState.CONNECTED) {
             return origState;
@@ -5015,6 +5060,23 @@
                 : DetailedState.CONNECTED;
     }
 
+    private void filterForLegacyLockdown(NetworkInfo ni) {
+        if (!mLockdownEnabled || !ni.isConnected()) return;
+        // The legacy lockdown VPN replaces the state of every network in CONNECTED state with the
+        // state of its VPN. This is to ensure that when an underlying network connects, apps will
+        // not see a CONNECTIVITY_ACTION broadcast for a network in state CONNECTED until the VPN
+        // comes up, at which point there is a new CONNECTIVITY_ACTION broadcast for the underlying
+        // network, this time with a state of CONNECTED.
+        //
+        // Now that the legacy lockdown code lives in ConnectivityService, and no longer has access
+        // to the internal state of the Vpn object, always replace the state with CONNECTING. This
+        // is not too far off the truth, since an always-on VPN, when not connected, is always
+        // trying to reconnect.
+        if (getLegacyLockdownNai() == null) {
+            ni.setDetailedState(DetailedState.CONNECTING, "", null);
+        }
+    }
+
     @Override
     public void setProvisioningNotificationVisible(boolean visible, int networkType,
             String action) {
@@ -5271,14 +5333,26 @@
             ensureAllNetworkRequestsHaveType(r);
             mRequests = initializeRequests(r);
             mNetworkRequestForCallback = nri.getNetworkRequestForCallback();
-            // Note here that the satisfier may have corresponded to an old request, that
-            // this code doesn't try to take over. While it is a small discrepancy in the
-            // structure of these requests, it will be fixed by the next rematch and it's
-            // not as bad as having an NRI not storing its real satisfier.
-            // Fixing this discrepancy would require figuring out in the copying code what
-            // is the new request satisfied by this, which is a bit complex and not very
-            // useful as no code is using it until rematch fixes it.
-            mSatisfier = nri.mSatisfier;
+            final NetworkAgentInfo satisfier = nri.getSatisfier();
+            if (null != satisfier) {
+                // If the old NRI was satisfied by an NAI, then it may have had an active request.
+                // The active request is necessary to figure out what callbacks to send, in
+                // particular then a network updates its capabilities.
+                // As this code creates a new NRI with a new set of requests, figure out which of
+                // the list of requests should be the active request. It is always the first
+                // request of the list that can be satisfied by the satisfier since the order of
+                // requests is a priority order.
+                // Note even in the presence of a satisfier there may not be an active request,
+                // when the satisfier is the no-service network.
+                NetworkRequest activeRequest = null;
+                for (final NetworkRequest candidate : r) {
+                    if (candidate.canBeSatisfiedBy(satisfier.networkCapabilities)) {
+                        activeRequest = candidate;
+                        break;
+                    }
+                }
+                setSatisfier(satisfier, activeRequest);
+            }
             mMessenger = nri.mMessenger;
             mBinder = nri.mBinder;
             mPid = nri.mPid;
@@ -6078,7 +6152,7 @@
         final NetworkAgentInfo nai = new NetworkAgentInfo(na,
                 new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
                 currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
-                this, mNetd, mDnsResolver, providerId, uid, mQosCallbackTracker);
+                this, mNetd, mDnsResolver, providerId, uid, mQosCallbackTracker, mDeps);
 
         // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
         processCapabilitiesFromAgent(nai, nc);
@@ -6281,13 +6355,13 @@
                 oldLp != null ? oldLp.getAllInterfaceNames() : null,
                 newLp != null ? newLp.getAllInterfaceNames() : null);
         if (!interfaceDiff.added.isEmpty()) {
-            final IBatteryStats bs = mDeps.getBatteryStatsService();
             for (final String iface : interfaceDiff.added) {
                 try {
                     if (DBG) log("Adding iface " + iface + " to network " + netId);
                     mNetd.networkAddInterface(netId, iface);
                     wakeupModifyInterface(iface, caps, true);
-                    bs.noteNetworkInterfaceForTransports(iface, caps.getTransportTypes());
+                    mDeps.reportNetworkInterfaceForTransports(mContext, iface,
+                            caps.getTransportTypes());
                 } catch (Exception e) {
                     loge("Exception adding interface: " + e);
                 }
@@ -7886,6 +7960,7 @@
         // and is still connected.
         NetworkInfo info = new NetworkInfo(nai.networkInfo);
         info.setType(type);
+        filterForLegacyLockdown(info);
         if (state != DetailedState.DISCONNECTED) {
             info.setDetailedState(state, null, info.getExtraInfo());
             sendConnectedBroadcast(info);
diff --git a/services/core/java/com/android/server/ConnectivityServiceInitializer.java b/services/core/java/com/android/server/ConnectivityServiceInitializer.java
index b992208..2465479 100644
--- a/services/core/java/com/android/server/ConnectivityServiceInitializer.java
+++ b/services/core/java/com/android/server/ConnectivityServiceInitializer.java
@@ -16,9 +16,6 @@
 
 package com.android.server;
 
-import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
-import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
-
 import android.content.Context;
 import android.util.Log;
 
@@ -42,6 +39,6 @@
     public void onStart() {
         Log.i(TAG, "Registering " + Context.CONNECTIVITY_SERVICE);
         publishBinderService(Context.CONNECTIVITY_SERVICE, mConnectivity,
-                /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
+                /* allowIsolated= */ false);
     }
 }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index c51a606..dce919d 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -72,6 +72,7 @@
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
@@ -153,7 +154,7 @@
 
         int phoneId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
 
-        boolean matchPhoneStateListenerEvent(int event) {
+        boolean matchTelephonyCallbackEvent(int event) {
             return (callback != null) && (this.eventList.contains(event));
         }
 
@@ -198,8 +199,8 @@
         public int getRegistrationLimit() {
             return Binder.withCleanCallingIdentity(() ->
                     DeviceConfig.getInt(DeviceConfig.NAMESPACE_TELEPHONY,
-                            PhoneStateListener.FLAG_PER_PID_REGISTRATION_LIMIT,
-                            PhoneStateListener.DEFAULT_PER_PID_REGISTRATION_LIMIT));
+                            TelephonyCallback.FLAG_PER_PID_REGISTRATION_LIMIT,
+                            TelephonyCallback.DEFAULT_PER_PID_REGISTRATION_LIMIT));
         }
 
         /**
@@ -210,7 +211,7 @@
          */
         public boolean isRegistrationLimitEnabledInPlatformCompat(int uid) {
             return Binder.withCleanCallingIdentity(() -> CompatChanges.isChangeEnabled(
-                    PhoneStateListener.PHONE_STATE_LISTENER_LIMIT_CHANGE_ID, uid));
+                    TelephonyCallback.PHONE_STATE_LISTENER_LIMIT_CHANGE_ID, uid));
         }
     }
 
@@ -332,37 +333,37 @@
     static {
         REQUIRE_PRECISE_PHONE_STATE_PERMISSION = new HashSet<Integer>();
         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
-                PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED);
+                TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED);
         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
-                PhoneStateListener.EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED);
+                TelephonyCallback.EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED);
         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
-                PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED);
+                TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED);
         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
-                PhoneStateListener.EVENT_CALL_DISCONNECT_CAUSE_CHANGED);
+                TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED);
         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
-                PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED);
+                TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED);
         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
-                PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED);
-        REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(PhoneStateListener.EVENT_REGISTRATION_FAILURE);
-        REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(PhoneStateListener.EVENT_BARRING_INFO_CHANGED);
+                TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED);
+        REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(TelephonyCallback.EVENT_REGISTRATION_FAILURE);
+        REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(TelephonyCallback.EVENT_BARRING_INFO_CHANGED);
         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
-                PhoneStateListener.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
+                TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
-                PhoneStateListener.EVENT_DATA_ENABLED_CHANGED);
+                TelephonyCallback.EVENT_DATA_ENABLED_CHANGED);
     }
 
     private boolean isLocationPermissionRequired(Set<Integer> events) {
-        return events.contains(PhoneStateListener.EVENT_CELL_LOCATION_CHANGED)
-                || events.contains(PhoneStateListener.EVENT_CELL_INFO_CHANGED)
-                || events.contains(PhoneStateListener.EVENT_REGISTRATION_FAILURE)
-                || events.contains(PhoneStateListener.EVENT_BARRING_INFO_CHANGED);
+        return events.contains(TelephonyCallback.EVENT_CELL_LOCATION_CHANGED)
+                || events.contains(TelephonyCallback.EVENT_CELL_INFO_CHANGED)
+                || events.contains(TelephonyCallback.EVENT_REGISTRATION_FAILURE)
+                || events.contains(TelephonyCallback.EVENT_BARRING_INFO_CHANGED);
     }
 
     private boolean isPhoneStatePermissionRequired(Set<Integer> events) {
-        return events.contains(PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)
-                || events.contains(PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)
-                || events.contains(PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)
-                || events.contains(PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED);
+        return events.contains(TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)
+                || events.contains(TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)
+                || events.contains(TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)
+                || events.contains(TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED);
     }
 
     private boolean isPrecisePhoneStatePermissionRequired(Set<Integer> events) {
@@ -375,14 +376,14 @@
     }
 
     private boolean isActiveEmergencySessionPermissionRequired(Set<Integer> events) {
-        return events.contains(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_CALL)
-                || events.contains(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_SMS);
+        return events.contains(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_CALL)
+                || events.contains(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_SMS);
     }
 
     private boolean isPrivilegedPhoneStatePermissionRequired(Set<Integer> events) {
-        return events.contains(PhoneStateListener.EVENT_SRVCC_STATE_CHANGED)
-                || events.contains(PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED)
-                || events.contains(PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED);
+        return events.contains(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED)
+                || events.contains(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED)
+                || events.contains(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED);
     }
 
     private static final int MSG_USER_SWITCHED = 1;
@@ -903,7 +904,7 @@
                 log("listen:  Register r=" + r + " r.subId=" + r.subId + " phoneId=" + phoneId);
             }
             if (notifyNow && validatePhoneId(phoneId)) {
-                if (events.contains(PhoneStateListener.EVENT_SERVICE_STATE_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_SERVICE_STATE_CHANGED)){
                     try {
                         if (VDBG) log("listen: call onSSC state=" + mServiceState[phoneId]);
                         ServiceState rawSs = new ServiceState(mServiceState[phoneId]);
@@ -920,7 +921,7 @@
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_SIGNAL_STRENGTH_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_SIGNAL_STRENGTH_CHANGED)) {
                     try {
                         if (mSignalStrength[phoneId] != null) {
                             int gsmSignalStrength = mSignalStrength[phoneId]
@@ -933,7 +934,7 @@
                     }
                 }
                 if (events.contains(
-                        PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)) {
+                        TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)) {
                     try {
                         r.callback.onMessageWaitingIndicatorChanged(
                                 mMessageWaiting[phoneId]);
@@ -942,7 +943,7 @@
                     }
                 }
                 if (events.contains(
-                        PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)) {
+                        TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)) {
                     try {
                         r.callback.onCallForwardingIndicatorChanged(
                                 mCallForwarding[phoneId]);
@@ -951,7 +952,7 @@
                     }
                 }
                 if (validateEventAndUserLocked(
-                        r, PhoneStateListener.EVENT_CELL_LOCATION_CHANGED)) {
+                        r, TelephonyCallback.EVENT_CELL_LOCATION_CHANGED)) {
                     try {
                         if (DBG_LOC) log("listen: mCellIdentity = " + mCellIdentity[phoneId]);
                         if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
@@ -963,7 +964,7 @@
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_CALL_STATE_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_CALL_STATE_CHANGED)) {
                     try {
                         r.callback.onCallStateChanged(mCallState[phoneId],
                                 getCallIncomingNumber(r, phoneId));
@@ -971,7 +972,7 @@
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED)) {
                     try {
                         r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
                                 mDataConnectionNetworkType[phoneId]);
@@ -979,14 +980,14 @@
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_DATA_ACTIVITY_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED)) {
                     try {
                         r.callback.onDataActivity(mDataActivity[phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED)) {
                     try {
                         if (mSignalStrength[phoneId] != null) {
                             r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]);
@@ -996,7 +997,7 @@
                     }
                 }
                 if (events.contains(
-                        PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) {
+                        TelephonyCallback.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) {
                     updateReportSignalStrengthDecision(r.subId);
                     try {
                         if (mSignalStrength[phoneId] != null) {
@@ -1007,7 +1008,7 @@
                     }
                 }
                 if (validateEventAndUserLocked(
-                        r, PhoneStateListener.EVENT_CELL_INFO_CHANGED)) {
+                        r, TelephonyCallback.EVENT_CELL_INFO_CHANGED)) {
                     try {
                         if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = "
                                 + mCellInfo.get(phoneId));
@@ -1019,14 +1020,14 @@
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED)) {
                     try {
                         r.callback.onPreciseCallStateChanged(mPreciseCallState[phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_CALL_DISCONNECT_CAUSE_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED)) {
                     try {
                         r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause[phoneId],
                                 mCallPreciseDisconnectCause[phoneId]);
@@ -1034,7 +1035,7 @@
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED)) {
                     try {
                         r.callback.onImsCallDisconnectCauseChanged(mImsReasonInfo.get(phoneId));
                     } catch (RemoteException ex) {
@@ -1042,7 +1043,7 @@
                     }
                 }
                 if (events.contains(
-                        PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED)) {
+                        TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED)) {
                     try {
                         for (PreciseDataConnectionState pdcs
                                 : mPreciseDataConnectionStates.get(phoneId).values()) {
@@ -1052,14 +1053,14 @@
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_CARRIER_NETWORK_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED)) {
                     try {
                         r.callback.onCarrierNetworkChange(mCarrierNetworkChangeState);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED)) {
                     try {
                         r.callback.onVoiceActivationStateChanged(
                                 mVoiceActivationState[phoneId]);
@@ -1067,21 +1068,21 @@
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_DATA_ACTIVATION_STATE_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED)) {
                     try {
                         r.callback.onDataActivationStateChanged(mDataActivationState[phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED)) {
                     try {
                         r.callback.onUserMobileDataStateChanged(mUserMobileDataState[phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED)) {
                     try {
                         if (mTelephonyDisplayInfos[phoneId] != null) {
                             r.callback.onDisplayInfoChanged(mTelephonyDisplayInfos[phoneId]);
@@ -1090,14 +1091,14 @@
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)) {
                     try {
                         r.callback.onEmergencyNumberListChanged(mEmergencyNumberList);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_PHONE_CAPABILITY_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED)) {
                     try {
                         r.callback.onPhoneCapabilityChanged(mPhoneCapability);
                     } catch (RemoteException ex) {
@@ -1105,35 +1106,35 @@
                     }
                 }
                 if (events.contains(
-                        PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED)) {
+                        TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED)) {
                     try {
                         r.callback.onActiveDataSubIdChanged(mActiveDataSubId);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED)) {
                     try {
                         r.callback.onRadioPowerStateChanged(mRadioPowerState);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_SRVCC_STATE_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED)) {
                     try {
                         r.callback.onSrvccStateChanged(mSrvccState[phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)) {
                     try {
                         r.callback.onCallAttributesChanged(mCallAttributes[phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
-                if (events.contains(PhoneStateListener.EVENT_BARRING_INFO_CHANGED)) {
+                if (events.contains(TelephonyCallback.EVENT_BARRING_INFO_CHANGED)) {
                     BarringInfo barringInfo = mBarringInfo.get(phoneId);
                     BarringInfo biNoLocation = barringInfo != null
                             ? barringInfo.createLocationInfoSanitizedCopy() : null;
@@ -1147,7 +1148,7 @@
                     }
                 }
                 if (events.contains(
-                        PhoneStateListener.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED)) {
+                        TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED)) {
                     try {
                         r.callback.onPhysicalChannelConfigChanged(
                                 mPhysicalChannelConfigs);
@@ -1156,7 +1157,7 @@
                     }
                 }
                 if (events.contains(
-                        PhoneStateListener.EVENT_DATA_ENABLED_CHANGED)) {
+                        TelephonyCallback.EVENT_DATA_ENABLED_CHANGED)) {
                     try {
                         r.callback.onDataEnabledChanged(
                                 mIsDataEnabled[phoneId], mDataEnabledReason[phoneId]);
@@ -1165,7 +1166,7 @@
                     }
                 }
                 if (events.contains(
-                        PhoneStateListener.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED)) {
+                        TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED)) {
                     try {
                         r.callback.onAllowedNetworkTypesChanged(mAllowedNetworkTypesList);
                     } catch (RemoteException ex) {
@@ -1183,8 +1184,8 @@
             for (Record r : mRecords) {
                 // If any of the system clients wants to always listen to signal strength,
                 // we need to set it on.
-                if (r.matchPhoneStateListenerEvent(
-                        PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) {
+                if (r.matchTelephonyCallbackEvent(
+                        TelephonyCallback.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) {
                     telephonyManager.createForSubscriptionId(subscriptionId)
                             .setAlwaysReportSignalStrength(true);
                     return;
@@ -1233,7 +1234,7 @@
                     throw new IllegalStateException(errorMsg);
                 }
             } else if (doesLimitApply && numRecordsForPid
-                    >= PhoneStateListener.DEFAULT_PER_PID_REGISTRATION_LIMIT / 2) {
+                    >= TelephonyCallback.DEFAULT_PER_PID_REGISTRATION_LIMIT / 2) {
                 // Log the warning independently of the dynamically set limit -- apps shouldn't be
                 // doing this regardless of whether we're throwing them an exception for it.
                 Rlog.w(TAG, "Pid " + callingPid + " has exceeded half the number of permissible"
@@ -1284,8 +1285,8 @@
                     // Every time a client that is registrating to always receive the signal
                     // strength is removed from registry records, we need to check if
                     // the signal strength decision needs to update on its slot.
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) {
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) {
                         updateReportSignalStrengthDecision(r.subId);
                     }
                     return;
@@ -1305,7 +1306,7 @@
 
         synchronized (mRecords) {
             for (Record r : mRecords) {
-                if (r.matchPhoneStateListenerEvent(PhoneStateListener.EVENT_CALL_STATE_CHANGED)
+                if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED)
                         && (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
                     try {
                         // Ensure the listener has read call log permission; if they do not return
@@ -1340,7 +1341,7 @@
                 mCallState[phoneId] = state;
                 mCallIncomingNumber[phoneId] = incomingNumber;
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(PhoneStateListener.EVENT_CALL_STATE_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED)
                             && (r.subId == subId)
                             && (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
                         try {
@@ -1382,8 +1383,8 @@
                         log("notifyServiceStateForSubscriber: r=" + r + " subId=" + subId
                                 + " phoneId=" + phoneId + " state=" + state);
                     }
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_SERVICE_STATE_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_SERVICE_STATE_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
 
                         try {
@@ -1444,8 +1445,8 @@
                     }
                     try {
                         if ((activationType == SIM_ACTIVATION_TYPE_VOICE)
-                                && r.matchPhoneStateListenerEvent(
-                                        PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED)
+                                && r.matchTelephonyCallbackEvent(
+                                        TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED)
                                 && idMatch(r.subId, subId, phoneId)) {
                             if (DBG) {
                                 log("notifyVoiceActivationStateForPhoneId: callback.onVASC r=" + r
@@ -1455,8 +1456,8 @@
                             r.callback.onVoiceActivationStateChanged(activationState);
                         }
                         if ((activationType == SIM_ACTIVATION_TYPE_DATA)
-                                && r.matchPhoneStateListenerEvent(
-                                        PhoneStateListener.EVENT_DATA_ACTIVATION_STATE_CHANGED)
+                                && r.matchTelephonyCallbackEvent(
+                                        TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED)
                                 && idMatch(r.subId, subId, phoneId)) {
                             if (DBG) {
                                 log("notifyDataActivationStateForPhoneId: callback.onDASC r=" + r
@@ -1495,11 +1496,10 @@
                         log("notifySignalStrengthForPhoneId: r=" + r + " subId=" + subId
                                 + " phoneId=" + phoneId + " ss=" + signalStrength);
                     }
-                    if ((r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED)
-                            || r.matchPhoneStateListenerEvent(
-                                    PhoneStateListener.
-                                            EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED))
+                    if ((r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED)
+                            || r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED))
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             if (DBG) {
@@ -1512,8 +1512,8 @@
                             mRemoveList.add(r.binder);
                         }
                     }
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_SIGNAL_STRENGTH_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_SIGNAL_STRENGTH_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             int gsmSignalStrength = signalStrength.getGsmSignalStrength();
@@ -1559,8 +1559,8 @@
                     log("notifyCarrierNetworkChange: active=" + active + "subId: " + subId);
                 }
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_CARRIER_NETWORK_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onCarrierNetworkChange(active);
@@ -1592,7 +1592,7 @@
                 mCellInfo.set(phoneId, cellInfo);
                 for (Record r : mRecords) {
                     if (validateEventAndUserLocked(
-                            r, PhoneStateListener.EVENT_CELL_INFO_CHANGED)
+                            r, TelephonyCallback.EVENT_CELL_INFO_CHANGED)
                             && idMatch(r.subId, subId, phoneId)
                             && (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
                                     && checkFineLocationAccess(r, Build.VERSION_CODES.Q))) {
@@ -1625,8 +1625,8 @@
             if (validatePhoneId(phoneId)) {
                 mMessageWaiting[phoneId] = mwi;
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onMessageWaitingIndicatorChanged(mwi);
@@ -1652,8 +1652,8 @@
             if (validatePhoneId(phoneId)) {
                 mUserMobileDataState[phoneId] = state;
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onUserMobileDataStateChanged(state);
@@ -1691,8 +1691,8 @@
             if (validatePhoneId(phoneId)) {
                 mTelephonyDisplayInfos[phoneId] = telephonyDisplayInfo;
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED)
                             && idMatchWithoutDefaultPhoneCheck(r.subId, subId)) {
                         try {
                             r.callback.onDisplayInfoChanged(telephonyDisplayInfo);
@@ -1723,8 +1723,8 @@
             if (validatePhoneId(phoneId)) {
                 mCallForwarding[phoneId] = cfi;
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onCallForwardingIndicatorChanged(cfi);
@@ -1752,8 +1752,8 @@
                 mDataActivity[phoneId] = state;
                 for (Record r : mRecords) {
                     // Notify by correct subId.
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_DATA_ACTIVITY_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onDataActivity(state);
@@ -1800,8 +1800,8 @@
                     log(str);
                     mLocalLog.log(str);
                     for (Record r : mRecords) {
-                        if (r.matchPhoneStateListenerEvent(
-                                PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED)
+                        if (r.matchTelephonyCallbackEvent(
+                                TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED)
                                 && idMatch(r.subId, subId, phoneId)) {
                             try {
                                 if (DBG) {
@@ -1825,8 +1825,8 @@
                         .remove(key);
                 if (!Objects.equals(oldState, preciseState)) {
                     for (Record r : mRecords) {
-                        if (r.matchPhoneStateListenerEvent(
-                                PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED)
+                        if (r.matchTelephonyCallbackEvent(
+                                TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED)
                                 && idMatch(r.subId, subId, phoneId)) {
                             try {
                                 r.callback.onPreciseDataConnectionStateChanged(preciseState);
@@ -1872,7 +1872,7 @@
                 mCellIdentity[phoneId] = cellIdentity;
                 for (Record r : mRecords) {
                     if (validateEventAndUserLocked(
-                            r, PhoneStateListener.EVENT_CELL_LOCATION_CHANGED)
+                            r, TelephonyCallback.EVENT_CELL_LOCATION_CHANGED)
                             && idMatch(r.subId, subId, phoneId)
                             && (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
                                     && checkFineLocationAccess(r, Build.VERSION_CODES.Q))) {
@@ -1925,8 +1925,8 @@
                 }
 
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onPreciseCallStateChanged(mPreciseCallState[phoneId]);
@@ -1934,8 +1934,8 @@
                             mRemoveList.add(r.binder);
                         }
                     }
-                    if (notifyCallAttributes && r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED)
+                    if (notifyCallAttributes && r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onCallAttributesChanged(mCallAttributes[phoneId]);
@@ -1959,8 +1959,9 @@
                 mCallDisconnectCause[phoneId] = disconnectCause;
                 mCallPreciseDisconnectCause[phoneId] = preciseDisconnectCause;
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(PhoneStateListener
-                            .LISTEN_CALL_DISCONNECT_CAUSES) && idMatch(r.subId, subId, phoneId)) {
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED)
+                            && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause[phoneId],
                                     mCallPreciseDisconnectCause[phoneId]);
@@ -1983,8 +1984,8 @@
             if (validatePhoneId(phoneId)) {
                 mImsReasonInfo.set(phoneId, imsReasonInfo);
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             if (DBG_LOC) {
@@ -2015,8 +2016,8 @@
             if (validatePhoneId(phoneId)) {
                 mSrvccState[phoneId] = state;
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_SRVCC_STATE_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_SRVCC_STATE_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             if (DBG_LOC) {
@@ -2044,8 +2045,8 @@
                     if (VDBG) {
                         log("notifyOemHookRawEventForSubscriber:  r=" + r + " subId=" + subId);
                     }
-                    if ((r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_OEM_HOOK_RAW))
+                    if ((r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_OEM_HOOK_RAW))
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onOemHookRawEvent(rawData);
@@ -2072,8 +2073,8 @@
             mPhoneCapability = capability;
 
             for (Record r : mRecords) {
-                if (r.matchPhoneStateListenerEvent(
-                        PhoneStateListener.EVENT_PHONE_CAPABILITY_CHANGED)) {
+                if (r.matchTelephonyCallbackEvent(
+                        TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED)) {
                     try {
                         r.callback.onPhoneCapabilityChanged(capability);
                     } catch (RemoteException ex) {
@@ -2097,8 +2098,8 @@
         mActiveDataSubId = activeDataSubId;
         synchronized (mRecords) {
             for (Record r : mRecords) {
-                if (r.matchPhoneStateListenerEvent(
-                        PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED)) {
+                if (r.matchTelephonyCallbackEvent(
+                        TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED)) {
                     try {
                         r.callback.onActiveDataSubIdChanged(activeDataSubId);
                     } catch (RemoteException ex) {
@@ -2124,8 +2125,8 @@
                 mRadioPowerState = state;
 
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onRadioPowerStateChanged(state);
@@ -2153,8 +2154,8 @@
                 mEmergencyNumberList = tm.getEmergencyNumberList();
 
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onEmergencyNumberListChanged(mEmergencyNumberList);
@@ -2185,8 +2186,8 @@
             }
             for (Record r : mRecords) {
                 // Send to all listeners regardless of subscription
-                if (r.matchPhoneStateListenerEvent(
-                        PhoneStateListener.EVENT_OUTGOING_EMERGENCY_CALL)) {
+                if (r.matchTelephonyCallbackEvent(
+                        TelephonyCallback.EVENT_OUTGOING_EMERGENCY_CALL)) {
                     try {
                         r.callback.onOutgoingEmergencyCall(emergencyNumber, subId);
                     } catch (RemoteException ex) {
@@ -2204,13 +2205,14 @@
         if (!checkNotifyPermission("notifyOutgoingEmergencySms()")) {
             return;
         }
+
         synchronized (mRecords) {
             if (validatePhoneId(phoneId)) {
                 mOutgoingSmsEmergencyNumber[phoneId] = emergencyNumber;
                 for (Record r : mRecords) {
                     // Send to all listeners regardless of subscription
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_OUTGOING_EMERGENCY_SMS)) {
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_OUTGOING_EMERGENCY_SMS)) {
                         try {
                             r.callback.onOutgoingEmergencySms(emergencyNumber, subId);
                         } catch (RemoteException ex) {
@@ -2239,8 +2241,8 @@
                         callNetworkType, callQuality);
 
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onCallAttributesChanged(mCallAttributes[phoneId]);
@@ -2270,8 +2272,8 @@
         synchronized (mRecords) {
             if (validatePhoneId(phoneId)) {
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_REGISTRATION_FAILURE)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_REGISTRATION_FAILURE)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onRegistrationFailed(
@@ -2313,8 +2315,8 @@
                 BarringInfo biNoLocation = barringInfo.createLocationInfoSanitizedCopy();
                 if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo);
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_BARRING_INFO_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_BARRING_INFO_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             if (DBG_LOC) {
@@ -2356,8 +2358,8 @@
             if (validatePhoneId(phoneId)) {
                 mPhysicalChannelConfigs.set(phoneId, configs.get(phoneId));
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             if (DBG_LOC) {
@@ -2386,7 +2388,7 @@
      *                {@link TelephonyManager}.
      */
     public void notifyDataEnabled(int phoneId, int subId, boolean enabled,
-                                  @TelephonyManager.DataEnabledReason int reason) {
+            @TelephonyManager.DataEnabledReason int reason) {
         if (!checkNotifyPermission("notifyDataEnabled()")) {
             return;
         }
@@ -2401,8 +2403,8 @@
                 mIsDataEnabled[phoneId] = enabled;
                 mDataEnabledReason[phoneId] = reason;
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_DATA_ENABLED_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_DATA_ENABLED_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onDataEnabledChanged(enabled, reason);
@@ -2435,8 +2437,8 @@
                 mAllowedNetworkTypesList = allowedNetworkTypesList;
 
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED)
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             if (VDBG) {
@@ -2815,7 +2817,7 @@
                     android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
         }
 
-        if ((events.contains(PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED))) {
+        if ((events.contains(TelephonyCallback.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED))) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH, null);
         }
@@ -2845,7 +2847,7 @@
         try {
             foregroundUser = ActivityManager.getCurrentUser();
             valid = UserHandle.getUserId(r.callerUid) == foregroundUser
-                    && r.matchPhoneStateListenerEvent(event);
+                    && r.matchTelephonyCallbackEvent(event);
             if (DBG | DBG_LOC) {
                 log("validateEventAndUserLocked: valid=" + valid
                         + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser
@@ -2956,7 +2958,7 @@
             return;
         }
 
-        if ((events.contains(PhoneStateListener.EVENT_SERVICE_STATE_CHANGED))) {
+        if ((events.contains(TelephonyCallback.EVENT_SERVICE_STATE_CHANGED))) {
             try {
                 if (VDBG) log("checkPossibleMissNotify: onServiceStateChanged state=" +
                         mServiceState[phoneId]);
@@ -2975,9 +2977,9 @@
             }
         }
 
-        if (events.contains(PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED)
+        if (events.contains(TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED)
                 || events.contains(
-                PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) {
+                TelephonyCallback.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) {
             try {
                 if (mSignalStrength[phoneId] != null) {
                     SignalStrength signalStrength = mSignalStrength[phoneId];
@@ -2992,7 +2994,7 @@
             }
         }
 
-        if (events.contains(PhoneStateListener.EVENT_SIGNAL_STRENGTH_CHANGED)) {
+        if (events.contains(TelephonyCallback.EVENT_SIGNAL_STRENGTH_CHANGED)) {
             try {
                 if (mSignalStrength[phoneId] != null) {
                     int gsmSignalStrength = mSignalStrength[phoneId]
@@ -3009,7 +3011,7 @@
             }
         }
 
-        if (validateEventAndUserLocked(r, PhoneStateListener.EVENT_CELL_INFO_CHANGED)) {
+        if (validateEventAndUserLocked(r, TelephonyCallback.EVENT_CELL_INFO_CHANGED)) {
             try {
                 if (DBG_LOC) {
                     log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = "
@@ -3024,7 +3026,7 @@
             }
         }
 
-        if (events.contains(PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED)) {
+        if (events.contains(TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED)) {
             try {
                 if (VDBG) {
                     log("checkPossibleMissNotify: onUserMobileDataStateChanged phoneId="
@@ -3036,7 +3038,7 @@
             }
         }
 
-        if (events.contains(PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED)) {
+        if (events.contains(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED)) {
             try {
                 if (VDBG) {
                     log("checkPossibleMissNotify: onDisplayInfoChanged phoneId="
@@ -3050,7 +3052,7 @@
             }
         }
 
-        if (events.contains(PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)) {
+        if (events.contains(TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)) {
             try {
                 if (VDBG) {
                     log("checkPossibleMissNotify: onMessageWaitingIndicatorChanged phoneId="
@@ -3063,7 +3065,7 @@
             }
         }
 
-        if (events.contains(PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)) {
+        if (events.contains(TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)) {
             try {
                 if (VDBG) {
                     log("checkPossibleMissNotify: onCallForwardingIndicatorChanged phoneId="
@@ -3076,7 +3078,7 @@
             }
         }
 
-        if (validateEventAndUserLocked(r, PhoneStateListener.EVENT_CELL_LOCATION_CHANGED)) {
+        if (validateEventAndUserLocked(r, TelephonyCallback.EVENT_CELL_LOCATION_CHANGED)) {
             try {
                 if (DBG_LOC) {
                     log("checkPossibleMissNotify: onCellLocationChanged mCellIdentity = "
@@ -3092,7 +3094,7 @@
             }
         }
 
-        if (events.contains(PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED)) {
+        if (events.contains(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED)) {
             try {
                 if (DBG) {
                     log("checkPossibleMissNotify: onDataConnectionStateChanged(mDataConnectionState"
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index ad2f524..502e74a 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -16,6 +16,9 @@
 
 package com.android.server;
 
+import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
+import static android.net.vcn.VcnManager.VCN_STATUS_CODE_INACTIVE;
+import static android.net.vcn.VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED;
 import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE;
 
 import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
@@ -37,6 +40,7 @@
 import android.net.vcn.VcnConfig;
 import android.net.vcn.VcnManager;
 import android.net.vcn.VcnManager.VcnErrorCode;
+import android.net.vcn.VcnManager.VcnStatusCode;
 import android.net.vcn.VcnUnderlyingNetworkPolicy;
 import android.net.wifi.WifiInfo;
 import android.os.Binder;
@@ -421,6 +425,11 @@
                                 // Carrier App manually removing/adding a VcnConfig.
                                 if (mVcns.get(uuidToTeardown) == instanceToTeardown) {
                                     stopVcnLocked(uuidToTeardown);
+
+                                    // TODO(b/181789060): invoke asynchronously after Vcn notifies
+                                    // through VcnCallback
+                                    notifyAllPermissionedStatusCallbacksLocked(
+                                            uuidToTeardown, VCN_STATUS_CODE_INACTIVE);
                                 }
                             }
                         }, instanceToTeardown, CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
@@ -455,6 +464,17 @@
     }
 
     @GuardedBy("mLock")
+    private void notifyAllPermissionedStatusCallbacksLocked(
+            @NonNull ParcelUuid subGroup, @VcnStatusCode int statusCode) {
+        for (final VcnStatusCallbackInfo cbInfo : mRegisteredStatusCallbacks.values()) {
+            if (isCallbackPermissioned(cbInfo, subGroup)) {
+                Binder.withCleanCallingIdentity(
+                        () -> cbInfo.mCallback.onVcnStatusChanged(statusCode));
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
     private void startVcnLocked(@NonNull ParcelUuid subscriptionGroup, @NonNull VcnConfig config) {
         Slog.v(TAG, "Starting VCN config for subGrp: " + subscriptionGroup);
 
@@ -470,6 +490,9 @@
         // Now that a new VCN has started, notify all registered listeners to refresh their
         // UnderlyingNetworkPolicy.
         notifyAllPolicyListenersLocked();
+
+        // TODO(b/181789060): invoke asynchronously after Vcn notifies through VcnCallback
+        notifyAllPermissionedStatusCallbacksLocked(subscriptionGroup, VCN_STATUS_CODE_ACTIVE);
     }
 
     @GuardedBy("mLock")
@@ -478,7 +501,16 @@
         Slog.v(TAG, "Starting or updating VCN config for subGrp: " + subscriptionGroup);
 
         if (mVcns.containsKey(subscriptionGroup)) {
-            mVcns.get(subscriptionGroup).updateConfig(config);
+            final Vcn vcn = mVcns.get(subscriptionGroup);
+            final boolean isActive = vcn.isActive();
+            vcn.updateConfig(config);
+
+            // Only notify VcnStatusCallbacks if this VCN was previously in Safe Mode
+            if (!isActive) {
+                // TODO(b/181789060): invoke asynchronously after Vcn notifies through VcnCallback
+                notifyAllPermissionedStatusCallbacksLocked(
+                        subscriptionGroup, VCN_STATUS_CODE_ACTIVE);
+            }
         } else {
             startVcnLocked(subscriptionGroup, config);
         }
@@ -531,9 +563,17 @@
         Binder.withCleanCallingIdentity(() -> {
             synchronized (mLock) {
                 mConfigs.remove(subscriptionGroup);
+                final boolean vcnExists = mVcns.containsKey(subscriptionGroup);
 
                 stopVcnLocked(subscriptionGroup);
 
+                if (vcnExists) {
+                    // TODO(b/181789060): invoke asynchronously after Vcn notifies through
+                    // VcnCallback
+                    notifyAllPermissionedStatusCallbacksLocked(
+                            subscriptionGroup, VCN_STATUS_CODE_NOT_CONFIGURED);
+                }
+
                 writeConfigsToDiskLocked();
             }
         });
@@ -604,18 +644,20 @@
                 android.Manifest.permission.NETWORK_FACTORY,
                 "Must have permission NETWORK_FACTORY to register a policy listener");
 
-        PolicyListenerBinderDeath listenerBinderDeath = new PolicyListenerBinderDeath(listener);
+        Binder.withCleanCallingIdentity(() -> {
+            PolicyListenerBinderDeath listenerBinderDeath = new PolicyListenerBinderDeath(listener);
 
-        synchronized (mLock) {
-            mRegisteredPolicyListeners.put(listener.asBinder(), listenerBinderDeath);
+            synchronized (mLock) {
+                mRegisteredPolicyListeners.put(listener.asBinder(), listenerBinderDeath);
 
-            try {
-                listener.asBinder().linkToDeath(listenerBinderDeath, 0 /* flags */);
-            } catch (RemoteException e) {
-                // Remote binder already died - cleanup registered Listener
-                listenerBinderDeath.binderDied();
+                try {
+                    listener.asBinder().linkToDeath(listenerBinderDeath, 0 /* flags */);
+                } catch (RemoteException e) {
+                    // Remote binder already died - cleanup registered Listener
+                    listenerBinderDeath.binderDied();
+                }
             }
-        }
+        });
     }
 
     /** Removes the provided listener from receiving VcnUnderlyingNetworkPolicy updates. */
@@ -625,14 +667,31 @@
             @NonNull IVcnUnderlyingNetworkPolicyListener listener) {
         requireNonNull(listener, "listener was null");
 
-        synchronized (mLock) {
-            PolicyListenerBinderDeath listenerBinderDeath =
-                    mRegisteredPolicyListeners.remove(listener.asBinder());
+        Binder.withCleanCallingIdentity(() -> {
+            synchronized (mLock) {
+                PolicyListenerBinderDeath listenerBinderDeath =
+                        mRegisteredPolicyListeners.remove(listener.asBinder());
 
-            if (listenerBinderDeath != null) {
-                listener.asBinder().unlinkToDeath(listenerBinderDeath, 0 /* flags */);
+                if (listenerBinderDeath != null) {
+                    listener.asBinder().unlinkToDeath(listenerBinderDeath, 0 /* flags */);
+                }
             }
+        });
+    }
+
+    private int getSubIdForNetworkCapabilities(@NonNull NetworkCapabilities networkCapabilities) {
+        if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
+                && networkCapabilities.getNetworkSpecifier() instanceof TelephonyNetworkSpecifier) {
+            TelephonyNetworkSpecifier telephonyNetworkSpecifier =
+                    (TelephonyNetworkSpecifier) networkCapabilities.getNetworkSpecifier();
+            return telephonyNetworkSpecifier.getSubscriptionId();
+        } else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
+                && networkCapabilities.getTransportInfo() instanceof WifiInfo) {
+            WifiInfo wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();
+            return mDeps.getSubIdForWifiInfo(wifiInfo);
         }
+
+        return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     }
 
     /**
@@ -652,51 +711,47 @@
                 "Must have permission NETWORK_FACTORY or be the SystemServer to get underlying"
                         + " Network policies");
 
-        // Defensive copy in case this call is in-process and the given NetworkCapabilities mutates
-        networkCapabilities = new NetworkCapabilities(networkCapabilities);
+        return Binder.withCleanCallingIdentity(() -> {
+            // Defensive copy in case this call is in-process and the given NetworkCapabilities
+            // mutates
+            final NetworkCapabilities ncCopy = new NetworkCapabilities(networkCapabilities);
 
-        int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-        if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
-                && networkCapabilities.getNetworkSpecifier() instanceof TelephonyNetworkSpecifier) {
-            TelephonyNetworkSpecifier telephonyNetworkSpecifier =
-                    (TelephonyNetworkSpecifier) networkCapabilities.getNetworkSpecifier();
-            subId = telephonyNetworkSpecifier.getSubscriptionId();
-        } else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
-                && networkCapabilities.getTransportInfo() instanceof WifiInfo) {
-            WifiInfo wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();
-            subId = mDeps.getSubIdForWifiInfo(wifiInfo);
-        }
+            final int subId = getSubIdForNetworkCapabilities(ncCopy);
+            boolean isVcnManagedNetwork = false;
+            boolean isRestrictedCarrierWifi = false;
+            if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+                synchronized (mLock) {
+                    ParcelUuid subGroup = mLastSnapshot.getGroupForSubId(subId);
 
-        boolean isVcnManagedNetwork = false;
-        boolean isRestrictedCarrierWifi = false;
-        if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            synchronized (mLock) {
-                ParcelUuid subGroup = mLastSnapshot.getGroupForSubId(subId);
+                    final Vcn vcn = mVcns.get(subGroup);
+                    if (vcn != null) {
+                        if (vcn.isActive()) {
+                            isVcnManagedNetwork = true;
+                        }
 
-                Vcn vcn = mVcns.get(subGroup);
-                if (vcn != null) {
-                    if (vcn.isActive()) {
-                        isVcnManagedNetwork = true;
-                    }
-
-                    if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
-                        // Carrier WiFi always restricted if VCN exists (even in safe mode).
-                        isRestrictedCarrierWifi = true;
+                        if (ncCopy.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
+                            // Carrier WiFi always restricted if VCN exists (even in safe mode).
+                            isRestrictedCarrierWifi = true;
+                        }
                     }
                 }
             }
-        }
 
-        if (isVcnManagedNetwork) {
-            networkCapabilities.removeCapability(
-                    NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
-        }
+            final NetworkCapabilities.Builder ncBuilder = new NetworkCapabilities.Builder(ncCopy);
 
-        if (isRestrictedCarrierWifi) {
-            networkCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
-        }
+            if (isVcnManagedNetwork) {
+                ncBuilder.removeCapability(
+                        NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+            }
 
-        return new VcnUnderlyingNetworkPolicy(false /* isTearDownRequested */, networkCapabilities);
+            if (isRestrictedCarrierWifi) {
+                ncBuilder.removeCapability(
+                        NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+            }
+
+            return new VcnUnderlyingNetworkPolicy(
+                    false /* isTearDownRequested */, ncBuilder.build());
+        });
     }
 
     /** Binder death recipient used to remove registered VcnStatusCallbacks. */
@@ -857,16 +912,7 @@
                 }
 
                 notifyAllPolicyListenersLocked();
-
-                // Notify all registered StatusCallbacks for this subGroup
-                for (VcnStatusCallbackInfo cbInfo : mRegisteredStatusCallbacks.values()) {
-                    if (isCallbackPermissioned(cbInfo, mSubGroup)) {
-                        Binder.withCleanCallingIdentity(
-                                () ->
-                                        cbInfo.mCallback.onVcnStatusChanged(
-                                                VCN_STATUS_CODE_SAFE_MODE));
-                    }
-                }
+                notifyAllPermissionedStatusCallbacksLocked(mSubGroup, VCN_STATUS_CODE_SAFE_MODE);
             }
         }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 149e3ba..af89907 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -1690,7 +1690,14 @@
 
         pw.println("Hanging the system...");
         pw.flush();
-        mInterface.hang(new Binder(), allowRestart);
+        try {
+            mInterface.hang(getShellCallback().getShellCallbackBinder(), allowRestart);
+        } catch (NullPointerException e) {
+            pw.println("Hanging failed, since caller " + Binder.getCallingPid() +
+                    " did not provide a ShellCallback!");
+            pw.flush();
+            return 1;
+        }
         return 0;
     }
 
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 3f9811c..226802c 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -73,6 +73,7 @@
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.ParseUtils;
 import com.android.net.module.util.NetworkCapabilitiesUtils;
+import com.android.net.module.util.PermissionUtils;
 import com.android.server.LocalServices;
 import com.android.server.net.BaseNetworkObserver;
 
@@ -1102,7 +1103,7 @@
 
     @Override
     public void noteNetworkInterfaceForTransports(final String iface, int[] transportTypes) {
-        enforceCallingPermission();
+        PermissionUtils.enforceNetworkStackPermission(mContext);
         mStats.noteNetworkInterfaceForTransports(iface, transportTypes);
     }
 
diff --git a/services/core/java/com/android/server/apphibernation/AppHibernationManagerInternal.java b/services/core/java/com/android/server/apphibernation/AppHibernationManagerInternal.java
new file mode 100644
index 0000000..b0335fe
--- /dev/null
+++ b/services/core/java/com/android/server/apphibernation/AppHibernationManagerInternal.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.apphibernation;
+
+/**
+ * App hibernation manager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class AppHibernationManagerInternal {
+
+    /**
+     * @see AppHibernationService#isHibernatingForUser
+     */
+    public abstract boolean isHibernatingForUser(String packageName, int userId);
+
+    /**
+     * @see AppHibernationService#setHibernatingForUser
+     */
+    public abstract void setHibernatingForUser(String packageName, int userId,
+            boolean isHibernating);
+
+    /**
+     * @see AppHibernationService#isHibernatingGlobally
+     */
+    public abstract boolean isHibernatingGlobally(String packageName);
+
+    /**
+     * @see AppHibernationService#setHibernatingGlobally
+     */
+    public abstract void setHibernatingGlobally(String packageName, boolean isHibernating);
+}
diff --git a/services/core/java/com/android/server/apphibernation/AppHibernationService.java b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
index 32ae878..968cf5f 100644
--- a/services/core/java/com/android/server/apphibernation/AppHibernationService.java
+++ b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
@@ -59,6 +59,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.LocalServices;
 import com.android.server.SystemService;
 
 import java.io.File;
@@ -134,6 +135,8 @@
         intentFilter.addAction(ACTION_PACKAGE_REMOVED);
         intentFilter.addDataScheme("package");
         userAllContext.registerReceiver(mBroadcastReceiver, intentFilter);
+
+        LocalServices.addService(AppHibernationManagerInternal.class, mLocalService);
     }
 
     @Override
@@ -545,6 +548,36 @@
         }
     }
 
+    private final AppHibernationManagerInternal mLocalService = new LocalService(this);
+
+    private static final class LocalService extends AppHibernationManagerInternal {
+        private final AppHibernationService mService;
+
+        LocalService(AppHibernationService service) {
+            mService = service;
+        }
+
+        @Override
+        public boolean isHibernatingForUser(String packageName, int userId) {
+            return mService.isHibernatingForUser(packageName, userId);
+        }
+
+        @Override
+        public void setHibernatingForUser(String packageName, int userId, boolean isHibernating) {
+            mService.setHibernatingForUser(packageName, userId, isHibernating);
+        }
+
+        @Override
+        public void setHibernatingGlobally(String packageName, boolean isHibernating) {
+            mService.setHibernatingGlobally(packageName, isHibernating);
+        }
+
+        @Override
+        public boolean isHibernatingGlobally(String packageName) {
+            return mService.isHibernatingGlobally(packageName);
+        }
+    }
+
     private final AppHibernationServiceStub mServiceStub = new AppHibernationServiceStub(this);
 
     static final class AppHibernationServiceStub extends IAppHibernationService.Stub {
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index fa80b25..c66a280 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -16,6 +16,8 @@
 
 package com.android.server.connectivity;
 
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+
 import static com.android.net.module.util.CollectionUtils.contains;
 
 import android.annotation.NonNull;
@@ -35,6 +37,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.net.module.util.NetworkStackConstants;
+import com.android.server.ConnectivityService;
 
 import java.net.Inet6Address;
 import java.util.Objects;
@@ -94,12 +97,15 @@
     private Inet6Address mIPv6Address;
     private State mState = State.IDLE;
 
+    private boolean mEnableClatOnCellular;
     private boolean mPrefixDiscoveryRunning;
 
-    public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver) {
+    public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver,
+            ConnectivityService.Dependencies deps) {
         mDnsResolver = dnsResolver;
         mNetd = netd;
         mNetwork = nai;
+        mEnableClatOnCellular = deps.getCellular464XlatEnabled();
     }
 
     /**
@@ -111,7 +117,7 @@
      * @return true if the network requires clat, false otherwise.
      */
     @VisibleForTesting
-    protected static boolean requiresClat(NetworkAgentInfo nai) {
+    protected boolean requiresClat(NetworkAgentInfo nai) {
         // TODO: migrate to NetworkCapabilities.TRANSPORT_*.
         final boolean supported = contains(NETWORK_TYPES, nai.networkInfo.getType());
         final boolean connected = contains(NETWORK_STATES, nai.networkInfo.getState());
@@ -126,7 +132,9 @@
         final boolean skip464xlat = (nai.netAgentConfig() != null)
                 && nai.netAgentConfig().skip464xlat;
 
-        return supported && connected && isIpv6OnlyNetwork && !skip464xlat;
+        return supported && connected && isIpv6OnlyNetwork && !skip464xlat
+            && (nai.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)
+                ? isCellular464XlatEnabled() : true);
     }
 
     /**
@@ -137,7 +145,7 @@
      * @return true if the network should start clat, false otherwise.
      */
     @VisibleForTesting
-    protected static boolean shouldStartClat(NetworkAgentInfo nai) {
+    protected boolean shouldStartClat(NetworkAgentInfo nai) {
         LinkProperties lp = nai.linkProperties;
         return requiresClat(nai) && lp != null && lp.getNat64Prefix() != null;
     }
@@ -507,4 +515,9 @@
     protected int getNetId() {
         return mNetwork.network.getNetId();
     }
+
+    @VisibleForTesting
+    protected boolean isCellular464XlatEnabled() {
+        return mEnableClatOnCellular;
+    }
 }
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 1d0e115..803cc9d 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -341,7 +341,7 @@
             @NonNull LinkProperties lp, @NonNull NetworkCapabilities nc, int score, Context context,
             Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd,
             IDnsResolver dnsResolver, int factorySerialNumber, int creatorUid,
-            QosCallbackTracker qosCallbackTracker) {
+            QosCallbackTracker qosCallbackTracker, ConnectivityService.Dependencies deps) {
         Objects.requireNonNull(net);
         Objects.requireNonNull(info);
         Objects.requireNonNull(lp);
@@ -355,7 +355,7 @@
         linkProperties = lp;
         networkCapabilities = nc;
         mScore = score;
-        clatd = new Nat464Xlat(this, netd, dnsResolver);
+        clatd = new Nat464Xlat(this, netd, dnsResolver, deps);
         mConnService = connService;
         mContext = context;
         mHandler = handler;
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
index 364aa2c..240464a 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
@@ -207,7 +207,7 @@
         public void reportMetric(boolean success) {
             // TODO(b/179105110) design error code; and report the true value for other fields.
             FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED, 0, 1, 1,
-                    -1, 0);
+                    -1, 0, -1);
         }
 
         public RebootEscrowEventLog getEventLog() {
@@ -251,6 +251,8 @@
         }
 
         if (rebootEscrowUsers.isEmpty()) {
+            Slog.i(TAG, "No reboot escrow data found for users,"
+                    + " skipping loading escrow data");
             return;
         }
 
diff --git a/services/core/java/com/android/server/locksettings/TEST_MAPPING b/services/core/java/com/android/server/locksettings/TEST_MAPPING
index 56f5cc0..8c19c54 100644
--- a/services/core/java/com/android/server/locksettings/TEST_MAPPING
+++ b/services/core/java/com/android/server/locksettings/TEST_MAPPING
@@ -10,6 +10,17 @@
                     "exclude-annotation": "android.platform.test.annotations.FlakyTest"
                 }
             ]
+        },
+        {
+            "name": "FrameworksServicesTests",
+            "options": [
+                {
+                    "include-filter": "com.android.server.locksettings."
+                },
+                {
+                    "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+                }
+            ]
         }
     ]
 }
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformDecryptionKey.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformDecryptionKey.java
index 35571f1..e75aae1 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformDecryptionKey.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformDecryptionKey.java
@@ -16,7 +16,7 @@
 
 package com.android.server.locksettings.recoverablekeystore;
 
-import android.security.keystore.AndroidKeyStoreSecretKey;
+import javax.crypto.SecretKey;
 
 /**
  * Used to unwrap recoverable keys before syncing them with remote storage.
@@ -30,7 +30,7 @@
 public class PlatformDecryptionKey {
 
     private final int mGenerationId;
-    private final AndroidKeyStoreSecretKey mKey;
+    private final SecretKey mKey;
 
     /**
      * A new instance.
@@ -40,7 +40,7 @@
      *
      * @hide
      */
-    public PlatformDecryptionKey(int generationId, AndroidKeyStoreSecretKey key) {
+    public PlatformDecryptionKey(int generationId, SecretKey key) {
         mGenerationId = generationId;
         mKey = key;
     }
@@ -59,7 +59,7 @@
      *
      * @hide
      */
-    public AndroidKeyStoreSecretKey getKey() {
+    public SecretKey getKey() {
         return mKey;
     }
 }
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java
index 38f5b45..ee33446 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java
@@ -16,7 +16,7 @@
 
 package com.android.server.locksettings.recoverablekeystore;
 
-import android.security.keystore.AndroidKeyStoreSecretKey;
+import javax.crypto.SecretKey;
 
 /**
  * Private key stored in AndroidKeyStore. Used to wrap recoverable keys before writing them to disk.
@@ -33,7 +33,7 @@
 public class PlatformEncryptionKey {
 
     private final int mGenerationId;
-    private final AndroidKeyStoreSecretKey mKey;
+    private final SecretKey mKey;
 
     /**
      * A new instance.
@@ -41,7 +41,7 @@
      * @param generationId The generation ID of the key.
      * @param key The secret key handle. Can be used to encrypt WITHOUT requiring screen unlock.
      */
-    public PlatformEncryptionKey(int generationId, AndroidKeyStoreSecretKey key) {
+    public PlatformEncryptionKey(int generationId, SecretKey key) {
         mGenerationId = generationId;
         mKey = key;
     }
@@ -56,7 +56,7 @@
     /**
      * Returns the actual key, which can only be used to encrypt.
      */
-    public AndroidKeyStoreSecretKey getKey() {
+    public SecretKey getKey() {
         return mKey;
     }
 }
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
index 202dfe7..5e06205 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
@@ -21,7 +21,6 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.security.GateKeeper;
-import android.security.keystore.AndroidKeyStoreSecretKey;
 import android.security.keystore.KeyPermanentlyInvalidatedException;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyProtection;
@@ -237,7 +236,7 @@
         if (!isKeyLoaded(userId, generationId)) {
             throw new UnrecoverableKeyException("KeyStore doesn't contain key " + alias);
         }
-        AndroidKeyStoreSecretKey key = (AndroidKeyStoreSecretKey) mKeyStore.getKey(
+        SecretKey key = (SecretKey) mKeyStore.getKey(
                 alias, /*password=*/ null);
         return new PlatformEncryptionKey(generationId, key);
     }
@@ -289,7 +288,7 @@
         if (!isKeyLoaded(userId, generationId)) {
             throw new UnrecoverableKeyException("KeyStore doesn't contain key " + alias);
         }
-        AndroidKeyStoreSecretKey key = (AndroidKeyStoreSecretKey) mKeyStore.getKey(
+        SecretKey key = (SecretKey) mKeyStore.getKey(
                 alias, /*password=*/ null);
         return new PlatformDecryptionKey(generationId, key);
     }
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index e0f5346..7b376847 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -24,7 +24,6 @@
 import static android.content.Intent.ACTION_USER_REMOVED;
 import static android.content.Intent.EXTRA_UID;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.net.ConnectivityManager.isNetworkTypeMobile;
 import static android.net.NetworkIdentity.SUBTYPE_COMBINED;
 import static android.net.NetworkStack.checkNetworkStackPermission;
 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
@@ -71,6 +70,7 @@
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
 import static android.text.format.DateUtils.SECOND_IN_MILLIS;
 
+import static com.android.net.module.util.NetworkCapabilitiesUtils.getDisplayTransport;
 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
 import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
 import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
@@ -1291,7 +1291,9 @@
         final boolean combineSubtypeEnabled = mSettings.getCombineSubtypeEnabled();
         final ArraySet<String> mobileIfaces = new ArraySet<>();
         for (NetworkStateSnapshot snapshot : snapshots) {
-            final boolean isMobile = isNetworkTypeMobile(snapshot.legacyType);
+            final int displayTransport =
+                    getDisplayTransport(snapshot.networkCapabilities.getTransportTypes());
+            final boolean isMobile = (NetworkCapabilities.TRANSPORT_CELLULAR == displayTransport);
             final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, snapshot.network);
             final int subType = combineSubtypeEnabled ? SUBTYPE_COMBINED
                     : getSubTypeForStateSnapshot(snapshot);
diff --git a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
index bf99bd6..0659bc3 100644
--- a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
+++ b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
@@ -114,7 +114,7 @@
         out.println("    'lowest', change priority of PACKAGE to the lowest priority.");
         out.println("    If PARENT is the special keyword 'highest', change priority of");
         out.println("    PACKAGE to the highest priority.");
-        out.println("  lookup [--verbose] PACKAGE-TO-LOAD PACKAGE:TYPE/NAME");
+        out.println("  lookup [--user USER_ID] [--verbose] PACKAGE-TO-LOAD PACKAGE:TYPE/NAME");
         out.println("    Load a package and print the value of a given resource");
         out.println("    applying the current configuration and enabled overlays.");
         out.println("    For a more fine-grained alernative, use 'idmap2 lookup'.");
@@ -274,7 +274,22 @@
         final PrintWriter out = getOutPrintWriter();
         final PrintWriter err = getErrPrintWriter();
 
-        final boolean verbose = "--verbose".equals(getNextOption());
+        int userId = UserHandle.USER_SYSTEM;
+        boolean verbose = false;
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "--user":
+                    userId = UserHandle.parseUserArg(getNextArgRequired());
+                    break;
+                case "--verbose":
+                    verbose = true;
+                    break;
+                default:
+                    err.println("Error: Unknown option: " + opt);
+                    return 1;
+            }
+        }
 
         final String packageToLoad = getNextArgRequired();
 
@@ -286,17 +301,15 @@
             return 1;
         }
 
-        final PackageManager pm = mContext.getPackageManager();
-        if (pm == null) {
-            err.println("Error: failed to get package manager");
-            return 1;
-        }
-
         final Resources res;
         try {
-            res = pm.getResourcesForApplication(packageToLoad);
+            res = mContext
+                .createContextAsUser(UserHandle.of(userId), /* flags */ 0)
+                .getPackageManager()
+                .getResourcesForApplication(packageToLoad);
         } catch (PackageManager.NameNotFoundException e) {
-            err.println("Error: failed to get resources for package " + packageToLoad);
+            err.println(String.format("Error: failed to get resources for package %s for user %d",
+                    packageToLoad, userId));
             return 1;
         }
         final AssetManager assets = res.getAssets();
diff --git a/services/core/java/com/android/server/stats/OWNERS b/services/core/java/com/android/server/stats/OWNERS
index fc7fd22..174ad3a 100644
--- a/services/core/java/com/android/server/stats/OWNERS
+++ b/services/core/java/com/android/server/stats/OWNERS
@@ -1,7 +1,10 @@
 jeffreyhuang@google.com
 joeo@google.com
+jtnguyen@google.com
 muhammadq@google.com
+rslawik@google.com
 ruchirr@google.com
+sharaienko@google.com
 singhtejinder@google.com
 tsaichristine@google.com
 yaochen@google.com
diff --git a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
index b2db9f5..8dcc547 100644
--- a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
+++ b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
@@ -23,7 +23,6 @@
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
-import android.net.NetworkCapabilities.NetCapability;
 import android.net.NetworkRequest;
 import android.net.TelephonyNetworkSpecifier;
 import android.os.Handler;
@@ -115,33 +114,61 @@
                 getWifiNetworkRequest(), mHandler, mWifiBringupCallback);
         updateSubIdsAndCellularRequests();
 
-        // register Network-selection request used to decide selected underlying Network
+        // Register Network-selection request used to decide selected underlying Network. All
+        // underlying networks must be VCN managed in order to be used.
         mConnectivityManager.requestBackgroundNetwork(
-                getNetworkRequestBase().build(), mHandler, mRouteSelectionCallback);
+                getBaseNetworkRequest(true /* requireVcnManaged */).build(),
+                mHandler,
+                mRouteSelectionCallback);
     }
 
     private NetworkRequest getWifiNetworkRequest() {
-        return getNetworkRequestBase().addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build();
+        // Request exclusively VCN managed networks to ensure that we only ever keep carrier wifi
+        // alive.
+        return getBaseNetworkRequest(true /* requireVcnManaged */)
+                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+                .build();
     }
 
     private NetworkRequest getCellNetworkRequestForSubId(int subId) {
-        return getNetworkRequestBase()
+        // Do not request NOT_VCN_MANAGED to ensure that the TelephonyNetworkFactory has a
+        // fulfillable request to bring up underlying cellular Networks even if the VCN is already
+        // connected.
+        return getBaseNetworkRequest(false /* requireVcnManaged */)
                 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                 .setNetworkSpecifier(new TelephonyNetworkSpecifier(subId))
                 .build();
     }
 
-    private NetworkRequest.Builder getNetworkRequestBase() {
-        NetworkRequest.Builder requestBase = new NetworkRequest.Builder();
-        for (@NetCapability int capability : mRequiredUnderlyingNetworkCapabilities) {
+    /**
+     * Builds and returns a NetworkRequest builder common to all Underlying Network requests
+     *
+     * <p>A NetworkRequest may either (1) Require the presence of a capability by using
+     * addCapability(), (2) require the absence of a capability using unwanted capabilities, or (3)
+     * allow any state. Underlying networks are never desired to have the NOT_VCN_MANAGED
+     * capability, and only cases (2) and (3) are used.
+     *
+     * @param requireVcnManaged whether the underlying network is required to be VCN managed to
+     *     match this request. If {@code true}, the NOT_VCN_MANAGED capability will be set as
+     *     unwanted. Else, the NOT_VCN_MANAGED capability will be removed, and any state is
+     *     acceptable.
+     */
+    private NetworkRequest.Builder getBaseNetworkRequest(boolean requireVcnManaged) {
+        NetworkRequest.Builder requestBase =
+                new NetworkRequest.Builder()
+                        .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+                        .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+                        .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+
+        for (int capability : mRequiredUnderlyingNetworkCapabilities) {
             requestBase.addCapability(capability);
         }
 
-        return requestBase
-                .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
-                .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                .addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+        if (requireVcnManaged) {
+            requestBase.addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+        }
+
+        return requestBase;
     }
 
     /**
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java
index 9d39c67..3f74938 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -128,7 +128,6 @@
      * from VcnManagementService, and therefore cannot rely on guarantees of running on the VCN
      * Looper.
      */
-    // TODO(b/179429339): update when exiting safemode (when a new VcnConfig is provided)
     private final AtomicBoolean mIsActive = new AtomicBoolean(true);
 
     public Vcn(
@@ -203,7 +202,8 @@
 
     @Override
     public void handleMessage(@NonNull Message msg) {
-        if (!isActive()) {
+        // Ignore if this Vcn is not active and we're not receiving new configs
+        if (!isActive() && msg.what != MSG_EVENT_CONFIG_UPDATED) {
             return;
         }
 
@@ -237,7 +237,13 @@
 
         mConfig = config;
 
-        // TODO: Reevaluate active VcnGatewayConnection(s)
+        // TODO(b/181815405): Reevaluate active VcnGatewayConnection(s)
+
+        if (!mIsActive.getAndSet(true)) {
+            // If this VCN was not previously active, it is exiting Safe Mode. Re-register the
+            // request listener to get NetworkRequests again (and all cached requests).
+            mVcnContext.getVcnNetworkProvider().registerListener(mRequestListener);
+        }
     }
 
     private void handleTeardown() {
@@ -253,6 +259,8 @@
     private void handleEnterSafeMode() {
         handleTeardown();
 
+        mVcnGatewayConnections.clear();
+
         mVcnCallback.onEnteredSafeMode();
     }
 
@@ -291,9 +299,7 @@
         for (VcnGatewayConnectionConfig gatewayConnectionConfig :
                 mConfig.getGatewayConnectionConfigs()) {
             if (isRequestSatisfiedByGatewayConnectionConfig(request, gatewayConnectionConfig)) {
-                Slog.v(
-                        getLogTag(),
-                        "Bringing up new VcnGatewayConnection for request " + request.requestId);
+                Slog.v(getLogTag(), "Bringing up new VcnGatewayConnection for request " + request);
 
                 final VcnGatewayConnection vcnGatewayConnection =
                         mDeps.newVcnGatewayConnection(
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 6bc9978..69a153f 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -20,6 +20,7 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.vcn.VcnManager.VCN_ERROR_CODE_CONFIG_ERROR;
@@ -59,6 +60,7 @@
 import android.net.ipsec.ike.exceptions.IkeException;
 import android.net.ipsec.ike.exceptions.IkeInternalException;
 import android.net.ipsec.ike.exceptions.IkeProtocolException;
+import android.net.vcn.VcnControlPlaneIkeConfig;
 import android.net.vcn.VcnGatewayConnectionConfig;
 import android.net.vcn.VcnTransportInfo;
 import android.net.wifi.WifiInfo;
@@ -979,7 +981,7 @@
         // IkeSessionCallback.onClosedExceptionally(), which calls sessionClosed()
         if (exception != null) {
             mGatewayStatusCallback.onGatewayConnectionError(
-                    mConnectionConfig.getRequiredUnderlyingCapabilities(),
+                    mConnectionConfig.getExposedCapabilities(),
                     VCN_ERROR_CODE_INTERNAL_ERROR,
                     RuntimeException.class.getName(),
                     "Received "
@@ -1016,7 +1018,7 @@
         }
 
         mGatewayStatusCallback.onGatewayConnectionError(
-                mConnectionConfig.getRequiredUnderlyingCapabilities(),
+                mConnectionConfig.getExposedCapabilities(),
                 errorCode,
                 exceptionClass,
                 exceptionMessage);
@@ -1348,7 +1350,7 @@
                 mIkeSession = null;
             }
 
-            mIkeSession = buildIkeSession();
+            mIkeSession = buildIkeSession(mUnderlying.network);
         }
 
         @Override
@@ -1726,6 +1728,7 @@
         final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
 
         builder.addTransportType(TRANSPORT_CELLULAR);
+        builder.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
         builder.addCapability(NET_CAPABILITY_NOT_CONGESTED);
         builder.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
 
@@ -1939,23 +1942,29 @@
                 new EventDisconnectRequestedInfo(reason, shouldQuit));
     }
 
-    private IkeSessionParams buildIkeParams() {
-        // TODO: Implement this once IkeSessionParams is persisted
-        return null;
+    private IkeSessionParams buildIkeParams(@NonNull Network network) {
+        final VcnControlPlaneIkeConfig controlPlaneConfig =
+                (VcnControlPlaneIkeConfig) mConnectionConfig.getControlPlaneConfig();
+        final IkeSessionParams.Builder builder =
+                new IkeSessionParams.Builder(controlPlaneConfig.getIkeSessionParams());
+        builder.setConfiguredNetwork(network);
+
+        return builder.build();
     }
 
     private ChildSessionParams buildChildParams() {
-        // TODO: Implement this once IkeSessionParams is persisted
-        return null;
+        final VcnControlPlaneIkeConfig controlPlaneConfig =
+                (VcnControlPlaneIkeConfig) mConnectionConfig.getControlPlaneConfig();
+        return controlPlaneConfig.getChildSessionParams();
     }
 
     @VisibleForTesting(visibility = Visibility.PRIVATE)
-    VcnIkeSession buildIkeSession() {
+    VcnIkeSession buildIkeSession(@NonNull Network network) {
         final int token = ++mCurrentToken;
 
         return mDeps.newIkeSession(
                 mVcnContext,
-                buildIkeParams(),
+                buildIkeParams(network),
                 buildChildParams(),
                 new IkeSessionCallbackImpl(token),
                 new VcnChildSessionCallback(token));
diff --git a/services/incremental/OWNERS b/services/incremental/OWNERS
index d825dfd..ad5eca7 100644
--- a/services/incremental/OWNERS
+++ b/services/incremental/OWNERS
@@ -1 +1,7 @@
+# Bug component: 554432
 include /services/core/java/com/android/server/pm/OWNERS
+
+alexbuy@google.com
+schfan@google.com
+toddke@google.com
+zyy@google.com
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/ResumeOnRebootServiceProviderTests.java b/services/tests/servicestests/src/com/android/server/locksettings/ResumeOnRebootServiceProviderTests.java
index b9af82b..f3a38e6 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/ResumeOnRebootServiceProviderTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/ResumeOnRebootServiceProviderTests.java
@@ -19,12 +19,12 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.Manifest;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -53,12 +53,9 @@
     Context mMockContext;
     @Mock
     PackageManager mMockPackageManager;
-    @Mock
-    ResolveInfo mMockResolvedInfo;
-    @Mock
-    ServiceInfo mMockServiceInfo;
-    @Mock
-    ComponentName mMockComponentName;
+
+    ResolveInfo mFakeResolvedInfo;
+    ServiceInfo mFakeServiceInfo;
     @Captor
     ArgumentCaptor<Intent> mIntentArgumentCaptor;
 
@@ -66,8 +63,13 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mMockContext.getUserId()).thenReturn(0);
-        when(mMockResolvedInfo.serviceInfo).thenReturn(mMockServiceInfo);
-        when(mMockServiceInfo.getComponentName()).thenReturn(mMockComponentName);
+
+        mFakeServiceInfo = new ServiceInfo();
+        mFakeServiceInfo.packageName = "fakePackageName";
+        mFakeServiceInfo.name = "fakeName";
+
+        mFakeResolvedInfo = new ResolveInfo();
+        mFakeResolvedInfo.serviceInfo = mFakeServiceInfo;
     }
 
     @Test
@@ -82,10 +84,9 @@
     @Test
     public void serviceNotGuardedWithPermission() throws Exception {
         ArrayList<ResolveInfo> resultList = new ArrayList<>();
-        when(mMockServiceInfo.permission).thenReturn("");
-        resultList.add(mMockResolvedInfo);
-        when(mMockPackageManager.queryIntentServices(any(), any())).thenReturn(
-                resultList);
+        mFakeServiceInfo.permission = "";
+        resultList.add(mFakeResolvedInfo);
+        when(mMockPackageManager.queryIntentServices(any(), anyInt())).thenReturn(resultList);
         assertThat(new ResumeOnRebootServiceProvider(mMockContext,
                 mMockPackageManager).getServiceConnection()).isNull();
     }
@@ -93,18 +94,15 @@
     @Test
     public void serviceResolved() throws Exception {
         ArrayList<ResolveInfo> resultList = new ArrayList<>();
-        resultList.add(mMockResolvedInfo);
-        when(mMockServiceInfo.permission).thenReturn(
-                Manifest.permission.BIND_RESUME_ON_REBOOT_SERVICE);
-        when(mMockPackageManager.queryIntentServices(any(),
-                eq(PackageManager.MATCH_SYSTEM_ONLY))).thenReturn(
-                resultList);
+        resultList.add(mFakeResolvedInfo);
+        mFakeServiceInfo.permission = Manifest.permission.BIND_RESUME_ON_REBOOT_SERVICE;
+        when(mMockPackageManager.queryIntentServices(any(), anyInt())).thenReturn(resultList);
 
         assertThat(new ResumeOnRebootServiceProvider(mMockContext,
                 mMockPackageManager).getServiceConnection()).isNotNull();
 
         verify(mMockPackageManager).queryIntentServices(mIntentArgumentCaptor.capture(),
-                eq(PackageManager.MATCH_SYSTEM_ONLY));
+                eq(PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_SERVICES));
         assertThat(mIntentArgumentCaptor.getValue().getAction()).isEqualTo(
                 ResumeOnRebootService.SERVICE_INTERFACE);
     }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
index 670bd81..fd4fe56 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
@@ -34,7 +34,6 @@
 import android.content.Context;
 import android.os.RemoteException;
 import android.security.GateKeeper;
-import android.security.keystore.AndroidKeyStoreSecretKey;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyProtection;
@@ -61,6 +60,7 @@
 import java.util.List;
 
 import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -586,7 +586,7 @@
         return (KeyProtection) mProtectionParameterCaptor.getValue();
     }
 
-    private AndroidKeyStoreSecretKey generateAndroidKeyStoreKey() throws Exception {
+    private SecretKey generateAndroidKeyStoreKey() throws Exception {
         KeyGenerator keyGenerator = KeyGenerator.getInstance(
                 KEY_ALGORITHM,
                 ANDROID_KEY_STORE_PROVIDER);
@@ -595,7 +595,7 @@
                 .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                 .build());
-        return (AndroidKeyStoreSecretKey) keyGenerator.generateKey();
+        return keyGenerator.generateKey();
     }
 
     class PlatformKeyManagerTestable extends PlatformKeyManager {
diff --git a/services/tests/servicestests/test-apps/SimpleServiceTestApp/OWNERS b/services/tests/servicestests/test-apps/SimpleServiceTestApp/OWNERS
new file mode 100644
index 0000000..72c0a9e
--- /dev/null
+++ b/services/tests/servicestests/test-apps/SimpleServiceTestApp/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/am/OWNERS
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 580513c..b022154 100755
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.app.Service;
 import android.content.ComponentName;
 import android.content.Intent;
@@ -1887,6 +1888,7 @@
     /** {@inheritDoc} */
     @Override
     public final IBinder onBind(Intent intent) {
+        onBindClient(intent);
         return mBinder;
     }
 
@@ -1897,6 +1899,13 @@
         return super.onUnbind(intent);
     }
 
+    /**
+     * Used for testing to let the test suite know when the connection service has been bound.
+     * @hide
+     */
+    @TestApi
+    public void onBindClient(@Nullable Intent intent) {
+    }
 
     /**
      * This can be used by telecom to either create a new outgoing conference call or attach
diff --git a/telephony/java/android/telephony/CarrierBandwidth.java b/telephony/java/android/telephony/CarrierBandwidth.java
index b153fef..9e1dee0 100644
--- a/telephony/java/android/telephony/CarrierBandwidth.java
+++ b/telephony/java/android/telephony/CarrierBandwidth.java
@@ -101,7 +101,7 @@
     }
 
     /**
-     * Retrieves the upstream bandwidth for the primary network in Kbps.  This always only refers to
+     * Retrieves the upstream bandwidth for the primary network in kbps.  This always only refers to
      * the estimated first hop transport bandwidth.
      * This will be {@link #INVALID} if the network is not connected
      *
@@ -112,7 +112,7 @@
     }
 
     /**
-     * Retrieves the downstream bandwidth for the primary network in Kbps.  This always only refers
+     * Retrieves the downstream bandwidth for the primary network in kbps.  This always only refers
      * to the estimated first hop transport bandwidth.
      * This will be {@link #INVALID} if the network is not connected
      *
@@ -123,7 +123,7 @@
     }
 
     /**
-     * Retrieves the upstream bandwidth for the secondary network in Kbps.  This always only refers
+     * Retrieves the upstream bandwidth for the secondary network in kbps.  This always only refers
      * to the estimated first hop transport bandwidth.
      * <p/>
      * This will be {@link #INVALID} if either are the case:
@@ -143,7 +143,7 @@
     }
 
     /**
-     * Retrieves the downstream bandwidth for the secondary network in Kbps.  This always only
+     * Retrieves the downstream bandwidth for the secondary network in kbps.  This always only
      * refers to the estimated first hop transport bandwidth.
      * <p/>
      * This will be {@link #INVALID} if either are the case:
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
index 1e5ce05..518fabc 100644
--- a/telephony/java/android/telephony/CellIdentity.java
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -37,7 +37,7 @@
 public abstract class CellIdentity implements Parcelable {
 
     /** @hide */
-    public static final int INVALID_CHANNEL_NUMBER = -1;
+    public static final int INVALID_CHANNEL_NUMBER = Integer.MAX_VALUE;
 
     /**
      * parameters for validation
diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java
index 9fb098e..dfe269c 100644
--- a/telephony/java/android/telephony/PhysicalChannelConfig.java
+++ b/telephony/java/android/telephony/PhysicalChannelConfig.java
@@ -50,7 +50,7 @@
     public static final int CONNECTION_UNKNOWN = -1;
 
     /** Channel number is unknown. */
-    public static final int CHANNEL_NUMBER_UNKNOWN = -1;
+    public static final int CHANNEL_NUMBER_UNKNOWN = Integer.MAX_VALUE;
 
     /** Physical Cell Id is unknown. */
     public static final int PHYSICAL_CELL_ID_UNKNOWN = -1;
diff --git a/telephony/java/android/telephony/TelephonyDisplayInfo.java b/telephony/java/android/telephony/TelephonyDisplayInfo.java
index 1fcb504..8778275 100644
--- a/telephony/java/android/telephony/TelephonyDisplayInfo.java
+++ b/telephony/java/android/telephony/TelephonyDisplayInfo.java
@@ -30,8 +30,8 @@
  * necessarily a precise or accurate representation of the current state and should be treated
  * accordingly.
  * To be notified of changes in TelephonyDisplayInfo, use
- * {@link TelephonyManager#registerPhoneStateListener} with a {@link PhoneStateListener}
- * that implements {@link PhoneStateListener.DisplayInfoChangedListener}.
+ * {@link TelephonyManager#registerTelephonyCallback} with a {@link TelephonyCallback}
+ * that implements {@link TelephonyCallback.DisplayInfoListener}.
  * Override the onDisplayInfoChanged() method to handle the broadcast.
  */
 public final class TelephonyDisplayInfo implements Parcelable {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index f12ff93..23dcee6 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -5580,28 +5580,25 @@
      * instability. If a process has registered too many listeners without unregistering them, it
      * may encounter an {@link IllegalStateException} when trying to register more listeners.
      *
-     * @param listener The {@link PhoneStateListener} object to register (or unregister)
-     * @param events The telephony state(s) of interest to the listener, as a bitwise-OR combination
-     *               of {@link PhoneStateListener} LISTEN_ flags.
-     * @deprecated Use {@link #registerPhoneStateListener(Executor, PhoneStateListener)}.
+     * @param listener The {@link PhoneStateListener} object to register
+     *                 (or unregister)
+     * @param events The telephony state(s) of interest to the listener,
+     *               as a bitwise-OR combination of {@link PhoneStateListener}
+     *               LISTEN_ flags.
+     * @deprecated Use {@link #registerTelephonyCallback(Executor, TelephonyCallback)}.
      */
     @Deprecated
     public void listen(PhoneStateListener listener, int events) {
-        if (!listener.isExecutorSet()) {
-            throw new IllegalStateException("PhoneStateListener should be created on a thread "
-                    + "with Looper.myLooper() != null");
-        }
-        boolean notifyNow = getITelephony() != null;
-        mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class);
-        if (mTelephonyRegistryMgr != null) {
-            if (events != PhoneStateListener.LISTEN_NONE) {
-                mTelephonyRegistryMgr.registerPhoneStateListenerWithEvents(mSubId,
-                        getOpPackageName(), getAttributionTag(), listener, events, notifyNow);
-            } else {
-                unregisterPhoneStateListener(listener);
-            }
+        if (mContext == null) return;
+        boolean notifyNow = (getITelephony() != null);
+        TelephonyRegistryManager telephonyRegistry =
+                (TelephonyRegistryManager)
+                        mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+        if (telephonyRegistry != null) {
+            telephonyRegistry.listenFromListener(mSubId, getOpPackageName(),
+                    getAttributionTag(), listener, events, notifyNow);
         } else {
-            throw new IllegalStateException("telephony service is null.");
+            Rlog.w(TAG, "telephony registry not ready.");
         }
     }
 
@@ -14123,12 +14120,11 @@
      * {@link #NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE}
      * </ol>
      * @return operation result.
-     * <p>Requires Permission:
-     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
      * @throws IllegalStateException if the Telephony process is not currently available.
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public @EnableNrDualConnectivityResult int setNrDualConnectivityState(
             @NrDualConnectivityState int nrDualConnectivityState) {
         try {
@@ -14548,6 +14544,75 @@
         return THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR;
     }
 
+    /**
+     * Registers a callback object to receive notification of changes in specified telephony states.
+     * <p>
+     * To register a callback, pass a {@link TelephonyCallback} which implements
+     * interfaces of events. For example,
+     * FakeServiceStateCallback extends {@link TelephonyCallback} implements
+     * {@link TelephonyCallback.ServiceStateListener}.
+     *
+     * At registration, and when a specified telephony state changes, the telephony manager invokes
+     * the appropriate callback method on the callback object and passes the current (updated)
+     * values.
+     * <p>
+     *
+     * If this TelephonyManager object has been created with {@link #createForSubscriptionId},
+     * applies to the given subId. Otherwise, applies to
+     * {@link SubscriptionManager#getDefaultSubscriptionId()}. To register events for multiple
+     * subIds, pass a separate callback object to each TelephonyManager object created with
+     * {@link #createForSubscriptionId}.
+     *
+     * Note: if you call this method while in the middle of a binder transaction, you <b>must</b>
+     * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A
+     * {@link SecurityException} will be thrown otherwise.
+     *
+     * This API should be used sparingly -- large numbers of callbacks will cause system
+     * instability. If a process has registered too many callbacks without unregistering them, it
+     * may encounter an {@link IllegalStateException} when trying to register more callbacks.
+     *
+     * @param executor The executor of where the callback will execute.
+     * @param callback The {@link TelephonyCallback} object to register.
+     */
+    public void registerTelephonyCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull TelephonyCallback callback) {
+        if (executor == null || callback == null) {
+            throw new IllegalArgumentException("TelephonyCallback and executor must be non-null");
+        }
+        mTelephonyRegistryMgr = (TelephonyRegistryManager)
+                mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+        if (mTelephonyRegistryMgr != null) {
+            mTelephonyRegistryMgr.registerTelephonyCallback(executor, mSubId, getOpPackageName(),
+                    getAttributionTag(), callback, getITelephony() != null);
+        } else {
+            throw new IllegalStateException("telephony service is null.");
+        }
+    }
+
+    /**
+     * Unregister an existing {@link TelephonyCallback}.
+     *
+     * @param callback The {@link TelephonyCallback} object to unregister.
+     */
+    public void unregisterTelephonyCallback(@NonNull TelephonyCallback callback) {
+
+        if (mContext == null) {
+            throw new IllegalStateException("telephony service is null.");
+        }
+
+        if (callback.callback == null) {
+            return;
+        }
+
+        mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class);
+        if (mTelephonyRegistryMgr != null) {
+            mTelephonyRegistryMgr.unregisterTelephonyCallback(mSubId, getOpPackageName(),
+                    getAttributionTag(), callback, getITelephony() != null);
+        } else {
+            throw new IllegalStateException("telephony service is null.");
+        }
+    }
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"GBA_FAILURE_REASON_"}, value = {
@@ -14724,73 +14789,6 @@
     }
 
     /**
-     * Registers a listener object to receive notification of changes in specified telephony states.
-     * <p>
-     * To register a listener, pass a {@link PhoneStateListener} which implements
-     * interfaces of events. For example,
-     * FakeServiceStateChangedListener extends {@link PhoneStateListener} implements
-     * {@link PhoneStateListener.ServiceStateChangedListener}.
-     *
-     * At registration, and when a specified telephony state changes, the telephony manager invokes
-     * the appropriate callback method on the listener object and passes the current (updated)
-     * values.
-     * <p>
-     *
-     * If this TelephonyManager object has been created with {@link #createForSubscriptionId},
-     * applies to the given subId. Otherwise, applies to
-     * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}. To listen events for multiple subIds,
-     * pass a separate listener object to each TelephonyManager object created with
-     * {@link #createForSubscriptionId}. Only {@link PhoneStateListener.CallStateChangedListener}
-     * can be used to receive changes for all subIds through
-     * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}.
-     *
-     * Note: if you call this method while in the middle of a binder transaction, you <b>must</b>
-     * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A
-     * {@link SecurityException} will be thrown otherwise.
-     *
-     * This API should be used sparingly -- large numbers of listeners will cause system
-     * instability. If a process has registered too many listeners without unregistering them, it
-     * may encounter an {@link IllegalStateException} when trying to register more listeners.
-     *
-     * @param executor The executor of where the callback will execute.
-     * @param listener The {@link PhoneStateListener} object to register.
-     */
-    public void registerPhoneStateListener(@NonNull @CallbackExecutor Executor executor,
-            @NonNull PhoneStateListener listener) {
-        if (executor == null || listener == null) {
-            throw new IllegalArgumentException("PhoneStateListener and executor must be non-null");
-        }
-        mTelephonyRegistryMgr = (TelephonyRegistryManager)
-                mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
-        if (mTelephonyRegistryMgr != null) {
-            mTelephonyRegistryMgr.registerPhoneStateListener(executor, mSubId,
-                    getOpPackageName(), getAttributionTag(), listener, getITelephony() != null);
-        } else {
-            throw new IllegalStateException("telephony service is null.");
-        }
-    }
-
-    /**
-     * Unregister an existing {@link PhoneStateListener}.
-     *
-     * @param listener The {@link PhoneStateListener} object to unregister.
-     */
-    public void unregisterPhoneStateListener(@NonNull PhoneStateListener listener) {
-
-        if (mContext == null) {
-            throw new IllegalStateException("telephony service is null.");
-        }
-
-        mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class);
-        if (mTelephonyRegistryMgr != null) {
-            mTelephonyRegistryMgr.unregisterPhoneStateListener(mSubId, getOpPackageName(),
-                    getAttributionTag(), listener, getITelephony() != null);
-        } else {
-            throw new IllegalStateException("telephony service is null.");
-        }
-    }
-
-    /**
      * The network type is valid or not.
      *
      * @param networkType The network type {@link NetworkType}.
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index a9ccb6a..aa9145b 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -1006,7 +1006,8 @@
          * server) or other operator defined triggers. If RCS provisioning is already
          * completed at the time of callback registration, then this method shall be
          * invoked with the current configuration
-         * @param configXml The RCS configurationXML received OTA.
+         * @param configXml The RCS configuration XML received by OTA. It is defined
+         * by GSMA RCC.07.
          */
         public void onConfigurationChanged(@NonNull byte[] configXml) {}
 
@@ -1373,7 +1374,9 @@
      * provisioning is done using autoconfiguration, then these parameters shall be
      * sent in the HTTP get request to fetch the RCS provisioning. RCS client
      * configuration must be provided by the application before registering for the
-     * provisioning status events {@link #registerRcsProvisioningChangedCallback}
+     * provisioning status events {@link #registerRcsProvisioningCallback()}
+     * When the IMS/RCS service receives the RCS client configuration, it will detect
+     * the change in the configuration, and trigger the auto-configuration as needed.
      * @param rcc RCS client configuration {@link RcsClientConfiguration}
      */
     @RequiresPermission(Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION)
@@ -1440,7 +1443,7 @@
     *
     * @param executor The {@link Executor} to call the callback methods on
     * @param callback The rcs provisioning callback to be registered.
-    * @see #unregisterRcsProvisioningChangedCallback(RcsProvisioningCallback)
+    * @see #unregisterRcsProvisioningCallback(RcsProvisioningCallback)
     * @see SubscriptionManager.OnSubscriptionsChangedListener
     * @throws IllegalArgumentException if the subscription associated with this
     * callback is not active (SIM is not inserted, ESIM inactive) or the
@@ -1456,12 +1459,12 @@
     */
     @RequiresPermission(anyOf = {Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
             Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION})
-    public void registerRcsProvisioningChangedCallback(
+    public void registerRcsProvisioningCallback(
             @NonNull @CallbackExecutor Executor executor,
             @NonNull RcsProvisioningCallback callback) throws ImsException {
         callback.setExecutor(executor);
         try {
-            getITelephony().registerRcsProvisioningChangedCallback(mSubId, callback.getBinder());
+            getITelephony().registerRcsProvisioningCallback(mSubId, callback.getBinder());
         } catch (ServiceSpecificException e) {
             throw new ImsException(e.getMessage(), e.errorCode);
         } catch (RemoteException | IllegalStateException e) {
@@ -1487,16 +1490,16 @@
      *
      * @param callback The existing {@link RcsProvisioningCallback} to be
      * removed.
-     * @see #registerRcsProvisioningChangedCallback
-     * @throws IllegalArgumentException if the subscription associated with this callback is
-     * invalid.
+     * @see #registerRcsProvisioningCallback(Executor, RcsProvisioningCallback)
+     * @throws IllegalArgumentException if the subscription associated with
+     * this callback is invalid.
      */
     @RequiresPermission(anyOf = {Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
             Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION})
-    public void unregisterRcsProvisioningChangedCallback(
+    public void unregisterRcsProvisioningCallback(
             @NonNull RcsProvisioningCallback callback) {
         try {
-            getITelephony().unregisterRcsProvisioningChangedCallback(
+            getITelephony().unregisterRcsProvisioningCallback(
                     mSubId, callback.getBinder());
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
@@ -1506,6 +1509,14 @@
     /**
      * Reconfiguration triggered by the RCS application. Most likely cause
      * is the 403 forbidden to a HTTP request.
+     *
+     * <p>When this api is called, the RCS configuration for the associated
+     * subscription will be removed, and the application which has registered
+     * {@link RcsProvisioningCallback} may expect to receive
+     * {@link RcsProvisioningCallback#onConfigurationReset}, then
+     * {@link RcsProvisioningCallback#onConfigurationChanged} when the new
+     * RCS configuration is received and notified by
+     * {@link #notifyRcsAutoConfigurationReceived}
      */
     @RequiresPermission(Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION)
     public void triggerRcsReconfiguration() {
diff --git a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
index 5eb75e7..cd1f4c5 100644
--- a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
+++ b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
@@ -23,9 +23,14 @@
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -38,6 +43,8 @@
 @SystemApi
 public final class RcsContactPresenceTuple implements Parcelable {
 
+    private static final String LOG_TAG = "RcsContactPresenceTuple";
+
     /**
      * The service ID used to indicate that MMTEL service is available.
      * <p>
@@ -353,7 +360,8 @@
         }
 
         /**
-         * The optional SIP Contact URI associated with the PIDF tuple element.
+         * The optional SIP Contact URI associated with the PIDF tuple element if the network
+         * expects the user to use the URI instead of the contact URI to contact it.
          */
         public @NonNull Builder setContactUri(@NonNull Uri contactUri) {
             mPresenceTuple.mContactUri = contactUri;
@@ -364,8 +372,24 @@
          * The optional timestamp indicating the data and time of the status change of this tuple.
          * Per RFC3863 section 4.1.7, the timestamp is formatted as an IMPP datetime format
          * string per RFC3339.
+         * @hide
          */
         public @NonNull Builder setTimestamp(@NonNull String timestamp) {
+            try {
+                mPresenceTuple.mTimestamp =
+                        DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(timestamp, Instant::from);
+            } catch (DateTimeParseException e) {
+                Log.d(LOG_TAG, "Parse timestamp failed " + e);
+            }
+            return this;
+        }
+
+        /**
+         * The optional timestamp indicating the data and time of the status change of this tuple.
+         * Per RFC3863 section 4.1.7, the timestamp is formatted as an IMPP datetime format
+         * string per RFC3339.
+         */
+        public @NonNull Builder setTime(@NonNull Instant timestamp) {
             mPresenceTuple.mTimestamp = timestamp;
             return this;
         }
@@ -397,7 +421,7 @@
     }
 
     private Uri mContactUri;
-    private String mTimestamp;
+    private Instant mTimestamp;
     private @BasicStatus String mStatus;
 
     // The service information in the service-description element.
@@ -416,7 +440,7 @@
 
     private RcsContactPresenceTuple(Parcel in) {
         mContactUri = in.readParcelable(Uri.class.getClassLoader());
-        mTimestamp = in.readString();
+        mTimestamp = convertStringFormatTimeToInstant(in.readString());
         mStatus = in.readString();
         mServiceId = in.readString();
         mServiceVersion = in.readString();
@@ -427,7 +451,7 @@
     @Override
     public void writeToParcel(@NonNull Parcel out, int flags) {
         out.writeParcelable(mContactUri, flags);
-        out.writeString(mTimestamp);
+        out.writeString(convertInstantToStringFormat(mTimestamp));
         out.writeString(mStatus);
         out.writeString(mServiceId);
         out.writeString(mServiceVersion);
@@ -453,6 +477,26 @@
                 }
             };
 
+    // Convert the Instant to the string format
+    private String convertInstantToStringFormat(Instant instant) {
+        if (instant == null) {
+            return "";
+        }
+        return instant.toString();
+    }
+
+    // Convert the time string format to Instant
+    private @Nullable Instant convertStringFormatTimeToInstant(String timestamp) {
+        if (TextUtils.isEmpty(timestamp)) {
+            return null;
+        }
+        try {
+            return DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(timestamp, Instant::from);
+        } catch (DateTimeParseException e) {
+            return null;
+        }
+    }
+
     /** @return the status of the tuple element. */
     public @NonNull @BasicStatus String getStatus() {
         return mStatus;
@@ -473,8 +517,16 @@
         return mContactUri;
     }
 
-    /** @return the timestamp element contained in the tuple if it exists */
+    /**
+     * @return the timestamp element contained in the tuple if it exists
+     * @hide
+     */
     public @Nullable String getTimestamp() {
+        return (mTimestamp == null) ? null : mTimestamp.toString();
+    }
+
+    /** @return the timestamp element contained in the tuple if it exists */
+    public @Nullable Instant getTime() {
         return mTimestamp;
     }
 
diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
index fe85502..b28dc27 100644
--- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java
+++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
@@ -339,6 +339,7 @@
     }
 
     /**
+     * Retrieve the contact URI requested by the applications.
      * @return the URI representing the contact associated with the capabilities.
      */
     public @NonNull Uri getContactUri() {
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index ce8bd7d..815c08d 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -36,6 +36,8 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -430,13 +432,15 @@
 
         /**
          * The pending request has completed successfully due to all requested contacts information
-         * being delivered.
+         * being delivered. The callback {@link #onCapabilitiesReceived(List)}
+         * for each contacts is required to be called before {@link #onComplete} is called.
          */
         void onComplete();
 
         /**
          * The pending request has resulted in an error and may need to be retried, depending on the
-         * error code.
+         * error code. The callback {@link #onCapabilitiesReceived(List)}
+         * for each contacts is required to be called before {@link #onError} is called.
          * @param errorCode The reason for the framework being unable to process the request.
          * @param retryIntervalMillis The time in milliseconds the requesting application should
          * wait before retrying, if non-zero.
@@ -483,7 +487,6 @@
      * becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
      * @hide
      */
-    @SystemApi
     @RequiresPermission(allOf = {Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE,
             Manifest.permission.READ_CONTACTS})
     public void requestCapabilities(@NonNull List<Uri> contactNumbers,
@@ -549,6 +552,94 @@
     }
 
     /**
+     * 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, 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 contactNumbers A list of numbers that the capabilities are being requested for.
+     * @param executor The executor that will be used when the request is completed and the
+     *         {@link CapabilitiesCallback} is called.
+     * @param c A one-time callback for when the request for capabilities completes or there is an
+     *         error processing the request.
+     * @throws ImsException if the subscription associated with this instance of
+     * {@link RcsUceAdapter} is valid, but the ImsService associated with the subscription is not
+     * available. This can happen if the ImsService has crashed, for example, or if the subscription
+     * becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(allOf = {Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE,
+            Manifest.permission.READ_CONTACTS})
+    public void requestCapabilities(@NonNull Collection<Uri> contactNumbers,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull CapabilitiesCallback c) throws ImsException {
+        if (c == null) {
+            throw new IllegalArgumentException("Must include a non-null CapabilitiesCallback.");
+        }
+        if (executor == null) {
+            throw new IllegalArgumentException("Must include a non-null Executor.");
+        }
+        if (contactNumbers == null) {
+            throw new IllegalArgumentException("Must include non-null contact number list.");
+        }
+
+        IImsRcsController imsRcsController = getIImsRcsController();
+        if (imsRcsController == null) {
+            Log.e(TAG, "requestCapabilities: IImsRcsController is null");
+            throw new ImsException("Can not 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, long retryAfterMilliseconds) {
+                final long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() -> c.onError(errorCode, retryAfterMilliseconds));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
+            }
+        };
+
+        try {
+            imsRcsController.requestCapabilities(mSubId, mContext.getOpPackageName(),
+                    mContext.getAttributionTag(), new ArrayList(contactNumbers), internalCallback);
+        } catch (ServiceSpecificException e) {
+            throw new ImsException(e.toString(), e.errorCode);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling IImsRcsController#requestCapabilities", e);
+            throw new ImsException("Remote IMS Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+    }
+
+    /**
      * Ignore the device cache and perform a capability discovery for one contact, also called
      * "availability fetch."
      * <p>
@@ -569,6 +660,10 @@
      * {@link CapabilitiesCallback} is called.
      * @param c A one-time callback for when the request for capabilities completes or there is
      * an error processing the request.
+     * @throws ImsException if the subscription associated with this instance of
+     * {@link RcsUceAdapter} is valid, but the ImsService associated with the subscription is not
+     * available. This can happen if the ImsService has crashed, for example, or if the subscription
+     * becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
      * @hide
      */
     @SystemApi
diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
index 908869b..00c9168 100644
--- a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
@@ -31,6 +31,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.Executor;
 
@@ -241,7 +242,7 @@
 
         /**
          * Notify the framework of the response to the SUBSCRIBE request from
-         * {@link #subscribeForCapabilities(List, SubscribeResponseCallback)}.
+         * {@link #subscribeForCapabilities(Collection, SubscribeResponseCallback)}.
          * <p>
          * If the carrier network responds to the SUBSCRIBE request with a 2XX response, then the
          * framework will expect the IMS stack to call {@link #onNotifyCapabilitiesUpdate},
@@ -266,7 +267,7 @@
 
         /**
          * Notify the framework  of the response to the SUBSCRIBE request from
-         * {@link #subscribeForCapabilities(List, SubscribeResponseCallback)} that also
+         * {@link #subscribeForCapabilities(Collection, SubscribeResponseCallback)} that also
          * includes a reason provided in the “reason” header. See RFC3326 for more
          * information.
          *
@@ -388,6 +389,7 @@
      * @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.
+     * @hide
      */
     // executor used is defined in the constructor.
     @SuppressLint("ExecutorRegistration")
@@ -403,6 +405,40 @@
     }
 
     /**
+     * The user capabilities of one or multiple contacts have been requested by the framework.
+     * <p>
+     * The implementer must follow up this call with an
+     * {@link SubscribeResponseCallback#onCommandError} call to indicate this operation has failed.
+     * The response from the network to the SUBSCRIBE request must be sent back to the framework
+     * using {@link SubscribeResponseCallback#onNetworkResponse(int, String)}.
+     * As NOTIFY requests come in from the network, the requested contact’s capabilities should be
+     * sent back to the framework using
+     * {@link SubscribeResponseCallback#onNotifyCapabilitiesUpdate(List<String>}) and
+     * {@link SubscribeResponseCallback#onResourceTerminated(List<Pair<Uri, String>>)}
+     * should be called with the presence information for the contacts specified.
+     * <p>
+     * Once the subscription is terminated,
+     * {@link SubscribeResponseCallback#onTerminated(String, long)} must be called for the
+     * framework to finish listening for NOTIFY responses.
+     *
+     * @param uris A {@link Collection} of the {@link Uri}s that the framework is requesting the
+     * UCE capabilities for.
+     * @param cb The callback of the subscribe request.
+     */
+    // executor used is defined in the constructor.
+    @SuppressLint("ExecutorRegistration")
+    public void subscribeForCapabilities(@NonNull Collection<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
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 6f33a88..f74484b 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2283,13 +2283,12 @@
     /**
      * Register RCS provisioning callback.
      */
-    void registerRcsProvisioningChangedCallback(int subId,
-            IRcsConfigCallback callback);
+    void registerRcsProvisioningCallback(int subId, IRcsConfigCallback callback);
 
     /**
      * Unregister RCS provisioning callback.
      */
-    void unregisterRcsProvisioningChangedCallback(int subId, IRcsConfigCallback callback);
+    void unregisterRcsProvisioningCallback(int subId, IRcsConfigCallback callback);
 
     /**
      * trigger RCS reconfiguration.
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 76243a5..3eda748 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -522,8 +522,8 @@
     int RIL_REQUEST_GET_SYSTEM_SELECTION_CHANNELS = 219;
     int RIL_REQUEST_GET_HAL_DEVICE_CAPABILITIES = 220;
     int RIL_REQUEST_SET_DATA_THROTTLING = 221;
-    int RIL_REQUEST_SET_ALLOWED_NETWORK_TYPE_BITMAP = 222;
-    int RIL_REQUEST_GET_ALLOWED_NETWORK_TYPE_BITMAP = 223;
+    int RIL_REQUEST_SET_ALLOWED_NETWORK_TYPES_BITMAP = 222;
+    int RIL_REQUEST_GET_ALLOWED_NETWORK_TYPES_BITMAP = 223;
 
     /* Responses begin */
     int RIL_RESPONSE_ACKNOWLEDGEMENT = 800;
diff --git a/tests/net/TEST_MAPPING b/tests/net/TEST_MAPPING
index 89fc6ea..d659688 100644
--- a/tests/net/TEST_MAPPING
+++ b/tests/net/TEST_MAPPING
@@ -9,6 +9,23 @@
       "name": "FrameworksNetDeflakeTest"
     }
   ],
+  "auto-postsubmit": [
+    // Test tag for automotive targets. These are only running in postsubmit so as to harden the
+    // automotive targets to avoid introducing additional test flake and build time. The plan for
+    // presubmit testing for auto is to augment the existing tests to cover auto use cases as well.
+    // Additionally, this tag is used in targeted test suites to limit resource usage on the test
+    // infra during the hardening phase.
+    // TODO: this tag to be removed once the above is no longer an issue.
+    {
+      "name": "FrameworksNetTests"
+    },
+    {
+      "name": "FrameworksNetIntegrationTests"
+    },
+    {
+      "name": "FrameworksNetDeflakeTest"
+    }
+  ],
   "imports": [
     {
       "path": "cts/tests/tests/net"
diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
index e1da3d0..01d8186 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -64,6 +64,7 @@
     private final HandlerThread mHandlerThread;
     private final Context mContext;
     private final String mLogTag;
+    private final NetworkAgentConfig mNetworkAgentConfig;
 
     private final ConditionVariable mDisconnected = new ConditionVariable();
     private final ConditionVariable mPreventReconnectReceived = new ConditionVariable();
@@ -115,13 +116,19 @@
         mHandlerThread = new HandlerThread(mLogTag);
         mHandlerThread.start();
 
-        mNetworkAgent = makeNetworkAgent(linkProperties, type, typeName);
+        // extraInfo is set to "" by default in NetworkAgentConfig.
+        final String extraInfo = (transport == TRANSPORT_CELLULAR) ? "internet.apn" : "";
+        mNetworkAgentConfig = new NetworkAgentConfig.Builder()
+                .setLegacyType(type)
+                .setLegacyTypeName(typeName)
+                .setLegacyExtraInfo(extraInfo)
+                .build();
+        mNetworkAgent = makeNetworkAgent(linkProperties, mNetworkAgentConfig);
     }
 
     protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties,
-            final int type, final String typeName)
-            throws Exception {
-        return new InstrumentedNetworkAgent(this, linkProperties, type, typeName);
+            final NetworkAgentConfig nac) throws Exception {
+        return new InstrumentedNetworkAgent(this, linkProperties, nac);
     }
 
     public static class InstrumentedNetworkAgent extends NetworkAgent {
@@ -129,11 +136,9 @@
         private static final String PROVIDER_NAME = "InstrumentedNetworkAgentProvider";
 
         public InstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp,
-                final int type, final String typeName) {
+                NetworkAgentConfig nac) {
             super(wrapper.mContext, wrapper.mHandlerThread.getLooper(), wrapper.mLogTag,
-                    wrapper.mNetworkCapabilities, lp, wrapper.mScore,
-                    new NetworkAgentConfig.Builder()
-                            .setLegacyType(type).setLegacyTypeName(typeName).build(),
+                    wrapper.mNetworkCapabilities, lp, wrapper.mScore, nac,
                     new NetworkProvider(wrapper.mContext, wrapper.mHandlerThread.getLooper(),
                             PROVIDER_NAME));
             mWrapper = wrapper;
@@ -301,6 +306,14 @@
         return mNetworkCapabilities;
     }
 
+    public int getLegacyType() {
+        return mNetworkAgentConfig.getLegacyType();
+    }
+
+    public String getExtraInfo() {
+        return mNetworkAgentConfig.getLegacyExtraInfo();
+    }
+
     public @NonNull ArrayTrackRecord<CallbackType>.ReadHead getCallbackHistory() {
         return mCallbackHistory;
     }
diff --git a/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt b/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt
index 9b0cfa9..c1315f6 100644
--- a/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt
+++ b/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt
@@ -21,7 +21,7 @@
 import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER
 import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE
 import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY
-import android.net.util.MultinetworkPolicyTracker.ActiveDataSubscriptionIdChangedListener
+import android.net.util.MultinetworkPolicyTracker.ActiveDataSubscriptionIdListener
 import android.provider.Settings
 import android.provider.Settings.Global.NETWORK_AVOID_BAD_WIFI
 import android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE
@@ -120,9 +120,9 @@
                 MULTIPATH_PREFERENCE_PERFORMANCE.toString())
 
         val listenerCaptor = ArgumentCaptor.forClass(
-                ActiveDataSubscriptionIdChangedListener::class.java)
+                ActiveDataSubscriptionIdListener::class.java)
         verify(telephonyManager, times(1))
-                .registerPhoneStateListener(any(), listenerCaptor.capture())
+                .registerTelephonyCallback(any(), listenerCaptor.capture())
         val listener = listenerCaptor.value
         listener.onActiveDataSubscriptionIdChanged(testSubId)
 
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 2546580..15a7b91 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -72,6 +72,7 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
@@ -265,7 +266,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.internal.app.IBatteryStats;
 import com.android.internal.net.VpnConfig;
 import com.android.internal.net.VpnProfile;
 import com.android.internal.util.ArrayUtils;
@@ -427,7 +427,6 @@
     @Mock DeviceIdleInternal mDeviceIdleInternal;
     @Mock INetworkManagementService mNetworkManagementService;
     @Mock NetworkStatsManager mStatsManager;
-    @Mock IBatteryStats mBatteryStatsService;
     @Mock IDnsResolver mMockDnsResolver;
     @Mock INetd mMockNetd;
     @Mock NetworkStackClient mNetworkStack;
@@ -719,7 +718,7 @@
 
         @Override
         protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties,
-                final int type, final String typeName) throws Exception {
+                NetworkAgentConfig nac) throws Exception {
             mNetworkMonitor = mock(INetworkMonitor.class);
 
             final Answer validateAnswer = inv -> {
@@ -738,8 +737,8 @@
                     any() /* name */,
                     nmCbCaptor.capture());
 
-            final InstrumentedNetworkAgent na = new InstrumentedNetworkAgent(this, linkProperties,
-                    type, typeName) {
+            final InstrumentedNetworkAgent na =
+                    new InstrumentedNetworkAgent(this, linkProperties, nac) {
                 @Override
                 public void networkStatus(int status, String redirectUrl) {
                     mRedirectUrl = redirectUrl;
@@ -1526,12 +1525,12 @@
         doReturn(mSystemProperties).when(deps).getSystemProperties();
         doReturn(mock(ProxyTracker.class)).when(deps).makeProxyTracker(any(), any());
         doReturn(true).when(deps).queryUserAccess(anyInt(), anyInt());
-        doReturn(mBatteryStatsService).when(deps).getBatteryStatsService();
         doAnswer(inv -> {
             mPolicyTracker = new WrappedMultinetworkPolicyTracker(
                     inv.getArgument(0), inv.getArgument(1), inv.getArgument(2));
             return mPolicyTracker;
         }).when(deps).makeMultinetworkPolicyTracker(any(), any(), any());
+        doReturn(true).when(deps).getCellular464XlatEnabled();
 
         return deps;
     }
@@ -1742,11 +1741,29 @@
         return expected;
     }
 
+    private boolean extraInfoInBroadcastHasExpectedNullness(NetworkInfo ni) {
+        final DetailedState state = ni.getDetailedState();
+        if (state == DetailedState.CONNECTED && ni.getExtraInfo() == null) return false;
+        // Expect a null extraInfo if the network is CONNECTING, because a CONNECTIVITY_ACTION
+        // broadcast with a state of CONNECTING only happens due to legacy VPN lockdown, which also
+        // nulls out extraInfo.
+        if (state == DetailedState.CONNECTING && ni.getExtraInfo() != null) return false;
+        // Can't make any assertions about DISCONNECTED broadcasts. When a network actually
+        // disconnects, disconnectAndDestroyNetwork sets its state to DISCONNECTED and its extraInfo
+        // to null. But if the DISCONNECTED broadcast is just simulated by LegacyTypeTracker due to
+        // a network switch, extraInfo will likely be populated.
+        // This is likely a bug in CS, but likely not one we can fix without impacting apps.
+        return true;
+    }
+
     private ExpectedBroadcast expectConnectivityAction(int type, NetworkInfo.DetailedState state) {
-        return registerConnectivityBroadcastThat(1, intent ->
-                type == intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) && state.equals(
-                        ((NetworkInfo) intent.getParcelableExtra(EXTRA_NETWORK_INFO))
-                                .getDetailedState()));
+        return registerConnectivityBroadcastThat(1, intent -> {
+            final int actualType = intent.getIntExtra(EXTRA_NETWORK_TYPE, -1);
+            final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO);
+            return type == actualType
+                    && state == ni.getDetailedState()
+                    && extraInfoInBroadcastHasExpectedNullness(ni);
+        });
     }
 
     @Test
@@ -5574,7 +5591,7 @@
         reset(mStatsManager);
 
         // Temp metered change shouldn't update ifaces
-        mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
+        mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED);
         waitForIdle();
         verify(mStatsManager, never()).notifyNetworkStatus(eq(Arrays.asList(onlyCell)),
                 any(List.class), eq(MOBILE_IFNAME), any(List.class));
@@ -7184,12 +7201,14 @@
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+        assertExtraInfoFromCmPresent(mCellNetworkAgent);
 
         setUidRulesChanged(RULE_REJECT_ALL);
         cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+        assertExtraInfoFromCmBlocked(mCellNetworkAgent);
 
         // ConnectivityService should cache it not to invoke the callback again.
         setUidRulesChanged(RULE_REJECT_METERED);
@@ -7200,12 +7219,14 @@
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+        assertExtraInfoFromCmPresent(mCellNetworkAgent);
 
         setUidRulesChanged(RULE_REJECT_METERED);
         cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+        assertExtraInfoFromCmBlocked(mCellNetworkAgent);
 
         // Restrict the network based on UID rule and NOT_METERED capability change.
         mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
@@ -7214,6 +7235,7 @@
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+        assertExtraInfoFromCmPresent(mCellNetworkAgent);
 
         mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
         cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED,
@@ -7222,12 +7244,14 @@
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+        assertExtraInfoFromCmBlocked(mCellNetworkAgent);
 
         setUidRulesChanged(RULE_ALLOW_METERED);
         cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+        assertExtraInfoFromCmPresent(mCellNetworkAgent);
 
         setUidRulesChanged(RULE_NONE);
         cellNetworkCallback.assertNoCallback();
@@ -7238,6 +7262,7 @@
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+        assertExtraInfoFromCmBlocked(mCellNetworkAgent);
         setRestrictBackgroundChanged(true);
         cellNetworkCallback.assertNoCallback();
 
@@ -7245,12 +7270,14 @@
         cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+        assertExtraInfoFromCmPresent(mCellNetworkAgent);
 
         setRestrictBackgroundChanged(false);
         cellNetworkCallback.assertNoCallback();
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+        assertExtraInfoFromCmPresent(mCellNetworkAgent);
 
         mCm.unregisterNetworkCallback(cellNetworkCallback);
     }
@@ -7309,6 +7336,15 @@
         assertNotNull(ni);
         assertEquals(type, ni.getType());
         assertEquals(ConnectivityManager.getNetworkTypeName(type), state, ni.getDetailedState());
+        if (state == DetailedState.CONNECTED || state == DetailedState.SUSPENDED) {
+            assertNotNull(ni.getExtraInfo());
+        } else {
+            // Technically speaking, a network that's in CONNECTING state will generally have a
+            // non-null extraInfo. This doesn't actually happen in this test because it never calls
+            // a legacy API while a network is connecting. When a network is in CONNECTING state
+            // because of legacy lockdown VPN, its extraInfo is always null.
+            assertNull(ni.getExtraInfo());
+        }
     }
 
     private void assertActiveNetworkInfo(int type, DetailedState state) {
@@ -7318,6 +7354,26 @@
         checkNetworkInfo(mCm.getNetworkInfo(type), type, state);
     }
 
+    private void assertExtraInfoFromCm(TestNetworkAgentWrapper network, boolean present) {
+        final NetworkInfo niForNetwork = mCm.getNetworkInfo(network.getNetwork());
+        final NetworkInfo niForType = mCm.getNetworkInfo(network.getLegacyType());
+        if (present) {
+            assertEquals(network.getExtraInfo(), niForNetwork.getExtraInfo());
+            assertEquals(network.getExtraInfo(), niForType.getExtraInfo());
+        } else {
+            assertNull(niForNetwork.getExtraInfo());
+            assertNull(niForType.getExtraInfo());
+        }
+    }
+
+    private void assertExtraInfoFromCmBlocked(TestNetworkAgentWrapper network) {
+        assertExtraInfoFromCm(network, false);
+    }
+
+    private void assertExtraInfoFromCmPresent(TestNetworkAgentWrapper network) {
+        assertExtraInfoFromCm(network, true);
+    }
+
     // Checks that each of the |agents| receive a blocked status change callback with the specified
     // |blocked| value, in any order. This is needed because when an event affects multiple
     // networks, ConnectivityService does not guarantee the order in which callbacks are fired.
@@ -7632,6 +7688,7 @@
         assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
         assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
         assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED);
+        assertExtraInfoFromCmBlocked(mCellNetworkAgent);
 
         // TODO: it would be nice if we could simply rely on the production code here, and have
         // LockdownVpnTracker start the VPN, have the VPN code register its NetworkAgent with
@@ -7660,6 +7717,7 @@
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED);
         assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED);
+        assertExtraInfoFromCmPresent(mCellNetworkAgent);
         assertTrue(vpnNc.hasTransport(TRANSPORT_VPN));
         assertTrue(vpnNc.hasTransport(TRANSPORT_CELLULAR));
         assertFalse(vpnNc.hasTransport(TRANSPORT_WIFI));
@@ -7702,6 +7760,7 @@
         assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
         assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
         assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED);
+        assertExtraInfoFromCmBlocked(mWiFiNetworkAgent);
 
         // The VPN comes up again on wifi.
         b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED);
@@ -7716,6 +7775,7 @@
         assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED);
         assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED);
+        assertExtraInfoFromCmPresent(mWiFiNetworkAgent);
         vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
         assertTrue(vpnNc.hasTransport(TRANSPORT_VPN));
         assertTrue(vpnNc.hasTransport(TRANSPORT_WIFI));
@@ -7732,6 +7792,7 @@
         assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED);
         assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED);
+        assertExtraInfoFromCmPresent(mWiFiNetworkAgent);
 
         b1 = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED);
         mWiFiNetworkAgent.disconnect();
@@ -7808,18 +7869,18 @@
         mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
         mCellNetworkAgent.connect(true);
         waitForIdle();
-        verify(mBatteryStatsService).noteNetworkInterfaceForTransports(cellLp.getInterfaceName(),
+        verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext,
+                cellLp.getInterfaceName(),
                 new int[] { TRANSPORT_CELLULAR });
-        reset(mBatteryStatsService);
 
         final LinkProperties wifiLp = new LinkProperties();
         wifiLp.setInterfaceName("wifi0");
         mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp);
         mWiFiNetworkAgent.connect(true);
         waitForIdle();
-        verify(mBatteryStatsService).noteNetworkInterfaceForTransports(wifiLp.getInterfaceName(),
+        verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext,
+                wifiLp.getInterfaceName(),
                 new int[] { TRANSPORT_WIFI });
-        reset(mBatteryStatsService);
 
         mCellNetworkAgent.disconnect();
         mWiFiNetworkAgent.disconnect();
@@ -7828,7 +7889,8 @@
         mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
         mCellNetworkAgent.connect(true);
         waitForIdle();
-        verify(mBatteryStatsService).noteNetworkInterfaceForTransports(cellLp.getInterfaceName(),
+        verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext,
+                cellLp.getInterfaceName(),
                 new int[] { TRANSPORT_CELLULAR });
         mCellNetworkAgent.disconnect();
     }
@@ -7901,7 +7963,6 @@
         mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
         reset(mMockDnsResolver);
         reset(mMockNetd);
-        reset(mBatteryStatsService);
 
         // Connect with ipv6 link properties. Expect prefix discovery to be started.
         mCellNetworkAgent.connect(true);
@@ -7912,7 +7973,8 @@
         assertRoutesAdded(cellNetId, ipv6Subnet, defaultRoute);
         verify(mMockDnsResolver, times(1)).createNetworkCache(eq(cellNetId));
         verify(mMockNetd, times(1)).networkAddInterface(cellNetId, MOBILE_IFNAME);
-        verify(mBatteryStatsService).noteNetworkInterfaceForTransports(cellLp.getInterfaceName(),
+        verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext,
+                cellLp.getInterfaceName(),
                 new int[] { TRANSPORT_CELLULAR });
 
         networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
@@ -7933,8 +7995,8 @@
         // Make sure BatteryStats was not told about any v4- interfaces, as none should have
         // come online yet.
         waitForIdle();
-        verify(mBatteryStatsService, never()).noteNetworkInterfaceForTransports(startsWith("v4-"),
-                any());
+        verify(mDeps, never())
+                .reportNetworkInterfaceForTransports(eq(mServiceContext), startsWith("v4-"), any());
 
         verifyNoMoreInteractions(mMockNetd);
         verifyNoMoreInteractions(mMockDnsResolver);
@@ -7986,8 +8048,9 @@
         assertTrue(ArrayUtils.contains(resolvrParams.servers, "8.8.8.8"));
 
         for (final LinkProperties stackedLp : stackedLpsAfterChange) {
-            verify(mBatteryStatsService).noteNetworkInterfaceForTransports(
-                    stackedLp.getInterfaceName(), new int[] { TRANSPORT_CELLULAR });
+            verify(mDeps).reportNetworkInterfaceForTransports(
+                    mServiceContext, stackedLp.getInterfaceName(),
+                    new int[] { TRANSPORT_CELLULAR });
         }
         reset(mMockNetd);
         when(mMockNetd.interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME))
@@ -8262,6 +8325,45 @@
     }
 
     @Test
+    public void testWith464XlatDisable() throws Exception {
+        doReturn(false).when(mDeps).getCellular464XlatEnabled();
+
+        final TestNetworkCallback callback = new TestNetworkCallback();
+        final TestNetworkCallback defaultCallback = new TestNetworkCallback();
+        final NetworkRequest networkRequest = new NetworkRequest.Builder()
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .build();
+        mCm.registerNetworkCallback(networkRequest, callback);
+        mCm.registerDefaultNetworkCallback(defaultCallback);
+
+        // Bring up validated cell.
+        final LinkProperties cellLp = new LinkProperties();
+        cellLp.setInterfaceName(MOBILE_IFNAME);
+        cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64"));
+        cellLp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, MOBILE_IFNAME));
+        mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+
+        mCellNetworkAgent.sendLinkProperties(cellLp);
+        mCellNetworkAgent.connect(true);
+        callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+        defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+        final int cellNetId = mCellNetworkAgent.getNetwork().netId;
+        waitForIdle();
+
+        verify(mMockDnsResolver, never()).startPrefix64Discovery(cellNetId);
+        Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent);
+        assertTrue("Nat464Xlat was not IDLE", !clat.isStarted());
+
+        // This cannot happen because prefix discovery cannot succeed if it is never started.
+        mService.mResolverUnsolEventCallback.onNat64PrefixEvent(
+                makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, "64:ff9b::", 96));
+
+        // ... but still, check that even if it did, clatd would not be started.
+        verify(mMockNetd, never()).clatdStart(anyString(), anyString());
+        assertTrue("Nat464Xlat was not IDLE", !clat.isStarted());
+    }
+
+    @Test
     public void testDataActivityTracking() throws Exception {
         final TestNetworkCallback networkCallback = new TestNetworkCallback();
         final NetworkRequest networkRequest = new NetworkRequest.Builder()
@@ -8967,7 +9069,7 @@
                 TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE));
         return new NetworkAgentInfo(null, new Network(NET_ID), info, new LinkProperties(),
                 nc, 0, mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0,
-                INVALID_UID, mQosCallbackTracker);
+                INVALID_UID, mQosCallbackTracker, new ConnectivityService.Dependencies());
     }
 
     @Test
@@ -10647,7 +10749,7 @@
                 null,
                 null);
 
-        // default NCs will be unregistered in tearDown
+        // default callbacks will be unregistered in tearDown
     }
 
     /**
@@ -10704,7 +10806,7 @@
                 null,
                 mService.mNoServiceNetwork.network());
 
-        // default NCs will be unregistered in tearDown
+        // default callbacks will be unregistered in tearDown
     }
 
     /**
@@ -10763,7 +10865,7 @@
                 null,
                 mService.mNoServiceNetwork.network());
 
-        // default NCs will be unregistered in tearDown
+        // default callbacks will be unregistered in tearDown
     }
 
     /**
@@ -10822,7 +10924,28 @@
                 null,
                 mService.mNoServiceNetwork.network());
 
-        // default NCs will be unregistered in tearDown
+        // default callbacks will be unregistered in tearDown
+    }
+
+    @Test
+    public void testCapabilityWithOemNetworkPreference() throws Exception {
+        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+                OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+        setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref);
+        registerDefaultNetworkCallbacks();
+
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+
+        mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+        mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+
+        mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED);
+        mSystemDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc ->
+                nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
+        mDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc ->
+                nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
+
+        // default callbacks will be unregistered in tearDown
     }
 
     @Test
@@ -10903,4 +11026,4 @@
         verifyNoNetwork();
         mCm.unregisterNetworkCallback(cellCb);
     }
-}
+}
\ No newline at end of file
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index a913673..1c0ba4f 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -357,7 +357,7 @@
         NetworkAgentInfo nai = new NetworkAgentInfo(null, new Network(netId), info,
                 new LinkProperties(), caps, 50, mCtx, null, new NetworkAgentConfig() /* config */,
                 mConnService, mNetd, mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(),
-                mQosCallbackTracker);
+                mQosCallbackTracker, new ConnectivityService.Dependencies());
         nai.everValidated = true;
         return nai;
     }
diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
index 5f56e25..9b2a638 100644
--- a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
+++ b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
@@ -16,11 +16,15 @@
 
 package com.android.server.connectivity;
 
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -34,6 +38,7 @@
 import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.NetworkAgentConfig;
+import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
 import android.os.Handler;
 import android.os.test.TestLooper;
@@ -72,11 +77,15 @@
     Handler mHandler;
     NetworkAgentConfig mAgentConfig = new NetworkAgentConfig();
 
-    Nat464Xlat makeNat464Xlat() {
-        return new Nat464Xlat(mNai, mNetd, mDnsResolver) {
+    Nat464Xlat makeNat464Xlat(boolean isCellular464XlatEnabled) {
+        return new Nat464Xlat(mNai, mNetd, mDnsResolver, new ConnectivityService.Dependencies()) {
             @Override protected int getNetId() {
                 return NETID;
             }
+
+            @Override protected boolean isCellular464XlatEnabled() {
+                return isCellular464XlatEnabled;
+            }
         };
     }
 
@@ -99,6 +108,7 @@
         mNai.linkProperties.setInterfaceName(BASE_IFACE);
         mNai.networkInfo = new NetworkInfo(null);
         mNai.networkInfo.setType(ConnectivityManager.TYPE_WIFI);
+        mNai.networkCapabilities = new NetworkCapabilities();
         markNetworkConnected();
         when(mNai.connService()).thenReturn(mConnectivity);
         when(mNai.netAgentConfig()).thenReturn(mAgentConfig);
@@ -110,21 +120,23 @@
     }
 
     private void assertRequiresClat(boolean expected, NetworkAgentInfo nai) {
+        Nat464Xlat nat = makeNat464Xlat(true);
         String msg = String.format("requiresClat expected %b for type=%d state=%s skip=%b "
                 + "nat64Prefix=%s addresses=%s", expected, nai.networkInfo.getType(),
                 nai.networkInfo.getDetailedState(),
                 mAgentConfig.skip464xlat, nai.linkProperties.getNat64Prefix(),
                 nai.linkProperties.getLinkAddresses());
-        assertEquals(msg, expected, Nat464Xlat.requiresClat(nai));
+        assertEquals(msg, expected, nat.requiresClat(nai));
     }
 
     private void assertShouldStartClat(boolean expected, NetworkAgentInfo nai) {
+        Nat464Xlat nat = makeNat464Xlat(true);
         String msg = String.format("shouldStartClat expected %b for type=%d state=%s skip=%b "
                 + "nat64Prefix=%s addresses=%s", expected, nai.networkInfo.getType(),
                 nai.networkInfo.getDetailedState(),
                 mAgentConfig.skip464xlat, nai.linkProperties.getNat64Prefix(),
                 nai.linkProperties.getLinkAddresses());
-        assertEquals(msg, expected, Nat464Xlat.shouldStartClat(nai));
+        assertEquals(msg, expected, nat.shouldStartClat(nai));
     }
 
     @Test
@@ -194,7 +206,7 @@
     }
 
     private void checkNormalStartAndStop(boolean dueToDisconnect) throws Exception {
-        Nat464Xlat nat = makeNat464Xlat();
+        Nat464Xlat nat = makeNat464Xlat(true);
         ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class);
 
         mNai.linkProperties.addLinkAddress(V6ADDR);
@@ -245,7 +257,7 @@
     }
 
     private void checkStartStopStart(boolean interfaceRemovedFirst) throws Exception {
-        Nat464Xlat nat = makeNat464Xlat();
+        Nat464Xlat nat = makeNat464Xlat(true);
         ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class);
         InOrder inOrder = inOrder(mNetd, mConnectivity);
 
@@ -335,7 +347,7 @@
 
     @Test
     public void testClatdCrashWhileRunning() throws Exception {
-        Nat464Xlat nat = makeNat464Xlat();
+        Nat464Xlat nat = makeNat464Xlat(true);
         ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class);
 
         nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX));
@@ -372,7 +384,7 @@
     }
 
     private void checkStopBeforeClatdStarts(boolean dueToDisconnect) throws Exception {
-        Nat464Xlat nat = makeNat464Xlat();
+        Nat464Xlat nat = makeNat464Xlat(true);
 
         mNai.linkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64"));
 
@@ -414,7 +426,7 @@
     }
 
     private void checkStopAndClatdNeverStarts(boolean dueToDisconnect) throws Exception {
-        Nat464Xlat nat = makeNat464Xlat();
+        Nat464Xlat nat = makeNat464Xlat(true);
 
         mNai.linkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64"));
 
@@ -450,7 +462,7 @@
         final IpPrefix prefixFromDns = new IpPrefix(NAT64_PREFIX);
         final IpPrefix prefixFromRa = new IpPrefix(OTHER_NAT64_PREFIX);
 
-        Nat464Xlat nat = makeNat464Xlat();
+        Nat464Xlat nat = makeNat464Xlat(true);
 
         final LinkProperties emptyLp = new LinkProperties();
         LinkProperties fixedupLp;
@@ -486,10 +498,57 @@
         assertEquals(null, fixedupLp.getNat64Prefix());
     }
 
+    private void checkClatDisabledOnCellular(boolean onCellular) throws Exception {
+        // Disable 464xlat on cellular networks.
+        Nat464Xlat nat = makeNat464Xlat(false);
+        mNai.linkProperties.addLinkAddress(V6ADDR);
+        mNai.networkCapabilities.setTransportType(TRANSPORT_CELLULAR, onCellular);
+        nat.update();
+
+        final IpPrefix nat64Prefix = new IpPrefix(NAT64_PREFIX);
+        if (onCellular) {
+            // Prefix discovery is never started.
+            verify(mDnsResolver, never()).startPrefix64Discovery(eq(NETID));
+            assertIdle(nat);
+
+            // If a NAT64 prefix comes in from an RA, clat is not started either.
+            mNai.linkProperties.setNat64Prefix(nat64Prefix);
+            nat.setNat64PrefixFromRa(nat64Prefix);
+            nat.update();
+            verify(mNetd, never()).clatdStart(anyString(), anyString());
+            assertIdle(nat);
+        } else {
+            // Prefix discovery is started.
+            verify(mDnsResolver).startPrefix64Discovery(eq(NETID));
+            assertIdle(nat);
+
+            // If a NAT64 prefix comes in from an RA, clat is started.
+            mNai.linkProperties.setNat64Prefix(nat64Prefix);
+            nat.setNat64PrefixFromRa(nat64Prefix);
+            nat.update();
+            verify(mNetd).clatdStart(BASE_IFACE, NAT64_PREFIX);
+            assertStarting(nat);
+        }
+    }
+
+    @Test
+    public void testClatDisabledOnCellular() throws Exception {
+        checkClatDisabledOnCellular(true);
+    }
+
+    @Test
+    public void testClatDisabledOnNonCellular() throws Exception {
+        checkClatDisabledOnCellular(false);
+    }
+
     static void assertIdle(Nat464Xlat nat) {
         assertTrue("Nat464Xlat was not IDLE", !nat.isStarted());
     }
 
+    static void assertStarting(Nat464Xlat nat) {
+        assertTrue("Nat464Xlat was not STARTING", nat.isStarting());
+    }
+
     static void assertRunning(Nat464Xlat nat) {
         assertTrue("Nat464Xlat was not RUNNING", nat.isRunning());
     }
diff --git a/tests/vcn/assets/client-end-cert.pem b/tests/vcn/assets/client-end-cert.pem
new file mode 100644
index 0000000..e82da85
--- /dev/null
+++ b/tests/vcn/assets/client-end-cert.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDaDCCAlCgAwIBAgIIcorRI3n29E4wDQYJKoZIhvcNAQELBQAwQTELMAkGA1UE
+BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF3R3by5jYS50ZXN0LmFu
+ZHJvaWQubmV0MB4XDTIwMDQxNDA1MDM0OVoXDTIzMDQxNDA1MDM0OVowRTELMAkG
+A1UEBhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxJDAiBgNVBAMTG2NsaWVudC50ZXN0
+LmlrZS5hbmRyb2lkLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AK/cK+sIaiQlJYvy5+Dq70sJbgR7PO1uS2qkLRP7Wb3z5SNvz94nQvZRrFn1AFIE
+CpfESh5kUF6gJe7t7NR3mpQ98iEosCRBMDJT8qB+EeHiL4wkrmCE9sYMTyvaApRc
+6Qzozn/9kKma7Qpj/25AvoPluTERqhZ6AQ77BJeb6FNOAoO1Aoe9GJuB1xmRxjRw
+D0mwusL+ciQ/7uKlsFP5VO5XqACcohXSerzO8jcD9necBvka3SDepqqzn1K0NPRC
+25fMmS5kSjddKtKOif7w2NI3OpVsmP3kHv66If73VURsy0lgXPYyKkq8lAMrtmXG
+R7svFGPbEl+Swkpr3b+dzF8CAwEAAaNgMF4wHwYDVR0jBBgwFoAUcqSu1uRYT/DL
+bLoDNUz38nGvCKQwJgYDVR0RBB8wHYIbY2xpZW50LnRlc3QuaWtlLmFuZHJvaWQu
+bmV0MBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQCa53tK
+I9RM9/MutZ5KNG2Gfs2cqaPyv8ZRhs90HDWZhkFVu7prywJAxOd2hxxHPsvgurio
+4bKAxnT4EXevgz5YoCbj2TPIL9TdFYh59zZ97XXMxk+SRdypgF70M6ETqKPs3hDP
+ZRMMoHvvYaqaPvp4StSBX9A44gSyjHxVYJkrjDZ0uffKg5lFL5IPvqfdmSRSpGab
+SyGTP4OLTy0QiNV3pBsJGdl0h5BzuTPR9OTl4xgeqqBQy2bDjmfJBuiYyCSCkPi7
+T3ohDYCymhuSkuktHPNG1aKllUJaw0tuZuNydlgdAveXPYfM36uvK0sfd9qr9pAy
+rmkYV2MAWguFeckh
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/vcn/assets/client-private-key.key b/tests/vcn/assets/client-private-key.key
new file mode 100644
index 0000000..22736e9
--- /dev/null
+++ b/tests/vcn/assets/client-private-key.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCv3CvrCGokJSWL
+8ufg6u9LCW4EezztbktqpC0T+1m98+Ujb8/eJ0L2UaxZ9QBSBAqXxEoeZFBeoCXu
+7ezUd5qUPfIhKLAkQTAyU/KgfhHh4i+MJK5ghPbGDE8r2gKUXOkM6M5//ZCpmu0K
+Y/9uQL6D5bkxEaoWegEO+wSXm+hTTgKDtQKHvRibgdcZkcY0cA9JsLrC/nIkP+7i
+pbBT+VTuV6gAnKIV0nq8zvI3A/Z3nAb5Gt0g3qaqs59StDT0QtuXzJkuZEo3XSrS
+jon+8NjSNzqVbJj95B7+uiH+91VEbMtJYFz2MipKvJQDK7Zlxke7LxRj2xJfksJK
+a92/ncxfAgMBAAECggEAQztaMvW5lm35J8LKsWs/5qEJRX9T8LWs8W0oqq36Riub
+G2wgvR6ndAIPcSjAYZqX7iOl7m6NZ0+0kN63HxdGqovwKIskpAekBGmhpYftED1n
+zh0r6UyMB3UnQ22KdOv8UOokIDxxdNX8728BdUYdT9Ggdkj5jLRB+VcwD0IUlNvo
+zzTpURV9HEd87uiLqd4AAHXSI0lIHI5U43z24HI/J6/YbYHT3Rlh6CIa/LuwO6vL
+gFkgqg0/oy6yJtjrHtzNVA67F0UaH62hR4YFgbC0d955SJnDidWOv/0j2DMpfdCc
+9kFAcPwUSyykvUSLnGIKWSG4D+6gzIeAeUx4oO7kMQKBgQDVNRkX8AGTHyLg+NXf
+spUWWcodwVioXl30Q7h6+4bt8OI61UbhQ7wX61wvJ1cySpa2KOYa2UdagQVhGhhL
+ADu363R77uXF/jZgzVfmjjyJ2nfDqRgHWRTlSkuq/jCOQCz7VIPHRZg5WL/9D4ms
+TAqMjpzqeMfFZI+w4/+xpcJIuQKBgQDTKBy+ZuerWrVT9icWKvLU58o5EVj/2yFy
+GJvKm+wRAAX2WzjNnR4HVd4DmMREVz1BPYby0j5gqjvtDsxYYu39+NT7JvMioLLK
+QPj+7k5geYgNqVgCxB1vP89RhY2X1RLrN9sTXOodgFPeXOQWNYITkGp3eQpx4nTJ
++K/al3oB1wKBgAjnc8nVIyuyxDEjE0OJYMKTM2a0uXAmqMPXxC+Wq5bqVXhhidlE
+i+lv0eTCPtkB1nN7F8kNQ/aaps/cWCFhvBy9P5shagUvzbOTP9WIIS0cq53HRRKh
+fMbqqGhWv05hjb9dUzeSR341n6cA7B3++v3Nwu3j52vt/DZF/1q68nc5AoGAS0SU
+ImbKE/GsizZGLoe2sZ/CHN+LKwCwhlwxRGKaHmE0vuE7eUeVSaYZEo0lAPtb8WJ+
+NRYueASWgeTxgFwbW5mUScZTirdfo+rPFwhZVdhcYApKPgosN9i2DOgfVcz1BnWN
+mPRY25U/0BaqkyQVruWeneG+kGPZn5kPDktKiVcCgYEAkzwU9vCGhm7ZVALvx/zR
+wARz2zsL9ImBc0P4DK1ld8g90FEnHrEgeI9JEwz0zFHOCMLwlk7kG0Xev7vfjZ7G
+xSqtQYOH33Qp6rtBOgdt8hSyDFvakvDl6bqhAw52gelO3MTpAB1+ZsfZ5gFx13Jf
+idNFcaIrC52PtZIH7QCzdDY=
+-----END PRIVATE KEY-----
\ No newline at end of file
diff --git a/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java b/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java
index 36f5e41..2333718 100644
--- a/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java
@@ -99,6 +99,13 @@
     }
 
     @Test
+    public void testPersistableBundle() {
+        final VcnControlPlaneIkeConfig config = buildTestConfig();
+
+        assertEquals(config, new VcnControlPlaneIkeConfig(config.toPersistableBundle()));
+    }
+
+    @Test
     public void testConstructConfigWithoutIkeParams() {
         try {
             new VcnControlPlaneIkeConfig(null, CHILD_PARAMS);
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
new file mode 100644
index 0000000..546d957
--- /dev/null
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.vcn.persistablebundleutils;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.telephony.TelephonyManager.APPTYPE_USIM;
+
+import static org.junit.Assert.assertEquals;
+
+import android.net.InetAddresses;
+import android.net.eap.EapSessionConfig;
+import android.net.ipsec.ike.IkeFqdnIdentification;
+import android.net.ipsec.ike.IkeSessionParams;
+import android.os.PersistableBundle;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.org.bouncycastle.util.io.pem.PemObject;
+import com.android.internal.org.bouncycastle.util.io.pem.PemReader;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.nio.charset.StandardCharsets;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateKey;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class IkeSessionParamsUtilsTest {
+    private static IkeSessionParams.Builder createBuilderMinimum() {
+        final InetAddress serverAddress = InetAddresses.parseNumericAddress("192.0.2.100");
+
+        return new IkeSessionParams.Builder()
+                .setServerHostname(serverAddress.getHostAddress())
+                .addSaProposal(SaProposalUtilsTest.buildTestIkeSaProposal())
+                .setLocalIdentification(new IkeFqdnIdentification("client.test.android.net"))
+                .setRemoteIdentification(new IkeFqdnIdentification("server.test.android.net"))
+                .setAuthPsk("psk".getBytes());
+    }
+
+    private static void verifyPersistableBundleEncodeDecodeIsLossless(IkeSessionParams params) {
+        final PersistableBundle bundle = IkeSessionParamsUtils.toPersistableBundle(params);
+        final IkeSessionParams result = IkeSessionParamsUtils.fromPersistableBundle(bundle);
+
+        assertEquals(result, params);
+    }
+
+    @Test
+    public void testEncodeRecodeParamsWithLifetimes() throws Exception {
+        final int hardLifetime = (int) TimeUnit.HOURS.toSeconds(20L);
+        final int softLifetime = (int) TimeUnit.HOURS.toSeconds(10L);
+        final IkeSessionParams params =
+                createBuilderMinimum().setLifetimeSeconds(hardLifetime, softLifetime).build();
+        verifyPersistableBundleEncodeDecodeIsLossless(params);
+    }
+
+    @Test
+    public void testEncodeRecodeParamsWithDpdDelay() throws Exception {
+        final int dpdDelay = (int) TimeUnit.MINUTES.toSeconds(10L);
+        final IkeSessionParams params = createBuilderMinimum().setDpdDelaySeconds(dpdDelay).build();
+
+        verifyPersistableBundleEncodeDecodeIsLossless(params);
+    }
+
+    @Test
+    public void testEncodeRecodeParamsWithNattKeepalive() throws Exception {
+        final int nattKeepAliveDelay = (int) TimeUnit.MINUTES.toSeconds(5L);
+        final IkeSessionParams params =
+                createBuilderMinimum().setNattKeepAliveDelaySeconds(nattKeepAliveDelay).build();
+
+        verifyPersistableBundleEncodeDecodeIsLossless(params);
+    }
+
+    @Test
+    public void testEncodeRecodeParamsWithRetransmissionTimeouts() throws Exception {
+        final int[] retransmissionTimeout = new int[] {500, 500, 500, 500, 500, 500};
+        final IkeSessionParams params =
+                createBuilderMinimum()
+                        .setRetransmissionTimeoutsMillis(retransmissionTimeout)
+                        .build();
+
+        verifyPersistableBundleEncodeDecodeIsLossless(params);
+    }
+
+    @Test
+    public void testEncodeRecodeParamsWithConfigRequests() throws Exception {
+        final Inet4Address ipv4Address =
+                (Inet4Address) InetAddresses.parseNumericAddress("192.0.2.100");
+        final Inet6Address ipv6Address =
+                (Inet6Address) InetAddresses.parseNumericAddress("2001:db8::1");
+
+        final IkeSessionParams params =
+                createBuilderMinimum()
+                        .addPcscfServerRequest(AF_INET)
+                        .addPcscfServerRequest(AF_INET6)
+                        .addPcscfServerRequest(ipv4Address)
+                        .addPcscfServerRequest(ipv6Address)
+                        .build();
+        verifyPersistableBundleEncodeDecodeIsLossless(params);
+    }
+
+    @Test
+    public void testEncodeRecodeParamsWithAuthPsk() throws Exception {
+        final IkeSessionParams params = createBuilderMinimum().setAuthPsk("psk".getBytes()).build();
+        verifyPersistableBundleEncodeDecodeIsLossless(params);
+    }
+
+    @Test
+    public void testEncodeRecodeParamsWithIkeOptions() throws Exception {
+        final IkeSessionParams params =
+                createBuilderMinimum()
+                        .addIkeOption(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID)
+                        .addIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE)
+                        .build();
+        verifyPersistableBundleEncodeDecodeIsLossless(params);
+    }
+
+    private static InputStream openAssetsFile(String fileName) throws Exception {
+        return InstrumentationRegistry.getContext().getResources().getAssets().open(fileName);
+    }
+
+    private static X509Certificate createCertFromPemFile(String fileName) throws Exception {
+        final CertificateFactory factory = CertificateFactory.getInstance("X.509");
+        return (X509Certificate) factory.generateCertificate(openAssetsFile(fileName));
+    }
+
+    private static RSAPrivateKey createRsaPrivateKeyFromKeyFile(String fileName) throws Exception {
+        final PemObject pemObject =
+                new PemReader(new InputStreamReader(openAssetsFile(fileName))).readPemObject();
+        return (RSAPrivateKey) CertUtils.privateKeyFromByteArray(pemObject.getContent());
+    }
+
+    @Test
+    public void testEncodeRecodeParamsWithDigitalSignAuth() throws Exception {
+        final X509Certificate serverCaCert = createCertFromPemFile("self-signed-ca.pem");
+        final X509Certificate clientEndCert = createCertFromPemFile("client-end-cert.pem");
+        final RSAPrivateKey clientPrivateKey =
+                createRsaPrivateKeyFromKeyFile("client-private-key.key");
+
+        final IkeSessionParams params =
+                createBuilderMinimum()
+                        .setAuthDigitalSignature(serverCaCert, clientEndCert, clientPrivateKey)
+                        .build();
+        verifyPersistableBundleEncodeDecodeIsLossless(params);
+    }
+
+    @Test
+    public void testEncodeRecodeParamsWithEapAuth() throws Exception {
+        final X509Certificate serverCaCert = createCertFromPemFile("self-signed-ca.pem");
+
+        final byte[] eapId = "test@android.net".getBytes(StandardCharsets.US_ASCII);
+        final int subId = 1;
+        final EapSessionConfig eapConfig =
+                new EapSessionConfig.Builder()
+                        .setEapIdentity(eapId)
+                        .setEapSimConfig(subId, APPTYPE_USIM)
+                        .setEapAkaConfig(subId, APPTYPE_USIM)
+                        .build();
+
+        final IkeSessionParams params =
+                createBuilderMinimum().setAuthEap(serverCaCert, eapConfig).build();
+        verifyPersistableBundleEncodeDecodeIsLossless(params);
+    }
+}
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
index 8ae8692..664044a 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
@@ -32,21 +32,25 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class SaProposalUtilsTest {
+    /** Package private so that IkeSessionParamsUtilsTest can use it */
+    static IkeSaProposal buildTestIkeSaProposal() {
+        return new IkeSaProposal.Builder()
+                .addEncryptionAlgorithm(
+                        SaProposal.ENCRYPTION_ALGORITHM_3DES, SaProposal.KEY_LEN_UNUSED)
+                .addEncryptionAlgorithm(
+                        SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128)
+                .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
+                .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128)
+                .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
+                .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256)
+                .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
+                .addDhGroup(SaProposal.DH_GROUP_3072_BIT_MODP)
+                .build();
+    }
+
     @Test
     public void testPersistableBundleEncodeDecodeIsLosslessIkeProposal() throws Exception {
-        final IkeSaProposal proposal =
-                new IkeSaProposal.Builder()
-                        .addEncryptionAlgorithm(
-                                SaProposal.ENCRYPTION_ALGORITHM_3DES, SaProposal.KEY_LEN_UNUSED)
-                        .addEncryptionAlgorithm(
-                                SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128)
-                        .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
-                        .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128)
-                        .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
-                        .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256)
-                        .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
-                        .addDhGroup(SaProposal.DH_GROUP_3072_BIT_MODP)
-                        .build();
+        final IkeSaProposal proposal = buildTestIkeSaProposal();
 
         final PersistableBundle bundle = IkeSaProposalUtils.toPersistableBundle(proposal);
         final SaProposal resultProposal = IkeSaProposalUtils.fromPersistableBundle(bundle);
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 73a6b88..11498de 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -461,6 +461,34 @@
     }
 
     @Test
+    public void testSetVcnConfigNotifiesStatusCallback() throws Exception {
+        mVcnMgmtSvc.systemReady();
+        doReturn(true)
+                .when(mLocationPermissionChecker)
+                .checkLocationPermission(eq(TEST_PACKAGE_NAME), any(), eq(TEST_UID), any());
+        triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_2));
+
+        mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_2, mMockStatusCallback, TEST_PACKAGE_NAME);
+        verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED);
+
+        // Use a different UUID to simulate a new VCN config.
+        mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
+
+        verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_ACTIVE);
+    }
+
+    @Test
+    public void testSetVcnConfigInSafeModeNotifiesStatusCallback() throws Exception {
+        setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_2, false /* isActive */);
+        mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_2, mMockStatusCallback, TEST_PACKAGE_NAME);
+        verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE);
+
+        mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
+
+        verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_ACTIVE);
+    }
+
+    @Test
     public void testClearVcnConfigRequiresNonSystemServer() throws Exception {
         doReturn(Process.SYSTEM_UID).when(mMockDeps).getBinderCallingUid();
 
@@ -503,6 +531,17 @@
     }
 
     @Test
+    public void testClearVcnConfigNotifiesStatusCallback() throws Exception {
+        setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_2, true /* isActive */);
+        mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_2, mMockStatusCallback, TEST_PACKAGE_NAME);
+        verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_ACTIVE);
+
+        mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2);
+
+        verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED);
+    }
+
+    @Test
     public void testSetVcnConfigClearVcnConfigStartsUpdatesAndTeardsDownVcns() throws Exception {
         // Use a different UUID to simulate a new VCN config.
         mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
diff --git a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
index 1d459a3..1ef1a61 100644
--- a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
@@ -194,29 +194,35 @@
     }
 
     private NetworkRequest getWifiRequest() {
-        return getExpectedRequestBase()
+        return getExpectedRequestBase(true)
                 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                 .build();
     }
 
     private NetworkRequest getCellRequestForSubId(int subId) {
-        return getExpectedRequestBase()
+        return getExpectedRequestBase(false)
                 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                 .setNetworkSpecifier(new TelephonyNetworkSpecifier(subId))
                 .build();
     }
 
     private NetworkRequest getRouteSelectionRequest() {
-        return getExpectedRequestBase().build();
+        return getExpectedRequestBase(true).build();
     }
 
-    private NetworkRequest.Builder getExpectedRequestBase() {
-        return new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
-                .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                .addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+    private NetworkRequest.Builder getExpectedRequestBase(boolean requireVcnManaged) {
+        final NetworkRequest.Builder builder =
+                new NetworkRequest.Builder()
+                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                        .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+                        .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+                        .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+
+        if (requireVcnManaged) {
+            builder.addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+        }
+
+        return builder;
     }
 
     @Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 69b2fb1..0e5f5e4 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -73,7 +73,7 @@
 
         mGatewayConnection.setUnderlyingNetwork(TEST_UNDERLYING_NETWORK_RECORD_1);
 
-        mIkeSession = mGatewayConnection.buildIkeSession();
+        mIkeSession = mGatewayConnection.buildIkeSession(TEST_UNDERLYING_NETWORK_RECORD_1.network);
         mGatewayConnection.setIkeSession(mIkeSession);
 
         mGatewayConnection.transitionTo(mGatewayConnection.mConnectedState);
@@ -241,7 +241,7 @@
 
         verify(mGatewayStatusCallback)
                 .onGatewayConnectionError(
-                        eq(mConfig.getRequiredUnderlyingCapabilities()),
+                        eq(mConfig.getExposedCapabilities()),
                         eq(VCN_ERROR_CODE_INTERNAL_ERROR),
                         any(),
                         any());
@@ -275,10 +275,7 @@
 
         verify(mGatewayStatusCallback)
                 .onGatewayConnectionError(
-                        eq(mConfig.getRequiredUnderlyingCapabilities()),
-                        eq(expectedErrorType),
-                        any(),
-                        any());
+                        eq(mConfig.getExposedCapabilities()), eq(expectedErrorType), any(), any());
     }
 
     @Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
index d07d2cf..7afa449 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
@@ -25,12 +25,15 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
+import android.net.ipsec.ike.IkeSessionParams;
+
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 
 /** Tests for VcnGatewayConnection.ConnectingState */
 @RunWith(AndroidJUnit4.class)
@@ -51,7 +54,12 @@
 
     @Test
     public void testEnterStateCreatesNewIkeSession() throws Exception {
-        verify(mDeps).newIkeSession(any(), any(), any(), any(), any());
+        final ArgumentCaptor<IkeSessionParams> paramsCaptor =
+                ArgumentCaptor.forClass(IkeSessionParams.class);
+        verify(mDeps).newIkeSession(any(), paramsCaptor.capture(), any(), any(), any());
+        assertEquals(
+                TEST_UNDERLYING_NETWORK_RECORD_1.network,
+                paramsCaptor.getValue().getConfiguredNetwork());
     }
 
     @Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
index 661e03a..99feffd 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
@@ -38,7 +38,8 @@
     public void setUp() throws Exception {
         super.setUp();
 
-        mGatewayConnection.setIkeSession(mGatewayConnection.buildIkeSession());
+        mGatewayConnection.setIkeSession(
+                mGatewayConnection.buildIkeSession(TEST_UNDERLYING_NETWORK_RECORD_2.network));
 
         // ensure that mGatewayConnection has an underlying Network before entering
         // DisconnectingState
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
index 748c792..d08af9d 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
@@ -18,6 +18,7 @@
 
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 
@@ -87,6 +88,7 @@
     private void verifyBuildNetworkCapabilitiesCommon(int transportType) {
         final NetworkCapabilities underlyingCaps = new NetworkCapabilities();
         underlyingCaps.addTransportType(transportType);
+        underlyingCaps.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
         underlyingCaps.addCapability(NET_CAPABILITY_NOT_METERED);
         underlyingCaps.addCapability(NET_CAPABILITY_NOT_ROAMING);
 
diff --git a/tests/vcn/java/com/android/server/vcn/VcnTest.java b/tests/vcn/java/com/android/server/vcn/VcnTest.java
index 3dd710a..4fa63d4 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnTest.java
@@ -22,7 +22,9 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
@@ -48,6 +50,7 @@
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
+import java.util.Arrays;
 import java.util.Set;
 import java.util.UUID;
 
@@ -58,7 +61,7 @@
     private static final int PROVIDER_ID = 5;
     private static final int[][] TEST_CAPS =
             new int[][] {
-                new int[] {NET_CAPABILITY_INTERNET, NET_CAPABILITY_MMS},
+                new int[] {NET_CAPABILITY_MMS, NET_CAPABILITY_INTERNET},
                 new int[] {NET_CAPABILITY_DUN}
             };
 
@@ -155,14 +158,6 @@
         }
     }
 
-    @Test
-    public void testGatewayEnteringSafeModeNotifiesVcn() {
-        final NetworkRequestListener requestListener = verifyAndGetRequestListener();
-        for (final int capability : VcnGatewayConnectionConfigTest.EXPOSED_CAPS) {
-            startVcnGatewayWithCapabilities(requestListener, capability);
-        }
-    }
-
     private void triggerVcnRequestListeners(NetworkRequestListener requestListener) {
         for (final int[] caps : TEST_CAPS) {
             startVcnGatewayWithCapabilities(requestListener, caps);
@@ -188,8 +183,20 @@
         return gatewayConnections;
     }
 
+    private void verifySafeMode(
+            NetworkRequestListener requestListener,
+            Set<VcnGatewayConnection> expectedGatewaysTornDown) {
+        assertFalse(mVcn.isActive());
+        assertTrue(mVcn.getVcnGatewayConnections().isEmpty());
+        for (final VcnGatewayConnection gatewayConnection : expectedGatewaysTornDown) {
+            verify(gatewayConnection).teardownAsynchronously();
+        }
+        verify(mVcnNetworkProvider).unregisterListener(requestListener);
+        verify(mVcnCallback).onEnteredSafeMode();
+    }
+
     @Test
-    public void testGatewayEnteringSafemodeNotifiesVcn() {
+    public void testGatewayEnteringSafeModeNotifiesVcn() {
         final NetworkRequestListener requestListener = verifyAndGetRequestListener();
         final Set<VcnGatewayConnection> gatewayConnections =
                 startGatewaysAndGetGatewayConnections(requestListener);
@@ -200,12 +207,7 @@
         statusCallback.onEnteredSafeMode();
         mTestLooper.dispatchAll();
 
-        assertFalse(mVcn.isActive());
-        for (final VcnGatewayConnection gatewayConnection : gatewayConnections) {
-            verify(gatewayConnection).teardownAsynchronously();
-        }
-        verify(mVcnNetworkProvider).unregisterListener(requestListener);
-        verify(mVcnCallback).onEnteredSafeMode();
+        verifySafeMode(requestListener, gatewayConnections);
     }
 
     @Test
@@ -234,4 +236,39 @@
                         any(),
                         mGatewayStatusCallbackCaptor.capture());
     }
+
+    @Test
+    public void testUpdateConfigExitsSafeMode() {
+        final NetworkRequestListener requestListener = verifyAndGetRequestListener();
+        final Set<VcnGatewayConnection> gatewayConnections =
+                new ArraySet<>(startGatewaysAndGetGatewayConnections(requestListener));
+
+        final VcnGatewayStatusCallback statusCallback = mGatewayStatusCallbackCaptor.getValue();
+        statusCallback.onEnteredSafeMode();
+        mTestLooper.dispatchAll();
+        verifySafeMode(requestListener, gatewayConnections);
+
+        doAnswer(invocation -> {
+            final NetworkRequestListener listener = invocation.getArgument(0);
+            triggerVcnRequestListeners(listener);
+            return null;
+        }).when(mVcnNetworkProvider).registerListener(eq(requestListener));
+
+        mVcn.updateConfig(mConfig);
+        mTestLooper.dispatchAll();
+
+        // Registered on start, then re-registered with new configs
+        verify(mVcnNetworkProvider, times(2)).registerListener(eq(requestListener));
+        assertTrue(mVcn.isActive());
+        for (final int[] caps : TEST_CAPS) {
+            // Expect each gateway connection created on initial startup, and again with new configs
+            verify(mDeps, times(2))
+                    .newVcnGatewayConnection(
+                            eq(mVcnContext),
+                            eq(TEST_SUB_GROUP),
+                            eq(mSubscriptionSnapshot),
+                            argThat(config -> Arrays.equals(caps, config.getExposedCapabilities())),
+                            any());
+        }
+    }
 }