Merge "Enable clang-format for frameworks/base"
diff --git a/Android.mk b/Android.mk
index d853248..46529eb 100644
--- a/Android.mk
+++ b/Android.mk
@@ -32,10 +32,6 @@
 # ============================================================
 include $(CLEAR_VARS)
 
-# This is used by ide.mk as the list of source files that are
-# always included.
-INTERNAL_SDK_SOURCE_DIRS := $(addprefix $(LOCAL_PATH)/,$(dirs_to_document))
-
 # sdk.atree needs to copy the whole dir: $(OUT_DOCS)/offline-sdk to the final zip.
 # So keep offline-sdk-timestamp target here, and unzip offline-sdk-docs.zip to
 # $(OUT_DOCS)/offline-sdk.
diff --git a/StubLibraries.bp b/StubLibraries.bp
index b984cb0..26478d3 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -229,11 +229,6 @@
 // namely @SystemApi(client=MODULE_LIBRARIES) APIs.
 /////////////////////////////////////////////////////////////////////
 
-// TODO(b/146727827) remove the *-api module when we can teach metalava
-// about the relationship among the API surfaces. Currently, these modules are only to generate
-// the API signature files and ensure that the APIs evolve in a backwards compatible manner.
-// They however are NOT used for building the API stub.
-
 droidstubs {
     name: "module-lib-api",
     defaults: ["metalava-full-api-stubs-default"],
@@ -270,7 +265,7 @@
     name: "module-lib-api-stubs-docs-non-updatable",
     defaults: ["metalava-non-updatable-api-stubs-default"],
     arg_files: ["core/res/AndroidManifest.xml"],
-    args: metalava_framework_docs_args + module_libs,
+    args: metalava_framework_docs_args + priv_apps + module_libs,
     check_api: {
         current: {
             api_file: "non-updatable-api/module-lib-current.txt",
@@ -279,17 +274,6 @@
     },
 }
 
-// The following droidstub module generates source files for the API stub library for
-// modules. Note that it not only includes its own APIs but also other APIs that have
-// narrower scope (all @SystemApis, not just the ones with 'client=MODULE_LIBRARIES').
-
-droidstubs {
-    name: "module-lib-api-stubs-docs",
-    defaults: ["metalava-non-updatable-api-stubs-default"],
-    arg_files: ["core/res/AndroidManifest.xml"],
-    args: metalava_framework_docs_args + priv_apps + module_libs,
-}
-
 /////////////////////////////////////////////////////////////////////
 // android_*_stubs_current modules are the stubs libraries compiled
 // from *-api-stubs-docs
@@ -335,7 +319,7 @@
 
 java_library_static {
     name: "android_module_lib_stubs_current",
-    srcs: [ ":module-lib-api-stubs-docs" ],
+    srcs: [ ":module-lib-api-stubs-docs-non-updatable" ],
     defaults: ["android_defaults_stubs_current"],
     libs: ["sdk_system_29_android"],
 }
diff --git a/api/current.txt b/api/current.txt
index f1338f0..8dd7af8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -41088,6 +41088,7 @@
     field public static final String EXTRA_KEY_ALIAS = "android.security.extra.KEY_ALIAS";
     field public static final String EXTRA_NAME = "name";
     field public static final String EXTRA_PKCS12 = "PKCS12";
+    field public static final String KEY_ALIAS_SELECTION_DENIED = "android:alias-selection-denied";
   }
 
   public interface KeyChainAliasCallback {
diff --git a/core/java/android/app/admin/DelegatedAdminReceiver.java b/core/java/android/app/admin/DelegatedAdminReceiver.java
index f66de8d..25b8eab 100644
--- a/core/java/android/app/admin/DelegatedAdminReceiver.java
+++ b/core/java/android/app/admin/DelegatedAdminReceiver.java
@@ -63,6 +63,10 @@
      * Allows this receiver to select the alias for a private key and certificate pair for
      * authentication.  If this method returns null, the default {@link android.app.Activity} will
      * be shown that lets the user pick a private key and certificate pair.
+     * If this method returns {@link KeyChain#KEY_ALIAS_SELECTION_DENIED},
+     * the default {@link android.app.Activity} will not be shown and the user will not be allowed
+     * to pick anything. And the app, that called {@link KeyChain#choosePrivateKeyAlias}, will
+     * receive {@code null} back.
      *
      * <p> This callback is only applicable if the delegated app has
      * {@link DevicePolicyManager#DELEGATION_CERT_SELECTION} capability. Additionally, it must
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 4771fd8..e3a49f3 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -791,6 +791,10 @@
      * Allows this receiver to select the alias for a private key and certificate pair for
      * authentication. If this method returns null, the default {@link android.app.Activity} will be
      * shown that lets the user pick a private key and certificate pair.
+     * If this method returns {@link KeyChain#KEY_ALIAS_SELECTION_DENIED},
+     * the default {@link android.app.Activity} will not be shown and the user will not be allowed
+     * to pick anything. And the app, that called {@link KeyChain#choosePrivateKeyAlias}, will
+     * receive {@code null} back.
      *
      * @param context The running context as per {@link #onReceive}.
      * @param intent The received intent as per {@link #onReceive}.
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index cb9463a..4b806e7 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -84,6 +84,15 @@
      * @hide
      */
     public static final int NETWORK_TYPE_ALL = -1;
+    /**
+     * Virtual RAT type to represent 5G NSA (Non Stand Alone) mode, where the primary cell is
+     * still LTE and network allocates a secondary 5G cell so telephony reports RAT = LTE along
+     * with NR state as connected. This should not be overlapped with any of the
+     * {@code TelephonyManager.NETWORK_TYPE_*} constants.
+     *
+     * @hide
+     */
+    public static final int NETWORK_TYPE_5G_NSA = -2;
 
     private static boolean isKnownMatchRule(final int rule) {
         switch (rule) {
@@ -472,6 +481,9 @@
                 return TelephonyManager.NETWORK_TYPE_LTE;
             case TelephonyManager.NETWORK_TYPE_NR:
                 return TelephonyManager.NETWORK_TYPE_NR;
+            // Virtual RAT type for 5G NSA mode, see {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}.
+            case NetworkTemplate.NETWORK_TYPE_5G_NSA:
+                return NetworkTemplate.NETWORK_TYPE_5G_NSA;
             default:
                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
         }
diff --git a/core/java/android/net/ProxyInfo.java b/core/java/android/net/ProxyInfo.java
index ffe9ae9..a32b41f 100644
--- a/core/java/android/net/ProxyInfo.java
+++ b/core/java/android/net/ProxyInfo.java
@@ -127,18 +127,6 @@
     }
 
     /**
-     * Create a ProxyProperties that points at a PAC URL.
-     * @hide
-     */
-    public ProxyInfo(String pacFileUrl) {
-        mHost = LOCAL_HOST;
-        mPort = LOCAL_PORT;
-        mExclusionList = LOCAL_EXCL_LIST;
-        mParsedExclusionList = parseExclusionList(mExclusionList);
-        mPacFileUrl = Uri.parse(pacFileUrl);
-    }
-
-    /**
      * Only used in PacManager after Local Proxy is bound.
      * @hide
      */
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index a95fe3c..7946dda 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -1331,8 +1331,7 @@
                 Object[] messages;
                 try {
                     messages = (Object[]) intent.getSerializableExtra("pdus");
-                }
-                catch (ClassCastException e) {
+                } catch (ClassCastException e) {
                     Rlog.e(TAG, "getMessagesFromIntent: " + e);
                     return null;
                 }
@@ -1344,9 +1343,12 @@
 
                 String format = intent.getStringExtra("format");
                 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
-                        SubscriptionManager.getDefaultSmsSubscriptionId());
-
-                Rlog.v(TAG, " getMessagesFromIntent sub_id : " + subId);
+                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+                if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+                    Rlog.v(TAG, "getMessagesFromIntent with valid subId : " + subId);
+                } else {
+                    Rlog.v(TAG, "getMessagesFromIntent");
+                }
 
                 int pduCount = messages.length;
                 SmsMessage[] msgs = new SmsMessage[pduCount];
diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java
index 8ea5aa8..b472749 100644
--- a/core/java/com/android/internal/net/VpnProfile.java
+++ b/core/java/com/android/internal/net/VpnProfile.java
@@ -21,6 +21,7 @@
 import android.net.Ikev2VpnProfile;
 import android.net.PlatformVpnProfile;
 import android.net.ProxyInfo;
+import android.net.Uri;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -287,7 +288,7 @@
                     profile.proxy = new ProxyInfo(host, port.isEmpty() ?
                             0 : Integer.parseInt(port), exclList);
                 } else if (!pacFileUrl.isEmpty()) {
-                    profile.proxy = new ProxyInfo(pacFileUrl);
+                    profile.proxy = new ProxyInfo(Uri.parse(pacFileUrl));
                 }
             } // else profile.proxy = null
 
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 18be374..fbb35e0 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -95,6 +95,19 @@
 
 #include "nativebridge/native_bridge.h"
 
+/* Functions in the callchain during the fork shall not be protected with
+   Armv8.3-A Pointer Authentication, otherwise child will not be able to return. */
+#ifdef __ARM_FEATURE_PAC_DEFAULT
+#ifdef __ARM_FEATURE_BTI_DEFAULT
+#define NO_PAC_FUNC __attribute__((target("branch-protection=bti")))
+#else
+#define NO_PAC_FUNC __attribute__((target("branch-protection=none")))
+#endif /* __ARM_FEATURE_BTI_DEFAULT */
+#else /* !__ARM_FEATURE_PAC_DEFAULT */
+#define NO_PAC_FUNC
+#endif /* __ARM_FEATURE_PAC_DEFAULT */
+
+
 namespace {
 
 // TODO (chriswailes): Add a function to initialize native Zygote data.
@@ -985,7 +998,23 @@
   gUsapPoolCount = 0;
 }
 
+NO_PAC_FUNC
+static void PAuthKeyChange(JNIEnv* env) {
+#ifdef __aarch64__
+  unsigned long int hwcaps = getauxval(AT_HWCAP);
+  if (hwcaps & HWCAP_PACA) {
+    const unsigned long key_mask = PR_PAC_APIAKEY | PR_PAC_APIBKEY |
+                                   PR_PAC_APDAKEY | PR_PAC_APDBKEY | PR_PAC_APGAKEY;
+    if (prctl(PR_PAC_RESET_KEYS, key_mask, 0, 0, 0) != 0) {
+      ALOGE("Failed to change the PAC keys: %s", strerror(errno));
+      RuntimeAbort(env, __LINE__, "PAC key change failed.");
+    }
+  }
+#endif
+}
+
 // Utility routine to fork a process from the zygote.
+NO_PAC_FUNC
 static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
                         const std::vector<int>& fds_to_close,
                         const std::vector<int>& fds_to_ignore,
@@ -1036,6 +1065,7 @@
     }
 
     // The child process.
+    PAuthKeyChange(env);
     PreApplicationInit();
 
     // Clean up any descriptors which must be closed immediately
@@ -1486,6 +1516,7 @@
   PreApplicationInit();
 }
 
+NO_PAC_FUNC
 static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
         JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
         jint runtime_flags, jobjectArray rlimits,
@@ -1533,6 +1564,7 @@
     return pid;
 }
 
+NO_PAC_FUNC
 static jint com_android_internal_os_Zygote_nativeForkSystemServer(
         JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
         jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
@@ -1600,6 +1632,7 @@
  * @param is_priority_fork  Controls the nice level assigned to the newly created process
  * @return
  */
+NO_PAC_FUNC
 static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env,
                                                           jclass,
                                                           jint read_pipe_fd,
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 59797f7..51266de 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2422,6 +2422,11 @@
     // OS: Q
     SETTINGS_GESTURE_TAP = 1751;
 
+    // OPEN: Settings > Security & screen lock -> Encryption & credentials > Install a certificate
+    // CATEGORY: SETTINGS
+    // OS: R
+    INSTALL_CERTIFICATE_FROM_STORAGE = 1803;
+
     // OPEN: Settings > Developer Options > Platform Compat
     // CATEGORY: SETTINGS
     // OS: R
diff --git a/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java b/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java
index d00d052..0af8c72 100644
--- a/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java
+++ b/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java
@@ -154,6 +154,29 @@
     }
 
     @Test
+    public void testBuilder_BasedOnAnotherProfileWithEmptyAccessRules() {
+        EuiccProfileInfo p =
+                new EuiccProfileInfo.Builder("21430000000000006587")
+                        .setNickname("profile nickname")
+                        .setProfileName("profile name")
+                        .setServiceProviderName("service provider")
+                        .setCarrierIdentifier(
+                                new CarrierIdentifier(
+                                        new byte[] {0x23, 0x45, 0x67},
+                                        "123",
+                                        "45"))
+                        .setState(EuiccProfileInfo.PROFILE_STATE_ENABLED)
+                        .setProfileClass(EuiccProfileInfo.PROFILE_CLASS_OPERATIONAL)
+                        .setPolicyRules(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE)
+                        .setUiccAccessRule(null)
+                        .build();
+
+        EuiccProfileInfo copied = new EuiccProfileInfo.Builder(p).build();
+
+        assertEquals(null, copied.getUiccAccessRules());
+    }
+
+    @Test
     public void testEqualsHashCode() {
         EuiccProfileInfo p =
                 new EuiccProfileInfo.Builder("21430000000000006587")
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index 7282bcf..62194d8 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -74,6 +74,15 @@
     /** Key containing suffix of lockdown VPN profile. */
     public static final String LOCKDOWN_VPN = "LOCKDOWN_VPN";
 
+    /** Name of CA certificate usage. */
+    public static final String CERTIFICATE_USAGE_CA = "ca";
+
+    /** Name of User certificate usage. */
+    public static final String CERTIFICATE_USAGE_USER = "user";
+
+    /** Name of WIFI certificate usage. */
+    public static final String CERTIFICATE_USAGE_WIFI = "wifi";
+
     /** Data type for public keys. */
     public static final String EXTRA_PUBLIC_KEY = "KEY";
 
@@ -94,9 +103,14 @@
     public static final String EXTRA_INSTALL_AS_UID = "install_as_uid";
 
     /**
-     * Intent extra: name for the user's private key.
+     * Intent extra: type of the certificate to install
      */
-    public static final String EXTRA_USER_PRIVATE_KEY_NAME = "user_private_key_name";
+    public static final String EXTRA_CERTIFICATE_USAGE = "certificate_install_usage";
+
+    /**
+     * Intent extra: name for the user's key pair.
+     */
+    public static final String EXTRA_USER_KEY_ALIAS = "user_key_pair_name";
 
     /**
      * Intent extra: data for the user's private key in PEM-encoded PKCS#8.
@@ -104,21 +118,11 @@
     public static final String EXTRA_USER_PRIVATE_KEY_DATA = "user_private_key_data";
 
     /**
-     * Intent extra: name for the user's certificate.
-     */
-    public static final String EXTRA_USER_CERTIFICATE_NAME = "user_certificate_name";
-
-    /**
      * Intent extra: data for the user's certificate in PEM-encoded X.509.
      */
     public static final String EXTRA_USER_CERTIFICATE_DATA = "user_certificate_data";
 
     /**
-     * Intent extra: name for CA certificate chain
-     */
-    public static final String EXTRA_CA_CERTIFICATES_NAME = "ca_certificates_name";
-
-    /**
      * Intent extra: data for CA certificate chain in PEM-encoded X.509.
      */
     public static final String EXTRA_CA_CERTIFICATES_DATA = "ca_certificates_data";
diff --git a/keystore/java/android/security/IKeyChainService.aidl b/keystore/java/android/security/IKeyChainService.aidl
index b3cdff7..97da3cc 100644
--- a/keystore/java/android/security/IKeyChainService.aidl
+++ b/keystore/java/android/security/IKeyChainService.aidl
@@ -43,7 +43,8 @@
     String installCaCertificate(in byte[] caCertificate);
 
     // APIs used by DevicePolicyManager
-    boolean installKeyPair(in byte[] privateKey, in byte[] userCert, in byte[] certChain, String alias);
+    boolean installKeyPair(
+        in byte[] privateKey, in byte[] userCert, in byte[] certChain, String alias, int uid);
     boolean removeKeyPair(String alias);
 
     // APIs used by Settings
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 1829d2f..254456c 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -343,6 +343,16 @@
     public static final int KEY_ATTESTATION_FAILURE = 4;
 
     /**
+     * Used by DPC or delegated app in
+     * {@link android.app.admin.DeviceAdminReceiver#onChoosePrivateKeyAlias} or
+     * {@link android.app.admin.DelegatedAdminReceiver#onChoosePrivateKeyAlias} to identify that
+     * the requesting app is not granted access to any key, and nor will the user be able to grant
+     * access manually.
+     */
+    public static final String KEY_ALIAS_SELECTION_DENIED =
+            "android:alias-selection-denied";
+
+    /**
      * Returns an {@code Intent} that can be used for credential
      * installation. The intent may be used without any extras, in
      * which case the user will be able to install credentials from
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index a285692..c55eeeb 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -40944,6 +40944,7 @@
     field public static final String EXTRA_KEY_ALIAS = "android.security.extra.KEY_ALIAS";
     field public static final String EXTRA_NAME = "name";
     field public static final String EXTRA_PKCS12 = "PKCS12";
+    field public static final String KEY_ALIAS_SELECTION_DENIED = "android:alias-selection-denied";
   }
 
   public interface KeyChainAliasCallback {
diff --git a/packages/Tethering/tests/privileged/Android.bp b/packages/Tethering/tests/privileged/Android.bp
new file mode 100644
index 0000000..a0fb246
--- /dev/null
+++ b/packages/Tethering/tests/privileged/Android.bp
@@ -0,0 +1,30 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+android_test {
+    name: "TetheringPrivilegedTests",
+    srcs: [
+        "src/**/*.java",
+        "src/**/*.kt",
+    ],
+    certificate: "networkstack",
+    platform_apis: true,
+    test_suites: [
+        "general-tests",
+        "mts",
+    ],
+    compile_multilib: "both",
+}
diff --git a/packages/Tethering/tests/privileged/AndroidManifest.xml b/packages/Tethering/tests/privileged/AndroidManifest.xml
new file mode 100644
index 0000000..49eba15d
--- /dev/null
+++ b/packages/Tethering/tests/privileged/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.networkstack.tethering.tests.privileged"
+          android:sharedUserId="android.uid.networkstack">
+
+    <!-- Note: do not add any privileged or signature permissions that are granted
+         to the network stack and its shared uid apps. Otherwise, the test APK will
+         install, but when the device is rebooted, it will bootloop because this
+         test APK is not in the privileged permission allow list -->
+
+    <application android:debuggable="true">
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.networkstack.tethering.tests.privileged"
+        android:label="Tethering privileged tests">
+    </instrumentation>
+</manifest>
diff --git a/packages/services/PacProcessor/src/com/android/net/IProxyService.aidl b/packages/services/PacProcessor/src/com/android/net/IProxyService.aidl
index 4e54aba..1bbc90d 100644
--- a/packages/services/PacProcessor/src/com/android/net/IProxyService.aidl
+++ b/packages/services/PacProcessor/src/com/android/net/IProxyService.aidl
@@ -21,7 +21,4 @@
     String resolvePacFile(String host, String url);
 
     oneway void setPacFile(String scriptContents);
