Merge "Remove VpnType usage in VpnTransportInfo"
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..d40f115 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",
@@ -834,17 +834,20 @@
     ],
 }
 
-// keep these files in sync with the package/Tethering/jarjar-rules.txt for the tethering module.
+// keep these files in sync with the package/Tethering/jarjar-rules.txt and
+// package/Connectivity/jarjar-rules.txt for the tethering module and connectivity module.
 filegroup {
-    name: "framework-tethering-shared-srcs",
+    name: "framework-connectivity-shared-srcs",
     srcs: [
         "core/java/android/util/LocalLog.java",
+        // This should be android.util.IndentingPrintWriter, but it's not available in all branches.
         "core/java/com/android/internal/util/IndentingPrintWriter.java",
         "core/java/com/android/internal/util/IState.java",
         "core/java/com/android/internal/util/MessageUtils.java",
         "core/java/com/android/internal/util/State.java",
         "core/java/com/android/internal/util/StateMachine.java",
         "core/java/com/android/internal/util/TrafficStatsConstants.java",
+        "core/java/com/android/internal/util/WakeupMessage.java",
     ],
 }
 
@@ -1130,6 +1133,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/config/preloaded-classes b/config/preloaded-classes
index 5e88d97d..56c35bc 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -1838,11 +1838,9 @@
 android.ddm.DdmHandleAppName$Names
 android.ddm.DdmHandleAppName
 android.ddm.DdmHandleExit
-android.ddm.DdmHandleHeap
 android.ddm.DdmHandleHello
 android.ddm.DdmHandleNativeHeap
 android.ddm.DdmHandleProfiling
-android.ddm.DdmHandleThread
 android.ddm.DdmHandleViewDebug
 android.ddm.DdmRegister
 android.debug.AdbManager
diff --git a/core/api/current.txt b/core/api/current.txt
index aa9a03e..0e7ecef 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -25018,10 +25018,6 @@
     ctor public NetworkSpecifier();
   }
 
-  public class ParseException extends java.lang.RuntimeException {
-    field public String response;
-  }
-
   public abstract class PlatformVpnProfile {
     method public final int getType();
     method @NonNull public final String getTypeString();
@@ -25433,236 +25429,236 @@
 
 package android.net.rtp {
 
-  public class AudioCodec {
-    method public static android.net.rtp.AudioCodec getCodec(int, String, String);
-    method public static android.net.rtp.AudioCodec[] getCodecs();
-    field public static final android.net.rtp.AudioCodec AMR;
-    field public static final android.net.rtp.AudioCodec GSM;
-    field public static final android.net.rtp.AudioCodec GSM_EFR;
-    field public static final android.net.rtp.AudioCodec PCMA;
-    field public static final android.net.rtp.AudioCodec PCMU;
-    field public final String fmtp;
-    field public final String rtpmap;
-    field public final int type;
+  @Deprecated public class AudioCodec {
+    method @Deprecated public static android.net.rtp.AudioCodec getCodec(int, String, String);
+    method @Deprecated public static android.net.rtp.AudioCodec[] getCodecs();
+    field @Deprecated public static final android.net.rtp.AudioCodec AMR;
+    field @Deprecated public static final android.net.rtp.AudioCodec GSM;
+    field @Deprecated public static final android.net.rtp.AudioCodec GSM_EFR;
+    field @Deprecated public static final android.net.rtp.AudioCodec PCMA;
+    field @Deprecated public static final android.net.rtp.AudioCodec PCMU;
+    field @Deprecated public final String fmtp;
+    field @Deprecated public final String rtpmap;
+    field @Deprecated public final int type;
   }
 
-  public class AudioGroup {
+  @Deprecated public class AudioGroup {
     ctor @Deprecated public AudioGroup();
-    ctor public AudioGroup(@NonNull android.content.Context);
-    method public void clear();
-    method public int getMode();
-    method public android.net.rtp.AudioStream[] getStreams();
-    method public void sendDtmf(int);
-    method public void setMode(int);
-    field public static final int MODE_ECHO_SUPPRESSION = 3; // 0x3
-    field public static final int MODE_MUTED = 1; // 0x1
-    field public static final int MODE_NORMAL = 2; // 0x2
-    field public static final int MODE_ON_HOLD = 0; // 0x0
+    ctor @Deprecated public AudioGroup(@NonNull android.content.Context);
+    method @Deprecated public void clear();
+    method @Deprecated public int getMode();
+    method @Deprecated public android.net.rtp.AudioStream[] getStreams();
+    method @Deprecated public void sendDtmf(int);
+    method @Deprecated public void setMode(int);
+    field @Deprecated public static final int MODE_ECHO_SUPPRESSION = 3; // 0x3
+    field @Deprecated public static final int MODE_MUTED = 1; // 0x1
+    field @Deprecated public static final int MODE_NORMAL = 2; // 0x2
+    field @Deprecated public static final int MODE_ON_HOLD = 0; // 0x0
   }
 
-  public class AudioStream extends android.net.rtp.RtpStream {
-    ctor public AudioStream(java.net.InetAddress) throws java.net.SocketException;
-    method public android.net.rtp.AudioCodec getCodec();
-    method public int getDtmfType();
-    method public android.net.rtp.AudioGroup getGroup();
-    method public final boolean isBusy();
-    method public void join(android.net.rtp.AudioGroup);
-    method public void setCodec(android.net.rtp.AudioCodec);
-    method public void setDtmfType(int);
+  @Deprecated public class AudioStream extends android.net.rtp.RtpStream {
+    ctor @Deprecated public AudioStream(java.net.InetAddress) throws java.net.SocketException;
+    method @Deprecated public android.net.rtp.AudioCodec getCodec();
+    method @Deprecated public int getDtmfType();
+    method @Deprecated public android.net.rtp.AudioGroup getGroup();
+    method @Deprecated public final boolean isBusy();
+    method @Deprecated public void join(android.net.rtp.AudioGroup);
+    method @Deprecated public void setCodec(android.net.rtp.AudioCodec);
+    method @Deprecated public void setDtmfType(int);
   }
 
-  public class RtpStream {
-    method public void associate(java.net.InetAddress, int);
-    method public java.net.InetAddress getLocalAddress();
-    method public int getLocalPort();
-    method public int getMode();
-    method public java.net.InetAddress getRemoteAddress();
-    method public int getRemotePort();
-    method public boolean isBusy();
-    method public void release();
-    method public void setMode(int);
-    field public static final int MODE_NORMAL = 0; // 0x0
-    field public static final int MODE_RECEIVE_ONLY = 2; // 0x2
-    field public static final int MODE_SEND_ONLY = 1; // 0x1
+  @Deprecated public class RtpStream {
+    method @Deprecated public void associate(java.net.InetAddress, int);
+    method @Deprecated public java.net.InetAddress getLocalAddress();
+    method @Deprecated public int getLocalPort();
+    method @Deprecated public int getMode();
+    method @Deprecated public java.net.InetAddress getRemoteAddress();
+    method @Deprecated public int getRemotePort();
+    method @Deprecated public boolean isBusy();
+    method @Deprecated public void release();
+    method @Deprecated public void setMode(int);
+    field @Deprecated public static final int MODE_NORMAL = 0; // 0x0
+    field @Deprecated public static final int MODE_RECEIVE_ONLY = 2; // 0x2
+    field @Deprecated public static final int MODE_SEND_ONLY = 1; // 0x1
   }
 
 }
 
 package android.net.sip {
 
-  public class SipAudioCall {
-    ctor public SipAudioCall(android.content.Context, android.net.sip.SipProfile);
-    method public void answerCall(int) throws android.net.sip.SipException;
-    method public void attachCall(android.net.sip.SipSession, String) throws android.net.sip.SipException;
-    method public void close();
-    method public void continueCall(int) throws android.net.sip.SipException;
-    method public void endCall() throws android.net.sip.SipException;
-    method public android.net.sip.SipProfile getLocalProfile();
-    method public android.net.sip.SipProfile getPeerProfile();
-    method public int getState();
-    method public void holdCall(int) throws android.net.sip.SipException;
-    method public boolean isInCall();
-    method public boolean isMuted();
-    method public boolean isOnHold();
-    method public void makeCall(android.net.sip.SipProfile, android.net.sip.SipSession, int) throws android.net.sip.SipException;
-    method public void sendDtmf(int);
-    method public void sendDtmf(int, android.os.Message);
-    method public void setListener(android.net.sip.SipAudioCall.Listener);
-    method public void setListener(android.net.sip.SipAudioCall.Listener, boolean);
-    method public void setSpeakerMode(boolean);
-    method public void startAudio();
-    method public void toggleMute();
+  @Deprecated public class SipAudioCall {
+    ctor @Deprecated public SipAudioCall(android.content.Context, android.net.sip.SipProfile);
+    method @Deprecated public void answerCall(int) throws android.net.sip.SipException;
+    method @Deprecated public void attachCall(android.net.sip.SipSession, String) throws android.net.sip.SipException;
+    method @Deprecated public void close();
+    method @Deprecated public void continueCall(int) throws android.net.sip.SipException;
+    method @Deprecated public void endCall() throws android.net.sip.SipException;
+    method @Deprecated public android.net.sip.SipProfile getLocalProfile();
+    method @Deprecated public android.net.sip.SipProfile getPeerProfile();
+    method @Deprecated public int getState();
+    method @Deprecated public void holdCall(int) throws android.net.sip.SipException;
+    method @Deprecated public boolean isInCall();
+    method @Deprecated public boolean isMuted();
+    method @Deprecated public boolean isOnHold();
+    method @Deprecated public void makeCall(android.net.sip.SipProfile, android.net.sip.SipSession, int) throws android.net.sip.SipException;
+    method @Deprecated public void sendDtmf(int);
+    method @Deprecated public void sendDtmf(int, android.os.Message);
+    method @Deprecated public void setListener(android.net.sip.SipAudioCall.Listener);
+    method @Deprecated public void setListener(android.net.sip.SipAudioCall.Listener, boolean);
+    method @Deprecated public void setSpeakerMode(boolean);
+    method @Deprecated public void startAudio();
+    method @Deprecated public void toggleMute();
   }
 
-  public static class SipAudioCall.Listener {
-    ctor public SipAudioCall.Listener();
-    method public void onCallBusy(android.net.sip.SipAudioCall);
-    method public void onCallEnded(android.net.sip.SipAudioCall);
-    method public void onCallEstablished(android.net.sip.SipAudioCall);
-    method public void onCallHeld(android.net.sip.SipAudioCall);
-    method public void onCalling(android.net.sip.SipAudioCall);
-    method public void onChanged(android.net.sip.SipAudioCall);
-    method public void onError(android.net.sip.SipAudioCall, int, String);
-    method public void onReadyToCall(android.net.sip.SipAudioCall);
-    method public void onRinging(android.net.sip.SipAudioCall, android.net.sip.SipProfile);
-    method public void onRingingBack(android.net.sip.SipAudioCall);
+  @Deprecated public static class SipAudioCall.Listener {
+    ctor @Deprecated public SipAudioCall.Listener();
+    method @Deprecated public void onCallBusy(android.net.sip.SipAudioCall);
+    method @Deprecated public void onCallEnded(android.net.sip.SipAudioCall);
+    method @Deprecated public void onCallEstablished(android.net.sip.SipAudioCall);
+    method @Deprecated public void onCallHeld(android.net.sip.SipAudioCall);
+    method @Deprecated public void onCalling(android.net.sip.SipAudioCall);
+    method @Deprecated public void onChanged(android.net.sip.SipAudioCall);
+    method @Deprecated public void onError(android.net.sip.SipAudioCall, int, String);
+    method @Deprecated public void onReadyToCall(android.net.sip.SipAudioCall);
+    method @Deprecated public void onRinging(android.net.sip.SipAudioCall, android.net.sip.SipProfile);
+    method @Deprecated public void onRingingBack(android.net.sip.SipAudioCall);
   }
 
-  public class SipErrorCode {
-    method public static String toString(int);
-    field public static final int CLIENT_ERROR = -4; // 0xfffffffc
-    field public static final int CROSS_DOMAIN_AUTHENTICATION = -11; // 0xfffffff5
-    field public static final int DATA_CONNECTION_LOST = -10; // 0xfffffff6
-    field public static final int INVALID_CREDENTIALS = -8; // 0xfffffff8
-    field public static final int INVALID_REMOTE_URI = -6; // 0xfffffffa
-    field public static final int IN_PROGRESS = -9; // 0xfffffff7
-    field public static final int NO_ERROR = 0; // 0x0
-    field public static final int PEER_NOT_REACHABLE = -7; // 0xfffffff9
-    field public static final int SERVER_ERROR = -2; // 0xfffffffe
-    field public static final int SERVER_UNREACHABLE = -12; // 0xfffffff4
-    field public static final int SOCKET_ERROR = -1; // 0xffffffff
-    field public static final int TIME_OUT = -5; // 0xfffffffb
-    field public static final int TRANSACTION_TERMINTED = -3; // 0xfffffffd
+  @Deprecated public class SipErrorCode {
+    method @Deprecated public static String toString(int);
+    field @Deprecated public static final int CLIENT_ERROR = -4; // 0xfffffffc
+    field @Deprecated public static final int CROSS_DOMAIN_AUTHENTICATION = -11; // 0xfffffff5
+    field @Deprecated public static final int DATA_CONNECTION_LOST = -10; // 0xfffffff6
+    field @Deprecated public static final int INVALID_CREDENTIALS = -8; // 0xfffffff8
+    field @Deprecated public static final int INVALID_REMOTE_URI = -6; // 0xfffffffa
+    field @Deprecated public static final int IN_PROGRESS = -9; // 0xfffffff7
+    field @Deprecated public static final int NO_ERROR = 0; // 0x0
+    field @Deprecated public static final int PEER_NOT_REACHABLE = -7; // 0xfffffff9
+    field @Deprecated public static final int SERVER_ERROR = -2; // 0xfffffffe
+    field @Deprecated public static final int SERVER_UNREACHABLE = -12; // 0xfffffff4
+    field @Deprecated public static final int SOCKET_ERROR = -1; // 0xffffffff
+    field @Deprecated public static final int TIME_OUT = -5; // 0xfffffffb
+    field @Deprecated public static final int TRANSACTION_TERMINTED = -3; // 0xfffffffd
   }
 
-  public class SipException extends java.lang.Exception {
-    ctor public SipException();
-    ctor public SipException(String);
-    ctor public SipException(String, Throwable);
+  @Deprecated public class SipException extends java.lang.Exception {
+    ctor @Deprecated public SipException();
+    ctor @Deprecated public SipException(String);
+    ctor @Deprecated public SipException(String, Throwable);
   }
 
-  public class SipManager {
-    method public void close(String) throws android.net.sip.SipException;
-    method public android.net.sip.SipSession createSipSession(android.net.sip.SipProfile, android.net.sip.SipSession.Listener) throws android.net.sip.SipException;
-    method public static String getCallId(android.content.Intent);
-    method public static String getOfferSessionDescription(android.content.Intent);
-    method public android.net.sip.SipSession getSessionFor(android.content.Intent) throws android.net.sip.SipException;
-    method public static boolean isApiSupported(android.content.Context);
-    method public static boolean isIncomingCallIntent(android.content.Intent);
-    method public boolean isOpened(String) throws android.net.sip.SipException;
-    method public boolean isRegistered(String) throws android.net.sip.SipException;
-    method public static boolean isSipWifiOnly(android.content.Context);
-    method public static boolean isVoipSupported(android.content.Context);
-    method public android.net.sip.SipAudioCall makeAudioCall(android.net.sip.SipProfile, android.net.sip.SipProfile, android.net.sip.SipAudioCall.Listener, int) throws android.net.sip.SipException;
-    method public android.net.sip.SipAudioCall makeAudioCall(String, String, android.net.sip.SipAudioCall.Listener, int) throws android.net.sip.SipException;
-    method public static android.net.sip.SipManager newInstance(android.content.Context);
-    method public void open(android.net.sip.SipProfile) throws android.net.sip.SipException;
-    method public void open(android.net.sip.SipProfile, android.app.PendingIntent, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
-    method public void register(android.net.sip.SipProfile, int, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
-    method public void setRegistrationListener(String, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
-    method public android.net.sip.SipAudioCall takeAudioCall(android.content.Intent, android.net.sip.SipAudioCall.Listener) throws android.net.sip.SipException;
-    method public void unregister(android.net.sip.SipProfile, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
-    field public static final String EXTRA_CALL_ID = "android:sipCallID";
-    field public static final String EXTRA_OFFER_SD = "android:sipOfferSD";
-    field public static final int INCOMING_CALL_RESULT_CODE = 101; // 0x65
+  @Deprecated public class SipManager {
+    method @Deprecated public void close(String) throws android.net.sip.SipException;
+    method @Deprecated public android.net.sip.SipSession createSipSession(android.net.sip.SipProfile, android.net.sip.SipSession.Listener) throws android.net.sip.SipException;
+    method @Deprecated public static String getCallId(android.content.Intent);
+    method @Deprecated public static String getOfferSessionDescription(android.content.Intent);
+    method @Deprecated public android.net.sip.SipSession getSessionFor(android.content.Intent) throws android.net.sip.SipException;
+    method @Deprecated public static boolean isApiSupported(android.content.Context);
+    method @Deprecated public static boolean isIncomingCallIntent(android.content.Intent);
+    method @Deprecated public boolean isOpened(String) throws android.net.sip.SipException;
+    method @Deprecated public boolean isRegistered(String) throws android.net.sip.SipException;
+    method @Deprecated public static boolean isSipWifiOnly(android.content.Context);
+    method @Deprecated public static boolean isVoipSupported(android.content.Context);
+    method @Deprecated public android.net.sip.SipAudioCall makeAudioCall(android.net.sip.SipProfile, android.net.sip.SipProfile, android.net.sip.SipAudioCall.Listener, int) throws android.net.sip.SipException;
+    method @Deprecated public android.net.sip.SipAudioCall makeAudioCall(String, String, android.net.sip.SipAudioCall.Listener, int) throws android.net.sip.SipException;
+    method @Deprecated public static android.net.sip.SipManager newInstance(android.content.Context);
+    method @Deprecated public void open(android.net.sip.SipProfile) throws android.net.sip.SipException;
+    method @Deprecated public void open(android.net.sip.SipProfile, android.app.PendingIntent, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
+    method @Deprecated public void register(android.net.sip.SipProfile, int, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
+    method @Deprecated public void setRegistrationListener(String, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
+    method @Deprecated public android.net.sip.SipAudioCall takeAudioCall(android.content.Intent, android.net.sip.SipAudioCall.Listener) throws android.net.sip.SipException;
+    method @Deprecated public void unregister(android.net.sip.SipProfile, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
+    field @Deprecated public static final String EXTRA_CALL_ID = "android:sipCallID";
+    field @Deprecated public static final String EXTRA_OFFER_SD = "android:sipOfferSD";
+    field @Deprecated public static final int INCOMING_CALL_RESULT_CODE = 101; // 0x65
   }
 
-  public class SipProfile implements java.lang.Cloneable android.os.Parcelable java.io.Serializable {
-    method public int describeContents();
-    method public String getAuthUserName();
-    method public boolean getAutoRegistration();
-    method public String getDisplayName();
-    method public String getPassword();
-    method public int getPort();
-    method public String getProfileName();
-    method public String getProtocol();
-    method public String getProxyAddress();
-    method public boolean getSendKeepAlive();
-    method public String getSipDomain();
-    method public String getUriString();
-    method public String getUserName();
-    method public void setCallingUid(int);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.net.sip.SipProfile> CREATOR;
+  @Deprecated public class SipProfile implements java.lang.Cloneable android.os.Parcelable java.io.Serializable {
+    method @Deprecated public int describeContents();
+    method @Deprecated public String getAuthUserName();
+    method @Deprecated public boolean getAutoRegistration();
+    method @Deprecated public String getDisplayName();
+    method @Deprecated public String getPassword();
+    method @Deprecated public int getPort();
+    method @Deprecated public String getProfileName();
+    method @Deprecated public String getProtocol();
+    method @Deprecated public String getProxyAddress();
+    method @Deprecated public boolean getSendKeepAlive();
+    method @Deprecated public String getSipDomain();
+    method @Deprecated public String getUriString();
+    method @Deprecated public String getUserName();
+    method @Deprecated public void setCallingUid(int);
+    method @Deprecated public void writeToParcel(android.os.Parcel, int);
+    field @Deprecated public static final android.os.Parcelable.Creator<android.net.sip.SipProfile> CREATOR;
   }
 
-  public static class SipProfile.Builder {
-    ctor public SipProfile.Builder(android.net.sip.SipProfile);
-    ctor public SipProfile.Builder(String) throws java.text.ParseException;
-    ctor public SipProfile.Builder(String, String) throws java.text.ParseException;
-    method public android.net.sip.SipProfile build();
-    method public android.net.sip.SipProfile.Builder setAuthUserName(String);
-    method public android.net.sip.SipProfile.Builder setAutoRegistration(boolean);
-    method public android.net.sip.SipProfile.Builder setDisplayName(String);
-    method public android.net.sip.SipProfile.Builder setOutboundProxy(String);
-    method public android.net.sip.SipProfile.Builder setPassword(String);
-    method public android.net.sip.SipProfile.Builder setPort(int) throws java.lang.IllegalArgumentException;
-    method public android.net.sip.SipProfile.Builder setProfileName(String);
-    method public android.net.sip.SipProfile.Builder setProtocol(String) throws java.lang.IllegalArgumentException;
-    method public android.net.sip.SipProfile.Builder setSendKeepAlive(boolean);
+  @Deprecated public static class SipProfile.Builder {
+    ctor @Deprecated public SipProfile.Builder(android.net.sip.SipProfile);
+    ctor @Deprecated public SipProfile.Builder(String) throws java.text.ParseException;
+    ctor @Deprecated public SipProfile.Builder(String, String) throws java.text.ParseException;
+    method @Deprecated public android.net.sip.SipProfile build();
+    method @Deprecated public android.net.sip.SipProfile.Builder setAuthUserName(String);
+    method @Deprecated public android.net.sip.SipProfile.Builder setAutoRegistration(boolean);
+    method @Deprecated public android.net.sip.SipProfile.Builder setDisplayName(String);
+    method @Deprecated public android.net.sip.SipProfile.Builder setOutboundProxy(String);
+    method @Deprecated public android.net.sip.SipProfile.Builder setPassword(String);
+    method @Deprecated public android.net.sip.SipProfile.Builder setPort(int) throws java.lang.IllegalArgumentException;
+    method @Deprecated public android.net.sip.SipProfile.Builder setProfileName(String);
+    method @Deprecated public android.net.sip.SipProfile.Builder setProtocol(String) throws java.lang.IllegalArgumentException;
+    method @Deprecated public android.net.sip.SipProfile.Builder setSendKeepAlive(boolean);
   }
 
-  public interface SipRegistrationListener {
-    method public void onRegistering(String);
-    method public void onRegistrationDone(String, long);
-    method public void onRegistrationFailed(String, int, String);
+  @Deprecated public interface SipRegistrationListener {
+    method @Deprecated public void onRegistering(String);
+    method @Deprecated public void onRegistrationDone(String, long);
+    method @Deprecated public void onRegistrationFailed(String, int, String);
   }
 
-  public final class SipSession {
-    method public void answerCall(String, int);
-    method public void changeCall(String, int);
-    method public void endCall();
-    method public String getCallId();
-    method public String getLocalIp();
-    method public android.net.sip.SipProfile getLocalProfile();
-    method public android.net.sip.SipProfile getPeerProfile();
-    method public int getState();
-    method public boolean isInCall();
-    method public void makeCall(android.net.sip.SipProfile, String, int);
-    method public void register(int);
-    method public void setListener(android.net.sip.SipSession.Listener);
-    method public void unregister();
+  @Deprecated public final class SipSession {
+    method @Deprecated public void answerCall(String, int);
+    method @Deprecated public void changeCall(String, int);
+    method @Deprecated public void endCall();
+    method @Deprecated public String getCallId();
+    method @Deprecated public String getLocalIp();
+    method @Deprecated public android.net.sip.SipProfile getLocalProfile();
+    method @Deprecated public android.net.sip.SipProfile getPeerProfile();
+    method @Deprecated public int getState();
+    method @Deprecated public boolean isInCall();
+    method @Deprecated public void makeCall(android.net.sip.SipProfile, String, int);
+    method @Deprecated public void register(int);
+    method @Deprecated public void setListener(android.net.sip.SipSession.Listener);
+    method @Deprecated public void unregister();
   }
 
-  public static class SipSession.Listener {
-    ctor public SipSession.Listener();
-    method public void onCallBusy(android.net.sip.SipSession);
-    method public void onCallChangeFailed(android.net.sip.SipSession, int, String);
-    method public void onCallEnded(android.net.sip.SipSession);
-    method public void onCallEstablished(android.net.sip.SipSession, String);
-    method public void onCalling(android.net.sip.SipSession);
-    method public void onError(android.net.sip.SipSession, int, String);
-    method public void onRegistering(android.net.sip.SipSession);
-    method public void onRegistrationDone(android.net.sip.SipSession, int);
-    method public void onRegistrationFailed(android.net.sip.SipSession, int, String);
-    method public void onRegistrationTimeout(android.net.sip.SipSession);
-    method public void onRinging(android.net.sip.SipSession, android.net.sip.SipProfile, String);
-    method public void onRingingBack(android.net.sip.SipSession);
+  @Deprecated public static class SipSession.Listener {
+    ctor @Deprecated public SipSession.Listener();
+    method @Deprecated public void onCallBusy(android.net.sip.SipSession);
+    method @Deprecated public void onCallChangeFailed(android.net.sip.SipSession, int, String);
+    method @Deprecated public void onCallEnded(android.net.sip.SipSession);
+    method @Deprecated public void onCallEstablished(android.net.sip.SipSession, String);
+    method @Deprecated public void onCalling(android.net.sip.SipSession);
+    method @Deprecated public void onError(android.net.sip.SipSession, int, String);
+    method @Deprecated public void onRegistering(android.net.sip.SipSession);
+    method @Deprecated public void onRegistrationDone(android.net.sip.SipSession, int);
+    method @Deprecated public void onRegistrationFailed(android.net.sip.SipSession, int, String);
+    method @Deprecated public void onRegistrationTimeout(android.net.sip.SipSession);
+    method @Deprecated public void onRinging(android.net.sip.SipSession, android.net.sip.SipProfile, String);
+    method @Deprecated public void onRingingBack(android.net.sip.SipSession);
   }
 
-  public static class SipSession.State {
-    method public static String toString(int);
-    field public static final int DEREGISTERING = 2; // 0x2
-    field public static final int INCOMING_CALL = 3; // 0x3
-    field public static final int INCOMING_CALL_ANSWERING = 4; // 0x4
-    field public static final int IN_CALL = 8; // 0x8
-    field public static final int NOT_DEFINED = 101; // 0x65
-    field public static final int OUTGOING_CALL = 5; // 0x5
-    field public static final int OUTGOING_CALL_CANCELING = 7; // 0x7
-    field public static final int OUTGOING_CALL_RING_BACK = 6; // 0x6
-    field public static final int PINGING = 9; // 0x9
-    field public static final int READY_TO_CALL = 0; // 0x0
-    field public static final int REGISTERING = 1; // 0x1
+  @Deprecated public static class SipSession.State {
+    method @Deprecated public static String toString(int);
+    field @Deprecated public static final int DEREGISTERING = 2; // 0x2
+    field @Deprecated public static final int INCOMING_CALL = 3; // 0x3
+    field @Deprecated public static final int INCOMING_CALL_ANSWERING = 4; // 0x4
+    field @Deprecated public static final int IN_CALL = 8; // 0x8
+    field @Deprecated public static final int NOT_DEFINED = 101; // 0x65
+    field @Deprecated public static final int OUTGOING_CALL = 5; // 0x5
+    field @Deprecated public static final int OUTGOING_CALL_CANCELING = 7; // 0x7
+    field @Deprecated public static final int OUTGOING_CALL_RING_BACK = 6; // 0x6
+    field @Deprecated public static final int PINGING = 9; // 0x9
+    field @Deprecated public static final int READY_TO_CALL = 0; // 0x0
+    field @Deprecated public static final int REGISTERING = 1; // 0x1
   }
 
 }
@@ -38399,22 +38395,22 @@
     method public final void conferenceRemoteConnections(android.telecom.RemoteConnection, android.telecom.RemoteConnection);
     method public final void connectionServiceFocusReleased();
     method @Nullable public final android.telecom.RemoteConference createRemoteIncomingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
-    method public final android.telecom.RemoteConnection createRemoteIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+    method @Nullable public final android.telecom.RemoteConnection createRemoteIncomingConnection(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.ConnectionRequest);
     method @Nullable public final android.telecom.RemoteConference createRemoteOutgoingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
-    method public final android.telecom.RemoteConnection createRemoteOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+    method @Nullable public final android.telecom.RemoteConnection createRemoteOutgoingConnection(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.ConnectionRequest);
     method public final java.util.Collection<android.telecom.Conference> getAllConferences();
     method public final java.util.Collection<android.telecom.Connection> getAllConnections();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public void onConference(android.telecom.Connection, android.telecom.Connection);
     method public void onConnectionServiceFocusGained();
     method public void onConnectionServiceFocusLost();
-    method @Nullable public android.telecom.Conference onCreateIncomingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
+    method @Nullable public android.telecom.Conference onCreateIncomingConference(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.ConnectionRequest);
     method public void onCreateIncomingConferenceFailed(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
     method public android.telecom.Connection onCreateIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public void onCreateIncomingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public android.telecom.Connection onCreateIncomingHandoverConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
-    method @Nullable public android.telecom.Conference onCreateOutgoingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
-    method public void onCreateOutgoingConferenceFailed(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
+    method @Nullable public android.telecom.Conference onCreateOutgoingConference(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.ConnectionRequest);
+    method public void onCreateOutgoingConferenceFailed(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.ConnectionRequest);
     method public android.telecom.Connection onCreateOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public void onCreateOutgoingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
     method public android.telecom.Connection onCreateOutgoingHandoverConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
@@ -40325,29 +40321,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 +40357,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 +40366,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();
@@ -40929,6 +40837,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 +41035,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 +41059,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..7c6ff8e 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 {
@@ -16,8 +20,24 @@
 
 }
 
+package android.content {
+
+  public class Intent implements java.lang.Cloneable android.os.Parcelable {
+    field public static final String ACTION_CLEAR_DNS_CACHE = "android.intent.action.CLEAR_DNS_CACHE";
+  }
+
+}
+
 package android.net {
 
+  public final class EthernetNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
+    ctor public EthernetNetworkSpecifier(@NonNull String);
+    method public int describeContents();
+    method @Nullable public String getInterfaceName();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkSpecifier> CREATOR;
+  }
+
   public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
     method public int getResourceId();
   }
@@ -52,10 +72,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 d84f202..acce0a8 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -6373,22 +6373,22 @@
 
 package android.net.sip {
 
-  public class SipAudioCall {
-    method @Nullable public android.net.rtp.AudioGroup getAudioGroup();
-    method public void setAudioGroup(@NonNull android.net.rtp.AudioGroup);
+  @Deprecated public class SipAudioCall {
+    method @Deprecated @Nullable public android.net.rtp.AudioGroup getAudioGroup();
+    method @Deprecated public void setAudioGroup(@NonNull android.net.rtp.AudioGroup);
   }
 
-  public class SipManager {
-    method @NonNull public java.util.List<android.net.sip.SipProfile> getProfiles() throws android.net.sip.SipException;
-    field public static final String ACTION_SIP_CALL_OPTION_CHANGED = "android.net.sip.action.SIP_CALL_OPTION_CHANGED";
-    field public static final String ACTION_SIP_INCOMING_CALL = "android.net.sip.action.SIP_INCOMING_CALL";
-    field public static final String ACTION_SIP_REMOVE_PROFILE = "android.net.sip.action.SIP_REMOVE_PROFILE";
-    field public static final String ACTION_SIP_SERVICE_UP = "android.net.sip.action.SIP_SERVICE_UP";
-    field public static final String ACTION_START_SIP = "android.net.sip.action.START_SIP";
+  @Deprecated public class SipManager {
+    method @Deprecated @NonNull public java.util.List<android.net.sip.SipProfile> getProfiles() throws android.net.sip.SipException;
+    field @Deprecated public static final String ACTION_SIP_CALL_OPTION_CHANGED = "android.net.sip.action.SIP_CALL_OPTION_CHANGED";
+    field @Deprecated public static final String ACTION_SIP_INCOMING_CALL = "android.net.sip.action.SIP_INCOMING_CALL";
+    field @Deprecated public static final String ACTION_SIP_REMOVE_PROFILE = "android.net.sip.action.SIP_REMOVE_PROFILE";
+    field @Deprecated public static final String ACTION_SIP_SERVICE_UP = "android.net.sip.action.SIP_SERVICE_UP";
+    field @Deprecated public static final String ACTION_START_SIP = "android.net.sip.action.START_SIP";
   }
 
-  public class SipProfile implements java.lang.Cloneable android.os.Parcelable java.io.Serializable {
-    method public int getCallingUid();
+  @Deprecated public class SipProfile implements java.lang.Cloneable android.os.Parcelable java.io.Serializable {
+    method @Deprecated public int getCallingUid();
   }
 
 }
@@ -6409,12 +6409,12 @@
 package android.net.vcn {
 
   public class VcnManager {
-    method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnNetworkPolicyListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnNetworkPolicyListener);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnNetworkPolicyChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener);
     method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.vcn.VcnNetworkPolicyResult applyVcnNetworkPolicy(@NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties);
-    method public void removeVcnNetworkPolicyListener(@NonNull android.net.vcn.VcnManager.VcnNetworkPolicyListener);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void removeVcnNetworkPolicyChangeListener(@NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener);
   }
 
-  public static interface VcnManager.VcnNetworkPolicyListener {
+  public static interface VcnManager.VcnNetworkPolicyChangeListener {
     method public void onPolicyChanged();
   }
 
@@ -9356,6 +9356,10 @@
     field public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool";
   }
 
+  public static final class CarrierConfigManager.Ims {
+    field public static final String KEY_PUBLISH_SERVICE_DESC_FEATURE_TAG_MAP_OVERRIDE_STRING_ARRAY = "ims.publish_service_desc_feature_tag_map_override_string_array";
+  }
+
   public static final class CarrierConfigManager.Wifi {
     field public static final String KEY_HOTSPOT_MAX_CLIENT_COUNT = "wifi.hotspot_maximum_client_count";
     field public static final String KEY_PREFIX = "wifi.";
@@ -9607,51 +9611,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 +9630,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 +9963,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 +10183,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);
@@ -10558,7 +10569,6 @@
   }
 
   public final class EpsBearerQosSessionAttributes implements android.os.Parcelable android.net.QosSessionAttributes {
-    method @NonNull public static android.telephony.data.EpsBearerQosSessionAttributes create(@NonNull android.os.Parcel);
     method public int describeContents();
     method public long getGuaranteedDownlinkBitRate();
     method public long getGuaranteedUplinkBitRate();
@@ -11536,6 +11546,7 @@
     method public void onAutoConfigurationErrorReceived(int, @NonNull String);
     method public void onConfigurationChanged(@NonNull byte[]);
     method public void onConfigurationReset();
+    method public void onPreProvisioningReceived(@NonNull byte[]);
     method public void onRemoved();
   }
 
@@ -11560,7 +11571,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 +11598,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 +11654,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
@@ -12005,6 +12016,7 @@
     method public int getConfigInt(int);
     method public String getConfigString(int);
     method public final void notifyAutoConfigurationErrorReceived(int, @NonNull String);
+    method public final void notifyPreProvisioningReceived(@NonNull byte[]);
     method public final void notifyProvisionedValueChanged(int, int);
     method public final void notifyProvisionedValueChanged(int, String);
     method public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean);
@@ -12120,7 +12132,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
@@ -12288,6 +12300,7 @@
 package android.uwb {
 
   public final class AngleMeasurement implements android.os.Parcelable {
+    ctor public AngleMeasurement(double, double, double);
     method public int describeContents();
     method @FloatRange(from=0.0, to=1.0) public double getConfidenceLevel();
     method @FloatRange(from=0.0, to=3.141592653589793) public double getErrorRadians();
@@ -12296,14 +12309,6 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.uwb.AngleMeasurement> CREATOR;
   }
 
-  public static final class AngleMeasurement.Builder {
-    ctor public AngleMeasurement.Builder();
-    method @NonNull public android.uwb.AngleMeasurement build();
-    method @NonNull public android.uwb.AngleMeasurement.Builder setConfidenceLevel(double);
-    method @NonNull public android.uwb.AngleMeasurement.Builder setErrorRadians(double);
-    method @NonNull public android.uwb.AngleMeasurement.Builder setRadians(double);
-  }
-
   public final class AngleOfArrivalMeasurement implements android.os.Parcelable {
     method public int describeContents();
     method @Nullable public android.uwb.AngleMeasurement getAltitude();
@@ -12313,10 +12318,9 @@
   }
 
   public static final class AngleOfArrivalMeasurement.Builder {
-    ctor public AngleOfArrivalMeasurement.Builder();
+    ctor public AngleOfArrivalMeasurement.Builder(@NonNull android.uwb.AngleMeasurement);
     method @NonNull public android.uwb.AngleOfArrivalMeasurement build();
     method @NonNull public android.uwb.AngleOfArrivalMeasurement.Builder setAltitude(@NonNull android.uwb.AngleMeasurement);
-    method @NonNull public android.uwb.AngleOfArrivalMeasurement.Builder setAzimuth(@NonNull android.uwb.AngleMeasurement);
   }
 
   public final class DistanceMeasurement implements android.os.Parcelable {
@@ -12416,7 +12420,7 @@
   public final class UwbManager {
     method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public long elapsedRealtimeResolutionNanos();
     method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public android.os.PersistableBundle getSpecificationInfo();
-    method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public AutoCloseable openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback);
+    method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public android.os.CancellationSignal openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback);
     method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void registerAdapterStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.uwb.UwbManager.AdapterStateCallback);
     method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void unregisterAdapterStateCallback(@NonNull android.uwb.UwbManager.AdapterStateCallback);
   }
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/content/Intent.java b/core/java/android/content/Intent.java
index 6bfc12d..4d68e90 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2329,6 +2329,7 @@
      * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final String ACTION_CLEAR_DNS_CACHE = "android.intent.action.CLEAR_DNS_CACHE";
     /**
      * Alarm Changed Action: This is broadcast when the AlarmClock
diff --git a/core/java/android/ddm/DdmHandleHeap.java b/core/java/android/ddm/DdmHandleHeap.java
index e24aeb2..8fa2352 100644
--- a/core/java/android/ddm/DdmHandleHeap.java
+++ b/core/java/android/ddm/DdmHandleHeap.java
@@ -30,15 +30,7 @@
  */
 public class DdmHandleHeap extends ChunkHandler {
 
-    public static final int CHUNK_HPIF = type("HPIF");
-    public static final int CHUNK_HPSG = type("HPSG");
-    public static final int CHUNK_HPDU = type("HPDU");
-    public static final int CHUNK_HPDS = type("HPDS");
-    public static final int CHUNK_NHSG = type("NHSG");
     public static final int CHUNK_HPGC = type("HPGC");
-    public static final int CHUNK_REAE = type("REAE");
-    public static final int CHUNK_REAQ = type("REAQ");
-    public static final int CHUNK_REAL = type("REAL");
 
     private static DdmHandleHeap mInstance = new DdmHandleHeap();
 
@@ -50,15 +42,7 @@
      * Register for the messages we're interested in.
      */
     public static void register() {
-        DdmServer.registerHandler(CHUNK_HPIF, mInstance);
-        DdmServer.registerHandler(CHUNK_HPSG, mInstance);
-        DdmServer.registerHandler(CHUNK_HPDU, mInstance);
-        DdmServer.registerHandler(CHUNK_HPDS, mInstance);
-        DdmServer.registerHandler(CHUNK_NHSG, mInstance);
         DdmServer.registerHandler(CHUNK_HPGC, mInstance);
-        DdmServer.registerHandler(CHUNK_REAE, mInstance);
-        DdmServer.registerHandler(CHUNK_REAQ, mInstance);
-        DdmServer.registerHandler(CHUNK_REAL, mInstance);
     }
 
     /**
@@ -81,24 +65,8 @@
             Log.v("ddm-heap", "Handling " + name(request.type) + " chunk");
         int type = request.type;
 
-        if (type == CHUNK_HPIF) {
-            return handleHPIF(request);
-        } else if (type == CHUNK_HPSG) {
-            return handleHPSGNHSG(request, false);
-        } else if (type == CHUNK_HPDU) {
-            return handleHPDU(request);
-        } else if (type == CHUNK_HPDS) {
-            return handleHPDS(request);
-        } else if (type == CHUNK_NHSG) {
-            return handleHPSGNHSG(request, true);
-        } else if (type == CHUNK_HPGC) {
+        if (type == CHUNK_HPGC) {
             return handleHPGC(request);
-        } else if (type == CHUNK_REAE) {
-            return handleREAE(request);
-        } else if (type == CHUNK_REAQ) {
-            return handleREAQ(request);
-        } else if (type == CHUNK_REAL) {
-            return handleREAL(request);
         } else {
             throw new RuntimeException("Unknown packet "
                 + ChunkHandler.name(type));
@@ -106,112 +74,6 @@
     }
 
     /*
-     * Handle a "HeaP InFo" request.
-     */
-    private Chunk handleHPIF(Chunk request) {
-        ByteBuffer in = wrapChunk(request);
-
-        int when = in.get();
-        if (false)
-            Log.v("ddm-heap", "Heap segment enable: when=" + when);
-
-        boolean ok = DdmVmInternal.heapInfoNotify(when);
-        if (!ok) {
-            return createFailChunk(1, "Unsupported HPIF what");
-        } else {
-            return null;        // empty response
-        }
-    }
-
-    /*
-     * Handle a "HeaP SeGment" or "Native Heap SeGment" request.
-     */
-    private Chunk handleHPSGNHSG(Chunk request, boolean isNative) {
-        ByteBuffer in = wrapChunk(request);
-
-        int when = in.get();
-        int what = in.get();
-        if (false)
-            Log.v("ddm-heap", "Heap segment enable: when=" + when
-                + ", what=" + what + ", isNative=" + isNative);
-
-        boolean ok = DdmVmInternal.heapSegmentNotify(when, what, isNative);
-        if (!ok) {
-            return createFailChunk(1, "Unsupported HPSG what/when");
-        } else {
-            // TODO: if "when" is non-zero and we want to see a dump
-            //       right away, initiate a GC.
-            return null;        // empty response
-        }
-    }
-
-    /*
-     * Handle a "HeaP DUmp" request.
-     *
-     * This currently just returns a result code.  We could pull up
-     * the entire contents of the file and return them, but hprof dump
-     * files can be a few megabytes.
-     */
-    private Chunk handleHPDU(Chunk request) {
-        ByteBuffer in = wrapChunk(request);
-        byte result;
-
-        /* get the filename for the output file */
-        int len = in.getInt();
-        String fileName = getString(in, len);
-        if (false)
-            Log.d("ddm-heap", "Heap dump: file='" + fileName + "'");
-
-        try {
-            Debug.dumpHprofData(fileName);
-            result = 0;
-        } catch (UnsupportedOperationException uoe) {
-            Log.w("ddm-heap", "hprof dumps not supported in this VM");
-            result = -1;
-        } catch (IOException ioe) {
-            result = -1;
-        } catch (RuntimeException re) {
-            result = -1;
-        }
-
-        /* create a non-empty reply so the handler fires on completion */
-        byte[] reply = { result };
-        return new Chunk(CHUNK_HPDU, reply, 0, reply.length);
-    }
-
-    /*
-     * Handle a "HeaP Dump Streaming" request.
-     *
-     * This tells the VM to create a heap dump and send it directly to
-     * DDMS.  The dumps are large enough that we don't want to copy the
-     * data into a byte[] and send it from here.
-     */
-    private Chunk handleHPDS(Chunk request) {
-        ByteBuffer in = wrapChunk(request);
-        byte result;
-
-        /* get the filename for the output file */
-        if (false)
-            Log.d("ddm-heap", "Heap dump: [DDMS]");
-
-        String failMsg = null;
-        try {
-            Debug.dumpHprofDataDdms();
-        } catch (UnsupportedOperationException uoe) {
-            failMsg = "hprof dumps not supported in this VM";
-        } catch (RuntimeException re) {
-            failMsg = "Exception: " + re.getMessage();
-        }
-
-        if (failMsg != null) {
-            Log.w("ddm-heap", failMsg);
-            return createFailChunk(1, failMsg);
-        } else {
-            return null;
-        }
-    }
-
-    /*
      * Handle a "HeaP Garbage Collection" request.
      */
     private Chunk handleHPGC(Chunk request) {
@@ -223,47 +85,4 @@
 
         return null;        // empty response
     }
-
-    /*
-     * Handle a "REcent Allocation Enable" request.
-     */
-    private Chunk handleREAE(Chunk request) {
-        ByteBuffer in = wrapChunk(request);
-        boolean enable;
-
-        enable = (in.get() != 0);
-
-        if (false)
-            Log.d("ddm-heap", "Recent allocation enable request: " + enable);
-
-        DdmVmInternal.enableRecentAllocations(enable);
-
-        return null;        // empty response
-    }
-
-    /*
-     * Handle a "REcent Allocation Query" request.
-     */
-    private Chunk handleREAQ(Chunk request) {
-        //ByteBuffer in = wrapChunk(request);
-
-        byte[] reply = new byte[1];
-        reply[0] = DdmVmInternal.getRecentAllocationStatus() ? (byte)1 :(byte)0;
-        return new Chunk(CHUNK_REAQ, reply, 0, reply.length);
-    }
-
-    /*
-     * Handle a "REcent ALlocations" request.
-     */
-    private Chunk handleREAL(Chunk request) {
-        //ByteBuffer in = wrapChunk(request);
-
-        if (false)
-            Log.d("ddm-heap", "Recent allocations request");
-
-        /* generate the reply in a ready-to-go format */
-        byte[] reply = DdmVmInternal.getRecentAllocations();
-        return new Chunk(CHUNK_REAL, reply, 0, reply.length);
-    }
 }
-
diff --git a/core/java/android/ddm/DdmHandleThread.java b/core/java/android/ddm/DdmHandleThread.java
deleted file mode 100644
index 613ab75..0000000
--- a/core/java/android/ddm/DdmHandleThread.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2007 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.ddm;
-
-import org.apache.harmony.dalvik.ddmc.Chunk;
-import org.apache.harmony.dalvik.ddmc.ChunkHandler;
-import org.apache.harmony.dalvik.ddmc.DdmServer;
-import org.apache.harmony.dalvik.ddmc.DdmVmInternal;
-import android.util.Log;
-import java.nio.ByteBuffer;
-
-/**
- * Handle thread-related traffic.
- */
-public class DdmHandleThread extends ChunkHandler {
-
-    public static final int CHUNK_THEN = type("THEN");
-    public static final int CHUNK_THCR = type("THCR");
-    public static final int CHUNK_THDE = type("THDE");
-    public static final int CHUNK_THST = type("THST");
-    public static final int CHUNK_STKL = type("STKL");
-
-    private static DdmHandleThread mInstance = new DdmHandleThread();
-
-
-    /* singleton, do not instantiate */
-    private DdmHandleThread() {}
-
-    /**
-     * Register for the messages we're interested in.
-     */
-    public static void register() {
-        DdmServer.registerHandler(CHUNK_THEN, mInstance);
-        DdmServer.registerHandler(CHUNK_THST, mInstance);
-        DdmServer.registerHandler(CHUNK_STKL, mInstance);
-    }
-
-    /**
-     * Called when the DDM server connects.  The handler is allowed to
-     * send messages to the server.
-     */
-    public void connected() {}
-
-    /**
-     * Called when the DDM server disconnects.  Can be used to disable
-     * periodic transmissions or clean up saved state.
-     */
-    public void disconnected() {}
-
-    /**
-     * Handle a chunk of data.
-     */
-    public Chunk handleChunk(Chunk request) {
-        if (false)
-            Log.v("ddm-thread", "Handling " + name(request.type) + " chunk");
-        int type = request.type;
-
-        if (type == CHUNK_THEN) {
-            return handleTHEN(request);
-        } else if (type == CHUNK_THST) {
-            return handleTHST(request);
-        } else if (type == CHUNK_STKL) {
-            return handleSTKL(request);
-        } else {
-            throw new RuntimeException("Unknown packet "
-                + ChunkHandler.name(type));
-        }
-    }
-
-    /*
-     * Handle a "THread notification ENable" request.
-     */
-    private Chunk handleTHEN(Chunk request) {
-        ByteBuffer in = wrapChunk(request);
-
-        boolean enable = (in.get() != 0);
-        //Log.i("ddm-thread", "Thread notify enable: " + enable);
-
-        DdmVmInternal.threadNotify(enable);
-        return null;        // empty response
-    }
-
-    /*
-     * Handle a "THread STatus" request.  This is constructed by the VM.
-     */
-    private Chunk handleTHST(Chunk request) {
-        ByteBuffer in = wrapChunk(request);
-        // currently nothing to read from "in"
-
-        //Log.d("ddm-thread", "Thread status request");
-
-        byte[] status = DdmVmInternal.getThreadStats();
-        if (status != null)
-            return new Chunk(CHUNK_THST, status, 0, status.length);
-        else
-            return createFailChunk(1, "Can't build THST chunk");
-    }
-
-    /*
-     * Handle a STacK List request.
-     *
-     * This is done by threadId, which isn't great since those are
-     * recycled.  We need a thread serial ID.  The Linux tid is an okay
-     * answer as it's unlikely to recycle at the exact wrong moment.
-     * However, we're using the short threadId in THST messages, so we
-     * use them here for consistency.  (One thought is to keep the current
-     * thread ID in the low 16 bits and somehow serialize the top 16 bits.)
-     */
-    private Chunk handleSTKL(Chunk request) {
-        ByteBuffer in = wrapChunk(request);
-        int threadId;
-
-        threadId = in.getInt();
-
-        //Log.d("ddm-thread", "Stack list request " + threadId);
-
-        StackTraceElement[] trace = DdmVmInternal.getStackTraceById(threadId);
-        if (trace == null) {
-            return createFailChunk(1, "Stack trace unavailable");
-        } else {
-            return createStackChunk(trace, threadId);
-        }
-    }
-
-    /*
-     * Serialize a StackTraceElement[] into an STKL chunk.
-     *
-     * We include the threadId in the response so the other side doesn't have
-     * to match up requests and responses as carefully.
-     */
-    private Chunk createStackChunk(StackTraceElement[] trace, int threadId) {
-        int bufferSize = 0;
-
-        bufferSize += 4;            // version, flags, whatever
-        bufferSize += 4;            // thread ID
-        bufferSize += 4;            // frame count
-        for (StackTraceElement elem : trace) {
-            bufferSize += 4 + elem.getClassName().length() * 2;
-            bufferSize += 4 + elem.getMethodName().length() * 2;
-            bufferSize += 4;
-            if (elem.getFileName() != null)
-                bufferSize += elem.getFileName().length() * 2;
-            bufferSize += 4;        // line number
-        }
-
-        ByteBuffer out = ByteBuffer.allocate(bufferSize);
-        out.putInt(0);
-        out.putInt(threadId);
-        out.putInt(trace.length);
-        for (StackTraceElement elem : trace) {
-            out.putInt(elem.getClassName().length());
-            putString(out, elem.getClassName());
-            out.putInt(elem.getMethodName().length());
-            putString(out, elem.getMethodName());
-            if (elem.getFileName() != null) {
-                out.putInt(elem.getFileName().length());
-                putString(out, elem.getFileName());
-            } else {
-                out.putInt(0);
-            }
-            out.putInt(elem.getLineNumber());
-        }
-
-        return new Chunk(CHUNK_STKL, out);
-    }
-}
-
diff --git a/core/java/android/ddm/DdmRegister.java b/core/java/android/ddm/DdmRegister.java
index e0faa51..ca10312 100644
--- a/core/java/android/ddm/DdmRegister.java
+++ b/core/java/android/ddm/DdmRegister.java
@@ -16,9 +16,10 @@
 
 package android.ddm;
 
-import org.apache.harmony.dalvik.ddmc.DdmServer;
 import android.util.Log;
 
+import org.apache.harmony.dalvik.ddmc.DdmServer;
+
 /**
  * Just a place to stick handler registrations, instead of scattering
  * them around.
@@ -46,7 +47,6 @@
         if (false)
             Log.v("ddm", "Registering DDM message handlers");
         DdmHandleHello.register();
-        DdmHandleThread.register();
         DdmHandleHeap.register();
         DdmHandleNativeHeap.register();
         DdmHandleProfiling.register();
diff --git a/core/java/android/net/EthernetNetworkSpecifier.java b/core/java/android/net/EthernetNetworkSpecifier.java
new file mode 100644
index 0000000..e168588
--- /dev/null
+++ b/core/java/android/net/EthernetNetworkSpecifier.java
@@ -0,0 +1,97 @@
+/*
+ * 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;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+
+/**
+ * A {@link NetworkSpecifier} used to identify ethernet interfaces.
+ *
+ * @see EthernetManager
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public final class EthernetNetworkSpecifier extends NetworkSpecifier implements Parcelable {
+
+    /**
+     * Name of the network interface.
+     */
+    @NonNull
+    private final String mInterfaceName;
+
+    public EthernetNetworkSpecifier(@NonNull String interfaceName) {
+        Preconditions.checkStringNotEmpty(interfaceName);
+        mInterfaceName = interfaceName;
+    }
+
+    // This may be null in the future to support specifiers based on data other than the interface
+    // name.
+    @Nullable
+    public String getInterfaceName() {
+        return mInterfaceName;
+    }
+
+    @Override
+    public boolean canBeSatisfiedBy(@Nullable NetworkSpecifier other) {
+        return equals(other);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (!(o instanceof EthernetNetworkSpecifier)) return false;
+        return TextUtils.equals(mInterfaceName, ((EthernetNetworkSpecifier) o).mInterfaceName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(mInterfaceName);
+    }
+
+    @Override
+    public String toString() {
+        return "EthernetNetworkSpecifier (" + mInterfaceName + ")";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(mInterfaceName);
+    }
+
+    public static final @NonNull Parcelable.Creator<EthernetNetworkSpecifier> CREATOR =
+            new Parcelable.Creator<EthernetNetworkSpecifier>() {
+        public EthernetNetworkSpecifier createFromParcel(Parcel in) {
+            return new EthernetNetworkSpecifier(in.readString());
+        }
+        public EthernetNetworkSpecifier[] newArray(int size) {
+            return new EthernetNetworkSpecifier[size];
+        }
+    };
+}
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/VcnManager.java b/core/java/android/net/vcn/VcnManager.java
index 8ebf757..062438c 100644
--- a/core/java/android/net/vcn/VcnManager.java
+++ b/core/java/android/net/vcn/VcnManager.java
@@ -73,7 +73,8 @@
 public class VcnManager {
     @NonNull private static final String TAG = VcnManager.class.getSimpleName();
 
-    private static final Map<VcnNetworkPolicyListener, VcnUnderlyingNetworkPolicyListenerBinder>
+    private static final Map<
+                    VcnNetworkPolicyChangeListener, VcnUnderlyingNetworkPolicyListenerBinder>
             REGISTERED_POLICY_LISTENERS = new ConcurrentHashMap<>();
 
     @NonNull private final Context mContext;
@@ -93,13 +94,13 @@
     }
 
     /**
-     * Get all currently registered VcnNetworkPolicyListeners for testing purposes.
+     * Get all currently registered VcnNetworkPolicyChangeListeners for testing purposes.
      *
      * @hide
      */
     @VisibleForTesting(visibility = Visibility.PRIVATE)
     @NonNull
-    public static Map<VcnNetworkPolicyListener, VcnUnderlyingNetworkPolicyListenerBinder>
+    public static Map<VcnNetworkPolicyChangeListener, VcnUnderlyingNetworkPolicyListenerBinder>
             getAllPolicyListeners() {
         return Collections.unmodifiableMap(REGISTERED_POLICY_LISTENERS);
     }
@@ -162,14 +163,14 @@
     }
 
     // TODO(b/180537630): remove all VcnUnderlyingNetworkPolicyListener refs once Telephony is using
-    // the new VcnNetworkPolicyListener API
+    // the new VcnNetworkPolicyChangeListener API
     /**
      * VcnUnderlyingNetworkPolicyListener is the interface through which internal system components
      * can register to receive updates for VCN-underlying Network policies from the System Server.
      *
      * @hide
      */
-    public interface VcnUnderlyingNetworkPolicyListener extends VcnNetworkPolicyListener {}
+    public interface VcnUnderlyingNetworkPolicyListener extends VcnNetworkPolicyChangeListener {}
 
     /**
      * Add a listener for VCN-underlying network policy updates.
@@ -185,7 +186,7 @@
     @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
     public void addVcnUnderlyingNetworkPolicyListener(
             @NonNull Executor executor, @NonNull VcnUnderlyingNetworkPolicyListener listener) {
-        addVcnNetworkPolicyListener(executor, listener);
+        addVcnNetworkPolicyChangeListener(executor, listener);
     }
 
     /**
@@ -198,7 +199,7 @@
      */
     public void removeVcnUnderlyingNetworkPolicyListener(
             @NonNull VcnUnderlyingNetworkPolicyListener listener) {
-        removeVcnNetworkPolicyListener(listener);
+        removeVcnNetworkPolicyChangeListener(listener);
     }
 
     /**
@@ -233,20 +234,20 @@
     }
 
     /**
-     * VcnNetworkPolicyListener is the interface through which internal system components (e.g.
-     * Network Factories) can register to receive updates for VCN-underlying Network policies from
-     * the System Server.
+     * VcnNetworkPolicyChangeListener is the interface through which internal system components
+     * (e.g. Network Factories) can register to receive updates for VCN-underlying Network policies
+     * from the System Server.
      *
      * <p>Any Network Factory that brings up Networks capable of being VCN-underlying Networks
-     * should register a VcnNetworkPolicyListener. VcnManager will then use this listener to notify
-     * the registrant when VCN Network policies change. Upon receiving this signal, the listener
-     * must check {@link VcnManager} for the current Network policy result for each of its Networks
-     * via {@link #applyVcnNetworkPolicy(NetworkCapabilities, LinkProperties)}.
+     * should register a VcnNetworkPolicyChangeListener. VcnManager will then use this listener to
+     * notify the registrant when VCN Network policies change. Upon receiving this signal, the
+     * listener must check {@link VcnManager} for the current Network policy result for each of its
+     * Networks via {@link #applyVcnNetworkPolicy(NetworkCapabilities, LinkProperties)}.
      *
      * @hide
      */
     @SystemApi
-    public interface VcnNetworkPolicyListener {
+    public interface VcnNetworkPolicyChangeListener {
         /**
          * Notifies the implementation that the VCN's underlying Network policy has changed.
          *
@@ -260,20 +261,21 @@
     /**
      * Add a listener for VCN-underlying Network policy updates.
      *
-     * <p>A {@link VcnNetworkPolicyListener} is eligible to begin receiving callbacks once it is
-     * registered. No callbacks are guaranteed upon registration.
+     * <p>A {@link VcnNetworkPolicyChangeListener} is eligible to begin receiving callbacks once it
+     * is registered. No callbacks are guaranteed upon registration.
      *
      * @param executor the Executor that will be used for invoking all calls to the specified
      *     Listener
-     * @param listener the VcnNetworkPolicyListener to be added
+     * @param listener the VcnNetworkPolicyChangeListener to be added
      * @throws SecurityException if the caller does not have permission NETWORK_FACTORY
-     * @throws IllegalStateException if the specified VcnNetworkPolicyListener is already registered
+     * @throws IllegalStateException if the specified VcnNetworkPolicyChangeListener is already
+     *     registered
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
-    public void addVcnNetworkPolicyListener(
-            @NonNull Executor executor, @NonNull VcnNetworkPolicyListener listener) {
+    public void addVcnNetworkPolicyChangeListener(
+            @NonNull Executor executor, @NonNull VcnNetworkPolicyChangeListener listener) {
         requireNonNull(executor, "executor must not be null");
         requireNonNull(listener, "listener must not be null");
 
@@ -292,15 +294,18 @@
     }
 
     /**
-     * Remove the specified VcnNetworkPolicyListener from VcnManager.
+     * Remove the specified VcnNetworkPolicyChangeListener from VcnManager.
      *
      * <p>If the specified listener is not currently registered, this is a no-op.
      *
-     * @param listener the VcnNetworkPolicyListener that will be removed
+     * @param listener the VcnNetworkPolicyChangeListener that will be removed
+     * @throws SecurityException if the caller does not have permission NETWORK_FACTORY
      * @hide
      */
     @SystemApi
-    public void removeVcnNetworkPolicyListener(@NonNull VcnNetworkPolicyListener listener) {
+    @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+    public void removeVcnNetworkPolicyChangeListener(
+            @NonNull VcnNetworkPolicyChangeListener listener) {
         requireNonNull(listener, "listener must not be null");
 
         VcnUnderlyingNetworkPolicyListenerBinder binder =
@@ -320,8 +325,9 @@
      * Applies the network policy for a {@link android.net.Network} with the given parameters.
      *
      * <p>Prior to a new NetworkAgent being registered, or upon notification that Carrier VCN policy
-     * may have changed via {@link VcnNetworkPolicyListener#onPolicyChanged()}, a Network Provider
-     * MUST poll for the updated Network policy based on that Network's capabilities and properties.
+     * may have changed via {@link VcnNetworkPolicyChangeListener#onPolicyChanged()}, a Network
+     * Provider MUST poll for the updated Network policy based on that Network's capabilities and
+     * properties.
      *
      * @param networkCapabilities the NetworkCapabilities to be used in determining the Network
      *     policy result for this Network.
@@ -532,17 +538,18 @@
     }
 
     /**
-     * Binder wrapper for added VcnNetworkPolicyListeners to receive signals from System Server.
+     * Binder wrapper for added VcnNetworkPolicyChangeListeners to receive signals from System
+     * Server.
      *
      * @hide
      */
     private static class VcnUnderlyingNetworkPolicyListenerBinder
             extends IVcnUnderlyingNetworkPolicyListener.Stub {
         @NonNull private final Executor mExecutor;
-        @NonNull private final VcnNetworkPolicyListener mListener;
+        @NonNull private final VcnNetworkPolicyChangeListener mListener;
 
         private VcnUnderlyingNetworkPolicyListenerBinder(
-                Executor executor, VcnNetworkPolicyListener listener) {
+                Executor executor, VcnNetworkPolicyChangeListener listener) {
             mExecutor = executor;
             mListener = listener;
         }
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/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/uwb/AngleMeasurement.java b/core/java/android/uwb/AngleMeasurement.java
index 9df213b..8c771ba 100644
--- a/core/java/android/uwb/AngleMeasurement.java
+++ b/core/java/android/uwb/AngleMeasurement.java
@@ -38,9 +38,30 @@
     private final double mErrorRadians;
     private final double mConfidenceLevel;
 
-    private AngleMeasurement(double radians, double errorRadians, double confidenceLevel) {
+    /**
+     * Constructs a new {@link AngleMeasurement} object
+     *
+     * @param radians the angle in radians
+     * @param errorRadians the error of the angle measurement in radians
+     * @param confidenceLevel confidence level of the angle measurement
+     *
+     * @throws IllegalArgumentException if the radians, errorRadians, or confidenceLevel is out of
+     *                                  allowed range
+     */
+    public AngleMeasurement(double radians, double errorRadians, double confidenceLevel) {
+        if (radians < -Math.PI || radians > Math.PI) {
+            throw new IllegalArgumentException("Invalid radians: " + radians);
+        }
         mRadians = radians;
+
+        if (errorRadians < 0.0 || errorRadians > Math.PI) {
+            throw new IllegalArgumentException("Invalid error radians: " + errorRadians);
+        }
         mErrorRadians = errorRadians;
+
+        if (confidenceLevel < 0.0 || confidenceLevel > 1.0) {
+            throw new IllegalArgumentException("Invalid confidence level: " + confidenceLevel);
+        }
         mConfidenceLevel = confidenceLevel;
     }
 
@@ -122,11 +143,7 @@
             new Creator<AngleMeasurement>() {
                 @Override
                 public AngleMeasurement createFromParcel(Parcel in) {
-                    Builder builder = new Builder();
-                    builder.setRadians(in.readDouble());
-                    builder.setErrorRadians(in.readDouble());
-                    builder.setConfidenceLevel(in.readDouble());
-                    return builder.build();
+                    return new AngleMeasurement(in.readDouble(), in.readDouble(), in.readDouble());
                 }
 
                 @Override
@@ -134,82 +151,4 @@
                     return new AngleMeasurement[size];
                 }
     };
-
-    /**
-     * Builder class for {@link AngleMeasurement}.
-     */
-    public static final class Builder {
-        private double mRadians = Double.NaN;
-        private double mErrorRadians = Double.NaN;
-        private double mConfidenceLevel = Double.NaN;
-
-        /**
-         * Set the angle in radians
-         *
-         * @param radians angle in radians
-         * @throws IllegalArgumentException if angle exceeds allowed limits of [-Math.PI, +Math.PI]
-         */
-        @NonNull
-        public Builder setRadians(double radians) {
-            if (radians < -Math.PI || radians > Math.PI) {
-                throw new IllegalArgumentException("Invalid radians: " + radians);
-            }
-            mRadians = radians;
-            return this;
-        }
-
-        /**
-         * Set the angle error in radians
-         *
-         * @param errorRadians error of the angle in radians
-         * @throws IllegalArgumentException if the error exceeds the allowed limits of [0, +Math.PI]
-         */
-        @NonNull
-        public Builder setErrorRadians(double errorRadians) {
-            if (errorRadians < 0.0 || errorRadians > Math.PI) {
-                throw new IllegalArgumentException(
-                        "Invalid error radians: " + errorRadians);
-            }
-            mErrorRadians = errorRadians;
-            return this;
-        }
-
-        /**
-         * Set the angle confidence level
-         *
-         * @param confidenceLevel level of confidence of the angle measurement
-         * @throws IllegalArgumentException if the error exceeds the allowed limits of [0.0, 1.0]
-         */
-        @NonNull
-        public Builder setConfidenceLevel(double confidenceLevel) {
-            if (confidenceLevel < 0.0 || confidenceLevel > 1.0) {
-                throw new IllegalArgumentException(
-                        "Invalid confidence level: " + confidenceLevel);
-            }
-            mConfidenceLevel = confidenceLevel;
-            return this;
-        }
-
-        /**
-         * Build the {@link AngleMeasurement} object
-         *
-         * @throws IllegalStateException if angle, error, or confidence values are missing
-         */
-        @NonNull
-        public AngleMeasurement build() {
-            if (Double.isNaN(mRadians)) {
-                throw new IllegalStateException("Angle is not set");
-            }
-
-            if (Double.isNaN(mErrorRadians)) {
-                throw new IllegalStateException("Angle error is not set");
-            }
-
-            if (Double.isNaN(mConfidenceLevel)) {
-                throw new IllegalStateException("Angle confidence level is not set");
-            }
-
-            return new AngleMeasurement(mRadians, mErrorRadians, mConfidenceLevel);
-        }
-    }
 }
diff --git a/core/java/android/uwb/AngleOfArrivalMeasurement.java b/core/java/android/uwb/AngleOfArrivalMeasurement.java
index 3d8626b..db04ad1 100644
--- a/core/java/android/uwb/AngleOfArrivalMeasurement.java
+++ b/core/java/android/uwb/AngleOfArrivalMeasurement.java
@@ -116,9 +116,8 @@
             new Creator<AngleOfArrivalMeasurement>() {
                 @Override
                 public AngleOfArrivalMeasurement createFromParcel(Parcel in) {
-                    Builder builder = new Builder();
-
-                    builder.setAzimuth(in.readParcelable(AngleMeasurement.class.getClassLoader()));
+                    Builder builder =
+                            new Builder(in.readParcelable(AngleMeasurement.class.getClassLoader()));
 
                     builder.setAltitude(in.readParcelable(AngleMeasurement.class.getClassLoader()));
 
@@ -135,18 +134,16 @@
      * Builder class for {@link AngleOfArrivalMeasurement}.
      */
     public static final class Builder {
-        private AngleMeasurement mAzimuthAngleMeasurement = null;
+        private final AngleMeasurement mAzimuthAngleMeasurement;
         private AngleMeasurement mAltitudeAngleMeasurement = null;
 
         /**
-         * Set the azimuth angle
+         * Constructs an {@link AngleOfArrivalMeasurement} object
          *
-         * @param azimuthAngle azimuth angle
+         * @param azimuthAngle the azimuth angle of the measurement
          */
-        @NonNull
-        public Builder setAzimuth(@NonNull AngleMeasurement azimuthAngle) {
+        public Builder(@NonNull AngleMeasurement azimuthAngle) {
             mAzimuthAngleMeasurement = azimuthAngle;
-            return this;
         }
 
         /**
@@ -162,15 +159,9 @@
 
         /**
          * Build the {@link AngleOfArrivalMeasurement} object
-         *
-         * @throws IllegalStateException if the required azimuth angle is not provided
          */
         @NonNull
         public AngleOfArrivalMeasurement build() {
-            if (mAzimuthAngleMeasurement == null) {
-                throw new IllegalStateException("Azimuth angle measurement is not set");
-            }
-
             return new AngleOfArrivalMeasurement(mAzimuthAngleMeasurement,
                     mAltitudeAngleMeasurement);
         }
diff --git a/core/java/android/uwb/IUwbAdapter.aidl b/core/java/android/uwb/IUwbAdapter.aidl
index 468a69c..4036892 100644
--- a/core/java/android/uwb/IUwbAdapter.aidl
+++ b/core/java/android/uwb/IUwbAdapter.aidl
@@ -62,9 +62,6 @@
   /**
    * Request to open a new ranging session
    *
-   * This function must return before calling any functions in
-   * IUwbAdapterCallbacks.
-   *
    * This function does not start the ranging session, but all necessary
    * components must be initialized and ready to start a new ranging
    * session prior to calling IUwbAdapterCallback#onRangingOpened.
@@ -77,12 +74,16 @@
    * RANGING_SESSION_OPEN_THRESHOLD_MS milliseconds of #openRanging being called
    * if the ranging session fails to be opened.
    *
+   * If the provided sessionHandle is already open for the calling client, then
+   * #onRangingOpenFailed must be called and the new session must not be opened.
+   *
+   * @param sessionHandle the session handle to open ranging for
    * @param rangingCallbacks the callbacks used to deliver ranging information
    * @param parameters the configuration to use for ranging
-   * @return a SessionHandle used to identify this ranging request
    */
-  SessionHandle openRanging(in IUwbRangingCallbacks rangingCallbacks,
-                            in PersistableBundle parameters);
+  void openRanging(in SessionHandle sessionHandle,
+                   in IUwbRangingCallbacks rangingCallbacks,
+                   in PersistableBundle parameters);
 
   /**
    * Request to start ranging
diff --git a/core/java/android/uwb/RangingManager.java b/core/java/android/uwb/RangingManager.java
index c0d8187..85f2c1c 100644
--- a/core/java/android/uwb/RangingManager.java
+++ b/core/java/android/uwb/RangingManager.java
@@ -17,6 +17,7 @@
 package android.uwb;
 
 import android.annotation.NonNull;
+import android.os.CancellationSignal;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.util.Log;
@@ -32,6 +33,7 @@
 
     private final IUwbAdapter mAdapter;
     private final Hashtable<SessionHandle, RangingSession> mRangingSessionTable = new Hashtable<>();
+    private int mNextSessionId = 1;
 
     public RangingManager(IUwbAdapter adapter) {
         mAdapter = adapter;
@@ -44,29 +46,26 @@
      * @param executor {@link Executor} to run callbacks
      * @param callbacks {@link RangingSession.Callback} to associate with the {@link RangingSession}
      *                  that is being opened.
-     * @return a new {@link RangingSession}
+     * @return a {@link CancellationSignal} that may be used to cancel the opening of the
+     *         {@link RangingSession}.
      */
-    public RangingSession openSession(@NonNull PersistableBundle params, @NonNull Executor executor,
+    public CancellationSignal openSession(@NonNull PersistableBundle params,
+            @NonNull Executor executor,
             @NonNull RangingSession.Callback callbacks) {
-        SessionHandle sessionHandle;
-        try {
-            sessionHandle = mAdapter.openRanging(this, params);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-
         synchronized (this) {
-            if (hasSession(sessionHandle)) {
-                Log.w(TAG, "Newly created session unexpectedly reuses an active SessionHandle");
-                executor.execute(() -> callbacks.onClosed(
-                        RangingSession.Callback.REASON_GENERIC_ERROR,
-                        new PersistableBundle()));
-            }
-
+            SessionHandle sessionHandle = new SessionHandle(mNextSessionId++);
             RangingSession session =
                     new RangingSession(executor, callbacks, mAdapter, sessionHandle);
             mRangingSessionTable.put(sessionHandle, session);
-            return session;
+            try {
+                mAdapter.openRanging(sessionHandle, this, params);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+
+            CancellationSignal cancellationSignal = new CancellationSignal();
+            cancellationSignal.setOnCancelListener(() -> session.close());
+            return cancellationSignal;
         }
     }
 
diff --git a/core/java/android/uwb/UwbManager.java b/core/java/android/uwb/UwbManager.java
index 63a6d05..844bbbe 100644
--- a/core/java/android/uwb/UwbManager.java
+++ b/core/java/android/uwb/UwbManager.java
@@ -25,6 +25,7 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.content.Context;
+import android.os.CancellationSignal;
 import android.os.IBinder;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
@@ -228,14 +229,14 @@
      * @param callbacks {@link RangingSession.Callback} to associate with the
      *                  {@link RangingSession} that is being opened.
      *
-     * @return an {@link AutoCloseable} that is able to be used to close or cancel the opening of a
+     * @return an {@link CancellationSignal} that is able to be used to cancel the opening of a
      *         {@link RangingSession} that has been requested through {@link #openRangingSession}
      *         but has not yet been made available by
      *         {@link RangingSession.Callback#onOpened(RangingSession)}.
      */
     @NonNull
     @RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
-    public AutoCloseable openRangingSession(@NonNull PersistableBundle parameters,
+    public CancellationSignal openRangingSession(@NonNull PersistableBundle parameters,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull RangingSession.Callback callbacks) {
         return mRangingManager.openSession(parameters, executor, callbacks);
diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS
index a86984f..31f6f6a 100644
--- a/core/java/android/view/OWNERS
+++ b/core/java/android/view/OWNERS
@@ -80,5 +80,6 @@
 per-file Window*.aidl = file:/services/core/java/com/android/server/wm/OWNERS
 
 # Scroll Capture
+per-file *ScrollCapture*.aidl = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
 per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
 per-file *CaptureHelper*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
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/compat/AndroidBuildClassifier.java b/core/java/com/android/internal/compat/AndroidBuildClassifier.java
index 0b937fa..364db06 100644
--- a/core/java/com/android/internal/compat/AndroidBuildClassifier.java
+++ b/core/java/com/android/internal/compat/AndroidBuildClassifier.java
@@ -31,4 +31,14 @@
     public boolean isFinalBuild() {
         return "REL".equals(Build.VERSION.CODENAME);
     }
+
+    /**
+     * The current platform SDK version.
+     */
+    public int platformTargetSdk() {
+        if (isFinalBuild()) {
+            return Build.VERSION.SDK_INT;
+        }
+        return Build.VERSION_CODES.CUR_DEVELOPMENT;
+    }
 }
diff --git a/core/java/com/android/internal/compat/OverrideAllowedState.java b/core/java/com/android/internal/compat/OverrideAllowedState.java
index c0bbe50..e408be2 100644
--- a/core/java/com/android/internal/compat/OverrideAllowedState.java
+++ b/core/java/com/android/internal/compat/OverrideAllowedState.java
@@ -34,7 +34,8 @@
             DISABLED_NON_TARGET_SDK,
             DISABLED_TARGET_SDK_TOO_HIGH,
             DEFERRED_VERIFICATION,
-            LOGGING_ONLY_CHANGE
+            LOGGING_ONLY_CHANGE,
+            PLATFORM_TOO_OLD
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface State {
@@ -65,6 +66,10 @@
      * Change is marked as logging only, and cannot be toggled.
      */
     public static final int LOGGING_ONLY_CHANGE = 5;
+    /**
+     * Change is gated by a target sdk version newer than the current platform sdk version.
+     */
+    public static final int PLATFORM_TOO_OLD = 6;
 
     @State
     public final int state;
@@ -123,6 +128,11 @@
                 throw new SecurityException(String.format(
                         "Cannot override %1$d because it is marked as a logging-only change.",
                         changeId));
+            case PLATFORM_TOO_OLD:
+                throw new SecurityException(String.format(
+                        "Cannot override %1$d for %2$s because the change's targetSdk threshold "
+                                + "(%3$d) is above the platform sdk.",
+                        changeId, packageName, changeIdTargetSdk));
         }
     }
 
@@ -170,6 +180,8 @@
                 return "DEFERRED_VERIFICATION";
             case LOGGING_ONLY_CHANGE:
                 return "LOGGING_ONLY_CHANGE";
+            case PLATFORM_TOO_OLD:
+                return "PLATFORM_TOO_OLD";
         }
         return "UNKNOWN";
     }
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/widget/OWNERS b/core/java/com/android/internal/widget/OWNERS
index d284d51..8e68be0 100644
--- a/core/java/com/android/internal/widget/OWNERS
+++ b/core/java/com/android/internal/widget/OWNERS
@@ -1,4 +1,6 @@
 per-file PointerLocationView.java = michaelwr@google.com, svv@google.com
+per-file RecyclerView.java = mount@google.com
+per-file ViewPager.java = mount@google.com
 
 # LockSettings related
 per-file *LockPattern* = file:/services/core/java/com/android/server/locksettings/OWNERS
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index c01f741..ed84434 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -630,6 +630,12 @@
     char saveResolvedClassesDelayMsOptsBuf[
             sizeof("-Xps-save-resolved-classes-delay-ms:")-1 + PROPERTY_VALUE_MAX];
     char madviseRandomOptsBuf[sizeof("-XX:MadviseRandomAccess:")-1 + PROPERTY_VALUE_MAX];
+    char madviseWillNeedFileSizeVdex[
+            sizeof("-XMadviseWillNeedVdexFileSize:")-1 + PROPERTY_VALUE_MAX];
+    char madviseWillNeedFileSizeOdex[
+            sizeof("-XMadviseWillNeedOdexFileSize:")-1 + PROPERTY_VALUE_MAX];
+    char madviseWillNeedFileSizeArt[
+            sizeof("-XMadviseWillNeedArtFileSize:")-1 + PROPERTY_VALUE_MAX];
     char gctypeOptsBuf[sizeof("-Xgc:")-1 + PROPERTY_VALUE_MAX];
     char backgroundgcOptsBuf[sizeof("-XX:BackgroundGC=")-1 + PROPERTY_VALUE_MAX];
     char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX];
@@ -838,6 +844,22 @@
     parseRuntimeOption("dalvik.vm.madvise-random", madviseRandomOptsBuf, "-XX:MadviseRandomAccess:");
 
     /*
+     * Use default platform configuration as limits for madvising,
+     * when no properties are specified.
+     */
+    parseRuntimeOption("dalvik.vm.madvise.vdexfile.size",
+                       madviseWillNeedFileSizeVdex,
+                       "-XMadviseWillNeedVdexFileSize:");
+
+    parseRuntimeOption("dalvik.vm.madvise.odexfile.size",
+                       madviseWillNeedFileSizeOdex,
+                       "-XMadviseWillNeedOdexFileSize:");
+
+    parseRuntimeOption("dalvik.vm.madvise.artfile.size",
+                       madviseWillNeedFileSizeArt,
+                       "-XMadviseWillNeedArtFileSize:");
+
+    /*
      * Profile related options.
      */
     parseRuntimeOption("dalvik.vm.hot-startup-method-samples", hotstartupsamplesOptsBuf,
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/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index f71b42c..2499504 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -1516,7 +1516,9 @@
             res = JNI_TRUE;
         } else {
             jniThrowException(env, "java/util/NoSuchElementException",
-                              "Death link does not exist");
+                              base::StringPrintf("Death link does not exist (%s)",
+                                                 statusToString(err).c_str())
+                                      .c_str());
         }
     }
 
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/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8ac00dc..4a06671 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3605,6 +3605,8 @@
     <string name="ext_media_checking_notification_title">Checking <xliff:g id="name" example="SD card">%s</xliff:g>\u2026</string>
     <!-- Notification body when external media is being checked [CHAR LIMIT=NONE] -->
     <string name="ext_media_checking_notification_message">Reviewing current content</string>
+    <!-- TV specific notification body when external media is being checked [CHAR LIMIT=75] -->
+    <string name="ext_media_checking_notification_message" product="tv">Analyzing media storage</string>
 
     <!-- Notification body when new external media is detected [CHAR LIMIT=30] -->
     <string name="ext_media_new_notification_title">New <xliff:g id="name" example="SD card">%s</xliff:g></string>
@@ -3612,11 +3614,15 @@
     <string name="ext_media_new_notification_title" product="automotive"><xliff:g id="name" example="SD card">%s</xliff:g> isn\u2019t working</string>
     <!-- Notification body when new external media is detected [CHAR LIMIT=NONE] -->
     <string name="ext_media_new_notification_message">Tap to set up</string>
+    <!-- TV specific notification body when new external media is detected [CHAR LIMIT=75] -->
+    <string name="ext_media_new_notification_message" product="tv">Select to set up</string>
     <!-- Automotive specific notification body when new external media is detected. [CHAR LIMIT=NONE] -->
     <string name="ext_media_new_notification_message" product="automotive">You may need to reformat the device. Tap to eject.</string>
 
     <!-- Notification body when external media is ready for use [CHAR LIMIT=NONE] -->
     <string name="ext_media_ready_notification_message">For transferring photos and media</string>
+    <!-- TV specific notification body when external media is ready for use [CHAR LIMIT=75] -->
+    <string name="ext_media_ready_notification_message" product="tv">Browse media files</string>
 
     <!-- Notification title when external media is unmountable (corrupt) [CHAR LIMIT=30] -->
     <string name="ext_media_unmountable_notification_title">Issue with <xliff:g id="name" example="SD card">%s</xliff:g></string>
@@ -3635,8 +3641,8 @@
     <string name="ext_media_unsupported_notification_title" product="automotive"><xliff:g id="name" example="SD card">%s</xliff:g> isn\u2019t working</string>
     <!-- Notification body when external media is unsupported [CHAR LIMIT=NONE] -->
     <string name="ext_media_unsupported_notification_message">This device doesn\u2019t support this <xliff:g id="name" example="SD card">%s</xliff:g>. Tap to set up in a supported format.</string>
-    <!-- TV-specific notification body when external media is unsupported [CHAR LIMIT=NONE] -->
-    <string name="ext_media_unsupported_notification_message" product="tv">This device doesn\u2019t support this <xliff:g id="name" example="SD card">%s</xliff:g>. Select to set up in a supported format.</string>
+    <!-- TV-specific notification body when external media is unsupported [CHAR LIMIT=75] -->
+    <string name="ext_media_unsupported_notification_message" product="tv">Select to set up <xliff:g id="name" example="SD card">%s</xliff:g> in a supported format.</string>
     <!-- Automotive specific notification body when external media is unsupported [CHAR LIMIT=NONE] -->
     <string name="ext_media_unsupported_notification_message" product="automotive">You may need to reformat the device</string>
 
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/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
index c01bb75..e41805d 100644
--- a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
+++ b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
@@ -22,7 +22,6 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import android.os.PersistableBundle;
 import android.os.RemoteException;
@@ -32,6 +31,7 @@
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 
 import java.util.concurrent.Executor;
 
@@ -42,51 +42,23 @@
 @RunWith(AndroidJUnit4.class)
 public class RangingManagerTest {
 
-    private static final IUwbAdapter ADAPTER = mock(IUwbAdapter.class);
     private static final Executor EXECUTOR = UwbTestUtils.getExecutor();
     private static final PersistableBundle PARAMS = new PersistableBundle();
     private static final @RangingChangeReason int REASON = RangingChangeReason.UNKNOWN;
 
     @Test
     public void testOpenSession_OpenRangingInvoked() throws RemoteException {
-        RangingManager rangingManager = new RangingManager(ADAPTER);
+        IUwbAdapter adapter = mock(IUwbAdapter.class);
+        RangingManager rangingManager = new RangingManager(adapter);
         RangingSession.Callback callback = mock(RangingSession.Callback.class);
         rangingManager.openSession(PARAMS, EXECUTOR, callback);
-        verify(ADAPTER, times(1)).openRanging(eq(rangingManager), eq(PARAMS));
-    }
-
-    @Test
-    public void testOpenSession_ErrorIfSameSessionHandleReturned() throws RemoteException {
-        RangingManager rangingManager = new RangingManager(ADAPTER);
-        RangingSession.Callback callback = mock(RangingSession.Callback.class);
-        SessionHandle handle = new SessionHandle(1);
-        when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
-
-        rangingManager.openSession(PARAMS, EXECUTOR, callback);
-
-        // Calling openSession will cause the same session handle to be returned. The onClosed
-        // callback should be invoked
-        RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
-        rangingManager.openSession(PARAMS, EXECUTOR, callback2);
-        verify(callback, times(0)).onClosed(anyInt(), any());
-        verify(callback2, times(1)).onClosed(anyInt(), any());
-    }
-
-    @Test
-    public void testOnRangingOpened_ValidSessionHandle() throws RemoteException {
-        RangingManager rangingManager = new RangingManager(ADAPTER);
-        RangingSession.Callback callback = mock(RangingSession.Callback.class);
-        SessionHandle handle = new SessionHandle(1);
-        when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
-
-        rangingManager.openSession(PARAMS, EXECUTOR, callback);
-        rangingManager.onRangingOpened(handle);
-        verify(callback, times(1)).onOpened(any());
+        verify(adapter, times(1)).openRanging(any(), eq(rangingManager), eq(PARAMS));
     }
 
     @Test
     public void testOnRangingOpened_InvalidSessionHandle() throws RemoteException {
-        RangingManager rangingManager = new RangingManager(ADAPTER);
+        IUwbAdapter adapter = mock(IUwbAdapter.class);
+        RangingManager rangingManager = new RangingManager(adapter);
         RangingSession.Callback callback = mock(RangingSession.Callback.class);
 
         rangingManager.onRangingOpened(new SessionHandle(2));
@@ -95,18 +67,20 @@
 
     @Test
     public void testOnRangingOpened_MultipleSessionsRegistered() throws RemoteException {
-        SessionHandle sessionHandle1 = new SessionHandle(1);
-        SessionHandle sessionHandle2 = new SessionHandle(2);
+        IUwbAdapter adapter = mock(IUwbAdapter.class);
         RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
         RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
+        ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+                ArgumentCaptor.forClass(SessionHandle.class);
 
-        when(ADAPTER.openRanging(any(), any()))
-                .thenReturn(sessionHandle1)
-                .thenReturn(sessionHandle2);
-
-        RangingManager rangingManager = new RangingManager(ADAPTER);
+        RangingManager rangingManager = new RangingManager(adapter);
         rangingManager.openSession(PARAMS, EXECUTOR, callback1);
+        verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+        SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
+
         rangingManager.openSession(PARAMS, EXECUTOR, callback2);
+        verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+        SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
 
         rangingManager.onRangingOpened(sessionHandle1);
         verify(callback1, times(1)).onOpened(any());
@@ -119,12 +93,17 @@
 
     @Test
     public void testCorrectCallbackInvoked() throws RemoteException {
-        RangingManager rangingManager = new RangingManager(ADAPTER);
+        IUwbAdapter adapter = mock(IUwbAdapter.class);
+        RangingManager rangingManager = new RangingManager(adapter);
         RangingSession.Callback callback = mock(RangingSession.Callback.class);
-        SessionHandle handle = new SessionHandle(1);
-        when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
+
+        ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+                ArgumentCaptor.forClass(SessionHandle.class);
 
         rangingManager.openSession(PARAMS, EXECUTOR, callback);
+        verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+        SessionHandle handle = sessionHandleCaptor.getValue();
+
         rangingManager.onRangingOpened(handle);
         verify(callback, times(1)).onOpened(any());
 
@@ -156,20 +135,23 @@
 
     @Test
     public void testOnRangingClosed_MultipleSessionsRegistered() throws RemoteException {
+        IUwbAdapter adapter = mock(IUwbAdapter.class);
         // Verify that if multiple sessions are registered, only the session that is
         // requested to close receives the associated callbacks
-        SessionHandle sessionHandle1 = new SessionHandle(1);
-        SessionHandle sessionHandle2 = new SessionHandle(2);
         RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
         RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
 
-        when(ADAPTER.openRanging(any(), any()))
-                .thenReturn(sessionHandle1)
-                .thenReturn(sessionHandle2);
+        RangingManager rangingManager = new RangingManager(adapter);
+        ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+                ArgumentCaptor.forClass(SessionHandle.class);
 
-        RangingManager rangingManager = new RangingManager(ADAPTER);
         rangingManager.openSession(PARAMS, EXECUTOR, callback1);
+        verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+        SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
+
         rangingManager.openSession(PARAMS, EXECUTOR, callback2);
+        verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+        SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
 
         rangingManager.onRangingClosed(sessionHandle1, REASON, PARAMS);
         verify(callback1, times(1)).onClosed(anyInt(), any());
@@ -182,19 +164,22 @@
 
     @Test
     public void testOnRangingReport_MultipleSessionsRegistered() throws RemoteException {
-        SessionHandle sessionHandle1 = new SessionHandle(1);
-        SessionHandle sessionHandle2 = new SessionHandle(2);
+        IUwbAdapter adapter = mock(IUwbAdapter.class);
         RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
         RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
 
-        when(ADAPTER.openRanging(any(), any()))
-                .thenReturn(sessionHandle1)
-                .thenReturn(sessionHandle2);
+        ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+                ArgumentCaptor.forClass(SessionHandle.class);
 
-        RangingManager rangingManager = new RangingManager(ADAPTER);
+        RangingManager rangingManager = new RangingManager(adapter);
         rangingManager.openSession(PARAMS, EXECUTOR, callback1);
+        verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+        SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
+
         rangingManager.onRangingStarted(sessionHandle1, PARAMS);
         rangingManager.openSession(PARAMS, EXECUTOR, callback2);
+        verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+        SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
         rangingManager.onRangingStarted(sessionHandle2, PARAMS);
 
         rangingManager.onRangingResult(sessionHandle1, UwbTestUtils.getRangingReports(1));
@@ -232,17 +217,24 @@
 
     private void runReason(@RangingChangeReason int reasonIn,
             @RangingSession.Callback.Reason int reasonOut) throws RemoteException {
-        RangingManager rangingManager = new RangingManager(ADAPTER);
+        IUwbAdapter adapter = mock(IUwbAdapter.class);
+        RangingManager rangingManager = new RangingManager(adapter);
         RangingSession.Callback callback = mock(RangingSession.Callback.class);
-        SessionHandle handle = new SessionHandle(1);
-        when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
+
+        ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+                ArgumentCaptor.forClass(SessionHandle.class);
+
         rangingManager.openSession(PARAMS, EXECUTOR, callback);
+        verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+        SessionHandle handle = sessionHandleCaptor.getValue();
 
         rangingManager.onRangingOpenFailed(handle, reasonIn, PARAMS);
         verify(callback, times(1)).onOpenFailed(eq(reasonOut), eq(PARAMS));
 
         // Open a new session
         rangingManager.openSession(PARAMS, EXECUTOR, callback);
+        verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+        handle = sessionHandleCaptor.getValue();
         rangingManager.onRangingOpened(handle);
 
         rangingManager.onRangingStartFailed(handle, reasonIn, PARAMS);
diff --git a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
index 8e7f7c56..75c6924 100644
--- a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
+++ b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
@@ -16,34 +16,23 @@
 
 package android.uwb;
 
-import android.content.Context;
-import android.content.pm.PackageManager;
 import android.os.SystemClock;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.concurrent.Executor;
 
 public class UwbTestUtils {
     private UwbTestUtils() {}
 
-    public static boolean isUwbSupported(Context context) {
-        PackageManager packageManager = context.getPackageManager();
-        return packageManager.hasSystemFeature(PackageManager.FEATURE_UWB);
-    }
-
     public static AngleMeasurement getAngleMeasurement() {
-        return new AngleMeasurement.Builder()
-                .setRadians(getDoubleInRange(-Math.PI, Math.PI))
-                .setErrorRadians(getDoubleInRange(0, Math.PI))
-                .setConfidenceLevel(getDoubleInRange(0, 1))
-                .build();
+        return new AngleMeasurement(
+                getDoubleInRange(-Math.PI, Math.PI),
+                getDoubleInRange(0, Math.PI),
+                getDoubleInRange(0, 1));
     }
 
     public static AngleOfArrivalMeasurement getAngleOfArrivalMeasurement() {
-        return new AngleOfArrivalMeasurement.Builder()
+        return new AngleOfArrivalMeasurement.Builder(getAngleMeasurement())
                 .setAltitude(getAngleMeasurement())
-                .setAzimuth(getAngleMeasurement())
                 .build();
     }
 
@@ -69,14 +58,6 @@
                 .build();
     }
 
-    public static List<RangingMeasurement> getRangingMeasurements(int num) {
-        List<RangingMeasurement> result = new ArrayList<>();
-        for (int i = 0; i < num; i++) {
-            result.add(getRangingMeasurement());
-        }
-        return result;
-    }
-
     public static RangingReport getRangingReports(int numMeasurements) {
         RangingReport.Builder builder = new RangingReport.Builder();
         for (int i = 0; i < numMeasurements; i++) {
diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
index ed789f0..35b1c16 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"));
     }
 
     /**
@@ -121,4 +121,22 @@
             return SYSTEM_ERROR;
         }
     }
+
+    /**
+     * Queries user state from Keystore 2.0.
+     *
+     * @param userId - Android user id of the user.
+     * @return UserState enum variant as integer if successful or an error
+     */
+    public static int getState(int userId) {
+        try {
+            return getService().getState(userId);
+        } catch (ServiceSpecificException e) {
+            Log.e(TAG, "getState failed", e);
+            return e.errorCode;
+        } catch (Exception e) {
+            Log.e(TAG, "Can not connect to keystore", e);
+            return SYSTEM_ERROR;
+        }
+    }
 }
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 93658e6..937f01c 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -43,6 +43,7 @@
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeystoreResponse;
 import android.security.keystore.UserNotAuthenticatedException;
+import android.security.maintenance.UserState;
 import android.system.keystore2.Domain;
 import android.util.Log;
 
@@ -196,6 +197,19 @@
     public State state(int userId) {
         final int ret;
         try {
+            if (android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) {
+                int userState = AndroidKeyStoreMaintenance.getState(userId);
+                switch (userState) {
+                    case UserState.UNINITIALIZED:
+                        return KeyStore.State.UNINITIALIZED;
+                    case UserState.LSKF_UNLOCKED:
+                        return KeyStore.State.UNLOCKED;
+                    case UserState.LSKF_LOCKED:
+                        return KeyStore.State.LOCKED;
+                    default:
+                        throw new AssertionError(KeyStore.VALUE_CORRUPTED);
+                }
+            }
             ret = mBinder.getState(userId);
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
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/media/jni/soundpool/Sound.cpp b/media/jni/soundpool/Sound.cpp
index f8b4bdb..50e0d33 100644
--- a/media/jni/soundpool/Sound.cpp
+++ b/media/jni/soundpool/Sound.cpp
@@ -99,8 +99,8 @@
                                     __func__);
                             break;
                         }
-                        int sampleSize = AMediaExtractor_readSampleData(ex.get(), buf, bufsize);
-                        ALOGV("%s: read %d", __func__, sampleSize);
+                        ssize_t sampleSize = AMediaExtractor_readSampleData(ex.get(), buf, bufsize);
+                        ALOGV("%s: read %zd", __func__, sampleSize);
                         if (sampleSize < 0) {
                             sampleSize = 0;
                             sawInputEOS = true;
@@ -124,8 +124,8 @@
                 }
 
                 AMediaCodecBufferInfo info;
-                const int status = AMediaCodec_dequeueOutputBuffer(codec.get(), &info, 1);
-                ALOGV("%s: dequeueoutput returned: %d", __func__, status);
+                const ssize_t status = AMediaCodec_dequeueOutputBuffer(codec.get(), &info, 1);
+                ALOGV("%s: dequeueoutput returned: %zd", __func__, status);
                 if (status >= 0) {
                     if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) {
                         ALOGV("%s: output EOS", __func__);
@@ -167,10 +167,10 @@
                 } else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
                     ALOGV("%s: no output buffer right now", __func__);
                 } else if (status <= AMEDIA_ERROR_BASE) {
-                    ALOGE("%s: decode error: %d", __func__, status);
+                    ALOGE("%s: decode error: %zd", __func__, status);
                     break;
                 } else {
-                    ALOGV("%s: unexpected info code: %d", __func__, status);
+                    ALOGV("%s: unexpected info code: %zd", __func__, status);
                 }
             }
 
diff --git a/media/jni/soundpool/Stream.cpp b/media/jni/soundpool/Stream.cpp
index 73e319a..f261bab 100644
--- a/media/jni/soundpool/Stream.cpp
+++ b/media/jni/soundpool/Stream.cpp
@@ -317,7 +317,8 @@
             // audio track while the new one is being started and avoids processing them with
             // wrong audio audio buffer size  (mAudioBufferSize)
             auto toggle = mToggle ^ 1;
-            void* userData = (void*)((uintptr_t)this | toggle);
+            // NOLINTNEXTLINE(performance-no-int-to-ptr)
+            void* userData = reinterpret_cast<void*>((uintptr_t)this | toggle);
             audio_channel_mask_t soundChannelMask = sound->getChannelMask();
             // When sound contains a valid channel mask, use it as is.
             // Otherwise, use stream count to calculate channel mask.
@@ -386,6 +387,7 @@
 void Stream::staticCallback(int event, void* user, void* info)
 {
     const auto userAsInt = (uintptr_t)user;
+    // NOLINTNEXTLINE(performance-no-int-to-ptr)
     auto stream = reinterpret_cast<Stream*>(userAsInt & ~1);
     stream->callback(event, info, int(userAsInt & 1), 0 /* tries */);
 }
diff --git a/media/jni/soundpool/StreamManager.cpp b/media/jni/soundpool/StreamManager.cpp
index 502ee00..8b84bf3 100644
--- a/media/jni/soundpool/StreamManager.cpp
+++ b/media/jni/soundpool/StreamManager.cpp
@@ -330,7 +330,7 @@
 
     // streams on mProcessingStreams are undergoing processing by the StreamManager thread
     // and do not participate in normal stream migration.
-    return found;
+    return (ssize_t)found;
 }
 
 void StreamManager::addToRestartQueue_l(Stream *stream) {
diff --git a/media/jni/soundpool/android_media_SoundPool.cpp b/media/jni/soundpool/android_media_SoundPool.cpp
index 357cc63..a66d99f 100644
--- a/media/jni/soundpool/android_media_SoundPool.cpp
+++ b/media/jni/soundpool/android_media_SoundPool.cpp
@@ -34,7 +34,8 @@
     jclass      mSoundPoolClass;
 } fields;
 static inline SoundPool* MusterSoundPool(JNIEnv *env, jobject thiz) {
-    return (SoundPool*)env->GetLongField(thiz, fields.mNativeContext);
+    // NOLINTNEXTLINE(performance-no-int-to-ptr)
+    return reinterpret_cast<SoundPool*>(env->GetLongField(thiz, fields.mNativeContext));
 }
 static const char* const kAudioAttributesClassPathName = "android/media/AudioAttributes";
 struct audio_attributes_fields_t {
diff --git a/packages/Connectivity/framework/api/current.txt b/packages/Connectivity/framework/api/current.txt
index a8f1a4d..243e4ca 100644
--- a/packages/Connectivity/framework/api/current.txt
+++ b/packages/Connectivity/framework/api/current.txt
@@ -143,6 +143,7 @@
 
   public static class ConnectivityManager.NetworkCallback {
     ctor public ConnectivityManager.NetworkCallback();
+    ctor public ConnectivityManager.NetworkCallback(int);
     method public void onAvailable(@NonNull android.net.Network);
     method public void onBlockedStatusChanged(@NonNull android.net.Network, boolean);
     method public void onCapabilitiesChanged(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities);
@@ -150,6 +151,7 @@
     method public void onLosing(@NonNull android.net.Network, int);
     method public void onLost(@NonNull android.net.Network);
     method public void onUnavailable();
+    field public static final int FLAG_INCLUDE_LOCATION_INFO = 1; // 0x1
   }
 
   public static interface ConnectivityManager.OnNetworkActiveListener {
@@ -293,6 +295,7 @@
     method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
     method public int getOwnerUid();
     method public int getSignalStrength();
+    method @NonNull public java.util.Set<java.lang.Integer> getSubIds();
     method @Nullable public android.net.TransportInfo getTransportInfo();
     method public boolean hasCapability(int);
     method public boolean hasTransport(int);
@@ -399,6 +402,11 @@
     method public android.net.NetworkRequest.Builder removeTransportType(int);
     method @Deprecated public android.net.NetworkRequest.Builder setNetworkSpecifier(String);
     method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier);
+    method @NonNull public android.net.NetworkRequest.Builder setSubIds(@NonNull java.util.Set<java.lang.Integer>);
+  }
+
+  public class ParseException extends java.lang.RuntimeException {
+    field public String response;
   }
 
   public class ProxyInfo implements android.os.Parcelable {
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt
index d2ed73e..4b33366 100644
--- a/packages/Connectivity/framework/api/module-lib-current.txt
+++ b/packages/Connectivity/framework/api/module-lib-current.txt
@@ -7,8 +7,9 @@
 
   public class ConnectivityManager {
     method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public java.util.List<android.net.NetworkStateSnapshot> getAllNetworkStateSnapshot();
+    method @NonNull public static android.util.Range<java.lang.Integer> getIpSecNetIdRange();
     method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @Nullable android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
   }
 
@@ -51,6 +52,14 @@
     field public static final String TEST_TAP_PREFIX = "testtap";
   }
 
+  public final class TestNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
+    ctor public TestNetworkSpecifier(@NonNull String);
+    method public int describeContents();
+    method @Nullable public String getInterfaceName();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.TestNetworkSpecifier> CREATOR;
+  }
+
   public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
     ctor public VpnTransportInfo(int);
     method public int describeContents();
diff --git a/packages/Connectivity/framework/api/system-current.txt b/packages/Connectivity/framework/api/system-current.txt
index a732430..a98f14e 100644
--- a/packages/Connectivity/framework/api/system-current.txt
+++ b/packages/Connectivity/framework/api/system-current.txt
@@ -296,6 +296,7 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorUid(int);
     method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkCapabilities.Builder setSignalStrength(int);
     method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setSsid(@Nullable String);
+    method @NonNull public android.net.NetworkCapabilities.Builder setSubIds(@NonNull java.util.Set<java.lang.Integer>);
     method @NonNull public android.net.NetworkCapabilities.Builder setTransportInfo(@Nullable android.net.TransportInfo);
   }
 
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index 45ed317..8c66db9 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -16,10 +16,10 @@
 package android.net;
 
 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-import static android.net.IpSecManager.INVALID_RESOURCE_ID;
 import static android.net.NetworkRequest.Type.BACKGROUND_REQUEST;
 import static android.net.NetworkRequest.Type.LISTEN;
 import static android.net.NetworkRequest.Type.REQUEST;
+import static android.net.NetworkRequest.Type.TRACK_BEST;
 import static android.net.NetworkRequest.Type.TRACK_DEFAULT;
 import static android.net.NetworkRequest.Type.TRACK_SYSTEM_DEFAULT;
 import static android.net.QosCallback.QosCallbackRegistrationException;
@@ -43,6 +43,7 @@
 import android.net.TetheringManager.StartTetheringCallback;
 import android.net.TetheringManager.TetheringEventCallback;
 import android.net.TetheringManager.TetheringRequest;
+import android.net.wifi.WifiNetworkSuggestion;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Build.VERSION_CODES;
@@ -1314,7 +1315,7 @@
     }
 
     /**
-     * Returns an array of {@link android.net.NetworkCapabilities} objects, representing
+     * Returns an array of {@link NetworkCapabilities} objects, representing
      * the Networks that applications run by the given user will use by default.
      * @hide
      */
@@ -1394,11 +1395,19 @@
     }
 
     /**
-     * Get the {@link android.net.NetworkCapabilities} for the given {@link Network}.  This
+     * Get the {@link NetworkCapabilities} for the given {@link Network}.  This
      * will return {@code null} if the network is unknown.
      *
+     * This will remove any location sensitive data in {@link TransportInfo} embedded in
+     * {@link NetworkCapabilities#getTransportInfo()}. Some transport info instances like
+     * {@link android.net.wifi.WifiInfo} contain location sensitive information. Retrieving
+     * this location sensitive information (subject to app's location permissions) will be
+     * noted by system. To include any location sensitive data in {@link TransportInfo},
+     * use a {@link NetworkCallback} with
+     * {@link NetworkCallback#FLAG_INCLUDE_LOCATION_INFO} flag.
+     *
      * @param network The {@link Network} object identifying the network in question.
-     * @return The {@link android.net.NetworkCapabilities} for the network, or {@code null}.
+     * @return The {@link NetworkCapabilities} for the network, or {@code null}.
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     @Nullable
@@ -1996,7 +2005,7 @@
             dup = createInvalidFd();
         }
         return new NattSocketKeepalive(mService, network, dup,
-                INVALID_RESOURCE_ID /* Unused */, source, destination, executor, callback);
+                -1 /* Unused */, source, destination, executor, callback);
     }
 
     /**
@@ -3244,6 +3253,54 @@
      */
     public static class NetworkCallback {
         /**
+         * No flags associated with this callback.
+         * @hide
+         */
+        public static final int FLAG_NONE = 0;
+        /**
+         * Use this flag to include any location sensitive data in {@link NetworkCapabilities} sent
+         * via {@link #onCapabilitiesChanged(Network, NetworkCapabilities)}.
+         * <p>
+         * These include:
+         * <li> Some transport info instances (retrieved via
+         * {@link NetworkCapabilities#getTransportInfo()}) like {@link android.net.wifi.WifiInfo}
+         * contain location sensitive information.
+         * <li> OwnerUid (retrieved via {@link NetworkCapabilities#getOwnerUid()} is location
+         * sensitive for wifi suggestor apps (i.e using {@link WifiNetworkSuggestion}).</li>
+         * </p>
+         * <p>
+         * Note:
+         * <li> Retrieving this location sensitive information (subject to app's location
+         * permissions) will be noted by system. </li>
+         * <li> Without this flag any {@link NetworkCapabilities} provided via the callback does
+         * not include location sensitive info.
+         * </p>
+         */
+        public static final int FLAG_INCLUDE_LOCATION_INFO = 1 << 0;
+
+        /** @hide */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(flag = true, prefix = "FLAG_", value = {
+                FLAG_NONE,
+                FLAG_INCLUDE_LOCATION_INFO
+        })
+        public @interface Flag { }
+
+        /**
+         * All the valid flags for error checking.
+         */
+        private static final int VALID_FLAGS = FLAG_INCLUDE_LOCATION_INFO;
+
+        public NetworkCallback() {
+            this(FLAG_NONE);
+        }
+
+        public NetworkCallback(@Flag int flags) {
+            Preconditions.checkArgument((flags & VALID_FLAGS) == flags);
+            mFlags = flags;
+        }
+
+        /**
          * Called when the framework connects to a new network to evaluate whether it satisfies this
          * request. If evaluation succeeds, this callback may be followed by an {@link #onAvailable}
          * callback. There is no guarantee that this new network will satisfy any requests, or that
@@ -3380,7 +3437,7 @@
          * calling these methods while in a callback may return an outdated or even a null object.
          *
          * @param network The {@link Network} whose capabilities have changed.
-         * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this
+         * @param networkCapabilities The new {@link NetworkCapabilities} for this
          *                            network.
          */
         public void onCapabilitiesChanged(@NonNull Network network,
@@ -3449,6 +3506,7 @@
         public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {}
 
         private NetworkRequest networkRequest;
+        private final int mFlags;
     }
 
     /**
@@ -3638,14 +3696,15 @@
                 }
                 Messenger messenger = new Messenger(handler);
                 Binder binder = new Binder();
+                final int callbackFlags = callback.mFlags;
                 if (reqType == LISTEN) {
                     request = mService.listenForNetwork(
-                            need, messenger, binder, callingPackageName,
+                            need, messenger, binder, callbackFlags, callingPackageName,
                             getAttributionTag());
                 } else {
                     request = mService.requestNetwork(
                             need, reqType.ordinal(), messenger, timeoutMs, binder, legacyType,
-                            callingPackageName, getAttributionTag());
+                            callbackFlags, callingPackageName, getAttributionTag());
                 }
                 if (request != null) {
                     sCallbacks.put(request, callback);
@@ -3692,7 +3751,7 @@
     }
 
     /**
-     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
+     * Request a network to satisfy a set of {@link NetworkCapabilities}.
      *
      * <p>This method will attempt to find the best network that matches the passed
      * {@link NetworkRequest}, and to bring up one that does if none currently satisfies the
@@ -3776,7 +3835,7 @@
     }
 
     /**
-     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
+     * Request a network to satisfy a set of {@link NetworkCapabilities}.
      *
      * This method behaves identically to {@link #requestNetwork(NetworkRequest, NetworkCallback)}
      * but runs all the callbacks on the passed Handler.
@@ -3798,7 +3857,7 @@
     }
 
     /**
-     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
+     * Request a network to satisfy a set of {@link NetworkCapabilities}, limited
      * by a timeout.
      *
      * This function behaves identically to the non-timed-out version
@@ -3833,7 +3892,7 @@
     }
 
     /**
-     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
+     * Request a network to satisfy a set of {@link NetworkCapabilities}, limited
      * by a timeout.
      *
      * This method behaves identically to
@@ -3878,7 +3937,7 @@
 
 
     /**
-     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
+     * Request a network to satisfy a set of {@link NetworkCapabilities}.
      *
      * This function behaves identically to the version that takes a NetworkCallback, but instead
      * of {@link NetworkCallback} a {@link PendingIntent} is used.  This means
@@ -4190,6 +4249,18 @@
     }
 
     /**
+     * @hide
+     */
+    // TODO: Make it public api.
+    @SuppressLint("ExecutorRegistration")
+    public void registerBestMatchingNetworkCallback(@NonNull NetworkRequest request,
+            @NonNull NetworkCallback networkCallback, @NonNull Handler handler) {
+        final NetworkCapabilities nc = request.networkCapabilities;
+        final CallbackHandler cbHandler = new CallbackHandler(handler);
+        sendRequestForNetwork(nc, networkCallback, 0, TRACK_BEST, TYPE_NONE, cbHandler);
+    }
+
+    /**
      * Requests bandwidth update for a given {@link Network} and returns whether the update request
      * is accepted by ConnectivityService. Once accepted, ConnectivityService will poll underlying
      * network connection for updated bandwidth information. The caller will be notified via
@@ -4898,7 +4969,7 @@
     }
 
     /**
-     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, but
+     * Request a network to satisfy a set of {@link NetworkCapabilities}, but
      * does not cause any networks to retain the NET_CAPABILITY_FOREGROUND capability. This can
      * be used to request that the system provide a network without causing the network to be
      * in the foreground.
@@ -4979,10 +5050,10 @@
             NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
     })
     public void requestBackgroundNetwork(@NonNull NetworkRequest request,
-            @Nullable Handler handler, @NonNull NetworkCallback networkCallback) {
+            @NonNull Handler handler, @NonNull NetworkCallback networkCallback) {
         final NetworkCapabilities nc = request.networkCapabilities;
         sendRequestForNetwork(nc, networkCallback, 0, BACKGROUND_REQUEST,
-                TYPE_NONE, handler == null ? getDefaultHandler() : new CallbackHandler(handler));
+                TYPE_NONE, new CallbackHandler(handler));
     }
 
     /**
@@ -5040,4 +5111,21 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    // The first network ID of IPSec tunnel interface.
+    private static final int TUN_INTF_NETID_START = 0xFC00;
+    // The network ID range of IPSec tunnel interface.
+    private static final int TUN_INTF_NETID_RANGE = 0x0400;
+
+    /**
+     * Get the network ID range reserved for IPSec tunnel interfaces.
+     *
+     * @return A Range which indicates the network ID range of IPSec tunnel interface.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @NonNull
+    public static Range<Integer> getIpSecNetIdRange() {
+        return new Range(TUN_INTF_NETID_START, TUN_INTF_NETID_START + TUN_INTF_NETID_RANGE - 1);
+    }
 }
diff --git a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
index cd49258..f9393e3 100644
--- a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
+++ b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
@@ -143,7 +143,7 @@
 
     NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, int reqType,
             in Messenger messenger, int timeoutSec, in IBinder binder, int legacy,
-            String callingPackageName, String callingAttributionTag);
+            int callbackFlags, String callingPackageName, String callingAttributionTag);
 
     NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities,
             in PendingIntent operation, String callingPackageName, String callingAttributionTag);
@@ -151,7 +151,7 @@
     void releasePendingNetworkRequest(in PendingIntent operation);
 
     NetworkRequest listenForNetwork(in NetworkCapabilities networkCapabilities,
-            in Messenger messenger, in IBinder binder, String callingPackageName,
+            in Messenger messenger, in IBinder binder, int callbackFlags, String callingPackageName,
             String callingAttributionTag);
 
     void pendingListenForNetwork(in NetworkCapabilities networkCapabilities,
diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
index c82cd3b..058f3c9 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
@@ -25,6 +25,7 @@
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.net.ConnectivityManager.NetworkCallback;
+import android.net.wifi.WifiNetworkSuggestion;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -131,6 +132,7 @@
         mPrivateDnsBroken = false;
         mRequestorUid = Process.INVALID_UID;
         mRequestorPackageName = null;
+        mSubIds = new ArraySet<>();
     }
 
     /**
@@ -159,6 +161,7 @@
         mPrivateDnsBroken = nc.mPrivateDnsBroken;
         mRequestorUid = nc.mRequestorUid;
         mRequestorPackageName = nc.mRequestorPackageName;
+        mSubIds = new ArraySet<>(nc.mSubIds);
     }
 
     /**
@@ -1048,6 +1051,16 @@
      *
      * Instances of NetworkCapabilities sent to apps without the appropriate permissions will have
      * this field cleared out.
+     *
+     * <p>
+     * This field will only be populated for VPN and wifi network suggestor apps (i.e using
+     * {@link WifiNetworkSuggestion}), and only for the network they own.
+     * In the case of wifi network suggestors apps, this field is also location sensitive, so the
+     * app needs to hold {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission. If the
+     * app targets SDK version greater than or equal to {@link Build.VERSION_CODES#S}, then they
+     * also need to use {@link NetworkCallback#FLAG_INCLUDE_LOCATION_INFO} to get the info in their
+     * callback. The app will be blamed for location access if this field is included.
+     * </p>
      */
     public int getOwnerUid() {
         return mOwnerUid;
@@ -1655,6 +1668,7 @@
         combineSSIDs(nc);
         combineRequestor(nc);
         combineAdministratorUids(nc);
+        combineSubIds(nc);
     }
 
     /**
@@ -1674,8 +1688,9 @@
                 && satisfiedBySpecifier(nc)
                 && (onlyImmutable || satisfiedBySignalStrength(nc))
                 && (onlyImmutable || satisfiedByUids(nc))
-                && (onlyImmutable || satisfiedBySSID(nc)))
-                && (onlyImmutable || satisfiedByRequestor(nc));
+                && (onlyImmutable || satisfiedBySSID(nc))
+                && (onlyImmutable || satisfiedByRequestor(nc))
+                && (onlyImmutable || satisfiedBySubIds(nc)));
     }
 
     /**
@@ -1771,7 +1786,8 @@
                 && equalsOwnerUid(that)
                 && equalsPrivateDnsBroken(that)
                 && equalsRequestor(that)
-                && equalsAdministratorUids(that);
+                && equalsAdministratorUids(that)
+                && equalsSubIds(that);
     }
 
     @Override
@@ -1793,7 +1809,8 @@
                 + Objects.hashCode(mPrivateDnsBroken) * 47
                 + Objects.hashCode(mRequestorUid) * 53
                 + Objects.hashCode(mRequestorPackageName) * 59
-                + Arrays.hashCode(mAdministratorUids) * 61;
+                + Arrays.hashCode(mAdministratorUids) * 61
+                + Objects.hashCode(mSubIds) * 67;
     }
 
     @Override
@@ -1827,6 +1844,7 @@
         dest.writeInt(mOwnerUid);
         dest.writeInt(mRequestorUid);
         dest.writeString(mRequestorPackageName);
+        dest.writeIntArray(CollectionUtils.toIntArray(mSubIds));
     }
 
     public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
@@ -1850,6 +1868,11 @@
                 netCap.mOwnerUid = in.readInt();
                 netCap.mRequestorUid = in.readInt();
                 netCap.mRequestorPackageName = in.readString();
+                netCap.mSubIds = new ArraySet<>();
+                final int[] subIdInts = Objects.requireNonNull(in.createIntArray());
+                for (int i = 0; i < subIdInts.length; i++) {
+                    netCap.mSubIds.add(subIdInts[i]);
+                }
                 return netCap;
             }
             @Override
@@ -1933,11 +1956,14 @@
             sb.append(" SSID: ").append(mSSID);
         }
 
-
         if (mPrivateDnsBroken) {
             sb.append(" PrivateDnsBroken");
         }
 
+        if (!mSubIds.isEmpty()) {
+            sb.append(" SubscriptionIds: ").append(mSubIds);
+        }
+
         sb.append("]");
         return sb.toString();
     }
@@ -2251,6 +2277,67 @@
     }
 
     /**
+     * Set of the subscription IDs that identifies the network or request, empty if none.
+     */
+    @NonNull
+    private ArraySet<Integer> mSubIds = new ArraySet<>();
+
+    /**
+     * Sets the subscription ID set that associated to this network or request.
+     *
+     * @hide
+     */
+    @NonNull
+    public NetworkCapabilities setSubIds(@NonNull Set<Integer> subIds) {
+        mSubIds = new ArraySet(Objects.requireNonNull(subIds));
+        return this;
+    }
+
+    /**
+     * Gets the subscription ID set that associated to this network or request.
+     * @return
+     */
+    @NonNull
+    public Set<Integer> getSubIds() {
+        return new ArraySet<>(mSubIds);
+    }
+
+    /**
+     * Tests if the subscription ID set of this network is the same as that of the passed one.
+     */
+    private boolean equalsSubIds(@NonNull NetworkCapabilities nc) {
+        return Objects.equals(mSubIds, nc.mSubIds);
+    }
+
+    /**
+     * Check if the subscription ID set requirements of this object are matched by the passed one.
+     * If specified in the request, the passed one need to have at least one subId and at least
+     * one of them needs to be in the request set.
+     */
+    private boolean satisfiedBySubIds(@NonNull NetworkCapabilities nc) {
+        if (mSubIds.isEmpty()) return true;
+        if (nc.mSubIds.isEmpty()) return false;
+        for (final Integer subId : nc.mSubIds) {
+            if (mSubIds.contains(subId)) return true;
+        }
+        return false;
+    }
+
+    /**
+     * Combine subscription ID set of the capabilities.
+     *
+     * <p>This is only legal if the subscription Ids are equal.
+     *
+     * <p>If both subscription IDs are not equal, they belong to different subscription
+     * (or no subscription). In this case, it would not make sense to add them together.
+     */
+    private void combineSubIds(@NonNull NetworkCapabilities nc) {
+        if (!Objects.equals(mSubIds, nc.mSubIds)) {
+            throw new IllegalStateException("Can't combine two subscription ID sets");
+        }
+    }
+
+    /**
      * Builder class for NetworkCapabilities.
      *
      * This class is mainly for for {@link NetworkAgent} instances to use. Many fields in
@@ -2556,6 +2643,18 @@
         }
 
         /**
+         * Set the subscription ID set.
+         *
+         * @param subIds a set that represent the subscription IDs. Empty if clean up.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setSubIds(@NonNull final Set<Integer> subIds) {
+            mCaps.setSubIds(subIds);
+            return this;
+        }
+
+        /**
          * Builds the instance of the capabilities.
          *
          * @return the built instance of NetworkCapabilities.
diff --git a/packages/Connectivity/framework/src/android/net/NetworkInfo.java b/packages/Connectivity/framework/src/android/net/NetworkInfo.java
index d752901..bb23494 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkInfo.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkInfo.java
@@ -21,7 +21,6 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.telephony.Annotation.NetworkType;
 import android.text.TextUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -164,7 +163,7 @@
      * @param typeName a human-readable string for the network type, or an empty string or null.
      * @param subtypeName a human-readable string for the subtype, or an empty string or null.
      */
-    public NetworkInfo(int type, @NetworkType int subtype,
+    public NetworkInfo(int type, int subtype,
             @Nullable String typeName, @Nullable String subtypeName) {
         if (!ConnectivityManager.isNetworkTypeValid(type)
                 && type != ConnectivityManager.TYPE_NONE) {
diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
index b4a651c..3fd95ee 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
@@ -31,6 +31,7 @@
 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.TRANSPORT_TEST;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -113,6 +114,10 @@
      *       for the network (if any) that satisfies the default Internet
      *       request.
      *
+     *     - TRACK_BEST, which causes the framework to send callbacks about
+     *       the single, highest scoring current network (if any) that matches
+     *       the specified NetworkCapabilities.
+     *
      *     - BACKGROUND_REQUEST, like REQUEST but does not cause any networks
      *       to retain the NET_CAPABILITY_FOREGROUND capability. A network with
      *       no foreground requests is in the background. A network that has
@@ -135,6 +140,7 @@
         REQUEST,
         BACKGROUND_REQUEST,
         TRACK_SYSTEM_DEFAULT,
+        TRACK_BEST,
     };
 
     /**
@@ -382,11 +388,17 @@
                 return setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
                         .setSubscriptionId(subId).build());
             } catch (NumberFormatException nfe) {
-                // A StringNetworkSpecifier does not accept null or empty ("") strings. When network
-                // specifiers were strings a null string and an empty string were considered
-                // equivalent. Hence no meaning is attached to a null or empty ("") string.
-                return setNetworkSpecifier(TextUtils.isEmpty(networkSpecifier) ? null
-                        : new StringNetworkSpecifier(networkSpecifier));
+                // An EthernetNetworkSpecifier or TestNetworkSpecifier does not accept null or empty
+                // ("") strings. When network specifiers were strings a null string and an empty
+                // string were considered equivalent. Hence no meaning is attached to a null or
+                // empty ("") string.
+                if (TextUtils.isEmpty(networkSpecifier)) {
+                    return setNetworkSpecifier((NetworkSpecifier) null);
+                } else if (mNetworkCapabilities.hasTransport(TRANSPORT_TEST)) {
+                    return setNetworkSpecifier(new TestNetworkSpecifier(networkSpecifier));
+                } else {
+                    return setNetworkSpecifier(new EthernetNetworkSpecifier(networkSpecifier));
+                }
             }
         }
 
@@ -449,6 +461,21 @@
             }
             nc.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
         }
+
+        /**
+         * Sets the optional subscription ID set.
+         * <p>
+         * This specify the subscription IDs requirement.
+         * A network will satisfy this request only if it matches one of the subIds in this set.
+         * An empty set matches all networks, including those without a subId.
+         *
+         * @param subIds A {@code Set} that represents subscription IDs.
+         */
+        @NonNull
+        public Builder setSubIds(@NonNull Set<Integer> subIds) {
+            mNetworkCapabilities.setSubIds(subIds);
+            return this;
+        }
     }
 
     // implement the Parcelable interface
diff --git a/packages/Connectivity/framework/src/android/net/NetworkState.java b/packages/Connectivity/framework/src/android/net/NetworkState.java
index d010265..9b69674 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkState.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkState.java
@@ -22,7 +22,7 @@
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.util.Slog;
+import android.util.Log;
 
 /**
  * Snapshot of network state.
@@ -83,7 +83,7 @@
         if (VALIDATE_ROAMING_STATE && networkInfo != null && networkCapabilities != null) {
             if (networkInfo.isRoaming() == networkCapabilities
                     .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)) {
-                Slog.wtf("NetworkState", "Roaming state disagreement between " + networkInfo
+                Log.wtf("NetworkState", "Roaming state disagreement between " + networkInfo
                         + " and " + networkCapabilities);
             }
         }
diff --git a/core/java/android/net/ParseException.java b/packages/Connectivity/framework/src/android/net/ParseException.java
similarity index 100%
rename from core/java/android/net/ParseException.java
rename to packages/Connectivity/framework/src/android/net/ParseException.java
diff --git a/packages/Connectivity/framework/src/android/net/QosSocketInfo.java b/packages/Connectivity/framework/src/android/net/QosSocketInfo.java
index d37c469..53d9669 100644
--- a/packages/Connectivity/framework/src/android/net/QosSocketInfo.java
+++ b/packages/Connectivity/framework/src/android/net/QosSocketInfo.java
@@ -92,7 +92,7 @@
         Objects.requireNonNull(socket, "socket cannot be null");
 
         mNetwork = Objects.requireNonNull(network, "network cannot be null");
-        mParcelFileDescriptor = ParcelFileDescriptor.dup(socket.getFileDescriptor$());
+        mParcelFileDescriptor = ParcelFileDescriptor.fromSocket(socket);
         mLocalSocketAddress =
                 new InetSocketAddress(socket.getLocalAddress(), socket.getLocalPort());
     }
@@ -114,10 +114,10 @@
         try {
             return new InetSocketAddress(InetAddress.getByAddress(address), port);
         } catch (final UnknownHostException e) {
-            /* The catch block was purposely left empty.  UnknownHostException will never be thrown
+            /* This can never happen. UnknownHostException will never be thrown
                since the address provided is numeric and non-null. */
+            throw new RuntimeException("UnknownHostException on numeric address", e);
         }
-        return new InetSocketAddress();
     }
 
     @Override
diff --git a/packages/Connectivity/framework/src/android/net/TestNetworkSpecifier.java b/packages/Connectivity/framework/src/android/net/TestNetworkSpecifier.java
new file mode 100644
index 0000000..b7470a5
--- /dev/null
+++ b/packages/Connectivity/framework/src/android/net/TestNetworkSpecifier.java
@@ -0,0 +1,97 @@
+/*
+ * 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;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+
+/**
+ * A {@link NetworkSpecifier} used to identify test interfaces.
+ *
+ * @see TestNetworkManager
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public final class TestNetworkSpecifier extends NetworkSpecifier implements Parcelable {
+
+    /**
+     * Name of the network interface.
+     */
+    @NonNull
+    private final String mInterfaceName;
+
+    public TestNetworkSpecifier(@NonNull String interfaceName) {
+        Preconditions.checkStringNotEmpty(interfaceName);
+        mInterfaceName = interfaceName;
+    }
+
+    // This may be null in the future to support specifiers based on data other than the interface
+    // name.
+    @Nullable
+    public String getInterfaceName() {
+        return mInterfaceName;
+    }
+
+    @Override
+    public boolean canBeSatisfiedBy(@Nullable NetworkSpecifier other) {
+        return equals(other);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof TestNetworkSpecifier)) return false;
+        return TextUtils.equals(mInterfaceName, ((TestNetworkSpecifier) o).mInterfaceName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(mInterfaceName);
+    }
+
+    @Override
+    public String toString() {
+        return "TestNetworkSpecifier (" + mInterfaceName + ")";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(mInterfaceName);
+    }
+
+    public static final @NonNull Creator<TestNetworkSpecifier> CREATOR =
+            new Creator<TestNetworkSpecifier>() {
+        public TestNetworkSpecifier createFromParcel(Parcel in) {
+            return new TestNetworkSpecifier(in.readString());
+        }
+        public TestNetworkSpecifier[] newArray(int size) {
+            return new TestNetworkSpecifier[size];
+        }
+    };
+}
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/Connectivity/service/Android.bp b/packages/Connectivity/service/Android.bp
index e65b7b4..2fb9f72 100644
--- a/packages/Connectivity/service/Android.bp
+++ b/packages/Connectivity/service/Android.bp
@@ -50,12 +50,11 @@
 }
 
 java_library {
-    name: "service-connectivity",
+    name: "service-connectivity-pre-jarjar",
     srcs: [
+        ":framework-connectivity-shared-srcs",
         ":connectivity-service-srcs",
     ],
-    installable: true,
-    jarjar_rules: "jarjar-rules.txt",
     libs: [
         "android.net.ipsec.ike",
         "services.core",
@@ -73,3 +72,16 @@
         "com.android.tethering",
     ],
 }
+
+java_library {
+    name: "service-connectivity",
+    installable: true,
+    static_libs:[
+        "service-connectivity-pre-jarjar",
+    ],
+    jarjar_rules: "jarjar-rules.txt",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.tethering",
+    ],
+}
diff --git a/packages/Connectivity/service/jarjar-rules.txt b/packages/Connectivity/service/jarjar-rules.txt
index d8205bf..d8c60a4 100644
--- a/packages/Connectivity/service/jarjar-rules.txt
+++ b/packages/Connectivity/service/jarjar-rules.txt
@@ -1,2 +1,13 @@
 rule com.android.net.module.util.** com.android.connectivity.net-utils.@1
-rule com.android.modules.utils.** com.android.connectivity.modules-utils.@1
\ No newline at end of file
+rule com.android.modules.utils.** com.android.connectivity.modules-utils.@1
+
+# internal util classes
+# Exclude AsyncChannel. TODO: remove AsyncChannel usage in ConnectivityService
+rule com.android.internal.util.AsyncChannel* @0
+# Exclude LocationPermissionChecker. This is going to be moved to libs/net
+rule com.android.internal.util.LocationPermissionChecker* @0
+rule android.util.LocalLog* com.android.connectivity.util.LocalLog@1
+# android.util.IndentingPrintWriter* should use a different package name from
+# the one in com.android.internal.util
+rule android.util.IndentingPrintWriter* android.connectivity.util.IndentingPrintWriter@1
+rule com.android.internal.util.** com.android.connectivity.util.@1
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/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
index c1dca5d..16a946d 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
@@ -138,9 +138,6 @@
     private long mCurrentPartitionSize;
     private long mCurrentPartitionInstalledSize;
 
-    private boolean mJustCancelledByUser;
-    private boolean mKeepNotification;
-
     // This is for testing only now
     private boolean mEnableWhenCompleted;
 
@@ -174,11 +171,6 @@
         if (cache != null) {
             cache.flush();
         }
-
-        if (!mKeepNotification) {
-            // Cancel the persistent notification.
-            mNM.cancel(NOTIFICATION_ID);
-        }
     }
 
     @Override
@@ -231,9 +223,11 @@
             return;
         }
 
+        boolean removeNotification = false;
         switch (result) {
             case RESULT_CANCELLED:
                 postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED, null);
+                removeNotification = true;
                 break;
 
             case RESULT_ERROR_IO:
@@ -251,7 +245,7 @@
         }
 
         // if it's not successful, reset the task and stop self.
-        resetTaskAndStop();
+        resetTaskAndStop(removeNotification);
     }
 
     private void executeInstallCommand(Intent intent) {
@@ -302,12 +296,12 @@
             return;
         }
 
-        stopForeground(true);
-        mJustCancelledByUser = true;
-
         if (mInstallTask.cancel(false)) {
-            // Will stopSelf() in onResult()
+            // onResult() would call resetTaskAndStop() upon task completion.
             Log.d(TAG, "Cancel request filed successfully");
+            // Dismiss the notification as soon as possible as DynamicSystemManager.remove() may
+            // block.
+            stopForeground(STOP_FOREGROUND_REMOVE);
         } else {
             Log.e(TAG, "Trying to cancel installation while it's already completed.");
         }
@@ -322,8 +316,7 @@
         if (!isDynamicSystemInstalled() && (getStatus() != STATUS_READY)) {
             Log.e(TAG, "Trying to discard AOT while there is no complete installation");
             // Stop foreground state and dismiss stale notification.
-            stopForeground(STOP_FOREGROUND_REMOVE);
-            resetTaskAndStop();
+            resetTaskAndStop(true);
             return;
         }
 
@@ -331,8 +324,8 @@
                 getString(R.string.toast_dynsystem_discarded),
                 Toast.LENGTH_LONG).show();
 
-        resetTaskAndStop();
         postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED, null);
+        resetTaskAndStop(true);
 
         mDynSystem.remove();
     }
@@ -412,12 +405,13 @@
     }
 
     private void resetTaskAndStop() {
-        mInstallTask = null;
+        resetTaskAndStop(/* removeNotification= */ false);
+    }
 
-        new Handler().postDelayed(() -> {
-            stopForeground(STOP_FOREGROUND_DETACH);
-            stopSelf();
-        }, 50);
+    private void resetTaskAndStop(boolean removeNotification) {
+        mInstallTask = null;
+        stopForeground(removeNotification ? STOP_FOREGROUND_REMOVE : STOP_FOREGROUND_DETACH);
+        stopSelf();
     }
 
     private void prepareNotification() {
@@ -525,7 +519,7 @@
     private void postStatus(int status, int cause, Throwable detail) {
         String statusString;
         String causeString;
-        mKeepNotification = false;
+        boolean notifyOnNotificationBar = true;
 
         switch (status) {
             case STATUS_NOT_STARTED:
@@ -551,18 +545,16 @@
                 break;
             case CAUSE_INSTALL_CANCELLED:
                 causeString = "INSTALL_CANCELLED";
+                notifyOnNotificationBar = false;
                 break;
             case CAUSE_ERROR_IO:
                 causeString = "ERROR_IO";
-                mKeepNotification = true;
                 break;
             case CAUSE_ERROR_INVALID_URL:
                 causeString = "ERROR_INVALID_URL";
-                mKeepNotification = true;
                 break;
             case CAUSE_ERROR_EXCEPTION:
                 causeString = "ERROR_EXCEPTION";
-                mKeepNotification = true;
                 break;
             default:
                 causeString = "CAUSE_NOT_SPECIFIED";
@@ -571,16 +563,6 @@
 
         Log.d(TAG, "status=" + statusString + ", cause=" + causeString + ", detail=" + detail);
 
-        boolean notifyOnNotificationBar = true;
-
-        if (status == STATUS_NOT_STARTED
-                && cause == CAUSE_INSTALL_CANCELLED
-                && mJustCancelledByUser) {
-            // if task is cancelled by user, do not notify them
-            notifyOnNotificationBar = false;
-            mJustCancelledByUser = false;
-        }
-
         if (notifyOnNotificationBar) {
             mNM.notify(NOTIFICATION_ID, buildNotification(status, cause, detail));
         }
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..afa3bd1 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -85,6 +85,7 @@
 import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
 import android.net.ConnectivityDiagnosticsManager.DataStallReport;
 import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
 import android.net.DataStallReportParcelable;
 import android.net.DnsResolverServiceManager;
 import android.net.ICaptivePortal;
@@ -175,6 +176,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,8 +191,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;
 import com.android.internal.util.MessageUtils;
@@ -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;
 
@@ -346,8 +344,7 @@
     private String mCurrentTcpBufferSizes;
 
     private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames(
-            new Class[] { AsyncChannel.class, ConnectivityService.class, NetworkAgent.class,
-                    NetworkAgentInfo.class });
+            new Class[] { ConnectivityService.class, NetworkAgent.class, NetworkAgentInfo.class });
 
     private enum ReapUnvalidatedNetworks {
         // Tear down networks that have no chance (e.g. even if validated) of becoming
@@ -884,27 +881,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 +1064,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);
         }
     }
 
@@ -1060,7 +1099,8 @@
         mNetworkRanker = new NetworkRanker();
         final NetworkRequest defaultInternetRequest = createDefaultRequest();
         mDefaultRequest = new NetworkRequestInfo(
-                defaultInternetRequest, null, new Binder(),
+                defaultInternetRequest, null,
+                new Binder(), NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
                 null /* attributionTags */);
         mNetworkRequests.put(defaultInternetRequest, mDefaultRequest);
         mDefaultNetworkRequests.add(mDefaultRequest);
@@ -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) {
@@ -1317,7 +1356,9 @@
 
         if (enable) {
             handleRegisterNetworkRequest(new NetworkRequestInfo(
-                    networkRequest, null, new Binder(),
+                    networkRequest, null,
+                    new Binder(),
+                    NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
                     null /* attributionTags */));
         } else {
             handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID,
@@ -1479,11 +1520,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 +1600,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;
     }
 
@@ -1678,8 +1719,8 @@
                 result.put(
                         nai.network,
                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
-                                nc, mDeps.getCallingUid(), callingPackageName,
-                                callingAttributionTag));
+                                nc, false /* includeLocationSensitiveInfo */,
+                                mDeps.getCallingUid(), callingPackageName, callingAttributionTag));
             }
         }
 
@@ -1692,7 +1733,9 @@
                     result.put(
                             network,
                             createWithLocationInfoSanitizedIfNecessaryWhenParceled(
-                                    nc, mDeps.getCallingUid(), callingPackageName,
+                                    nc,
+                                    false /* includeLocationSensitiveInfo */,
+                                    mDeps.getCallingUid(), callingPackageName,
                                     callingAttributionTag));
                 }
             }
@@ -1774,6 +1817,7 @@
         enforceAccessPermission();
         return createWithLocationInfoSanitizedIfNecessaryWhenParceled(
                 getNetworkCapabilitiesInternal(network),
+                false /* includeLocationSensitiveInfo */,
                 mDeps.getCallingUid(), callingPackageName, callingAttributionTag);
     }
 
@@ -1807,8 +1851,8 @@
     @VisibleForTesting
     @Nullable
     NetworkCapabilities createWithLocationInfoSanitizedIfNecessaryWhenParceled(
-            @Nullable NetworkCapabilities nc, int callerUid, @NonNull String callerPkgName,
-            @Nullable String callingAttributionTag) {
+            @Nullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo,
+            int callerUid, @NonNull String callerPkgName, @Nullable String callingAttributionTag) {
         if (nc == null) {
             return null;
         }
@@ -1816,7 +1860,9 @@
         final NetworkCapabilities newNc;
         // Avoid doing location permission check if the transport info has no location sensitive
         // data.
-        if (nc.getTransportInfo() != null && nc.getTransportInfo().hasLocationSensitiveFields()) {
+        if (includeLocationSensitiveInfo
+                && nc.getTransportInfo() != null
+                && nc.getTransportInfo().hasLocationSensitiveFields()) {
             hasLocationPermission =
                     hasLocationPermission(callerUid, callerPkgName, callingAttributionTag);
             newNc = new NetworkCapabilities(nc, hasLocationPermission);
@@ -1833,6 +1879,16 @@
             // Owner UIDs already checked above. No need to re-check.
             return newNc;
         }
+        // If the caller does not want location sensitive data & target SDK >= S, then mask info.
+        // Else include the owner UID iff the caller has location permission to provide backwards
+        // compatibility for older apps.
+        if (!includeLocationSensitiveInfo
+                && isTargetSdkAtleast(
+                        Build.VERSION_CODES.S, callerUid, callerPkgName)) {
+            newNc.setOwnerUid(INVALID_UID);
+            return newNc;
+        }
+
         if (hasLocationPermission == null) {
             // Location permission not checked yet, check now for masking owner UID.
             hasLocationPermission =
@@ -2354,9 +2410,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 +2647,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 +2662,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);
@@ -2854,22 +2907,6 @@
             super(looper);
         }
 
-        private boolean maybeHandleAsyncChannelMessage(Message msg) {
-            switch (msg.what) {
-                default:
-                    return false;
-                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
-                    handleAsyncChannelHalfConnect(msg);
-                    break;
-                }
-                case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
-                    handleAsyncChannelDisconnected(msg);
-                    break;
-                }
-            }
-            return true;
-        }
-
         private void maybeHandleNetworkAgentMessage(Message msg) {
             final Pair<NetworkAgentInfo, Object> arg = (Pair<NetworkAgentInfo, Object>) msg.obj;
             final NetworkAgentInfo nai = arg.first;
@@ -3161,8 +3198,7 @@
 
         @Override
         public void handleMessage(Message msg) {
-            if (!maybeHandleAsyncChannelMessage(msg)
-                    && !maybeHandleNetworkMonitorMessage(msg)
+            if (!maybeHandleNetworkMonitorMessage(msg)
                     && !maybeHandleNetworkAgentInfoMessage(msg)) {
                 maybeHandleNetworkAgentMessage(msg);
             }
@@ -3426,21 +3462,6 @@
         return false;
     }
 
-    private void handleAsyncChannelHalfConnect(Message msg) {
-        ensureRunningOnConnectivityServiceThread();
-        if (mNetworkProviderInfos.containsKey(msg.replyTo)) {
-            if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
-                if (VDBG) log("NetworkFactory connected");
-                // Finish setting up the full connection
-                NetworkProviderInfo npi = mNetworkProviderInfos.get(msg.replyTo);
-                sendAllRequestsToProvider(npi);
-            } else {
-                loge("Error connecting NetworkFactory");
-                mNetworkProviderInfos.remove(msg.obj);
-            }
-        }
-    }
-
     private void handleNetworkAgentRegistered(Message msg) {
         final NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
         if (!mNetworkAgentInfos.contains(nai)) {
@@ -3471,14 +3492,6 @@
         }
     }
 
-    // This is a no-op if it's called with a message designating a provider that has
-    // already been destroyed, because its reference will not be found in the relevant
-    // maps.
-    private void handleAsyncChannelDisconnected(Message msg) {
-        NetworkProviderInfo npi = mNetworkProviderInfos.remove(msg.replyTo);
-        if (DBG && npi != null) log("unregisterNetworkFactory for " + npi.name);
-    }
-
     // Destroys a network, remove references to it from the internal state managed by
     // ConnectivityService, free its interfaces and clean up.
     // Must be called on the Handler thread.
@@ -3604,11 +3617,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 +3663,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 +5015,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 +5025,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 +5037,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) {
@@ -5093,8 +5132,8 @@
         private final IBinder.DeathRecipient mDeathRecipient;
         public final int providerId;
 
-        NetworkProviderInfo(String name, Messenger messenger, AsyncChannel asyncChannel,
-                int providerId, @NonNull IBinder.DeathRecipient deathRecipient) {
+        NetworkProviderInfo(String name, Messenger messenger, int providerId,
+                @NonNull IBinder.DeathRecipient deathRecipient) {
             this.name = name;
             this.messenger = messenger;
             this.providerId = providerId;
@@ -5188,6 +5227,7 @@
         private final IBinder mBinder;
         final int mPid;
         final int mUid;
+        final @NetworkCallback.Flag int mCallbackFlags;
         @Nullable
         final String mCallingAttributionTag;
         // In order to preserve the mapping of NetworkRequest-to-callback when apps register
@@ -5235,17 +5275,26 @@
             mPid = getCallingPid();
             mUid = mDeps.getCallingUid();
             mNetworkRequestCounter.incrementCountOrThrow(mUid);
+            /**
+             * Location sensitive data not included in pending intent. Only included in
+             * {@link NetworkCallback}.
+             */
+            mCallbackFlags = NetworkCallback.FLAG_NONE;
             mCallingAttributionTag = callingAttributionTag;
         }
 
         NetworkRequestInfo(@NonNull final NetworkRequest r, @Nullable final Messenger m,
-                @Nullable final IBinder binder, @Nullable String callingAttributionTag) {
-            this(Collections.singletonList(r), r, m, binder, callingAttributionTag);
+                @Nullable final IBinder binder,
+                @NetworkCallback.Flag int callbackFlags,
+                @Nullable String callingAttributionTag) {
+            this(Collections.singletonList(r), r, m, binder, callbackFlags, callingAttributionTag);
         }
 
         NetworkRequestInfo(@NonNull final List<NetworkRequest> r,
                 @NonNull final NetworkRequest requestForCallback, @Nullable final Messenger m,
-                @Nullable final IBinder binder, @Nullable String callingAttributionTag) {
+                @Nullable final IBinder binder,
+                @NetworkCallback.Flag int callbackFlags,
+                @Nullable String callingAttributionTag) {
             super();
             ensureAllNetworkRequestsHaveType(r);
             mRequests = initializeRequests(r);
@@ -5256,6 +5305,7 @@
             mUid = mDeps.getCallingUid();
             mPendingIntent = null;
             mNetworkRequestCounter.incrementCountOrThrow(mUid);
+            mCallbackFlags = callbackFlags;
             mCallingAttributionTag = callingAttributionTag;
 
             try {
@@ -5271,20 +5321,33 @@
             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;
             mUid = nri.mUid;
             mPendingIntent = nri.mPendingIntent;
             mNetworkRequestCounter.incrementCountOrThrow(mUid);
+            mCallbackFlags = nri.mCallbackFlags;
             mCallingAttributionTag = nri.mCallingAttributionTag;
         }
 
@@ -5334,7 +5397,8 @@
                     + " callback request Id: "
                     + mNetworkRequestForCallback.requestId
                     + " " + mRequests
-                    + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent);
+                    + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent)
+                    + "callback flags: " + mCallbackFlags;
         }
     }
 
@@ -5418,13 +5482,13 @@
         }
     }
 
-    private boolean checkUnsupportedStartingFrom(int version, String callingPackageName) {
-        final UserHandle user = UserHandle.getUserHandleForUid(mDeps.getCallingUid());
+    private boolean isTargetSdkAtleast(int version, int callingUid,
+            @NonNull String callingPackageName) {
+        final UserHandle user = UserHandle.getUserHandleForUid(callingUid);
         final PackageManager pm =
                 mContext.createContextAsUser(user, 0 /* flags */).getPackageManager();
         try {
-            final int callingVersion = pm.getApplicationInfo(
-                    callingPackageName, 0 /* flags */).targetSdkVersion;
+            final int callingVersion = pm.getTargetSdkVersion(callingPackageName);
             if (callingVersion < version) return false;
         } catch (PackageManager.NameNotFoundException e) { }
         return true;
@@ -5433,10 +5497,11 @@
     @Override
     public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
             int reqTypeInt, Messenger messenger, int timeoutMs, IBinder binder,
-            int legacyType, @NonNull String callingPackageName,
+            int legacyType, int callbackFlags, @NonNull String callingPackageName,
             @Nullable String callingAttributionTag) {
         if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) {
-            if (checkUnsupportedStartingFrom(Build.VERSION_CODES.M, callingPackageName)) {
+            if (isTargetSdkAtleast(Build.VERSION_CODES.M, mDeps.getCallingUid(),
+                    callingPackageName)) {
                 throw new SecurityException("Insufficient permissions to specify legacy type");
             }
         }
@@ -5473,6 +5538,8 @@
                 //  request if the app changes network state. http://b/29964605
                 enforceMeteredApnPolicy(networkCapabilities);
                 break;
+            case TRACK_BEST:
+                throw new UnsupportedOperationException("Not implemented yet");
             default:
                 throw new IllegalArgumentException("Unsupported request type " + reqType);
         }
@@ -5496,7 +5563,7 @@
         final NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
                 nextNetworkRequestId(), reqType);
         final NetworkRequestInfo nri = getNriToRegister(
-                networkRequest, messenger, binder, callingAttributionTag);
+                networkRequest, messenger, binder, callbackFlags, callingAttributionTag);
         if (DBG) log("requestNetwork for " + nri);
 
         // For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were
@@ -5531,6 +5598,7 @@
      */
     private NetworkRequestInfo getNriToRegister(@NonNull final NetworkRequest nr,
             @Nullable final Messenger msgr, @Nullable final IBinder binder,
+            @NetworkCallback.Flag int callbackFlags,
             @Nullable String callingAttributionTag) {
         final List<NetworkRequest> requests;
         if (NetworkRequest.Type.TRACK_DEFAULT == nr.type) {
@@ -5539,7 +5607,8 @@
         } else {
             requests = Collections.singletonList(nr);
         }
-        return new NetworkRequestInfo(requests, nr, msgr, binder, callingAttributionTag);
+        return new NetworkRequestInfo(
+                requests, nr, msgr, binder, callbackFlags, callingAttributionTag);
     }
 
     private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities,
@@ -5665,8 +5734,9 @@
 
     @Override
     public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities,
-            Messenger messenger, IBinder binder, @NonNull String callingPackageName,
-            @Nullable String callingAttributionTag) {
+            Messenger messenger, IBinder binder,
+            @NetworkCallback.Flag int callbackFlags,
+            @NonNull String callingPackageName, @NonNull String callingAttributionTag) {
         final int callingUid = mDeps.getCallingUid();
         if (!hasWifiNetworkListenPermission(networkCapabilities)) {
             enforceAccessPermission();
@@ -5687,7 +5757,8 @@
         NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
                 NetworkRequest.Type.LISTEN);
         NetworkRequestInfo nri =
-                new NetworkRequestInfo(networkRequest, messenger, binder, callingAttributionTag);
+                new NetworkRequestInfo(networkRequest, messenger, binder, callbackFlags,
+                        callingAttributionTag);
         if (VDBG) log("listenForNetwork for " + nri);
 
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
@@ -5756,8 +5827,7 @@
     public int registerNetworkProvider(Messenger messenger, String name) {
         enforceNetworkFactoryOrSettingsPermission();
         NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger,
-                null /* asyncChannel */, nextNetworkProviderId(),
-                () -> unregisterNetworkProvider(messenger));
+                nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger));
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi));
         return npi.providerId;
     }