-
-    oneway void startPacSystem();
-    oneway void stopPacSystem();
 }
diff --git a/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
index b006d6e..3c25bfd 100644
--- a/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
+++ b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
@@ -83,15 +83,5 @@
             }
             mPacNative.setCurrentProxyScript(script);
         }
-
-        @Override
-        public void startPacSystem() throws RemoteException {
-            //TODO: remove
-        }
-
-        @Override
-        public void stopPacSystem() throws RemoteException {
-            //TODO: remove
-        }
     }
 }
diff --git a/services/core/java/com/android/server/connectivity/PacManager.java b/services/core/java/com/android/server/connectivity/PacManager.java
index f6ce2dc..de302fc 100644
--- a/services/core/java/com/android/server/connectivity/PacManager.java
+++ b/services/core/java/com/android/server/connectivity/PacManager.java
@@ -196,13 +196,7 @@
                 mPacUrl = Uri.EMPTY;
                 mCurrentPac = null;
                 if (mProxyService != null) {
-                    try {
-                        mProxyService.stopPacSystem();
-                    } catch (RemoteException e) {
-                        Log.w(TAG, "Failed to stop PAC service", e);
-                    } finally {
-                        unbind();
-                    }
+                    unbind();
                 }
             }
             return DO_SEND_BROADCAST;