@@ -6078,7 +6148,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 +6351,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);
                 }
@@ -7016,6 +7086,8 @@
         if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL) {
             putParcelable(bundle, networkAgent.network);
         }
+        final boolean includeLocationSensitiveInfo =
+                (nri.mCallbackFlags & NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) != 0;
         switch (notificationType) {
             case ConnectivityManager.CALLBACK_AVAILABLE: {
                 final NetworkCapabilities nc =
@@ -7024,7 +7096,8 @@
                 putParcelable(
                         bundle,
                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
-                                nc, nri.mUid, nrForCallback.getRequestorPackageName(),
+                                nc, includeLocationSensitiveInfo, nri.mUid,
+                                nrForCallback.getRequestorPackageName(),
                                 nri.mCallingAttributionTag));
                 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
                         networkAgent.linkProperties, nri.mPid, nri.mUid));
@@ -7044,7 +7117,8 @@
                 putParcelable(
                         bundle,
                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
-                                netCap, nri.mUid, nrForCallback.getRequestorPackageName(),
+                                netCap, includeLocationSensitiveInfo, nri.mUid,
+                                nrForCallback.getRequestorPackageName(),
                                 nri.mCallingAttributionTag));
                 break;
             }
@@ -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/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 81d4b9d..4c3c6ef 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -56,6 +56,7 @@
 import android.system.OsConstants;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.Range;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
@@ -756,13 +757,9 @@
         }
     }
 
-    // These values have been reserved in NetIdManager
-    @VisibleForTesting static final int TUN_INTF_NETID_START = 0xFC00;
-
-    public static final int TUN_INTF_NETID_RANGE = 0x0400;
-
     private final SparseBooleanArray mTunnelNetIds = new SparseBooleanArray();
-    private int mNextTunnelNetIdIndex = 0;
+    final Range<Integer> mNetIdRange = ConnectivityManager.getIpSecNetIdRange();
+    private int mNextTunnelNetId = mNetIdRange.getLower();
 
     /**
      * Reserves a netId within the range of netIds allocated for IPsec tunnel interfaces
@@ -775,11 +772,13 @@
      */
     @VisibleForTesting
     int reserveNetId() {
+        final int range = mNetIdRange.getUpper() - mNetIdRange.getLower() + 1;
         synchronized (mTunnelNetIds) {
-            for (int i = 0; i < TUN_INTF_NETID_RANGE; i++) {
-                int index = mNextTunnelNetIdIndex;
-                int netId = index + TUN_INTF_NETID_START;
-                if (++mNextTunnelNetIdIndex >= TUN_INTF_NETID_RANGE) mNextTunnelNetIdIndex = 0;
+            for (int i = 0; i < range; i++) {
+                final int netId = mNextTunnelNetId;
+                if (++mNextTunnelNetId > mNetIdRange.getUpper()) {
+                    mNextTunnelNetId = mNetIdRange.getLower();
+                }
                 if (!mTunnelNetIds.get(netId)) {
                     mTunnelNetIds.put(netId, true);
                     return netId;
diff --git a/services/core/java/com/android/server/NetIdManager.java b/services/core/java/com/android/server/NetIdManager.java
index 097fb3a..61925c8 100644
--- a/services/core/java/com/android/server/NetIdManager.java
+++ b/services/core/java/com/android/server/NetIdManager.java
@@ -17,6 +17,7 @@
 package com.android.server;
 
 import android.annotation.NonNull;
+import android.net.ConnectivityManager;
 import android.util.SparseBooleanArray;
 
 import com.android.internal.annotations.GuardedBy;
@@ -31,7 +32,7 @@
     // Sequence number for Networks; keep in sync with system/netd/NetworkController.cpp
     public static final int MIN_NET_ID = 100; // some reserved marks
     // Top IDs reserved by IpSecService
-    public static final int MAX_NET_ID = 65535 - IpSecService.TUN_INTF_NETID_RANGE;
+    public static final int MAX_NET_ID = ConnectivityManager.getIpSecNetIdRange().getLower() - 1;
 
     @GuardedBy("mNetIdInUse")
     private final SparseBooleanArray mNetIdInUse = new SparseBooleanArray();
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index 222c96f..3bcde12 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -19,6 +19,7 @@
 
 per-file *Alarm* = file:/apex/jobscheduler/OWNERS
 per-file *AppOp* = file:/core/java/android/permission/OWNERS
+per-file *Battery* = file:/BATTERY_STATS_OWNERS
 per-file *Bluetooth* = file:/core/java/android/bluetooth/OWNERS
 per-file *Gnss* = file:/services/core/java/com/android/server/location/OWNERS
 per-file *Location* = file:/services/core/java/com/android/server/location/OWNERS
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/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index 55408ea..ee61067 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -33,8 +33,8 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkProvider;
 import android.net.RouteInfo;
-import android.net.StringNetworkSpecifier;
 import android.net.TestNetworkInterface;
+import android.net.TestNetworkSpecifier;
 import android.net.util.NetdService;
 import android.os.Binder;
 import android.os.Handler;
@@ -242,7 +242,7 @@
         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
-        nc.setNetworkSpecifier(new StringNetworkSpecifier(iface));
+        nc.setNetworkSpecifier(new TestNetworkSpecifier(iface));
         nc.setAdministratorUids(administratorUids);
         if (!isMetered) {
             nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 502e74a..1ef93f4 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -667,6 +667,10 @@
             @NonNull IVcnUnderlyingNetworkPolicyListener listener) {
         requireNonNull(listener, "listener was null");
 
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.NETWORK_FACTORY,
+                "Must have permission NETWORK_FACTORY to unregister a policy listener");
+
         Binder.withCleanCallingIdentity(() -> {
             synchronized (mLock) {
                 PolicyListenerBinderDeath listenerBinderDeath =
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/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java
index df83df9..ae9b001 100644
--- a/services/core/java/com/android/server/compat/CompatChange.java
+++ b/services/core/java/com/android/server/compat/CompatChange.java
@@ -28,6 +28,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 
+import com.android.internal.compat.AndroidBuildClassifier;
 import com.android.internal.compat.CompatibilityChangeInfo;
 import com.android.internal.compat.OverrideAllowedState;
 import com.android.server.compat.config.Change;
@@ -55,7 +56,7 @@
      * A change ID to be used only in the CTS test for this SystemApi
      */
     @ChangeId
-    @EnabledSince(targetSdkVersion = 1235) // Needs to be > test APK targetSdkVersion.
+    @EnabledSince(targetSdkVersion = 31) // Needs to be > test APK targetSdkVersion.
     static final long CTS_SYSTEM_API_CHANGEID = 149391281; // This is a bug id.
 
     /**
@@ -80,6 +81,15 @@
     }
 
     /**
+     * @param change an object generated by services/core/xsd/platform-compat-config.xsd
+     */
+    public CompatChange(Change change) {
+        this(change.getId(), change.getName(), change.getEnableAfterTargetSdk(),
+                change.getEnableSinceTargetSdk(), change.getDisabled(), change.getLoggingOnly(),
+                change.getDescription(), change.getOverridable());
+    }
+
+    /**
      * @param changeId Unique ID for the change. See {@link android.compat.Compatibility}.
      * @param name Short descriptive name.
      * @param enableAfterTargetSdk {@code targetSdkVersion} restriction. See {@link EnabledAfter};
@@ -93,15 +103,10 @@
             boolean overridable) {
         super(changeId, name, enableAfterTargetSdk, enableSinceTargetSdk, disabled, loggingOnly,
               description, overridable);
-    }
 
-    /**
-     * @param change an object generated by services/core/xsd/platform-compat-config.xsd
-     */
-    public CompatChange(Change change) {
-        super(change.getId(), change.getName(), change.getEnableAfterTargetSdk(),
-                change.getEnableSinceTargetSdk(), change.getDisabled(), change.getLoggingOnly(),
-                change.getDescription(), change.getOverridable());
+        // Initialize override maps.
+        mEvaluatedOverrides = new HashMap<>();
+        mRawOverrides = new HashMap<>();
     }
 
     void registerListener(ChangeListener listener) {
@@ -127,18 +132,13 @@
             throw new IllegalArgumentException(
                     "Can't add overrides for a logging only change " + toString());
         }
-        if (mEvaluatedOverrides == null) {
-            mEvaluatedOverrides = new HashMap<>();
-        }
         mEvaluatedOverrides.put(pname, enabled);
         notifyListener(pname);
     }
 
     private void removePackageOverrideInternal(String pname) {
-        if (mEvaluatedOverrides != null) {
-            if (mEvaluatedOverrides.remove(pname) != null) {
-                notifyListener(pname);
-            }
+        if (mEvaluatedOverrides.remove(pname) != null) {
+            notifyListener(pname);
         }
     }
 
@@ -157,9 +157,6 @@
             throw new IllegalArgumentException(
                     "Can't add overrides for a logging only change " + toString());
         }
-        if (mRawOverrides == null) {
-            mRawOverrides = new HashMap<>();
-        }
         mRawOverrides.put(packageName, override);
         recheckOverride(packageName, allowedState, context);
     }
@@ -212,7 +209,7 @@
     }
 
     boolean hasPackageOverride(String pname) {
-        return mRawOverrides != null && mRawOverrides.containsKey(pname);
+        return mRawOverrides.containsKey(pname);
     }
     /**
      * Remove any package override for the given package name, restoring the default behaviour.
@@ -223,7 +220,7 @@
      */
     boolean removePackageOverride(String pname, OverrideAllowedState allowedState,
             Context context) {
-        if (mRawOverrides != null && (mRawOverrides.remove(pname) != null)) {
+        if (mRawOverrides.remove(pname) != null) {
             recheckOverride(pname, allowedState, context);
             return true;
         }
@@ -237,18 +234,24 @@
      * @param app Info about the app in question
      * @return {@code true} if the change should be enabled for the package.
      */
-    boolean isEnabled(ApplicationInfo app) {
+    boolean isEnabled(ApplicationInfo app, AndroidBuildClassifier buildClassifier) {
         if (app == null) {
             return defaultValue();
         }
-        if (mEvaluatedOverrides != null && mEvaluatedOverrides.containsKey(app.packageName)) {
+        if (mEvaluatedOverrides.containsKey(app.packageName)) {
             return mEvaluatedOverrides.get(app.packageName);
         }
         if (getDisabled()) {
             return false;
         }
         if (getEnableSinceTargetSdk() != -1) {
-            return app.targetSdkVersion >= getEnableSinceTargetSdk();
+            // If the change is gated by a platform version newer than the one currently installed
+            // on the device, disregard the app's target sdk version.
+            int compareSdk = Math.min(app.targetSdkVersion, buildClassifier.platformTargetSdk());
+            if (compareSdk != app.targetSdkVersion) {
+                compareSdk = app.targetSdkVersion;
+            }
+            return compareSdk >= getEnableSinceTargetSdk();
         }
         return true;
     }
@@ -289,7 +292,7 @@
      * @return true if there is such override
      */
     private boolean hasOverride(String packageName) {
-        return mEvaluatedOverrides != null && mEvaluatedOverrides.containsKey(packageName);
+        return mEvaluatedOverrides.containsKey(packageName);
     }
 
     /**
@@ -298,20 +301,15 @@
      * @return true if there is such a deferred override
      */
     private boolean hasRawOverride(String packageName) {
-        return mRawOverrides != null && mRawOverrides.containsKey(packageName);
+        return mRawOverrides.containsKey(packageName);
+    }
+
+    void clearOverrides() {
+        mRawOverrides.clear();
+        mEvaluatedOverrides.clear();
     }
 
     void loadOverrides(ChangeOverrides changeOverrides) {
-        if (mRawOverrides == null) {
-            mRawOverrides = new HashMap<>();
-        }
-        mRawOverrides.clear();
-
-        if (mEvaluatedOverrides == null) {
-            mEvaluatedOverrides = new HashMap<>();
-        }
-        mEvaluatedOverrides.clear();
-
         // Load deferred overrides for backwards compatibility
         if (changeOverrides.getDeferred() != null) {
             for (OverrideValue override : changeOverrides.getDeferred().getOverrideValue()) {
@@ -345,34 +343,30 @@
     }
 
     ChangeOverrides saveOverrides() {
-        if (mRawOverrides == null || mRawOverrides.isEmpty()) {
+        if (mRawOverrides.isEmpty()) {
             return null;
         }
         ChangeOverrides changeOverrides = new ChangeOverrides();
         changeOverrides.setChangeId(getId());
         ChangeOverrides.Raw rawOverrides = new ChangeOverrides.Raw();
         List<RawOverrideValue> rawList = rawOverrides.getRawOverrideValue();
-        if (mRawOverrides != null) {
-            for (Map.Entry<String, PackageOverride> entry : mRawOverrides.entrySet()) {
-                RawOverrideValue override = new RawOverrideValue();
-                override.setPackageName(entry.getKey());
-                override.setMinVersionCode(entry.getValue().getMinVersionCode());
-                override.setMaxVersionCode(entry.getValue().getMaxVersionCode());
-                override.setEnabled(entry.getValue().getEnabled());
-                rawList.add(override);
-            }
+        for (Map.Entry<String, PackageOverride> entry : mRawOverrides.entrySet()) {
+            RawOverrideValue override = new RawOverrideValue();
+            override.setPackageName(entry.getKey());
+            override.setMinVersionCode(entry.getValue().getMinVersionCode());
+            override.setMaxVersionCode(entry.getValue().getMaxVersionCode());
+            override.setEnabled(entry.getValue().getEnabled());
+            rawList.add(override);
         }
         changeOverrides.setRaw(rawOverrides);
 
         ChangeOverrides.Validated validatedOverrides = new ChangeOverrides.Validated();
         List<OverrideValue> validatedList = validatedOverrides.getOverrideValue();
-        if (mEvaluatedOverrides != null) {
-            for (Map.Entry<String, Boolean> entry : mEvaluatedOverrides.entrySet()) {
-                OverrideValue override = new OverrideValue();
-                override.setPackageName(entry.getKey());
-                override.setEnabled(entry.getValue());
-                validatedList.add(override);
-            }
+        for (Map.Entry<String, Boolean> entry : mEvaluatedOverrides.entrySet()) {
+            OverrideValue override = new OverrideValue();
+            override.setPackageName(entry.getKey());
+            override.setEnabled(entry.getValue());
+            validatedList.add(override);
         }
         changeOverrides.setValidated(validatedOverrides);
         return changeOverrides;
@@ -394,10 +388,10 @@
         if (getLoggingOnly()) {
             sb.append("; loggingOnly");
         }
-        if (mEvaluatedOverrides != null && mEvaluatedOverrides.size() > 0) {
+        if (!mEvaluatedOverrides.isEmpty()) {
             sb.append("; packageOverrides=").append(mEvaluatedOverrides);
         }
-        if (mRawOverrides != null && mRawOverrides.size() > 0) {
+        if (!mRawOverrides.isEmpty()) {
             sb.append("; rawOverrides=").append(mRawOverrides);
         }
         if (getOverridable()) {
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index 66a6520..ef86f42 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -67,18 +67,21 @@
 
     private static final String TAG = "CompatConfig";
     private static final String APP_COMPAT_DATA_DIR = "/data/misc/appcompat";
+    private static final String STATIC_OVERRIDES_PRODUCT_DIR = "/product/etc/appcompat";
     private static final String OVERRIDES_FILE = "compat_framework_overrides.xml";
 
     @GuardedBy("mChanges")
     private final LongSparseArray<CompatChange> mChanges = new LongSparseArray<>();
 
     private final OverrideValidatorImpl mOverrideValidator;
+    private final AndroidBuildClassifier mAndroidBuildClassifier;
     private Context mContext;
     private File mOverridesFile;
 
     @VisibleForTesting
     CompatConfig(AndroidBuildClassifier androidBuildClassifier, Context context) {
         mOverrideValidator = new OverrideValidatorImpl(androidBuildClassifier, context, this);
+        mAndroidBuildClassifier = androidBuildClassifier;
         mContext = context;
     }
 
@@ -94,8 +97,7 @@
             config.initConfigFromLib(Environment.buildPath(
                     apex.apexDirectory, "etc", "compatconfig"));
         }
-        File overridesFile = new File(APP_COMPAT_DATA_DIR, OVERRIDES_FILE);
-        config.initOverrides(overridesFile);
+        config.initOverrides();
         config.invalidateCache();
         return config;
     }
@@ -133,7 +135,7 @@
         synchronized (mChanges) {
             for (int i = 0; i < mChanges.size(); ++i) {
                 CompatChange c = mChanges.valueAt(i);
-                if (!c.isEnabled(app)) {
+                if (!c.isEnabled(app, mAndroidBuildClassifier)) {
                     disabled.add(c.getId());
                 }
             }
@@ -175,7 +177,7 @@
                 // we know nothing about this change: default behaviour is enabled.
                 return true;
             }
-            return c.isEnabled(app);
+            return c.isEnabled(app, mAndroidBuildClassifier);
         }
     }
 
@@ -475,7 +477,7 @@
         synchronized (mChanges) {
             for (int i = 0; i < mChanges.size(); ++i) {
                 CompatChange c = mChanges.valueAt(i);
-                if (c.isEnabled(applicationInfo)) {
+                if (c.isEnabled(applicationInfo, mAndroidBuildClassifier)) {
                     enabled.add(c.getId());
                 } else {
                     disabled.add(c.getId());
@@ -525,10 +527,34 @@
         }
     }
 
-    void initOverrides(File overridesFile) {
+    private void initOverrides() {
+        initOverrides(new File(APP_COMPAT_DATA_DIR, OVERRIDES_FILE),
+                new File(STATIC_OVERRIDES_PRODUCT_DIR, OVERRIDES_FILE));
+    }
+
+    @VisibleForTesting
+    void initOverrides(File dynamicOverridesFile, File staticOverridesFile) {
+        // Clear overrides from all changes before loading.
+        synchronized (mChanges) {
+            for (int i = 0; i < mChanges.size(); ++i) {
+                mChanges.valueAt(i).clearOverrides();
+            }
+        }
+
+        loadOverrides(staticOverridesFile);
+
+        mOverridesFile = dynamicOverridesFile;
+        loadOverrides(dynamicOverridesFile);
+
+        if (staticOverridesFile.exists()) {
+            // Only save overrides if there is a static overrides file.
+            saveOverrides();
+        }
+    }
+
+    private void loadOverrides(File overridesFile) {
         if (!overridesFile.exists()) {
-            mOverridesFile = overridesFile;
-            // There have not been any overrides added yet.
+            // Overrides file doesn't exist.
             return;
         }
 
@@ -548,7 +574,6 @@
             Slog.w(TAG, "Error processing " + overridesFile + " " + e.toString());
             return;
         }
-        mOverridesFile = overridesFile;
     }
 
     /**
diff --git a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
index fe5b4a9..aa66a1a 100644
--- a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
+++ b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
@@ -22,6 +22,7 @@
 import static com.android.internal.compat.OverrideAllowedState.DISABLED_NOT_DEBUGGABLE;
 import static com.android.internal.compat.OverrideAllowedState.DISABLED_TARGET_SDK_TOO_HIGH;
 import static com.android.internal.compat.OverrideAllowedState.LOGGING_ONLY_CHANGE;
+import static com.android.internal.compat.OverrideAllowedState.PLATFORM_TOO_OLD;
 
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -85,6 +86,9 @@
         if (debuggableBuild) {
             return new OverrideAllowedState(ALLOWED, -1, -1);
         }
+        if (maxTargetSdk >= mAndroidBuildClassifier.platformTargetSdk()) {
+            return new OverrideAllowedState(PLATFORM_TOO_OLD, -1, maxTargetSdk);
+        }
         PackageManager packageManager = mContext.getPackageManager();
         if (packageManager == null) {
             throw new IllegalStateException("No PackageManager!");
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index edfc8b8..40e3863 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -66,18 +66,22 @@
     private final Context mContext;
     private final ChangeReporter mChangeReporter;
     private final CompatConfig mCompatConfig;
+    private final AndroidBuildClassifier mBuildClassifier;
 
     public PlatformCompat(Context context) {
         mContext = context;
         mChangeReporter = new ChangeReporter(ChangeReporter.SOURCE_SYSTEM_SERVER);
-        mCompatConfig = CompatConfig.create(new AndroidBuildClassifier(), mContext);
+        mBuildClassifier = new AndroidBuildClassifier();
+        mCompatConfig = CompatConfig.create(mBuildClassifier, mContext);
     }
 
     @VisibleForTesting
-    PlatformCompat(Context context, CompatConfig compatConfig) {
+    PlatformCompat(Context context, CompatConfig compatConfig,
+                   AndroidBuildClassifier buildClassifier) {
         mContext = context;
         mChangeReporter = new ChangeReporter(ChangeReporter.SOURCE_SYSTEM_SERVER);
         mCompatConfig = compatConfig;
+        mBuildClassifier = buildClassifier;
 
         registerPackageReceiver(context);
     }
@@ -392,7 +396,8 @@
             return false;
         }
         if (change.getEnableSinceTargetSdk() > 0) {
-            return change.getEnableSinceTargetSdk() >= Build.VERSION_CODES.Q;
+            return change.getEnableSinceTargetSdk() >= Build.VERSION_CODES.Q
+                && change.getEnableSinceTargetSdk() <= mBuildClassifier.platformTargetSdk();
         }
         return true;
     }
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/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 9411e33..488677a 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -31,14 +31,17 @@
 import static com.android.net.module.util.CollectionUtils.toIntArray;
 
 import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.PackageManagerInternal;
 import android.net.INetd;
 import android.net.UidRange;
+import android.net.Uri;
 import android.os.Build;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
@@ -54,7 +57,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.net.module.util.CollectionUtils;
-import com.android.server.LocalServices;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -71,7 +73,7 @@
  *
  * @hide
  */
-public class PermissionMonitor implements PackageManagerInternal.PackageListObserver {
+public class PermissionMonitor {
     private static final String TAG = "PermissionMonitor";
     private static final boolean DBG = true;
     protected static final Boolean SYSTEM = Boolean.TRUE;
@@ -83,6 +85,7 @@
     private final SystemConfigManager mSystemConfigManager;
     private final INetd mNetd;
     private final Dependencies mDeps;
+    private final Context mContext;
 
     @GuardedBy("this")
     private final Set<UserHandle> mUsers = new HashSet<>();
@@ -102,6 +105,25 @@
     @GuardedBy("this")
     private final Set<Integer> mAllApps = new HashSet<>();
 
+    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+            final Uri packageData = intent.getData();
+            final String packageName =
+                    packageData != null ? packageData.getSchemeSpecificPart() : null;
+
+            if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
+                onPackageAdded(packageName, uid);
+            } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+                onPackageRemoved(packageName, uid);
+            } else {
+                Log.wtf(TAG, "received unexpected intent: " + action);
+            }
+        }
+    };
+
     /**
      * Dependencies of PermissionMonitor, for injection in tests.
      */
@@ -127,6 +149,7 @@
         mSystemConfigManager = context.getSystemService(SystemConfigManager.class);
         mNetd = netd;
         mDeps = deps;
+        mContext = context;
     }
 
     // Intended to be called only once at startup, after the system is ready. Installs a broadcast
@@ -134,12 +157,14 @@
     public synchronized void startMonitoring() {
         log("Monitoring");
 
-        PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
-        if (pmi != null) {
-            pmi.getPackageList(this);
-        } else {
-            loge("failed to get the PackageManagerInternal service");
-        }
+        final IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        intentFilter.addDataScheme("package");
+        mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */).registerReceiver(
+                mIntentReceiver, intentFilter, null /* broadcastPermission */,
+                null /* scheduler */);
+
         List<PackageInfo> apps = mPackageManager.getInstalledPackages(GET_PERMISSIONS
                 | MATCH_ANY_USER);
         if (apps == null) {
@@ -347,9 +372,10 @@
      *
      * @hide
      */
-    @Override
     public synchronized void onPackageAdded(@NonNull final String packageName, final int uid) {
-        sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
+        // TODO: Netd is using appId for checking traffic permission. Correct the methods that are
+        //  using appId instead of uid actually
+        sendPackagePermissionsForUid(UserHandle.getAppId(uid), getPermissionForUid(uid));
 
         // If multiple packages share a UID (cf: android:sharedUserId) and ask for different
         // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
@@ -384,9 +410,10 @@
      *
      * @hide
      */
-    @Override
     public synchronized void onPackageRemoved(@NonNull final String packageName, final int uid) {
-        sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
+        // TODO: Netd is using appId for checking traffic permission. Correct the methods that are
+        //  using appId instead of uid actually
+        sendPackagePermissionsForUid(UserHandle.getAppId(uid), getPermissionForUid(uid));
 
         // If the newly-removed package falls within some VPN's uid range, update Netd with it.
         // This needs to happen before the mApps update below, since removeBypassingUids() depends
@@ -432,19 +459,6 @@
         }
     }
 
-    /**
-     * Called when a package is changed.
-     *
-     * @param packageName The name of the changed package.
-     * @param uid The uid of the changed package.
-     *
-     * @hide
-     */
-    @Override
-    public synchronized void onPackageChanged(@NonNull final String packageName, final int uid) {
-        sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
-    }
-
     private static int getNetdPermissionMask(String[] requestedPermissions,
                                              int[] requestedPermissionsFlags) {
         int permissions = 0;
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
index 364aa2c..6e99cba 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
@@ -64,6 +64,8 @@
     @VisibleForTesting
     public static final String REBOOT_ESCROW_ARMED_KEY = "reboot_escrow_armed_count";
 
+    static final String REBOOT_ESCROW_KEY_ARMED_TIMESTAMP = "reboot_escrow_key_stored_timestamp";
+
     /**
      * Number of boots until we consider the escrow data to be stale for the purposes of metrics.
      * <p>
@@ -144,8 +146,7 @@
 
         private RebootEscrowProviderInterface createRebootEscrowProvider() {
             RebootEscrowProviderInterface rebootEscrowProvider;
-            if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_OTA,
-                    "server_based_ror_enabled", false)) {
+            if (serverBasedResumeOnReboot()) {
                 Slog.i(TAG, "Using server based resume on reboot");
                 rebootEscrowProvider = new RebootEscrowProviderServerBasedImpl(mContext, mStorage);
             } else {
@@ -166,6 +167,11 @@
             handler.postDelayed(runnable, delayMillis);
         }
 
+        public boolean serverBasedResumeOnReboot() {
+            return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_OTA,
+                    "server_based_ror_enabled", false);
+        }
+
         public Context getContext() {
             return mContext;
         }
@@ -204,10 +210,12 @@
                     DEFAULT_LOAD_ESCROW_DATA_RETRY_INTERVAL_SECONDS);
         }
 
-        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);
+        public void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount,
+                int escrowDurationInSeconds, int vbmetaDigestStatus,
+                int durationSinceBootCompleteInSeconds) {
+            FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED, success,
+                    errorCode, serviceType, attemptCount, escrowDurationInSeconds,
+                    vbmetaDigestStatus, durationSinceBootCompleteInSeconds);
         }
 
         public RebootEscrowEventLog getEventLog() {
@@ -230,7 +238,7 @@
         mKeyStoreManager = injector.getKeyStoreManager();
     }
 
-    private void onGetRebootEscrowKeyFailed(List<UserInfo> users) {
+    private void onGetRebootEscrowKeyFailed(List<UserInfo> users, int attemptCount) {
         Slog.w(TAG, "Had reboot escrow data for users, but no key; removing escrow storage.");
         for (UserInfo user : users) {
             mStorage.removeRebootEscrow(user.id);
@@ -238,7 +246,7 @@
 
         // Clear the old key in keystore.
         mKeyStoreManager.clearKeyStoreEncryptionKey();
-        onEscrowRestoreComplete(false);
+        onEscrowRestoreComplete(false, attemptCount);
     }
 
     void loadRebootEscrowDataIfAvailable(Handler retryHandler) {
@@ -251,6 +259,8 @@
         }
 
         if (rebootEscrowUsers.isEmpty()) {
+            Slog.i(TAG, "No reboot escrow data found for users,"
+                    + " skipping loading escrow data");
             return;
         }
 
@@ -274,7 +284,7 @@
         }
 
         Slog.w(TAG, "Failed to load reboot escrow data after " + attemptNumber + " attempts");
-        onGetRebootEscrowKeyFailed(users);
+        onGetRebootEscrowKeyFailed(users, attemptNumber);
     }
 
     void loadRebootEscrowDataWithRetry(Handler retryHandler, int attemptNumber,
@@ -297,7 +307,7 @@
         }
 
         if (escrowKey == null) {
-            onGetRebootEscrowKeyFailed(users);
+            onGetRebootEscrowKeyFailed(users, attemptNumber + 1);
             return;
         }
 
@@ -311,16 +321,35 @@
         // Clear the old key in keystore. A new key will be generated by new RoR requests.
         mKeyStoreManager.clearKeyStoreEncryptionKey();
 
-        onEscrowRestoreComplete(allUsersUnlocked);
+        onEscrowRestoreComplete(allUsersUnlocked, attemptNumber + 1);
     }
 
-    private void onEscrowRestoreComplete(boolean success) {
+    private void reportMetricOnRestoreComplete(boolean success, int attemptCount) {
+        int serviceType = mInjector.serverBasedResumeOnReboot()
+                ? FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED__TYPE__SERVER_BASED
+                : FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED__TYPE__HAL;
+
+        long armedTimestamp = mStorage.getLong(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, -1,
+                USER_SYSTEM);
+        mStorage.removeKey(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, USER_SYSTEM);
+        int escrowDurationInSeconds = armedTimestamp != -1
+                ? (int) (System.currentTimeMillis() - armedTimestamp) / 1000 : -1;
+
+        // TODO(b/179105110) design error code; and report the true value for other fields.
+        int vbmetaDigestStatus = FrameworkStatsLog
+                .REBOOT_ESCROW_RECOVERY_REPORTED__VBMETA_DIGEST_STATUS__MATCH_EXPECTED_SLOT;
+
+        mInjector.reportMetric(success, 0 /* error code */, serviceType, attemptCount,
+                escrowDurationInSeconds, vbmetaDigestStatus, -1);
+    }
+
+    private void onEscrowRestoreComplete(boolean success, int attemptCount) {
         int previousBootCount = mStorage.getInt(REBOOT_ESCROW_ARMED_KEY, -1, USER_SYSTEM);
         mStorage.removeKey(REBOOT_ESCROW_ARMED_KEY, USER_SYSTEM);
 
         int bootCountDelta = mInjector.getBootCount() - previousBootCount;
         if (success || (previousBootCount != -1 && bootCountDelta <= BOOT_COUNT_TOLERANCE)) {
-            mInjector.reportMetric(success);
+            reportMetricOnRestoreComplete(success, attemptCount);
         }
     }
 
@@ -476,6 +505,8 @@
         boolean armedRebootEscrow = rebootEscrowProvider.storeRebootEscrowKey(escrowKey, kk);
         if (armedRebootEscrow) {
             mStorage.setInt(REBOOT_ESCROW_ARMED_KEY, mInjector.getBootCount(), USER_SYSTEM);
+            mStorage.setLong(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, System.currentTimeMillis(),
+                    USER_SYSTEM);
             mEventLog.addEntry(RebootEscrowEvent.SET_ARMED_STATUS);
         }
 
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/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 c55913e..3f74938 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -299,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/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
index 07f6732..1c96838 100644
--- a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
@@ -40,9 +40,11 @@
 import android.net.Uri;
 import android.os.RemoteException;
 import android.os.UserManager;
+import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.server.LocalServices;
 import com.android.server.SystemService;
 
 import org.junit.Before;
@@ -60,6 +62,7 @@
  * Tests for {@link com.android.server.apphibernation.AppHibernationService}
  */
 @SmallTest
+@Presubmit
 public final class AppHibernationServiceTest {
     private static final String PACKAGE_SCHEME = "package";
     private static final String PACKAGE_NAME_1 = "package1";
@@ -91,6 +94,7 @@
         MockitoAnnotations.initMocks(this);
         doReturn(mContext).when(mContext).createContextAsUser(any(), anyInt());
 
+        LocalServices.removeServiceForTest(AppHibernationManagerInternal.class);
         mAppHibernationService = new AppHibernationService(new MockInjector(mContext));
 
         verify(mContext).registerReceiver(mReceiverCaptor.capture(), any());
diff --git a/services/tests/servicestests/src/com/android/server/apphibernation/HibernationStateDiskStoreTest.java b/services/tests/servicestests/src/com/android/server/apphibernation/HibernationStateDiskStoreTest.java
index 59f3c35..2237c84 100644
--- a/services/tests/servicestests/src/com/android/server/apphibernation/HibernationStateDiskStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/apphibernation/HibernationStateDiskStoreTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertEquals;
 
 import android.os.FileUtils;
+import android.platform.test.annotations.Presubmit;
 import android.util.proto.ProtoInputStream;
 import android.util.proto.ProtoOutputStream;
 
@@ -48,6 +49,7 @@
 
 
 @SmallTest
+@Presubmit
 public class HibernationStateDiskStoreTest {
     private static final String STATES_FILE_NAME = "states";
     private final MockScheduledExecutorService mMockScheduledExecutorService =
diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java
index f00edcc..fcd6b84 100644
--- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java
@@ -120,6 +120,11 @@
         return this;
     }
 
+    CompatConfigBuilder addEnabledSinceApexChangeWithId(int sdk, long id) {
+        mChanges.add(new CompatChange(id, "", -1, sdk, false, false, "", false));
+        return this;
+    }
+
     CompatConfig build() {
         CompatConfig config = new CompatConfig(mBuildClassifier, mContext);
         config.forceNonDebuggableFinalForTest(false);
diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
index 8b0e948..bd77405 100644
--- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
@@ -86,6 +86,7 @@
         // Assume userdebug/eng non-final build
         when(mBuildClassifier.isDebuggableBuild()).thenReturn(true);
         when(mBuildClassifier.isFinalBuild()).thenReturn(false);
+        when(mBuildClassifier.platformTargetSdk()).thenReturn(30);
         ChangeIdStateCache.disable();
         when(mPackageManager.getApplicationInfo(anyString(), anyInt()))
                 .thenThrow(new NameNotFoundException());
@@ -567,6 +568,34 @@
     }
 
     @Test
+    public void testReadApexConfig() throws IOException {
+        String configXml = "<config>"
+                + "<compat-change id=\"1234\" name=\"MY_CHANGE1\" enableAfterTargetSdk=\"2\" />"
+                + "<compat-change id=\"1235\" name=\"MY_CHANGE2\" disabled=\"true\" />"
+                + "<compat-change id=\"1236\" name=\"MY_CHANGE3\" />"
+                + "<compat-change id=\"1237\" name=\"MY_CHANGE4\" enableSinceTargetSdk=\"31\" />"
+                + "</config>";
+
+        File dir = createTempDir();
+        writeToFile(dir, "platform_compat_config.xml", configXml);
+        CompatConfig compatConfig = new CompatConfig(mBuildClassifier, mContext);
+        compatConfig.forceNonDebuggableFinalForTest(false);
+
+        compatConfig.initConfigFromLib(dir);
+
+        assertThat(compatConfig.isChangeEnabled(1234L,
+            ApplicationInfoBuilder.create().withTargetSdk(1).build())).isFalse();
+        assertThat(compatConfig.isChangeEnabled(1234L,
+            ApplicationInfoBuilder.create().withTargetSdk(3).build())).isTrue();
+        assertThat(compatConfig.isChangeEnabled(1235L,
+            ApplicationInfoBuilder.create().withTargetSdk(5).build())).isFalse();
+        assertThat(compatConfig.isChangeEnabled(1236L,
+            ApplicationInfoBuilder.create().withTargetSdk(1).build())).isTrue();
+        assertThat(compatConfig.isChangeEnabled(1237L,
+            ApplicationInfoBuilder.create().withTargetSdk(31).build())).isTrue();
+    }
+
+    @Test
     public void testReadConfigMultipleFiles() throws IOException {
         String configXml1 = "<config>"
                 + "<compat-change id=\"1234\" name=\"MY_CHANGE1\" enableAfterTargetSdk=\"2\" />"
@@ -602,12 +631,12 @@
                 .addEnableSinceSdkChangeWithId(2, 2L)
                 .build();
         compatConfig.forceNonDebuggableFinalForTest(true);
-        compatConfig.initOverrides(overridesFile);
+        compatConfig.initOverrides(overridesFile, new File(""));
         when(mPackageManager.getApplicationInfo(eq("foo.bar"), anyInt()))
                 .thenReturn(ApplicationInfoBuilder.create()
-                                .withPackageName("foo.bar")
-                                .debuggable()
-                                .build());
+                        .withPackageName("foo.bar")
+                        .debuggable()
+                        .build());
         when(mPackageManager.getApplicationInfo(eq("bar.baz"), anyInt()))
                 .thenThrow(new NameNotFoundException());
 
@@ -649,7 +678,7 @@
                 .addEnableSinceSdkChangeWithId(2, 2L)
                 .build();
         compatConfig.forceNonDebuggableFinalForTest(true);
-        compatConfig.initOverrides(overridesFile);
+        compatConfig.initOverrides(overridesFile, new File(""));
 
         compatConfig.addOverrides(new CompatibilityOverrideConfig(Collections.singletonMap(1L,
                 new PackageOverride.Builder()
@@ -673,11 +702,11 @@
     }
 
     @Test
-    public void testLoadOverridesRaw() throws Exception {
+    public void testInitOverridesRaw() throws Exception {
         File tempDir = createTempDir();
         File overridesFile = new File(tempDir, "overrides.xml");
         // Change 1 is enabled for foo.bar (validated)
-        // Change 2 is disabled for bar.baz (deferred)
+        // Change 2 is disabled for bar.baz (raw)
         String xmlData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
                 + "<overrides>\n"
                 + "    <change-overrides changeId=\"1\">\n"
@@ -709,7 +738,7 @@
                 .addEnableSinceSdkChangeWithId(2, 2L)
                 .build();
         compatConfig.forceNonDebuggableFinalForTest(true);
-        compatConfig.initOverrides(overridesFile);
+        compatConfig.initOverrides(overridesFile, new File(""));
         ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
                 .withPackageName("foo.bar")
                 .withVersionCode(100L)
@@ -728,7 +757,7 @@
     }
 
     @Test
-    public void testLoadOverridesDeferred() throws Exception {
+    public void testInitOverridesDeferred() throws Exception {
         File tempDir = createTempDir();
         File overridesFile = new File(tempDir, "overrides.xml");
         // Change 1 is enabled for foo.bar (validated)
@@ -754,7 +783,7 @@
                 .addEnableSinceSdkChangeWithId(2, 2L)
                 .build();
         compatConfig.forceNonDebuggableFinalForTest(true);
-        compatConfig.initOverrides(overridesFile);
+        compatConfig.initOverrides(overridesFile, new File(""));
         ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
                 .withPackageName("foo.bar")
                 .debuggable()
@@ -767,4 +796,115 @@
         assertThat(compatConfig.isChangeEnabled(1L, applicationInfo)).isTrue();
         assertThat(compatConfig.willChangeBeEnabled(2L, "bar.baz")).isFalse();
     }
+
+    @Test
+    public void testInitOverridesWithStaticFile() throws Exception {
+        File tempDir = createTempDir();
+        File dynamicOverridesFile = new File(tempDir, "dynamic_overrides.xml");
+        File staticOverridesFile = new File(tempDir, "static_overrides.xml");
+        // Change 1 is enabled for foo.bar (raw)
+        // Change 2 is disabled for bar.baz (raw)
+        String dynamicXmlData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+                + "<overrides>"
+                +    "<change-overrides changeId=\"1\">"
+                +        "<raw>"
+                + "            <raw-override-value packageName=\"foo.bar\" "
+                + "minVersionCode=\"-9223372036854775808\" "
+                + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+                + "            </raw-override-value>\n"
+                +        "</raw>"
+                +    "</change-overrides>"
+                +    "<change-overrides changeId=\"2\">"
+                +        "<raw>"
+                + "            <raw-override-value packageName=\"bar.baz\" "
+                + "minVersionCode=\"-9223372036854775808\" "
+                + "maxVersionCode=\"9223372036854775807\" enabled=\"false\">\n"
+                + "            </raw-override-value>\n"
+                +        "</raw>"
+                +    "</change-overrides>"
+                + "</overrides>";
+        writeToFile(tempDir, "dynamic_overrides.xml", dynamicXmlData);
+        // Change 2 is enabled for foo.bar and bar.baz (raw)
+        // Change 3 is enabled for bar.baz (raw)
+        String staticXmlData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+                + "<overrides>"
+                +    "<change-overrides changeId=\"2\">"
+                +        "<raw>"
+                + "            <raw-override-value packageName=\"foo.bar\" "
+                + "minVersionCode=\"-9223372036854775808\" "
+                + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+                + "            </raw-override-value>\n"
+                + "            <raw-override-value packageName=\"bar.baz\" "
+                + "minVersionCode=\"-9223372036854775808\" "
+                + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+                + "            </raw-override-value>\n"
+                +        "</raw>"
+                +    "</change-overrides>"
+                +    "<change-overrides changeId=\"3\">"
+                +        "<raw>"
+                + "            <raw-override-value packageName=\"bar.baz\" "
+                + "minVersionCode=\"-9223372036854775808\" "
+                + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+                + "            </raw-override-value>\n"
+                +        "</raw>"
+                +    "</change-overrides>"
+                + "</overrides>";
+        writeToFile(tempDir, "static_overrides.xml", staticXmlData);
+        CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
+                .addDisabledChangeWithId(1L)
+                .addDisabledChangeWithId(2L)
+                .addDisabledChangeWithId(3L)
+                .build();
+        compatConfig.forceNonDebuggableFinalForTest(true);
+        // Adding an override that will be cleared after initOverrides is called.
+        compatConfig.addOverride(1L, "bar.baz", true);
+        compatConfig.initOverrides(dynamicOverridesFile, staticOverridesFile);
+        when(mPackageManager.getApplicationInfo(eq("foo.bar"), anyInt()))
+                .thenThrow(new NameNotFoundException());
+        when(mPackageManager.getApplicationInfo(eq("bar.baz"), anyInt()))
+                .thenThrow(new NameNotFoundException());
+
+        assertThat(compatConfig.willChangeBeEnabled(1L, "foo.bar")).isTrue();
+        assertThat(compatConfig.willChangeBeEnabled(2L, "foo.bar")).isTrue();
+        assertThat(compatConfig.willChangeBeEnabled(2L, "bar.baz")).isFalse();
+        assertThat(compatConfig.willChangeBeEnabled(3L, "bar.baz")).isTrue();
+        assertThat(readFile(dynamicOverridesFile))
+                .isEqualTo("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+                + "<overrides>\n"
+                + "    <change-overrides changeId=\"1\">\n"
+                + "        <validated>\n"
+                + "        </validated>\n"
+                + "        <raw>\n"
+                + "            <raw-override-value packageName=\"foo.bar\" "
+                + "minVersionCode=\"-9223372036854775808\" "
+                + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+                + "            </raw-override-value>\n"
+                + "        </raw>\n"
+                + "    </change-overrides>\n"
+                + "    <change-overrides changeId=\"2\">\n"
+                + "        <validated>\n"
+                + "        </validated>\n"
+                + "        <raw>\n"
+                + "            <raw-override-value packageName=\"foo.bar\" "
+                + "minVersionCode=\"-9223372036854775808\" "
+                + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+                + "            </raw-override-value>\n"
+                + "            <raw-override-value packageName=\"bar.baz\" "
+                + "minVersionCode=\"-9223372036854775808\" "
+                + "maxVersionCode=\"9223372036854775807\" enabled=\"false\">\n"
+                + "            </raw-override-value>\n"
+                + "        </raw>\n"
+                + "    </change-overrides>\n"
+                + "    <change-overrides changeId=\"3\">\n"
+                + "        <validated>\n"
+                + "        </validated>\n"
+                + "        <raw>\n"
+                + "            <raw-override-value packageName=\"bar.baz\" "
+                + "minVersionCode=\"-9223372036854775808\" "
+                + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+                + "            </raw-override-value>\n"
+                + "        </raw>\n"
+                + "    </change-overrides>\n"
+                + "</overrides>\n");
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java b/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java
index 0fd6445..57fdcd3 100644
--- a/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java
@@ -22,6 +22,7 @@
 import static com.android.internal.compat.OverrideAllowedState.DISABLED_NOT_DEBUGGABLE;
 import static com.android.internal.compat.OverrideAllowedState.DISABLED_TARGET_SDK_TOO_HIGH;
 import static com.android.internal.compat.OverrideAllowedState.LOGGING_ONLY_CHANGE;
+import static com.android.internal.compat.OverrideAllowedState.PLATFORM_TOO_OLD;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -52,6 +53,7 @@
     private static final int TARGET_SDK = 10;
     private static final int TARGET_SDK_BEFORE = 9;
     private static final int TARGET_SDK_AFTER = 11;
+    private static final int PLATFORM_SDK_VERSION = 30;
 
     @Mock
     private PackageManager mPackageManager;
@@ -61,6 +63,7 @@
     private AndroidBuildClassifier debuggableBuild() {
         AndroidBuildClassifier buildClassifier = mock(AndroidBuildClassifier.class);
         when(buildClassifier.isDebuggableBuild()).thenReturn(true);
+        when(buildClassifier.platformTargetSdk()).thenReturn(PLATFORM_SDK_VERSION);
         return buildClassifier;
     }
 
@@ -68,6 +71,7 @@
         AndroidBuildClassifier buildClassifier = mock(AndroidBuildClassifier.class);
         when(buildClassifier.isDebuggableBuild()).thenReturn(false);
         when(buildClassifier.isFinalBuild()).thenReturn(false);
+        when(buildClassifier.platformTargetSdk()).thenReturn(PLATFORM_SDK_VERSION);
         return buildClassifier;
     }
 
@@ -75,6 +79,7 @@
         AndroidBuildClassifier buildClassifier = mock(AndroidBuildClassifier.class);
         when(buildClassifier.isDebuggableBuild()).thenReturn(false);
         when(buildClassifier.isFinalBuild()).thenReturn(true);
+        when(buildClassifier.platformTargetSdk()).thenReturn(PLATFORM_SDK_VERSION);
         return buildClassifier;
     }
 
@@ -333,6 +338,26 @@
     }
 
     @Test
+    public void getOverrideAllowedState_targetSdkChangeGreaterThanOsVersion_rejectOverride()
+            throws Exception {
+        final AndroidBuildClassifier buildClassifier = finalBuild();
+        CompatConfig config = CompatConfigBuilder.create(finalBuild(), mContext)
+                        .addEnabledSinceApexChangeWithId(PLATFORM_SDK_VERSION + 1, 1).build();
+        IOverrideValidator overrideValidator = config.getOverrideValidator();
+        when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt()))
+                .thenReturn(ApplicationInfoBuilder.create()
+                        .withPackageName(PACKAGE_NAME)
+                        .debuggable()
+                        .build());
+
+        OverrideAllowedState stateTargetSdkLessChange =
+                overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME);
+        assertThat(stateTargetSdkLessChange).isEqualTo(
+                new OverrideAllowedState(PLATFORM_TOO_OLD, -1,
+                                         PLATFORM_SDK_VERSION));
+    }
+
+    @Test
     public void getOverrideAllowedState_finalBuildEnabledChangeDebugApp_rejectOverride()
             throws Exception {
         CompatConfig config = CompatConfigBuilder.create(finalBuild(), mContext)
diff --git a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
index 799b067..3fc6e99 100644
--- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
@@ -78,11 +78,12 @@
         when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt()))
             .thenThrow(new PackageManager.NameNotFoundException());
         mCompatConfig = new CompatConfig(mBuildClassifier, mContext);
-        mPlatformCompat = new PlatformCompat(mContext, mCompatConfig);
+        mPlatformCompat = new PlatformCompat(mContext, mCompatConfig, mBuildClassifier);
         // Assume userdebug/eng non-final build
         mCompatConfig.forceNonDebuggableFinalForTest(false);
         when(mBuildClassifier.isDebuggableBuild()).thenReturn(true);
         when(mBuildClassifier.isFinalBuild()).thenReturn(false);
+        when(mBuildClassifier.platformTargetSdk()).thenReturn(30);
         LocalServices.removeServiceForTest(PackageManagerInternal.class);
         LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal);
     }
@@ -99,7 +100,7 @@
                 .addLoggingOnlyChangeWithId(7L)
                 .addOverridableChangeWithId(8L)
                 .build();
-        mPlatformCompat = new PlatformCompat(mContext, mCompatConfig);
+        mPlatformCompat = new PlatformCompat(mContext, mCompatConfig, mBuildClassifier);
         assertThat(mPlatformCompat.listAllChanges()).asList().containsExactly(
                 new CompatibilityChangeInfo(1L, "", -1, -1, false, false, "", false),
                 new CompatibilityChangeInfo(2L, "change2", -1, -1, true, false, "", false),
@@ -125,8 +126,9 @@
                 .addEnableSinceSdkChangeWithId(Build.VERSION_CODES.Q, 5L)
                 .addEnableSinceSdkChangeWithId(Build.VERSION_CODES.R, 6L)
                 .addLoggingOnlyChangeWithId(7L)
+                .addEnableSinceSdkChangeWithId(31, 8L)
                 .build();
-        mPlatformCompat = new PlatformCompat(mContext, mCompatConfig);
+        mPlatformCompat = new PlatformCompat(mContext, mCompatConfig, mBuildClassifier);
         assertThat(mPlatformCompat.listUIChanges()).asList().containsExactly(
                 new CompatibilityChangeInfo(1L, "", -1, -1, false, false, "", false),
                 new CompatibilityChangeInfo(2L, "change2", -1, -1, true, false, "", false),
@@ -144,7 +146,7 @@
                 .addEnableAfterSdkChangeWithId(Build.VERSION_CODES.O, 3L)
                 .build();
         mCompatConfig.forceNonDebuggableFinalForTest(true);
-        mPlatformCompat = new PlatformCompat(mContext, mCompatConfig);
+        mPlatformCompat = new PlatformCompat(mContext, mCompatConfig, mBuildClassifier);
 
         // Before adding overrides.
         assertThat(mPlatformCompat.isChangeEnabledByPackageName(1, PACKAGE_NAME, 0)).isTrue();
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
index b51f4df..91342ce 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
@@ -26,6 +26,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.clearInvocations;
@@ -109,7 +110,8 @@
     public interface MockableRebootEscrowInjected {
         int getBootCount();
 
-        void reportMetric(boolean success);
+        void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount,
+                int escrowDurationInSeconds, int vbmetaDigestStatus, int durationSinceBootComplete);
     }
 
     static class MockInjector extends RebootEscrowManager.Injector {
@@ -119,6 +121,7 @@
         private final UserManager mUserManager;
         private final MockableRebootEscrowInjected mInjected;
         private final RebootEscrowKeyStoreManager mKeyStoreManager;
+        private final boolean mServerBased;
 
         MockInjector(Context context, UserManager userManager,
                 IRebootEscrow rebootEscrow,
@@ -128,6 +131,7 @@
             super(context, storage);
             mRebootEscrow = rebootEscrow;
             mServiceConnection = null;
+            mServerBased = false;
             RebootEscrowProviderHalImpl.Injector halInjector =
                     new RebootEscrowProviderHalImpl.Injector() {
                         @Override
@@ -149,6 +153,7 @@
             super(context, storage);
             mServiceConnection = serviceConnection;
             mRebootEscrow = null;
+            mServerBased = true;
             RebootEscrowProviderServerBasedImpl.Injector injector =
                     new RebootEscrowProviderServerBasedImpl.Injector(serviceConnection);
             mRebootEscrowProvider = new RebootEscrowProviderServerBasedImpl(storage, injector);
@@ -168,6 +173,11 @@
         }
 
         @Override
+        public boolean serverBasedResumeOnReboot() {
+            return mServerBased;
+        }
+
+        @Override
         public RebootEscrowProviderInterface getRebootEscrowProvider() {
             return mRebootEscrowProvider;
         }
@@ -195,8 +205,11 @@
         }
 
         @Override
-        public void reportMetric(boolean success) {
-            mInjected.reportMetric(success);
+        public void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount,
+                int escrowDurationInSeconds, int vbmetaDigestStatus,
+                int durationSinceBootComplete) {
+            mInjected.reportMetric(success, errorCode, serviceType, attemptCount,
+                    escrowDurationInSeconds, vbmetaDigestStatus, durationSinceBootComplete);
         }
     }
 
@@ -418,7 +431,9 @@
 
         when(mInjected.getBootCount()).thenReturn(1);
         ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
-        doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture());
+        doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
+                eq(0) /* error code */, eq(1) /* HAL based */, eq(1) /* attempt count */,
+                anyInt(), anyInt(), anyInt());
         when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> keyByteCaptor.getValue());
 
         mService.loadRebootEscrowDataIfAvailable(null);
@@ -451,7 +466,9 @@
         // pretend reboot happens here
         when(mInjected.getBootCount()).thenReturn(1);
         ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
-        doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture());
+        doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
+                eq(0) /* error code */, eq(2) /* Server based */, eq(1) /* attempt count */,
+                anyInt(), anyInt(), anyInt());
 
         when(mServiceConnection.unwrap(any(), anyLong()))
                 .thenAnswer(invocation -> invocation.getArgument(0));
@@ -485,7 +502,8 @@
         // pretend reboot happens here
         when(mInjected.getBootCount()).thenReturn(1);
         ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
-        doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture());
+        doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
+                anyInt(), anyInt(), eq(2) /* attempt count */, anyInt(), anyInt(), anyInt());
 
         when(mServiceConnection.unwrap(any(), anyLong()))
                 .thenThrow(new IOException())
@@ -528,7 +546,8 @@
 
         mService.loadRebootEscrowDataIfAvailable(null);
         verify(mRebootEscrow).retrieveKey();
-        verify(mInjected, never()).reportMetric(anyBoolean());
+        verify(mInjected, never()).reportMetric(anyBoolean(), anyInt(), anyInt(), anyInt(),
+                anyInt(), anyInt(), anyInt());
     }
 
     @Test
@@ -554,7 +573,8 @@
         when(mRebootEscrow.retrieveKey()).thenReturn(new byte[32]);
 
         mService.loadRebootEscrowDataIfAvailable(null);
-        verify(mInjected, never()).reportMetric(anyBoolean());
+        verify(mInjected, never()).reportMetric(anyBoolean(), anyInt(), anyInt(), anyInt(),
+                anyInt(), anyInt(), anyInt());
     }
 
     @Test
@@ -588,7 +608,8 @@
         when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> keyByteCaptor.getValue());
 
         mService.loadRebootEscrowDataIfAvailable(null);
-        verify(mInjected).reportMetric(eq(true));
+        verify(mInjected).reportMetric(eq(true), eq(0) /* error code */, eq(1) /* HAL based */,
+                eq(1) /* attempt count */, anyInt(), anyInt(), anyInt());
     }
 
     @Test
@@ -615,7 +636,9 @@
 
         when(mInjected.getBootCount()).thenReturn(1);
         ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
-        doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture());
+        doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
+                anyInt() /* error code */, eq(1) /* HAL based */, eq(1) /* attempt count */,
+                anyInt(), anyInt(), anyInt());
         when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> new byte[32]);
         mService.loadRebootEscrowDataIfAvailable(null);
         verify(mRebootEscrow).retrieveKey();
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/Conference.java b/telecomm/java/android/telecom/Conference.java
index dc2fb94..f84dd7b 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -338,7 +338,7 @@
      *
      * @param videoState The video state in which to answer the connection.
      */