@@ -327,11 +321,6 @@
                     if (mProxyService == null) {
                         Log.e(TAG, "No proxy service");
                     } else {
-                        try {
-                            mProxyService.startPacSystem();
-                        } catch (RemoteException e) {
-                            Log.e(TAG, "Unable to reach ProxyService - PAC will not be started", e);
-                        }
                         mNetThreadHandler.post(mPacDownloader);
                     }
                 }
diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java
index f812a05..26cc3ee 100644
--- a/services/core/java/com/android/server/connectivity/ProxyTracker.java
+++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java
@@ -163,7 +163,7 @@
         if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) {
             ProxyInfo proxyProperties;
             if (!TextUtils.isEmpty(pacFileUrl)) {
-                proxyProperties = new ProxyInfo(pacFileUrl);
+                proxyProperties = new ProxyInfo(Uri.parse(pacFileUrl));
             } else {
                 proxyProperties = new ProxyInfo(host, port, exclList);
             }
diff --git a/services/core/java/com/android/server/net/IpConfigStore.java b/services/core/java/com/android/server/net/IpConfigStore.java
index e3e02e3..f0bf5c0 100644
--- a/services/core/java/com/android/server/net/IpConfigStore.java
+++ b/services/core/java/com/android/server/net/IpConfigStore.java
@@ -24,6 +24,7 @@
 import android.net.ProxyInfo;
 import android.net.RouteInfo;
 import android.net.StaticIpConfiguration;
+import android.net.Uri;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.SparseArray;
@@ -372,7 +373,7 @@
                             config.httpProxy = proxyInfo;
                             break;
                         case PAC:
-                            ProxyInfo proxyPacProperties = new ProxyInfo(pacFileUrl);
+                            ProxyInfo proxyPacProperties = new ProxyInfo(Uri.parse(pacFileUrl));
                             config.proxySettings = proxySettings;
                             config.httpProxy = proxyPacProperties;
                             break;
diff --git a/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
index 7711c6a..5f2c4a3 100644
--- a/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
+++ b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
@@ -16,12 +16,14 @@
 
 package com.android.server.net;
 
+import static android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA;
 import static android.net.NetworkTemplate.getCollapsedRatType;
 
 import android.annotation.NonNull;
 import android.content.Context;
 import android.os.Looper;
 import android.telephony.Annotation;
+import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
@@ -196,7 +198,18 @@
 
         @Override
         public void onServiceStateChanged(@NonNull ServiceState ss) {
-            final int networkType = ss.getDataNetworkType();
+            // In 5G SA (Stand Alone) mode, the primary cell itself will be 5G hence telephony
+            // would report RAT = 5G_NR.
+            // However, in 5G NSA (Non Stand Alone) mode, the primary cell is still LTE and
+            // network allocates a secondary 5G cell so telephony reports RAT = LTE along with
+            // NR state as connected. In such case, attributes the data usage to NR.
+            // See b/160727498.
+            final boolean is5GNsa = (ss.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_LTE
+                    || ss.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_LTE_CA)
+                    && ss.getNrState() == NetworkRegistrationInfo.NR_STATE_CONNECTED;
+
+            final int networkType =
+                    (is5GNsa ? NETWORK_TYPE_5G_NSA : ss.getDataNetworkType());
             final int collapsedRatType = getCollapsedRatType(networkType);
             if (collapsedRatType == mLastCollapsedRatType) return;
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 03e71f9..a363f9b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -5672,7 +5672,7 @@
                     KeyChain.bindAsUser(mContext, UserHandle.getUserHandleForUid(callingUid));
             try {
                 IKeyChainService keyChain = keyChainConnection.getService();
-                if (!keyChain.installKeyPair(privKey, cert, chain, alias)) {
+                if (!keyChain.installKeyPair(privKey, cert, chain, alias, KeyStore.UID_SELF)) {
                     return false;
                 }
                 if (requestAccess) {
diff --git a/telephony/java/android/service/euicc/EuiccProfileInfo.java b/telephony/java/android/service/euicc/EuiccProfileInfo.java
index 8450a90..92e4197 100644
--- a/telephony/java/android/service/euicc/EuiccProfileInfo.java
+++ b/telephony/java/android/service/euicc/EuiccProfileInfo.java
@@ -29,6 +29,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 
@@ -231,7 +232,9 @@
             mState = baseProfile.mState;
             mCarrierIdentifier = baseProfile.mCarrierIdentifier;
             mPolicyRules = baseProfile.mPolicyRules;
-            mAccessRules = Arrays.asList(baseProfile.mAccessRules);
+            mAccessRules = baseProfile.mAccessRules == null
+                            ? Collections.emptyList()
+                            : Arrays.asList(baseProfile.mAccessRules);
         }
 
         /** Builds the profile instance. */
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index c667165..e91d6fc9 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -72,28 +72,20 @@
     /**
      * Provides network support info for LTE VoPS and LTE Emergency bearer support
      */
+    @Nullable
     private final LteVopsSupportInfo mLteVopsSupportInfo;
 
     /**
-     * Indicates if it's using carrier aggregation
-     *
-     * @hide
-     */
-    public boolean mIsUsingCarrierAggregation;
-
-    /**
      * @hide
      */
     DataSpecificRegistrationInfo(
             int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable,
-            boolean isEnDcAvailable, LteVopsSupportInfo lteVops,
-            boolean isUsingCarrierAggregation) {
+            boolean isEnDcAvailable, @Nullable LteVopsSupportInfo lteVops) {
         this.maxDataCalls = maxDataCalls;
         this.isDcNrRestricted = isDcNrRestricted;
         this.isNrAvailable = isNrAvailable;
         this.isEnDcAvailable = isEnDcAvailable;
         this.mLteVopsSupportInfo = lteVops;
-        this.mIsUsingCarrierAggregation = isUsingCarrierAggregation;
     }
 
     /**
@@ -102,32 +94,29 @@
      * @param dsri another data specific registration info
      * @hide
      */
-    DataSpecificRegistrationInfo(DataSpecificRegistrationInfo dsri) {
+    DataSpecificRegistrationInfo(@NonNull DataSpecificRegistrationInfo dsri) {
         maxDataCalls = dsri.maxDataCalls;
         isDcNrRestricted = dsri.isDcNrRestricted;
         isNrAvailable = dsri.isNrAvailable;
         isEnDcAvailable = dsri.isEnDcAvailable;
         mLteVopsSupportInfo = dsri.mLteVopsSupportInfo;
-        mIsUsingCarrierAggregation = dsri.mIsUsingCarrierAggregation;
     }
 
-    private DataSpecificRegistrationInfo(Parcel source) {
+    private DataSpecificRegistrationInfo(/* @NonNull */ Parcel source) {
         maxDataCalls = source.readInt();
         isDcNrRestricted = source.readBoolean();
         isNrAvailable = source.readBoolean();
         isEnDcAvailable = source.readBoolean();
         mLteVopsSupportInfo = LteVopsSupportInfo.CREATOR.createFromParcel(source);
-        mIsUsingCarrierAggregation = source.readBoolean();
     }
 
     @Override
-    public void writeToParcel(Parcel dest, int flags) {
+    public void writeToParcel(/* @NonNull */ Parcel dest, int flags) {
         dest.writeInt(maxDataCalls);
         dest.writeBoolean(isDcNrRestricted);
         dest.writeBoolean(isNrAvailable);
         dest.writeBoolean(isEnDcAvailable);
         mLteVopsSupportInfo.writeToParcel(dest, flags);
-        dest.writeBoolean(mIsUsingCarrierAggregation);
     }
 
     @Override
@@ -144,8 +133,7 @@
                 .append(" isDcNrRestricted = " + isDcNrRestricted)
                 .append(" isNrAvailable = " + isNrAvailable)
                 .append(" isEnDcAvailable = " + isEnDcAvailable)
-                .append(" " + mLteVopsSupportInfo.toString())
-                .append(" mIsUsingCarrierAggregation = " + mIsUsingCarrierAggregation)
+                .append(" " + mLteVopsSupportInfo)
                 .append(" }")
                 .toString();
     }
@@ -153,7 +141,7 @@
     @Override
     public int hashCode() {
         return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable,
-                mLteVopsSupportInfo, mIsUsingCarrierAggregation);
+                mLteVopsSupportInfo);
     }
 
     @Override
@@ -167,8 +155,7 @@
                 && this.isDcNrRestricted == other.isDcNrRestricted
                 && this.isNrAvailable == other.isNrAvailable
                 && this.isEnDcAvailable == other.isEnDcAvailable
-                && this.mLteVopsSupportInfo.equals(other.mLteVopsSupportInfo)
-                && this.mIsUsingCarrierAggregation == other.mIsUsingCarrierAggregation;
+                && Objects.equals(mLteVopsSupportInfo, other.mLteVopsSupportInfo);
     }
 
     public static final @NonNull Parcelable.Creator<DataSpecificRegistrationInfo> CREATOR =
@@ -192,23 +179,4 @@
         return mLteVopsSupportInfo;
     }
 
-    /**
-     * Set the flag indicating if using carrier aggregation.
-     *
-     * @param isUsingCarrierAggregation {@code true} if using carrier aggregation.
-     * @hide
-     */
-    public void setIsUsingCarrierAggregation(boolean isUsingCarrierAggregation) {
-        mIsUsingCarrierAggregation = isUsingCarrierAggregation;
-    }
-
-    /**
-     * Get whether network has configured carrier aggregation or not.
-     *
-     * @return {@code true} if using carrier aggregation.
-     * @hide
-     */
-    public boolean isUsingCarrierAggregation() {
-        return mIsUsingCarrierAggregation;
-    }
 }
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 31a83c9..68753e1 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -218,6 +218,9 @@
     @NonNull
     private String mRplmn;
 
+    // Updated based on the accessNetworkTechnology
+    private boolean mIsUsingCarrierAggregation;
+
     /**
      * @param domain Network domain. Must be a {@link Domain}. For transport type
      * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, this must set to {@link #DOMAIN_PS}.
@@ -251,7 +254,7 @@
         mRegistrationState = registrationState;
         mRoamingType = (registrationState == REGISTRATION_STATE_ROAMING)
                 ? ServiceState.ROAMING_TYPE_UNKNOWN : ServiceState.ROAMING_TYPE_NOT_ROAMING;
-        mAccessNetworkTechnology = accessNetworkTechnology;
+        setAccessNetworkTechnology(accessNetworkTechnology);
         mRejectCause = rejectCause;
         mAvailableServices = (availableServices != null)
                 ? new ArrayList<>(availableServices) : new ArrayList<>();
@@ -290,13 +293,11 @@
                                    @Nullable CellIdentity cellIdentity, @Nullable String rplmn,
                                    int maxDataCalls, boolean isDcNrRestricted,
                                    boolean isNrAvailable, boolean isEndcAvailable,
-                                   LteVopsSupportInfo lteVopsSupportInfo,
-                                   boolean isUsingCarrierAggregation) {
+                                   LteVopsSupportInfo lteVopsSupportInfo) {
         this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
                 emergencyOnly, availableServices, cellIdentity, rplmn);
         mDataSpecificInfo = new DataSpecificRegistrationInfo(
-                maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo,
-                isUsingCarrierAggregation);
+                maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo);
         updateNrState();
     }
 
@@ -317,6 +318,7 @@
                 DataSpecificRegistrationInfo.class.getClassLoader());
         mNrState = source.readInt();
         mRplmn = source.readString();
+        mIsUsingCarrierAggregation = source.readBoolean();
     }
 
     /**
@@ -331,6 +333,7 @@
         mRegistrationState = nri.mRegistrationState;
         mRoamingType = nri.mRoamingType;
         mAccessNetworkTechnology = nri.mAccessNetworkTechnology;
+        mIsUsingCarrierAggregation = nri.mIsUsingCarrierAggregation;
         mRejectCause = nri.mRejectCause;
         mEmergencyOnly = nri.mEmergencyOnly;
         mAvailableServices = new ArrayList<>(nri.mAvailableServices);
@@ -484,9 +487,7 @@
         if (tech == TelephonyManager.NETWORK_TYPE_LTE_CA) {
             // For old device backward compatibility support
             tech = TelephonyManager.NETWORK_TYPE_LTE;
-            if (mDataSpecificInfo != null) {
-                mDataSpecificInfo.setIsUsingCarrierAggregation(true);
-            }
+            mIsUsingCarrierAggregation = true;
         }
         mAccessNetworkTechnology = tech;
     }
@@ -511,6 +512,27 @@
     }
 
     /**
+     * Set whether network has configured carrier aggregation or not.
+     *
+     * @param isUsingCarrierAggregation set whether or not carrier aggregation is used.
+     *
+     * @hide
+     */
+    public void setIsUsingCarrierAggregation(boolean isUsingCarrierAggregation) {
+        mIsUsingCarrierAggregation = isUsingCarrierAggregation;
+    }
+
+    /**
+     * Get whether network has configured carrier aggregation or not.
+     *
+     * @return {@code true} if using carrier aggregation.
+     * @hide
+     */
+    public boolean isUsingCarrierAggregation() {
+        return mIsUsingCarrierAggregation;
+    }
+
+    /**
      * @hide
      */
     @Nullable
@@ -616,6 +638,7 @@
                 .append(" dataSpecificInfo=").append(mDataSpecificInfo)
                 .append(" nrState=").append(nrStateToString(mNrState))
                 .append(" rRplmn=").append(mRplmn)
+                .append(" isUsingCarrierAggregation=").append(mIsUsingCarrierAggregation)
                 .append("}").toString();
     }
 