-    public void onAnswer(int videoState) {}
+    public void onAnswer(@VideoProfile.VideoState int videoState) {}
 
     /**
      * Notifies this Conference, which is in {@code STATE_RINGING}, of
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 580513c..d82205e 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
@@ -2544,9 +2553,9 @@
      * @return The {@code Connection} object to satisfy this call, or {@code null} to
      *         not handle the call.
      */
-    public final RemoteConnection createRemoteIncomingConnection(
-            PhoneAccountHandle connectionManagerPhoneAccount,
-            ConnectionRequest request) {
+    public final @Nullable RemoteConnection createRemoteIncomingConnection(
+            @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+            @NonNull ConnectionRequest request) {
         return mRemoteConnectionManager.createRemoteConnection(
                 connectionManagerPhoneAccount, request, true);
     }
@@ -2563,9 +2572,9 @@
      * @return The {@code Connection} object to satisfy this call, or {@code null} to
      *         not handle the call.
      */
-    public final RemoteConnection createRemoteOutgoingConnection(
-            PhoneAccountHandle connectionManagerPhoneAccount,
-            ConnectionRequest request) {
+    public final @Nullable RemoteConnection createRemoteOutgoingConnection(
+            @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+            @NonNull ConnectionRequest request) {
         return mRemoteConnectionManager.createRemoteConnection(
                 connectionManagerPhoneAccount, request, false);
     }
@@ -2805,12 +2814,14 @@
      * @param connectionManagerPhoneAccount See description at
      *         {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
      * @param request Details about the incoming conference call.
-     * @return The {@code Conference} object to satisfy this call, or {@code null} to
-     *         not handle the call.
+     * @return The {@code Conference} object to satisfy this call. If the conference attempt is
+     *         failed, the return value will be a result of an invocation of
+     *         {@link Connection#createFailedConnection(DisconnectCause)}.
+     *         Return {@code null} if the {@link ConnectionService} cannot handle the call.
      */
     public @Nullable Conference onCreateIncomingConference(
-            @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
-            @Nullable ConnectionRequest request) {
+            @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+            @NonNull ConnectionRequest request) {
         return null;
     }
 
@@ -2913,8 +2924,8 @@
      * @param request The outgoing connection request.
      */
     public void onCreateOutgoingConferenceFailed(
-            @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
-            @Nullable ConnectionRequest request) {
+            @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+            @NonNull ConnectionRequest request) {
     }
 
 
@@ -2978,12 +2989,14 @@
      *         a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
      *         making the connection.
      * @param request Details about the outgoing call.
-     * @return The {@code Conference} object to satisfy this call, or the result of an invocation
-     *         of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
+     * @return The {@code Conference} object to satisfy this call. If the conference attempt is
+     *         failed, the return value will be a result of an invocation of
+     *         {@link Connection#createFailedConnection(DisconnectCause)}.
+     *         Return {@code null} if the {@link ConnectionService} cannot handle the call.
      */
     public @Nullable Conference onCreateOutgoingConference(
-            @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
-            @Nullable ConnectionRequest request) {
+            @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+            @NonNull ConnectionRequest request) {
         return null;
     }
 
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/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 9c9670c..dc05488 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -33,7 +33,11 @@
 import android.service.carrier.CarrierService;
 import android.telecom.TelecomManager;
 import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsRegistrationAttributes;
 import android.telephony.ims.ImsSsData;
+import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.feature.RcsFeature;
 
 import com.android.internal.telephony.ICarrierConfigLoader;
 import com.android.telephony.Rlog;
@@ -3941,6 +3945,43 @@
                 KEY_PREFIX + "enable_presence_publish_bool";
 
         /**
+         * Each string in this array contains a mapping between the service-id and version portion
+         * of the service-description element and the associated IMS feature tag(s) that are
+         * associated with each element (see RCC.07 Table 7).
+         * <p>
+         * Each string contains 3 parts, which define the mapping between service-description and
+         * feature tag(s) that must be present in the IMS REGISTER for the RCS service to be
+         * published as part of the RCS PUBLISH procedure:
+         * [service-id]|[version]|[desc]|[feature_tag];[feature_tag];...
+         * <ul>
+         *   <li>[service-id]: the service-id element associated with the RCS capability.</li>
+         *   <li>[version]: The version element associated with that service-id</li>
+         *   <li>[desc]: The optional desecription element associated with that service-id</li>
+         *   <li>[feature_tag];[feature_tag]: The list of all feature tags associated with this
+         *       capability that MUST ALL be present in the IMS registration for this this
+         *       capability to be published to the network.</li>
+         * </ul>
+         * <p>
+         * Features managed by the framework will be considered capable when the ImsService reports
+         * that those services are capable via the
+         * {@link MmTelFeature#notifyCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities)} or
+         * {@link RcsFeature#notifyCapabilitiesStatusChanged(RcsFeature.RcsImsCapabilities)} APIs.
+         * For RCS services not managed by the framework, the capability of these services are
+         * determined by looking at the feature tags associated with the IMS registration using the
+         * {@link ImsRegistrationAttributes} API and mapping them to the service-description map.
+         * <p>
+         * The framework contains a default value of this key, which is based off of RCC.07
+         * specification. Capabilities based of carrier extensions may be added to this list on a
+         * carrier-by-carrier basis as required in order to support additional services in the
+         * PUBLISH. If this list contains a service-id and version that overlaps with the default,
+         * it will override the framework default.
+         * @hide
+         */
+        @SystemApi
+        public static final String KEY_PUBLISH_SERVICE_DESC_FEATURE_TAG_MAP_OVERRIDE_STRING_ARRAY =
+                KEY_PREFIX + "publish_service_desc_feature_tag_map_override_string_array";
+
+        /**
          * Flag indicating whether or not this carrier supports the exchange of phone numbers with
          * the carrier's RCS presence server in order to retrieve the RCS capabilities of requested
          * contacts used in the RCS User Capability Exchange (UCE) procedure. See RCC.71, section 3
@@ -3999,6 +4040,8 @@
             defaults.putInt(KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT, 4000);
             defaults.putBoolean(KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false);
             defaults.putBoolean(KEY_ENABLE_PRESENCE_PUBLISH_BOOL, false);
+            defaults.putStringArray(KEY_PUBLISH_SERVICE_DESC_FEATURE_TAG_MAP_OVERRIDE_STRING_ARRAY,
+                    new String[] {});
             defaults.putBoolean(KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL, false);
             defaults.putBoolean(KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL, false);
             defaults.putBoolean(KEY_ENABLE_PRESENCE_GROUP_SUBSCRIBE_BOOL, true);
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..8244342 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 = {
@@ -14655,13 +14720,17 @@
      * </ul>
      * @param appType icc application type, like {@link #APPTYPE_USIM} or {@link
      * #APPTYPE_ISIM} or {@link#APPTYPE_UNKNOWN}
-     * @param nafId Network Application Function(NAF) fully qualified domain name and
-     * the selected GBA mode. It shall contain two parts delimited by "@" sign. The first
-     * part is the constant string "3GPP-bootstrapping" (GBA_ME),
-     * "3GPP-bootstrapping-uicc" (GBA_ U), or "3GPP-bootstrapping-digest" (GBA_Digest),
-     * and the latter part shall be the FQDN of the NAF (e.g.
-     * "3GPP-bootstrapping@naf1.operator.com" or "3GPP-bootstrapping-uicc@naf1.operator.com",
-     * or "3GPP-bootstrapping-digest@naf1.operator.com").
+     * @param nafId A URI to specify Network Application Function(NAF) fully qualified domain
+     * name (FQDN) and the selected GBA mode. The authority of the URI must contain two parts
+     * delimited by "@" sign. The first part is the constant string "3GPP-bootstrapping" (GBA_ME),
+     * "3GPP-bootstrapping-uicc" (GBA_ U), or "3GPP-bootstrapping-digest" (GBA_Digest).
+     * The second part shall be the FQDN of the NAF. The scheme of the URI is not actually used
+     * for the authentication, which may be set the same as the resource that the application is
+     * going to access. For example, the nafId can be
+     * "https://3GPP-bootstrapping@naf1.operator.com",
+     * "https://3GPP-bootstrapping-uicc@naf1.operator.com",
+     * "https://3GPP-bootstrapping-digest@naf1.operator.com",
+     * "ftps://3GPP-bootstrapping-digest@naf1.operator.com".
      * @param securityProtocol Security protocol identifier between UE and NAF.  See
      * 3GPP TS 33.220 Annex H. Application can use
      * {@link UaSecurityProtocolIdentifier#createDefaultUaSpId},
@@ -14724,73 +14793,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/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java
index ca1f861..363e47a 100644
--- a/telephony/java/android/telephony/data/DataServiceCallback.java
+++ b/telephony/java/android/telephony/data/DataServiceCallback.java
@@ -254,15 +254,15 @@
     }
 
     /**
-     * The APN is throttled for the duration specified in
-     * {@link DataCallResponse#getRetryDurationMillis}.  Calling this method unthrottles that
-     * APN.
+     * Unthrottles the APN on the current transport.  There is no matching "APN throttle" method.
+     * Instead, the APN is throttled for the time specified in
+     * {@link DataCallResponse#getRetryDurationMillis}.
      * <p/>
      * see: {@link DataCallResponse#getRetryDurationMillis}
      *
      * @param apn Access Point Name defined by the carrier.
      */
-    public void onApnUnthrottled(@NonNull String apn) {
+    public void onApnUnthrottled(final @NonNull String apn) {
         if (mCallback != null) {
             try {
                 if (DBG) Rlog.d(TAG, "onApnUnthrottled");
diff --git a/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java b/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java
index 041edc0..406c38b 100644
--- a/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java
+++ b/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java
@@ -184,16 +184,6 @@
         mRemoteAddresses = Collections.unmodifiableList(remoteAddresses);
     }
 
-    /**
-     * Creates attributes based off of a parcel
-     * @param in the parcel
-     * @return the attributes
-     */
-    @NonNull
-    public static EpsBearerQosSessionAttributes create(@NonNull final Parcel in) {
-        return new EpsBearerQosSessionAttributes(in);
-    }
-
     @Override
     public int describeContents() {
         return 0;
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index aa9145b..1e80ab7 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -993,6 +993,16 @@
                 }
             }
 
+            @Override
+            public void onPreProvisioningReceived(byte[] configXml) {
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() -> mLocalCallback.onPreProvisioningReceived(configXml));
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+
             private void setExecutor(Executor executor) {
                 mExecutor = executor;
             }
@@ -1005,7 +1015,7 @@
          * due to various triggers defined in GSMA RCC.14 for ACS(auto configuration
          * 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
+         * invoked with the current configuration.
          * @param configXml The RCS configuration XML received by OTA. It is defined
          * by GSMA RCC.07.
          */
@@ -1038,6 +1048,20 @@
          */
         public void onRemoved() {}
 
+        /**
+         * Some carriers using ACS (auto configuration server) may send a carrier-specific
+         * pre-provisioning configuration XML if the user has not been provisioned for RCS
+         * services yet. When this provisioning XML is received, the framework will move
+         * into a "not provisioned" state for RCS. In order for provisioning to proceed,
+         * the application must parse this configuration XML and perform the carrier specific
+         * opt-in flow for RCS services. If the user accepts, {@link #triggerRcsReconfiguration}
+         * must be called in order for the device to move out of this state and try to fetch
+         * the RCS provisioning information.
+         *
+         * @param configXml the pre-provisioning config in carrier specified format.
+         */
+        public void onPreProvisioningReceived(@NonNull byte[] configXml) {}
+
         /**@hide*/
         public final IRcsConfigCallback getBinder() {
             return mBinder;
diff --git a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
index 5eb75e7..9c28c36 100644
--- a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
+++ b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
@@ -21,11 +21,16 @@
 import android.annotation.StringDef;
 import android.annotation.SystemApi;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.TextUtils;
 
 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,17 @@
 @SystemApi
 public final class RcsContactPresenceTuple implements Parcelable {
 
+    private static final String LOG_TAG = "RcsContactPresenceTuple";
+
+    /**
+     * The service ID used to indicate that service discovery via presence is available.
+     * <p>
+     * See RCC.07 v5.0 specification for more information.
+     * @hide
+     */
+    public static final String SERVICE_ID_PRESENCE =
+            "org.3gpp.urn:urn-7:3gpp-application.ims.iari.rcse.dp";
+
     /**
      * The service ID used to indicate that MMTEL service is available.
      * <p>
@@ -329,6 +345,13 @@
         public @NonNull @DuplexMode List<String> getUnsupportedDuplexModes() {
             return Collections.unmodifiableList(mUnsupportedDuplexModeList);
         }
+
+        @Override
+        public String toString() {
+            return "servCaps{" + "a=" + mIsAudioCapable + ", v=" + mIsVideoCapable
+                    + ", supported=" + mSupportedDuplexModeList + ", unsupported="
+                    + mUnsupportedDuplexModeList + '}';
+        }
     }
 
     /**
@@ -353,7 +376,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;
@@ -365,7 +389,7 @@
          * Per RFC3863 section 4.1.7, the timestamp is formatted as an IMPP datetime format
          * string per RFC3339.
          */
-        public @NonNull Builder setTimestamp(@NonNull String timestamp) {
+        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;
@@ -474,7 +518,7 @@
     }
 
     /** @return the timestamp element contained in the tuple if it exists */
-    public @Nullable String getTimestamp() {
+    public @Nullable Instant getTime() {
         return mTimestamp;
     }
 
@@ -487,4 +531,36 @@
     public @Nullable ServiceCapabilities getServiceCapabilities() {
         return mServiceCapabilities;
     }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder("{");
+        if (Build.IS_ENG) {
+            builder.append("u=");
+            builder.append(mContactUri);
+        } else {
+            builder.append("u=");
+            builder.append(mContactUri != null ? "XXX" : "null");
+        }
+        builder.append(", id=");
+        builder.append(mServiceId);
+        builder.append(", v=");
+        builder.append(mServiceVersion);
+        builder.append(", s=");
+        builder.append(mStatus);
+        if (mTimestamp != null) {
+            builder.append(", timestamp=");
+            builder.append(mTimestamp);
+        }
+        if (mServiceDescription != null) {
+            builder.append(", servDesc=");
+            builder.append(mServiceDescription);
+        }
+        if (mServiceCapabilities != null) {
+            builder.append(", servCaps=");
+            builder.append(mServiceCapabilities);
+        }
+        builder.append("}");
+        return builder.toString();
+    }
 }
diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
index fe85502..52d0f03 100644
--- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java
+++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
@@ -21,6 +21,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -339,9 +340,45 @@
     }
 
     /**
+     * Retrieve the contact URI requested by the applications.
      * @return the URI representing the contact associated with the capabilities.
      */
     public @NonNull Uri getContactUri() {
         return mContactUri;
     }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder("RcsContactUceCapability");
+        if (mCapabilityMechanism == CAPABILITY_MECHANISM_PRESENCE) {
+            builder.append("(presence) {");
+        } else if (mCapabilityMechanism == CAPABILITY_MECHANISM_OPTIONS) {
+            builder.append("(options) {");
+        } else {
+            builder.append("(?) {");
+        }
+        if (Build.IS_ENG) {
+            builder.append("uri=");
+            builder.append(mContactUri);
+        } else {
+            builder.append("uri (isNull)=");
+            builder.append(mContactUri != null ? "XXX" : "null");
+        }
+        builder.append(", sourceType=");
+        builder.append(mSourceType);
+        builder.append(", requestResult=");
+        builder.append(mRequestResult);
+
+        if (mCapabilityMechanism == CAPABILITY_MECHANISM_PRESENCE) {
+            builder.append(", presenceTuples={");
+            builder.append(mPresenceTuples);
+            builder.append("}");
+        } else if (mCapabilityMechanism == CAPABILITY_MECHANISM_OPTIONS) {
+            builder.append(", featureTags={");
+            builder.append(mFeatureTags);
+            builder.append("}");
+        }
+
+        return builder.toString();
+    }
 }
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index ce8bd7d..dd91026 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,7 +432,8 @@
 
         /**
          * 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();
 
@@ -486,7 +489,7 @@
     @SystemApi
     @RequiresPermission(allOf = {Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE,
             Manifest.permission.READ_CONTACTS})
-    public void requestCapabilities(@NonNull List<Uri> contactNumbers,
+    public void requestCapabilities(@NonNull Collection<Uri> contactNumbers,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull CapabilitiesCallback c) throws ImsException {
         if (c == null) {
@@ -538,7 +541,7 @@
 
         try {
             imsRcsController.requestCapabilities(mSubId, mContext.getOpPackageName(),
-                    mContext.getAttributionTag(), contactNumbers, internalCallback);
+                    mContext.getAttributionTag(), new ArrayList(contactNumbers), internalCallback);
         } catch (ServiceSpecificException e) {
             throw new ImsException(e.toString(), e.errorCode);
         } catch (RemoteException e) {
@@ -569,6 +572,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/aidl/IRcsConfigCallback.aidl b/telephony/java/android/telephony/ims/aidl/IRcsConfigCallback.aidl
index 5a8973e..d0853d1 100644
--- a/telephony/java/android/telephony/ims/aidl/IRcsConfigCallback.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IRcsConfigCallback.aidl
@@ -25,5 +25,6 @@
     void onAutoConfigurationErrorReceived(int errorCode, String errorString);
     void onConfigurationReset();
     void onRemoved();
+    void onPreProvisioningReceived(in byte[] config);
 }
 
diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
index 34984e0..4dcb7f5 100644
--- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
@@ -542,11 +542,34 @@
         }
         mRcsCallbacks.broadcastAction(c -> {
             try {
-                //TODO compressed by default?
                 c.onAutoConfigurationErrorReceived(errorCode, errorString);
             } catch (RemoteException e) {
                 Log.w(TAG, "dead binder in notifyAutoConfigurationErrorReceived, skipping.");
             }
         });
     }
+
+    /**
+     * Notifies application that pre-provisioning config is received.
+     *
+     * <p>Some carriers using ACS (auto configuration server) may send a carrier-specific
+     * pre-provisioning configuration XML if the user has not been provisioned for RCS
+     * services yet. When such provisioning XML is received, ACS client must call this
+     * method to notify the application with the XML.
+     *
+     * @param configXml the pre-provisioning config in carrier specified format.
+     */
+    public final void notifyPreProvisioningReceived(@NonNull byte[] configXml) {
+        // can be null in testing
+        if (mRcsCallbacks == null) {
+            return;
+        }
+        mRcsCallbacks.broadcastAction(c -> {
+            try {
+                c.onPreProvisioningReceived(configXml);
+            } catch (RemoteException e) {
+                Log.w(TAG, "dead binder in notifyPreProvisioningReceived, skipping.");
+            }
+        });
+    }
 }
diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
index 908869b..03e17fb 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.
          *
@@ -385,13 +386,13 @@
      * {@link SubscribeResponseCallback#onTerminated(String, long)} must be called for the
      * framework to finish listening for NOTIFY responses.
      *
-     * @param uris A {@link List} of the {@link Uri}s that the framework is requesting the UCE
-     * capabilities for.
+     * @param 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 List<Uri> uris,
+    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.");
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/Android.bp b/tests/net/Android.bp
index 8122495..7f0318a 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -70,7 +70,7 @@
         "mockito-target-minus-junit4",
         "net-tests-utils",
         "platform-test-annotations",
-        "service-connectivity",
+        "service-connectivity-pre-jarjar",
         "services.core",
         "services.net",
     ],
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/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index 5d0e016..0dfec75 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -28,6 +28,7 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
@@ -44,6 +45,10 @@
 import static android.net.NetworkCapabilities.UNRESTRICTED_CAPABILITIES;
 import static android.os.Process.INVALID_UID;
 
+import static com.android.modules.utils.build.SdkLevel.isAtLeastR;
+import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
+import static com.android.testutils.MiscAsserts.assertEmpty;
+import static com.android.testutils.MiscAsserts.assertThrows;
 import static com.android.testutils.ParcelUtils.assertParcelSane;
 import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
 import static com.android.testutils.ParcelUtils.parcelingRoundTrip;
@@ -67,7 +72,7 @@
 
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.modules.utils.build.SdkLevel;
+import com.android.testutils.CompatUtil;
 import com.android.testutils.DevSdkIgnoreRule;
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
 
@@ -84,6 +89,9 @@
 public class NetworkCapabilitiesTest {
     private static final String TEST_SSID = "TEST_SSID";
     private static final String DIFFERENT_TEST_SSID = "DIFFERENT_TEST_SSID";
+    private static final int TEST_SUBID1 = 1;
+    private static final int TEST_SUBID2 = 2;
+    private static final int TEST_SUBID3 = 3;
 
     @Rule
     public DevSdkIgnoreRule mDevSdkIgnoreRule = new DevSdkIgnoreRule();
@@ -91,14 +99,6 @@
     private DiscoverySession mDiscoverySession = Mockito.mock(DiscoverySession.class);
     private PeerHandle mPeerHandle = Mockito.mock(PeerHandle.class);
 
-    private boolean isAtLeastR() {
-        return SdkLevel.isAtLeastR();
-    }
-
-    private boolean isAtLeastS() {
-        return SdkLevel.isAtLeastS();
-    }
-
     @Test
     public void testMaybeMarkCapabilitiesRestricted() {
         // verify EIMS is restricted
@@ -211,7 +211,7 @@
         nc1 = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI);
         nc2 = new NetworkCapabilities()
                 .addTransportType(TRANSPORT_WIFI)
-                .setNetworkSpecifier(new StringNetworkSpecifier("specs"));
+                .setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier("eth42"));
         assertNotEquals("", nc1.describeImmutableDifferences(nc2));
         assertEquals("", nc1.describeImmutableDifferences(nc1));
     }
@@ -304,7 +304,9 @@
             .setUids(uids)
             .addCapability(NET_CAPABILITY_EIMS)
             .addCapability(NET_CAPABILITY_NOT_METERED);
-        if (isAtLeastR()) {
+        if (isAtLeastS()) {
+            netCap.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2));
+        } else if (isAtLeastR()) {
             netCap.setOwnerUid(123);
             netCap.setAdministratorUids(new int[] {5, 11});
         }
@@ -379,7 +381,7 @@
 
     private void testParcelSane(NetworkCapabilities cap) {
         if (isAtLeastS()) {
-            assertParcelSane(cap, 16);
+            assertParcelSane(cap, 17);
         } else if (isAtLeastR()) {
             assertParcelSane(cap, 15);
         } else {
@@ -613,6 +615,20 @@
         assertFalse(nc2.appliesToUid(12));
         assertTrue(nc1.appliesToUid(22));
         assertTrue(nc2.appliesToUid(22));
+
+        // Verify the subscription id list can be combined only when they are equal.
+        if (isAtLeastS()) {
+            nc1.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2));
+            nc2.setSubIds(Set.of(TEST_SUBID2));
+            assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1));
+
+            nc2.setSubIds(Set.of());
+            assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1));
+
+            nc2.setSubIds(Set.of(TEST_SUBID2, TEST_SUBID1));
+            nc2.combineCapabilities(nc1);
+            assertEquals(Set.of(TEST_SUBID2, TEST_SUBID1), nc2.getSubIds());
+        }
     }
 
     @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
@@ -671,7 +687,7 @@
         NetworkCapabilities nc1 = new NetworkCapabilities();
         nc1.addTransportType(TRANSPORT_CELLULAR).addTransportType(TRANSPORT_WIFI);
         try {
-            nc1.setNetworkSpecifier(new StringNetworkSpecifier("specs"));
+            nc1.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier("eth0"));
             fail("Cannot set NetworkSpecifier on a NetworkCapability with multiple transports!");
         } catch (IllegalStateException expected) {
             // empty
@@ -680,7 +696,7 @@
         // Sequence 2: Transport + NetworkSpecifier + Transport
         NetworkCapabilities nc2 = new NetworkCapabilities();
         nc2.addTransportType(TRANSPORT_CELLULAR).setNetworkSpecifier(
-                new StringNetworkSpecifier("specs"));
+                CompatUtil.makeEthernetNetworkSpecifier("testtap3"));
         try {
             nc2.addTransportType(TRANSPORT_WIFI);
             fail("Cannot set a second TransportType of a network which has a NetworkSpecifier!");
@@ -761,6 +777,24 @@
         nc1.setUids(uidRange(10, 13));
         nc2.set(nc1);  // Overwrites, as opposed to combineCapabilities
         assertEquals(nc1, nc2);
+
+        if (isAtLeastS()) {
+            assertThrows(NullPointerException.class, () -> nc1.setSubIds(null));
+            nc1.setSubIds(Set.of());
+            nc2.set(nc1);
+            assertEquals(nc1, nc2);
+
+            nc1.setSubIds(Set.of(TEST_SUBID1));
+            nc2.set(nc1);
+            assertEquals(nc1, nc2);
+
+            nc2.setSubIds(Set.of(TEST_SUBID2, TEST_SUBID1));
+            nc2.set(nc1);
+            assertEquals(nc1, nc2);
+
+            nc2.setSubIds(Set.of(TEST_SUBID3, TEST_SUBID2));
+            assertNotEquals(nc1, nc2);
+        }
     }
 
     @Test