@@ -623,7 +646,8 @@
     public int hashCode() {
         return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType,
                 mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
-                mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState, mRplmn);
+                mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState, mRplmn,
+                mIsUsingCarrierAggregation);
     }
 
     @Override
@@ -643,6 +667,7 @@
                 && mRejectCause == other.mRejectCause
                 && mEmergencyOnly == other.mEmergencyOnly
                 && mAvailableServices.equals(other.mAvailableServices)
+                && mIsUsingCarrierAggregation == other.mIsUsingCarrierAggregation
                 && Objects.equals(mCellIdentity, other.mCellIdentity)
                 && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo)
                 && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo)
@@ -669,6 +694,7 @@
         dest.writeParcelable(mDataSpecificInfo, 0);
         dest.writeInt(mNrState);
         dest.writeString(mRplmn);
+        dest.writeBoolean(mIsUsingCarrierAggregation);
     }
 
     /**
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 5c84297..243b24b 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1392,29 +1392,14 @@
 
     /** @hide */
     public boolean isUsingCarrierAggregation() {
-        boolean isUsingCa = false;
-        NetworkRegistrationInfo nri = getNetworkRegistrationInfo(
-                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        if (nri != null) {
-            DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo();
-            if (dsri != null) {
-                isUsingCa = dsri.isUsingCarrierAggregation();
-            }
-        }
-        return isUsingCa || getCellBandwidths().length > 1;
-    }
+        if (getCellBandwidths().length > 1) return true;
 
-    /** @hide */
-    public void setIsUsingCarrierAggregation(boolean ca) {
-        NetworkRegistrationInfo nri = getNetworkRegistrationInfo(
-                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        if (nri != null) {
-            DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo();
-            if (dsri != null) {
-                dsri.setIsUsingCarrierAggregation(ca);
-                addNetworkRegistrationInfo(nri);
+        synchronized (mNetworkRegistrationInfos) {
+            for (NetworkRegistrationInfo nri : mNetworkRegistrationInfos) {
+                if (nri.isUsingCarrierAggregation()) return true;
             }
         }
+        return false;
     }
 
     /**
diff --git a/tests/net/java/android/net/NetworkTemplateTest.kt b/tests/net/java/android/net/NetworkTemplateTest.kt
index 5dd0fda..9ba56e4 100644
--- a/tests/net/java/android/net/NetworkTemplateTest.kt
+++ b/tests/net/java/android/net/NetworkTemplateTest.kt
@@ -26,6 +26,7 @@
 import android.net.NetworkStats.ROAMING_ALL
 import android.net.NetworkTemplate.MATCH_MOBILE
 import android.net.NetworkTemplate.MATCH_WIFI
+import android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA
 import android.net.NetworkTemplate.NETWORK_TYPE_ALL
 import android.net.NetworkTemplate.buildTemplateMobileWithRatType
 import android.telephony.TelephonyManager
@@ -145,11 +146,13 @@
         assertParcelSane(templateWifi, 8)
     }
 
-    // Verify NETWORK_TYPE_ALL does not conflict with TelephonyManager#NETWORK_TYPE_* constants.
+    // Verify NETWORK_TYPE_* constants in NetworkTemplate do not conflict with
+    // TelephonyManager#NETWORK_TYPE_* constants.
     @Test
-    fun testNetworkTypeAll() {
+    fun testNetworkTypeConstants() {
         for (ratType in TelephonyManager.getAllNetworkTypes()) {
             assertNotEquals(NETWORK_TYPE_ALL, ratType)
+            assertNotEquals(NETWORK_TYPE_5G_NSA, ratType)
         }
     }
 }
diff --git a/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java b/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java
index c813269..9531b0a 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java
@@ -17,6 +17,7 @@
 package com.android.server.net;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
@@ -30,7 +31,9 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.net.NetworkTemplate;
 import android.os.test.TestLooper;
+import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
@@ -61,7 +64,6 @@
     private static final String TEST_IMSI3 = "466929999999999";
 
     @Mock private Context mContext;
-    @Mock private PhoneStateListener mPhoneStateListener;
     @Mock private SubscriptionManager mSubscriptionManager;
     @Mock private TelephonyManager mTelephonyManager;
     @Mock private NetworkStatsSubscriptionsMonitor.Delegate mDelegate;
@@ -215,4 +217,55 @@
         verify(mTelephonyManager, times(2)).listen(any(), eq(PhoneStateListener.LISTEN_NONE));
         assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN);
     }
+
+
+    @Test
+    public void test5g() {
+        mMonitor.start();
+        // Insert sim1, verify RAT type is NETWORK_TYPE_UNKNOWN, and never get any callback
+        // before changing RAT type. Also capture listener for later use.
+        addTestSub(TEST_SUBID1, TEST_IMSI1);
+        assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN);
+        final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor =
+                ArgumentCaptor.forClass(RatTypeListener.class);
+        verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor.capture(),
+                eq(PhoneStateListener.LISTEN_SERVICE_STATE));
+        final RatTypeListener listener = CollectionUtils
+                .find(ratTypeListenerCaptor.getAllValues(), it -> it.getSubId() == TEST_SUBID1);
+        assertNotNull(listener);
+
+        // Set RAT type to 5G NSA (non-standalone) mode, verify the monitor outputs
+        // NETWORK_TYPE_5G_NSA.
+        final ServiceState serviceState = mock(ServiceState.class);
+        when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_LTE);
+        when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED);
+        listener.onServiceStateChanged(serviceState);
+        assertRatTypeChangedForSub(TEST_IMSI1, NetworkTemplate.NETWORK_TYPE_5G_NSA);
+        reset(mDelegate);
+
+        // Set RAT type to LTE without NR connected, the RAT type should be downgraded to LTE.
+        when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_NONE);
+        listener.onServiceStateChanged(serviceState);
+        assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_LTE);
+        reset(mDelegate);
+
+        // Verify NR connected with other RAT type does not take effect.
+        when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_UMTS);
+        when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED);
+        listener.onServiceStateChanged(serviceState);
+        assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS);
+        reset(mDelegate);
+
+        // Set RAT type to 5G standalone mode, the RAT type should be NR.
+        setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1,
+                TelephonyManager.NETWORK_TYPE_NR);
+        assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR);
+        reset(mDelegate);
+
+        // Set NR state to none in standalone mode does not change anything.
+        when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_NR);
+        when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_NONE);
+        listener.onServiceStateChanged(serviceState);
+        assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR);
+    }
 }