@@ -841,6 +875,50 @@
         } catch (NullPointerException expected) { }
     }
 
+    private static NetworkCapabilities capsWithSubIds(Integer ... subIds) {
+        // Since the NetworkRequest would put NOT_VCN_MANAGED capabilities in general, for
+        // every NetworkCapabilities that simulates networks needs to add it too in order to
+        // satisfy these requests.
+        final NetworkCapabilities nc = new NetworkCapabilities.Builder()
+                .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
+                .setSubIds(new ArraySet<>(subIds)).build();
+        assertEquals(new ArraySet<>(subIds), nc.getSubIds());
+        return nc;
+    }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+    public void testSubIds() throws Exception {
+        final NetworkCapabilities ncWithoutId = capsWithSubIds();
+        final NetworkCapabilities ncWithId = capsWithSubIds(TEST_SUBID1);
+        final NetworkCapabilities ncWithOtherIds = capsWithSubIds(TEST_SUBID1, TEST_SUBID3);
+        final NetworkCapabilities ncWithoutRequestedIds = capsWithSubIds(TEST_SUBID3);
+
+        final NetworkRequest requestWithoutId = new NetworkRequest.Builder().build();
+        assertEmpty(requestWithoutId.networkCapabilities.getSubIds());
+        final NetworkRequest requestWithIds = new NetworkRequest.Builder()
+                .setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2)).build();
+        assertEquals(Set.of(TEST_SUBID1, TEST_SUBID2),
+                requestWithIds.networkCapabilities.getSubIds());
+
+        assertFalse(requestWithIds.canBeSatisfiedBy(ncWithoutId));
+        assertTrue(requestWithIds.canBeSatisfiedBy(ncWithOtherIds));
+        assertFalse(requestWithIds.canBeSatisfiedBy(ncWithoutRequestedIds));
+        assertTrue(requestWithIds.canBeSatisfiedBy(ncWithId));
+        assertTrue(requestWithoutId.canBeSatisfiedBy(ncWithoutId));
+        assertTrue(requestWithoutId.canBeSatisfiedBy(ncWithId));
+    }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+    public void testEqualsSubIds() throws Exception {
+        assertEquals(capsWithSubIds(), capsWithSubIds());
+        assertNotEquals(capsWithSubIds(), capsWithSubIds(TEST_SUBID1));
+        assertEquals(capsWithSubIds(TEST_SUBID1), capsWithSubIds(TEST_SUBID1));
+        assertNotEquals(capsWithSubIds(TEST_SUBID1), capsWithSubIds(TEST_SUBID2));
+        assertNotEquals(capsWithSubIds(TEST_SUBID1), capsWithSubIds(TEST_SUBID2, TEST_SUBID1));
+        assertEquals(capsWithSubIds(TEST_SUBID1, TEST_SUBID2),
+                capsWithSubIds(TEST_SUBID2, TEST_SUBID1));
+    }
+
     @Test
     public void testLinkBandwidthKbps() {
         final NetworkCapabilities nc = new NetworkCapabilities();
@@ -1021,5 +1099,11 @@
             fail("Should not set null into NetworkCapabilities.Builder");
         } catch (NullPointerException expected) { }
         assertEquals(nc, new NetworkCapabilities.Builder(nc).build());
+
+        if (isAtLeastS()) {
+            final NetworkCapabilities nc2 = new NetworkCapabilities.Builder()
+                    .setSubIds(Set.of(TEST_SUBID1)).build();
+            assertEquals(Set.of(TEST_SUBID1), nc2.getSubIds());
+        }
     }
 }
diff --git a/tests/net/common/java/android/net/NetworkProviderTest.kt b/tests/net/common/java/android/net/NetworkProviderTest.kt
index bcc9072..340e6f9 100644
--- a/tests/net/common/java/android/net/NetworkProviderTest.kt
+++ b/tests/net/common/java/android/net/NetworkProviderTest.kt
@@ -27,6 +27,7 @@
 import android.os.Looper
 import androidx.test.InstrumentationRegistry
 import com.android.net.module.util.ArrayTrackRecord
+import com.android.testutils.CompatUtil
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
 import com.android.testutils.DevSdkIgnoreRunner
 import com.android.testutils.isDevSdkInRange
@@ -102,7 +103,8 @@
         mCm.registerNetworkProvider(provider)
         assertNotEquals(provider.getProviderId(), NetworkProvider.ID_NONE)
 
-        val specifier = StringNetworkSpecifier(UUID.randomUUID().toString())
+        val specifier = CompatUtil.makeTestNetworkSpecifier(
+                UUID.randomUUID().toString())
         val nr: NetworkRequest = NetworkRequest.Builder()
                 .addTransportType(TRANSPORT_TEST)
                 .setNetworkSpecifier(specifier)
@@ -183,7 +185,8 @@
 
         mCm.registerNetworkProvider(provider)
 
-        val specifier = StringNetworkSpecifier(UUID.randomUUID().toString())
+        val specifier = CompatUtil.makeTestNetworkSpecifier(
+                UUID.randomUUID().toString())
         val nr: NetworkRequest = NetworkRequest.Builder()
                 .addTransportType(TRANSPORT_TEST)
                 .setNetworkSpecifier(specifier)
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/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
index 6a09b02..6fc605e 100644
--- a/tests/net/java/android/net/ConnectivityManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -220,7 +220,7 @@
 
         // register callback
         when(mService.requestNetwork(any(), anyInt(), captor.capture(), anyInt(), any(), anyInt(),
-                any(), nullable(String.class))).thenReturn(request);
+                anyInt(), any(), nullable(String.class))).thenReturn(request);
         manager.requestNetwork(request, callback, handler);
 
         // callback triggers
@@ -248,7 +248,7 @@
 
         // register callback
         when(mService.requestNetwork(any(), anyInt(), captor.capture(), anyInt(), any(), anyInt(),
-                any(), nullable(String.class))).thenReturn(req1);
+                anyInt(), any(), nullable(String.class))).thenReturn(req1);
         manager.requestNetwork(req1, callback, handler);
 
         // callback triggers
@@ -266,7 +266,7 @@
 
         // callback can be registered again
         when(mService.requestNetwork(any(), anyInt(), captor.capture(), anyInt(), any(), anyInt(),
-                any(), nullable(String.class))).thenReturn(req2);
+                anyInt(), any(), nullable(String.class))).thenReturn(req2);
         manager.requestNetwork(req2, callback, handler);
 
         // callback triggers
@@ -289,8 +289,8 @@
         info.targetSdkVersion = VERSION_CODES.N_MR1 + 1;
 
         when(mCtx.getApplicationInfo()).thenReturn(info);
-        when(mService.requestNetwork(any(), anyInt(), any(), anyInt(), any(), anyInt(), any(),
-                nullable(String.class))).thenReturn(request);
+        when(mService.requestNetwork(any(), anyInt(), any(), anyInt(), any(), anyInt(), anyInt(),
+                any(), nullable(String.class))).thenReturn(request);
 
         Handler handler = new Handler(Looper.getMainLooper());
         manager.requestNetwork(request, callback, handler);
@@ -358,34 +358,34 @@
 
         manager.requestNetwork(request, callback);
         verify(mService).requestNetwork(eq(request.networkCapabilities),
-                eq(REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
+                eq(REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
                 eq(testPkgName), eq(testAttributionTag));
         reset(mService);
 
         // Verify that register network callback does not calls requestNetwork at all.
         manager.registerNetworkCallback(request, callback);
-        verify(mService, never()).requestNetwork(any(), anyInt(), any(), anyInt(), any(),
+        verify(mService, never()).requestNetwork(any(), anyInt(), any(), anyInt(), any(), anyInt(),
                 anyInt(), any(), any());
-        verify(mService).listenForNetwork(eq(request.networkCapabilities), any(), any(),
+        verify(mService).listenForNetwork(eq(request.networkCapabilities), any(), any(), anyInt(),
                 eq(testPkgName), eq(testAttributionTag));
         reset(mService);
 
         manager.registerDefaultNetworkCallback(callback);
         verify(mService).requestNetwork(eq(null),
-                eq(TRACK_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
-                eq(testPkgName), eq(testAttributionTag));
-        reset(mService);
-
-        manager.requestBackgroundNetwork(request, null, callback);
-        verify(mService).requestNetwork(eq(request.networkCapabilities),
-                eq(BACKGROUND_REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
+                eq(TRACK_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
                 eq(testPkgName), eq(testAttributionTag));
         reset(mService);
 
         Handler handler = new Handler(ConnectivityThread.getInstanceLooper());
+        manager.requestBackgroundNetwork(request, handler, callback);
+        verify(mService).requestNetwork(eq(request.networkCapabilities),
+                eq(BACKGROUND_REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
+                eq(testPkgName), eq(testAttributionTag));
+        reset(mService);
+
         manager.registerSystemDefaultNetworkCallback(callback, handler);
         verify(mService).requestNetwork(eq(null),
-                eq(TRACK_SYSTEM_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
+                eq(TRACK_SYSTEM_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
                 eq(testPkgName), eq(testAttributionTag));
         reset(mService);
     }
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..2c8c8a6 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;
@@ -1455,6 +1454,8 @@
         applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
         when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any()))
                 .thenReturn(applicationInfo);
+        when(mPackageManager.getTargetSdkVersion(anyString()))
+                .thenReturn(applicationInfo.targetSdkVersion);
         when(mSystemConfigManager.getSystemPermissionUids(anyString())).thenReturn(new int[0]);
 
         // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
@@ -1526,12 +1527,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 +1743,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
@@ -3732,8 +3751,8 @@
             networkCapabilities.addTransportType(TRANSPORT_WIFI)
                     .setNetworkSpecifier(new MatchAllNetworkSpecifier());
             mService.requestNetwork(networkCapabilities, NetworkRequest.Type.REQUEST.ordinal(),
-                    null, 0, null, ConnectivityManager.TYPE_WIFI, mContext.getPackageName(),
-                    getAttributionTag());
+                    null, 0, null, ConnectivityManager.TYPE_WIFI, NetworkCallback.FLAG_NONE,
+                    mContext.getPackageName(), getAttributionTag());
         });
 
         class NonParcelableSpecifier extends NetworkSpecifier {
@@ -4010,7 +4029,8 @@
         grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid());
         final TestNetworkCallback cellBgCallback = new TestNetworkCallback();
         mCm.requestBackgroundNetwork(new NetworkRequest.Builder()
-                .addTransportType(TRANSPORT_CELLULAR).build(), null, cellBgCallback);
+                .addTransportType(TRANSPORT_CELLULAR).build(),
+                mCsHandlerThread.getThreadHandler(), cellBgCallback);
 
         // Make callbacks for monitoring.
         final NetworkRequest request = new NetworkRequest.Builder().build();
@@ -5574,7 +5594,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 +7204,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 +7222,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 +7238,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 +7247,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 +7265,7 @@
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+        assertExtraInfoFromCmBlocked(mCellNetworkAgent);
         setRestrictBackgroundChanged(true);
         cellNetworkCallback.assertNoCallback();
 
@@ -7245,12 +7273,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 +7339,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 +7357,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 +7691,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 +7720,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 +7763,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 +7778,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 +7795,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 +7872,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 +7892,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 +7966,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 +7976,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 +7998,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 +8051,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 +8328,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()
@@ -8653,6 +8758,7 @@
         applicationInfo.targetSdkVersion = targetSdk;
         when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any()))
                 .thenReturn(applicationInfo);
+        when(mPackageManager.getTargetSdkVersion(any())).thenReturn(targetSdk);
 
         when(mLocationManager.isLocationEnabledForUser(any())).thenReturn(locationToggle);
 
@@ -8667,102 +8773,183 @@
         }
     }
 
-    private int getOwnerUidNetCapsForCallerPermission(int ownerUid, int callerUid) {
+    private int getOwnerUidNetCapsPermission(int ownerUid, int callerUid,
+            boolean includeLocationSensitiveInfo) {
         final NetworkCapabilities netCap = new NetworkCapabilities().setOwnerUid(ownerUid);
 
         return mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
-                netCap, callerUid, mContext.getPackageName(), getAttributionTag()).getOwnerUid();
+                netCap, includeLocationSensitiveInfo, callerUid,
+                mContext.getPackageName(), getAttributionTag())
+                .getOwnerUid();
     }
 
-    private void verifyWifiInfoCopyNetCapsForCallerPermission(
-            int callerUid, boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) {
+    private void verifyWifiInfoCopyNetCapsPermission(
+            int callerUid, boolean includeLocationSensitiveInfo,
+            boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) {
         final WifiInfo wifiInfo = mock(WifiInfo.class);
         when(wifiInfo.hasLocationSensitiveFields()).thenReturn(true);
         final NetworkCapabilities netCap = new NetworkCapabilities().setTransportInfo(wifiInfo);
 
         mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
-                netCap, callerUid, mContext.getPackageName(), getAttributionTag());
+                netCap, includeLocationSensitiveInfo, callerUid,
+                mContext.getPackageName(), getAttributionTag());
         verify(wifiInfo).makeCopy(eq(shouldMakeCopyWithLocationSensitiveFieldsParcelable));
     }
 
+    private void verifyOwnerUidAndWifiInfoNetCapsPermission(
+            boolean shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag,
+            boolean shouldInclLocationSensitiveOwnerUidWithIncludeFlag,
+            boolean shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag,
+            boolean shouldInclLocationSensitiveWifiInfoWithIncludeFlag) {
+        final int myUid = Process.myUid();
+
+        final int expectedOwnerUidWithoutIncludeFlag =
+                shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag
+                        ? Process.myUid() : INVALID_UID;
+        assertEquals(expectedOwnerUidWithoutIncludeFlag, getOwnerUidNetCapsPermission(
+                myUid, myUid, false /* includeLocationSensitiveInfo */));
+
+        final int expectedOwnerUidWithIncludeFlag =
+                shouldInclLocationSensitiveOwnerUidWithIncludeFlag ? myUid : INVALID_UID;
+        assertEquals(expectedOwnerUidWithIncludeFlag, getOwnerUidNetCapsPermission(
+                myUid, myUid, true /* includeLocationSensitiveInfo */));
+
+        verifyWifiInfoCopyNetCapsPermission(myUid,
+                false, /* includeLocationSensitiveInfo */
+                shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag);
+
+        verifyWifiInfoCopyNetCapsPermission(myUid,
+                true, /* includeLocationSensitiveInfo */
+                shouldInclLocationSensitiveWifiInfoWithIncludeFlag);
+
+    }
+
     @Test
-    public void testCreateForCallerWithLocationInfoSanitizedWithFineLocationAfterQ()
+    public void testCreateWithLocationInfoSanitizedWithFineLocationAfterQ()
             throws Exception {
         setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
                 Manifest.permission.ACCESS_FINE_LOCATION);
 
-        final int myUid = Process.myUid();
-        assertEquals(myUid, getOwnerUidNetCapsForCallerPermission(myUid, myUid));
-
-        verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
-                true /* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+        verifyOwnerUidAndWifiInfoNetCapsPermission(
+                // Ensure that we include owner uid even if the request asks to remove it since the
+                // app has necessary permissions and targetSdk < S.
+                true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+                true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+                // Ensure that we remove location info if the request asks to remove it even if the
+                // app has necessary permissions.
+                true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+        );
     }
 
     @Test
-    public void testCreateForCallerWithLocationInfoSanitizedWithCoarseLocationPreQ()
+    public void testCreateWithLocationInfoSanitizedWithFineLocationPreSWithAndWithoutCallbackFlag()
+            throws Exception {
+        setupLocationPermissions(Build.VERSION_CODES.R, true, AppOpsManager.OPSTR_FINE_LOCATION,
+                Manifest.permission.ACCESS_FINE_LOCATION);
+
+        verifyOwnerUidAndWifiInfoNetCapsPermission(
+                // Ensure that we include owner uid even if the request asks to remove it since the
+                // app has necessary permissions and targetSdk < S.
+                true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+                true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+                // Ensure that we remove location info if the request asks to remove it even if the
+                // app has necessary permissions.
+                true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+        );
+    }
+
+    @Test
+    public void
+            testCreateWithLocationInfoSanitizedWithFineLocationAfterSWithAndWithoutCallbackFlag()
+            throws Exception {
+        setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION,
+                Manifest.permission.ACCESS_FINE_LOCATION);
+
+        verifyOwnerUidAndWifiInfoNetCapsPermission(
+                // Ensure that we owner UID if the request asks us to remove it even if the app
+                // has necessary permissions since targetSdk >= S.
+                false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+                true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+                // Ensure that we remove location info if the request asks to remove it even if the
+                // app has necessary permissions.
+                true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+        );
+    }
+
+    @Test
+    public void testCreateWithLocationInfoSanitizedWithCoarseLocationPreQ()
             throws Exception {
         setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION,
                 Manifest.permission.ACCESS_COARSE_LOCATION);
 
-        final int myUid = Process.myUid();
-        assertEquals(myUid, getOwnerUidNetCapsForCallerPermission(myUid, myUid));
-
-        verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
-                true /* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+        verifyOwnerUidAndWifiInfoNetCapsPermission(
+                // Ensure that we owner UID if the request asks us to remove it even if the app
+                // has necessary permissions since targetSdk >= S.
+                true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+                true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+                // Ensure that we remove location info if the request asks to remove it even if the
+                // app has necessary permissions.
+                true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+        );
     }
 
     @Test
-    public void testCreateForCallerWithLocationInfoSanitizedLocationOff() throws Exception {
+    public void testCreateWithLocationInfoSanitizedLocationOff() throws Exception {
         // Test that even with fine location permission, and UIDs matching, the UID is sanitized.
         setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION,
                 Manifest.permission.ACCESS_FINE_LOCATION);
 
-        final int myUid = Process.myUid();
-        assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid, myUid));
-
-        verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
-                false/* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+        verifyOwnerUidAndWifiInfoNetCapsPermission(
+                false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+                false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+                false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+        );
     }
 
     @Test
-    public void testCreateForCallerWithLocationInfoSanitizedWrongUid() throws Exception {
+    public void testCreateWithLocationInfoSanitizedWrongUid() throws Exception {
         // Test that even with fine location permission, not being the owner leads to sanitization.
         setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
                 Manifest.permission.ACCESS_FINE_LOCATION);
 
         final int myUid = Process.myUid();
-        assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid + 1, myUid));
-
-        verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
-                true /* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+        assertEquals(Process.INVALID_UID,
+                getOwnerUidNetCapsPermission(myUid + 1, myUid,
+                        true /* includeLocationSensitiveInfo */));
     }
 
     @Test
-    public void testCreateForCallerWithLocationInfoSanitizedWithCoarseLocationAfterQ()
+    public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterQ()
             throws Exception {
         // Test that not having fine location permission leads to sanitization.
         setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION,
                 Manifest.permission.ACCESS_COARSE_LOCATION);
 
-        // Test that without the location permission, the owner field is sanitized.
-        final int myUid = Process.myUid();
-        assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid, myUid));
-
-        verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
-                false/* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+        verifyOwnerUidAndWifiInfoNetCapsPermission(
+                false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+                false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+                false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+        );
     }
 
     @Test
-    public void testCreateForCallerWithLocationInfoSanitizedWithoutLocationPermission()
+    public void testCreateWithLocationInfoSanitizedWithoutLocationPermission()
             throws Exception {
+        // Test that not having fine location permission leads to sanitization.
         setupLocationPermissions(Build.VERSION_CODES.Q, true, null /* op */, null /* perm */);
 
-        // Test that without the location permission, the owner field is sanitized.
-        final int myUid = Process.myUid();
-        assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid, myUid));
-
-        verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
-                false/* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+        verifyOwnerUidAndWifiInfoNetCapsPermission(
+                false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+                false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+                false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+        );
     }
 
     private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType)
@@ -8967,7 +9154,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
@@ -9353,8 +9540,8 @@
             assertThrows("Expect throws for invalid request type " + reqTypeInt,
                     IllegalArgumentException.class,
                     () -> mService.requestNetwork(nc, reqTypeInt, null, 0, null,
-                            ConnectivityManager.TYPE_NONE, mContext.getPackageName(),
-                            getAttributionTag())
+                            ConnectivityManager.TYPE_NONE, NetworkCallback.FLAG_NONE,
+                            mContext.getPackageName(), getAttributionTag())
             );
         }
     }
@@ -10647,7 +10834,7 @@
                 null,
                 null);
 
-        // default NCs will be unregistered in tearDown
+        // default callbacks will be unregistered in tearDown
     }
 
     /**
@@ -10704,7 +10891,7 @@
                 null,
                 mService.mNoServiceNetwork.network());
 
-        // default NCs will be unregistered in tearDown
+        // default callbacks will be unregistered in tearDown
     }
 
     /**
@@ -10763,7 +10950,7 @@
                 null,
                 mService.mNoServiceNetwork.network());
 
-        // default NCs will be unregistered in tearDown
+        // default callbacks will be unregistered in tearDown
     }
 
     /**
@@ -10822,7 +11009,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 +11111,12 @@
         verifyNoNetwork();
         mCm.unregisterNetworkCallback(cellCb);
     }
+
+    @Test
+    public void testRegisterBestMatchingNetworkCallback() throws Exception {
+        final NetworkRequest request = new NetworkRequest.Builder().build();
+        assertThrows(UnsupportedOperationException.class,
+                () -> mCm.registerBestMatchingNetworkCallback(request, new NetworkCallback(),
+                        mCsHandlerThread.getThreadHandler()));
+    }
 }
diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java
index f97eabf..6232423 100644
--- a/tests/net/java/com/android/server/IpSecServiceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceTest.java
@@ -35,6 +35,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.net.ConnectivityManager;
 import android.net.INetd;
 import android.net.IpSecAlgorithm;
 import android.net.IpSecConfig;
@@ -47,6 +48,7 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.StructStat;
+import android.util.Range;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -647,9 +649,9 @@
 
     @Test
     public void testReserveNetId() {
-        int start = mIpSecService.TUN_INTF_NETID_START;
-        for (int i = 0; i < mIpSecService.TUN_INTF_NETID_RANGE; i++) {
-            assertEquals(start + i, mIpSecService.reserveNetId());
+        final Range<Integer> netIdRange = ConnectivityManager.getIpSecNetIdRange();
+        for (int netId = netIdRange.getLower(); netId <= netIdRange.getUpper(); netId++) {
+            assertEquals(netId, mIpSecService.reserveNetId());
         }
 
         // Check that resource exhaustion triggers an exception
@@ -661,7 +663,7 @@
 
         // Now release one and try again
         int releasedNetId =
-                mIpSecService.TUN_INTF_NETID_START + mIpSecService.TUN_INTF_NETID_RANGE / 2;
+                netIdRange.getLower() + (netIdRange.getUpper() - netIdRange.getLower()) / 2;
         mIpSecService.releaseNetId(releasedNetId);
         assertEquals(releasedNetId, mIpSecService.reserveNetId());
     }
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/MultipathPolicyTrackerTest.java b/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
index 950d7163..38f6d7f 100644
--- a/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
+++ b/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
@@ -46,12 +46,12 @@
 import android.content.pm.ApplicationInfo;
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
+import android.net.EthernetNetworkSpecifier;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkPolicy;
 import android.net.NetworkPolicyManager;
 import android.net.NetworkTemplate;
-import android.net.StringNetworkSpecifier;
 import android.net.TelephonyNetworkSpecifier;
 import android.os.Handler;
 import android.os.UserHandle;
@@ -240,7 +240,7 @@
         NetworkCapabilities capabilities = new NetworkCapabilities()
                 .addCapability(NET_CAPABILITY_INTERNET)
                 .addTransportType(TRANSPORT_CELLULAR)
-                .setNetworkSpecifier(new StringNetworkSpecifier("234"));
+                .setNetworkSpecifier(new EthernetNetworkSpecifier("eth234"));
         if (!roaming) {
             capabilities.addCapability(NET_CAPABILITY_NOT_ROAMING);
         }
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/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index e4e24b4..fec5ef3 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -48,18 +48,22 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
 import android.net.INetd;
 import android.net.UidRange;
+import android.net.Uri;
 import android.os.Build;
 import android.os.SystemConfigManager;
 import android.os.UserHandle;
@@ -70,12 +74,11 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.server.LocalServices;
-import com.android.server.pm.PackageList;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.AdditionalAnswers;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
@@ -112,7 +115,6 @@
     @Mock private Context mContext;
     @Mock private PackageManager mPackageManager;
     @Mock private INetd mNetdService;
-    @Mock private PackageManagerInternal mMockPmi;
     @Mock private UserManager mUserManager;
     @Mock private PermissionMonitor.Dependencies mDeps;
     @Mock private SystemConfigManager mSystemConfigManager;
@@ -131,16 +133,14 @@
         when(mContext.getSystemService(Context.SYSTEM_CONFIG_SERVICE))
                 .thenReturn(mSystemConfigManager);
         when(mSystemConfigManager.getSystemPermissionUids(anyString())).thenReturn(new int[0]);
+        final Context asUserCtx = mock(Context.class, AdditionalAnswers.delegatesTo(mContext));
+        doReturn(UserHandle.ALL).when(asUserCtx).getUser();
+        when(mContext.createContextAsUser(eq(UserHandle.ALL), anyInt())).thenReturn(asUserCtx);
 
         mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService, mDeps));
 
-        LocalServices.removeServiceForTest(PackageManagerInternal.class);
-        LocalServices.addService(PackageManagerInternal.class, mMockPmi);
-        when(mMockPmi.getPackageList(any())).thenReturn(new PackageList(new ArrayList<String>(),
-                  /* observer */ null));
         when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(/* empty app list */ null);
         mPermissionMonitor.startMonitoring();
-        verify(mMockPmi).getPackageList(mPermissionMonitor);
     }
 
     private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion, int uid,
@@ -770,4 +770,32 @@
                 INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS,
                 new int[]{ MOCK_UID2 });
     }
+
+    @Test
+    public void testIntentReceiver() throws Exception {
+        final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+        final ArgumentCaptor<BroadcastReceiver> receiverCaptor =
+                ArgumentCaptor.forClass(BroadcastReceiver.class);
+        verify(mContext, times(1)).registerReceiver(receiverCaptor.capture(), any(), any(), any());
+        final BroadcastReceiver receiver = receiverCaptor.getValue();
+
+        // Verify receiving PACKAGE_ADDED intent.
+        final Intent addedIntent = new Intent(Intent.ACTION_PACKAGE_ADDED,
+                Uri.fromParts("package", MOCK_PACKAGE1, null /* fragment */));
+        addedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID1);
+        setPackagePermissions(MOCK_PACKAGE1, MOCK_UID1,
+                new String[] { INTERNET, UPDATE_DEVICE_STATS });
+        receiver.onReceive(mContext, addedIntent);
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+                | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[] { MOCK_UID1 });
+
+        // Verify receiving PACKAGE_REMOVED intent.
+        when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(null);
+        final Intent removedIntent = new Intent(Intent.ACTION_PACKAGE_REMOVED,
+                Uri.fromParts("package", MOCK_PACKAGE1, null /* fragment */));
+        removedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID1);
+        receiver.onReceive(mContext, removedIntent);
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[] { MOCK_UID1 });
+    }
+
 }
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 11498de..a0200275 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -593,6 +593,16 @@
         mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
     }
 
+    @Test(expected = SecurityException.class)
+    public void testRemoveVcnUnderlyingNetworkPolicyListenerInvalidPermission() {
+        doThrow(new SecurityException())
+                .when(mMockContext)
+                .enforceCallingOrSelfPermission(
+                        eq(android.Manifest.permission.NETWORK_FACTORY), any());
+
+        mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
+    }
+
     @Test
     public void testRemoveVcnUnderlyingNetworkPolicyListenerNeverRegistered() {
         mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
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);